From a49e89da7c8563bad867499be09eb5cad0e2f557 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 11 Apr 2025 18:36:07 +0200 Subject: [PATCH 001/122] Add radix prefix --- src/terrainlib/Dataset.cpp | 12 ++-- src/terrainlib/Dataset.h | 8 +-- src/terrainlib/DatasetReader.cpp | 20 +++--- src/terrainlib/DatasetReader.h | 6 +- src/terrainlib/ParallelTileGenerator.cpp | 19 +++--- src/terrainlib/ParallelTileGenerator.h | 24 ++++--- src/terrainlib/ParallelTiler.cpp | 22 +++---- src/terrainlib/ParallelTiler.h | 10 +-- src/terrainlib/TileHeightsGenerator.cpp | 8 +-- src/terrainlib/TileHeightsGenerator.h | 6 +- src/terrainlib/Tiler.cpp | 18 ++---- src/terrainlib/Tiler.h | 18 +++--- src/terrainlib/TopDownTiler.cpp | 12 ++-- src/terrainlib/TopDownTiler.h | 4 +- src/terrainlib/alpine_raster.cpp | 6 +- src/terrainlib/alpine_raster.h | 17 +++-- src/terrainlib/ctb/GlobalGeodetic.hpp | 6 +- src/terrainlib/ctb/GlobalMercator.hpp | 4 +- src/terrainlib/ctb/Grid.hpp | 72 +++++++++------------ src/terrainlib/depth_first_tile_traverser.h | 5 +- src/terrainlib/mesh/terrain_mesh.cpp | 8 +-- src/terrainlib/mesh/terrain_mesh.h | 4 +- src/terrainlib/srs.h | 7 +- src/terrainlib/tntn/Raster.h | 2 +- 24 files changed, 140 insertions(+), 178 deletions(-) diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index bbe446a..d87daea 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -67,8 +67,7 @@ std::string Dataset::name() const Dataset::~Dataset() = default; -tile::SrsBounds Dataset::bounds() const -{ +radix::tile::SrsBounds Dataset::bounds() const { std::array adfGeoTransform = {}; if (m_gdal_dataset->GetGeoTransform(adfGeoTransform.data()) != CE_None) throw Exception("Could not get transformation information from source dataset"); @@ -90,8 +89,7 @@ tile::SrsBounds Dataset::bounds() const return { {westX, southY}, {eastX, northY} }; } -tile::SrsBounds Dataset::bounds(const OGRSpatialReference& targetSrs) const -{ +radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) const { const auto l_bounds = bounds(); const auto west = l_bounds.min.x; const auto east = l_bounds.max.x; @@ -164,13 +162,11 @@ unsigned Dataset::heightInPixels() const return ctb::i_pixel(m_gdal_dataset->GetRasterYSize()); } -double Dataset::widthInPixels(const tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const -{ +double Dataset::widthInPixels(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &bounds_srs) const { return bounds.width() / pixelWidthIn(bounds_srs); } -double Dataset::heightInPixels(const tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const -{ +double Dataset::heightInPixels(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &bounds_srs) const { return bounds.height() / pixelHeightIn(bounds_srs); } diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index aaa9570..ef62bcf 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -45,13 +45,13 @@ class Dataset { [[nodiscard]] std::string name() const; - [[nodiscard]] tile::SrsBounds bounds() const; - [[nodiscard]] tile::SrsBounds bounds(const OGRSpatialReference& targetSrs) const; + [[nodiscard]] radix::tile::SrsBounds bounds() const; + [[nodiscard]] radix::tile::SrsBounds bounds(const OGRSpatialReference &targetSrs) const; [[nodiscard]] OGRSpatialReference srs() const; [[nodiscard]] unsigned widthInPixels() const; [[nodiscard]] unsigned heightInPixels() const; - [[nodiscard]] double widthInPixels(const tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; - [[nodiscard]] double heightInPixels(const tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; + [[nodiscard]] double widthInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; + [[nodiscard]] double heightInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; [[nodiscard]] unsigned n_bands() const; [[nodiscard]] GDALDataset* gdalDataset(); diff --git a/src/terrainlib/DatasetReader.cpp b/src/terrainlib/DatasetReader.cpp index cb81338..7032ad6 100644 --- a/src/terrainlib/DatasetReader.cpp +++ b/src/terrainlib/DatasetReader.cpp @@ -43,17 +43,16 @@ std::string toWkt(const OGRSpatialReference& srs) return wkt_string; } -std::array computeGeoTransform(const tile::SrsBounds& bounds, unsigned width, unsigned height) +std::array computeGeoTransform(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) { return { bounds.min.x, bounds.width() / width, 0, bounds.max.y, 0, -bounds.height() / height }; } using GdalImageTransformArgsPtr = std::unique_ptr; -GdalImageTransformArgsPtr make_image_transform_args(const DatasetReader& reader, - Dataset* dataset, - const tile::SrsBounds& bounds, unsigned width, unsigned height) -{ +GdalImageTransformArgsPtr make_image_transform_args(const DatasetReader &reader, + Dataset *dataset, + const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) { CPLStringList transformOptions; if (reader.isReprojecting()) { transformOptions.SetNameValue("SRC_SRS", reader.dataset_srs_wkt().c_str()); @@ -73,7 +72,7 @@ GdalImageTransformArgsPtr make_image_transform_args(const DatasetReader& reader, using GdalWarpOptionsPtr = std::unique_ptr; using WarpOptionData = std::pair; -WarpOptionData makeWarpOptions(const DatasetReader& reader, Dataset* dataset, const tile::SrsBounds& bounds, unsigned width, unsigned height) +WarpOptionData makeWarpOptions(const DatasetReader& reader, Dataset* dataset, const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) { auto options = GdalWarpOptionsPtr(GDALCreateWarpOptions(), &GDALDestroyWarpOptions); options->hSrcDS = dataset->gdalDataset(); @@ -185,13 +184,11 @@ DatasetReader::DatasetReader(const std::shared_ptr& dataset, const OGRS throw Exception(fmt::format("Dataset does not contain band number {} (there are {} bands).", band, dataset->n_bands())); } -HeightData DatasetReader::read(const tile::SrsBounds& bounds, unsigned width, unsigned height) const -{ +HeightData DatasetReader::read(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { return readFrom(m_dataset, bounds, width, height); } -HeightData DatasetReader::readWithOverviews(const tile::SrsBounds& bounds, unsigned width, unsigned height) const -{ +HeightData DatasetReader::readWithOverviews(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { #ifdef ATB_ENABLE_OVERVIEW_READING auto transformer_args = make_image_transform_args(*this, m_dataset.get(), bounds, width, height); auto source_dataset = getOverviewDataset(m_dataset, transformer_args.get(), m_warn_on_missing_overviews); @@ -202,8 +199,7 @@ HeightData DatasetReader::readWithOverviews(const tile::SrsBounds& bounds, unsig #endif } -HeightData DatasetReader::readFrom(const std::shared_ptr& source_dataset, const tile::SrsBounds& bounds, unsigned width, unsigned height) const -{ +HeightData DatasetReader::readFrom(const std::shared_ptr &source_dataset, const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { // if we have performance problems with the warping, it'd still be possible to approximate the warping operation with a linear transform (mostly when zoomed in / on higher zoom levels). // CTB does this in GDALTiler.cpp around line 375 ("// Decide if we are doing an approximate or exact transformation"). diff --git a/src/terrainlib/DatasetReader.h b/src/terrainlib/DatasetReader.h index 01b85b8..62e161e 100644 --- a/src/terrainlib/DatasetReader.h +++ b/src/terrainlib/DatasetReader.h @@ -33,8 +33,8 @@ class DatasetReader { public: DatasetReader(const std::shared_ptr& dataset, const OGRSpatialReference& targetSRS, unsigned band, bool warn_on_missing_overviews = true); - HeightData read(const tile::SrsBounds& bounds, unsigned width, unsigned height) const; - HeightData readWithOverviews(const tile::SrsBounds& bounds, unsigned width, unsigned height) const; + HeightData read(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const; + HeightData readWithOverviews(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const; unsigned dataset_band() const { return m_band; } bool isReprojecting() const { return m_requires_reprojection; } @@ -42,7 +42,7 @@ class DatasetReader { std::string target_srs_wkt() const { return m_target_srs_wkt; } protected: - HeightData readFrom(const std::shared_ptr& dataset, const tile::SrsBounds& bounds, unsigned width, unsigned height) const; + HeightData readFrom(const std::shared_ptr &dataset, const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const; private: std::shared_ptr m_dataset; diff --git a/src/terrainlib/ParallelTileGenerator.cpp b/src/terrainlib/ParallelTileGenerator.cpp index 671b846..cd28ae2 100644 --- a/src/terrainlib/ParallelTileGenerator.cpp +++ b/src/terrainlib/ParallelTileGenerator.cpp @@ -40,12 +40,11 @@ ParallelTileGenerator::ParallelTileGenerator(const std::string& input_data_path, { } -ParallelTileGenerator ParallelTileGenerator::make(const std::string& input_data_path, - ctb::Grid::Srs srs, tile::Scheme tiling_scheme, - std::unique_ptr tile_writer, - const std::string& output_data_path, - unsigned grid_resolution) -{ +ParallelTileGenerator ParallelTileGenerator::make(const std::string &input_data_path, + ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, + std::unique_ptr tile_writer, + const std::string &output_data_path, + unsigned grid_resolution) { const auto dataset = Dataset::make_shared(input_data_path); ctb::Grid grid = ctb::GlobalGeodetic(grid_resolution); if (srs == ctb::Grid::Srs::SphericalMercator) @@ -64,8 +63,7 @@ const ctb::Grid& ParallelTileGenerator::grid() const return m_grid; } -void ParallelTileGenerator::write(const tile::Descriptor& tile, const HeightData& heights) const -{ +void ParallelTileGenerator::write(const radix::tile::Descriptor &tile, const HeightData &heights) const { const auto dir_path = fmt::format("{}/{}/{}", m_output_data_path, tile.id.zoom_level, tile.id.coords.x); const auto file_path = fmt::format("{}/{}.{}", dir_path, tile.id.coords.y, m_tile_writer->formatFileEnding()); std::filesystem::create_directories(dir_path); @@ -86,7 +84,7 @@ void ParallelTileGenerator::process(const std::pair& z if (progress_bar_on_console) monitoring_thread = pi.startMonitoring(); // destructor will join. - const auto fun = [&pi, progress_bar_on_console, this](const tile::Descriptor& tile) { + const auto fun = [&pi, progress_bar_on_console, this](const radix::tile::Descriptor &tile) { // Recreating Dataset for every tile. This was the easiest fix for multithreading, // and it takes only 0.5% of the time (half a percent). // most of the cpu time is used in 'readWithOverviews' (specificly 'RasterIO', and @@ -101,8 +99,7 @@ void ParallelTileGenerator::process(const std::pair& z std::for_each(std::execution::par, tiles.begin(), tiles.end(), fun); } -tile::Border ParallelTileWriterInterface::formatRequiresBorder() const -{ +radix::tile::Border ParallelTileWriterInterface::formatRequiresBorder() const { return m_format_requires_border; } diff --git a/src/terrainlib/ParallelTileGenerator.h b/src/terrainlib/ParallelTileGenerator.h index 2d3796e..033334d 100644 --- a/src/terrainlib/ParallelTileGenerator.h +++ b/src/terrainlib/ParallelTileGenerator.h @@ -40,36 +40,34 @@ class ParallelTileGenerator { public: ParallelTileGenerator(const std::string& input_data_path, const ctb::Grid& grid, const ParallelTiler& tiler, std::unique_ptr tile_writer, const std::string& output_data_path); - [[nodiscard]] static ParallelTileGenerator make(const std::string& input_data_path, - ctb::Grid::Srs srs, tile::Scheme tiling_scheme, - std::unique_ptr tile_writer, - const std::string& output_data_path, - unsigned grid_resolution = 256); + [[nodiscard]] static ParallelTileGenerator make(const std::string &input_data_path, + ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, + std::unique_ptr tile_writer, + const std::string &output_data_path, + unsigned grid_resolution = 256); void setWarnOnMissingOverviews(bool flag) { m_warn_on_missing_overviews = flag; } [[nodiscard]] const ParallelTiler& tiler() const; [[nodiscard]] const ctb::Grid& grid() const; - void write(const tile::Descriptor& tile, const HeightData& heights) const; + void write(const radix::tile::Descriptor &tile, const HeightData &heights) const; void process(const std::pair& zoom_range, bool progress_bar_on_console = false, bool generate_world_wide_tiles = false) const; }; class ParallelTileWriterInterface { - tile::Border m_format_requires_border; + radix::tile::Border m_format_requires_border; std::string m_file_ending; public: - ParallelTileWriterInterface(tile::Border format_requires_border, const std::string& file_ending) - : m_format_requires_border(format_requires_border) - , m_file_ending(file_ending) - { + ParallelTileWriterInterface(radix::tile::Border format_requires_border, const std::string &file_ending) + : m_format_requires_border(format_requires_border), m_file_ending(file_ending) { } ParallelTileWriterInterface(const ParallelTileWriterInterface&) = default; ParallelTileWriterInterface(ParallelTileWriterInterface&&) = default; virtual ~ParallelTileWriterInterface() = default; ParallelTileWriterInterface& operator=(const ParallelTileWriterInterface&) = default; ParallelTileWriterInterface& operator=(ParallelTileWriterInterface&&) = default; - virtual void write(const std::string& file_path, const tile::Descriptor& tile, const HeightData& heights) const = 0; - [[nodiscard]] tile::Border formatRequiresBorder() const; + virtual void write(const std::string &file_path, const radix::tile::Descriptor &tile, const HeightData &heights) const = 0; + [[nodiscard]] radix::tile::Border formatRequiresBorder() const; [[nodiscard]] const std::string& formatFileEnding() const; }; diff --git a/src/terrainlib/ParallelTiler.cpp b/src/terrainlib/ParallelTiler.cpp index 5349cff..ca77293 100644 --- a/src/terrainlib/ParallelTiler.cpp +++ b/src/terrainlib/ParallelTiler.cpp @@ -22,32 +22,31 @@ #include "Exception.h" #include -ParallelTiler::ParallelTiler(const ctb::Grid& grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme) : Tiler(grid, bounds, border, scheme) +ParallelTiler::ParallelTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) : Tiler(grid, bounds, border, scheme) { } -tile::Id ParallelTiler::southWestTile(unsigned zoom_level) const -{ +radix::tile::Id ParallelTiler::southWestTile(unsigned zoom_level) const { return grid().crsToTile(bounds().min, zoom_level).to(scheme()); } -tile::Id ParallelTiler::northEastTile(unsigned zoom_level) const +radix::tile::Id ParallelTiler::northEastTile(unsigned zoom_level) const { const auto epsilon = grid().resolution(zoom_level) / 100; return grid().crsToTile(bounds().max - epsilon, zoom_level).to(scheme()); } -std::vector ParallelTiler::generateTiles(unsigned zoom_level) const +std::vector ParallelTiler::generateTiles(unsigned zoom_level) const { // in the tms scheme south west corresponds to the smaller numbers. hence we can iterate from sw to ne - const auto sw = southWestTile(zoom_level).to(tile::Scheme::Tms).coords; - const auto ne = northEastTile(zoom_level).to(tile::Scheme::Tms).coords; + const auto sw = southWestTile(zoom_level).to(radix::tile::Scheme::Tms).coords; + const auto ne = northEastTile(zoom_level).to(radix::tile::Scheme::Tms).coords; - std::vector tiles; + std::vector tiles; tiles.reserve((ne.y - sw.y + 1) * (ne.x - sw.x + 1)); for (auto ty = sw.y; ty <= ne.y; ++ty) { for (auto tx = sw.x; tx <= ne.x; ++tx) { - const auto tile_id = tile::Id { zoom_level, { tx, ty }, tile::Scheme::Tms }.to(scheme()); + const auto tile_id = radix::tile::Id{zoom_level, {tx, ty}, radix::tile::Scheme::Tms}.to(scheme()); tiles.emplace_back(tile_for(tile_id)); if (tiles.size() >= 1'000'000'000) // think about creating an on the fly tile generator. storing so many tiles takes a lot of memory. @@ -61,9 +60,8 @@ std::vector ParallelTiler::generateTiles(unsigned zoom_level) return tiles; } -std::vector ParallelTiler::generateTiles(const std::pair& zoom_range) const -{ - std::vector tiles; +std::vector ParallelTiler::generateTiles(const std::pair &zoom_range) const { + std::vector tiles; assert(zoom_range.first <= zoom_range.second); for (ctb::i_zoom i = zoom_range.first; i <= zoom_range.second; ++i) { auto zoom_level_tiles = generateTiles(i); diff --git a/src/terrainlib/ParallelTiler.h b/src/terrainlib/ParallelTiler.h index b772925..2ab9c5e 100644 --- a/src/terrainlib/ParallelTiler.h +++ b/src/terrainlib/ParallelTiler.h @@ -23,11 +23,11 @@ class ParallelTiler : public Tiler { public: - ParallelTiler(const ctb::Grid& grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme); + ParallelTiler(const ctb::Grid &grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme); - [[nodiscard]] std::vector generateTiles(unsigned zoom_level) const; - [[nodiscard]] std::vector generateTiles(const std::pair& zoom_range) const; + [[nodiscard]] std::vector generateTiles(unsigned zoom_level) const; + [[nodiscard]] std::vector generateTiles(const std::pair& zoom_range) const; - [[nodiscard]] tile::Id southWestTile(unsigned zoom_level) const; - [[nodiscard]] tile::Id northEastTile(unsigned zoom_level) const; + [[nodiscard]] radix::tile::Id southWestTile(unsigned zoom_level) const; + [[nodiscard]] radix::tile::Id northEastTile(unsigned zoom_level) const; }; diff --git a/src/terrainlib/TileHeightsGenerator.cpp b/src/terrainlib/TileHeightsGenerator.cpp index ca4c651..8b8e359 100644 --- a/src/terrainlib/TileHeightsGenerator.cpp +++ b/src/terrainlib/TileHeightsGenerator.cpp @@ -28,7 +28,7 @@ #include "depth_first_tile_traverser.h" #include -TileHeightsGenerator::TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, tile::Scheme scheme, tile::Border border, std::filesystem::path output_path) +TileHeightsGenerator::TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path) : m_input_data_path(std::move(input_data_path)) , m_srs(srs) , m_scheme(scheme) @@ -40,7 +40,7 @@ TileHeightsGenerator::TileHeightsGenerator(std::string input_data_path, ctb::Gri void TileHeightsGenerator::run(unsigned max_zoom_level) const { struct MinMaxData { - tile::Id tile_id; + radix::tile::Id tile_id; std::pair min_max = std::make_pair(0, 9000); }; @@ -52,9 +52,9 @@ void TileHeightsGenerator::run(unsigned max_zoom_level) const const auto bounds = dataset->bounds(grid.getSRS()); const auto tile_reader = DatasetReader(dataset, grid.getSRS(), 1, false); const auto tiler = TopDownTiler(grid, bounds, m_border, m_scheme); - auto tile_heights = TileHeights(); + auto tile_heights = radix::TileHeights(); - const auto read_function = [&](const tile::Descriptor& tile) -> MinMaxData { + const auto read_function = [&](const radix::tile::Descriptor &tile) -> MinMaxData { const auto tile_data = tile_reader.readWithOverviews(tile.srsBounds, tile.tileSize, tile.tileSize); auto [min, max] = std::ranges::minmax(tile_data); tile_heights.emplace(tile.id, std::make_pair(min, max)); diff --git a/src/terrainlib/TileHeightsGenerator.h b/src/terrainlib/TileHeightsGenerator.h index 29fcbf6..00f63a7 100644 --- a/src/terrainlib/TileHeightsGenerator.h +++ b/src/terrainlib/TileHeightsGenerator.h @@ -29,11 +29,11 @@ class TileHeightsGenerator { std::string m_input_data_path; ctb::Grid::Srs m_srs; - tile::Scheme m_scheme; - tile::Border m_border; + radix::tile::Scheme m_scheme; + radix::tile::Border m_border; std::filesystem::path m_output_path; public: - TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, tile::Scheme scheme, tile::Border border, std::filesystem::path output_path); + TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path); void run(unsigned max_zoom_level) const; }; diff --git a/src/terrainlib/Tiler.cpp b/src/terrainlib/Tiler.cpp index 275c96b..eb0f703 100644 --- a/src/terrainlib/Tiler.cpp +++ b/src/terrainlib/Tiler.cpp @@ -20,7 +20,7 @@ #include -Tiler::Tiler(ctb::Grid grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme) +Tiler::Tiler(ctb::Grid grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) : m_grid(std::move(grid)) , m_bounds(bounds) , m_border_south_east(border) @@ -44,29 +44,25 @@ ctb::i_tile Tiler::tile_size() const return grid_size() + unsigned(border_south_east()); } -tile::Border Tiler::border_south_east() const +radix::tile::Border Tiler::border_south_east() const { return m_border_south_east; } -tile::Descriptor Tiler::tile_for(const tile::Id& tile_id) const +radix::tile::Descriptor Tiler::tile_for(const radix::tile::Id& tile_id) const { - tile::SrsBounds srs_bounds = grid().srsBounds(tile_id, border_south_east() == tile::Border::Yes); + radix::tile::SrsBounds srs_bounds = grid().srsBounds(tile_id, border_south_east() == radix::tile::Border::Yes); return {tile_id, srs_bounds, grid().getEpsgCode(), grid_size(), tile_size()}; } -tile::Scheme Tiler::scheme() const -{ +radix::tile::Scheme Tiler::scheme() const { return m_scheme; } -const tile::SrsBounds& Tiler::bounds() const -{ +const radix::tile::SrsBounds &Tiler::bounds() const { return m_bounds; } -void Tiler::setBounds(const tile::SrsBounds& newBounds) -{ +void Tiler::setBounds(const radix::tile::SrsBounds &newBounds) { m_bounds = newBounds; } - diff --git a/src/terrainlib/Tiler.h b/src/terrainlib/Tiler.h index ae2d6fa..c9ffd8d 100644 --- a/src/terrainlib/Tiler.h +++ b/src/terrainlib/Tiler.h @@ -25,24 +25,24 @@ class Tiler { public: - Tiler(ctb::Grid grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme); + Tiler(ctb::Grid grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme); - [[nodiscard]] tile::Scheme scheme() const; - [[nodiscard]] const tile::SrsBounds& bounds() const; - void setBounds(const tile::SrsBounds& newBounds); - [[nodiscard]] tile::Descriptor tile_for(const tile::Id& tile_id) const; + [[nodiscard]] radix::tile::Scheme scheme() const; + [[nodiscard]] const radix::tile::SrsBounds &bounds() const; + void setBounds(const radix::tile::SrsBounds &newBounds); + [[nodiscard]] radix::tile::Descriptor tile_for(const radix::tile::Id &tile_id) const; protected: [[nodiscard]] const ctb::Grid& grid() const; [[nodiscard]] ctb::i_tile grid_size() const; [[nodiscard]] ctb::i_tile tile_size() const; - [[nodiscard]] tile::Border border_south_east() const; + [[nodiscard]] radix::tile::Border border_south_east() const; private: const ctb::Grid m_grid; - tile::SrsBounds m_bounds; - const tile::Border m_border_south_east; - const tile::Scheme m_scheme; + radix::tile::SrsBounds m_bounds; + const radix::tile::Border m_border_south_east; + const radix::tile::Scheme m_scheme; }; diff --git a/src/terrainlib/TopDownTiler.cpp b/src/terrainlib/TopDownTiler.cpp index d4300cf..8030532 100644 --- a/src/terrainlib/TopDownTiler.cpp +++ b/src/terrainlib/TopDownTiler.cpp @@ -18,18 +18,16 @@ #include "TopDownTiler.h" -TopDownTiler::TopDownTiler(const ctb::Grid& grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme) - : Tiler(grid, bounds, border, scheme) -{ +TopDownTiler::TopDownTiler(const ctb::Grid &grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme) + : Tiler(grid, bounds, border, scheme) { } -std::vector TopDownTiler::generateTiles(const tile::Id& parent_id) const -{ +std::vector TopDownTiler::generateTiles(const radix::tile::Id &parent_id) const { assert(parent_id.scheme == scheme()); const auto tile_ids = parent_id.to(scheme()).children(); - std::vector tiles; + std::vector tiles; for (const auto& tile_id : tile_ids) { - tile::Descriptor t = tile_for(tile_id); + radix::tile::Descriptor t = tile_for(tile_id); if (intersect(bounds(), t.srsBounds)) tiles.push_back(std::move(t)); } diff --git a/src/terrainlib/TopDownTiler.h b/src/terrainlib/TopDownTiler.h index 363e97b..0b7c533 100644 --- a/src/terrainlib/TopDownTiler.h +++ b/src/terrainlib/TopDownTiler.h @@ -24,7 +24,7 @@ class TopDownTiler : public Tiler { public: - TopDownTiler(const ctb::Grid& grid, const tile::SrsBounds& bounds, tile::Border border, tile::Scheme scheme); + TopDownTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme); - [[nodiscard]] std::vector generateTiles(const tile::Id& parent_id) const; + [[nodiscard]] std::vector generateTiles(const radix::tile::Id &parent_id) const; }; diff --git a/src/terrainlib/alpine_raster.cpp b/src/terrainlib/alpine_raster.cpp index d06c9ba..53c45d0 100644 --- a/src/terrainlib/alpine_raster.cpp +++ b/src/terrainlib/alpine_raster.cpp @@ -30,13 +30,11 @@ #include "ctb/Grid.hpp" #include -ParallelTileGenerator alpine_raster::make_generator(const std::string& input_data_path, const std::string& output_data_path, ctb::Grid::Srs srs, tile::Scheme tiling_scheme, tile::Border border, unsigned grid_resolution) -{ +ParallelTileGenerator alpine_raster::make_generator(const std::string &input_data_path, const std::string &output_data_path, ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, radix::tile::Border border, unsigned grid_resolution) { return ParallelTileGenerator::make(input_data_path, srs, tiling_scheme, std::make_unique(border), output_data_path, grid_resolution); } -void alpine_raster::TileWriter::write(const std::string& file_path, const tile::Descriptor& tile, const HeightData& heights) const -{ +void alpine_raster::TileWriter::write(const std::string &file_path, const radix::tile::Descriptor &tile, const HeightData &heights) const { image::saveImageAsPng(image::transformImage(heights, radix::height_encoding::to_rgb), file_path); } diff --git a/src/terrainlib/alpine_raster.h b/src/terrainlib/alpine_raster.h index 506f456..b1ad459 100644 --- a/src/terrainlib/alpine_raster.h +++ b/src/terrainlib/alpine_raster.h @@ -34,19 +34,18 @@ namespace alpine_raster { class TileWriter : public ParallelTileWriterInterface { public: - TileWriter(tile::Border border) - : ParallelTileWriterInterface(border, "png") - { + TileWriter(radix::tile::Border border) + : ParallelTileWriterInterface(border, "png") { } - void write(const std::string& base_path, const tile::Descriptor& tile, const HeightData& heights) const override; + void write(const std::string& base_path, const radix::tile::Descriptor& tile, const HeightData& heights) const override; }; [[nodiscard]] ParallelTileGenerator make_generator( - const std::string& input_data_path, - const std::string& output_data_path, + const std::string &input_data_path, + const std::string &output_data_path, ctb::Grid::Srs srs, - tile::Scheme tiling_scheme, - tile::Border border, + radix::tile::Scheme tiling_scheme, + radix::tile::Border border, unsigned grid_resolution = 256); -}; +} #endif // ALPINERASTERGENERATOR_H diff --git a/src/terrainlib/ctb/GlobalGeodetic.hpp b/src/terrainlib/ctb/GlobalGeodetic.hpp index ef26a9f..5ddeecc 100644 --- a/src/terrainlib/ctb/GlobalGeodetic.hpp +++ b/src/terrainlib/ctb/GlobalGeodetic.hpp @@ -38,11 +38,11 @@ class GlobalGeodetic : public Grid { /// Initialise the profile with a specific tile size GlobalGeodetic(i_tile tileSize = 256) : Grid(tileSize, - tile::SrsBounds{{-180, -90}, {180, 90}}, + radix::tile::SrsBounds{{-180, -90}, {180, 90}}, cSRS, 4326, - // according to this global geodetic has 2 root tiles: https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic - std::vector{tile::Id{0, {0, 0}, tile::Scheme::Tms}, tile::Id{0, {1, 0}, tile::Scheme::Tms}}, + // global geodetic has 2 root tiles: https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic + std::vector{radix::tile::Id{0, {0, 0}, radix::tile::Scheme::Tms}, radix::tile::Id{0, {1, 0}, radix::tile::Scheme::Tms}}, 2) { } diff --git a/src/terrainlib/ctb/GlobalMercator.hpp b/src/terrainlib/ctb/GlobalMercator.hpp index 2d257e2..2da275a 100644 --- a/src/terrainlib/ctb/GlobalMercator.hpp +++ b/src/terrainlib/ctb/GlobalMercator.hpp @@ -38,10 +38,10 @@ class ctb::GlobalMercator : public Grid { public: GlobalMercator(i_tile tileSize = 256) : Grid(tileSize, - tile::SrsBounds{{-cOriginShift, -cOriginShift}, {cOriginShift, cOriginShift}}, + radix::tile::SrsBounds{{-cOriginShift, -cOriginShift}, {cOriginShift, cOriginShift}}, cSRS, 3857, - std::vector{tile::Id{0, {0, 0}, tile::Scheme::Tms}}, + std::vector{radix::tile::Id{0, {0, 0}, radix::tile::Scheme::Tms}}, 2) { } diff --git a/src/terrainlib/ctb/Grid.hpp b/src/terrainlib/ctb/Grid.hpp index dfdf79d..a433884 100644 --- a/src/terrainlib/ctb/Grid.hpp +++ b/src/terrainlib/ctb/Grid.hpp @@ -70,21 +70,12 @@ class ctb::Grid { /// Initialise a grid tile Grid(i_tile gridSize, - const tile::SrsBounds extent, - const OGRSpatialReference& srs, - int epsgCode, - std::vector rootTiles, - double zoomFactor) - : mGridSize(gridSize) - , mExtent(extent) - , mSRS(srs) - , mEpsgCode(epsgCode) - , mInitialResolution((extent.size().x / rootTiles.size()) / gridSize) - , mXOriginShift(extent.size().x / 2) - , mYOriginShift(extent.size().y / 2) - , mZoomFactor(zoomFactor) - , mRootTiles(rootTiles) - { + const radix::tile::SrsBounds extent, + const OGRSpatialReference &srs, + int epsgCode, + std::vector rootTiles, + double zoomFactor) + : mGridSize(gridSize), mExtent(extent), mSRS(srs), mEpsgCode(epsgCode), mInitialResolution((extent.size().x / rootTiles.size()) / gridSize), mXOriginShift(extent.size().x / 2), mYOriginShift(extent.size().y / 2), mZoomFactor(zoomFactor), mRootTiles(rootTiles) { mSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); } @@ -150,20 +141,18 @@ class ctb::Grid { } /// Get the tile coordinate in which a location falls at a specific zoom level - [[nodiscard]] inline tile::Id crsToTile(const CRSPoint& coord, i_zoom zoom) const - { + [[nodiscard]] inline radix::tile::Id crsToTile(const CRSPoint &coord, i_zoom zoom) const { const PixelPoint pixel = crsToPixels(coord, zoom); TilePoint tile = pixelsToTile(pixel); - return { zoom, tile, tile::Scheme::Tms }; + return {zoom, tile, radix::tile::Scheme::Tms}; } /// Get the CRS bounds of a particular tile /// border_se should be true if a border should be included on the south eastern corner /// e.g., for the cesium raster terrain format (https://github.com/CesiumGS/cesium/wiki/heightmap-1%2E0) - [[nodiscard]] inline tile::SrsBounds srsBounds(const tile::Id& tile_id, bool border_se) const - { - const auto tms_tile_id = tile_id.to(tile::Scheme::Tms); + [[nodiscard]] inline radix::tile::SrsBounds srsBounds(const radix::tile::Id &tile_id, bool border_se) const { + const auto tms_tile_id = tile_id.to(radix::tile::Scheme::Tms); // get the pixels coordinates representing the tile bounds const PixelPoint pxMinLeft(tms_tile_id.coords.x * mGridSize, tms_tile_id.coords.y * mGridSize); const PixelPoint pxMaxRight((tms_tile_id.coords.x + 1) * mGridSize + border_se, (tms_tile_id.coords.y + 1) * mGridSize + border_se); @@ -174,13 +163,13 @@ class ctb::Grid { return { minLeft, maxRight }; } - - [[nodiscard]] const std::vector& rootTiles() const { + + [[nodiscard]] const std::vector &rootTiles() const { return this->mRootTiles; } // Searches for the smallest tile that encompasses the given bounding box. - [[nodiscard]] std::optional findSmallestEncompassingTile(const tile::SrsBounds &bounds) const { + [[nodiscard]] std::optional findSmallestEncompassingTile(const radix::tile::SrsBounds &bounds) const { // We dont want to recurse indefinetely if the bounds are empty. if (bounds.width() == 0 || bounds.height() == 0) { throw std::invalid_argument("bounds cannot be empty"); @@ -195,9 +184,9 @@ class ctb::Grid { // We start at the root tiles and repeatedly check every subtile until we find one that contains all // of the bounding box. - for (const tile::Id &root_tile : this->rootTiles()) { + for (const radix::tile::Id &root_tile : this->rootTiles()) { // Get the bounds of the current root tile. - const tile::SrsBounds root_tile_bounds = this->srsBounds(root_tile, false); + const radix::tile::SrsBounds root_tile_bounds = this->srsBounds(root_tile, false); // Check if all of the target bounding box is inside this tile. bool all_points_inside = true; @@ -214,14 +203,14 @@ class ctb::Grid { } // Now find the smallest tile under this root. - tile::Id current_smallest_encompassing_tile = root_tile; + radix::tile::Id current_smallest_encompassing_tile = root_tile; while (true) { - const std::array children = current_smallest_encompassing_tile.children(); + const std::array children = current_smallest_encompassing_tile.children(); bool all_points_inside_any_child = false; for (const auto &child : children) { // Get the bounds of the current child - const tile::SrsBounds tile_bounds = this->srsBounds(child, false); + const radix::tile::SrsBounds tile_bounds = this->srsBounds(child, false); // Check if all of the target bounding box is inside this tile. bool all_points_inside = true; @@ -255,19 +244,19 @@ class ctb::Grid { } // Searches for the smallest tile that encompasses the given bounding box. - [[nodiscard]] std::optional findLargestContainedTile(const tile::SrsBounds &bounds) const { - const std::optional root = this->findSmallestEncompassingTile(bounds); + [[nodiscard]] std::optional findLargestContainedTile(const radix::tile::SrsBounds &bounds) const { + const std::optional root = this->findSmallestEncompassingTile(bounds); if (!root.has_value()) { return std::nullopt; } - std::vector tiles_to_inspect; - const std::array root_children = root->children(); + std::vector tiles_to_inspect; + const std::array root_children = root->children(); tiles_to_inspect.insert(tiles_to_inspect.end(), root_children.begin(), root_children.end()); - std::optional current_candidate; + std::optional current_candidate; while (!tiles_to_inspect.empty()) { - const tile::Id tile = tiles_to_inspect.back(); + const radix::tile::Id tile = tiles_to_inspect.back(); tiles_to_inspect.pop_back(); if (current_candidate.has_value() && current_candidate->zoom_level <= tile.zoom_level) { @@ -275,14 +264,14 @@ class ctb::Grid { continue; } - const tile::SrsBounds tile_bounds = this->srsBounds(tile, false); + const radix::tile::SrsBounds tile_bounds = this->srsBounds(tile, false); const std::array points = { tile_bounds.min, tile_bounds.max, glm::dvec2(tile_bounds.min.x, tile_bounds.max.y), glm::dvec2(tile_bounds.max.x, tile_bounds.min.y)}; - const bool target_bounds_overlapping_tile = geometry::intersect(tile_bounds, bounds); + const bool target_bounds_overlapping_tile = radix::geometry::intersect(tile_bounds, bounds); bool target_bounds_fully_inside_tile = false; if (target_bounds_overlapping_tile) { target_bounds_fully_inside_tile = true; @@ -302,7 +291,7 @@ class ctb::Grid { } if (target_bounds_overlapping_tile) { - const std::array children = tile.children(); + const std::array children = tile.children(); tiles_to_inspect.insert(tiles_to_inspect.end(), children.begin(), children.end()); } } @@ -323,8 +312,7 @@ class ctb::Grid { } /// Get the extent covered by the grid in CRS coordinates - [[nodiscard]] inline const tile::SrsBounds& getExtent() const - { + [[nodiscard]] inline const radix::tile::SrsBounds &getExtent() const { return mExtent; } @@ -338,7 +326,7 @@ class ctb::Grid { i_tile mGridSize; /// The area covered by the grid - tile::SrsBounds mExtent; + radix::tile::SrsBounds mExtent; /// The spatial reference system covered by the grid OGRSpatialReference mSRS; @@ -352,7 +340,7 @@ class ctb::Grid { double mZoomFactor; /// A list of all the root tiles of the grid. - std::vector mRootTiles; + std::vector mRootTiles; }; #endif /* CTBGRID_HPP */ diff --git a/src/terrainlib/depth_first_tile_traverser.h b/src/terrainlib/depth_first_tile_traverser.h index 526f54c..68379de 100644 --- a/src/terrainlib/depth_first_tile_traverser.h +++ b/src/terrainlib/depth_first_tile_traverser.h @@ -21,9 +21,8 @@ #include "TopDownTiler.h" template -auto traverse_depth_first_and_aggregate(const TopDownTiler& tiler, ReadFunction read, AggregateFunction aggregate, const tile::Id& root_tile_id, unsigned max_zoom_level) - -> decltype(read(tiler.tile_for(root_tile_id))) -{ +auto traverse_depth_first_and_aggregate(const TopDownTiler &tiler, ReadFunction read, AggregateFunction aggregate, const radix::tile::Id &root_tile_id, unsigned max_zoom_level) + -> decltype(read(tiler.tile_for(root_tile_id))) { using DataType = decltype(read(tiler.tile_for(root_tile_id))); const auto subtiles = tiler.generateTiles(root_tile_id); // subtiles can be empty if the parent tile had an overlap with the dataset extent only on the border pixels. diff --git a/src/terrainlib/mesh/terrain_mesh.cpp b/src/terrainlib/mesh/terrain_mesh.cpp index 7886bda..e3d7fc4 100644 --- a/src/terrainlib/mesh/terrain_mesh.cpp +++ b/src/terrainlib/mesh/terrain_mesh.cpp @@ -2,8 +2,8 @@ #include "terrain_mesh.h" -geometry::Aabb<3, double> calculate_bounds(const TerrainMesh& mesh) { - geometry::Aabb<3, double> bounds; +radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh) { + radix::geometry::Aabb<3, double> bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); for (unsigned int j = 0; j < mesh.positions.size(); j++) { @@ -13,8 +13,8 @@ geometry::Aabb<3, double> calculate_bounds(const TerrainMesh& mesh) { return bounds; } -geometry::Aabb<3, double> calculate_bounds(std::span meshes) { - geometry::Aabb<3, double> bounds; +radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes) { + radix::geometry::Aabb<3, double> bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); for (unsigned int i = 0; i < meshes.size(); i++) { diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index d734f9a..6d9b76a 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -53,8 +53,8 @@ class TerrainMesh { } }; -geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); -geometry::Aabb<3, double> calculate_bounds(std::span meshes); +radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); +radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes); std::vector find_isolated_vertices(const TerrainMesh& mesh); size_t remove_isolated_vertices(TerrainMesh& mesh); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index e442222..bf413b3 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -44,8 +44,7 @@ inline std::unique_ptr transformation(const OGRSpat } // this transform is non exact, because we are only transforming the corner vertices. however, due to projection warping, a rectangle can become an trapezoid with curved edges. -inline tile::SrsBounds nonExactBoundsTransform(const tile::SrsBounds& bounds, const OGRSpatialReference& sourceSrs, const OGRSpatialReference& targetSrs) -{ +inline radix::tile::SrsBounds nonExactBoundsTransform(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { const auto transform = transformation(sourceSrs, targetSrs); std::array xes = { bounds.min.x, bounds.max.x }; std::array yes = { bounds.min.y, bounds.max.y }; @@ -176,13 +175,13 @@ inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BB /// Transforms bounds from one srs to another, /// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. /// But there can be points inside the new bounds that were not present in the original ones. -inline tile::SrsBounds encompassing_bounding_box_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const tile::SrsBounds &source_bounds) { +inline radix::tile::SrsBounds encompassing_bounding_box_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { if (source_srs.IsSame(&target_srs)) { return source_bounds; } const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); - tile::SrsBounds target_bounds; + radix::tile::SrsBounds target_bounds; const int result = transformation->TransformBounds( source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, diff --git a/src/terrainlib/tntn/Raster.h b/src/terrainlib/tntn/Raster.h index 9b51674..6b22e43 100644 --- a/src/terrainlib/tntn/Raster.h +++ b/src/terrainlib/tntn/Raster.h @@ -61,7 +61,7 @@ class Raster { public: Raster() { ::tntn::detail::NDVDefault::set(m_noDataValue); } Raster(Raster&& other) noexcept = default; - explicit Raster(Image&& other, const tile::SrsBounds& srs_bounds) + explicit Raster(Image&& other, const radix::tile::SrsBounds& srs_bounds) : m_width(other.width()) , m_height(other.height()) , m_data(std::move(other.m_data)) From 0e9133e62d183197c0c8abe2ba07716da0b3e478 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Mon, 14 Apr 2025 20:33:00 +0200 Subject: [PATCH 002/122] Enforce C++20 --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0e6a8a..0453b50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.19) project(terrain_builder_src LANGUAGES C CXX) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") + option(ALP_AUTOUPDATE_RADIX "Keeps whack up-to-date with origin/main, but prevents local edits. Change to OFF if you want to edit radix" ON) option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) From 6c6e56fc6c40a259a25abcc2c7ae432f3f07c2a8 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Mon, 14 Apr 2025 20:33:10 +0200 Subject: [PATCH 003/122] Add radix prefix --- src/terrainbuilder/border.h | 3 +- src/terrainbuilder/main.cpp | 12 ++-- src/terrainbuilder/mesh_builder.cpp | 12 ++-- src/terrainbuilder/mesh_builder.h | 5 +- src/terrainbuilder/raw_dataset_reader.h | 32 +++++------ src/terrainbuilder/terrainbuilder.cpp | 19 +++---- src/terrainbuilder/terrainbuilder.h | 2 +- src/terrainbuilder/texture_assembler.h | 75 ++++++++++++------------- src/terrainbuilder/tile_provider.h | 24 ++++---- 9 files changed, 90 insertions(+), 94 deletions(-) diff --git a/src/terrainbuilder/border.h b/src/terrainbuilder/border.h index e936869..ff754b2 100644 --- a/src/terrainbuilder/border.h +++ b/src/terrainbuilder/border.h @@ -43,13 +43,12 @@ class Border { }; template -inline void add_border_to_aabb(geometry::Aabb2 &bounds, const Border &border) { +inline void add_border_to_aabb(radix::geometry::Aabb2 &bounds, const Border &border) { bounds.min.x -= border.left; bounds.min.y -= border.top; bounds.max.x += border.right; bounds.max.y += border.bottom; } - } #endif diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index fb1c89f..afbebd9 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -51,10 +51,10 @@ int run(std::span args) { ->excludes("--bounds"); target->require_option(1); - tile::Scheme target_tile_scheme; - std::map scheme_str_map{{"slippymap", tile::Scheme::SlippyMap}, {"google", tile::Scheme::SlippyMap}, {"tms", tile::Scheme::Tms}}; + radix::tile::Scheme target_tile_scheme; + std::map scheme_str_map{{"slippymap", radix::tile::Scheme::SlippyMap}, {"google", radix::tile::Scheme::SlippyMap}, {"tms", radix::tile::Scheme::Tms}}; app.add_option("--scheme", target_tile_scheme, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") - ->default_val(tile::Scheme::SlippyMap) + ->default_val(radix::tile::Scheme::SlippyMap) ->excludes("--bounds") ->transform(CLI::CheckedTransformer(scheme_str_map, CLI::ignore_case)); @@ -92,17 +92,17 @@ int run(std::span args) { texture_srs.importFromEPSG(3857); texture_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds tile_bounds; + radix::tile::SrsBounds tile_bounds; if (!target_bounds_data.empty()) { const glm::dvec2 tile_bounds_min(target_bounds_data[0], target_bounds_data[1]); const glm::dvec2 tile_bounds_size(target_bounds_data[2], target_bounds_data[3]); - tile_bounds = tile::SrsBounds(tile_bounds_min, tile_bounds_min + tile_bounds_size); + tile_bounds = radix::tile::SrsBounds(tile_bounds_min, tile_bounds_min + tile_bounds_size); } else { const ctb::Grid grid = ctb::GlobalMercator(); const unsigned int zoom_level = target_tile_data[0]; const glm::uvec2 tile_coords(target_tile_data[1], target_tile_data[2]); - const tile::Id target_tile(zoom_level, tile_coords, target_tile_scheme); + const radix::tile::Id target_tile(zoom_level, tile_coords, target_tile_scheme); if (!tile_srs.IsSame(&grid.getSRS())) { LOG_ERROR("Target tile id is only supported for webmercator reference system"); exit(1); diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index b432142..a70343c 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -57,18 +57,18 @@ static glm::dvec3 apply_transform(OGRCoordinateTransformation *transform, const tl::expected build_reference_mesh_tile( Dataset &dataset, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, tile::SrsBounds &texture_bounds, + const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, const Border &vertex_border, const bool inclusive_bounds) { const OGRSpatialReference &source_srs = dataset.srs(); // Translate tile bounds from tile srs into the source srs, so we know what data to read. - const tile::SrsBounds tile_bounds_in_source_srs = srs::encompassing_bounding_box_transfer(tile_srs, source_srs, tile_bounds); + const radix::tile::SrsBounds tile_bounds_in_source_srs = srs::encompassing_bounding_box_transfer(tile_srs, source_srs, tile_bounds); // Read height data according to bounds directly from dataset (no interpolation). RawDatasetReader reader(dataset); - geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(tile_bounds_in_source_srs); + radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(tile_bounds_in_source_srs); add_border_to_aabb(pixel_bounds, vertex_border); if (inclusive_bounds) { add_border_to_aabb(pixel_bounds, Border(1)); @@ -95,7 +95,7 @@ tl::expected build_reference_mesh_tile( // Preparation for loop const double infinity = std::numeric_limits::infinity(); - tile::SrsBounds actual_tile_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); + radix::tile::SrsBounds actual_tile_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); std::vector source_positions; source_positions.resize(max_vertex_count); @@ -249,7 +249,7 @@ tl::expected build_reference_mesh_tile( // Calculate absolute texture coordinates for every vertex. LOG_TRACE("Calculating uv coordinates"); - tile::SrsBounds actual_texture_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); + radix::tile::SrsBounds actual_texture_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); std::vector texture_positions; texture_positions.reserve(max_vertex_count); for (unsigned int i = 0; i < actual_vertex_count; i++) { diff --git a/src/terrainbuilder/mesh_builder.h b/src/terrainbuilder/mesh_builder.h index 8a35045..0d1c4b8 100644 --- a/src/terrainbuilder/mesh_builder.h +++ b/src/terrainbuilder/mesh_builder.h @@ -20,11 +20,10 @@ enum class BuildError { tl::expected build_reference_mesh_tile( Dataset &dataset, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, tile::SrsBounds &texture_bounds, + const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, const Border &vertex_border, const bool inclusive_bounds); - } #endif diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/terrainbuilder/raw_dataset_reader.h index 8e20654..e2afbf6 100644 --- a/src/terrainbuilder/raw_dataset_reader.h +++ b/src/terrainbuilder/raw_dataset_reader.h @@ -39,7 +39,7 @@ class RawDatasetReader { return glm::uvec2(heights_band->GetXSize(), heights_band->GetYSize()); } - std::optional read_data_in_pixel_bounds(geometry::Aabb2i bounds, const bool clamp_bounds = false) { + std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { if (clamp_bounds) { const glm::ivec2 max_in_bounds = glm::ivec2(this->dataset_size()) - glm::ivec2(1); bounds.min = glm::clamp(bounds.min, glm::ivec2(0), max_in_bounds); @@ -79,43 +79,43 @@ class RawDatasetReader { return height_data; } - std::optional read_data_in_srs_bounds(const tile::SrsBounds &bounds, const bool clamp_bounds = false) { + std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { // Transform the SrsBounds to pixel space - const geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); + const radix::geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); // Use the transformed pixel bounds to read data return this->read_data_in_pixel_bounds(pixel_bounds, clamp_bounds); } - geometry::Aabb2i transform_srs_bounds_to_pixel_bounds(const tile::SrsBounds &bounds) const { - geometry::Aabb2d pixel_bounds_exact = this->transform_srs_bounds_to_pixel_bounds_exact(bounds); + radix::geometry::Aabb2i transform_srs_bounds_to_pixel_bounds(const radix::tile::SrsBounds &bounds) const { + radix::geometry::Aabb2d pixel_bounds_exact = this->transform_srs_bounds_to_pixel_bounds_exact(bounds); - const geometry::Aabb2i pixel_bounds( + const radix::geometry::Aabb2i pixel_bounds( glm::ivec2(static_cast(std::floor(pixel_bounds_exact.min.x)), static_cast(std::floor(pixel_bounds_exact.min.y))), glm::ivec2(static_cast(std::ceil(pixel_bounds_exact.max.x)), static_cast(std::ceil(pixel_bounds_exact.max.y)))); return pixel_bounds; } - tile::SrsBounds transform_srs_bounds_to_pixel_bounds_exact(const tile::SrsBounds &bounds) const { - tile::SrsBounds transformed_bounds; + radix::tile::SrsBounds transform_srs_bounds_to_pixel_bounds_exact(const radix::tile::SrsBounds &bounds) const { + radix::tile::SrsBounds transformed_bounds; transformed_bounds.min = this->transform_srs_point_to_pixel_exact(bounds.min); transformed_bounds.max = this->transform_srs_point_to_pixel_exact(bounds.max); - transformed_bounds = tile::SrsBounds(glm::min(transformed_bounds.min, transformed_bounds.max), - glm::max(transformed_bounds.min, transformed_bounds.max)); + transformed_bounds = radix::tile::SrsBounds(glm::min(transformed_bounds.min, transformed_bounds.max), + glm::max(transformed_bounds.min, transformed_bounds.max)); return transformed_bounds; } - tile::SrsBounds transform_pixel_bounds_to_srs_bounds(const tile::SrsBounds &bounds) const { - tile::SrsBounds transformed_bounds; + radix::tile::SrsBounds transform_pixel_bounds_to_srs_bounds(const radix::tile::SrsBounds &bounds) const { + radix::tile::SrsBounds transformed_bounds; transformed_bounds.min = this->transform_pixel_to_srs_point(bounds.min); transformed_bounds.max = this->transform_pixel_to_srs_point(bounds.max); - transformed_bounds = tile::SrsBounds(glm::min(transformed_bounds.min, transformed_bounds.max), - glm::max(transformed_bounds.min, transformed_bounds.max)); + transformed_bounds = radix::tile::SrsBounds(glm::min(transformed_bounds.min, transformed_bounds.max), + glm::max(transformed_bounds.min, transformed_bounds.max)); return transformed_bounds; } - tile::SrsBounds transform_pixel_bounds_to_srs_bounds(const geometry::Aabb2i &bounds) const { - return this->transform_pixel_bounds_to_srs_bounds(tile::SrsBounds(glm::dvec2(bounds.min), glm::dvec2(bounds.max))); + radix::tile::SrsBounds transform_pixel_bounds_to_srs_bounds(const radix::geometry::Aabb2i &bounds) const { + return this->transform_pixel_bounds_to_srs_bounds(radix::tile::SrsBounds(glm::dvec2(bounds.min), glm::dvec2(bounds.max))); } template diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 6994985..e30cdd8 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -33,7 +33,7 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { BasemapSchemeTilePathProvider(std::filesystem::path base_path) : base_path(base_path) {} - std::optional get_tile_path(const tile::Id tile_id) const override { + std::optional get_tile_path(const radix::tile::Id tile_id) const override { return fmt::format("{}/{}/{}/{}.jpeg", this->base_path.generic_string(), tile_id.zoom_level, tile_id.coords.y, tile_id.coords.x); } @@ -47,12 +47,12 @@ void build( const OGRSpatialReference &mesh_srs, const OGRSpatialReference &tile_srs, const OGRSpatialReference &texture_srs, - const tile::SrsBounds &tile_bounds, + const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path) { const ctb::Grid grid = ctb::GlobalMercator(); - tile::SrsBounds target_tile_bounds(tile_bounds); - tile::SrsBounds texture_bounds; + radix::tile::SrsBounds target_tile_bounds(tile_bounds); + radix::tile::SrsBounds texture_bounds; std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); @@ -67,11 +67,11 @@ void build( if (!mesh_result.has_value()) { const mesh::BuildError error = mesh_result.error(); if (error == mesh::BuildError::OutOfBounds) { - const tile::SrsBounds dataset_bounds = dataset.bounds(); - const tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(tile::Scheme::SlippyMap); - const tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(tile::Scheme::SlippyMap); - const tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(tile::Scheme::SlippyMap); - const tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(tile::Scheme::SlippyMap); + const radix::tile::SrsBounds dataset_bounds = dataset.bounds(); + const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); + const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_ERROR("Target bounds are fully outside of dataset region\n" "Dataset {{\n" "\tBounds {{x={}, y={}, w={}, h={}}}.\n" @@ -136,5 +136,4 @@ void build( LOG_DEBUG("Writing mesh took {}s", format_secs_since(start)); LOG_INFO("Done", output_path.string()); } - } diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index 60e1745..0254f10 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -16,7 +16,7 @@ void build( const OGRSpatialReference &mesh_srs, const OGRSpatialReference &tile_srs, const OGRSpatialReference &texture_srs, - const tile::SrsBounds &tile_bounds, + const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path); } diff --git a/src/terrainbuilder/texture_assembler.h b/src/terrainbuilder/texture_assembler.h index 1c8299c..06a09e6 100644 --- a/src/terrainbuilder/texture_assembler.h +++ b/src/terrainbuilder/texture_assembler.h @@ -24,8 +24,8 @@ namespace terrainbuilder::texture { /// Estimates the zoom level of the target bounds in relation to some reference tile given by its zoom level and bounds. [[nodiscard]] unsigned int estimate_zoom_level( const unsigned int reference_zoom_level, - const tile::SrsBounds reference_tile_bounds, - const tile::SrsBounds target_bounds) { + const radix::tile::SrsBounds reference_tile_bounds, + const radix::tile::SrsBounds target_bounds) { const glm::dvec2 relative_size = reference_tile_bounds.size() / target_bounds.size(); const double relative_factor = (relative_size.x + relative_size.y) / 2; const int zoom_level_change = std::rint(std::log2(relative_factor)); @@ -36,13 +36,13 @@ namespace terrainbuilder::texture { /// Find all the tiles needed to construct the texture for the given target bounds under the root tile. /// The result tiles are ordered in such a way that they can be sequentially written to a texture. /// Larger tiles are only included if they are not covered by smaller tiles. -[[nodiscard]] std::vector find_relevant_tiles_to_splatter_in_bounds( +[[nodiscard]] std::vector find_relevant_tiles_to_splatter_in_bounds( /// The root tile specifying the tiles to consider. - const tile::Id root_tile, + const radix::tile::Id root_tile, /// Specifes the grid used to organize the image tiles. const ctb::Grid &grid, /// The bounds for which texture data should be created. - const tile::SrsBounds &target_bounds, + const radix::tile::SrsBounds &target_bounds, /// Provider class that maps tile ids to their textures. const TileProvider &tile_provider, /// The maximal zoom level to be considered. @@ -57,17 +57,17 @@ namespace terrainbuilder::texture { } // A list of tiles determined to be relevant for the target bounds. - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; - const std::function helper = [&](const tile::Id tile) { + const std::function helper = [&](const radix::tile::Id tile) { // Check if we have recursed too deep. if (max_zoom_level_to_consider.has_value() && tile.zoom_level > max_zoom_level_to_consider.value()) { return false; } // Check if we even require this tile to fill the target region. - const tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); - if (!geometry::intersect(target_bounds, tile_bounds)) { + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); + if (!radix::geometry::intersect(target_bounds, tile_bounds)) { return true; } @@ -75,7 +75,7 @@ namespace terrainbuilder::texture { bool all_children_present = false; if (tile.zoom_level + 1 <= min_zoom_level_to_examine.value()) { all_children_present = true; - for (const tile::Id subtile : tile.children()) { + for (const radix::tile::Id subtile : tile.children()) { if (!helper(subtile)) { all_children_present = false; } @@ -104,11 +104,11 @@ namespace terrainbuilder::texture { } /// Calculate the offset and size of the target bounds inside the root tile. -[[nodiscard]] geometry::Aabb2ui calculate_target_image_region( +[[nodiscard]] radix::geometry::Aabb2ui calculate_target_image_region( /// The bounds for which texture data should be created. - const tile::SrsBounds target_bounds, + const radix::tile::SrsBounds target_bounds, /// The bounds of the root tile. - const tile::SrsBounds root_tile_bounds, + const radix::tile::SrsBounds root_tile_bounds, /// The image size of each tile. const glm::uvec2 tile_image_pixel_size, /// The range of zoom levels from the root to the maximum zoom. @@ -119,32 +119,32 @@ namespace terrainbuilder::texture { const glm::uvec2 root_tile_image_size = tile_image_pixel_size * glm::uvec2(full_image_size_factor); const glm::uvec2 target_pixel_offset_min(glm::floor(relative_min * glm::dvec2(root_tile_image_size))); const glm::uvec2 target_pixel_offset_max(glm::ceil(relative_max * glm::dvec2(root_tile_image_size))); - const geometry::Aabb2ui target_image_region( + const radix::geometry::Aabb2ui target_image_region( glm::uvec2(target_pixel_offset_min.x, root_tile_image_size.y - target_pixel_offset_max.y), glm::uvec2(target_pixel_offset_max.x, root_tile_image_size.y - target_pixel_offset_min.y)); return target_image_region; } -[[nodiscard]] geometry::Aabb2ui calculate_pixel_tile_bounds( - tile::Id tile, - const tile::Id root_tile, +[[nodiscard]] radix::geometry::Aabb2ui calculate_pixel_tile_bounds( + radix::tile::Id tile, + const radix::tile::Id root_tile, const glm::uvec2 tile_image_pixel_size, const unsigned int max_zoom_level) { - if (tile.scheme != tile::Scheme::SlippyMap) { - tile = tile.to(tile::Scheme::SlippyMap); + if (tile.scheme != radix::tile::Scheme::SlippyMap) { + tile = tile.to(radix::tile::Scheme::SlippyMap); } const size_t relative_zoom_level = tile.zoom_level - root_tile.zoom_level; const glm::uvec2 tile_size_factor = glm::uvec2(std::pow(2, max_zoom_level - tile.zoom_level)); const glm::uvec2 tile_size = tile_image_pixel_size * tile_size_factor; const glm::uvec2 relative_tile_coords = tile.coords - root_tile.coords * glm::uvec2(std::pow(2, relative_zoom_level)); const glm::uvec2 tile_position = relative_tile_coords * tile_size; - return geometry::Aabb2ui(tile_position, tile_position + tile_size); + return radix::geometry::Aabb2ui(tile_position, tile_position + tile_size); } void copy_paste_image( cv::Mat &target, const cv::Mat &source, - const geometry::Aabb2i target_bounds, + const radix::geometry::Aabb2i target_bounds, const bool trim_excess = false, const cv::InterpolationFlags rescale_filter = cv::INTER_LINEAR) { if (target_bounds.width() != source.cols || target_bounds.height() != source.rows) { @@ -175,11 +175,11 @@ void copy_paste_image( const glm::ivec2 target_position, const bool trim_excess = false, const cv::InterpolationFlags rescale_filter = cv::INTER_LINEAR) { - copy_paste_image(target, source, geometry::Aabb2i(target_position, target_position + glm::ivec2(source.cols, source.rows)), trim_excess, rescale_filter); + copy_paste_image(target, source, radix::geometry::Aabb2i(target_position, target_position + glm::ivec2(source.cols, source.rows)), trim_excess, rescale_filter); } namespace { -std::optional try_get_tile_path(const tile::Id tile, const TileProvider &tile_provider) { +std::optional try_get_tile_path(const radix::tile::Id tile, const TileProvider &tile_provider) { const TilePathProvider *tile_path_provider = dynamic_cast(&tile_provider); if (tile_path_provider != nullptr) { return tile_path_provider->get_tile_path(tile).value(); @@ -189,42 +189,42 @@ std::optional try_get_tile_path(const tile::Id tile, cons } [[nodiscard]] cv::Mat splatter_tiles_to_texture( - const tile::Id root_tile, + const radix::tile::Id root_tile, /// Specifes the grid used to organize the image tiles. const ctb::Grid &grid, /// The bounds for which texture data should be created. - const tile::SrsBounds &target_bounds, + const radix::tile::SrsBounds &target_bounds, /// A mapping from tile id to a filesystem path. const TileProvider &tile_provider, - const std::span tiles_to_splatter, + const std::span tiles_to_splatter, const cv::InterpolationFlags rescale_filter = cv::INTER_LINEAR) { if (tiles_to_splatter.empty()) { return {}; } - const tile::SrsBounds root_tile_bounds = grid.srsBounds(root_tile, false); + const radix::tile::SrsBounds root_tile_bounds = grid.srsBounds(root_tile, false); unsigned int max_zoom_level = 0; - for (const tile::Id &tile : tiles_to_splatter) { + for (const radix::tile::Id &tile : tiles_to_splatter) { max_zoom_level = std::max(tile.zoom_level, max_zoom_level); } assert(max_zoom_level >= root_tile.zoom_level); const unsigned int zoom_level_range = max_zoom_level - root_tile.zoom_level; // Choose any tile to load infer like tile size and format to allocate our texture buffer accordingly. - const tile::Id &any_tile = tiles_to_splatter.front(); + const radix::tile::Id &any_tile = tiles_to_splatter.front(); const cv::Mat any_tile_image = tile_provider.get_tile(any_tile).value(); const glm::uvec2 tile_image_size(any_tile_image.cols, any_tile_image.rows); // Calculate the offset and size of the target bounds inside the smallest encompassing tile. // As we dont want to allocate and fill a larger buffer than we have to. - const geometry::Aabb2ui target_image_region = calculate_target_image_region(target_bounds, root_tile_bounds, tile_image_size, zoom_level_range); + const radix::geometry::Aabb2ui target_image_region = calculate_target_image_region(target_bounds, root_tile_bounds, tile_image_size, zoom_level_range); const glm::uvec2 image_size = target_image_region.size(); // Allocate the image to write all the individual tiles into. cv::Mat image = cv::Mat::zeros(image_size.y, image_size.x, any_tile_image.type()); - for (const tile::Id &tile : tiles_to_splatter) { + for (const radix::tile::Id &tile : tiles_to_splatter) { cv::Mat tile_image = tile_provider.get_tile(tile).value(); if (tile_image.empty()) { const std::optional tile_path = try_get_tile_path(tile, tile_provider); @@ -246,12 +246,12 @@ std::optional try_get_tile_path(const tile::Id tile, cons } // Pixel bounds of this image relative to the root tile. - const geometry::Aabb2ui pixel_tile_bounds = calculate_pixel_tile_bounds(tile, root_tile, tile_image_size, max_zoom_level); + const radix::geometry::Aabb2ui pixel_tile_bounds = calculate_pixel_tile_bounds(tile, root_tile, tile_image_size, max_zoom_level); assert(glm::all(glm::greaterThanEqual(pixel_tile_bounds.size(), current_tile_image_size))); // Pixel bounds relative to the target image texture region. const glm::ivec2 tile_target_position = glm::ivec2(pixel_tile_bounds.min) - glm::ivec2(target_image_region.min); - const geometry::Aabb2i target_pixel_tile_bounds(tile_target_position, tile_target_position + glm::ivec2(pixel_tile_bounds.size())); + const radix::geometry::Aabb2i target_pixel_tile_bounds(tile_target_position, tile_target_position + glm::ivec2(pixel_tile_bounds.size())); // Resize current tile image and copy into image buffer. copy_paste_image(image, tile_image, target_pixel_tile_bounds, true /* allows und handles overflow */, rescale_filter); @@ -269,7 +269,7 @@ std::optional try_get_tile_path(const tile::Id tile, cons /// Specifies the srs the target bounds are in. const OGRSpatialReference &target_srs, /// The bounds for which texture data should be created. - const tile::SrsBounds &target_bounds, + const radix::tile::SrsBounds &target_bounds, /// Provider class that maps tile ids to their textures. const TileProvider &tile_provider, /// The maximal zoom level to be considered. If not present, this function will use the maximal available. @@ -282,9 +282,9 @@ std::optional try_get_tile_path(const tile::Id tile, cons } // Start by transforming the input bounds into the srs the tiles are in. - const tile::SrsBounds encompassing_bounds = srs::encompassing_bounding_box_transfer(target_srs, grid.getSRS(), target_bounds); + const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounding_box_transfer(target_srs, grid.getSRS(), target_bounds); // Then we find the smallest tile (id) that encompasses these bounds. - const tile::Id smallest_encompassing_tile = grid.findSmallestEncompassingTile(encompassing_bounds).value().to(tile::Scheme::SlippyMap); + const radix::tile::Id smallest_encompassing_tile = grid.findSmallestEncompassingTile(encompassing_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_TRACE("Smallest encompassing tile for texture bounds is [{}, ({}, {})]", smallest_encompassing_tile.zoom_level, smallest_encompassing_tile.coords.x, smallest_encompassing_tile.coords.y); @@ -293,7 +293,7 @@ std::optional try_get_tile_path(const tile::Id tile, cons } // Find relevant tiles in bounds - const std::vector tiles_to_splatter = find_relevant_tiles_to_splatter_in_bounds( + const std::vector tiles_to_splatter = find_relevant_tiles_to_splatter_in_bounds( smallest_encompassing_tile, grid, encompassing_bounds, tile_provider, max_zoom); LOG_TRACE("Found {} relevant texture tiles", tiles_to_splatter.size()); @@ -306,7 +306,6 @@ std::optional try_get_tile_path(const tile::Id tile, cons // Splatter tiles into texture buffer return splatter_tiles_to_texture(smallest_encompassing_tile, grid, encompassing_bounds, tile_provider, tiles_to_splatter, rescale_filter); } - } #endif diff --git a/src/terrainbuilder/tile_provider.h b/src/terrainbuilder/tile_provider.h index 2fd0b61..76fbd56 100644 --- a/src/terrainbuilder/tile_provider.h +++ b/src/terrainbuilder/tile_provider.h @@ -10,24 +10,24 @@ class TileProvider { public: - virtual std::optional get_tile(const tile::Id tile) const = 0; - virtual bool has_tile(const tile::Id tile) const { + virtual std::optional get_tile(const radix::tile::Id tile) const = 0; + virtual bool has_tile(const radix::tile::Id tile) const { return this->get_tile(tile).has_value(); } }; class TilePathProvider : public TileProvider { public: - virtual std::optional get_tile_path(const tile::Id tile) const = 0; + virtual std::optional get_tile_path(const radix::tile::Id tile) const = 0; - std::optional get_tile(const tile::Id tile) const override { + std::optional get_tile(const radix::tile::Id tile) const override { const std::optional tile_path = this->get_tile_path(tile); if (tile_path.has_value() && TilePathProvider::is_usable_tile_path(tile_path.value())) { return cv::imread(tile_path.value()); } return std::nullopt; } - virtual bool has_tile(const tile::Id tile) const override { + virtual bool has_tile(const radix::tile::Id tile) const override { const std::optional tile_path = this->get_tile_path(tile); return tile_path.has_value() && TilePathProvider::is_usable_tile_path(tile_path.value()); } @@ -47,18 +47,18 @@ class TilePathProvider : public TileProvider { class StaticTileProvider : public TileProvider { public: - std::unordered_map tiles; + std::unordered_map tiles; - StaticTileProvider(const std::unordered_map& tiles) { + StaticTileProvider(const std::unordered_map& tiles) { // TODO: remove this once the == operator of tile::Id is updated. for (const auto& tile : tiles) { - const tile::Id tile_id = tile.first.to(tile::Scheme::SlippyMap); + const radix::tile::Id tile_id = tile.first.to(radix::tile::Scheme::SlippyMap); this->tiles[tile_id] = tile.second; } } - virtual std::optional get_tile(const tile::Id tile_id) const override { - const auto tile = this->tiles.find(tile_id.to(tile::Scheme::SlippyMap)); + virtual std::optional get_tile(const radix::tile::Id tile_id) const override { + const auto tile = this->tiles.find(tile_id.to(radix::tile::Scheme::SlippyMap)); if (tile != this->tiles.end()) { return tile->second; } else { @@ -66,8 +66,8 @@ class StaticTileProvider : public TileProvider { } } - virtual bool has_tile(const tile::Id tile_id) const override { - return this->tiles.find(tile_id.to(tile::Scheme::SlippyMap)) != this->tiles.cend(); + virtual bool has_tile(const radix::tile::Id tile_id) const override { + return this->tiles.find(tile_id.to(radix::tile::Scheme::SlippyMap)) != this->tiles.cend(); } }; From 6c6cca4f3059d3aad6bfeef51a4d64370f03698e Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Mon, 14 Apr 2025 20:33:26 +0200 Subject: [PATCH 004/122] Fix missing #include --- src/terrainlib/Image.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/terrainlib/Image.h b/src/terrainlib/Image.h index a6b3540..9bc4b8e 100644 --- a/src/terrainlib/Image.h +++ b/src/terrainlib/Image.h @@ -25,6 +25,7 @@ #include #include #include +#include #include From 3baa137831a8fac0094a844ca9e834b474c7a764 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Tue, 22 Apr 2025 19:46:42 +0200 Subject: [PATCH 005/122] Initial commit. --- .gitignore | 10 +++ CMakeLists.txt | 8 ++ src/CMakeLists.txt | 91 ++++++++++++++++++++ src/core/Application.cpp | 179 +++++++++++++++++++++++++++++++++++++++ src/core/Application.h | 31 +++++++ src/core/Window.cpp | 103 ++++++++++++++++++++++ src/core/Window.h | 36 ++++++++ src/main.cpp | 12 +++ src/res/CMakeLists.txt | 18 ++++ src/utils/log/Log.cpp | 22 +++++ src/utils/log/Log.h | 72 ++++++++++++++++ 11 files changed, 582 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 src/core/Application.cpp create mode 100644 src/core/Application.h create mode 100644 src/core/Window.cpp create mode 100644 src/core/Window.h create mode 100644 src/main.cpp create mode 100644 src/res/CMakeLists.txt create mode 100644 src/utils/log/Log.cpp create mode 100644 src/utils/log/Log.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a36e9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# 3rd party code +3rdparty/ + +# Build results +out/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +CMakePresets.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b607ef0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.24) + +project(alpenite-browser VERSION 0.0.1 LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_subdirectory(src) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..9790b65 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,91 @@ +include(FetchContent) + +if(NOT TARGET glm) + FetchContent_Declare(glm + GIT_REPOSITORY https://github.com/g-truc/glm + GIT_TAG master + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glm + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + message(STATUS "Including glm") + FetchContent_MakeAvailable(glm) +endif() + +if(NOT TARGET glfw) + FetchContent_Declare(glfw + GIT_REPOSITORY https://github.com/glfw/glfw + GIT_TAG master + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glfw + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + + # Don't build glfw docs, tests and examples + set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) + set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + + if (UNIX) + # Disable Wayland and enable X11 + set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) + set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) + endif (UNIX) + + message(STATUS "Including glfw") + FetchContent_MakeAvailable(glfw) +endif() + +if(NOT TARGET glad_gl_core_46) + FetchContent_Declare(glad + GIT_REPOSITORY https://github.com/Dav1dde/glad + GIT_TAG glad2 + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glad + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + message(STATUS "Including glad") + FetchContent_MakeAvailable(glad) + + # Generate glad/gl.h for OpenGL 4.6 + set(GLAD_SOURCES_DIR "${PROJECT_SOURCE_DIR}/3rdparty/glad") + add_subdirectory("${GLAD_SOURCES_DIR}/cmake" glad_cmake) + glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) +endif() + +if(NOT TARGET resources-lib) + FetchContent_Declare(CMakeRC + GIT_REPOSITORY https://github.com/vector-of-bool/cmrc.git + GIT_TAG master + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/CMakeRC + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + message(STATUS "Including CMakeRC") + FetchContent_MakeAvailable(CMakeRC) + + add_subdirectory(res) +endif() + +if(NOT TARGET spdlog) + FetchContent_Declare(spdlog + GIT_REPOSITORY https://github.com/gabime/spdlog.git + GIT_TAG v1.x + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/spdlog + GIT_PROGRESS TRUE + USES_TERMINAL_DOWNLOAD TRUE + ) + message(STATUS "Including spdlog") + FetchContent_MakeAvailable(spdlog) +endif() + +add_executable(alpenite-browser + main.cpp + + core/Application.cpp + core/Window.cpp + + utils/log/Log.cpp +) +target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog) +target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/core/Application.cpp b/src/core/Application.cpp new file mode 100644 index 0000000..88fb252 --- /dev/null +++ b/src/core/Application.cpp @@ -0,0 +1,179 @@ +#include "Application.h" +#include "utils/log/Log.h" +#include + +Application::Application(std::string title, int width, int height) + : m_title(title), m_width(width), m_height(height) { + + WindowConfig c = { + .width = 1280, + .height = 720, + .title = "Alpenite Browser", + .resizeable = true, + .opengl_version = {4, 6}, + .opengl_core_profile = true + }; + + m_window = std::make_unique(c); + + init_glad(); + init_gl(); +} + +void Application::run() { + while (!m_window->should_close()) { + // Check if any events have been activated (key pressed, mouse moved etc.) + // and call corresponding response functions + m_window->poll_events(); + } +} + +Application::~Application() { + LOG_INFO("Exiting"); +} + +void Application::init_glad() { + // Load OpenGL functions, gladLoadGL returns the loaded version, 0 on error. + int version = gladLoadGL(glfwGetProcAddress); + if (version == 0) { + LOG_GL_FATAL_AND_EXIT("Failed to initialize OpenGL context"); + } + + // Successfully loaded OpenGL + LOG_GL_INFO("Loaded OpenGL {0}.{1}", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version)); +} + +void Application::init_gl() { +#ifdef _DEBUG + glEnable(GL_DEBUG_OUTPUT); + // set debug callback + glDebugMessageCallback(gl_debug_callback, nullptr); +#endif // _DEBUG + + glViewport(0, 0, m_width, m_height); +} + +void Application::gl_debug_callback(GLenum source, GLenum type, + GLuint id, GLenum severity, + GLsizei length, + const GLchar *message, + const GLvoid *userParam) { + std::stringstream stringStream; + std::string sourceString; + std::string typeString; + std::string severityString; + + switch (source) { + case GL_DEBUG_SOURCE_API: { + sourceString = "API"; + break; + } + case GL_DEBUG_SOURCE_APPLICATION: { + sourceString = "Application"; + break; + } + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: { + sourceString = "Window System"; + break; + } + case GL_DEBUG_SOURCE_SHADER_COMPILER: { + sourceString = "Shader Compiler"; + break; + } + case GL_DEBUG_SOURCE_THIRD_PARTY: { + sourceString = "Third Party"; + break; + } + case GL_DEBUG_SOURCE_OTHER: { + sourceString = "Other"; + break; + } + default: { + sourceString = "Unknown"; + break; + } + } + + switch (type) { + case GL_DEBUG_TYPE_ERROR: { + typeString = "Error"; + break; + } + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: { + typeString = "Deprecated Behavior"; + break; + } + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: { + typeString = "Undefined Behavior"; + break; + } + case GL_DEBUG_TYPE_PORTABILITY_ARB: { + typeString = "Portability"; + break; + } + case GL_DEBUG_TYPE_PERFORMANCE: { + typeString = "Performance"; + break; + } + case GL_DEBUG_TYPE_OTHER: { + typeString = "Other"; + break; + } + default: { + typeString = "Unknown"; + break; + } + } + + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: { + severityString = "High"; + break; + } + case GL_DEBUG_SEVERITY_MEDIUM: { + severityString = "Medium"; + break; + } + case GL_DEBUG_SEVERITY_LOW: { + severityString = "Low"; + break; + } + case GL_DEBUG_SEVERITY_NOTIFICATION: { + severityString = "Notification"; + break; + } + default: { + severityString = "Unknown"; + break; + } + } + + stringStream << message; + stringStream << " [Source = " << sourceString; + stringStream << ", Type = " << typeString; + stringStream << ", Severity = " << severityString; + stringStream << ", ID = " << id << "]"; + + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: { + LOG_GL_ERROR(stringStream.str()); + break; + } + case GL_DEBUG_SEVERITY_MEDIUM: { + LOG_GL_WARN(stringStream.str()); + break; + } + case GL_DEBUG_SEVERITY_LOW: { + LOG_GL_INFO(stringStream.str()); + break; + } + case GL_DEBUG_SEVERITY_NOTIFICATION: { + LOG_GL_DEBUG(stringStream.str()); + break; + } + default: { + LOG_GL_TRACE(stringStream.str()); + break; + } + } +} diff --git a/src/core/Application.h b/src/core/Application.h new file mode 100644 index 0000000..314a72a --- /dev/null +++ b/src/core/Application.h @@ -0,0 +1,31 @@ +#pragma once +#include + +#include + +#include +#include +#include "Window.h" + +class Application { +public: + Application(std::string title, int width, int height); + + void run(); + + ~Application(); + +private: + std::string m_title; + int m_width, m_height; + + std::unique_ptr m_window; + + void init_glad(); + void init_gl(); + + static void gl_debug_callback(GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, + const GLchar *message, + const GLvoid *userParam); +}; \ No newline at end of file diff --git a/src/core/Window.cpp b/src/core/Window.cpp new file mode 100644 index 0000000..ff2eb30 --- /dev/null +++ b/src/core/Window.cpp @@ -0,0 +1,103 @@ +#include "Window.h" +#include + +std::atomic Window::glfw_initialized(false); +std::atomic Window::window_instances(0); + +Window::Window(WindowConfig config) : m_width(config.width), m_height(config.height), m_title(config.title) { + update_window_count(1); + + const auto [gl_major_version, gl_minor_version] = config.opengl_version; + + LOG_GL_INFO("Creating window with context: OpenGL {}.{}{}", gl_major_version, gl_minor_version, config.opengl_core_profile ? " CORE" : ""); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, gl_major_version); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, gl_minor_version); + glfwWindowHint(GLFW_OPENGL_PROFILE, config.opengl_core_profile ? GLFW_OPENGL_CORE_PROFILE : GLFW_OPENGL_ANY_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, config.resizeable ? GLFW_TRUE : GLFW_FALSE); + +#ifdef _DEBUG + // enable debug mode + LOG_GL_DEBUG("Setting OpenGL Debug Context"); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_FALSE); + // doesnt work: glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); +#endif // _DEBUG + + m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), NULL, NULL); + if (m_window == NULL) { + update_window_count(-1); + LOG_GL_FATAL_AND_EXIT("Failed to create GLFW window"); + } + glfwMakeContextCurrent(m_window); + + // Set the required callback functions + glfwSetKeyCallback(m_window, key_callback); +} + +Window::~Window() { + LOG_GL_INFO("Destroying Window \"{}\"", m_title); + glfwDestroyWindow(m_window); + + update_window_count(-1); +} + +bool Window::should_close() { + return glfwWindowShouldClose(m_window); +} + +void Window::poll_events() { + glfwPollEvents(); +} + +void Window::glfw_error_callback(int error, const char* description) { + LOG_GLFW_ERROR("[{}] {}", error, description); +} + +void Window::key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +void Window::update_window_count(int delta) { + if (delta == 0) { + return; + } + + auto w_instances = Window::window_instances.load(std::memory_order_acquire); + auto g_initialized = Window::glfw_initialized.load(std::memory_order_acquire); + + if (w_instances + delta < 0) { + LOG_GLFW_FATAL_AND_EXIT("Illegal window count change from {} >> {} by {}!", w_instances, w_instances + delta, delta); + } + + LOG_GLFW_INFO("Window count changed from {} >> {} by {}!", w_instances, w_instances + delta, delta); + + // If the previous window count was 0 AND glfw is not initialized, initialize GLFW + bool needs_glfw_init = w_instances == 0 && !Window::glfw_initialized; + + // If the current window count is 0, AND glfw is initialized, destruct GLFW + bool needs_glfw_destruction = w_instances + delta == 0 && Window::glfw_initialized; + + if (needs_glfw_init) { + LOG_GLFW_INFO("Initializing GLFW"); + glfwInit(); + glfwSetErrorCallback(glfw_error_callback); + + g_initialized = true; + Window::glfw_initialized.store(g_initialized, std::memory_order_release); + } + + if (needs_glfw_destruction) { + LOG_GLFW_INFO("Terminating GLFW"); + + glfwTerminate(); + + g_initialized = false; + Window::glfw_initialized.store(g_initialized, std::memory_order_release); + } + + w_instances += delta; + Window::window_instances.store(w_instances, std::memory_order_release); +} diff --git a/src/core/Window.h b/src/core/Window.h new file mode 100644 index 0000000..cde3509 --- /dev/null +++ b/src/core/Window.h @@ -0,0 +1,36 @@ +#pragma once +#include +#include +#include + +struct WindowConfig { + int width = 1280; + int height = 720; + std::string title = "Window Title"; + bool resizeable = true; + + std::tuple opengl_version = { 4, 6 }; + bool opengl_core_profile = true; +}; + +class Window { +public: + Window(WindowConfig config); + ~Window(); + + bool should_close(); + void poll_events(); +private: + static std::atomic window_instances; + static std::atomic glfw_initialized; + + int m_width, m_height; + std::string m_title; + + GLFWwindow* m_window; + + static void glfw_error_callback(int error, const char* description); + static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); + + static void update_window_count(int delta); +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e4edc83 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,12 @@ +#include "core/Application.h" +#include "utils/log/Log.h" + +int main() { + Log::Init(spdlog::level::trace); + + Application app("Alpenite Browser", 1280, 720); + + app.run(); + + return 0; +} \ No newline at end of file diff --git a/src/res/CMakeLists.txt b/src/res/CMakeLists.txt new file mode 100644 index 0000000..2c7ae34 --- /dev/null +++ b/src/res/CMakeLists.txt @@ -0,0 +1,18 @@ +# Default Resource Library +# Resources are accessed in the code by +# 1. Including the CMRC header file: #include +# 2. Placing the following macro at the global scope of the code file: CMRC_DECLARE(); +# 3. Getting a handle for the resource library: auto r = cmrc::::get_filesystem(); +# 4. Accessing a resource: auto data = r.open(); +# +# For usage see: https://github.com/vector-of-bool/cmrc/tree/master#usage + +cmrc_add_resource_library( + resources-lib + NAMESPACE res + +# ADD NEW RESOURCES AFTER HERE + # shaders/basic.vsh + # shaders/basic.fsh + # shaders/select.csh +) diff --git a/src/utils/log/Log.cpp b/src/utils/log/Log.cpp new file mode 100644 index 0000000..d996461 --- /dev/null +++ b/src/utils/log/Log.cpp @@ -0,0 +1,22 @@ +#include "Log.h" + +#include +#include + +std::shared_ptr Log::Logger; +std::shared_ptr Log::GLLogger; +std::shared_ptr Log::GLFWLogger; +std::shared_ptr Log::PXLogger; +std::shared_ptr Log::FTLogger; + +void Log::Init(spdlog::level::level_enum logLevel) +{ + spdlog::set_pattern("[%Y-%m-%d %T.%e] [%=3n] [%^%l%$] %v"); + Logger = spdlog::stderr_color_mt("LOG"); + GLLogger = spdlog::stderr_color_mt("GL"); + GLFWLogger = spdlog::stderr_color_mt("GLFW"); + + Logger->set_level(logLevel); + GLLogger->set_level(logLevel); + GLFWLogger->set_level(logLevel); +} diff --git a/src/utils/log/Log.h b/src/utils/log/Log.h new file mode 100644 index 0000000..dc54d57 --- /dev/null +++ b/src/utils/log/Log.h @@ -0,0 +1,72 @@ +#pragma once + +#include +#include + +class Log +{ +private: + static std::shared_ptr Logger; + static std::shared_ptr GLLogger; + static std::shared_ptr GLFWLogger; + static std::shared_ptr PXLogger; + static std::shared_ptr FTLogger; + +public: + static void Init(spdlog::level::level_enum logLevel); + + inline static std::shared_ptr &GetLogger() + { + return Logger; + } + + inline static std::shared_ptr &GetGLLogger() + { + return GLLogger; + } + + inline static std::shared_ptr &GetGLFWLogger() + { + return GLFWLogger; + } +}; + +#define LOG_TRACE(...) ::Log::GetLogger()->trace(__VA_ARGS__) +#define LOG_DEBUG(...) ::Log::GetLogger()->debug(__VA_ARGS__) +#define LOG_INFO(...) ::Log::GetLogger()->info(__VA_ARGS__) +#define LOG_WARN(...) ::Log::GetLogger()->warn(__VA_ARGS__) +#define LOG_ERROR(...) ::Log::GetLogger()->error(__VA_ARGS__) +#define LOG_FATAL(...) ::Log::GetLogger()->critical(__VA_ARGS__) + +#define LOG_GL_TRACE(...) ::Log::GetGLLogger()->trace(__VA_ARGS__) +#define LOG_GL_DEBUG(...) ::Log::GetGLLogger()->debug(__VA_ARGS__) +#define LOG_GL_INFO(...) ::Log::GetGLLogger()->info(__VA_ARGS__) +#define LOG_GL_WARN(...) ::Log::GetGLLogger()->warn(__VA_ARGS__) +#define LOG_GL_ERROR(...) ::Log::GetGLLogger()->error(__VA_ARGS__) +#define LOG_GL_FATAL(...) ::Log::GetGLLogger()->critical(__VA_ARGS__) + +#define LOG_GLFW_TRACE(...) ::Log::GetGLFWLogger()->trace(__VA_ARGS__) +#define LOG_GLFW_DEBUG(...) ::Log::GetGLFWLogger()->debug(__VA_ARGS__) +#define LOG_GLFW_INFO(...) ::Log::GetGLFWLogger()->info(__VA_ARGS__) +#define LOG_GLFW_WARN(...) ::Log::GetGLFWLogger()->warn(__VA_ARGS__) +#define LOG_GLFW_ERROR(...) ::Log::GetGLFWLogger()->error(__VA_ARGS__) +#define LOG_GLFW_FATAL(...) ::Log::GetGLFWLogger()->critical(__VA_ARGS__) + +#define LOG_FATAL_AND_EXIT(...) \ + do \ + { \ + LOG_FATAL(__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (false) +#define LOG_GL_FATAL_AND_EXIT(...) \ + do \ + { \ + LOG_GL_FATAL(__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (false) +#define LOG_GLFW_FATAL_AND_EXIT(...) \ + do \ + { \ + LOG_GLFW_FATAL(__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (false) From 1119c18fada363e2504d87a92cbfe836c4408c5a Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Thu, 1 May 2025 14:48:08 +0200 Subject: [PATCH 006/122] Add OpenGL Shader handling. --- src/core/Shader.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/core/Shader.h | 17 +++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/core/Shader.cpp create mode 100644 src/core/Shader.h diff --git a/src/core/Shader.cpp b/src/core/Shader.cpp new file mode 100644 index 0000000..a293eac --- /dev/null +++ b/src/core/Shader.cpp @@ -0,0 +1,51 @@ +#include "Shader.h" +#include + +Shader::Shader(GLenum type) : m_type(type) { + m_handle = glCreateShader(m_type); +} + +void Shader::compile(std::string_view code) { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried compiling source for Shader with invalid handle!"); + } + + const char* code_ptr = code.data(); + const GLint code_length = code.length(); + glShaderSource(m_handle, 1, &code_ptr, &code_length); + glCompileShader(m_handle); + + // check compilation result + GLint succeded; + glGetShaderiv(m_handle, GL_COMPILE_STATUS, &succeded); + if (succeded == GL_FALSE) { + // get log length + GLint log_size; + glGetShaderiv(m_handle, GL_INFO_LOG_LENGTH, &log_size); + + // read log into buffer + std::string message; + message.resize(log_size); + glGetShaderInfoLog(m_handle, log_size, nullptr, &message[0]); + + LOG_GL_FATAL_AND_EXIT(message); + } +} + +GLuint Shader::handle() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried getting handle of Shader with invalid handle!"); + } + + return m_handle; +} + +Shader::~Shader() { + if (handle_valid()) { + glDeleteShader(m_handle); + } +} + +bool Shader::handle_valid() { + return m_handle != 0; +} diff --git a/src/core/Shader.h b/src/core/Shader.h new file mode 100644 index 0000000..158cbde --- /dev/null +++ b/src/core/Shader.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include + +class Shader { +public: + Shader(GLenum type); + void compile(std::string_view code); + GLuint handle(); + ~Shader(); + +private: + GLuint m_handle; + GLenum m_type; + + bool handle_valid(); +}; \ No newline at end of file From a29c7a621b1c6f234c784dc8c79f10eefcba96ea Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Thu, 1 May 2025 14:48:29 +0200 Subject: [PATCH 007/122] Add OpenGL ShaderProgram and Uniform handling. --- src/core/GLUniformAbstractions.h | 159 +++++++++++++++++++++++++++++++ src/core/ShaderProgram.cpp | 91 ++++++++++++++++++ src/core/ShaderProgram.h | 29 ++++++ src/core/Uniform.h | 15 +++ 4 files changed, 294 insertions(+) create mode 100644 src/core/GLUniformAbstractions.h create mode 100644 src/core/ShaderProgram.cpp create mode 100644 src/core/ShaderProgram.h create mode 100644 src/core/Uniform.h diff --git a/src/core/GLUniformAbstractions.h b/src/core/GLUniformAbstractions.h new file mode 100644 index 0000000..0041fd2 --- /dev/null +++ b/src/core/GLUniformAbstractions.h @@ -0,0 +1,159 @@ +#pragma once + +#include +#include +#include + +namespace { + // vectors + template + void glUniformv(const GLint location, const GLsizei count, const T* data); + + template <> + inline void glUniformv(const GLint location, const GLsizei count, const float* data) { + glUniform1fv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const float* data) { + glUniform2fv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const float* data) { + glUniform3fv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const float* data) { + glUniform4fv(location, count, data); + } + + template <> + inline void glUniformv(const GLint location, const GLsizei count, const int* data) { + glUniform1iv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const int* data) { + glUniform2iv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const int* data) { + glUniform3iv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const int* data) { + glUniform4iv(location, count, data); + } + + template <> + inline void glUniformv(const GLint location, const GLsizei count, const unsigned int* data) { + glUniform1uiv(location, count, data); + } + template <> + inline void glUniformv(const GLint location, const GLsizei count, const unsigned int* data) { + glUniform2uiv(location, count, data); + } + template <> + void glUniformv(const GLint location, const GLsizei count, const unsigned int* data) { + glUniform3uiv(location, count, data); + } + template <> + void glUniformv(const GLint location, const GLsizei count, const unsigned int* data) { + glUniform4uiv(location, count, data); + } + + // matrices + template + void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const T* data); + + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix2fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix3fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix4fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix2x3fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix2x4fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix4x2fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix3x4fv(location, count, transpose, data); + } + template <> + inline void glUniformMatrix(const GLint location, const GLsizei count, const bool transpose, const float* data) { + glUniformMatrix4x3fv(location, count, transpose, data); + } +} // namespace + +template +void glUniform(const GLint location, const T* data, const GLsizei count); + +template <> +inline void glUniform(const GLint location, const float* data, const GLsizei count) { + glUniform1fv(location, count, data); +} +template <> +inline void glUniform(const GLint location, const int* data, const GLsizei count) { + glUniform1iv(location, count, data); +} +template <> +inline void glUniform(const GLint location, const unsigned int* data, const GLsizei count) { + glUniform1uiv(location, count, data); +} +template +void glUniform(const GLint location, const glm::vec* data, const GLsizei count) { + glUniformv(location, count, glm::value_ptr(*data)); +} +template +void glUniform(const GLint location, const glm::mat* data, const GLsizei count) { + glUniformMatrix(location, count, false, glm::value_ptr(*data)); +} + +template +void glUniform(const GLint location, T data); + +template <> +inline void glUniform(const GLint location, bool data) { + glUniform1i(location, data ? GL_TRUE : GL_FALSE); +} +template <> +inline void glUniform(const GLint location, float data) { + glUniform1f(location, data); +} +template <> +inline void glUniform(const GLint location, int data) { + glUniform1i(location, data); +} +template <> +inline void glUniform(const GLint location, unsigned int data) { + glUniform1ui(location, data); +} +template +void glUniform(const GLint location, const glm::vec& data) { + glUniformv(location, 1, glm::value_ptr(data)); +} +template +void glUniform(const GLint location, const glm::mat& data) { + glUniformMatrix(location, 1, false, glm::value_ptr(data)); +} +template +void glUniform(const GLint location, const std::array& data) { + glUniform<>(location, data.data(), (GLsizei)data.size()); +} +template +void glUniform(const GLint location, const std::vector& data) { + glUniform(location, data.data(), (GLsizei)data.size()); +} diff --git a/src/core/ShaderProgram.cpp b/src/core/ShaderProgram.cpp new file mode 100644 index 0000000..1f2a67f --- /dev/null +++ b/src/core/ShaderProgram.cpp @@ -0,0 +1,91 @@ +#include "ShaderProgram.h" +#include +#include + +ShaderProgram::ShaderProgram() { + m_handle = glCreateProgram(); +} + +void ShaderProgram::attach(Shader shader) { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried attaching Shader to ShaderProgram with invalid handle!"); + } + glAttachShader(m_handle, shader.handle()); +} + +void ShaderProgram::link() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried linking ShaderProgram with invalid handle!"); + } + + glLinkProgram(m_handle); + + // check link result + GLint succeded; + glGetProgramiv(m_handle, GL_LINK_STATUS, &succeded); + if (succeded == GL_FALSE) { + // get log length + GLint log_size; + glGetProgramiv(m_handle, GL_INFO_LOG_LENGTH, &log_size); + + // read log into buffer + std::string message; + message.resize(log_size); + glGetProgramInfoLog(m_handle, log_size, nullptr, &message[0]); + + LOG_GL_FATAL_AND_EXIT(message); + } + + // load all uniform locations + + GLint uniformCount; + glGetProgramiv(m_handle, GL_ACTIVE_UNIFORMS, &uniformCount); + LOG_DEBUG("Active Uniforms: {}", uniformCount); + + GLsizei length; // name length + GLint size; // size of the variable + GLenum type; // type of the variable (float, vec3 or mat4, etc) + std::string name; + name.resize(16); // name buffer + for (GLint i = 0; i < uniformCount; i++) { + while (true) { + glGetActiveUniform(m_handle, (GLuint)i, (GLsizei)name.length(), &length, &size, &type, name.data()); + if (name.length() - 1 > length) { + break; + } else { + name.resize(name.length() * 2); + } + } + + const auto location = glGetUniformLocation(m_handle, name.c_str()); + m_uniform_locations.insert(std::make_pair(name.substr(0, length), location)); + LOG_DEBUG("Uniform #{} Name: {}", i, name.substr(0, length)); + } +} + +GLint ShaderProgram::get_uniform_location(std::string name) { + const auto result = m_uniform_locations.find(name); + if (result == m_uniform_locations.end()) { + LOG_GL_FATAL_AND_EXIT("Could not find Uniform '{}'", name); + } else { + return result->second; + } +} + +void ShaderProgram::use() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried using ShaderProgram with invalid handle!"); + } + glUseProgram(m_handle); +} + +ShaderProgram::~ShaderProgram() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried destructing ShaderProgram with invalid handle!"); + } + glDeleteProgram(m_handle); +} + +bool ShaderProgram::handle_valid() { + return m_handle != 0; +} diff --git a/src/core/ShaderProgram.h b/src/core/ShaderProgram.h new file mode 100644 index 0000000..ebeb965 --- /dev/null +++ b/src/core/ShaderProgram.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include "Shader.h" +#include "Uniform.h" + +class ShaderProgram { +public: + ShaderProgram(); + + void attach(Shader shader); + + void link(); + + GLint get_uniform_location(std::string name); + + template + Uniform get_uniform(std::string name) { + return Uniform(get_uniform_location(name)); + } + + void use(); + + ~ShaderProgram(); +private: + GLuint m_handle; + std::unordered_map m_uniform_locations; + + bool handle_valid(); +}; \ No newline at end of file diff --git a/src/core/Uniform.h b/src/core/Uniform.h new file mode 100644 index 0000000..ae1ba5b --- /dev/null +++ b/src/core/Uniform.h @@ -0,0 +1,15 @@ +#pragma once +#include +#include "GLUniformAbstractions.h" + +template +class Uniform { +public: + Uniform(GLint location) : m_location(location) {} + void set(const T& value) { + glUniform(m_location, value); + } + +private: + GLint m_location; +}; From fbb3bd4f69c0c5d2562e17a9a0999bb2a3fdb182 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Thu, 1 May 2025 14:49:10 +0200 Subject: [PATCH 008/122] Add Shader files to resources. --- src/res/CMakeLists.txt | 4 ++-- src/res/shaders/basic.frag | 11 +++++++++++ src/res/shaders/basic.vert | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/res/shaders/basic.frag create mode 100644 src/res/shaders/basic.vert diff --git a/src/res/CMakeLists.txt b/src/res/CMakeLists.txt index 2c7ae34..4f92c69 100644 --- a/src/res/CMakeLists.txt +++ b/src/res/CMakeLists.txt @@ -12,7 +12,7 @@ cmrc_add_resource_library( NAMESPACE res # ADD NEW RESOURCES AFTER HERE - # shaders/basic.vsh - # shaders/basic.fsh + shaders/basic.vert + shaders/basic.frag # shaders/select.csh ) diff --git a/src/res/shaders/basic.frag b/src/res/shaders/basic.frag new file mode 100644 index 0000000..90c172d --- /dev/null +++ b/src/res/shaders/basic.frag @@ -0,0 +1,11 @@ +#version 460 core + +in VS_OUT { + vec4 world_pos; +} fs_in; + +out vec4 frag_color; + +void main() { + frag_color = vec4(1.0f); +} diff --git a/src/res/shaders/basic.vert b/src/res/shaders/basic.vert new file mode 100644 index 0000000..ab95568 --- /dev/null +++ b/src/res/shaders/basic.vert @@ -0,0 +1,17 @@ +#version 460 core + +layout (location = 0) in vec3 pos; + +uniform mat4 view; +uniform mat4 projection; + +out VS_OUT { + vec4 world_pos; +} vs_out; + +void main() +{ + vs_out.world_pos = projection * view * vec4(pos, 1.0); + + gl_Position = vec4(vs_out.world_pos.xyz, 1.0f); +} From 361c30cc9fd83b40544098d0d8c19cfb4d1349d5 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Thu, 1 May 2025 14:49:50 +0200 Subject: [PATCH 009/122] Add missing cpp files to CMake. --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9790b65..f1eac81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,6 +84,8 @@ add_executable(alpenite-browser core/Application.cpp core/Window.cpp + core/Shader.cpp + core/ShaderProgram.cpp utils/log/Log.cpp ) From f36ce0602499eb96394d6564070321a6a151e6c1 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Fri, 2 May 2025 16:33:43 +0200 Subject: [PATCH 010/122] Add Buffer --- src/CMakeLists.txt | 1 + src/core/Buffer.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/core/Buffer.h | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/core/Buffer.cpp create mode 100644 src/core/Buffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1eac81..88b34ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,7 @@ add_executable(alpenite-browser core/Window.cpp core/Shader.cpp core/ShaderProgram.cpp + core/Buffer.cpp utils/log/Log.cpp ) diff --git a/src/core/Buffer.cpp b/src/core/Buffer.cpp new file mode 100644 index 0000000..54c9171 --- /dev/null +++ b/src/core/Buffer.cpp @@ -0,0 +1,40 @@ +#include "Buffer.h" +#include + +Buffer::Buffer(GLenum target = GL_ARRAY_BUFFER, GLenum usage = GL_STATIC_DRAW) : m_target(target), m_usage(usage) { + glCreateBuffers(1, &m_handle); +} + +GLuint Buffer::handle() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried getting handle of Buffer with invalid handle!"); + } + return GLuint(); +} + +void Buffer::bind() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried binding Buffer with invalid handle!"); + } + + glBindBuffer(m_target, m_handle); +} + +void Buffer::set_data(const void* data, const size_t size) { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried setting data to Buffer with invalid handle!"); + } + + glNamedBufferData(m_handle, size, data, m_usage); +} + +Buffer::~Buffer() { + if (!handle_valid()) { + LOG_GL_FATAL_AND_EXIT("Tried destructing Buffer with invalid handle!"); + } + glDeleteBuffers(1, &m_handle); +} + +bool Buffer::handle_valid() { + return m_handle != 0; +} diff --git a/src/core/Buffer.h b/src/core/Buffer.h new file mode 100644 index 0000000..b82d0f9 --- /dev/null +++ b/src/core/Buffer.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include + +class Buffer { +public: + Buffer() : Buffer(GL_ARRAY_BUFFER, GL_STATIC_DRAW) {} + Buffer(GLenum target, GLenum usage); + + GLuint handle(); + void bind(); + + template + inline void set_data(const std::vector& data) { + this->set_data(data.data(), data.size() * sizeof(T)); + } + + template + inline void set_data(const std::array& data) { + this->set_data(data.data(), sizeof(std::array)); + } + + void set_data(const void* data, const size_t size); + + ~Buffer(); + +private: + GLuint m_handle; + GLenum m_target; + GLenum m_usage; + + bool handle_valid(); +}; \ No newline at end of file From 3b02fb1a72299ed57f783449961525e4a3d065e6 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Fri, 2 May 2025 16:34:25 +0200 Subject: [PATCH 011/122] Commit current WIP state. --- src/CMakeLists.txt | 2 + src/core/Application.cpp | 174 +++++++++++++++++++++++++++++++++++-- src/core/Camera.cpp | 78 +++++++++++++++++ src/core/Camera.h | 45 ++++++++++ src/core/ShaderProgram.cpp | 4 + src/core/ShaderProgram.h | 2 + src/core/Window.cpp | 86 ++++++++++++++++++ src/core/Window.h | 19 ++++ src/res/shaders/basic.frag | 4 +- src/res/shaders/basic.vert | 2 +- 10 files changed, 408 insertions(+), 8 deletions(-) create mode 100644 src/core/Camera.cpp create mode 100644 src/core/Camera.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88b34ad..c4c0c2f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,8 +87,10 @@ add_executable(alpenite-browser core/Shader.cpp core/ShaderProgram.cpp core/Buffer.cpp + core/Camera.cpp utils/log/Log.cpp + ) target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog) target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/core/Application.cpp b/src/core/Application.cpp index 88fb252..091d8b7 100644 --- a/src/core/Application.cpp +++ b/src/core/Application.cpp @@ -1,6 +1,16 @@ #include "Application.h" #include "utils/log/Log.h" #include +#include + +// CMRC Resource Compiler +#include +#include "Shader.h" +#include "ShaderProgram.h" +#include "Buffer.h" +#include "Camera.h" + +CMRC_DECLARE(res); Application::Application(std::string title, int width, int height) : m_title(title), m_width(width), m_height(height) { @@ -21,11 +31,165 @@ Application::Application(std::string title, int width, int height) } void Application::run() { - while (!m_window->should_close()) { - // Check if any events have been activated (key pressed, mouse moved etc.) - // and call corresponding response functions - m_window->poll_events(); - } + auto RES = cmrc::res::get_filesystem(); + + double last_frame_time = glfwGetTime(); + + LOG_INFO("Setting up shaders"); + auto vertex_shader_code = RES.open("shaders/basic.vert"); + Shader vertex_shader(GL_VERTEX_SHADER); + vertex_shader.compile(std::string_view(vertex_shader_code.begin(), vertex_shader_code.end())); + + auto fragment_shader_code = RES.open("shaders/basic.frag"); + Shader fragment_shader(GL_FRAGMENT_SHADER); + fragment_shader.compile(std::string_view(fragment_shader_code.begin(), fragment_shader_code.end())); + + ShaderProgram shader_program; + + shader_program.attach(vertex_shader); + shader_program.attach(fragment_shader); + shader_program.link(); + shader_program.use(); + + Uniform U_projection = shader_program.get_uniform("projection"); + Uniform U_view = shader_program.get_uniform("view"); + + LOG_INFO("Setting up camera"); + CameraConfig camera_config = { + .fov_deg = 60.0f, + .aspect_ratio = m_window->getAspectRatio(), + .near_plane = 0.1f, + .far_plane = 100.0f, + + .position = glm::vec3(0.0f, 0.0f, 5.0f), + .target = glm::vec3(0.0f), + .up = glm::vec3(0.0f, 1.0f, 0.0f), + }; + Camera camera(camera_config); + + U_projection.set(camera.projection_matrix()); + U_view.set(camera.view_matrix()); + + LOG_INFO("Setting up lines"); + + std::vector vertices = { + glm::vec3(-1.0, -1.0, -1.0), //000 //#0 + glm::vec3(-1.0, 1.0, -1.0), //010 //#1 + glm::vec3( 1.0, 1.0, -1.0), //110 //#2 + glm::vec3( 1.0, -1.0, -1.0), //100 //#3 + + glm::vec3(-1.0, -1.0, 1.0), //001 //#4 + glm::vec3(-1.0, 1.0, 1.0), //011 //#5 + glm::vec3( 1.0, 1.0, 1.0), //111 //#6 + glm::vec3( 1.0, -1.0, 1.0), //101 //#7 + }; + + std::vector indices = { + //Bottom Loop + 0, 1, 1, 2, 2, 3, 3, 0, + //Top Loop + 4, 5, 5, 6, 6, 7, 7, 4, + //Connecting Top and Bottom + 0, 4, + 1, 5, + 2, 6, + 3, 7 + }; + + unsigned int VAO; + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + Buffer cube_ibo(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW); + Buffer cube_vbo; + + cube_vbo.set_data(vertices); + cube_ibo.set_data(indices); + + cube_vbo.bind(); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL); + glEnableVertexAttribArray(0); + + cube_ibo.bind(); + + //glEnable(GL_CULL_FACE); + //glCullFace(GL_BACK); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glClearColor(0.f, 0.f, 0.f, 1.f); + + glm::dvec2 last_cursor_position = m_window->get_cursor_position() / m_window->get_window_size(); + + float default_movement_speed = 5.0f; + float mouse_sensitivity = 100.0f; + + while (!m_window->should_close()) { + const double current_frame_time = glfwGetTime(); + const double frame_delta_time = current_frame_time - last_frame_time; + last_frame_time = current_frame_time; + + m_window->poll_events(); + + glm::dvec2 current_cursor_position = m_window->get_cursor_position(); + + if (m_window->is_mouse_button_pressed(GLFW_MOUSE_BUTTON_LEFT)) { + m_window->set_capture_mouse(true); + + const glm::dvec2 cursor_position_delta = (current_cursor_position - last_cursor_position) / m_window->get_window_size(); + glm::vec3 camera_rotation_delta = glm::vec3(cursor_position_delta.y, cursor_position_delta.x, 0.0f) * (float)frame_delta_time * mouse_sensitivity; + + camera.rotate(camera_rotation_delta); + } else { + m_window->set_capture_mouse(false); + } + + + glm::vec3 local_movement_delta(0.0f); + float movement_speed = default_movement_speed; + + if (m_window->is_key_pressed(GLFW_KEY_LEFT_SHIFT)) { + movement_speed *= 2.0f; + } + + if (m_window->is_key_pressed(GLFW_KEY_W) || m_window->is_key_pressed(GLFW_KEY_UP)) { + local_movement_delta.z += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_S) || m_window->is_key_pressed(GLFW_KEY_DOWN)) { + local_movement_delta.z -= 1.0f; + } + + if (m_window->is_key_pressed(GLFW_KEY_D) || m_window->is_key_pressed(GLFW_KEY_RIGHT)) { + local_movement_delta.x += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_A) || m_window->is_key_pressed(GLFW_KEY_LEFT)) { + local_movement_delta.x -= 1.0f; + } + + if (m_window->is_key_pressed(GLFW_KEY_SPACE)) { + local_movement_delta.y += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_LEFT_CONTROL)) { + local_movement_delta.y -= 1.0f; + } + + if (glm::abs(local_movement_delta.x) + glm::abs(local_movement_delta.y) + glm::abs(local_movement_delta.z) != 0.0f) { + camera.move_local(local_movement_delta * (float)frame_delta_time * movement_speed); + } + + if (camera.is_view_matrix_outdated()) { + LOG_DEBUG("Camera view outdated"); + U_view.set(camera.view_matrix()); + } + + last_cursor_position = current_cursor_position; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPointSize(10.0f); + glDrawElements(GL_LINES, indices.size(), GL_UNSIGNED_INT, 0); + + m_window->swapBuffers(); + } } Application::~Application() { diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp new file mode 100644 index 0000000..5f22b24 --- /dev/null +++ b/src/core/Camera.cpp @@ -0,0 +1,78 @@ +#include "Camera.h" +#include + +Camera::Camera(CameraConfig config) : + m_fov_deg(config.fov_deg), + m_aspect_ratio(config.aspect_ratio), + m_near_plane(config.near_plane), + m_far_plane(config.far_plane), + m_position(config.position), + m_up(glm::normalize(config.up)){ + + glm::vec3 forward = glm::normalize(config.target - m_position); + m_rotation = glm::quatLookAt(forward, m_up); + + update_projection_matrix(); + update_view_matrix(); +} + +void Camera::rotate(glm::vec3 euler_radians_delta) { + m_view_matrix_cache.reset(); + + glm::vec3 euler_rot = glm::eulerAngles(m_rotation); + glm::vec3 new_euler_rot = euler_rot + euler_radians_delta; + + new_euler_rot.x = glm::mod(new_euler_rot.x, glm::two_pi()); + new_euler_rot.y = glm::mod(new_euler_rot.y, glm::two_pi()); + new_euler_rot.z = glm::mod(new_euler_rot.z, glm::two_pi()); + + LOG_DEBUG("{} / {} / {} => {} / {} / {}", euler_rot.x, euler_rot.y, euler_rot.z, new_euler_rot.x, new_euler_rot.y, new_euler_rot.z); + + m_rotation = glm::quat(new_euler_rot); +} + +void Camera::move_local(glm::vec3 local_movement_delta) { + m_view_matrix_cache.reset(); + + glm::vec3 right_dir = local_movement_delta.x * glm::normalize(m_rotation * glm::vec3(1.0f, 0.0f, 0.0f)); + glm::vec3 up_dir = local_movement_delta.y * glm::normalize(m_rotation * m_up); + glm::vec3 forward_dir = local_movement_delta.z * glm::normalize(m_rotation * glm::vec3(0.0f, 0.0f, -1.0f)); + + auto copy = glm::vec3(m_position); + + m_position += right_dir + up_dir + forward_dir; +} + +bool Camera::is_view_matrix_outdated() { + return !m_view_matrix_cache.has_value(); +} + +bool Camera::is_projection_matrix_outdated() { + return !m_projection_matrix_cache.has_value(); +} + +glm::mat4 Camera::projection_matrix() { + update_projection_matrix(); + + return m_projection_matrix_cache.value(); +} + +glm::mat4 Camera::view_matrix() { + update_view_matrix(); + + return m_view_matrix_cache.value(); +} + +void Camera::update_view_matrix() { + if (!m_view_matrix_cache.has_value()) { + glm::mat4 rotation = glm::mat4_cast(m_rotation); + glm::mat4 translation = glm::translate(glm::mat4(1.0f), m_position); + m_view_matrix_cache.emplace(glm::inverse(translation * rotation)); + } +} + +void Camera::update_projection_matrix() { + if (!m_projection_matrix_cache.has_value()) { + m_projection_matrix_cache.emplace(glm::perspective(glm::radians(m_fov_deg), m_aspect_ratio, m_near_plane, m_far_plane)); + } +} diff --git a/src/core/Camera.h b/src/core/Camera.h new file mode 100644 index 0000000..46b7200 --- /dev/null +++ b/src/core/Camera.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include +#include + +struct CameraConfig { + float fov_deg = 60.0f; + float aspect_ratio = 16.0f / 9.0f; + float near_plane = 0.1f; + float far_plane = 100.0f; + + glm::vec3 position = glm::vec3(0.0f, 0.0f, 5.0f); + glm::vec3 target = glm::vec3(0.0f); + glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); +}; + +class Camera { +public: + Camera(CameraConfig config); + + void rotate(glm::vec3 euler_delta); + void move_local(glm::vec3 local_movement_delta); + + bool is_view_matrix_outdated(); + bool is_projection_matrix_outdated(); + + glm::mat4 projection_matrix(); + glm::mat4 view_matrix(); + +private: + float m_fov_deg; + float m_aspect_ratio; + float m_near_plane; + float m_far_plane; + + glm::vec3 m_up; + glm::vec3 m_position; + glm::quat m_rotation; + + std::optional m_view_matrix_cache; + std::optional m_projection_matrix_cache; + + void update_view_matrix(); + void update_projection_matrix(); +}; diff --git a/src/core/ShaderProgram.cpp b/src/core/ShaderProgram.cpp index 1f2a67f..48a8788 100644 --- a/src/core/ShaderProgram.cpp +++ b/src/core/ShaderProgram.cpp @@ -63,6 +63,10 @@ void ShaderProgram::link() { } } +GLuint ShaderProgram::handle() { + return m_handle; +} + GLint ShaderProgram::get_uniform_location(std::string name) { const auto result = m_uniform_locations.find(name); if (result == m_uniform_locations.end()) { diff --git a/src/core/ShaderProgram.h b/src/core/ShaderProgram.h index ebeb965..ea4d494 100644 --- a/src/core/ShaderProgram.h +++ b/src/core/ShaderProgram.h @@ -11,6 +11,8 @@ class ShaderProgram { void link(); + GLuint handle(); + GLint get_uniform_location(std::string name); template diff --git a/src/core/Window.cpp b/src/core/Window.cpp index ff2eb30..155fdd6 100644 --- a/src/core/Window.cpp +++ b/src/core/Window.cpp @@ -33,6 +33,11 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei // Set the required callback functions glfwSetKeyCallback(m_window, key_callback); + glfwSetMouseButtonCallback(m_window, mouse_button_callback); + glfwSetCursorPosCallback(m_window, cursor_position_callback); + + // Link a pointer to this class with the window handle, to be able to access this class from the callbacks + glfwSetWindowUserPointer(m_window, (void*)this); } Window::~Window() { @@ -50,14 +55,95 @@ void Window::poll_events() { glfwPollEvents(); } +void Window::swapBuffers() { + glfwSwapBuffers(m_window); +} + +void Window::set_capture_mouse(bool captured) { + if (captured) { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } else { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } +} + +glm::dvec2 Window::get_cursor_position() { + glm::dvec2 cursor_position; + glfwGetCursorPos(m_window, &cursor_position.x, &cursor_position.y); + return cursor_position; +} + +glm::dvec2 Window::get_window_size() { + return glm::dvec2(m_width, m_height); +} + +bool Window::is_key_pressed(int key) { + auto result = m_key_states.find(key); + + if (result == m_key_states.end()) { + return false; + } + + return result->second; +} + +bool Window::is_mouse_button_pressed(int button) { + auto result = m_mouse_button_states.find(button); + + if (result == m_mouse_button_states.end()) { + return false; + } + + return result->second; +} + +float Window::getAspectRatio() { + return (float)m_width / (float)m_height; +} + void Window::glfw_error_callback(int error, const char* description) { LOG_GLFW_ERROR("[{}] {}", error, description); } void Window::key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { + Window* w = (Window*)glfwGetWindowUserPointer(window); + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window, GL_TRUE); } + + if (!w->m_key_states.contains(key)) { + w->m_key_states.emplace(key, false); + } + + if (action == GLFW_PRESS) { + LOG_DEBUG("KEY {} PRESS", key); + w->m_key_states[key] = true; + } else if (action == GLFW_RELEASE) { + LOG_DEBUG("KEY {} RELEASE", key); + w->m_key_states[key] = false; + } +} + +void Window::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { + Window* w = (Window*)glfwGetWindowUserPointer(window); + + if (!w->m_mouse_button_states.contains(button)) { + w->m_mouse_button_states.emplace(button, false); + } + + if (action == GLFW_PRESS) { + w->m_mouse_button_states[button] = true; + } else if (action == GLFW_RELEASE) { + w->m_mouse_button_states[button] = false; + } +} + +void Window::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { + Window* w = (Window*)glfwGetWindowUserPointer(window); + + w->m_current_cursor_pos.x = xpos; + w->m_current_cursor_pos.y = ypos; } void Window::update_window_count(int delta) { diff --git a/src/core/Window.h b/src/core/Window.h index cde3509..f3c7241 100644 --- a/src/core/Window.h +++ b/src/core/Window.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include #include +#include struct WindowConfig { int width = 1280; @@ -20,6 +22,17 @@ class Window { bool should_close(); void poll_events(); + void swapBuffers(); + + void set_capture_mouse(bool captured); + + glm::dvec2 get_cursor_position(); + glm::dvec2 get_window_size(); + bool is_key_pressed(int key); + bool is_mouse_button_pressed(int key); + + float getAspectRatio(); + private: static std::atomic window_instances; static std::atomic glfw_initialized; @@ -29,8 +42,14 @@ class Window { GLFWwindow* m_window; + std::map m_mouse_button_states; + std::map m_key_states; + glm::dvec2 m_current_cursor_pos; + static void glfw_error_callback(int error, const char* description); static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); + static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); + static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos); static void update_window_count(int delta); }; diff --git a/src/res/shaders/basic.frag b/src/res/shaders/basic.frag index 90c172d..beac6d6 100644 --- a/src/res/shaders/basic.frag +++ b/src/res/shaders/basic.frag @@ -4,8 +4,8 @@ in VS_OUT { vec4 world_pos; } fs_in; -out vec4 frag_color; +out vec4 FragColor; void main() { - frag_color = vec4(1.0f); + FragColor = vec4(1.0f); } diff --git a/src/res/shaders/basic.vert b/src/res/shaders/basic.vert index ab95568..b356d89 100644 --- a/src/res/shaders/basic.vert +++ b/src/res/shaders/basic.vert @@ -13,5 +13,5 @@ void main() { vs_out.world_pos = projection * view * vec4(pos, 1.0); - gl_Position = vec4(vs_out.world_pos.xyz, 1.0f); + gl_Position = vs_out.world_pos; } From 8723049bf8c31c1548e2076b3e1fbffea4de7eb1 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 2 May 2025 21:10:51 +0200 Subject: [PATCH 012/122] Add octree based mesh generation (WIP) --- README.md | 3 +- src/CMakeLists.txt | 6 +- src/terrainbuilder/border.h | 47 +- src/terrainbuilder/main.cpp | 92 +++- src/terrainbuilder/mesh_builder.cpp | 560 +++++++++++----------- src/terrainbuilder/mesh_builder.h | 9 +- src/terrainbuilder/octree/id.h | 161 +++++++ src/terrainbuilder/octree/space.h | 120 +++++ src/terrainbuilder/octree/storage.h | 46 ++ src/terrainbuilder/octree/utils.cpp | 2 + src/terrainbuilder/octree/utils.h | 10 + src/terrainbuilder/raster.h | 144 ++++++ src/terrainbuilder/raw_dataset_reader.h | 8 +- src/terrainbuilder/terrainbuilder.cpp | 53 +- src/terrainbuilder/terrainbuilder.h | 6 +- src/terrainbuilder/texture_assembler.h | 2 +- src/terrainlib/Dataset.cpp | 4 +- src/terrainlib/mesh/terrain_mesh.cpp | 37 ++ src/terrainlib/mesh/terrain_mesh.h | 8 +- src/terrainlib/srs.h | 333 +++++++++---- src/terrainmerger/merge.cpp | 16 +- src/terrainmerger/simplify.cpp | 24 +- unittests/CMakeLists.txt | 23 +- unittests/catch2_helpers.h | 3 +- unittests/terrainbuilder/mesh.cpp | 48 +- unittests/terrainbuilder/mesh2.cpp | 320 +++++++++++++ unittests/terrainbuilder/octree_id.cpp | 63 +++ unittests/terrainbuilder/octree_space.cpp | 113 +++++ unittests/terrainbuilder/texture.cpp | 181 ++++--- 29 files changed, 1854 insertions(+), 588 deletions(-) create mode 100644 src/terrainbuilder/octree/id.h create mode 100644 src/terrainbuilder/octree/space.h create mode 100644 src/terrainbuilder/octree/storage.h create mode 100644 src/terrainbuilder/octree/utils.cpp create mode 100644 src/terrainbuilder/octree/utils.h create mode 100644 src/terrainbuilder/raster.h create mode 100644 unittests/terrainbuilder/mesh2.cpp create mode 100644 unittests/terrainbuilder/octree_id.cpp create mode 100644 unittests/terrainbuilder/octree_space.cpp diff --git a/README.md b/README.md index e7e6a0c..bbbbf88 100644 --- a/README.md +++ b/README.md @@ -83,4 +83,5 @@ In order to build, you need to install: - FreeImage - tbb (intel threading building blocks) -sudo apt-get install libfmt-dev libglm-dev libgdal-dev catch2 libfreeimage-dev libtbb-dev +sudo apt-get install libcgal-dev libopencv-dev libfmt-dev libglm-dev libgdal-dev catch2 libfreeimage-dev libtbb-dev libcurl4-openssl-dev +(libgmp-dev libmpfr-dev libeigen3-dev) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0453b50..46abfdf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,7 @@ endif() if(ALP_AUTOUPDATE_RADIX) FetchContent_Declare(radix GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git - GIT_TAG origin/main + GIT_TAG d01b84248e21e4754e028492bf70519e3416c86 SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix SOURCE_SUBDIR src ) @@ -217,8 +217,12 @@ add_library(terrainbuilderlib terrainbuilder/raw_dataset_reader.h terrainbuilder/texture_assembler.h terrainbuilder/border.h + terrainbuilder/raster.h terrainbuilder/terrainbuilder.h terrainbuilder/terrainbuilder.cpp + terrainbuilder/octree/id.h + terrainbuilder/octree/storage.h + terrainbuilder/octree/space.h ) target_include_directories(terrainbuilderlib PUBLIC terrainbuilder terrainlib) target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 expected) diff --git a/src/terrainbuilder/border.h b/src/terrainbuilder/border.h index ff754b2..01746ea 100644 --- a/src/terrainbuilder/border.h +++ b/src/terrainbuilder/border.h @@ -42,12 +42,51 @@ class Border { } }; +namespace { + template + constexpr T saturating_add(T x, T y) noexcept { + static_assert(std::is_integral_v, "saturating_add requires an integer type"); + + T result; + if (!__builtin_add_overflow(x, y, &result)) { + return result; + } + + if constexpr (std::is_unsigned_v) { + return std::numeric_limits::max(); + } else if (x < 0) { + return std::numeric_limits::min(); + } else { + return std::numeric_limits::max(); + } +} + +// Saturating subtract for integers +template +constexpr T saturating_sub(T x, T y) noexcept { + static_assert(std::is_integral_v, "saturating_sub requires an integer type"); + + T result; + if (!__builtin_sub_overflow(x, y, &result)) { + return result; + } + + if constexpr (std::is_unsigned_v) { + return 0; + } else if (x < 0) { + return std::numeric_limits::min(); + } else { + return std::numeric_limits::max(); + } +} +} + template inline void add_border_to_aabb(radix::geometry::Aabb2 &bounds, const Border &border) { - bounds.min.x -= border.left; - bounds.min.y -= border.top; - bounds.max.x += border.right; - bounds.max.y += border.bottom; + bounds.min.x = saturating_sub(bounds.min.x, border.left); + bounds.min.y = saturating_sub(bounds.min.y, border.top); + bounds.max.x = saturating_add(bounds.max.x, border.right); + bounds.max.y = saturating_add(bounds.max.y, border.bottom); } } diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index afbebd9..9263bfb 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -16,6 +16,16 @@ #include "terrainbuilder.h" #include "log.h" +#include "octree/storage.h" +#include "octree/space.h" + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + int run(std::span args) { int argc = args.size(); char ** argv = args.data(); @@ -35,27 +45,32 @@ int run(std::span args) { std::string mesh_srs_input; app.add_option("--mesh-srs", mesh_srs_input, "EPSG code of the target srs of the mesh positions") - ->default_val("EPSG:4978"); + ->default_val("EPSG:4978"); // ECEF std::string target_srs_input; - app.add_option("--target-srs", target_srs_input, "EPSG code of the srs of the target bounds or tile id") - ->default_val("EPSG:3857"); + app.add_option("--target-srs", target_srs_input, "EPSG code of the srs of the target bounds or id") + ->default_val("EPSG:4978"); // ECEF auto *target = app.add_option_group("target"); std::vector target_bounds_data; - target->add_option("--bounds", target_bounds_data, "Target bounds for the reference tile as \"{xmin} {ymin} {width} {height}\"") - ->expected(4); - std::vector target_tile_data; + target->add_option("--bounds", target_bounds_data, "Target bounds for the reference mesh as \"{xmin} {width} {ymin} {height} [{zmin} {depth}]\"") + ->expected(4, 6); + std::vector target_tile_data; target->add_option("--tile", target_tile_data, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") ->expected(3) ->excludes("--bounds"); + std::vector target_node_data; + target->add_option("--node", target_node_data, "Target node id for the reference node as \"{zoom} {index}\" or \"{zoom} {x} {y} {z}\"") + ->expected(2, 4) + ->excludes("--tile") + ->excludes("--bounds"); target->require_option(1); radix::tile::Scheme target_tile_scheme; std::map scheme_str_map{{"slippymap", radix::tile::Scheme::SlippyMap}, {"google", radix::tile::Scheme::SlippyMap}, {"tms", radix::tile::Scheme::Tms}}; - app.add_option("--scheme", target_tile_scheme, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") + app.add_option("--scheme", target_tile_scheme, "Target scheme for the tile id") ->default_val(radix::tile::Scheme::SlippyMap) - ->excludes("--bounds") + ->needs("--tile") ->transform(CLI::CheckedTransformer(scheme_str_map, CLI::ignore_case)); std::filesystem::path output_path; @@ -80,44 +95,71 @@ int run(std::span args) { Dataset dataset(dataset_path); - OGRSpatialReference tile_srs; - tile_srs.SetFromUserInput(target_srs_input.c_str()); - tile_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + OGRSpatialReference target_bounds_srs; + target_bounds_srs.SetFromUserInput(target_srs_input.c_str()); + target_bounds_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); OGRSpatialReference mesh_srs; mesh_srs.SetFromUserInput(mesh_srs_input.c_str()); mesh_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - OGRSpatialReference texture_srs; - texture_srs.importFromEPSG(3857); - texture_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + OGRSpatialReference texture_srs = srs::webmercator(); - radix::tile::SrsBounds tile_bounds; + radix::geometry::Aabb3d target_bounds; if (!target_bounds_data.empty()) { - const glm::dvec2 tile_bounds_min(target_bounds_data[0], target_bounds_data[1]); - const glm::dvec2 tile_bounds_size(target_bounds_data[2], target_bounds_data[3]); - tile_bounds = radix::tile::SrsBounds(tile_bounds_min, tile_bounds_min + tile_bounds_size); - } else { + // Target bounds are given directly + if (target_bounds_data.size() == 4) { + const glm::dvec2 min(target_bounds_data[0], target_bounds_data[2]); + const glm::dvec2 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3]); + target_bounds = extend_bounds_to_3d(radix::geometry::Aabb2d(min, max)); + } else if (target_bounds_data.size() == 6) { + const glm::dvec3 min(target_bounds_data[0], target_bounds_data[2], target_bounds_data[4]); + const glm::dvec3 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3], target_bounds_data[4] + target_bounds_data[5]); + target_bounds = radix::geometry::Aabb3d(min, max); + } else { + LOG_ERROR("Invalid number of elements for --bounds. Expected 4 or 6 ({xmin} {width} {ymin} {height} [{zmin} {depth}])."); + return 1; + } + } else if (!target_tile_data.empty()) { + // Target bounds are based on a webmercator tile id const ctb::Grid grid = ctb::GlobalMercator(); const unsigned int zoom_level = target_tile_data[0]; const glm::uvec2 tile_coords(target_tile_data[1], target_tile_data[2]); const radix::tile::Id target_tile(zoom_level, tile_coords, target_tile_scheme); - if (!tile_srs.IsSame(&grid.getSRS())) { - LOG_ERROR("Target tile id is only supported for webmercator reference system"); + if (!target_bounds_srs.IsSame(&grid.getSRS())) { + LOG_ERROR("Target tile id is only supported for the webmercator reference system"); exit(1); } - tile_bounds = grid.srsBounds(target_tile, false); + target_bounds = extend_bounds_to_3d(grid.srsBounds(target_tile, false)); + } else { + // Target bounds are based on an octree node id + const uint32_t zoom_level = target_node_data[0]; + octree::Id target_node = octree::Id::root(); + if (target_node_data.size() == 2) { + const uint64_t node_index = target_node_data[1]; + target_node = {zoom_level, node_index}; + } else if (target_node_data.size() == 4) { + const glm::uvec3 coords(target_node_data[1], target_node_data[2], target_node_data[3]); + target_node = { zoom_level, coords }; + } else { + LOG_ERROR("Invalid number of args for --node. Expected 2 or 4."); + return 1; + } + + const octree::Space world = octree::Space::earth(); + target_bounds = world.get_node_bounds(target_node); } + terrainbuilder::build( dataset, + target_bounds_srs, + target_bounds, + texture_srs, texture_base_path, mesh_srs, - tile_srs, - texture_srs, - tile_bounds, output_path); return 0; diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index a70343c..bc094ac 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -7,336 +9,344 @@ #include #include "Dataset.h" -#include "Image.h" #include "mesh/terrain_mesh.h" #include "srs.h" -#include "tntn/gdal_init.h" +#include "raster.h" #include "log.h" #include "mesh_builder.h" #include "raw_dataset_reader.h" +#include namespace terrainbuilder::mesh { +std::ostream &operator<<(std::ostream &os, BuildError error) { + switch (error) { + case BuildError::OutOfBounds: + os << "out of bounds"; + break; + case BuildError::EmptyRegion: + os << "empty region"; + break; + default: + os << "unknown build error"; + break; + } + return os; +} + template static glm::dvec2 apply_transform(std::array transform, const glm::tvec2 &v) { glm::dvec2 result; GDALApplyGeoTransform(transform.data(), v.x, v.y, &result.x, &result.y); return result; } -static glm::dvec2 apply_transform(OGRCoordinateTransformation *transform, const glm::dvec2 &v) { - glm::dvec2 result(v); - if (!transform->Transform(1, &result.x, &result.y)) { - throw std::runtime_error("apply_transform() failed"); - } - return result; -} -static glm::dvec3 apply_transform(OGRCoordinateTransformation *transform, const glm::dvec3 &v) { - glm::dvec3 result(v); - if (!transform->Transform(1, &result.x, &result.y, &result.z)) { - throw std::runtime_error("apply_transform() failed"); - } - return result; -} - -/// Builds a mesh from the given height dataset. -// TODO: split this up: Grid class, Mask class/alias, mask filter method/utils -// steps (each a method): -// - read data (height) -// - filter invalid values (create mask) -// - calculate positions in source srs -// - filter by bounds (considering inclusivity and invalid values) -// - extend mask by border -// - compact vertices -// - check if empty -// - calculate position in texture srs and normalize -// - generate actual triangles -// (shouldnt require reindexing of vertices; use an interface that combines this and inclusivity filtering) -// - validate final mesh -// TODO: return result struct instead of using inout parameters -tl::expected build_reference_mesh_tile( - Dataset &dataset, - const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, - const Border &vertex_border, - const bool inclusive_bounds) { - const OGRSpatialReference &source_srs = dataset.srs(); - - // Translate tile bounds from tile srs into the source srs, so we know what data to read. - const radix::tile::SrsBounds tile_bounds_in_source_srs = srs::encompassing_bounding_box_transfer(tile_srs, source_srs, tile_bounds); - - // Read height data according to bounds directly from dataset (no interpolation). - RawDatasetReader reader(dataset); - radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(tile_bounds_in_source_srs); - add_border_to_aabb(pixel_bounds, vertex_border); - if (inclusive_bounds) { - add_border_to_aabb(pixel_bounds, Border(1)); - } - LOG_TRACE("Reading pixels [({}, {})-({}, {})] from dataset", pixel_bounds.min.x, pixel_bounds.min.y, pixel_bounds.max.x, pixel_bounds.max.y); - const std::optional read_result = reader.read_data_in_pixel_bounds(pixel_bounds, true); - if (!read_result.has_value() || read_result->size() == 0) { - return tl::unexpected(BuildError::OutOfBounds); - } - const HeightData raw_tile_data = read_result.value(); - - // Allocate mesh data structure - const unsigned int max_vertex_count = raw_tile_data.width() * raw_tile_data.height(); - const unsigned int max_triangle_count = (raw_tile_data.width() - 1) * (raw_tile_data.height() - 1) * 2; - TerrainMesh mesh; - mesh.positions.reserve(max_vertex_count); - mesh.uvs.reserve(max_vertex_count); - mesh.triangles.reserve(max_triangle_count); - - // Prepare transformations here to avoid io inside the loop. - const std::unique_ptr transform_source_tile = srs::transformation(source_srs, tile_srs); - const std::unique_ptr transform_source_mesh = srs::transformation(source_srs, mesh_srs); - const std::unique_ptr transform_source_texture = srs::transformation(source_srs, texture_srs); - - // Preparation for loop - const double infinity = std::numeric_limits::infinity(); - radix::tile::SrsBounds actual_tile_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); - - std::vector source_positions; - source_positions.resize(max_vertex_count); - std::vector is_in_bounds; - is_in_bounds.resize(max_vertex_count); - std::fill(is_in_bounds.begin(), is_in_bounds.end(), false); +using PixelBounds = radix::geometry::Aabb2i; - std::vector is_valid; - is_valid.resize(max_vertex_count); - std::fill(is_valid.begin(), is_valid.end(), true); +// TODO:: write documentation +// TODO: use referencedBounds - // Pixel values represent the average over their area, or a value at their center. - const glm::dvec2 point_offset_in_raster(0.5); - - LOG_TRACE("Transforming pixels to vertices"); - // Iterate over height map and calculate vertex positions for each pixel and whether they are inside the requested bounds. - for (unsigned int j = 0; j < raw_tile_data.height(); j++) { - for (unsigned int i = 0; i < raw_tile_data.width(); i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - const double height = raw_tile_data.pixel(j, i); - - // Check if pixel is valid. - if (isnan(height) || isinf(height) /* <- invalid values */ - || height < -20000 || height > 20000) /* <- padding */ { - is_valid[vertex_index] = false; - continue; - } +bool is_valid(float height) { + return !isnan(height) && !isinf(height) /* <- invalid values */ + && height > -20000 && height < 20000; /* <- padding */ +} - // Convert pixel coordinates into a point in the dataset's srs. - const glm::dvec2 coords_raster_relative = glm::dvec2(i, j) + point_offset_in_raster; - const glm::dvec2 coords_raster_absolute = coords_raster_relative + glm::dvec2(pixel_bounds.min); - const glm::dvec3 coords_source(reader.transform_pixel_to_srs_point(coords_raster_absolute), height); - actual_tile_bounds.expand_by(coords_source); - source_positions[vertex_index] = coords_source; - - // Check if the point is inside the given bounds. - if (inclusive_bounds) { - // For inclusive bounds we decide based on the center of the quad, - // that is spanned from the current vertex to the right and bottom. - // We do not account for the extra quads on the top and left here, - // because this is done by adding a 1px border to raw_tile_data above. - - if (i >= raw_tile_data.width() - 1 || j >= raw_tile_data.height() - 1) { - // Skip last row and column because they don't form new triangles - continue; - } +glm::dvec3 convert_pixel_to_vertex(const float height, const raster::Coords pixel_coords, const RawDatasetReader& reader, const PixelBounds& pixel_bounds) { + const glm::dvec2 point_offset_in_raster(0.5); // Convert pixel coordinates into a point in the dataset's srs. + const glm::dvec2 coords_raster_relative = glm::dvec2(pixel_coords) + point_offset_in_raster; + const glm::dvec2 coords_raster_absolute = coords_raster_relative + glm::dvec2(pixel_bounds.min); + const glm::dvec3 coords_source(reader.transform_pixel_to_srs_point(coords_raster_absolute), height); + return coords_source; +} - // Transform the center of the quad into the srs the bounds are given. - const glm::ivec2 coords_center_raster_relative = glm::dvec2(i, j) + point_offset_in_raster + glm::dvec2(0.5); - const glm::ivec2 coords_center_raster_absolute = coords_center_raster_relative + pixel_bounds.min; - const glm::dvec2 coords_center_source = reader.transform_pixel_to_srs_point(coords_center_raster_absolute); - const glm::dvec2 coords_center_tile = apply_transform(transform_source_tile.get(), coords_center_source); +TerrainMesh meshify(const raster::Raster& source_points, const raster::Mask& mask) { + // Compact the vertex grid into a list of valid ones. + const size_t valid_vertex_count = std::reduce(mask.begin(), mask.end(), 0); + // Check if we even have any valid vertices. Can happen if all of the region is padding. + if (valid_vertex_count == 0) { + return TerrainMesh(); + } - if (!tile_bounds.contains_inclusive(coords_center_tile)) { - continue; - } - } else { - // For exclusive bounds, we only include points (and thereforce triangles) that are (fully) inside the bounds. - const glm::dvec2 coords_tile = apply_transform(transform_source_tile.get(), coords_source); - if (!tile_bounds.contains_inclusive(coords_tile)) { - continue; + std::vector positions; + positions.reserve(valid_vertex_count); + + const raster::Raster vertex_index_map = raster::transform(source_points, mask, [&](const glm::dvec3 &point) -> size_t { + const size_t index = positions.size(); + positions.push_back(point); + return index; + }); + assert(positions.size() == valid_vertex_count); + + // Allocate triangle vector + const size_t max_triangle_count = (source_points.width() - 1) * (source_points.height() - 1) * 2; + std::vector triangles; + triangles.reserve(max_triangle_count); + + for (size_t x = 0; x < source_points.width() - 1; x++) { + for (size_t y = 0; y < source_points.height() - 1; y++) { + const std::array quad { + raster::Coords{x, y}, + raster::Coords{x + 1, y}, + raster::Coords{x + 1, y + 1}, + raster::Coords{x, y + 1}}; + + for (uint32_t i = 0; i < 4; i++) { + const auto& v0 = quad[i]; + const auto& v1 = quad[(i + 1) % 4]; + const auto& v2 = quad[(i + 2) % 4]; + + // Check if the indices are valid + if (mask.pixel(v0) && mask.pixel(v1) && mask.pixel(v2)) { + triangles.emplace_back(vertex_index_map.pixel(v0), vertex_index_map.pixel(v1), vertex_index_map.pixel(v2)); + i++; } } - - // If we arrive here the point is inside the bounds. - is_in_bounds[vertex_index] = true; } } + assert(triangles.size() <= max_triangle_count); - // Mark all border vertices as inside bounds. - // TODO: This code is rather inefficient for larger borders. - if (!vertex_border.is_empty()) { - LOG_TRACE("Adding border vertices"); - std::vector border_vertices; - const unsigned int max_border_vertices = std::max(raw_tile_data.width(), raw_tile_data.height()); // for each step, assuming convexity - border_vertices.reserve(max_border_vertices); - - const std::array, 4> border_offsets = { - std::make_pair(vertex_border.left, glm::ivec2(-1, 0)), - std::make_pair(vertex_border.right, glm::ivec2(1, 0)), - std::make_pair(vertex_border.top, glm::ivec2(0, -1)), - std::make_pair(vertex_border.bottom, glm::ivec2(0, 1))}; - - for (unsigned int k = 0; k < border_offsets.size(); k++) { - const unsigned int border_thickness = border_offsets[k].first; - const glm::ivec2 border_direction = border_offsets[k].second; - - for (unsigned int l = 0; l < border_thickness; l++) { - for (unsigned int j = 0; j < raw_tile_data.height() - 1; j++) { - for (unsigned int i = 0; i < raw_tile_data.width() - 1; i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - - // skip all vertices already inside bounds - if (is_in_bounds[vertex_index]) { - continue; - } - - // Current vertex index offset into the opposite direction of the current border direction. - // So if we are currently making a top border, we offset the current position down. - const unsigned int vertex_index_to_check = (j + border_direction.y) * raw_tile_data.width() + (i + border_direction.x); - assert(vertex_index_to_check < max_vertex_count); - if (is_in_bounds[vertex_index_to_check]) { - // as we cannot have a reference into an std::vector we have to have another lookup here. - border_vertices.push_back(vertex_index); - } - } - } + return TerrainMesh(triangles, positions); +} - for (const unsigned int border_vertex : border_vertices) { - assert(border_vertex < is_in_bounds.size()); - if (is_valid[border_vertex]) { - is_in_bounds[border_vertex] = true; - } - } +TerrainMesh transform_mesh(const TerrainMesh &source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs) { + TerrainMesh target_mesh; + target_mesh.positions = srs::transform_points(source_srs, target_srs, source_mesh.positions); + target_mesh.triangles = source_mesh.triangles; + target_mesh.uvs = source_mesh.uvs; + target_mesh.texture = source_mesh.texture; + return target_mesh; +} - assert(border_vertices.size() <= max_border_vertices); - border_vertices.clear(); +TerrainMesh reindex_mesh(const TerrainMesh &mesh) { + std::vector new_positions; + new_positions.reserve(mesh.vertex_count()); + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + const uint32_t invalid_index = static_cast(-1); + std::vector index_map(mesh.positions.size(), invalid_index); + + for (const auto &triangle : mesh.triangles) { + glm::uvec3 new_triangle_indices; + for (size_t i = 0; i < 3; i++) { + const uint32_t old_index = triangle[i]; + if (index_map[old_index] == invalid_index) { + // Vertex newly encountered + const uint32_t new_index = new_positions.size(); + new_positions.push_back(mesh.positions[old_index]); + new_triangle_indices[i] = new_index; + index_map[old_index] = new_index; + } else { + // Vertex already encountered + new_triangle_indices[i] = index_map[old_index]; } } + new_triangles.push_back(new_triangle_indices); } - // Compact the vertex array to exclude all vertices out of bounds. - const unsigned int actual_vertex_count = std::accumulate(is_in_bounds.begin(), is_in_bounds.end(), 0); - // Check if we even have any valid vertices. Can happen if all of the region is padding. - if (actual_vertex_count == 0) { - return tl::unexpected(BuildError::EmptyRegion); - } - // Marks entries that are not present in the new vector (not inside bounds or border) - const unsigned int no_new_index = max_vertex_count + 1; - // Index in old vector mapped to the index in the new one. - std::vector new_vertex_indices; - if (actual_vertex_count != max_vertex_count) { - new_vertex_indices.reserve(max_vertex_count); - - unsigned int write_index = 0; - for (unsigned int read_index = 0; read_index < max_vertex_count; read_index++) { - if (is_in_bounds[read_index]) { - assert(is_valid[read_index]); - new_vertex_indices.push_back(write_index); - source_positions[write_index] = source_positions[read_index]; - write_index += 1; - } else { - new_vertex_indices.push_back(no_new_index); - } + return TerrainMesh(new_triangles, new_positions); +} + +namespace { + struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); } + }; - // Remove out of bounds vertices - source_positions.resize(actual_vertex_count); - } + struct DVec3Equal { + const double epsilon; - // Calculate absolute texture coordinates for every vertex. - LOG_TRACE("Calculating uv coordinates"); - radix::tile::SrsBounds actual_texture_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); - std::vector texture_positions; - texture_positions.reserve(max_vertex_count); - for (unsigned int i = 0; i < actual_vertex_count; i++) { - const glm::dvec3 coords_source = source_positions[i]; - const glm::dvec2 coords_texture_absolute = apply_transform(transform_source_texture.get(), coords_source); - actual_texture_bounds.expand_by(coords_texture_absolute); - texture_positions.push_back(coords_texture_absolute); - } + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } + }; +} - // Normalize texture coordinates - mesh.uvs = std::move(texture_positions); - for (glm::dvec2 &uv : mesh.uvs) { - uv = (uv - actual_texture_bounds.min) / actual_texture_bounds.size(); +TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bounds) { + if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { + return {}; } - assert(mesh.uvs.size() == actual_vertex_count); - // Add triangles - LOG_TRACE("Generating triangles"); - for (unsigned int j = 0; j < raw_tile_data.height() - 1; j++) { - for (unsigned int i = 0; i < raw_tile_data.width() - 1; i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - - std::array quad = { - vertex_index, - vertex_index + 1, - vertex_index + raw_tile_data.width() + 1, - vertex_index + raw_tile_data.width(), - }; - - if (inclusive_bounds) { - // Check if all of the quad is inside the bounds - bool skip_quad = false; - for (const unsigned int vertex_index : quad) { - if (!is_in_bounds[vertex_index]) { - skip_quad = true; + // Calculate epsilon to merge newly created vertices + const double average_edge_length = estimate_average_edge_length(mesh).value(); + const double epsilon = average_edge_length / 1000; + + std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); + + // Construct 6 axis-aligned clipping planes from the bounding box + const std::array, 6> planes = { + radix::geometry::Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left + radix::geometry::Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right + radix::geometry::Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom + radix::geometry::Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top + radix::geometry::Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near + radix::geometry::Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far + }; + + std::vector new_positions = mesh.positions; + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + + // Iterate over each triangle in the mesh + for (const glm::uvec3 &source_triangle : mesh.triangles) { + using Tri = radix::geometry::Triangle<3, double>; + + // Get the positions for the current triangle + const Tri triangle = { + mesh.positions[source_triangle.x], + mesh.positions[source_triangle.y], + mesh.positions[source_triangle.z]}; + + uint16_t inside_count = 0; + for (const auto &vertex : triangle) { + if (bounds.contains_inclusive(vertex)) { + inside_count += 1; + } + } + if (inside_count == 0) { + continue; + } + if (inside_count == source_triangle.length()) { + new_triangles.push_back(source_triangle); + continue; + } + + // Start with the original triangle + // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle + const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); + assert(!clipped_triangles.empty()); + + for (const auto &clipped_triangle : clipped_triangles) { + glm::uvec3 decomposed_triangle; + for (size_t i = 0; i < clipped_triangle.size(); i++) { + const auto &vertex = clipped_triangle[i]; + std::optional vertex_index; + + // Check if this vertex was already in the source triangle + for (size_t j = 0; j < triangle.size(); j++) { + const auto &source_vertex = triangle[j]; + if (vertex == source_vertex) { + vertex_index = source_triangle[j]; break; } } - if (skip_quad) { - continue; - } - // Calculate the index of the given vertex in the reindexed buffer. - if (actual_vertex_count != max_vertex_count) { - for (unsigned int &vertex_index : quad) { - vertex_index = new_vertex_indices[vertex_index]; - assert(vertex_index != no_new_index); + // Check if this vertex was already added + if (!vertex_index.has_value()) { + const auto it = seen_vertices.find(vertex); + if (it != seen_vertices.cend()) { + vertex_index = it->second; } + } - mesh.triangles.emplace_back(quad[0], quad[3], quad[2]); - mesh.triangles.emplace_back(quad[0], quad[2], quad[1]); - } else { - for (unsigned int i = 0; i < 4; i++) { - const unsigned int v0 = quad[i]; - const unsigned int v1 = quad[(i + 1) % 4]; - const unsigned int v2 = quad[(i + 2) % 4]; - - // Check if the indices are valid - if (is_in_bounds[v0] && is_in_bounds[v1] && is_in_bounds[v2]) { - mesh.triangles.emplace_back(new_vertex_indices[v0], new_vertex_indices[v1], new_vertex_indices[v2]); - i++; - } + // Add a new vertex + if (!vertex_index.has_value()) { + vertex_index = new_positions.size(); + new_positions.push_back(vertex); + seen_vertices.emplace(vertex, vertex_index.value()); } + + decomposed_triangle[i] = vertex_index.value(); } + new_triangles.push_back(decomposed_triangle); } } - assert(mesh.triangles.size() <= max_triangle_count); - mesh.positions = std::move(source_positions); - for (glm::dvec3 &position : mesh.positions) { - position = apply_transform(transform_source_mesh.get(), position); + // TODO: derive new_positions from seen_vertices + return reindex_mesh(TerrainMesh(new_triangles, new_positions)); +} + +std::vector generate_uv_space(const std::vector& positions, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds& texture_bounds) { + std::vector uvs = srs::transform_points_to_2d(srs::transformation(mesh_srs, texture_srs).get(), positions); + texture_bounds = radix::tile::SrsBounds(radix::geometry::find_bounds(uvs)); + + for (glm::dvec2 &uv : uvs) { + uv = (uv - texture_bounds.min) / texture_bounds.size(); + } + + return uvs; +} + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + +tl::expected build_reference_mesh_tile( + Dataset &dataset, + const OGRSpatialReference &mesh_srs, + const OGRSpatialReference &tile_srs, const radix::tile::SrsBounds &tile_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds) { + return build_reference_mesh_patch(dataset, mesh_srs, tile_srs, extend_bounds_to_3d(tile_bounds), texture_srs, texture_bounds); +} + +tl::expected build_reference_mesh_patch( + Dataset &dataset, + const OGRSpatialReference &mesh_srs, + const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds) { + const OGRSpatialReference &source_srs = dataset.srs(); + + // Translate tile bounds from tile srs into the source srs, so we know what data to read. + radix::tile::SrsBounds target_bounds_in_source_srs; + if (std::isinf(clip_bounds.min.z) && std::isinf(clip_bounds.max.z)) { + // Make target bounds 2d if the unbounded by height. + target_bounds_in_source_srs = srs::encompassing_bounds_transfer(clip_srs, source_srs, radix::tile::SrsBounds(clip_bounds)); + } else { + target_bounds_in_source_srs = srs::encompassing_bounds_transfer(clip_srs, source_srs, clip_bounds); + } + + // Read height data according to bounds directly from dataset (no interpolation). + RawDatasetReader reader(dataset); + radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(target_bounds_in_source_srs); + add_border_to_aabb(pixel_bounds, Border(1)); + LOG_TRACE("Reading pixels [({}, {})-({}, {})] from dataset", pixel_bounds.min.x, pixel_bounds.min.y, pixel_bounds.max.x, pixel_bounds.max.y); + const std::optional read_result = reader.read_data_in_pixel_bounds(pixel_bounds, true); + if (!read_result.has_value() || read_result->size() == 0) { + return tl::unexpected(BuildError::OutOfBounds); } - assert(mesh.positions.size() == actual_vertex_count); + const raster::HeightMap height_map = read_result.value(); + + LOG_TRACE("Finding valid pixels"); + const raster::Mask valid_mask = raster::transform(height_map, is_valid); + + LOG_TRACE("Transforming pixels to vertices"); + const raster::Raster source_points = raster::transform(height_map, valid_mask, [&](const float height, const raster::Coords& coords) { + return convert_pixel_to_vertex(height, coords, reader, pixel_bounds); + }); - // Sadly all that work above trying to only include vertices that will appear in a triangle - // is not enough for some configurations with non inclusive bounds or when there are invalid vertices. - // Thus we have to filter any loose vertices here. - remove_isolated_vertices(mesh); + LOG_TRACE("Generating triangles"); + const TerrainMesh mesh_in_source_srs = meshify(source_points, valid_mask); + // Check if we even have any valid vertices. Can happen if all of the region is padding. + if (mesh_in_source_srs.vertex_count() == 0 || mesh_in_source_srs.face_count() == 0) { + return tl::unexpected(BuildError::EmptyRegion); + } - // Now validate the final mesh - validate_mesh(mesh); + LOG_TRACE("Clipping mesh based on target bounds"); + const TerrainMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); + TerrainMesh clipped_mesh = mesh_in_clip_srs; // clip_mesh(mesh_in_clip_srs, clip_bounds); + // Check if there are any vertices left + if (clipped_mesh.vertex_count() == 0 || clipped_mesh.face_count() == 0) { + return tl::unexpected(BuildError::EmptyRegion); + } - tile_bounds = actual_tile_bounds; - texture_bounds = actual_texture_bounds; + // TODO: move this to another function? + LOG_TRACE("Generating uv space and calculating required texture bounds"); + clipped_mesh.uvs = generate_uv_space(clipped_mesh.positions, clip_srs, texture_srs, texture_bounds); - return mesh; + LOG_TRACE("Transforming mesh into output srs"); + TerrainMesh target_mesh = transform_mesh(clipped_mesh, clip_srs, mesh_srs); + + remove_isolated_vertices(target_mesh); // TODO: is this still required? + validate_mesh(target_mesh); + return target_mesh; } } // namespace terrainbuilder::mesh diff --git a/src/terrainbuilder/mesh_builder.h b/src/terrainbuilder/mesh_builder.h index 0d1c4b8..feadc3c 100644 --- a/src/terrainbuilder/mesh_builder.h +++ b/src/terrainbuilder/mesh_builder.h @@ -15,15 +15,14 @@ enum class BuildError { OutOfBounds, EmptyRegion }; +std::ostream &operator<<(std::ostream &os, BuildError error); /// Builds a mesh from the given height dataset. -tl::expected build_reference_mesh_tile( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, - const Border &vertex_border, - const bool inclusive_bounds); + const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds); } #endif diff --git a/src/terrainbuilder/octree/id.h b/src/terrainbuilder/octree/id.h new file mode 100644 index 0000000..00c35cc --- /dev/null +++ b/src/terrainbuilder/octree/id.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace octree { + +class Id { +public: + constexpr Id(uint32_t level, glm::uvec3 coords) + : _level(level), _index(interleave3(coords)) {} + constexpr Id(uint32_t level, uint64_t index) + : _level(level), _index(index) {} + + constexpr uint32_t level() const { + return this->_level; + } + constexpr uint64_t index_on_level() const { + return this->_index; + } + constexpr glm::uvec3 coords() const { + return deinterleave3(this->index_on_level()); + } + constexpr uint32_t x() const { + return this->coords().x; + } + constexpr uint32_t y() const { + return this->coords().y; + } + constexpr uint32_t z() const { + return this->coords().z; + } + + constexpr std::optional neighbour(const glm::ivec3& d) const { + const auto new_coords = glm::ivec3(this->coords()) + d; + if (new_coords.x < 0 || new_coords.y < 0 || new_coords.z < 0) { + // throw std::out_of_range("Neighbour coordinates cannot be negative"); + return std::nullopt; + } + return Id(this->level(), glm::uvec3(new_coords)); + } + + constexpr std::vector neighbours() const { + std::vector result; + result.reserve(26); + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + for (int dz = -1; dz <= 1; dz++) { + if (dx == 0 && dy == 0 && dz == 0) { + continue; // Skip the center itself + } + + const glm::ivec3 offset(dx, dy, dz); + const auto neighbour = this->neighbour({dx, dy, dz}); + if (!neighbour.has_value()) { + continue; + } + result.push_back(neighbour.value()); + } + } + } + return result; + } + + constexpr std::optional parent() const { + if (this->level() == 0) { + return std::nullopt; + } + + const auto parent_coords = this->coords() / glm::uvec3(2); + return Id(this->level() - 1, parent_coords); + } + + constexpr Id child(uint32_t child_index) const { + if (child_index > 7) { + throw std::invalid_argument("Invalid child index (must be 0-7)"); + } + return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); + } + + constexpr std::array children() const { + return { + this->child(0), this->child(1), this->child(2), this->child(3), + this->child(4), this->child(5), this->child(6), this->child(7) + }; + } + + static constexpr Id root() { + return Id(0, 0); + } + + bool operator==(const Id &other) const { + return this->_level == other._level && this->_index == other._index; + } + +private: + uint32_t _level; + uint64_t _index; + + static constexpr uint64_t interleave3(const glm::uvec3 &coords) { + const uint64_t x = coords.x; + const uint64_t y = coords.y; + const uint64_t z = coords.z; + + uint64_t result = 0; + for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + result |= ((x >> i) & 1) << (3 * i); + result |= ((y >> i) & 1) << (3 * i + 1); + result |= ((z >> i) & 1) << (3 * i + 2); + } + return result; + } + + static constexpr glm::uvec3 deinterleave3(uint64_t index) { + uint32_t x = 0; + uint32_t y = 0; + uint32_t z = 0; + for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + x |= ((index >> (3 * i)) & 1) << i; + y |= ((index >> (3 * i + 1)) & 1) << i; + z |= ((index >> (3 * i + 2)) & 1) << i; + } + return {x, y, z}; + } +}; + +} // namespace octree + +template <> +struct fmt::formatter { + // Parses format specifications; here we ignore them. + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + // Format the Id object. + template + auto format(const octree::Id &id, FormatContext &ctx) { + return fmt::format_to( + ctx.out(), + "Id(level={}, coords=({}, {}, {}), index={})", + id.level(), id.x(), id.y(), id.z(), id.index_on_level()); + } +}; +#include +#include +namespace octree{ +inline std::string to_string(const octree::Id &id) { + return fmt::format("{}", id); +} +inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { + fmt::print(os, "{}", id); + return os; +} +} diff --git a/src/terrainbuilder/octree/space.h b/src/terrainbuilder/octree/space.h new file mode 100644 index 0000000..d1ae7d2 --- /dev/null +++ b/src/terrainbuilder/octree/space.h @@ -0,0 +1,120 @@ +#pragma once + +#include + +#include "id.h" + +namespace octree { +using Bounds = radix::geometry::Aabb3d; + +class Space { +public: + const Bounds bounds; + + static constexpr Space earth() { + const float max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) + const float extends = max_radius * 1.1; // TODO: how much padding do we want here + return Space(Bounds( + {-extends, -extends, -extends}, {extends, extends, extends})); + } + + std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { + // We don't want to recurse indefinitely if the bounds are empty. + const glm::dvec3 target_size = target_bounds.size(); + if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { + throw std::invalid_argument("target bounds cannot be empty"); + } + + const std::array corners = radix::geometry::corners(target_bounds); + + const Bounds root_bounds = get_node_bounds(root); + // Check if all points of the target bounds are inside the root bounds. + bool all_corners_inside_root = true; + for (const auto &corner : corners) { + if (!root_bounds.contains_inclusive(corner)) { + all_corners_inside_root = false; + break; + } + } + + if (!all_corners_inside_root) { + return std::nullopt; // Target bounds are outside the defined space. + } + + Id current_smallest_encompassing_node = root; + while (true) { + const std::array children = current_smallest_encompassing_node.children(); + std::optional next_smallest; + + for (const auto &child : children) { + const Bounds child_bounds = get_node_bounds(child); + bool all_corners_inside_child = true; + for (const auto &corner : corners) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside_child = false; + break; + } + } + + if (all_corners_inside_child) { + next_smallest = child; + break; // Found a child that fully contains the bounds, go deeper. + } + } + + if (next_smallest.has_value()) { + current_smallest_encompassing_node = next_smallest.value(); + } else { + break; // No child fully contains the bounds, so the current node is the smallest. + } + } + + return current_smallest_encompassing_node; + } + + std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { + Id current = root; + const Bounds root_bounds = this->get_node_bounds(current); + if (!root_bounds.contains_exclusive(point)) { + return std::nullopt; + } + + while (current.level() < target_level) { + for (const auto& child : current.children()) { + const Bounds child_bounds = this->get_node_bounds(child); + if (child_bounds.contains_exclusive(point)) { + current = child; + break; + } + } + } + + return current; + } + + Bounds get_node_bounds(const Id &id) const { + const auto coords = id.coords(); + const uint32_t level = id.level(); + const uint32_t resolution = 1 << level; + + // Calculate the size of a node at this level + const glm::dvec3 bounds_size = bounds.size(); + const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); + + // Calculate the minimum point of the node + const glm::dvec3 min_bound = bounds.min; + const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; + + // Calculate the maximum point of the node + const glm::dvec3 node_max = node_min + node_size; + + Bounds node_bounds; + node_bounds.min = node_min; + node_bounds.max = node_max; + return node_bounds; + } + +private: +}; + +} // namespace octree diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainbuilder/octree/storage.h new file mode 100644 index 0000000..bb8831b --- /dev/null +++ b/src/terrainbuilder/octree/storage.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include + +#include "id.h" +#include "mesh/io.h" +#include "mesh/terrain_mesh.h" + +namespace octree { +using Node = TerrainMesh; + +class Storage { + public: + Storage(const std::filesystem::path &basePath) : base_path(basePath) {} + + std::optional load_node(const Id &id) const { + const auto node_path = this->get_node_path(id); + const auto result = io::load_mesh_from_path(node_path); + if (result.has_value()) { + return result.value(); + } else { + return std::nullopt; + } + } + + bool save_node(const Id &id, const Node &node) const { + const auto node_path = this->get_node_path(id); + const auto result = io::save_mesh_to_path(node_path, node); + return result.has_value(); + } + + bool has_node(const Id &id) const { + return std::filesystem::exists(this->get_node_path(id)); + } + + private: + std::filesystem::path get_node_path(const Id &id) const { + return base_path / std::to_string(id.level()) / std::to_string(id.x()) / (std::to_string(id.y()) + ".gltf"); + } + + private: + const std::filesystem::path base_path; +}; +} diff --git a/src/terrainbuilder/octree/utils.cpp b/src/terrainbuilder/octree/utils.cpp new file mode 100644 index 0000000..2916c30 --- /dev/null +++ b/src/terrainbuilder/octree/utils.cpp @@ -0,0 +1,2 @@ +#include "utils.h" + diff --git a/src/terrainbuilder/octree/utils.h b/src/terrainbuilder/octree/utils.h new file mode 100644 index 0000000..6eb734b --- /dev/null +++ b/src/terrainbuilder/octree/utils.h @@ -0,0 +1,10 @@ +#pragma once + +#include "id.h" + +#include +#include + +namespace octree { + +} // namespace octree diff --git a/src/terrainbuilder/raster.h b/src/terrainbuilder/raster.h new file mode 100644 index 0000000..3a53587 --- /dev/null +++ b/src/terrainbuilder/raster.h @@ -0,0 +1,144 @@ +#pragma once + +#include +#include +#include +#include + +namespace raster { + +using Index = size_t; +using Coords = glm::vec<2, size_t>; + +template +class Raster { +public: + Raster() = default; + Raster(Index width, Index height) + : _width(width), _height(height), _data(width * height) { + } + + [[nodiscard]] Index width() const { + return this->_width; + } + [[nodiscard]] Index height() const { + return this->_height; + } + [[nodiscard]] decltype(auto) pixel(const Coords &coords) { + assert(coords.x < this->_width); + assert(coords.y < this->_height); + const Index pixel_index = this->index(coords); + if constexpr (std::is_same_v) { + return static_cast(this->_data[pixel_index]); + } else { + return static_cast(this->_data[pixel_index]); + } + } + [[nodiscard]] decltype(auto) pixel(const Coords &coords) const { + assert(coords.x < this->_width); + assert(coords.y < this->_height); + const Index pixel_index = this->index(coords); + if constexpr (std::is_same_v) { + return static_cast(this->_data[pixel_index]); + } else { + return static_cast(this->_data[pixel_index]); + } + } + + [[nodiscard]] Index index(const Coords& coords) const { + return coords.y * this->_width + coords.x; + } + + [[nodiscard]] T *data() { + return this->_data.data(); + } + [[nodiscard]] const T *data() const { + return this->_data.data(); + } + + [[nodiscard]] Index size() const { + return this->_data.size(); + } + [[nodiscard]] auto begin() { + return this->_data.begin(); + } + [[nodiscard]] auto end() { + return this->_data.end(); + } + [[nodiscard]] auto begin() const { + return this->_data.begin(); + } + [[nodiscard]] auto end() const { + return this->_data.end(); + } + +private: + unsigned _width = 0; + unsigned _height = 0; + std::vector _data; +}; + +using Mask = Raster; +using HeightMap = Raster; + +template +concept TransformFn = requires(F f, In in) { + { f(in) }; +}; + +template +concept TransformFnWithCoords = requires(F f, In in, Coords coord) { + { f(in, coord) }; +}; + +template F> +[[nodiscard]] auto transform(const Raster &input, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)))); + Raster output(input.width(), input.height()); + std::transform(input.begin(), input.end(), output.begin(), std::forward(f)); + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0), Coords(0, 0)))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + output.pixel(coords) = std::forward(f)(input.pixel(coords), coords); + } + } + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, const Mask &mask, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + if (mask.pixel(coords)) { + output.pixel(coords) = std::forward(f)(input.pixel(coords)); + } + } + } + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, const Mask &mask, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)), Coords(0, 0))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + if (mask.pixel(coords)) { + output.pixel(coords) = std::forward(f)(input.pixel(coords), coords); + } + } + } + return output; +} +} \ No newline at end of file diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/terrainbuilder/raw_dataset_reader.h index e2afbf6..49026db 100644 --- a/src/terrainbuilder/raw_dataset_reader.h +++ b/src/terrainbuilder/raw_dataset_reader.h @@ -8,6 +8,7 @@ #include #include "log.h" +#include "raster.h" namespace terrainbuilder { @@ -39,7 +40,8 @@ class RawDatasetReader { return glm::uvec2(heights_band->GetXSize(), heights_band->GetYSize()); } - std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { + // TODO: support reading other data types + std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { if (clamp_bounds) { const glm::ivec2 max_in_bounds = glm::ivec2(this->dataset_size()) - glm::ivec2(1); bounds.min = glm::clamp(bounds.min, glm::ivec2(0), max_in_bounds); @@ -55,7 +57,7 @@ class RawDatasetReader { GDALRasterBand *heights_band = this->dataset->GetRasterBand(1); // non-owning pointer // Initialize the HeightData for reading - HeightData height_data(bounds.width(), bounds.height()); + raster::HeightMap height_data(bounds.width(), bounds.height()); if (bounds.width() == 0 || bounds.height() == 0) { if (clamp_bounds) { LOG_WARN("Target dataset bounds are empty (clamped)"); @@ -79,7 +81,7 @@ class RawDatasetReader { return height_data; } - std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { + std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { // Transform the SrsBounds to pixel space const radix::geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index e30cdd8..203e54c 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -14,9 +14,11 @@ #include "mesh/io.h" #include "mesh/terrain_mesh.h" #include "mesh_builder.h" +#include "terrainbuilder.h" #include "texture_assembler.h" #include "tile_provider.h" -#include "terrainbuilder.h" + +#include "octree/space.h" namespace terrainbuilder { @@ -43,57 +45,45 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { void build( Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, - const OGRSpatialReference &texture_srs, - const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path) { const ctb::Grid grid = ctb::GlobalMercator(); - - radix::tile::SrsBounds target_tile_bounds(tile_bounds); radix::tile::SrsBounds texture_bounds; std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); LOG_INFO("Building mesh..."); - tl::expected mesh_result = mesh::build_reference_mesh_tile( + tl::expected mesh_result = mesh::build_reference_mesh_patch( dataset, mesh_srs, - tile_srs, target_tile_bounds, - texture_srs, texture_bounds, - Border(0, 1, 1, 0), - true); + target_bounds_srs, target_bounds, + texture_srs, texture_bounds); if (!mesh_result.has_value()) { const mesh::BuildError error = mesh_result.error(); if (error == mesh::BuildError::OutOfBounds) { const radix::tile::SrsBounds dataset_bounds = dataset.bounds(); - const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_ERROR("Target bounds are fully outside of dataset region\n" "Dataset {{\n" - "\tBounds {{x={}, y={}, w={}, h={}}}.\n" - "\tLargest Contained Tile {{zoom={}, x={}, y={}}}.\n" - "\tSmallest Encompassing Tile {{zoom={}, x={}, y={}}}.\n" + "\t x={}, y={}, w={}, h={}.\n" "}}\n" "Target {{\n" - "\tBounds {{x={}, y={}, w={}, h={}}}.\n" - "\tLargest Contained Tile {{zoom={}, x={}, y={}}}.\n" - "\tSmallest Encompassing Tile {{zoom={}, x={}, y={}}}.\n" + "\t x={}, y={}, w={}, h={}.\n" "}}", dataset_bounds.min.x, dataset_bounds.min.y, dataset_bounds.width(), dataset_bounds.height(), - dataset_largest_tile.zoom_level, dataset_largest_tile.coords.x, dataset_largest_tile.coords.y, - dataset_encompassing_tile.zoom_level, dataset_encompassing_tile.coords.x, dataset_encompassing_tile.coords.y, - tile_bounds.min.x, tile_bounds.min.y, tile_bounds.width(), tile_bounds.height(), - target_largest_tile.zoom_level, target_largest_tile.coords.x, target_largest_tile.coords.y, - target_encompassing_tile.zoom_level, target_encompassing_tile.coords.x, target_encompassing_tile.coords.y); + target_bounds.min.x, target_bounds.min.y, target_bounds.size().x, target_bounds.size().y); + exit(1); } else if (error == mesh::BuildError::EmptyRegion) { - LOG_ERROR("Target bounds are inside dataset, but the region is empty (only made up of padding)"); + LOG_WARN("Target bounds are inside dataset, but the region is empty"); + exit(0); } - - exit(1); } TerrainMesh mesh = mesh_result.value(); LOG_DEBUG("Mesh building took {}s", format_secs_since(start)); @@ -105,7 +95,7 @@ void build( BasemapSchemeTilePathProvider tile_provider(texture_base_path.value()); std::optional texture = texture::assemble_texture_from_tiles(grid, texture_srs, texture_bounds, tile_provider); if (!texture.has_value()) { - LOG_ERROR("Failed to assemble tile texture"); + LOG_ERROR("Failed to assemble texture"); exit(1); } mesh.texture = texture; @@ -120,6 +110,8 @@ void build( start = std::chrono::high_resolution_clock::now(); // TODO: use a JSON libary instead std::unordered_map metadata; + // TODO: redo + /*/ metadata["mesh_srs"] = mesh_srs.GetAuthorityCode(nullptr); metadata["bounds_srs"] = tile_srs.GetAuthorityCode(nullptr); metadata["texture_srs"] = texture_srs.GetAuthorityCode(nullptr); @@ -129,6 +121,7 @@ void build( metadata["texture_bounds"] = fmt::format( "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); + */ if (!io::save_mesh_to_path(output_path, mesh, io::SaveOptions{.metadata = metadata}).has_value()) { LOG_ERROR("Failed to save mesh to file {}", output_path.string()); exit(2); diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index 0254f10..e77a58d 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -12,11 +12,11 @@ namespace terrainbuilder { void build( Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, - const OGRSpatialReference &texture_srs, - const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path); } diff --git a/src/terrainbuilder/texture_assembler.h b/src/terrainbuilder/texture_assembler.h index 06a09e6..253231f 100644 --- a/src/terrainbuilder/texture_assembler.h +++ b/src/terrainbuilder/texture_assembler.h @@ -282,7 +282,7 @@ std::optional try_get_tile_path(const radix::tile::Id til } // Start by transforming the input bounds into the srs the tiles are in. - const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounding_box_transfer(target_srs, grid.getSRS(), target_bounds); + const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounds_transfer(target_srs, grid.getSRS(), target_bounds); // Then we find the smallest tile (id) that encompasses these bounds. const radix::tile::Id smallest_encompassing_tile = grid.findSmallestEncompassingTile(encompassing_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_TRACE("Smallest encompassing tile for texture bounds is [{}, ({}, {})]", diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index d87daea..512a41c 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -190,12 +190,12 @@ double Dataset::gridResolution(const OGRSpatialReference& target_srs) const double Dataset::pixelWidthIn(const OGRSpatialReference& target_srs) const { const auto b0 = bounds(); - const auto b1 = srs::nonExactBoundsTransform(b0, srs(), target_srs); + const auto b1 = srs::non_exact_bounds_transform(b0, srs(), target_srs); return b1.width() / widthInPixels(); } double Dataset::pixelHeightIn(const OGRSpatialReference& target_srs) const { - const auto b = srs::nonExactBoundsTransform(bounds(), srs(), target_srs); + const auto b = srs::non_exact_bounds_transform(bounds(), srs(), target_srs); return b.height() / heightInPixels(); } diff --git a/src/terrainlib/mesh/terrain_mesh.cpp b/src/terrainlib/mesh/terrain_mesh.cpp index e3d7fc4..f71ea7b 100644 --- a/src/terrainlib/mesh/terrain_mesh.cpp +++ b/src/terrainlib/mesh/terrain_mesh.cpp @@ -1,3 +1,4 @@ +#include #include #include "terrain_mesh.h" @@ -27,6 +28,42 @@ radix::geometry::Aabb<3, double> calculate_bounds(std::span m return bounds; } +std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size) { + const auto &triangles = mesh.triangles; + if (triangles.empty()) { + return std::nullopt; + } + + // Random sampling setup + std::vector sampled_triangles; + sampled_triangles.reserve(std::min(sample_size, triangles.size())); + + std::random_device rd; + std::mt19937 rng(rd()); + std::sample(triangles.begin(), triangles.end(), + std::back_inserter(sampled_triangles), + std::min(sample_size, triangles.size()), + rng); + + double total_length = 0.0; + size_t edge_count = 0; + + for (const auto &tri : sampled_triangles) { + const glm::dvec3 &a = mesh.positions[tri.x]; + const glm::dvec3 &b = mesh.positions[tri.y]; + const glm::dvec3 &c = mesh.positions[tri.z]; + + total_length += glm::distance(a, b); + total_length += glm::distance(b, c); + total_length += glm::distance(c, a); + + edge_count += 3; + } + + assert(edge_count > 0); + return total_length / edge_count; +} + std::vector find_isolated_vertices(const TerrainMesh& mesh) { std::vector connected; connected.resize(mesh.vertex_count()); diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index 6d9b76a..627196f 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -21,8 +21,10 @@ class TerrainMesh { using Texture = cv::Mat; using serialize = zpp::bits::members<4>; - TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs) : - TerrainMesh(triangles, positions, uvs, std::nullopt) {} + TerrainMesh(std::vector triangles, std::vector positions) + : TerrainMesh(triangles, positions, {}) {} + TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs) + : TerrainMesh(triangles, positions, uvs, std::nullopt) {} TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) : TerrainMesh(triangles, positions, uvs, std::optional(std::move(texture))) {} TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) @@ -56,6 +58,8 @@ class TerrainMesh { radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes); +std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size = 1000); + std::vector find_isolated_vertices(const TerrainMesh& mesh); size_t remove_isolated_vertices(TerrainMesh& mesh); size_t remove_triangles_of_negligible_size(TerrainMesh& mesh, const double threshold_percentage_of_average = 0.001); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index bf413b3..ea6c608 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -34,113 +34,301 @@ namespace srs { -inline std::unique_ptr transformation(const OGRSpatialReference& source, const OGRSpatialReference& targetSrs) -{ - const auto data_srs = source; - auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&data_srs, &targetSrs)); - if (!transformer) +inline std::unique_ptr transformation(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs) { + auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&source_srs, &target_srs)); + if (!transformer) { throw Exception("Couldn't create SRS transformation"); + } return transformer; } -// this transform is non exact, because we are only transforming the corner vertices. however, due to projection warping, a rectangle can become an trapezoid with curved edges. -inline radix::tile::SrsBounds nonExactBoundsTransform(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { - const auto transform = transformation(sourceSrs, targetSrs); - std::array xes = { bounds.min.x, bounds.max.x }; - std::array yes = { bounds.min.y, bounds.max.y }; - if (!transform->Transform(2, xes.data(), yes.data())) - throw Exception("nonExactBoundsTransform failed"); - return { {xes[0], yes[0]}, {xes[1], yes[1]} }; +template +inline glm::tvec2 transform_point(OGRCoordinateTransformation *transform, glm::tvec2 p) { + if (!transform->Transform(1, &p.x, &p.y)) + throw Exception("srs::transform_point(glm::tvec2) failed"); + return p; } - template -inline glm::tvec3 to(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs, glm::tvec3 p) -{ - const auto transform = transformation(source_srs, target_srs); +inline glm::tvec3 transform_point(OGRCoordinateTransformation *transform, glm::tvec3 p) { if (!transform->Transform(1, &p.x, &p.y, &p.z)) - throw Exception("srs::to(glm::tvec3) failed"); + throw Exception("srs::transform_point(glm::tvec3) failed"); return p; } template -inline glm::tvec2 to(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, glm::tvec2 p) { +inline glm::tvec2 transform_point(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, glm::tvec2 p) { const auto transform = transformation(source_srs, target_srs); - if (!transform->Transform(1, &p.x, &p.y)) - throw Exception("srs::to(glm::tvec2) failed"); - return p; + return transform_point(transform.get(), p); } - template -inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) -{ - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - return to(source_srs, ecef_srs, p); +inline glm::tvec3 transform_point(const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs, glm::tvec3 p){ + const auto transform = transformation(source_srs, target_srs); + return transform_point(transform.get(), p); } +template +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { + std::array xs; + std::array ys; + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data())) { + throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + } + + for (size_t i = 0; i < points.size(); ++i) { + points[i] = {xs[i], ys[i]}; + } +} template -inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) -{ - std::vector xes; +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { + std::vector xs; std::vector ys; - std::vector zs; - xes.reserve(points.size()); - ys.reserve(points.size()); - zs.reserve(points.size()); - for (const auto& p : points) { - xes.push_back(p.x); - ys.push_back(p.y); - zs.push_back(p.z); + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; } - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto transform = transformation(source_srs, ecef_srs); - if (!transform->Transform(int(points.size()), xes.data(), ys.data(), zs.data())) - throw Exception("toECEF(glm::tvec3) failed"); + if (!transform->Transform(points.size(), xs.data(), ys.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } for (size_t i = 0; i < points.size(); ++i) { - points[i] = { xes[i], ys[i], zs[i] }; + points[i] = {xs[i], ys[i]}; } - return points; } template -inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) -{ - std::array xes; +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { + std::array xs; std::array ys; std::array zs; + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + zs[i] = points[i].z; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + } + for (size_t i = 0; i < points.size(); ++i) { - xes[i] = points[i].x; + points[i] = {xs[i], ys[i], zs[i]}; + } +} +template +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { + std::vector xs; + std::vector ys; + std::vector zs; + + xs.resize(points.size()); + ys.resize(points.size()); + zs.resize(points.size()); + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; ys[i] = points[i].y; zs[i] = points[i].z; } - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto transform = transformation(source_srs, ecef_srs); - if (!transform->Transform(points.size(), xes.data(), ys.data(), zs.data())) - throw Exception("toECEF(glm::tvec3) failed"); + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } for (size_t i = 0; i < points.size(); ++i) { - points[i] = { xes[i], ys[i], zs[i] }; + points[i] = {xs[i], ys[i], zs[i]}; } +} + +template +inline Container transform_points(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, Container points) { + const auto transform = transformation(source_srs, target_srs); + transform_points_inplace(transform.get(), points); return points; } + +// TODO: somehow integrate into a single transform_points +template +inline std::vector> transform_points_to_2d(OGRCoordinateTransformation *transform, const std::vector> &points) { + std::vector xs; + std::vector ys; + std::vector zs; + + xs.resize(points.size()); + ys.resize(points.size()); + zs.resize(points.size()); + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + zs[i] = points[i].z; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } + + std::vector> transformed; + transformed.resize(points.size()); + for (size_t i = 0; i < points.size(); ++i) { + transformed[i] = {xs[i], ys[i]}; + } + + return transformed; +} + +inline radix::tile::SrsBounds non_exact_bounds_transform(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { + const auto transform = transformation(sourceSrs, targetSrs); + std::array xs = {bounds.min.x, bounds.max.x}; + std::array ys = {bounds.min.y, bounds.max.y}; + if (!transform->Transform(2, xs.data(), ys.data())) { + throw Exception("srs::non_exact_bounds_transform failed"); + } + return {{xs[0], ys[0]}, {xs[1], ys[1]}}; +} + +inline radix::geometry::Aabb3d non_exact_bounds_transform(const radix::geometry::Aabb3d &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { + const auto transform = transformation(sourceSrs, targetSrs); + std::array xs = {bounds.min.x, bounds.max.x}; + std::array ys = {bounds.min.y, bounds.max.y}; + std::array zs = {bounds.min.z, bounds.max.z}; + if (!transform->Transform(2, xs.data(), ys.data(), zs.data())) { + throw Exception("srs::non_exact_bounds_transform failed"); + } + return {{xs[0], ys[0], zs[0]}, {xs[1], ys[1], zs[1]}}; +} + +/// Transforms bounds from one srs to another, +/// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. +/// But there can be points inside the new bounds that were not present in the original ones. +inline radix::tile::SrsBounds encompassing_bounds_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); + radix::tile::SrsBounds target_bounds; + const int result = transformation->TransformBounds( + source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, + &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, + 21); + if (result != TRUE) { + throw std::runtime_error("srs::encompassing_bounding_box_transfer failed"); + } + return target_bounds; +} + +inline radix::geometry::Aabb3d encompassing_bounds_transfer( + const OGRSpatialReference &source_srs, + const OGRSpatialReference &target_srs, + const radix::geometry::Aabb3d &source_bounds, + const uint32_t intermediate_points_edges = 21, + const uint32_t intermediate_points_faces = 5) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + std::vector points; + + // Add corner points + const auto corners = radix::geometry::corners(source_bounds); + std::copy(corners.begin(), corners.end(), std::back_inserter(points)); + + // Sample points on the edges + const auto edges = radix::geometry::edges(source_bounds); + for (const auto &edge : edges) { + const auto &[p0, p1] = edge; + + for (uint32_t i = 1; i <= intermediate_points_edges; i++) { + const double t = static_cast(i) / (intermediate_points_edges + 1); + const auto p = glm::mix(p0, p1, t); + points.push_back(p); + } + } + + // TODO: do we need this? + // Sample points on the faces + const auto quads = radix::geometry::quads(source_bounds); + for (const auto &quad : quads) { + const auto &[p0, p1, p2, p3] = quad; + + for (uint32_t i = 1; i <= intermediate_points_faces; i++) { + const double u = static_cast(i) / (intermediate_points_faces + 1); + const auto edge_p0 = glm::mix(p0, p1, u); + const auto edge_p1 = glm::mix(p3, p2, u); + + for (uint32_t j = 1; j <= intermediate_points_faces; j++) { + const double v = static_cast(j) / (intermediate_points_faces + 1); + const auto point = glm::mix(edge_p0, edge_p1, v); + points.push_back(point); + } + } + } + + // Transform all collected points + const auto transform = srs::transformation(source_srs, target_srs); + transform_points_inplace(transform.get(), points); + + // Compute bounds from transformed points + radix::geometry::Aabb3d target_bounds; + target_bounds.min = glm::dvec3(std::numeric_limits::max()); + target_bounds.max = glm::dvec3(std::numeric_limits::min()); + for (const auto &point : points) { + target_bounds.expand_by(point); + } + + return target_bounds; +} + +inline OGRSpatialReference from_epsg(uint32_t epsg) { + OGRSpatialReference srs; + srs.importFromEPSG(epsg); + srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + return srs; +} +inline OGRSpatialReference ecef() { + return from_epsg(4978); +} +inline OGRSpatialReference webmercator() { + return from_epsg(3857); +} +inline OGRSpatialReference wgs84() { + return from_epsg(4326); +} +inline OGRSpatialReference mgi() { + return from_epsg(4312); +} + +// only for tntn +template +inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) { + return transform_point(source_srs, ecef(), p); +} + +template +inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) { + return transform_points(source_srs, ecef(), points); +} + +template +inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) { + return transform_points(source_srs, ecef(), points); +} + template -inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) -{ +inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) { return toECEF(source_srs, { p1, p2 }); } -inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BBox3D& box) -{ +inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BBox3D& box) { constexpr auto n_samples = 100; std::vector points; points.emplace_back(box.min.x, box.min.y, box.min.z); @@ -172,25 +360,6 @@ inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BB return resulting_bbox; } -/// Transforms bounds from one srs to another, -/// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. -/// But there can be points inside the new bounds that were not present in the original ones. -inline radix::tile::SrsBounds encompassing_bounding_box_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { - if (source_srs.IsSame(&target_srs)) { - return source_bounds; - } - - const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); - radix::tile::SrsBounds target_bounds; - const int result = transformation->TransformBounds( - source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, - &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, - 21); - if (result != TRUE) { - throw std::runtime_error("encompassing_bounding_box_transfer failed"); - } - return target_bounds; -} } #endif // SRS_H diff --git a/src/terrainmerger/merge.cpp b/src/terrainmerger/merge.cpp index 9400ba1..ccf945e 100644 --- a/src/terrainmerger/merge.cpp +++ b/src/terrainmerger/merge.cpp @@ -167,15 +167,15 @@ class Grid3d { std::vector grid_data; }; -static geometry::Aabb<3, double> pad_bounds(const geometry::Aabb<3, double> &bounds, const double percentage) { +static radix::geometry::Aabb<3, double> pad_bounds(const radix::geometry::Aabb<3, double> &bounds, const double percentage) { const glm::dvec3 bounds_padding = bounds.size() * percentage; - const geometry::Aabb<3, double> padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + const radix::geometry::Aabb<3, double> padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); return padded_bounds; } template -static Grid3d _construct_grid_for_meshes(const geometry::Aabb<3, double> &bounds, const size_t vertex_count) { - const geometry::Aabb<3, double> padded_bounds = pad_bounds(bounds, 0.01); +static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb<3, double> &bounds, const size_t vertex_count) { + const radix::geometry::Aabb<3, double> padded_bounds = pad_bounds(bounds, 0.01); const double max_extends = max_component(padded_bounds.size()); const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; @@ -187,14 +187,14 @@ static Grid3d _construct_grid_for_meshes(const geometry::Aabb<3, double> &bou template static Grid3d construct_grid_for_mesh(const TerrainMesh &mesh) { - const geometry::Aabb<3, double> bounds = calculate_bounds(mesh); + const radix::geometry::Aabb<3, double> bounds = calculate_bounds(mesh); const size_t vertex_count = mesh.vertex_count(); return _construct_grid_for_meshes(bounds, vertex_count); } template static Grid3d construct_grid_for_meshes(const std::span meshes) { - const geometry::Aabb<3, double> bounds = calculate_bounds(meshes); + const radix::geometry::Aabb<3, double> bounds = calculate_bounds(meshes); const size_t maximal_merged_mesh_size = std::transform_reduce( meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const TerrainMesh &mesh) { return mesh.vertex_count(); }); return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); @@ -480,7 +480,7 @@ static bool are_all_bounds_connected(const std::span meshes) return true; } - std::vector> mesh_bounds; + std::vector> mesh_bounds; mesh_bounds.reserve(meshes.size()); std::transform(meshes.begin(), meshes.end(), std::back_inserter(mesh_bounds), @@ -492,7 +492,7 @@ static bool are_all_bounds_connected(const std::span meshes) continue; } - if (geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { + if (radix::geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { intersect_any_other = true; break; } diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index 6267d2f..65efe05 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -117,8 +117,8 @@ static double measure_max_absolute_error(const SurfaceMesh &original, const Surf return error + bound_on_error; } -static geometry::Aabb<3, double> calculate_bounds(const SurfaceMesh &mesh) { - geometry::Aabb<3, double> bounds; +static radix::geometry::Aabb<3, double> calculate_bounds(const SurfaceMesh &mesh) { + radix::geometry::Aabb<3, double> bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); @@ -190,26 +190,6 @@ static std::pair check_condition(const StopCondition &stop_conditi stop_condition); } -static double get_condition_target(const StopCondition &stop_condition) { - return std::visit(overloaded{ - [&](const VertexRatio &vertex_ratio) { - return vertex_ratio.ratio; - }, - [&](const EdgeRatio &edge_ratio) { - return edge_ratio.ratio; - }, - [&](const FaceRatio &face_ratio) { - return face_ratio.ratio; - }, - [&](const RelativeError &relative_error) { - return relative_error.error_bound; - }, - [&](const AbsoluteError &absolute_error) { - return absolute_error.error_bound; - }}, - stop_condition); -} - static bool is_evaluation_expensive(const StopCondition &stop_condition) { return std::visit(overloaded{ [&](const VertexRatio &) { diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 7f30e8d..2af3f18 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -10,7 +10,7 @@ include(FetchContent) FetchContent_Declare(catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.3.2 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Catch2 + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Catch2 ) FetchContent_MakeAvailable(catch2) @@ -68,21 +68,28 @@ if (ATB_UNITTESTS_DEBUG_IMAGES) else() target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_DEBUG_IMAGES=false") endif() -target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2) +target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2WithMain) add_executable(unittests_terrainmerger catch2_helpers.h terrainmerger/convert.cpp - terrainmerger/merge.cpp) + terrainmerger/merge.cpp +) -target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2::Catch2) +target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2WithMain) add_executable(unittests_terrainbuilder catch2_helpers.h - terrainbuilder/mesh_io.cpp - terrainbuilder/mesh.cpp - terrainbuilder/texture.cpp) -target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2::Catch2 CGAL::CGAL) + terrainbuilder/octree_id.cpp + terrainbuilder/octree_space.cpp + terrainbuilder/mesh2.cpp + # TODO: + # terrainbuilder/mesh_io.cpp + # terrainbuilder/mesh.cpp + # terrainbuilder/texture.cpp +) + +target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain CGAL::CGAL) target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") diff --git a/unittests/catch2_helpers.h b/unittests/catch2_helpers.h index a91b69a..a577a07 100644 --- a/unittests/catch2_helpers.h +++ b/unittests/catch2_helpers.h @@ -20,7 +20,8 @@ #ifndef CATCH2_HELPERS_H #define CATCH2_HELPERS_H -#include +#include +#include #include diff --git a/unittests/terrainbuilder/mesh.cpp b/unittests/terrainbuilder/mesh.cpp index 57c11ee..296091f 100644 --- a/unittests/terrainbuilder/mesh.cpp +++ b/unittests/terrainbuilder/mesh.cpp @@ -112,23 +112,25 @@ void check_non_empty(const TerrainMesh &mesh) { } TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { - const std::vector> tile_test_cases = { - {"tiny tile", "/austria/pizbuin_1m_epsg4326.tif", tile::Id(23, glm::uvec2(4430412, 2955980), tile::Scheme::SlippyMap)}, - {"small tile", "/austria/pizbuin_1m_epsg3857.tif", tile::Id(20, glm::uvec2(553801, 369497), tile::Scheme::SlippyMap)}, - {"tile on the border", "/austria/pizbuin_1m_mgi.tif", tile::Id(18, glm::uvec2(138457, 169781), tile::Scheme::Tms)} + const std::vector> tile_test_cases = { + {"tiny tile", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::Id(23, glm::uvec2(4430412, 2955980), radix::tile::Scheme::SlippyMap)}, + {"small tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap)}, + {"tile on the border", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(18, glm::uvec2(138457, 169781), radix::tile::Scheme::Tms)} #if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED - {"tile slightly larger than dataset", "/austria/pizbuin_1m_mgi.tif", tile::Id(11, glm::uvec2(1081, 721), tile::Scheme::SlippyMap)}, - {"huge tile", "/austria/pizbuin_1m_epsg3857.tif", tile::Id(6, glm::uvec2(33, 41), tile::Scheme::Tms)}, - {"giant tile", "/austria/at_mgi.tif", tile::Id(1, glm::uvec2(1, 0), tile::Scheme::SlippyMap)}, + {"tile slightly larger than dataset", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(11, glm::uvec2(1081, 721), radix::tile::Scheme::SlippyMap)}, + {"huge tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(6, glm::uvec2(33, 41), radix::tile::Scheme::Tms)}, + {"giant tile", "/austria/at_mgi.tif", radix::tile::Id(1, glm::uvec2(1, 0), radix::tile::Scheme::SlippyMap)}, #endif }; + + const ctb::Grid grid = ctb::GlobalMercator(); - std::vector> test_cases = { - {"custom bounds", "/austria/pizbuin_1m_epsg4326.tif", tile::SrsBounds(glm::dvec2(1127962, 5915858), glm::dvec2(1127966, 5915882))}}; + std::vector> test_cases = { + {"custom bounds", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::SrsBounds(glm::dvec2(1127962, 5915858), glm::dvec2(1127966, 5915882))}}; for (const auto &test : tile_test_cases) { const auto [test_name, dataset_suffix, target_tile] = test; - const tile::SrsBounds tile_bounds = grid.srsBounds(target_tile, false); + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(target_tile, false); test_cases.push_back({test_name, dataset_suffix, tile_bounds}); } @@ -146,8 +148,8 @@ TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = target_bounds; output_texture_bounds = target_bounds; @@ -179,11 +181,11 @@ TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { TEST_CASE("neighbouring tiles fit together", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); const std::string dataset_suffix = "/austria/pizbuin_1m_epsg3857.tif"; - const std::array tiles = tile::Id(20, glm::uvec2(553801, 369497), tile::Scheme::SlippyMap).children(); + const std::array tiles = radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap).children(); std::vector tile_meshes; - for (const tile::Id &tile : tiles) { - const tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); + for (const radix::tile::Id &tile : tiles) { + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); DYNAMIC_SECTION(tile) { const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); @@ -195,8 +197,8 @@ TEST_CASE("neighbouring tiles fit together", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = tile_bounds; output_texture_bounds = tile_bounds; @@ -221,12 +223,12 @@ TEST_CASE("neighbouring tiles fit together repeatedly", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); const std::string dataset_suffix = "/austria/innenstadt_gs_1m_mgi.tif"; - const tile::Id root_tile_id(16, glm::uvec2(35748, 22724), tile::Scheme::SlippyMap); + const radix::tile::Id root_tile_id(16, glm::uvec2(35748, 22724), radix::tile::Scheme::SlippyMap); std::vector child_meshes; - for (const tile::Id child_tile_id : root_tile_id.children()) { + for (const radix::tile::Id child_tile_id : root_tile_id.children()) { std::vector grand_child_meshes; - for (const tile::Id grand_child_tile_id : child_tile_id.children()) { - const tile::SrsBounds grand_child_tile_bounds = grid.srsBounds(grand_child_tile_id, false); + for (const radix::tile::Id grand_child_tile_id : child_tile_id.children()) { + const radix::tile::SrsBounds grand_child_tile_bounds = grid.srsBounds(grand_child_tile_id, false); DYNAMIC_SECTION(grand_child_tile_id) { const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); @@ -238,8 +240,8 @@ TEST_CASE("neighbouring tiles fit together repeatedly", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = grand_child_tile_bounds; output_texture_bounds = grand_child_tile_bounds; diff --git a/unittests/terrainbuilder/mesh2.cpp b/unittests/terrainbuilder/mesh2.cpp new file mode 100644 index 0000000..362b29a --- /dev/null +++ b/unittests/terrainbuilder/mesh2.cpp @@ -0,0 +1,320 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "../catch2_helpers.h" +#include "Dataset.h" +#include "merge.h" +#include "mesh/terrain_mesh.h" +#include "mesh_builder.h" +#include "octree/id.h" +#include "octree/space.h" +#include "srs.h" + +#include "mesh/io.h" + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point3; +typedef CGAL::Surface_mesh SurfaceMesh; +typedef SurfaceMesh::Vertex_index VertexIndex; +typedef SurfaceMesh::Edge_index EdgeIndex; +typedef SurfaceMesh::Halfedge_index HalfEdgeIndex; +typedef SurfaceMesh::Face_index FaceIndex; +typedef boost::graph_traits::vertex_descriptor VertexDescriptor; +typedef boost::graph_traits::halfedge_descriptor HalfedgeDescriptor; + +Point3 glm2cgal(glm::dvec3 point) { + return Point3(point[0], point[1], point[2]); +} + +SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { + SurfaceMesh cgal_mesh; + + for (const glm::dvec3 &position : mesh.positions) { + const CGAL::SM_Vertex_index vertex = cgal_mesh.add_vertex(glm2cgal(position)); + REQUIRE(vertex != SurfaceMesh::null_vertex()); + } + + for (const glm::uvec3 &triangle : mesh.triangles) { + const FaceIndex face = cgal_mesh.add_face( + VertexIndex(triangle.x), + VertexIndex(triangle.y), + VertexIndex(triangle.z)); + + REQUIRE(face != SurfaceMesh::null_face()); + } + + return cgal_mesh; +} + +void check_mesh(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + CHECK(cgal_mesh.is_valid(true)); + CHECK(CGAL::is_triangle_mesh(cgal_mesh)); + CHECK(CGAL::is_valid_polygon_mesh(cgal_mesh, true)); + CHECK_FALSE(CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); +} + +void check_no_holes(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + std::vector border_cycles; + CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); + const size_t nb_holes = border_cycles.size(); + CHECK(nb_holes == 0); +} + +void check_uvs(const TerrainMesh &mesh) { + REQUIRE(mesh.uvs.size() == mesh.positions.size()); + + for (const glm::dvec2 uv : mesh.uvs) { + REQUIRE(glm::all(glm::greaterThanEqual(uv, glm::dvec2(0)))); + REQUIRE(glm::all(glm::lessThanEqual(uv, glm::dvec2(1)))); + } +} + +void check_non_empty(const TerrainMesh &mesh) { + REQUIRE(mesh.positions.size() > 0); + REQUIRE(mesh.triangles.size() > 0); +} + +struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } +}; + +struct DVec3Equal { + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } +}; + +void check_duplicate_vertices(const std::vector &positions) { + std::unordered_set seen; + for (const auto &pos : positions) { + REQUIRE(seen.insert(pos).second); + } +} +/* +void check_duplicate_vertices(const std::vector &positions, double epsilon=1e-8) { + for (size_t i = 0; i < positions.size(); i++) { + for (size_t j = i + 1; j < positions.size(); j++) { + REQUIRE(glm::distance(positions[i], positions[j]) > epsilon); + } + } +} +*/ + +void check_duplicate_triangles(std::vector triangles) { + const auto duplicate_triangles = find_duplicate_triangles(triangles, true); + CHECK(duplicate_triangles == triangles.end()); +} + +template +radix::geometry::Aabb bounds_around_point(const glm::vec centre, const T margin) { + radix::geometry::Aabb bounds; + bounds.min = centre - glm::vec(margin); + bounds.max = centre + glm::vec(margin); + return bounds; +} + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + +TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuilder]") { + struct TestData { + std::string path_suffix; + radix::geometry::Aabb3d target_bounds; + OGRSpatialReference target_srs; + OGRSpatialReference mesh_srs; + double resolution; // in m + }; + + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const glm::dvec3 steffl_wgs84(16.3735655, 48.2083264, 204); + const glm::dvec3 steffl_ecef = srs::transform_point(wgs84_srs, ecef_srs, steffl_wgs84); + + const std::vector test_data{ + {"/austria/pizbuin_1m_epsg4326.tif", + extend_bounds_to_3d(bounds_around_point(glm::dvec2(pizbuin_summit_wgs84), 0.0001)), + wgs84_srs, + wgs84_srs, + 1}, + {"/austria/pizbuin_1m_mgi.tif", + bounds_around_point(pizbuin_summit_ecef, 50 * 1.), + ecef_srs, + ecef_srs, + 1}, + {"/austria/vienna_20m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 20.), + ecef_srs, + ecef_srs, + 20}, + {"/austria/at_100m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 100.), + ecef_srs, + ecef_srs, + 100}}; + + for (const auto &data : test_data) { + DYNAMIC_SECTION(data.path_suffix) { + Dataset dataset(std::filesystem::path(ATB_TEST_DATA_DIR).concat(data.path_suffix)); + const auto source_srs = dataset.srs(); + const auto &mesh_srs = data.mesh_srs; + const auto &target_srs = data.target_srs; + const auto &target_bounds = data.target_bounds; + const auto resolution = data.resolution; + + radix::tile::SrsBounds texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + mesh_srs, + target_srs, target_bounds, + source_srs, texture_bounds); + if (!result) { + FAIL("Failed to build mesh: " << result.error()); + } + const TerrainMesh mesh = result.value(); + + SECTION("Basic mesh properties") { + check_non_empty(mesh); + check_uvs(mesh); + check_duplicate_vertices(mesh.positions); + check_duplicate_triangles(mesh.triangles); + check_mesh(mesh); + } + + const std::vector positions_in_target_srs = srs::transform_points(mesh_srs, target_srs, mesh.positions); + SECTION("Vertices within target bounds") { + for (const auto &position : positions_in_target_srs) { + REQUIRE(radix::geometry::Aabb2d(target_bounds).contains_inclusive(glm::dvec2(position))); + REQUIRE(target_bounds.contains_inclusive(position)); + } + } + + SECTION("Some vertices on bounds (clipping check)") { + std::vector vertices_on_bounds; + for (const glm::dvec3 position : positions_in_target_srs) { + if (!target_bounds.contains_exclusive(position)) { + vertices_on_bounds.push_back(position); + } + } + CHECK(vertices_on_bounds.size() > 10); + } + + SECTION("Matches dataset resolution") { + const auto positions_in_source_srs = srs::transform_points(mesh_srs, source_srs, mesh.positions); + auto flat_positions_in_source_srs = positions_in_source_srs; + for (auto &pos : flat_positions_in_source_srs) { + pos.z = 0.0; + } + const auto flat_positions_in_ecef_srs = srs::transform_points(source_srs, ecef_srs, flat_positions_in_source_srs); + + const auto target_bounds_2d = radix::geometry::Aabb2d(target_bounds); + const auto padding = target_bounds_2d.size() * 0.1; + const auto inner_min = target_bounds_2d.min + padding; + const auto inner_max = target_bounds_2d.max - padding; + const radix::geometry::Aabb2d inner_bounds_2d{inner_min, inner_max}; + + std::vector filtered_triangles; + for (const auto &tri : mesh.triangles) { + const glm::dvec3 &a = positions_in_target_srs[tri.x]; + const glm::dvec3 &b = positions_in_target_srs[tri.y]; + const glm::dvec3 &c = positions_in_target_srs[tri.z]; + if (inner_bounds_2d.contains_inclusive(a) && + inner_bounds_2d.contains_inclusive(b) && + inner_bounds_2d.contains_inclusive(c)) { + filtered_triangles.push_back(tri); + } + } + TerrainMesh inside_flat_mesh; + inside_flat_mesh.positions = flat_positions_in_ecef_srs; + inside_flat_mesh.triangles = filtered_triangles; + + const auto avg_edge_length = estimate_average_edge_length(inside_flat_mesh); + REQUIRE(avg_edge_length.has_value()); + const auto expected_avg_edge_length = ((1 + 1 + std::sqrt(3)) / 3) * resolution; + CHECK(avg_edge_length.value() == Catch::Approx(expected_avg_edge_length).margin(expected_avg_edge_length * 0.2)); + } + } + } +} + +TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const octree::Space space = octree::Space::earth(); + const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 16).value(); + std::vector nodes = summit_node.neighbours(); + nodes.push_back(summit_node); + + const std::string dataset_suffix = "/austria/pizbuin_1m_mgi.tif"; + const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); + Dataset dataset(dataset_path); + + std::vector node_meshes; + for (const octree::Id &node : nodes) { + const octree::Bounds node_bounds = space.get_node_bounds(node); + radix::tile::SrsBounds output_texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + ecef_srs, + ecef_srs, node_bounds, + webmercator_srs, output_texture_bounds); + if (!result.has_value()) { + continue; + } + const TerrainMesh mesh = result.value(); + node_meshes.push_back(mesh); + } + CHECK(node_meshes.size() >= 3); + + const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-8); + const std::filesystem::path mesh_path = "/mnt/e/Code/TU/2023S/Project/terrain-builder/build/unittests/mesh.glb"; + io::save_mesh_to_path(mesh_path, merged_mesh, io::SaveOptions{.texture_format = ".png"}); + check_non_empty(merged_mesh); + check_no_holes(merged_mesh); +} \ No newline at end of file diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainbuilder/octree_id.cpp new file mode 100644 index 0000000..482f40b --- /dev/null +++ b/unittests/terrainbuilder/octree_id.cpp @@ -0,0 +1,63 @@ +#include + +#include "../catch2_helpers.h" + +#include "octree/id.h" + +using namespace octree; + +TEST_CASE("Id basic construction and accessors", "[octree::Id]") { + Id id(2, glm::uvec3(3, 1, 4)); + CHECK(id.level() == 2); + CHECK(id.coords() == glm::uvec3(3, 1, 4)); + CHECK(id.x() == 3); + CHECK(id.y() == 1); + CHECK(id.z() == 4); +} + +TEST_CASE("Id interleave and deinterleave roundtrip", "[octree::Id]") { + glm::uvec3 coords(1, 2, 3); + Id id(17, coords); + CHECK(id.coords() == coords); +} + +TEST_CASE("Id neighbour within bounds", "[octree::Id]") { + Id id(3, glm::uvec3(4, 4, 4)); + auto neighbor = id.neighbour(glm::ivec3(1, -1, 0)); + REQUIRE(neighbor.has_value()); + CHECK(neighbor.value().coords() == glm::uvec3(5, 3, 4)); +} + +TEST_CASE("Id neighbour out of bounds returns nullopt", "[octree::Id]") { + Id id(3, glm::uvec3(0, 0, 0)); + CHECK_FALSE(id.neighbour(glm::ivec3(-1, 0, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, -1, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, 0, -1)).has_value()); +} + +TEST_CASE("Id parent returns nullopt at root level", "[octree::Id]") { + Id root = Id::root(); + CHECK_FALSE(root.parent().has_value()); +} + +TEST_CASE("Id parent returns correct parent", "[octree::Id]") { + Id id(2, glm::uvec3(6, 4, 2)); + auto parent = id.parent(); + REQUIRE(parent.has_value()); + CHECK(parent->level() == 1); + CHECK(parent->coords() == glm::uvec3(3, 2, 1)); +} + +TEST_CASE("Id child returns correct child", "[octree::Id]") { + Id parent(1, glm::uvec3(1, 1, 1)); + Id child = parent.child(5); + CHECK(child.level() == 2); + CHECK((child.index_on_level() >> 3) == parent.index_on_level()); + CHECK((child.index_on_level() & 7) == 5); +} + +TEST_CASE("Id child throws on invalid index", "[octree::Id]") { + Id parent(1, glm::uvec3(1, 1, 1)); + CHECK_THROWS_AS(parent.child(8), std::invalid_argument); + CHECK_THROWS_AS(parent.child(-1), std::invalid_argument); +} \ No newline at end of file diff --git a/unittests/terrainbuilder/octree_space.cpp b/unittests/terrainbuilder/octree_space.cpp new file mode 100644 index 0000000..6202c51 --- /dev/null +++ b/unittests/terrainbuilder/octree_space.cpp @@ -0,0 +1,113 @@ +#include + +#include "../catch2_helpers.h" + +#include "octree/id.h" +#include "octree/space.h" + +using namespace octree; + +TEST_CASE("find_smallest_node_encompassing_bounds includes full space", "[octree::Space]") { + Space space = Space::earth(); + + auto full_space_id = space.find_smallest_node_encompassing_bounds(space.bounds); + REQUIRE(full_space_id.has_value()); + CHECK(full_space_id.value() == Id::root()); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns more specific child", "[octree::Space]") { + Space space = Space::earth(); + + Bounds inner_box{ + space.bounds.min, + space.bounds.min + space.bounds.size() / 2.0 + }; + + auto id = space.find_smallest_node_encompassing_bounds(inner_box); + REQUIRE(id.has_value()); + CHECK(id->level() == 1); + CHECK(id->coords() == glm::uvec3(0, 0, 0)); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns nullopt for out-of-bounds", "[octree::Space]") { + Space space = Space::earth(); + glm::dvec3 offset = space.bounds.size() * 2.0; + + Bounds far_away{ + space.bounds.min + offset, + space.bounds.min + offset + glm::dvec3(1.0) + }; + + auto id = space.find_smallest_node_encompassing_bounds(far_away); + REQUIRE_FALSE(id.has_value()); +} + +TEST_CASE("find_smallest_node_encompassing_bounds throws on zero-size box", "[octree::Space]") { + Space space = Space::earth(); + glm::dvec3 p = {1.0, 1.0, 1.0}; + + Bounds degenerate{p, p}; + + REQUIRE_THROWS_AS(space.find_smallest_node_encompassing_bounds(degenerate), std::invalid_argument); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns smallest valid node", "[octree]") { + Space space = Space::earth(); + + // Pick a very small bounds somewhere inside the root + glm::dvec3 offset = space.bounds.size() * 0.1; + glm::dvec3 size = space.bounds.size() * 0.001; + + Bounds target{ + space.bounds.min + offset, + space.bounds.min + offset + size}; + + auto maybe_id = space.find_smallest_node_encompassing_bounds(target); + REQUIRE(maybe_id.has_value()); + Id id = *maybe_id; + + // Get the bounds of that node + Bounds node_bounds = space.get_node_bounds(id); + + // Check that node bounds fully contain the target + for (const auto &corner : radix::geometry::corners(target)) { + REQUIRE(node_bounds.contains_inclusive(corner)); + } + + // Now check that no child of this node fully contains the target + for (const auto &child_id : id.children()) { + Bounds child_bounds = space.get_node_bounds(child_id); + bool all_corners_inside = true; + for (const auto &corner : radix::geometry::corners(target)) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside = false; + break; + } + } + // At least one child must fail to contain the target bounds + REQUIRE_FALSE(all_corners_inside); + } +} + +TEST_CASE("find_smallest_node_encompassing_bounds roundtrips from Id to bounds and back", "[octree]") { + Space space = Space::earth(); + + // Pick a non-root ID + Id original_id{4, {3, 1, 2}}; // Level 4, arbitrary coords + + // Get bounds of this node + Bounds node_bounds = space.get_node_bounds(original_id); + + // Sanity check: bounds should be non-empty + auto size = node_bounds.size(); + REQUIRE(size.x > 0); + REQUIRE(size.y > 0); + REQUIRE(size.z > 0); + + // Find the smallest node encompassing the bounds + auto maybe_id = space.find_smallest_node_encompassing_bounds(node_bounds); + + // It should find exactly the same ID + REQUIRE(maybe_id.has_value()); + REQUIRE(maybe_id.value() == original_id); +} diff --git a/unittests/terrainbuilder/texture.cpp b/unittests/terrainbuilder/texture.cpp index 0c90911..a1903a7 100644 --- a/unittests/terrainbuilder/texture.cpp +++ b/unittests/terrainbuilder/texture.cpp @@ -22,9 +22,6 @@ #include #include -#define CATCH_CONFIG_MAIN -#include - #include #include "../catch2_helpers.h" @@ -38,20 +35,20 @@ TEST_CASE("estimate_zoom_level", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id tile(20, glm::uvec2(0, 1), tile::Scheme::SlippyMap); - const tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); - const tile::SrsBounds shifted_bounds(tile_bounds.min + glm::dvec2(-100, 420), tile_bounds.max + glm::dvec2(-100, 420)); + const radix::tile::Id tile(20, glm::uvec2(0, 1), radix::tile::Scheme::SlippyMap); + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); + const radix::tile::SrsBounds shifted_bounds(tile_bounds.min + glm::dvec2(-100, 420), tile_bounds.max + glm::dvec2(-100, 420)); REQUIRE(terrainbuilder::texture::estimate_zoom_level(tile.zoom_level, tile_bounds, shifted_bounds) == tile.zoom_level); } class AvailabilityListEmptyTileProvider : public TileProvider { public: - AvailabilityListEmptyTileProvider(std::set available_tiles) + AvailabilityListEmptyTileProvider(std::set available_tiles) : available_tiles(available_tiles) { } - virtual std::optional get_tile(const tile::Id tile) const override { + virtual std::optional get_tile(const radix::tile::Id tile) const override { if (this->available_tiles.find(tile) != this->available_tiles.end()) { return cv::Mat(); } else { @@ -60,168 +57,168 @@ class AvailabilityListEmptyTileProvider : public TileProvider { } private: - const std::set available_tiles; + const std::set available_tiles; }; class AlwaysEmptyTileProvider : public TileProvider { public: - virtual std::optional get_tile(const tile::Id) const override { + virtual std::optional get_tile(const radix::tile::Id) const override { return cv::Mat(); } }; TEST_CASE("texture assembler takes root tile if only available ", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler ignores parent if all children are present", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}, - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}, + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler considers max zoom level", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}, - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}, + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider, 3); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler works for arbitrary bounds", "[terrainbuilder]") { - const std::set available_tiles = { - // {21, {1048576, 1048576}, tile::Scheme::Tms}, - {21, {1048577, 1048576}, tile::Scheme::Tms}, - {21, {1048578, 1048576}, tile::Scheme::Tms}, - {21, {1048579, 1048576}, tile::Scheme::Tms}, - {21, {1048580, 1048576}, tile::Scheme::Tms}, - // {21, {1048581, 1048576}, tile::Scheme::Tms}, - {20, {524288, 524288}, tile::Scheme::Tms}, - {20, {524289, 524288}, tile::Scheme::Tms}, - {20, {524290, 524288}, tile::Scheme::Tms}, - // {19, {262144, 262144}, tile::Scheme::Tms}, - {19, {262145, 262144}, tile::Scheme::Tms}}; - const std::set expected_tiles = { - // {21, {1048576, 1048576}, tile::Scheme::Tms}, - {21, {1048577, 1048576}, tile::Scheme::Tms}, - {21, {1048578, 1048576}, tile::Scheme::Tms}, - {21, {1048579, 1048576}, tile::Scheme::Tms}, - {21, {1048580, 1048576}, tile::Scheme::Tms}, - // {21, {1048581, 1048576}, tile::Scheme::Tms}, - {20, {524288, 524288}, tile::Scheme::Tms}, - // {20, {524289, 524288}, tile::Scheme::Tms}, - {20, {524290, 524288}, tile::Scheme::Tms}, - // {19, {262144, 262144}, tile::Scheme::Tms}, - // {19, {262145, 262144}, tile::Scheme::Tms} + const std::set available_tiles = { + // {21, {1048576, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048577, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048578, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048579, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048580, 1048576}, radix::tile::Scheme::Tms}, + // {21, {1048581, 1048576}, radix::tile::Scheme::Tms}, + {20, {524288, 524288}, radix::tile::Scheme::Tms}, + {20, {524289, 524288}, radix::tile::Scheme::Tms}, + {20, {524290, 524288}, radix::tile::Scheme::Tms}, + // {19, {262144, 262144}, radix::tile::Scheme::Tms}, + {19, {262145, 262144}, radix::tile::Scheme::Tms}}; + const std::set expected_tiles = { + // {21, {1048576, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048577, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048578, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048579, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048580, 1048576}, radix::tile::Scheme::Tms}, + // {21, {1048581, 1048576}, radix::tile::Scheme::Tms}, + {20, {524288, 524288}, radix::tile::Scheme::Tms}, + // {20, {524289, 524288}, radix::tile::Scheme::Tms}, + {20, {524290, 524288}, radix::tile::Scheme::Tms}, + // {19, {262144, 262144}, radix::tile::Scheme::Tms}, + // {19, {262145, 262144}, radix::tile::Scheme::Tms} }; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); - const tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + const radix::tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); + const radix::tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, target_bounds, tile_provider, 23, 21); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler does not fail if there are not tiles", "[terrainbuilder]") { - const std::set available_tiles = {}; - const std::set expected_tiles = {}; + const std::set available_tiles = {}; + const std::set expected_tiles = {}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); - const tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + const radix::tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); + const radix::tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, target_bounds, tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler assembles single tile", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(0, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(0, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, @@ -237,18 +234,18 @@ TEST_CASE("texture assembler assembles single tile", "[terrainbuilder]") { } TEST_CASE("texture assembler assembles two tiles", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(1, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, - {tile::Id(1, {0, 1}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 255, 0))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(1, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 255, 0))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, @@ -265,21 +262,21 @@ TEST_CASE("texture assembler assembles two tiles", "[terrainbuilder]") { } TEST_CASE("texture assembler correct order of texture writes", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(0, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(1))}, - {tile::Id(1, {0, 1}, tile::Scheme::Tms), cv::Mat(1, 1, CV_8UC1, uint8_t(2))}, - {tile::Id(1, {0, 1}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(3))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(0, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(1))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::Tms), cv::Mat(1, 1, CV_8UC1, uint8_t(2))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(3))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); std::sort(tiles_to_splatter.begin(), tiles_to_splatter.end(), - [](const tile::Id &a, const tile::Id &b) { return a.zoom_level < b.zoom_level; }); + [](const radix::tile::Id &a, const radix::tile::Id &b) { return a.zoom_level < b.zoom_level; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, From 1fbd1f90e30241d2f2f2feffc9144707ace82295 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 2 May 2025 21:10:51 +0200 Subject: [PATCH 013/122] Add octree based mesh generation (WIP) --- README.md | 3 +- src/CMakeLists.txt | 6 +- src/terrainbuilder/border.h | 47 +- src/terrainbuilder/main.cpp | 92 +++- src/terrainbuilder/mesh_builder.cpp | 560 +++++++++++----------- src/terrainbuilder/mesh_builder.h | 9 +- src/terrainbuilder/octree/id.h | 161 +++++++ src/terrainbuilder/octree/space.h | 120 +++++ src/terrainbuilder/octree/storage.h | 46 ++ src/terrainbuilder/octree/utils.cpp | 2 + src/terrainbuilder/octree/utils.h | 10 + src/terrainbuilder/raster.h | 144 ++++++ src/terrainbuilder/raw_dataset_reader.h | 8 +- src/terrainbuilder/terrainbuilder.cpp | 53 +- src/terrainbuilder/terrainbuilder.h | 6 +- src/terrainbuilder/texture_assembler.h | 2 +- src/terrainlib/Dataset.cpp | 4 +- src/terrainlib/mesh/terrain_mesh.cpp | 37 ++ src/terrainlib/mesh/terrain_mesh.h | 8 +- src/terrainlib/srs.h | 333 +++++++++---- src/terrainmerger/merge.cpp | 16 +- src/terrainmerger/simplify.cpp | 24 +- unittests/CMakeLists.txt | 23 +- unittests/catch2_helpers.h | 3 +- unittests/terrainbuilder/mesh.cpp | 48 +- unittests/terrainbuilder/mesh2.cpp | 320 +++++++++++++ unittests/terrainbuilder/octree_id.cpp | 63 +++ unittests/terrainbuilder/octree_space.cpp | 113 +++++ unittests/terrainbuilder/texture.cpp | 181 ++++--- 29 files changed, 1854 insertions(+), 588 deletions(-) create mode 100644 src/terrainbuilder/octree/id.h create mode 100644 src/terrainbuilder/octree/space.h create mode 100644 src/terrainbuilder/octree/storage.h create mode 100644 src/terrainbuilder/octree/utils.cpp create mode 100644 src/terrainbuilder/octree/utils.h create mode 100644 src/terrainbuilder/raster.h create mode 100644 unittests/terrainbuilder/mesh2.cpp create mode 100644 unittests/terrainbuilder/octree_id.cpp create mode 100644 unittests/terrainbuilder/octree_space.cpp diff --git a/README.md b/README.md index e7e6a0c..bbbbf88 100644 --- a/README.md +++ b/README.md @@ -83,4 +83,5 @@ In order to build, you need to install: - FreeImage - tbb (intel threading building blocks) -sudo apt-get install libfmt-dev libglm-dev libgdal-dev catch2 libfreeimage-dev libtbb-dev +sudo apt-get install libcgal-dev libopencv-dev libfmt-dev libglm-dev libgdal-dev catch2 libfreeimage-dev libtbb-dev libcurl4-openssl-dev +(libgmp-dev libmpfr-dev libeigen3-dev) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0453b50..46abfdf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,7 @@ endif() if(ALP_AUTOUPDATE_RADIX) FetchContent_Declare(radix GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git - GIT_TAG origin/main + GIT_TAG d01b84248e21e4754e028492bf70519e3416c86 SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix SOURCE_SUBDIR src ) @@ -217,8 +217,12 @@ add_library(terrainbuilderlib terrainbuilder/raw_dataset_reader.h terrainbuilder/texture_assembler.h terrainbuilder/border.h + terrainbuilder/raster.h terrainbuilder/terrainbuilder.h terrainbuilder/terrainbuilder.cpp + terrainbuilder/octree/id.h + terrainbuilder/octree/storage.h + terrainbuilder/octree/space.h ) target_include_directories(terrainbuilderlib PUBLIC terrainbuilder terrainlib) target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 expected) diff --git a/src/terrainbuilder/border.h b/src/terrainbuilder/border.h index ff754b2..01746ea 100644 --- a/src/terrainbuilder/border.h +++ b/src/terrainbuilder/border.h @@ -42,12 +42,51 @@ class Border { } }; +namespace { + template + constexpr T saturating_add(T x, T y) noexcept { + static_assert(std::is_integral_v, "saturating_add requires an integer type"); + + T result; + if (!__builtin_add_overflow(x, y, &result)) { + return result; + } + + if constexpr (std::is_unsigned_v) { + return std::numeric_limits::max(); + } else if (x < 0) { + return std::numeric_limits::min(); + } else { + return std::numeric_limits::max(); + } +} + +// Saturating subtract for integers +template +constexpr T saturating_sub(T x, T y) noexcept { + static_assert(std::is_integral_v, "saturating_sub requires an integer type"); + + T result; + if (!__builtin_sub_overflow(x, y, &result)) { + return result; + } + + if constexpr (std::is_unsigned_v) { + return 0; + } else if (x < 0) { + return std::numeric_limits::min(); + } else { + return std::numeric_limits::max(); + } +} +} + template inline void add_border_to_aabb(radix::geometry::Aabb2 &bounds, const Border &border) { - bounds.min.x -= border.left; - bounds.min.y -= border.top; - bounds.max.x += border.right; - bounds.max.y += border.bottom; + bounds.min.x = saturating_sub(bounds.min.x, border.left); + bounds.min.y = saturating_sub(bounds.min.y, border.top); + bounds.max.x = saturating_add(bounds.max.x, border.right); + bounds.max.y = saturating_add(bounds.max.y, border.bottom); } } diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index afbebd9..9263bfb 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -16,6 +16,16 @@ #include "terrainbuilder.h" #include "log.h" +#include "octree/storage.h" +#include "octree/space.h" + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + int run(std::span args) { int argc = args.size(); char ** argv = args.data(); @@ -35,27 +45,32 @@ int run(std::span args) { std::string mesh_srs_input; app.add_option("--mesh-srs", mesh_srs_input, "EPSG code of the target srs of the mesh positions") - ->default_val("EPSG:4978"); + ->default_val("EPSG:4978"); // ECEF std::string target_srs_input; - app.add_option("--target-srs", target_srs_input, "EPSG code of the srs of the target bounds or tile id") - ->default_val("EPSG:3857"); + app.add_option("--target-srs", target_srs_input, "EPSG code of the srs of the target bounds or id") + ->default_val("EPSG:4978"); // ECEF auto *target = app.add_option_group("target"); std::vector target_bounds_data; - target->add_option("--bounds", target_bounds_data, "Target bounds for the reference tile as \"{xmin} {ymin} {width} {height}\"") - ->expected(4); - std::vector target_tile_data; + target->add_option("--bounds", target_bounds_data, "Target bounds for the reference mesh as \"{xmin} {width} {ymin} {height} [{zmin} {depth}]\"") + ->expected(4, 6); + std::vector target_tile_data; target->add_option("--tile", target_tile_data, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") ->expected(3) ->excludes("--bounds"); + std::vector target_node_data; + target->add_option("--node", target_node_data, "Target node id for the reference node as \"{zoom} {index}\" or \"{zoom} {x} {y} {z}\"") + ->expected(2, 4) + ->excludes("--tile") + ->excludes("--bounds"); target->require_option(1); radix::tile::Scheme target_tile_scheme; std::map scheme_str_map{{"slippymap", radix::tile::Scheme::SlippyMap}, {"google", radix::tile::Scheme::SlippyMap}, {"tms", radix::tile::Scheme::Tms}}; - app.add_option("--scheme", target_tile_scheme, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") + app.add_option("--scheme", target_tile_scheme, "Target scheme for the tile id") ->default_val(radix::tile::Scheme::SlippyMap) - ->excludes("--bounds") + ->needs("--tile") ->transform(CLI::CheckedTransformer(scheme_str_map, CLI::ignore_case)); std::filesystem::path output_path; @@ -80,44 +95,71 @@ int run(std::span args) { Dataset dataset(dataset_path); - OGRSpatialReference tile_srs; - tile_srs.SetFromUserInput(target_srs_input.c_str()); - tile_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + OGRSpatialReference target_bounds_srs; + target_bounds_srs.SetFromUserInput(target_srs_input.c_str()); + target_bounds_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); OGRSpatialReference mesh_srs; mesh_srs.SetFromUserInput(mesh_srs_input.c_str()); mesh_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - OGRSpatialReference texture_srs; - texture_srs.importFromEPSG(3857); - texture_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + OGRSpatialReference texture_srs = srs::webmercator(); - radix::tile::SrsBounds tile_bounds; + radix::geometry::Aabb3d target_bounds; if (!target_bounds_data.empty()) { - const glm::dvec2 tile_bounds_min(target_bounds_data[0], target_bounds_data[1]); - const glm::dvec2 tile_bounds_size(target_bounds_data[2], target_bounds_data[3]); - tile_bounds = radix::tile::SrsBounds(tile_bounds_min, tile_bounds_min + tile_bounds_size); - } else { + // Target bounds are given directly + if (target_bounds_data.size() == 4) { + const glm::dvec2 min(target_bounds_data[0], target_bounds_data[2]); + const glm::dvec2 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3]); + target_bounds = extend_bounds_to_3d(radix::geometry::Aabb2d(min, max)); + } else if (target_bounds_data.size() == 6) { + const glm::dvec3 min(target_bounds_data[0], target_bounds_data[2], target_bounds_data[4]); + const glm::dvec3 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3], target_bounds_data[4] + target_bounds_data[5]); + target_bounds = radix::geometry::Aabb3d(min, max); + } else { + LOG_ERROR("Invalid number of elements for --bounds. Expected 4 or 6 ({xmin} {width} {ymin} {height} [{zmin} {depth}])."); + return 1; + } + } else if (!target_tile_data.empty()) { + // Target bounds are based on a webmercator tile id const ctb::Grid grid = ctb::GlobalMercator(); const unsigned int zoom_level = target_tile_data[0]; const glm::uvec2 tile_coords(target_tile_data[1], target_tile_data[2]); const radix::tile::Id target_tile(zoom_level, tile_coords, target_tile_scheme); - if (!tile_srs.IsSame(&grid.getSRS())) { - LOG_ERROR("Target tile id is only supported for webmercator reference system"); + if (!target_bounds_srs.IsSame(&grid.getSRS())) { + LOG_ERROR("Target tile id is only supported for the webmercator reference system"); exit(1); } - tile_bounds = grid.srsBounds(target_tile, false); + target_bounds = extend_bounds_to_3d(grid.srsBounds(target_tile, false)); + } else { + // Target bounds are based on an octree node id + const uint32_t zoom_level = target_node_data[0]; + octree::Id target_node = octree::Id::root(); + if (target_node_data.size() == 2) { + const uint64_t node_index = target_node_data[1]; + target_node = {zoom_level, node_index}; + } else if (target_node_data.size() == 4) { + const glm::uvec3 coords(target_node_data[1], target_node_data[2], target_node_data[3]); + target_node = { zoom_level, coords }; + } else { + LOG_ERROR("Invalid number of args for --node. Expected 2 or 4."); + return 1; + } + + const octree::Space world = octree::Space::earth(); + target_bounds = world.get_node_bounds(target_node); } + terrainbuilder::build( dataset, + target_bounds_srs, + target_bounds, + texture_srs, texture_base_path, mesh_srs, - tile_srs, - texture_srs, - tile_bounds, output_path); return 0; diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index a70343c..2aac57a 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -7,336 +9,344 @@ #include #include "Dataset.h" -#include "Image.h" #include "mesh/terrain_mesh.h" #include "srs.h" -#include "tntn/gdal_init.h" +#include "raster.h" #include "log.h" #include "mesh_builder.h" #include "raw_dataset_reader.h" +#include namespace terrainbuilder::mesh { +std::ostream &operator<<(std::ostream &os, BuildError error) { + switch (error) { + case BuildError::OutOfBounds: + os << "out of bounds"; + break; + case BuildError::EmptyRegion: + os << "empty region"; + break; + default: + os << "unknown build error"; + break; + } + return os; +} + template static glm::dvec2 apply_transform(std::array transform, const glm::tvec2 &v) { glm::dvec2 result; GDALApplyGeoTransform(transform.data(), v.x, v.y, &result.x, &result.y); return result; } -static glm::dvec2 apply_transform(OGRCoordinateTransformation *transform, const glm::dvec2 &v) { - glm::dvec2 result(v); - if (!transform->Transform(1, &result.x, &result.y)) { - throw std::runtime_error("apply_transform() failed"); - } - return result; -} -static glm::dvec3 apply_transform(OGRCoordinateTransformation *transform, const glm::dvec3 &v) { - glm::dvec3 result(v); - if (!transform->Transform(1, &result.x, &result.y, &result.z)) { - throw std::runtime_error("apply_transform() failed"); - } - return result; -} - -/// Builds a mesh from the given height dataset. -// TODO: split this up: Grid class, Mask class/alias, mask filter method/utils -// steps (each a method): -// - read data (height) -// - filter invalid values (create mask) -// - calculate positions in source srs -// - filter by bounds (considering inclusivity and invalid values) -// - extend mask by border -// - compact vertices -// - check if empty -// - calculate position in texture srs and normalize -// - generate actual triangles -// (shouldnt require reindexing of vertices; use an interface that combines this and inclusivity filtering) -// - validate final mesh -// TODO: return result struct instead of using inout parameters -tl::expected build_reference_mesh_tile( - Dataset &dataset, - const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, - const Border &vertex_border, - const bool inclusive_bounds) { - const OGRSpatialReference &source_srs = dataset.srs(); - - // Translate tile bounds from tile srs into the source srs, so we know what data to read. - const radix::tile::SrsBounds tile_bounds_in_source_srs = srs::encompassing_bounding_box_transfer(tile_srs, source_srs, tile_bounds); - - // Read height data according to bounds directly from dataset (no interpolation). - RawDatasetReader reader(dataset); - radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(tile_bounds_in_source_srs); - add_border_to_aabb(pixel_bounds, vertex_border); - if (inclusive_bounds) { - add_border_to_aabb(pixel_bounds, Border(1)); - } - LOG_TRACE("Reading pixels [({}, {})-({}, {})] from dataset", pixel_bounds.min.x, pixel_bounds.min.y, pixel_bounds.max.x, pixel_bounds.max.y); - const std::optional read_result = reader.read_data_in_pixel_bounds(pixel_bounds, true); - if (!read_result.has_value() || read_result->size() == 0) { - return tl::unexpected(BuildError::OutOfBounds); - } - const HeightData raw_tile_data = read_result.value(); - - // Allocate mesh data structure - const unsigned int max_vertex_count = raw_tile_data.width() * raw_tile_data.height(); - const unsigned int max_triangle_count = (raw_tile_data.width() - 1) * (raw_tile_data.height() - 1) * 2; - TerrainMesh mesh; - mesh.positions.reserve(max_vertex_count); - mesh.uvs.reserve(max_vertex_count); - mesh.triangles.reserve(max_triangle_count); - - // Prepare transformations here to avoid io inside the loop. - const std::unique_ptr transform_source_tile = srs::transformation(source_srs, tile_srs); - const std::unique_ptr transform_source_mesh = srs::transformation(source_srs, mesh_srs); - const std::unique_ptr transform_source_texture = srs::transformation(source_srs, texture_srs); - - // Preparation for loop - const double infinity = std::numeric_limits::infinity(); - radix::tile::SrsBounds actual_tile_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); - - std::vector source_positions; - source_positions.resize(max_vertex_count); - std::vector is_in_bounds; - is_in_bounds.resize(max_vertex_count); - std::fill(is_in_bounds.begin(), is_in_bounds.end(), false); +using PixelBounds = radix::geometry::Aabb2i; - std::vector is_valid; - is_valid.resize(max_vertex_count); - std::fill(is_valid.begin(), is_valid.end(), true); +// TODO:: write documentation +// TODO: use referencedBounds - // Pixel values represent the average over their area, or a value at their center. - const glm::dvec2 point_offset_in_raster(0.5); - - LOG_TRACE("Transforming pixels to vertices"); - // Iterate over height map and calculate vertex positions for each pixel and whether they are inside the requested bounds. - for (unsigned int j = 0; j < raw_tile_data.height(); j++) { - for (unsigned int i = 0; i < raw_tile_data.width(); i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - const double height = raw_tile_data.pixel(j, i); - - // Check if pixel is valid. - if (isnan(height) || isinf(height) /* <- invalid values */ - || height < -20000 || height > 20000) /* <- padding */ { - is_valid[vertex_index] = false; - continue; - } +bool is_valid(float height) { + return !isnan(height) && !isinf(height) /* <- invalid values */ + && height > -20000 && height < 20000; /* <- padding */ +} - // Convert pixel coordinates into a point in the dataset's srs. - const glm::dvec2 coords_raster_relative = glm::dvec2(i, j) + point_offset_in_raster; - const glm::dvec2 coords_raster_absolute = coords_raster_relative + glm::dvec2(pixel_bounds.min); - const glm::dvec3 coords_source(reader.transform_pixel_to_srs_point(coords_raster_absolute), height); - actual_tile_bounds.expand_by(coords_source); - source_positions[vertex_index] = coords_source; - - // Check if the point is inside the given bounds. - if (inclusive_bounds) { - // For inclusive bounds we decide based on the center of the quad, - // that is spanned from the current vertex to the right and bottom. - // We do not account for the extra quads on the top and left here, - // because this is done by adding a 1px border to raw_tile_data above. - - if (i >= raw_tile_data.width() - 1 || j >= raw_tile_data.height() - 1) { - // Skip last row and column because they don't form new triangles - continue; - } +glm::dvec3 convert_pixel_to_vertex(const float height, const raster::Coords pixel_coords, const RawDatasetReader& reader, const PixelBounds& pixel_bounds) { + const glm::dvec2 point_offset_in_raster(0.5); // Convert pixel coordinates into a point in the dataset's srs. + const glm::dvec2 coords_raster_relative = glm::dvec2(pixel_coords) + point_offset_in_raster; + const glm::dvec2 coords_raster_absolute = coords_raster_relative + glm::dvec2(pixel_bounds.min); + const glm::dvec3 coords_source(reader.transform_pixel_to_srs_point(coords_raster_absolute), height); + return coords_source; +} - // Transform the center of the quad into the srs the bounds are given. - const glm::ivec2 coords_center_raster_relative = glm::dvec2(i, j) + point_offset_in_raster + glm::dvec2(0.5); - const glm::ivec2 coords_center_raster_absolute = coords_center_raster_relative + pixel_bounds.min; - const glm::dvec2 coords_center_source = reader.transform_pixel_to_srs_point(coords_center_raster_absolute); - const glm::dvec2 coords_center_tile = apply_transform(transform_source_tile.get(), coords_center_source); +TerrainMesh meshify(const raster::Raster& source_points, const raster::Mask& mask) { + // Compact the vertex grid into a list of valid ones. + const size_t valid_vertex_count = std::reduce(mask.begin(), mask.end(), 0); + // Check if we even have any valid vertices. Can happen if all of the region is padding. + if (valid_vertex_count == 0) { + return TerrainMesh(); + } - if (!tile_bounds.contains_inclusive(coords_center_tile)) { - continue; - } - } else { - // For exclusive bounds, we only include points (and thereforce triangles) that are (fully) inside the bounds. - const glm::dvec2 coords_tile = apply_transform(transform_source_tile.get(), coords_source); - if (!tile_bounds.contains_inclusive(coords_tile)) { - continue; + std::vector positions; + positions.reserve(valid_vertex_count); + + const raster::Raster vertex_index_map = raster::transform(source_points, mask, [&](const glm::dvec3 &point) -> size_t { + const size_t index = positions.size(); + positions.push_back(point); + return index; + }); + assert(positions.size() == valid_vertex_count); + + // Allocate triangle vector + const size_t max_triangle_count = (source_points.width() - 1) * (source_points.height() - 1) * 2; + std::vector triangles; + triangles.reserve(max_triangle_count); + + for (size_t x = 0; x < source_points.width() - 1; x++) { + for (size_t y = 0; y < source_points.height() - 1; y++) { + const std::array quad { + raster::Coords{x, y}, + raster::Coords{x + 1, y}, + raster::Coords{x + 1, y + 1}, + raster::Coords{x, y + 1}}; + + for (uint32_t i = 0; i < 4; i++) { + const auto& v0 = quad[i]; + const auto& v1 = quad[(i + 1) % 4]; + const auto& v2 = quad[(i + 2) % 4]; + + // Check if the indices are valid + if (mask.pixel(v0) && mask.pixel(v1) && mask.pixel(v2)) { + triangles.emplace_back(vertex_index_map.pixel(v0), vertex_index_map.pixel(v1), vertex_index_map.pixel(v2)); + i++; } } - - // If we arrive here the point is inside the bounds. - is_in_bounds[vertex_index] = true; } } + assert(triangles.size() <= max_triangle_count); - // Mark all border vertices as inside bounds. - // TODO: This code is rather inefficient for larger borders. - if (!vertex_border.is_empty()) { - LOG_TRACE("Adding border vertices"); - std::vector border_vertices; - const unsigned int max_border_vertices = std::max(raw_tile_data.width(), raw_tile_data.height()); // for each step, assuming convexity - border_vertices.reserve(max_border_vertices); - - const std::array, 4> border_offsets = { - std::make_pair(vertex_border.left, glm::ivec2(-1, 0)), - std::make_pair(vertex_border.right, glm::ivec2(1, 0)), - std::make_pair(vertex_border.top, glm::ivec2(0, -1)), - std::make_pair(vertex_border.bottom, glm::ivec2(0, 1))}; - - for (unsigned int k = 0; k < border_offsets.size(); k++) { - const unsigned int border_thickness = border_offsets[k].first; - const glm::ivec2 border_direction = border_offsets[k].second; - - for (unsigned int l = 0; l < border_thickness; l++) { - for (unsigned int j = 0; j < raw_tile_data.height() - 1; j++) { - for (unsigned int i = 0; i < raw_tile_data.width() - 1; i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - - // skip all vertices already inside bounds - if (is_in_bounds[vertex_index]) { - continue; - } - - // Current vertex index offset into the opposite direction of the current border direction. - // So if we are currently making a top border, we offset the current position down. - const unsigned int vertex_index_to_check = (j + border_direction.y) * raw_tile_data.width() + (i + border_direction.x); - assert(vertex_index_to_check < max_vertex_count); - if (is_in_bounds[vertex_index_to_check]) { - // as we cannot have a reference into an std::vector we have to have another lookup here. - border_vertices.push_back(vertex_index); - } - } - } + return TerrainMesh(triangles, positions); +} - for (const unsigned int border_vertex : border_vertices) { - assert(border_vertex < is_in_bounds.size()); - if (is_valid[border_vertex]) { - is_in_bounds[border_vertex] = true; - } - } +TerrainMesh transform_mesh(const TerrainMesh &source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs) { + TerrainMesh target_mesh; + target_mesh.positions = srs::transform_points(source_srs, target_srs, source_mesh.positions); + target_mesh.triangles = source_mesh.triangles; + target_mesh.uvs = source_mesh.uvs; + target_mesh.texture = source_mesh.texture; + return target_mesh; +} - assert(border_vertices.size() <= max_border_vertices); - border_vertices.clear(); +TerrainMesh reindex_mesh(const TerrainMesh &mesh) { + std::vector new_positions; + new_positions.reserve(mesh.vertex_count()); + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + const uint32_t invalid_index = static_cast(-1); + std::vector index_map(mesh.positions.size(), invalid_index); + + for (const auto &triangle : mesh.triangles) { + glm::uvec3 new_triangle_indices; + for (size_t i = 0; i < 3; i++) { + const uint32_t old_index = triangle[i]; + if (index_map[old_index] == invalid_index) { + // Vertex newly encountered + const uint32_t new_index = new_positions.size(); + new_positions.push_back(mesh.positions[old_index]); + new_triangle_indices[i] = new_index; + index_map[old_index] = new_index; + } else { + // Vertex already encountered + new_triangle_indices[i] = index_map[old_index]; } } + new_triangles.push_back(new_triangle_indices); } - // Compact the vertex array to exclude all vertices out of bounds. - const unsigned int actual_vertex_count = std::accumulate(is_in_bounds.begin(), is_in_bounds.end(), 0); - // Check if we even have any valid vertices. Can happen if all of the region is padding. - if (actual_vertex_count == 0) { - return tl::unexpected(BuildError::EmptyRegion); - } - // Marks entries that are not present in the new vector (not inside bounds or border) - const unsigned int no_new_index = max_vertex_count + 1; - // Index in old vector mapped to the index in the new one. - std::vector new_vertex_indices; - if (actual_vertex_count != max_vertex_count) { - new_vertex_indices.reserve(max_vertex_count); - - unsigned int write_index = 0; - for (unsigned int read_index = 0; read_index < max_vertex_count; read_index++) { - if (is_in_bounds[read_index]) { - assert(is_valid[read_index]); - new_vertex_indices.push_back(write_index); - source_positions[write_index] = source_positions[read_index]; - write_index += 1; - } else { - new_vertex_indices.push_back(no_new_index); - } + return TerrainMesh(new_triangles, new_positions); +} + +namespace { + struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); } + }; - // Remove out of bounds vertices - source_positions.resize(actual_vertex_count); - } + struct DVec3Equal { + const double epsilon; - // Calculate absolute texture coordinates for every vertex. - LOG_TRACE("Calculating uv coordinates"); - radix::tile::SrsBounds actual_texture_bounds(glm::dvec2(infinity), glm::dvec2(-infinity)); - std::vector texture_positions; - texture_positions.reserve(max_vertex_count); - for (unsigned int i = 0; i < actual_vertex_count; i++) { - const glm::dvec3 coords_source = source_positions[i]; - const glm::dvec2 coords_texture_absolute = apply_transform(transform_source_texture.get(), coords_source); - actual_texture_bounds.expand_by(coords_texture_absolute); - texture_positions.push_back(coords_texture_absolute); - } + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } + }; +} - // Normalize texture coordinates - mesh.uvs = std::move(texture_positions); - for (glm::dvec2 &uv : mesh.uvs) { - uv = (uv - actual_texture_bounds.min) / actual_texture_bounds.size(); +TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bounds) { + if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { + return {}; } - assert(mesh.uvs.size() == actual_vertex_count); - // Add triangles - LOG_TRACE("Generating triangles"); - for (unsigned int j = 0; j < raw_tile_data.height() - 1; j++) { - for (unsigned int i = 0; i < raw_tile_data.width() - 1; i++) { - const unsigned int vertex_index = j * raw_tile_data.width() + i; - - std::array quad = { - vertex_index, - vertex_index + 1, - vertex_index + raw_tile_data.width() + 1, - vertex_index + raw_tile_data.width(), - }; - - if (inclusive_bounds) { - // Check if all of the quad is inside the bounds - bool skip_quad = false; - for (const unsigned int vertex_index : quad) { - if (!is_in_bounds[vertex_index]) { - skip_quad = true; + // Calculate epsilon to merge newly created vertices + const double average_edge_length = estimate_average_edge_length(mesh).value(); + const double epsilon = average_edge_length / 1000; + + std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); + + // Construct 6 axis-aligned clipping planes from the bounding box + const std::array, 6> planes = { + radix::geometry::Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left + radix::geometry::Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right + radix::geometry::Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom + radix::geometry::Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top + radix::geometry::Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near + radix::geometry::Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far + }; + + std::vector new_positions = mesh.positions; + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + + // Iterate over each triangle in the mesh + for (const glm::uvec3 &source_triangle : mesh.triangles) { + using Tri = radix::geometry::Triangle<3, double>; + + // Get the positions for the current triangle + const Tri triangle = { + mesh.positions[source_triangle.x], + mesh.positions[source_triangle.y], + mesh.positions[source_triangle.z]}; + + uint16_t inside_count = 0; + for (const auto &vertex : triangle) { + if (bounds.contains_inclusive(vertex)) { + inside_count += 1; + } + } + if (inside_count == 0) { + continue; + } + if (inside_count == source_triangle.length()) { + new_triangles.push_back(source_triangle); + continue; + } + + // Start with the original triangle + // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle + const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); + assert(!clipped_triangles.empty()); + + for (const auto &clipped_triangle : clipped_triangles) { + glm::uvec3 decomposed_triangle; + for (size_t i = 0; i < clipped_triangle.size(); i++) { + const auto &vertex = clipped_triangle[i]; + std::optional vertex_index; + + // Check if this vertex was already in the source triangle + for (size_t j = 0; j < triangle.size(); j++) { + const auto &source_vertex = triangle[j]; + if (vertex == source_vertex) { + vertex_index = source_triangle[j]; break; } } - if (skip_quad) { - continue; - } - // Calculate the index of the given vertex in the reindexed buffer. - if (actual_vertex_count != max_vertex_count) { - for (unsigned int &vertex_index : quad) { - vertex_index = new_vertex_indices[vertex_index]; - assert(vertex_index != no_new_index); + // Check if this vertex was already added + if (!vertex_index.has_value()) { + const auto it = seen_vertices.find(vertex); + if (it != seen_vertices.cend()) { + vertex_index = it->second; } + } - mesh.triangles.emplace_back(quad[0], quad[3], quad[2]); - mesh.triangles.emplace_back(quad[0], quad[2], quad[1]); - } else { - for (unsigned int i = 0; i < 4; i++) { - const unsigned int v0 = quad[i]; - const unsigned int v1 = quad[(i + 1) % 4]; - const unsigned int v2 = quad[(i + 2) % 4]; - - // Check if the indices are valid - if (is_in_bounds[v0] && is_in_bounds[v1] && is_in_bounds[v2]) { - mesh.triangles.emplace_back(new_vertex_indices[v0], new_vertex_indices[v1], new_vertex_indices[v2]); - i++; - } + // Add a new vertex + if (!vertex_index.has_value()) { + vertex_index = new_positions.size(); + new_positions.push_back(vertex); + seen_vertices.emplace(vertex, vertex_index.value()); } + + decomposed_triangle[i] = vertex_index.value(); } + new_triangles.push_back(decomposed_triangle); } } - assert(mesh.triangles.size() <= max_triangle_count); - mesh.positions = std::move(source_positions); - for (glm::dvec3 &position : mesh.positions) { - position = apply_transform(transform_source_mesh.get(), position); + // TODO: derive new_positions from seen_vertices + return reindex_mesh(TerrainMesh(new_triangles, new_positions)); +} + +std::vector generate_uv_space(const std::vector& positions, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds& texture_bounds) { + std::vector uvs = srs::transform_points_to_2d(srs::transformation(mesh_srs, texture_srs).get(), positions); + texture_bounds = radix::tile::SrsBounds(radix::geometry::find_bounds(uvs)); + + for (glm::dvec2 &uv : uvs) { + uv = (uv - texture_bounds.min) / texture_bounds.size(); + } + + return uvs; +} + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + +tl::expected build_reference_mesh_tile( + Dataset &dataset, + const OGRSpatialReference &mesh_srs, + const OGRSpatialReference &tile_srs, const radix::tile::SrsBounds &tile_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds) { + return build_reference_mesh_patch(dataset, mesh_srs, tile_srs, extend_bounds_to_3d(tile_bounds), texture_srs, texture_bounds); +} + +tl::expected build_reference_mesh_patch( + Dataset &dataset, + const OGRSpatialReference &mesh_srs, + const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds) { + const OGRSpatialReference &source_srs = dataset.srs(); + + // Translate tile bounds from tile srs into the source srs, so we know what data to read. + radix::tile::SrsBounds target_bounds_in_source_srs; + if (std::isinf(clip_bounds.min.z) && std::isinf(clip_bounds.max.z)) { + // Make target bounds 2d if the unbounded by height. + target_bounds_in_source_srs = srs::encompassing_bounds_transfer(clip_srs, source_srs, radix::tile::SrsBounds(clip_bounds)); + } else { + target_bounds_in_source_srs = srs::encompassing_bounds_transfer(clip_srs, source_srs, clip_bounds); + } + + // Read height data according to bounds directly from dataset (no interpolation). + RawDatasetReader reader(dataset); + radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(target_bounds_in_source_srs); + add_border_to_aabb(pixel_bounds, Border(1)); + LOG_TRACE("Reading pixels [({}, {})-({}, {})] from dataset", pixel_bounds.min.x, pixel_bounds.min.y, pixel_bounds.max.x, pixel_bounds.max.y); + const std::optional read_result = reader.read_data_in_pixel_bounds(pixel_bounds, true); + if (!read_result.has_value() || read_result->size() == 0) { + return tl::unexpected(BuildError::OutOfBounds); } - assert(mesh.positions.size() == actual_vertex_count); + const raster::HeightMap height_map = read_result.value(); + + LOG_TRACE("Finding valid pixels"); + const raster::Mask valid_mask = raster::transform(height_map, is_valid); + + LOG_TRACE("Transforming pixels to vertices"); + const raster::Raster source_points = raster::transform(height_map, valid_mask, [&](const float height, const raster::Coords& coords) { + return convert_pixel_to_vertex(height, coords, reader, pixel_bounds); + }); - // Sadly all that work above trying to only include vertices that will appear in a triangle - // is not enough for some configurations with non inclusive bounds or when there are invalid vertices. - // Thus we have to filter any loose vertices here. - remove_isolated_vertices(mesh); + LOG_TRACE("Generating triangles"); + const TerrainMesh mesh_in_source_srs = meshify(source_points, valid_mask); + // Check if we even have any valid vertices. Can happen if all of the region is padding. + if (mesh_in_source_srs.vertex_count() == 0 || mesh_in_source_srs.face_count() == 0) { + return tl::unexpected(BuildError::EmptyRegion); + } - // Now validate the final mesh - validate_mesh(mesh); + LOG_TRACE("Clipping mesh based on target bounds"); + const TerrainMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); + TerrainMesh clipped_mesh = clip_mesh(mesh_in_clip_srs, clip_bounds); + // Check if there are any vertices left + if (clipped_mesh.vertex_count() == 0 || clipped_mesh.face_count() == 0) { + return tl::unexpected(BuildError::EmptyRegion); + } - tile_bounds = actual_tile_bounds; - texture_bounds = actual_texture_bounds; + // TODO: move this to another function? + LOG_TRACE("Generating uv space and calculating required texture bounds"); + clipped_mesh.uvs = generate_uv_space(clipped_mesh.positions, clip_srs, texture_srs, texture_bounds); - return mesh; + LOG_TRACE("Transforming mesh into output srs"); + TerrainMesh target_mesh = transform_mesh(clipped_mesh, clip_srs, mesh_srs); + + remove_isolated_vertices(target_mesh); // TODO: is this still required? + validate_mesh(target_mesh); + return target_mesh; } } // namespace terrainbuilder::mesh diff --git a/src/terrainbuilder/mesh_builder.h b/src/terrainbuilder/mesh_builder.h index 0d1c4b8..feadc3c 100644 --- a/src/terrainbuilder/mesh_builder.h +++ b/src/terrainbuilder/mesh_builder.h @@ -15,15 +15,14 @@ enum class BuildError { OutOfBounds, EmptyRegion }; +std::ostream &operator<<(std::ostream &os, BuildError error); /// Builds a mesh from the given height dataset. -tl::expected build_reference_mesh_tile( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, radix::tile::SrsBounds &tile_bounds, - const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds, - const Border &vertex_border, - const bool inclusive_bounds); + const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, + const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds); } #endif diff --git a/src/terrainbuilder/octree/id.h b/src/terrainbuilder/octree/id.h new file mode 100644 index 0000000..00c35cc --- /dev/null +++ b/src/terrainbuilder/octree/id.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace octree { + +class Id { +public: + constexpr Id(uint32_t level, glm::uvec3 coords) + : _level(level), _index(interleave3(coords)) {} + constexpr Id(uint32_t level, uint64_t index) + : _level(level), _index(index) {} + + constexpr uint32_t level() const { + return this->_level; + } + constexpr uint64_t index_on_level() const { + return this->_index; + } + constexpr glm::uvec3 coords() const { + return deinterleave3(this->index_on_level()); + } + constexpr uint32_t x() const { + return this->coords().x; + } + constexpr uint32_t y() const { + return this->coords().y; + } + constexpr uint32_t z() const { + return this->coords().z; + } + + constexpr std::optional neighbour(const glm::ivec3& d) const { + const auto new_coords = glm::ivec3(this->coords()) + d; + if (new_coords.x < 0 || new_coords.y < 0 || new_coords.z < 0) { + // throw std::out_of_range("Neighbour coordinates cannot be negative"); + return std::nullopt; + } + return Id(this->level(), glm::uvec3(new_coords)); + } + + constexpr std::vector neighbours() const { + std::vector result; + result.reserve(26); + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + for (int dz = -1; dz <= 1; dz++) { + if (dx == 0 && dy == 0 && dz == 0) { + continue; // Skip the center itself + } + + const glm::ivec3 offset(dx, dy, dz); + const auto neighbour = this->neighbour({dx, dy, dz}); + if (!neighbour.has_value()) { + continue; + } + result.push_back(neighbour.value()); + } + } + } + return result; + } + + constexpr std::optional parent() const { + if (this->level() == 0) { + return std::nullopt; + } + + const auto parent_coords = this->coords() / glm::uvec3(2); + return Id(this->level() - 1, parent_coords); + } + + constexpr Id child(uint32_t child_index) const { + if (child_index > 7) { + throw std::invalid_argument("Invalid child index (must be 0-7)"); + } + return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); + } + + constexpr std::array children() const { + return { + this->child(0), this->child(1), this->child(2), this->child(3), + this->child(4), this->child(5), this->child(6), this->child(7) + }; + } + + static constexpr Id root() { + return Id(0, 0); + } + + bool operator==(const Id &other) const { + return this->_level == other._level && this->_index == other._index; + } + +private: + uint32_t _level; + uint64_t _index; + + static constexpr uint64_t interleave3(const glm::uvec3 &coords) { + const uint64_t x = coords.x; + const uint64_t y = coords.y; + const uint64_t z = coords.z; + + uint64_t result = 0; + for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + result |= ((x >> i) & 1) << (3 * i); + result |= ((y >> i) & 1) << (3 * i + 1); + result |= ((z >> i) & 1) << (3 * i + 2); + } + return result; + } + + static constexpr glm::uvec3 deinterleave3(uint64_t index) { + uint32_t x = 0; + uint32_t y = 0; + uint32_t z = 0; + for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + x |= ((index >> (3 * i)) & 1) << i; + y |= ((index >> (3 * i + 1)) & 1) << i; + z |= ((index >> (3 * i + 2)) & 1) << i; + } + return {x, y, z}; + } +}; + +} // namespace octree + +template <> +struct fmt::formatter { + // Parses format specifications; here we ignore them. + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + // Format the Id object. + template + auto format(const octree::Id &id, FormatContext &ctx) { + return fmt::format_to( + ctx.out(), + "Id(level={}, coords=({}, {}, {}), index={})", + id.level(), id.x(), id.y(), id.z(), id.index_on_level()); + } +}; +#include +#include +namespace octree{ +inline std::string to_string(const octree::Id &id) { + return fmt::format("{}", id); +} +inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { + fmt::print(os, "{}", id); + return os; +} +} diff --git a/src/terrainbuilder/octree/space.h b/src/terrainbuilder/octree/space.h new file mode 100644 index 0000000..d1ae7d2 --- /dev/null +++ b/src/terrainbuilder/octree/space.h @@ -0,0 +1,120 @@ +#pragma once + +#include + +#include "id.h" + +namespace octree { +using Bounds = radix::geometry::Aabb3d; + +class Space { +public: + const Bounds bounds; + + static constexpr Space earth() { + const float max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) + const float extends = max_radius * 1.1; // TODO: how much padding do we want here + return Space(Bounds( + {-extends, -extends, -extends}, {extends, extends, extends})); + } + + std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { + // We don't want to recurse indefinitely if the bounds are empty. + const glm::dvec3 target_size = target_bounds.size(); + if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { + throw std::invalid_argument("target bounds cannot be empty"); + } + + const std::array corners = radix::geometry::corners(target_bounds); + + const Bounds root_bounds = get_node_bounds(root); + // Check if all points of the target bounds are inside the root bounds. + bool all_corners_inside_root = true; + for (const auto &corner : corners) { + if (!root_bounds.contains_inclusive(corner)) { + all_corners_inside_root = false; + break; + } + } + + if (!all_corners_inside_root) { + return std::nullopt; // Target bounds are outside the defined space. + } + + Id current_smallest_encompassing_node = root; + while (true) { + const std::array children = current_smallest_encompassing_node.children(); + std::optional next_smallest; + + for (const auto &child : children) { + const Bounds child_bounds = get_node_bounds(child); + bool all_corners_inside_child = true; + for (const auto &corner : corners) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside_child = false; + break; + } + } + + if (all_corners_inside_child) { + next_smallest = child; + break; // Found a child that fully contains the bounds, go deeper. + } + } + + if (next_smallest.has_value()) { + current_smallest_encompassing_node = next_smallest.value(); + } else { + break; // No child fully contains the bounds, so the current node is the smallest. + } + } + + return current_smallest_encompassing_node; + } + + std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { + Id current = root; + const Bounds root_bounds = this->get_node_bounds(current); + if (!root_bounds.contains_exclusive(point)) { + return std::nullopt; + } + + while (current.level() < target_level) { + for (const auto& child : current.children()) { + const Bounds child_bounds = this->get_node_bounds(child); + if (child_bounds.contains_exclusive(point)) { + current = child; + break; + } + } + } + + return current; + } + + Bounds get_node_bounds(const Id &id) const { + const auto coords = id.coords(); + const uint32_t level = id.level(); + const uint32_t resolution = 1 << level; + + // Calculate the size of a node at this level + const glm::dvec3 bounds_size = bounds.size(); + const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); + + // Calculate the minimum point of the node + const glm::dvec3 min_bound = bounds.min; + const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; + + // Calculate the maximum point of the node + const glm::dvec3 node_max = node_min + node_size; + + Bounds node_bounds; + node_bounds.min = node_min; + node_bounds.max = node_max; + return node_bounds; + } + +private: +}; + +} // namespace octree diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainbuilder/octree/storage.h new file mode 100644 index 0000000..bb8831b --- /dev/null +++ b/src/terrainbuilder/octree/storage.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include + +#include "id.h" +#include "mesh/io.h" +#include "mesh/terrain_mesh.h" + +namespace octree { +using Node = TerrainMesh; + +class Storage { + public: + Storage(const std::filesystem::path &basePath) : base_path(basePath) {} + + std::optional load_node(const Id &id) const { + const auto node_path = this->get_node_path(id); + const auto result = io::load_mesh_from_path(node_path); + if (result.has_value()) { + return result.value(); + } else { + return std::nullopt; + } + } + + bool save_node(const Id &id, const Node &node) const { + const auto node_path = this->get_node_path(id); + const auto result = io::save_mesh_to_path(node_path, node); + return result.has_value(); + } + + bool has_node(const Id &id) const { + return std::filesystem::exists(this->get_node_path(id)); + } + + private: + std::filesystem::path get_node_path(const Id &id) const { + return base_path / std::to_string(id.level()) / std::to_string(id.x()) / (std::to_string(id.y()) + ".gltf"); + } + + private: + const std::filesystem::path base_path; +}; +} diff --git a/src/terrainbuilder/octree/utils.cpp b/src/terrainbuilder/octree/utils.cpp new file mode 100644 index 0000000..2916c30 --- /dev/null +++ b/src/terrainbuilder/octree/utils.cpp @@ -0,0 +1,2 @@ +#include "utils.h" + diff --git a/src/terrainbuilder/octree/utils.h b/src/terrainbuilder/octree/utils.h new file mode 100644 index 0000000..6eb734b --- /dev/null +++ b/src/terrainbuilder/octree/utils.h @@ -0,0 +1,10 @@ +#pragma once + +#include "id.h" + +#include +#include + +namespace octree { + +} // namespace octree diff --git a/src/terrainbuilder/raster.h b/src/terrainbuilder/raster.h new file mode 100644 index 0000000..3a53587 --- /dev/null +++ b/src/terrainbuilder/raster.h @@ -0,0 +1,144 @@ +#pragma once + +#include +#include +#include +#include + +namespace raster { + +using Index = size_t; +using Coords = glm::vec<2, size_t>; + +template +class Raster { +public: + Raster() = default; + Raster(Index width, Index height) + : _width(width), _height(height), _data(width * height) { + } + + [[nodiscard]] Index width() const { + return this->_width; + } + [[nodiscard]] Index height() const { + return this->_height; + } + [[nodiscard]] decltype(auto) pixel(const Coords &coords) { + assert(coords.x < this->_width); + assert(coords.y < this->_height); + const Index pixel_index = this->index(coords); + if constexpr (std::is_same_v) { + return static_cast(this->_data[pixel_index]); + } else { + return static_cast(this->_data[pixel_index]); + } + } + [[nodiscard]] decltype(auto) pixel(const Coords &coords) const { + assert(coords.x < this->_width); + assert(coords.y < this->_height); + const Index pixel_index = this->index(coords); + if constexpr (std::is_same_v) { + return static_cast(this->_data[pixel_index]); + } else { + return static_cast(this->_data[pixel_index]); + } + } + + [[nodiscard]] Index index(const Coords& coords) const { + return coords.y * this->_width + coords.x; + } + + [[nodiscard]] T *data() { + return this->_data.data(); + } + [[nodiscard]] const T *data() const { + return this->_data.data(); + } + + [[nodiscard]] Index size() const { + return this->_data.size(); + } + [[nodiscard]] auto begin() { + return this->_data.begin(); + } + [[nodiscard]] auto end() { + return this->_data.end(); + } + [[nodiscard]] auto begin() const { + return this->_data.begin(); + } + [[nodiscard]] auto end() const { + return this->_data.end(); + } + +private: + unsigned _width = 0; + unsigned _height = 0; + std::vector _data; +}; + +using Mask = Raster; +using HeightMap = Raster; + +template +concept TransformFn = requires(F f, In in) { + { f(in) }; +}; + +template +concept TransformFnWithCoords = requires(F f, In in, Coords coord) { + { f(in, coord) }; +}; + +template F> +[[nodiscard]] auto transform(const Raster &input, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)))); + Raster output(input.width(), input.height()); + std::transform(input.begin(), input.end(), output.begin(), std::forward(f)); + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0), Coords(0, 0)))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + output.pixel(coords) = std::forward(f)(input.pixel(coords), coords); + } + } + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, const Mask &mask, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + if (mask.pixel(coords)) { + output.pixel(coords) = std::forward(f)(input.pixel(coords)); + } + } + } + return output; +} + +template F> +[[nodiscard]] auto transform(const Raster &input, const Mask &mask, F &&f) { + using Out = decltype(f(input.pixel(Coords(0, 0)), Coords(0, 0))); + Raster output(input.width(), input.height()); + for (Index y = 0; y < input.height(); ++y) { + for (Index x = 0; x < input.width(); ++x) { + Coords coords(x, y); + if (mask.pixel(coords)) { + output.pixel(coords) = std::forward(f)(input.pixel(coords), coords); + } + } + } + return output; +} +} \ No newline at end of file diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/terrainbuilder/raw_dataset_reader.h index e2afbf6..49026db 100644 --- a/src/terrainbuilder/raw_dataset_reader.h +++ b/src/terrainbuilder/raw_dataset_reader.h @@ -8,6 +8,7 @@ #include #include "log.h" +#include "raster.h" namespace terrainbuilder { @@ -39,7 +40,8 @@ class RawDatasetReader { return glm::uvec2(heights_band->GetXSize(), heights_band->GetYSize()); } - std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { + // TODO: support reading other data types + std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { if (clamp_bounds) { const glm::ivec2 max_in_bounds = glm::ivec2(this->dataset_size()) - glm::ivec2(1); bounds.min = glm::clamp(bounds.min, glm::ivec2(0), max_in_bounds); @@ -55,7 +57,7 @@ class RawDatasetReader { GDALRasterBand *heights_band = this->dataset->GetRasterBand(1); // non-owning pointer // Initialize the HeightData for reading - HeightData height_data(bounds.width(), bounds.height()); + raster::HeightMap height_data(bounds.width(), bounds.height()); if (bounds.width() == 0 || bounds.height() == 0) { if (clamp_bounds) { LOG_WARN("Target dataset bounds are empty (clamped)"); @@ -79,7 +81,7 @@ class RawDatasetReader { return height_data; } - std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { + std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { // Transform the SrsBounds to pixel space const radix::geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index e30cdd8..203e54c 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -14,9 +14,11 @@ #include "mesh/io.h" #include "mesh/terrain_mesh.h" #include "mesh_builder.h" +#include "terrainbuilder.h" #include "texture_assembler.h" #include "tile_provider.h" -#include "terrainbuilder.h" + +#include "octree/space.h" namespace terrainbuilder { @@ -43,57 +45,45 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { void build( Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, - const OGRSpatialReference &texture_srs, - const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path) { const ctb::Grid grid = ctb::GlobalMercator(); - - radix::tile::SrsBounds target_tile_bounds(tile_bounds); radix::tile::SrsBounds texture_bounds; std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); LOG_INFO("Building mesh..."); - tl::expected mesh_result = mesh::build_reference_mesh_tile( + tl::expected mesh_result = mesh::build_reference_mesh_patch( dataset, mesh_srs, - tile_srs, target_tile_bounds, - texture_srs, texture_bounds, - Border(0, 1, 1, 0), - true); + target_bounds_srs, target_bounds, + texture_srs, texture_bounds); if (!mesh_result.has_value()) { const mesh::BuildError error = mesh_result.error(); if (error == mesh::BuildError::OutOfBounds) { const radix::tile::SrsBounds dataset_bounds = dataset.bounds(); - const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); - const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); + // const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_ERROR("Target bounds are fully outside of dataset region\n" "Dataset {{\n" - "\tBounds {{x={}, y={}, w={}, h={}}}.\n" - "\tLargest Contained Tile {{zoom={}, x={}, y={}}}.\n" - "\tSmallest Encompassing Tile {{zoom={}, x={}, y={}}}.\n" + "\t x={}, y={}, w={}, h={}.\n" "}}\n" "Target {{\n" - "\tBounds {{x={}, y={}, w={}, h={}}}.\n" - "\tLargest Contained Tile {{zoom={}, x={}, y={}}}.\n" - "\tSmallest Encompassing Tile {{zoom={}, x={}, y={}}}.\n" + "\t x={}, y={}, w={}, h={}.\n" "}}", dataset_bounds.min.x, dataset_bounds.min.y, dataset_bounds.width(), dataset_bounds.height(), - dataset_largest_tile.zoom_level, dataset_largest_tile.coords.x, dataset_largest_tile.coords.y, - dataset_encompassing_tile.zoom_level, dataset_encompassing_tile.coords.x, dataset_encompassing_tile.coords.y, - tile_bounds.min.x, tile_bounds.min.y, tile_bounds.width(), tile_bounds.height(), - target_largest_tile.zoom_level, target_largest_tile.coords.x, target_largest_tile.coords.y, - target_encompassing_tile.zoom_level, target_encompassing_tile.coords.x, target_encompassing_tile.coords.y); + target_bounds.min.x, target_bounds.min.y, target_bounds.size().x, target_bounds.size().y); + exit(1); } else if (error == mesh::BuildError::EmptyRegion) { - LOG_ERROR("Target bounds are inside dataset, but the region is empty (only made up of padding)"); + LOG_WARN("Target bounds are inside dataset, but the region is empty"); + exit(0); } - - exit(1); } TerrainMesh mesh = mesh_result.value(); LOG_DEBUG("Mesh building took {}s", format_secs_since(start)); @@ -105,7 +95,7 @@ void build( BasemapSchemeTilePathProvider tile_provider(texture_base_path.value()); std::optional texture = texture::assemble_texture_from_tiles(grid, texture_srs, texture_bounds, tile_provider); if (!texture.has_value()) { - LOG_ERROR("Failed to assemble tile texture"); + LOG_ERROR("Failed to assemble texture"); exit(1); } mesh.texture = texture; @@ -120,6 +110,8 @@ void build( start = std::chrono::high_resolution_clock::now(); // TODO: use a JSON libary instead std::unordered_map metadata; + // TODO: redo + /*/ metadata["mesh_srs"] = mesh_srs.GetAuthorityCode(nullptr); metadata["bounds_srs"] = tile_srs.GetAuthorityCode(nullptr); metadata["texture_srs"] = texture_srs.GetAuthorityCode(nullptr); @@ -129,6 +121,7 @@ void build( metadata["texture_bounds"] = fmt::format( "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); + */ if (!io::save_mesh_to_path(output_path, mesh, io::SaveOptions{.metadata = metadata}).has_value()) { LOG_ERROR("Failed to save mesh to file {}", output_path.string()); exit(2); diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index 0254f10..e77a58d 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -12,11 +12,11 @@ namespace terrainbuilder { void build( Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, - const OGRSpatialReference &tile_srs, - const OGRSpatialReference &texture_srs, - const radix::tile::SrsBounds &tile_bounds, const std::filesystem::path &output_path); } diff --git a/src/terrainbuilder/texture_assembler.h b/src/terrainbuilder/texture_assembler.h index 06a09e6..253231f 100644 --- a/src/terrainbuilder/texture_assembler.h +++ b/src/terrainbuilder/texture_assembler.h @@ -282,7 +282,7 @@ std::optional try_get_tile_path(const radix::tile::Id til } // Start by transforming the input bounds into the srs the tiles are in. - const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounding_box_transfer(target_srs, grid.getSRS(), target_bounds); + const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounds_transfer(target_srs, grid.getSRS(), target_bounds); // Then we find the smallest tile (id) that encompasses these bounds. const radix::tile::Id smallest_encompassing_tile = grid.findSmallestEncompassingTile(encompassing_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_TRACE("Smallest encompassing tile for texture bounds is [{}, ({}, {})]", diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index d87daea..512a41c 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -190,12 +190,12 @@ double Dataset::gridResolution(const OGRSpatialReference& target_srs) const double Dataset::pixelWidthIn(const OGRSpatialReference& target_srs) const { const auto b0 = bounds(); - const auto b1 = srs::nonExactBoundsTransform(b0, srs(), target_srs); + const auto b1 = srs::non_exact_bounds_transform(b0, srs(), target_srs); return b1.width() / widthInPixels(); } double Dataset::pixelHeightIn(const OGRSpatialReference& target_srs) const { - const auto b = srs::nonExactBoundsTransform(bounds(), srs(), target_srs); + const auto b = srs::non_exact_bounds_transform(bounds(), srs(), target_srs); return b.height() / heightInPixels(); } diff --git a/src/terrainlib/mesh/terrain_mesh.cpp b/src/terrainlib/mesh/terrain_mesh.cpp index e3d7fc4..f71ea7b 100644 --- a/src/terrainlib/mesh/terrain_mesh.cpp +++ b/src/terrainlib/mesh/terrain_mesh.cpp @@ -1,3 +1,4 @@ +#include #include #include "terrain_mesh.h" @@ -27,6 +28,42 @@ radix::geometry::Aabb<3, double> calculate_bounds(std::span m return bounds; } +std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size) { + const auto &triangles = mesh.triangles; + if (triangles.empty()) { + return std::nullopt; + } + + // Random sampling setup + std::vector sampled_triangles; + sampled_triangles.reserve(std::min(sample_size, triangles.size())); + + std::random_device rd; + std::mt19937 rng(rd()); + std::sample(triangles.begin(), triangles.end(), + std::back_inserter(sampled_triangles), + std::min(sample_size, triangles.size()), + rng); + + double total_length = 0.0; + size_t edge_count = 0; + + for (const auto &tri : sampled_triangles) { + const glm::dvec3 &a = mesh.positions[tri.x]; + const glm::dvec3 &b = mesh.positions[tri.y]; + const glm::dvec3 &c = mesh.positions[tri.z]; + + total_length += glm::distance(a, b); + total_length += glm::distance(b, c); + total_length += glm::distance(c, a); + + edge_count += 3; + } + + assert(edge_count > 0); + return total_length / edge_count; +} + std::vector find_isolated_vertices(const TerrainMesh& mesh) { std::vector connected; connected.resize(mesh.vertex_count()); diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index 6d9b76a..627196f 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -21,8 +21,10 @@ class TerrainMesh { using Texture = cv::Mat; using serialize = zpp::bits::members<4>; - TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs) : - TerrainMesh(triangles, positions, uvs, std::nullopt) {} + TerrainMesh(std::vector triangles, std::vector positions) + : TerrainMesh(triangles, positions, {}) {} + TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs) + : TerrainMesh(triangles, positions, uvs, std::nullopt) {} TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) : TerrainMesh(triangles, positions, uvs, std::optional(std::move(texture))) {} TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) @@ -56,6 +58,8 @@ class TerrainMesh { radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes); +std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size = 1000); + std::vector find_isolated_vertices(const TerrainMesh& mesh); size_t remove_isolated_vertices(TerrainMesh& mesh); size_t remove_triangles_of_negligible_size(TerrainMesh& mesh, const double threshold_percentage_of_average = 0.001); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index bf413b3..ea6c608 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -34,113 +34,301 @@ namespace srs { -inline std::unique_ptr transformation(const OGRSpatialReference& source, const OGRSpatialReference& targetSrs) -{ - const auto data_srs = source; - auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&data_srs, &targetSrs)); - if (!transformer) +inline std::unique_ptr transformation(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs) { + auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&source_srs, &target_srs)); + if (!transformer) { throw Exception("Couldn't create SRS transformation"); + } return transformer; } -// this transform is non exact, because we are only transforming the corner vertices. however, due to projection warping, a rectangle can become an trapezoid with curved edges. -inline radix::tile::SrsBounds nonExactBoundsTransform(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { - const auto transform = transformation(sourceSrs, targetSrs); - std::array xes = { bounds.min.x, bounds.max.x }; - std::array yes = { bounds.min.y, bounds.max.y }; - if (!transform->Transform(2, xes.data(), yes.data())) - throw Exception("nonExactBoundsTransform failed"); - return { {xes[0], yes[0]}, {xes[1], yes[1]} }; +template +inline glm::tvec2 transform_point(OGRCoordinateTransformation *transform, glm::tvec2 p) { + if (!transform->Transform(1, &p.x, &p.y)) + throw Exception("srs::transform_point(glm::tvec2) failed"); + return p; } - template -inline glm::tvec3 to(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs, glm::tvec3 p) -{ - const auto transform = transformation(source_srs, target_srs); +inline glm::tvec3 transform_point(OGRCoordinateTransformation *transform, glm::tvec3 p) { if (!transform->Transform(1, &p.x, &p.y, &p.z)) - throw Exception("srs::to(glm::tvec3) failed"); + throw Exception("srs::transform_point(glm::tvec3) failed"); return p; } template -inline glm::tvec2 to(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, glm::tvec2 p) { +inline glm::tvec2 transform_point(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, glm::tvec2 p) { const auto transform = transformation(source_srs, target_srs); - if (!transform->Transform(1, &p.x, &p.y)) - throw Exception("srs::to(glm::tvec2) failed"); - return p; + return transform_point(transform.get(), p); } - template -inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) -{ - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - return to(source_srs, ecef_srs, p); +inline glm::tvec3 transform_point(const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs, glm::tvec3 p){ + const auto transform = transformation(source_srs, target_srs); + return transform_point(transform.get(), p); } +template +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { + std::array xs; + std::array ys; + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data())) { + throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + } + + for (size_t i = 0; i < points.size(); ++i) { + points[i] = {xs[i], ys[i]}; + } +} template -inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) -{ - std::vector xes; +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { + std::vector xs; std::vector ys; - std::vector zs; - xes.reserve(points.size()); - ys.reserve(points.size()); - zs.reserve(points.size()); - for (const auto& p : points) { - xes.push_back(p.x); - ys.push_back(p.y); - zs.push_back(p.z); + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; } - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto transform = transformation(source_srs, ecef_srs); - if (!transform->Transform(int(points.size()), xes.data(), ys.data(), zs.data())) - throw Exception("toECEF(glm::tvec3) failed"); + if (!transform->Transform(points.size(), xs.data(), ys.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } for (size_t i = 0; i < points.size(); ++i) { - points[i] = { xes[i], ys[i], zs[i] }; + points[i] = {xs[i], ys[i]}; } - return points; } template -inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) -{ - std::array xes; +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { + std::array xs; std::array ys; std::array zs; + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + zs[i] = points[i].z; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + } + for (size_t i = 0; i < points.size(); ++i) { - xes[i] = points[i].x; + points[i] = {xs[i], ys[i], zs[i]}; + } +} +template +inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { + std::vector xs; + std::vector ys; + std::vector zs; + + xs.resize(points.size()); + ys.resize(points.size()); + zs.resize(points.size()); + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; ys[i] = points[i].y; zs[i] = points[i].z; } - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto transform = transformation(source_srs, ecef_srs); - if (!transform->Transform(points.size(), xes.data(), ys.data(), zs.data())) - throw Exception("toECEF(glm::tvec3) failed"); + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } for (size_t i = 0; i < points.size(); ++i) { - points[i] = { xes[i], ys[i], zs[i] }; + points[i] = {xs[i], ys[i], zs[i]}; } +} + +template +inline Container transform_points(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, Container points) { + const auto transform = transformation(source_srs, target_srs); + transform_points_inplace(transform.get(), points); return points; } + +// TODO: somehow integrate into a single transform_points +template +inline std::vector> transform_points_to_2d(OGRCoordinateTransformation *transform, const std::vector> &points) { + std::vector xs; + std::vector ys; + std::vector zs; + + xs.resize(points.size()); + ys.resize(points.size()); + zs.resize(points.size()); + + for (size_t i = 0; i < points.size(); i++) { + xs[i] = points[i].x; + ys[i] = points[i].y; + zs[i] = points[i].z; + } + + if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { + throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + } + + std::vector> transformed; + transformed.resize(points.size()); + for (size_t i = 0; i < points.size(); ++i) { + transformed[i] = {xs[i], ys[i]}; + } + + return transformed; +} + +inline radix::tile::SrsBounds non_exact_bounds_transform(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { + const auto transform = transformation(sourceSrs, targetSrs); + std::array xs = {bounds.min.x, bounds.max.x}; + std::array ys = {bounds.min.y, bounds.max.y}; + if (!transform->Transform(2, xs.data(), ys.data())) { + throw Exception("srs::non_exact_bounds_transform failed"); + } + return {{xs[0], ys[0]}, {xs[1], ys[1]}}; +} + +inline radix::geometry::Aabb3d non_exact_bounds_transform(const radix::geometry::Aabb3d &bounds, const OGRSpatialReference &sourceSrs, const OGRSpatialReference &targetSrs) { + const auto transform = transformation(sourceSrs, targetSrs); + std::array xs = {bounds.min.x, bounds.max.x}; + std::array ys = {bounds.min.y, bounds.max.y}; + std::array zs = {bounds.min.z, bounds.max.z}; + if (!transform->Transform(2, xs.data(), ys.data(), zs.data())) { + throw Exception("srs::non_exact_bounds_transform failed"); + } + return {{xs[0], ys[0], zs[0]}, {xs[1], ys[1], zs[1]}}; +} + +/// Transforms bounds from one srs to another, +/// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. +/// But there can be points inside the new bounds that were not present in the original ones. +inline radix::tile::SrsBounds encompassing_bounds_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); + radix::tile::SrsBounds target_bounds; + const int result = transformation->TransformBounds( + source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, + &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, + 21); + if (result != TRUE) { + throw std::runtime_error("srs::encompassing_bounding_box_transfer failed"); + } + return target_bounds; +} + +inline radix::geometry::Aabb3d encompassing_bounds_transfer( + const OGRSpatialReference &source_srs, + const OGRSpatialReference &target_srs, + const radix::geometry::Aabb3d &source_bounds, + const uint32_t intermediate_points_edges = 21, + const uint32_t intermediate_points_faces = 5) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + std::vector points; + + // Add corner points + const auto corners = radix::geometry::corners(source_bounds); + std::copy(corners.begin(), corners.end(), std::back_inserter(points)); + + // Sample points on the edges + const auto edges = radix::geometry::edges(source_bounds); + for (const auto &edge : edges) { + const auto &[p0, p1] = edge; + + for (uint32_t i = 1; i <= intermediate_points_edges; i++) { + const double t = static_cast(i) / (intermediate_points_edges + 1); + const auto p = glm::mix(p0, p1, t); + points.push_back(p); + } + } + + // TODO: do we need this? + // Sample points on the faces + const auto quads = radix::geometry::quads(source_bounds); + for (const auto &quad : quads) { + const auto &[p0, p1, p2, p3] = quad; + + for (uint32_t i = 1; i <= intermediate_points_faces; i++) { + const double u = static_cast(i) / (intermediate_points_faces + 1); + const auto edge_p0 = glm::mix(p0, p1, u); + const auto edge_p1 = glm::mix(p3, p2, u); + + for (uint32_t j = 1; j <= intermediate_points_faces; j++) { + const double v = static_cast(j) / (intermediate_points_faces + 1); + const auto point = glm::mix(edge_p0, edge_p1, v); + points.push_back(point); + } + } + } + + // Transform all collected points + const auto transform = srs::transformation(source_srs, target_srs); + transform_points_inplace(transform.get(), points); + + // Compute bounds from transformed points + radix::geometry::Aabb3d target_bounds; + target_bounds.min = glm::dvec3(std::numeric_limits::max()); + target_bounds.max = glm::dvec3(std::numeric_limits::min()); + for (const auto &point : points) { + target_bounds.expand_by(point); + } + + return target_bounds; +} + +inline OGRSpatialReference from_epsg(uint32_t epsg) { + OGRSpatialReference srs; + srs.importFromEPSG(epsg); + srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + return srs; +} +inline OGRSpatialReference ecef() { + return from_epsg(4978); +} +inline OGRSpatialReference webmercator() { + return from_epsg(3857); +} +inline OGRSpatialReference wgs84() { + return from_epsg(4326); +} +inline OGRSpatialReference mgi() { + return from_epsg(4312); +} + +// only for tntn +template +inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) { + return transform_point(source_srs, ecef(), p); +} + +template +inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) { + return transform_points(source_srs, ecef(), points); +} + +template +inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) { + return transform_points(source_srs, ecef(), points); +} + template -inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) -{ +inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) { return toECEF(source_srs, { p1, p2 }); } -inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BBox3D& box) -{ +inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BBox3D& box) { constexpr auto n_samples = 100; std::vector points; points.emplace_back(box.min.x, box.min.y, box.min.z); @@ -172,25 +360,6 @@ inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BB return resulting_bbox; } -/// Transforms bounds from one srs to another, -/// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. -/// But there can be points inside the new bounds that were not present in the original ones. -inline radix::tile::SrsBounds encompassing_bounding_box_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { - if (source_srs.IsSame(&target_srs)) { - return source_bounds; - } - - const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); - radix::tile::SrsBounds target_bounds; - const int result = transformation->TransformBounds( - source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, - &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, - 21); - if (result != TRUE) { - throw std::runtime_error("encompassing_bounding_box_transfer failed"); - } - return target_bounds; -} } #endif // SRS_H diff --git a/src/terrainmerger/merge.cpp b/src/terrainmerger/merge.cpp index 9400ba1..ccf945e 100644 --- a/src/terrainmerger/merge.cpp +++ b/src/terrainmerger/merge.cpp @@ -167,15 +167,15 @@ class Grid3d { std::vector grid_data; }; -static geometry::Aabb<3, double> pad_bounds(const geometry::Aabb<3, double> &bounds, const double percentage) { +static radix::geometry::Aabb<3, double> pad_bounds(const radix::geometry::Aabb<3, double> &bounds, const double percentage) { const glm::dvec3 bounds_padding = bounds.size() * percentage; - const geometry::Aabb<3, double> padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + const radix::geometry::Aabb<3, double> padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); return padded_bounds; } template -static Grid3d _construct_grid_for_meshes(const geometry::Aabb<3, double> &bounds, const size_t vertex_count) { - const geometry::Aabb<3, double> padded_bounds = pad_bounds(bounds, 0.01); +static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb<3, double> &bounds, const size_t vertex_count) { + const radix::geometry::Aabb<3, double> padded_bounds = pad_bounds(bounds, 0.01); const double max_extends = max_component(padded_bounds.size()); const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; @@ -187,14 +187,14 @@ static Grid3d _construct_grid_for_meshes(const geometry::Aabb<3, double> &bou template static Grid3d construct_grid_for_mesh(const TerrainMesh &mesh) { - const geometry::Aabb<3, double> bounds = calculate_bounds(mesh); + const radix::geometry::Aabb<3, double> bounds = calculate_bounds(mesh); const size_t vertex_count = mesh.vertex_count(); return _construct_grid_for_meshes(bounds, vertex_count); } template static Grid3d construct_grid_for_meshes(const std::span meshes) { - const geometry::Aabb<3, double> bounds = calculate_bounds(meshes); + const radix::geometry::Aabb<3, double> bounds = calculate_bounds(meshes); const size_t maximal_merged_mesh_size = std::transform_reduce( meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const TerrainMesh &mesh) { return mesh.vertex_count(); }); return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); @@ -480,7 +480,7 @@ static bool are_all_bounds_connected(const std::span meshes) return true; } - std::vector> mesh_bounds; + std::vector> mesh_bounds; mesh_bounds.reserve(meshes.size()); std::transform(meshes.begin(), meshes.end(), std::back_inserter(mesh_bounds), @@ -492,7 +492,7 @@ static bool are_all_bounds_connected(const std::span meshes) continue; } - if (geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { + if (radix::geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { intersect_any_other = true; break; } diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index 6267d2f..65efe05 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -117,8 +117,8 @@ static double measure_max_absolute_error(const SurfaceMesh &original, const Surf return error + bound_on_error; } -static geometry::Aabb<3, double> calculate_bounds(const SurfaceMesh &mesh) { - geometry::Aabb<3, double> bounds; +static radix::geometry::Aabb<3, double> calculate_bounds(const SurfaceMesh &mesh) { + radix::geometry::Aabb<3, double> bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); @@ -190,26 +190,6 @@ static std::pair check_condition(const StopCondition &stop_conditi stop_condition); } -static double get_condition_target(const StopCondition &stop_condition) { - return std::visit(overloaded{ - [&](const VertexRatio &vertex_ratio) { - return vertex_ratio.ratio; - }, - [&](const EdgeRatio &edge_ratio) { - return edge_ratio.ratio; - }, - [&](const FaceRatio &face_ratio) { - return face_ratio.ratio; - }, - [&](const RelativeError &relative_error) { - return relative_error.error_bound; - }, - [&](const AbsoluteError &absolute_error) { - return absolute_error.error_bound; - }}, - stop_condition); -} - static bool is_evaluation_expensive(const StopCondition &stop_condition) { return std::visit(overloaded{ [&](const VertexRatio &) { diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 7f30e8d..2af3f18 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -10,7 +10,7 @@ include(FetchContent) FetchContent_Declare(catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.3.2 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Catch2 + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Catch2 ) FetchContent_MakeAvailable(catch2) @@ -68,21 +68,28 @@ if (ATB_UNITTESTS_DEBUG_IMAGES) else() target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_DEBUG_IMAGES=false") endif() -target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2) +target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2WithMain) add_executable(unittests_terrainmerger catch2_helpers.h terrainmerger/convert.cpp - terrainmerger/merge.cpp) + terrainmerger/merge.cpp +) -target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2::Catch2) +target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2WithMain) add_executable(unittests_terrainbuilder catch2_helpers.h - terrainbuilder/mesh_io.cpp - terrainbuilder/mesh.cpp - terrainbuilder/texture.cpp) -target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2::Catch2 CGAL::CGAL) + terrainbuilder/octree_id.cpp + terrainbuilder/octree_space.cpp + terrainbuilder/mesh2.cpp + # TODO: + # terrainbuilder/mesh_io.cpp + # terrainbuilder/mesh.cpp + # terrainbuilder/texture.cpp +) + +target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain CGAL::CGAL) target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") diff --git a/unittests/catch2_helpers.h b/unittests/catch2_helpers.h index a91b69a..a577a07 100644 --- a/unittests/catch2_helpers.h +++ b/unittests/catch2_helpers.h @@ -20,7 +20,8 @@ #ifndef CATCH2_HELPERS_H #define CATCH2_HELPERS_H -#include +#include +#include #include diff --git a/unittests/terrainbuilder/mesh.cpp b/unittests/terrainbuilder/mesh.cpp index 57c11ee..296091f 100644 --- a/unittests/terrainbuilder/mesh.cpp +++ b/unittests/terrainbuilder/mesh.cpp @@ -112,23 +112,25 @@ void check_non_empty(const TerrainMesh &mesh) { } TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { - const std::vector> tile_test_cases = { - {"tiny tile", "/austria/pizbuin_1m_epsg4326.tif", tile::Id(23, glm::uvec2(4430412, 2955980), tile::Scheme::SlippyMap)}, - {"small tile", "/austria/pizbuin_1m_epsg3857.tif", tile::Id(20, glm::uvec2(553801, 369497), tile::Scheme::SlippyMap)}, - {"tile on the border", "/austria/pizbuin_1m_mgi.tif", tile::Id(18, glm::uvec2(138457, 169781), tile::Scheme::Tms)} + const std::vector> tile_test_cases = { + {"tiny tile", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::Id(23, glm::uvec2(4430412, 2955980), radix::tile::Scheme::SlippyMap)}, + {"small tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap)}, + {"tile on the border", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(18, glm::uvec2(138457, 169781), radix::tile::Scheme::Tms)} #if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED - {"tile slightly larger than dataset", "/austria/pizbuin_1m_mgi.tif", tile::Id(11, glm::uvec2(1081, 721), tile::Scheme::SlippyMap)}, - {"huge tile", "/austria/pizbuin_1m_epsg3857.tif", tile::Id(6, glm::uvec2(33, 41), tile::Scheme::Tms)}, - {"giant tile", "/austria/at_mgi.tif", tile::Id(1, glm::uvec2(1, 0), tile::Scheme::SlippyMap)}, + {"tile slightly larger than dataset", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(11, glm::uvec2(1081, 721), radix::tile::Scheme::SlippyMap)}, + {"huge tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(6, glm::uvec2(33, 41), radix::tile::Scheme::Tms)}, + {"giant tile", "/austria/at_mgi.tif", radix::tile::Id(1, glm::uvec2(1, 0), radix::tile::Scheme::SlippyMap)}, #endif }; + + const ctb::Grid grid = ctb::GlobalMercator(); - std::vector> test_cases = { - {"custom bounds", "/austria/pizbuin_1m_epsg4326.tif", tile::SrsBounds(glm::dvec2(1127962, 5915858), glm::dvec2(1127966, 5915882))}}; + std::vector> test_cases = { + {"custom bounds", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::SrsBounds(glm::dvec2(1127962, 5915858), glm::dvec2(1127966, 5915882))}}; for (const auto &test : tile_test_cases) { const auto [test_name, dataset_suffix, target_tile] = test; - const tile::SrsBounds tile_bounds = grid.srsBounds(target_tile, false); + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(target_tile, false); test_cases.push_back({test_name, dataset_suffix, tile_bounds}); } @@ -146,8 +148,8 @@ TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = target_bounds; output_texture_bounds = target_bounds; @@ -179,11 +181,11 @@ TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { TEST_CASE("neighbouring tiles fit together", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); const std::string dataset_suffix = "/austria/pizbuin_1m_epsg3857.tif"; - const std::array tiles = tile::Id(20, glm::uvec2(553801, 369497), tile::Scheme::SlippyMap).children(); + const std::array tiles = radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap).children(); std::vector tile_meshes; - for (const tile::Id &tile : tiles) { - const tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); + for (const radix::tile::Id &tile : tiles) { + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); DYNAMIC_SECTION(tile) { const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); @@ -195,8 +197,8 @@ TEST_CASE("neighbouring tiles fit together", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = tile_bounds; output_texture_bounds = tile_bounds; @@ -221,12 +223,12 @@ TEST_CASE("neighbouring tiles fit together repeatedly", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); const std::string dataset_suffix = "/austria/innenstadt_gs_1m_mgi.tif"; - const tile::Id root_tile_id(16, glm::uvec2(35748, 22724), tile::Scheme::SlippyMap); + const radix::tile::Id root_tile_id(16, glm::uvec2(35748, 22724), radix::tile::Scheme::SlippyMap); std::vector child_meshes; - for (const tile::Id child_tile_id : root_tile_id.children()) { + for (const radix::tile::Id child_tile_id : root_tile_id.children()) { std::vector grand_child_meshes; - for (const tile::Id grand_child_tile_id : child_tile_id.children()) { - const tile::SrsBounds grand_child_tile_bounds = grid.srsBounds(grand_child_tile_id, false); + for (const radix::tile::Id grand_child_tile_id : child_tile_id.children()) { + const radix::tile::SrsBounds grand_child_tile_bounds = grid.srsBounds(grand_child_tile_id, false); DYNAMIC_SECTION(grand_child_tile_id) { const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); @@ -238,8 +240,8 @@ TEST_CASE("neighbouring tiles fit together repeatedly", "[terrainbuilder]") { ecef_srs.importFromEPSG(4978); ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - tile::SrsBounds output_tile_bounds; - tile::SrsBounds output_texture_bounds; + radix::tile::SrsBounds output_tile_bounds; + radix::tile::SrsBounds output_texture_bounds; output_tile_bounds = grand_child_tile_bounds; output_texture_bounds = grand_child_tile_bounds; diff --git a/unittests/terrainbuilder/mesh2.cpp b/unittests/terrainbuilder/mesh2.cpp new file mode 100644 index 0000000..362b29a --- /dev/null +++ b/unittests/terrainbuilder/mesh2.cpp @@ -0,0 +1,320 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "../catch2_helpers.h" +#include "Dataset.h" +#include "merge.h" +#include "mesh/terrain_mesh.h" +#include "mesh_builder.h" +#include "octree/id.h" +#include "octree/space.h" +#include "srs.h" + +#include "mesh/io.h" + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point3; +typedef CGAL::Surface_mesh SurfaceMesh; +typedef SurfaceMesh::Vertex_index VertexIndex; +typedef SurfaceMesh::Edge_index EdgeIndex; +typedef SurfaceMesh::Halfedge_index HalfEdgeIndex; +typedef SurfaceMesh::Face_index FaceIndex; +typedef boost::graph_traits::vertex_descriptor VertexDescriptor; +typedef boost::graph_traits::halfedge_descriptor HalfedgeDescriptor; + +Point3 glm2cgal(glm::dvec3 point) { + return Point3(point[0], point[1], point[2]); +} + +SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { + SurfaceMesh cgal_mesh; + + for (const glm::dvec3 &position : mesh.positions) { + const CGAL::SM_Vertex_index vertex = cgal_mesh.add_vertex(glm2cgal(position)); + REQUIRE(vertex != SurfaceMesh::null_vertex()); + } + + for (const glm::uvec3 &triangle : mesh.triangles) { + const FaceIndex face = cgal_mesh.add_face( + VertexIndex(triangle.x), + VertexIndex(triangle.y), + VertexIndex(triangle.z)); + + REQUIRE(face != SurfaceMesh::null_face()); + } + + return cgal_mesh; +} + +void check_mesh(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + CHECK(cgal_mesh.is_valid(true)); + CHECK(CGAL::is_triangle_mesh(cgal_mesh)); + CHECK(CGAL::is_valid_polygon_mesh(cgal_mesh, true)); + CHECK_FALSE(CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); +} + +void check_no_holes(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + std::vector border_cycles; + CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); + const size_t nb_holes = border_cycles.size(); + CHECK(nb_holes == 0); +} + +void check_uvs(const TerrainMesh &mesh) { + REQUIRE(mesh.uvs.size() == mesh.positions.size()); + + for (const glm::dvec2 uv : mesh.uvs) { + REQUIRE(glm::all(glm::greaterThanEqual(uv, glm::dvec2(0)))); + REQUIRE(glm::all(glm::lessThanEqual(uv, glm::dvec2(1)))); + } +} + +void check_non_empty(const TerrainMesh &mesh) { + REQUIRE(mesh.positions.size() > 0); + REQUIRE(mesh.triangles.size() > 0); +} + +struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } +}; + +struct DVec3Equal { + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } +}; + +void check_duplicate_vertices(const std::vector &positions) { + std::unordered_set seen; + for (const auto &pos : positions) { + REQUIRE(seen.insert(pos).second); + } +} +/* +void check_duplicate_vertices(const std::vector &positions, double epsilon=1e-8) { + for (size_t i = 0; i < positions.size(); i++) { + for (size_t j = i + 1; j < positions.size(); j++) { + REQUIRE(glm::distance(positions[i], positions[j]) > epsilon); + } + } +} +*/ + +void check_duplicate_triangles(std::vector triangles) { + const auto duplicate_triangles = find_duplicate_triangles(triangles, true); + CHECK(duplicate_triangles == triangles.end()); +} + +template +radix::geometry::Aabb bounds_around_point(const glm::vec centre, const T margin) { + radix::geometry::Aabb bounds; + bounds.min = centre - glm::vec(margin); + bounds.max = centre + glm::vec(margin); + return bounds; +} + +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); +} + +TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuilder]") { + struct TestData { + std::string path_suffix; + radix::geometry::Aabb3d target_bounds; + OGRSpatialReference target_srs; + OGRSpatialReference mesh_srs; + double resolution; // in m + }; + + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const glm::dvec3 steffl_wgs84(16.3735655, 48.2083264, 204); + const glm::dvec3 steffl_ecef = srs::transform_point(wgs84_srs, ecef_srs, steffl_wgs84); + + const std::vector test_data{ + {"/austria/pizbuin_1m_epsg4326.tif", + extend_bounds_to_3d(bounds_around_point(glm::dvec2(pizbuin_summit_wgs84), 0.0001)), + wgs84_srs, + wgs84_srs, + 1}, + {"/austria/pizbuin_1m_mgi.tif", + bounds_around_point(pizbuin_summit_ecef, 50 * 1.), + ecef_srs, + ecef_srs, + 1}, + {"/austria/vienna_20m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 20.), + ecef_srs, + ecef_srs, + 20}, + {"/austria/at_100m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 100.), + ecef_srs, + ecef_srs, + 100}}; + + for (const auto &data : test_data) { + DYNAMIC_SECTION(data.path_suffix) { + Dataset dataset(std::filesystem::path(ATB_TEST_DATA_DIR).concat(data.path_suffix)); + const auto source_srs = dataset.srs(); + const auto &mesh_srs = data.mesh_srs; + const auto &target_srs = data.target_srs; + const auto &target_bounds = data.target_bounds; + const auto resolution = data.resolution; + + radix::tile::SrsBounds texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + mesh_srs, + target_srs, target_bounds, + source_srs, texture_bounds); + if (!result) { + FAIL("Failed to build mesh: " << result.error()); + } + const TerrainMesh mesh = result.value(); + + SECTION("Basic mesh properties") { + check_non_empty(mesh); + check_uvs(mesh); + check_duplicate_vertices(mesh.positions); + check_duplicate_triangles(mesh.triangles); + check_mesh(mesh); + } + + const std::vector positions_in_target_srs = srs::transform_points(mesh_srs, target_srs, mesh.positions); + SECTION("Vertices within target bounds") { + for (const auto &position : positions_in_target_srs) { + REQUIRE(radix::geometry::Aabb2d(target_bounds).contains_inclusive(glm::dvec2(position))); + REQUIRE(target_bounds.contains_inclusive(position)); + } + } + + SECTION("Some vertices on bounds (clipping check)") { + std::vector vertices_on_bounds; + for (const glm::dvec3 position : positions_in_target_srs) { + if (!target_bounds.contains_exclusive(position)) { + vertices_on_bounds.push_back(position); + } + } + CHECK(vertices_on_bounds.size() > 10); + } + + SECTION("Matches dataset resolution") { + const auto positions_in_source_srs = srs::transform_points(mesh_srs, source_srs, mesh.positions); + auto flat_positions_in_source_srs = positions_in_source_srs; + for (auto &pos : flat_positions_in_source_srs) { + pos.z = 0.0; + } + const auto flat_positions_in_ecef_srs = srs::transform_points(source_srs, ecef_srs, flat_positions_in_source_srs); + + const auto target_bounds_2d = radix::geometry::Aabb2d(target_bounds); + const auto padding = target_bounds_2d.size() * 0.1; + const auto inner_min = target_bounds_2d.min + padding; + const auto inner_max = target_bounds_2d.max - padding; + const radix::geometry::Aabb2d inner_bounds_2d{inner_min, inner_max}; + + std::vector filtered_triangles; + for (const auto &tri : mesh.triangles) { + const glm::dvec3 &a = positions_in_target_srs[tri.x]; + const glm::dvec3 &b = positions_in_target_srs[tri.y]; + const glm::dvec3 &c = positions_in_target_srs[tri.z]; + if (inner_bounds_2d.contains_inclusive(a) && + inner_bounds_2d.contains_inclusive(b) && + inner_bounds_2d.contains_inclusive(c)) { + filtered_triangles.push_back(tri); + } + } + TerrainMesh inside_flat_mesh; + inside_flat_mesh.positions = flat_positions_in_ecef_srs; + inside_flat_mesh.triangles = filtered_triangles; + + const auto avg_edge_length = estimate_average_edge_length(inside_flat_mesh); + REQUIRE(avg_edge_length.has_value()); + const auto expected_avg_edge_length = ((1 + 1 + std::sqrt(3)) / 3) * resolution; + CHECK(avg_edge_length.value() == Catch::Approx(expected_avg_edge_length).margin(expected_avg_edge_length * 0.2)); + } + } + } +} + +TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const octree::Space space = octree::Space::earth(); + const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 16).value(); + std::vector nodes = summit_node.neighbours(); + nodes.push_back(summit_node); + + const std::string dataset_suffix = "/austria/pizbuin_1m_mgi.tif"; + const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); + Dataset dataset(dataset_path); + + std::vector node_meshes; + for (const octree::Id &node : nodes) { + const octree::Bounds node_bounds = space.get_node_bounds(node); + radix::tile::SrsBounds output_texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + ecef_srs, + ecef_srs, node_bounds, + webmercator_srs, output_texture_bounds); + if (!result.has_value()) { + continue; + } + const TerrainMesh mesh = result.value(); + node_meshes.push_back(mesh); + } + CHECK(node_meshes.size() >= 3); + + const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-8); + const std::filesystem::path mesh_path = "/mnt/e/Code/TU/2023S/Project/terrain-builder/build/unittests/mesh.glb"; + io::save_mesh_to_path(mesh_path, merged_mesh, io::SaveOptions{.texture_format = ".png"}); + check_non_empty(merged_mesh); + check_no_holes(merged_mesh); +} \ No newline at end of file diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainbuilder/octree_id.cpp new file mode 100644 index 0000000..482f40b --- /dev/null +++ b/unittests/terrainbuilder/octree_id.cpp @@ -0,0 +1,63 @@ +#include + +#include "../catch2_helpers.h" + +#include "octree/id.h" + +using namespace octree; + +TEST_CASE("Id basic construction and accessors", "[octree::Id]") { + Id id(2, glm::uvec3(3, 1, 4)); + CHECK(id.level() == 2); + CHECK(id.coords() == glm::uvec3(3, 1, 4)); + CHECK(id.x() == 3); + CHECK(id.y() == 1); + CHECK(id.z() == 4); +} + +TEST_CASE("Id interleave and deinterleave roundtrip", "[octree::Id]") { + glm::uvec3 coords(1, 2, 3); + Id id(17, coords); + CHECK(id.coords() == coords); +} + +TEST_CASE("Id neighbour within bounds", "[octree::Id]") { + Id id(3, glm::uvec3(4, 4, 4)); + auto neighbor = id.neighbour(glm::ivec3(1, -1, 0)); + REQUIRE(neighbor.has_value()); + CHECK(neighbor.value().coords() == glm::uvec3(5, 3, 4)); +} + +TEST_CASE("Id neighbour out of bounds returns nullopt", "[octree::Id]") { + Id id(3, glm::uvec3(0, 0, 0)); + CHECK_FALSE(id.neighbour(glm::ivec3(-1, 0, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, -1, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, 0, -1)).has_value()); +} + +TEST_CASE("Id parent returns nullopt at root level", "[octree::Id]") { + Id root = Id::root(); + CHECK_FALSE(root.parent().has_value()); +} + +TEST_CASE("Id parent returns correct parent", "[octree::Id]") { + Id id(2, glm::uvec3(6, 4, 2)); + auto parent = id.parent(); + REQUIRE(parent.has_value()); + CHECK(parent->level() == 1); + CHECK(parent->coords() == glm::uvec3(3, 2, 1)); +} + +TEST_CASE("Id child returns correct child", "[octree::Id]") { + Id parent(1, glm::uvec3(1, 1, 1)); + Id child = parent.child(5); + CHECK(child.level() == 2); + CHECK((child.index_on_level() >> 3) == parent.index_on_level()); + CHECK((child.index_on_level() & 7) == 5); +} + +TEST_CASE("Id child throws on invalid index", "[octree::Id]") { + Id parent(1, glm::uvec3(1, 1, 1)); + CHECK_THROWS_AS(parent.child(8), std::invalid_argument); + CHECK_THROWS_AS(parent.child(-1), std::invalid_argument); +} \ No newline at end of file diff --git a/unittests/terrainbuilder/octree_space.cpp b/unittests/terrainbuilder/octree_space.cpp new file mode 100644 index 0000000..6202c51 --- /dev/null +++ b/unittests/terrainbuilder/octree_space.cpp @@ -0,0 +1,113 @@ +#include + +#include "../catch2_helpers.h" + +#include "octree/id.h" +#include "octree/space.h" + +using namespace octree; + +TEST_CASE("find_smallest_node_encompassing_bounds includes full space", "[octree::Space]") { + Space space = Space::earth(); + + auto full_space_id = space.find_smallest_node_encompassing_bounds(space.bounds); + REQUIRE(full_space_id.has_value()); + CHECK(full_space_id.value() == Id::root()); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns more specific child", "[octree::Space]") { + Space space = Space::earth(); + + Bounds inner_box{ + space.bounds.min, + space.bounds.min + space.bounds.size() / 2.0 + }; + + auto id = space.find_smallest_node_encompassing_bounds(inner_box); + REQUIRE(id.has_value()); + CHECK(id->level() == 1); + CHECK(id->coords() == glm::uvec3(0, 0, 0)); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns nullopt for out-of-bounds", "[octree::Space]") { + Space space = Space::earth(); + glm::dvec3 offset = space.bounds.size() * 2.0; + + Bounds far_away{ + space.bounds.min + offset, + space.bounds.min + offset + glm::dvec3(1.0) + }; + + auto id = space.find_smallest_node_encompassing_bounds(far_away); + REQUIRE_FALSE(id.has_value()); +} + +TEST_CASE("find_smallest_node_encompassing_bounds throws on zero-size box", "[octree::Space]") { + Space space = Space::earth(); + glm::dvec3 p = {1.0, 1.0, 1.0}; + + Bounds degenerate{p, p}; + + REQUIRE_THROWS_AS(space.find_smallest_node_encompassing_bounds(degenerate), std::invalid_argument); +} + +TEST_CASE("find_smallest_node_encompassing_bounds returns smallest valid node", "[octree]") { + Space space = Space::earth(); + + // Pick a very small bounds somewhere inside the root + glm::dvec3 offset = space.bounds.size() * 0.1; + glm::dvec3 size = space.bounds.size() * 0.001; + + Bounds target{ + space.bounds.min + offset, + space.bounds.min + offset + size}; + + auto maybe_id = space.find_smallest_node_encompassing_bounds(target); + REQUIRE(maybe_id.has_value()); + Id id = *maybe_id; + + // Get the bounds of that node + Bounds node_bounds = space.get_node_bounds(id); + + // Check that node bounds fully contain the target + for (const auto &corner : radix::geometry::corners(target)) { + REQUIRE(node_bounds.contains_inclusive(corner)); + } + + // Now check that no child of this node fully contains the target + for (const auto &child_id : id.children()) { + Bounds child_bounds = space.get_node_bounds(child_id); + bool all_corners_inside = true; + for (const auto &corner : radix::geometry::corners(target)) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside = false; + break; + } + } + // At least one child must fail to contain the target bounds + REQUIRE_FALSE(all_corners_inside); + } +} + +TEST_CASE("find_smallest_node_encompassing_bounds roundtrips from Id to bounds and back", "[octree]") { + Space space = Space::earth(); + + // Pick a non-root ID + Id original_id{4, {3, 1, 2}}; // Level 4, arbitrary coords + + // Get bounds of this node + Bounds node_bounds = space.get_node_bounds(original_id); + + // Sanity check: bounds should be non-empty + auto size = node_bounds.size(); + REQUIRE(size.x > 0); + REQUIRE(size.y > 0); + REQUIRE(size.z > 0); + + // Find the smallest node encompassing the bounds + auto maybe_id = space.find_smallest_node_encompassing_bounds(node_bounds); + + // It should find exactly the same ID + REQUIRE(maybe_id.has_value()); + REQUIRE(maybe_id.value() == original_id); +} diff --git a/unittests/terrainbuilder/texture.cpp b/unittests/terrainbuilder/texture.cpp index 0c90911..a1903a7 100644 --- a/unittests/terrainbuilder/texture.cpp +++ b/unittests/terrainbuilder/texture.cpp @@ -22,9 +22,6 @@ #include #include -#define CATCH_CONFIG_MAIN -#include - #include #include "../catch2_helpers.h" @@ -38,20 +35,20 @@ TEST_CASE("estimate_zoom_level", "[terrainbuilder]") { const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id tile(20, glm::uvec2(0, 1), tile::Scheme::SlippyMap); - const tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); - const tile::SrsBounds shifted_bounds(tile_bounds.min + glm::dvec2(-100, 420), tile_bounds.max + glm::dvec2(-100, 420)); + const radix::tile::Id tile(20, glm::uvec2(0, 1), radix::tile::Scheme::SlippyMap); + const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); + const radix::tile::SrsBounds shifted_bounds(tile_bounds.min + glm::dvec2(-100, 420), tile_bounds.max + glm::dvec2(-100, 420)); REQUIRE(terrainbuilder::texture::estimate_zoom_level(tile.zoom_level, tile_bounds, shifted_bounds) == tile.zoom_level); } class AvailabilityListEmptyTileProvider : public TileProvider { public: - AvailabilityListEmptyTileProvider(std::set available_tiles) + AvailabilityListEmptyTileProvider(std::set available_tiles) : available_tiles(available_tiles) { } - virtual std::optional get_tile(const tile::Id tile) const override { + virtual std::optional get_tile(const radix::tile::Id tile) const override { if (this->available_tiles.find(tile) != this->available_tiles.end()) { return cv::Mat(); } else { @@ -60,168 +57,168 @@ class AvailabilityListEmptyTileProvider : public TileProvider { } private: - const std::set available_tiles; + const std::set available_tiles; }; class AlwaysEmptyTileProvider : public TileProvider { public: - virtual std::optional get_tile(const tile::Id) const override { + virtual std::optional get_tile(const radix::tile::Id) const override { return cv::Mat(); } }; TEST_CASE("texture assembler takes root tile if only available ", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler ignores parent if all children are present", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}, - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}, + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler considers max zoom level", "[terrainbuilder]") { - const tile::Id root_tile(3, glm::uvec2(5, 4), tile::Scheme::SlippyMap); - const std::set available_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}, - {4, {10, 8}, tile::Scheme::SlippyMap}, - {4, {11, 8}, tile::Scheme::SlippyMap}, - {4, {10, 9}, tile::Scheme::SlippyMap}, - {4, {11, 9}, tile::Scheme::SlippyMap}}; - const std::set expected_tiles = { - {3, {5, 4}, tile::Scheme::SlippyMap}}; + const radix::tile::Id root_tile(3, glm::uvec2(5, 4), radix::tile::Scheme::SlippyMap); + const std::set available_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}, + {4, {10, 8}, radix::tile::Scheme::SlippyMap}, + {4, {11, 8}, radix::tile::Scheme::SlippyMap}, + {4, {10, 9}, radix::tile::Scheme::SlippyMap}, + {4, {11, 9}, radix::tile::Scheme::SlippyMap}}; + const std::set expected_tiles = { + {3, {5, 4}, radix::tile::Scheme::SlippyMap}}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, grid.srsBounds(root_tile, false), tile_provider, 3); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler works for arbitrary bounds", "[terrainbuilder]") { - const std::set available_tiles = { - // {21, {1048576, 1048576}, tile::Scheme::Tms}, - {21, {1048577, 1048576}, tile::Scheme::Tms}, - {21, {1048578, 1048576}, tile::Scheme::Tms}, - {21, {1048579, 1048576}, tile::Scheme::Tms}, - {21, {1048580, 1048576}, tile::Scheme::Tms}, - // {21, {1048581, 1048576}, tile::Scheme::Tms}, - {20, {524288, 524288}, tile::Scheme::Tms}, - {20, {524289, 524288}, tile::Scheme::Tms}, - {20, {524290, 524288}, tile::Scheme::Tms}, - // {19, {262144, 262144}, tile::Scheme::Tms}, - {19, {262145, 262144}, tile::Scheme::Tms}}; - const std::set expected_tiles = { - // {21, {1048576, 1048576}, tile::Scheme::Tms}, - {21, {1048577, 1048576}, tile::Scheme::Tms}, - {21, {1048578, 1048576}, tile::Scheme::Tms}, - {21, {1048579, 1048576}, tile::Scheme::Tms}, - {21, {1048580, 1048576}, tile::Scheme::Tms}, - // {21, {1048581, 1048576}, tile::Scheme::Tms}, - {20, {524288, 524288}, tile::Scheme::Tms}, - // {20, {524289, 524288}, tile::Scheme::Tms}, - {20, {524290, 524288}, tile::Scheme::Tms}, - // {19, {262144, 262144}, tile::Scheme::Tms}, - // {19, {262145, 262144}, tile::Scheme::Tms} + const std::set available_tiles = { + // {21, {1048576, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048577, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048578, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048579, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048580, 1048576}, radix::tile::Scheme::Tms}, + // {21, {1048581, 1048576}, radix::tile::Scheme::Tms}, + {20, {524288, 524288}, radix::tile::Scheme::Tms}, + {20, {524289, 524288}, radix::tile::Scheme::Tms}, + {20, {524290, 524288}, radix::tile::Scheme::Tms}, + // {19, {262144, 262144}, radix::tile::Scheme::Tms}, + {19, {262145, 262144}, radix::tile::Scheme::Tms}}; + const std::set expected_tiles = { + // {21, {1048576, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048577, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048578, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048579, 1048576}, radix::tile::Scheme::Tms}, + {21, {1048580, 1048576}, radix::tile::Scheme::Tms}, + // {21, {1048581, 1048576}, radix::tile::Scheme::Tms}, + {20, {524288, 524288}, radix::tile::Scheme::Tms}, + // {20, {524289, 524288}, radix::tile::Scheme::Tms}, + {20, {524290, 524288}, radix::tile::Scheme::Tms}, + // {19, {262144, 262144}, radix::tile::Scheme::Tms}, + // {19, {262145, 262144}, radix::tile::Scheme::Tms} }; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); - const tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + const radix::tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); + const radix::tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, target_bounds, tile_provider, 23, 21); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler does not fail if there are not tiles", "[terrainbuilder]") { - const std::set available_tiles = {}; - const std::set expected_tiles = {}; + const std::set available_tiles = {}; + const std::set expected_tiles = {}; const AvailabilityListEmptyTileProvider tile_provider(available_tiles); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); - const tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); - std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( + const radix::tile::SrsBounds target_bounds(glm::dvec2(0, 0), glm::dvec2(100, 1)); + const radix::tile::Id root_tile = grid.findSmallestEncompassingTile(target_bounds).value(); + std::vector actual_tiles_vec = terrainbuilder::texture::find_relevant_tiles_to_splatter_in_bounds( root_tile, grid, target_bounds, tile_provider); - std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), + std::set actual_tiles(std::make_move_iterator(actual_tiles_vec.begin()), std::make_move_iterator(actual_tiles_vec.end())); CHECK(expected_tiles == actual_tiles); } TEST_CASE("texture assembler assembles single tile", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(0, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(0, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, @@ -237,18 +234,18 @@ TEST_CASE("texture assembler assembles single tile", "[terrainbuilder]") { } TEST_CASE("texture assembler assembles two tiles", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(1, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, - {tile::Id(1, {0, 1}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 255, 0))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(1, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 0, 255))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC3, cv::Vec3b(0, 255, 0))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, @@ -265,21 +262,21 @@ TEST_CASE("texture assembler assembles two tiles", "[terrainbuilder]") { } TEST_CASE("texture assembler correct order of texture writes", "[terrainbuilder]") { - const std::unordered_map tiles_to_texture = { - {tile::Id(0, {0, 0}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(1))}, - {tile::Id(1, {0, 1}, tile::Scheme::Tms), cv::Mat(1, 1, CV_8UC1, uint8_t(2))}, - {tile::Id(1, {0, 1}, tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(3))}, + const std::unordered_map tiles_to_texture = { + {radix::tile::Id(0, {0, 0}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(1))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::Tms), cv::Mat(1, 1, CV_8UC1, uint8_t(2))}, + {radix::tile::Id(1, {0, 1}, radix::tile::Scheme::SlippyMap), cv::Mat(1, 1, CV_8UC1, uint8_t(3))}, }; - std::vector tiles_to_splatter; + std::vector tiles_to_splatter; std::transform(tiles_to_texture.begin(), tiles_to_texture.end(), std::back_inserter(tiles_to_splatter), [](const auto &pair) { return pair.first; }); std::sort(tiles_to_splatter.begin(), tiles_to_splatter.end(), - [](const tile::Id &a, const tile::Id &b) { return a.zoom_level < b.zoom_level; }); + [](const radix::tile::Id &a, const radix::tile::Id &b) { return a.zoom_level < b.zoom_level; }); const StaticTileProvider tile_provider(tiles_to_texture); const ctb::Grid grid = ctb::GlobalMercator(); - const tile::Id root_tile(0, {0, 0}, tile::Scheme::SlippyMap); + const radix::tile::Id root_tile(0, {0, 0}, radix::tile::Scheme::SlippyMap); cv::Mat assembled_texture = terrainbuilder::texture::splatter_tiles_to_texture( root_tile, grid, From e8e2ee497cce24d5a5b1647c88b0c305feae42a2 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Sun, 4 May 2025 21:38:56 +0200 Subject: [PATCH 014/122] work on updated cmake setup (compiles with custom gdal version) --- .gitignore | 1 + CMakeLists.txt | 3 + cmake/AddRepo.cmake | 225 ++++++++++++++++++++++++++++++ cmake/CheckForScriptUpdates.cmake | 76 ++++++++++ src/CMakeLists.txt | 67 +++------ src/tile_downloader/main.cpp | 1 + unittests/CMakeLists.txt | 14 +- 7 files changed, 334 insertions(+), 53 deletions(-) create mode 100644 cmake/AddRepo.cmake create mode 100644 cmake/CheckForScriptUpdates.cmake diff --git a/.gitignore b/.gitignore index b4f814a..eeace7f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ build/ .vscode unittest_tiles .vs +/extern/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 45b5677..5c2273a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.21) project(alpine-terrain-builder) option(ALP_UNITTESTS "include unit test targets in the buildsystem" ON) +include(cmake/AddRepo.cmake) + + add_subdirectory(src) if (ALP_UNITTESTS) add_subdirectory(unittests) diff --git a/cmake/AddRepo.cmake b/cmake/AddRepo.cmake new file mode 100644 index 0000000..772f876 --- /dev/null +++ b/cmake/AddRepo.cmake @@ -0,0 +1,225 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2023 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +find_package(Git 2.22 REQUIRED) + +# CMake's FetchContent caches information about the downloads / clones in the build dir. +# Therefore it walks over the clones every time we switch the build type (release, debug, webassembly, android etc), +# which takes forever. Moreover, it messes up changes to subprojects. This function, on the other hand, checks whether +# we are on a branch and in that case only issues a warning. Use origin/main or similar, if you want to stay up-to-date +# with upstream. + +if(NOT DEFINED _alp_add_repo_check_flag) + set_property(GLOBAL PROPERTY _alp_add_repo_check_flag FALSE) +endif() + +function(alp_add_git_repository name) + set(options DO_NOT_ADD_SUBPROJECT NOT_SYSTEM PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) + set(oneValueArgs URL COMMITISH DESTINATION_PATH) + set(multiValueArgs ) + cmake_parse_arguments(PARSE_ARGV 1 PARAM "${options}" "${oneValueArgs}" "${multiValueArgs}") + + get_property(_check_ran GLOBAL PROPERTY _alp_add_repo_check_flag) + if(NOT PARAM_PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES AND NOT _check_ran) + if(NOT COMMAND alp_check_for_script_updates) + include(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CheckForScriptUpdates.cmake) + endif() + alp_check_for_script_updates(${CMAKE_CURRENT_FUNCTION_LIST_FILE}) + set_property(GLOBAL PROPERTY _alp_add_repo_check_flag TRUE) + endif() + + if (NOT DEFINED ALP_EXTERN_DIR OR ALP_EXTERN_DIR STREQUAL "") + set(ALP_EXTERN_DIR extern) + endif() + + file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/${ALP_EXTERN_DIR} ) + set(repo_dir ${CMAKE_SOURCE_DIR}/${ALP_EXTERN_DIR}/${name}) + set(short_repo_dir ${ALP_EXTERN_DIR}/${name}) + if (DEFINED PARAM_DESTINATION_PATH AND NOT PARAM_DESTINATION_PATH STREQUAL "") + set(repo_dir ${CMAKE_SOURCE_DIR}/${PARAM_DESTINATION_PATH}) + set(short_repo_dir ${PARAM_DESTINATION_PATH}) + endif() + + set(${name}_SOURCE_DIR "${repo_dir}" PARENT_SCOPE) + set(ALP_EXTERN_${name} "${repo_dir}" CACHE PATH "Path to an external repository within the project. Note that this is read only (it'll be overwritten).") + + if(EXISTS "${repo_dir}/.git") + message(STATUS "Updating git repo in ${short_repo_dir}") + + # Check internet connection + execute_process( + COMMAND ${GIT_EXECUTABLE} ls-remote ${PARAM_URL} + OUTPUT_QUIET + ERROR_QUIET + RESULT_VARIABLE GIT_LSREMOTE_RESULT + ) + string(REGEX MATCH "^[^/]+/.+" commitish_is_remote_branch "${PARAM_COMMITISH}") + + # First, see if PARAM_COMMITISH is a valid local ref at all: + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH} + WORKING_DIRECTORY ${repo_dir} + OUTPUT_VARIABLE GIT_COMMIT_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_COMMIT_RESULT + ) + + if (NOT GIT_COMMIT_RESULT) + # + # At this point, PARAM_COMMITISH is recognized by Git + # (could be a tag (lightweight or annotated) or a direct commit SHA). + # The problem: if it's an *annotated* tag, rev-parse gives us + # the tag object's hash, not the commit hash. + # + # => Force resolve the actual commit object with ^{commit}: + # + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH}^{commit} + WORKING_DIRECTORY ${repo_dir} + OUTPUT_VARIABLE GIT_COMMIT_OBJECT + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_COMMIT_OBJECT_RESULT + ) + + if (GIT_COMMIT_OBJECT_RESULT EQUAL 0) + # Successfully resolved a commit object + set(CHECK_COMMITISH "${GIT_COMMIT_OBJECT}") + else() + # Fallback if that fails (should rarely happen if it's a proper commit/tag) + set(CHECK_COMMITISH "${GIT_COMMIT_OUTPUT}") + endif() + + # Grab HEAD commit + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify HEAD + WORKING_DIRECTORY ${repo_dir} + OUTPUT_VARIABLE GIT_HEAD_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (GIT_HEAD_OUTPUT STREQUAL CHECK_COMMITISH AND NOT commitish_is_remote_branch) + message(STATUS "Repo in ${short_repo_dir} is already at ${PARAM_COMMITISH}. Skipping checkout.") + else() + if (GIT_LSREMOTE_RESULT) + message(WARNING "No internet connection or remote unavailable. Leaving ${name} as is.") + else() + message(STATUS "Fetching updates for ${name}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} fetch + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_FETCH_RESULT + ) + endif() + + message(STATUS "Checking out ${PARAM_COMMITISH} in ${name}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_CHECKOUT_RESULT + ) + if (NOT GIT_CHECKOUT_RESULT) + message(STATUS "Checking out ${PARAM_COMMITISH} was successfull.") + else() + message(FATAL_ERROR "In ${name}, checking out ${PARAM_COMMITISH} was NOT successfull!") + endif() + endif() + else() + # + # If rev-parse --verify failed, + # we assume it's a branch name that doesn't exist as a direct ref locally + # + message(STATUS "COMMITISH ${PARAM_COMMITISH} might be a branch, checking for internet connection.") + + if (GIT_LSREMOTE_RESULT) + message(WARNING "No internet connection or remote unavailable. Leaving branch ${PARAM_COMMITISH} as-is.") + else() + message(STATUS "Fetching updates for branch ${PARAM_COMMITISH}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} fetch + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_FETCH_RESULT + ) + if (NOT GIT_FETCH_RESULT) + message(STATUS "Fetch successfull.") + + execute_process( + COMMAND ${GIT_EXECUTABLE} branch --show-current + WORKING_DIRECTORY ${repo_dir} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE GIT_BRANCH_OUTPUT + RESULT_VARIABLE GIT_BRANCH_RESULT + ) + if (GIT_BRANCH_RESULT) + message(FATAL_ERROR "${repo_dir}: git branch --show-current not successfull") + endif() + + if (GIT_BRANCH_OUTPUT STREQUAL "") + # Currently detached; let's checkout the branch + execute_process( + COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_CHECKOUT_RESULT + ) + if (NOT GIT_CHECKOUT_RESULT) + message(STATUS "In ${name}, checking out branch ${PARAM_COMMITISH} was successfull.") + else() + message(FATAL_ERROR "In ${name}, checking out branch ${PARAM_COMMITISH} was NOT successfull!") + endif() + else() + message(WARNING + "${short_repo_dir} is on branch ${GIT_BRANCH_OUTPUT}, leaving it there. " + "NOT checking out ${PARAM_COMMITISH}! Use origin/main or similar if you " + "want to stay up-to-date with upstream." + ) + endif() + else() + message(WARNING "Fetching ${name} was NOT successfull!") + endif() + endif() + endif() + else() + # If the repo doesn't exist, do a fresh clone + message(STATUS "Cloning ${PARAM_URL} to ${short_repo_dir}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} clone --recurse-submodules ${PARAM_URL} ${repo_dir} + RESULT_VARIABLE GIT_CLONE_RESULT + ) + if (NOT GIT_CLONE_RESULT) + execute_process( + COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_CHECKOUT_RESULT + ) + if (NOT GIT_CHECKOUT_RESULT) + message(STATUS "Checking out ${PARAM_COMMITISH} was successfull.") + else() + message(FATAL_ERROR "In ${name}, checking out ${PARAM_COMMITISH} was NOT successfull!") + endif() + else() + message(FATAL_ERROR "Cloning ${name} was NOT successfull!") + endif() + endif() + + if (NOT ${PARAM_DO_NOT_ADD_SUBPROJECT}) + if (NOT ${PARAM_NOT_SYSTEM}) + add_subdirectory(${repo_dir} ${CMAKE_BINARY_DIR}/alp_external/${name} SYSTEM) + else() + add_subdirectory(${repo_dir} ${CMAKE_BINARY_DIR}/alp_external/${name}) + endif() + endif() +endfunction() diff --git a/cmake/CheckForScriptUpdates.cmake b/cmake/CheckForScriptUpdates.cmake new file mode 100644 index 0000000..224e681 --- /dev/null +++ b/cmake/CheckForScriptUpdates.cmake @@ -0,0 +1,76 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2025 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +include_guard(GLOBAL) + + +# Function to check if a local CMake script specified by file_path +# differs from the version in the central AlpineMapsOrg/cmake_scripts repository. +# +# Arguments: +# file_path: Path to the CMake script + + +if(NOT COMMAND alp_add_git_repository) + include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) +endif() + +if(NOT DEFINED _alp_check_for_script_updates_repo_flag) + set_property(GLOBAL PROPERTY _alp_check_for_script_updates_repo_flag FALSE) +endif() + +function(alp_check_for_script_updates script_path) + get_filename_component(script_name "${script_path}" NAME) + + get_property(_repo_done GLOBAL PROPERTY _alp_check_for_script_updates_repo_flag) + if(_repo_done) + get_property(cmake_scripts_SOURCE_DIR GLOBAL PROPERTY _alp_check_for_script_updates_script_repo) + else() + alp_add_git_repository(cmake_scripts + URL "git@github.com:AlpineMapsOrg/cmake_scripts.git" + COMMITISH origin/main + DO_NOT_ADD_SUBPROJECT PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) + set_property(GLOBAL PROPERTY _alp_check_for_script_updates_repo_flag TRUE) + set_property(GLOBAL PROPERTY _alp_check_for_script_updates_script_repo ${cmake_scripts_SOURCE_DIR}) + endif() + + set(external_script_path "${cmake_scripts_SOURCE_DIR}/${script_name}") + get_filename_component(absolute_script_path "${script_path}" REALPATH) + + if(NOT EXISTS "${absolute_script_path}") + message(WARNING "alp_check_for_cmake_script_updates: Local script '${script_path}' (${absolute_script_path}) does not exist. Cannot compare.") + return() + endif() + + if(NOT EXISTS "${external_script_path}") + message(WARNING "alp_check_for_cmake_script_updates: Corresponding external script '${external_script_path}' does not exist in the 'cmake_scripts' repository. Cannot compare.") + return() + endif() + + file(READ "${script_path}" local_content) + file(READ "${external_script_path}" external_content) + + if(NOT local_content STREQUAL external_content) + message(WARNING "alp_check_for_cmake_script_updates: The local script '${script_path}' has different content compared to the version in the central 'cmake_scripts' repository ('${external_script_path}'). Consider updating the local file or the repository.") + else() + message(STATUS "alp_check_for_cmake_script_updates: Local script '${script_path}' is up-to-date.") + endif() +endfunction() + +alp_check_for_script_updates("${CMAKE_CURRENT_LIST_FILE}") + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46abfdf..3bd87bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,11 +5,26 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") -option(ALP_AUTOUPDATE_RADIX "Keeps whack up-to-date with origin/main, but prevents local edits. Change to OFF if you want to edit radix" ON) option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) -find_package(GDAL REQUIRED) + + +# alp_add_git_repository(PROJ URL https://github.com/OSGeo/PROJ.git COMMITISH 9.6.0) +# # set(CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}/alp_external/PROJ" ${CMAKE_PREFIX_PATH}) + +# set(PROJ_ROOT ${CMAKE_BINARY_DIR}/alp_external/PROJ CACHE INTERNAL "unsure this is correct") +# set(PROJ_DIR ${CMAKE_BINARY_DIR}/alp_external/PROJ CACHE INTERNAL "unsure this is correct") +# set(PROJ_INCLUDE_DIR ${CMAKE_BINARY_DIR}/alp_external/PROJ/include CACHE INTERNAL "this should be correct") +# set(PROJ_LIBRARY PROJ::proj CACHE INTERNAL "hope this works") + +# can't include proj via repo, gdals find script doesn't play well with it. +# next: set gdal flags to build only lib, build only necessary formats, build alpine maps, clone cgal, replace FetchContent, clean up +set(GDAL_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "") +set(OGR_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "") +set(BUILD_APPS OFF CACHE BOOL "") +alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH v3.10.3) + find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) find_package(OpenCV REQUIRED) @@ -17,18 +32,6 @@ find_package(CGAL REQUIRED) find_package(Eigen3 REQUIRED NO_MODULE) find_package(CURL REQUIRED) -if(NOT GDAL_CONFIG) - message(FATAL_ERROR "gdal-config command not found (not in PATH?), cannot proceed") -endif() - -execute_process( - COMMAND ${GDAL_CONFIG} --version - OUTPUT_VARIABLE SYSTEM_GDAL_VERSION -) - -if(SYSTEM_GDAL_VERSION VERSION_LESS "3.3") - message(FATAL_ERROR "GDAL version \"${SYSTEM_GDAL_VERSION}\" is too old, at least 3.2 is required") -endif() include(FetchContent) @@ -41,26 +44,7 @@ if(NOT TARGET fmt::fmt) FetchContent_MakeAvailable(fmt) endif() -if(ALP_AUTOUPDATE_RADIX) - FetchContent_Declare(radix - GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git - GIT_TAG d01b84248e21e4754e028492bf70519e3416c86 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix - SOURCE_SUBDIR src - ) - FetchContent_MakeAvailable(radix) -else() - if(NOT EXISTS ${CMAKE_SOURCE_DIR}/3rdparty/radix) - FetchContent_Declare(radix - GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git - GIT_TAG 7ace0d0cab1a6166c196bba5d0f11bbf07381abd - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix - ) - FetchContent_MakeAvailable(radix) - else() - add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/radix ${CMAKE_BINARY_DIR}/_deps/radix-build) - endif() -endif() +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH bbed8f3607c2d5fa97e309b119d0520fbebca983 NOT_SYSTEM) if(NOT TARGET cgltf) FetchContent_Declare(cgltf @@ -108,14 +92,9 @@ if(NOT TARGET cli11) endif() endif() -if(NOT TARGET expected) - FetchContent_Declare(expected - GIT_REPOSITORY https://github.com/TartanLlama/expected.git - GIT_TAG 3f0ca7b19253129700a073abfa6d8638d9f7c80c - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/expected - ) - FetchContent_MakeAvailable(expected) -endif() +alp_add_git_repository(tl_expected URL https://github.com/TartanLlama/expected.git COMMITISH v1.1.0 DO_NOT_ADD_SUBPROJECT) +add_library(tl_expected INTERFACE) +target_include_directories(tl_expected INTERFACE ${tl_expected_SOURCE_DIR}/include) if(NOT TARGET spdlog) set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "SPDLOG_FMT_EXTERNAL" FORCE) @@ -204,7 +183,7 @@ add_library(terrainlib terrainlib/tntn/zemlya_meshing.h terrainlib/tntn/zemlya_meshing.cpp terrainlib/tntn/ZoomRange.h ) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb expected ${OpenCV_LIBS}) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected ${OpenCV_LIBS}) target_include_directories(terrainlib PUBLIC terrainlib ${OpenCV_INCLUDE_DIRS}) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) @@ -225,7 +204,7 @@ add_library(terrainbuilderlib terrainbuilder/octree/space.h ) target_include_directories(terrainbuilderlib PUBLIC terrainbuilder terrainlib) -target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 expected) +target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) add_executable(terrainbuilder terrainbuilder/main.cpp ) diff --git a/src/tile_downloader/main.cpp b/src/tile_downloader/main.cpp index 84dcea7..fe89b41 100644 --- a/src/tile_downloader/main.cpp +++ b/src/tile_downloader/main.cpp @@ -14,6 +14,7 @@ #include "srs.h" using namespace std::literals; +using namespace radix; static unsigned verbosity = 1; diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 2af3f18..8c32870 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -6,13 +6,9 @@ option(ATB_UNITTESTS_EXTENDED "perform extended unit tests (they take long)" OFF option(ATB_UNITTESTS_DEBUG_IMAGES "output debug height images for visual comparison" OFF) set(ATB_UNITTESTS_AUSTRIA_HIGHRES CACHE FILEPATH "path to the high res austrian dataset (terrain model, i.e., OeRect_01m_gt_31287.img)") -include(FetchContent) -FetchContent_Declare(catch2 - GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v3.3.2 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/Catch2 -) -FetchContent_MakeAvailable(catch2) +if (NOT TARGET Catch2) + alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.5.1) +endif() add_executable(unittests_terrainlib alpine_raster_format.cpp @@ -68,7 +64,7 @@ if (ATB_UNITTESTS_DEBUG_IMAGES) else() target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_DEBUG_IMAGES=false") endif() -target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2WithMain) +target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) add_executable(unittests_terrainmerger @@ -77,7 +73,7 @@ add_executable(unittests_terrainmerger terrainmerger/merge.cpp ) -target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2WithMain) +target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2::Catch2WithMain) add_executable(unittests_terrainbuilder From dd46587e39629c985a15eea7ce3cd513b6d799a5 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Sun, 4 May 2025 22:09:18 +0200 Subject: [PATCH 015/122] disable unnecessary executable targets, and many gdal features. --- src/CMakeLists.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3bd87bd..7c069d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,9 +20,20 @@ option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with ne # can't include proj via repo, gdals find script doesn't play well with it. # next: set gdal flags to build only lib, build only necessary formats, build alpine maps, clone cgal, replace FetchContent, clean up -set(GDAL_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "") -set(OGR_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "") -set(BUILD_APPS OFF CACHE BOOL "") + +set(GDAL_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) +set(OGR_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) +set(BUILD_APPS OFF CACHE BOOL "don't build gdal apps" FORCE) +set(BUILD_TESTING OFF CACHE BOOL "don't build gdal apps" FORCE) +set(BUILD_PYTHON_BINDINGS OFF CACHE BOOL "" FORCE) +set(BUILD_JAVA_BINDINGS OFF CACHE BOOL "" FORCE) +set(BUILD_CSHARP_BINDINGS OFF CACHE BOOL "" FORCE) +set(GDAL_USE_JPEG OFF CACHE BOOL "not targetting jpeg for now and it builds an additonal executable" FORCE) + +# The Iconv library is used to convert text from one encoding to another encoding. It is generally available as a system library for Unix-like systems. +# On Windows, GDAL can leverage the API of the operating system for a few base conversions, but using Iconv will provide additional capabilities. +# gdal supports vector layers, we won't need it here for now, and an unnecessary target will be produced. +set(GDAL_USE_ICONV OFF CACHE BOOL "i don't think we need this one" FORCE) alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH v3.10.3) find_package(TBB REQUIRED) @@ -60,6 +71,7 @@ endif() if(NOT TARGET tinygltf) set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) + set(TINYGLTF_BUILD_LOADER_EXAMPLE OFF CACHE INTERNAL "" FORCE) FetchContent_Declare(tinygltf GIT_REPOSITORY https://github.com/syoyo/tinygltf GIT_TAG 4fea26f6c8652f545560807bccc934cf0cdd86dd From bb1068c94b5d81e2d6138d8c0b33d3624f991e44 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 10:32:25 +0200 Subject: [PATCH 016/122] compiles and tests run --- src/CMakeLists.txt | 24 ++------- src/terrainlib/mesh/io.h | 5 +- src/terrainlib/mesh/terrain_mesh.h | 5 +- src/terrainmerger/simplify.cpp | 2 +- unittests/CMakeLists.txt | 50 +++++++++---------- .../algorithms/raster_triangle_scanline.cpp | 6 +-- unittests/alpine_raster_format.cpp | 6 ++- unittests/dataset.cpp | 12 +++-- unittests/dataset_reading.cpp | 9 ++-- unittests/depth_first_tile_traverser.cpp | 4 +- unittests/grid.cpp | 5 +- unittests/image.cpp | 6 ++- unittests/main.cpp | 3 +- unittests/parallel_tile_generator.cpp | 5 +- unittests/parallel_tiler.cpp | 16 +++--- unittests/progress_indicator_test.cpp | 10 ++-- unittests/srs_test.cpp | 9 ++-- unittests/terrainmerger/convert.cpp | 4 +- unittests/terrainmerger/merge.cpp | 4 +- unittests/tile_heights_generator.cpp | 4 +- unittests/top_down_tiler.cpp | 7 +-- 21 files changed, 98 insertions(+), 98 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c069d9..e093382 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -46,15 +46,7 @@ find_package(CURL REQUIRED) include(FetchContent) -if(NOT TARGET fmt::fmt) - FetchContent_Declare(fmt - GIT_REPOSITORY https://github.com/fmtlib/fmt - GIT_TAG 10.2.1 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/fmt - ) - FetchContent_MakeAvailable(fmt) -endif() - +alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH bbed8f3607c2d5fa97e309b119d0520fbebca983 NOT_SYSTEM) if(NOT TARGET cgltf) @@ -119,16 +111,10 @@ if(NOT TARGET spdlog) add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) endif() -if(NOT TARGET zpp_bits) - FetchContent_Declare(zpp_bits - GIT_REPOSITORY https://github.com/eyalz800/zpp_bits.git - GIT_TAG v4.4.20 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/zpp_bits - ) - FetchContent_MakeAvailable(zpp_bits) - add_library(zpp_bits INTERFACE) - target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) -endif() + +alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COMMITISH v4.5 DO_NOT_ADD_SUBPROJECT) +add_library(zpp_bits INTERFACE) +target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) add_library(terrainlib terrainlib/alpine_raster.h terrainlib/alpine_raster.cpp diff --git a/src/terrainlib/mesh/io.h b/src/terrainlib/mesh/io.h index 1ee81ba..78a3b62 100644 --- a/src/terrainlib/mesh/io.h +++ b/src/terrainlib/mesh/io.h @@ -1,5 +1,4 @@ -#ifndef IO_H -#define IO_H +#pragma once #include #include @@ -155,5 +154,3 @@ auto serialize(auto &archive, const cv::Mat &v) { } } // namespace zpp::bits - -#endif diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index 627196f..a493e01 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -1,5 +1,4 @@ -#ifndef TERRAINMESH_H -#define TERRAINMESH_H +#pragma once #include #include @@ -92,5 +91,3 @@ void sort_and_normalize_triangles(TerrainMesh &mesh); void sort_and_normalize_triangles(std::span triangles); void validate_mesh(const TerrainMesh &mesh); - -#endif diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index 65efe05..d49e36f 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -290,7 +290,7 @@ struct UvMapUpdateEdgeCollapseVisitor : CGAL::Surface_mesh_simplification::Edge_ // Called during the processing phase for each edge being collapsed. // If placement is absent the edge is left uncollapsed. - void OnCollapsing(const Profile &profile, boost::optional placement) { + void OnCollapsing(const Profile &profile, std::optional placement) { if (!placement) { return; } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 8c32870..d15cfd6 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -26,31 +26,31 @@ add_executable(unittests_terrainlib srs_test.cpp tile_heights_generator.cpp top_down_tiler.cpp - algorithms/primitives.cpp - algorithms/raster_triangle_scanline.cpp - tntn/Delaunay_tests.cpp - tntn/File_tests.cpp - tntn/geometrix_tests.cpp - tntn/Mesh_tests.cpp - tntn/ObjPool_tests.cpp - tntn/OFFReader_tests.cpp - - tntn/RasterIO_tests.cpp - tntn/Raster_tests.cpp - tntn/raster_tools_tests.cpp - tntn/simple_meshing_tests.cpp - tntn/SimpleRange_tests.cpp - tntn/SuperTriangle_tests.cpp - tntn/SurfacePoints_tests.cpp - tntn/terra_meshing_tests.cpp - tntn/test_common.cpp - tntn/test_common.h - tntn/triangle_indices.cpp - tntn/triangle_indices_data.cpp - tntn/triangle_indices.h - tntn/util_tests.cpp - tntn/vertex_points.cpp - tntn/vertex_points.h) + # algorithms/primitives.cpp + # algorithms/raster_triangle_scanline.cpp + # tntn/Delaunay_tests.cpp + # tntn/File_tests.cpp + # tntn/geometrix_tests.cpp + # tntn/Mesh_tests.cpp + # tntn/ObjPool_tests.cpp + # tntn/OFFReader_tests.cpp + # tntn/RasterIO_tests.cpp + # tntn/Raster_tests.cpp + # tntn/raster_tools_tests.cpp + # tntn/simple_meshing_tests.cpp + # tntn/SimpleRange_tests.cpp + # tntn/SuperTriangle_tests.cpp + # tntn/SurfacePoints_tests.cpp + # tntn/terra_meshing_tests.cpp + # tntn/test_common.cpp + # tntn/test_common.h + # tntn/triangle_indices.cpp + # tntn/triangle_indices_data.cpp + # tntn/triangle_indices.h + # tntn/util_tests.cpp + # tntn/vertex_points.cpp + # tntn/vertex_points.h +) target_compile_definitions(unittests_terrainlib PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_AUSTRIA_HIGHRES=\"${ATB_UNITTESTS_AUSTRIA_HIGHRES}\"") diff --git a/unittests/algorithms/raster_triangle_scanline.cpp b/unittests/algorithms/raster_triangle_scanline.cpp index a20bb05..9cf4a8f 100644 --- a/unittests/algorithms/raster_triangle_scanline.cpp +++ b/unittests/algorithms/raster_triangle_scanline.cpp @@ -17,12 +17,10 @@ * along with this program. If not, see . *****************************************************************************/ -#include "../catch2_helpers.h" -#include -#include - #include "algorithms/raster_triangle_scanline.h" +#include "../catch2_helpers.h" #include "tntn/Raster.h" +#include TEST_CASE("raster triangle goes through pixels exactly once (small rect)") { diff --git a/unittests/alpine_raster_format.cpp b/unittests/alpine_raster_format.cpp index 2129457..5f71b60 100644 --- a/unittests/alpine_raster_format.cpp +++ b/unittests/alpine_raster_format.cpp @@ -19,13 +19,17 @@ #include -#include +#include +#include #include +#include #include "Image.h" #include "alpine_raster.h" #include "ctb/Grid.hpp" +using namespace radix; + tile::Border testTypeValue2Border(bool v) { return v ? tile::Border::Yes : tile::Border::No; diff --git a/unittests/dataset.cpp b/unittests/dataset.cpp index 0fb31d2..4ff40bc 100644 --- a/unittests/dataset.cpp +++ b/unittests/dataset.cpp @@ -17,7 +17,8 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include +#include #include "Dataset.h" #include "ctb/GlobalGeodetic.hpp" @@ -25,6 +26,9 @@ #include "ctb/types.hpp" #include "srs.h" +using namespace radix; +using Catch::Approx; + void checkBounds(const tile::SrsBounds& a, const tile::SrsBounds& b) { REQUIRE(a.height() > 0); @@ -118,8 +122,8 @@ TEST_CASE("bbox width pixels") REQUIRE(d_mgi.widthInPixels(d_mgi.bounds(), d_mgi.srs()) == Approx(620.0)); REQUIRE(d_mgi.heightInPixels(d_mgi.bounds(), d_mgi.srs()) == Approx(350.0)); - REQUIRE(d_mgi.widthInPixels(srs::nonExactBoundsTransform(d_mgi.bounds(), d_mgi.srs(), webmercator), webmercator) == Approx(620.0)); - REQUIRE(d_mgi.heightInPixels(srs::nonExactBoundsTransform(d_mgi.bounds(), d_mgi.srs(), webmercator), webmercator) == Approx(350.0)); + REQUIRE(d_mgi.widthInPixels(srs::non_exact_bounds_transform(d_mgi.bounds(), d_mgi.srs(), webmercator), webmercator) == Approx(620.0)); + REQUIRE(d_mgi.heightInPixels(srs::non_exact_bounds_transform(d_mgi.bounds(), d_mgi.srs(), webmercator), webmercator) == Approx(350.0)); auto adjust_bounds = [](auto bounds) { const auto unadjusted_width = bounds.width(); @@ -132,7 +136,7 @@ TEST_CASE("bbox width pixels") REQUIRE(d_wgs84.widthInPixels(adjust_bounds(d_wgs84.bounds()), d_wgs84.srs()) == Approx(620.0 * 0.7)); REQUIRE(d_wgs84.heightInPixels(adjust_bounds(d_wgs84.bounds()), d_wgs84.srs()) == Approx(350.0 * 0.5)); - const auto webmercator_bounds = srs::nonExactBoundsTransform(d_wgs84.bounds(), d_wgs84.srs(), webmercator); + const auto webmercator_bounds = srs::non_exact_bounds_transform(d_wgs84.bounds(), d_wgs84.srs(), webmercator); REQUIRE(d_wgs84.widthInPixels(webmercator_bounds, webmercator) == Approx(620.0)); REQUIRE(d_wgs84.heightInPixels(webmercator_bounds, webmercator) == Approx(350.0)); diff --git a/unittests/dataset_reading.cpp b/unittests/dataset_reading.cpp index 8b4ba05..9418806 100644 --- a/unittests/dataset_reading.cpp +++ b/unittests/dataset_reading.cpp @@ -18,17 +18,18 @@ *****************************************************************************/ #include +#include #include #include - -#include +#include #include - #include "Dataset.h" #include "DatasetReader.h" #include "ctb/types.hpp" #include "srs.h" +using namespace radix; + TEST_CASE("reading") { const std::vector at100m = { @@ -94,7 +95,7 @@ TEST_CASE("reading") srs.importFromEPSG(test_srs); srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto srs_bounds = srs::nonExactBoundsTransform(geodetic_bounds, geodetic_srs, srs); + const auto srs_bounds = srs::non_exact_bounds_transform(geodetic_bounds, geodetic_srs, srs); const auto reader = DatasetReader(dataset, srs, 1); if (ATB_UNITTESTS_DEBUG_IMAGES) { diff --git a/unittests/depth_first_tile_traverser.cpp b/unittests/depth_first_tile_traverser.cpp index de2db5d..23c7949 100644 --- a/unittests/depth_first_tile_traverser.cpp +++ b/unittests/depth_first_tile_traverser.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include #include @@ -27,6 +27,8 @@ #include "depth_first_tile_traverser.h" #include +using namespace radix; + TEST_CASE("depth_first_tile_traverser interface") { struct ReadType { }; diff --git a/unittests/grid.cpp b/unittests/grid.cpp index 19000c4..bf24a35 100644 --- a/unittests/grid.cpp +++ b/unittests/grid.cpp @@ -17,7 +17,8 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include +#include #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" @@ -27,6 +28,8 @@ // Therefore it's unlikely, that it will be fully covered by tests. // New functions should be tested though! +using Catch::Approx; + TEST_CASE("grid") { SECTION("epsg codes") diff --git a/unittests/image.cpp b/unittests/image.cpp index 7b30132..448aef2 100644 --- a/unittests/image.cpp +++ b/unittests/image.cpp @@ -18,10 +18,12 @@ *****************************************************************************/ #include -#include - +#include +#include #include "Image.h" +using Catch::Approx; + TEST_CASE("image") { SECTION("iteration") diff --git a/unittests/main.cpp b/unittests/main.cpp index 79aea7b..73406e0 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -18,10 +18,11 @@ *****************************************************************************/ #include +#include #include #define CATCH_CONFIG_MAIN -#include +#include #ifdef NDEBUG constexpr bool asserts_are_enabled = false; diff --git a/unittests/parallel_tile_generator.cpp b/unittests/parallel_tile_generator.cpp index 793d804..e516145 100644 --- a/unittests/parallel_tile_generator.cpp +++ b/unittests/parallel_tile_generator.cpp @@ -21,9 +21,10 @@ #include #include #include - #include "ParallelTileGenerator.h" -#include +#include + +using namespace radix; TEST_CASE("parallel tile generator") { diff --git a/unittests/parallel_tiler.cpp b/unittests/parallel_tiler.cpp index a8a16e9..9f12cac 100644 --- a/unittests/parallel_tiler.cpp +++ b/unittests/parallel_tiler.cpp @@ -17,17 +17,21 @@ * along with this program. If not, see . *****************************************************************************/ -#include -#include - -#include -#include - #include "Dataset.h" #include "ParallelTiler.h" #include "catch2_helpers.h" #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" +#include +#include +#include +#include +#include +#include +#include + +using Catch::Approx; +using namespace radix; TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::false_type) { diff --git a/unittests/progress_indicator_test.cpp b/unittests/progress_indicator_test.cpp index 865e100..c5016c5 100644 --- a/unittests/progress_indicator_test.cpp +++ b/unittests/progress_indicator_test.cpp @@ -17,17 +17,15 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include "ParallelTileGenerator.h" +#include "ProgressIndicator.h" +#include #include #include #include -#include - -#include "ParallelTileGenerator.h" -#include "ProgressIndicator.h" - using namespace std::literals; +using namespace radix; TEST_CASE("progress indicator") { diff --git a/unittests/srs_test.cpp b/unittests/srs_test.cpp index 009fcbe..83cd0dc 100644 --- a/unittests/srs_test.cpp +++ b/unittests/srs_test.cpp @@ -17,13 +17,16 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include "srs.h" +#include +#include #include #include #include #include -#include "srs.h" +using namespace radix; +using Catch::Approx; TEST_CASE("ECEF conversinos") { @@ -39,7 +42,7 @@ TEST_CASE("ECEF conversinos") { // comparison against https://www.oc.nps.edu/oc2902w/coord/llhxyz.htm const auto steffl_wgs84 = glm::dvec3(16.372489, 48.208814, 171.28); - const auto steffl_webmercator = srs::to(wgs84, webmercator, steffl_wgs84); + const auto steffl_webmercator = srs::transform_point(wgs84, webmercator, steffl_wgs84); { const auto steffl_ecef = srs::toECEF(wgs84, steffl_wgs84); CHECK(steffl_ecef.x == Approx(4085862.0)); diff --git a/unittests/terrainmerger/convert.cpp b/unittests/terrainmerger/convert.cpp index a0c2d31..9b6db0b 100644 --- a/unittests/terrainmerger/convert.cpp +++ b/unittests/terrainmerger/convert.cpp @@ -1,7 +1,5 @@ -#include +#include #include - -#include "../catch2_helpers.h" #include "mesh/io.h" #include "convert.h" #include "cgal.h" diff --git a/unittests/terrainmerger/merge.cpp b/unittests/terrainmerger/merge.cpp index 18de0f4..bb0db93 100644 --- a/unittests/terrainmerger/merge.cpp +++ b/unittests/terrainmerger/merge.cpp @@ -18,9 +18,7 @@ *****************************************************************************/ #define CATCH_CONFIG_MAIN -#include - -#include "../catch2_helpers.h" +#include #include "merge.h" TEST_CASE("terrainmerger") { diff --git a/unittests/tile_heights_generator.cpp b/unittests/tile_heights_generator.cpp index 21d21a5..1978cda 100644 --- a/unittests/tile_heights_generator.cpp +++ b/unittests/tile_heights_generator.cpp @@ -17,9 +17,11 @@ *****************************************************************************/ #include "TileHeightsGenerator.h" -#include +#include #include +using namespace radix; + TEST_CASE("TileHeightsGenerator") { const auto base_path = std::filesystem::path("./unittest_tile_heights"); diff --git a/unittests/top_down_tiler.cpp b/unittests/top_down_tiler.cpp index 6460f28..01d9bc8 100644 --- a/unittests/top_down_tiler.cpp +++ b/unittests/top_down_tiler.cpp @@ -16,14 +16,15 @@ * along with this program. If not, see . *****************************************************************************/ -#include -#include - #include "Dataset.h" #include "ParallelTiler.h" #include "TopDownTiler.h" #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" +#include +#include + +using namespace radix; namespace { void compare_tile_lists(const std::vector& a_tiles, std::vector b_tiles) From 27514c476e7b868b8f969b9b5f932f309499cef1 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 11:10:30 +0200 Subject: [PATCH 017/122] clean up / remove FetchContent --- src/CMakeLists.txt | 75 ++++++++++------------------------------------ 1 file changed, 16 insertions(+), 59 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e093382..f2a4a94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with ne # set(PROJ_LIBRARY PROJ::proj CACHE INTERNAL "hope this works") # can't include proj via repo, gdals find script doesn't play well with it. -# next: set gdal flags to build only lib, build only necessary formats, build alpine maps, clone cgal, replace FetchContent, clean up +# todo: clone cgal, clean up set(GDAL_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) set(OGR_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) @@ -44,73 +44,30 @@ find_package(Eigen3 REQUIRED NO_MODULE) find_package(CURL REQUIRED) -include(FetchContent) - -alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH bbed8f3607c2d5fa97e309b119d0520fbebca983 NOT_SYSTEM) +alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) +alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH 20de8b73bbbabaf2f94dd07c4ece8ff3590af531) -if(NOT TARGET cgltf) - FetchContent_Declare(cgltf - GIT_REPOSITORY https://github.com/jkuhlmann/cgltf - GIT_TAG 7331a5adf4b0fde15f0e682a5803e4f17137e0ad - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/cgltf - ) - FetchContent_MakeAvailable(cgltf) - add_library(cgltf INTERFACE) - target_include_directories(cgltf INTERFACE ${cgltf_SOURCE_DIR}) -endif() - -if(NOT TARGET tinygltf) - set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) - set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) - set(TINYGLTF_BUILD_LOADER_EXAMPLE OFF CACHE INTERNAL "" FORCE) - FetchContent_Declare(tinygltf - GIT_REPOSITORY https://github.com/syoyo/tinygltf - GIT_TAG 4fea26f6c8652f545560807bccc934cf0cdd86dd - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/tinygltf - ) - FetchContent_MakeAvailable(tinygltf) -endif() +alp_add_git_repository(cgltf URL https://github.com/jkuhlmann/cgltf COMMITISH 7331a5adf4b0fde15f0e682a5803e4f17137e0ad DO_NOT_ADD_SUBPROJECT) +add_library(cgltf INTERFACE) +target_include_directories(cgltf INTERFACE ${cgltf_SOURCE_DIR}) -if(NOT TARGET stb) - FetchContent_Declare(stb - GIT_REPOSITORY https://github.com/nothings/stb - GIT_TAG f4a71b13373436a2866c5d68f8f80ac6f0bc1ffe - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/stb - ) - FetchContent_MakeAvailable(stb) - add_library(stb INTERFACE) - target_include_directories(stb INTERFACE ${stb_SOURCE_DIR}) -endif() +set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) +set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) +set(TINYGLTF_BUILD_LOADER_EXAMPLE OFF CACHE INTERNAL "" FORCE) +alp_add_git_repository(tinygltf URL https://github.com/syoyo/tinygltf COMMITISH 4fea26f6c8652f545560807bccc934cf0cdd86dd) -if(NOT TARGET cli11) - if(NOT EXISTS ${CMAKE_SOURCE_DIR}/3rdparty/cli11) - FetchContent_Declare(cli11 - GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git - GIT_TAG 20de8b73bbbabaf2f94dd07c4ece8ff3590af531 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/cli11 - ) - FetchContent_MakeAvailable(cli11) - else() - add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/cli11 ${CMAKE_BINARY_DIR}/_deps/cli11-build) - endif() -endif() +alp_add_git_repository(stb URL https://github.com/nothings/stb COMMITISH f4a71b13373436a2866c5d68f8f80ac6f0bc1ffe DO_NOT_ADD_SUBPROJECT) +add_library(stb INTERFACE) +target_include_directories(stb INTERFACE ${stb_SOURCE_DIR}) alp_add_git_repository(tl_expected URL https://github.com/TartanLlama/expected.git COMMITISH v1.1.0 DO_NOT_ADD_SUBPROJECT) add_library(tl_expected INTERFACE) target_include_directories(tl_expected INTERFACE ${tl_expected_SOURCE_DIR}/include) -if(NOT TARGET spdlog) - set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "SPDLOG_FMT_EXTERNAL" FORCE) - FetchContent_Declare(spdlog - GIT_REPOSITORY https://github.com/gabime/spdlog.git - GIT_TAG v1.13.0 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/spdlog - ) - FetchContent_MakeAvailable(spdlog) - add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) -endif() - +set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "SPDLOG_FMT_EXTERNAL" FORCE) +alp_add_git_repository(spdlog URL https://github.com/gabime/spdlog.git COMMITISH v1.13.0) +add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COMMITISH v4.5 DO_NOT_ADD_SUBPROJECT) add_library(zpp_bits INTERFACE) From f228c844148b963dbff5ff57aba322f85d4150ac Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 11:43:36 +0200 Subject: [PATCH 018/122] clean away tntn --- glm | 1 - src/CMakeLists.txt | 37 +- src/terrainlib/Dataset.cpp | 8 +- src/terrainlib/DatasetReader.cpp | 13 +- src/terrainlib/Image.cpp | 2 +- .../{tntn/gdal_init.cpp => init.cpp} | 8 +- src/terrainlib/{tntn/gdal_init.h => init.h} | 0 src/terrainlib/srs.h | 48 +- src/terrainlib/tntn/BinaryIO.cpp | 156 - src/terrainlib/tntn/BinaryIO.h | 231 - src/terrainlib/tntn/Delaunator.cpp | 501 - src/terrainlib/tntn/Delaunator.h | 49 - src/terrainlib/tntn/DelaunayMesh.cpp | 300 - src/terrainlib/tntn/DelaunayMesh.h | 80 - src/terrainlib/tntn/DelaunayTriangle.cpp | 22 - src/terrainlib/tntn/DelaunayTriangle.h | 48 - src/terrainlib/tntn/File.cpp | 385 - src/terrainlib/tntn/File.h | 201 - src/terrainlib/tntn/FileFormat.h | 144 - src/terrainlib/tntn/Mesh.cpp | 646 - src/terrainlib/tntn/Mesh.h | 78 - src/terrainlib/tntn/Mesh2Raster.cpp | 528 - src/terrainlib/tntn/Mesh2Raster.h | 44 - src/terrainlib/tntn/MeshIO.cpp | 351 - src/terrainlib/tntn/MeshIO.h | 25 - src/terrainlib/tntn/MeshMode.h | 11 - src/terrainlib/tntn/MeshWriter.cpp | 26 - src/terrainlib/tntn/MeshWriter.h | 41 - src/terrainlib/tntn/NOTICE | 27 - src/terrainlib/tntn/OFFReader.cpp | 216 - src/terrainlib/tntn/OFFReader.h | 55 - src/terrainlib/tntn/ObjPool.h | 161 - src/terrainlib/tntn/Points2Mesh.cpp | 79 - src/terrainlib/tntn/Points2Mesh.h | 11 - src/terrainlib/tntn/QuadEdge.cpp | 147 - src/terrainlib/tntn/QuadEdge.h | 250 - src/terrainlib/tntn/QuantizedMeshIO.cpp | 798 - src/terrainlib/tntn/QuantizedMeshIO.h | 103 - src/terrainlib/tntn/Raster.h | 560 - src/terrainlib/tntn/RasterIO.cpp | 397 - src/terrainlib/tntn/RasterIO.h | 19 - src/terrainlib/tntn/SuperTriangle.cpp | 126 - src/terrainlib/tntn/SuperTriangle.h | 28 - src/terrainlib/tntn/SurfacePoints.cpp | 357 - src/terrainlib/tntn/SurfacePoints.h | 62 - src/terrainlib/tntn/TerraMesh.cpp | 188 - src/terrainlib/tntn/TerraMesh.h | 37 - src/terrainlib/tntn/TerraUtils.cpp | 27 - src/terrainlib/tntn/TerraUtils.h | 112 - src/terrainlib/tntn/ZemlyaMesh.cpp | 375 - src/terrainlib/tntn/ZemlyaMesh.h | 50 - src/terrainlib/tntn/ZoomRange.h | 21 - src/terrainlib/tntn/endianness.h | 36 - src/terrainlib/tntn/geometrix.cpp | 724 - src/terrainlib/tntn/geometrix.h | 208 - src/terrainlib/tntn/logging.cpp | 93 - src/terrainlib/tntn/logging.h | 53 - src/terrainlib/tntn/raster_tools.cpp | 276 - src/terrainlib/tntn/raster_tools.h | 27 - src/terrainlib/tntn/simple_meshing.cpp | 202 - src/terrainlib/tntn/simple_meshing.h | 14 - src/terrainlib/tntn/terra_meshing.cpp | 39 - src/terrainlib/tntn/terra_meshing.h | 17 - src/terrainlib/tntn/tntn_assert.h | 17 - src/terrainlib/tntn/util.cpp | 86 - src/terrainlib/tntn/util.h | 67 - src/terrainlib/tntn/zemlya_meshing.cpp | 30 - src/terrainlib/tntn/zemlya_meshing.h | 15 - unittests/CMakeLists.txt | 24 - unittests/algorithms/primitives.cpp | 101 - .../algorithms/raster_triangle_scanline.cpp | 155 - unittests/tntn/Delaunay_tests.cpp | 133 - unittests/tntn/File_tests.cpp | 110 - unittests/tntn/Mesh_tests.cpp | 324 - unittests/tntn/OFFReader_tests.cpp | 69 - unittests/tntn/ObjPool_tests.cpp | 50 - unittests/tntn/RasterIO_tests.cpp | 41 - unittests/tntn/Raster_tests.cpp | 458 - unittests/tntn/SimpleRange_tests.cpp | 31 - unittests/tntn/SuperTriangle_tests.cpp | 45 - unittests/tntn/SurfacePoints_tests.cpp | 147 - unittests/tntn/geometrix_tests.cpp | 104 - unittests/tntn/raster_tools_tests.cpp | 32 - unittests/tntn/simple_meshing_tests.cpp | 104 - unittests/tntn/terra_meshing_tests.cpp | 205 - unittests/tntn/test_common.cpp | 25 - unittests/tntn/test_common.h | 10 - unittests/tntn/triangle_indices.cpp | 20190 ---------------- unittests/tntn/triangle_indices.h | 8 - unittests/tntn/triangle_indices_data.cpp | 15 - unittests/tntn/util_tests.cpp | 25 - unittests/tntn/vertex_points.cpp | 10991 --------- unittests/tntn/vertex_points.h | 8 - 93 files changed, 21 insertions(+), 43478 deletions(-) delete mode 160000 glm rename src/terrainlib/{tntn/gdal_init.cpp => init.cpp} (82%) rename src/terrainlib/{tntn/gdal_init.h => init.h} (100%) delete mode 100644 src/terrainlib/tntn/BinaryIO.cpp delete mode 100644 src/terrainlib/tntn/BinaryIO.h delete mode 100644 src/terrainlib/tntn/Delaunator.cpp delete mode 100644 src/terrainlib/tntn/Delaunator.h delete mode 100644 src/terrainlib/tntn/DelaunayMesh.cpp delete mode 100644 src/terrainlib/tntn/DelaunayMesh.h delete mode 100644 src/terrainlib/tntn/DelaunayTriangle.cpp delete mode 100644 src/terrainlib/tntn/DelaunayTriangle.h delete mode 100644 src/terrainlib/tntn/File.cpp delete mode 100644 src/terrainlib/tntn/File.h delete mode 100644 src/terrainlib/tntn/FileFormat.h delete mode 100644 src/terrainlib/tntn/Mesh.cpp delete mode 100644 src/terrainlib/tntn/Mesh.h delete mode 100644 src/terrainlib/tntn/Mesh2Raster.cpp delete mode 100644 src/terrainlib/tntn/Mesh2Raster.h delete mode 100644 src/terrainlib/tntn/MeshIO.cpp delete mode 100644 src/terrainlib/tntn/MeshIO.h delete mode 100644 src/terrainlib/tntn/MeshMode.h delete mode 100644 src/terrainlib/tntn/MeshWriter.cpp delete mode 100644 src/terrainlib/tntn/MeshWriter.h delete mode 100644 src/terrainlib/tntn/NOTICE delete mode 100644 src/terrainlib/tntn/OFFReader.cpp delete mode 100644 src/terrainlib/tntn/OFFReader.h delete mode 100644 src/terrainlib/tntn/ObjPool.h delete mode 100644 src/terrainlib/tntn/Points2Mesh.cpp delete mode 100644 src/terrainlib/tntn/Points2Mesh.h delete mode 100644 src/terrainlib/tntn/QuadEdge.cpp delete mode 100644 src/terrainlib/tntn/QuadEdge.h delete mode 100644 src/terrainlib/tntn/QuantizedMeshIO.cpp delete mode 100644 src/terrainlib/tntn/QuantizedMeshIO.h delete mode 100644 src/terrainlib/tntn/Raster.h delete mode 100644 src/terrainlib/tntn/RasterIO.cpp delete mode 100644 src/terrainlib/tntn/RasterIO.h delete mode 100644 src/terrainlib/tntn/SuperTriangle.cpp delete mode 100644 src/terrainlib/tntn/SuperTriangle.h delete mode 100644 src/terrainlib/tntn/SurfacePoints.cpp delete mode 100644 src/terrainlib/tntn/SurfacePoints.h delete mode 100644 src/terrainlib/tntn/TerraMesh.cpp delete mode 100644 src/terrainlib/tntn/TerraMesh.h delete mode 100644 src/terrainlib/tntn/TerraUtils.cpp delete mode 100644 src/terrainlib/tntn/TerraUtils.h delete mode 100644 src/terrainlib/tntn/ZemlyaMesh.cpp delete mode 100644 src/terrainlib/tntn/ZemlyaMesh.h delete mode 100644 src/terrainlib/tntn/ZoomRange.h delete mode 100644 src/terrainlib/tntn/endianness.h delete mode 100644 src/terrainlib/tntn/geometrix.cpp delete mode 100644 src/terrainlib/tntn/geometrix.h delete mode 100644 src/terrainlib/tntn/logging.cpp delete mode 100644 src/terrainlib/tntn/logging.h delete mode 100644 src/terrainlib/tntn/raster_tools.cpp delete mode 100644 src/terrainlib/tntn/raster_tools.h delete mode 100644 src/terrainlib/tntn/simple_meshing.cpp delete mode 100644 src/terrainlib/tntn/simple_meshing.h delete mode 100644 src/terrainlib/tntn/terra_meshing.cpp delete mode 100644 src/terrainlib/tntn/terra_meshing.h delete mode 100644 src/terrainlib/tntn/tntn_assert.h delete mode 100644 src/terrainlib/tntn/util.cpp delete mode 100644 src/terrainlib/tntn/util.h delete mode 100644 src/terrainlib/tntn/zemlya_meshing.cpp delete mode 100644 src/terrainlib/tntn/zemlya_meshing.h delete mode 100644 unittests/algorithms/primitives.cpp delete mode 100644 unittests/algorithms/raster_triangle_scanline.cpp delete mode 100644 unittests/tntn/Delaunay_tests.cpp delete mode 100644 unittests/tntn/File_tests.cpp delete mode 100644 unittests/tntn/Mesh_tests.cpp delete mode 100644 unittests/tntn/OFFReader_tests.cpp delete mode 100644 unittests/tntn/ObjPool_tests.cpp delete mode 100644 unittests/tntn/RasterIO_tests.cpp delete mode 100644 unittests/tntn/Raster_tests.cpp delete mode 100644 unittests/tntn/SimpleRange_tests.cpp delete mode 100644 unittests/tntn/SuperTriangle_tests.cpp delete mode 100644 unittests/tntn/SurfacePoints_tests.cpp delete mode 100644 unittests/tntn/geometrix_tests.cpp delete mode 100644 unittests/tntn/raster_tools_tests.cpp delete mode 100644 unittests/tntn/simple_meshing_tests.cpp delete mode 100644 unittests/tntn/terra_meshing_tests.cpp delete mode 100644 unittests/tntn/test_common.cpp delete mode 100644 unittests/tntn/test_common.h delete mode 100644 unittests/tntn/triangle_indices.cpp delete mode 100644 unittests/tntn/triangle_indices.h delete mode 100644 unittests/tntn/triangle_indices_data.cpp delete mode 100644 unittests/tntn/util_tests.cpp delete mode 100644 unittests/tntn/vertex_points.cpp delete mode 100644 unittests/tntn/vertex_points.h diff --git a/glm b/glm deleted file mode 160000 index b06b775..0000000 --- a/glm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b06b775c1c80af51a1183c0e167f9de3b2351a79 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2a4a94..3c9c4a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -95,48 +95,13 @@ add_library(terrainlib terrainlib/TileHeightsGenerator.h terrainlib/TileHeightsGenerator.cpp terrainlib/Tiler.h terrainlib/Tiler.cpp terrainlib/TopDownTiler.h terrainlib/TopDownTiler.cpp - terrainlib/algorithms/primitives.h - terrainlib/algorithms/raster_triangle_scanline.h terrainlib/ctb/CTBException.hpp terrainlib/ctb/GlobalGeodetic.hpp terrainlib/ctb/GlobalGeodetic.cpp terrainlib/ctb/GlobalMercator.hpp terrainlib/ctb/GlobalMercator.cpp terrainlib/ctb/Grid.hpp terrainlib/ctb/TileCoordinate.hpp terrainlib/ctb/types.hpp - terrainlib/tntn/BinaryIO.h terrainlib/tntn/BinaryIO.cpp - terrainlib/tntn/Delaunator.h terrainlib/tntn/Delaunator.cpp - terrainlib/tntn/DelaunayMesh.h terrainlib/tntn/DelaunayMesh.cpp - terrainlib/tntn/DelaunayTriangle.h terrainlib/tntn/DelaunayTriangle.cpp - terrainlib/tntn/endianness.h - terrainlib/tntn/FileFormat.h - terrainlib/tntn/File.h terrainlib/tntn/File.cpp - terrainlib/tntn/gdal_init.h terrainlib/tntn/gdal_init.cpp - terrainlib/tntn/geometrix.h terrainlib/tntn/geometrix.cpp - terrainlib/tntn/logging.h terrainlib/tntn/logging.cpp - terrainlib/tntn/Mesh2Raster.h terrainlib/tntn/Mesh2Raster.cpp - terrainlib/tntn/Mesh.h terrainlib/tntn/Mesh.cpp - terrainlib/tntn/MeshIO.h terrainlib/tntn/MeshIO.cpp - terrainlib/tntn/MeshMode.h - terrainlib/tntn/MeshWriter.h terrainlib/tntn/MeshWriter.cpp - terrainlib/tntn/ObjPool.h - terrainlib/tntn/OFFReader.h terrainlib/tntn/OFFReader.cpp - terrainlib/tntn/Points2Mesh.h terrainlib/tntn/Points2Mesh.cpp - terrainlib/tntn/QuadEdge.h terrainlib/tntn/QuadEdge.cpp - terrainlib/tntn/QuantizedMeshIO.h terrainlib/tntn/QuantizedMeshIO.cpp - terrainlib/tntn/Raster.h - terrainlib/tntn/RasterIO.h terrainlib/tntn/RasterIO.cpp - terrainlib/tntn/raster_tools.h terrainlib/tntn/raster_tools.cpp - terrainlib/tntn/simple_meshing.h terrainlib/tntn/simple_meshing.cpp - terrainlib/tntn/SuperTriangle.h terrainlib/tntn/SuperTriangle.cpp - terrainlib/tntn/SurfacePoints.h terrainlib/tntn/SurfacePoints.cpp - terrainlib/tntn/TerraMesh.h terrainlib/tntn/TerraMesh.cpp - terrainlib/tntn/terra_meshing.h terrainlib/tntn/terra_meshing.cpp - terrainlib/tntn/TerraUtils.h terrainlib/tntn/TerraUtils.cpp - terrainlib/tntn/tntn_assert.h - terrainlib/tntn/util.h terrainlib/tntn/util.cpp - terrainlib/tntn/ZemlyaMesh.h terrainlib/tntn/ZemlyaMesh.cpp - terrainlib/tntn/zemlya_meshing.h terrainlib/tntn/zemlya_meshing.cpp - terrainlib/tntn/ZoomRange.h + terrainlib/init.h terrainlib/init.cpp ) target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected ${OpenCV_LIBS}) target_include_directories(terrainlib PUBLIC terrainlib ${OpenCV_INCLUDE_DIRS}) diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 512a41c..f8de08a 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -30,15 +30,15 @@ #include "Exception.h" #include "ctb/Grid.hpp" #include "srs.h" -#include "tntn/gdal_init.h" -#include "tntn/logging.h" +#include "init.h" +#include "log.h" Dataset::Dataset(const std::string& path) { tntn::initialize_gdal_once(); m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); if (!m_gdal_dataset) { - TNTN_LOG_FATAL("Couldn't open dataset {}.\n", path); + LOG_ERROR("Couldn't open dataset {}.\n", path); throw Exception(""); } m_name = std::regex_replace(path, std::regex("^.*/"), ""); @@ -50,7 +50,7 @@ Dataset::Dataset(GDALDataset* dataset) tntn::initialize_gdal_once(); m_gdal_dataset.reset(dataset); if (!m_gdal_dataset) { - TNTN_LOG_FATAL("Dataset is null.\n"); + LOG_ERROR("Dataset is null.\n"); throw Exception("Dataset is null."); } } diff --git a/src/terrainlib/DatasetReader.cpp b/src/terrainlib/DatasetReader.cpp index 7032ad6..351bfc8 100644 --- a/src/terrainlib/DatasetReader.cpp +++ b/src/terrainlib/DatasetReader.cpp @@ -31,7 +31,6 @@ #include "Exception.h" #include "Image.h" #include "ctb/types.hpp" -#include "tntn/logging.h" namespace { std::string toWkt(const OGRSpatialReference& srs) @@ -123,7 +122,7 @@ std::shared_ptr getOverviewDataset(const std::shared_ptr& data assert(nOvCount >= 0); if (nOvCount == 0) { if (warn_on_missing_overviews) - TNTN_LOG_WARN("No dataset overviews found."); + LOG_WARN("No dataset overviews found."); return dataset; } @@ -137,16 +136,16 @@ std::shared_ptr getOverviewDataset(const std::shared_ptr& data adfSuggestedGeoTransform.data(), &nPixels, &nLines, adfExtent.data(), 0) == CE_Failure) { - TNTN_LOG_WARN("GDALSuggestedWarpOutput2 failed. We won't use dataset overviews!"); + LOG_WARN("GDALSuggestedWarpOutput2 failed. We won't use dataset overviews!"); return dataset; } double dfTargetRatio = 1.0 / adfSuggestedGeoTransform[1]; // if( dfTargetRatio <= 1.0 ) { - // TNTN_LOG_WARN(fmt::format("dfTargetRatio {} <= 1.0. We won't use dataset overviews!\n", dfTargetRatio)); - // TNTN_LOG_WARN(fmt::format("Other values: nPixels={}, nLines={}, adfExtent={}/{}/{}/{}\n", + // LOG_WARN(fmt::format("dfTargetRatio {} <= 1.0. We won't use dataset overviews!\n", dfTargetRatio)); + // LOG_WARN(fmt::format("Other values: nPixels={}, nLines={}, adfExtent={}/{}/{}/{}\n", // nPixels, nLines, adfExtent[0], adfExtent[1], adfExtent[2], adfExtent[3])); - // TNTN_LOG_WARN(fmt::format("Other values: adfSuggestedGeoTransform={}/{}/{}/{}/{}/{}\n", + // LOG_WARN(fmt::format("Other values: adfSuggestedGeoTransform={}/{}/{}/{}/{}/{}\n", // adfSuggestedGeoTransform[0], adfSuggestedGeoTransform[1], adfSuggestedGeoTransform[2], // adfSuggestedGeoTransform[3], adfSuggestedGeoTransform[4], adfSuggestedGeoTransform[5])); // return dataset; @@ -163,7 +162,7 @@ std::shared_ptr getOverviewDataset(const std::shared_ptr& data } iOvr += nOvLevel + 2; if (iOvr >= 0) { - TNTN_LOG_DEBUG("WARPING: Selecting overview level {} for output dataset {}x{}\n", iOvr, nPixels, nLines); + LOG_DEBUG("WARPING: Selecting overview level {} for output dataset {}x{}\n", iOvr, nPixels, nLines); return std::make_shared(static_cast(GDALCreateOverviewDataset(poSrcDS, iOvr, FALSE))); } return dataset; diff --git a/src/terrainlib/Image.cpp b/src/terrainlib/Image.cpp index d68796d..e718d70 100644 --- a/src/terrainlib/Image.cpp +++ b/src/terrainlib/Image.cpp @@ -18,7 +18,7 @@ *****************************************************************************/ #include "Image.h" -#include "tntn/gdal_init.h" +#include "init.h" #include #include diff --git a/src/terrainlib/tntn/gdal_init.cpp b/src/terrainlib/init.cpp similarity index 82% rename from src/terrainlib/tntn/gdal_init.cpp rename to src/terrainlib/init.cpp index feca82f..c44918d 100644 --- a/src/terrainlib/tntn/gdal_init.cpp +++ b/src/terrainlib/init.cpp @@ -1,5 +1,5 @@ -#include "gdal_init.h" -#include "logging.h" +#include "init.h" +#include "log.h" #include #include //for call_once @@ -12,7 +12,7 @@ std::once_flag g_gdal_initialized_once_flag; void initialize_gdal_once() { std::call_once(g_gdal_initialized_once_flag, []() { - TNTN_LOG_DEBUG("calling GDALAllRegister..."); + LOG_DEBUG("calling GDALAllRegister..."); GDALAllRegister(); }); } @@ -31,7 +31,7 @@ namespace { void initialize_freeimage_once() { std::call_once(g_freeimage_initialized_once_flag, []() { - TNTN_LOG_DEBUG("calling GDALAllRegister..."); + LOG_DEBUG("calling GDALAllRegister..."); FreeImage_Initialise(); }); static FreeImageDeinitialiserHandler deinitialiser; diff --git a/src/terrainlib/tntn/gdal_init.h b/src/terrainlib/init.h similarity index 100% rename from src/terrainlib/tntn/gdal_init.h rename to src/terrainlib/init.h diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index ea6c608..833cc6a 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -1,6 +1,5 @@ /***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org + * AlpineMaps.org * Copyright (C) 2022 Adam Celarek * * This program is free software: you can redistribute it and/or modify @@ -17,20 +16,16 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef SRS_H -#define SRS_H +#pragma once +#include "Exception.h" #include #include -#include - #include +#include #include -#include - -#include "Exception.h" -#include "tntn/geometrix.h" #include +#include namespace srs { @@ -328,38 +323,5 @@ template inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) { return toECEF(source_srs, { p1, p2 }); } -inline tntn::BBox3D toECEF(const OGRSpatialReference& source_srs, const tntn::BBox3D& box) { - constexpr auto n_samples = 100; - std::vector points; - points.emplace_back(box.min.x, box.min.y, box.min.z); - points.emplace_back(box.min.x, box.min.y, box.max.z); - points.emplace_back(box.min.x, box.max.y, box.min.z); - points.emplace_back(box.min.x, box.max.y, box.max.z); - points.emplace_back(box.max.x, box.min.y, box.min.z); - points.emplace_back(box.max.x, box.min.y, box.max.z); - points.emplace_back(box.max.x, box.max.y, box.min.z); - points.emplace_back(box.max.x, box.max.y, box.max.z); - - const auto dx = (box.max.x - box.min.x) / n_samples; - const auto dy = (box.max.y - box.min.y) / n_samples; - for (auto i = 0; i < n_samples; ++i) { - // top and bottom - points.emplace_back(box.min.x + i * dx, box.min.y, box.min.z); - points.emplace_back(box.min.x + i * dx, box.min.y, box.max.z); - points.emplace_back(box.min.x + i * dx, box.max.y, box.min.z); - points.emplace_back(box.min.x + i * dx, box.max.y, box.max.z); - // left and right - points.emplace_back(box.min.x, box.min.y + i * dy, box.min.z); - points.emplace_back(box.min.x, box.min.y + i * dy, box.max.z); - points.emplace_back(box.max.x, box.min.y + i * dy, box.min.z); - points.emplace_back(box.max.x, box.min.y + i * dy, box.max.z); - } - const auto ecef_points = toECEF(source_srs, points); - tntn::BBox3D resulting_bbox; - resulting_bbox.add(ecef_points.begin(), ecef_points.end()); - return resulting_bbox; -} } - -#endif // SRS_H diff --git a/src/terrainlib/tntn/BinaryIO.cpp b/src/terrainlib/tntn/BinaryIO.cpp deleted file mode 100644 index 627c7f9..0000000 --- a/src/terrainlib/tntn/BinaryIO.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "BinaryIO.h" -#include "endianness.h" -#include "tntn_assert.h" - -#include -#include - -namespace tntn { - -std::string BinaryIOError::to_string() const -{ - if (!is_error()) { - return std::string(); - } - - std::string out; - out += what == BinaryIOError::READ ? "reading failed at " : "writing failed at "; - out += std::to_string(where); - out += " expected "; - out += std::to_string(expected_bytes); - out += " bytes, got "; - out += std::to_string(actual_bytes); - out += " bytes on type "; - out += type; - - return out; -} - -// treat nullptrs as empty strings -static bool cstrs_equal_nullptr_tolerant(const char* a, const char* b) -{ - if (a == b) { - return true; - } else if (a == nullptr || b == nullptr) { - return false; - } else { - return std::strcmp(a, b) == 0; - } -} - -bool BinaryIOError::operator==(const BinaryIOError& other) const -{ - return cstrs_equal_nullptr_tolerant(type, other.type) && where == other.where && what == other.what && expected_bytes == other.expected_bytes && actual_bytes == other.actual_bytes; -} - -std::string BinaryIOErrorTracker::to_string() const -{ - std::string out; - if (first_error.is_error() && first_error == last_error) { - out += "error: "; - out += first_error.to_string(); - } else { - if (first_error.is_error()) { - out += "first error: "; - out += first_error.to_string(); - } - if (last_error.is_error()) { - out += out.empty() ? "last error: " : ", last error: "; - out += last_error.to_string(); - } - } - return out; -} - -// returns successfully read element count -size_t BinaryIO::read_impl(void* const dest, - size_t dest_elem_size, - size_t dest_count, - const char* const elem_type, - BinaryIOErrorTracker& e) -{ - TNTN_ASSERT(dest_elem_size > 0); - TNTN_ASSERT(dest_count > 0); - - unsigned char* dest_c = reinterpret_cast(dest); - const size_t bytes_to_read = dest_elem_size * dest_count; - const size_t bytes_read = m_f->read(m_read_pos, dest_c, bytes_to_read); - - if (bytes_read != bytes_to_read) { - e.last_error.type = elem_type; - e.last_error.where = m_read_pos; - e.last_error.what = BinaryIOError::READ; - e.last_error.actual_bytes = bytes_read; - e.last_error.expected_bytes = bytes_to_read; - if (!e.first_error.type) { - e.first_error = e.last_error; - } - } - - if (PLATFORM_NATIVE_ENDIANNESS != m_target_endianness) { - for (unsigned char* p = dest_c; p < dest_c + bytes_to_read; p += dest_elem_size) { - std::reverse(p, p + dest_elem_size); - } - } - - m_read_pos += bytes_read; - - return bytes_read / dest_elem_size; -} - -void BinaryIO::write_impl(const void* const src, - size_t src_elem_size, - size_t src_count, - const char* const elem_type, - BinaryIOErrorTracker& e) -{ - TNTN_ASSERT(src_elem_size > 0); - TNTN_ASSERT(src_elem_size <= 32); - if (src_elem_size > 32) { - return; - } - - const size_t bytes_to_write = src_elem_size * src_count; - const unsigned char* src_c = reinterpret_cast(src); - if (PLATFORM_NATIVE_ENDIANNESS == m_target_endianness) { - // simple write - const bool write_ok = m_f->write(m_write_pos, src_c, bytes_to_write); - if (!write_ok) { - e.last_error.type = elem_type; - e.last_error.where = m_write_pos; - e.last_error.what = BinaryIOError::WRITE; - e.last_error.actual_bytes = 0; - e.last_error.expected_bytes = bytes_to_write; - if (!e.first_error.type) { - e.first_error = e.last_error; - } - } - if (write_ok) { - m_write_pos += bytes_to_write; - } - } else { - // copy to temporary storage, reverse, write - unsigned char tmp[34]; - for (const unsigned char* p = src_c; p < src_c + bytes_to_write; p += src_elem_size) { - memcpy(tmp, p, src_elem_size); - std::reverse(tmp, tmp + src_elem_size); - const bool write_ok = m_f->write(m_write_pos, tmp, src_elem_size); - if (!write_ok) { - e.last_error.type = elem_type; - e.last_error.where = m_write_pos; - e.last_error.what = BinaryIOError::WRITE; - e.last_error.actual_bytes = 0; - e.last_error.expected_bytes = bytes_to_write; - if (!e.first_error.type) { - e.first_error = e.last_error; - } - break; - } - if (write_ok) { - m_write_pos += bytes_to_write; - } - } - } -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/BinaryIO.h b/src/terrainlib/tntn/BinaryIO.h deleted file mode 100644 index a9dcee6..0000000 --- a/src/terrainlib/tntn/BinaryIO.h +++ /dev/null @@ -1,231 +0,0 @@ -#pragma once - -#include "File.h" -#include "endianness.h" - -#include -#include -#include -#include - -namespace tntn { - -struct BinaryIOError { - enum InOrOut { - NONE, - READ, - WRITE - }; - - const char* type = nullptr; - File::position_type where = -1; - InOrOut what = NONE; - size_t expected_bytes = 0; - size_t actual_bytes = 0; - - std::string to_string() const; - bool is_error() const { return type != nullptr; } - - bool operator==(const BinaryIOError& other) const; - bool operator!=(const BinaryIOError& other) const { return !(*this == other); } -}; - -struct BinaryIOErrorTracker { - BinaryIOError first_error; - BinaryIOError last_error; - bool has_error() const { return first_error.is_error(); } - std::string to_string() const; -}; - -class BinaryIO { -public: - BinaryIO(std::shared_ptr f, Endianness target_endianness) - : m_f(f) - , m_target_endianness(target_endianness) - { - } - - File::position_type read_pos() const noexcept { return m_read_pos; } - File::position_type write_pos() const noexcept { return m_write_pos; } - - void read_skip(const File::position_type bytes, BinaryIOErrorTracker& e) - { - m_read_pos += bytes; - } - void read_byte(uint8_t& b, BinaryIOErrorTracker& e) { read_impl(&b, 1, 1, "uint8_t", e); } - void read_uint16(uint16_t& o, BinaryIOErrorTracker& e) { read_impl(&o, 2, 1, "uint16_t", e); } - void read_int16(int16_t& o, BinaryIOErrorTracker& e) { read_impl(&o, 2, 1, "int16_t", e); } - void read_uint32(uint32_t& o, BinaryIOErrorTracker& e) { read_impl(&o, 4, 1, "uint32_t", e); } - void read_int32(int32_t& o, BinaryIOErrorTracker& e) { read_impl(&o, 4, 1, "int32_t", e); } - void read_array_uint16(std::vector& o, size_t count, BinaryIOErrorTracker& e) - { - o.resize(count); - const auto new_count = read_impl(o.data(), 2, count, "uint16_t[]", e); - o.resize(new_count); - } - void read_array_int16(std::vector& o, size_t count, BinaryIOErrorTracker& e) - { - o.resize(count); - const auto new_count = read_impl(o.data(), 2, count, "int16_t[]", e); - o.resize(new_count); - } - void read_array_uint32(std::vector& o, size_t count, BinaryIOErrorTracker& e) - { - o.resize(count); - const auto new_count = read_impl(o.data(), 4, count, "uint32_t[]", e); - o.resize(new_count); - } - void read_array_int32(std::vector& o, size_t count, BinaryIOErrorTracker& e) - { - o.resize(count); - const auto new_count = read_impl(o.data(), 4, count, "int32_t[]", e); - o.resize(new_count); - } - void read_float(float& o, BinaryIOErrorTracker& e) { read_impl(&o, 4, 1, "float", e); } - void read_double(double& o, BinaryIOErrorTracker& e) { read_impl(&o, 8, 1, "double", e); } - - template - void read_array(std::vector& o, size_t count, BinaryIOErrorTracker& e); - - void write_byte(const uint8_t v, BinaryIOErrorTracker& e) - { - write_impl(&v, 1, 1, "uint8_t", e); - } - void write_uint16(const uint16_t v, BinaryIOErrorTracker& e) - { - write_impl(&v, 2, 1, "uint16_t", e); - } - void write_int16(const int16_t v, BinaryIOErrorTracker& e) - { - write_impl(&v, 2, 1, "int16_t", e); - } - void write_uint32(const uint32_t v, BinaryIOErrorTracker& e) - { - write_impl(&v, 4, 1, "uint32_t", e); - } - void write_int32(const int32_t v, BinaryIOErrorTracker& e) - { - write_impl(&v, 4, 1, "int32_t", e); - } - void write_array_uint16(const std::vector& v, BinaryIOErrorTracker& e) - { - write_impl(v.data(), 2, v.size(), "uint16_t[]", e); - } - void write_array_int16(const std::vector& v, BinaryIOErrorTracker& e) - { - write_impl(v.data(), 2, v.size(), "int16_t[]", e); - } - void write_array_uint32(const std::vector& v, BinaryIOErrorTracker& e) - { - write_impl(v.data(), 4, v.size(), "uint32_t[]", e); - } - void write_array_int32(const std::vector& v, BinaryIOErrorTracker& e) - { - write_impl(v.data(), 4, v.size(), "int32_t[]", e); - } - void write_float(const float v, BinaryIOErrorTracker& e) { write_impl(&v, 4, 1, "float", e); } - void write_double(const double& v, BinaryIOErrorTracker& e) - { - write_impl(&v, 8, 1, "double", e); - } - - template - void write(const T& v, BinaryIOErrorTracker& e); - - template - void write_array(const std::vector& v, BinaryIOErrorTracker& e); - -private: - // returns successfully read element count - size_t read_impl(void* const dest, - size_t dest_elem_size, - size_t dest_count, - const char* const elem_type, - BinaryIOErrorTracker& e); - void write_impl(const void* const src, - size_t src_elem_size, - size_t src_count, - const char* const elem_type, - BinaryIOErrorTracker& e); - - const std::shared_ptr m_f; - const Endianness m_target_endianness; - File::position_type m_read_pos = 0; - File::position_type m_write_pos = 0; -}; - -template <> -inline void BinaryIO::read_array(std::vector& o, - size_t count, - BinaryIOErrorTracker& e) -{ - return read_array_int16(o, count, e); -} -template <> -inline void BinaryIO::read_array(std::vector& o, - size_t count, - BinaryIOErrorTracker& e) -{ - return read_array_uint16(o, count, e); -} -template <> -inline void BinaryIO::read_array(std::vector& o, - size_t count, - BinaryIOErrorTracker& e) -{ - return read_array_int32(o, count, e); -} -template <> -inline void BinaryIO::read_array(std::vector& o, - size_t count, - BinaryIOErrorTracker& e) -{ - return read_array_uint32(o, count, e); -} - -template <> -inline void BinaryIO::write_array(const std::vector& v, BinaryIOErrorTracker& e) -{ - return write_array_int16(v, e); -} -template <> -inline void BinaryIO::write_array(const std::vector& v, - BinaryIOErrorTracker& e) -{ - return write_array_uint16(v, e); -} - -template <> -inline void BinaryIO::write_array(const std::vector& v, BinaryIOErrorTracker& e) -{ - return write_array_int32(v, e); -} -template <> -inline void BinaryIO::write_array(const std::vector& v, - BinaryIOErrorTracker& e) -{ - return write_array_uint32(v, e); -} - -template <> -inline void BinaryIO::write(const int16_t& v, BinaryIOErrorTracker& e) -{ - return write_int16(v, e); -} -template <> -inline void BinaryIO::write(const uint16_t& v, BinaryIOErrorTracker& e) -{ - return write_uint16(v, e); -} -template <> -inline void BinaryIO::write(const int32_t& v, BinaryIOErrorTracker& e) -{ - return write_int32(v, e); -} -template <> -inline void BinaryIO::write(const uint32_t& v, BinaryIOErrorTracker& e) -{ - return write_uint32(v, e); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/Delaunator.cpp b/src/terrainlib/tntn/Delaunator.cpp deleted file mode 100644 index d86b7f0..0000000 --- a/src/terrainlib/tntn/Delaunator.cpp +++ /dev/null @@ -1,501 +0,0 @@ -#include "Delaunator.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace delaunator_cpp { -namespace { - const double max_double = numeric_limits::max(); - double dist(const double& ax, const double& ay, const double& bx, const double& by) - { - const double dx = ax - bx; - const double dy = ay - by; - return dx * dx + dy * dy; - } - - double circumradius(const double& ax, - const double& ay, - const double& bx, - const double& by, - const double& cx, - const double& cy) - { - const double dx = bx - ax; - const double dy = by - ay; - const double ex = cx - ax; - const double ey = cy - ay; - - const double bl = dx * dx + dy * dy; - const double cl = ex * ex + ey * ey; - const double d = dx * ey - dy * ex; - - const double x = (ey * bl - dy * cl) * 0.5 / d; - const double y = (dx * cl - ex * bl) * 0.5 / d; - - if (bl && cl && d) { - return x * x + y * y; - } else { - return max_double; - } - } - - double area(const double px, - const double py, - const double qx, - const double qy, - const double rx, - const double ry) - { - return (qy - py) * (rx - qx) - (qx - px) * (ry - qy); - } - - tuple circumcenter(const double& ax, - const double& ay, - const double& bx, - const double& by, - const double& cx, - const double& cy) - { - const double dx = bx - ax; - const double dy = by - ay; - const double ex = cx - ax; - const double ey = cy - ay; - - const double bl = dx * dx + dy * dy; - const double cl = ex * ex + ey * ey; - const double d = dx * ey - dy * ex; - - const double x = ax + (ey * bl - dy * cl) * 0.5 / d; - const double y = ay + (dx * cl - ex * bl) * 0.5 / d; - - return make_tuple(x, y); - } - - double compare(const vector& coords, uint64_t i, uint64_t j, double cx, double cy) - { - const double d1 = dist(coords[2 * i], coords[2 * i + 1], cx, cy); - const double d2 = dist(coords[2 * j], coords[2 * j + 1], cx, cy); - const double diff1 = d1 - d2; - const double diff2 = coords[2 * i] - coords[2 * j]; - const double diff3 = coords[2 * i + 1] - coords[2 * j + 1]; - - if (diff1) { - return diff1; - } else if (diff2) { - return diff2; - } else { - return diff3; - } - } - - bool in_circle( - double ax, double ay, double bx, double by, double cx, double cy, double px, double py) - { - const double dx = ax - px; - const double dy = ay - py; - const double ex = bx - px; - const double ey = by - py; - const double fx = cx - px; - const double fy = cy - py; - - const double ap = dx * dx + dy * dy; - const double bp = ex * ex + ey * ey; - const double cp = fx * fx + fy * fy; - - return (dx * (ey * cp - bp * fy) - dy * (ex * cp - bp * fx) + ap * (ex * fy - ey * fx)) < 0; - } -} // namespace - -bool Delaunator::triangulate(const vector& coords) -{ - m_center_x = 0; - m_center_y = 0; - m_hash_size = 0; - - m_hash.clear(); - m_hull.clear(); - triangles.clear(); - halfedges.clear(); - - // coords = move(in_coords); - const int64_t n = coords.size() / 2; - double max_x = -1 * max_double; - double max_y = -1 * max_double; - double min_x = max_double; - double min_y = max_double; - - std::vector ids; - ids.reserve(n); - for (int64_t i = 0; i < n; i++) { - const double x = coords[2 * i]; - const double y = coords[2 * i + 1]; - // print64_tf("%f %f", x, y); - - if (x < min_x) - min_x = x; - if (y < min_y) - min_y = y; - if (x > max_x) - max_x = x; - if (y > max_y) - max_y = y; - // ids[i] = i; - ids.push_back(i); - } - const double cx = (min_x + max_x) / 2; - const double cy = (min_y + max_y) / 2; - double min_dist = max_double; - uint64_t i0 = 0; - uint64_t i1 = 0; - uint64_t i2 = 0; - - // pick a seed point64_t close to the centroid - for (uint64_t i = 0; i < n; i++) { - assert((2 * i + 1 < coords.size()) && i >= 0); - - const double d = dist(cx, cy, coords[2 * i], coords[2 * i + 1]); - if (d < min_dist) { - i0 = i; - min_dist = d; - } - } - - min_dist = max_double; - - // find the point64_t closest to the seed - for (uint64_t i = 0; i < n; i++) { - if (i == i0) - continue; - const double d = dist(coords[2 * i0], coords[2 * i0 + 1], coords[2 * i], coords[2 * i + 1]); - if (d < min_dist && d > 0) { - i1 = i; - min_dist = d; - } - } - - double min_radius = max_double; - - // find the third point64_t which forms the smallest circumcircle with the first two - for (uint64_t i = 0; i < n; i++) { - if (i == i0 || i == i1) - continue; - - const double r = circumradius(coords[2 * i0], - coords[2 * i0 + 1], - coords[2 * i1], - coords[2 * i1 + 1], - coords[2 * i], - coords[2 * i + 1]); - - if (r < min_radius) { - i2 = i; - min_radius = r; - } - } - - if (min_radius == max_double) { - return false; - // throw runtime_error("no triangulation: min_radius == max_double"); - } - - if (area(coords[2 * i0], - coords[2 * i0 + 1], - coords[2 * i1], - coords[2 * i1 + 1], - coords[2 * i2], - coords[2 * i2 + 1]) - < 0) { - const double tmp = i1; - i1 = i2; - i2 = tmp; - } - - const double i0x = coords[2 * i0]; - const double i0y = coords[2 * i0 + 1]; - const double i1x = coords[2 * i1]; - const double i1y = coords[2 * i1 + 1]; - const double i2x = coords[2 * i2]; - const double i2y = coords[2 * i2 + 1]; - - tie(m_center_x, m_center_y) = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y); - - std::sort(ids.begin(), ids.end(), [&](int64_t i, int64_t j) { - return compare(coords, i, j, m_center_x, m_center_y) < 0; - }); - - m_hash_size = ceil(sqrt(n)); - m_hash.reserve(m_hash_size); - for (int64_t i = 0; i < m_hash_size; i++) - m_hash.push_back(-1); - - m_hull.reserve(coords.size()); - - int64_t e = insert_node(i0, coords); - hash_edge(e); - m_hull[e].t = 0; - - e = insert_node(i1, e, coords); - hash_edge(e); - m_hull[e].t = 1; - - e = insert_node(i2, e, coords); - hash_edge(e); - m_hull[e].t = 2; - - const int64_t max_triangles = 2 * n - 5; - triangles.reserve(max_triangles * 3); - halfedges.reserve(max_triangles * 3); - add_triangle(i0, i1, i2, -1, -1, -1); - double xp = NAN; - double yp = NAN; - for (int64_t k = 0; k < n; k++) { - const int64_t i = ids[k]; - - assert(i >= 0 && i < coords.size() / 2); - - const double x = coords[2 * i]; - const double y = coords[2 * i + 1]; - if (x == xp && y == yp) - continue; - xp = x; - yp = y; - if ((x == i0x && y == i0y) || (x == i1x && y == i1y) || (x == i2x && y == i2y)) - continue; - - const int64_t start_key = hash_key(x, y); - int64_t key = start_key; - int64_t start = -1; - do { - assert(key >= 0 && key < m_hash.size()); - start = m_hash[key]; - key = (key + 1) % m_hash_size; - } while ((start < 0 || m_hull[start].removed) && (key != start_key)); - - e = start; - assert(e >= 0 && e < m_hull.size()); - while (area(x, - y, - m_hull[e].x, - m_hull[e].y, - m_hull[m_hull[e].next].x, - m_hull[m_hull[e].next].y) - >= 0) { - e = m_hull[e].next; - assert(e >= 0 && e < m_hull.size()); - if (e == start) { - return false; - // throw runtime_error("Something is wrong with the input point64_ts."); - } - } - - const bool walk_back = e == start; - - // add the first triangle from the point64_t - int64_t t = add_triangle(m_hull[e].i, i, m_hull[m_hull[e].next].i, -1, -1, m_hull[e].t); - - m_hull[e].t = t; // keep track of boundary triangles on the hull - e = insert_node(i, e, coords); - - // recursively flip triangles from the point64_t until they satisfy the Delaunay condition - m_hull[e].t = legalize(t + 2, coords); - if (m_hull[m_hull[m_hull[e].prev].prev].t == halfedges[t + 1]) { - m_hull[m_hull[m_hull[e].prev].prev].t = t + 2; - } - // walk forward through the hull, adding more triangles and flipping recursively - int64_t q = m_hull[e].next; - while (area(x, - y, - m_hull[q].x, - m_hull[q].y, - m_hull[m_hull[q].next].x, - m_hull[m_hull[q].next].y) - < 0) { - t = add_triangle(m_hull[q].i, - i, - m_hull[m_hull[q].next].i, - m_hull[m_hull[q].prev].t, - -1, - m_hull[q].t); - m_hull[m_hull[q].prev].t = legalize(t + 2, coords); - remove_node(q); - q = m_hull[q].next; - - assert(q >= 0 && q < m_hull.size()); - } - if (walk_back) { - // walk backward from the other side, adding more triangles and flipping - q = m_hull[e].prev; - - assert(q >= 0 && q < m_hull.size()); - - while (area(x, - y, - m_hull[m_hull[q].prev].x, - m_hull[m_hull[q].prev].y, - m_hull[q].x, - m_hull[q].y) - < 0) { - t = add_triangle(m_hull[m_hull[q].prev].i, - i, - m_hull[q].i, - -1, - m_hull[q].t, - m_hull[m_hull[q].prev].t); - legalize(t + 2, coords); - m_hull[m_hull[q].prev].t = t; - remove_node(q); - q = m_hull[q].prev; - assert(q >= 0 && q < m_hull.size()); - } - } - hash_edge(e); - hash_edge(m_hull[e].prev); - } - - return true; -}; - -int64_t Delaunator::remove_node(int64_t node) -{ - m_hull[m_hull[node].prev].next = m_hull[node].next; - m_hull[m_hull[node].next].prev = m_hull[node].prev; - m_hull[node].removed = true; - return m_hull[node].prev; -} - -int64_t Delaunator::legalize(int64_t a, const vector& coords) -{ - // int64_t halfedges_size = halfedges.size(); - const int64_t b = halfedges[a]; - - const int64_t a0 = a - a % 3; - const int64_t b0 = b - b % 3; - - const int64_t al = a0 + (a + 1) % 3; - const int64_t ar = a0 + (a + 2) % 3; - const int64_t bl = b0 + (b + 2) % 3; - - const int64_t p0 = triangles[ar]; - const int64_t pr = triangles[a]; - const int64_t pl = triangles[al]; - const int64_t p1 = triangles[bl]; - - const bool illegal = in_circle(coords[2 * p0], - coords[2 * p0 + 1], - coords[2 * pr], - coords[2 * pr + 1], - coords[2 * pl], - coords[2 * pl + 1], - coords[2 * p1], - coords[2 * p1 + 1]); - - if (illegal) { - triangles[a] = p1; - triangles[b] = p0; - link(a, halfedges[bl]); - link(b, halfedges[ar]); - link(ar, bl); - - const int64_t br = b0 + (b + 1) % 3; - - legalize(a, coords); - return legalize(br, coords); - } - return ar; -} - -int64_t Delaunator::insert_node(int64_t i, int64_t prev, const vector& coords) -{ - const int64_t node = insert_node(i, coords); - m_hull[node].next = m_hull[prev].next; - m_hull[node].prev = prev; - m_hull[m_hull[node].next].prev = node; - m_hull[prev].next = node; - return node; -}; - -int64_t Delaunator::insert_node(int64_t i, const vector& coords) -{ - int64_t node = m_hull.size(); - DelaunatorPoint p; - p.i = i; - p.x = coords[2 * i]; - p.y = coords[2 * i + 1]; - p.prev = node; - p.next = node; - p.removed = false; - m_hull.push_back(move(p)); - return node; -} - -int64_t Delaunator::hash_key(double x, double y) -{ - const double dx = x - m_center_x; - const double dy = y - m_center_y; - // use pseudo-angle: a measure that monotonically increases - // with real angle, but doesn't require expensive trigonometry - - double den = std::abs(dx) + std::abs(dy); - double p = 0; - - // potential division by zero! - // previously: const double p = 1 - dx / (std::abs(dx) + std::abs(dy)); - if (den != 0) { - p = 1 - dx / den; - } - - double nom = (2 + (dy < 0 ? -p : p)); - int64_t key = std::floor((m_hash_size - 1) * (nom / 4.0)); // this will behave differently from js version! - // int64_t key = std::floor( (m_hash_size) * (nom / 4.0) ); // this will behave differently from js version! - - return key; -} - -void Delaunator::hash_edge(int64_t e) -{ - m_hash[hash_key(m_hull[e].x, m_hull[e].y)] = e; -} - -int64_t Delaunator::add_triangle( - int64_t i0, int64_t i1, int64_t i2, int64_t a, int64_t b, int64_t c) -{ - const int64_t t = triangles.size(); - triangles.push_back(i0); - triangles.push_back(i1); - triangles.push_back(i2); - link(t, a); - link(t + 1, b); - link(t + 2, c); - return t; -} - -void Delaunator::link(int64_t a, int64_t b) -{ - int64_t s = halfedges.size(); - if (a == s) { - halfedges.push_back(b); - } else if (a < s) { - halfedges[a] = b; - } else { - throw runtime_error("Cannot link edge"); - } - if (b != -1) { - int64_t s = halfedges.size(); - if (b == s) { - halfedges.push_back(a); - } else if (b < s) { - halfedges[b] = a; - } else { - throw runtime_error("Cannot link edge"); - } - } -}; -} // namespace delaunator_cpp diff --git a/src/terrainlib/tntn/Delaunator.h b/src/terrainlib/tntn/Delaunator.h deleted file mode 100644 index 6d354e1..0000000 --- a/src/terrainlib/tntn/Delaunator.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace delaunator_cpp { -struct DelaunatorPoint { - int64_t i; - double x; - double y; - int64_t t; - int64_t prev; - int64_t next; - bool removed; -}; - -class Delaunator { - -public: - bool triangulate(const std::vector& coords); - - std::vector triangles; - std::vector halfedges; - -private: - double m_center_x; - double m_center_y; - int64_t m_hash_size; - - std::vector m_hash; - std::vector m_hull; - -private: - int64_t hash_key(double x, double y); - void hash_edge(int64_t e); - - int64_t add_triangle(int64_t i0, int64_t i1, int64_t i2, int64_t a, int64_t b, int64_t c); - - void link(int64_t a, int64_t b); - int64_t legalize(int64_t a, const std::vector& coords); - - int64_t remove_node(int64_t node); - int64_t insert_node(int64_t i, const std::vector& coords); - int64_t insert_node(int64_t i, int64_t prev, const std::vector& coords); -}; - -} // namespace delaunator_cpp diff --git a/src/terrainlib/tntn/DelaunayMesh.cpp b/src/terrainlib/tntn/DelaunayMesh.cpp deleted file mode 100644 index 7ad8407..0000000 --- a/src/terrainlib/tntn/DelaunayMesh.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include "DelaunayMesh.h" -#include "DelaunayTriangle.h" - -namespace tntn { -namespace terra { - - dt_ptr DelaunayMesh::make_face(qe_ptr e) - { - dt_ptr t = m_triangles->spawn(); - t->init(t, e); - - m_first_face = t->linkTo(m_first_face); - return t; - } - - void DelaunayMesh::init_mesh(const Point2D a, const Point2D b, const Point2D c, const Point2D d) - { - qe_ptr ea = m_edges->spawn(); - ea->init(ea); - ea->set_end_points(a, b); - - qe_ptr eb = m_edges->spawn(); - eb->init(eb); - splice(ea->Sym(), eb); - eb->set_end_points(b, c); - - qe_ptr ec = m_edges->spawn(); - ec->init(ec); - splice(eb->Sym(), ec); - ec->set_end_points(c, d); - - qe_ptr ed = m_edges->spawn(); - ed->init(ed); - splice(ec->Sym(), ed); - ed->set_end_points(d, a); - splice(ed->Sym(), ea); - - qe_ptr diag = m_edges->spawn(); - diag->init(diag); - splice(ed->Sym(), diag); - splice(eb->Sym(), diag->Sym()); - diag->set_end_points(a, c); - - m_starting_edge = ea; - - m_first_face.clear(); - - make_face(ea->Sym()); - make_face(ec->Sym()); - } - - void DelaunayMesh::delete_edge(qe_ptr e) - { - splice(e, e->Oprev()); - splice(e->Sym(), e->Sym()->Oprev()); - e->recycle_next(); - e.recycle(); - } - - qe_ptr DelaunayMesh::connect(qe_ptr a, qe_ptr b) - { - qe_ptr e = m_edges->spawn(); - e->init(e); - - splice(e, a->Lnext()); - splice(e->Sym(), b); - e->set_end_points(a->Dest(), b->Org()); - return e; - } - - void DelaunayMesh::swap(qe_ptr e) - { - dt_ptr f1 = e->Lface(); - dt_ptr f2 = e->Sym()->Lface(); - - qe_ptr a = e->Oprev(); - qe_ptr b = e->Sym()->Oprev(); - - splice(e, a); - splice(e->Sym(), b); - splice(e, a->Lnext()); - splice(e->Sym(), b->Lnext()); - e->set_end_points(a->Dest(), b->Dest()); - - f1->reshape(e); - f2->reshape(e->Sym()); - } - - // - // Helper functions - // - - bool DelaunayMesh::ccw_boundary(qe_ptr e) - { - return !rightOf(e->Oprev()->Dest(), e); - } - - bool DelaunayMesh::on_edge(const Point2D x, qe_ptr e) - { - double t1, t2, t3; - - t1 = (x - e->Org()).length(); - t2 = (x - e->Dest()).length(); - - if (t1 < EPS || t2 < EPS) - return true; - - t3 = (e->Org() - e->Dest()).length(); - - if (t1 > t3 || t2 > t3) - return false; - - Line line(e->Org(), e->Dest()); - return (fabs(line.eval(x)) < EPS); - } - - // Tests whether e is an interior edge - bool DelaunayMesh::is_interior(qe_ptr e) - { - return (e->Lnext()->Lnext()->Lnext() == e && e->Rnext()->Rnext()->Rnext() == e); - } - - bool DelaunayMesh::should_swap(const Point2D x, qe_ptr e) - { - qe_ptr t = e->Oprev(); - return inCircle(e->Org(), t->Dest(), e->Dest(), x); - } - - void DelaunayMesh::scan_triangle(dt_ptr t) - { - // noop - } - - qe_ptr DelaunayMesh::locate(const Point2D x, qe_ptr start) - { - qe_ptr e = start; - double t = triAreaX2(x, e->Dest(), e->Org()); - - if (t > 0) { // x is to the right of edge e - t = -t; - e = e->Sym(); - } - - while (true) { - qe_ptr eo = e->Onext(); - qe_ptr ed = e->Dprev(); - - double to = triAreaX2(x, eo->Dest(), eo->Org()); - double td = triAreaX2(x, ed->Dest(), ed->Org()); - - if (td > 0) { // x is below ed - if (to > 0 || (to == 0 && t == 0)) { - // x is interior, or origin endpoint - m_starting_edge = e; - return e; - } else { - // x is below ed, below eo - t = to; - e = eo; - } - } else { // x is on or above ed - if (to > 0) { - // x is above eo - if (td == 0 && t == 0) { - // x is destination endpoint - m_starting_edge = e; - return e; - } else { - // x is on or above ed and above eo - t = td; - e = ed; - } - } else { - // x is on or below eo - if (t == 0 && !leftOf(eo->Dest(), e)) { - // x on e but DelaunayMesh is to right - e = e->Sym(); - } else if ((next_random_number() & 1) == 0) { - // x is on or above ed and on or below eo; step randomly - t = to; - e = eo; - } else { - t = td; - e = ed; - } - } - } - } - } - - qe_ptr DelaunayMesh::spoke(const Point2D x, qe_ptr e) - { - dt_ptr new_faces[4]; - int facedex = 0; - - qe_ptr boundary_edge; - - dt_ptr lface = e->Lface(); - lface->dontAnchor(e); - new_faces[facedex++] = lface; - - if (on_edge(x, e)) { - if (ccw_boundary(e)) { - // e lies on the boundary - // Defer deletion until after new edges are added. - boundary_edge = e; - } else { - dt_ptr sym_lface = e->Sym()->Lface(); - new_faces[facedex++] = sym_lface; - sym_lface->dontAnchor(e->Sym()); - - e = e->Oprev(); - delete_edge(e->Onext()); - } - } else { - // x lies within the Lface of e - } - - qe_ptr base = m_edges->spawn(); - base->init(base); - - base->set_end_points(e->Org(), x); - - splice(base, e); - - m_starting_edge = base; - do { - base = connect(e, base->Sym()); - e = base->Oprev(); - } while (e->Lnext() != m_starting_edge); - - if (boundary_edge) - delete_edge(boundary_edge); - - // Update all the faces in our new spoked polygon. - // If point x on perimeter, then don't add an exterior face. - - base = boundary_edge ? m_starting_edge->Rprev() : m_starting_edge->Sym(); - - do { - if (facedex) { - new_faces[--facedex]->reshape(base); - } else { - make_face(base); - } - - base = base->Onext(); - } while (base != m_starting_edge->Sym()); - - return m_starting_edge; - } - - // s is a spoke pointing OUT from x - void DelaunayMesh::optimize(const Point2D x, qe_ptr s) - { - qe_ptr start_spoke = s; - qe_ptr spoke = s; - - do { - qe_ptr e = spoke->Lnext(); - if (is_interior(e) && should_swap(x, e)) { - swap(e); - } else { - spoke = spoke->Onext(); - if (spoke == start_spoke) - break; - } - } while (true); - - // Now, update all the triangles - spoke = start_spoke; - - do { - qe_ptr e = spoke->Lnext(); - dt_ptr t = e->Lface(); - - if (t) - this->scan_triangle(t); - - spoke = spoke->Onext(); - } while (spoke != start_spoke); - } - - void DelaunayMesh::insert(const Point2D x, dt_ptr tri) - { - qe_ptr e = tri ? locate(x, tri->getAnchor()) : locate(x); - - if ((x == e->Org()) || (x == e->Dest())) { - // point is already in the mesh, so update the triangles x is in - optimize(x, e); - } else { - qe_ptr start_spoke = spoke(x, e); - if (start_spoke) { - optimize(x, start_spoke->Sym()); - } - } - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/DelaunayMesh.h b/src/terrainlib/tntn/DelaunayMesh.h deleted file mode 100644 index 1f66145..0000000 --- a/src/terrainlib/tntn/DelaunayMesh.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "DelaunayTriangle.h" -#include "Mesh.h" -#include "ObjPool.h" -#include "QuadEdge.h" -#include "SurfacePoints.h" - -#include - -namespace tntn { -namespace terra { - - class DelaunayMesh { - private: - std::shared_ptr> m_edges; - std::shared_ptr> m_triangles; - std::mt19937 m_random_gen; - - protected: - qe_ptr m_starting_edge; - dt_ptr m_first_face; - - dt_ptr make_face(qe_ptr e); - - void delete_edge(qe_ptr e); - - qe_ptr connect(qe_ptr a, qe_ptr b); - void swap(qe_ptr e); - - bool ccw_boundary(qe_ptr e); - bool on_edge(const Point2D, qe_ptr e); - - unsigned int next_random_number() - { - return m_random_gen() % std::numeric_limits::max(); - } - - public: - DelaunayMesh() - : m_edges(ObjPool::create()) - , m_triangles(ObjPool::create()) - , m_random_gen(42) // fixed seed for deterministics sequence of random numbers - { - m_edges->reserve(4096); - m_triangles->reserve(1024); - } - - void init_mesh(const Point2D a, const Point2D b, const Point2D c, const Point2D d); - - // convenience function using our 2D bounding box - void init_mesh(const BBox2D& bb) - { - const glm::dvec2& a = bb.min; - const glm::dvec2& d = bb.max; - const glm::dvec2& b = glm::dvec2(bb.max.x, bb.min.y); - const glm::dvec2& c = glm::dvec2(bb.min.x, bb.max.y); - init_mesh(a, b, c, d); - } - - // virtual function for customization - virtual bool should_swap(const Point2D, qe_ptr e); - virtual void scan_triangle(dt_ptr t); - - bool is_interior(qe_ptr e); - - // add a new point to the mesh (add vertex and edges to surrounding vertices) - qe_ptr spoke(const Point2D x, qe_ptr e); - void optimize(const Point2D x, qe_ptr e); - - qe_ptr locate(const Point2D x) { return locate(x, m_starting_edge); } - qe_ptr locate(const Point2D, qe_ptr hint); - void insert(const Point2D x, dt_ptr tri); - - // void overEdges(edge_callback, void *closure=NULL); - // void overFaces(face_callback, void *closure=NULL); - }; - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/DelaunayTriangle.cpp b/src/terrainlib/tntn/DelaunayTriangle.cpp deleted file mode 100644 index 76f2f45..0000000 --- a/src/terrainlib/tntn/DelaunayTriangle.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "DelaunayTriangle.h" - -namespace tntn { -namespace terra { - - void DelaunayTriangle::dontAnchor(qe_ptr e) - { - if (anchor == e) { - anchor = e->Lnext(); - } - } - - void DelaunayTriangle::reshape(qe_ptr e) - { - anchor = e; - e->set_Lface(self_ptr); - e->Lnext()->set_Lface(self_ptr); - e->Lprev()->set_Lface(self_ptr); - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/DelaunayTriangle.h b/src/terrainlib/tntn/DelaunayTriangle.h deleted file mode 100644 index 09c81e0..0000000 --- a/src/terrainlib/tntn/DelaunayTriangle.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "ObjPool.h" -#include "QuadEdge.h" -#include "tntn_assert.h" - -namespace tntn { -namespace terra { - - class DelaunayTriangle; - typedef pool_ptr dt_ptr; - - class DelaunayTriangle { - qe_ptr anchor; - dt_ptr next_face; - dt_ptr self_ptr; - - public: - DelaunayTriangle() { } - - void init(dt_ptr self_ptr, qe_ptr e) - { - TNTN_ASSERT(self_ptr.get() == this); - this->self_ptr = self_ptr; - reshape(e); - } - - dt_ptr linkTo(dt_ptr t) - { - next_face = t; - return self_ptr; - } - - dt_ptr getLink() { return next_face; } - - qe_ptr getAnchor() { return anchor; } - - void dontAnchor(qe_ptr e); - - void reshape(qe_ptr e); - - Point2D point1() const { return anchor->Org(); } - Point2D point2() const { return anchor->Dest(); } - Point2D point3() const { return anchor->Lprev()->Org(); } - }; - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/File.cpp b/src/terrainlib/tntn/File.cpp deleted file mode 100644 index a9aa309..0000000 --- a/src/terrainlib/tntn/File.cpp +++ /dev/null @@ -1,385 +0,0 @@ -#include "File.h" -#include "logging.h" -#include "tntn_assert.h" - -#include -#include -#include -#include - -namespace tntn { - -static constexpr size_t max_read_write_chunk_size = std::numeric_limits::max(); - -static const char* openmode_to_fopen_mode(File::OpenMode open_mode) -{ - switch (open_mode) { - case File::OM_R: - return "r"; - case File::OM_RW: - return "r+"; - case File::OM_RWC: - return "w+x"; - case File::OM_RWCF: - return "w+"; - default: - return "r"; - } -} - -class File::FileImpl { -public: - bool open(const char* filename, OpenMode open_mode) - { - close(); - const char* const omstr = openmode_to_fopen_mode(open_mode); - FILE* fp = fopen(filename, omstr); - const auto err = errno; - TNTN_LOG_TRACE("fopen({}, {}) = {} / errno = {}", filename, omstr, fp != nullptr, err); - m_fp = fp; - m_is_good = fp != nullptr; - m_size = get_size(); - m_filename = filename; - return is_good(); - } - - bool close() - { - int rc = 0; - if (m_fp != nullptr) { - rc = fclose(m_fp); - const auto err = errno; - if (rc != 0) { - TNTN_LOG_DEBUG("fclose on {} failed with errno {}", m_filename, err); - } - m_fp = nullptr; - m_size = 0; - m_is_good = false; - m_filename.clear(); - } - return rc == 0; - } - - std::string name() const { return m_filename; } - - bool is_good() { return m_fp != nullptr && m_is_good; } - - position_type size() { return m_size; } - - size_t read(position_type from_offset, unsigned char* buffer, size_t size_of_buffer) - { - if (!is_good()) { - return 0; - } - if (!seek_to_position(from_offset)) { - m_is_good = false; - return 0; - } - if (size_of_buffer > max_read_write_chunk_size) { - TNTN_LOG_ERROR("huge read > INT_MAX bytes, won't do that"); - return 0; - } - - const size_t rc = fread(buffer, 1, size_of_buffer, m_fp); - return rc; - } - - bool write(position_type to_offset, const unsigned char* data, size_t data_size) - { - if (!is_good()) { - return false; - } - if (data_size > max_read_write_chunk_size) { - TNTN_LOG_ERROR("huge write > INT_MAX bytes, won't do that"); - m_is_good = false; - return false; - } - if (!seek_to_position(to_offset)) { - m_is_good = false; - return false; - } - - const size_t rc = fwrite(data, 1, data_size, m_fp); - const auto err = errno; - if (rc != data_size) { - TNTN_LOG_ERROR( - "unable to write {} bytes into file {}, errno = {}", data_size, m_filename, err); - m_is_good = false; - m_size = get_size(); - return false; - } else { - // rc == data_size - if (to_offset + static_cast(data_size) > m_size) { - m_size = to_offset + data_size; - } - return true; - } - } - - void flush() - { - if (m_fp) { - int rc = fflush(m_fp); - const auto err = errno; - if (rc != 0) { - TNTN_LOG_ERROR("fflush failed, errno = {}", m_filename, err); - } - } - } - -private: - bool seek_to_position(position_type position) - { - int rc = fseek(m_fp, 0, SEEK_SET); - auto err = errno; - while (rc == 0 && position > 0) { - if (position > std::numeric_limits::max()) { - rc = fseek(m_fp, std::numeric_limits::max(), SEEK_CUR); - err = errno; - position -= std::numeric_limits::max(); - } else { - rc = fseek(m_fp, static_cast(position), SEEK_CUR); - err = errno; - position = 0; - } - } - if (rc == 0 && position == 0) { - return true; - } else { - TNTN_LOG_ERROR("unable to fseek correctly in file {}, errno = {}", m_filename, err); - return false; - } - } - - position_type get_size() - { - if (!m_fp) { - return 0; - } - int rc = fseek(m_fp, 0, SEEK_END); - auto err = errno; - if (rc == 0) { - const off_t end_pos = ftello(m_fp); - if (end_pos >= 0) { - return static_cast(end_pos); - } - } else { - TNTN_LOG_ERROR("unable to fseek correctly in file {}, errno = {}", m_filename, err); - m_is_good = false; - } - return 0; - } - - FILE* m_fp = nullptr; - position_type m_size = 0; - bool m_is_good = false; - std::string m_filename; -}; - -File::File() - : m_impl(std::make_unique()) -{ -} - -File::~File() -{ - m_impl->close(); -} - -bool File::open(const char* filename, OpenMode open_mode) -{ - return m_impl->open(filename, open_mode); -} -bool File::open(const std::string& filename, OpenMode open_mode) -{ - return open(filename.c_str(), open_mode); -} - -bool File::close() -{ - return m_impl->close(); -} - -std::string File::name() const -{ - return m_impl->name(); -} - -bool File::is_good() -{ - return m_impl->is_good(); -} -FileLike::position_type File::size() -{ - return m_impl->size(); -} -size_t File::read(position_type from_offset, unsigned char* buffer, size_t size_of_buffer) -{ - return m_impl->read(from_offset, buffer, size_of_buffer); -} -bool File::write(position_type to_offset, const unsigned char* data, size_t data_size) -{ - return m_impl->write(to_offset, data, data_size); -} -void File::flush() -{ - return m_impl->flush(); -} - -bool MemoryFile::is_good() -{ - return m_is_good; -} - -FileLike::position_type MemoryFile::size() -{ - return m_data.size(); -} - -size_t MemoryFile::read(position_type from_offset_ui64, - unsigned char* buffer, - size_t size_of_buffer) -{ - if (!m_is_good) { - return false; - } - if (!buffer) { - TNTN_LOG_ERROR("buffer is NULL"); - return false; - } - if (size_of_buffer == 0) { - return 0; - } - if (from_offset_ui64 > std::numeric_limits::max()) { - TNTN_LOG_ERROR("unable to read more then SIZE_T_MAX bytes from MemoryFile"); - return 0; - } - if (size_of_buffer > max_read_write_chunk_size) { - TNTN_LOG_ERROR("huge read > INT_MAX bytes, won't do that"); - return 0; - } - - const size_t from_offset = static_cast(from_offset_ui64); - - size_t bytes_to_read = 0; - if (from_offset > m_data.size()) { - m_is_good = false; - return 0; - } else if (from_offset + size_of_buffer > m_data.size()) { - bytes_to_read = m_data.size() - from_offset; - } else { - bytes_to_read = size_of_buffer; - } - - memcpy(buffer, m_data.data() + from_offset, bytes_to_read); - return bytes_to_read; -} - -bool MemoryFile::write(position_type to_offset_ui64, const unsigned char* data, size_t data_size) -{ - if (!m_is_good) { - return false; - } - if (!data || data_size == 0) { - return true; - } - if (to_offset_ui64 > std::numeric_limits::max()) { - TNTN_LOG_ERROR("unable to write more then SIZE_T_MAX bytes into MemoryFile"); - return false; - } - if (data_size > max_read_write_chunk_size) { - TNTN_LOG_ERROR("huge write > INT_MAX bytes, won't do that"); - m_is_good = false; - return false; - } - - const size_t to_offset = static_cast(to_offset_ui64); - - if (to_offset + data_size > m_data.size()) { - try { - m_data.resize(to_offset + data_size); - } catch (const std::bad_alloc&) { - TNTN_LOG_ERROR("unabled to resize MemoryFile to {}, std::bad_alloc", - to_offset + data_size); - return false; - } - } - memcpy(m_data.data() + to_offset, data, data_size); - return data_size; -} - -FileLike::position_type getline(FileLike::position_type from_offset, - FileLike& f, - std::string& str) -{ - str.clear(); - if (!f.is_good()) { - TNTN_LOG_ERROR("file-like object is not in a good state, cannot getline"); - return 0; - } - const char delim = '\n'; - // read in chunks of 4k - constexpr size_t read_chunk_size = 4 * 1024; - std::vector tmp; - tmp.reserve(read_chunk_size); - - bool delim_found = false; - bool has_eof = false; - auto read_position = from_offset; - while (!delim_found && !has_eof) { - f.read(read_position, tmp, read_chunk_size); - read_position += tmp.size(); - if (tmp.size() != read_chunk_size) { - // eof or read error - has_eof = true; - } - size_t copy_count = 0; - // scan for delimiter - for (; copy_count < tmp.size() && !delim_found; copy_count++) { - delim_found = tmp[copy_count] == delim; - } - copy_count -= delim_found ? 1 : 0; // ignore delimiter - // copy over chunk - if (copy_count > 0) { - const size_t old_str_size = str.size(); - str.resize(old_str_size + copy_count); - memcpy(&str[old_str_size], &tmp[0], copy_count); - } - } - return from_offset + str.size() + (delim_found ? 1 : 0); -} - -FileLike::position_type getline(FileLike::position_type from_offset, - const std::shared_ptr& f, - std::string& str) -{ - if (!f) { - TNTN_LOG_ERROR("cannot getline from file-like object that is NULL"); - return 0; - } - return getline(from_offset, *f, str); -} - -GZipWriteFile::~GZipWriteFile() -{ - auto* file = gzopen(m_filename.c_str(), "w9"); - { - const auto err = errno; - if (file == nullptr) { - TNTN_LOG_ERROR("gzopen({}, {}) = {} / errno = {}", m_filename.c_str(), "w+9", file != nullptr, err); - return; - } - TNTN_LOG_TRACE("gzopen({}, {}) = {} / errno = {}", m_filename.c_str(), "w+9", file != nullptr, err); - } - - TNTN_ASSERT(size_t(m_memory_file.m_data.size()) < size_t(std::numeric_limits::max())); - const auto n_uncompressed_bytes_written = gzwrite(file, voidpc(m_memory_file.m_data.data()), unsigned(m_memory_file.size())); - TNTN_ASSERT(n_uncompressed_bytes_written == int(m_memory_file.size())); - - const auto err = gzclose(file); - if (err != Z_OK) { - TNTN_LOG_DEBUG("gzclose on {} failed with errno {}", m_filename, err); - } -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/File.h b/src/terrainlib/tntn/File.h deleted file mode 100644 index 9ea8a1b..0000000 --- a/src/terrainlib/tntn/File.h +++ /dev/null @@ -1,201 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace tntn { - -class FileLike { -private: - // disallow copy and assign - FileLike(const FileLike& other) = delete; - FileLike& operator=(const FileLike& other) = delete; - -public: - FileLike() = default; - virtual ~FileLike() = default; - - typedef uint64_t position_type; - - /** - get an optional describing string - for a real File it should be a filename - for other implementations the meaning is implementation specific - */ - virtual std::string name() const = 0; - - /** - check whether the object can be used (read from, written to) - implementations might set the internal is_good flag to false on - failing write and/or read operations. - */ - virtual bool is_good() = 0; - - /** - get the number of bytes currently in this object - keep in mind that this value is allways an unsigned 64bit type while - on 32bit platforms size_t is only 32bit. - */ - virtual position_type size() = 0; - - /** - read data - @param from_offset offset against the beginning of the file-like, 0 is the beginning. - @return the actual number of bytes read, returns less then size_of_buffer on eof or read error - */ - virtual size_t read(position_type from_offset, - unsigned char* buffer, - size_t size_of_buffer) - = 0; - - /** - write data - - @param to_offset offset against the beginning of the file, can be > size in which case the internal object will be expanded - @return success/failure - */ - virtual bool write(position_type to_offset, const unsigned char* data, size_t data_size) = 0; - - virtual void flush() = 0; - - // convenience wrappers: - - size_t read(position_type from_offset, char* buffer, size_t size_of_buffer) - { - return read(from_offset, reinterpret_cast(buffer), size_of_buffer); - } - void read(position_type from_offset, std::vector& buffer, size_t max_bytes) - { - buffer.resize(max_bytes); - size_t bytes_read = read(from_offset, buffer.data(), max_bytes); - buffer.resize(bytes_read); - } - void read(position_type from_offset, std::vector& buffer, size_t max_bytes) - { - buffer.resize(max_bytes); - size_t bytes_read = read(from_offset, buffer.data(), max_bytes); - buffer.resize(bytes_read); - } - void read(position_type from_offset, std::string& buffer, size_t max_bytes) - { - buffer.resize(max_bytes); - if (max_bytes > 0) { - size_t bytes_read = read(from_offset, &buffer[0], max_bytes); - buffer.resize(bytes_read); - } - } - - bool write(position_type to_offset, const char* data, size_t data_size) - { - return write(to_offset, reinterpret_cast(data), data_size); - } - bool write(position_type to_offset, const std::vector& data) - { - return write(to_offset, data.data(), data.size()); - } - bool write(position_type to_offset, const std::vector& data) - { - return write(to_offset, data.data(), data.size()); - } - bool write(position_type to_offset, const std::string& data) - { - return write(to_offset, data.data(), data.size()); - } -}; - -class File : public FileLike { -public: - enum OpenMode { - OM_NONE, - OM_R, // read - OM_RW, // read-write - OM_RWC, // read-write-create (not overwriting aka exclusive create) - OM_RWCF, // read-write, force-create (overwrite when existing) - }; - bool open(const char* filename, OpenMode open_mode); - bool open(const std::string& filename, OpenMode open_mode); - - bool close(); - - File(); - ~File(); - - std::string name() const override; - - bool is_good() override; - position_type size() override; - - size_t read(position_type from_offset, unsigned char* buffer, size_t size_of_buffer) override; - using FileLike::read; // import convenience overloads - - bool write(position_type to_offset, const unsigned char* data, size_t data_size) override; - using FileLike::write; // import convenience overloads - - void flush() override; - -private: - class FileImpl; - std::unique_ptr m_impl; -}; - -class GZipWriteFile; - -class MemoryFile : public FileLike { - friend class GZipWriteFile; - -public: - std::string name() const override { return std::string(); } - - bool is_good() override; - position_type size() override; - - size_t read(position_type from_offset, unsigned char* buffer, size_t size_of_buffer) override; - using FileLike::read; // import convenience overloads - - bool write(position_type to_offset, const unsigned char* data, size_t data_size) override; - using FileLike::write; // import convenience overloads - - void flush() override { } - -private: - std::vector m_data; - bool m_is_good = true; -}; - -class GZipWriteFile : public FileLike { -public: - GZipWriteFile(const std::string& filename) - : m_filename(filename) - { - } - ~GZipWriteFile() override; - - std::string name() const override { return m_filename; } - - bool is_good() override { return m_memory_file.is_good(); } - position_type size() override { return m_memory_file.size(); } - - size_t read(position_type from_offset, unsigned char* buffer, size_t size_of_buffer) override { return m_memory_file.read(from_offset, buffer, size_of_buffer); } - using FileLike::read; // import convenience overloads - - bool write(position_type to_offset, const unsigned char* data, size_t data_size) override { return m_memory_file.write(to_offset, data, data_size); } - using FileLike::write; // import convenience overloads - - void flush() override { } // don't want to write before everything is there. writing in destructor. - -private: - std::string m_filename; - MemoryFile m_memory_file; -}; - -FileLike::position_type getline(FileLike::position_type from_offset, - FileLike& f, - std::string& str); -FileLike::position_type getline(FileLike::position_type from_offset, - const std::shared_ptr& f, - std::string& str); - -} // namespace tntn diff --git a/src/terrainlib/tntn/FileFormat.h b/src/terrainlib/tntn/FileFormat.h deleted file mode 100644 index 10942be..0000000 --- a/src/terrainlib/tntn/FileFormat.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#include "MeshMode.h" -#include -#include - -namespace tntn { - -class FileFormat { -public: - enum Value { - NONE = 0, - OFF = 1, - OBJ = 2, - ASC = 3, - XYZ = 4, - TERRAIN = 5, - JSON = 6, - GEOJSON = 7, - TIFF = 8, - TIF = 9, - TERRAINGZ = 10, - }; - - FileFormat() = default; - FileFormat(const FileFormat& f) = default; - FileFormat& operator=(const FileFormat& f) = default; - - FileFormat(const Value v) - : m_value(v) - { - } - FileFormat& operator=(const Value v) noexcept - { - m_value = v; - return *this; - } - - bool operator==(const Value v) const noexcept { return m_value == v; } - bool operator!=(const Value v) const noexcept { return m_value != v; } - bool operator==(const FileFormat& f) const noexcept { return m_value == f.m_value; } - bool operator!=(const FileFormat& f) const noexcept { return m_value != f.m_value; } - - // for use in std::map etc. - bool operator<(const FileFormat& f) const noexcept - { - return static_cast(m_value) < static_cast(f.m_value); - } - - std::string to_string() const { return std::string(to_cstring()); } - - const char* to_cstring() const noexcept - { - switch (m_value) { - case NONE: - return ""; - case OFF: - return "off"; - case OBJ: - return "obj"; - case ASC: - return "asc"; - case XYZ: - return "xyz"; - case TERRAINGZ: - "terrain.gz"; - case TERRAIN: - return "terrain"; - case JSON: - return "json"; - case GEOJSON: - return "geojson"; - case TIFF: - return "tiff"; - case TIF: - return "tif"; - } - return ""; - } - - static FileFormat from_string(const std::string& s) noexcept - { - return from_string(s.c_str()); - } - static FileFormat from_string(const char* s) noexcept - { - if (strcasecmp(s, "off") == 0) - return OFF; - else if (strcasecmp(s, "obj") == 0) - return OBJ; - else if (strcasecmp(s, "asc") == 0) - return ASC; - else if (strcasecmp(s, "xyz") == 0) - return XYZ; - else if (strcasecmp(s, "terrain") == 0) - return TERRAIN; - else if (strcasecmp(s, "terrain.gz") == 0) - return TERRAINGZ; - else if (strcasecmp(s, "json") == 0) - return JSON; - else if (strcasecmp(s, "geojson") == 0) - return GEOJSON; - else if (strcasecmp(s, "tiff") == 0) - return TIFF; - else if (strcasecmp(s, "tif") == 0) - return TIF; - else - return NONE; - } - - static FileFormat from_fileext(const std::string& s) noexcept - { - return from_fileext(s.c_str()); - } - static FileFormat from_fileext(const char* s) noexcept - { - if (*s == '.') { - return from_string(s + 1); - } else { - return from_string(s); - } - } - - MeshMode optimal_mesh_mode() const - { - switch (m_value) { - case OBJ: - [[fallthrough]]; - case OFF: - [[fallthrough]]; - case TERRAINGZ: - [[fallthrough]]; - case TERRAIN: - return MeshMode::decomposed; - default: - return MeshMode::none; - } - } - -private: - Value m_value = NONE; -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/Mesh.cpp b/src/terrainlib/tntn/Mesh.cpp deleted file mode 100644 index 6b8e7c0..0000000 --- a/src/terrainlib/tntn/Mesh.cpp +++ /dev/null @@ -1,646 +0,0 @@ -#include "Mesh.h" - -#include -#include -#include -#include -#include - -#include "geometrix.h" -#include "logging.h" -#include "tntn_assert.h" - -namespace tntn { - -void Mesh::clear() -{ - m_triangles.clear(); - m_vertices.clear(); - m_faces.clear(); -} - -void Mesh::clear_triangles() -{ - m_triangles.clear(); -} - -void Mesh::clear_decomposed() -{ - m_vertices.clear(); - m_faces.clear(); -} - -Mesh Mesh::clone() const -{ - Mesh out; - out.m_faces = m_faces; - out.m_vertices = m_vertices; - out.m_triangles = m_triangles; - return out; -} - -void Mesh::from_decomposed(std::vector&& vertices, std::vector&& faces) -{ - clear(); - m_vertices = std::move(vertices); - m_faces = std::move(faces); -} - -void Mesh::from_triangles(std::vector&& triangles) -{ - m_triangles = std::move(triangles); -} - -size_t Mesh::poly_count() const -{ - TNTN_ASSERT((!has_triangles() || !has_decomposed()) || (has_triangles() && has_decomposed() && m_triangles.size() == m_faces.size())); - return has_triangles() ? m_triangles.size() : m_faces.size(); -} - -void Mesh::add_triangle(const Triangle& t, const bool decompose) -{ - m_triangles.push_back(t); - if (decompose || has_decomposed()) { - decompose_triangle(t); - } -} - -void Mesh::generate_triangles() -{ - - if (has_triangles()) { - return; - } - - TNTN_LOG_DEBUG("generate triangels..."); - - m_triangles.reserve(m_faces.size()); - - Triangle t; - for (const auto& face : m_faces) { - bool is_valid = true; - for (int i = 0; i < 3; i++) { - const VertexIndex vi = face[i]; - if (vi < m_vertices.size()) { - t[i] = m_vertices[vi]; - } else { - is_valid = false; - } - } - if (is_valid) { - m_triangles.push_back(t); - } - } - - TNTN_LOG_DEBUG("done"); -} - -void Mesh::generate_decomposed() -{ - if (has_decomposed()) - return; - - TNTN_LOG_DEBUG("generate decomposed..."); - - m_faces.reserve(m_triangles.size()); - m_vertices.reserve(m_triangles.size() * 0.66); - - std::unordered_map vertex_lookup; - vertex_lookup.reserve(m_vertices.capacity()); - - for (const auto& t : m_triangles) { - Face f; - for (int i = 0; i < 3; i++) { - const Vertex& v = t[i]; - const auto v_it = vertex_lookup.find(v); - if (v_it != vertex_lookup.end()) { - // vertex already in m_vertices; - f[i] = v_it->second; - } else { - // new vertex - f[i] = m_vertices.size(); - vertex_lookup.emplace_hint(v_it, v, m_vertices.size()); - m_vertices.push_back(v); - } - } - m_faces.push_back(f); - } - - TNTN_LOG_DEBUG("done"); -} - -void Mesh::decompose_triangle(const Triangle& t) -{ - Face f = { { std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max() } }; - - int found = 0; - for (size_t j = 0; j < m_vertices.size() && found < 3; j++) { - const auto& v = m_vertices[j]; - for (int i = 0; i < 3; i++) { - if (t[i] == v) { - f[i] = j; - found++; - } - } - } - if (found != 3) { - for (int i = 0; i < 3; i++) { - if (f[i] == std::numeric_limits::max()) { - f[i] = m_vertices.size(); - m_vertices.push_back(t[i]); - } - } - } - - m_faces.push_back(f); -} - -bool Mesh::compose_triangle(const Face& f, Triangle& out) const -{ - // check validity of indices - for (int i = 0; i < 3; i++) { - if (f[i] >= m_vertices.size()) - return false; - } - for (int i = 0; i < 3; i++) { - out[i] = m_vertices[f[i]]; - } - return true; -} - -SimpleRange Mesh::triangles() const -{ - if (m_triangles.empty()) { - return { nullptr, nullptr }; - } - return { m_triangles.data(), m_triangles.data() + m_triangles.size() }; -} - -SimpleRange Mesh::faces() const -{ - if (m_faces.empty()) { - return { nullptr, nullptr }; - } - return { m_faces.data(), m_faces.data() + m_faces.size() }; -} - -SimpleRange Mesh::vertices() const -{ - if (m_vertices.empty()) { - return { nullptr, nullptr }; - } - return { m_vertices.data(), m_vertices.data() + m_vertices.size() }; -} - -const std::vector& Mesh::vertices_as_vector() const -{ - return m_vertices; -} - -void Mesh::grab_triangles(std::vector& into) -{ - into.clear(); - into.swap(m_triangles); -} - -void Mesh::grab_decomposed(std::vector& vertices, std::vector& faces) -{ - vertices.clear(); - faces.clear(); - - vertices.swap(m_vertices); - faces.swap(m_faces); -} - -bool Mesh::semantic_equal(const Mesh& other) const -{ - if (poly_count() != other.poly_count()) { - return false; - } - - if (has_triangles() && other.has_triangles()) { - // both triangles - return semantic_equal_tri_tri(other); - } else if (has_decomposed() && other.has_decomposed()) { - // both vertices/faces - return semantic_equal_dec_dec(other); - } else { - // one triangles, one faces - if (has_triangles() && other.has_decomposed()) { - return semantic_equal_tri_dec(other); - } else if (has_decomposed() && other.has_triangles()) { - return other.semantic_equal_tri_dec(*this); - } else { - // empty meshes - TNTN_ASSERT(empty() && other.empty()); - return true; - } - } -} - -bool Mesh::semantic_equal_tri_tri(const Mesh& other) const -{ - const auto other_tris = other.triangles(); - std::vector other_tri_ptrs; - other_tri_ptrs.reserve(other_tris.size()); - other_tris.for_each([&other_tri_ptrs](const Triangle& t) { other_tri_ptrs.push_back(&t); }); - - // for each triangle find and equivalent triangle in other - // if found, remove from list so that cardinalities are honored - triangle_semantic_equal eq; - for (const Triangle& t : m_triangles) { - bool found_semantic_equal = false; - for (size_t i = 0; i < other_tri_ptrs.size(); i++) { - if (other_tri_ptrs[i] != nullptr && eq(t, *other_tri_ptrs[i])) { - other_tri_ptrs[i] = nullptr; - found_semantic_equal = true; - break; - } - } - if (!found_semantic_equal) - return false; - } - return true; -} - -bool Mesh::semantic_equal_dec_dec(const Mesh& other) const -{ - const auto other_faces = other.faces(); - std::vector other_face_ptrs; - other_face_ptrs.reserve(other_faces.size()); - other_faces.for_each([&other_face_ptrs](const Face& f) { other_face_ptrs.push_back(&f); }); - - // for each face, find equivalend face in other - // if found, remove from list so that cardinalities are honored - triangle_semantic_equal eq; - Triangle t1; - Triangle t2; - for (const Face& f : m_faces) { - if (!compose_triangle(f, t1)) { - continue; - } - bool found_semantic_equal = false; - for (size_t i = 0; i < other_face_ptrs.size(); i++) { - if (other_face_ptrs[i] != nullptr) { - if (!other.compose_triangle(*other_face_ptrs[i], t2)) { - other_face_ptrs[i] = nullptr; - continue; - } - if (eq(t1, t2)) { - other_face_ptrs[i] = nullptr; - found_semantic_equal = true; - break; - } - } - } - if (!found_semantic_equal) - return false; - } - return true; -} - -bool Mesh::semantic_equal_tri_dec(const Mesh& other) const -{ - TNTN_ASSERT(this->has_triangles()); - TNTN_ASSERT(other.has_decomposed()); - - const auto other_faces = other.faces(); - std::vector other_face_ptrs; - other_face_ptrs.reserve(other_faces.size()); - other_faces.for_each([&other_face_ptrs](const Face& f) { other_face_ptrs.push_back(&f); }); - - // for each triangle, find equivalend face in other - // if found, remove from list so that cardinalities are honored - triangle_semantic_equal eq; - Triangle t2; - for (const Triangle& t1 : m_triangles) { - bool found_semantic_equal = false; - for (size_t i = 0; i < other_face_ptrs.size(); i++) { - if (other_face_ptrs[i] != nullptr) { - if (!other.compose_triangle(*other_face_ptrs[i], t2)) { - other_face_ptrs[i] = nullptr; - continue; - } - if (eq(t1, t2)) { - other_face_ptrs[i] = nullptr; - found_semantic_equal = true; - break; - } - } - } - if (!found_semantic_equal) - return false; - } - return true; -} - -void Mesh::get_bbox(BBox3D& bbox) const -{ - bbox.add(m_vertices.begin(), m_vertices.end()); -} - -BBox3D Mesh::bbox() const -{ - BBox3D bbox; - bbox.add(m_vertices.begin(), m_vertices.end()); - return bbox; -} - -static bool face_edge_crosses_other_edge(const size_t fi, - const std::vector& faces, - const std::vector& vertices) -{ - const Face f = faces[fi]; - const std::array face_edges = { { - { f[0], f[1] }, - { f[1], f[2] }, - { f[2], f[0] }, - } }; - - Triangle ft; - ft[0] = vertices[f[0]]; - ft[1] = vertices[f[1]]; - ft[2] = vertices[f[2]]; - - BBox2D ft_bbox(ft); - - for (size_t oi = fi + 1; oi < faces.size(); oi++) { - const Face o = faces[oi]; - - const Triangle ot = { { - vertices[o[0]], - vertices[o[1]], - vertices[o[2]], - } }; - - BBox2D ot_bbox(ot); - if (ft_bbox.intersects(ot_bbox)) { - for (const Edge& e : face_edges) { - Edge oe = { o[0], o[1] }; - if (!e.shares_point(oe) && e.intersects2D(oe, vertices)) { - return true; - } - - oe.assign(o[1], o[2]); - if (!e.shares_point(oe) && e.intersects2D(oe, vertices)) { - return true; - } - oe.assign(o[2], o[0]); - if (!e.shares_point(oe) && e.intersects2D(oe, vertices)) { - return true; - } - } - } - } - - return false; -} - -/** - checks if mesh convex hull is square - and aligned with the bounding box extremes - - @return true if mesh is square, false otherwise - */ -bool Mesh::is_square() const -{ - BBox3D bb3d; - get_bbox(bb3d); - - double dx = bb3d.max.x - bb3d.min.x; - double dy = bb3d.max.y - bb3d.min.y; - - TNTN_ASSERT(dx > 0); - TNTN_ASSERT(dy > 0); - - double eps = (dx + dy) / 20000.0; - - // double check assumption that mesh is square and aligned with bb - // see if we have vertex points at all 4 corners of bb - - bool corners_exist[4]; - for (int i = 0; i < 4; i++) { - corners_exist[i] = false; - } - - for (const Vertex& v : m_vertices) { - if (std::abs(v.x - bb3d.min.x) < eps && std::abs(v.y - bb3d.min.y) < eps) { - corners_exist[0] = true; - } - - if (std::abs(v.x - bb3d.max.x) < eps && std::abs(v.y - bb3d.max.y) < eps) { - corners_exist[1] = true; - } - - if (std::abs(v.x - bb3d.max.x) < eps && std::abs(v.y - bb3d.min.y) < eps) { - corners_exist[2] = true; - } - - if (std::abs(v.x - bb3d.min.x) < eps && std::abs(v.y - bb3d.max.y) < eps) { - corners_exist[3] = true; - } - - int true_count = 0; - for (int i = 0; i < 4; i++) { - if (corners_exist[i]) { - true_count++; - } - } - - if (true_count == 4) { - return true; - } - } - - return false; -} - -/** - checks if mesh has holes in it - will only work for meshes where the convex hull is square - and aligned with the bounding box extremes - - @return true if mesh has hole, false otherwise - */ -bool Mesh::check_for_holes_in_square_mesh() const -{ - - // check for holes in mesh - // method: - // 1.find area of mesh - // 2. sum area of all triangles - // 3. comapre 1 & 2 to see if they are equal - // assumptions: mesh area (convex hull) is square and can be simply computed from bb / x y min max points - - // get bounding box - BBox3D bb3d; - this->get_bbox(bb3d); - - double dx = bb3d.max.x - bb3d.min.x; - double dy = bb3d.max.y - bb3d.min.y; - - TNTN_ASSERT(dx > 0); - TNTN_ASSERT(dy > 0); - - double eps = (dx + dy) / 20000.0; - - if (is_square()) { - TNTN_LOG_DEBUG("mesh is square - checking for holes"); - - double area_bb = dx * dy; - double area_tri_sum = 0; - - for (const Face& f : m_faces) { - const Vertex& v1 = m_vertices[f[0]]; - const Vertex& v2 = m_vertices[f[1]]; - const Vertex& v3 = m_vertices[f[2]]; - - // area of triangle - double area_tri = 0.5 * std::abs((v2.x - v1.x) * (v3.y - v1.y) - (v3.x - v1.x) * (v2.y - v1.y)); - - area_tri_sum += area_tri; - } - - if (std::abs(area_tri_sum - area_bb) > eps) { - TNTN_LOG_DEBUG( - "mesh has holes. area of bounding box {} area of all triangles combined {}", - area_bb, - area_tri_sum); - return true; - } else { - TNTN_LOG_DEBUG("mesh has no holes"); - return false; - } - } else { - TNTN_LOG_DEBUG("mesh is not square - can not check for holes"); - return false; - } -} - -bool Mesh::check_tin_properties() const -{ - TNTN_LOG_DEBUG("checking mesh consistency / TIN properties..."); - if (!has_decomposed()) { - return false; - } - - // O(n) checks first - { - const size_t vertices_size = m_vertices.size(); - std::vector vertex_used(vertices_size); - for (const Face& f : m_faces) { - // all vertex indices are valid - if (f[0] >= vertices_size || f[1] >= vertices_size || f[2] >= vertices_size) { - TNTN_LOG_DEBUG( - "mesh is NOT a regular/propper TIN, some face indices are not valid"); - return false; - } - - // check if vertices are referenced - vertex_used[f[0]] = 1; - vertex_used[f[1]] = 1; - vertex_used[f[2]] = 1; - - // no face has two collapsed corner points - if (f[0] == f[1] || f[0] == f[2] || f[1] == f[2]) { - TNTN_LOG_DEBUG( - "mesh is NOT a regular/propper TIN, some faces have collapsed corner points"); - return false; - } - - // face is oriented upwards - if (!is_facing_upwards(f, m_vertices)) { - TNTN_LOG_DEBUG( - "triangle is NOT a regular/propper TIN, some faces are not oriented upwards"); - return false; - } - } - - for (const char is_used : vertex_used) { - if (!is_used) { - TNTN_LOG_DEBUG( - "mesh is NOT a regular/propper TIN, some vertices are not referenced by a face"); - return false; - } - } - } - - // no duplicate vertices (this is O(n*log(n)) - { - std::vector vertices_sorted; - vertices_sorted.resize(m_vertices.size()); - std::partial_sort_copy(m_vertices.begin(), - m_vertices.end(), - vertices_sorted.begin(), - vertices_sorted.end(), - vertex_compare<>()); - auto it = std::adjacent_find(vertices_sorted.begin(), vertices_sorted.end()); - if (it != vertices_sorted.end()) { - TNTN_LOG_DEBUG("mesh is NOT a regular/propper TIN, there are duplicate vertices"); - return false; - } - } - - // no overlapping triangles ( this is O(n^2) :/ ) - for (size_t fi = 0; fi < m_faces.size(); fi++) { - // edges are either the same or do not intersect - if (face_edge_crosses_other_edge(fi, m_faces, m_vertices)) { - TNTN_LOG_DEBUG("mesh is NOT a regular/propper TIN, some triangles are overlapping"); - return false; - } - } - -#if 0 - //euler characteristics - //https://en.wikipedia.org/wiki/Euler_characteristic - { - //TODO: transform mesh to topological sphere (not a geometrical sphere) by connecting all outer vertices into one - - //collapse bbox boundary vertices into a single pole - BBox2D bbox; - bbox.add(m_vertices.begin(), m_vertices.end()); - const Vertex pole = {std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()}; - auto vertices = m_vertices; - std::vector collapsed_vertices; - for(size_t vi = 0; vi edges; - for(const Face &f : m_faces) { - edges.emplace(f[0], f[1]); - edges.emplace(f[1], f[2]); - edges.emplace(f[2], f[0]); - } - const int64_t E = edges.size(); - const int64_t V = m_vertices.size(); - const int64_t F = m_faces.size(); - - const int64_t chi = V - E + F; - if(chi != 2) { - TNTN_LOG_DEBUG("mesh is NOT a regular/propper TIN, some triangles are missing (euler charachteristics violated)"); - return false; - } - } -#endif - - // IF the mesh convex hull is square - // this function will detect holes - if (check_for_holes_in_square_mesh()) { - return false; - } - - TNTN_LOG_DEBUG("mesh is a regular/propper TIN"); - return true; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/Mesh.h b/src/terrainlib/tntn/Mesh.h deleted file mode 100644 index a640414..0000000 --- a/src/terrainlib/tntn/Mesh.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "MeshMode.h" -#include "geometrix.h" -#include "util.h" - -#include -#include - -#include - -namespace tntn { - -class Mesh { -private: - // disallow copy and assign, force passing by pointer or move semantics - Mesh(const Mesh& other) = delete; - Mesh& operator=(const Mesh& other) = delete; - -public: - Mesh() = default; - Mesh(Mesh&& other) = default; - Mesh& operator=(Mesh&& other) = default; - - void clear(); - Mesh clone() const; - - void from_decomposed(std::vector&& vertices, std::vector&& faces); - void from_triangles(std::vector&& triangles); - void add_triangle(const Triangle& t, const bool decompose = false); - - size_t poly_count() const; - bool empty() const { return poly_count() == 0; } - - bool has_triangles() const { return !m_triangles.empty(); } - bool has_decomposed() const { return !m_vertices.empty() && !m_faces.empty(); } - - void generate_triangles(); - void generate_decomposed(); - void clear_triangles(); - void clear_decomposed(); - - SimpleRange triangles() const; - SimpleRange faces() const; - SimpleRange vertices() const; - const std::vector& vertices_as_vector() const; - - void grab_triangles(std::vector& into); - void grab_decomposed(std::vector& vertices, std::vector& faces); - - bool compose_triangle(const Face& f, Triangle& out) const; - - /** - Two meshes are semantically equal iff all their triangles are semantically equal - */ - bool semantic_equal(const Mesh& other) const; - - void get_bbox(BBox3D& bbox) const; - BBox3D bbox() const; - - bool check_tin_properties() const; - - bool is_square() const; - bool check_for_holes_in_square_mesh() const; - -private: - bool semantic_equal_tri_tri(const Mesh& other) const; - bool semantic_equal_dec_dec(const Mesh& other) const; - bool semantic_equal_tri_dec(const Mesh& other) const; - - std::vector m_vertices; - std::vector m_faces; - std::vector m_triangles; - - void decompose_triangle(const Triangle& t); -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/Mesh2Raster.cpp b/src/terrainlib/tntn/Mesh2Raster.cpp deleted file mode 100644 index 1e4faff..0000000 --- a/src/terrainlib/tntn/Mesh2Raster.cpp +++ /dev/null @@ -1,528 +0,0 @@ -#include "Mesh2Raster.h" -#include "SuperTriangle.h" -#include "geometrix.h" -#include "raster_tools.h" - -namespace tntn { -/** - renders a single triangle to a raster - by interpolating the vertex z-position inside the triangle - traverses all pixels inside the triangle bounding box - @param raster - image to render to - @param tri - triangle with coordinates scaled to pixel coordinates - of raster (i.e. colum and rows with lower left coordinate system in keeping with raster format) - */ -void Mesh2Raster::rasterise_triangle(RasterDouble& raster, SuperTriangle& tri) -{ - bool visited = false; - - int w = raster.get_width(); - int h = raster.get_height(); - - BBox2D bb = tri.getBB(); - - // row start and end index - int rs = (int)(bb.min.y); - int re = (int)(bb.max.y + 1.5); - - // column start and end index - int cs = (int)(bb.min.x); - int ce = (int)(bb.max.x + 1.5); - - // conform to raster bounds -#if true - rs = rs < 0 ? 0 : rs > h ? h - : rs; - re = re < 0 ? 0 : re > h ? h - : re; - - cs = cs < 0 ? 0 : cs > w ? w - : cs; - ce = ce < 0 ? 0 : ce > w ? w - : ce; -#endif - - // cycle through raster - for (int r = rs; r < re; r++) { - // double* pH = raster.getPtr(h-r-1); - double* pH = raster.get_ptr(r); - - for (int c = cs; c < ce; c++) { - double terrain_height = 0; - - // if(tri.interpolate(raster.col2x(c),raster.rowLL2y(r),terrain_height)) - if (tri.interpolate(c, r, terrain_height)) { - visited = true; -#if false - if(pH[c] != ndv) - { - if(std::abs(pH[c] - terrain_height) > 0.0001) - { - TNTN_LOG_WARN("overwriting pixel with different value - before: {} after: {}",pH[c],ht); - } - } - - if( terrain_height> (maxz + 0.0001) || terrain_height < (minz-0.0001)) - { - TNTN_LOG_WARN("interpolate out of range"); - } -#endif - pH[c] = terrain_height; - } - } - } - - if (!visited) { - TNTN_LOG_WARN("triangle NOT rendered X min: {} max: {} Y min: {} max: {}", - tri.getBB().min.x, - tri.getBB().max.x, - tri.getBB().min.y, - tri.getBB().max.y); - TNTN_LOG_WARN("rs: {} re: {}", rs, re); - TNTN_LOG_WARN("cs: {} ce: {}", cs, ce); - - auto t = tri.getTriangle(); - - for (int i = 0; i < 3; i++) { - std::vector plist; - for (int j = 0; j < 3; j++) { - if (i != j) { - plist.push_back(t[j]); - } - } - - if (plist.size() == 2) { - - double dx = plist[0].x - plist[1].x; - double dy = plist[0].y - plist[1].y; - - double dd = dx * dx + dy * dy; - - double d = sqrt(dd); - - TNTN_LOG_DEBUG("edge: {} length: {}", i, d); - } - } - } - /*else - { - TNTN_LOG_WARN("triangle rendered X min: {} max: {} Y min: {} max: {}",tri.getBB().min.x,tri.getBB().max.x,tri.getBB().min.y,tri.getBB().max.y); - }*/ -} - -/** - renders a mesh to a raster - uses the bounding box of vertices to define rendering area - this is then scaled to out_width and height (height determined using mesh aspect ratio) - note: for benchmarking it's important that the source raster and the - raster returned by this function have the correct scaling and offset - it's therefore necessary to know the source raster dimensions - and it's important that the mesh algorithm sets vertices at the edges - of the raster otherwise the re-rasterisation will be scaled. - - we assume that vertex positions where derived from raster positions (row, col) - by adding cellSize/2. i.e - x = (col+0.5) * cellSize + xpos and y = (height - row - 1 + 0.5) * cellsize + ypos - this is the accepted way to derive coordianates - - in this case the x coordinate in a mesh derived for an image of original size w is in the range: - min.x = x_start = (0+0.5) * cellSize + xpos - max.x = x_end = (w-1+0.5) * cellSize + xpos - mesh_w = max.x - min.x = (w-1+0.5) * cellSize - (0+0.5) * cellSize - mesh_w = (w-1) * cellSize and mesh_h = (h-1) * cellSize - this means we have two unknows - w and cellsize!! - - we further assume there is a vertex at min x/y and max x/y of the origian raster otherwise scaling cannot be guranteed - - @param out_width width of output raster - we assume this is the same as the original raster size. if not the orignal can be specified.. - @param original_width - width of original rast - @return rasterised mesh - */ -RasterDouble Mesh2Raster::rasterise( - Mesh& mesh, int out_width, int out_height, int original_width, int original_height) -{ - m_bb = findBoundingBox(mesh); - - double mesh_w = m_bb.max.x - m_bb.min.x; - double mesh_h = m_bb.max.y - m_bb.min.y; - - RasterDouble raster; - if (mesh_w <= 0 || mesh_h <= 0) { - TNTN_LOG_ERROR("mesh dimensions zero"); - return raster; - } - - if (original_width == -1) - original_width = out_width; - if (original_height == -1) - original_height = out_height; - - double cellWidth_original = mesh_w / double(original_width - 1); - double cellWidth = (mesh_w + cellWidth_original) / double(out_width); - double cellHeight_original = mesh_h / double(original_height - 1); - double cellHeight = (mesh_h + cellHeight_original) / double(out_height); - - // width is user supplied (in pixels) - double raster_w = out_width; - - // derive height from mesh bb to preserve aspect ratio - double raster_h = out_height; - - // oversample factor set here - int oversample = 1; - - TNTN_LOG_DEBUG("oversample {}", oversample); - - // size of raster with oversampling - double os_w = oversample * raster_w; - double os_h = oversample * raster_h; - - // round to nearest integer for raster - const auto w = int(os_w + 0.5); - const auto h = int(os_h + 0.5); - - TNTN_LOG_DEBUG("raster w: {}", w); - TNTN_LOG_DEBUG("raster h: {}", h); - - // allocate - raster.allocate(w, h); - - // set parameters - raster.set_no_data_value(-99999); - raster.set_all(raster.get_no_data_value()); - - TNTN_LOG_DEBUG("cell size width: {}, height: {}", cellWidth, cellHeight); - - raster.set_cell_width(cellWidth); - raster.set_cell_height(cellHeight); - - raster.set_pos_x(m_bb.min.x); - raster.set_pos_y(m_bb.min.y); - - TNTN_LOG_DEBUG("x-pos:: {}", raster.get_pos_x()); - TNTN_LOG_DEBUG("y-pos: {}", raster.get_pos_y()); - - mesh.generate_triangles(); - auto trange = mesh.triangles(); - - int tcount = 0; - for (auto ptr = trange.begin; ptr != trange.end; ptr++) { - SuperTriangle super_triangle(scaleTriangle(*ptr, raster)); - // SuperTriangle super_triangle(*ptr); - rasterise_triangle(raster, super_triangle); - - if ((tcount % (1 + trange.size() / 10)) == 0) { - float p = tcount / (float)trange.size(); - TNTN_LOG_INFO("{} %", p * 100.0); - } - tcount++; - } - -#ifdef TNTN_DEBUG - // count empty pixels - // i.e. where rendere hasn't been able to add height - int countempty = 0; - double ndv = raster.get_no_data_value(); - for (int r = 2; r < raster.get_height() - 2; r++) { - double* pH = raster.get_ptr(r); - - for (int c = 2; c < raster.get_width() - 2; c++) { - if (pH[c] == ndv) { - countempty++; - } - } - } - - if (countempty > 0) { - TNTN_LOG_WARN("{} empty pixel ", countempty); - } -#endif - - if (oversample != 1) { - raster = raster_tools::integer_downsample_mean(raster, oversample); - } - - return raster; -} - -// return value is the root of the mean squared error -// errorMap is the difference for that pixels position -// maxError is the maximum abs difference between any two pixel values -double Mesh2Raster::findRMSError(const RasterDouble& r1, - const RasterDouble& r2, - RasterDouble& errorMap, - double& maxError) -{ - int w = r1.get_width(); - int h = r1.get_height(); - - if (h != r2.get_height()) { - return 0; - } - - if (w != r2.get_width()) { - return 0; - } - - long double sum = 0; - long int count = 0; - - maxError = -std::numeric_limits::max(); - - errorMap.allocate(w, h); - errorMap.set_no_data_value(-99999); - errorMap.set_all(errorMap.get_no_data_value()); - - double r1ndv = r1.get_no_data_value(); - double r2ndv = r2.get_no_data_value(); - - TNTN_LOG_DEBUG("no data value for r1 : {}", r1ndv); - TNTN_LOG_DEBUG("no data value for r2 : {}", r2ndv); - - int count_r1_nd = 0; - int count_r2_nd = 0; - int count_er_nd = 0; - - // ignore 2 pixel boundary around raster - // in each direction - for (int r = 2; r < h - 2; r++) { - double* pE = errorMap.get_ptr(r); - const double* pH1 = r1.get_ptr(r); - const double* pH2 = r2.get_ptr(r); - - for (int c = 2; c < w - 2; c++) { - if (pH1[c] == r1ndv) - count_r1_nd++; - if (pH2[c] == r2ndv) - count_r2_nd++; - - // only perform comparison for non-empty pixels - if ((pH1[c] != r1ndv) && (pH2[c] != r2ndv)) { - double d = std::abs(pH1[c] - pH2[c]); - - double dd = d * d; - - // store abs error map - pE[c] = d; - - // max error - if (d > maxError) { - maxError = d; - } - - // rms error - sum += dd; - count++; - } else { - count_er_nd++; - pE[c] = 0; - // pE[c] = errorMap.getNoDataValue(); - } - } - } - - TNTN_LOG_DEBUG("findRMS - no data in"); - TNTN_LOG_DEBUG("r1 : {}", count_r1_nd); - TNTN_LOG_DEBUG("r2 : {}", count_r2_nd); - TNTN_LOG_DEBUG("error map : {}", count_er_nd); - - // compute standard deviation - if (count > 0) { - sum = sum / (long double)count; - sum = sqrt(sum); - } - - return sum; -} - -RasterDouble Mesh2Raster::measureError(const RasterDouble& r1, - const RasterDouble& r2, - double& out_mean, - double& out_std, - double& out_max_abs_error) -{ - int w = r1.get_width(); - int h = r1.get_height(); - - // cant be negative - double max_abs_error = 0; - double std = 0; - double mean = 0; - - RasterDouble errorMap; - - if (h != r2.get_height() || w != r2.get_width() || r1.empty() || r2.empty()) { - return errorMap; - } - - errorMap.allocate(w, h); - errorMap.set_no_data_value(-99999); - errorMap.set_all(errorMap.get_no_data_value()); - - double r1ndv = r1.get_no_data_value(); - double r2ndv = r2.get_no_data_value(); - - TNTN_LOG_DEBUG("no data value for r1 : {}", r1ndv); - TNTN_LOG_DEBUG("no data value for r2 : {}", r2ndv); - - int count_r1_nd = 0; - int count_r2_nd = 0; - int count_er_nd = 0; - - /* - using single pass to compute variance and mean - - use method that preserves numerical accuracy: - http://jonisalonen.com/2013/deriving-welfords-method-for-computing-variance/ - - variance(samples): - - M := 0 - S := 0 - - for k from 1 to N: - x := samples[k] - oldM := M - M := M + (x-M)/k - S := S + (x-M)*(x-oldM) - return S/(N-1) - */ - - long double m_sum = 0; - long double s_sum = 0; - - long double sum = 0; - long int count = 0; - - // ignore 2 pixel boundary around raster - for (int r = 2; r < h - 2; r++) { - double* pE = errorMap.get_ptr(r); // output error map - const double* pH1 = r1.get_ptr(r); // raster 1 - const double* pH2 = r2.get_ptr(r); // raster 2 - - for (int c = 2; c < w - 2; c++) { - // for debug reasons count empty pixels - if (pH1[c] == r1ndv) - count_r1_nd++; - if (pH2[c] == r2ndv) - count_r2_nd++; - - // only perform comparison for - // non-empty pixels in both rasters - if ((pH1[c] != r1ndv) && (pH2[c] != r2ndv)) { - // the error we want to measure - long double d = pH1[c] - pH2[c]; - - // oldM := M - long double old_m = m_sum; - - // M := M + (x-M)/k - m_sum = m_sum + (d - m_sum) / (long double)(count + 1); - - // S := S + (x-M)*(x-oldM) - s_sum = s_sum + (d - m_sum) * (d - old_m); - - // computing mean - sum += d; - - // for max error calculation - double d_abs = std::abs(d); - - // max error - if (d_abs > max_abs_error) { - max_abs_error = d_abs; - } - - // ...and error map - pE[c] = d_abs; - - // increment count - // as not all pixels will be included - count++; - } else { - // count ocurrance - count_er_nd++; - - // unknown error value at this point - // so make no data value - pE[c] = errorMap.get_no_data_value(); - } - } - } - - TNTN_LOG_DEBUG("measureError - no data in"); - TNTN_LOG_DEBUG("r1 : {}", count_r1_nd); - TNTN_LOG_DEBUG("r2 : {}", count_r2_nd); - TNTN_LOG_DEBUG("error map : {}", count_er_nd); - - // compute standard deviation - if (count > 0) { - double variance = (double)(s_sum / (long double)(count)); - - // mean and variance - std = sqrt(variance); - mean = sum / (long double)count; - } - - // only set output in success return path so caller can keep NaNs - out_std = std; - out_mean = mean; - out_max_abs_error = max_abs_error; - return errorMap; -} - -BBox2D Mesh2Raster::findBoundingBox(Mesh& mesh) -{ - BBox2D bb; - auto vrange = mesh.vertices(); - for (auto ptr = vrange.begin; ptr != vrange.end; ptr++) { - bb.add(*ptr); - } - - return bb; -} - -Triangle Mesh2Raster::scaleTriangle(const Triangle& t, float w, float h) -{ - Triangle nt; - for (int i = 0; i < 3; i++) { - nt[i] = scaleVertex(t[i], w, h); - } - return nt; -} - -Triangle Mesh2Raster::scaleTriangle(const Triangle& t, RasterDouble& raster) -{ - Triangle nt; - for (int i = 0; i < 3; i++) { - nt[i] = scaleVertex(t[i], raster); - } - return nt; -} - -Vertex Mesh2Raster::scaleVertex(const Vertex& v, float w, float h) -{ - Vertex vs; - - vs.x = (w - 1) * (double)(v.x - m_bb.min.x) / (double)(m_bb.max.x - m_bb.min.x); - vs.y = (h - 1) * (double)(v.y - m_bb.min.y) / (double)(m_bb.max.y - m_bb.min.y); - - // vs.x = w * (double)(v.x - m_bb.min.x) / (double)(m_bb.max.x - m_bb.min.x); - // vs.y = h * (double)(v.y - m_bb.min.y) / (double)(m_bb.max.y - m_bb.min.y); - - vs.z = v.z; - vs.z = v.z; - - return vs; -} - -Vertex Mesh2Raster::scaleVertex(const Vertex& v, RasterDouble& raster) -{ - Vertex vs; - vs.x = raster.x2col(v.x); - vs.y = raster.y2row(v.y); - vs.z = v.z; - - return vs; -} -} // namespace tntn diff --git a/src/terrainlib/tntn/Mesh2Raster.h b/src/terrainlib/tntn/Mesh2Raster.h deleted file mode 100644 index bb1f42e..0000000 --- a/src/terrainlib/tntn/Mesh2Raster.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "Mesh.h" -#include "Raster.h" -#include "SuperTriangle.h" - -namespace tntn { - -class Mesh2Raster { - -public: - RasterDouble rasterise(Mesh& mesh, - int out_width, - int out_height, - int original_width = -1, - int original_height = -1); - void rasterise_triangle(RasterDouble& raster, SuperTriangle& tri); - - static double findRMSError(const RasterDouble& r1, - const RasterDouble& r2, - RasterDouble& errorMap, - double& maxError); - static RasterDouble measureError(const RasterDouble& r1, - const RasterDouble& r2, - double& mean, - double& std, - double& max_abs_error); - - BBox2D getBoundingBox() { return m_bb; } - -private: - static BBox2D findBoundingBox(Mesh& mesh); - - Triangle scaleTriangle(const Triangle& t, float w, float h); - Triangle scaleTriangle(const Triangle& t, RasterDouble& raster); - - Vertex scaleVertex(const Vertex& v, float w, float h); - Vertex scaleVertex(const Vertex& v, RasterDouble& raster); - -private: - BBox2D m_bb; -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/MeshIO.cpp b/src/terrainlib/tntn/MeshIO.cpp deleted file mode 100644 index 8165745..0000000 --- a/src/terrainlib/tntn/MeshIO.cpp +++ /dev/null @@ -1,351 +0,0 @@ -#include "MeshIO.h" -#include "File.h" -#include "OFFReader.h" -#include "QuantizedMeshIO.h" -#include "logging.h" - -#include -#include -#include -#include - -namespace tntn { - -bool write_mesh_to_file(const char* filename, const Mesh& m, const FileFormat& f) -{ - if (f == FileFormat::OFF) { - return write_mesh_as_off(filename, m); - } else if (f == FileFormat::OBJ) { - return write_mesh_as_obj(filename, m); - } else if (f == FileFormat::TERRAIN) { - return write_mesh_as_qm(filename, m); - } else if (f == FileFormat::TERRAINGZ) { - return write_mesh_as_qm(filename, m, true); - } else if (f == FileFormat::JSON || f == FileFormat::GEOJSON) { - return write_mesh_as_geojson(filename, m); - } else { - TNTN_LOG_ERROR("unsupported file format {} for mesh output", f.to_cstring()); - return false; - } -} - -std::unique_ptr load_mesh_from_obj(const char* filename) -{ - auto mesh = std::make_unique(); - - std::ifstream f(filename); - if (!f.is_open()) { - return std::unique_ptr(); - } - - std::vector vertices; - std::vector faces; - - char t = 0; - double x, y, z; - while (f >> t >> x >> y >> z) { - if (t == 'v') { - vertices.push_back({ x, y, z }); - } else if (t == 'f') { - const size_t sx = static_cast(x); - const size_t sy = static_cast(y); - const size_t sz = static_cast(z); - - faces.push_back({ { sx - 1, sy - 1, sz - 1 } }); - } - } - - mesh->from_decomposed(std::move(vertices), std::move(faces)); - - return mesh; -} - -std::string make_geojson_face(const Vertex& v1, const Vertex& v2, const Vertex& v3) -{ - constexpr auto format_string = "{{\n \"type\" : \"Feature\" , \"properties\" : {{ \"id\" : 0 }} , \"geometry\" :\n {{ \n \"type\" : \ - \"LineString\", \"coordinates\" : \n \ - [ \n [ {:.18f} , {:.18f} ], \n [ {:.18f}, {:.18f} ], \n [ {:.18f}, {:.18f} ],\n [ {:.18f}, {:.18f} ] \ - \n ] \n }} \n }} \n"; - - // std::string format_string = "[ {:.18f} , {:.18f} ], \n [ {:.18f}, {:.18f} ], \n [ {:.18f}, {:.18f} ],\n [ {:.18f}, {:.18f} ]"; - - return fmt::format(format_string, v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.x, v1.y); -} - -std::string make_geojson_vertex(const Vertex& v) -{ - constexpr auto format_string = "{{ \n \ - \"type\": \"Feature\",\n \ - \"properties\": {{}},\n \ - \"geometry\": {{\n \ - \"type\": \"Point\",\n \ - \"coordinates\": [\n \ - {:.18f}, \n \ - {:.18f} \n \ - ]\n \ - }} \ - }}"; - - return fmt::format(format_string, v.x, v.y); -} - -bool write_mesh_as_geojson(FileLike& out_file, const Mesh& m) -{ - if (!m.has_decomposed()) { - TNTN_LOG_ERROR("mesh is not in decomposed format, please decompose first"); - return false; - } - - auto faces_range = m.faces(); - auto vertices_range = m.vertices(); - - std::string line_buffer; - line_buffer.reserve(1000); - - File::position_type write_pos = 0; - - line_buffer.resize(0); - line_buffer += fmt::format("{{\n"); - line_buffer += fmt::format("\"type\": \"FeatureCollection\",\n"); - line_buffer += fmt::format("\"crs\": {{ \"type\": \"name\", \"properties\": {{ \"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\" }} }},\n"); - line_buffer += fmt::format("\"features\": [\n"); - if (!out_file.write(write_pos, line_buffer.data(), line_buffer.size())) - return false; - write_pos += line_buffer.size(); - - TNTN_LOG_INFO("number of faces {}", faces_range.size()); - - int count = 0; - // for (const Face *f = faces_range.begin; f != faces_range.end; f++) - - // write points - for (int i = 0; i < vertices_range.size(); i++) { - const Vertex& v = vertices_range.begin[i]; - - line_buffer.resize(0); - - std::string vertex_string = make_geojson_vertex(v); - - line_buffer += fmt::format("{},", vertex_string); - - if (!out_file.write(write_pos, line_buffer.data(), line_buffer.size())) - return false; - - write_pos += line_buffer.size(); - } - - // write triangels - for (int i = 0; i < faces_range.size(); i++) { - - TNTN_LOG_TRACE("write face {}...", i); - - const Face& face = faces_range.begin[i]; - - line_buffer.resize(0); - - const Vertex& v1 = vertices_range.begin[face[0]]; - const Vertex& v2 = vertices_range.begin[face[1]]; - const Vertex& v3 = vertices_range.begin[face[2]]; - - std::string face_string = make_geojson_face(v1, v2, v3); - - if (i == faces_range.size() - 1) { - TNTN_LOG_DEBUG("write end seg v2-v3"); - line_buffer += fmt::format("{} \n ] \n }}", face_string); - } else { - line_buffer += fmt::format("{},", face_string); - } - - if (!out_file.write(write_pos, line_buffer.data(), line_buffer.size())) - return false; - - write_pos += line_buffer.size(); - - TNTN_LOG_DEBUG("done"); - } - - out_file.flush(); - - TNTN_LOG_DEBUG("lines: {}", count); - TNTN_LOG_DEBUG("write complete"); - - return out_file.is_good(); -} - -bool write_mesh_as_geojson(const char* filename, const Mesh& m) -{ - File f; - if (!f.open(filename, File::OM_RWCF)) { - return false; - } - return write_mesh_as_geojson(f, m); -} - -bool write_mesh_as_obj(const char* filename, const Mesh& m) -{ - File f; - if (!f.open(filename, File::OM_RWCF)) { - return false; - } - return write_mesh_as_obj(f, m); -} - -bool write_mesh_as_obj(FileLike& out_file, const Mesh& m) -{ - if (!m.has_decomposed()) { - TNTN_LOG_ERROR("mesh is not in decomposed format, please decompose first"); - return false; - } - - auto faces_range = m.faces(); - auto vertices_range = m.vertices(); - - std::string line_buffer; - line_buffer.reserve(128); - - File::position_type write_pos = 0; - for (const Vertex* v = vertices_range.begin; v != vertices_range.end; v++) { - line_buffer.resize(0); - line_buffer += fmt::format("v {:.18f} {:.18f} {:.18f}\n", v->x, v->y, v->z); - if (!out_file.write(write_pos, line_buffer.data(), line_buffer.size())) { - return false; - } - write_pos += line_buffer.size(); - } - - for (const Face* f = faces_range.begin; f != faces_range.end; f++) { - line_buffer.resize(0); - line_buffer += fmt::format("f {} {} {}\n", (*f)[0] + 1, (*f)[1] + 1, (*f)[2] + 1); - if (!out_file.write(write_pos, line_buffer.data(), line_buffer.size())) { - return false; - } - write_pos += line_buffer.size(); - } - - return out_file.is_good(); -} - -std::unique_ptr load_mesh_from_off(const char* filename) -{ - File f; - if (!f.open(filename, File::OM_R)) { - TNTN_LOG_ERROR("unable to open input file {}", filename); - return std::unique_ptr(); - } - return load_mesh_from_off(f); -} - -std::unique_ptr load_mesh_from_off(FileLike& f) -{ - OFFReader reader; - - if (!reader.readFile(f)) { - TNTN_LOG_ERROR("unable to read input from FileLike with name {}", f.name()); - return std::unique_ptr(); - } - - return reader.convertToMesh(); -} - -struct EdgeCompareLess { - bool operator()(const std::pair& left, - const std::pair& right) const - { - const VertexIndex lmin = std::min(left.first, left.second); - const VertexIndex lmax = std::max(left.first, left.second); - - const VertexIndex rmin = std::min(right.first, right.second); - const VertexIndex rmax = std::max(right.first, right.second); - - if (lmin < rmin) { - return true; - } else if (lmin > rmin) { - return false; - } else /*if(lmin == rmin)*/ - { - if (lmax < rmax) { - return true; - } else { - return false; - } - } - } -}; - -static size_t calculate_num_edges(const SimpleRange faces) -{ - - std::set, EdgeCompareLess> edges; - - for (const Face* fp = faces.begin; fp != faces.end; fp++) { - edges.insert(std::make_pair((*fp)[0], (*fp)[1])); - edges.insert(std::make_pair((*fp)[1], (*fp)[2])); - edges.insert(std::make_pair((*fp)[2], (*fp)[0])); - } - - return edges.size(); -} - -bool write_mesh_as_off(const char* filename, const Mesh& m) -{ - if (!m.has_decomposed()) { - TNTN_LOG_ERROR("mesh is not in decomposed format, please decompose first"); - return false; - } - - File out_file; - if (!out_file.open(filename, File::OM_RWCF)) { - return false; - } - - const bool mesh_write_ok = write_mesh_as_off(out_file, m); - const bool close_ok = out_file.close(); - return mesh_write_ok && close_ok; -} - -bool write_mesh_as_off(FileLike& out_file, const Mesh& m) -{ - if (!m.has_decomposed()) { - TNTN_LOG_ERROR("mesh is not in decomposed format, please decompose first"); - return false; - } - - if (!out_file.is_good()) { - TNTN_LOG_ERROR("output file is not in a good state"); - return false; - } - - auto faces_range = m.faces(); - auto vertices_range = m.vertices(); - - std::string line_buffer; - line_buffer.reserve(128); - - FileLike::position_type write_offset = 0; - out_file.write(write_offset, "OFF\n", 4); - write_offset += 4; - - const size_t num_vertices = vertices_range.size(); - const size_t num_faces = faces_range.size(); - const size_t num_edges = calculate_num_edges(faces_range); - - line_buffer = fmt::format("{} {} {}\n", num_vertices, num_faces, num_edges); - out_file.write(write_offset, line_buffer.data(), line_buffer.size()); - write_offset += line_buffer.size(); - - for (const Vertex* v = vertices_range.begin; v != vertices_range.end; v++) { - line_buffer = fmt::format("{:.18f} {:.18f} {:.18f}\n", v->x, v->y, v->z); - out_file.write(write_offset, line_buffer.data(), line_buffer.size()); - write_offset += line_buffer.size(); - } - - for (const Face* f = faces_range.begin; f != faces_range.end; f++) { - line_buffer = fmt::format("3 {} {} {}\n", (*f)[0], (*f)[1], (*f)[2]); - out_file.write(write_offset, line_buffer.data(), line_buffer.size()); - write_offset += line_buffer.size(); - } - - return true; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/MeshIO.h b/src/terrainlib/tntn/MeshIO.h deleted file mode 100644 index eb9f686..0000000 --- a/src/terrainlib/tntn/MeshIO.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "File.h" -#include "FileFormat.h" -#include "Mesh.h" -#include - -namespace tntn { - -bool write_mesh_to_file(const char* filename, const Mesh& m, const FileFormat& f); - -std::unique_ptr load_mesh_from_obj(const char* filename); -bool write_mesh_as_obj(const char* filename, const Mesh& m); -bool write_mesh_as_obj(FileLike& f, const Mesh& m); - -std::unique_ptr load_mesh_from_off(const char* filename); -std::unique_ptr load_mesh_from_off(FileLike& f); - -bool write_mesh_as_off(FileLike& f, const Mesh& m); -bool write_mesh_as_off(const char* filename, const Mesh& m); - -bool write_mesh_as_geojson(const char* filename, const Mesh& m); -bool write_mesh_as_geojson(FileLike& out_file, const Mesh& m); - -} // namespace tntn diff --git a/src/terrainlib/tntn/MeshMode.h b/src/terrainlib/tntn/MeshMode.h deleted file mode 100644 index 261aa4e..0000000 --- a/src/terrainlib/tntn/MeshMode.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace tntn { - -enum class MeshMode { - none, - decomposed, - triangles -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/MeshWriter.cpp b/src/terrainlib/tntn/MeshWriter.cpp deleted file mode 100644 index 980796a..0000000 --- a/src/terrainlib/tntn/MeshWriter.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "MeshWriter.h" -#include "MeshIO.h" -#include "QuantizedMeshIO.h" - -namespace tntn { - -bool ObjMeshWriter::write_mesh_to_file(const char* filename, Mesh& mesh, const BBox3D& bbox) -{ - return write_mesh_as_obj(filename, mesh); -} - -std::string ObjMeshWriter::file_extension() -{ - return "obj"; -} - -bool QuantizedMeshWriter::write_mesh_to_file(const char* filename, Mesh& mesh, const BBox3D& bbox) -{ - return write_mesh_as_qm(filename, mesh, bbox, true, m_gzipped); -} - -std::string QuantizedMeshWriter::file_extension() -{ - return "terrain"; -} -} // namespace tntn diff --git a/src/terrainlib/tntn/MeshWriter.h b/src/terrainlib/tntn/MeshWriter.h deleted file mode 100644 index 5650569..0000000 --- a/src/terrainlib/tntn/MeshWriter.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "Mesh.h" -#include "geometrix.h" - -namespace tntn { - -class MeshWriter { -public: - virtual bool write_mesh_to_file(const char* filename, Mesh& mesh, const BBox3D& bbox) = 0; - virtual std::string file_extension() = 0; - virtual ~MeshWriter() {}; -}; - -class ObjMeshWriter : public MeshWriter { -public: - virtual bool write_mesh_to_file(const char* filename, - Mesh& mesh, - const BBox3D& bbox) override; - - virtual std::string file_extension() override; - virtual ~ObjMeshWriter() {}; -}; - -class QuantizedMeshWriter : public MeshWriter { -public: - QuantizedMeshWriter(bool gzipped = false) - : m_gzipped(gzipped) - { - } - virtual bool write_mesh_to_file(const char* filename, - Mesh& mesh, - const BBox3D& bbox) override; - virtual std::string file_extension() override; - virtual ~QuantizedMeshWriter() {}; - -private: - bool m_gzipped = false; -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/NOTICE b/src/terrainlib/tntn/NOTICE deleted file mode 100644 index 44f113a..0000000 --- a/src/terrainlib/tntn/NOTICE +++ /dev/null @@ -1,27 +0,0 @@ -The files in this directory are from tin - terrain : https : // github.com/adam-ce/tin-terrain - forked from https : // github.com/heremaps/tin-terrain - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - - - The MIT - License(MIT) - - Copyright(C) 2018 HERE Europe B.V.Copyright(C) 2022 Adam Celarek - - Permission is hereby granted, - free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : - - The above copyright notice and this permission notice shall be included in all copies - or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", - WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER - LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - diff --git a/src/terrainlib/tntn/OFFReader.cpp b/src/terrainlib/tntn/OFFReader.cpp deleted file mode 100644 index 74fe514..0000000 --- a/src/terrainlib/tntn/OFFReader.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "OFFReader.h" -#include "logging.h" -#include "util.h" - -#include -#include -#include -#include -#include - -namespace tntn { - -std::unique_ptr OFFReader::convertToMesh() -{ - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(m_vertices), std::move(m_facades)); - clear(); - return mesh; -} - -void OFFReader::findXYBounds(double& xmin, double& ymin, double& xmax, double& ymax) -{ - xmin = std::numeric_limits::max(); - ymin = std::numeric_limits::max(); - - xmax = std::numeric_limits::min(); - ymax = std::numeric_limits::min(); - - for (int i = 0; i < m_num_vertices; i++) { - Vertex& v = m_vertices[i]; - if (v.x < xmin) - xmin = v.x; - if (v.x > xmax) - xmax = v.x; - - if (v.y < ymin) - ymin = v.y; - if (v.y > ymax) - ymax = v.y; - } -} - -void OFFReader::readDimensions(std::string line, std::vector& tokens) -{ - tokenize(line, tokens); - if (tokens.size() == 3) { - m_num_vertices = std::stoi(tokens[0]); - m_num_faces = std::stoi(tokens[1]); - m_ne = std::stoi(tokens[2]); - } -} - -bool OFFReader::readVertex(std::string line, Vertex& v, std::vector& tokens) -{ - tokenize(line, tokens); - - if (tokens.size() >= 3 && tokens[0][0] != '#') { - v.x = std::stod(tokens[0]); - v.y = std::stod(tokens[1]); - v.z = std::stod(tokens[2]); - - return true; - } else { - return false; - } -} - -bool OFFReader::readFacade(std::string line, Face& f, std::vector& tokens) -{ - tokenize(line, tokens); - - if (tokens.size() >= 3 && tokens[0][0] != '#') { - if (tokens.size() > 3) { - int n = std::stoi(tokens[0]); - - if (n == 3 && tokens.size() >= 4) { - f[0] = std::stoi(tokens[1]); - f[1] = std::stoi(tokens[2]); - f[2] = std::stoi(tokens[3]); - } else { - TNTN_LOG_WARN( - "incorrect facade format, vertices per facade: {} (only supporing n=3) ", n); - } - } - return true; - } else { - return false; - } -} - -// Parser -bool OFFReader::parse(FileLike& in) -{ - std::vector tokens; - if (!in.is_good()) { - TNTN_LOG_ERROR("infile is not open/in a good state"); - return false; - } - // Container holding last line read - std::string readLine; - // Containers for delimiter positions - // int delimiterPos_1, delimiterPos_2, delimiterPos_3, delimiterPos_4; - - FileLike::position_type from_offset = 0; - // Check if file is in OFF format - from_offset = getline(from_offset, in, readLine); - if (readLine != "OFF") { - TNTN_LOG_ERROR("The file to read is not in OFF format."); - return false; - } else { - TNTN_LOG_DEBUG("file is OFF format"); - } - - while (true) { - from_offset = getline(from_offset, in, readLine); - - TNTN_LOG_TRACE("line: {}", readLine); - - tokenize(readLine, tokens); - - for (auto s : tokens) { - TNTN_LOG_TRACE("s: {}", s); - } - - if (tokens.size() > 0) { - if (tokens[0][0] != '#' && tokens.size() == 3) { - TNTN_LOG_TRACE("found dimension line"); - - // read dimensions - readDimensions(readLine, tokens); - - TNTN_LOG_DEBUG("vertices: {}", m_num_vertices); - TNTN_LOG_DEBUG("facades: {}", m_num_faces); - - break; - } - } - } - - if (m_num_vertices > 0 && m_num_faces > 0) { - // Read the vertices - m_vertices.resize(m_num_vertices); - - while (true) { - from_offset = getline(from_offset, in, readLine); - - tokenize(readLine, tokens); - - if (tokens.size() > 0) { - if (tokens[0][0] != '#' && tokens.size() == 3) { - TNTN_LOG_DEBUG("found first vertex line"); - break; - } - } - } - - TNTN_LOG_INFO("reading vertices"); - - int vread = 0; - - for (int i = 0; i < m_num_vertices; i++) { - Vertex& v = m_vertices[i]; - if (readVertex(readLine, v, tokens) != true) { - TNTN_LOG_WARN("could not read vertex {} line: {}", i, readLine); - } else { - vread++; - } - from_offset = getline(from_offset, in, readLine); - if (i % (1 + m_num_vertices / 10) == 0) { - float p = i / (float)m_num_vertices; - TNTN_LOG_INFO("{} %", p * 100.0); - } - } - - // Read the facades - m_facades.resize(m_num_faces); - - TNTN_LOG_INFO("reading faces"); - - int fread = 0; - - for (int i = 0; i < m_num_faces; i++) { - - Face& f = m_facades[i]; - if (readFacade(readLine, f, tokens) != true) { - TNTN_LOG_WARN("could not read facade {}", i); - } else { - fread++; - } - - from_offset = getline(from_offset, in, readLine); - - if ((i % (1 + m_num_faces / 10)) == 0) { - float p = i / (float)m_num_faces; - TNTN_LOG_INFO("{} %", p * 100.0); - } - } - - if (vread != m_num_vertices) { - TNTN_LOG_ERROR( - "not all vertices read. m_num_vertices = {} vread = {}", m_num_vertices, vread); - return false; - } - - if (fread != m_num_faces) { - TNTN_LOG_ERROR("not all facades read. nf = {} fread = {}", m_num_faces, fread); - return false; - } - - TNTN_LOG_DEBUG("reading OFF file completed"); - } - - return true; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/OFFReader.h b/src/terrainlib/tntn/OFFReader.h deleted file mode 100644 index 52c6135..0000000 --- a/src/terrainlib/tntn/OFFReader.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include "File.h" -#include "Mesh.h" -#include "geometrix.h" - -#include -#include -#include - -namespace tntn { - -class OFFReader { -public: - OFFReader() { } - - void clear() - { - m_vertices.clear(); - m_facades.clear(); - m_num_vertices = 0; - m_num_faces = 0; - m_ne = 0; - } - - bool readFile(FileLike& f) { return parse(f); } - - Vertex* getVertices() { return m_vertices.data(); } - - Face* getFacades() { return m_facades.data(); } - - int getNumVertices() const { return m_num_vertices; } - - int getNumTriangles() const { return m_num_faces; } - - std::unique_ptr convertToMesh(); - - void findXYBounds(double& xmin, double& ymin, double& xmax, double& ymax); - -private: - void readDimensions(std::string line, std::vector& tokens); - bool readVertex(std::string line, Vertex& v, std::vector& tokens); - bool readFacade(std::string line, Face& f, std::vector& tokens); - bool parse(FileLike& f); - -private: - int m_num_vertices = 0; - int m_num_faces = 0; - int m_ne = 0; - - std::vector m_vertices; - std::vector m_facades; -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/ObjPool.h b/src/terrainlib/tntn/ObjPool.h deleted file mode 100644 index c5a49d8..0000000 --- a/src/terrainlib/tntn/ObjPool.h +++ /dev/null @@ -1,161 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "tntn_assert.h" -#include "util.h" - -namespace tntn { - -// forward declare ObjPool for use in pool_ptr -template -class ObjPool; - -template -class pool_ptr { -public: - pool_ptr() = default; - pool_ptr(ObjPool* pool, size_t index) - : m_pool(pool) - , m_index(index) - { - } - - pool_ptr(const pool_ptr& other) = default; - pool_ptr& operator=(const pool_ptr& other) = default; - - T& operator*() const; - T* operator->() const; - T* get() const; - - ObjPool* pool() const noexcept { return m_pool; } - size_t index() const noexcept { return m_index; } - - void clear() noexcept - { - m_pool = nullptr; - m_index = invalid_index; - } - - void recycle() - { - if (m_pool) { - m_pool->recycle(*this); - clear(); - } - } - - bool is_valid() const noexcept { return m_pool && m_pool->contains(*this); } - - explicit operator bool() const noexcept { return is_valid(); } - - bool operator==(const pool_ptr& other) const noexcept - { - return m_pool == other.m_pool && m_index == other.m_index; - } - bool operator!=(const pool_ptr& other) const noexcept { return !(*this == other); } - // for use in std::map/std::set - bool operator<(const pool_ptr& other) const noexcept - { - if (m_pool < other.m_pool) - return true; - if (m_pool > other.m_pool) - return false; - if (m_index < other.m_index) - return true; - return false; - } - -private: - static constexpr size_t invalid_index = ~(static_cast(0)); - friend class ObjPool; - ObjPool* m_pool = nullptr; - size_t m_index = invalid_index; -}; - -template -class ObjPool { -private: - // disallow copy, assign and move - ObjPool(const ObjPool& other) = delete; - ObjPool(ObjPool&& other) = delete; - ObjPool& operator=(const ObjPool& other) = delete; - ObjPool& operator=(ObjPool&& other) = delete; - - // private ctor, use create() static method - ObjPool() = delete; - struct private_tag { - }; - -public: - static std::shared_ptr create() { return std::make_shared(private_tag()); } - - void reserve(size_t capacity) { m_pool.reserve(capacity); } - - template - pool_ptr spawn(Args&&... args) - { - m_pool.emplace_back(std::forward(args)...); - return pool_ptr(this, m_pool.size() - 1); - } - - void recycle(const pool_ptr& p) - { - // noop until now - should be implemented with some kind of garbage collection and erase/remove-idiom - } - - bool contains(const pool_ptr& p) const noexcept - { - return p.m_pool == this && p.m_index < m_pool.size(); - } - - // do not use this ctor, it's a workaround to make std::make_shared work - explicit ObjPool(const private_tag) { } - -private: - friend class pool_ptr; - friend class pool_ptr; - - T* get_addr(size_t index) const - { - TNTN_ASSERT(index < m_pool.size()); - return const_cast(&m_pool[index]); - } - - std::vector m_pool; -}; - -template -inline T* pool_ptr::get() const -{ - return m_pool->get_addr(m_index); -} - -template -inline T& pool_ptr::operator*() const -{ - return *(get()); -} - -template -inline T* pool_ptr::operator->() const -{ - return get(); -} - -} // namespace tntn - -namespace std { -template -struct hash<::tntn::pool_ptr> { - std::size_t operator()(const ::tntn::pool_ptr& p) const noexcept - { - size_t seed = 0; - ::tntn::hash_combine(seed, p.pool()); - ::tntn::hash_combine(seed, p.index()); - return seed; - } -}; -} // namespace std diff --git a/src/terrainlib/tntn/Points2Mesh.cpp b/src/terrainlib/tntn/Points2Mesh.cpp deleted file mode 100644 index 6ec6dc4..0000000 --- a/src/terrainlib/tntn/Points2Mesh.cpp +++ /dev/null @@ -1,79 +0,0 @@ - -#include "Points2Mesh.h" -#include "logging.h" - -#include "Delaunator.h" - -using namespace std; -namespace tntn { - -bool generate_delaunay_faces(const std::vector& vlist, std::vector& faces) -{ - std::vector points; - points.reserve(vlist.size()); - - for (int i = 0; i < vlist.size(); i++) { - points.push_back(vlist[i].x); - points.push_back(vlist[i].y); - } - - delaunator_cpp::Delaunator dn; - - if (dn.triangulate(points)) { - faces.reserve(dn.triangles.size() / 3); - for (int i = 0; i < dn.triangles.size() / 3; i++) { - Face f; - f[0] = dn.triangles[3 * i]; - f[1] = dn.triangles[3 * i + 1]; - f[2] = dn.triangles[3 * i + 2]; - faces.push_back(f); - } - return true; - } - - return false; -} - -std::vector check_duplicates(const std::vector& vlist, double precision) -{ - int dcount = 0; - - std::vector duplicates; - - double p2 = precision * precision; - for (int i = 0; i < vlist.size(); i++) { - for (int j = i; j < vlist.size(); j++) { - if (i != j) { - double dx = vlist[i].x - vlist[j].x; - double dy = vlist[i].y - vlist[j].y; - double dd = dx * dx + dy * dy; - - if (dd < p2) { - duplicates.push_back(i); - dcount++; - } - } - } - } - - return duplicates; -} - -void remove_duplicates(std::vector& vlist, const std::vector del) -{ - for (int i : del) { - vlist[i] = vlist.back(); - vlist.pop_back(); - } -} - -std::unique_ptr generate_delaunay_mesh(std::vector&& vlist) -{ - std::vector faces; - generate_delaunay_faces(vlist, faces); - std::unique_ptr pMesh = std::make_unique(); - pMesh->from_decomposed(std::move(vlist), std::move(faces)); - return pMesh; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/Points2Mesh.h b/src/terrainlib/tntn/Points2Mesh.h deleted file mode 100644 index a9af82a..0000000 --- a/src/terrainlib/tntn/Points2Mesh.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Mesh.h" -#include "geometrix.h" -#include - -namespace tntn { -bool generate_delaunay_faces(const std::vector& vlist, std::vector& faces); -std::unique_ptr generate_delaunay_mesh(std::vector&& vlist); - -} // namespace tntn diff --git a/src/terrainlib/tntn/QuadEdge.cpp b/src/terrainlib/tntn/QuadEdge.cpp deleted file mode 100644 index 5ebdd53..0000000 --- a/src/terrainlib/tntn/QuadEdge.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "QuadEdge.h" -#include "DelaunayTriangle.h" -#include "tntn_assert.h" - -namespace tntn { -namespace terra { - -#if 0 -QuadEdge::QuadEdge(qe_ptr prev) -{ - qprev = prev; - prev->qnext = this; -} - -QuadEdge::QuadEdge() -{ - QuadEdge *e0 = this; - QuadEdge *e1 = new QuadEdge(e0); - QuadEdge *e2 = new QuadEdge(e1); - QuadEdge *e3 = new QuadEdge(e2); - - qprev = e3; - e3->qnext = e0; - - e0->next = e0; - e1->next = e3; - e2->next = e2; - e3->next = e1; -} -#endif - - // init with dual edge qprev aka invRot - void QuadEdge::init(qe_ptr self_ptr, qe_ptr qprev) - { - TNTN_ASSERT(self_ptr.get() == this); - this->self_ptr = self_ptr; - - this->qprev = qprev; - qprev->qnext = self_ptr; - } - - /* - - creates 3 more QuadEdges - - this=e0 - e1,e2,e3 - - - they are linked together like this: - - | ^ e0 - | _---->| - e1 | /qprev | - <--------+--------+---------- - ^ | | - \___| | - qprev | |___ - | | \ qprev - | | V - ---------+--------+---------> - | qprev/ | e3 - |<-___/ | - e2 V | - */ - void QuadEdge::init(qe_ptr self_ptr) - { - TNTN_ASSERT(self_ptr.get() == this); - this->self_ptr = self_ptr; - - qe_ptr e0 = self_ptr; - - qe_ptr e1 = self_ptr.pool()->spawn(); - qe_ptr e2 = self_ptr.pool()->spawn(); - qe_ptr e3 = self_ptr.pool()->spawn(); - - e1->init(e1, e0); - e2->init(e2, e1); - e3->init(e3, e2); - - e0->qprev = e3; - e3->qnext = e0; - - e0->next = e0; - e1->next = e3; - e2->next = e2; - e3->next = e1; - } - -#if 0 -QuadEdge::~QuadEdge() -{ - if (qnext) { - QuadEdge *e1 = qnext; - QuadEdge *e2 = qnext->qnext; - QuadEdge *e3 = qprev; - - e1->qnext = NULL; - e2->qnext = NULL; - e3->qnext = NULL; - - delete e1; - delete e2; - delete e3; - } -} -#endif - - void QuadEdge::recycle_next() - { - if (qnext) { - qe_ptr e1 = qnext; - qe_ptr e2 = qnext->qnext; - qe_ptr e3 = qprev; - - e1->qnext.clear(); - e2->qnext.clear(); - e3->qnext.clear(); - - // TODO this a recursive graph traversal on the stack... make this iterative - e1->recycle_next(); - e1.recycle(); - e2->recycle_next(); - e2.recycle(); - e3->recycle_next(); - e3.recycle(); - } - } - - void splice(qe_ptr a, qe_ptr b) - { - qe_ptr alpha = a->Onext()->Rot(); - qe_ptr beta = b->Onext()->Rot(); - - qe_ptr t1 = b->Onext(); - qe_ptr t2 = a->Onext(); - qe_ptr t3 = beta->Onext(); - qe_ptr t4 = alpha->Onext(); - - a->next = t1; - b->next = t2; - alpha->next = t3; - beta->next = t4; - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/QuadEdge.h b/src/terrainlib/tntn/QuadEdge.h deleted file mode 100644 index 59b2250..0000000 --- a/src/terrainlib/tntn/QuadEdge.h +++ /dev/null @@ -1,250 +0,0 @@ -#pragma once - -#include "../algorithms/primitives.h" -#include "ObjPool.h" -#include "geometrix.h" - -#define EPS 1e-6 - -namespace tntn { -namespace terra { - - typedef glm::dvec2 Point2D; - - using primitives::ccw; - using primitives::leftOf; - using primitives::rightOf; - using primitives::triAreaX2; - - // Returns True if the point d is inside the circle defined by the - // points a, b, c. See Guibas and Stolfi (1985) p.107. - inline bool inCircle(const Point2D& a, const Point2D& b, const Point2D& c, const Point2D& d) - { - return (a[0] * a[0] + a[1] * a[1]) * triAreaX2(b, c, d) - (b[0] * b[0] + b[1] * b[1]) * triAreaX2(a, c, d) + (c[0] * c[0] + c[1] * c[1]) * triAreaX2(a, b, d) - (d[0] * d[0] + d[1] * d[1]) * triAreaX2(a, b, c) > EPS; - } - - class Line { - private: - double a; - double b; - double c; - - public: - Line(const glm::dvec2& p, const glm::dvec2& q) - { - const glm::dvec2 t = q - p; - double l = t.length(); - - a = t.y / l; - b = -t.x / l; - c = -(a * p.x + b * p.y); - } - - inline double eval(const glm::dvec2& p) const noexcept { return (a * p.x + b * p.y + c); } - }; - - class Plane { - public: - double a; - double b; - double c; - - Plane() = default; - Plane(const glm::dvec3& p, const glm::dvec3& q, const glm::dvec3& r) { init(p, q, r); } - - inline void init(const glm::dvec3& p, const glm::dvec3& q, const glm::dvec3& r) noexcept; - - double eval(double x, double y) const noexcept { return a * x + b * y + c; } - }; - - // find the plane z=ax+by+c passing through three points p,q,r - inline void Plane::init(const glm::dvec3& p, const glm::dvec3& q, const glm::dvec3& r) noexcept - { - // We explicitly declare these (rather than putting them in a - // Vector) so that they can be allocated into registers. - const double ux = q.x - p.x; - const double uy = q.y - p.y; - const double uz = q.z - p.z; - - const double vx = r.x - p.x; - const double vy = r.y - p.y; - const double vz = r.z - p.z; - - const double den = ux * vy - uy * vx; - - const double _a = (uz * vy - uy * vz) / den; - const double _b = (ux * vz - uz * vx) / den; - - a = _a; - b = _b; - c = p.z - _a * p.x - _b * p.y; - } - - class DelaunayTriangle; - typedef pool_ptr dt_ptr; - - class QuadEdge; - typedef pool_ptr qe_ptr; - - // see http://www.cs.cmu.edu/afs/andrew/scs/cs/15-463/2001/pub/src/a2/quadedge.html - /* - - \_ _/ - \_ _/ - \_ | _/ - \_ | _/ - \_*_/ - |e->Dest - | - ^ - * |e * - e->Left | e->Right - |e->Org - _*_ - _/ | \_ - _/ | \_ - _/ | \_ - _/ \_ - / \ - - - - - next=ccw - \_ _/ - \_ _/ - \_ | _/ - Dprev \_ | _/ >Rprev - \_|_/ - | Dest - | - ^ +---> --+ - |e | prev=cw | - | +---------+ - | - _|_Org - _/ | \_ - >Lprev _/ | \_ >Oprev - _/ | \_ - _/ \_ - / \ - - - - * - | - v e->Sym - e->InvRot | - *----->-----|-------<-----* - | e->Rot - e ^ - | - * - - - */ - - class QuadEdge { - private: - qe_ptr qnext; // aka Rot - qe_ptr qprev; // aka invRot - qe_ptr self_ptr; - - QuadEdge(qe_ptr prev); - - protected: - Point2D data; - qe_ptr next; // aka Onext - dt_ptr lface; - - public: - QuadEdge() = default; - - void init(qe_ptr self_ptr); - void init(qe_ptr self_ptr, qe_ptr qprev); - void recycle_next(); - - //"next" means next in a counterclockwise (ccw) sense around a neighboring face or vertex - //"prev" means next in a clockwise (cw) sense around a neighboring face or vertex - - // Primitive methods - // next edge around origin, with same origin - qe_ptr Onext() const noexcept { return next; } - - // edge pointing opposite to this - qe_ptr Sym() const { return qnext->qnext; } - - // dual edge pointing to the left of this - qe_ptr Rot() const noexcept { return qnext; } - // dual edge pointing to the right of this - qe_ptr invRot() const noexcept { return qprev; } - - // Synthesized methods - qe_ptr Oprev() const { return Rot()->Onext()->Rot(); } - qe_ptr Dnext() const { return Sym()->Onext()->Sym(); } - qe_ptr Dprev() const { return invRot()->Onext()->invRot(); } - - // next edge around left face, with same left face - qe_ptr Lnext() const { return invRot()->Onext()->Rot(); } - // prev edge around left face, with same left face - qe_ptr Lprev() const { return Onext()->Sym(); } - - // next edge around right face, with same right face - qe_ptr Rnext() const { return Rot()->Onext()->invRot(); } - // prev edge around right face, with same right face - qe_ptr Rprev() const { return Sym()->Onext(); } - - // origin point - Point2D Org() const noexcept { return data; } - // destination point - Point2D Dest() const { return Sym()->data; } - - // face on the left - dt_ptr Lface() const noexcept { return lface; } - void set_Lface(dt_ptr t) noexcept { lface = t; } - - void set_end_points(const Point2D org, const Point2D dest) - { - data = org; - Sym()->data = dest; - } - - // The fundamental topological operator - friend void splice(qe_ptr a, qe_ptr b); - }; - - inline bool rightOf(const Point2D& x, qe_ptr e) - { - return rightOf(x, e->Org(), e->Dest()); - } - - inline bool leftOf(const Point2D& x, qe_ptr e) - { - return leftOf(x, e->Org(), e->Dest()); - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/QuantizedMeshIO.cpp b/src/terrainlib/tntn/QuantizedMeshIO.cpp deleted file mode 100644 index 6297634..0000000 --- a/src/terrainlib/tntn/QuantizedMeshIO.cpp +++ /dev/null @@ -1,798 +0,0 @@ -#include "QuantizedMeshIO.h" - -#include "Exception.h" -#include "BinaryIO.h" -#include "OFFReader.h" -#include "logging.h" -#include "tntn_assert.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "srs.h" - -// FIXME: remove collappsed vertices/triangles after quantization of mesh - -namespace tntn { - -struct QuantizedMeshLog { - File::position_type QuantizedMeshHeader_start = 0; - File::position_type VertexData_vertexCount_start = 0; - uint32_t VertexData_vertexCount = 0; - File::position_type VertexData_u_start = 0; - File::position_type VertexData_v_start = 0; - File::position_type VertexData_height_start = 0; - int IndexData_bits = 0; - File::position_type IndexData_triangleCount_start = 0; - uint32_t IndexData_triangleCount = 0; - File::position_type IndexData_indices_start = 0; - - std::string to_string() const - { - std::string out; - out = "{\n"; - out += "\t\"QuantizedMeshHeader_start\": " + std::to_string(QuantizedMeshHeader_start) + "\n"; - out += "\t\"VertexData_vertexCount_start\": " + std::to_string(VertexData_vertexCount_start) + "\n"; - out += "\t\"VertexData_vertexCount\": " + std::to_string(VertexData_vertexCount) + "\n"; - out += "\t\"VertexData_u_start\": " + std::to_string(VertexData_u_start) + "\n"; - out += "\t\"VertexData_v_start\": " + std::to_string(VertexData_v_start) + "\n"; - out += "\t\"VertexData_height_start\": " + std::to_string(VertexData_height_start) + "\n"; - out += "\t\"IndexData_bits\": " + std::to_string(IndexData_bits) + "\n"; - out += "\t\"IndexData_triangleCount_start\": " + std::to_string(IndexData_triangleCount_start) + "\n"; - out += "\t\"IndexData_triangleCount\": " + std::to_string(IndexData_triangleCount) + "\n"; - out += "\t\"IndexData_indices_start\": " + std::to_string(IndexData_indices_start) + "\n"; - out += "}\n"; - return out; - } -}; - -namespace detail { - - uint16_t zig_zag_encode(int16_t i) - { - return uint16_t((i >> 15) ^ (i << 1)); - } - - int16_t zig_zag_decode(uint16_t i) - { - return static_cast(i >> 1) ^ -static_cast(i & 1); - } - - // HORIZON OCCLUSION POINT - // https://cesiumjs.org/2013/05/09/Computing-the-horizon-occlusion-point - // taken from ctb (https://github.com/ahuarte47/cesium-terrain-builder) and edited - // Apache License, Version 2.0 - - // Constants taken from http://cesiumjs.org/2013/04/25/Horizon-culling - constexpr double llh_ecef_radiusX = 6378137.0; - constexpr double llh_ecef_radiusY = 6378137.0; - constexpr double llh_ecef_radiusZ = 6356752.3142451793; - - constexpr double llh_ecef_rX = 1.0 / llh_ecef_radiusX; - constexpr double llh_ecef_rY = 1.0 / llh_ecef_radiusY; - constexpr double llh_ecef_rZ = 1.0 / llh_ecef_radiusZ; - - double ocp_computeMagnitude(const glm::dvec3& position, const glm::dvec3& sphereCenter) - { - double magnitudeSquared = glm::dot(position, position); - double magnitude = std::sqrt(magnitudeSquared); - glm::dvec3 direction = position * (1.0 / magnitude); - - // For the purpose of this computation, points below the ellipsoid - // are considered to be on it instead. - magnitudeSquared = std::fmax(1.0, magnitudeSquared); - magnitude = std::fmax(1.0, magnitude); - - double cosAlpha = glm::dot(direction, sphereCenter); - double sinAlpha = glm::length(cross(direction, sphereCenter)); - double cosBeta = 1.0 / magnitude; - double sinBeta = std::sqrt(magnitudeSquared - 1.0) * cosBeta; - - return 1.0 / (cosAlpha * cosBeta - sinAlpha * sinBeta); - } - glm::dvec3 ocp_fromPoints(const std::vector& ecef_points, const glm::dvec3& ecef_bounding_sphere_center) - { - const double MIN = -std::numeric_limits::infinity(); - double max_magnitude = MIN; - - // Bring coordinates to ellipsoid scaled coordinates - glm::dvec3 scaledCenter = glm::dvec3(ecef_bounding_sphere_center.x * llh_ecef_rX, ecef_bounding_sphere_center.y * llh_ecef_rY, ecef_bounding_sphere_center.z * llh_ecef_rZ); - - for (const auto& point : ecef_points) { - glm::dvec3 scaledPoint(point.x * llh_ecef_rX, point.y * llh_ecef_rY, point.z * llh_ecef_rZ); - - double magnitude = ocp_computeMagnitude(scaledPoint, scaledCenter); - if (magnitude > max_magnitude) - max_magnitude = magnitude; - } - return scaledCenter * max_magnitude; - } - - // HORIZON OCCLUSION POINT -- end - -} // namespace detail - -using namespace detail; - -constexpr int QUANTIZED_COORDINATE_SIZE = 32767; - -static unsigned int scale_coordinate(const double v) -{ - const int scaled_v = static_cast(v * QUANTIZED_COORDINATE_SIZE + 0.5); - return scaled_v; -} - -static double unscale_coordinate(const int v) -{ - const double unscaled_v = static_cast(v) / QUANTIZED_COORDINATE_SIZE; - return unscaled_v; -} - -static unsigned int quantize_coordinate(const double v, const double min, const double max) -{ - TNTN_ASSERT(v >= min && v <= max); - const double delta = max - min; - TNTN_ASSERT(delta > 0); - const double offset_to_min = (v - min); - TNTN_ASSERT(offset_to_min >= 0 && offset_to_min <= delta); - return scale_coordinate(offset_to_min / delta); -} - -static double dequantize_coordinate(const int v, const double min, const double max) -{ - const double unscaled_v = unscale_coordinate(v); - - const double delta = max - min; - TNTN_ASSERT(delta > 0); - - const double offset_to_min = unscaled_v * delta; - const double deq_coord = min + offset_to_min; - return deq_coord; -} - -static void add_alignment(BinaryIO& bio, - BinaryIOErrorTracker& e, - const int alignment, - const uint8_t value = 0xCA) -{ - const auto sp = bio.write_pos(); - const int pad_size = sp % alignment == 0 ? 0 : alignment - (sp % alignment); - - for (int i = 0; i < pad_size; i++) { - bio.write_byte(value, e); - } -} - -template -struct get_alignment_helper { -}; - -template <> -struct get_alignment_helper { - enum { - value = 4 - }; -}; -template <> -struct get_alignment_helper { - enum { - value = 2 - }; -}; - -template -static void write_faces(BinaryIO& bio, - BinaryIOErrorTracker& e, - QuantizedMeshLog& log, - const SimpleRange& tris, - const detail::VertexOrdering& order) -{ - typedef IndexType index_t; - - log.IndexData_bits = sizeof(index_t) * 8; - - const uint32_t ntriangles = tris.size(); - - std::vector indices; - - indices.reserve(static_cast(ntriangles) * 3); - - // High-water mark encode triangle indices - index_t watermark = 0; - for (auto it = tris.begin; it != tris.end; ++it) { - for (int n = 0; n < 3; ++n) { - const Vertex& v = (*it)[n]; - const auto order_v_it = order.find(v); - TNTN_ASSERT(order_v_it != order.end()); - TNTN_ASSERT(order_v_it->second <= std::numeric_limits::max()); - - const index_t index = order_v_it->second; - TNTN_ASSERT((int64_t)watermark - (int64_t)index >= 0); - const index_t delta = watermark - index; - - indices.push_back(delta); - if (index == watermark) { - watermark++; - } - } - } - - const int alignment = get_alignment_helper::value; - add_alignment(bio, e, alignment); - - log.IndexData_triangleCount_start = bio.write_pos(); - log.IndexData_triangleCount = ntriangles; - bio.write_uint32(ntriangles, e); - if (ntriangles > 0) { - log.IndexData_indices_start = bio.write_pos(); - bio.write_array(indices, e); - } -} - -template -static void write_indices(BinaryIO& bio, - BinaryIOErrorTracker& e, - const std::vector& indices) -{ - const uint32_t nindices = indices.size(); - - bio.write_uint32(nindices, e); - - // TODO specialize write for 16/32bit so 32bit write is fast - for (uint32_t i = 0; i < nindices; i++) { - const IndexType index = indices[i]; - bio.write(index, e); - } -} - -bool write_mesh_as_qm(const char* filename, const Mesh& m, bool compress) -{ - BBox3D bbox; - m.get_bbox(bbox); - return write_mesh_as_qm(filename, m, bbox, false, compress); -} - -bool write_mesh_as_qm(const char* filename, const Mesh& m, const BBox3D& bbox, bool mesh_is_rescaled, bool compress) -{ - OGRSpatialReference webmercator; - webmercator.importFromEPSG(3857); - webmercator.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - return write_mesh_as_qm(filename, m, bbox, webmercator, mesh_is_rescaled, compress); -} - -bool write_mesh_as_qm(const char* filename, - const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& mesh_srs, - bool mesh_is_rescaled, bool comprress) -{ - if (comprress) { - auto f = std::make_shared(filename); - return write_mesh_as_qm(f, m, bbox, mesh_srs, mesh_is_rescaled); - } - - auto f = std::make_shared(); - f->open(filename, File::OM_RWCF); - return write_mesh_as_qm(f, m, bbox, mesh_srs, mesh_is_rescaled); -} - -bool write_mesh_as_qm(const std::shared_ptr& f, const Mesh& m) -{ - OGRSpatialReference webmercator; - webmercator.importFromEPSG(3857); - webmercator.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - BBox3D bbox; - m.get_bbox(bbox); - return write_mesh_as_qm(f, m, bbox, webmercator, false); -} - -static void write_qmheader(BinaryIO& bio, - BinaryIOErrorTracker& e, - const QuantizedMeshHeader& qmheader) -{ - bio.write_double(qmheader.center.x, e); - bio.write_double(qmheader.center.y, e); - bio.write_double(qmheader.center.z, e); - - bio.write_float(qmheader.MinimumHeight, e); - bio.write_float(qmheader.MaximumHeight, e); - - bio.write_double(qmheader.bounding_sphere_center.x, e); - bio.write_double(qmheader.bounding_sphere_center.y, e); - bio.write_double(qmheader.bounding_sphere_center.z, e); - bio.write_double(qmheader.BoundingSphereRadius, e); - - bio.write_double(qmheader.horizon_occlusion.x, e); - bio.write_double(qmheader.horizon_occlusion.y, e); - bio.write_double(qmheader.horizon_occlusion.z, e); -} - -QuantizedMeshHeader detail::quantised_mesh_header(const Mesh& m, const BBox3D& bbox, const OGRSpatialReference& srs, bool mesh_is_rescaled) -{ - const auto ecef_bbox = srs::toECEF(srs, bbox); - - Vertex c = (ecef_bbox.max + ecef_bbox.min) / 2.0; - - QuantizedMeshHeader header; - header.center = c; - header.bounding_sphere_center = c; - header.BoundingSphereRadius = glm::distance(ecef_bbox.min, ecef_bbox.max) / 2; - - header.MinimumHeight = bbox.min.z; - header.MaximumHeight = bbox.max.z; - - // https://cesium.com/blog/2013/05/09/computing-the-horizon-occlusion-point/ - if (mesh_is_rescaled) { - std::vector srs_points; - srs_points.reserve(m.vertices_as_vector().size()); - const auto scaling = bbox.max - bbox.min; - assert(scaling.x > 0); - assert(scaling.y > 0); - assert(scaling.z > 0); - - for (const auto& p : m.vertices_as_vector()) { - srs_points.emplace_back(p * scaling + bbox.min); - } - header.horizon_occlusion = ocp_fromPoints(srs::toECEF(srs, srs_points), c); - } else { - header.horizon_occlusion = ocp_fromPoints(srs::toECEF(srs, m.vertices_as_vector()), c); - } - - return header; -} - -QuantizedMeshVertexData detail::quantised_mesh_vertex_data(const Mesh& m, const BBox3D& bbox, const OGRSpatialReference& srs, bool mesh_is_rescaled) -{ - // Write QM vertex data - std::vector northlings; - std::vector eastlings; - std::vector southlings; - std::vector westlings; - VertexOrdering vertices_order; - std::vector us; - std::vector vs; - std::vector hs; - const size_t nvertices = m.vertices().size(); - - us.reserve(nvertices); - vs.reserve(nvertices); - hs.reserve(nvertices); - - int u = 0; - int v = 0; - int h = 0; - int prev_u = 0; - int prev_v = 0; - int prev_h = 0; - int vertex_index = 0; - - auto triangles = m.triangles(); - - vertices_order.reserve(triangles.size() / 2); - for (auto it = triangles.begin; it != triangles.end; ++it) { - for (int n = 0; n < 3; ++n) { - const Vertex node = (*it)[n]; - - const auto vertices_order_it = vertices_order.find(node); - if (vertices_order_it != vertices_order.end()) - continue; - - vertices_order.emplace_hint(vertices_order_it, std::make_pair(node, vertex_index)); - - // Rescale coordinates - if (mesh_is_rescaled) { - u = scale_coordinate(node.x); - v = scale_coordinate(node.y); - h = scale_coordinate(node.z); - } else { - u = quantize_coordinate(node.x, bbox.min.x, bbox.max.x); - v = quantize_coordinate(node.y, bbox.min.y, bbox.max.y); - h = quantize_coordinate(node.z, bbox.min.z, bbox.max.z); - } - TNTN_ASSERT(u >= 0 && u <= QUANTIZED_COORDINATE_SIZE); - TNTN_ASSERT(v >= 0 && v <= QUANTIZED_COORDINATE_SIZE); - TNTN_ASSERT(h >= 0 && h <= QUANTIZED_COORDINATE_SIZE); - - if (u == 0) { - westlings.push_back(vertex_index); - } else if (u == QUANTIZED_COORDINATE_SIZE) { - eastlings.push_back(vertex_index); - } - - if (v == 0) { - southlings.push_back(vertex_index); - } else if (v == QUANTIZED_COORDINATE_SIZE) { - northlings.push_back(vertex_index); - } - - TNTN_ASSERT(u - prev_u >= -32768 && u - prev_u <= 32767); - TNTN_ASSERT(v - prev_v >= -32768 && v - prev_v <= 32767); - TNTN_ASSERT(h - prev_h >= -32768 && h - prev_h <= 32767); - - us.push_back(zig_zag_encode(int16_t(u - prev_u))); - vs.push_back(zig_zag_encode(int16_t(v - prev_v))); - hs.push_back(zig_zag_encode(int16_t(h - prev_h))); - - prev_u = u; - prev_v = v; - prev_h = h; - - vertex_index++; - } - } - - return { - northlings, - eastlings, - southlings, - westlings, - vertices_order, - us, - vs, - hs, - nvertices, - }; -} - -std::vector detail::quantized_mesh_encode(const std::vector& input) -{ - int16_t prev = 0; - std::vector encoded_array; - encoded_array.reserve(input.size()); - for (int16_t current : input) { - TNTN_ASSERT(current - prev == int(int16_t(current - prev))); - encoded_array.push_back(zig_zag_encode(int16_t(current - prev))); - prev = current; - } - return encoded_array; -} - -std::vector detail::quantized_mesh_decode(const std::vector& input) -{ - std::vector decoded_array; - decoded_array.reserve(input.size()); - int prev = 0; - for (uint16_t current : input) { - prev += zig_zag_decode(current); - TNTN_ASSERT(prev == int(int16_t(prev))); - decoded_array.push_back(int16_t(prev)); - } - return decoded_array; -} - -bool write_mesh_as_qm(const std::shared_ptr& f, - const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& mesh_srs, - bool mesh_is_rescaled) -{ - if (!m.empty() && !m.has_triangles()) { - TNTN_LOG_ERROR("Mesh has to be triangulated in order to be written as QM"); - return false; - } - - BinaryIO bio(f, Endianness::LITTLE); - BinaryIOErrorTracker e; - QuantizedMeshLog log; - - const auto header = quantised_mesh_header(m, bbox, mesh_srs, mesh_is_rescaled); - log.QuantizedMeshHeader_start = bio.write_pos(); - write_qmheader(bio, e, header); - if (e.has_error()) { - TNTN_LOG_ERROR("{} in file {}", e.to_string(), f->name()); - return false; - } - TNTN_ASSERT( - bio.write_pos() == sizeof(QuantizedMeshHeader)); // might not be true for some platforms, mostly for debugging - - const auto vdata = quantised_mesh_vertex_data(m, bbox, mesh_srs, mesh_is_rescaled); - log.VertexData_vertexCount_start = bio.write_pos(); - log.VertexData_vertexCount = vdata.nvertices; - bio.write_uint32(vdata.nvertices, e); - if (e.has_error()) { - TNTN_LOG_ERROR("{} in file {}", e.to_string(), f->name()); - return false; - } - - log.VertexData_u_start = bio.write_pos(); - bio.write_array_uint16(vdata.us, e); - - log.VertexData_v_start = bio.write_pos(); - bio.write_array_uint16(vdata.vs, e); - - log.VertexData_height_start = bio.write_pos(); - bio.write_array_uint16(vdata.hs, e); - - if (e.has_error()) { - TNTN_LOG_ERROR("{} in file {}", e.to_string(), f->name()); - return false; - } - - // Write triangle indices data - if (vdata.nvertices <= 65536) { - write_faces(bio, e, log, m.triangles(), vdata.vertices_order); - write_indices(bio, e, vdata.westlings); - write_indices(bio, e, vdata.southlings); - write_indices(bio, e, vdata.eastlings); - write_indices(bio, e, vdata.northlings); - } else { - write_faces(bio, e, log, m.triangles(), vdata.vertices_order); - write_indices(bio, e, vdata.westlings); - write_indices(bio, e, vdata.southlings); - write_indices(bio, e, vdata.eastlings); - write_indices(bio, e, vdata.northlings); - } - - if (e.has_error()) { - TNTN_LOG_ERROR("{} in file {}", e.to_string(), f->name()); - return false; - } - - // TNTN_LOG_INFO("writer log: {}", log.to_string()); - return true; -} - -static BBox3D bbox_from_header(const QuantizedMeshHeader& qmheader) -{ - const glm::dvec2 top_left = qmheader.bounding_sphere_center - qmheader.BoundingSphereRadius; - const glm::dvec2 bottom_right = qmheader.bounding_sphere_center + qmheader.BoundingSphereRadius; - - BBox3D out(glm::dvec3(top_left, qmheader.MinimumHeight), - glm::dvec3(bottom_right, qmheader.MaximumHeight)); - - return out; -} - -static std::vector decode_qm_vertices(const BBox3D& bbox, - const std::vector& u_buffer, - const std::vector& v_buffer, - const std::vector& height_buffer) -{ - if (!(u_buffer.size() == v_buffer.size() && v_buffer.size() == height_buffer.size())) { - TNTN_ASSERT(false); // should never happen - TNTN_LOG_ERROR("u,v,height must have the same size"); - return std::vector(); - } - std::vector vx_buffer; - vx_buffer.reserve(u_buffer.size()); - - int u = 0; - int v = 0; - int height = 0; - for (size_t i = 0; i < u_buffer.size(); i++) { - u += zig_zag_decode(u_buffer[i]); - v += zig_zag_decode(v_buffer[i]); - height += zig_zag_decode(height_buffer[i]); - - const double x = dequantize_coordinate(u, bbox.min.x, bbox.max.x); - const double y = dequantize_coordinate(v, bbox.min.y, bbox.max.y); - const double z = dequantize_coordinate(height, bbox.min.z, bbox.max.z); - - vx_buffer.emplace_back(x, y, z); - } - - return vx_buffer; -} - -template -static void decode_qm_faces_impl(const std::vector& indices, - std::vector& face_buffer) -{ - int highest = 0; - for (size_t i = 0; i < indices.size(); i += 3) { - Face f; - for (size_t k = 0; k < 3; k++) { - const int code = indices[i + k]; - f[k] = highest - code; - if (code == 0) { - highest++; - } - } - face_buffer.push_back(f); - } -} - -static std::vector decode_qm_faces(const std::vector& indices16, - const std::vector& indices32) -{ - std::vector face_buffer; - face_buffer.reserve(indices16.size() / 3 + indices32.size() / 3); - decode_qm_faces_impl(indices16, face_buffer); - decode_qm_faces_impl(indices32, face_buffer); - return face_buffer; -} - -static void read_qmheader(BinaryIO& bio, BinaryIOErrorTracker& e, QuantizedMeshHeader& qmheader) -{ - bio.read_double(qmheader.center.x, e); - bio.read_double(qmheader.center.y, e); - bio.read_double(qmheader.center.z, e); - - bio.read_float(qmheader.MinimumHeight, e); - bio.read_float(qmheader.MaximumHeight, e); - - bio.read_double(qmheader.bounding_sphere_center.x, e); - bio.read_double(qmheader.bounding_sphere_center.y, e); - bio.read_double(qmheader.bounding_sphere_center.z, e); - bio.read_double(qmheader.BoundingSphereRadius, e); - - bio.read_double(qmheader.horizon_occlusion.x, e); - bio.read_double(qmheader.horizon_occlusion.y, e); - bio.read_double(qmheader.horizon_occlusion.z, e); -} - -static bool read_qm_data(const std::shared_ptr& f, - QuantizedMeshHeader& qmheader, - std::vector& vertex_data_u, - std::vector& vertex_data_v, - std::vector& vertex_data_height, - std::vector& indices16, - std::vector& indices32) -{ - if (!f->is_good()) { - TNTN_LOG_ERROR("input file {} is not open/good", f->name()); - return false; - } - - BinaryIO bio(f, Endianness::LITTLE); - BinaryIOErrorTracker e; - QuantizedMeshLog log; - - log.QuantizedMeshHeader_start = bio.read_pos(); - read_qmheader(bio, e, qmheader); - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {} during QuantizedMeshHeader", e.to_string(), f->name()); - return false; - } - - // VertexData - uint32_t vertex_count = 0; - log.VertexData_vertexCount_start = bio.read_pos(); - bio.read_uint32(vertex_count, e); - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {} during VertexData::vertexCount", e.to_string(), f->name()); - return false; - } - TNTN_LOG_DEBUG("vertex_count: {}", vertex_count); - log.VertexData_vertexCount = vertex_count; - - if (vertex_count > 0) { - log.VertexData_u_start = bio.read_pos(); - bio.read_array_uint16(vertex_data_u, vertex_count, e); - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {} during VertexData::u", e.to_string(), f->name()); - return false; - } - - log.VertexData_v_start = bio.read_pos(); - bio.read_array_uint16(vertex_data_v, vertex_count, e); - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {} during VertexData::v", e.to_string(), f->name()); - return false; - } - - log.VertexData_height_start = bio.read_pos(); - bio.read_array_uint16(vertex_data_height, vertex_count, e); - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {} during VertexData::height", e.to_string(), f->name()); - return false; - } - } - - // padding - const size_t alignment = vertex_count <= 65536 ? 2 : 4; - const auto read_pos = bio.read_pos(); - if (read_pos % alignment != 0) { - int pad_size = alignment - (read_pos % alignment); - bio.read_skip(pad_size, e); - } - - // Index Data - uint32_t triangle_count = 0; - log.IndexData_triangleCount_start = bio.read_pos(); - bio.read_uint32(triangle_count, e); - if (e.has_error()) { - TNTN_LOG_ERROR( - "{} on file {} during IndexData(16/32)::triangleCount", e.to_string(), f->name()); - return false; - } - log.IndexData_triangleCount = triangle_count; - - if (triangle_count > 0) { - if (vertex_count <= 65536) { - log.IndexData_bits = 16; - log.IndexData_indices_start = bio.read_pos(); - bio.read_array_uint16(indices16, static_cast(triangle_count) * 3, e); - if (e.has_error()) { - TNTN_LOG_ERROR( - "{} on file {} during IndexData16::indices", e.to_string(), f->name()); - return false; - } - } else { - log.IndexData_bits = 32; - log.IndexData_indices_start = bio.read_pos(); - bio.read_array_uint32(indices32, static_cast(triangle_count) * 3, e); - if (e.has_error()) { - TNTN_LOG_ERROR( - "{} on file {} during IndexData32::indices", e.to_string(), f->name()); - return false; - } - } - } - // TODO edge indices - - // TODO extensions - - if (e.has_error()) { - TNTN_LOG_ERROR("{} on file {}", e.to_string(), f->name()); - return false; - } - - TNTN_LOG_INFO("reader log: {}", log.to_string()); - return true; -} - -std::unique_ptr load_mesh_from_qm(const char* filename) -{ - auto f = std::make_shared(); - if (!f->open(filename, File::OM_R)) { - TNTN_LOG_ERROR("unable to open quantized mesh in file {}", filename); - return std::unique_ptr(); - } - return load_mesh_from_qm(f); -} - -std::unique_ptr load_mesh_from_qm(const std::shared_ptr& f) -{ - QuantizedMeshHeader qmheader; - std::vector vertex_data_u; - std::vector vertex_data_v; - std::vector vertex_data_height; - std::vector indices16; - std::vector indices32; - - TNTN_LOG_DEBUG("reading QuantizedMesh data..."); - if (!read_qm_data( - f, qmheader, vertex_data_u, vertex_data_v, vertex_data_height, indices16, indices32)) { - TNTN_LOG_ERROR("error reading quantized mesh data from file {}", f->name()); - return std::unique_ptr(); - } - TNTN_LOG_DEBUG( - "before decoding: VertexData::u.size={} VertexData::v.size={} VertexData::height.size={} IndicesData16::indices.size={} IndicesData32::indices.size={}", - vertex_data_u.size(), - vertex_data_v.size(), - vertex_data_height.size(), - indices16.size(), - indices32.size()); - - const BBox3D header_bbox = bbox_from_header(qmheader); - TNTN_LOG_DEBUG("bbox derived from header: {}", header_bbox.to_string()); - - std::vector vertices = decode_qm_vertices(header_bbox, vertex_data_u, vertex_data_v, vertex_data_height); - - std::vector faces = decode_qm_faces(indices16, indices32); - - TNTN_LOG_DEBUG("{} vertices, {} faces after decoding", vertices.size(), faces.size()); - - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(vertices), std::move(faces)); - - { - BBox3D mesh_bbox; - mesh->get_bbox(mesh_bbox); - TNTN_LOG_DEBUG("bbox derived from resulting mesh: {}", mesh_bbox.to_string()); - } - return mesh; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/QuantizedMeshIO.h b/src/terrainlib/tntn/QuantizedMeshIO.h deleted file mode 100644 index 12c3dbc..0000000 --- a/src/terrainlib/tntn/QuantizedMeshIO.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "File.h" -#include "Mesh.h" -#include "geometrix.h" - -namespace tntn { - -// exposed for testing -namespace detail { - using QMVertex = glm::dvec3; - using VertexOrdering = std::unordered_map; - - struct QuantizedMeshHeader { - // The center of the tile in Earth-centered Fixed coordinates. - // double CenterX; - // double CenterY; - // double CenterZ; - QMVertex center; - - // The minimum and maximum heights in the area covered by this tile. - // The minimum may be lower and the maximum may be higher than - // the height of any vertex in this tile in the case that the min/max vertex - // was removed during mesh simplification, but these are the appropriate - // values to use for analysis or visualization. - float MinimumHeight; - float MaximumHeight; - - // The tile’s bounding sphere. The X,Y,Z coordinates are again expressed - // in Earth-centered Fixed coordinates, and the radius is in meters. - QMVertex bounding_sphere_center; - // double BoundingSphereCenterX; - // double BoundingSphereCenterY; - // double BoundingSphereCenterZ; - double BoundingSphereRadius; - - // The horizon occlusion point, expressed in the ellipsoid-scaled Earth-centered Fixed frame. - // If this point is below the horizon, the entire tile is below the horizon. - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ for more information. - QMVertex horizon_occlusion; - // double HorizonOcclusionPointX; - // double HorizonOcclusionPointY; - // double HorizonOcclusionPointZ; - }; - - struct QuantizedMeshVertexData { - std::vector northlings; - std::vector eastlings; - std::vector southlings; - std::vector westlings; - VertexOrdering vertices_order; - std::vector us; - std::vector vs; - std::vector hs; - size_t nvertices; - }; - - uint16_t zig_zag_encode(int16_t i); - int16_t zig_zag_decode(uint16_t i); - - std::vector quantized_mesh_encode(const std::vector& input); - std::vector quantized_mesh_decode(const std::vector& input); - - QuantizedMeshHeader quantised_mesh_header(const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& srs, - bool mesh_is_rescaled = false); - - QuantizedMeshVertexData quantised_mesh_vertex_data(const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& srs, - bool mesh_is_rescaled = false); - -} // namespace detail - -bool write_mesh_as_qm(const char* filename, const Mesh& m, bool compress = false); -bool write_mesh_as_qm(const char* filename, - const Mesh& m, - const BBox3D& bbox, - bool mesh_is_rescaled = false, - bool compress = false); -bool write_mesh_as_qm(const char* filename, - const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& mesh_srs, - bool mesh_is_rescaled = false, - bool compress = false); - -bool write_mesh_as_qm(const std::shared_ptr& f, const Mesh& m); -bool write_mesh_as_qm(const std::shared_ptr& f, - const Mesh& m, - const BBox3D& bbox, - const OGRSpatialReference& mesh_srs, - bool mesh_is_rescaled = false); - -std::unique_ptr load_mesh_from_qm(const char* filename); -std::unique_ptr load_mesh_from_qm(const std::shared_ptr& f); - -} // namespace tntn diff --git a/src/terrainlib/tntn/Raster.h b/src/terrainlib/tntn/Raster.h deleted file mode 100644 index 6b22e43..0000000 --- a/src/terrainlib/tntn/Raster.h +++ /dev/null @@ -1,560 +0,0 @@ -#pragma once - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Image.h" -#include "geometrix.h" -#include "logging.h" -#include "tntn_assert.h" -#include - -namespace tntn { - -namespace detail { - - template - struct isnan_helper { - static bool isnan(const T&) noexcept { return false; } - }; - - template <> - struct isnan_helper { - static bool isnan(const double x) noexcept { return std::isnan(x); } - }; - - template <> - struct isnan_helper { - static bool isnan(const double x) noexcept { return std::isnan(x); } - }; - - template - class NDVDefault { - public: - static void set(T& value) { } - }; - - template <> - class NDVDefault { - public: - static void set(double& value) { value = std::numeric_limits::max(); } - }; - -} // namespace detail - -// Terrain Raster -template -class Raster { -private: - // disallow copy and assign, only move semantics allowed to avoid accidential copies - Raster(const Raster& other) = default; - Raster& operator=(const Raster& other) = delete; - -public: - Raster() { ::tntn::detail::NDVDefault::set(m_noDataValue); } - Raster(Raster&& other) noexcept = default; - explicit Raster(Image&& other, const radix::tile::SrsBounds& srs_bounds) - : m_width(other.width()) - , m_height(other.height()) - , m_data(std::move(other.m_data)) - , m_cell_width_in_srs(srs_bounds.width() / other.width()) - , m_cell_height_in_srs(srs_bounds.height() / other.height()) - , m_xpos(srs_bounds.min.x) - , m_ypos(srs_bounds.min.y) - { - ::tntn::detail::NDVDefault::set(m_noDataValue); - } - Raster& operator=(Raster&& other) noexcept = default; - - /** - deep copy raster - - @return copy of current raster - */ - Raster clone() const - { - return *this; - } - - /** - constructor - - @param w width of raster - @param h height of raster - */ - Raster(const unsigned int w, const unsigned int h) - : Raster() - { - allocate(w, h); - } - - /** - copies settable parameters from parent raster - (i.e. not width and height) - - @param raster parent to copy parametrs from - */ - void copy_parameters(const Raster& raster) - { - m_xpos = raster.m_xpos; - m_ypos = raster.m_ypos; - m_cell_width_in_srs = raster.m_cell_width_in_srs; - m_cell_height_in_srs = raster.m_cell_height_in_srs; - m_noDataValue = raster.m_noDataValue; - } - - /** - clears all data and parameters - (except noDataValue) - */ - void clear() - { - m_width = 0; - m_height = 0; - m_xpos = 0; - m_ypos = 0; - m_cell_width_in_srs = 0; - m_cell_height_in_srs = 0; - - m_data.resize(0); - } - - /** - allocate memory for data - - @param w width of raster - @param h height of raster - */ - void allocate(const unsigned int w, const unsigned int h) - { - m_width = w; - m_height = h; - m_data.resize(m_width * m_height); - } - - /** - set all raster pixels to this value - - @param value value to be set - */ - void set_all(T value) { std::fill(get_ptr(), get_ptr() + m_width * m_height, value); } - - /** - count all ourrences of given value - - @param value value to count - @return number of pixels with given value - */ - long count(T value) - { - long count = 0; - - T* pData = get_ptr(0); - - for (int i = 0; i < m_width * m_height; i++) { - if (pData[i] == value) - count++; - } - - return count; - } - - /** - crop to sub raster - - row and column index coordinates with origin at LOWER left - automatically sets xpos and ypos as expected (using lower left coordinate system) - - @param cx column of sub image lower left corner - @param cy row of sub image lower left corner - @param cw width of sub image - @param ch height of sub image - @return the sub image with updated xpos & ypos and correct cellsize parameter - */ - Raster crop_ll(const unsigned int cx, - const unsigned int cy, - const unsigned int cw, - const unsigned int ch) const - { - int cyn = m_height - (cy + ch); - return crop(cx, cyn, cw, ch); - } - - /** - crop to sub raster - - row and column index coordinates with origin at TOP left - automatically sets xpos and ypos as expected (using lower left coordinate system) - - @param cx column of sub image lower left corner - @param cy row of sub image lower left corner - @param cw width of sub image - @param ch height of sub image - @param dst_raster output raster (will be overwritten) - */ - void crop(const int cx, const int cy, const int cw, const int ch, Raster& dst_raster) const - { - - // bounds: - int max_x = cx + cw; - int max_y = cy + ch; - - int min_x = cx; - int min_y = cy; - - if (max_x > m_width) { - TNTN_LOG_DEBUG("raster.crop - max x {} larger than width {}", max_x, m_width); - } - - if (max_y > m_height) { - TNTN_LOG_DEBUG("raster.crop - max y {} larger than height {} ", max_y, m_height); - } - - if (min_x < 0) { - TNTN_LOG_DEBUG("raster.crop - min x {} smaller than zero", min_x); - } - - if (min_y < 0) { - TNTN_LOG_DEBUG("raster.crop - min y {} smaller than zero ", min_y); - } - - // fix bounds - max_x = max_x > m_width ? m_width : max_x; - max_y = max_y > m_height ? m_height : max_y; - - min_x = min_x < 0 ? 0 : min_x; - min_y = min_y < 0 ? 0 : min_y; - - // const int w = m_width; - // const int h = m_height; - - const int crop_width = max_x - min_x; - const int crop_height = max_y - min_y; - - dst_raster.allocate(crop_width, crop_height); - dst_raster.set_all(get_no_data_value()); - dst_raster.set_no_data_value(get_no_data_value()); - - dst_raster.set_cell_width(get_cell_width()); - dst_raster.set_cell_height(get_cell_height()); - - dst_raster.set_pos_x(col2x(min_x)); - dst_raster.set_pos_y(row2y(max_y - 1)); - - // copy pixels across - for (int r = min_y; r < max_y; r++) { - const T* pIn = get_ptr(r); - T* pOut = dst_raster.get_ptr(r - min_y); - - for (int c = min_x; c < max_x; c++) { - pOut[c - min_x] = pIn[c]; - } - } - } - - /** - crop to sub raster - - row and column index coordinates with origin at TOP left - automatically sets xpos and ypos as expected (using lower left coordinate system) - - @param cx column of sub image lower left corner - @param cy row of sub image lower left corner - @param cw width of sub image - @param ch height of sub image - @return the sub image with updated xpos & ypos and correct cellsize parameter - */ - Raster crop(const unsigned int cx, - const unsigned int cy, - const unsigned int cw, - const unsigned int ch) const - { - Raster dst_raster; - crop(cx, cy, cw, ch, dst_raster); - return dst_raster; - } - - /** - get bounding box of raster - - @return 2d bounding box - */ - BBox2D get_bounding_box() const - { - BBox2D bb; - - bb.min.x = col_ll2x(0); - bb.min.y = row_ll2y(0); - - bb.max.x = col_ll2x(get_width()); - bb.max.y = row_ll2y(get_height()); - - return bb; - } - - /** - @return raster width in pixels - */ - unsigned int get_width() const { return m_width; } - - /** - @return raster height in pixels - */ - unsigned int get_height() const { return m_height; } - - /** - get tile position in geo coordinates - @return x position of lower left corner - */ - double get_pos_x() const { return m_xpos; } - - /** - set tile position in geo coordinates - @param xpos position of lower left corner - */ - void set_pos_x(const double xpos) { m_xpos = xpos; } - - /** - get tile position in geo coordinates - @return y position of lower left corner - */ - double get_pos_y() const { return m_ypos; } - - /** - set tile position in geo coordinates - @param ypos position of lower left corner - */ - void set_pos_y(const double ypos) { m_ypos = ypos; } - - /** - get value that represents missing or no data at this location - @return no data value - */ - T get_no_data_value() const { return m_noDataValue; } - - /** - set value that represents missing or no data at this location - @param ndv no data value - */ - void set_no_data_value(T ndv) { m_noDataValue = ndv; } - - /** - get width or height of pixel or cell - @return cell size in geo coordinates - */ - glm::dvec2 get_cell_size() const { return { m_cell_width_in_srs, m_cell_height_in_srs }; } - double get_cell_width() const { return m_cell_width_in_srs; } - double get_cell_height() const { return m_cell_height_in_srs; } - - /** - set width or height of pixel or cell - @param cs cell size in geo coordinates - */ - void set_cell_size(const glm::dvec2& cs) - { - m_cell_width_in_srs = cs.x; - m_cell_height_in_srs = cs.y; - } - void set_cell_width(const double cs) { m_cell_width_in_srs = cs; } - void set_cell_height(const double cs) { m_cell_height_in_srs = cs; } - - /** - get raw pointer to beginning of raster (top left is origin) - @return raw pointer - */ - const T* get_ptr() const { return m_data.data(); } - T* get_ptr() { return m_data.data(); } - - /** - get raw pointer to beginning of raster row (top left is origin) - @param r row - @return raw pointer - */ - const T* get_ptr(const unsigned int r) const { return m_data.data() + r * m_width; } - T* get_ptr(const unsigned int r) { return m_data.data() + r * m_width; } - - /** - get raw pointer to beginning of raster row (lower left is origin) - @param r row - @return raw pointer - */ - const T* get_ptr_ll(const unsigned int r) const { return m_data.data() + (m_height - 1 - r) * m_width; } - T* get_ptr_ll(const unsigned int r) { return m_data.data() + (m_height - 1 - r) * m_width; } - - /** - get value at raster position - - @param r row - @param c column - @return value - */ - const T& value(const unsigned int r, const unsigned int c) const - { - TNTN_ASSERT(c < m_width); - TNTN_ASSERT(r < m_height); - return get_ptr(r)[c]; - } - T& value(const unsigned int r, const unsigned int c) - { - TNTN_ASSERT(c < m_width); - TNTN_ASSERT(r < m_height); - return get_ptr(r)[c]; - } - - /** - get value at raster position (using lower left coordinate system) - - @param r row - @param c column - @return value - */ - const T& value_ll(const unsigned int r, const unsigned int c) const { return get_ptr_ll(r)[c]; } - T& value_ll(const unsigned int r, const unsigned int c) { return get_ptr_ll(r)[c]; } - - /** - get x component of geo/world coordinates at column c - - @param c column - @return x geo coordinates - */ - double col2x(const unsigned int c) const { return m_xpos + c * m_cell_width_in_srs; } - - int x2col(double x) const - { - if (m_cell_width_in_srs > 0) { - const auto col = int((x - m_xpos) / m_cell_width_in_srs + 0.5); - TNTN_ASSERT(col >= 0); - TNTN_ASSERT(col < m_width); - return col; - } else { - return 0; - } - } - - int y2row(double y) const - { - // y = m_xpos + (r + 0.5) * m_cellsize - - if (m_cell_height_in_srs > 0) { - - int r_ll = int((y - m_ypos) / m_cell_height_in_srs + 0.5); - int r_tl = m_height - r_ll - 1; - TNTN_ASSERT(r_tl >= 0); - TNTN_ASSERT(r_tl < m_height); - return r_tl; - } else { - return 0; - } - } - - /** - get x component of geo/world coordinates at column c - - @param c column - @return x geo coordinates - */ - double row2y(const unsigned int r_tl) const - { - int r_ll = m_height - 1 - r_tl; - return m_ypos + r_ll * m_cell_height_in_srs; - } - - /** - get y component of geo/world coordinates at row r - (row in lower left coordinate system) - - @param r row from lower left - @return y geo coordinates - */ - double row_ll2y(const unsigned int r_ll) const { return m_ypos + r_ll * m_cell_height_in_srs; } - - /** - get x component of geo/world coordinates at column c - (column in lower left coordinate system) - - @param c column from lower left - @return x geo coordinates - */ - double col_ll2x(const unsigned int c) const { return col2x(c); } - - /** - is raster empty - @return false if empty, true if not - */ - bool empty() const { return m_width == 0 && m_height == 0; } - - // note: - // do we need this? - // since getPtr() is public and so are the parameters via get function - // I question the need for a general purpose function like this - // as it can easily be implemented outside this class - // further, it seems there should be only one correct implementation of this - - // signature for VertexReceiverFn must be (void)(double x, double y, T z) - template - void to_vertices(VertexReceiverFn&& receiver_fn) const - { - const double cw = get_cell_width(); - const double ch = get_cell_height(); - const double xpos = get_pos_x(); - const double ypos = get_pos_y(); - const int width = get_width(); - const int height = get_height(); - const auto* p = get_ptr(); - - // coordinate system has origin at lower left corner! - for (int r = 0; r < height; r++) { - const double y_coordinate = ypos + (height - r - 1) * ch; - - for (int c = 0; c < width; c++) { - const double x_coordinate = xpos + c * cw; - receiver_fn(x_coordinate, y_coordinate, p[c]); - } - - p += width; - } - } - - bool is_no_data(const T& a_value) const - { - return detail::isnan_helper::isnan(a_value) || a_value == m_noDataValue; - } - - auto begin() const { return m_data.begin(); } - auto begin() { return m_data.begin(); } - - auto end() const { return m_data.end(); } - auto end() { return m_data.end(); } - - const std::vector& asVector() const { return m_data; } - -private: - // raster width and height - unsigned int m_width = 0; - unsigned int m_height = 0; - - // tile position in world coordinates - double m_xpos = 0; - double m_ypos = 0; - - double m_cell_width_in_srs = 1; - double m_cell_height_in_srs = 1; - - // value of data that indicates absence of data - T m_noDataValue; - - std::vector m_data; -}; - -typedef Raster RasterDouble; -// typedef Raster RasterByte; //eg. for grey scale image - -} // namespace tntn diff --git a/src/terrainlib/tntn/RasterIO.cpp b/src/terrainlib/tntn/RasterIO.cpp deleted file mode 100644 index fc1eaca..0000000 --- a/src/terrainlib/tntn/RasterIO.cpp +++ /dev/null @@ -1,397 +0,0 @@ - -#include "RasterIO.h" -#include "fmt/format.h" -#include "fmt/printf.h" -#include "logging.h" -#include "raster_tools.h" -#include "util.h" - -#include -#include -#include -#include - -#include -#include - -#include "gdal_init.h" - -namespace tntn { - -std::string getFirstNonZero(std::vector tokens, int start) -{ - for (int i = start; i < tokens.size(); i++) { - if (tokens[i].size() > 0) - return tokens[i]; - } - - return ""; -} - -// reads from file in ESRI ASCII Raster format -// http://resources.esri.com/help/9.3/arcgisdesktop/com/gp_toolref/spatial_analyst_tools/esri_ascii_raster_format.htm -RasterDouble load_raster_from_asc(const std::string& filename) -{ - TNTN_LOG_INFO("load raster..."); - - RasterDouble raster; - std::ifstream input(filename); - - int count = 0; - int r = 0; - int c = 0; - - int width = 0; - int height = 0; - - int numPoints = 0; - - std::vector tokens; - for (std::string line; getline(input, line);) { - tokenize(line, tokens); - - if (tokens.size() > 1) { - if (count == 0) { - width = std::stoi(getFirstNonZero(tokens, 1)); - } else if (count == 1) { - height = std::stoi(getFirstNonZero(tokens, 1)); - raster.allocate(width, height); - } else if (count == 2) { - raster.set_pos_x(std::stod(getFirstNonZero(tokens, 1))); - } else if (count == 3) { - raster.set_pos_y(std::stod(getFirstNonZero(tokens, 1))); - } else if (count == 4) { - raster.set_cell_width(std::stod(getFirstNonZero(tokens, 1))); - } else if (count == 5) { - raster.set_no_data_value(std::stod(getFirstNonZero(tokens, 1))); - } else { -#if true - - // read data - if (tokens.size() != raster.get_width()) { - TNTN_LOG_ERROR("can't read data"); - return raster; - } else { - c = 0; - for (auto p : tokens) { - try { - raster.value(r, c) = std::stod(p); - } catch (const char* msg) { - std::cout << msg << std::endl; - raster.value(r, c) = raster.get_no_data_value(); - } - - numPoints++; - c++; - } - - if ((r % (raster.get_height() / 10)) == 0) { - float p = r / (float)raster.get_height(); - TNTN_LOG_INFO("{} %", p * 100.0); - } - - r++; - } -#else - std::stringstream stream(input); - while (true) { - double v; - stream >> v; - if (!stream) - break; - } -#endif - } - } - - count++; - } - - TNTN_LOG_INFO("done"); - - return raster; -} - -// writes to file in ESRI ASCII Raster format -// http://resources.esri.com/help/9.3/arcgisdesktop/com/gp_toolref/spatial_analyst_tools/esri_ascii_raster_format.htm -bool write_raster_to_asc(const std::string& filename, const RasterDouble& raster) -{ - File f; - if (!f.open(filename.c_str(), File::OM_RWCF)) { - TNTN_LOG_ERROR("unable to open raster file {} for writing", filename); - return false; - } - return write_raster_to_asc(f, raster); -} - -bool write_raster_to_asc(FileLike& file, const RasterDouble& raster) -{ - /* - NCOLS xxx - NROWS xxx - XLLCENTER xxx | XLLCORNER xxx - YLLCENTER xxx | YLLCORNER xxx - CELLSIZE xxx - NODATA_VALUE xxx - row 1 - row 2 - ... - row n - */ - if (!file.is_good()) { - return false; - } - TNTN_LOG_INFO("write raster..."); - - std::string line_buffer; - line_buffer.reserve(4096); - FileLike::position_type write_position = 0; - - // file << "NCOLS " << raster.getWidth() << std::endl; - line_buffer += fmt::format("NCOLS {}\n", raster.get_width()); - // file << "NROWS " << raster.getHeight() << std::endl; - line_buffer += fmt::format("NROWS {}\n", raster.get_height()); - // file << "XLLCORNER " << std::setprecision(9) << raster.getXPos() << std::endl; - line_buffer += fmt::format("XLLCORNER {:.9f}\n", raster.get_pos_x()); - // file << "YLLCORNER " << std::setprecision(9) << raster.getYPos() << std::endl; - line_buffer += fmt::format("YLLCORNER {:.9f}\n", raster.get_pos_y()); - // file << "CELLSIZE " << std::setprecision(9) << raster.getCellsize() << std::endl; - line_buffer += fmt::format("CELLSIZE {:.9f}\n", raster.get_cell_width()); - // file << "NODATA_VALUE " << std::setprecision(9) << raster.getNoDataValue() << std::endl; - line_buffer += fmt::format("NODATA_VALUE {:.9f}\n", raster.get_no_data_value()); - - if (!file.write(write_position, line_buffer.data(), line_buffer.size())) - return false; - write_position += line_buffer.size(); - line_buffer.resize(0); - - if (!file.is_good()) { - return false; - } - - for (int r = 0; r < raster.get_height(); r++) { - for (int c = 0; c < raster.get_width(); c++) { - line_buffer += fmt::format("{} ", raster.value(r, c)); - } - - line_buffer += fmt::format("\n"); - - if (!file.write(write_position, line_buffer.data(), line_buffer.size())) - return false; - write_position += line_buffer.size(); - line_buffer.resize(0); - - if ((r % (1 + raster.get_height() / 10)) == 0) { - float p = r / (float)raster.get_height(); - TNTN_LOG_INFO("{} %", p * 100.0); - } - } - - if (!file.write(write_position, line_buffer.data(), line_buffer.size())) - return false; - line_buffer.resize(0); - - TNTN_LOG_INFO("done"); - - return true; -} - -// -------------------------------------------------------------------------------- -// Import raster from GDAL - -typedef std::unique_ptr GDALDataset_ptr; - -struct TransformationMatrix { - union { - double matrix[6]; - struct - { - double origin_x; - double scale_x; - double padding_0; - double origin_y; - double padding_1; - double scale_y; - }; - }; -}; - -static void GDALClose_wrapper(GDALDataset* p) -{ - if (p != nullptr) { - GDALClose(p); - } -} - -static bool get_transformation_matrix(GDALDataset* dataset, TransformationMatrix& gt) -{ - if (dataset->GetGeoTransform(gt.matrix) != CE_None) { - TNTN_LOG_ERROR("Input raster is missing geotransformation matrix"); - return false; - } - - // if(fabs(gt.scale_x) != fabs(gt.scale_y)) - // { - // TNTN_LOG_ERROR("Can not process rasters with non square pixels ({}x{})", - // fabs(gt.scale_x), - // fabs(gt.scale_y)); - // return false; - // } - - return true; -} - -static bool is_valid_projection(GDALDataset* dataset) -{ - // returned pointer should not be altered, freed or expected to last for long. - const char* projection_wkt = dataset->GetProjectionRef(); - - if (projection_wkt == NULL) { - TNTN_LOG_ERROR("Input raster file does not provide spatial reference information"); - return false; - } - - OGRSpatialReference raster_srs; - -#if GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR < 3 - raster_srs.importFromWkt(const_cast(&projection_wkt)); -#else - raster_srs.importFromWkt(projection_wkt); -#endif - - int matches_number; - - OGRSpatialReference web_mercator; - web_mercator.importFromEPSG(3857); - - bool matched = false; - -#if GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR < 3 - OGRErr match_projection_error = raster_srs.AutoIdentifyEPSG(); - - if (match_projection_error != 0) { - TNTN_LOG_ERROR("Can not match projection to EPSG:3857"); - return false; - } - - if (web_mercator.IsSame(&raster_srs)) { - matched = true; - } -#else - // Matched projections must be freed with OSRFreeSRSArray() - OGRSpatialReferenceH* matched_projections = raster_srs.FindMatches(NULL, &matches_number, NULL); - - if (matched_projections == 0) { - TNTN_LOG_ERROR("Can not match projection to EPSG:3857"); - return false; - } - - for (int i = 0; i < matches_number; i++) { - if (web_mercator.IsSame(static_cast(matched_projections[i]))) { - matched = true; - break; - } - } - - if (matched_projections) { - OSRFreeSRSArray(matched_projections); - } -#endif - - if (!matched) { - TNTN_LOG_ERROR("Can not match projection to EPSG:3857"); - } - - return matched; -} - -bool load_raster_file(const std::string& file_name, - RasterDouble& target_raster, - bool validate_projection) -{ - initialize_gdal_once(); - - TNTN_LOG_INFO("Opening raster file {} with GDAL...", file_name); - - GDALDataset_ptr dataset(static_cast(GDALOpen(file_name.c_str(), GA_ReadOnly)), - &GDALClose_wrapper); - - if (dataset == nullptr) { - TNTN_LOG_ERROR("Can't open input raster {}: ", file_name); - return false; - } - - TransformationMatrix gt; - - if (!get_transformation_matrix(dataset.get(), gt)) { - return false; - } - - if (validate_projection && !is_valid_projection(dataset.get())) { - fmt::print("input raster file must be in EPSG:3857 (Web Mercator) format\n"); - fmt::print("you can reproject raster terrain using GDAL\n"); - fmt::print("as follows: 'gdalwarp -t_srs EPSG:3857 input.tif output.tif'\n"); - - return false; - } - - int bands_count = dataset->GetRasterCount(); - - if (bands_count == 0) { - TNTN_LOG_ERROR("Can't process a raster file witout raster bands"); - return false; - } else if (bands_count > 1) { - TNTN_LOG_WARN("File {} has {} raster bands, processing with a raster band #1", - file_name, - bands_count); - } - - // TODO: Perhaps make raster band number a parameter - GDALRasterBand* raster_band = dataset->GetRasterBand(1); - - int raster_width = raster_band->GetXSize(); - int raster_height = raster_band->GetYSize(); - - target_raster.set_cell_width(fabs(gt.scale_x)); - target_raster.set_cell_height(fabs(gt.scale_y)); - target_raster.allocate(raster_width, raster_height); - target_raster.set_no_data_value(raster_band->GetNoDataValue()); - - TNTN_LOG_INFO("reading raster data..."); - if (raster_band->RasterIO(GF_Read, - 0, - 0, - raster_width, - raster_height, - target_raster.get_ptr(), - raster_width, - raster_height, - GDT_Float64, - 0, - 0) - != CE_None) { - TNTN_LOG_ERROR("Can not read raster data"); - return false; - } - - double x1 = gt.origin_x; - double y1 = gt.origin_y; - double x2 = gt.origin_x + raster_width * gt.scale_x; - double y2 = gt.origin_y + raster_height * gt.scale_y; - - // Ensure raster's origin is exactly at the lower left corner - target_raster.set_pos_x(std::min(x1, x2)); - target_raster.set_pos_y(std::min(y1, y2)); - - if (gt.scale_x < 0) { - raster_tools::flip_data_x(target_raster); - } - - if (gt.scale_y > 0) { - raster_tools::flip_data_y(target_raster); - } - - return true; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/RasterIO.h b/src/terrainlib/tntn/RasterIO.h deleted file mode 100644 index 254a24e..0000000 --- a/src/terrainlib/tntn/RasterIO.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "Raster.h" -#include "File.h" -#include - -namespace tntn { -// template Raster load_raster_from_asc(const std::string &filename); -// template void write_raster_to_asc(const std::string &filename,Raster); - -RasterDouble load_raster_from_asc(const std::string& filename); - -bool write_raster_to_asc(const std::string& filename, const RasterDouble& raster); -bool write_raster_to_asc(FileLike& f, const RasterDouble& raster); - -bool load_raster_file(const std::string& filename, - RasterDouble& raster, - bool validate_projection = true); -} // namespace tntn diff --git a/src/terrainlib/tntn/SuperTriangle.cpp b/src/terrainlib/tntn/SuperTriangle.cpp deleted file mode 100644 index dd561b1..0000000 --- a/src/terrainlib/tntn/SuperTriangle.cpp +++ /dev/null @@ -1,126 +0,0 @@ - -#include "SuperTriangle.h" - -namespace tntn { - -SuperTriangle::SuperTriangle(const Vertex& v1, const Vertex& v2, const Vertex& v3) -{ - m_t[0] = v1; - m_t[1] = v2; - m_t[2] = v3; - - init(); -} - -SuperTriangle::SuperTriangle(const Triangle& tr) -{ - m_t = tr; - - init(); -} - -BBox2D SuperTriangle::getBB() -{ - return m_bb; -} - -Triangle SuperTriangle::getTriangle() -{ - return m_t; -} - -bool SuperTriangle::interpolate(const double x, const double y, double& z) -{ - auto& v1 = m_t[0]; - auto& v2 = m_t[1]; - auto& v3 = m_t[2]; - - // https://codeplea.com/triangular-interpolation - const double w1 = ((v2.y - v3.y) * (x - v3.x) + (v3.x - v2.x) * (y - v3.y)) / m_wdem; - const double w2 = ((v3.y - v1.y) * (x - v3.x) + (v1.x - v3.x) * (y - v3.y)) / m_wdem; - const double w3 = 1.0 - w1 - w2; - - z = (double)(v1.z * w1 + v2.z * w2 + v3.z * w3); - - if (0 <= w1 && w1 <= 1 && 0 <= w2 && w2 <= 1 && 0 <= w3 && w3 <= 1) - return true; - else - return false; -} - -void SuperTriangle::rasterise(RasterDouble& raster) -{ - int w = raster.get_width(); - int h = raster.get_height(); - - int rs = (int)(m_bb.min.y + 0.5); - int re = (int)(m_bb.max.y + 1.5); - - int cs = (int)(m_bb.min.x + 0.5); - int ce = (int)(m_bb.max.x + 1.5); - - // bounds check - rs = rs < 0 ? 0 : rs > h ? h - : rs; - re = re < 0 ? 0 : re > h ? h - : re; - - cs = cs < 0 ? 0 : cs > w ? w - : cs; - ce = ce < 0 ? 0 : ce > w ? w - : ce; - -#if false - double ndv = raster.getNoDataValue(); - - double minz = m_v1.z < m_v2.z ? m_v1.z : m_v2.z; - minz = minz < m_v3.z ? minz : m_v3.z; - - double maxz = m_v1.z > m_v2.z ? m_v1.z : m_v2.z; - maxz = maxz > m_v3.z ? maxz : m_v3.z; -#endif - - for (int r = rs; r < re; r++) { - double* pH = raster.get_ptr(h - r - 1); - - for (int c = cs; c < ce; c++) { - double ht; - if (interpolate(c + 0.5, r + 0.5, ht)) { -#if false - if(pH[c] != ndv) - { - if(std::abs(pH[c] - ht) > 0.0001) - { - TNTN_LOG_WARN("overwriting pixel with different value - before: {} after: {}",pH[c],ht); - } - } - - if(ht > (maxz + 0.0001) || ht < (minz-0.0001)) - { - TNTN_LOG_WARN("interpolate out of range"); - } -#endif - - pH[c] = ht; - } - } - } -} - -void SuperTriangle::init() -{ - auto& v1 = m_t[0]; - auto& v2 = m_t[1]; - auto& v3 = m_t[2]; - - m_wdem = (v2.y - v3.y) * (v1.x - v3.x) + (v3.x - v2.x) * (v1.y - v3.y); - - findBounds(); -} - -void SuperTriangle::findBounds() -{ - for (int i = 0; i < 3; i++) - m_bb.add(m_t[i]); -} -} // namespace tntn diff --git a/src/terrainlib/tntn/SuperTriangle.h b/src/terrainlib/tntn/SuperTriangle.h deleted file mode 100644 index 05afd23..0000000 --- a/src/terrainlib/tntn/SuperTriangle.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "Raster.h" -#include "geometrix.h" - -namespace tntn { -class SuperTriangle { -public: - SuperTriangle(const Vertex& v1, const Vertex& v2, const Vertex& v3); - SuperTriangle(const Triangle& tr); - - bool interpolate(const double x, const double y, double& z); - void rasterise(RasterDouble& raster); - - BBox2D getBB(); - Triangle getTriangle(); - -private: - void init(); - void findBounds(); - void updateBounds(const Vertex& v); - -private: - Triangle m_t; - BBox2D m_bb; - double m_wdem; -}; -} // namespace tntn diff --git a/src/terrainlib/tntn/SurfacePoints.cpp b/src/terrainlib/tntn/SurfacePoints.cpp deleted file mode 100644 index ef9c8a0..0000000 --- a/src/terrainlib/tntn/SurfacePoints.cpp +++ /dev/null @@ -1,357 +0,0 @@ -#include "SurfacePoints.h" -#include "gdal_init.h" -#include "logging.h" - -#include -#include -#include -#include -#include -#include - -#include "cpl_conv.h" // for CPLMalloc() -#include "gdal.h" -#include "gdal_priv.h" - -namespace tntn { - -void SurfacePoints::clear() -{ - m_points.clear(); - m_bbox.reset(); -} - -size_t SurfacePoints::size() const -{ - return m_points.size(); -} - -bool SurfacePoints::load_from_xyz_file(const std::string& filename) -{ - std::ifstream f(filename); - if (!f.is_open()) { - TNTN_LOG_ERROR("error opening input file {}", filename); - return false; - } - - clear(); - - double x, y, z; - while (f >> x >> y >> z) { - // skip nodata values - if (std::isnan(z) || z < -10000.0 || z > 10000.0) { - continue; - } - push_back({ x, y, z }); - } - - TNTN_LOG_DEBUG("loaded input file {} with {} points", filename, m_points.size()); - TNTN_LOG_DEBUG(" range of values X: {} - {}", m_bbox.min.x, m_bbox.max.x); - TNTN_LOG_DEBUG(" range of values Y: {} - {}", m_bbox.min.y, m_bbox.max.y); - TNTN_LOG_DEBUG(" range of values Z: {} - {}", m_bbox.min.z, m_bbox.max.z); - - return true; -} - -void SurfacePoints::load_from_memory(std::vector&& points) -{ - m_points = std::move(points); - m_bbox.reset(); - for (const auto& vertex : m_points) { - m_bbox.add(vertex); - } - - TNTN_LOG_DEBUG("loaded input {} points", m_points.size()); - TNTN_LOG_DEBUG(" range of values X: {} - {}", m_bbox.min.x, m_bbox.max.x); - TNTN_LOG_DEBUG(" range of values Y: {} - {}", m_bbox.min.y, m_bbox.max.y); - TNTN_LOG_DEBUG(" range of values Z: {} - {}", m_bbox.min.z, m_bbox.max.z); -} - -void SurfacePoints::load_from_raster(const RasterDouble& raster) -{ - clear(); - - const auto nodataval = raster.get_no_data_value(); - - m_points.reserve(raster.get_width() * raster.get_height()); - m_bbox.reset(); - - raster.to_vertices([this, nodataval](const double x, const double y, const double z) { - if (z != nodataval) { - Vertex v(x, y, z); - m_points.emplace_back(v); - m_bbox.add(v); - } - }); -} - -void SurfacePoints::swap(SurfacePoints& other) noexcept -{ - std::swap(m_points, other.m_points); - std::swap(m_bbox, other.m_bbox); -} - -SurfacePoints SurfacePoints::clone() const -{ - SurfacePoints ret; - ret.m_points = m_points; - ret.m_bbox = m_bbox; - return ret; -} - -SimpleRange SurfacePoints::points() const -{ - if (m_points.empty()) { - return { nullptr, nullptr }; - } else { - return { m_points.data(), m_points.data() + m_points.size() }; - } -} - -double SurfacePoints::find_non_zero_min_diff(const std::vector& values, - double& min, - double& max) -{ - min = std::numeric_limits::max(); - max = -std::numeric_limits::max(); - if (values.size() < 1) - return 0; - - double min_diff = 0; - - // initialize search - double last = values[0]; - double local_min = last; - double local_max = last; - - for (int i = 1; i < values.size(); i++) { - double v = values[i]; - - TNTN_LOG_TRACE("v: {:6}", v); - - double d = fabs(last - v); - if (d > 0) { - if (min_diff == 0) { - min_diff = d; - } else if (d < min_diff) { - min_diff = d; - } - } - - if (v < local_min) - local_min = v; - if (v > local_max) - local_max = v; - - last = v; - } - - min = local_min; - max = local_max; - return min_diff; -} - -static void get_xy_values_from_points(const std::vector& points, - std::vector& x_values, - std::vector& y_values) -{ - x_values.clear(); - y_values.clear(); - - // find all x and y coordinates (determine the raster grid) - std::unordered_set x_values_set; - std::unordered_set y_values_set; - - x_values_set.reserve(sqrt(points.size()) + 1); - y_values_set.reserve(sqrt(points.size()) + 1); - - for (const auto& p : points) { - x_values_set.insert(p.x); - y_values_set.insert(p.y); - } - - x_values.reserve(x_values_set.size()); - std::copy(x_values_set.begin(), x_values_set.end(), std::back_inserter(x_values)); - std::sort(x_values.begin(), x_values.end()); - - y_values.reserve(y_values_set.size()); - std::copy(y_values_set.begin(), y_values_set.end(), std::back_inserter(y_values)); - std::sort(y_values.begin(), y_values.end(), std::greater()); -} - -// reshapes point cloud back to raster -// big assumption: this point cloud was derived from a 2D regular spaced raster -// please note: currently not performing any checks on this assumption -std::unique_ptr SurfacePoints::to_raster() const -{ - auto raster = std::make_unique(); - - // sort x y coordinates seperately - std::vector x_values; - std::vector y_values; - get_xy_values_from_points(m_points, x_values, y_values); - - // find max difference between adjacent values - // this gives us a rough idea of x y raster spacing - - double max_x, min_x; - double min_dx = find_non_zero_min_diff(x_values, min_x, max_x); - - double max_y, min_y; - double min_dy = find_non_zero_min_diff(y_values, min_y, max_y); - - // recover width and height - int w = min_dx == 0 ? 1 : 1 + (max_x - min_x) / min_dx; - int h = min_dy == 0 ? 1 : 1 + (max_y - min_y) / min_dy; - - // bring raster to size and set all NaN - { - raster->allocate(w, h); - raster->set_no_data_value(-std::numeric_limits::max()); - raster->set_all(raster->get_no_data_value()); - } - - // TODO: double check / write unit tests etc - raster->set_pos_x(min_x); - raster->set_pos_y(min_y); - raster->set_cell_width((min_dx + min_dy) / 2.0); - - for (const auto& p : m_points) { - int c = min_dx == 0 ? 0 : ((p.x - min_x) / min_dx); - int r = min_dy == 0 ? 0 : (h - 1 - (p.y - min_y) / min_dy); - - if (c >= 0 && c < w && r >= 0 && r < h) { - raster->value(r, c) = p.z; - } - } - - return raster; -} - -std::unique_ptr> SurfacePoints::to_vxraster() const -{ - auto vxraster = std::make_unique>(); - - std::vector x_values; - std::vector y_values; - get_xy_values_from_points(m_points, x_values, y_values); - - // bring raster to size and set all NaN - { - vxraster->allocate(x_values.size(), y_values.size()); - const Vertex no_data_vx = { std::numeric_limits::min(), - std::numeric_limits::min(), - std::numeric_limits::min() }; - vxraster->set_no_data_value(no_data_vx); - vxraster->set_all(no_data_vx); - } - - // find max difference between adjacent values - // this gives us a rough idea of x y raster spacing - - double max_x, min_x; - double min_dx = find_non_zero_min_diff(x_values, min_x, max_x); - - double max_y, min_y; - double min_dy = find_non_zero_min_diff(y_values, min_y, max_y); - - vxraster->set_pos_x(min_x); - vxraster->set_pos_y(min_y); - vxraster->set_cell_width((min_dx + min_dy) / 2.0); - - TNTN_LOG_DEBUG("raster: ({}, {}, {})", - vxraster->get_pos_x(), - vxraster->get_pos_y(), - vxraster->get_cell_width()); - - // assign each point to a raster cell - { - for (const auto& p : m_points) { - const auto x_it = std::lower_bound(x_values.begin(), x_values.end(), p.x); - const size_t x_i = std::distance(x_values.begin(), x_it); - - const auto y_it = std::lower_bound(y_values.begin(), y_values.end(), p.y, std::greater()); - const size_t y_i = std::distance(y_values.begin(), y_it); - - Vertex& v = vxraster->value(y_i, x_i); - v = p; - } - } - - return vxraster; -} - -static bool create_points_from_raster( - GDALRasterBand* band, double ox, double oy, double sx, double sy, SurfacePoints& points) -{ - int width = band->GetXSize(); - int height = band->GetYSize(); - - std::vector pixel_data(width * height); - - if (band->RasterIO( - GF_Read, 0, 0, width, height, &pixel_data.front(), width, height, GDT_Float64, 0, 0) - != CE_None) { - TNTN_LOG_ERROR("Can't access raster band"); - return false; - } - - double nodata = band->GetNoDataValue(); - - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - - double point_value = pixel_data[y * width + x]; - - if (point_value == nodata) - continue; - - double px = ox + sx * x; - double py = oy + sy * y; - double pz = point_value; - - points.push_back({ px, py, pz }); - } - } - - return true; -} - -bool SurfacePoints::load_from_gdal(const std::string& filename) -{ - initialize_gdal_once(); - - TNTN_LOG_INFO("Loading input file {} with GDAL...", filename); - std::shared_ptr ds( - static_cast(GDALOpen(filename.c_str(), GA_ReadOnly)), &GDALClose); - if (ds == nullptr) { - TNTN_LOG_ERROR("Can't open input raster {}", filename); - return false; - } - - double gt[6]; - if (ds->GetGeoTransform(gt) != CE_None) { - TNTN_LOG_ERROR("Input raster is missing geotransformation matrix"); - return false; - } - - GDALRasterBand* band = ds->GetRasterBand(1); - if (!band) { - TNTN_LOG_ERROR("Can not read input raster band"); - return false; - } - - const double x_pos = gt[0]; - const double y_pos = gt[3]; - const double csx = gt[1]; - const double csy = gt[5]; - - TNTN_LOG_INFO("Converting band 1 from GDAL raster to points..."); - if (!create_points_from_raster(band, x_pos, y_pos, csx, csy, *this)) { - TNTN_LOG_ERROR("error transforming {} to points", filename); - return false; - } - - return true; -} -} // namespace tntn diff --git a/src/terrainlib/tntn/SurfacePoints.h b/src/terrainlib/tntn/SurfacePoints.h deleted file mode 100644 index ebb79f7..0000000 --- a/src/terrainlib/tntn/SurfacePoints.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "Raster.h" -#include "geometrix.h" -#include "util.h" -#include -#include -#include - -namespace tntn { - -class SurfacePoints { -private: - // disallow copy and assign - SurfacePoints(const SurfacePoints& other) = delete; - SurfacePoints& operator=(const SurfacePoints& other) = delete; - -public: - SurfacePoints() = default; - SurfacePoints(SurfacePoints&& other) { swap(other); } - SurfacePoints& operator=(SurfacePoints&& other) - { - swap(other); - return *this; - } - - void swap(SurfacePoints& other) noexcept; - SurfacePoints clone() const; - - void clear(); - size_t size() const; - bool empty() const { return size() == 0; } - - bool load_from_xyz_file(const std::string& filename); - bool load_from_gdal(const std::string& filename); - void load_from_memory(std::vector&& points); - void load_from_raster(const RasterDouble& raster); - - void reserve(size_t size) { m_points.reserve(size); } - void push_back(const Vertex& p) - { - m_points.push_back(p); - m_bbox.add(p); - } - SimpleRange points() const; - - BBox3D bounding_box() const { return m_bbox; } - - std::unique_ptr to_raster() const; - std::unique_ptr> to_vxraster() const; - -private: - static double find_non_zero_min_diff(const std::vector& values, - double& min, - double& max); - -private: - std::vector m_points; - BBox3D m_bbox; -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/TerraMesh.cpp b/src/terrainlib/tntn/TerraMesh.cpp deleted file mode 100644 index e89cae8..0000000 --- a/src/terrainlib/tntn/TerraMesh.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "TerraMesh.h" -#include "algorithms/raster_triangle_scanline.h" -#include "DelaunayTriangle.h" -#include "SurfacePoints.h" -#include "TerraUtils.h" -#include "logging.h" - -#include -#include -#include -#include -#include -#include - -namespace tntn { -namespace terra { - - void TerraMesh::greedy_insert(double max_error) - { - m_max_error = max_error; - m_counter = 0; - const auto w = m_raster->get_width(); - const auto h = m_raster->get_height(); - TNTN_ASSERT(w > 0); - TNTN_ASSERT(h > 0); - - TNTN_LOG_DEBUG("starting greedy insertion with raster width: {}, height: {}", w, h); - - // Initialize m_used - m_used.allocate(w, h); - m_used.set_all(0); - - // Ensure the four corners are not NAN, otherwise the algorithm can't proceed. - this->repair_point(0, 0); - this->repair_point(0, h - 1); - this->repair_point(w - 1, h - 1); - this->repair_point(w - 1, 0); - - // Initialize the mesh to two triangles with the height field grid corners as vertices - TNTN_LOG_DEBUG("initialize the mesh with four corner points"); - this->init_mesh(glm::dvec2(0, 0), glm::dvec2(0, h - 1), glm::dvec2(w - 1, h - 1), glm::dvec2(w - 1, 0)); - - m_used.value(0, 0) = 1; - m_used.value(h - 1, 0) = 1; - m_used.value(h - 1, w - 1) = 1; - m_used.value(0, w - 1) = 1; - - // Initialize m_token - m_token.allocate(w, h); - m_token.set_all(0); - - // Scan all the triangles and push all candidates into a stack - // these are actually only the two triangles of the quad. - dt_ptr t = m_first_face; - while (t) { - scan_triangle(t); - t = t->getLink(); - } - - // Iterate until the error threshold is met - while (!m_candidates.empty()) { - Candidate candidate = m_candidates.grab_greatest(); - - if (candidate.importance < m_max_error) - continue; - - // Skip if the candidate is not the latest - if (m_token.value(candidate.y, candidate.x) != candidate.token) - continue; - - m_used.value(candidate.y, candidate.x) = 1; - - // TNTN_LOG_DEBUG("inserting point: ({}, {}, {})", candidate.x, candidate.y, candidate.z); - // insert will recursively call scan_triangle through a virtual function call. - this->insert(glm::dvec2(candidate.x, candidate.y), candidate.triangle); - } - - TNTN_LOG_DEBUG("finished greedy insertion"); - } - - void TerraMesh::scan_triangle(dt_ptr t) - { - Plane z_plane; - compute_plane(z_plane, t, *m_raster); - - // i didn't write the algorithm, but i think the triangle points should be integer always. - // maybe that happened during one of my refactorings, e.g., while removing +0.5 in the raster image class. - // leaving this to be certain / catch errors. - assert(std::abs(t->point1().x - std::floor(t->point1().x)) < 0.0000000000001); - assert(std::abs(t->point1().y - std::floor(t->point1().y)) < 0.0000000000001); - - assert(std::abs(t->point2().x - std::floor(t->point2().x)) < 0.0000000000001); - assert(std::abs(t->point2().y - std::floor(t->point2().y)) < 0.0000000000001); - - assert(std::abs(t->point3().x - std::floor(t->point3().x)) < 0.0000000000001); - assert(std::abs(t->point3().y - std::floor(t->point3().y)) < 0.0000000000001); - - // oh, the original raster scanline algorithm was buggy, so i replaced it with a unit tested one. - - glm::uvec2 p0 = glm::uvec2(t->point1()); - glm::uvec2 p1 = glm::uvec2(t->point2()); - glm::uvec2 p2 = glm::uvec2(t->point3()); - - Candidate candidate = { 0, 0, 0.0, -DBL_MAX, m_counter++, t }; - const double no_data_value = m_raster->get_no_data_value(); - const auto fun = [&](const glm::uvec2 coord, double height) { - if (m_used.value(coord.y, coord.x)) - return; - if (is_no_data(height, no_data_value)) - return; - - const auto predicted_height = z_plane.eval(coord.x, coord.y); - const auto error = std::abs(predicted_height - height); - candidate.consider(coord.x, coord.y, height, error); - }; - - raster::triangle_scanline(*m_raster, p0, p1, p2, fun); - - // We have now found the appropriate candidate point - m_token.value(candidate.y, candidate.x) = candidate.token; - - // Push the candidate into the stack - m_candidates.push_back(candidate); - } - - std::unique_ptr TerraMesh::convert_to_mesh() - { - // Find all the vertices - int w = m_raster->get_width(); - int h = m_raster->get_height(); - - std::vector mvertices; - - Raster vertex_id; - vertex_id.allocate(w, h); - vertex_id.set_all(0); - - const double no_data_value = m_raster->get_no_data_value(); - int index = 0; - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - if (m_used.value(y, x) == 1) { - const double z = m_raster->value(y, x); - if (is_no_data(z, no_data_value)) { - continue; - } - - Vertex v = Vertex({ m_raster->col2x(x), m_raster->row2y(y), z }); - mvertices.push_back(v); - vertex_id.value(y, x) = index; - index++; - } - } - } - - // Find all the faces - std::vector mfaces; - dt_ptr t = m_first_face; - while (t) { - Face f; - - glm::dvec2 p1 = t->point1(); - glm::dvec2 p2 = t->point2(); - glm::dvec2 p3 = t->point3(); - - if (!ccw(p1, p2, p3)) { - f[0] = vertex_id.value((int)p1.y, (int)p1.x); - f[1] = vertex_id.value((int)p2.y, (int)p2.x); - f[2] = vertex_id.value((int)p3.y, (int)p3.x); - } else { - f[0] = vertex_id.value((int)p3.y, (int)p3.x); - f[1] = vertex_id.value((int)p2.y, (int)p2.x); - f[2] = vertex_id.value((int)p1.y, (int)p1.x); - } - - mfaces.push_back(f); - - t = t->getLink(); - } - - // now initialise our mesh class with this - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(mvertices), std::move(mfaces)); - return mesh; - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/TerraMesh.h b/src/terrainlib/tntn/TerraMesh.h deleted file mode 100644 index 1ce9868..0000000 --- a/src/terrainlib/tntn/TerraMesh.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "Raster.h" -#include "DelaunayMesh.h" -#include "MeshIO.h" -#include "TerraUtils.h" -#include "geometrix.h" - -#include - -namespace tntn { -namespace terra { - - class TerraMesh : public TerraBaseMesh { - private: - Raster m_used; - Raster m_token; - - CandidateList m_candidates; - double m_max_error; - int m_counter; - - void scan_triangle_line(const Plane& plane, - int y, - double x1, - double x2, - Candidate& candidate, - const double no_data_value); - - public: - void greedy_insert(double max_error); - void scan_triangle(dt_ptr t) override; - std::unique_ptr convert_to_mesh(); - }; - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/TerraUtils.cpp b/src/terrainlib/tntn/TerraUtils.cpp deleted file mode 100644 index 3c292ea..0000000 --- a/src/terrainlib/tntn/TerraUtils.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "TerraUtils.h" -#include "logging.h" -#include "raster_tools.h" - -namespace tntn { -namespace terra { - - void TerraBaseMesh::repair_point(unsigned px, unsigned py) - { - double& p = m_raster->value(py, px); - const double z = raster_tools::sample_nearest_valid_avg(*m_raster, py, px); - const double no_data_value = m_raster->get_no_data_value(); - if (is_no_data(z, no_data_value)) { - p = 0.0; - } else { - TNTN_LOG_DEBUG("fill missing point: ({}, {}, {})", px, py, z); - p = z; - } - } - - void TerraBaseMesh::load_raster(std::unique_ptr raster) - { - m_raster = std::move(raster); - } - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/TerraUtils.h b/src/terrainlib/tntn/TerraUtils.h deleted file mode 100644 index 1e34208..0000000 --- a/src/terrainlib/tntn/TerraUtils.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include "DelaunayMesh.h" -#include "DelaunayTriangle.h" -#include "Raster.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace tntn { -namespace terra { - - struct Candidate { - unsigned x = 0; - unsigned y = 0; - double z = 0.0; - double importance = -DBL_MAX; - int token = 0; - dt_ptr triangle; - - void consider(unsigned sx, unsigned sy, double sz, double imp) noexcept - { - if (imp > importance) { - x = sx; - y = sy; - z = sz; - importance = imp; - } - } - - bool operator>(const Candidate& c) const noexcept { return (importance > c.importance); } - bool operator<(const Candidate& c) const noexcept { return (importance < c.importance); } - }; - - class CandidateList { - public: - void push_back(const Candidate& candidate) { m_candidates.push(candidate); } - - size_t size() const noexcept { return m_candidates.size(); } - bool empty() const noexcept { return m_candidates.empty(); } - - // find greatest element, remove from candidate list and return - Candidate grab_greatest() - { - if (m_candidates.empty()) { - return Candidate(); - } - - Candidate candidate = m_candidates.top(); - m_candidates.pop(); - return candidate; - } - - private: - std::priority_queue m_candidates; - }; - - inline void order_triangle_points(std::array& p) noexcept - { - // bubble sort - if (p[0].y > p[1].y) { - std::swap(p[0], p[1]); - } - if (p[1].y > p[2].y) { - std::swap(p[1], p[2]); - } - if (p[0].y > p[1].y) { - std::swap(p[0], p[1]); - } - } - - inline bool is_no_data(const double value, const double no_data_value) noexcept - { - return std::isnan(value) || value == no_data_value; - } - - inline void compute_plane(Plane& plane, dt_ptr t, const RasterDouble& raster) - { - const glm::dvec2& p1 = t->point1(); - const glm::dvec2& p2 = t->point2(); - const glm::dvec2& p3 = t->point3(); - - const glm::dvec3 v1(p1, raster.value(unsigned(p1.y), unsigned(p1.x))); - const glm::dvec3 v2(p2, raster.value(unsigned(p2.y), unsigned(p2.x))); - const glm::dvec3 v3(p3, raster.value(unsigned(p3.y), unsigned(p3.x))); - - plane.init(v1, v2, v3); - } - - // abstract base class for Terra and Zemlya - class TerraBaseMesh : protected DelaunayMesh { - public: - TerraBaseMesh() - : m_raster(std::make_unique()) - { - } - - void load_raster(std::unique_ptr raster); - - protected: - std::unique_ptr m_raster; - - void repair_point(unsigned px, unsigned py); - }; - -} // namespace terra -} // namespace tntn diff --git a/src/terrainlib/tntn/ZemlyaMesh.cpp b/src/terrainlib/tntn/ZemlyaMesh.cpp deleted file mode 100644 index 3c3b888..0000000 --- a/src/terrainlib/tntn/ZemlyaMesh.cpp +++ /dev/null @@ -1,375 +0,0 @@ -#include "ZemlyaMesh.h" -#include "Exception.h" -#include "DelaunayTriangle.h" -#include "SurfacePoints.h" -#include "TerraUtils.h" -#include "logging.h" -#include "raster_tools.h" - -#include -#include -#include -#include -#include - -namespace tntn { -namespace zemlya { - - static double average_of( - const double d1, const double d2, const double d3, const double d4, double no_data_value) - { - int count = 0; - double sum = 0.0; - - for (double d : { d1, d2, d3, d4 }) { - if (terra::is_no_data(d, no_data_value)) { - continue; - } - count++; - sum += d; - } - - if (count > 0) { - return sum / count; - } else { - return NAN; - } - } - - void ZemlyaMesh::greedy_insert(double max_error) - { - m_max_error = max_error; - m_counter = 0; - int w = m_raster->get_width(); - int h = m_raster->get_height(); - m_max_level = static_cast(ceil(log2(w > h ? w : h))); - - TNTN_LOG_INFO("starting greedy insertion with raster width: {}, height: {}", w, h); - - // Create another raster to store average values - m_sample.allocate(w, h); - m_sample.set_all(NAN); - - const double no_data_value = m_raster->get_no_data_value(); - - for (int level = m_max_level - 1; level >= 1; level--) { - int step = m_max_level - level; - for (int y = 0; y < h; y += pow(2, step)) { - for (int x = 0; x < w; x += pow(2, step)) { - if (step == 1) { - double v1 = y < h && x < w ? m_raster->value(y, x) : NAN; - double v2 = y < h && x + 1 < w ? m_raster->value(y, x + 1) : NAN; - double v3 = y + 1 < h && x < w ? m_raster->value(y + 1, x) : NAN; - double v4 = y + 1 < h && x + 1 < w ? m_raster->value(y + 1, x + 1) : NAN; - - if (y + 1 < h && x + 1 < w) { - m_sample.value(y + 1, x + 1) = average_of(v1, v2, v3, v4, no_data_value); - } - } else { - int co = pow(2, step - 1); // offset - int d = pow(2, step - 2); // delta - - double v1 = y + co - d < h && x + co - d < w - ? m_sample.value(y + co - d, x + co - d) - : NAN; - double v2 = y + co - d < h && x + co + d < w - ? m_sample.value(y + co - d, x + co + d) - : NAN; - double v3 = y + co + d < h && x + co - d < w - ? m_sample.value(y + co + d, x + co - d) - : NAN; - double v4 = y + co + d < h && x + co + d < w - ? m_sample.value(y + co + d, x + co + d) - : NAN; - - if (y + co < h && x + co < w) { - m_sample.value(y + co, x + co) = average_of(v1, v2, v3, v4, no_data_value); - } - } - } - } - } - - // Ensure the four corners are not NAN, otherwise the algorithm can't proceed. - this->repair_point(0, 0); - this->repair_point(0, h - 1); - this->repair_point(w - 1, h - 1); - this->repair_point(w - 1, 0); - - // Initialize m_result - m_result.allocate(w, h); - m_result.set_all(NAN); - - m_result.value(0, 0) = m_raster->value(0, 0); - m_result.value(h - 1, 0) = m_raster->value(h - 1, 0); - m_result.value(h - 1, w - 1) = m_raster->value(h - 1, w - 1); - m_result.value(0, w - 1) = m_raster->value(0, w - 1); - - // Initialize m_insert - m_insert.allocate(w, h); - m_insert.set_all(NAN); - - // Initialize m_used - m_used.allocate(w, h); - - // Initialize m_token - m_token.allocate(w, h); - m_token.set_all(0); - - // Initialize the mesh to two triangles with the height field grid corners as vertices - TNTN_LOG_INFO("initialize the mesh with four corner points"); - this->init_mesh( - glm::dvec2(0, 0), glm::dvec2(0, h - 1), glm::dvec2(w - 1, h - 1), glm::dvec2(w - 1, 0)); - - // Iterate over the levels - for (int level = 1; level <= m_max_level; level++) { - m_current_level = level; - TNTN_LOG_INFO("starting level {}", level); - - // Clear m_used - m_used.set_all(0); - - // Use points from the original raster starting from level 5 to compensate for the half-pixel offset of average values. - if (level >= 5 && level <= m_max_level - 1) { - int step = m_max_level - level; - - // Update points from previous levels - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - double& z = m_insert.value(y, x); - if (terra::is_no_data(z, no_data_value)) { - continue; - } - z = m_raster->value(y, x); - } - } - - // Add new points from this level - for (int y = 0; y < h; y += pow(2, step)) { - for (int x = 0; x < w; x += pow(2, step)) { - int co = pow(2, step - 1); // current step's offset - if (y + co < h && x + co < w) { - m_insert.value(y + co, x + co) = m_raster->value(y + co, x + co); - } - } - } - } else if (level < m_max_level) { - int step = m_max_level - level; - - // Update points from previous levels by shrinking their commanding areas - // This is crucial for transitioning from global averages to local values. - if (step >= 3) { - double d = pow(2, step - 3); // delta - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - double& z = m_insert.value(y, x); - if (terra::is_no_data(z, no_data_value)) { - continue; - } - - const double v1 = y - d < h && x - d < w ? m_sample.value(y - d, x - d) : NAN; - const double v2 = y - d < h && x + d < w ? m_sample.value(y - d, x + d) : NAN; - const double v3 = y + d < h && x - d < w ? m_sample.value(y + d, x - d) : NAN; - const double v4 = y + d < h && x + d < w ? m_sample.value(y + d, x + d) : NAN; - const double avg = average_of(v1, v2, v3, v4, no_data_value); - if (terra::is_no_data(avg, no_data_value)) { - continue; - } - z = avg; - } - } - } - - // Add new points from this level - for (int y = 0; y < h; y += pow(2, step)) { - for (int x = 0; x < w; x += pow(2, step)) { - int co = pow(2, step - 1); // current step's offset - if (y + co < h && x + co < w) { - m_insert.value(y + co, x + co) = m_sample.value(y + co, x + co); - } - } - } - } - - // Scan all the triangles and push all candidates into a stack - dt_ptr t = m_first_face; - while (t) { - scan_triangle(t); - t = t->getLink(); - } - - // Iterate until the error threshold is met - while (!m_candidates.empty()) { - terra::Candidate candidate = m_candidates.grab_greatest(); - - if (candidate.importance < m_max_error) - continue; - - // Skip if the candidate is not the latest - if (m_token.value(candidate.y, candidate.x) != candidate.token) - continue; - - m_result.value(candidate.y, candidate.x) = candidate.z; - m_used.value(candidate.y, candidate.x) = 1; - - // TNTN_LOG_DEBUG("inserting point: ({}, {}, {})", candidate.x, candidate.y, candidate.z); - this->insert(glm::dvec2(candidate.x, candidate.y), candidate.triangle); - } - } - - TNTN_LOG_INFO("finished greedy insertion"); - } - - void ZemlyaMesh::scan_triangle_line(const Plane& plane, - int y, - double x1, - double x2, - Candidate& candidate, - const double no_data_value) - { - const int startx = static_cast(ceil(fmin(x1, x2))); - const int endx = static_cast(floor(fmax(x1, x2))); - - if (startx > endx) - return; - - double z0 = plane.eval(startx, y); - const double dz = plane.a; - - for (int x = startx; x <= endx; x++) { - if (!m_used.value(y, x)) { - // attention - use m_raster/m_insert depending on level - const double z = m_current_level == m_max_level ? m_raster->value(y, x) : m_insert.value(y, x); - if (!terra::is_no_data(z, no_data_value)) { - const double diff = fabs(z - z0); - // TNTN_LOG_DEBUG("candidate consider: ({}, {}, {}), diff: {}", x, y, z, diff); - candidate.consider(x, y, z, diff); - } - } - z0 += dz; - } - } - - void ZemlyaMesh::scan_triangle(dt_ptr t) - { - throw Exception("This scan triangle method is buggy. I fixed it already for the TerraMesh, but not yet for zemlya"); - Plane z_plane; - terra::compute_plane(z_plane, t, m_result); - - std::array by_y = { { - t->point1(), - t->point2(), - t->point3(), - } }; - terra::order_triangle_points(by_y); - const double v0_x = by_y[0].x; - const double v0_y = by_y[0].y; - const double v1_x = by_y[1].x; - const double v1_y = by_y[1].y; - const double v2_x = by_y[2].x; - const double v2_y = by_y[2].y; - - terra::Candidate candidate = { 0, 0, 0.0, -DBL_MAX, m_counter++, t }; - - const double dx2 = (v2_x - v0_x) / (v2_y - v0_y); - const double no_data_value = m_raster->get_no_data_value(); - - if (v1_y != v0_y) { - const double dx1 = (v1_x - v0_x) / (v1_y - v0_y); - - double x1 = v0_x; - double x2 = v0_x; - - const int starty = v0_y; - const int endy = v1_y; - - for (int y = starty; y < endy; y++) { - scan_triangle_line(z_plane, y, x1, x2, candidate, no_data_value); - x1 += dx1; - x2 += dx2; - } - } - - if (v2_y != v1_y) { - const double dx1 = (v2_x - v1_x) / (v2_y - v1_y); - - double x1 = v1_x; - double x2 = v0_x; - - const int starty = v1_y; - const int endy = v2_y; - - for (int y = starty; y <= endy; y++) { - scan_triangle_line(z_plane, y, x1, x2, candidate, no_data_value); - x1 += dx1; - x2 += dx2; - } - } - - // We have now found the appropriate candidate point - m_token.value(candidate.y, candidate.x) = candidate.token; - - // Push the candidate into the stack - m_candidates.push_back(candidate); - } - - std::unique_ptr ZemlyaMesh::convert_to_mesh() - { - // Find all the vertices - int w = m_raster->get_width(); - int h = m_raster->get_height(); - - std::vector mvertices; - - Raster vertex_id; - vertex_id.allocate(w, h); - vertex_id.set_all(0); - - int index = 0; - const double no_data_value = m_raster->get_no_data_value(); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - const double z = m_result.value(y, x); - if (!terra::is_no_data(z, no_data_value)) { - Vertex v = Vertex({ m_raster->col2x(x), m_raster->row2y(y), z }); - mvertices.push_back(v); - vertex_id.value(y, x) = index; - index++; - } - } - } - - // Find all the faces - std::vector mfaces; - dt_ptr t = m_first_face; - while (t) { - Face f; - - glm::dvec2 p1 = t->point1(); - glm::dvec2 p2 = t->point2(); - glm::dvec2 p3 = t->point3(); - - if (!terra::ccw(p1, p2, p3)) { - f[0] = vertex_id.value((int)p1.y, (int)p1.x); - f[1] = vertex_id.value((int)p2.y, (int)p2.x); - f[2] = vertex_id.value((int)p3.y, (int)p3.x); - } else { - f[0] = vertex_id.value((int)p3.y, (int)p3.x); - f[1] = vertex_id.value((int)p2.y, (int)p2.x); - f[2] = vertex_id.value((int)p1.y, (int)p1.x); - } - - mfaces.push_back(f); - - t = t->getLink(); - } - - // now initialise our mesh class with this - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(mvertices), std::move(mfaces)); - return mesh; - } - -} // namespace zemlya -} // namespace tntn diff --git a/src/terrainlib/tntn/ZemlyaMesh.h b/src/terrainlib/tntn/ZemlyaMesh.h deleted file mode 100644 index 0c93ffd..0000000 --- a/src/terrainlib/tntn/ZemlyaMesh.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "DelaunayMesh.h" -#include "MeshIO.h" -#include "Raster.h" -#include "TerraUtils.h" -#include "geometrix.h" - -#include - -namespace tntn { -namespace zemlya { - - using dt_ptr = terra::dt_ptr; - using qe_ptr = terra::qe_ptr; - using Plane = terra::Plane; - using Point2D = terra::Point2D; - using CandidateList = terra::CandidateList; - using Candidate = terra::Candidate; - - class ZemlyaMesh : public terra::TerraBaseMesh { - private: - Raster m_sample; - Raster m_insert; - Raster m_result; - Raster m_used; - Raster m_token; - - CandidateList m_candidates; - double m_max_error = 0; - int m_counter = 0; - int m_current_level = 0; - int m_max_level = 0; - - void scan_triangle_line(const Plane& plane, - int y, - double x1, - double x2, - Candidate& candidate, - const double no_data_value); - - public: - void greedy_insert(double max_error); - - void scan_triangle(dt_ptr t) override; - std::unique_ptr convert_to_mesh(); - }; - -} // namespace zemlya -} // namespace tntn diff --git a/src/terrainlib/tntn/ZoomRange.h b/src/terrainlib/tntn/ZoomRange.h deleted file mode 100644 index fcd2415..0000000 --- a/src/terrainlib/tntn/ZoomRange.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -namespace here { -namespace tntn { - - struct ZoomRange { - int min_zoom = 0; - int max_zoom = 0; - - void normalize() - { - if (min_zoom > max_zoom) { - std::swap(min_zoom, max_zoom); - } - } - }; - -} // namespace tntn -} // namespace here diff --git a/src/terrainlib/tntn/endianness.h b/src/terrainlib/tntn/endianness.h deleted file mode 100644 index 08d2f8b..0000000 --- a/src/terrainlib/tntn/endianness.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) -#define TNTN_BIG_ENDIAN -#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) -#define TNTN_LITTLE_ENDIAN -#else -#error unknown architecture -#endif - -#if !defined(TNTN_LITTLE_ENDIAN) && !defined(TNTN_BIG_ENDIAN) -#error neither little, nor big endian, platform not supported -#endif - -namespace tntn { - -enum class Endianness { - BIG, - LITTLE, -}; - -#ifdef TNTN_BIG_ENDIAN -constexpr Endianness PLATFORM_NATIVE_ENDIANNESS = Endianness::BIG; -#else -constexpr Endianness PLATFORM_NATIVE_ENDIANNESS = Endianness::LITTLE; -#endif - -inline void flip_endianness_4byte(unsigned char* data) -{ - std::swap(data[0], data[3]); - std::swap(data[1], data[2]); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/geometrix.cpp b/src/terrainlib/tntn/geometrix.cpp deleted file mode 100644 index 57c93b3..0000000 --- a/src/terrainlib/tntn/geometrix.cpp +++ /dev/null @@ -1,724 +0,0 @@ -#include "geometrix.h" - -#include -#include - -#include - -namespace tntn { - -static bool epseq(const double a, double b, double epsilon) -{ - return fabs(a - b) < epsilon; -} - -bool triangle_semantic_equal::operator()(const Triangle& l, const Triangle& _r) const -{ - Triangle r = _r; -#if 1 - if (l == r) { - return true; - } - std::rotate(r.begin(), r.begin() + 1, r.end()); - if (l == r) { - return true; - } - std::rotate(r.begin(), r.begin() + 1, r.end()); - if (l == r) { - return true; - } - return false; -#else - // compare winding - const glm::dvec3 ln = glm::triangleNormal(l[0], l[1], l[2]); - const glm::dvec3 rn = glm::triangleNormal(r[0], r[1], r[2]); - if ((ln.x > 0 && rn.x <= 0) || (ln.y > 0 && rn.y <= 0) || (ln.z > 0 && rn.z <= 0)) { - return false; - } - - // compare point sets - for (const auto& p : l) { - bool found = false; - for (int ri = 0; ri < 3; ri++) { - if (r[ri] == p) { - r[ri].x = NAN; - r[ri].y = NAN; - r[ri].z = NAN; - found = true; - break; - } - } - - if (!found) { - return false; - } - } - - return true; -#endif -} - -static inline bool is_facing_upwards_impl(const double t0_x, - const double t0_y, - const double t1_x, - const double t1_y, - const double t2_x, - const double t2_y) -{ - // const glm::dvec3 n = glm::cross(t[0] - t[1], t[0] - t[2]); - const double n_z = (t0_x - t1_x) * (t0_y - t2_y) - (t0_x - t2_x) * (t0_y - t1_y); - return n_z >= 0; -} - -bool is_facing_upwards(const Triangle& t) -{ - const double t0_x = t[0].x; - const double t0_y = t[0].y; - - const double t1_x = t[1].x; - const double t1_y = t[1].y; - - const double t2_x = t[2].x; - const double t2_y = t[2].y; - - return is_facing_upwards_impl(t0_x, t0_y, t1_x, t1_y, t2_x, t2_y); -} - -bool is_facing_upwards(const Face& f, const std::vector& vertices) -{ - const double t0_x = vertices[f[0]].x; - const double t0_y = vertices[f[0]].y; - - const double t1_x = vertices[f[1]].x; - const double t1_y = vertices[f[1]].y; - - const double t2_x = vertices[f[2]].x; - const double t2_y = vertices[f[2]].y; - - return is_facing_upwards_impl(t0_x, t0_y, t1_x, t1_y, t2_x, t2_y); -} - -static glm::dvec2 intersect_2D_linesegment_by_line(const glm::dvec2& p0, - const glm::dvec2& p1, - const glm::dvec2& l0, - const glm::dvec2& l1) -{ - // from https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection - - const double x_1 = p0.x; - const double x_2 = p1.x; - const double x_3 = l0.x; - const double x_4 = l1.x; - - const double y_1 = p0.y; - const double y_2 = p1.y; - const double y_3 = l0.y; - const double y_4 = l1.y; - - const double denom = (x_1 - x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 - x_4); - const double eps = 0.000000001; - if (glm::abs(denom) < eps) { - return glm::dvec2(NAN, NAN); - } - - const double c_x = ((x_1 * y_2 - y_1 * x_2) * (x_3 - x_4) - (x_1 - x_2) * (x_3 * y_4 - y_3 * x_4)) / denom; - const double c_y = ((x_1 * y_2 - y_1 * x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 * y_4 - y_3 * x_4)) / denom; - - return glm::dvec2(c_x == -0.0 ? 0.0 : c_x, c_y == -0.0 ? 0.0 : c_y); -} - -bool Edge::intersects2D(const Edge& other, const std::vector& vertices) const -{ - const glm::dvec2 p0 = vertices[this->first]; - const glm::dvec2 p1 = vertices[this->second]; - - const glm::dvec2 l0 = vertices[other.first]; - const glm::dvec2 l1 = vertices[other.second]; - - const BBox2D e1_bbox(p0, p1); - const BBox2D e2_bbox(l0, l1); - - if (!e1_bbox.intersects(e2_bbox)) { - return false; - } - - const glm::dvec2 intersection_point = intersect_2D_linesegment_by_line(p0, p1, l0, l1); - if (std::isnan(intersection_point.x) || std::isnan(intersection_point.y)) { - return false; - } - - return e1_bbox.contains(intersection_point) && e2_bbox.contains(intersection_point); -} - -BBox2D::BBox2D() - : min(std::numeric_limits::infinity()) - , max(-std::numeric_limits::infinity()) -{ -} - -BBox2D::BBox2D(glm::dvec2 a, glm::dvec2 b) - : min(std::min(a.x, b.x), std::min(a.y, b.y)) - , max(std::max(a.x, b.x), std::max(a.y, b.y)) -{ -} - -BBox2D::BBox2D(glm::vec2 a, glm::vec2 b) - : BBox2D(glm::dvec2(a.x, a.y), glm::dvec2(b.x, b.y)) -{ -} - -BBox2D::BBox2D(glm::vec3 a, glm::vec3 b) - : BBox2D(glm::dvec2(a.x, a.y), glm::dvec2(b.x, b.y)) -{ -} - -BBox2D::BBox2D(glm::dvec3 a, glm::dvec3 b) - : BBox2D(xy(a), xy(b)) -{ -} - -BBox2D::BBox2D(const Triangle& t) - : BBox2D(xy(t[0]), xy(t[1])) -{ - add(xy(t[2])); -} - -void BBox2D::reset() -{ - min = glm::dvec2(std::numeric_limits::infinity()); - max = glm::dvec2(-std::numeric_limits::infinity()); -} - -void BBox2D::add(glm::vec2 p) -{ - add(glm::dvec2(p.x, p.y)); -} - -void BBox2D::add(glm::dvec2 p) -{ - min.x = std::min(min.x, p.x); - min.y = std::min(min.y, p.y); - max.x = std::max(max.x, p.x); - max.y = std::max(max.y, p.y); -} - -void BBox2D::add(glm::vec3 p) -{ - add(xy(p)); -} - -void BBox2D::add(glm::dvec3 p) -{ - add(xy(p)); -} - -void BBox2D::add(const Triangle& t) -{ - for (int i = 0; i < 3; i++) { - add(t[i]); - } -} - -void BBox2D::grow(const double delta) -{ - min.x -= delta; - min.y -= delta; - max.x += delta; - max.y += delta; -} - -bool BBox2D::intersects(const BBox2D& other, const double epsilon) const -{ - // epsilon grows both rectangles - - // https://stackoverflow.com/questions/306316/determine-if-two-rectangles-overlap-each-other - - // is this above other? - if (min.y - epsilon > other.max.y + epsilon) - return false; - - // is this below other? - if (max.y + epsilon < other.min.y - epsilon) - return false; - - // is this left of other? - if (max.x + epsilon < other.min.x - epsilon) - return false; - - // is this right of other? - if (min.x - epsilon > other.max.x + epsilon) - return false; - - // otherwise they must intersect - return true; -} - -bool BBox2D::contains(const glm::dvec2 point, const double epsilon) const -{ - return (min.x - epsilon) <= point.x && (min.y - epsilon) <= point.y && (max.x + epsilon) >= point.x && (max.y + epsilon) >= point.y; -} - -bool BBox2D::is_equal(const BBox2D& bb) const -{ - if (bb.min.x != min.x) - return false; - if (bb.min.y != min.y) - return false; - if (bb.max.x != max.x) - return false; - if (bb.max.y != max.y) - return false; - return true; -} - -bool BBox2D::is_on_border(const glm::dvec2 point, const double epsilon) const -{ - return epseq(point.x, min.x, epsilon) || epseq(point.x, max.x, epsilon) || epseq(point.y, min.y, epsilon) || epseq(point.y, max.y, epsilon); -} - -std::string BBox2D::to_string() const -{ - std::string out; - constexpr int double_str_len = 16; - out.reserve(4 * 2 + 3 + 4 * double_str_len + 1 /*to make it a even*/); - out = "[("; // 2 - out += std::to_string(min.x); // double - out += ", "; // 2 - out += std::to_string(min.y); // double - out += "),("; // 3 - out += std::to_string(max.x); // double - out += ", "; // 2 - out += std::to_string(max.y); // double - out += "])"; // 2 - return out; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -BBox3D::BBox3D() - : min(std::numeric_limits::infinity()) - , max(-std::numeric_limits::infinity()) -{ -} - -BBox3D::BBox3D(glm::dvec3 a, glm::dvec3 b) - : min(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z)) - , max(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z)) -{ -} - -BBox3D::BBox3D(const Triangle& t) - : BBox3D(t[0], t[1]) -{ - add(t[2]); -} - -void BBox3D::reset() -{ - min = glm::dvec3(std::numeric_limits::infinity()); - max = glm::dvec3(-std::numeric_limits::infinity()); -} - -void BBox3D::add(glm::dvec3 p) -{ - min.x = std::min(min.x, p.x); - min.y = std::min(min.y, p.y); - min.z = std::min(min.z, p.z); - - max.x = std::max(max.x, p.x); - max.y = std::max(max.y, p.y); - max.z = std::max(max.z, p.z); -} - -void BBox3D::add(glm::vec3 p) -{ - add(glm::dvec3(p.x, p.y, p.z)); -} - -void BBox3D::add(const Triangle& t) -{ - for (int i = 0; i < 3; i++) { - add(t[i]); - } -} - -void BBox3D::grow(const double delta) -{ - min.x -= delta; - min.y -= delta; - min.z -= delta; - - max.x += delta; - max.y += delta; - max.z += delta; -} - -bool BBox3D::contains(const glm::dvec3 point, const double epsilon) const -{ - return (min.x - epsilon) <= point.x && (min.y - epsilon) <= point.y && (min.z - epsilon) <= point.z && - - (max.x + epsilon) >= point.x && (max.y + epsilon) >= point.y && (max.z + epsilon) >= point.z; -} - -std::string BBox3D::to_string() const -{ - std::string out; - constexpr int double_str_len = 16; - out.reserve(6 * 2 + 3 + 6 * double_str_len + 1 /*to make it a even*/); - out = "[("; // 2 - out += std::to_string(min.x); // double - out += ", "; // 2 - out += std::to_string(min.y); // double - out += ", "; // 2 - out += std::to_string(min.z); // double - out += "),("; // 3 - out += std::to_string(max.x); // double - out += ", "; // 2 - out += std::to_string(max.y); // double - out += ", "; // 2 - out += std::to_string(max.z); // double - out += "])"; // 2 - return out; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static glm::dvec3 abs_zero(const glm::dvec3& v) -{ - return glm::dvec3(v.x == -0.0 ? 0.0 : v.x, v.y == -0.0 ? 0.0 : v.y, v.z == -0.0 ? 0.0 : v.z); -} - -static double squared_3D_distance(const glm::dvec3& p0, const glm::dvec3& p1) -{ - const double dx = p1.x - p0.x; - const double dy = p1.y - p0.y; - const double dz = p1.z - p0.z; - return dx * dx + dy * dy + dz * dz; -} -static double squared_2D_distance(const glm::dvec2& p0, const glm::dvec2& p1) -{ - const double dx = p1.x - p0.x; - const double dy = p1.y - p0.y; - return dx * dx + dy * dy; -} - -/** - - returns the intersection point of the 2.5D line segment p0-p1 (2D line with height in z) with the 2D line l_origin -> l_direction - - returns NaN if lines are (close to) parallel or intersection is outside the line segment p0-p1 - - */ -glm::dvec3 intersect_25D_linesegment_by_line(glm::dvec3 p0, - glm::dvec3 p1, - glm::dvec2 l_org, - glm::dvec2 l_dir) -{ - // from https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection - - const double x_1 = p0.x; - const double x_2 = p1.x; - const double x_3 = l_org.x; - const double x_4 = l_org.x + l_dir.x; - - const double y_1 = p0.y; - const double y_2 = p1.y; - const double y_3 = l_org.y; - const double y_4 = l_org.y + l_dir.y; - - const double denom = (x_1 - x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 - x_4); - const double eps = 0.000000001; - if (glm::abs(denom) < eps) { - return glm::dvec3(NAN, NAN, NAN); - } - - glm::dvec3 c; - c.x = ((x_1 * y_2 - y_1 * x_2) * (x_3 - x_4) - (x_1 - x_2) * (x_3 * y_4 - y_3 * x_4)) / denom; - c.y = ((x_1 * y_2 - y_1 * x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 * y_4 - y_3 * x_4)) / denom; - - // interpolate z - - // z = mx + n - const double d_p0p1 = glm::distance(xy(p0), xy(p1)); - const double m = (p1.z - p0.z) / d_p0p1; - const double n = p0.z; - - const double d_p0c = glm::distance(xy(p0), xy(c)); - if (d_p0c < 0.0 - eps || d_p0c > (d_p0p1 + eps)) { - return glm::dvec3(NAN, NAN, NAN); - } - - c.z = m * d_p0c + n; - return abs_zero(c); -} - -int sign_2D(const glm::dvec3& p, const glm::dvec2& l_org, const glm::dvec2& l_dir) -{ - // specialized versions using comparison - if (l_dir.x == 0.0) { - // left-right clipping - const int direction_sign = l_dir.y > 0.0 ? -1 /* upwards */ : 1 /* downwards */; - if (p.x < l_org.x) { - return direction_sign; - } else if (p.x > l_org.x) { - return -direction_sign; - } else { - return 0; - } - } else if (l_dir.y == 0.0) { - // top-bottom clipping - const int direction_sign = l_dir.x > 0 ? -1 /* right-wards */ : 1 /* left-wards */; - if (p.y < l_org.y) { - return -direction_sign; - } else if (p.y > l_org.y) { - return direction_sign; - } else { - return 0; - } - } else { - // generic version using cross product - const double d = (p.x - l_org.x) * (l_dir.y) - (p.y - l_org.y) * (l_dir.x); - const double eps = 0.000000001; - if (d < eps) { - return -1; - } else if (d > eps) { - return 1; - } else { - return 0; - } - } -} - -int compare_length(const glm::dvec3& a1, - const glm::dvec3& a2, - const glm::dvec3& b1, - const glm::dvec3& b2) -{ - const double da_sq = squared_3D_distance(a1, a2); - const double db_sq = squared_3D_distance(b1, b2); - - if (da_sq < db_sq) { - return -1; - } else if (da_sq == db_sq) { - return 0; - } else { - return 1; - } -} - -int compare_length(const glm::dvec2& a1, - const glm::dvec2& a2, - const glm::dvec2& b1, - const glm::dvec2& b2) -{ - const double da_sq = squared_2D_distance(a1, a2); - const double db_sq = squared_2D_distance(b1, b2); - - if (da_sq < db_sq) { - return -1; - } else if (da_sq == db_sq) { - return 0; - } else { - return 1; - } -} - -static bool has_NaNs(const Triangle& t) -{ -#if 1 - int num_nans = 0; - for (int i = 0; i < 3; i++) { - for (int k = 0; k < 3; k++) { - num_nans += std::isnan(t[i][k]); - } - } - return num_nans != 0; -#else - for (int i = 0; i < 3; i++) { - if (std::isnan(t[i].x) || std::isnan(t[i].y) || std::isnan(t[i].z)) { - return true; - } - } - return false; -#endif -} - -static inline bool is_front_facing(const Triangle& t) -{ -#if 0 - //const glm::dvec3 n = glm::triangleNormal(t[0], t[1], t[2]); - const glm::dvec3 n = glm::cross(t[0] - t[1], t[0] - t[2]); - return n.z >= 0; -#else - const double t0_x = t[0].x; - const double t0_y = t[0].y; - const double n_z = (t0_x - t[1].x) * (t0_y - t[2].y) - (t0_x - t[2].x) * (t0_y - t[1].y); - return n_z >= 0; -#endif -} - -void make_front_facing(Triangle& t) -{ - if (!is_front_facing(t)) { - std::swap(t[0], t[1]); - } -} - -void clip_25D_triangle_by_line(std::vector& tv, - size_t triangle_idx, - glm::dvec2 l_org, - glm::dvec2 l_dir) -{ - Triangle& t = tv[triangle_idx]; - // ignore NAN triangles: - if (has_NaNs(t)) { - return; - } - - /* - - lp - left_points - op - other_points - - winding order counter-clockwise = inside - + - /| - / | - / | - / | - / | - / | - / | - / | - / | - / | - l1 s0/ |s1 l0 - x----*-----------*-------x - / | - / | -lp[0] + | - \ | - \ | - \ | - \ | - \ | - \ | - \ | - + lp[1] - - */ - - // calculate the points which are right of the clip-line - std::array left_points; - std::array other_points; - std::array other_signs; - int num_left_points = 0; - int num_other_points = 0; - - for (const auto& point : t) { - const int d = sign_2D(point, l_org, l_dir); - if (d < 0) { - left_points[num_left_points] = point; - num_left_points++; - } else { - other_points[num_other_points] = point; - other_signs[num_other_points] = d; - num_other_points++; - } - } - - if (num_left_points == 0) { - // mark triangle for later removal (make it invalid) - t[0] = glm::dvec3(NAN, NAN, NAN); - // t[1] = glm::dvec3(NAN, NAN, NAN); - // t[2] = glm::dvec3(NAN, NAN, NAN); - } else if (num_left_points == 1) { - assert(num_other_points == 2); - // intersect adjacent edges with line - // use original point when the point is exactly on the clib-line - const glm::dvec3 s0 = other_signs[0] == 0 - ? other_points[0] - : intersect_25D_linesegment_by_line(left_points[0], other_points[0], l_org, l_dir); - const glm::dvec3 s1 = other_signs[1] == 0 - ? other_points[1] - : intersect_25D_linesegment_by_line(left_points[0], other_points[1], l_org, l_dir); - - // replace triangle t with new triangle - t[0] = left_points[0]; - t[1] = s0; - t[2] = s1; - make_front_facing(t); - } else if (num_left_points == 2) { - assert(num_other_points == 1); - if (other_signs[0] == 0) { - // other point is exactly on clib-line, keep original triangle - return; - } - - const glm::dvec3 s0 = intersect_25D_linesegment_by_line(other_points[0], left_points[0], l_org, l_dir); - const glm::dvec3 s1 = intersect_25D_linesegment_by_line(other_points[0], left_points[1], l_org, l_dir); - - // determine the shorter of the two possible new edges - // const double d0 = glm::distance(s0, left_points[1]); - // const double d1 = glm::distance(s1, left_points[0]); - const int d0_d1_cmp = compare_length(s0, left_points[1], s1, left_points[0]); - - // replace triangle t with new triangle - // and construct a new second new triangle - // the new edge is selected to be the shorter of the two possible ones - - t[0] = d0_d1_cmp >= 0 ? s1 : s0; - t[1] = left_points[0]; - t[2] = left_points[1]; - - Triangle t_new = { { s1, s0, d0_d1_cmp >= 0 ? left_points[0] : left_points[1] } }; - - make_front_facing(t); - make_front_facing(t_new); - tv.push_back(t_new); - } - - return; -} - -void clip_25D_triangles_to_01_quadrant(std::vector& tv) -{ - - /* - (0,1) (1,1) - +---+ - | | //winding order: counter-clock-wise = inside - +---+ - (0,0) (1,0) - */ - - size_t tv_size = tv.size(); - for (size_t i = 0; i < tv_size; i++) { - // clip at bottom edge - right-wards line - clip_25D_triangle_by_line(tv, i, { 0, 0 }, { 1, 0 }); - } - - tv_size = tv.size(); - for (size_t i = 0; i < tv_size; i++) { - // clip at right edge - upwards line - clip_25D_triangle_by_line(tv, i, { 1, 0 }, { 0, 1 }); - } - - tv_size = tv.size(); - for (size_t i = 0; i < tv_size; i++) { - // clip at top edge - leftwards line - clip_25D_triangle_by_line(tv, i, { 1, 1 }, { -1, 0 }); - } - - tv_size = tv.size(); - for (size_t i = 0; i < tv_size; i++) { - // clip at left edge - downwards line - clip_25D_triangle_by_line(tv, i, { 0, 1 }, { 0, -1 }); - } - - // filter out NaN triangles - tv.erase(std::remove_if(tv.begin(), tv.end(), [](const Triangle& t) { return has_NaNs(t); }), - tv.end()); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/geometrix.h b/src/terrainlib/tntn/geometrix.h deleted file mode 100644 index f7db74d..0000000 --- a/src/terrainlib/tntn/geometrix.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "util.h" - -#include - -namespace tntn { - -typedef glm::dvec3 Vertex; -typedef std::array Triangle; - -typedef size_t VertexIndex; // 0-based index into an array/vector of vertices -typedef std::array Face; - -struct Edge { - Edge() = default; - Edge(const Edge& other) = default; - - Edge(const VertexIndex a, const VertexIndex b) - : first(std::min(a, b)) - , second(std::max(a, b)) - { - } - Edge& operator=(const std::pair& other) - { - assign(other.first, other.second); - return *this; - } - Edge& operator=(const Edge& other) = default; - - bool operator==(const Edge& other) const - { - return first == other.first && second == other.second; - } - bool operator!=(const Edge& other) const - { - return first != other.first || second != other.second; - } - - void assign(const VertexIndex a, const VertexIndex b) - { - first = std::min(a, b); - second = std::max(a, b); - } - - bool shares_point(const Edge& other) const - { - return this->first == other.first || this->first == other.second || this->second == other.first || this->second == other.second; - } - - bool intersects2D(const Edge& other, const std::vector& vertices) const; - - VertexIndex first; - VertexIndex second; -}; - -// for sorting vertices -template > -struct vertex_compare { - bool operator()(const Vertex& left, const Vertex& right) const - { - CompareT compare; - for (int i = 0; i < 3; i++) { - if (compare(left[i], right[i])) { - return true; - } else if (compare(right[i], left[i])) { - return false; - } - } - return false; - } -}; - -// for sorting triangles -template > -struct triangle_compare { - bool operator()(Triangle left, Triangle right) const - { - vertex_compare compare; - for (int i = 0; i < 3; i++) { - if (compare(left[i], right[i])) { - return true; - } else if (compare(right[i], left[i])) { - return false; - } - } - return false; - } -}; - -/** - semantic comparison of triangles - - two triangles are equal if they are built from the same set of vertices and - their normals are facing into the same direction -*/ -struct triangle_semantic_equal { - bool operator()(const Triangle& l, const Triangle& _r) const; -}; - -bool is_facing_upwards(const Triangle& t); -bool is_facing_upwards(const Face& f, const std::vector& vertices); - -struct BBox2D { - static constexpr double eps = 0.000000001; - - BBox2D(); - BBox2D(glm::vec2 a, glm::vec2 b); - BBox2D(glm::dvec2 a, glm::dvec2 b); - BBox2D(glm::vec3 a, glm::vec3 b); - BBox2D(glm::dvec3 a, glm::dvec3 b); - BBox2D(const Triangle& t); - - void reset(); - - void add(glm::vec2 point); - void add(glm::dvec2 point); - void add(glm::vec3 point); - void add(glm::dvec3 point); - void add(const Triangle& t); - - void grow(const double delta); - - template - void add(Iterator begin, const Iterator end) - { - std::for_each(begin, end, [this](const auto& v) { add(v); }); - } - - bool intersects(const BBox2D& other, const double epsilon = eps) const; - bool contains(const glm::dvec2 point, const double epsilon = eps) const; - bool is_equal(const BBox2D& bb) const; - bool is_on_border(const glm::dvec2 point, const double epsilon = eps) const; - std::string to_string() const; - - glm::dvec2 min = { 0, 0 }; - glm::dvec2 max = { 0, 0 }; -}; - -struct BBox3D { - static constexpr double eps = 0.000000001; - - BBox3D(); - BBox3D(glm::dvec3 a, glm::dvec3 b); - BBox3D(const Triangle& t); - - void reset(); - - BBox2D to2D() const { return BBox2D(min, max); } - - void add(glm::vec3 point); - void add(glm::dvec3 point); - void add(const Triangle& t); - - void grow(const double delta); - - template - void add(Iterator begin, const Iterator end) - { - std::for_each(begin, end, [this](const auto& v) { add(v); }); - } - - bool contains(const glm::dvec3 point, const double epsilon = eps) const; - - std::string to_string() const; - - glm::dvec3 min; - glm::dvec3 max; -}; - -void clip_25D_triangles_to_01_quadrant(std::vector& tv); - -} // namespace tntn - -namespace std { - -// for using Vertex as a key in unordered_map or unordered_set -template <> -struct hash<::tntn::Vertex> { - std::size_t operator()(const ::tntn::Vertex& v) const - { - size_t seed = 0; - for (int i = 0; i < 3; i++) { - ::tntn::hash_combine(seed, v[i]); - } - return seed; - } -}; - -// for using Edge as a key in unordered_map or unordered_set -template <> -struct hash<::tntn::Edge> { - std::size_t operator()(const ::tntn::Edge& e) const - { - size_t seed = 0; - ::tntn::hash_combine(seed, e.first); - ::tntn::hash_combine(seed, e.second); - return seed; - } -}; - -} // namespace std diff --git a/src/terrainlib/tntn/logging.cpp b/src/terrainlib/tntn/logging.cpp deleted file mode 100644 index e8031be..0000000 --- a/src/terrainlib/tntn/logging.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "logging.h" - -#include -#include - -namespace tntn { - -#if (defined(DEBUG) || defined(TNTN_DEBUG)) && !defined(NDEBUG) -constexpr LogLevel GLOBAL_DEFAULT_LOG_LEVEL = LogLevel::DEBUG; -#else -constexpr LogLevel GLOBAL_DEFAULT_LOG_LEVEL = LogLevel::INFO; -#endif - -static std::atomic g_global_log_level = { GLOBAL_DEFAULT_LOG_LEVEL }; -static std::atomic g_global_log_stream = { LogStream::STDERR }; - -void log_set_global_logstream(LogStream ls) -{ - g_global_log_stream = ls; -} - -void log_set_global_level(LogLevel lvl) -{ - g_global_log_level = lvl; -} - -LogLevel log_get_global_level() -{ - return g_global_log_level; -} - -LogLevel log_decrease_global_level() -{ - LogLevel l = g_global_log_level; - int li = static_cast(l); - - if (li > 0) { - li--; - l = static_cast(li); - g_global_log_level = l; - } - return l; -} - -static const char* loglevel_to_str(const LogLevel lvl) -{ - switch (lvl) { - case LogLevel::TRACE: - return "TRACE"; - case LogLevel::DEBUG: - return "DEBUG"; - case LogLevel::INFO: - return "INFO"; - case LogLevel::WARN: - return "WARN"; - case LogLevel::ERROR: - return "ERROR"; - case LogLevel::FATAL: - return "FATAL"; - default: - return ""; - } -} - -void log_message(LogLevel lvl, const char* filename, const int line, const std::string& message) -{ - const LogLevel global_lvl = g_global_log_level; - const LogStream global_ls = g_global_log_stream; - - std::FILE* const log_stream = global_ls == LogStream::STDOUT - ? stdout - : (global_ls == LogStream::STDERR ? stderr : nullptr); - - if (global_lvl <= lvl && !message.empty() && log_stream) { - if (lvl == LogLevel::INFO) { - std::fprintf(log_stream, "%s\n", message.c_str()); - } else { - const char* filename_last_component = strrchr(filename, '/'); - if (filename_last_component) { - filename = filename_last_component + 1; - } - std::fprintf(log_stream, - "%s %s:%d %s\n", - loglevel_to_str(lvl), - filename, - line, - message.c_str()); - } - std::fflush(log_stream); - } -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/logging.h b/src/terrainlib/tntn/logging.h deleted file mode 100644 index ca13145..0000000 --- a/src/terrainlib/tntn/logging.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include - -namespace tntn { -enum class LogLevel { - TRACE = 0, - DEBUG = 1, - INFO = 2, - WARN = 3, - ERROR = 4, - FATAL = 5, -}; - -enum class LogStream { - NONE, - STDOUT, - STDERR, -}; - -void log_set_global_logstream(LogStream ls); -void log_set_global_level(LogLevel lvl); -LogLevel log_get_global_level(); -LogLevel log_decrease_global_level(); -void log_message(LogLevel lvl, const char* filename, const int line, const std::string& message); - -} // namespace tntn - -// trace log messages are fully disabled in non-debug builds to not interfere with performance sensitive code -#ifdef TNTN_DEBUG -#define TNTN_LOG_TRACE(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::TRACE, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) -#else -#define TNTN_LOG_TRACE(fmtstr, ...) -#endif - -#define TNTN_LOG_DEBUG(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::DEBUG, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) -#define TNTN_LOG_INFO(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::INFO, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) -#define TNTN_LOG_WARN(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::WARN, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) -#define TNTN_LOG_ERROR(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::ERROR, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) -#define TNTN_LOG_FATAL(fmtstr, ...) \ - ::tntn::log_message( \ - ::tntn::LogLevel::FATAL, __FILE__, __LINE__, ::fmt::format(fmtstr, ##__VA_ARGS__)) diff --git a/src/terrainlib/tntn/raster_tools.cpp b/src/terrainlib/tntn/raster_tools.cpp deleted file mode 100644 index e3bb6ca..0000000 --- a/src/terrainlib/tntn/raster_tools.cpp +++ /dev/null @@ -1,276 +0,0 @@ -#include "raster_tools.h" -#include -#include - -#include -#include - -namespace tntn { -/** downsample image by an integer factor - takes the mean of all pixels in a window_size by window_size sub window - @param src - source raster image - @param window_size - factor to downsample by (will truncate output size to nearest integer) - @return downsampled raster image - */ -RasterDouble raster_tools::integer_downsample_mean(const RasterDouble& src, int win) -{ - int w = src.get_width(); - int h = src.get_height(); - - int ws = w / win; - int hs = h / win; - - double ndv = src.get_no_data_value(); - - RasterDouble dst(ws, hs); - - dst.copy_parameters(src); - dst.set_cell_width(src.get_cell_width() * win); - dst.set_cell_height(src.get_cell_height() * win); - dst.set_all(ndv); - - for (int rs = 0; rs < hs; rs++) { - for (int cs = 0; cs < ws; cs++) { - int count = 0; - double sum = 0; - - for (int i = 0; i < win; i++) { - for (int j = 0; j < win; j++) { - double sv = src.value(rs * win + i, cs * win + j); - - if (sv != ndv) { - sum += src.value(rs * win + i, cs * win + j); - count++; - } - } - } - - if (count == 0) - dst.value(rs, cs) = ndv; - else if (sum > 0) - dst.value(rs, cs) = sum / (double)(count); - } - } - - return dst; -} - -void raster_tools::flip_data_x(RasterDouble& raster) -{ - const int height = raster.get_height(); - const int width = raster.get_width(); - - for (int row = 0; row < height; row++) { - double* begin = raster.get_ptr(row); - double* end = begin + width; - std::reverse(begin, end); - } -} - -void raster_tools::flip_data_y(RasterDouble& raster) -{ - int row = 0; - const int height = raster.get_height(); - const int width = raster.get_width(); - const int half_height = height / 2; - - while (row < half_height) { - double* a_begin = raster.get_ptr(row); - double* a_end = a_begin + width; - double* b_begin = raster.get_ptr_ll(row); - - std::swap_ranges(a_begin, a_end, b_begin); - row++; - } -} - -/** - Treat raster as a DEM and return 3D bounding box - - @return 3d bounding box - */ -BBox3D raster_tools::get_bounding_box3d(const RasterDouble& raster) -{ - auto bbox2d = raster.get_bounding_box(); - - auto [min_height, max_height] = std::ranges::minmax(raster); - - BBox3D bbox3d; - bbox3d.min = { bbox2d.min.x, bbox2d.min.y, min_height }; - bbox3d.max = { bbox2d.max.x, bbox2d.max.y, max_height }; - - return bbox3d; -} - -static inline bool is_no_data(const double z, const double no_data_value) -{ - return z == no_data_value || std::isnan(z); -} - -template -static inline double average_nan_arr(const std::array& to_average) -{ - double sum = 0; - int avg_count = 0; - for (int i = 0; i < Size; i++) { - const double v = to_average[i]; - if (!std::isnan(v)) { - sum += v; - avg_count++; - } - } - if (avg_count == 0) { - return NAN; - } - return sum / avg_count; -} - -static inline double safe_get_pixel( - const RasterDouble& src, const int64_t w, const int64_t h, const int64_t r, const int64_t c) -{ - return r >= 0 && r < h && c >= 0 && c < w ? src.value(r, c) : NAN; -} - -static double subsample_raster_3x3(const RasterDouble& src, - const double no_data_value, - const int64_t w, - const int64_t h, - const int64_t r, - const int64_t c) -{ - - double center_pixel; - std::array cross_pixels; // weight = 0.35 - std::array diag_pixels; // weight = 0.15 - - diag_pixels[0] = safe_get_pixel(src, w, h, r - 1, c - 1); // top-left - cross_pixels[0] = safe_get_pixel(src, w, h, r - 1, c); // top - diag_pixels[1] = safe_get_pixel(src, w, h, r - 1, c + 1); // top-right - cross_pixels[1] = safe_get_pixel(src, w, h, r, c - 1); // center-left - center_pixel = safe_get_pixel(src, w, h, r, c); // center-center - cross_pixels[2] = safe_get_pixel(src, w, h, r, c + 1); // center-right - diag_pixels[2] = safe_get_pixel(src, w, h, r + 1, c - 1); // bottom-left - cross_pixels[3] = safe_get_pixel(src, w, h, r + 1, c); // bottom-center - diag_pixels[3] = safe_get_pixel(src, w, h, r + 1, c + 1); // bottom-right - - // replace no_data_value with NAN - center_pixel = center_pixel == no_data_value ? NAN : center_pixel; - for (int i = 0; i < 4; i++) { - if (diag_pixels[i] == no_data_value) { - diag_pixels[i] = NAN; - } - if (cross_pixels[i] == no_data_value) { - cross_pixels[i] = NAN; - } - } - - const double cross_avg = average_nan_arr(cross_pixels); - const double diag_avg = average_nan_arr(diag_pixels); - - const std::array weighted = { { - center_pixel, - center_pixel, - center_pixel, - cross_avg, - cross_avg, - diag_avg, - } }; - const double weighted_avg = average_nan_arr(weighted); - return weighted_avg; -} - -static constexpr int MAX_AVERAGING_SAMPLES = 64; - -static inline double average(const std::array& to_average, - const int avg_count) -{ - if (avg_count == 0) { - return NAN; - } - double sum = 0; - for (int i = 0; i < MAX_AVERAGING_SAMPLES; i++) { - sum += to_average[i]; - } - const double avg = sum / avg_count; - return avg; -} - -double raster_tools::sample_nearest_valid_avg(const RasterDouble& src, - const unsigned int _row, - const unsigned int _column, - int min_averaging_samples) -{ - min_averaging_samples = std::min(min_averaging_samples, MAX_AVERAGING_SAMPLES); - - const int64_t row = _row; - const int64_t column = _column; - const int64_t w = src.get_width(); - const int64_t h = src.get_height(); - const int64_t max_radius = static_cast(std::sqrt(w * w + h * h)); - const auto no_data_value = src.get_no_data_value(); - - double z = 0; - if (row < h && column < w) { - // valid coordinate - z = src.value(row, column); - } - if (!is_no_data(z, no_data_value)) { - return z; - } - - std::array to_average; - std::fill(to_average.begin(), to_average.end(), 0.0); - int avg_count = 0; - - auto putpixel = [row, column, w, h, no_data_value, &src, &to_average, &avg_count](int x, - int y) { - const int64_t dest_r = row + y; - const int64_t dest_c = column + x; - double z = subsample_raster_3x3(src, no_data_value, w, h, dest_r, dest_c); - if (!is_no_data(z, no_data_value)) { - to_average[avg_count] = z; - avg_count++; - } - }; - - for (int64_t radius = 2; radius <= max_radius && avg_count < min_averaging_samples; radius++) { - - int64_t x = radius - 1; - int64_t y = 0; - int64_t dx = 1; - int64_t dy = 1; - int64_t err = dx - (radius / 2); - - while (x >= y) { - putpixel(x, y); - putpixel(y, x); - putpixel(-y, x); - putpixel(-x, y); - putpixel(-x, -y); - putpixel(-y, -x); - putpixel(y, -x); - putpixel(x, -y); - - if (err <= 0) { - y++; - err += dy; - dy += 2; - } else - // if (err > 0) - { - x--; - dx += 2; - err += dx - (radius / 2); - } - } - } - - // short path for only one sample - if (avg_count == 1) { - return to_average[0]; - } - - return average(to_average, avg_count); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/raster_tools.h b/src/terrainlib/tntn/raster_tools.h deleted file mode 100644 index c997a5d..0000000 --- a/src/terrainlib/tntn/raster_tools.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "Raster.h" -#include "geometrix.h" -#include -#include - -namespace tntn { - -namespace raster_tools { - RasterDouble integer_downsample_mean(const RasterDouble& src, int window_size); - - void flip_data_x(RasterDouble& r); - - void flip_data_y(RasterDouble& r); - - void find_minmax(const RasterDouble& raster, double& min, double& max); - - BBox3D get_bounding_box3d(const RasterDouble& raster); - - double sample_nearest_valid_avg(const RasterDouble& src, - const unsigned int row, - const unsigned int column, - int min_averaging_samples = 1); -}; - -} // namespace tntn diff --git a/src/terrainlib/tntn/simple_meshing.cpp b/src/terrainlib/tntn/simple_meshing.cpp deleted file mode 100644 index fee93c1..0000000 --- a/src/terrainlib/tntn/simple_meshing.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "simple_meshing.h" -#include "Exception.h" -#include "MeshIO.h" -#include "Points2Mesh.h" -#include "RasterIO.h" -#include "SurfacePoints.h" -#include "logging.h" -#include "raster_tools.h" -#include "tntn_assert.h" - -#if defined(TNTN_USE_ADDONS) && TNTN_USE_ADDONS -#include "Raster2Mesh.h" -#endif - -namespace tntn { - -std::unique_ptr generate_tin_curvature(const RasterDouble& raster, double threshold) -{ -#if defined(TNTN_USE_ADDONS) && TNTN_USE_ADDONS - TNTN_LOG_INFO("curvature point reduction..."); - - Raster2Mesh cur(threshold); - std::vector verList = cur.generate_vertices(raster); - - TNTN_LOG_INFO("delaunay meshing of {} points", verList.size()); - std::unique_ptr pMesh = generate_delaunay_mesh(std::move(verList)); - - TNTN_LOG_INFO("done"); - - return pMesh; -#else - TNTN_LOG_ERROR("curvature point reduction not available"); - return std::make_unique(); -#endif -} - -static void dense_quadwalk_make_face(const size_t this_vx_index, - const size_t vertices_per_row, - std::vector& faces) -{ - /* - +--+ upper-right - |\A| - |B\| - +--+ lower-right - */ - // remember: ccw order - // Face A - Face f; - f[0] = this_vx_index; // lower-right - f[1] = this_vx_index - vertices_per_row; // upper-right - f[2] = this_vx_index - vertices_per_row - 1; // upper-left - faces.push_back(f); - - // Face B - f[0] = this_vx_index; // lower-right - f[1] = this_vx_index - vertices_per_row - 1; // upper-left - f[2] = this_vx_index - 1; // lower-left - faces.push_back(f); -} - -static void dense_quadwalk_make_quads_for_row(const RasterDouble& raster, - const int r, - const int w, - const double step, - const int vx_r, - const int vertices_per_row, - std::vector& vertices, - std::vector& faces) -{ - const double* const row_ptr = raster.get_ptr(r); - const double y = raster.row2y(r); - - // first column, only insert vertex - { - double z = row_ptr[0]; - if (raster.is_no_data(z) || std::isnan(z)) { - z = raster_tools::sample_nearest_valid_avg(raster, r, 0); - } - vertices.push_back({ raster.col2x(0), y, z }); - } - - // every following column, insert vertex and 2 faces - for (int vx_c = 1; vx_c < vertices_per_row; vx_c++) { - const int c = std::min(int(vx_c * step), w - 1); - - double z = row_ptr[c]; - if (raster.is_no_data(z) || std::isnan(z)) { - z = raster_tools::sample_nearest_valid_avg(raster, r, c); - } - vertices.push_back({ raster.col2x(c), y, z }); - const size_t this_vx_index = vx_r * vertices_per_row + vx_c; - dense_quadwalk_make_face(this_vx_index, vertices_per_row, faces); - } -} - -std::unique_ptr generate_tin_dense_quadwalk(const RasterDouble& raster, int step) -{ - TNTN_ASSERT(step > 0); - if (step <= 0) { - TNTN_LOG_ERROR("step width for dense meshing must be at least 1"); - return std::unique_ptr(); - } - const int h = raster.get_height(); - const int w = raster.get_width(); - if (h < 2 || w < 2) { - TNTN_LOG_ERROR("raster to small, must have at least 2x2 cells"); - return std::make_unique(); - } - - const int vertices_per_column = (h - 1) / step + ((h - 1) % step ? 1 : 0) + 1; - const int vertices_per_row = (w - 1) / step + ((w - 1) % step ? 1 : 0) + 1; - TNTN_LOG_DEBUG( - "generating regular mesh with {}x{} vertices...", vertices_per_row, vertices_per_column); - TNTN_ASSERT(vertices_per_column >= 2); - TNTN_ASSERT(vertices_per_row >= 2); - - std::vector vertices; - vertices.reserve(vertices_per_row * vertices_per_column); - std::vector faces; - faces.reserve((vertices_per_row - 1) * (vertices_per_column - 1) * 2); - - // first row, just generate vertices - { - const double* const row_ptr = raster.get_ptr(0); - const double y = raster.row2y(0); - - for (int vx_c = 0; vx_c < vertices_per_row; vx_c++) { - const int c = std::min(vx_c * step, w - 1); - double z = row_ptr[c]; - if (raster.is_no_data(z) || std::isnan(z)) { - z = raster_tools::sample_nearest_valid_avg(raster, 0, c); - } - vertices.push_back({ raster.col2x(c), y, z }); - } - } - - // every following row, generate vertices and faces - for (int vx_r = 1; vx_r < vertices_per_column; vx_r++) { - const int r = std::min(vx_r * step, h - 1); - dense_quadwalk_make_quads_for_row( - raster, r, w, step, vx_r, vertices_per_row, vertices, faces); - } - - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(vertices), std::move(faces)); - return mesh; -} - -std::unique_ptr generate_tin_dense_quadwalk(const RasterDouble& raster, unsigned vertices_per_column, unsigned vertices_per_row) -{ - TNTN_ASSERT(vertices_per_column > 1); - TNTN_ASSERT(vertices_per_row > 1); - if (vertices_per_column < 2 || vertices_per_row < 2) { - throw Exception("number of vertices must be at least 2"); - } - const int h = raster.get_height(); - const int w = raster.get_width(); - if (h < 2 || w < 2) { - TNTN_LOG_ERROR("raster to small, must have at least 2x2 cells"); - return std::make_unique(); - } - const auto step_x = (w - 1.0) / (vertices_per_column - 1.0); - const auto step_y = (h - 1.0) / (vertices_per_column - 1.0); - - TNTN_LOG_DEBUG( - "generating regular mesh with {}x{} vertices...", vertices_per_row, vertices_per_column); - TNTN_ASSERT(vertices_per_column >= 2); - TNTN_ASSERT(vertices_per_row >= 2); - - std::vector vertices; - vertices.reserve(vertices_per_row * vertices_per_column); - std::vector faces; - faces.reserve((vertices_per_row - 1) * (vertices_per_column - 1) * 2); - - // first row, just generate vertices - { - const double* const row_ptr = raster.get_ptr(0); - const double y = raster.row2y(0); - - for (int vx_c = 0; vx_c < vertices_per_row; vx_c++) { - const int c = std::min(int(vx_c * step_x), w - 1); - double z = row_ptr[c]; - if (raster.is_no_data(z) || std::isnan(z)) { - z = raster_tools::sample_nearest_valid_avg(raster, 0, c); - } - vertices.push_back({ raster.col2x(c), y, z }); - } - } - - // every following row, generate vertices and faces - for (int vx_r = 1; vx_r < vertices_per_column; vx_r++) { - const int r = std::min(int(vx_r * step_y), h - 1); - dense_quadwalk_make_quads_for_row(raster, r, w, step_x, vx_r, vertices_per_row, vertices, faces); - } - - auto mesh = std::make_unique(); - mesh->from_decomposed(std::move(vertices), std::move(faces)); - return mesh; -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/simple_meshing.h b/src/terrainlib/tntn/simple_meshing.h deleted file mode 100644 index 731f6fa..0000000 --- a/src/terrainlib/tntn/simple_meshing.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "Mesh.h" -#include "Raster.h" - -namespace tntn { - -std::unique_ptr generate_tin_curvature(const RasterDouble& raster, double threshold); -std::unique_ptr generate_tin_dense_quadwalk(const RasterDouble& raster, int step = 1); -std::unique_ptr generate_tin_dense_quadwalk(const RasterDouble& raster, unsigned vertices_per_column, unsigned vertices_per_row); - -} // namespace tntn diff --git a/src/terrainlib/tntn/terra_meshing.cpp b/src/terrainlib/tntn/terra_meshing.cpp deleted file mode 100644 index 68155ca..0000000 --- a/src/terrainlib/tntn/terra_meshing.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "terra_meshing.h" -#include "MeshIO.h" -#include "TerraMesh.h" -#include "tntn_assert.h" - -namespace tntn { - -std::unique_ptr generate_tin_terra(std::unique_ptr raster, double max_error) -{ - TNTN_ASSERT(raster != nullptr); - terra::TerraMesh g; - g.load_raster(std::move(raster)); - g.greedy_insert(max_error); - return g.convert_to_mesh(); -} - -std::unique_ptr generate_tin_terra(std::unique_ptr surface_points, - double max_error) -{ - auto raster = surface_points->to_raster(); - surface_points.reset(); - - terra::TerraMesh g; - g.load_raster(std::move(raster)); - g.greedy_insert(max_error); - return g.convert_to_mesh(); -} - -std::unique_ptr generate_tin_terra(const SurfacePoints& surface_points, double max_error) -{ - auto raster = surface_points.to_raster(); - - terra::TerraMesh g; - g.load_raster(std::move(raster)); - g.greedy_insert(max_error); - return g.convert_to_mesh(); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/terra_meshing.h b/src/terrainlib/tntn/terra_meshing.h deleted file mode 100644 index 222623b..0000000 --- a/src/terrainlib/tntn/terra_meshing.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Mesh.h" -#include "Raster.h" -#include "SurfacePoints.h" - -#include - -namespace tntn { - -std::unique_ptr generate_tin_terra(std::unique_ptr raster, double max_error); - -std::unique_ptr generate_tin_terra(std::unique_ptr surface_points, - double max_error); -std::unique_ptr generate_tin_terra(const SurfacePoints& surface_points, double max_error); - -} // namespace tntn diff --git a/src/terrainlib/tntn/tntn_assert.h b/src/terrainlib/tntn/tntn_assert.h deleted file mode 100644 index 781ffd3..0000000 --- a/src/terrainlib/tntn/tntn_assert.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -#if !defined(TNTN_ASSERT_ACTIVE) -#if (defined(DEBUG) || defined(TNTN_DEBUG)) && !defined(NDEBUG) -#define TNTN_ASSERT_ACTIVE 1 -#else -#define TNTN_ASSERT_ACTIVE 0 -#endif -#endif - -#if TNTN_ASSERT_ACTIVE -#define TNTN_ASSERT(x) assert(x) -#else -#define TNTN_ASSERT(x) -#endif diff --git a/src/terrainlib/tntn/util.cpp b/src/terrainlib/tntn/util.cpp deleted file mode 100644 index cb7dcab..0000000 --- a/src/terrainlib/tntn/util.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "util.h" -#include - -namespace tntn { - -static bool is_delimiter(const char c, const char* delimiters, const size_t num_delimiters) -{ - for (size_t i = 0; i < num_delimiters; i++) { - if (c == delimiters[i]) { - return true; - } - } - return false; -} - -static void tokenize_impl(const char* s, - const size_t s_size, - std::vector& out_tokens, - const char* delimiters) -{ - const char default_delimiters[] = " \n\r\t\0"; - size_t num_delimiters = 0; - if (!delimiters) { - delimiters = default_delimiters; - num_delimiters = sizeof(default_delimiters) - 1; - } else { - num_delimiters = std::strlen(delimiters); - } - - out_tokens.clear(); - - std::string token; - size_t pos = 0; - -state_in_space_label: - for (; pos < s_size; pos++) { - const char c = s[pos]; - if (is_delimiter(c, delimiters, num_delimiters)) { - continue; - } else { - // switch to token state - goto state_in_token_label; - } - } - -state_in_token_label: - for (; pos < s_size; pos++) { - const char c = s[pos]; - if (is_delimiter(c, delimiters, num_delimiters)) { - // swith to delimiter state, push token to output container - if (!token.empty()) { - out_tokens.push_back(std::move(token)); - } - token.clear(); - goto state_in_space_label; - } else { - // store char in temporary token - token.push_back(c); - } - } - - // also store last token - if (!token.empty()) { - out_tokens.push_back(std::move(token)); - } -} - -void tokenize(const std::string& s, std::vector& out_tokens, const char* delimiters) -{ - tokenize_impl(s.c_str(), s.size(), out_tokens, delimiters); -} - -void tokenize(const char* s, - size_t s_size, - std::vector& out_tokens, - const char* delimiters) -{ - tokenize_impl(s, s_size, out_tokens, delimiters); -} - -void tokenize(const char* s, std::vector& out_tokens, const char* delimiters) -{ - tokenize_impl(s, strlen(s), out_tokens, delimiters); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/util.h b/src/terrainlib/tntn/util.h deleted file mode 100644 index 9973024..0000000 --- a/src/terrainlib/tntn/util.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace tntn { - -template -glm::tvec2 xy(const glm::tvec3& v) -{ - return { v.x, v.y }; -} - -template -struct SimpleRange { - typedef T iterator_type; - T begin; - T end; - - size_t size() const { return std::distance(begin, end); } - - template - void for_each(CallableT&& c) const - { - for (auto p = begin; p != end; ++p) { - c(*p); - } - } - template - void for_each(CallableT&& c) - { - for (auto p = begin; p != end; ++p) { - c(*p); - } - } - - template - void copy_into(ContainerT& c) const - { - c.reserve(size()); - std::copy(begin, end, std::back_inserter(c)); - } -}; - -template -inline void hash_combine(size_t& seed, const T& t) noexcept -{ - seed ^= std::hash()(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2); -} - -void tokenize(const std::string& s, - std::vector& out_tokens, - const char* delimiters = nullptr); -void tokenize(const char* s, - const size_t s_size, - std::vector& out_tokens, - const char* delimiters = nullptr); -void tokenize(const char* s, - std::vector& out_tokens, - const char* delimiters = nullptr); - -} // namespace tntn diff --git a/src/terrainlib/tntn/zemlya_meshing.cpp b/src/terrainlib/tntn/zemlya_meshing.cpp deleted file mode 100644 index 5372744..0000000 --- a/src/terrainlib/tntn/zemlya_meshing.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "zemlya_meshing.h" -#include "MeshIO.h" -#include "ZemlyaMesh.h" - -namespace tntn { - -std::unique_ptr generate_tin_zemlya(std::unique_ptr raster, double max_error) -{ - zemlya::ZemlyaMesh g; - g.load_raster(std::move(raster)); - g.greedy_insert(max_error); - return g.convert_to_mesh(); -} - -std::unique_ptr generate_tin_zemlya(std::unique_ptr surface_points, - double max_error) -{ - auto raster = surface_points->to_raster(); - surface_points.reset(); - - return generate_tin_zemlya(std::move(raster), max_error); -} - -std::unique_ptr generate_tin_zemlya(const SurfacePoints& surface_points, double max_error) -{ - auto raster = surface_points.to_raster(); - return generate_tin_zemlya(std::move(raster), max_error); -} - -} // namespace tntn diff --git a/src/terrainlib/tntn/zemlya_meshing.h b/src/terrainlib/tntn/zemlya_meshing.h deleted file mode 100644 index 88f17e7..0000000 --- a/src/terrainlib/tntn/zemlya_meshing.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "Mesh.h" -#include "SurfacePoints.h" - -#include - -namespace tntn { - -std::unique_ptr generate_tin_zemlya(std::unique_ptr raster, double max_error); -std::unique_ptr generate_tin_zemlya(std::unique_ptr surface_points, - double max_error); -std::unique_ptr generate_tin_zemlya(const SurfacePoints& surface_points, double max_error); - -} // namespace tntn diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index d15cfd6..5ca7460 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -26,30 +26,6 @@ add_executable(unittests_terrainlib srs_test.cpp tile_heights_generator.cpp top_down_tiler.cpp - # algorithms/primitives.cpp - # algorithms/raster_triangle_scanline.cpp - # tntn/Delaunay_tests.cpp - # tntn/File_tests.cpp - # tntn/geometrix_tests.cpp - # tntn/Mesh_tests.cpp - # tntn/ObjPool_tests.cpp - # tntn/OFFReader_tests.cpp - # tntn/RasterIO_tests.cpp - # tntn/Raster_tests.cpp - # tntn/raster_tools_tests.cpp - # tntn/simple_meshing_tests.cpp - # tntn/SimpleRange_tests.cpp - # tntn/SuperTriangle_tests.cpp - # tntn/SurfacePoints_tests.cpp - # tntn/terra_meshing_tests.cpp - # tntn/test_common.cpp - # tntn/test_common.h - # tntn/triangle_indices.cpp - # tntn/triangle_indices_data.cpp - # tntn/triangle_indices.h - # tntn/util_tests.cpp - # tntn/vertex_points.cpp - # tntn/vertex_points.h ) target_compile_definitions(unittests_terrainlib PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") diff --git a/unittests/algorithms/primitives.cpp b/unittests/algorithms/primitives.cpp deleted file mode 100644 index 53d3929..0000000 --- a/unittests/algorithms/primitives.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "../catch2_helpers.h" -#include -#include -#include - -#include "algorithms/primitives.h" - -TEST_CASE("primitive tests") -{ - SECTION("triangle area and cw / ccw") - { - CHECK(primitives::triAreaX2(glm::dvec2(0, 0), glm::dvec2(10, 0), glm::dvec2(10, 10)) == Approx(100)); - - CHECK(primitives::ccw(glm::dvec2(0, 0), glm::dvec2(10, 0), glm::dvec2(10, 10))); - CHECK(!primitives::ccw(glm::dvec2(0, 0), glm::dvec2(10, 10), glm::dvec2(10, 0))); - CHECK(primitives::ccw(glm::dvec2(0, 0), glm::dvec2(0.10, 0), glm::dvec2(0.10, 0.1))); - CHECK(!primitives::ccw(glm::dvec2(0, 0), glm::dvec2(0.10, 10), glm::dvec2(0.10, 0))); - } - - SECTION("left/rightOf for floating types") - { - CHECK(primitives::leftOf(glm::dvec2(0, 5), glm::dvec2(0, 0), glm::dvec2(5, 5))); - CHECK(primitives::rightOf(glm::dvec2(5, 0), glm::dvec2(0, 0), glm::dvec2(5, 5))); - CHECK(!primitives::leftOf(glm::dvec2(5, 0), glm::dvec2(0, 0), glm::dvec2(5, 5))); - CHECK(!primitives::rightOf(glm::dvec2(0, 5), glm::dvec2(0, 0), glm::dvec2(5, 5))); - } - - SECTION("left/rightOf for unsigned types") - { - CHECK(primitives::leftOf(glm::uvec2(0, 5), glm::uvec2(0, 0), glm::uvec2(5, 5))); - CHECK(primitives::rightOf(glm::uvec2(5, 0), glm::uvec2(0, 0), glm::uvec2(5, 5))); - CHECK(!primitives::leftOf(glm::uvec2(5, 0), glm::uvec2(0, 0), glm::uvec2(5, 5))); - CHECK(!primitives::rightOf(glm::uvec2(0, 5), glm::uvec2(0, 0), glm::uvec2(5, 5))); - } - - SECTION("left/rightOf for unsigned types and border cases") - { - CHECK(primitives::leftOf(glm::uvec2(0, 5), glm::uvec2(0, 0), glm::uvec2(0, 5))); - CHECK(primitives::rightOf(glm::uvec2(3, 3), glm::uvec2(0, 0), glm::uvec2(5, 5))); - CHECK(!primitives::leftOf(glm::uvec2(0, 5), glm::uvec2(0, 0), glm::uvec2(0, 5))); - CHECK(!primitives::rightOf(glm::uvec2(3, 3), glm::uvec2(0, 0), glm::uvec2(5, 5))); - } - - SECTION("triangle inside / outside normal cases") - { - CHECK(primitives::inside({ 2, 1 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(primitives::inside({ 2, 1 }, { 0, 0 }, { 30, 0 }, { 3, 3 })); - CHECK(primitives::inside({ 2, 1 }, { 0, 0 }, { 3, 0 }, { 3, 30 })); - CHECK(primitives::inside({ 2, 1 }, { 0, 0 }, { 3, 0 }, { 30, 30 })); - - CHECK(!primitives::inside({ 1, 2 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 3, 4 }, { 0, 0 }, { 30, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 4, 0 }, { 0, 0 }, { 3, 0 }, { 3, 30 })); - CHECK(!primitives::inside({ 2, 3 }, { 0, 0 }, { 3, 0 }, { 30, 30 })); - } - - SECTION("bottom right triangle, edges should be inside") - { - CHECK(!primitives::inside({ 0, 0 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(primitives::inside({ 1, 1 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(primitives::inside({ 2, 2 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 1, 0 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 2, 0 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 3, 0 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 3, 1 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 3, 2 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - CHECK(!primitives::inside({ 3, 3 }, { 0, 0 }, { 3, 0 }, { 3, 3 })); - } - - SECTION("top left triangle, left and top should be inside, diagonal should be outside") - { - CHECK(!primitives::inside({ 0, 0 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(!primitives::inside({ 1, 1 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(!primitives::inside({ 2, 2 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(primitives::inside({ 1, 3 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(primitives::inside({ 2, 3 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(!primitives::inside({ 3, 3 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(primitives::inside({ 0, 1 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(primitives::inside({ 0, 2 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - CHECK(primitives::inside({ 0, 3 }, { 0, 0 }, { 3, 3 }, { 0, 3 })); - } -} diff --git a/unittests/algorithms/raster_triangle_scanline.cpp b/unittests/algorithms/raster_triangle_scanline.cpp deleted file mode 100644 index 9cf4a8f..0000000 --- a/unittests/algorithms/raster_triangle_scanline.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "algorithms/raster_triangle_scanline.h" -#include "../catch2_helpers.h" -#include "tntn/Raster.h" -#include - -TEST_CASE("raster triangle goes through pixels exactly once (small rect)") -{ - constexpr auto width = 3; - constexpr auto height = 3; - tntn::Raster raster(width, height); - const auto scan_tri = [&](const glm::uvec2& coords, int value) { - REQUIRE(coords.x < width); - REQUIRE(coords.y < height); - CHECK(value == 0); - raster.value(coords.y, coords.x)++; - }; - raster.set_all(0); - /* d----c - * | e | - * a----b - */ - glm::uvec2 a = { 0, 0 }; - glm::uvec2 b = { width - 1, 0 }; - glm::uvec2 c = { width - 1, height - 1 }; - glm::uvec2 d = { 0, height - 1 }; - glm::uvec2 e = { 1, 1 }; - - // SECTION("upper left triangle") { - // const auto check_tri = [&](){ - // CHECK(raster.value(0, 0) == 0); - // CHECK(raster.value(0, 1) == 0); - // CHECK(raster.value(0, 2) == 0); - // CHECK(raster.value(1, 0) == 1); - // CHECK(raster.value(1, 1) == 0); - // CHECK(raster.value(1, 2) == 0); - // CHECK(raster.value(2, 0) == 1); - // CHECK(raster.value(2, 1) == 1); - // CHECK(raster.value(2, 2) == 0); - // }; - // raster::triangle_scanline(raster, a, c, d, scan_tri); - // check_tri(); - // raster.set_all(0); - // raster::triangle_scanline(raster, c, d, a, scan_tri); - // check_tri(); - // raster.set_all(0); - // raster::triangle_scanline(raster, d, a, c, scan_tri); - // check_tri(); - // raster.set_all(0); - // } - - SECTION("lower right triangle") - { - const auto check_tri = [&]() { - CHECK(raster.value(0, 0) == 1); - CHECK(raster.value(0, 1) == 1); - CHECK(raster.value(0, 2) == 1); - CHECK(raster.value(1, 0) == 0); - CHECK(raster.value(1, 1) == 1); - CHECK(raster.value(1, 2) == 1); - CHECK(raster.value(2, 0) == 0); - CHECK(raster.value(2, 1) == 0); - CHECK(raster.value(2, 2) == 1); - }; - - raster::triangle_scanline(raster, a, b, c, scan_tri); - check_tri(); - raster.set_all(0); - raster::triangle_scanline(raster, b, c, a, scan_tri); - check_tri(); - raster.set_all(0); - raster::triangle_scanline(raster, c, a, b, scan_tri); - check_tri(); - raster.set_all(0); - } - - SECTION("fill") - { - raster::triangle_scanline(raster, a, b, e, scan_tri); - raster::triangle_scanline(raster, e, b, c, scan_tri); - raster::triangle_scanline(raster, e, c, d, scan_tri); - raster::triangle_scanline(raster, d, a, e, scan_tri); - for (const auto& v : raster.asVector()) { - CHECK(v == 1); - } - raster.set_all(0); - } -} - -TEST_CASE("raster triangle goes through pixels exactly once (larger rect)") -{ - constexpr auto width = 17; - constexpr auto height = 20; - tntn::Raster raster(width, height); - const auto scan_tri = [&](const glm::uvec2& coords, int value) { - REQUIRE(coords.x < width); - REQUIRE(coords.y < height); - if (value != 0) - CHECK(value == 0); - raster.value(coords.y, coords.x)++; - }; - raster.set_all(0); - /* - * g----h----i - * | / | \ | - * d----e----f - * | / | \ | - * a----b----c - */ - glm::uvec2 a = { 0, 0 }; - glm::uvec2 b = { 4, 0 }; - glm::uvec2 c = { width - 1, 0 }; - glm::uvec2 d = { 0, 12 }; - glm::uvec2 e = { 10, 10 }; - glm::uvec2 f = { width - 1, 11 }; - glm::uvec2 g = { 0, height - 1 }; - glm::uvec2 h = { 1, height - 1 }; - glm::uvec2 i = { width - 1, height - 1 }; - SECTION("fill") - { - raster::triangle_scanline(raster, a, b, e, scan_tri); - raster::triangle_scanline(raster, a, e, d, scan_tri); - - raster::triangle_scanline(raster, b, c, e, scan_tri); - raster::triangle_scanline(raster, f, e, c, scan_tri); - - raster::triangle_scanline(raster, g, d, h, scan_tri); - raster::triangle_scanline(raster, h, d, e, scan_tri); - - raster::triangle_scanline(raster, i, h, f, scan_tri); - raster::triangle_scanline(raster, f, h, e, scan_tri); - for (const auto& v : raster.asVector()) { - CHECK(v == 1); - } - raster.set_all(0); - } -} diff --git a/unittests/tntn/Delaunay_tests.cpp b/unittests/tntn/Delaunay_tests.cpp deleted file mode 100644 index 41b495d..0000000 --- a/unittests/tntn/Delaunay_tests.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include - -#include -#include - -#include "tntn/File.h" - -#include "tntn/Points2Mesh.h" -#include "tntn/geometrix.h" - -#include "tntn/MeshIO.h" - -#include "tntn/Delaunator.h" - -// data -#include "triangle_indices.h" -#include "vertex_points.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("delaunator test", "[tntn]") - { - - // super simple - one triangle - // points in anti-clockwise order - - std::vector ps_simple { 0, 0, 1, 1, 1, 0 }; - - delaunator_cpp::Delaunator dn; - if (!dn.triangulate(ps_simple)) { - CHECK(false); - } - - CHECK(dn.triangles.size() == 3); - - for (int i = 0; i < dn.triangles.size(); i += 3) { - for (int j = 0; j < 3; j++) { - int pi = dn.triangles[j]; - CHECK(pi == j); - } - } - - std::vector vertex_list_big; - init_vertex_list(vertex_list_big); - - // delaunator_cpp::Delaunator dn_big; - if (!dn.triangulate(vertex_list_big)) { - CHECK(false); - } - - std::vector tri_big; - init_triangle_list(tri_big); - - CHECK(dn.triangles.size() == tri_big.size()); - for (int i = 0; i < dn.triangles.size(); i++) { - CHECK(dn.triangles[i] == tri_big[i]); - } - } - - TEST_CASE("simple delaunay", "[tntn]") - { - std::vector vlist; - - Vertex v; - - // A (i = 0) - v.x = 0; - v.y = 0; - v.z = 0; - - vlist.push_back(v); - - // B (i = 1) - v.x = 100; - v.y = 0; - v.z = 0; - - vlist.push_back(v); - - // C (i = 2) - v.x = 100; - v.y = 100; - v.z = 0; - - vlist.push_back(v); - - // D (i = 3) - v.x = 0; - v.y = 100; - v.z = 0; - - vlist.push_back(v); - - std::vector faces; - generate_delaunay_faces(vlist, faces); - - CHECK(faces.size() == 2); - - int h = 10; - int w = 20; - - vlist.clear(); - for (int r = 0; r < h; r++) { - for (int c = 0; c < w; c++) { - Vertex vvv; - vvv.x = c; - vvv.y = r; - - float dx = c - w / 2; - float dy = r - h / 2; - if (dx * dx + dy * dy < 30 * 30) { - vvv.z = 20; - } else - vvv.z = 0; - - vlist.push_back(vvv); - } - } - - faces.clear(); - - std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - generate_delaunay_faces(vlist, faces); - std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); - - CHECK(faces.size() == (w - 1) * (h - 1) * 2); - - // std::cout <<"delaunay on " << vlist.size()/1000.0 << "k vertices in " << std::chrono::duration_cast(end - begin).count() / 1000.0 << "seconds" << std::endl; - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/File_tests.cpp b/unittests/tntn/File_tests.cpp deleted file mode 100644 index 079c854..0000000 --- a/unittests/tntn/File_tests.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#include -#include -#include -#include -//#include - -#include - -#include "tntn/File.h" - -namespace tntn { -namespace unittests { - - namespace fs = std::filesystem; - - namespace { - const auto milliseconds_since_epoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - static auto gen64 = std::mt19937_64(uint_fast64_t(milliseconds_since_epoch)); - std::string unique_path() - { - return fmt::format("tntn_{}_{}", gen64(), gen64()); - } - - class FileKiller { - fs::path m_file_path; - - public: - FileKiller(const fs::path& p) - : m_file_path(p) - { - } - ~FileKiller() - { - fs::remove(m_file_path); - REQUIRE(!fs::exists(m_file_path)); - } - }; - } - - TEST_CASE("File open existing and read", "[tntn]") - { - auto tempfilename = fs::temp_directory_path() / unique_path(); - const auto fk = FileKiller { tempfilename }; - - File fout; - REQUIRE(fout.open(tempfilename.c_str(), File::OM_RWC)); - CHECK(fout.write(0, "fooo", 4)); - CHECK(fout.write(3, "bar", 3)); - CHECK(fout.size() == 6); - CHECK(fout.close()); - - REQUIRE(fs::exists(tempfilename)); - - File fin; - REQUIRE(fin.open(tempfilename.c_str(), File::OM_R)); - CHECK(fin.size() == 6); - std::string foobar; - fin.read(0, foobar, 6); - CHECK(fin.is_good()); - CHECK(foobar == "foobar"); - } - - TEST_CASE("File write past end", "[tntn]") - { - auto tempfilename = fs::temp_directory_path() / unique_path(); - const auto fk = FileKiller { tempfilename }; - - File fout; - REQUIRE(fout.open(tempfilename.c_str(), File::OM_RWC)); - - CHECK(fout.write(42, "foo", 3)); - - std::vector foo; - fout.read(0, foo, 42 + 3); - CHECK(foo.size() == 42 + 3); - } - - TEST_CASE("getline on MemoryFile", "[tntn]") - { - - MemoryFile f; - std::string foo_line = "foo\n"; - std::string bar_line = "bar\n"; - std::string baz_line = "baz"; - - f.write(0, foo_line); - f.write(f.size(), bar_line); - f.write(f.size(), baz_line); - - REQUIRE(f.size() == foo_line.size() + bar_line.size() + baz_line.size()); - - std::string line; - FileLike::position_type from_offset = 0; - from_offset = getline(from_offset, f, line); - CHECK(from_offset < f.size()); - CHECK(line == "foo"); - - from_offset = getline(from_offset, f, line); - CHECK(from_offset < f.size()); - CHECK(line == "bar"); - - from_offset = getline(from_offset, f, line); - CHECK(from_offset == f.size()); - CHECK(line == "baz"); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/Mesh_tests.cpp b/unittests/tntn/Mesh_tests.cpp deleted file mode 100644 index cbeb1d8..0000000 --- a/unittests/tntn/Mesh_tests.cpp +++ /dev/null @@ -1,324 +0,0 @@ -#include - -#include "tntn/Mesh.h" -#include "tntn/geometrix.h" -#include - -namespace tntn { -namespace unittests { - - TEST_CASE("test detector for holes", "[tntn]") - { - std::vector vertices; - std::vector faces; - - vertices.push_back({ 0.0, 0.0, 0.0 }); // 0 - vertices.push_back({ 1.0, 0.0, 0.0 }); // 1 - vertices.push_back({ 1.0, 1.0, 0.0 }); // 2 - vertices.push_back({ 0.0, 1.0, 0.0 }); // 3 - vertices.push_back({ 0.5, 0.5, 0.0 }); // 4 - - faces.push_back({ { 0, 4, 3 } }); // t0 - faces.push_back({ { 1, 2, 4 } }); // t1 - faces.push_back({ { 3, 4, 2 } }); // t2 - - Mesh has_hole; - has_hole.from_decomposed(std::move(vertices), std::move(faces)); - has_hole.generate_triangles(); - - CHECK(has_hole.poly_count() == 3); - CHECK(has_hole.check_for_holes_in_square_mesh() == true); - - vertices.clear(); - faces.clear(); - - vertices.push_back({ 0.0, 0.0, 0.0 }); // 0 - vertices.push_back({ 1.0, 0.0, 0.0 }); // 1 - vertices.push_back({ 1.0, 1.0, 0.0 }); // 2 - vertices.push_back({ 0.0, 1.0, 0.0 }); // 3 - vertices.push_back({ 0.5, 0.5, 0.0 }); // 4 - - faces.push_back({ { 0, 4, 3 } }); // t0 - faces.push_back({ { 1, 2, 4 } }); // t1 - faces.push_back({ { 3, 4, 2 } }); // t2 - faces.push_back({ { 0, 4, 1 } }); // t3 - - Mesh has_no_hole; - has_no_hole.from_decomposed(std::move(vertices), std::move(faces)); - has_no_hole.generate_triangles(); - - CHECK(has_no_hole.poly_count() == 4); - CHECK(has_no_hole.check_for_holes_in_square_mesh() == false); - } - - TEST_CASE("test detector for square mesh", "[tntn]") - { - - std::vector vertices; - std::vector faces; - - vertices.push_back({ 0.0, 0.0, 0.0 }); // 0 - vertices.push_back({ 1.0, 0.0, 0.0 }); // 1 - vertices.push_back({ 1.0, 1.0, 0.0 }); // 2 - - faces.push_back({ { 0, 1, 2 } }); // t0 - - Mesh non_square; - non_square.from_decomposed(std::move(vertices), std::move(faces)); - non_square.generate_triangles(); - - CHECK(non_square.poly_count() == 1); - CHECK(non_square.is_square() == false); - - vertices.clear(); - faces.clear(); - - vertices.push_back({ 0.0, 0.0, 0.0 }); // 0 - vertices.push_back({ 1.0, 1.0, 0.0 }); // 1 - vertices.push_back({ 0.0, 1.0, 0.0 }); // 2 - vertices.push_back({ 1.0, 0.0, 0.0 }); // 3 - - faces.push_back({ { 0, 3, 1 } }); // t0 - faces.push_back({ { 0, 1, 2 } }); // t1 - - Mesh square; - square.from_decomposed(std::move(vertices), std::move(faces)); - square.generate_triangles(); - - CHECK(square.poly_count() == 2); - CHECK(square.is_square() == true); - } - - TEST_CASE("Mesh from triangles", "[tntn]") - { - Mesh m; - - std::vector triangles; - - triangles.push_back({ { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 2.0, 2.0, 2.0 } } }); - - m.from_triangles(std::move(triangles)); - - CHECK(m.poly_count() == 1); - - CHECK(!m.has_decomposed()); - - m.generate_decomposed(); - - CHECK(m.has_decomposed()); - } - - TEST_CASE("Mesh from decomposed", "[tntn]") - { - Mesh m; - - std::vector vertices; - std::vector faces; - - vertices.push_back({ 0.0, 0.0, 0.0 }); - vertices.push_back({ 1.0, 1.0, 1.0 }); - vertices.push_back({ 2.0, 2.0, 2.0 }); - - faces.push_back({ { 0, 1, 2 } }); - - m.from_decomposed(std::move(vertices), std::move(faces)); - - CHECK(m.poly_count() == 1); - - CHECK(!m.has_triangles()); - - m.generate_triangles(); - - CHECK(m.has_triangles()); - } - - TEST_CASE("Mesh from added triangles", "[tntn]") - { - Mesh m; - - m.add_triangle({ { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 2.0, 2.0, 2.0 } } }, true); - - m.add_triangle({ { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 3.0, 3.0, 3.0 } } }, true); - - CHECK(m.poly_count() == 2); - - auto vertices = m.vertices(); - CHECK(std::distance(vertices.begin, vertices.end) == 4); - } - -#if 1 - TEST_CASE("Mesh triangle/decomposed round tripping", "[tntn]") - { - Mesh tr_m; - const int c = 10; - for (int x = 0; x < c; x++) { - for (int y = 0; y < c; y++) { - tr_m.add_triangle({ { { x, y, x * y }, - { x + 1, y + 1, (x + 1) * (y + 1) }, - { x + 2, y + 2, (x + 2) * (y + 2) } } }); - } - } - const size_t poly_count = c * c; - - CHECK(tr_m.poly_count() == poly_count); - - Mesh de_m = tr_m.clone(); - de_m.generate_decomposed(); - de_m.clear_triangles(); - - CHECK(de_m.poly_count() == tr_m.poly_count()); - - Mesh tr_m2 = de_m.clone(); - tr_m2.generate_triangles(); - - std::vector new_triangles; - tr_m2.grab_triangles(new_triangles); - std::sort(new_triangles.begin(), new_triangles.end(), triangle_compare<>()); - - std::vector original_triangles; - tr_m.grab_triangles(original_triangles); - std::sort(original_triangles.begin(), original_triangles.end(), triangle_compare<>()); - - CHECK(new_triangles.size() == poly_count); - CHECK(new_triangles == original_triangles); - } -#endif - - TEST_CASE("Mesh move construction", "[tntn]") - { - Mesh m1; - m1.add_triangle({ { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 2.0, 2.0, 2.0 } } }); - - CHECK(m1.poly_count() == 1); - - Mesh m2(std::move(m1)); - - CHECK(m1.poly_count() == 0); - CHECK(m2.poly_count() == 1); - } - - TEST_CASE("Mesh move assignment", "[tntn]") - { - Mesh m1; - m1.add_triangle({ { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 2.0, 2.0, 2.0 } } }); - - CHECK(m1.poly_count() == 1); - - Mesh m2; - m2 = std::move(m1); - - CHECK(m1.poly_count() == 0); - CHECK(m2.poly_count() == 1); - } - - TEST_CASE("Mesh::check_tin_properties works on simple mesh") - { - Mesh m; - - m.from_decomposed( - { - { 0, 0, 1 }, - { 1, 0, 2 }, - { 1, 1, 3 }, - { 0, 1, 4 }, - { 0.5, -1, 5 }, - }, - { - { { 0, 1, 2 } }, // ccw - { { 0, 2, 3 } }, // ccw - { { 0, 4, 1 } }, // ccw - }); - - CHECK(m.check_tin_properties()); - } - - TEST_CASE("Mesh::check_tin_properties detects not-front facing faces") - { - Mesh m; - - m.from_decomposed( - { - { 0, 0, 1 }, - { 1, 0, 2 }, - { 1, 1, 3 }, - }, - { - { { 0, 2, 1 } }, // cw - }); - - CHECK(!m.check_tin_properties()); - } - - TEST_CASE("Mesh::check_tin_properties detects invalid vertex indices") - { - Mesh m; - - m.from_decomposed( - { - { 0, 1, 2 }, - { 1, 2, 3 }, - { 2, 3, 4 }, - }, - { - { { 0, 1, 2 } }, - { { 0, 1, 3 } }, - }); - - CHECK(!m.check_tin_properties()); - } - - TEST_CASE("Mesh::check_tin_properties detects collapsed vertices in face") - { - Mesh m; - - m.from_decomposed( - { - { 0, 1, 2 }, - { 1, 2, 3 }, - { 2, 3, 4 }, - }, - { - { { 0, 1, 2 } }, - { { 0, 0, 2 } }, - }); - - CHECK(!m.check_tin_properties()); - } - - TEST_CASE("Mesh::check_tin_properties detects duplicate vertices") - { - Mesh m; - - m.from_decomposed( - { - { 0, 1, 2 }, - { 1, 2, 3 }, - { 0, 1, 2 }, - }, - { - { { 0, 1, 2 } }, - }); - - CHECK(!m.check_tin_properties()); - } - - TEST_CASE("Mesh::check_tin_properties detects unreferenced vertices") - { - Mesh m; - - m.from_decomposed( - { - { 0, 1, 2 }, - { 1, 2, 3 }, - { 2, 3, 4 }, - { 3, 4, 5 }, - }, - { - { { 0, 1, 2 } }, - }); - - CHECK(!m.check_tin_properties()); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/OFFReader_tests.cpp b/unittests/tntn/OFFReader_tests.cpp deleted file mode 100644 index 5d7324a..0000000 --- a/unittests/tntn/OFFReader_tests.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include - -#include - -#include "tntn/Mesh.h" -#include "tntn/MeshIO.h" -#include "tntn/OFFReader.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("OFFReader interop with write_mesh_as_off", "[tntn]") - { - Mesh m; - - m.add_triangle({ { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 } } }); - - m.add_triangle({ { { 0, 0, 0 }, { 2, 2, 2 }, { 3, 3, 3 } } }); - - m.add_triangle({ { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } } }); - - m.add_triangle({ { { 3, 3, 3 }, { 2, 2, 2 }, { 1, 1, 1 } } }); - - m.add_triangle({ { { M_PI, -M_PI, 0.123456789123456789123456789123456789 }, - { std::numeric_limits::max(), - M_PI * M_PI * M_PI * M_PI, - std::numeric_limits::min() }, - { -std::numeric_limits::max(), - -M_PI * M_PI, - -std::numeric_limits::min() } } }); - - m.generate_decomposed(); - - MemoryFile out_mem; - REQUIRE(write_mesh_as_off(out_mem, m)); - - CHECK(out_mem.size() > 0); - - auto m2 = load_mesh_from_off(out_mem); - REQUIRE(m2 != nullptr); - - // do dimensions argee - CHECK(m2->poly_count() == 5); - CHECK(m2->poly_count() == m.poly_count()); - - // simple value check on vertices - SimpleRange v_src = m.vertices(); - SimpleRange v_dst = m2->vertices(); - - CHECK(v_src.size() == v_dst.size()); - - for (int i = 0; i < v_dst.size(); i++) { - double prec = 1e-15; - - double dx = std::abs(v_src.begin[i].x - v_dst.begin[i].x); - double dy = std::abs(v_src.begin[i].y - v_dst.begin[i].y); - double dz = std::abs(v_src.begin[i].z - v_dst.begin[i].z); - - CHECK(dx <= prec); - CHECK(dy <= prec); - CHECK(dz <= prec); - } - - // semantic equal - // CHECK(m.semantic_equal(*m2)); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/ObjPool_tests.cpp b/unittests/tntn/ObjPool_tests.cpp deleted file mode 100644 index c6d9b86..0000000 --- a/unittests/tntn/ObjPool_tests.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -#include -#include - -#include "tntn/ObjPool.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("ObjPool operations", "[tntn]") - { - auto pool = ObjPool::create(); - - auto p1 = pool->spawn(); - p1->assign("foo"); - - auto s1 = *p1; - CHECK(s1 == "foo"); - - const auto p2 = p1.pool()->spawn(); - - CHECK(p1 != p2); - CHECK(!(p1 == p2)); - - if (p1) { - CHECK(true); - } - if (!p2) { - CHECK(false); - } - - std::unordered_set> ptr_hash_set; - ptr_hash_set.insert(p1); - ptr_hash_set.insert(p2); - CHECK(ptr_hash_set.size() == 2); - ptr_hash_set.insert(p2); - CHECK(ptr_hash_set.size() == 2); - - auto p3 = p1; - pool_ptr p4; - CHECK(!p4); - p4 = p1; - CHECK(p4); - - CHECK(p3 == p4); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/RasterIO_tests.cpp b/unittests/tntn/RasterIO_tests.cpp deleted file mode 100644 index 14e8936..0000000 --- a/unittests/tntn/RasterIO_tests.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#include "tntn/Raster.h" -#include "tntn/RasterIO.h" - -#include "test_common.h" - -#include -#include -#include - -namespace tntn { -namespace unittests { - - TEST_CASE("load_raster_file", "[tntn]") - { - RasterDouble raster; - bool load_result; - - fs::path bogus_file = fixture_path("there.is.no.such.raster.file"); - - load_result = load_raster_file(bogus_file.string(), raster); - REQUIRE(load_result == false); - - fs::path valid_raster_file = fixture_path("valid_raster.tif"); - - load_result = load_raster_file(valid_raster_file.string(), raster); - REQUIRE(load_result == true); - REQUIRE(!raster.empty()); - REQUIRE(raster.get_width() == 100); - REQUIRE(raster.get_height() == 80); - REQUIRE(raster.get_no_data_value() == -3.4028234663852886e+38); - - REQUIRE(double_eq(raster.get_cell_width(), 3.91694, 0.00001)); - REQUIRE(double_eq(raster.get_cell_height(), 3.91694, 0.00001)); - REQUIRE(double_eq(raster.get_pos_x(), -13636677.018, 0.001)); - REQUIRE(double_eq(raster.get_pos_y(), 4543905.659, 0.001)); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/Raster_tests.cpp b/unittests/tntn/Raster_tests.cpp deleted file mode 100644 index 8998b79..0000000 --- a/unittests/tntn/Raster_tests.cpp +++ /dev/null @@ -1,458 +0,0 @@ -#include - -#include "tntn/Mesh.h" -#include "tntn/Mesh2Raster.h" -#include "tntn/Raster.h" -#include "tntn/RasterIO.h" -#include "tntn/SurfacePoints.h" -#include "tntn/raster_tools.h" -#include - -#include -#include -#include - -namespace tntn { -namespace unittests { - - TEST_CASE("raster default value", "[tntn]") - { - RasterDouble raster; - double ndv = raster.get_no_data_value(); - - double check = 0; - detail::NDVDefault::set(check); - - CHECK(ndv == check); - } - - TEST_CASE("raster bb", "[tntn]") - { - RasterDouble raster(798, 212); - - raster.set_pos_x(11.024); - raster.set_pos_y(-334.242); - raster.set_cell_width(1.123); - raster.set_cell_height(1.341); - - BBox2D rbb = raster.get_bounding_box(); - - double w = raster.get_width() * raster.get_cell_width(); - double h = raster.get_height() * raster.get_cell_height(); - - CHECK(std::abs((rbb.max.x - rbb.min.x) - w) < 0.001); - CHECK(std::abs((rbb.max.y - rbb.min.y) - h) < 0.001); - } - - TEST_CASE("raster coordinates", "[tntn]") - { - RasterDouble raster(7, 21); - - raster.set_pos_x(11); - raster.set_pos_y(-334); - raster.set_cell_width(1.123); - raster.set_cell_height(1.341); - - for (int r = 0; r < raster.get_height(); r++) { - for (int c = 0; c < raster.get_width(); c++) { - double x = raster.col2x(c); - double y = raster.row2y(r); - - int cn = raster.x2col(x); - int rn = raster.y2row(y); - - CHECK(cn == c); - CHECK(rn == r); - } - } - } - - TEST_CASE("mesh 2 raster", "[tntn]") - { - - std::vector trList; - - Triangle t; - - t[0].x = 0.0; - t[0].y = 0.0; - t[0].z = 1; - - t[1].x = 0.0; - t[1].y = 3.0; - t[1].z = 1; - - t[2].x = 3.0; - t[2].y = 3.0; - t[2].z = 1; - - trList.push_back(t); - - t[0].x = 0.0; - t[0].y = 0.0; - t[0].z = -1; - - t[1].x = 3.0; - t[1].y = 3.0; - t[1].z = -1; - - t[2].x = 3.0; - t[2].y = 0.0; - t[2].z = -1; - - trList.push_back(t); - - Mesh m; - m.from_triangles(std::move(trList)); - m.generate_decomposed(); - - SECTION("pixel width / height == 1") - { - Mesh2Raster m2r; - RasterDouble raster_4 = m2r.rasterise(m, 4, 4); - - CHECK(raster_4.get_cell_width() == 1); - CHECK(raster_4.get_cell_height() == 1); - - RasterDouble raster_10 = m2r.rasterise(m, 10, 10, 4, 4); - - CHECK(raster_10.get_cell_width() == 0.4); - CHECK(raster_10.get_cell_height() == 0.4); - } - - SECTION("pixel width / height == 1.5") - { - Mesh2Raster m2r; - RasterDouble raster_4 = m2r.rasterise(m, 6, 4); - - CHECK(raster_4.get_cell_width() == Approx(0.6)); - CHECK(raster_4.get_cell_height() == Approx(1.0)); - - RasterDouble raster_10 = m2r.rasterise(m, 15, 10, 6, 4); - - CHECK(raster_10.get_cell_width() == Approx((3.0 / (6.0 - 1.0)) * (6.0 / 15.0))); - CHECK(raster_10.get_cell_height() == Approx((3.0 / (4.0 - 1.0)) * (4.0 / 10.0))); - - RasterDouble raster_15 = m2r.rasterise(m, 15, 15, 6, 4); - - CHECK(raster_15.get_cell_width() == Approx((3.0 / (6.0 - 1.0)) * (6.0 / 15.0))); - CHECK(raster_15.get_cell_height() == Approx((3.0 / (4.0 - 1.0)) * (4.0 / 15.0))); - } - } - - TEST_CASE("Raster integer downsampe", "[tntn]") - { - RasterDouble big(8, 10); - big.set_all(1); - - RasterDouble small_01 = raster_tools::integer_downsample_mean(big, 2); - - CHECK(small_01.get_height() == big.get_height() / 2); - CHECK(small_01.get_width() == big.get_width() / 2); - - int ws = small_01.get_width(); - int hs = small_01.get_height(); - - for (int rs = 0; rs < hs; rs++) { - for (int cs = 0; cs < ws; cs++) { - CHECK(small_01.value(rs, cs) == 1.0); - } - } - } - - TEST_CASE("Raster crop", "[tntn]") - { - struct P { - int r = -10; - int c = -10; - }; - - Raster

raster; - raster.allocate(5, 6); - - raster.set_cell_width(1); - raster.set_cell_height(1); - raster.set_pos_x(0); - raster.set_pos_y(0); - - P p; - p.r = -999; - p.c = -888; - - raster.set_no_data_value(p); - - int w = raster.get_width(); - int h = raster.get_height(); - - for (int r = 0; r < h; r++) { - for (int c = 0; c < w; c++) { - raster.value(r, c).r = r; - raster.value(r, c).c = c; - } - } - - // control - just a copy! - auto c1 = raster.crop(0, 0, w, h); - - CHECK(c1.get_width() == w); - CHECK(c1.get_height() == h); - CHECK(c1.get_no_data_value().r == -999); - CHECK(c1.get_no_data_value().c == -888); - CHECK(c1.get_pos_x() == 0); - CHECK(c1.get_pos_y() == 0); - - for (int r = 0; r < h; r++) { - for (int c = 0; c < w; c++) { - CHECK(c1.value(r, c).r == r); - CHECK(c1.value(r, c).c == c); - } - } - - // crop from top left with width=3 height=4 - // using raster coorinates with origin at top left! - // (i.e. as data is stored) - auto c2 = raster.crop(0, 0, 3, 4); - - CHECK(c2.get_width() == 3); - CHECK(c2.get_height() == 4); - CHECK(c2.get_no_data_value().r == -999); - CHECK(c2.get_no_data_value().c == -888); - CHECK(c2.get_pos_x() == 0); - CHECK(c2.get_pos_y() == 2); - - for (int r = 0; r < c2.get_height(); r++) { - for (int c = 0; c < c2.get_width(); c++) { - CHECK(c2.value(r, c).r == r); - CHECK(c2.value(r, c).c == c); - } - } - - // crop from bottom left with width=3 height=4 - // using raster coorinates with origin at top left! - // this should be identical to c2! - auto c3 = raster.crop_ll(0, 2, 3, 4); - - CHECK(c2.get_height() == c3.get_height()); - CHECK(c2.get_width() == c3.get_width()); - - CHECK(c3.get_pos_x() == 0); - CHECK(c3.get_pos_y() == 2); - - for (int r = 0; r < c2.get_height(); r++) { - for (int c = 0; c < c2.get_width(); c++) { - CHECK(c2.value(r, c).r == c3.value(r, c).r); - CHECK(c2.value(r, c).c == c3.value(r, c).c); - } - } - - // test what happens if crop region is larger than original raster - // this should return overlapping region: - - Raster raster_int(10, 23); - - raster_int.set_all(-1); - raster_int.set_pos_x(-14); - raster_int.set_pos_y(18); - raster_int.set_cell_width(0.3); - raster_int.set_cell_height(0.3); - raster_int.set_no_data_value(-9999); - - for (int r = 0; r < raster_int.get_height(); r++) { - for (int c = 0; c < raster_int.get_width(); c++) { - raster_int.value(r, c) = r * c; - } - } - - // crop is large than original in all dimensions: - - Raster cropped_raster; - - raster_int.crop(-12, -5, 100, 80, cropped_raster); - - CHECK(raster_int.get_width() == cropped_raster.get_width()); - CHECK(raster_int.get_height() == cropped_raster.get_height()); - CHECK(raster_int.get_cell_size() == cropped_raster.get_cell_size()); - CHECK(raster_int.get_pos_x() == cropped_raster.get_pos_x()); - CHECK(raster_int.get_pos_y() == cropped_raster.get_pos_y()); - - for (int r = 0; r < raster_int.get_height(); r++) { - for (int c = 0; c < raster_int.get_width(); c++) { - CHECK(raster_int.value(r, c) == cropped_raster.value(r, c)); - } - } - - // crop is overlapping original: - cropped_raster.clear(); - - raster_int.crop(-12, -5, 20, 10, cropped_raster); - - for (int r = 0; r < cropped_raster.get_height(); r++) { - for (int c = 0; c < cropped_raster.get_width(); c++) { - CHECK(cropped_raster.get_no_data_value() != cropped_raster.value(r, c)); - CHECK(raster_int.value(r, c) == cropped_raster.value(r, c)); - } - } - - cropped_raster.clear(); - - int sx = 5; - int sy = 7; - raster_int.crop(sx, sy, 300, 500, cropped_raster); - - for (int r = 0; r < cropped_raster.get_height(); r++) { - for (int c = 0; c < cropped_raster.get_width(); c++) { - CHECK(cropped_raster.get_no_data_value() != cropped_raster.value(r, c)); - CHECK(raster_int.value(r + sy, c + sx) == cropped_raster.value(r, c)); - } - } - } - - TEST_CASE("Raster setAll", "[tntn]") - { - - Raster r; - r.set_all(42.0); - - r.allocate(100, 100); - r.set_all(23.0); - - CHECK(r.value(50, 50) == 23.0); - - class TestClass { - public: - TestClass() {}; - TestClass(int vv) - : v(vv) - { - } - int v = -1; - double a = 0; - double b = 0; - }; - - Raster r2; - TestClass tc(123); - r2.set_all(tc); - - r2.allocate(10, 1); - r2.set_all(tc); - - for (int i = 0; i < r2.get_width() * r2.get_height(); i++) { - CHECK(r2.get_ptr()[i].v == 123); - } - - tc.v = -321; - r2.allocate(1, 10); - r2.set_all(tc); - - for (int i = 0; i < r2.get_width() * r2.get_height(); i++) { - CHECK(r2.get_ptr()[i].v == -321); - } - } - - class FailOnCopy { - int v = 0; - - public: - FailOnCopy() = default; - FailOnCopy(const FailOnCopy& other) - : v(other.v) - { - CHECK(false); - } - FailOnCopy(FailOnCopy&& other) noexcept - : v(other.v) - { - CHECK(true); - } - FailOnCopy& operator=(const FailOnCopy& other) - { - v = other.v; - CHECK(false); - return *this; - } - FailOnCopy& operator=(FailOnCopy&& other) noexcept - { - v = other.v; - CHECK(true); - return *this; - } - ~FailOnCopy() = default; - }; - - TEST_CASE("move-construct Raster", "[tntn]") - { - - Raster r; - r.allocate(10, 10); - - Raster r2(std::move(r)); - - CHECK(r2.get_width() == 10); - CHECK(r2.get_height() == 10); - } - - TEST_CASE("move-construct Raster from Image", "[tntn]") - { - Image r(10, 10); - - Raster r2(std::move(r), {}); - - CHECK(r2.get_width() == 10); - CHECK(r2.get_height() == 10); - } - - TEST_CASE("move-assign Raster", "[tntn]") - { - - Raster r; - r.allocate(10, 10); - - Raster r2; - r2 = std::move(r); - - CHECK(r2.get_width() == 10); - CHECK(r2.get_height() == 10); - } - - TEST_CASE("Raster::toVertices", "[tntn]") - { - - Raster r; - r.allocate(10, 10); - r.set_pos_x(10); - r.set_pos_y(10); - r.set_cell_size({ 1.0, 1.0 }); - - for (int y = 0; y < r.get_height(); y++) { - for (int x = 0; x < r.get_width(); x++) { - r.value(y, x) = y * r.get_width() + x; - } - } - - SurfacePoints pts; - pts.reserve(r.get_height() * r.get_width()); - - r.to_vertices([&pts](const double x, const double y, const double z) { - pts.push_back({ x, y, z }); - }); - - int num_found = 0; - auto ptsrange = pts.points(); - ptsrange.for_each([&num_found](const Vertex& v) { - if (v.x == 10.0 && v.y == 10.0) { - // lower-left cell - num_found++; - CHECK(v.z == 9 * 10 + 0); - } else if (v.x == 19.0 && v.y == 19.0) { - // upper-right cell - num_found++; - CHECK(v.z == 0 * 10 + 9); - } - }); - - CHECK(num_found == 2); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/SimpleRange_tests.cpp b/unittests/tntn/SimpleRange_tests.cpp deleted file mode 100644 index 908d26a..0000000 --- a/unittests/tntn/SimpleRange_tests.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#include "tntn/util.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("SimpleRange::for_each with lambda", "[tntn]") - { - std::vector v { 0, 1, 2, 3, 4, 5 }; - SimpleRange::iterator> r { v.begin(), v.end() }; - - std::vector cp; - r.for_each([&cp](int x) { cp.push_back(x); }); - - CHECK(cp == v); - } - - TEST_CASE("SimpleRange:copy_into vector", "[tntn]") - { - std::vector v { 0, 1, 2, 3, 4, 5 }; - SimpleRange::iterator> r { v.begin(), v.end() }; - - std::vector v2; - r.copy_into(v2); - - CHECK(v == v2); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/SuperTriangle_tests.cpp b/unittests/tntn/SuperTriangle_tests.cpp deleted file mode 100644 index c0b7f15..0000000 --- a/unittests/tntn/SuperTriangle_tests.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include - -#include "tntn/SuperTriangle.h" -#include "tntn/logging.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("SuperTriangle test", "[tntn]") - { - float z = 1234; - - Vertex v1; - v1.x = 0; - v1.y = 0; - v1.z = z; - - Vertex v2; - v2.x = 0; - v2.y = 10; - v2.z = z; - - Vertex v3; - v3.x = 10; - v3.y = 10; - v3.z = z; - - SuperTriangle t(v1, v2, v3); - - bool inside = false; - double ih; - - inside = t.interpolate(0.5, 0.5, ih); - TNTN_LOG_DEBUG("ih: {}", ih); - - CHECK(ih == z); - - double ih_1, ih_2, ih_3; - t.interpolate(0.0, 0.0, ih_1); - t.interpolate(100.0, 100.0, ih_2); - t.interpolate(10, 0, ih_3); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/SurfacePoints_tests.cpp b/unittests/tntn/SurfacePoints_tests.cpp deleted file mode 100644 index 24162fd..0000000 --- a/unittests/tntn/SurfacePoints_tests.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include - -#include "tntn/SurfacePoints.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("VertexRaster from points", "[tntn]") - { - const int w = 4; - - // build a 4x4 raster as points - SurfacePoints sp; - for (int y = 0; y < w; y++) { - for (int x = 0; x < w; x++) { - sp.push_back({ x, y, y * w + x }); - } - } - - auto raster = sp.to_vxraster(); - - REQUIRE(raster->get_width() == w); - REQUIRE(raster->get_height() == w); - - for (int y = 0; y < w; y++) { - for (int x = 0; x < w; x++) { - CHECK(raster->value(y, x).z == (w - y - 1) * w + x); - } - } - CHECK(raster->value(0, 0) == Vertex { 0, w - 1, (w - 1) * w }); - } - - TEST_CASE("SurfacePoints::load_from_raster", "[tntn]") - { - SurfacePoints sp; - - RasterDouble r; - r.allocate(10, 10); - - // per convention: lower left corner - r.set_pos_x(100); - r.set_pos_y(200); - r.set_cell_size({ 1.0, 1.0 }); - - for (int y = 0; y < r.get_height(); y++) { - for (int x = 0; x < r.get_width(); x++) { - r.value(r.get_height() - y - 1, x) = y * r.get_width() + x; - } - } - - sp.load_from_raster(r); - - auto points = sp.points(); - - int found_points = 0; - for (auto p = points.begin; p != points.end; p++) { - const auto pt = *p; - if (pt.x == 100 && pt.y == 200) { - // lower left corner point - found_points++; - CHECK(pt.z == 0 * 10 + 0); - } - - if (pt.x == 109 && pt.y == 209) { - // upper right corner point - found_points++; - CHECK(pt.z == 9 * 10 + 9); - } - - if (pt.x == 105 && pt.y == 205) { - // center point - found_points++; - CHECK(pt.z == 5 * 10 + 5); - } - } - CHECK(found_points == 3); - } - - TEST_CASE("SurfacePoints::to_raster orders points correct orientation", "[tntn]") - { - SurfacePoints sp; - const int w = 100; - const int h = 200; - sp.reserve(w * h); - for (int y = 100; y < 100 + h; y++) { - for (int x = 100; x < 100 + w; x++) { - sp.push_back({ x, y, y * w + x }); - } - } - - auto raster = sp.to_raster(); - - REQUIRE(raster->get_width() == w); - REQUIRE(raster->get_height() == h); - - CHECK(raster->value(0, 0) == (100 + 199) * w + 100); - CHECK(raster->value(199, 0) == 100 * w + 100); - - CHECK(raster->value(0, 99) == (100 + 199) * w + 100 + 99); - CHECK(raster->value(199, 99) == 100 * w + 100 + 99); - } - - TEST_CASE("SurfacePoints::to_raster width or height 1", "[tntn]") - { - SurfacePoints sp; - const int w = 1; - const int h = 1; - sp.reserve(w * h); - for (int y = 100; y < 100 + h; y++) { - for (int x = 100; x < 100 + w; x++) { - sp.push_back({ x, y, y * w + x }); - } - } - - auto raster = sp.to_raster(); - - REQUIRE(raster->get_width() == w); - REQUIRE(raster->get_height() == h); - CHECK(raster->value(0, 0) == 100 * 1 + 100); - } - - TEST_CASE("SurfacePoints::to_vxraster orders points correct orientation", "[tntn]") - { - SurfacePoints sp; - const int w = 100; - const int h = 200; - sp.reserve(w * h); - for (int y = 100; y < 100 + h; y++) { - for (int x = 100; x < 100 + w; x++) { - sp.push_back({ x, y, y * w + x }); - } - } - - auto raster = sp.to_vxraster(); - - REQUIRE(raster->get_width() == w); - REQUIRE(raster->get_height() == h); - - CHECK(raster->value(0, 0).z == (100 + 199) * w + 100); - CHECK(raster->value(199, 0).z == 100 * w + 100); - - CHECK(raster->value(0, 99).z == (100 + 199) * w + 100 + 99); - CHECK(raster->value(199, 99).z == 100 * w + 100 + 99); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/geometrix_tests.cpp b/unittests/tntn/geometrix_tests.cpp deleted file mode 100644 index e4432d8..0000000 --- a/unittests/tntn/geometrix_tests.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include - -#include "glm/gtx/normal.hpp" -#include "tntn/geometrix.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("triangle_semantic_equal equal triangles are detected as equal", "[tntn]") - { - Triangle t1 = { { - { 0, 0, 0 }, - { 1, 1, 1 }, - { 2, 2, 4 }, - } }; - - Triangle t2 = { { - { 1, 1, 1 }, - { 2, 2, 4 }, - { 0, 0, 0 }, - } }; - - Triangle t3 = { { - { 2, 2, 4 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - } }; - - triangle_semantic_equal eq; - CHECK(eq(t1, t1)); - CHECK(eq(t1, t2)); - CHECK(eq(t1, t3)); - - CHECK(eq(t2, t2)); - CHECK(eq(t2, t3)); - CHECK(eq(t2, t1)); - - CHECK(eq(t3, t3)); - CHECK(eq(t3, t1)); - CHECK(eq(t3, t2)); - } - - TEST_CASE("triangle_semantic_equal triangle with different vertex is not equal", "[tntn]") - { - Triangle t1 = { { - { 0, 0, 0 }, - { 1, 1, 1 }, - { 2, 2, 4 }, - } }; - Triangle t2 = { { - { 0, 0, 0 }, - { 1, 1, 1 }, - { 3, 3, 9 }, - } }; - - triangle_semantic_equal eq; - CHECK(!eq(t1, t2)); - CHECK(!eq(t2, t1)); - } - - TEST_CASE("triangle_semantic_equal triangle with different winding order is not equal", "[tntn]") - { - Triangle t1 = { { - { 0, 0, 0 }, - { 1, 1, 1 }, - { 2, 2, 4 }, - } }; - Triangle t2 = { { - { 0, 0, 0 }, - { 2, 2, 4 }, - { 1, 1, 1 }, - } }; - - triangle_semantic_equal eq; - CHECK(!eq(t1, t2)); - CHECK(!eq(t2, t1)); - } - - static bool is_front_facing(const Triangle& t) - { - glm::dvec3 n = glm::triangleNormal(t[0], t[1], t[2]); - return n.z > 0; - } - - static bool all_front_facing(std::vector& tv) - { - for (const auto& t : tv) { - if (!is_front_facing(t)) { - return false; - } - } - return true; - } - - TEST_CASE("BBox2D - add point to default initialized", "[tntn]") - { - BBox2D bbox; - bbox.add(glm::dvec2(0, 0)); - CHECK(bbox.min == glm::dvec2(0, 0)); - CHECK(bbox.max == glm::dvec2(0, 0)); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/raster_tools_tests.cpp b/unittests/tntn/raster_tools_tests.cpp deleted file mode 100644 index 760275a..0000000 --- a/unittests/tntn/raster_tools_tests.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#include "tntn/Raster.h" -#include "tntn/raster_tools.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("sample_nearest_valid_avg works", "[tntn]") - { - RasterDouble raster; - raster.allocate(11, 11); - raster.set_no_data_value(-99999); - raster.set_all(raster.get_no_data_value()); - - const auto w = raster.get_width(); - const auto h = raster.get_height(); - - raster.value(0, 0) = 3; - raster.value(h - 1, 0) = 6; - raster.value(0, w - 1) = 12; - raster.value(h - 1, w - 1) = 24; - - raster.value(5, 5) = NAN; - - const double avg_sample = raster_tools::sample_nearest_valid_avg(raster, 5, 5, 3); - - CHECK(avg_sample == (3 + 6 + 12 + 24) / 4.0); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/simple_meshing_tests.cpp b/unittests/tntn/simple_meshing_tests.cpp deleted file mode 100644 index 61e598c..0000000 --- a/unittests/tntn/simple_meshing_tests.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include - -#include "tntn/MeshIO.h" -#include "tntn/Raster.h" -#include "tntn/simple_meshing.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("generate_tin_dense_quadwalk meshing on artificial terrain", "[tntn]") - { - auto terrain_fn = [](int x, int y) -> double { return sin(x) * sin(y); }; - - const int w = 11; - const int h = 20; - const double cellsize = 1.5; - const double raster_xpos = 42; - const double raster_ypos = 23; - - RasterDouble raster; - raster.allocate(w, h); - raster.set_pos_x(raster_xpos); - raster.set_pos_y(raster_ypos); - raster.set_cell_size({ cellsize, cellsize }); - - for (int y = 0; y < h; y++) { - auto row_ptr = raster.get_ptr(y); - for (int x = 0; x < w; x++) { - row_ptr[x] = terrain_fn(x, y); - } - } - - auto general_checks = [&](auto& mesh) { - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - BBox3D bbox; - mesh->get_bbox(bbox); - - CHECK(bbox.min.x == raster_xpos); - CHECK(bbox.min.y == raster_ypos); - CHECK(bbox.max.x == raster_xpos + (w - 1) * cellsize); - CHECK(bbox.max.y == raster_ypos + (h - 1) * cellsize); - }; - - SECTION("with step = 1") - { - auto mesh = generate_tin_dense_quadwalk(raster, 1); - general_checks(mesh); - CHECK(mesh->poly_count() == (w - 1) * (h - 1) * 2); - } - - SECTION("with step = 2") - { - auto mesh = generate_tin_dense_quadwalk(raster, 2); - general_checks(mesh); - CHECK(mesh->poly_count() == (6 - 1) * (11 - 1) * 2); - } - - SECTION("with step = 3") - { - auto mesh = generate_tin_dense_quadwalk(raster, 3); - general_checks(mesh); - CHECK(mesh->poly_count() == (5 - 1) * (8 - 1) * 2); - } - - SECTION("with step = 4") - { - auto mesh = generate_tin_dense_quadwalk(raster, 4); - general_checks(mesh); - CHECK(mesh->poly_count() == (4 - 1) * (6 - 1) * 2); - } - - SECTION("with vertex count = 2") - { - auto mesh = generate_tin_dense_quadwalk(raster, 2, 2); - general_checks(mesh); - CHECK(mesh->poly_count() == 2); - } - - SECTION("with vertex count = 3") - { - auto mesh = generate_tin_dense_quadwalk(raster, 3, 3); - general_checks(mesh); - CHECK(mesh->poly_count() == 4 * 2); - } - - SECTION("with vertex count = 5") - { - auto mesh = generate_tin_dense_quadwalk(raster, 5, 5); - general_checks(mesh); - CHECK(mesh->poly_count() == 16 * 2); - } - - SECTION("with vertex count = 8") - { - auto mesh = generate_tin_dense_quadwalk(raster, 8, 8); - general_checks(mesh); - CHECK(mesh->poly_count() == 49 * 2); - } - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/terra_meshing_tests.cpp b/unittests/tntn/terra_meshing_tests.cpp deleted file mode 100644 index f4606f1..0000000 --- a/unittests/tntn/terra_meshing_tests.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include - -#include -#include -#include - -#include "tntn/MeshIO.h" -#include "tntn/SurfacePoints.h" -#include "tntn/TerraMesh.h" -#include "tntn/geometrix.h" -#include "tntn/terra_meshing.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("terra ccw works", "[tntn]") - { - glm::dvec2 a(0, 0); - glm::dvec2 b(1, 0); - glm::dvec2 c(1, 1); - - CHECK(terra::ccw(a, b, c)); - CHECK(!terra::ccw(a, c, b)); - } - - TEST_CASE("terra meshing on artificial terrain", "[tntn]") - { - auto terrain_fn = [](int x, int y) -> double { return sin(x) * sin(y); }; - - auto sp = std::make_unique(); - - const int w = 10; - const int h = 20; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - sp->push_back({ x, y, terrain_fn(x, y) }); - } - } - - auto mesh = generate_tin_terra(std::move(sp), 0.1); - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - // write_mesh_as_obj("terrain.obj", *mesh); - } - -#if 1 - - TEST_CASE("terra meshing on artificial terrain with missing points (random deletion)", "[tntn]") - { - auto terrain_fn = [](int x, int y) -> double { return 10 * sin(x * 0.1) * sin(y * 0.1); }; - - const int w = 100; - const int h = 200; - - std::vector vertices; - vertices.reserve(h * w); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - vertices.push_back({ x, y, terrain_fn(x, y) }); - } - } - - // remove a sequence of points - std::mt19937 generator(42); // fixed seed - - while (vertices.size() > h * w / 16) { - std::uniform_int_distribution dist(0, vertices.size() - 1); - const size_t point_to_delete = dist(generator); - vertices.erase(vertices.begin() + point_to_delete); - } - - auto sp = std::make_unique(); - sp->load_from_memory(std::move(vertices)); - auto mesh = generate_tin_terra(std::move(sp), 0.1); - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - // write_mesh_as_obj("terrain.obj", *mesh); - } -#endif - -#if 1 - TEST_CASE("terra meshing on artificial terrain with missing points (random insertion)", "[tntn]") - { - auto terrain_fn = [](int x, int y) -> double { return 10 * sin(x * 0.1) * sin(y * 0.1); }; - - const int w = 100; - const int h = 200; - - std::vector vertices; - vertices.reserve(h * w); - std::mt19937 generator(42); // fixed seed - std::uniform_int_distribution dist(0, 16); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - if (dist(generator) == 0) { - vertices.push_back({ x, y, terrain_fn(x, y) }); - } - } - } - - auto sp = std::make_unique(); - sp->load_from_memory(std::move(vertices)); - auto mesh = generate_tin_terra(std::move(sp), 0.1); - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - // write_mesh_as_obj("terrain.obj", *mesh); - } -#endif - - template - static void remove_elements(std::vector& v, std::vector positions_to_remove) - { - size_t num_removed = 0; - - for (size_t i = 0; i < positions_to_remove.size(); i++) { - const size_t pos = positions_to_remove[i]; - const size_t swap_pos = v.size() - 1 - num_removed; - - if (pos >= v.size() || swap_pos >= v.size()) { - continue; - } - - std::swap(v[pos], v[swap_pos]); - - for (size_t k = i + 1; k < positions_to_remove.size(); k++) { - if (positions_to_remove[k] == swap_pos) { - positions_to_remove[k] = pos; - } - } - - num_removed++; - } - v.erase(v.end() - num_removed, v.end()); - } - - TEST_CASE("terra meshing on 5x5 raster with missing points", "[tntn]") - { - - auto terrain_fn = [](int x, int y) -> double { return sin(x) * sin(y); }; - - const int w = 5; - const int h = 5; - - std::vector vertices; - vertices.reserve(h * w); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - vertices.push_back({ x * 2.0, y * 2.0, terrain_fn(x * 2.0, y * 2.0) * 2.0 }); - } - } - -#if 1 - remove_elements(vertices, - { - 0, - w * h - 1, - }); -#endif - - auto sp = std::make_unique(); - sp->load_from_memory(std::move(vertices)); - auto mesh = generate_tin_terra(std::move(sp), 0.001); - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - // write_mesh_as_obj("terrain.obj", *mesh); - } - - TEST_CASE("terra meshing on 2x2 raster with missing point", "[tntn]") - { - - const int w = 2; - const int h = 2; - - std::vector vertices; - vertices.resize(w * h); - vertices[0] = { 0, 0, 0 * w + 0 }; - vertices[1] = { 0, 1, 1 * w + 0 }; - vertices[2] = { 1, 0, 0 * w + 1 }; - vertices[3] = { 1, 1, 1 * w + 1 }; - -#if 1 - remove_elements(vertices, - { - 0, - w * h - 1, - }); -#endif - - auto sp = std::make_unique(); - sp->load_from_memory(std::move(vertices)); - auto mesh = generate_tin_terra(std::move(sp), 0.001); - REQUIRE(mesh != nullptr); - CHECK(mesh->check_tin_properties()); - - // write_mesh_as_obj("terrain.obj", *mesh); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/test_common.cpp b/unittests/tntn/test_common.cpp deleted file mode 100644 index 32288d5..0000000 --- a/unittests/tntn/test_common.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -#include "tntn/logging.h" - -#include "test_common.h" - -bool double_eq(double a, double b, double eps) -{ - bool result = std::abs(a - b) < eps; - - if (!result) { - TNTN_LOG_DEBUG("DOUBLE_EQ TEST FAILED: ({} - {}) > {}", - a, b, eps); - } - - return result; -} - -// Takes a path relative to fixture directory and returns an absolute file path -fs::path fixture_path(const fs::path& fragment) -{ - // ATB_TEST_DATA_DIR is a macro defined via CMakeLists for test suite. - static fs::path base_fixture_path(ATB_TEST_DATA_DIR "/tntn"); - return base_fixture_path / fs::path(fragment); -} diff --git a/unittests/tntn/test_common.h b/unittests/tntn/test_common.h deleted file mode 100644 index 188251a..0000000 --- a/unittests/tntn/test_common.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -namespace fs = std::filesystem; - -bool double_eq(double a, double b, double eps); - -// Takes a path relative to fixture directory and returns an absolute file path -fs::path fixture_path(const fs::path& fragment); diff --git a/unittests/tntn/triangle_indices.cpp b/unittests/tntn/triangle_indices.cpp deleted file mode 100644 index 674290d..0000000 --- a/unittests/tntn/triangle_indices.cpp +++ /dev/null @@ -1,20190 +0,0 @@ -#include "triangle_indices.h" - -namespace tntn { -namespace unittests { - - void init_triangle_list(std::vector& data) - { - - data = { - 20719, 20633, 20715, 20633, 20575, 20715, 20719, 20422, 20633, 20633, 20422, 20575, 20719, - 20816, 20422, 20715, 20816, 20719, 20715, 20952, 20816, 20575, 20903, 20715, 20715, 21270, - 20952, 20816, 20659, 20422, 20952, 20659, 20816, 20903, 21270, 20715, 20903, 21261, 21270, - 20903, 21222, 21261, 21270, 21401, 20952, 20952, 21189, 20659, 21395, 21401, 21270, 20659, - 20525, 20422, 20419, 20525, 20803, 21343, 21395, 21270, 21261, 21343, 21270, 21375, 21343, - 21261, 20575, 20169, 20903, 20903, 21317, 21222, 20039, 20129, 20575, 20039, 20575, 20422, - 21222, 21375, 21261, 19960, 20039, 19912, 20129, 20169, 20575, 21401, 21458, 20952, 21454, - 21446, 21401, 21454, 21401, 21395, 21454, 21395, 21343, 21456, 21454, 21343, 21446, 21458, - 21401, 20129, 20106, 20169, 20051, 20106, 20129, 19912, 20039, 19845, 20039, 20051, 20129, - 21458, 21473, 20952, 21375, 21456, 21343, 21478, 21456, 21375, 19845, 20039, 20422, 21222, - 21478, 21375, 21454, 21590, 21446, 21446, 21590, 21458, 21458, 21570, 21473, 21545, 21590, - 21454, 21545, 21454, 21456, 21605, 21545, 21456, 19960, 20051, 20039, 19970, 20051, 19960, - 21065, 21317, 20903, 21222, 21507, 21478, 20106, 20099, 20169, 20824, 21065, 20903, 20051, - 20099, 20106, 19799, 19845, 20422, 20525, 19799, 20422, 20962, 20525, 20659, 21317, 21507, - 21222, 21478, 21605, 21456, 21685, 21570, 21458, 21501, 21189, 20952, 21695, 21605, 21478, - 19925, 19970, 19960, 20051, 20040, 20099, 19925, 19960, 19912, 19845, 19842, 19912, 19842, - 19925, 19912, 20099, 20071, 20169, 20040, 20071, 20099, 21501, 20952, 21473, 21590, 21698, - 21458, 21545, 21698, 21590, 21887, 21698, 21545, 21698, 21685, 21458, 21633, 21501, 21473, - 19980, 19799, 20525, 21189, 20962, 20659, 21685, 21661, 21570, 19970, 20040, 20051, 19958, - 20040, 19970, 21633, 21473, 21570, 19845, 19766, 19842, 19842, 19735, 19925, 19722, 19958, - 19970, 19645, 19766, 19845, 21189, 21001, 20962, 21086, 21001, 21189, 20824, 20903, 20169, - 21652, 21695, 21507, 20824, 20169, 20287, 21661, 21633, 21570, 20287, 20169, 20071, 19570, - 19673, 19845, 20419, 19980, 20525, 19722, 19970, 19925, 20040, 20017, 20071, 21418, 21086, - 21189, 21507, 21695, 21478, 21605, 21767, 21545, 21652, 21507, 21317, 21685, 21799, 21661, - 21661, 21839, 21633, 21698, 21799, 21685, 21887, 21799, 21698, 19958, 20017, 20040, 19673, - 19645, 19845, 19766, 19735, 19842, 19684, 19735, 19766, 21633, 21671, 21501, 21501, 21418, - 21189, 21736, 21671, 21633, 21769, 21652, 21750, 21695, 21767, 21605, 19645, 19684, 19766, - 20132, 20287, 20071, 21001, 21029, 20962, 20962, 20803, 20525, 20013, 19732, 19980, 21086, - 21029, 21001, 21096, 21029, 21086, 21761, 21767, 21695, 19958, 19946, 20017, 20017, 20132, - 20071, 19892, 19946, 19958, 19496, 19570, 19845, 19673, 19606, 19645, 19645, 19634, 19684, - 21029, 20803, 20962, 21839, 21736, 21633, 19570, 19606, 19673, 19735, 19722, 19925, 19585, - 19722, 19735, 19585, 19735, 19684, 19606, 19634, 19645, 20011, 20132, 20017, 21736, 21782, - 21671, 21671, 21775, 21501, 21652, 21761, 21695, 21769, 21761, 21652, 19634, 19585, 19684, - 21799, 21839, 21661, 21736, 21845, 21782, 22068, 21839, 21799, 21887, 21545, 21767, 21893, - 21887, 21767, 19799, 19496, 19845, 19570, 19525, 19606, 19606, 19525, 19634, 19634, 19493, - 19585, 19372, 19496, 19246, 19946, 20011, 20017, 19966, 20011, 19946, 20287, 20512, 20824, - 20824, 20811, 21065, 20358, 20512, 20287, 20358, 20287, 20201, 21782, 21775, 21671, 21896, - 21775, 21782, 21750, 21652, 21317, 21761, 21893, 21767, 21839, 21845, 21736, 21852, 21893, - 21761, 19431, 19525, 19570, 19525, 19493, 19634, 19585, 19115, 19722, 19722, 19892, 19958, - 19882, 19892, 19758, 20073, 20287, 20132, 20011, 20073, 20132, 19957, 20073, 20011, 21769, - 21852, 21761, 19892, 19966, 19946, 21065, 21750, 21317, 21769, 21889, 21852, 21862, 21750, - 21970, 21845, 21896, 21782, 21330, 21096, 21086, 21750, 21889, 21769, 20073, 20201, 20287, - 20146, 20201, 20073, 20803, 20631, 20419, 20971, 20631, 20803, 21096, 20803, 21029, 20512, - 20625, 20824, 20568, 20625, 20512, 20568, 20512, 20358, 21706, 21501, 21775, 19496, 19431, - 19570, 19525, 19486, 19493, 20377, 20568, 20358, 19892, 19882, 19966, 19966, 19957, 20011, - 19758, 19892, 19722, 21896, 21706, 21775, 19431, 19486, 19525, 19493, 19486, 19585, 20201, - 20377, 20358, 21845, 21921, 21896, 21896, 21809, 21706, 21839, 21921, 21845, 22068, 21921, - 21839, 22068, 21799, 22545, 22062, 21887, 21893, 22062, 21893, 21852, 19882, 19957, 19966, - 20201, 20146, 20377, 21750, 21862, 21889, 21889, 21938, 21852, 21938, 21862, 21970, 19957, - 20146, 20073, 19496, 19372, 19431, 19431, 19416, 19486, 19202, 19496, 19799, 20625, 20811, - 20824, 20568, 20587, 20625, 20620, 20587, 20417, 20587, 20568, 20417, 21706, 21418, 21501, - 21907, 21809, 21896, 21706, 21812, 21418, 19372, 19416, 19431, 19115, 19758, 19722, 21330, - 21210, 21096, 21096, 20971, 20803, 21418, 21330, 21086, 21921, 21907, 21896, 21862, 21938, - 21889, 21970, 21860, 22027, 21103, 20971, 21096, 19980, 19732, 19799, 20013, 19980, 20419, - 19115, 19585, 19486, 19882, 19828, 19957, 19957, 19877, 20146, 21330, 21269, 21210, 21210, - 21103, 21096, 22027, 21860, 22088, 21163, 21103, 21210, 22545, 21799, 21887, 21921, 22051, - 21907, 22062, 21852, 21938, 19372, 19246, 19416, 19202, 19246, 19496, 20587, 20811, 20625, - 20417, 20568, 20377, 20620, 20811, 20587, 20146, 20417, 20377, 20454, 20417, 20146, 21907, - 21926, 21809, 21809, 21926, 21706, 21477, 21372, 21330, 21330, 21372, 21269, 22068, 22051, - 21921, 22174, 22062, 21938, 19416, 19235, 19486, 19159, 19235, 19416, 19758, 19828, 19882, - 19797, 19828, 19746, 22033, 21926, 21907, 21103, 21054, 20971, 20971, 21050, 20631, 20013, - 19669, 19732, 21163, 21054, 21103, 19828, 19877, 19957, 22051, 22033, 21907, 22150, 22033, - 22051, 20620, 20588, 20811, 20417, 20588, 20620, 20745, 20523, 20718, 21477, 21330, 21418, - 21269, 21163, 21210, 19246, 19159, 19416, 19746, 19828, 19758, 19143, 19159, 19246, 21372, - 21163, 21269, 19828, 19797, 19877, 19877, 19798, 20146, 19115, 19486, 19235, 21970, 22027, - 21938, 21970, 21750, 21860, 19159, 19204, 19235, 21054, 21050, 20971, 21163, 21050, 21054, - 21679, 21477, 21418, 21372, 21407, 21163, 21163, 21199, 21050, 21679, 21418, 21812, 22068, - 22150, 22051, 22033, 22150, 21926, 20013, 20419, 20631, 19732, 19202, 19799, 21812, 21706, - 21926, 21477, 21407, 21372, 21391, 21407, 21477, 22027, 22174, 21938, 22062, 22545, 21887, - 22343, 22170, 22150, 20588, 20745, 20811, 20811, 21156, 21065, 20745, 20588, 20523, 20745, - 20772, 20811, 22027, 22078, 22174, 22088, 22078, 22027, 19669, 19202, 19732, 21288, 21199, - 21163, 18999, 19143, 19246, 19159, 19143, 19204, 19204, 19069, 19235, 21993, 21812, 21926, - 21391, 21288, 21407, 22150, 21993, 21926, 22078, 22173, 22174, 21106, 20013, 20631, 21407, - 21288, 21163, 21391, 21477, 21679, 19143, 19069, 19204, 19656, 19746, 19758, 19797, 19798, - 19877, 19069, 19129, 19235, 21943, 21391, 21679, 19746, 19798, 19797, 22150, 22170, 21993, - 22343, 22150, 22068, 19202, 18999, 19246, 19143, 19054, 19069, 19069, 19054, 19129, 20745, - 20718, 20772, 20772, 20941, 20811, 20523, 20588, 20417, 21993, 21929, 21812, 21812, 21848, - 21679, 22104, 21929, 21993, 19129, 19115, 19235, 18930, 19115, 19129, 20454, 20523, 20417, - 21929, 21848, 21812, 20718, 20859, 20772, 22170, 22104, 21993, 21860, 21750, 21065, 22078, - 22221, 22173, 20859, 20941, 20772, 21288, 21284, 21199, 21199, 21172, 21050, 21050, 21106, - 20631, 21391, 21284, 21288, 21249, 21284, 21391, 19746, 19779, 19798, 19798, 19844, 20146, - 19656, 19779, 19746, 22088, 22221, 22078, 18809, 19054, 19143, 20941, 21003, 20811, 19779, - 19844, 19798, 22221, 22277, 22173, 22173, 22322, 22174, 22174, 22322, 22062, 22277, 22322, - 22173, 19316, 19656, 19076, 19779, 19750, 19844, 20718, 20808, 20859, 20859, 20963, 20941, - 20941, 21038, 21003, 20523, 20751, 20718, 20492, 20751, 20523, 21284, 21172, 21199, 21249, - 21172, 21284, 21003, 21156, 20811, 21094, 21156, 21003, 22170, 22217, 22104, 22119, 21989, - 21929, 21929, 21943, 21848, 22258, 22217, 22170, 22597, 22545, 22062, 20454, 20492, 20523, - 20751, 20808, 20718, 19844, 20454, 20146, 22388, 22343, 22068, 19656, 19750, 19779, 19889, - 20373, 20454, 22343, 22258, 22170, 19115, 18983, 19758, 18930, 18983, 19115, 21941, 21249, - 21391, 21943, 21679, 21848, 20963, 21038, 20941, 21989, 21943, 21929, 21929, 22104, 22119, - 19054, 18930, 19129, 18809, 18930, 19054, 21172, 21106, 21050, 21249, 21106, 21172, 21038, - 21094, 21003, 22280, 22285, 22088, 22499, 22388, 22068, 22343, 22374, 22258, 19656, 19667, - 19750, 19750, 19658, 19844, 19592, 19667, 19656, 22221, 22285, 22277, 22277, 22439, 22322, - 22088, 22285, 22221, 21860, 21065, 21156, 22564, 22597, 22062, 22545, 22499, 22068, 22564, - 22062, 22322, 22502, 22439, 22277, 18999, 18809, 19143, 18333, 18809, 18999, 22119, 22104, - 22217, 21943, 22047, 21391, 22374, 22217, 22258, 22420, 22374, 22343, 20808, 20963, 20859, - 21038, 20963, 21094, 20827, 20963, 20808, 20827, 20808, 20751, 20827, 20751, 20492, 22578, - 22499, 22723, 22388, 22420, 22343, 21604, 21860, 21156, 21226, 21156, 21094, 22479, 22420, - 22388, 22346, 22119, 22217, 18983, 18940, 19758, 18820, 18929, 18983, 18820, 18983, 18930, - 22499, 22546, 22388, 22578, 22546, 22499, 22439, 22564, 22322, 22455, 22217, 22374, 21989, - 22047, 21943, 21249, 21720, 21106, 18733, 18820, 18930, 20963, 21226, 21094, 18929, 18940, - 18983, 18769, 18940, 18929, 22546, 22479, 22388, 22420, 22455, 22374, 22578, 22479, 22546, - 19520, 19592, 19340, 19667, 19658, 19750, 21226, 21258, 21156, 22439, 22632, 22564, 22435, - 22502, 22277, 22435, 22277, 22285, 19592, 19658, 19667, 21285, 21217, 21033, 22598, 22455, - 22420, 22513, 22435, 22528, 22723, 22499, 22758, 22479, 22598, 22420, 18809, 18733, 18930, - 18820, 18790, 18929, 22119, 22047, 21989, 22081, 22047, 22119, 18733, 18712, 18820, 21226, - 21217, 21258, 21258, 21604, 21156, 20963, 21217, 21226, 20373, 20492, 20454, 22435, 22471, - 22502, 22502, 22632, 22439, 22578, 22598, 22479, 18712, 18790, 18820, 19520, 19658, 19592, - 21217, 21248, 21258, 22758, 22499, 22545, 22578, 22728, 22598, 22758, 22545, 22850, 19889, - 20454, 19844, 21217, 21285, 21248, 22047, 21941, 21391, 22346, 22081, 22119, 22471, 22632, - 22502, 22850, 22545, 23049, 19658, 19651, 19844, 19520, 19651, 19658, 19592, 19656, 19340, - 22435, 22508, 22471, 22471, 22590, 22632, 22513, 22508, 22435, 22435, 22285, 22528, 18790, - 18769, 18929, 21248, 21333, 21258, 21285, 21333, 21248, 18733, 18695, 18712, 18712, 18546, - 18790, 18790, 18546, 18769, 18620, 18695, 18733, 18620, 18733, 18809, 19656, 19758, 19076, - 18769, 18898, 18940, 22508, 22590, 22471, 22850, 23049, 22998, 22597, 23049, 22545, 22723, - 22728, 22578, 22280, 22088, 21860, 22508, 22554, 22590, 19076, 19758, 18940, 22393, 22280, - 21860, 18898, 19076, 18940, 19316, 19340, 19656, 21033, 21217, 20963, 21333, 21604, 21258, - 19340, 19466, 19520, 19520, 19623, 19651, 21434, 21604, 21333, 22513, 22554, 22508, 22798, - 22564, 22632, 22528, 22554, 22513, 18433, 18620, 18809, 18695, 18546, 18712, 18769, 18748, - 18898, 21285, 21397, 21333, 22280, 22528, 22285, 22758, 22728, 22723, 22598, 22881, 22455, - 22455, 22346, 22217, 19202, 18567, 18999, 18293, 18567, 19202, 19211, 19202, 19669, 22798, - 22632, 22590, 22758, 22834, 22728, 18822, 18936, 19076, 18694, 18748, 18769, 19412, 19211, - 19669, 19412, 19669, 20013, 19316, 19301, 19340, 19301, 19484, 19466, 19076, 19157, 19316, - 19074, 19157, 19076, 22411, 22346, 22582, 19484, 19623, 19520, 19651, 19889, 19844, 19484, - 19520, 19466, 21397, 21434, 21333, 21604, 21655, 21860, 18620, 18546, 18695, 19301, 19466, - 19340, 20373, 20827, 20492, 21285, 21455, 21397, 21397, 21455, 21434, 20735, 20827, 20373, - 22850, 22834, 22758, 22728, 22881, 22598, 18748, 18717, 18898, 18694, 18717, 18748, 21434, - 21565, 21604, 21455, 21565, 21434, 22346, 22249, 22081, 22081, 22228, 22047, 22411, 22249, - 22346, 22834, 22898, 22728, 19157, 19301, 19316, 19074, 19301, 19157, 22249, 22228, 22081, - 18620, 18503, 18546, 18538, 18694, 18769, 18433, 18503, 18620, 18538, 18769, 18546, 18822, - 19076, 18898, 22554, 22798, 22590, 22739, 22798, 22554, 22850, 22979, 22834, 22834, 22979, - 22898, 23053, 22597, 22564, 18822, 18898, 18717, 19465, 19412, 20013, 19623, 19889, 19651, - 19666, 19889, 19623, 19474, 19623, 19484, 21449, 21455, 21285, 21565, 21655, 21604, 22898, - 22881, 22728, 23069, 22881, 22898, 18503, 18538, 18546, 22998, 22979, 22850, 18787, 18822, - 18717, 19299, 19474, 19484, 20032, 20735, 20373, 20827, 21033, 20963, 22799, 22739, 22554, - 23128, 23053, 22564, 22799, 22554, 22528, 22799, 22528, 22764, 19889, 20032, 20373, 18906, - 19074, 19076, 19301, 19299, 19484, 18906, 19076, 18936, 21455, 21572, 21565, 21449, 21572, - 21455, 22582, 22346, 22455, 22363, 22210, 22228, 18333, 18433, 18809, 18503, 18308, 18538, - 18763, 18906, 18936, 19074, 19299, 19301, 22228, 22210, 22047, 22363, 22228, 22249, 22871, - 22564, 22798, 22998, 23023, 22979, 20735, 21033, 20827, 23233, 23049, 22597, 22979, 23122, - 22898, 21572, 21655, 21565, 21541, 21655, 21572, 22764, 22528, 22786, 22739, 22871, 22798, - 22832, 22871, 22739, 23049, 23023, 22998, 18682, 18787, 18717, 18822, 18763, 18936, 18682, - 18717, 18583, 21334, 21449, 21285, 23023, 23122, 22979, 22494, 22363, 22411, 18906, 19050, - 19074, 19074, 19050, 19299, 18912, 19050, 18906, 22411, 22363, 22249, 22378, 22363, 22494, - 18763, 18912, 18906, 22799, 22832, 22739, 22871, 23128, 22564, 18583, 18717, 18694, 18787, - 18763, 18822, 18583, 18694, 18538, 22210, 21941, 22047, 21106, 20994, 20013, 22275, 21941, - 22210, 22799, 22844, 22832, 22786, 22528, 22566, 21449, 21541, 21572, 22870, 22786, 22944, - 21497, 21541, 21449, 18567, 18333, 18999, 18143, 18333, 18567, 18433, 18308, 18503, 18201, - 18286, 18433, 18286, 18308, 18433, 17867, 18583, 18538, 18669, 18763, 18787, 22764, 22844, - 22799, 23141, 23128, 22871, 23049, 23192, 23023, 23023, 23137, 23122, 23233, 23192, 23049, - 22393, 21860, 21655, 22764, 22870, 22844, 22363, 22378, 22210, 22582, 22455, 23006, 21334, - 21497, 21449, 21541, 21646, 21655, 23122, 23069, 22898, 23132, 23069, 23122, 23006, 22455, - 22881, 23192, 23137, 23023, 23005, 22871, 22832, 23053, 23233, 22597, 18669, 18787, 18682, - 18684, 18897, 19050, 21497, 21585, 21541, 18293, 18364, 18567, 18293, 19202, 19211, 18472, - 18669, 18682, 18333, 18201, 18433, 18286, 18178, 18308, 18308, 18222, 18538, 18583, 18472, - 18682, 18030, 18201, 18333, 23413, 23233, 23053, 23192, 23276, 23137, 18201, 18178, 18286, - 22582, 22494, 22411, 22378, 22275, 22210, 22543, 22494, 22649, 21033, 21334, 21285, 21497, - 21334, 21585, 21278, 21334, 21033, 22844, 23005, 22832, 22936, 23005, 22844, 23137, 23132, - 23122, 23069, 23186, 22881, 23475, 23132, 23137, 21585, 21646, 21541, 21554, 21646, 21585, - 18178, 18190, 18308, 22786, 22870, 22764, 22566, 22528, 22280, 22350, 22275, 22378, 18190, - 18222, 18308, 23386, 23276, 23192, 17867, 18472, 18583, 19474, 19666, 19623, 19889, 19666, - 20032, 20522, 20967, 20735, 21174, 21278, 21033, 19230, 19666, 19474, 19230, 19474, 19145, - 19474, 19299, 19049, 23005, 23141, 22871, 22870, 22936, 22844, 23132, 23186, 23069, 23317, - 23186, 23132, 22494, 22543, 22378, 22649, 22494, 22582, 20967, 21033, 20735, 21334, 21439, - 21585, 21646, 22393, 21655, 23030, 23055, 22936, 22659, 22649, 22582, 22393, 22566, 22280, - 22287, 22041, 21941, 22543, 22350, 22378, 18364, 18143, 18567, 18201, 17998, 18178, 18178, - 18027, 18190, 18190, 18027, 18222, 23233, 23386, 23192, 23475, 23317, 23132, 23435, 23413, - 23635, 20522, 20735, 20032, 21720, 20994, 21106, 22287, 21941, 22275, 23413, 23386, 23233, - 22936, 23055, 23005, 23576, 23435, 23635, 23030, 22936, 22870, 23186, 23170, 22881, 23317, - 23170, 23186, 20967, 21174, 21033, 21278, 21392, 21334, 22533, 22608, 22393, 23006, 22659, - 22582, 22649, 22644, 22543, 22644, 22326, 22350, 18472, 18527, 18669, 18669, 18527, 18763, - 19049, 19299, 19050, 17867, 18527, 18472, 23170, 23006, 22881, 22350, 22326, 22275, 22644, - 22350, 22543, 23475, 23137, 23276, 21174, 21294, 21278, 22326, 22287, 22275, 18143, 18030, - 18333, 18222, 17867, 18538, 23055, 23141, 23005, 23208, 23141, 23055, 22041, 21720, 21941, - 22115, 21994, 22041, 22944, 23030, 22870, 18030, 17998, 18201, 23413, 23435, 23386, 23386, - 23453, 23276, 23413, 23053, 23635, 21294, 21392, 21278, 17998, 18027, 18178, 21720, 21249, - 21941, 22668, 22644, 22649, 22385, 22252, 22287, 22668, 22649, 22659, 23435, 23453, 23386, - 22771, 22668, 22861, 21392, 21439, 21334, 21994, 21720, 22041, 21994, 21969, 21720, 22287, - 22115, 22041, 22252, 22115, 22287, 21439, 21554, 21585, 22385, 22287, 22326, 22115, 22057, - 21994, 22063, 22057, 22115, 23030, 23208, 23055, 23635, 23053, 23649, 23215, 23208, 23030, - 22944, 22786, 22566, 18143, 17901, 18030, 18030, 17960, 17998, 17998, 17993, 18027, 17982, - 17901, 18143, 17901, 17960, 18030, 18027, 17760, 18222, 17985, 17982, 18143, 17960, 17993, - 17998, 23435, 23524, 23453, 23453, 23475, 23276, 23880, 23128, 23141, 23730, 23475, 23453, - 23458, 23006, 23170, 23120, 22659, 23006, 22861, 22668, 22659, 18364, 17985, 18143, 17830, - 17985, 17800, 23576, 23524, 23435, 22057, 21969, 21994, 21720, 21445, 20994, 22120, 21969, - 22057, 23208, 23260, 23141, 21439, 21438, 21554, 23016, 22566, 22393, 21392, 21438, 21439, - 21294, 21438, 21392, 21448, 21438, 21294, 21448, 21294, 21174, 22544, 22385, 22326, 22195, - 22063, 22115, 22648, 22326, 22644, 23016, 22944, 22566, 23208, 23245, 23260, 21793, 21646, - 21554, 18277, 18293, 19211, 18277, 19211, 18673, 22195, 22115, 22252, 21829, 21721, 21720, - 21438, 21600, 21554, 22668, 22771, 22644, 22861, 22659, 23120, 20994, 19465, 20013, 23215, - 23245, 23208, 23649, 23053, 23128, 21969, 21829, 21720, 21721, 21445, 21720, 21838, 21829, - 21930, 23120, 23006, 23327, 19049, 19050, 18897, 19666, 19631, 20032, 21424, 21448, 21400, - 22338, 22195, 22252, 22063, 22120, 22057, 22338, 22252, 22385, 17901, 17873, 17960, 17960, - 17873, 17993, 17993, 17760, 18027, 17794, 17873, 17901, 17837, 17901, 17982, 19050, 18912, - 18633, 23387, 23141, 23260, 23576, 23730, 23524, 23524, 23730, 23453, 17985, 17837, 17982, - 17830, 17837, 17985, 17800, 17985, 18364, 23635, 23730, 23576, 19049, 19145, 19474, 23245, - 23387, 23260, 23333, 23387, 23245, 19230, 19419, 19666, 19310, 19419, 19230, 22195, 22120, - 22063, 22099, 22120, 22290, 23880, 23649, 23128, 21591, 21445, 21721, 20994, 20159, 19465, - 21728, 21721, 21829, 21438, 21448, 21600, 23428, 23215, 23571, 21573, 21448, 21424, 21838, - 21728, 21829, 22771, 22820, 22644, 22943, 22820, 22771, 18673, 19211, 19412, 18293, 18079, - 18364, 19145, 19222, 19230, 22944, 23215, 23030, 21676, 21554, 21600, 22820, 22648, 22644, - 22648, 22544, 22326, 21728, 21591, 21721, 21448, 21550, 21600, 19419, 19449, 19666, 19310, - 19449, 19419, 19449, 19631, 19666, 21728, 21641, 21591, 21930, 21829, 21969, 21930, 21969, - 22026, 23327, 23006, 23401, 22861, 22943, 22771, 23006, 23458, 23401, 21742, 21641, 21728, - 21550, 21676, 21600, 17837, 17794, 17901, 17873, 17785, 17993, 17653, 17794, 17837, 17794, - 17785, 17873, 22544, 22338, 22385, 23635, 23823, 23730, 23730, 23822, 23475, 23931, 23823, - 23635, 18842, 18673, 19412, 18107, 18079, 18293, 17830, 17800, 17837, 18107, 18293, 18277, - 22099, 21969, 22120, 21838, 21742, 21728, 22290, 22120, 22195, 22820, 22663, 22648, 22648, - 22663, 22544, 22525, 22325, 22338, 22770, 22663, 22820, 23215, 23333, 23245, 23387, 23498, - 23141, 23513, 23498, 23387, 23823, 23822, 23730, 18633, 18912, 18763, 19049, 18954, 19145, - 19145, 19003, 19222, 19222, 19310, 19230, 18633, 18763, 18457, 23120, 22943, 22861, 17712, - 17800, 18364, 21851, 21742, 21838, 21676, 21793, 21554, 22338, 22290, 22195, 22182, 22290, - 22283, 18897, 18954, 19049, 17619, 17760, 17993, 17760, 17768, 18222, 18954, 19003, 19145, - 19449, 19489, 19631, 21425, 20809, 20994, 21591, 21575, 21445, 21641, 21575, 21591, 21667, - 21575, 21641, 21448, 21573, 21550, 21550, 21573, 21676, 21676, 21658, 21793, 21448, 21174, - 21400, 22099, 22026, 21969, 21930, 21851, 21838, 21742, 21667, 21641, 22182, 22026, 22099, - 23333, 23513, 23387, 24009, 23888, 24103, 18104, 18107, 18277, 19096, 19310, 19222, 21992, - 21851, 21930, 18457, 18763, 18527, 18897, 18807, 18954, 18954, 18807, 19003, 18633, 18684, - 19050, 19003, 19096, 19222, 18985, 19096, 19003, 22663, 22752, 22544, 22916, 22770, 22820, - 23170, 23875, 23458, 23120, 23160, 22943, 22943, 22999, 22820, 21573, 21658, 21676, 23428, - 23333, 23215, 23020, 22999, 22943, 17794, 17653, 17785, 17785, 17619, 17993, 17760, 17615, - 17768, 17583, 17653, 17837, 23888, 23931, 23635, 23823, 23857, 23822, 23822, 24045, 23475, - 23888, 23635, 23649, 23880, 23141, 23498, 19465, 18842, 19412, 18010, 18104, 18277, 18804, - 18807, 18897, 20315, 20522, 20032, 21573, 21674, 21658, 20315, 20032, 19631, 21425, 20994, - 21445, 19465, 18756, 18842, 19310, 19373, 19449, 19245, 19373, 19310, 23333, 23466, 23513, - 23768, 23880, 23498, 23428, 23466, 23333, 22393, 21646, 22533, 17690, 17712, 18364, 17800, - 17641, 17837, 17956, 17911, 18079, 23931, 23857, 23823, 23170, 23317, 23875, 23327, 23160, - 23120, 23857, 23887, 23822, 23251, 23160, 23327, 17768, 17867, 18222, 21658, 21752, 21793, - 21674, 21752, 21658, 17712, 17641, 17800, 21400, 21174, 20967, 18807, 18985, 19003, 19096, - 19245, 19310, 17690, 18364, 18079, 18107, 17956, 18079, 17855, 17956, 17987, 19373, 19489, - 19449, 19356, 19489, 19373, 18970, 19245, 19096, 22290, 22182, 22099, 21992, 21882, 21851, - 21851, 21882, 21742, 22325, 22290, 22338, 23875, 23317, 23475, 23411, 23251, 23327, 22990, - 22916, 22820, 22770, 22752, 22663, 22990, 22820, 22999, 18633, 18604, 18684, 18684, 18804, - 18897, 18807, 18804, 18985, 18449, 18457, 18165, 22916, 22752, 22770, 23020, 22990, 22999, - 23020, 22943, 23160, 21992, 21930, 22026, 21575, 21425, 21445, 18604, 18804, 18684, 23217, - 23020, 23160, 18052, 18104, 18010, 22525, 22338, 22544, 21882, 21667, 21742, 21424, 21674, - 21573, 23612, 23428, 23665, 21532, 21674, 21424, 17690, 18079, 17911, 19489, 19502, 19631, - 19356, 19502, 19489, 20522, 21400, 20967, 22694, 22525, 22544, 23411, 23327, 23401, 23768, - 23498, 23513, 23888, 24009, 23931, 23931, 23983, 23857, 23857, 24055, 23887, 24037, 24009, - 24103, 17571, 17583, 17837, 17653, 17619, 17785, 17768, 17617, 17867, 17571, 17837, 17641, - 22325, 22283, 22290, 22116, 21992, 22026, 21882, 21792, 21667, 22257, 22283, 22342, 23428, - 23571, 23665, 23466, 23595, 23513, 24009, 23983, 23931, 24045, 23875, 23475, 17618, 17571, - 17641, 17497, 17619, 17653, 17462, 17618, 17517, 18985, 18970, 19096, 19245, 19356, 19373, - 18804, 18970, 18985, 21667, 21425, 21575, 21686, 21425, 21667, 23589, 23411, 23401, 18457, - 18604, 18633, 18804, 18574, 18970, 18481, 18604, 18457, 19502, 20315, 19631, 21304, 21332, - 21400, 22752, 22825, 22544, 22841, 22825, 22752, 22931, 22752, 22916, 22931, 22916, 22990, - 23046, 22990, 23020, 23217, 23160, 23251, 17619, 17615, 17760, 17956, 17855, 17911, 17987, - 17956, 18107, 22116, 22026, 22182, 23428, 23595, 23466, 22825, 22694, 22544, 22257, 22182, - 22283, 22257, 22116, 22182, 23450, 23217, 23251, 17787, 17690, 17911, 17513, 17517, 17641, - 17855, 17787, 17911, 17615, 17586, 17768, 18449, 18481, 18457, 19266, 19356, 19245, 20003, - 20268, 20315, 22283, 22325, 22422, 21992, 21916, 21882, 18104, 17987, 18107, 17658, 17635, - 17787, 18052, 17987, 18104, 22422, 22325, 22525, 23428, 23612, 23595, 23595, 23639, 23513, - 21646, 21793, 22533, 22044, 21916, 21992, 17584, 17590, 17712, 17584, 17712, 17690, 18604, - 18487, 18804, 18970, 19266, 19245, 18457, 18527, 18165, 21400, 21332, 21424, 21387, 21332, - 21304, 23046, 22931, 22990, 22825, 22841, 22694, 22686, 22422, 22525, 17583, 17497, 17653, - 17619, 17503, 17615, 17615, 17528, 17586, 17376, 17497, 17583, 17515, 17583, 17571, 17515, - 17571, 17618, 18165, 18527, 18060, 22931, 22841, 22752, 23217, 23046, 23020, 23253, 23046, - 23217, 24009, 24037, 23983, 23983, 24055, 23857, 24103, 23888, 23649, 24037, 24097, 23983, - 23458, 23589, 23401, 17462, 17515, 17618, 18010, 18277, 18673, 22686, 22525, 22694, 17787, - 17635, 17690, 17658, 17787, 17855, 21916, 21792, 21882, 24045, 23822, 23887, 23411, 23450, - 23251, 17517, 17618, 17641, 24097, 24055, 23983, 17582, 17584, 17690, 17513, 17641, 17712, - 17586, 17617, 17768, 17461, 17617, 17586, 19097, 18756, 19465, 18842, 18756, 18673, 17382, - 17503, 17619, 23880, 24103, 23649, 24302, 24103, 24537, 19200, 19266, 18970, 19356, 19352, - 19502, 23875, 23645, 23458, 23612, 23639, 23595, 22116, 22044, 21992, 21916, 21949, 21792, - 22155, 22044, 22116, 22155, 22116, 22257, 17513, 17712, 17590, 22422, 22342, 22283, 22472, - 22342, 22422, 22533, 21793, 22092, 23612, 23665, 23639, 21793, 21752, 22092, 23713, 23589, - 23458, 17613, 17582, 17690, 17458, 17513, 17590, 17458, 17590, 17370, 17503, 17528, 17615, - 17662, 18010, 18673, 18052, 17935, 17987, 17351, 17613, 17280, 17635, 17613, 17690, 22092, - 21752, 21995, 18481, 18487, 18604, 18340, 18487, 18481, 18340, 18481, 18449, 17356, 17458, - 17370, 22381, 22155, 22257, 21693, 21686, 21788, 21995, 21752, 21674, 23639, 23768, 23513, - 23879, 23768, 23639, 24055, 24045, 23887, 17809, 17855, 17987, 17356, 17385, 17458, 21792, - 21686, 21667, 20877, 20691, 20809, 21985, 21916, 22044, 23645, 23713, 23458, 23531, 23450, - 23411, 23748, 23713, 23645, 23748, 23645, 23930, 18060, 18527, 17628, 18010, 17935, 18052, - 21304, 21400, 20522, 21332, 21442, 21424, 20809, 20159, 20994, 20877, 20809, 21425, 23010, - 22686, 22694, 22106, 21985, 22155, 23010, 22694, 22841, 23010, 22841, 22931, 23183, 22931, - 23046, 24037, 24221, 24097, 24097, 24174, 24055, 24055, 24242, 24045, 24302, 24221, 24037, - 17515, 17376, 17583, 17240, 17382, 17619, 17503, 17358, 17528, 17462, 17376, 17515, 17430, - 17376, 17462, 17430, 17462, 17517, 17430, 17517, 17406, 24221, 24174, 24097, 21514, 20877, - 21425, 17617, 17454, 17867, 17528, 17461, 17586, 17443, 17461, 17528, 21387, 21442, 21332, - 23531, 23411, 23589, 22155, 21985, 22044, 22106, 22155, 22262, 17406, 17517, 17513, 17406, - 17513, 17385, 17240, 17619, 17497, 23571, 23215, 22944, 17385, 17513, 17458, 17382, 17358, - 17503, 20372, 20159, 20809, 18165, 18340, 18449, 19152, 19200, 19030, 18247, 18340, 18165, - 21442, 21532, 21424, 17935, 17809, 17987, 18010, 17977, 17935, 17662, 17977, 18010, 22686, - 22472, 22422, 23748, 23531, 23589, 23748, 23589, 23713, 23525, 23571, 22944, 23697, 23571, - 23839, 23450, 23253, 23217, 22686, 22646, 22472, 23271, 23253, 23374, 17590, 17584, 17370, - 17977, 17809, 17935, 17370, 17584, 17423, 19266, 19352, 19356, 18574, 18804, 18487, 19238, - 19352, 19266, 21788, 21686, 21792, 21686, 21693, 21425, 22381, 22257, 22342, 23930, 23645, - 23875, 24017, 23930, 23875, 17584, 17582, 17423, 17461, 17454, 17617, 17380, 17454, 17461, - 21177, 21304, 20522, 21387, 21373, 21442, 21442, 21471, 21532, 20268, 20522, 20315, 21949, - 21916, 21985, 22127, 21949, 21985, 23571, 23697, 23665, 23665, 23879, 23639, 17628, 18527, - 17867, 17423, 17582, 17613, 24221, 24245, 24174, 24407, 24242, 24055, 24074, 24017, 23875, - 24302, 24245, 24221, 24302, 24037, 24103, 24302, 24364, 24402, 21949, 21788, 21792, 21693, - 21514, 21425, 22486, 22381, 22342, 22821, 22646, 22686, 24560, 23880, 23768, 17809, 17658, - 17855, 17280, 17658, 17032, 19200, 19238, 19266, 20003, 20315, 19965, 19152, 19238, 19200, - 23760, 23879, 23665, 18340, 18414, 18487, 18324, 18414, 18340, 22486, 22342, 22472, 22106, - 22127, 21985, 21949, 21951, 21788, 17328, 17423, 17351, 17312, 17443, 17528, 20691, 20372, - 20809, 20734, 20372, 20691, 20734, 20691, 20877, 21516, 21514, 21693, 21532, 21995, 21674, - 22092, 22992, 22533, 21471, 21995, 21532, 23183, 23010, 22931, 24074, 24291, 24150, 23930, - 23980, 23748, 20315, 19896, 19965, 22646, 22486, 22472, 22596, 22486, 22646, 17406, 17326, - 17430, 17061, 17254, 17376, 17240, 17299, 17382, 17382, 17299, 17358, 17358, 17312, 17528, - 17385, 17326, 17406, 17309, 17326, 17385, 17309, 17385, 17356, 17309, 17356, 17283, 17254, - 17497, 17376, 17443, 17380, 17461, 17454, 17386, 17867, 17333, 17380, 17443, 21703, 21516, - 21693, 20840, 20734, 20877, 21703, 21693, 21788, 23010, 22821, 22686, 17283, 17356, 17370, - 17299, 17312, 17358, 19238, 19325, 19352, 19030, 19200, 18970, 20159, 19907, 19465, 20310, - 20133, 20159, 21195, 21177, 21117, 21304, 21373, 21387, 22381, 22262, 22155, 22297, 22262, - 22320, 24407, 24055, 24174, 22180, 22127, 22106, 24017, 23945, 23930, 23748, 23951, 23531, - 23271, 23046, 23253, 23271, 23183, 23046, 24128, 23945, 24017, 23697, 23760, 23665, 23839, - 23760, 23697, 23016, 22393, 22608, 17380, 17442, 17454, 17333, 17442, 17380, 21177, 21262, - 21304, 22008, 21951, 21949, 24254, 23875, 24045, 18414, 18574, 18487, 18247, 18324, 18340, - 23253, 23450, 23374, 23010, 22938, 22821, 23183, 23102, 23010, 22992, 23016, 22608, 23624, - 23016, 23216, 23374, 23558, 23437, 22821, 22596, 22646, 22622, 22320, 22381, 22908, 22596, - 22821, 21262, 21373, 21304, 23102, 22938, 23010, 23374, 23450, 23558, 24242, 24240, 24045, - 17442, 17386, 17454, 17762, 18247, 18165, 17333, 17386, 17442, 19152, 19325, 19238, 19150, - 19325, 19152, 22262, 22180, 22106, 22127, 22008, 21949, 22297, 22180, 22262, 23945, 23980, - 23930, 24128, 23980, 23945, 17061, 17376, 17430, 17299, 17220, 17312, 17270, 17430, 17326, - 20840, 20877, 20853, 20372, 20310, 20159, 24245, 24437, 24174, 24242, 24429, 24240, 24402, - 24437, 24245, 24402, 24245, 24302, 24364, 24302, 24537, 17254, 17208, 17497, 17312, 17288, - 17443, 18305, 18574, 18414, 24391, 24103, 23880, 17208, 17240, 17497, 22180, 22008, 22127, - 21951, 21864, 21788, 17423, 17328, 17370, 17309, 17270, 17326, 17351, 17423, 17613, 21373, - 21471, 21442, 24240, 24254, 24045, 24074, 24128, 24017, 24552, 24254, 24240, 23525, 23839, - 23571, 23760, 23985, 23879, 24560, 24391, 23880, 20642, 20310, 20372, 21945, 21864, 21951, - 21516, 21475, 21514, 17283, 17270, 17309, 17240, 17220, 17299, 17328, 17283, 17370, 17285, - 17351, 17280, 24437, 24407, 24174, 19030, 19150, 19152, 20315, 19502, 19896, 23878, 23985, - 23760, 24155, 24128, 24074, 23980, 23951, 23748, 17296, 17628, 17867, 18680, 19030, 18970, - 23839, 23878, 23760, 23843, 23878, 23839, 17220, 17288, 17312, 18110, 18247, 17762, 18324, - 18305, 18414, 19007, 19122, 19030, 18247, 18305, 18324, 21177, 21195, 21262, 21262, 21271, - 21373, 21373, 21271, 21471, 21117, 21177, 20522, 23183, 23311, 23102, 23102, 23071, 22938, - 22938, 22908, 22821, 23271, 23307, 23183, 23437, 23307, 23271, 23311, 23307, 23437, 24407, - 24429, 24242, 24291, 24074, 23875, 23311, 23071, 23102, 17147, 17333, 17443, 17386, 17296, - 17867, 21864, 21703, 21788, 22008, 21945, 21951, 21864, 21705, 21703, 21958, 21945, 21982, - 22297, 22008, 22180, 22262, 22381, 22320, 24155, 24150, 24322, 20133, 19907, 20159, 20202, - 20025, 20133, 19502, 19561, 19896, 20924, 21117, 20522, 21195, 21271, 21262, 24560, 23768, - 24567, 23016, 23525, 22944, 17156, 17283, 17328, 20025, 19947, 20133, 19502, 19352, 19561, - 24107, 23951, 23980, 24132, 23980, 24128, 23985, 24079, 23879, 23878, 23952, 23985, 23995, - 23952, 23878, 24155, 24132, 24128, 17333, 17308, 17386, 17258, 17308, 17333, 17254, 17185, - 17208, 17208, 17144, 17240, 17240, 17144, 17220, 17220, 17141, 17288, 17086, 17185, 17254, - 17086, 17254, 17061, 20734, 20642, 20372, 20310, 20202, 20133, 20025, 20035, 19947, 20840, - 20642, 20734, 23914, 23843, 23839, 24150, 24155, 24074, 24291, 23875, 24254, 20853, 20877, - 21074, 17185, 17144, 17208, 17288, 17147, 17443, 21074, 20877, 21514, 24391, 24537, 24103, - 24364, 24537, 24402, 24402, 24698, 24437, 24437, 24464, 24407, 24407, 24464, 24429, 19947, - 19907, 20133, 19929, 19907, 19947, 19561, 19352, 19325, 21612, 21475, 21516, 21612, 21516, - 21703, 23307, 23311, 23183, 22320, 22622, 22416, 23437, 23271, 23374, 21475, 21074, 21514, - 24372, 24291, 24495, 22908, 22938, 23071, 21705, 21612, 21703, 23558, 23450, 23701, 24132, - 24107, 23980, 23701, 23450, 23787, 24322, 24107, 24132, 24094, 24107, 24146, 23952, 24079, - 23985, 24210, 24079, 23952, 21958, 21864, 21945, 21042, 20981, 21074, 17144, 17141, 17220, - 20277, 20202, 20310, 21126, 21117, 20924, 21195, 21170, 21271, 20089, 20268, 20003, 20089, - 20003, 19982, 23843, 23995, 23878, 24201, 23995, 24147, 24994, 24464, 24437, 24429, 24489, - 24240, 23450, 23531, 23787, 17141, 17133, 17288, 19982, 20003, 19965, 21117, 21170, 21195, - 21271, 21254, 21471, 22198, 22589, 21995, 19106, 19561, 19325, 19896, 19914, 19965, 19122, - 19325, 19150, 21982, 21945, 22008, 17280, 17613, 17635, 17351, 17156, 17328, 17283, 17119, - 17270, 17280, 17635, 17658, 23303, 22908, 23071, 23787, 23531, 24042, 20202, 20035, 20025, - 24464, 24489, 24429, 19030, 19122, 19150, 18680, 18970, 18574, 22381, 22486, 22622, 22128, - 21982, 22008, 24107, 24094, 23951, 24322, 24132, 24155, 18185, 18680, 18574, 18275, 18574, - 18305, 24042, 23531, 23951, 17156, 17119, 17283, 20035, 19929, 19947, 19907, 19701, 19465, - 24489, 24552, 24240, 24291, 24322, 24150, 17108, 17280, 17101, 17285, 17156, 17351, 21870, - 21705, 21864, 21042, 21074, 21115, 21870, 21864, 21958, 17308, 17296, 17386, 17762, 18165, - 18060, 17258, 17296, 17308, 18247, 18110, 18305, 18105, 18110, 17990, 22293, 22008, 22297, - 24372, 24322, 24291, 18110, 18275, 18305, 23016, 23485, 23525, 23525, 23914, 23839, 23624, - 23485, 23016, 22608, 22533, 22992, 20642, 20277, 20310, 20202, 20090, 20035, 20035, 20047, - 19929, 20840, 20640, 20642, 20821, 20640, 20840, 20821, 20840, 20853, 20821, 20853, 20981, - 17061, 17430, 17270, 17185, 16953, 17144, 17144, 16925, 17141, 17141, 16962, 17133, 20981, - 20853, 21074, 17096, 17156, 17285, 16956, 17061, 17270, 19825, 19914, 19896, 23437, 23335, - 23311, 23311, 23335, 23071, 23558, 23609, 23437, 23683, 23609, 23558, 23683, 23558, 23701, - 24552, 24460, 24254, 24537, 24590, 24402, 24703, 24552, 24489, 24703, 24460, 24552, 24760, - 24601, 24460, 24670, 24590, 24537, 24670, 24537, 24391, 16956, 17270, 17119, 24787, 24670, - 24841, 17147, 17258, 17333, 21982, 21870, 21958, 21074, 21475, 21115, 24495, 24291, 24254, - 22320, 22293, 22297, 21982, 22225, 21870, 22416, 22293, 22320, 23781, 23683, 23701, 23781, - 23701, 23787, 18680, 19007, 19030, 19122, 19106, 19325, 19561, 19825, 19896, 20640, 20277, - 20642, 17133, 17147, 17288, 16954, 17147, 17133, 19929, 19860, 19907, 17402, 17190, 17977, - 19924, 19860, 19929, 19870, 19825, 19839, 22293, 22128, 22008, 24460, 24469, 24254, 24601, - 24469, 24460, 21117, 21126, 21170, 21170, 21254, 21271, 20924, 20522, 20268, 20224, 20268, - 20089, 20128, 20089, 19982, 24026, 23781, 23787, 20277, 20090, 20202, 19982, 19965, 19914, - 17258, 17197, 17296, 17296, 17216, 17628, 17129, 17197, 17258, 19860, 19764, 19907, 19809, - 19764, 19860, 24469, 24495, 24254, 24601, 24495, 24469, 23684, 23335, 23437, 22203, 22184, - 22293, 23684, 23437, 23609, 23618, 23609, 23683, 24008, 23914, 23525, 23995, 24210, 23952, - 19007, 19106, 19122, 19072, 19106, 19052, 19106, 19007, 19052, 20090, 20047, 20035, 21126, - 21254, 21170, 24201, 24210, 23995, 24567, 23768, 23879, 22293, 22184, 22128, 22128, 22203, - 21982, 22486, 22596, 22622, 24094, 24042, 23951, 24146, 24042, 24094, 24352, 24107, 24322, - 24352, 24322, 24372, 19764, 19701, 19907, 19653, 19701, 19764, 20047, 19936, 19929, 19870, - 19982, 19914, 19870, 19914, 19825, 23770, 23618, 23683, 23770, 23683, 23781, 17197, 17209, - 17296, 17182, 17209, 17197, 24518, 24352, 24372, 24026, 23770, 23781, 17086, 16953, 17185, - 17147, 17129, 17258, 16910, 16953, 17086, 16910, 17086, 16786, 24590, 24698, 24402, 24787, - 24698, 24590, 24787, 24590, 24670, 19936, 19924, 19929, 19839, 19825, 19738, 22622, 22596, - 22908, 24283, 24146, 24107, 24042, 24200, 23787, 24841, 24670, 24391, 24147, 23995, 23843, - 17046, 17129, 17147, 21296, 21108, 21115, 20821, 20672, 20640, 20272, 20139, 20277, 20277, - 20139, 20090, 20090, 20127, 20047, 20047, 20127, 19936, 19936, 19809, 19924, 21612, 21296, - 21475, 20502, 20924, 20268, 21126, 21214, 21254, 20224, 20089, 20128, 20224, 20128, 20217, - 23879, 24079, 24567, 16953, 16925, 17144, 17209, 17216, 17296, 17118, 17216, 17209, 20217, - 20128, 20043, 21612, 21705, 21883, 22805, 22622, 22932, 17108, 17096, 17285, 17156, 17096, - 17119, 17108, 17285, 17280, 16925, 16962, 17141, 18110, 18105, 18275, 18275, 18185, 18574, - 17762, 18060, 17711, 20457, 20277, 20640, 20043, 20128, 19982, 21883, 21705, 21870, 20924, - 21142, 21126, 18105, 18232, 18275, 17129, 17182, 17197, 16876, 17182, 17129, 24352, 24283, - 24107, 24654, 24518, 24372, 24654, 24372, 24495, 16962, 16954, 17133, 20139, 20127, 20090, - 21142, 21214, 21126, 23021, 22992, 22589, 23618, 23684, 23609, 23335, 23303, 23071, 23754, - 23684, 23618, 23754, 23618, 23770, 17101, 17280, 17065, 17096, 16956, 17119, 16954, 17046, - 17147, 24703, 24489, 24464, 24567, 24079, 24455, 19106, 19072, 19561, 19052, 19007, 18831, - 22442, 22203, 22293, 22184, 22203, 22128, 22622, 22514, 22416, 22583, 22514, 22622, 24146, - 24184, 24042, 24283, 24184, 24146, 23914, 24147, 23843, 24201, 24303, 24210, 17711, 18060, - 17628, 22442, 22293, 22416, 24026, 23754, 23770, 16945, 16956, 17096, 19870, 20043, 19982, - 19839, 20043, 19870, 25118, 24703, 24464, 17108, 16945, 17096, 17065, 17280, 17032, 16971, - 16992, 17032, 17182, 17118, 17209, 17592, 17711, 17298, 17081, 17118, 17182, 17176, 17628, - 17216, 19701, 19097, 19465, 19724, 19653, 19764, 19809, 19860, 19924, 24518, 24492, 24352, - 24747, 24492, 24518, 24601, 24654, 24495, 24760, 24654, 24601, 16786, 17086, 17061, 16730, - 16836, 16925, 16925, 16836, 16962, 16962, 16836, 16954, 19738, 19825, 19561, 19035, 19052, - 18947, 20981, 20672, 20821, 20139, 20110, 20127, 20865, 20672, 20981, 20865, 20981, 21067, - 22514, 22442, 22416, 22583, 22442, 22514, 24492, 24283, 24352, 24184, 24200, 24042, 24147, - 24303, 24201, 20427, 20502, 20268, 20924, 21016, 21142, 21142, 21194, 21214, 20427, 20268, - 20224, 20427, 20224, 20357, 17762, 17990, 18110, 18126, 18185, 18232, 18232, 18185, 18275, - 17664, 17990, 17762, 20672, 20457, 20640, 20110, 19809, 19936, 20357, 20224, 20143, 20502, - 20905, 20924, 24787, 24810, 24698, 24698, 24994, 24437, 24841, 24810, 24787, 24356, 24200, - 24184, 18036, 18232, 18105, 20457, 20371, 20277, 20143, 20224, 20217, 23528, 23303, 23335, - 23528, 23335, 23684, 20371, 20272, 20277, 20905, 21016, 20924, 24885, 24841, 24391, 16957, - 16945, 17108, 16744, 16786, 17061, 20110, 19936, 20127, 19135, 19561, 19072, 20043, 20143, - 20217, 23754, 23743, 23684, 23987, 23743, 23754, 16769, 16925, 16953, 16954, 16818, 17046, - 17081, 17216, 17118, 20176, 20143, 20043, 17658, 17190, 17032, 17101, 16957, 17108, 24455, - 24079, 24210, 24890, 24885, 24391, 19153, 19097, 19701, 19153, 19701, 19510, 19052, 19135, - 19072, 19035, 19135, 19052, 16836, 16818, 16954, 20272, 20110, 20139, 24510, 24455, 24210, - 24147, 24279, 24303, 24321, 24279, 24147, 24321, 24147, 23914, 16945, 16808, 16956, 16972, - 16957, 17101, 19809, 19724, 19764, 19581, 19724, 19590, 19657, 19738, 19619, 19839, 19807, - 20043, 24703, 24760, 24460, 24654, 24739, 24518, 24492, 24356, 24283, 24850, 24760, 24908, - 24363, 24210, 24303, 24176, 24026, 23787, 16986, 16972, 17101, 17658, 17809, 17190, 24455, - 24674, 24567, 25017, 24921, 24841, 16986, 17101, 17065, 16828, 16808, 16945, 17990, 18036, - 18105, 18947, 19052, 18831, 17927, 18036, 17676, 23743, 23528, 23684, 23811, 23528, 23974, - 16828, 16945, 16957, 18036, 18126, 18232, 23485, 24008, 23525, 22992, 22092, 21995, 22198, - 22584, 22589, 19097, 18986, 18756, 19083, 18986, 19097, 19007, 18680, 18831, 19723, 19807, - 19738, 24279, 24363, 24303, 24455, 24566, 24674, 24405, 24363, 24279, 17081, 17176, 17216, - 17711, 17664, 17762, 17081, 17182, 16876, 19510, 19701, 19653, 22225, 21883, 21870, 20489, - 20520, 20672, 22442, 22243, 22203, 22373, 22243, 22442, 22583, 22622, 22805, 22622, 22908, - 22932, 20502, 20630, 20905, 20905, 20993, 21016, 20467, 20630, 20502, 20467, 20502, 20427, - 20467, 20427, 20357, 20467, 20357, 20176, 16910, 16791, 16953, 16836, 16691, 16818, 16499, - 16791, 16910, 17592, 17664, 17711, 20672, 20520, 20457, 20457, 20469, 20371, 20371, 20263, - 20272, 20272, 20199, 20110, 20981, 21042, 21067, 16927, 16986, 17065, 16851, 16828, 16957, - 22225, 21982, 22203, 24760, 24739, 24654, 24325, 24176, 24200, 24200, 24176, 23787, 24855, - 24739, 24760, 16744, 17061, 16956, 20176, 20357, 20143, 21067, 21042, 21115, 20630, 20901, - 20905, 21016, 21194, 21142, 24810, 24921, 24698, 24841, 24921, 24810, 24391, 24560, 24890, - 16876, 17129, 17046, 24645, 24566, 24455, 24762, 24560, 24567, 16687, 16744, 16956, 16791, - 16769, 16953, 16540, 16876, 17046, 20901, 20993, 20905, 22932, 22908, 23044, 24356, 24184, - 24283, 24026, 23987, 23754, 17284, 17711, 17628, 24207, 23987, 24026, 23624, 24008, 23485, - 16769, 16730, 16925, 16851, 16957, 16972, 16644, 16687, 16956, 19738, 19807, 19839, 19723, - 19738, 19657, 20345, 20263, 20371, 20110, 20105, 19809, 21108, 21067, 21115, 20993, 21013, - 21016, 20263, 20199, 20272, 19188, 19083, 19153, 20098, 20176, 20005, 21296, 21115, 21475, - 24762, 24567, 24674, 17032, 16927, 17065, 16831, 16851, 16972, 16992, 16927, 17032, 19153, - 19083, 19097, 19510, 19653, 19581, 19581, 19653, 19724, 22243, 22225, 22203, 22522, 22373, - 22442, 22522, 22442, 22583, 22633, 22522, 22583, 24975, 24356, 24492, 24363, 24510, 24210, - 24442, 24405, 24279, 24540, 24510, 24363, 24739, 24747, 24518, 24855, 24747, 24739, 24778, - 24762, 24674, 24778, 24674, 24566, 23044, 22908, 23303, 22805, 22732, 22583, 21194, 21254, - 21214, 16831, 16972, 16986, 16644, 16956, 16808, 19738, 19561, 19619, 20005, 20176, 20043, - 20199, 20105, 20110, 21013, 21194, 21016, 22234, 22225, 22243, 24387, 24325, 24200, 24176, - 24247, 24026, 24061, 24321, 23914, 24661, 24645, 24455, 24908, 24760, 24703, 24762, 24805, - 24560, 21883, 21296, 21612, 21053, 21296, 21359, 16813, 16831, 16986, 16644, 16808, 16639, - 19619, 19561, 19135, 19723, 19754, 19807, 24850, 24855, 24760, 24494, 24387, 24356, 24933, - 24855, 24850, 24805, 24890, 24560, 24325, 24284, 24176, 24356, 24387, 24200, 24345, 24387, - 24494, 24321, 24442, 24279, 24405, 24540, 24363, 24510, 24661, 24455, 24589, 24442, 24432, - 19231, 19188, 19153, 22373, 22234, 22243, 22225, 22248, 21883, 22352, 22234, 22373, 22633, - 22373, 22522, 24634, 24661, 24510, 24645, 24778, 24566, 24762, 24807, 24805, 24805, 24905, - 24890, 22932, 22732, 22805, 24345, 24284, 24325, 16927, 16813, 16986, 16808, 16828, 16639, - 16838, 16813, 16927, 19590, 19724, 19809, 19510, 19231, 19153, 19657, 19754, 19723, 18995, - 19619, 19135, 20630, 20737, 20901, 20901, 20852, 20993, 20993, 21028, 21013, 21013, 21028, - 21194, 20513, 20737, 20630, 20513, 20630, 20467, 20513, 20467, 20478, 23267, 23044, 23303, - 22932, 23026, 22732, 23383, 23303, 23580, 23303, 23528, 23580, 24008, 24061, 23914, 23624, - 24061, 24008, 24432, 24061, 24408, 24921, 24994, 24698, 25017, 24994, 24921, 25017, 24841, - 24885, 17190, 17809, 17977, 20520, 20469, 20457, 20263, 20252, 20199, 20199, 20190, 20105, - 20105, 19590, 19809, 20762, 20489, 20672, 20762, 20672, 20865, 20762, 20865, 20886, 20865, - 21067, 20886, 20478, 20467, 20176, 20886, 21067, 21053, 20737, 20786, 20901, 24720, 24778, - 24645, 20489, 20469, 20520, 20291, 20478, 20176, 20786, 20852, 20901, 20469, 20345, 20371, - 24980, 25017, 24885, 25073, 24908, 24703, 24494, 24356, 24975, 20345, 20252, 20263, 20852, - 21028, 20993, 23021, 23216, 22992, 17662, 18673, 18756, 18778, 18756, 18986, 19067, 18986, - 19083, 19035, 18995, 19135, 18831, 18680, 18437, 24442, 24540, 24405, 24661, 24720, 24645, - 24589, 24540, 24442, 17176, 17284, 17628, 17026, 17093, 17176, 17026, 17176, 17081, 19188, - 19067, 19083, 19059, 19067, 19188, 24540, 24634, 24510, 16828, 16851, 16639, 16911, 16838, - 16927, 16911, 16927, 16992, 16540, 17046, 16818, 23528, 23743, 23974, 24778, 24807, 24762, - 24890, 24980, 24885, 24866, 24807, 24778, 16851, 16831, 16639, 16744, 16568, 16786, 16786, - 16499, 16910, 16557, 16730, 16769, 16557, 16691, 16730, 16730, 16691, 16836, 16557, 16769, - 16495, 20252, 20190, 20199, 24387, 24345, 24325, 24284, 24247, 24176, 24933, 24747, 24855, - 25141, 24980, 25132, 16876, 17026, 17081, 19440, 19231, 19510, 24695, 24720, 24661, 19709, - 19754, 19657, 19709, 19657, 19619, 23383, 23267, 23303, 23044, 23026, 22932, 24944, 24905, - 24805, 24385, 24247, 24284, 16639, 16831, 16575, 23267, 23196, 23044, 22992, 23216, 23016, - 23021, 22589, 23189, 16781, 16911, 16992, 16575, 16831, 16813, 19581, 19440, 19510, 19535, - 19440, 19581, 18947, 18995, 19035, 18935, 18995, 18947, 19564, 19709, 19619, 20599, 20626, - 20580, 24908, 24933, 24850, 25023, 24933, 24908, 25132, 24980, 24890, 24807, 24944, 24805, - 24948, 24944, 24807, 19067, 18827, 18986, 18814, 18827, 19067, 19059, 19188, 19231, 18307, - 18680, 18185, 22732, 22633, 22583, 21053, 21108, 21296, 22636, 22860, 22670, 17190, 16971, - 17032, 24634, 24695, 24661, 24720, 24866, 24778, 24727, 24695, 24634, 25118, 25073, 24703, - 23196, 23026, 23044, 22992, 21995, 22589, 24247, 24207, 24026, 17093, 17284, 17176, 17676, - 17990, 17664, 17676, 18036, 17990, 18036, 17927, 18126, 18126, 18008, 18185, 17027, 17284, - 17093, 24247, 24353, 24207, 24345, 24385, 24284, 24494, 24385, 24345, 17676, 17664, 17417, - 23811, 23580, 23528, 23383, 23446, 23267, 23267, 23214, 23196, 23196, 23214, 23026, 18278, - 17662, 18756, 16725, 16781, 16971, 17927, 18008, 18126, 19440, 19409, 19231, 19450, 19409, - 19440, 20175, 19590, 20105, 23580, 23502, 23383, 24823, 24866, 24720, 20762, 20596, 20489, - 20489, 20505, 20469, 20469, 20442, 20345, 20345, 20311, 20252, 20252, 20311, 20190, 20190, - 20175, 20105, 20698, 20596, 20762, 20513, 20626, 20737, 20737, 20711, 20786, 20786, 20898, - 20852, 20852, 20898, 21028, 20478, 20626, 20513, 20043, 19807, 20005, 20596, 20505, 20489, - 17284, 17298, 17711, 21053, 21067, 21108, 22352, 22225, 22234, 20711, 20898, 20786, 21028, - 21020, 21194, 18831, 18935, 18947, 19433, 19564, 19619, 18952, 18935, 18831, 24540, 24589, - 24634, 24695, 24823, 24720, 24432, 24442, 24321, 16575, 16813, 16838, 16781, 16838, 16911, - 17026, 16949, 17093, 17284, 17168, 17298, 16856, 16949, 17026, 16856, 17026, 16876, 19057, - 19059, 19231, 22633, 22352, 22373, 22496, 22352, 22633, 24701, 24727, 24634, 18827, 18778, - 18986, 18814, 18778, 18827, 24975, 24492, 24747, 24385, 24428, 24247, 16687, 16568, 16744, - 16336, 16568, 16687, 16390, 16568, 16336, 16495, 16769, 16791, 16691, 16540, 16818, 20442, - 20311, 20345, 20898, 21020, 21028, 24980, 25141, 25017, 25017, 25309, 24994, 24994, 25118, - 24464, 25029, 24890, 24905, 19590, 19535, 19581, 19295, 19057, 19231, 19377, 19535, 19332, - 16557, 16598, 16691, 16754, 16856, 16612, 20311, 20175, 20190, 24494, 24428, 24385, 23974, - 23743, 23987, 17662, 17402, 17977, 22636, 22633, 22860, 23446, 23214, 23267, 25100, 25023, - 24908, 24933, 25036, 24747, 25100, 24908, 25073, 24944, 25029, 24905, 25037, 25029, 24944, - 24948, 24807, 24866, 20005, 19807, 19754, 25259, 25387, 25341, 25119, 25132, 24890, 19535, - 19450, 19440, 19377, 19450, 19535, 25018, 24948, 24866, 16949, 17027, 17093, 16899, 17027, - 16949, 18966, 18814, 19067, 18778, 18619, 18756, 18966, 19067, 19059, 19057, 18966, 19059, - 19564, 19754, 19709, 19847, 20005, 19754, 23974, 23987, 24263, 23580, 23446, 23502, 23502, - 23446, 23383, 24589, 24701, 24634, 24727, 24823, 24695, 25427, 24701, 24589, 17417, 17664, - 17592, 17934, 18056, 18008, 25023, 25036, 24933, 25111, 25036, 25023, 24948, 25037, 24944, - 25029, 25119, 24890, 24701, 24823, 24727, 18008, 18056, 18185, 17827, 18008, 17927, 16598, - 16540, 16691, 16971, 16781, 16992, 16725, 16971, 16621, 24061, 24432, 24321, 24408, 24061, - 23624, 24408, 23624, 23884, 25115, 25119, 25029, 20886, 20698, 20762, 20596, 20556, 20505, - 20505, 20442, 20469, 20311, 20251, 20175, 20977, 20698, 20886, 20626, 20711, 20737, 20898, - 20937, 21020, 20599, 20711, 20626, 20291, 20176, 20098, 16568, 16499, 16786, 16557, 16482, - 16598, 16598, 16352, 16540, 16315, 16499, 16326, 16687, 16317, 16336, 18935, 18952, 18995, - 18858, 18952, 18831, 20698, 20556, 20596, 19910, 19332, 19590, 16499, 16495, 16791, 18814, - 18797, 18778, 18939, 18797, 18814, 18939, 18814, 18966, 20556, 20442, 20505, 20711, 20870, - 20898, 21318, 21254, 21194, 16856, 16899, 16949, 16938, 17113, 17284, 17298, 17417, 17592, - 16754, 16899, 16856, 19295, 19231, 19409, 20870, 20937, 20898, 25194, 25100, 25073, 24602, - 24493, 24494, 25018, 25037, 24948, 25203, 25029, 25037, 25203, 25115, 25029, 16495, 16482, - 16557, 18797, 18619, 18778, 20442, 20251, 20311, 19450, 19295, 19409, 20056, 20291, 20098, - 20056, 20098, 20005, 21359, 21296, 21883, 23021, 23189, 23216, 21154, 21194, 21020, 19377, - 19295, 19450, 17676, 17827, 17927, 18056, 18307, 18185, 17934, 17827, 17875, 25141, 25309, - 25017, 25118, 25182, 25073, 25132, 25155, 25141, 25206, 25155, 25132, 25206, 25132, 25119, - 17827, 17934, 18008, 24263, 23987, 24207, 23757, 23446, 23580, 25100, 25111, 25023, 25192, - 25111, 25100, 21125, 21154, 21020, 24428, 24353, 24247, 24493, 24353, 24428, 24493, 24428, - 24494, 23757, 23580, 23811, 22636, 22496, 22633, 16899, 16846, 17027, 16754, 16846, 16899, - 19057, 18962, 18966, 18797, 18672, 18619, 18960, 18962, 19057, 24823, 25018, 24866, 25233, - 25018, 25427, 25018, 24823, 25427, 16938, 17284, 17027, 21154, 21318, 21194, 25149, 25206, - 25119, 25149, 25119, 25188, 16621, 16971, 17190, 16781, 16695, 16838, 17662, 17444, 17402, - 16894, 16621, 17190, 17588, 17444, 17662, 17113, 17168, 17284, 21531, 21359, 21883, 24975, - 24747, 25036, 24353, 24263, 24207, 25259, 25182, 25118, 25188, 25119, 25115, 24310, 24263, - 24452, 16658, 16695, 16781, 19187, 19332, 19154, 19295, 19223, 19057, 16695, 16575, 16838, - 19433, 19619, 19105, 18962, 18939, 18966, 18960, 18939, 18962, 22732, 22860, 22633, 22352, - 22405, 22225, 25182, 25194, 25073, 25311, 24975, 25406, 25257, 25188, 25115, 16846, 16938, - 17027, 17073, 17151, 17168, 16499, 16315, 16495, 16495, 16352, 16482, 16326, 16499, 16390, - 20580, 20626, 20478, 20711, 20655, 20870, 21055, 21125, 20937, 20937, 21125, 21020, 21154, - 21291, 21318, 20580, 20478, 20291, 16390, 16499, 16568, 18619, 18278, 18756, 18171, 18278, - 18339, 18089, 18307, 18056, 19105, 19619, 18995, 20556, 20583, 20442, 20442, 20385, 20251, - 20251, 19910, 20175, 20698, 20583, 20556, 20554, 20583, 20698, 20977, 20886, 21053, 20449, - 20580, 20291, 16687, 16644, 16317, 18437, 18592, 18831, 20583, 20409, 20442, 17934, 17926, - 18056, 17875, 17926, 17934, 17875, 17652, 17791, 20409, 20385, 20442, 21207, 20977, 21053, - 25194, 25192, 25100, 16725, 16658, 16781, 16695, 16490, 16575, 16621, 16658, 16725, 19377, - 19228, 19295, 19223, 19228, 19187, 24975, 25036, 25406, 16482, 16352, 16598, 16612, 16856, - 16876, 16296, 16352, 16495, 17151, 17417, 17298, 17151, 17298, 17168, 17926, 18089, 18056, - 17073, 17168, 17113, 18307, 18437, 18680, 18380, 18437, 18266, 16359, 16644, 16382, 21055, - 20937, 20870, 21995, 21471, 22198, 25155, 25275, 25141, 25182, 25259, 25194, 25194, 25248, - 25192, 25240, 25275, 25155, 25240, 25155, 25206, 25240, 25206, 25231, 16575, 16468, 16639, - 16391, 16468, 16575, 18677, 18858, 18831, 18677, 18831, 18592, 21531, 21280, 21359, 22732, - 23026, 22860, 21471, 21254, 21557, 16846, 16848, 16938, 16991, 17073, 17113, 16612, 15917, - 16125, 19223, 18960, 19057, 18517, 18278, 18619, 24263, 24310, 23974, 24081, 23757, 23811, - 24471, 24263, 24353, 24471, 24353, 24493, 16359, 16317, 16644, 18467, 18677, 18592, 25231, - 25206, 25149, 19105, 18995, 18952, 19847, 20056, 20005, 19228, 19223, 19295, 19060, 19223, - 19187, 16382, 16644, 16639, 19601, 19754, 19564, 21359, 21280, 21053, 22405, 22352, 22496, - 21125, 21291, 21154, 25266, 25231, 25149, 25266, 25149, 25188, 17151, 17088, 17417, 16991, - 17113, 16938, 24708, 24602, 24494, 25018, 25203, 25037, 25233, 25203, 25018, 18278, 18171, - 17662, 18672, 18797, 18939, 25415, 25118, 24994, 25192, 25248, 25111, 25257, 25266, 25188, - 17926, 17903, 18089, 18089, 18133, 18307, 17875, 17827, 17652, 16754, 16848, 16846, 18921, - 19105, 18952, 18677, 18731, 18858, 18648, 18731, 18677, 18380, 18592, 18437, 19433, 19601, - 19564, 19458, 19601, 19433, 24652, 24471, 24493, 17875, 17903, 17926, 16468, 16382, 16639, - 16137, 16382, 16468, 16894, 17190, 17402, 16514, 16490, 16695, 16801, 16991, 16938, 17073, - 17097, 17151, 18921, 18952, 18858, 20599, 20655, 20711, 21125, 21209, 21291, 20580, 20655, - 20599, 20449, 20655, 20580, 16326, 16301, 16315, 16315, 16296, 16495, 16390, 16301, 16326, - 16167, 16301, 16390, 16167, 16390, 16097, 16146, 16336, 16317, 16270, 16317, 16359, 20583, - 20554, 20409, 20409, 20401, 20385, 20385, 20333, 20251, 20539, 20554, 20698, 20539, 20698, - 20730, 25357, 25309, 25141, 25357, 25141, 25275, 25357, 25275, 25300, 25275, 25307, 25300, - 16153, 16296, 16103, 16352, 16219, 16540, 20554, 20401, 20409, 20438, 20449, 20291, 20655, - 20449, 20581, 25259, 25248, 25194, 25353, 25248, 25259, 25203, 25257, 25115, 25275, 25240, - 25307, 16514, 16695, 16658, 16543, 16514, 16658, 16797, 17097, 17073, 17652, 17827, 17676, - 18266, 18437, 18307, 24615, 24652, 24708, 24708, 24652, 24602, 24602, 24652, 24493, 25240, - 25231, 25307, 16296, 16219, 16352, 17903, 18133, 18089, 25307, 25231, 25266, 22589, 22584, - 23189, 21557, 21254, 21318, 16848, 16801, 16938, 16991, 16797, 17073, 16751, 16801, 16848, - 16751, 16848, 16754, 18878, 18672, 18939, 18965, 18939, 18960, 19223, 18965, 18960, 19060, - 18965, 19223, 22549, 22405, 22496, 22549, 22496, 22636, 18171, 17588, 17662, 16966, 16894, - 17402, 17560, 17588, 17731, 18133, 18266, 18307, 19302, 19458, 19433, 19601, 19847, 19754, - 21280, 21207, 21053, 21220, 21207, 21246, 21055, 21209, 21125, 21291, 21419, 21318, 24615, - 24452, 24471, 24471, 24452, 24263, 24310, 24341, 23974, 22860, 23026, 23130, 25918, 25307, - 25266, 16324, 16391, 16490, 16621, 16543, 16658, 16473, 16543, 16621, 19105, 19178, 19433, - 19138, 19178, 19105, 18921, 18858, 18872, 18858, 18731, 18872, 16264, 16270, 16359, 16264, - 16359, 16382, 16264, 16137, 16174, 24652, 24615, 24471, 24708, 24494, 25495, 16391, 16575, - 16490, 16710, 16751, 16754, 16801, 16817, 16991, 22860, 23130, 22968, 25387, 25259, 25118, - 25406, 25036, 25111, 18378, 18592, 18380, 21738, 21531, 21883, 22670, 22549, 22636, 16966, - 17402, 17444, 16793, 16817, 16801, 17652, 17676, 17417, 18672, 18565, 18619, 18561, 18565, - 18672, 23365, 23214, 23687, 16456, 16490, 16514, 19501, 19620, 19601, 19501, 19601, 19458, - 19302, 19433, 19178, 19187, 19228, 19377, 18965, 18914, 18939, 19021, 19138, 19105, 21320, - 21419, 21291, 25341, 25353, 25259, 18219, 18378, 18380, 24748, 24708, 24788, 20655, 20623, - 20870, 21209, 21320, 21291, 20581, 20623, 20655, 20581, 20449, 20438, 24452, 24486, 24310, - 24758, 24486, 24452, 24758, 24452, 24615, 25309, 25415, 24994, 25341, 25396, 25353, 25435, - 25449, 25309, 25435, 25309, 25363, 25309, 25357, 25363, 16301, 16167, 16315, 16296, 16171, - 16219, 16146, 16390, 16336, 16146, 16317, 16270, 20554, 20539, 20401, 20401, 20333, 20385, - 20519, 20539, 20608, 20438, 20291, 20238, 25449, 25415, 25309, 25363, 25357, 25422, 16103, - 16296, 16315, 15917, 16876, 16540, 16543, 16456, 16514, 16473, 16456, 16543, 19171, 19302, - 19178, 20539, 20479, 20401, 20455, 20438, 20394, 25422, 25357, 25300, 16137, 16264, 16382, - 16393, 16324, 16490, 19380, 19501, 19458, 19695, 19847, 19601, 19695, 19601, 19620, 21521, - 21531, 21738, 21207, 21097, 20977, 21419, 21557, 21318, 21443, 21557, 21419, 25427, 24823, - 24701, 25203, 25233, 25257, 25637, 25422, 25307, 25307, 25422, 25300, 16153, 16171, 16296, - 20479, 20333, 20401, 18921, 19021, 19105, 19138, 19171, 19178, 18766, 18872, 18731, 16751, - 16793, 16801, 16967, 17151, 17097, 16710, 16793, 16751, 18467, 18648, 18677, 17875, 17791, - 17903, 17903, 17849, 18133, 18133, 18053, 18266, 18266, 18219, 18380, 16967, 17097, 16797, - 20623, 21055, 20870, 25637, 25307, 25918, 16116, 16540, 16219, 19060, 18968, 18965, 19077, - 18968, 19060, 18872, 19021, 18921, 16174, 16146, 16270, 16174, 16270, 16264, 17791, 17849, - 17903, 18565, 18517, 18619, 18561, 18517, 18565, 18378, 18467, 18592, 18479, 18467, 18378, - 21220, 21097, 21207, 25415, 25362, 25118, 16456, 16393, 16490, 16137, 16468, 16180, 19187, - 19377, 19332, 19091, 19171, 19138, 19302, 19380, 19458, 21246, 21207, 21280, 25362, 25387, - 25118, 24485, 24341, 24310, 24485, 24310, 24486, 16797, 16991, 16817, 24708, 24748, 24615, - 24758, 24748, 24788, 19637, 19695, 19620, 20455, 20507, 20438, 19637, 19620, 19501, 21531, - 21246, 21280, 21055, 21320, 21209, 25387, 25417, 25341, 25353, 25369, 25248, 16612, 16710, - 16754, 16696, 16797, 16817, 17849, 18053, 18133, 18648, 18766, 18731, 18872, 18766, 19021, - 19021, 19091, 19138, 18479, 18766, 18648, 18479, 18648, 18467, 24758, 24485, 24486, 18968, - 18914, 18965, 19077, 18914, 18968, 18752, 18561, 18672, 18517, 18339, 18278, 16456, 16394, - 16393, 16297, 16391, 16324, 16361, 16394, 16456, 19234, 19380, 19302, 19234, 19302, 19171, - 16297, 16324, 16393, 25417, 25396, 25341, 16894, 16473, 16621, 18867, 19091, 19021, 16696, - 16817, 16793, 16967, 17088, 17151, 16978, 17088, 16967, 18053, 18108, 18266, 17791, 17728, - 17849, 17849, 17848, 18053, 18053, 18063, 18108, 16977, 17652, 17417, 21320, 21443, 21419, - 21557, 22198, 21471, 25396, 25369, 25353, 17652, 17728, 17791, 24421, 23974, 24341, 24081, - 23811, 23974, 16167, 16103, 16315, 16153, 16088, 16171, 16171, 16116, 16219, 15994, 16103, - 16167, 16097, 16390, 16089, 19220, 19234, 19171, 19380, 19429, 19501, 25544, 25485, 25449, - 25449, 25485, 25415, 25415, 25666, 25362, 25548, 25417, 25387, 25596, 25490, 25417, 25417, - 25490, 25396, 25396, 25490, 25369, 25544, 25449, 25435, 25544, 25435, 25463, 25463, 25363, - 25500, 25463, 25435, 25363, 20539, 20519, 20479, 20479, 20407, 20333, 19332, 19535, 19590, - 20608, 20539, 20730, 20698, 20977, 20730, 20998, 21097, 21185, 20581, 20507, 20623, 20623, - 20501, 21055, 21430, 21443, 21320, 21430, 21546, 21443, 20438, 20507, 20581, 19868, 20056, - 19847, 25500, 25363, 25422, 16259, 16297, 16393, 16259, 16393, 16394, 16089, 16390, 16146, - 16103, 16088, 16153, 16180, 16468, 16391, 15949, 16089, 16146, 16710, 16696, 16793, 16463, - 16696, 16710, 16463, 16710, 16612, 17728, 17848, 17849, 18108, 18219, 18266, 18063, 18219, - 18108, 18914, 18878, 18939, 18874, 18878, 18914, 19695, 19785, 19847, 19707, 19785, 19695, - 20519, 20407, 20479, 20394, 20438, 20238, 21531, 21521, 21246, 21246, 21352, 21220, 22248, - 22225, 22405, 22670, 22614, 22549, 22549, 22493, 22405, 22875, 22614, 22670, 22875, 22670, - 22860, 24545, 24421, 24341, 24545, 24341, 24485, 23884, 23624, 23216, 24432, 25427, 24589, - 23884, 23216, 23189, 25602, 25500, 25637, 15957, 16146, 16174, 18561, 18525, 18517, 18657, - 18525, 18561, 18219, 18479, 18378, 19268, 19220, 18867, 19091, 19220, 19171, 23130, 23026, - 23214, 17848, 17932, 18053, 21443, 21640, 21557, 21546, 21640, 21443, 16242, 16259, 16394, - 16297, 16180, 16391, 19268, 19429, 19380, 19268, 19380, 19234, 16473, 16361, 16456, 16267, - 16361, 16473, 16797, 16799, 16967, 17575, 17725, 17652, 16460, 16799, 16797, 18443, 18339, - 18517, 19590, 20175, 19910, 19187, 19077, 19060, 19344, 19441, 19420, 22493, 22248, 22405, - 23365, 23130, 23214, 18236, 18002, 18171, 17588, 16966, 17444, 17932, 18063, 18053, 17747, - 18274, 18479, 16032, 16180, 16048, 16137, 16078, 16174, 18878, 18752, 18672, 18525, 18443, - 18517, 18874, 18752, 18878, 19637, 19707, 19695, 19785, 19868, 19847, 22248, 21738, 21883, - 21521, 21352, 21246, 22968, 22875, 22860, 22614, 22493, 22549, 22976, 22875, 22968, 17731, - 17588, 18171, 16195, 16267, 16039, 22626, 22493, 22614, 17728, 17651, 17848, 17848, 17674, - 17932, 17932, 17703, 18063, 17652, 17725, 17728, 16977, 17417, 17088, 16048, 16180, 16297, - 16361, 16242, 16394, 16641, 16966, 17588, 16799, 16978, 16967, 19910, 20251, 20333, 19154, - 19077, 19187, 23687, 23214, 23446, 23130, 22976, 22968, 24748, 24758, 24615, 24788, 24708, - 25349, 18271, 18443, 18525, 18339, 18236, 18171, 15970, 16116, 16171, 21523, 21352, 21521, - 25594, 25387, 25362, 25406, 25111, 25492, 18002, 17731, 18171, 17432, 17731, 17399, 19158, - 19077, 19154, 19560, 19637, 19501, 19814, 19868, 19785, 19560, 19501, 19429, 23757, 23687, - 23446, 23897, 23687, 23757, 24081, 23974, 24421, 24598, 24545, 24485, 16032, 16078, 16137, - 16032, 16137, 16180, 19953, 19868, 19814, 18259, 18236, 18339, 23365, 23315, 23130, 23339, - 23315, 23365, 25495, 24494, 24975, 24764, 24598, 24485, 18752, 18657, 18561, 18443, 18259, - 18339, 18742, 18657, 18752, 19332, 19328, 19154, 19077, 18874, 18914, 19158, 19328, 19277, - 19220, 19268, 19234, 19268, 19344, 19420, 21640, 22198, 21557, 23321, 23884, 23189, 18742, - 18874, 18815, 22493, 22527, 22248, 21691, 21521, 21738, 22853, 22626, 22614, 22853, 22614, - 22875, 15981, 15994, 16167, 16103, 15961, 16088, 16088, 15970, 16171, 15981, 16167, 16097, - 15981, 16097, 15969, 15994, 15961, 16103, 19507, 19560, 19429, 19814, 19785, 19726, 20730, - 20977, 20916, 20519, 20545, 20407, 20407, 19910, 20333, 20680, 20730, 20826, 24764, 24485, - 24758, 24408, 24616, 24432, 24686, 24616, 24408, 15969, 16097, 16089, 20507, 20501, 20623, - 20455, 20501, 20507, 20398, 20501, 20455, 23285, 22976, 23130, 25485, 25559, 25415, 25544, - 25559, 25485, 25602, 25559, 25544, 25602, 25544, 25463, 25500, 25602, 25463, 25637, 25500, - 25422, 21430, 21320, 21055, 21640, 21856, 22198, 15949, 15969, 16089, 15961, 15970, 16088, - 20394, 20398, 20455, 15957, 15949, 16146, 20238, 20291, 20056, 20004, 20238, 20056, 16978, - 17007, 17088, 16886, 17007, 16978, 16886, 16978, 16799, 24788, 24764, 24758, 24649, 24421, - 24545, 24339, 24081, 24421, 24569, 24545, 24598, 16361, 16267, 16242, 16048, 16297, 16049, - 16267, 16194, 16039, 25111, 25248, 25492, 24788, 24872, 24764, 25666, 25594, 25362, 25492, - 25248, 25369, 17725, 17651, 17728, 18063, 17463, 18219, 17575, 17651, 17725, 24180, 23884, - 24153, 16078, 15957, 16174, 15977, 15957, 16078, 16086, 16463, 16612, 16696, 16460, 16797, - 18874, 18742, 18752, 18271, 18259, 18443, 18815, 18874, 19077, 25594, 25548, 25387, 16966, - 16891, 16894, 16431, 16891, 16641, 17007, 16977, 17088, 16535, 16886, 16799, 23315, 23285, - 23130, 23467, 23339, 23365, 23563, 23365, 23687, 16297, 16259, 16049, 21546, 21722, 21640, - 21726, 21722, 21546, 19868, 20004, 20056, 19953, 20004, 19868, 25548, 25596, 25417, 25492, - 25369, 25843, 23777, 23715, 23687, 24872, 24569, 24598, 24872, 24598, 24764, 19507, 19707, - 19637, 16032, 15977, 16078, 16184, 16259, 16242, 21722, 21856, 21640, 21726, 21856, 21722, - 18236, 18259, 18002, 18271, 18525, 18367, 23339, 23285, 23315, 22976, 22853, 22875, 23442, - 23285, 23339, 16825, 16977, 17007, 16825, 17007, 16886, 23715, 23563, 23687, 16017, 15977, - 16032, 20545, 19910, 20407, 18973, 18815, 19077, 20876, 21430, 21055, 18367, 18525, 18657, - 18973, 19077, 19084, 16267, 16184, 16242, 16195, 16184, 16267, 16184, 16049, 16259, 16048, - 16017, 16032, 19560, 19507, 19637, 19420, 19507, 19429, 19420, 19429, 19268, 18867, 19344, - 19268, 25843, 25369, 25490, 19158, 19154, 19328, 20730, 20680, 20608, 20608, 20545, 20519, - 20826, 20730, 20916, 15961, 15879, 15970, 15970, 15588, 16116, 16379, 16458, 16463, 15994, - 15879, 15961, 15877, 15879, 15994, 15877, 15994, 15981, 15877, 15981, 15969, 15877, 15969, - 15949, 15877, 15949, 15890, 16787, 16825, 16886, 17651, 17674, 17848, 16741, 17575, 17652, - 17674, 17575, 17468, 19726, 19785, 19707, 20680, 20545, 20608, 20916, 20977, 21097, 20916, - 21097, 20998, 23563, 23467, 23365, 24081, 24019, 23757, 23715, 23660, 23563, 23660, 23442, - 23467, 24040, 24019, 24081, 18708, 18657, 18742, 15890, 15949, 15957, 20394, 20421, 20398, - 20398, 20421, 20501, 20501, 20876, 21055, 20391, 20421, 20394, 20391, 20394, 20238, 20391, - 20238, 20198, 20238, 20004, 20198, 20845, 20916, 20998, 25559, 25666, 25415, 25594, 25650, - 25548, 25548, 25711, 25596, 25596, 25843, 25490, 25788, 25645, 25559, 17575, 17674, 17651, - 20198, 20004, 20034, 24019, 23897, 23757, 25645, 25666, 25559, 15864, 15890, 15957, 25666, - 25644, 25594, 25918, 25266, 25257, 25602, 25788, 25559, 25918, 25257, 25233, 16024, 16010, - 16049, 16267, 16473, 16194, 19358, 19328, 19332, 20034, 20004, 19953, 19507, 19726, 19707, - 23897, 23777, 23687, 15933, 15864, 15957, 15933, 15957, 15977, 20034, 19953, 19986, 25644, - 25650, 25594, 16463, 16458, 16696, 16379, 16463, 16183, 18815, 18708, 18742, 18737, 18708, - 18815, 18926, 18815, 18973, 23052, 22853, 22976, 22626, 22713, 22493, 21691, 21523, 21521, - 23052, 22976, 23285, 15772, 15933, 15836, 18975, 18926, 18973, 23229, 23052, 23285, 23229, - 23285, 23442, 25650, 25711, 25548, 16010, 16017, 16048, 16010, 16048, 16049, 21856, 22036, - 22198, 22989, 23321, 22584, 21430, 21726, 21546, 21832, 21726, 21746, 19986, 19953, 19900, - 19910, 19358, 19332, 19158, 19084, 19077, 25492, 25484, 25406, 25406, 25484, 25311, 24895, - 24872, 24788, 25972, 25484, 25492, 18259, 18059, 18002, 17731, 17432, 17560, 17560, 17432, - 17588, 18271, 18265, 18259, 18367, 18265, 18271, 19277, 19084, 19158, 23442, 23339, 23467, - 24804, 24872, 24895, 24181, 24040, 24081, 19900, 19953, 19814, 16035, 16049, 16184, 15836, - 15933, 15977, 21726, 21837, 21856, 21832, 21837, 21726, 24019, 24023, 23897, 23897, 23907, - 23777, 23660, 23467, 23563, 24649, 24545, 24569, 22853, 22809, 22626, 22757, 22809, 22867, - 23103, 22853, 23052, 24040, 24023, 24019, 19726, 19900, 19814, 19981, 19900, 19584, 16195, - 16035, 16184, 16039, 16035, 16195, 19358, 19277, 19328, 19367, 19277, 19358, 23660, 23715, - 23777, 23229, 23185, 23052, 17674, 17703, 17932, 17468, 17703, 17674, 16908, 17652, 16977, - 24770, 24649, 24569, 23159, 23185, 23336, 16035, 16024, 16049, 15836, 15977, 15793, 19084, - 18975, 18973, 18926, 18737, 18815, 18708, 18650, 18657, 18911, 18975, 19084, 20680, 20619, - 20545, 20545, 20462, 19910, 19434, 19367, 19358, 20814, 20619, 20680, 20814, 20680, 20826, - 20814, 20826, 20916, 21691, 21738, 21820, 20845, 20814, 20916, 24804, 24770, 24569, 21097, - 21220, 21185, 25645, 25788, 25666, 25666, 25775, 25644, 25644, 25775, 25650, 25650, 25779, - 25711, 25711, 25776, 25596, 26186, 25788, 25602, 21185, 21220, 21352, 16612, 16876, 15917, - 16458, 16460, 16696, 16825, 16908, 16977, 20198, 20295, 20391, 20391, 20295, 20421, 20876, - 21806, 21430, 20072, 20295, 20198, 20072, 20198, 20034, 20072, 20034, 19981, 25788, 25775, - 25666, 16787, 16908, 16825, 18882, 18737, 18926, 19507, 19584, 19726, 19981, 20034, 19986, - 19091, 18867, 19220, 22527, 21738, 22248, 21327, 21185, 21352, 21837, 22036, 21856, 21933, - 22036, 21837, 23907, 23660, 23777, 23336, 23185, 23229, 24872, 24804, 24569, 24895, 25162, - 25033, 16379, 16460, 16458, 15864, 15772, 15890, 15890, 15772, 15877, 15418, 15588, 15879, - 15933, 15772, 15864, 15977, 16017, 15793, 25775, 25779, 25650, 23884, 24315, 24408, 24180, - 24315, 23884, 17399, 17731, 17490, 16194, 16473, 16894, 19981, 19986, 19900, 21327, 21352, - 21523, 24040, 24166, 24023, 24023, 23907, 23897, 24339, 24181, 24081, 24339, 24421, 24550, - 24421, 24649, 24550, 24550, 24649, 24656, 16535, 16787, 16886, 24656, 24649, 24702, 24895, - 24788, 25162, 16741, 17468, 17575, 19021, 18766, 18867, 16741, 17652, 16908, 24649, 24770, - 24702, 19277, 19256, 19084, 18745, 18650, 18737, 19434, 19358, 19910, 22036, 22065, 22198, - 22103, 22065, 22036, 15891, 16017, 16010, 16194, 16894, 16123, 15853, 15891, 16024, 16024, - 15891, 16010, 25779, 25776, 25711, 24702, 24770, 24947, 18737, 18650, 18708, 18265, 18113, - 18259, 18882, 18926, 18975, 22809, 22757, 22626, 22867, 22809, 22853, 23159, 23052, 23185, - 16028, 16024, 16035, 19584, 19900, 19726, 21592, 21327, 21523, 21592, 21523, 21691, 21746, - 21726, 21430, 23988, 23907, 24023, 23336, 23229, 23442, 15783, 16194, 15615, 18911, 18882, - 18975, 18476, 18367, 18657, 23336, 23442, 23667, 16039, 16028, 16035, 16021, 16028, 16039, - 19367, 19256, 19277, 19405, 19256, 19367, 15891, 15793, 16017, 15917, 16540, 16116, 16252, - 16535, 16460, 15917, 16116, 15358, 21832, 21933, 21837, 21746, 21933, 21832, 16460, 16535, - 16799, 16787, 16716, 16908, 16057, 16460, 16379, 18367, 18113, 18265, 23667, 23442, 23660, - 16647, 16716, 16787, 20814, 20683, 20619, 20619, 20462, 20545, 20781, 20683, 20814, 20781, - 20814, 20845, 20781, 20845, 20998, 20781, 20998, 21010, 21010, 20998, 21185, 18650, 18606, - 18657, 18160, 18059, 18113, 18653, 18606, 18650, 18745, 18737, 18882, 22757, 22713, 22626, - 23103, 22867, 22853, 23103, 23052, 23159, 24525, 24292, 24339, 24339, 24292, 24181, 24181, - 24166, 24040, 23807, 23667, 23660, 24503, 24339, 24550, 16086, 16183, 16463, 18860, 18745, - 18882, 22867, 22713, 22757, 24292, 24166, 24181, 24656, 24503, 24550, 24702, 24503, 24656, - 25376, 25427, 24432, 25013, 24432, 24616, 23084, 23103, 23155, 15588, 15970, 15879, 16125, - 16086, 16612, 19405, 19434, 19456, 19198, 18911, 19084, 19420, 19441, 19507, 17589, 18063, - 17703, 20295, 20296, 20421, 20137, 20296, 20295, 20137, 20295, 20072, 20137, 20072, 20179, - 20964, 21010, 21059, 24166, 24054, 24023, 15770, 16086, 16125, 16535, 16647, 16787, 16777, - 16647, 16637, 19198, 19084, 19256, 22713, 22527, 22493, 20690, 20782, 20871, 24686, 25013, - 24616, 20179, 20072, 19981, 25779, 25869, 25776, 25776, 25843, 25596, 25775, 25833, 25779, - 25889, 25833, 25775, 25889, 25775, 25988, 25775, 25788, 25988, 17468, 17589, 17703, 17494, - 17589, 17468, 16777, 16908, 16716, 24054, 23988, 24023, 24880, 24770, 24804, 24315, 24686, - 24408, 15836, 15736, 15772, 15772, 15661, 15877, 15695, 15736, 15836, 15695, 15836, 15793, - 15695, 15573, 15647, 25833, 25869, 25779, 21806, 21746, 21430, 16194, 16021, 16039, 16028, - 15853, 16024, 22065, 22286, 22198, 21933, 22103, 22036, 22013, 22103, 21933, 15639, 15793, - 15891, 18113, 18059, 18259, 18167, 18113, 18367, 18606, 18476, 18657, 18563, 18476, 18606, - 18653, 18650, 18745, 18770, 18653, 18745, 16647, 16777, 16716, 16741, 16777, 16637, 24895, - 24880, 24804, 25033, 24880, 24895, 24975, 25311, 25495, 18476, 18269, 18367, 19441, 19584, - 19507, 25954, 25843, 25776, 25495, 25311, 25484, 23321, 23189, 22584, 24315, 24867, 24686, - 19441, 19528, 19584, 19859, 20179, 19981, 19344, 19528, 19441, 18867, 18766, 18274, 17426, - 17494, 17339, 17955, 17921, 18059, 18476, 18391, 18269, 18400, 18391, 18476, 20683, 20681, - 20619, 20781, 20681, 20683, 20782, 20681, 20781, 20782, 20781, 21010, 21059, 21185, 21496, - 26195, 25495, 25484, 16021, 15938, 16028, 15783, 15938, 16021, 15783, 16021, 16194, 15917, - 15916, 16125, 15952, 16057, 16183, 16637, 16647, 16604, 15770, 15916, 15715, 18059, 17921, - 18002, 18167, 18367, 18269, 19284, 19198, 19256, 18911, 18860, 18882, 18400, 18345, 18391, - 19405, 19367, 19434, 15938, 15853, 16028, 18345, 18167, 18269, 21746, 22013, 21933, 22103, - 22176, 22065, 22015, 22013, 21746, 16777, 16741, 16908, 16057, 16379, 16183, 24880, 24947, - 24770, 24651, 24525, 24503, 24503, 24525, 24339, 24292, 24520, 24166, 24166, 24178, 24054, - 24178, 23956, 23988, 25031, 24947, 24880, 24884, 24947, 25031, 15736, 15661, 15772, 15647, - 15661, 15736, 15647, 15736, 15695, 20137, 20179, 20296, 20876, 20501, 20421, 19514, 19981, - 19584, 25869, 25954, 25776, 25833, 25889, 25869, 25988, 25788, 26186, 15573, 15695, 15793, - 25889, 25920, 25869, 25843, 25957, 25492, 19527, 19434, 19910, 18563, 18606, 18653, 17463, - 18063, 17589, 19528, 19514, 19584, 22013, 22082, 22103, 22015, 22082, 22013, 18391, 18345, - 18269, 18167, 18160, 18113, 18860, 18911, 19198, 24651, 24503, 24702, 23956, 23660, 23907, - 23155, 23103, 23159, 24709, 24651, 24702, 18674, 18860, 18800, 17490, 17731, 18002, 16641, - 16891, 16966, 17490, 18002, 17921, 23956, 23907, 23988, 23103, 23084, 22867, 22867, 22933, - 22713, 22713, 22777, 22527, 25920, 25954, 25869, 18208, 18160, 18167, 17494, 17488, 17589, - 17426, 17488, 17494, 19405, 19284, 19256, 19248, 19284, 19405, 22082, 22176, 22103, 22138, - 22176, 22082, 25954, 25882, 25843, 15853, 15708, 15891, 15669, 15708, 15853, 19626, 19527, - 19910, 19344, 19514, 19528, 24178, 23988, 24054, 24947, 24884, 24702, 25031, 24880, 25033, - 15952, 16183, 16086, 18770, 18563, 18653, 18345, 18208, 18167, 18770, 18745, 18860, 18003, - 17955, 18059, 18003, 18059, 18160, 18522, 18400, 18476, 23471, 23159, 23336, 21820, 21592, - 21691, 25349, 25162, 24788, 15934, 15952, 16086, 18570, 18770, 18674, 21820, 21738, 22527, - 25882, 25957, 25843, 18349, 18208, 18345, 22989, 22584, 22198, 17339, 17494, 17468, 16604, - 16647, 16484, 20681, 20462, 20619, 20782, 20690, 20681, 20964, 20782, 21010, 22176, 22286, - 22065, 22218, 22286, 22176, 25144, 25031, 25033, 19527, 19456, 19434, 18570, 18563, 18770, - 19513, 19456, 19527, 21806, 22015, 21746, 15418, 15879, 15877, 15916, 15770, 16125, 15592, - 15877, 15661, 21059, 21010, 21185, 15708, 15639, 15891, 15545, 15592, 15661, 25884, 25918, - 25233, 15545, 15661, 15647, 17955, 17850, 17921, 18121, 18003, 18160, 21496, 21185, 21327, - 23667, 23471, 23336, 23566, 23471, 23667, 26186, 25602, 25637, 25889, 26020, 25920, 25920, - 26059, 25954, 25954, 26012, 25882, 25882, 26003, 25957, 23956, 23807, 23660, 25162, 25144, - 25033, 15481, 15545, 15647, 24651, 24633, 24525, 24365, 24178, 24166, 23956, 24123, 23807, - 24821, 24709, 24702, 24821, 24702, 24917, 24702, 24884, 24917, 25988, 26020, 25889, 18400, - 18349, 18345, 17942, 17994, 18003, 18563, 18522, 18476, 18534, 18522, 18563, 18534, 18563, - 18570, 23084, 22933, 22867, 23041, 22933, 23084, 22414, 22989, 22198, 17488, 17463, 17589, - 16939, 17468, 16741, 20876, 20421, 20296, 22933, 22777, 22713, 24520, 24292, 24525, 24917, - 24884, 24982, 18522, 18349, 18400, 22015, 22138, 22082, 22286, 22414, 22198, 22142, 22138, - 22015, 23409, 23155, 23159, 26020, 26059, 25920, 17994, 17850, 17955, 17994, 17955, 18003, - 17850, 17490, 17921, 16123, 16894, 16891, 17426, 17463, 17488, 19344, 19475, 19514, 18274, - 18766, 18479, 22777, 22585, 22527, 24982, 24884, 25031, 23471, 23409, 23159, 23423, 23409, - 23471, 25495, 25349, 24708, 25162, 25213, 25144, 25139, 24982, 25031, 25222, 25349, 25424, - 19671, 19626, 19910, 19456, 19248, 19405, 25947, 25884, 25233, 26186, 26127, 25988, 25947, - 25233, 25427, 15639, 15573, 15793, 16637, 16660, 16741, 16604, 16660, 16637, 25139, 25031, - 25144, 26059, 26012, 25954, 25957, 25972, 25492, 18867, 19278, 19344, 19514, 19859, 19981, - 22138, 22218, 22176, 22142, 22218, 22138, 17588, 17432, 16641, 15938, 15759, 15853, 15708, - 15669, 15639, 15380, 15482, 15573, 15715, 15916, 15917, 15952, 15985, 16057, 16057, 16252, - 16460, 18121, 18160, 18208, 17850, 17576, 17490, 23807, 23566, 23667, 23886, 23566, 23807, - 25349, 25222, 25162, 15887, 15985, 15952, 21592, 21496, 21327, 21820, 21496, 21592, 22933, - 22896, 22777, 22777, 22804, 22585, 23041, 22896, 22933, 23041, 23084, 23155, 23322, 23155, - 23409, 15593, 15669, 15853, 16252, 16647, 16535, 19626, 19513, 19527, 19609, 19513, 19626, - 15792, 15934, 16086, 18349, 18233, 18208, 18342, 18233, 18349, 18534, 18349, 18522, 25013, - 25376, 24432, 25412, 25376, 25013, 25288, 25013, 24686, 24633, 24520, 24525, 24178, 24123, - 23956, 24633, 24651, 24709, 24633, 24709, 24852, 24709, 24821, 24852, 25051, 24821, 24917, - 24520, 24365, 24166, 26012, 26003, 25882, 15783, 15759, 15938, 16939, 16741, 16660, 16939, - 17339, 17468, 17426, 17414, 17463, 17747, 18479, 18219, 15770, 15792, 16086, 15715, 15792, - 15770, 23566, 23423, 23471, 23452, 23423, 23566, 25222, 25213, 25162, 24982, 25051, 24917, - 19278, 19475, 19344, 19242, 19475, 19278, 20690, 20462, 20681, 20836, 20462, 20690, 20871, - 20782, 20964, 20871, 20964, 20944, 20836, 20871, 20944, 19248, 19198, 19284, 25376, 25617, - 25427, 24379, 24123, 24178, 25139, 25051, 24982, 15545, 15516, 15592, 15592, 15418, 15877, - 15481, 15516, 15545, 15481, 15647, 15573, 16484, 16554, 16604, 15934, 15887, 15952, 15855, - 15887, 15934, 22896, 22804, 22777, 22585, 21820, 22527, 22859, 22804, 22896, 26020, 26127, - 26059, 26059, 26109, 26012, 26012, 26148, 26003, 25988, 26127, 26020, 26186, 25637, 26500, - 24867, 25288, 24686, 25688, 25622, 25617, 24867, 24315, 24180, 19888, 19671, 19910, 19473, - 19248, 19456, 22020, 22142, 22015, 22218, 22188, 22286, 26003, 25972, 25957, 26148, 25972, - 26003, 25884, 26033, 25918, 26125, 26033, 25884, 15482, 15481, 15573, 18233, 18121, 18208, - 16943, 17399, 17090, 18090, 18121, 18233, 25288, 25412, 25013, 16604, 16554, 16660, 16252, - 16057, 15985, 25213, 25139, 25144, 26127, 26109, 26059, 19671, 19609, 19626, 19697, 19609, - 19671, 21535, 21597, 21451, 20944, 20964, 21059, 15754, 16252, 15985, 15380, 15573, 15639, - 15380, 15639, 15294, 15208, 15715, 15917, 15716, 15855, 15934, 16946, 17432, 17399, 15783, - 15638, 15759, 16252, 16484, 16647, 19473, 19456, 19513, 18867, 19242, 19278, 19375, 19179, - 19347, 22142, 22188, 22218, 22188, 22414, 22286, 24123, 23886, 23807, 23198, 23041, 23155, - 16943, 16946, 17399, 16943, 17090, 17002, 23322, 23409, 23452, 21451, 21597, 21428, 18674, - 18770, 18860, 18090, 17942, 18121, 23041, 22859, 22896, 25104, 24821, 25051, 25104, 24852, - 24821, 24633, 24619, 24520, 24520, 24619, 24365, 24379, 24086, 24123, 24123, 24086, 23886, - 24606, 24867, 24180, 25617, 25648, 25427, 25622, 25648, 25617, 23452, 23409, 23423, 20462, - 19888, 19910, 16946, 16641, 17432, 17339, 17414, 17426, 17315, 17414, 17339, 16493, 16660, - 16554, 23886, 23452, 23566, 23669, 24153, 23884, 23669, 23884, 23321, 23669, 23321, 24007, - 26109, 26148, 26012, 25706, 25349, 25495, 19609, 19473, 19513, 18800, 18860, 19198, 19578, - 19473, 19609, 20871, 20836, 20690, 19818, 19698, 19888, 20944, 21059, 21009, 22142, 22075, - 22188, 22188, 22085, 22414, 21806, 22020, 22015, 21910, 22020, 21806, 21910, 21813, 21935, - 19859, 19514, 19475, 24379, 24178, 24365, 24262, 23806, 23452, 15516, 15418, 15592, 15588, - 15358, 16116, 15421, 15418, 15516, 15421, 15516, 15481, 26456, 25637, 25918, 26127, 26190, - 26109, 26109, 26190, 26148, 20889, 20944, 21009, 22930, 23321, 22989, 25222, 25336, 25213, - 25213, 25163, 25139, 25139, 25104, 25051, 25424, 25336, 25222, 25706, 26250, 25944, 26087, - 25484, 25972, 25648, 25947, 25427, 25556, 25617, 25376, 25536, 25376, 25412, 23322, 23198, - 23155, 23041, 23198, 22859, 23806, 23198, 23322, 15887, 15855, 15985, 15716, 15934, 15792, - 18800, 19198, 19191, 18090, 18233, 18072, 25272, 25163, 25213, 15673, 15638, 15783, 15759, - 15593, 15853, 16143, 16123, 16891, 16143, 16891, 16431, 25441, 25536, 25412, 25441, 25412, - 25288, 25753, 25947, 25648, 15433, 15421, 15481, 15433, 15481, 15482, 19242, 19375, 19475, - 19375, 19242, 19179, 22020, 22075, 22142, 22414, 22930, 22989, 19888, 19697, 19671, 19698, - 19697, 19888, 15715, 15716, 15792, 15632, 15716, 15460, 16946, 16840, 16641, 17804, 17850, - 17994, 24942, 24619, 24633, 24879, 24633, 24852, 15380, 15433, 15482, 16943, 16840, 16946, - 16409, 16143, 16431, 16409, 16431, 16323, 18121, 17942, 18003, 18349, 18534, 18342, 25522, - 25424, 25349, 25336, 25272, 25213, 16615, 16431, 16641, 25163, 25104, 25139, 25265, 25272, - 25423, 26329, 26190, 26127, 26205, 26087, 25972, 16840, 16682, 16641, 19697, 19578, 19609, - 19191, 19198, 19248, 19698, 19578, 19697, 26223, 25972, 26148, 15638, 15593, 15759, 15615, - 15673, 15783, 15581, 15593, 15638, 25947, 26025, 25884, 26394, 26456, 25918, 26063, 26025, - 25947, 25622, 25753, 25648, 25787, 25753, 25622, 16123, 16003, 16194, 16029, 16003, 16123, - 25536, 25556, 25376, 25733, 25556, 25642, 16682, 16615, 16641, 25265, 25104, 25163, 17942, - 17804, 17994, 18342, 18534, 18386, 17795, 17631, 17804, 19191, 19248, 19276, 16143, 16036, - 16123, 16050, 16036, 16143, 16192, 16143, 16409, 18534, 18570, 18386, 15288, 15639, 15669, - 21910, 21806, 21813, 22020, 22017, 22075, 22075, 22085, 22188, 26150, 26125, 25884, 16484, - 16493, 16554, 16320, 16493, 16484, 16504, 16493, 16320, 19368, 19248, 19473, 25411, 25441, - 25288, 15593, 15464, 15669, 15381, 15464, 15593, 21910, 22017, 22020, 26025, 26150, 25884, - 26699, 26329, 26186, 26167, 26150, 26025, 15936, 15789, 16194, 15673, 15581, 15638, 15936, - 16194, 16003, 15844, 15936, 15821, 16615, 16323, 16431, 16036, 16029, 16123, 17804, 17576, - 17850, 17631, 17576, 17804, 18386, 18570, 18493, 17895, 17804, 17942, 25272, 25265, 25163, - 25423, 25272, 25336, 25556, 25688, 25617, 25753, 26063, 25947, 25733, 25688, 25556, 17090, - 17399, 17087, 16943, 16822, 16840, 16840, 16743, 16682, 16682, 16563, 16615, 16615, 16462, - 16323, 16841, 16939, 16625, 17087, 17399, 17490, 15418, 15297, 15588, 15359, 15297, 15418, - 15359, 15418, 15421, 15359, 15421, 15328, 20944, 20889, 20836, 20836, 20538, 20462, 21009, - 21059, 21496, 16746, 16743, 16840, 25102, 24879, 24852, 24619, 24379, 24365, 24942, 24879, - 25044, 26374, 26223, 26148, 26087, 26195, 25484, 15328, 15421, 15433, 15328, 15433, 15380, - 15515, 15581, 15673, 16743, 16655, 16682, 21068, 21009, 21099, 24860, 24379, 24619, 24086, - 24262, 23886, 23452, 23806, 23322, 16323, 16235, 16409, 16310, 16235, 16323, 16983, 17002, - 17090, 17895, 17942, 18090, 16113, 16050, 16143, 19578, 19368, 19473, 18595, 18674, 18800, - 18595, 18570, 18674, 19571, 19368, 19578, 19375, 19347, 19475, 19179, 19242, 18867, 22017, - 22085, 22075, 25424, 25423, 25336, 25581, 25522, 25349, 25701, 25349, 25706, 26186, 26329, - 26127, 26190, 26370, 26148, 26376, 26033, 26125, 17747, 18219, 17463, 17282, 17315, 17339, - 19818, 19888, 20208, 26223, 26205, 25972, 26341, 26205, 26223, 15243, 15328, 15110, 16481, - 16462, 16615, 16493, 16504, 16660, 16432, 16504, 16320, 15936, 15811, 15789, 15789, 15615, - 16194, 15844, 15811, 15936, 18122, 18072, 18233, 18595, 18800, 18681, 25688, 25787, 25622, - 25733, 25787, 25688, 25723, 25701, 25706, 15855, 15752, 15985, 15716, 15752, 15855, 15632, - 15752, 15716, 16235, 16192, 16409, 16050, 16029, 16036, 16069, 16192, 16235, 18789, 18800, - 19191, 19698, 19571, 19578, 19730, 19571, 19698, 25522, 25423, 25424, 25102, 24852, 25104, - 25470, 25423, 25522, 25441, 25541, 25536, 25496, 25411, 25288, 25496, 25288, 24867, 26076, - 26063, 25753, 19368, 19276, 19248, 19388, 19276, 19368, 16002, 16029, 16050, 18122, 18233, - 18342, 25701, 25581, 25349, 26329, 26370, 26190, 16462, 16369, 16323, 15654, 15615, 15789, - 19066, 18789, 19191, 21910, 21935, 22017, 22017, 22018, 22085, 20876, 20296, 20179, 26205, - 26271, 26087, 26341, 26271, 26205, 14730, 15358, 15588, 17002, 16822, 16943, 16743, 16567, - 16655, 16655, 16563, 16682, 16462, 16341, 16369, 16983, 16822, 17002, 16983, 17090, 17087, - 16625, 16939, 16660, 16939, 17282, 17339, 17087, 17049, 16922, 16822, 16746, 16840, 16981, - 17087, 16988, 17648, 17576, 17631, 24153, 24606, 24180, 24406, 24606, 24153, 24879, 24942, - 24633, 25102, 25104, 25247, 16192, 16113, 16143, 15963, 16113, 16069, 17920, 17895, 18090, - 25411, 25541, 25441, 25496, 25541, 25411, 16369, 16310, 16323, 16179, 16310, 16369, 18798, - 19179, 18867, 20760, 20876, 20179, 15288, 15294, 15639, 15288, 15669, 15360, 15669, 15464, - 15360, 15811, 15700, 15789, 15821, 15936, 16003, 15821, 16003, 15847, 18386, 18352, 18342, - 18072, 17920, 18090, 18415, 18352, 18386, 18493, 18570, 18595, 17747, 17463, 17520, 26370, - 26374, 26148, 15738, 15700, 15811, 18614, 18493, 18595, 16567, 16563, 16655, 17315, 17302, - 17414, 16895, 17282, 16939, 24399, 24406, 24153, 24578, 24406, 24557, 25247, 25104, 25265, - 18352, 18122, 18342, 21935, 22018, 22017, 22768, 22930, 22414, 25591, 25470, 25522, 25423, - 25529, 25265, 25701, 25675, 25581, 25723, 25675, 25701, 26150, 26167, 26125, 26324, 26167, - 26025, 18789, 18681, 18800, 18627, 18681, 18789, 16563, 16481, 16615, 16504, 16432, 16660, - 16320, 16484, 15907, 17282, 17302, 17315, 19385, 19475, 19347, 21935, 21813, 22018, 16113, - 16002, 16050, 15963, 16002, 16113, 15895, 16002, 15963, 18046, 17920, 18072, 17895, 17795, - 17804, 21009, 20954, 20889, 20889, 20902, 20836, 21068, 20954, 21009, 21009, 21496, 21099, - 21496, 21535, 21099, 19276, 19066, 19191, 19259, 19066, 19276, 21496, 21820, 21535, 15615, - 15595, 15673, 15580, 15595, 15615, 16228, 16320, 16070, 19571, 19388, 19368, 19479, 19388, - 19571, 19179, 19385, 19347, 19219, 19385, 19179, 15328, 15225, 15359, 15359, 15064, 15297, - 15297, 14730, 15588, 15243, 15225, 15328, 21597, 21535, 21855, 15381, 15593, 15428, 15110, - 15328, 15380, 26374, 26341, 26223, 25842, 25723, 25944, 17781, 17795, 17895, 25591, 25522, - 25581, 15253, 15380, 15294, 15844, 15738, 15811, 15700, 15654, 15789, 15760, 15738, 15844, - 15752, 15754, 15985, 15629, 15754, 15752, 15895, 16003, 16029, 26195, 26087, 26271, 25664, - 25591, 25581, 25642, 25556, 25536, 25787, 25904, 25753, 26449, 26376, 26389, 15685, 15654, - 15700, 15497, 15716, 15715, 18681, 18614, 18595, 18212, 18135, 18352, 18135, 18046, 18122, - 18122, 18046, 18072, 17655, 17648, 17795, 18627, 18614, 18681, 15595, 15515, 15673, 15509, - 15515, 15595, 24942, 24860, 24619, 24379, 24911, 24086, 25044, 24860, 24942, 25044, 24879, - 25102, 16002, 15895, 16029, 16113, 16192, 16069, 16983, 16784, 16822, 16822, 16784, 16746, - 16746, 16567, 16743, 16563, 16567, 16481, 17087, 16981, 16983, 16988, 17087, 16922, 18135, - 18122, 18352, 24606, 24749, 24867, 24608, 24749, 24606, 25541, 25642, 25536, 25791, 25642, - 25541, 15329, 15360, 15464, 15251, 15253, 15294, 21779, 21813, 21806, 26167, 26376, 26125, - 26376, 26167, 26389, 15428, 15593, 15581, 19388, 19259, 19276, 18627, 18415, 18614, 19479, - 19259, 19388, 26292, 26195, 26271, 16602, 16625, 16660, 16841, 16895, 16939, 17282, 17267, - 17302, 16602, 16660, 16432, 24750, 24608, 24578, 24406, 24608, 24606, 25247, 25044, 25102, - 16694, 16567, 16746, 16069, 16235, 16310, 16402, 16602, 16432, 26394, 25918, 26033, 26685, - 26374, 26370, 26685, 26441, 26374, 26374, 26441, 26341, 16341, 16462, 16481, 25750, 25581, - 25675, 25470, 25529, 25423, 15515, 15428, 15581, 15381, 15329, 15464, 15342, 15428, 15515, - 15738, 15685, 15700, 15654, 15580, 15615, 15821, 15760, 15844, 15699, 15760, 15821, 15847, - 16003, 15895, 15645, 15685, 15738, 15632, 15629, 15752, 16228, 16408, 16320, 15460, 15629, - 15632, 22136, 22414, 22085, 22136, 22085, 22018, 15762, 15847, 15895, 16567, 16341, 16481, - 16320, 16408, 16432, 16402, 16408, 16228, 17655, 17795, 17781, 18212, 18352, 18325, 25723, - 25759, 25675, 25842, 25759, 25723, 15251, 15294, 15288, 15251, 15288, 15215, 16179, 16069, - 16310, 15762, 15699, 15847, 17795, 17648, 17631, 17895, 17920, 17781, 19811, 19818, 19875, - 21252, 21535, 21360, 25591, 25529, 25470, 25664, 25529, 25591, 26376, 26394, 26033, 15574, - 15580, 15654, 19490, 19479, 19571, 18627, 18789, 18615, 15215, 15288, 15360, 19818, 19730, - 19698, 20954, 20902, 20889, 19648, 19552, 19730, 20997, 20902, 20954, 20997, 20954, 21068, - 20997, 21068, 21035, 26685, 26370, 26329, 26413, 26292, 26271, 21035, 21068, 21099, 15580, - 15509, 15595, 15275, 15329, 15381, 15208, 15497, 15715, 16865, 16784, 16983, 16271, 16291, - 16341, 16865, 16983, 16981, 16638, 16841, 16625, 16638, 16773, 16841, 16638, 16625, 16546, - 16988, 16865, 16981, 16773, 16895, 16841, 17520, 17463, 17414, 24750, 24789, 24749, 24749, - 24937, 24867, 24750, 24749, 24608, 24789, 24937, 24749, 17520, 17414, 17302, 18274, 18544, - 18867, 21130, 21035, 21099, 15275, 15381, 15428, 16784, 16694, 16746, 16546, 16625, 16602, - 17087, 17490, 17049, 21813, 22136, 22018, 21964, 22136, 21813, 24578, 24608, 24406, 26481, - 26271, 26341, 25944, 25723, 25706, 16175, 16179, 16369, 15762, 15895, 15935, 16291, 16369, - 16341, 15266, 15215, 15360, 15358, 15208, 15917, 14658, 15208, 15358, 15685, 15574, 15654, - 15580, 15408, 15509, 15760, 15645, 15738, 15699, 15645, 15760, 15699, 15821, 15847, 15895, - 15963, 15935, 16485, 16546, 16602, 18415, 18386, 18493, 17949, 17920, 18046, 18415, 18493, - 18614, 18789, 19066, 19042, 21508, 21779, 21806, 24399, 24153, 24307, 25706, 25495, 26250, - 25750, 25664, 25581, 26277, 25495, 26195, 25733, 25904, 25787, 26376, 26449, 26394, 26116, - 25904, 25733, 25791, 25733, 25642, 26441, 26427, 26341, 26239, 26025, 26063, 15591, 15574, - 15685, 17747, 18035, 18274, 19042, 19066, 19120, 26456, 26500, 25637, 26685, 26495, 26427, - 26785, 26500, 26456, 26584, 26456, 26394, 19120, 19066, 19259, 19485, 19259, 19479, 26076, - 26239, 26063, 15236, 15266, 15360, 15329, 15236, 15360, 15342, 15275, 15428, 15236, 15275, - 15134, 24937, 25496, 24867, 26292, 26352, 26195, 26472, 26352, 26292, 26306, 26324, 26025, - 16408, 16402, 16432, 16484, 16252, 15907, 17091, 17267, 17282, 24307, 24153, 23669, 25529, - 25247, 25265, 25351, 24943, 24860, 25351, 25247, 25767, 17747, 17815, 18035, 17801, 17815, - 17747, 25750, 25675, 25759, 26131, 26076, 25753, 15253, 15110, 15380, 15034, 15064, 15225, - 15225, 15064, 15359, 15160, 15110, 15253, 15160, 15253, 15126, 15253, 15251, 15126, 15982, - 15963, 16069, 16271, 16341, 16567, 16234, 16228, 16070, 24073, 24307, 23669, 19730, 19490, - 19571, 19552, 19490, 19730, 26427, 26481, 26341, 26495, 26481, 26427, 17949, 18046, 18135, - 18415, 18325, 18352, 18297, 18325, 18415, 18193, 18325, 18297, 18103, 18323, 18274, 18103, - 18274, 18035, 25944, 25958, 25842, 25844, 25750, 25759, 25997, 25958, 25944, 15126, 15251, - 15146, 15982, 16069, 16025, 15699, 15591, 15645, 15645, 15591, 15685, 16025, 16069, 16179, - 17049, 17490, 17576, 17949, 18135, 18157, 18132, 18103, 18029, 19073, 19219, 19179, 19385, - 19859, 19475, 26352, 26277, 26195, 26416, 26277, 26352, 26593, 26584, 26449, 26239, 26306, - 26025, 26523, 26306, 26545, 16291, 16175, 16369, 18157, 18135, 18212, 25844, 25759, 25842, - 25664, 25767, 25529, 25496, 25791, 25541, 25904, 26131, 25753, 15497, 15460, 15716, 16279, - 16234, 16070, 14446, 15460, 15497, 15146, 15251, 15215, 15146, 15215, 15266, 16988, 16811, - 16865, 16865, 16789, 16784, 16784, 16589, 16694, 16694, 16589, 16567, 16291, 16166, 16175, - 16922, 16811, 16988, 19362, 19859, 19385, 20876, 21508, 21806, 26449, 26584, 26394, 26389, - 26167, 26324, 15275, 15236, 15329, 15342, 15515, 15509, 19490, 19485, 19479, 19042, 18615, - 18789, 19552, 19485, 19490, 26481, 26413, 26271, 26495, 26413, 26481, 26488, 26389, 26324, - 16699, 16589, 16784, 16546, 16511, 16638, 16638, 16668, 16773, 16773, 16668, 16895, 17038, - 17306, 17267, 16485, 16511, 16546, 16485, 16602, 16342, 17049, 17576, 17085, 16342, 16602, - 16402, 17572, 17576, 17648, 24578, 24557, 24750, 24913, 25074, 24789, 24789, 25074, 24937, - 24937, 25264, 25496, 24399, 24557, 24406, 24555, 24557, 24399, 15982, 15935, 15963, 16025, - 15935, 15982, 17655, 17572, 17648, 17949, 17781, 17920, 20660, 20760, 20179, 26500, 26699, - 26186, 26634, 26699, 26500, 15344, 15342, 15509, 15463, 15580, 15574, 17306, 17520, 17302, - 18029, 18103, 18035, 17306, 17302, 17267, 19374, 19120, 19259, 20760, 20765, 20876, 16234, - 16342, 16402, 16234, 16402, 16228, 20208, 19888, 20462, 20997, 20927, 20902, 21035, 20927, - 20997, 21130, 20927, 21035, 18325, 18193, 18212, 17672, 17669, 17781, 18469, 18415, 18627, - 25958, 25926, 25842, 25997, 25926, 25958, 15762, 15591, 15699, 15287, 15111, 15216, 26413, - 26472, 26292, 26250, 25997, 25944, 26641, 26472, 26413, 15034, 15243, 15110, 15034, 15225, - 15243, 15034, 14904, 14976, 26103, 25767, 25664, 25926, 25844, 25842, 15029, 15146, 15266, - 14904, 15110, 15160, 15067, 15146, 15029, 14928, 15160, 15126, 15591, 15463, 15574, 16321, - 16271, 16567, 16095, 16025, 16179, 16252, 15578, 15907, 18589, 18615, 19042, 18323, 18544, - 18274, 18539, 18544, 18323, 18273, 18323, 18264, 21228, 21130, 21252, 26785, 26634, 26500, - 16095, 16179, 16175, 15344, 15438, 15287, 17669, 17572, 17655, 17669, 17655, 17781, 17520, - 17551, 17747, 17392, 17551, 17520, 19120, 19009, 19042, 18849, 19009, 18844, 15438, 15408, - 15580, 15342, 15247, 15275, 17091, 17282, 16895, 26472, 26416, 26352, 26555, 26416, 26472, - 21779, 21898, 21813, 23209, 23509, 22930, 21741, 21898, 21779, 17015, 16922, 17049, 17824, - 17781, 17949, 16579, 16668, 16638, 16579, 16638, 16511, 16579, 16511, 16485, 16579, 16485, - 16339, 16811, 16789, 16865, 16589, 16446, 16567, 16913, 16789, 16811, 16913, 16811, 16922, - 16913, 16922, 17015, 16668, 16739, 16895, 18469, 18297, 18415, 18193, 18157, 18212, 18469, - 18627, 18615, 18132, 18323, 18103, 26250, 25495, 26277, 25926, 25929, 25844, 16339, 16485, - 16342, 17015, 17049, 16918, 18181, 18157, 18193, 17897, 18035, 17815, 16166, 16095, 16175, - 15463, 15111, 15287, 16166, 16291, 16271, 18589, 18469, 18615, 18933, 19073, 19179, 18273, - 18539, 18323, 19811, 19730, 19818, 19485, 19374, 19259, 21898, 21964, 21813, 21847, 21964, - 21898, 26116, 26131, 25904, 26545, 26306, 26239, 26488, 26449, 26389, 26685, 26427, 26441, - 16363, 16446, 16589, 16918, 17049, 17085, 21319, 21508, 20876, 16446, 16321, 16567, 16279, - 16339, 16342, 16279, 16342, 16234, 16739, 17091, 16895, 15463, 15438, 15580, 15344, 15247, - 15342, 15287, 15438, 15463, 14917, 15038, 15591, 24007, 24073, 23669, 24307, 24555, 24399, - 24202, 24073, 24159, 17640, 17801, 17747, 17640, 17747, 17551, 17897, 17801, 17640, 20208, - 20462, 20538, 21508, 21582, 21779, 26699, 26685, 26329, 26584, 26593, 26456, 26657, 26593, - 26449, 26488, 26324, 26523, 16252, 15754, 15578, 24496, 24555, 24307, 24913, 24789, 24750, - 26523, 26324, 26306, 15344, 15509, 15408, 18798, 18867, 18544, 19219, 19362, 19385, 26416, - 26442, 26277, 26555, 26442, 26416, 26555, 26472, 26620, 19859, 20660, 20179, 20760, 20744, - 20765, 20765, 20858, 20876, 21508, 21494, 21582, 20744, 20660, 20648, 15146, 15067, 15126, - 15029, 15266, 15236, 16308, 16166, 16271, 15762, 15935, 15731, 17672, 17599, 17669, 18297, - 18181, 18193, 18417, 18181, 18297, 18132, 18264, 18323, 18273, 18436, 18539, 18510, 18798, - 18544, 18029, 18264, 18132, 18264, 18436, 18273, 20761, 20858, 20765, 17975, 18029, 18035, - 25979, 25929, 25926, 25844, 25929, 25750, 25979, 25926, 25997, 15578, 15754, 15629, 17669, - 17599, 17572, 17824, 17949, 18157, 19552, 19374, 19485, 18849, 18589, 19042, 18469, 18498, - 18297, 19285, 19374, 19421, 15064, 14724, 15297, 15034, 14908, 15064, 14976, 14908, 15034, - 18498, 18589, 18547, 18023, 17824, 18157, 17801, 17897, 17815, 17640, 17551, 17526, 15054, - 15029, 15236, 14904, 15034, 15110, 15907, 16070, 16320, 19811, 19648, 19730, 21582, 21741, - 21779, 21964, 22168, 22136, 21659, 21741, 21582, 24073, 24312, 24307, 14904, 15160, 14928, - 20538, 20836, 20902, 19811, 19760, 19648, 20538, 20902, 20927, 16789, 16699, 16784, 16363, - 16308, 16321, 16321, 16308, 16271, 16913, 16699, 16789, 16861, 16699, 16913, 16861, 16913, - 17015, 16739, 16688, 17091, 17392, 17520, 17306, 16668, 16684, 16739, 16596, 16684, 16668, - 16596, 16668, 16579, 16596, 16173, 16489, 16596, 16489, 16555, 24913, 24750, 24557, 26357, - 26116, 25791, 25791, 26116, 25733, 24913, 24840, 24977, 24913, 24557, 24840, 16918, 16861, - 17015, 21130, 21052, 20927, 21252, 21130, 21099, 21252, 21099, 21535, 15438, 15344, 15408, - 15247, 15134, 15275, 15935, 16025, 15731, 18510, 18544, 18539, 26641, 26413, 26495, 26154, - 25979, 25997, 17085, 17576, 17572, 17771, 17672, 17781, 17392, 17306, 17313, 17486, 17572, - 17599, 21741, 21847, 21898, 21890, 21847, 21741, 26488, 26657, 26449, 26673, 26657, 26488, - 17313, 17306, 17122, 24312, 24496, 24307, 24073, 24202, 24312, 24007, 23321, 23509, 21360, - 21535, 21451, 21535, 21820, 21855, 21031, 21319, 20876, 25929, 26048, 25750, 26250, 26277, - 26442, 16022, 16025, 16095, 16363, 16321, 16446, 14928, 15126, 15067, 18111, 18336, 18264, - 18336, 18510, 18436, 18436, 18510, 18539, 17897, 17975, 18035, 17749, 17975, 17897, 18589, - 18498, 18469, 17753, 17771, 17824, 17824, 17771, 17781, 18849, 19042, 19009, 18336, 18436, - 18264, 21855, 21820, 22529, 21319, 21349, 21508, 26268, 26250, 26300, 26593, 26785, 26456, - 26634, 26810, 26699, 26699, 27676, 26685, 26765, 26785, 26593, 18798, 18933, 19179, 19073, - 19082, 19219, 18856, 18933, 18798, 15049, 15134, 15247, 14924, 14928, 15067, 24435, 24496, - 24312, 26545, 26239, 26076, 17672, 17486, 17599, 17411, 17486, 17672, 17392, 17526, 17551, - 17640, 17608, 17897, 17325, 17526, 17392, 20208, 19875, 19818, 19421, 19374, 19552, 21855, - 21560, 21597, 21349, 21494, 21508, 26967, 26765, 26593, 26785, 26765, 26967, 15344, 15230, - 15247, 16022, 16095, 16166, 18023, 18157, 18181, 14924, 15067, 15029, 19875, 19857, 19811, - 19104, 19009, 19120, 21494, 21574, 21582, 26685, 26641, 26495, 26537, 26250, 26442, 26754, - 26641, 27213, 26357, 25791, 25496, 26131, 26545, 26076, 18724, 18849, 18844, 18974, 19082, - 19073, 18875, 18856, 18741, 18974, 19073, 18933, 24319, 24007, 24243, 24202, 24290, 24312, - 17940, 18023, 18067, 18417, 18297, 18498, 25979, 26048, 25929, 26154, 26048, 25979, 26250, - 26268, 25997, 26546, 26442, 26599, 16579, 16173, 16596, 16684, 16705, 16739, 16596, 16705, - 16684, 25074, 25264, 24937, 24913, 25046, 25074, 24977, 25046, 24913, 14962, 14924, 15029, - 16040, 16022, 16166, 17526, 17408, 17640, 17038, 17267, 17091, 19857, 19760, 19811, 20660, - 20744, 20760, 20858, 21031, 20876, 21319, 21301, 21349, 21349, 21378, 21494, 21494, 21432, - 21574, 20648, 20660, 20570, 21574, 21659, 21582, 21847, 21890, 21964, 21631, 21659, 21574, - 24159, 24290, 24202, 24977, 25109, 25046, 24860, 24943, 24379, 25351, 24860, 25044, 25351, - 25044, 25247, 21052, 20538, 20927, 20208, 19883, 19875, 19875, 19883, 19857, 19857, 19804, - 19760, 21052, 21130, 21139, 21130, 21228, 21139, 21228, 21213, 21139, 20744, 20761, 20765, - 20761, 20863, 20858, 16440, 16363, 16589, 16308, 16142, 16166, 16440, 16589, 16699, 16558, - 16699, 16861, 16918, 16890, 16861, 17085, 16890, 16918, 15134, 15054, 15236, 15092, 15054, - 15134, 18724, 18547, 18589, 19265, 19362, 19219, 26641, 26620, 26472, 26754, 26620, 26641, - 26523, 26673, 26488, 26545, 26673, 26523, 20863, 20945, 20858, 26867, 26810, 26634, 26867, - 26634, 26833, 26634, 26785, 26833, 21228, 21252, 21213, 20945, 21031, 20858, 15054, 14962, - 15029, 14908, 14724, 15064, 14976, 14799, 14908, 14851, 14799, 14976, 14851, 14976, 14904, - 14851, 14904, 14878, 14904, 14928, 14878, 15837, 15731, 16025, 19082, 19265, 19219, 18875, - 18974, 18933, 21213, 21252, 21259, 24007, 24159, 24073, 24290, 24435, 24312, 26701, 26442, - 26555, 26833, 26785, 26967, 15287, 15230, 15344, 15216, 15230, 15287, 16164, 16142, 16308, - 16022, 15837, 16025, 17486, 17085, 17572, 17331, 17085, 17486, 17699, 17672, 17771, 16688, - 17038, 17091, 18849, 18724, 18589, 19285, 19120, 19374, 14878, 14928, 14775, 21259, 21252, - 21360, 15049, 15092, 15134, 15054, 14819, 14962, 19421, 19552, 19648, 19362, 19478, 19859, - 19213, 19265, 19082, 26620, 26687, 26555, 26754, 26687, 26620, 25767, 25247, 25529, 26260, - 26154, 25997, 26260, 25997, 26268, 21659, 21890, 21741, 21723, 21890, 21659, 16142, 16040, - 16166, 21428, 21259, 21360, 21428, 21360, 21451, 21031, 21301, 21319, 26920, 26833, 26967, - 26537, 26300, 26250, 15781, 15837, 16022, 21301, 21378, 21349, 26546, 26576, 26442, 26623, - 26576, 26546, 26726, 26545, 26131, 26967, 26593, 27022, 18023, 17753, 17824, 17699, 17753, - 17739, 18417, 18498, 18547, 15092, 14918, 15054, 15057, 15049, 15247, 24319, 24435, 24290, - 26687, 26701, 26555, 26754, 26701, 26687, 15230, 15057, 15247, 15111, 15463, 15591, 15111, - 15591, 15038, 14775, 14928, 14924, 14775, 14924, 14962, 16627, 16558, 16861, 16363, 16164, - 16308, 16142, 16038, 16040, 16750, 16861, 16890, 16705, 16688, 16739, 16596, 16555, 16705, - 16579, 16339, 16173, 16339, 16090, 16173, 19922, 19883, 20028, 19777, 19421, 19648, 22804, - 22859, 22947, 21378, 21432, 21494, 25046, 25109, 25074, 24557, 24555, 24840, 16558, 16440, - 16699, 16555, 16688, 16705, 24840, 24555, 24496, 16440, 16353, 16363, 15837, 15714, 15731, - 15613, 15714, 15837, 15781, 16022, 15900, 17313, 17325, 17392, 18741, 18798, 18450, 18741, - 18856, 18798, 18856, 18875, 18933, 17276, 17325, 17313, 17122, 17306, 17038, 19777, 19648, - 19760, 19041, 18844, 19009, 19253, 19478, 19362, 19253, 19362, 19265, 24699, 24840, 24496, - 26284, 26260, 26268, 26154, 26173, 26048, 26284, 26268, 26300, 19883, 19804, 19857, 23419, - 22859, 23198, 18501, 18417, 18547, 18584, 18547, 18724, 19104, 19120, 19285, 18798, 18510, - 18450, 18974, 18991, 19082, 26461, 26284, 26300, 26576, 26537, 26442, 26647, 26537, 26576, - 26701, 26599, 26442, 26796, 26599, 26701, 15285, 15578, 15629, 15907, 15804, 16070, 15527, - 15578, 15285, 14705, 15497, 15208, 19804, 19777, 19760, 21432, 21631, 21574, 23509, 23321, - 22930, 20624, 20648, 20570, 20744, 20648, 20761, 20761, 20958, 20863, 20863, 20958, 20945, - 20945, 20958, 21031, 21031, 21082, 21301, 21301, 21355, 21378, 21378, 21355, 21432, 21432, - 21584, 21631, 15900, 16022, 16040, 16164, 16038, 16142, 17325, 17408, 17526, 17330, 17408, - 17325, 26810, 26986, 26699, 27056, 26986, 26810, 27056, 26810, 26867, 17753, 17699, 17771, - 16386, 16440, 16558, 17940, 17753, 18023, 14799, 14724, 14908, 14679, 14724, 14799, 14679, - 14799, 14669, 20624, 20958, 20761, 21631, 21723, 21659, 21584, 21723, 21631, 18875, 18991, - 18974, 26599, 26623, 26546, 26507, 26461, 26300, 26767, 26623, 26599, 15216, 15140, 15230, - 15049, 14918, 15092, 15111, 15140, 15216, 15057, 15140, 14929, 16698, 17122, 17038, 18875, - 19039, 18991, 18336, 18111, 18174, 14525, 14730, 15297, 20958, 21082, 21031, 26260, 26173, - 26154, 26291, 26173, 26260, 26291, 26260, 26284, 18283, 18336, 18174, 14932, 14918, 15049, - 14669, 14799, 14851, 18067, 18023, 18181, 26796, 26754, 26957, 21213, 21162, 21139, 21139, - 21162, 21052, 21052, 20344, 20538, 20028, 19883, 20208, 19883, 19922, 19804, 19804, 19739, - 19777, 21259, 21162, 21213, 21302, 21162, 21259, 21302, 21259, 21428, 26833, 26920, 26867, - 26593, 26657, 27022, 19478, 19574, 19859, 19548, 19574, 19478, 16476, 16489, 16119, 16555, - 16476, 16688, 16688, 16606, 17038, 26507, 26300, 26537, 15875, 15900, 16040, 15762, 15731, - 15376, 17122, 17276, 17313, 18283, 18450, 18336, 17330, 17276, 17163, 16353, 16164, 16363, - 16038, 16007, 16040, 16440, 16388, 16353, 16386, 16388, 16440, 16750, 16890, 17085, 16627, - 16750, 16788, 17940, 17739, 17753, 21311, 21302, 21406, 17331, 17486, 17411, 25225, 25264, - 25109, 24840, 24941, 24977, 24957, 24941, 24840, 25664, 25750, 26103, 26623, 26647, 26576, - 26767, 26647, 26623, 14658, 14856, 15208, 14704, 14775, 14962, 15057, 14932, 15049, 16154, - 16164, 16353, 19241, 19180, 19285, 18092, 18181, 18417, 18092, 18067, 18181, 19241, 19285, - 19421, 18991, 19213, 19082, 19039, 19213, 18991, 19423, 19548, 19478, 20570, 20660, 19859, - 17411, 17672, 17699, 24159, 24319, 24290, 24620, 24699, 24496, 24007, 24319, 24159, 22930, - 22768, 23209, 26103, 25750, 26048, 20028, 20208, 20344, 19777, 19739, 19421, 27022, 26657, - 26673, 24620, 24496, 24435, 18584, 18724, 18753, 17940, 17864, 17739, 17371, 17411, 17699, - 22168, 21964, 21890, 26470, 26291, 26284, 26173, 26103, 26048, 26470, 26284, 26461, 17924, - 17864, 17940, 18336, 18450, 18510, 18854, 19039, 18875, 18062, 18111, 18264, 15140, 15057, - 15230, 15731, 15714, 15543, 15950, 16007, 16038, 15613, 15837, 15781, 24522, 24620, 24435, - 19180, 19104, 19285, 19214, 19104, 19180, 17708, 17699, 17739, 16788, 16750, 17085, 15613, - 15781, 15658, 17864, 17708, 17739, 18753, 18724, 18844, 26746, 26507, 26537, 14819, 15054, - 14918, 14819, 14918, 14745, 19922, 19739, 19804, 16007, 15875, 16040, 20648, 20624, 20761, - 20958, 21110, 21082, 21082, 21198, 21301, 20570, 19859, 20430, 14756, 14819, 14745, 19649, - 19859, 19574, 16489, 16476, 16555, 16090, 16279, 16070, 16476, 16606, 16688, 25109, 25264, - 25074, 25225, 25109, 24977, 25225, 24977, 24941, 24957, 24840, 24699, 19104, 19041, 19009, - 19040, 19041, 19104, 18696, 18875, 18741, 19213, 19253, 19265, 26796, 26767, 26599, 26647, - 26756, 26537, 26796, 26701, 26754, 14669, 14851, 14634, 14724, 14525, 15297, 16750, 16627, - 16861, 16388, 16154, 16353, 16164, 15950, 16038, 15878, 15791, 15875, 16788, 16758, 16683, - 18067, 17924, 17940, 17568, 17525, 17708, 18422, 18092, 18417, 19041, 18753, 18844, 18584, - 18501, 18547, 26920, 27056, 26867, 26957, 26754, 27213, 27156, 27056, 26920, 18069, 17924, - 18067, 17452, 17640, 17408, 18450, 18696, 18741, 26494, 26470, 26461, 26291, 26643, 26173, - 26494, 26461, 26507, 15563, 15804, 15907, 24319, 24380, 24435, 24800, 24957, 24699, 24243, - 24380, 24319, 14634, 14851, 14878, 16285, 16154, 16388, 16090, 16339, 16279, 17167, 17085, - 17331, 21122, 21110, 20958, 24943, 24911, 24379, 25381, 24911, 24943, 24800, 24699, 24620, - 19417, 19241, 19421, 19039, 19253, 19213, 19548, 19567, 19574, 21723, 22168, 21890, 21822, - 22168, 21723, 24262, 23452, 23886, 21311, 21203, 21302, 18629, 18501, 18584, 21162, 21203, - 21052, 19922, 19878, 19739, 21302, 21203, 21162, 21302, 21428, 21406, 21110, 21198, 21082, - 15804, 16090, 16070, 14756, 14704, 14962, 14620, 14634, 14878, 19423, 19567, 19548, 14620, - 14878, 14775, 20344, 20208, 20538, 19417, 19214, 19241, 21406, 21428, 21560, 17276, 17330, - 17325, 17163, 17276, 17122, 24052, 24243, 24007, 24380, 24522, 24435, 26767, 26753, 26647, - 26908, 26753, 26767, 18387, 18696, 18450, 19239, 19423, 19253, 19241, 19214, 19180, 19041, - 18893, 18753, 18629, 18422, 18501, 19417, 19421, 19739, 20028, 19977, 19922, 21560, 21428, - 21597, 21198, 21355, 21301, 18283, 18387, 18450, 18264, 18029, 18062, 14573, 14620, 14775, - 15791, 15781, 15900, 15791, 15900, 15875, 17411, 17218, 17331, 17525, 17371, 17699, 17525, - 17699, 17708, 18501, 18422, 18417, 17894, 17864, 17924, 17568, 17708, 17864, 18629, 18584, - 18753, 18353, 18387, 18283, 26470, 26643, 26291, 26660, 26494, 26507, 14819, 14756, 14962, - 14704, 14573, 14775, 14745, 14918, 14932, 14929, 14932, 15057, 14867, 14929, 15140, 14867, - 15140, 14869, 19253, 19423, 19478, 20430, 20600, 20570, 19239, 19253, 19039, 26753, 26756, - 26647, 26844, 26756, 26916, 15578, 15563, 15907, 15640, 15786, 16090, 15285, 15629, 15460, - 15878, 15875, 16007, 16427, 16558, 16627, 16427, 16386, 16558, 16154, 15950, 16164, 16427, - 16627, 16599, 16599, 16627, 16582, 21820, 22585, 22529, 24466, 24522, 24380, 26631, 26357, - 26517, 25332, 25225, 24941, 25332, 24941, 24957, 26641, 26685, 27213, 16386, 16285, 16388, - 16582, 16627, 16788, 14730, 14658, 15358, 14856, 14705, 15208, 14327, 14658, 14186, 14662, - 14705, 14856, 15613, 15543, 15714, 15477, 15543, 15613, 15527, 15563, 15578, 17371, 17218, - 17411, 17568, 17864, 17761, 17330, 17452, 17408, 17337, 17452, 17330, 19330, 19417, 19467, - 19214, 19040, 19104, 14597, 14525, 14724, 14597, 14724, 14679, 14597, 14679, 14479, 14679, - 14669, 14479, 20624, 20600, 20958, 21110, 21122, 21198, 21198, 21324, 21355, 20570, 20600, - 20624, 19649, 19574, 19567, 17167, 17218, 17159, 14479, 14669, 14482, 18174, 18353, 18283, - 17859, 18029, 17975, 16019, 15950, 16154, 15791, 15658, 15781, 19144, 19040, 19214, 21187, - 20344, 21052, 20028, 20052, 19977, 19977, 19878, 19922, 21187, 21052, 21203, 21187, 21203, - 21311, 21187, 21311, 21265, 24688, 24800, 24620, 18600, 18667, 18696, 18696, 18667, 18875, - 18093, 18353, 18174, 19662, 19649, 19616, 19649, 19567, 19616, 17608, 17749, 17897, 20600, - 21122, 20958, 21355, 21584, 21432, 14929, 14745, 14932, 14756, 14636, 14704, 14452, 14482, - 14634, 15376, 15591, 15762, 14702, 14692, 14745, 15950, 15878, 16007, 24522, 24688, 24620, - 26706, 26660, 26507, 26494, 26643, 26470, 26746, 26537, 26756, 15601, 15658, 15791, 15543, - 15376, 15731, 15527, 15492, 15563, 15563, 15537, 15804, 15405, 15492, 15527, 18069, 18067, - 18092, 17159, 17218, 17238, 17452, 17608, 17640, 17563, 17608, 17434, 21265, 21311, 21406, - 26967, 27156, 26920, 27213, 26685, 27676, 27160, 27156, 26967, 14658, 14662, 14856, 14565, - 14662, 14402, 22947, 22585, 22804, 21358, 21265, 21406, 27666, 27022, 26673, 27666, 26673, - 26545, 26726, 26131, 26116, 20344, 20052, 20028, 21358, 21406, 21560, 21122, 21324, 21198, - 18600, 18696, 18387, 26844, 26746, 26756, 18123, 18069, 18092, 18123, 18092, 18422, 17859, - 18062, 18029, 18111, 18093, 18174, 18341, 18600, 18387, 17859, 17975, 17749, 23806, 23419, - 23198, 23636, 23419, 23806, 16421, 16422, 16427, 16427, 16422, 16386, 16386, 16251, 16285, - 16285, 16158, 16154, 15950, 15812, 15878, 16421, 16427, 16599, 16422, 16251, 16386, 20052, - 19972, 19977, 21324, 21338, 21355, 15232, 15285, 15460, 17916, 17894, 17924, 17732, 17859, - 17749, 23509, 23704, 24007, 24466, 24584, 24522, 24522, 24584, 24688, 23631, 23704, 23509, - 22414, 22136, 22768, 26357, 25496, 26517, 16251, 16158, 16285, 16683, 16582, 16788, 17167, - 17331, 17218, 17036, 17167, 17159, 17371, 17238, 17218, 16906, 17163, 17122, 17608, 17702, - 17749, 16698, 17038, 16606, 16420, 16606, 16476, 16420, 16476, 16119, 26660, 26616, 26494, - 26741, 26616, 26660, 16158, 16047, 16154, 15878, 15794, 15791, 16758, 16788, 17085, 15523, - 15376, 15543, 15523, 15543, 15477, 15400, 15537, 15563, 15285, 15405, 15527, 17563, 17702, - 17608, 19972, 19878, 19977, 18900, 18893, 19040, 19040, 18893, 19041, 19144, 19214, 19417, - 18667, 18854, 18875, 18726, 18854, 18667, 14745, 14636, 14756, 14692, 14636, 14745, 16047, - 16019, 16154, 19330, 19144, 19417, 26796, 26908, 26767, 26746, 26706, 26507, 27877, 26986, - 27056, 18658, 18629, 18753, 18341, 18387, 18353, 21338, 21584, 21355, 26978, 26706, 26746, - 15477, 15613, 15658, 17163, 17244, 17330, 23779, 24052, 24007, 14538, 14573, 14704, 18069, - 17916, 17924, 17894, 17761, 17864, 17941, 17916, 18069, 18062, 18093, 18111, 17859, 17909, - 18062, 17890, 17909, 17859, 17732, 17749, 17702, 18355, 18123, 18422, 18054, 18093, 18062, - 21855, 21681, 21560, 21576, 21681, 21581, 14597, 14436, 14525, 14525, 14502, 14730, 14350, - 14436, 14597, 15285, 15350, 15405, 15400, 15563, 15492, 15232, 15350, 15285, 15812, 15794, - 15878, 17780, 17761, 17894, 17719, 17732, 17702, 18629, 18355, 18422, 18093, 18341, 18353, - 22768, 22136, 22168, 23704, 23779, 24007, 23789, 23779, 23704, 26616, 26643, 26494, 26774, - 26643, 26616, 14869, 15140, 15111, 14945, 15111, 15038, 18893, 18755, 18753, 18629, 18326, - 18355, 18889, 18755, 18893, 18624, 18726, 18667, 19616, 19567, 19522, 18624, 18667, 18600, - 26916, 26756, 26753, 26706, 26741, 26660, 20382, 20430, 19859, 20524, 21165, 21122, 21122, - 21165, 21324, 21324, 21165, 21338, 21338, 21423, 21584, 20382, 19859, 19649, 26957, 26908, - 26796, 27035, 26908, 27213, 14482, 14669, 14634, 14436, 14502, 14525, 15357, 15492, 15405, - 16241, 16420, 16119, 17244, 17337, 17330, 24911, 24262, 24086, 19239, 19039, 18808, 14917, - 14945, 15038, 14917, 15591, 14841, 17434, 17608, 17452, 23419, 22947, 22859, 23301, 22947, - 23419, 26980, 26741, 26706, 14702, 14745, 14929, 14636, 14538, 14704, 17167, 17036, 17085, - 17371, 17350, 17238, 19264, 19239, 19217, 24466, 24380, 24243, 25359, 25365, 24800, 24800, - 25332, 24957, 24466, 24243, 24052, 16158, 16006, 16047, 16047, 16006, 16019, 16019, 15812, - 15950, 16251, 16237, 16158, 16422, 16237, 16251, 16421, 16237, 16422, 16421, 16599, 16582, - 16524, 16582, 16683, 16401, 16420, 16241, 17163, 17131, 17244, 17244, 17227, 17337, 16420, - 16436, 16606, 14452, 14634, 14620, 14452, 14620, 14573, 16758, 16524, 16683, 19522, 19567, - 19423, 20382, 20582, 20430, 20582, 21122, 20600, 27156, 27160, 27056, 27022, 27160, 26967, - 19144, 18900, 19040, 18755, 18658, 18753, 18805, 18900, 19144, 22790, 22529, 22585, 26908, - 26916, 26753, 26980, 26774, 26741, 27035, 26916, 26908, 14945, 14869, 15111, 14420, 14591, - 14692, 15523, 15131, 15376, 15601, 15477, 15658, 17337, 17434, 17452, 17403, 17434, 17345, - 18728, 18658, 18755, 22947, 22790, 22585, 22865, 22768, 22168, 21715, 21723, 21584, 26643, - 26103, 26173, 25767, 26120, 25351, 25381, 25009, 24911, 24911, 24462, 24262, 15868, 16006, - 16158, 15558, 15601, 15791, 15350, 15357, 15405, 15133, 15232, 15460, 15133, 15460, 14938, - 17371, 17525, 17350, 17036, 16758, 17085, 16906, 17131, 17163, 23846, 23636, 23806, 22947, - 23037, 22790, 24160, 24466, 24052, 14591, 14538, 14636, 14591, 14636, 14692, 16847, 16758, - 17036, 20382, 19649, 19662, 19239, 19522, 19423, 17732, 17890, 17859, 17909, 18054, 18062, - 18464, 18600, 18341, 17563, 17719, 17702, 17403, 17719, 17563, 19972, 19933, 19878, 19467, - 19417, 19739, 20052, 19933, 19972, 20014, 19933, 20052, 20136, 20052, 20344, 20136, 20344, - 20271, 21358, 21187, 21265, 21576, 21358, 21560, 21576, 21560, 21681, 24131, 23846, 23806, - 14945, 14848, 14869, 14801, 14917, 14751, 26741, 26774, 26616, 26586, 26120, 26819, 26978, - 26746, 26844, 14342, 14452, 14573, 21165, 21423, 21338, 15467, 15601, 15558, 14751, 14917, - 14779, 16994, 16847, 17036, 17482, 17525, 17568, 18900, 18889, 18893, 18728, 18889, 18900, - 17761, 17482, 17568, 17686, 17482, 17761, 17780, 17894, 17916, 17941, 18069, 18123, 17941, - 18123, 18028, 18123, 18355, 18194, 14662, 14565, 14705, 14402, 14662, 14658, 14702, 14929, - 14867, 14801, 14848, 14945, 18464, 18624, 18600, 18726, 18639, 18854, 19612, 19616, 19522, - 18464, 18341, 18327, 21581, 21681, 21880, 21423, 21553, 21584, 18326, 18629, 18389, 26357, - 26653, 26116, 27847, 27877, 27160, 26631, 26653, 26357, 15232, 15191, 15350, 15133, 15191, - 15232, 17429, 17350, 17525, 16994, 17036, 17159, 17429, 17525, 17482, 14702, 14867, 14869, - 14538, 14455, 14573, 16429, 16421, 16582, 16237, 16165, 16158, 16006, 15812, 16019, 16429, - 16582, 16524, 16429, 16524, 16365, 16436, 16698, 16606, 16420, 16401, 16436, 16489, 16173, - 16119, 16173, 15786, 16119, 18194, 18326, 18204, 26653, 26726, 26116, 14848, 14702, 14869, - 16421, 16429, 16365, 26916, 26976, 26844, 27035, 26976, 26916, 15191, 15357, 15350, 20430, - 20582, 20600, 21165, 21499, 21423, 21423, 21499, 21553, 20382, 19662, 19642, 23779, 24003, - 24052, 23789, 24003, 23779, 23789, 23704, 23631, 14479, 14350, 14597, 14436, 14267, 14502, - 14327, 14402, 14658, 14352, 14350, 14479, 14352, 14479, 14412, 14412, 14479, 14482, 14412, - 14482, 14375, 18624, 18639, 18726, 18221, 18341, 18093, 19642, 19662, 19616, 19612, 19642, - 19616, 19264, 19522, 19239, 16335, 16698, 16436, 17227, 17434, 17337, 17434, 17403, 17563, - 25381, 24943, 25351, 24262, 24131, 23806, 19721, 19739, 19878, 18389, 18629, 18559, 14375, - 14482, 14452, 15357, 15400, 15492, 16365, 16524, 16450, 17543, 17429, 17482, 17227, 17244, - 17131, 17931, 18054, 17909, 25009, 24462, 24911, 15868, 15812, 16006, 14451, 14455, 14538, - 14451, 14538, 14591, 18194, 18028, 18123, 17780, 17686, 17761, 18194, 18355, 18326, 17890, - 17732, 17688, 23636, 23516, 23419, 22501, 22236, 22529, 23561, 23516, 23636, 23561, 23636, - 23814, 15100, 15214, 15357, 15308, 15429, 15400, 14446, 15497, 14705, 17688, 17732, 17719, - 20271, 20344, 20329, 19933, 19975, 19878, 21344, 21187, 21358, 18616, 18639, 18624, 18616, - 18624, 18464, 26976, 26978, 26844, 26774, 26980, 26643, 27035, 26978, 26976, 18629, 18658, - 18559, 18054, 18221, 18093, 23516, 23301, 23419, 22529, 22236, 21855, 17780, 17916, 17941, - 20136, 20014, 20052, 16698, 16906, 17122, 22651, 22529, 22790, 14917, 14801, 14945, 14848, - 14766, 14702, 14420, 14451, 14591, 15398, 15523, 15477, 15467, 15477, 15601, 18559, 18658, - 18728, 23301, 23037, 22947, 15558, 15791, 15794, 17811, 17931, 17890, 17187, 17227, 17131, - 24462, 24346, 24262, 24502, 24346, 24462, 14307, 14375, 14452, 20014, 19975, 19933, 21503, - 21344, 21358, 21503, 21358, 21576, 24264, 24131, 24262, 22927, 22651, 22790, 27213, 26908, - 26957, 16220, 16165, 16237, 16220, 16237, 16421, 16220, 16421, 16365, 17159, 17107, 16994, - 16401, 16335, 16436, 16537, 16897, 16906, 16173, 16090, 15786, 21581, 21503, 21576, 21608, - 21499, 21165, 21553, 21704, 21584, 25225, 25657, 25264, 25365, 25332, 24800, 24800, 24688, - 25359, 25365, 25359, 25498, 16090, 15804, 15640, 18728, 18755, 18889, 14420, 14692, 14322, - 14455, 14342, 14573, 17890, 17931, 17909, 18054, 17931, 18221, 18221, 18327, 18341, 17688, - 17719, 17403, 15467, 15398, 15477, 15388, 15398, 15467, 15558, 15794, 15618, 17227, 17345, - 17434, 17187, 17345, 17227, 23301, 23244, 23037, 23037, 23027, 22790, 23516, 23346, 23301, - 23561, 23346, 23516, 23407, 23244, 23346, 24346, 24264, 24262, 24415, 24264, 24346, 17686, - 17543, 17482, 17792, 17780, 17941, 17673, 17780, 17792, 17941, 17833, 17792, 18028, 18194, - 18204, 21569, 21581, 21880, 21499, 21549, 21553, 23631, 23509, 23209, 24003, 24160, 24052, - 23631, 23209, 23427, 16012, 15868, 16158, 15618, 15794, 15812, 17811, 18327, 18221, 17673, - 17543, 17686, 17159, 17238, 17107, 15640, 15804, 15537, 18805, 18728, 18900, 18204, 18326, - 18389, 18805, 19144, 19330, 19975, 19721, 19878, 21549, 21704, 21553, 14335, 14267, 14436, - 14335, 14436, 14350, 14335, 14350, 14300, 14350, 14352, 14300, 14300, 14352, 14412, 14801, - 14766, 14848, 14751, 14766, 14801, 26978, 26980, 26706, 27035, 26980, 26978, 16897, 17187, - 17131, 17214, 17688, 17403, 16897, 17131, 16906, 20382, 20443, 20582, 20582, 20524, 21122, - 21608, 21731, 21549, 21549, 21731, 21704, 20375, 20443, 20382, 24696, 24502, 24462, 23636, - 24002, 23814, 14229, 14300, 14412, 14307, 14412, 14375, 14306, 14342, 14455, 14306, 14455, - 14451, 21704, 21715, 21584, 21731, 21715, 21704, 19217, 19239, 18808, 20294, 20375, 20382, - 19039, 18854, 18808, 20329, 20344, 20637, 20136, 20064, 20014, 20014, 20064, 19975, 19975, - 19790, 19721, 21369, 21187, 21344, 21369, 21344, 21503, 24111, 24160, 24003, 23427, 23209, - 22865, 15704, 15618, 15812, 15558, 15494, 15467, 15414, 15640, 15537, 15429, 15537, 15400, - 17238, 17350, 17107, 16537, 16906, 16698, 20271, 20180, 20136, 17780, 17673, 17686, 17107, - 17350, 17429, 18204, 18389, 18444, 17811, 17688, 17581, 18448, 18473, 18327, 18444, 18389, - 18559, 23346, 23244, 23301, 24077, 24131, 24264, 14658, 14730, 14186, 14565, 14512, 14705, - 19515, 19612, 19522, 21715, 21822, 21723, 21731, 21822, 21715, 15308, 15400, 15214, 24502, - 24415, 24346, 16165, 16094, 16158, 15868, 15704, 15812, 16054, 16094, 16165, 16054, 16165, - 16220, 14398, 14512, 14565, 15214, 15400, 15357, 16094, 16012, 16158, 16450, 16524, 16758, - 16241, 16335, 16401, 16178, 16335, 16241, 16044, 16241, 16119, 16044, 16119, 15932, 18311, - 18444, 18559, 19472, 19515, 19522, 18808, 18854, 18639, 20180, 20064, 20136, 23244, 23027, - 23037, 22651, 22501, 22529, 21470, 21503, 21581, 27676, 26699, 26986, 28182, 27470, 26980, - 15618, 15602, 15558, 14841, 15591, 15376, 15561, 15602, 15618, 16847, 16450, 16758, 17107, - 17429, 17011, 25009, 24696, 24462, 24502, 24623, 24415, 24876, 24696, 25110, 16012, 15923, - 15868, 20375, 20524, 20443, 19472, 19522, 19264, 14171, 14307, 14452, 21470, 21369, 21503, - 21470, 21581, 21569, 16335, 16537, 16698, 18616, 18808, 18639, 18616, 18464, 18473, 15429, - 15414, 15537, 15357, 15191, 15072, 18473, 18464, 18327, 23027, 22927, 22790, 15602, 15494, - 15558, 15491, 15494, 15602, 17480, 17429, 17543, 16994, 16826, 16847, 21681, 21855, 22102, - 24077, 23846, 24131, 23244, 23191, 23027, 23027, 22929, 22927, 26103, 26120, 25767, 26586, - 26819, 26786, 17833, 17941, 18028, 17673, 17602, 17543, 17833, 18028, 17819, 19721, 19467, - 19739, 18101, 18204, 18444, 19355, 19467, 19617, 19462, 19472, 19264, 20382, 20002, 20294, - 19462, 19264, 19354, 23561, 23407, 23346, 15923, 15704, 15868, 17654, 17602, 17673, 20064, - 19790, 19975, 22102, 21855, 22236, 14994, 15376, 15131, 14322, 14692, 14246, 15494, 15388, - 15467, 15345, 15388, 15407, 22927, 22691, 22651, 22849, 22691, 22927, 14627, 14702, 14766, - 14177, 14247, 14307, 22334, 22102, 22236, 14186, 14730, 14502, 14402, 14398, 14565, 15072, - 15191, 15133, 15308, 15352, 15429, 24111, 24003, 23789, 14751, 14627, 14766, 17811, 18221, - 17931, 18616, 18575, 18808, 19354, 19264, 19255, 23191, 22929, 23027, 14267, 14208, 14502, - 14098, 14208, 14267, 14098, 14267, 14335, 14176, 14335, 14300, 15704, 15561, 15618, 16950, - 16826, 16994, 16950, 16994, 17107, 20443, 20524, 20582, 19566, 19612, 19515, 14229, 14176, - 14300, 14229, 14412, 14247, 16012, 15971, 15923, 15923, 15671, 15704, 15597, 15491, 15561, - 16094, 15971, 16012, 16203, 16054, 16220, 16203, 16220, 16261, 15932, 16119, 15775, 16335, - 16221, 16537, 16119, 15786, 15775, 16261, 16220, 16365, 16044, 16178, 16241, 25678, 25381, - 25351, 14548, 14938, 15460, 16054, 15971, 16094, 16383, 16261, 16365, 17792, 17654, 17673, - 17011, 16950, 17107, 17819, 18028, 18031, 21875, 21731, 21628, 21822, 21961, 22168, 14247, - 14412, 14307, 23686, 23427, 23698, 23631, 23801, 23789, 14512, 14446, 14705, 14190, 14398, - 14402, 15131, 15523, 15398, 14751, 14680, 14627, 14938, 15072, 15133, 17642, 17654, 17792, - 15180, 15352, 15308, 15180, 15308, 15214, 14424, 14446, 14512, 16520, 16450, 16847, 17480, - 17543, 17602, 16347, 16383, 16450, 22691, 22501, 22651, 22587, 22501, 22691, 15072, 15100, - 15357, 17654, 17480, 17602, 21731, 21900, 21822, 21875, 21900, 21731, 24530, 24077, 24264, - 23561, 23593, 23407, 23407, 23410, 23244, 24501, 24264, 24415, 24623, 24502, 24696, 20180, - 20085, 20064, 20064, 19833, 19790, 19617, 19467, 19721, 20171, 20085, 20180, 20320, 20180, - 20271, 20344, 21187, 20637, 21486, 21369, 21470, 14177, 14307, 14171, 14208, 14186, 14502, - 14181, 14424, 14398, 14420, 14306, 14451, 14240, 14306, 14420, 15352, 15414, 15429, 15168, - 15180, 15214, 15195, 15414, 15352, 24876, 24623, 24696, 14171, 14452, 14342, 14994, 14841, - 15376, 23814, 23593, 23561, 22929, 22849, 22927, 17688, 17811, 17890, 17581, 17688, 17214, - 17403, 17345, 17214, 17345, 17187, 17000, 17187, 16897, 16727, 18473, 18575, 18616, 18448, - 18575, 18473, 23003, 22849, 22929, 24002, 23636, 23846, 24002, 23846, 24077, 23427, 23801, - 23631, 23593, 23410, 23407, 15072, 15078, 15100, 15168, 15194, 15180, 14905, 15078, 15072, - 14905, 15072, 14938, 21569, 21486, 21470, 21528, 21486, 21569, 21528, 21569, 21653, 22501, - 22334, 22236, 22429, 22334, 22501, 24075, 24002, 24077, 19472, 19462, 19515, 19557, 19462, - 19354, 14779, 14680, 14751, 14627, 14476, 14702, 15388, 15345, 15398, 14994, 14857, 14841, - 15407, 15388, 15494, 15491, 15602, 15561, 23410, 23191, 23244, 24623, 24501, 24415, 24530, - 24501, 24623, 14248, 14171, 14342, 21880, 21681, 22102, 15118, 15131, 15398, 16178, 16152, - 16335, 15954, 16152, 16178, 15954, 16178, 16044, 15671, 15561, 15704, 15775, 15786, 15705, - 16152, 16221, 16335, 22202, 22145, 22102, 15598, 15786, 15640, 16450, 16383, 16365, 15988, - 15920, 16203, 16203, 15920, 16054, 15803, 15923, 15971, 15652, 15671, 15923, 16771, 16847, - 16826, 14398, 14424, 14512, 14548, 14815, 14938, 14190, 14402, 14327, 14571, 14558, 14627, - 22334, 22202, 22102, 22587, 22429, 22501, 22587, 22691, 22849, 23191, 23003, 22929, 17833, - 17642, 17792, 17654, 17642, 17480, 17480, 17011, 17429, 16950, 16771, 16826, 18031, 18028, - 18204, 18031, 18204, 18101, 15180, 15194, 15352, 15510, 15598, 15640, 15168, 15214, 15100, - 14841, 14779, 14917, 14680, 14571, 14627, 14717, 14779, 14841, 18311, 18559, 18397, 14176, - 14098, 14335, 14208, 13982, 14186, 14102, 14098, 14176, 14102, 14176, 14229, 14102, 14229, - 14029, 14229, 14000, 14029, 14988, 14987, 14994, 15016, 15168, 15100, 14815, 14905, 14938, - 17810, 17642, 17833, 15053, 14988, 15131, 15131, 14988, 14994, 15491, 15407, 15494, 15323, - 15407, 15491, 16829, 17011, 16677, 14083, 14247, 14177, 14363, 14692, 14702, 14306, 14248, - 14342, 15597, 15671, 15569, 21505, 21369, 21486, 20637, 21187, 20882, 19833, 19617, 19790, - 20294, 20002, 20196, 21608, 21549, 21499, 22230, 22202, 22334, 21578, 21505, 21528, 15204, - 15398, 15345, 23936, 24111, 23789, 24572, 24584, 24466, 26517, 25496, 25264, 26653, 27039, - 26726, 26726, 27344, 26545, 14558, 14476, 14627, 14487, 14476, 14558, 20329, 20320, 20271, - 18070, 17963, 18031, 19566, 19642, 19612, 20320, 20171, 20180, 14240, 14248, 14306, 14145, - 14083, 14177, 15510, 15640, 15303, 19557, 19566, 19515, 19557, 19515, 19462, 21900, 21961, - 21822, 23817, 23936, 23801, 23801, 23936, 23789, 21608, 21165, 21479, 14562, 14571, 14680, - 18302, 18448, 18327, 19264, 19217, 19255, 15303, 15640, 15414, 15016, 15100, 15078, 25928, - 26517, 25264, 25657, 25225, 25332, 14145, 14177, 14171, 16829, 16771, 16950, 16829, 16950, - 17011, 14092, 14190, 14327, 14120, 14327, 14186, 14779, 14683, 14680, 14791, 14717, 14841, - 14857, 14994, 14987, 14731, 14857, 14864, 17819, 17810, 17833, 16770, 16829, 16677, 17886, - 17810, 17819, 18031, 17963, 17819, 18805, 19330, 19283, 18558, 18808, 18575, 20256, 20359, - 20294, 21875, 21961, 21900, 21834, 21961, 21875, 15906, 15954, 16044, 16152, 16008, 16221, - 17000, 17187, 16727, 15906, 16044, 15932, 15906, 15932, 15750, 19283, 19330, 19467, 22985, - 22587, 22849, 22429, 22230, 22334, 25381, 25378, 25009, 25678, 25531, 25381, 14476, 14363, - 14702, 14470, 14487, 14558, 14470, 14558, 14571, 18529, 18558, 18575, 14155, 14145, 14171, - 15750, 15932, 15775, 18311, 18101, 18444, 23686, 23801, 23427, 24572, 24466, 24160, 25657, - 25365, 25670, 25804, 25678, 25351, 26631, 27039, 26653, 26900, 27039, 26631, 15261, 15204, - 15345, 14988, 14985, 14987, 15261, 15345, 15407, 24501, 24530, 24264, 24002, 23959, 23814, - 23814, 23799, 23593, 23582, 23334, 23410, 23410, 23334, 23191, 23191, 23156, 23003, 23003, - 22985, 22849, 24856, 24530, 24623, 26120, 25804, 25351, 17011, 16595, 16677, 21528, 21505, - 21486, 21578, 21528, 21653, 21569, 21880, 21653, 25110, 24696, 25009, 14322, 14240, 14420, - 14248, 14155, 14171, 14089, 14240, 14322, 15086, 15053, 15131, 14946, 15016, 15078, 15195, - 15352, 15194, 14838, 15078, 14905, 15624, 15705, 15786, 15624, 15786, 15598, 15604, 15624, - 15598, 14108, 14155, 14248, 22102, 22145, 21880, 21479, 21165, 20778, 14296, 14363, 14476, - 14275, 14363, 14296, 15204, 15118, 15398, 15151, 15118, 15204, 18448, 18529, 18575, 19255, - 19217, 19061, 18429, 18529, 18448, 19617, 19721, 19790, 19217, 18808, 19061, 20256, 20294, - 20196, 14857, 14791, 14841, 14717, 14683, 14779, 14731, 14791, 14857, 14985, 14988, 15053, - 15671, 15597, 15561, 15920, 15971, 16054, 16203, 16261, 15988, 16261, 16383, 15988, 22865, - 23209, 22768, 13799, 14120, 13560, 14548, 15460, 14446, 21880, 22145, 22199, 21608, 21628, - 21731, 22289, 22865, 22168, 14641, 14683, 14717, 17963, 17886, 17819, 16677, 16470, 16434, - 18101, 18070, 18031, 18083, 18070, 18101, 14936, 14985, 15053, 24393, 24075, 24077, 23959, - 24197, 23973, 14098, 14019, 14208, 14102, 14010, 14098, 13927, 14010, 14102, 14229, 14247, - 14000, 14247, 14083, 14000, 14010, 14019, 14098, 14683, 14562, 14680, 21186, 21369, 21396, - 21186, 21187, 21369, 20329, 20243, 20320, 20320, 20243, 20171, 19086, 19283, 19121, 21369, - 21505, 21396, 15195, 15194, 14995, 15194, 15168, 14995, 14120, 14092, 14327, 14101, 14181, - 14398, 14270, 14548, 14446, 13799, 14092, 14120, 19355, 19283, 19467, 18397, 18559, 18728, - 20064, 20085, 19833, 19642, 20002, 20382, 19061, 18808, 18894, 15323, 15261, 15407, 15118, - 15086, 15131, 14995, 15168, 15016, 20375, 20359, 20524, 21588, 21730, 21628, 20294, 20359, - 20375, 19566, 20002, 19642, 14000, 14083, 14050, 14914, 15086, 15118, 14946, 14995, 15016, - 19566, 19406, 20002, 26517, 26608, 26631, 26780, 26608, 26517, 15906, 16008, 15954, 15954, - 16008, 16152, 15750, 16008, 15906, 15750, 15775, 15705, 15689, 15705, 15624, 14562, 14470, - 14571, 16347, 16450, 16520, 25378, 25110, 25009, 25678, 25663, 25531, 25769, 25663, 25678, - 14050, 14083, 14145, 16829, 16770, 16771, 17724, 17642, 17810, 19566, 19557, 19386, 14240, - 14108, 14248, 14045, 14050, 14145, 14089, 14108, 14240, 14334, 14692, 14363, 15920, 15803, - 15971, 15167, 15151, 15261, 19833, 20085, 20210, 22199, 22145, 22202, 21396, 21505, 21433, - 21628, 21834, 21875, 21730, 21834, 21628, 14045, 14145, 14155, 21505, 21578, 21433, 14101, - 14398, 14190, 22370, 22230, 22429, 22561, 22429, 22587, 14791, 14641, 14717, 14683, 14549, - 14562, 14387, 14399, 14470, 14864, 14857, 14987, 14864, 14987, 14985, 23959, 23799, 23814, - 23686, 23817, 23801, 24572, 24160, 24145, 23698, 23817, 23686, 14936, 14864, 14985, 14815, - 14838, 14905, 14204, 14838, 14815, 15261, 15151, 15204, 15086, 14936, 15053, 15323, 15491, - 15368, 24075, 23959, 24002, 24393, 24077, 24530, 16520, 16847, 16771, 19386, 19557, 19354, - 14092, 14137, 14190, 13799, 14137, 14092, 14514, 14549, 14683, 23582, 23410, 23593, 14275, - 14334, 14363, 14476, 14487, 14296, 15517, 15491, 15597, 15195, 15303, 15414, 15510, 15604, - 15598, 15313, 15303, 15161, 14922, 15195, 14995, 22289, 22168, 21961, 14914, 14936, 15086, - 14838, 14946, 15078, 21433, 21578, 21552, 15652, 15569, 15671, 15526, 15604, 15510, 14214, - 14246, 14692, 18188, 18311, 18362, 18070, 17886, 17963, 18894, 18808, 18757, 19255, 19287, - 19354, 23292, 23156, 23191, 13992, 14045, 14155, 13992, 14155, 14108, 14084, 14089, 14322, - 21552, 21578, 21653, 21552, 21653, 21636, 28136, 27676, 26986, 26103, 27470, 26931, 27877, - 27056, 27160, 15569, 15517, 15597, 16770, 16520, 16771, 16571, 16520, 16770, 25378, 25381, - 25531, 24581, 24393, 24530, 24581, 24530, 24856, 14334, 14214, 14692, 14386, 14487, 14470, - 20210, 20085, 20171, 19121, 19283, 19323, 18397, 18728, 18805, 21636, 21653, 21880, 14399, - 14386, 14470, 14731, 14641, 14791, 14387, 14470, 14562, 14563, 14641, 14731, 14718, 14731, - 14864, 17902, 17886, 18070, 23156, 22985, 23003, 24160, 24111, 24145, 22865, 23698, 23427, - 14245, 14214, 14334, 13961, 13998, 13955, 14064, 14446, 14424, 14838, 14980, 14946, 18188, - 18083, 18101, 16205, 15988, 16383, 15920, 15849, 15803, 15803, 15652, 15923, 15569, 15459, - 15517, 16231, 16383, 16347, 25365, 25657, 25332, 24111, 23936, 24145, 15822, 15849, 15920, - 25804, 25769, 25678, 25663, 25659, 25531, 25991, 25769, 25804, 25991, 25804, 26120, 25991, - 26230, 26141, 15151, 14914, 15118, 14936, 14718, 14864, 15323, 15167, 15261, 15042, 15167, - 15323, 24145, 23936, 23817, 18311, 18188, 18101, 18397, 18805, 18542, 23181, 22937, 22985, - 23334, 23292, 23191, 23518, 23292, 23334, 23582, 23593, 23799, 23582, 23799, 23659, 15689, - 15750, 15705, 15689, 15624, 15575, 25615, 25378, 25531, 14946, 14980, 14995, 15303, 15313, - 15510, 14922, 14980, 14115, 15517, 15368, 15491, 15402, 15368, 15517, 14922, 15303, 15195, - 14029, 13927, 14102, 14010, 13802, 14019, 14019, 13982, 14208, 13769, 13927, 14029, 13979, - 14029, 14000, 13979, 14000, 14050, 13802, 13982, 14019, 14137, 14101, 14190, 14181, 14064, - 14424, 13815, 14101, 14137, 14301, 14296, 14487, 14130, 14245, 14334, 14301, 14487, 14386, - 15684, 15652, 15803, 15575, 15624, 15604, 16438, 16231, 16347, 19186, 19287, 19255, 19186, - 19255, 19061, 21588, 21628, 21608, 21834, 22289, 21961, 22230, 22199, 22202, 22370, 22199, - 22230, 21186, 20882, 21187, 20465, 20243, 20329, 21063, 20882, 21186, 21063, 21186, 21091, - 21512, 21396, 21433, 14084, 14322, 14246, 14130, 14334, 14275, 14387, 14562, 14549, 19086, - 18805, 19283, 18529, 18511, 18558, 18302, 18429, 18448, 18302, 18327, 17811, 16374, 16640, - 16897, 15526, 15575, 15604, 20465, 20329, 20637, 20778, 21165, 20524, 20256, 20227, 20359, - 20196, 20227, 20256, 20242, 20227, 20207, 20227, 20196, 20207, 13905, 13979, 14050, 13905, - 14050, 14045, 13905, 14045, 13872, 20243, 20210, 20171, 23698, 23819, 23817, 23849, 23819, - 23698, 18083, 17902, 18070, 16677, 16571, 16770, 17959, 17902, 18083, 17896, 17902, 17959, - 23659, 23799, 23788, 14914, 14718, 14936, 14641, 14563, 14683, 16537, 16374, 16897, 15605, - 15459, 15569, 15313, 15526, 15510, 19175, 19186, 19022, 19287, 19386, 19354, 13998, 14108, - 14089, 23819, 24145, 23817, 26608, 26872, 26631, 26780, 26872, 26608, 14296, 14226, 14275, - 14294, 14301, 14386, 14294, 14386, 14399, 18757, 18808, 18558, 22722, 22561, 22587, 22722, - 22587, 22985, 22722, 22985, 22937, 14084, 14246, 14214, 14084, 14214, 14005, 15066, 15151, - 15167, 15066, 14914, 15151, 15459, 15402, 15517, 16520, 16438, 16347, 16595, 16470, 16677, - 16537, 16221, 16374, 18511, 18757, 18558, 17581, 18302, 17811, 14005, 14214, 14245, 15066, - 15167, 15042, 17000, 17214, 17345, 19283, 19355, 19323, 18922, 19086, 19006, 22510, 22370, - 22429, 21843, 21636, 21880, 21552, 21512, 21433, 26784, 26780, 26517, 25769, 25659, 25663, - 25378, 25371, 25110, 25657, 25762, 25264, 25498, 25670, 25365, 15849, 15744, 15803, 15652, - 15605, 15569, 15459, 15446, 15402, 15988, 15822, 15920, 15856, 15822, 15988, 16205, 16383, - 16231, 20559, 20524, 20359, 21730, 22289, 21834, 25659, 25615, 25531, 24856, 24623, 24876, - 25670, 25762, 25657, 16312, 16205, 16231, 17724, 17810, 17886, 16374, 16221, 16008, 15822, - 15744, 15849, 25615, 25515, 25378, 25359, 24688, 24584, 25359, 24584, 25158, 14511, 14563, - 14731, 14514, 14563, 14511, 17902, 17896, 17886, 18138, 18083, 18188, 18138, 18188, 18362, - 23925, 23799, 23959, 23261, 23181, 23292, 23925, 23959, 23973, 24197, 24075, 24430, 18511, - 18529, 18429, 19175, 19232, 19186, 22561, 22510, 22429, 22985, 23156, 23181, 15744, 15684, - 15803, 16438, 16520, 16571, 18385, 18511, 18429, 23181, 23156, 23292, 25498, 25359, 25519, - 21479, 21588, 21608, 15182, 15323, 15368, 14380, 14514, 14359, 15182, 15368, 15402, 24856, - 24876, 25069, 15684, 15605, 15652, 19232, 19386, 19287, 19232, 19287, 19186, 26069, 25991, - 26141, 25769, 25853, 25659, 16640, 16727, 16897, 17000, 17134, 17214, 14380, 14387, 14549, - 14301, 14226, 14296, 27039, 27344, 26726, 27338, 27275, 27039, 26900, 26631, 26872, 13998, - 13992, 14108, 13961, 13992, 13998, 21843, 21880, 22199, 15526, 15505, 15575, 15575, 15499, - 15689, 15689, 15499, 15750, 16260, 16374, 15677, 16640, 16632, 16727, 15424, 15505, 15526, - 15161, 15526, 15313, 16454, 16374, 16260, 14294, 14226, 14301, 13955, 13998, 14089, 13927, - 13802, 14010, 13982, 13809, 14186, 13769, 13802, 13927, 13826, 14029, 13979, 13826, 13979, - 13905, 20242, 20559, 20227, 19175, 19022, 19139, 13802, 13809, 13982, 20227, 20559, 20359, - 21558, 21666, 21588, 20196, 20081, 20207, 14101, 14064, 14181, 13815, 14064, 14101, 14387, - 14294, 14399, 16550, 16438, 16571, 16550, 16571, 16677, 16727, 16879, 17000, 16732, 16879, - 16727, 16958, 17134, 17000, 17214, 17221, 17581, 18365, 18385, 18302, 18302, 18385, 18429, - 18365, 18302, 18192, 18511, 18768, 18757, 18757, 18768, 18894, 19086, 18922, 18805, 19355, - 19617, 19323, 20699, 20465, 20637, 20243, 20266, 20210, 20210, 19887, 19833, 20699, 20637, - 20882, 21877, 21843, 22233, 22612, 22510, 22561, 22612, 22561, 22722, 23973, 23788, 23925, - 25082, 24876, 25110, 27275, 27344, 27039, 20465, 20339, 20243, 23518, 23334, 23582, 22937, - 22829, 22722, 23925, 23788, 23799, 24594, 24393, 24581, 14563, 14514, 14683, 14387, 14053, - 14294, 14731, 14718, 14511, 20196, 20002, 20081, 21512, 21186, 21396, 21756, 21843, 21877, - 21636, 21512, 21552, 13872, 13826, 13905, 20081, 20002, 20093, 27847, 27160, 28034, 16434, - 16550, 16677, 26956, 26900, 26872, 27275, 27408, 27344, 26956, 26872, 26780, 18362, 18311, - 18397, 17401, 17480, 17642, 21879, 22289, 21730, 23054, 23849, 23698, 13701, 13872, 14045, - 19406, 19566, 19386, 27738, 27160, 27022, 15541, 15579, 15684, 15684, 15579, 15605, 15822, - 15757, 15744, 16205, 15856, 15988, 15757, 15856, 15666, 15856, 16205, 15666, 25928, 26784, - 26517, 25670, 25746, 25762, 25498, 25685, 25670, 25583, 25685, 25498, 25583, 25498, 25519, - 25685, 25746, 25670, 14064, 14262, 14446, 14548, 14204, 14815, 16814, 16958, 16879, 16879, - 16958, 17000, 25519, 25359, 25528, 25911, 25853, 25769, 25659, 25789, 25615, 25694, 25371, - 25515, 25515, 25371, 25378, 14078, 14130, 14275, 13992, 13701, 14045, 14078, 14275, 14226, - 13955, 14089, 13918, 25564, 25519, 25528, 15528, 15459, 15605, 15284, 15182, 15402, 14511, - 14254, 14321, 16523, 16632, 16640, 18542, 18362, 18397, 18610, 18768, 18511, 18192, 18302, - 17581, 17221, 17214, 17134, 23518, 23582, 23726, 15676, 15684, 15744, 25694, 25515, 25615, - 19323, 19617, 19370, 18922, 18751, 18805, 15579, 15528, 15605, 13961, 13823, 13992, 13918, - 14089, 14084, 16958, 17109, 17134, 16806, 17109, 16958, 21648, 21512, 21636, 24856, 24594, - 24581, 24689, 24594, 24856, 25928, 25264, 25762, 14023, 14005, 14245, 13658, 14078, 14226, - 13658, 14226, 14294, 16632, 16732, 16727, 18610, 18511, 18316, 19232, 19406, 19386, 14514, - 14380, 14549, 14718, 14254, 14511, 23726, 23582, 23659, 23726, 23659, 23788, 15528, 15446, - 15459, 27338, 27408, 27275, 26864, 26956, 26780, 14023, 14245, 14130, 19121, 19006, 19086, - 19194, 19006, 19121, 27596, 27666, 26545, 27596, 26545, 27344, 19175, 19406, 19232, 27666, - 27738, 27022, 14262, 14270, 14446, 14980, 14922, 14995, 23518, 23261, 23292, 23091, 22829, - 22937, 27338, 27039, 26900, 16632, 16626, 16732, 16374, 16454, 16640, 15614, 16008, 15750, - 21756, 21648, 21636, 21756, 21636, 21843, 21947, 21831, 21877, 21588, 21666, 21730, 21417, - 21588, 21479, 16732, 16814, 16879, 16626, 16814, 16732, 26784, 26864, 26780, 26845, 26864, - 26784, 23091, 22937, 23181, 14262, 14167, 14270, 14067, 14167, 14262, 19370, 19617, 19833, - 23316, 23091, 23181, 14434, 14914, 15066, 13944, 14023, 14078, 25746, 25928, 25762, 25685, - 25808, 25746, 25660, 25808, 25685, 25660, 25685, 25583, 13560, 14120, 14186, 14064, 14067, - 14262, 13796, 13961, 13955, 14078, 14023, 14130, 14244, 14387, 14380, 15856, 15757, 15822, - 15579, 15458, 15528, 15528, 15340, 15446, 16312, 16231, 16438, 16454, 16523, 16640, 20784, - 20699, 20882, 20465, 20365, 20339, 20339, 20266, 20243, 20784, 20882, 21063, 21091, 21186, - 21512, 21495, 21091, 21512, 22199, 22370, 22233, 24197, 23959, 24075, 23518, 23550, 23261, - 23207, 22974, 23091, 25540, 25082, 25110, 24430, 24075, 24393, 25564, 25660, 25583, 25564, - 25583, 25519, 27662, 27596, 27344, 27666, 27900, 27738, 13826, 13769, 14029, 13802, 13587, - 13809, 13809, 13560, 14186, 13594, 13769, 13661, 13769, 13826, 13661, 14394, 14359, 14514, - 15757, 15676, 15744, 18138, 17959, 18083, 18016, 17959, 18138, 18153, 18138, 18362, 25693, - 25564, 25560, 25813, 25789, 25659, 25371, 25540, 25110, 25991, 25911, 25769, 26069, 25911, - 25991, 25809, 25928, 25746, 20471, 20365, 20465, 24430, 24393, 24594, 15676, 15541, 15684, - 14115, 14980, 14838, 15505, 15499, 15575, 20365, 20266, 20339, 20242, 20248, 20559, 21323, - 21417, 21479, 20207, 20248, 20242, 20197, 20248, 20207, 20197, 20207, 20081, 14270, 14286, - 14548, 14239, 14286, 14270, 18245, 18153, 18362, 18896, 18922, 19006, 13796, 13823, 13961, - 13918, 14084, 13938, 22491, 22370, 22510, 21495, 21512, 21556, 15541, 15458, 15579, 15021, - 15042, 15182, 15182, 15042, 15323, 15424, 15499, 15505, 16414, 16545, 16523, 20093, 20197, - 20081, 21512, 21648, 21556, 13938, 14084, 14005, 14922, 15161, 15303, 16545, 16626, 16523, - 16523, 16626, 16632, 19865, 20093, 20002, 19186, 19061, 19022, 25082, 25069, 24876, 25215, - 25069, 25082, 17173, 17221, 17134, 17110, 17134, 17109, 17110, 17109, 16955, 24689, 24430, - 24594, 13999, 14067, 13952, 14167, 14236, 14270, 19865, 20002, 19406, 18617, 18744, 18634, - 22829, 22612, 22722, 22796, 22612, 22829, 15365, 15424, 15526, 14153, 14236, 14167, 27408, - 27490, 27344, 27520, 27490, 27408, 27338, 26900, 27417, 16806, 16958, 16814, 15284, 15402, - 15446, 13918, 13796, 13955, 13944, 13938, 14005, 13944, 14005, 14023, 15340, 15284, 15446, - 14359, 14317, 14380, 14511, 14394, 14514, 14321, 14394, 14511, 23776, 23726, 23788, 22974, - 22796, 22829, 23776, 23788, 23973, 23776, 23973, 24022, 13771, 13796, 13918, 13620, 13701, - 13992, 13799, 13815, 14137, 13571, 13815, 13799, 18153, 18016, 18138, 17724, 17886, 17896, - 18245, 18016, 18153, 13620, 13992, 13823, 18751, 18542, 18805, 18896, 18751, 18922, 18477, - 18751, 18617, 21556, 21648, 21687, 21648, 21756, 21687, 21498, 21417, 21323, 21666, 21879, - 21730, 16550, 16434, 16438, 16406, 16434, 16470, 16545, 16806, 16626, 16626, 16806, 16814, - 14236, 14239, 14270, 14286, 14178, 14548, 14090, 14239, 14236, 14153, 14167, 14067, 18431, - 18245, 18362, 18365, 18192, 18385, 19139, 19216, 19175, 18130, 18192, 17527, 17237, 17581, - 17221, 17173, 17134, 17110, 21687, 21756, 21803, 21417, 21558, 21588, 25813, 25659, 25853, - 25808, 25809, 25746, 26818, 26845, 26784, 25660, 25747, 25808, 25693, 25747, 25660, 25693, - 25660, 25564, 25911, 25813, 25853, 25747, 25809, 25808, 15499, 15614, 15750, 15426, 15614, - 15499, 25789, 25694, 25615, 25528, 25359, 25158, 16955, 17173, 17110, 25911, 26058, 25813, - 26457, 26315, 26230, 15284, 15162, 15182, 14321, 14317, 14394, 16414, 16523, 16454, 21803, - 21756, 21877, 25694, 25473, 25371, 25991, 26457, 26230, 22974, 22829, 23091, 22612, 22491, - 22510, 27665, 27662, 27344, 27596, 27881, 27666, 24171, 23973, 24197, 23726, 23550, 23518, - 13999, 14153, 14067, 18542, 18431, 18362, 18425, 18431, 18542, 14394, 14317, 14359, 14902, - 15066, 15042, 23776, 23550, 23726, 24430, 24171, 24197, 24360, 24171, 24430, 24689, 24856, - 25069, 25991, 26586, 26457, 27201, 26900, 26956, 27490, 27665, 27344, 13789, 13944, 14078, - 13938, 13771, 13918, 16806, 16955, 17109, 17080, 16955, 16663, 22703, 22491, 22612, 25215, - 24689, 25069, 26818, 26784, 25928, 26864, 26950, 26956, 21831, 21803, 21877, 13594, 13587, - 13802, 13594, 13802, 13769, 13661, 13826, 13513, 15162, 15021, 15182, 20699, 20541, 20465, - 20365, 20335, 20266, 20266, 19887, 20210, 18401, 18542, 18477, 20784, 20541, 20699, 20784, - 21063, 21091, 20784, 20692, 20590, 21091, 21495, 21464, 21495, 21556, 21662, 21662, 21556, - 21687, 20541, 20471, 20465, 20248, 20416, 20559, 21417, 21498, 21558, 20328, 20416, 20248, - 20167, 20248, 20197, 20167, 20197, 20093, 13513, 13826, 13872, 15424, 15426, 15499, 15161, - 15365, 15526, 15239, 15365, 15161, 16406, 16312, 16438, 15389, 15541, 15502, 15389, 15458, - 15541, 15340, 15528, 15458, 15340, 15244, 15284, 15284, 15244, 15162, 14880, 14960, 15021, - 16406, 16438, 16434, 15677, 16374, 16008, 16545, 16663, 16806, 17173, 17237, 17221, 17150, - 17237, 17173, 20471, 20335, 20365, 21803, 21662, 21687, 22233, 21843, 22199, 13785, 13771, - 13938, 13796, 13704, 13823, 13433, 13513, 13455, 19175, 19216, 19406, 19061, 18894, 19022, - 22438, 22233, 22370, 19865, 20167, 20093, 15541, 15676, 15502, 17724, 17896, 17959, 16260, - 16414, 16454, 27662, 27772, 27596, 27738, 28034, 27160, 27864, 27772, 27662, 15021, 14902, - 15042, 14960, 14902, 15021, 14153, 14090, 14236, 14239, 14178, 14286, 15326, 15426, 15365, - 14040, 14090, 14153, 26845, 26950, 26864, 27094, 26950, 27002, 13599, 13704, 13650, 18016, - 17724, 17959, 18150, 17724, 18016, 18255, 18016, 18245, 23819, 23849, 24145, 24585, 25158, - 24572, 23054, 23698, 22865, 23054, 22865, 22892, 16377, 16595, 16316, 13650, 13704, 13796, - 13944, 13785, 13938, 13789, 13785, 13944, 19022, 18894, 18768, 20447, 20328, 20167, 25809, - 25870, 25928, 25858, 25870, 25809, 25858, 25809, 25747, 25858, 25747, 25693, 25694, 25673, - 25473, 25473, 25540, 25371, 25758, 25673, 25694, 25856, 25694, 25789, 25856, 25789, 25813, - 25959, 25813, 26058, 26078, 26069, 26141, 25870, 25986, 25928, 14094, 14178, 14239, 13952, - 14067, 14064, 14090, 14094, 14239, 22796, 22703, 22612, 22491, 22438, 22370, 23316, 23181, - 23261, 25673, 25608, 25473, 26349, 26078, 26141, 22942, 22703, 22796, 20778, 20524, 20559, - 21558, 21519, 21666, 28212, 28034, 28180, 27847, 28333, 27877, 27877, 28136, 26986, 17527, - 18192, 17581, 16955, 17150, 17173, 17180, 17150, 17080, 15551, 15676, 15757, 15055, 15021, - 15162, 15666, 16205, 15874, 16229, 16312, 16406, 15365, 15426, 15424, 16212, 16215, 16260, - 16260, 16215, 16414, 15239, 15161, 14942, 25608, 25540, 25473, 25158, 24584, 24572, 14040, - 14094, 14090, 18431, 18255, 18245, 18303, 18255, 18431, 18425, 18542, 18401, 23550, 23316, - 23261, 23207, 23316, 23464, 23316, 23550, 23623, 19182, 19406, 19216, 18610, 19022, 18768, - 18511, 18385, 18316, 22390, 22438, 22491, 21947, 21662, 21831, 27772, 27881, 27596, 27907, - 27881, 27903, 21498, 21519, 21558, 15389, 15340, 15458, 26230, 26349, 26141, 25991, 26120, - 26586, 14317, 14244, 14380, 14251, 14321, 14254, 13704, 13620, 13823, 13599, 13620, 13704, - 13835, 13952, 14064, 13999, 14040, 14153, 13835, 14064, 13815, 14254, 14718, 14434, 15136, - 15162, 15244, 21831, 21662, 21803, 21947, 21877, 22233, 13981, 14040, 13999, 14942, 15161, - 14922, 16354, 16229, 16406, 16354, 16406, 16470, 16212, 16260, 15677, 16414, 16364, 16545, - 18303, 18425, 18401, 22892, 22865, 22289, 26931, 26819, 26120, 27637, 27665, 27490, 27520, - 27408, 27338, 14207, 14244, 14317, 13699, 13789, 14078, 13650, 13796, 13771, 13587, 13565, - 13809, 13594, 13565, 13587, 13556, 13565, 13594, 13556, 13594, 13661, 17527, 17581, 17237, - 20510, 20742, 20559, 21498, 21484, 21519, 20510, 20559, 20416, 20510, 20416, 20328, 27625, - 27520, 27338, 28333, 28136, 27877, 26518, 26586, 26603, 13411, 13556, 13661, 15128, 15136, - 15244, 16377, 16354, 16470, 20541, 20555, 20471, 20471, 20362, 20335, 20335, 20362, 20266, - 20784, 20555, 20541, 20451, 20555, 20542, 20328, 20248, 20167, 20742, 20778, 20559, 26518, - 26603, 26528, 20555, 20362, 20471, 19182, 19216, 19139, 15874, 16205, 16312, 15389, 15305, - 15340, 15340, 15128, 15244, 16210, 16312, 16229, 25959, 25856, 25813, 25673, 25793, 25608, - 25608, 25552, 25540, 25911, 26069, 26058, 26069, 26121, 26058, 26078, 26121, 26069, 25870, - 26034, 25986, 27027, 27002, 26845, 25792, 25858, 25693, 26078, 26279, 26121, 13469, 13513, - 13433, 15666, 15551, 15757, 18316, 18385, 18192, 22792, 22892, 22289, 25856, 25758, 25694, - 26230, 26315, 26349, 25974, 26034, 25870, 19132, 19182, 19139, 19132, 19139, 19022, 27881, - 27900, 27666, 27907, 27900, 27881, 15551, 15502, 15676, 26349, 26315, 26528, 15136, 15055, - 15162, 14251, 14207, 14321, 14941, 15055, 15136, 18255, 18150, 18016, 18425, 18303, 18431, - 18262, 18303, 18215, 18130, 18316, 18192, 23316, 23207, 23091, 22974, 22942, 22796, 22557, - 22390, 22491, 23759, 23550, 23776, 24585, 24572, 24145, 25528, 25560, 25564, 17180, 17527, - 17237, 18130, 18156, 18316, 17180, 17237, 17150, 25793, 25552, 25608, 25317, 25215, 25082, - 25609, 25560, 25528, 13699, 13745, 13789, 14321, 14207, 14317, 14914, 14434, 14718, 13650, - 13771, 13541, 13620, 13550, 13701, 21927, 21947, 22000, 20542, 20555, 20784, 22390, 22233, - 22438, 27094, 27201, 26956, 27094, 26956, 26950, 20778, 21323, 21479, 22794, 22792, 22693, - 15289, 15305, 15389, 15426, 15335, 15614, 15239, 15326, 15365, 15361, 15326, 15233, 26528, - 26315, 26457, 14178, 14204, 14548, 14094, 14148, 14178, 13922, 14148, 13830, 13924, 14094, - 14040, 19011, 19132, 19022, 20195, 20447, 20167, 27900, 28030, 27738, 27903, 27881, 27772, - 27864, 27662, 27665, 15055, 14880, 15021, 14909, 14880, 15055, 14586, 14942, 14922, 13395, - 13560, 13809, 17080, 17150, 16955, 21323, 21341, 21498, 27002, 26950, 26845, 13952, 13981, - 13999, 13788, 13981, 13952, 16272, 16210, 16229, 16272, 16229, 16354, 16272, 16354, 16377, - 16215, 16286, 16414, 15677, 16008, 15614, 13499, 13550, 13620, 13662, 13771, 13785, 18303, - 18262, 18255, 19194, 19121, 19323, 20078, 19887, 20266, 21341, 21484, 21498, 27520, 27637, - 27490, 27625, 27637, 27520, 13789, 13745, 13785, 14053, 14387, 14244, 15271, 15128, 15340, - 16470, 16595, 16377, 16212, 16286, 16215, 22557, 22491, 22703, 26586, 26518, 26457, 26931, - 26120, 26103, 14207, 14087, 14244, 14254, 14017, 14071, 14148, 14204, 14178, 14117, 14204, - 13922, 19887, 19370, 19833, 13571, 13835, 13815, 13981, 13924, 14040, 14125, 14087, 14207, - 21879, 21666, 21519, 22892, 23200, 23054, 23054, 23200, 23849, 23849, 24585, 24145, 27923, - 27864, 27665, 13825, 13924, 13981, 18477, 18542, 18751, 16286, 16364, 16414, 24625, 24360, - 24430, 24171, 24022, 23973, 24625, 24430, 24689, 13499, 13620, 13599, 13499, 13599, 13520, - 25856, 25910, 25758, 25758, 25793, 25673, 25317, 25082, 25540, 25959, 25910, 25856, 26062, - 25910, 25959, 26062, 25959, 26058, 26062, 26058, 26138, 26279, 26078, 26349, 25910, 25793, - 25758, 25560, 25792, 25693, 25858, 25974, 25870, 26818, 25928, 25986, 25609, 25792, 25560, - 13406, 13699, 13296, 13520, 13599, 13650, 15305, 15271, 15340, 15502, 15417, 15389, 15551, - 15417, 15502, 15315, 15417, 15551, 15315, 15551, 15666, 15874, 16312, 16210, 15995, 15874, - 16210, 18262, 18150, 18255, 18215, 18150, 18262, 18019, 18156, 17970, 18316, 18199, 18610, - 18917, 19011, 18877, 18199, 18156, 18019, 17180, 17203, 17527, 16663, 16955, 16806, 13556, - 13407, 13565, 13565, 13395, 13809, 13411, 13407, 13556, 13411, 13661, 13513, 13407, 13445, - 13565, 14941, 14909, 15055, 15066, 14902, 14434, 14941, 15136, 15128, 20742, 20705, 20778, - 20778, 20895, 21323, 21323, 21367, 21341, 21341, 21367, 21484, 20510, 20705, 20742, 20649, - 20705, 20510, 20649, 20510, 20447, 25636, 25540, 25552, 15417, 15289, 15389, 15326, 15361, - 15426, 16212, 16262, 16286, 16286, 16262, 16364, 15137, 15326, 15239, 25158, 25609, 25528, - 26480, 26279, 26349, 28136, 28248, 27676, 28256, 28248, 28136, 28236, 27847, 28034, 20362, - 20247, 20266, 20555, 20451, 20362, 21464, 21495, 21662, 20705, 20895, 20778, 13469, 13411, - 13513, 20451, 20356, 20362, 19430, 19194, 19370, 13835, 13788, 13952, 13924, 13784, 14094, - 13726, 13788, 13835, 13513, 13872, 13455, 13662, 13785, 13745, 13455, 13872, 13701, 14902, - 14552, 14434, 14251, 14125, 14207, 14087, 14053, 14244, 15289, 15271, 15305, 20356, 20247, - 20362, 21489, 21879, 21519, 21489, 21519, 21484, 27907, 28030, 27900, 28038, 28030, 27907, - 22877, 23200, 22892, 22794, 22892, 22792, 27864, 27903, 27772, 27923, 27903, 27864, 13455, - 13701, 13424, 14071, 14125, 14251, 26155, 25986, 26034, 27094, 27227, 27201, 27661, 27625, - 27338, 13424, 13701, 13550, 14942, 15137, 15239, 15138, 15137, 14830, 20247, 20078, 20266, - 26518, 26528, 26457, 26603, 26586, 26786, 13560, 13571, 13799, 13052, 13571, 13560, 21947, - 21927, 21662, 22000, 21947, 22233, 14125, 14053, 14087, 27173, 27227, 27094, 27899, 27923, - 27665, 27417, 26900, 27201, 13500, 13662, 13745, 13541, 13662, 13500, 28212, 28236, 28034, - 27903, 28038, 27907, 13788, 13825, 13981, 13726, 13825, 13788, 18401, 18215, 18303, 18617, - 18751, 18896, 23207, 22942, 22974, 22390, 22000, 22233, 23163, 22942, 23207, 16553, 16663, - 16545, 16150, 16262, 16212, 27470, 26103, 26643, 21393, 21367, 21323, 28034, 27738, 28180, - 13541, 13520, 13650, 13379, 13424, 13550, 21701, 21464, 21662, 22049, 22000, 22122, 18156, - 18199, 18316, 18156, 18130, 17970, 25910, 26062, 25793, 25793, 25636, 25552, 26138, 26058, - 26121, 26138, 26121, 26172, 26121, 26304, 26172, 25982, 25974, 25858, 25982, 25858, 25906, - 13472, 13550, 13499, 21701, 21662, 21794, 21367, 21489, 21484, 26480, 26349, 26528, 25974, - 26155, 26034, 24270, 24022, 24171, 23883, 24022, 24060, 27398, 27417, 27201, 14902, 14960, - 14666, 14961, 14941, 15128, 16272, 16065, 16210, 16257, 16377, 16316, 19132, 19103, 19182, - 18990, 19011, 18917, 24022, 23759, 23776, 26980, 27470, 26643, 26695, 26480, 26528, 15361, - 15335, 15426, 15233, 15335, 15361, 25802, 25636, 25793, 28180, 27738, 28030, 27794, 27661, - 27338, 27818, 27665, 27637, 27903, 28033, 28038, 13825, 13859, 13924, 13726, 13859, 13825, - 22693, 22792, 22289, 22693, 22289, 22507, 15138, 15233, 15137, 15137, 15233, 15326, 26735, - 26528, 26603, 21794, 21662, 21927, 25215, 25160, 24689, 25273, 25160, 25215, 26786, 26783, - 26603, 27035, 28182, 26980, 28298, 28180, 28413, 24248, 24585, 23849, 25671, 25689, 25609, - 25906, 25858, 25792, 23252, 23849, 23200, 16187, 16065, 16272, 15199, 15315, 15666, 15198, - 15271, 15289, 15104, 15070, 15271, 15271, 15070, 15128, 13367, 13472, 13291, 13472, 13499, - 13291, 21942, 21794, 21927, 21942, 21927, 22000, 13407, 13393, 13445, 13445, 13395, 13565, - 13411, 13393, 13407, 13172, 13393, 13206, 13206, 13411, 13469, 13316, 13469, 13433, 13316, - 13433, 13455, 13316, 13455, 13388, 13393, 13289, 13445, 20447, 20510, 20328, 20705, 20837, - 20895, 20895, 21064, 21323, 21367, 21393, 21489, 13289, 13395, 13445, 20590, 20542, 20784, - 20451, 20484, 20356, 20356, 20484, 20247, 20247, 20213, 20078, 20784, 20790, 20692, 20590, - 20692, 20657, 20649, 20837, 20705, 28248, 28566, 27676, 28642, 28256, 28136, 28333, 27847, - 28236, 28333, 28236, 28298, 14125, 14026, 14053, 13500, 13745, 13699, 14254, 14071, 14251, - 14960, 14880, 14666, 24022, 23883, 23759, 23759, 23623, 23550, 24270, 24171, 24360, 15315, - 15289, 15417, 14860, 14880, 14909, 18744, 18896, 19006, 18399, 18215, 18401, 17011, 16619, - 16595, 19194, 19323, 19370, 19370, 19887, 19849, 20542, 20484, 20451, 19865, 19406, 19182, - 26819, 26783, 26786, 27035, 28493, 28182, 27702, 27637, 27625, 28413, 28180, 28030, 24625, - 24270, 24360, 13859, 13784, 13924, 14204, 14117, 14838, 13703, 13784, 13859, 20837, 20976, - 20895, 13662, 13541, 13771, 13500, 13699, 13561, 20058, 19887, 20078, 23755, 23623, 23759, - 20976, 21064, 20895, 22942, 22557, 22703, 22956, 22557, 22942, 27923, 28033, 27903, 27227, - 27285, 27201, 27771, 27702, 27661, 27173, 27285, 27227, 27173, 27094, 27002, 13388, 13455, - 13424, 20484, 20213, 20247, 15070, 14961, 15128, 16377, 16257, 16272, 17642, 17724, 17401, - 25160, 24997, 24689, 25563, 25317, 25540, 26897, 26783, 26819, 25974, 26175, 26155, 26155, - 26204, 25986, 25906, 25792, 25936, 27661, 27702, 27625, 27771, 27661, 27794, 15316, 15614, - 15335, 15316, 15677, 15614, 25689, 25792, 25609, 21861, 21942, 22049, 21743, 21464, 21701, - 26138, 26172, 26062, 26062, 25802, 25793, 25636, 25632, 25540, 26304, 26121, 26279, 26304, - 26279, 26401, 26175, 26204, 26155, 16553, 16545, 16364, 17080, 17084, 17180, 16150, 16364, - 16262, 25125, 24997, 25160, 19011, 19103, 19132, 18990, 19103, 19011, 13326, 13388, 13424, - 13326, 13424, 13307, 14860, 14909, 14941, 15683, 15666, 15874, 15070, 14882, 14961, 15995, - 16210, 16065, 16663, 17020, 17080, 20213, 20058, 20078, 25796, 25802, 25838, 26401, 26279, - 26480, 27286, 27173, 27412, 28298, 28236, 28212, 28298, 28212, 28180, 13347, 13726, 13835, - 14961, 14860, 14941, 14763, 14860, 14961, 16187, 15995, 16065, 17401, 17724, 18150, 23211, - 23252, 23200, 22507, 22289, 21879, 21414, 21879, 21489, 25317, 25273, 25215, 25432, 25273, - 25317, 15315, 15198, 15289, 18399, 18401, 18477, 18399, 18477, 18617, 22877, 22892, 22794, - 25802, 25632, 25636, 25735, 25689, 25671, 26695, 26401, 26480, 27702, 27818, 27637, 27923, - 28120, 28033, 13307, 13424, 13379, 21205, 21393, 21323, 13922, 14204, 14148, 14148, 14094, - 13830, 17905, 17401, 18150, 24270, 24140, 24022, 23883, 23755, 23759, 24194, 24140, 24411, - 14071, 14026, 14125, 14017, 14026, 14071, 23464, 23163, 23207, 23877, 23755, 23883, 15198, - 15104, 15271, 15120, 15138, 14830, 15233, 15120, 15335, 16187, 16272, 16257, 25632, 25563, - 25540, 13379, 13550, 13472, 27285, 27398, 27201, 27887, 27946, 27818, 27452, 27398, 27285, - 13561, 13699, 13406, 13367, 13379, 13472, 19011, 19022, 18877, 20558, 20649, 20447, 19022, - 18610, 18877, 24997, 24894, 24689, 25020, 24894, 24997, 13830, 14094, 13784, 26931, 26897, - 26819, 26783, 26735, 26603, 27136, 26897, 26931, 27794, 27338, 27512, 13499, 13520, 13291, - 20058, 19849, 19887, 28205, 28030, 28038, 17020, 17084, 17080, 17076, 17084, 16839, 18458, - 18399, 18617, 18215, 17905, 18150, 18617, 18896, 18744, 24894, 24625, 24689, 27818, 27899, - 27665, 28033, 28205, 28038, 28057, 27899, 28003, 13698, 13830, 13784, 13699, 14078, 13658, - 13291, 13520, 13541, 14860, 14666, 14880, 15104, 14882, 15070, 16295, 16187, 16257, 16295, - 16257, 16316, 16117, 16150, 16212, 16689, 16839, 17020, 20558, 20402, 20577, 18877, 18610, - 18569, 22551, 22507, 22526, 22693, 22877, 22794, 26843, 26735, 26783, 14687, 14666, 14860, - 14434, 14017, 14254, 16619, 17011, 17480, 16381, 16553, 16364, 25273, 25125, 25160, 24894, - 24730, 24625, 25166, 25125, 25273, 24140, 24060, 24022, 24194, 24060, 24140, 23464, 23316, - 23623, 24060, 23877, 23883, 13291, 13382, 13278, 25982, 26175, 25974, 27292, 27173, 27002, - 25906, 26056, 25982, 25936, 26056, 25906, 28586, 27213, 27676, 25735, 25936, 25792, 18458, - 18555, 18372, 18399, 18177, 18215, 22766, 22877, 22693, 13393, 13172, 13289, 13289, 13282, - 13395, 13395, 12987, 13560, 13603, 13703, 13726, 13206, 13393, 13411, 13206, 13469, 13226, - 13469, 13316, 13226, 13316, 13256, 13226, 13388, 13256, 13316, 13174, 13256, 13388, 13172, - 13282, 13289, 16254, 16295, 16316, 20542, 20493, 20484, 20484, 20487, 20213, 20213, 20077, - 20058, 20058, 19891, 19849, 21743, 21701, 21794, 20649, 20639, 20837, 20837, 20907, 20976, - 20976, 20972, 21064, 21064, 21205, 21323, 20558, 20639, 20649, 19182, 19103, 19101, 13726, - 13703, 13859, 13698, 13703, 13603, 20590, 20493, 20542, 19101, 19103, 18990, 23629, 23623, - 23755, 21853, 21861, 22049, 23744, 23629, 23755, 27887, 27818, 27702, 27512, 27338, 27417, - 20493, 20487, 20484, 20743, 20907, 20837, 22662, 22551, 22586, 13326, 13174, 13388, 18228, - 18610, 18199, 18988, 19101, 18990, 22507, 22551, 22693, 21414, 21489, 21393, 25563, 25476, - 25317, 25632, 25698, 25563, 25802, 25796, 25632, 25721, 25796, 25838, 25802, 26356, 25838, - 26899, 26172, 26304, 26598, 26304, 26401, 25689, 25735, 25792, 25671, 25609, 25158, 21942, - 21861, 21794, 21743, 21861, 21853, 13326, 13243, 13174, 14666, 14552, 14902, 14520, 14552, - 14666, 17401, 16619, 17480, 16595, 16459, 16316, 13922, 13868, 14117, 13830, 13861, 13922, - 13688, 13861, 13830, 17970, 18130, 17527, 23629, 23464, 23623, 13326, 13307, 13243, 21058, - 21088, 21064, 25796, 25698, 25632, 25672, 25671, 25158, 24956, 24730, 24894, 24411, 24140, - 24270, 24956, 24894, 25020, 27173, 27286, 27285, 27543, 27512, 27417, 26818, 25986, 26552, - 17076, 17203, 17084, 16150, 16381, 16364, 21088, 21205, 21064, 13476, 13541, 13500, 13243, - 13307, 13263, 18634, 18458, 18617, 18744, 19006, 19194, 18988, 18990, 18917, 26757, 26695, - 26528, 26757, 26528, 26735, 26757, 26735, 26843, 27899, 28057, 27923, 27946, 27899, 27818, - 13307, 13379, 13263, 21205, 21255, 21393, 28661, 28642, 28136, 28298, 28384, 28333, 28511, - 28384, 28298, 13703, 13698, 13784, 13688, 13698, 13603, 13967, 14017, 14434, 13406, 13476, - 13561, 18019, 18228, 18199, 18903, 18988, 18917, 18972, 18744, 19194, 24411, 24270, 24625, - 24060, 23971, 23877, 23677, 23564, 23629, 23629, 23564, 23464, 27452, 27417, 27398, 27887, - 27702, 27771, 28003, 27946, 28127, 28116, 28120, 27923, 24666, 24411, 24625, 25020, 24997, - 25125, 17084, 17203, 17180, 18019, 18025, 18228, 17084, 17020, 16839, 24666, 24625, 24730, - 27286, 27452, 27285, 13263, 13379, 13188, 14689, 14687, 14860, 13967, 13896, 14017, 16569, - 16459, 16595, 16150, 16193, 16381, 15953, 16117, 16212, 15953, 16212, 15677, 19849, 19430, - 19370, 19751, 19430, 19849, 25668, 25476, 25563, 26843, 26783, 26897, 13188, 13379, 13367, - 13561, 13476, 13500, 13093, 13188, 13367, 13772, 14053, 14026, 13861, 13868, 13922, 15234, - 15335, 15120, 13688, 13868, 13861, 16534, 16663, 16553, 16534, 16553, 16381, 17203, 17970, - 17527, 18903, 18917, 18877, 19101, 19865, 19182, 23090, 23092, 23293, 23163, 23092, 22942, - 23677, 23629, 23744, 24862, 24666, 24730, 28244, 28205, 28033, 16295, 16161, 16187, 16187, - 16161, 15995, 15995, 15854, 15874, 14882, 15104, 14883, 14763, 14882, 14729, 14673, 14763, - 14729, 14882, 14763, 14961, 16254, 16161, 16295, 16117, 16193, 16150, 25476, 25432, 25317, - 27060, 26843, 26897, 26552, 25986, 26204, 27657, 27543, 27594, 23366, 23163, 23464, 22877, - 23211, 23200, 23252, 24248, 23849, 22551, 22766, 22693, 22662, 22766, 22551, 13278, 13367, - 13291, 19307, 19865, 19101, 25936, 26038, 26056, 26056, 26175, 25982, 25970, 26038, 25936, - 25970, 25936, 25735, 26111, 26175, 26056, 16619, 16569, 16595, 16378, 16254, 16316, 16512, - 16569, 16619, 16443, 16569, 16512, 16505, 16534, 16319, 27405, 27136, 26931, 15234, 15316, - 15335, 16117, 16074, 16193, 15233, 15138, 15120, 25848, 25970, 25735, 13698, 13688, 13830, - 13603, 13726, 13347, 16689, 17020, 16663, 24956, 24834, 24730, 24992, 24834, 24956, 15120, - 15045, 15129, 25756, 25735, 25671, 25756, 25848, 25735, 14883, 15198, 15315, 14448, 14434, - 14552, 16378, 16316, 16459, 26818, 26922, 26845, 27027, 26922, 27102, 23246, 24248, 23252, - 26022, 26145, 26192, 27512, 27709, 27794, 27452, 27543, 27417, 27448, 27452, 27286, 14017, - 13896, 14026, 14520, 14666, 14687, 15137, 14942, 14830, 15683, 15854, 15623, 16161, 15854, - 15995, 25698, 25668, 25563, 25476, 25535, 25432, 25796, 25721, 25698, 25764, 25721, 25838, - 26598, 26401, 26695, 26598, 26695, 26757, 24680, 25158, 24585, 21861, 21743, 21794, 21942, - 22000, 22049, 23744, 23755, 23877, 23564, 23537, 23464, 24203, 24060, 24194, 24203, 24194, - 24293, 24194, 24411, 24293, 28609, 28413, 28519, 25721, 25668, 25698, 25113, 25020, 25125, - 26918, 26598, 26757, 26918, 26757, 26843, 28057, 28116, 27923, 28120, 28244, 28033, 28443, - 28437, 28413, 28149, 28116, 28057, 28003, 27899, 27946, 13347, 13835, 13203, 16534, 16689, - 16663, 16707, 16689, 16505, 23051, 23211, 22877, 25166, 25273, 25268, 24570, 24411, 24666, - 27887, 27771, 27794, 20493, 20567, 20487, 20487, 20077, 20213, 20590, 20657, 20493, 20784, - 21091, 20790, 20639, 20743, 20837, 20907, 20972, 20976, 21088, 21104, 21205, 21205, 21160, - 21255, 20558, 20607, 20639, 20577, 20607, 20558, 20607, 20743, 20639, 13282, 13142, 13395, - 13067, 13142, 13282, 13067, 13282, 13172, 13067, 13172, 13034, 13172, 13206, 13034, 13034, - 12933, 12934, 12983, 13256, 13174, 13150, 13174, 13243, 13150, 13243, 13263, 14763, 14689, - 14860, 14673, 14689, 14763, 16443, 16378, 16459, 15623, 15854, 15650, 20402, 20558, 20447, - 26922, 27027, 26845, 27114, 27027, 27166, 20195, 20402, 20447, 13658, 14294, 14053, 13382, - 13291, 13541, 24468, 24680, 24585, 28345, 28244, 28120, 16009, 15953, 15910, 16193, 16051, - 16381, 20743, 20972, 20907, 22526, 22507, 22440, 18884, 18903, 18877, 17970, 18025, 18019, - 17965, 18025, 17970, 17965, 17970, 17893, 17965, 17939, 18041, 17893, 17939, 17965, 20692, - 20567, 20657, 22000, 22390, 22122, 27969, 27887, 27794, 20972, 21058, 21064, 21058, 21104, - 21088, 15953, 16074, 16117, 25629, 25535, 25476, 13382, 13541, 13476, 13077, 13150, 13263, - 14689, 14520, 14687, 14509, 14520, 14689, 16253, 16161, 16254, 16569, 16443, 16459, 16512, - 16619, 16649, 20486, 20077, 20487, 23092, 22956, 22942, 23090, 22956, 23092, 24570, 24666, - 24776, 23677, 23537, 23564, 24862, 24730, 24834, 25438, 25273, 25432, 27027, 27114, 27002, - 27202, 27114, 27166, 24098, 23971, 24060, 13181, 13382, 13164, 13772, 13658, 14053, 13164, - 13382, 13476, 18370, 18177, 18399, 18372, 18399, 18458, 18458, 18634, 18555, 18972, 19194, - 19430, 23211, 23246, 23252, 23051, 23246, 23211, 23051, 22877, 22766, 21414, 21393, 21255, - 23971, 23744, 23877, 26398, 26552, 26204, 26038, 26111, 26056, 25995, 26111, 26038, 25995, - 26038, 25970, 25995, 25970, 26022, 26022, 25970, 25848, 26022, 25848, 25756, 24862, 24834, - 24992, 25535, 25438, 25432, 13077, 13263, 13188, 15316, 15058, 15677, 15953, 16009, 16074, - 15234, 15177, 15316, 15129, 15177, 15234, 15129, 15234, 15120, 15854, 15683, 15874, 16253, - 16254, 16378, 22122, 22390, 22484, 21091, 21464, 20790, 17893, 17910, 17939, 18569, 18610, - 18228, 23710, 23537, 23677, 14115, 14838, 14117, 26398, 26204, 26175, 14520, 14448, 14552, - 14509, 14448, 14520, 16649, 16619, 17401, 16384, 16253, 16378, 19167, 18972, 19430, 25166, - 25113, 25125, 25241, 25113, 25166, 27114, 27184, 27002, 27202, 27184, 27114, 12996, 13077, - 13188, 20077, 19891, 20058, 21314, 21414, 21255, 28437, 28511, 28298, 28722, 28610, 28256, - 28437, 28298, 28413, 18555, 18634, 18744, 22956, 22769, 22557, 23293, 23092, 23163, 23058, - 23051, 22766, 24992, 24956, 25020, 27470, 27405, 26931, 27087, 27060, 26897, 27347, 27405, - 27517, 27292, 27412, 27173, 27700, 27709, 27512, 28116, 28238, 28120, 28443, 28413, 28609, - 28003, 28149, 28057, 28242, 28149, 28003, 28127, 27946, 27887, 25668, 25629, 25476, 25527, - 25409, 25438, 25721, 25764, 25668, 25838, 26356, 25969, 14883, 15104, 15198, 16384, 16378, - 16443, 22941, 22769, 22956, 27087, 26897, 27136, 25802, 26062, 26356, 23484, 23366, 23464, - 13807, 13967, 13847, 13896, 13772, 14026, 23933, 23734, 23744, 23744, 23710, 23677, 23537, - 23484, 23464, 24203, 24098, 24060, 24293, 24098, 24203, 24293, 24411, 24382, 27657, 27512, - 27543, 14853, 14883, 15315, 24453, 24411, 24570, 25764, 25629, 25668, 25131, 24992, 25113, - 27594, 27543, 27452, 13967, 13772, 13896, 27709, 27841, 27794, 18972, 18923, 18744, 18576, - 18923, 18686, 18988, 18903, 19101, 20475, 20540, 20402, 18569, 18228, 18270, 22983, 23058, - 22766, 22440, 22507, 21879, 13397, 14115, 14117, 13497, 14117, 13868, 13497, 13868, 13688, - 19891, 19751, 19849, 24776, 24453, 24570, 24248, 24468, 24585, 26267, 26022, 26192, 24902, - 24468, 24248, 24902, 24248, 24576, 28030, 28205, 28519, 16451, 16384, 16443, 16594, 16649, - 16659, 16649, 16767, 16659, 24862, 24776, 24666, 25113, 24992, 25020, 25268, 25273, 25438, - 27405, 27303, 27136, 27184, 27292, 27002, 27631, 27594, 27452, 27296, 27292, 27184, 15650, - 15854, 16161, 16451, 16443, 16512, 25409, 25268, 25438, 27033, 26918, 26843, 27264, 27087, - 27136, 14883, 14813, 14882, 14586, 14830, 14942, 23734, 23710, 23744, 18372, 18370, 18399, - 18314, 18370, 18372, 18576, 18555, 18744, 18041, 18228, 18025, 28149, 28238, 28116, 28345, - 28397, 28368, 25062, 24776, 24862, 13278, 13093, 13367, 12996, 13093, 12995, 28265, 28205, - 28244, 13142, 12987, 13395, 13034, 13206, 12933, 13226, 12933, 13206, 13174, 13150, 12983, - 12983, 13150, 13077, 14673, 14509, 14689, 14813, 14729, 14882, 17965, 18041, 18025, 17203, - 17076, 16935, 20526, 20475, 20388, 18655, 18884, 18877, 20657, 20567, 20493, 20077, 19749, - 19891, 19749, 19538, 19751, 21895, 21743, 21853, 20577, 20540, 20607, 20607, 20540, 20743, - 20743, 20495, 20972, 20972, 21160, 21058, 21058, 21160, 21104, 21104, 21160, 21205, 20402, - 20540, 20577, 20475, 20402, 20388, 22526, 22586, 22551, 22556, 22586, 22526, 23710, 23484, - 23537, 23013, 22941, 23090, 23090, 22941, 22956, 27033, 26843, 27060, 28345, 28265, 28244, - 13067, 12987, 13142, 20567, 20486, 20487, 18825, 19101, 18903, 21914, 21895, 21853, 21914, - 21853, 22049, 27292, 27380, 27412, 26961, 26922, 26818, 27405, 27347, 27303, 27303, 27278, - 27136, 27086, 27033, 27060, 27517, 27405, 27667, 27296, 27380, 27292, 26870, 26961, 26818, - 26111, 26398, 26175, 26485, 26398, 26111, 26222, 26111, 25995, 27709, 27858, 27841, 27841, - 27969, 27794, 27657, 27700, 27512, 27774, 27700, 27657, 15129, 15165, 15177, 15177, 14997, - 15316, 15045, 15165, 15129, 24453, 24382, 24411, 24293, 24382, 24098, 23933, 23744, 23971, - 23710, 23449, 23484, 24476, 24382, 24453, 27448, 27286, 27412, 28256, 28610, 28248, 28136, - 28333, 28661, 28612, 28384, 28511, 28612, 28511, 28437, 23293, 23163, 23366, 21988, 21914, - 22049, 25613, 25438, 25535, 25241, 25131, 25113, 24992, 25062, 24862, 24776, 24476, 24453, - 27086, 27060, 27087, 19751, 19553, 19430, 18314, 18372, 18555, 19538, 19553, 19751, 21627, - 21464, 21743, 21988, 22049, 22122, 23359, 23293, 23366, 23359, 23366, 23484, 13382, 13181, - 13278, 13164, 13476, 13264, 13390, 13406, 13296, 14830, 15045, 15120, 20495, 21160, 20972, - 22449, 22440, 22291, 23933, 23971, 24098, 25764, 25797, 25629, 25629, 25613, 25535, 26062, - 26172, 26356, 25969, 26072, 25932, 27929, 27969, 27841, 28610, 28566, 28248, 13296, 13699, - 13658, 21160, 21314, 21255, 16649, 16594, 16512, 16098, 15968, 16253, 18075, 18215, 18177, - 25241, 25166, 25268, 27499, 27278, 27303, 27202, 27296, 27184, 27380, 27448, 27412, 27263, - 27296, 27202, 25838, 25797, 25764, 18484, 18655, 18569, 18569, 18655, 18877, 16935, 17076, - 16839, 27969, 28035, 27887, 28422, 28205, 28265, 14115, 14586, 14922, 14830, 14972, 15045, - 22390, 22557, 22640, 21627, 21743, 21895, 27033, 27158, 26918, 27233, 27086, 27087, 12996, - 12983, 13077, 12996, 13188, 13093, 27437, 27448, 27380, 13264, 13476, 13406, 12995, 13093, - 13278, 22440, 21879, 22291, 22983, 22766, 22662, 28422, 28426, 28205, 28345, 28120, 28238, - 23051, 23058, 23246, 23165, 23058, 22983, 28566, 28586, 27676, 28790, 28612, 28437, 28609, - 28437, 28443, 18163, 18228, 18041, 18884, 18869, 18903, 28397, 28238, 28149, 18370, 18102, - 18177, 18249, 18102, 18370, 18314, 18555, 18513, 17910, 18163, 18041, 23226, 23013, 23090, - 22640, 22557, 22769, 23449, 23359, 23484, 13967, 13807, 13772, 13772, 13459, 13658, 13847, - 13967, 14434, 13847, 14434, 13721, 21997, 21895, 21914, 22640, 22769, 22755, 27594, 27774, - 27657, 27700, 27858, 27709, 27969, 28073, 28035, 27743, 27774, 27594, 27820, 27858, 27700, - 16074, 16051, 16193, 16689, 16707, 16839, 15910, 15953, 15348, 16594, 16451, 16512, 16767, - 16649, 17401, 16505, 16689, 16534, 25131, 25062, 24992, 25455, 25062, 25131, 25241, 25268, - 25403, 25732, 25613, 25629, 26870, 26818, 26552, 14583, 14509, 14673, 25403, 25268, 25409, - 24382, 23933, 24098, 23559, 23449, 23710, 25067, 24476, 24776, 27670, 27631, 27452, 27898, - 27929, 27841, 28035, 28127, 27887, 12995, 13278, 12886, 13390, 13264, 13406, 13179, 13264, - 13390, 28491, 28422, 28265, 28519, 28413, 28030, 13278, 13181, 12780, 16776, 16935, 16839, - 17939, 17910, 18041, 28072, 28073, 27969, 14729, 14615, 14673, 14747, 14615, 14729, 14747, - 14729, 14813, 14747, 14813, 14883, 16009, 16051, 16074, 25613, 25527, 25438, 18249, 18314, - 18112, 18095, 18270, 18163, 18163, 18270, 18228, 26445, 26536, 26530, 26762, 26712, 26552, - 13327, 13296, 13658, 16613, 16451, 16594, 15683, 15199, 15666, 16707, 16776, 16839, 16319, - 16534, 16381, 27278, 27264, 27136, 27086, 27158, 27033, 27409, 27264, 27278, 27409, 27278, - 27499, 13160, 13181, 13164, 15968, 16161, 16253, 16855, 16767, 17401, 16659, 16613, 16594, - 18075, 18177, 18102, 16642, 16776, 16707, 18112, 18075, 18102, 23226, 23090, 23293, 23486, - 23449, 23559, 27448, 27670, 27452, 27296, 27437, 27380, 27357, 27437, 27296, 28153, 28127, - 28035, 28570, 28519, 28422, 18739, 18869, 18884, 18739, 18884, 18655, 23013, 22769, 22941, - 13034, 12928, 13067, 13067, 12914, 12987, 13203, 13835, 13571, 12934, 12928, 13034, 13226, - 13256, 12933, 13256, 12845, 12933, 12928, 12914, 13067, 14615, 14583, 14673, 14173, 14434, - 14448, 14572, 14583, 14615, 21997, 21914, 21988, 20567, 20553, 20486, 20486, 20412, 20077, - 25527, 25403, 25409, 25241, 25455, 25131, 26829, 26712, 26790, 26961, 27102, 26922, 27233, - 27158, 27086, 27058, 27102, 26961, 28661, 28333, 28384, 28610, 28637, 28566, 28566, 28711, - 28586, 12933, 12846, 12797, 20692, 20553, 20567, 20540, 20526, 20743, 21160, 21624, 21314, - 20475, 20526, 20540, 20388, 20402, 20195, 20553, 20412, 20486, 27858, 27898, 27841, 27929, - 28072, 27969, 28073, 28153, 28035, 27774, 27820, 27700, 27849, 27820, 27774, 27743, 27594, - 27631, 28642, 28722, 28256, 27768, 27743, 27631, 28519, 28205, 28426, 28664, 28661, 28384, - 12883, 12983, 12996, 20195, 20167, 19865, 24108, 23933, 24382, 28037, 27898, 27858, 25797, - 25732, 25629, 25613, 25864, 25527, 25527, 25864, 25403, 25969, 25732, 25797, 25969, 25797, - 25838, 26712, 26870, 26552, 27545, 27670, 27448, 13052, 13560, 12447, 13603, 13497, 13688, - 23364, 23293, 23359, 27992, 28072, 27929, 18314, 18249, 18370, 18576, 18744, 18923, 20324, - 20195, 20246, 28188, 28242, 28127, 28127, 28242, 28003, 28722, 28637, 28610, 28664, 28384, - 28612, 26304, 26598, 26899, 27327, 27233, 27087, 27102, 27166, 27027, 27437, 27545, 27448, - 27226, 27166, 27102, 28422, 28519, 28426, 28368, 28265, 28345, 13296, 13179, 13390, 13264, - 13160, 13164, 13099, 13179, 13157, 18652, 18739, 18655, 18869, 18825, 18903, 28637, 28711, - 28566, 14773, 14747, 14883, 16767, 16613, 16659, 16947, 16855, 17401, 17905, 18215, 18075, - 16776, 16845, 16935, 17893, 17970, 17203, 16760, 16845, 16776, 27667, 27405, 27470, 27264, - 27327, 27087, 27667, 27470, 27766, 27585, 27545, 27437, 13347, 13497, 13603, 14761, 14830, - 14281, 17978, 17905, 18075, 17893, 17203, 17140, 18270, 18409, 18569, 28140, 28153, 28073, - 12653, 13560, 12987, 22122, 21997, 21988, 22137, 21997, 22122, 22137, 22122, 22399, 16191, - 16319, 16381, 16611, 16642, 16707, 16009, 15999, 16051, 15910, 15999, 16009, 15953, 15677, - 15348, 27043, 27058, 26961, 28790, 28664, 28612, 28661, 28664, 28784, 13099, 13160, 13264, - 22440, 22556, 22526, 22497, 22449, 22327, 22556, 22449, 22497, 16191, 16381, 16051, 18241, - 18409, 18270, 27409, 27327, 27264, 26598, 26918, 26899, 27166, 27263, 27202, 27271, 27263, - 27166, 16433, 16707, 16505, 13807, 13702, 13772, 14173, 14448, 14509, 26022, 26222, 25995, - 26712, 26829, 26870, 26870, 26932, 26961, 26445, 26222, 26281, 27743, 27849, 27774, 28037, - 28025, 27898, 27898, 27992, 27929, 28072, 28140, 28073, 27768, 27849, 27743, 27768, 27631, - 27670, 13722, 13702, 13807, 15623, 15535, 15683, 15486, 15535, 15623, 16253, 16384, 16098, - 18077, 18095, 18163, 18739, 18825, 18869, 18484, 18652, 18655, 22920, 22755, 22769, 22920, - 22769, 23013, 23364, 23359, 23449, 23486, 23364, 23449, 28397, 28345, 28238, 28153, 28188, - 28127, 28315, 28188, 28153, 28397, 28149, 28390, 28025, 27992, 27898, 21774, 21627, 21895, - 22484, 22390, 22640, 14583, 14411, 14509, 14603, 14572, 14615, 14603, 14615, 14747, 27058, - 27098, 27102, 27157, 27098, 27058, 17025, 16947, 17105, 16711, 16613, 16767, 27766, 27470, - 28220, 27499, 27303, 27347, 15045, 14972, 15165, 14761, 14972, 14830, 14997, 14981, 15022, - 25732, 25806, 25613, 26918, 27158, 26899, 17907, 17893, 17888, 17888, 17893, 17140, 17910, - 18077, 18163, 22607, 22484, 22640, 27992, 28140, 28072, 16319, 16433, 16505, 16642, 16760, - 16776, 16411, 16433, 16319, 27521, 27158, 27233, 27528, 27347, 27517, 27263, 27357, 27296, - 27545, 27768, 27670, 27487, 27357, 27263, 12995, 12883, 12996, 12886, 12883, 12995, 21986, - 21895, 21997, 26693, 26552, 26398, 23058, 23165, 23246, 22983, 22662, 22831, 27667, 27528, - 27517, 13347, 12739, 13497, 13052, 13203, 13571, 15942, 16191, 16051, 15942, 16051, 15999, - 19167, 18923, 18972, 18112, 17978, 18075, 18513, 18435, 18279, 22755, 22607, 22640, 23065, - 22920, 23013, 17907, 18077, 17910, 18363, 18484, 18409, 18711, 18739, 18652, 23364, 23226, - 23293, 23559, 23710, 23680, 25811, 25806, 25732, 25403, 25455, 25241, 23680, 23933, 23732, - 23680, 23734, 23933, 23680, 23710, 23734, 26829, 26932, 26870, 27098, 27226, 27102, 12803, - 12886, 13278, 13847, 13722, 13807, 13702, 13652, 13772, 13667, 13722, 13847, 12780, 12803, - 13278, 13179, 13099, 13264, 13157, 13179, 13296, 18711, 18825, 18739, 18484, 18569, 18409, - 22813, 22607, 22755, 22097, 21986, 22137, 22137, 21986, 21997, 22449, 22556, 22440, 21879, - 21414, 21624, 13555, 13652, 13702, 27992, 28181, 28140, 28037, 27858, 27820, 28037, 27820, - 27849, 12914, 12865, 12987, 12928, 12857, 12914, 12934, 12857, 12928, 12797, 12857, 12934, - 12797, 12934, 12933, 12933, 12845, 12846, 20553, 20552, 20412, 19749, 19751, 19891, 20692, - 20650, 20553, 20790, 20650, 20692, 28642, 28818, 28722, 28722, 28759, 28637, 28637, 28753, - 28711, 28833, 28805, 28642, 28833, 28642, 28661, 16711, 16767, 16855, 16433, 16611, 16707, - 16411, 16611, 16433, 20650, 20552, 20553, 20526, 20495, 20743, 20388, 20495, 20526, 20383, - 20495, 20388, 20383, 20388, 20195, 21179, 20790, 21464, 27483, 27233, 27327, 27542, 27499, - 27347, 27787, 27768, 27545, 28805, 28818, 28642, 13256, 12983, 12845, 12857, 12865, 12914, - 14773, 14603, 14747, 14411, 14173, 14509, 14997, 15177, 15165, 16313, 16411, 16319, 26932, - 27043, 26961, 28818, 28734, 28722, 28766, 28833, 28661, 12845, 12983, 12693, 20460, 20383, - 20324, 28734, 28759, 28722, 28711, 28778, 28586, 18576, 18513, 18555, 17105, 16947, 17401, - 19167, 19430, 19553, 18241, 18270, 18095, 22831, 22662, 22586, 28273, 28149, 28242, 28533, - 28570, 28422, 28784, 28664, 28851, 28273, 28242, 28188, 28273, 28188, 28315, 13339, 13327, - 13658, 18077, 18241, 18095, 23486, 23226, 23364, 22920, 22813, 22755, 28315, 28153, 28181, - 28759, 28754, 28637, 28784, 28766, 28661, 28802, 28609, 28519, 12853, 12983, 12883, 28491, - 28265, 28368, 16098, 16384, 16080, 15910, 15942, 15999, 18630, 18711, 18652, 20324, 20383, - 20195, 26222, 26485, 26111, 26829, 26951, 26932, 27004, 27157, 27043, 28558, 28491, 28368, - 18112, 18102, 18249, 16761, 16711, 16855, 18077, 18218, 18241, 17893, 17907, 17910, 17203, - 16935, 16884, 23933, 24108, 23732, 23486, 23559, 23226, 28754, 28753, 28637, 28790, 28437, - 28609, 14972, 14997, 15165, 16015, 16055, 15942, 14997, 14972, 14981, 15531, 15486, 15623, - 15535, 15199, 15683, 26485, 26693, 26398, 16760, 16935, 16845, 16313, 16319, 16191, 16761, - 16855, 16947, 16080, 16384, 16451, 26693, 26762, 26552, 27528, 27542, 27347, 27483, 27327, - 27409, 27650, 27542, 27528, 28753, 28778, 28711, 22399, 22122, 22484, 20844, 20773, 20790, - 15968, 15650, 16161, 16080, 16131, 16085, 27157, 27226, 27098, 27357, 27487, 27437, 27157, - 27058, 27043, 28164, 28037, 27849, 28377, 28181, 27992, 23166, 23065, 23226, 23226, 23065, - 23013, 22535, 22399, 22484, 25969, 25932, 25732, 25806, 25864, 25613, 27483, 27409, 27499, - 26762, 26790, 26712, 28558, 28533, 28491, 28273, 28390, 28149, 28315, 28390, 28273, 28778, - 28821, 28586, 27667, 27766, 27528, 22535, 22484, 22607, 18279, 18112, 18314, 28181, 28153, - 28140, 12990, 13157, 13296, 12803, 12883, 12886, 13652, 13562, 13772, 13327, 13140, 13296, - 13555, 13562, 13652, 13459, 13562, 13431, 22833, 22813, 22920, 17105, 17401, 17248, 17401, - 17905, 17685, 27035, 27213, 28493, 12816, 12853, 12883, 12816, 12883, 12803, 28821, 28771, - 28586, 25932, 25811, 25732, 14411, 14583, 14572, 21920, 21774, 21895, 22399, 22097, 22137, - 27271, 27487, 27263, 28369, 28377, 28037, 14401, 14411, 14572, 14478, 14572, 14603, 18218, - 18363, 18241, 18241, 18363, 18409, 18484, 18630, 18652, 16760, 16642, 16522, 23892, 23166, - 23226, 24382, 24476, 24108, 27226, 27271, 27166, 27568, 27271, 27226, 28493, 27213, 28586, - 28377, 27992, 28025, 12803, 12677, 12774, 16711, 16538, 16613, 16869, 16761, 16947, 16522, - 16642, 16611, 22185, 22148, 22097, 22555, 22535, 22607, 21624, 21414, 21314, 22556, 22831, - 22586, 18218, 18077, 17907, 23065, 22833, 22920, 22813, 22555, 22607, 23732, 23226, 23559, - 21850, 21624, 20974, 28867, 28790, 28609, 20324, 20246, 20347, 18460, 18630, 18484, 23094, - 22833, 23065, 22983, 23093, 23165, 23707, 24248, 23246, 22743, 22831, 22556, 13318, 13339, - 13658, 27004, 27043, 26932, 16055, 16313, 16191, 16411, 16522, 16611, 16055, 16191, 15942, - 16586, 16538, 16711, 16305, 16522, 16411, 27542, 27554, 27499, 27650, 27554, 27542, 27487, - 27585, 27437, 27683, 27585, 27487, 27683, 27487, 27271, 12931, 13160, 13099, 15486, 15199, - 15535, 15003, 15199, 15259, 17025, 16869, 16947, 16761, 16586, 16711, 16941, 17105, 17033, - 21920, 21895, 21986, 21920, 21986, 22148, 26222, 26445, 26485, 26485, 26627, 26693, 26693, - 26627, 26762, 26762, 26797, 26790, 26790, 26951, 26829, 26222, 26022, 26267, 26215, 26192, - 26145, 26445, 26512, 26485, 22717, 22555, 22813, 22148, 21986, 22097, 28491, 28533, 28422, - 28570, 28802, 28519, 28466, 28368, 28397, 28466, 28397, 28390, 28466, 28390, 28765, 14997, - 15022, 15316, 14981, 14972, 14862, 26512, 26627, 26485, 21624, 22291, 21879, 22975, 23093, - 22831, 14830, 14586, 14281, 13562, 13459, 13772, 13555, 13702, 13722, 14462, 14478, 14603, - 14411, 14113, 14173, 16098, 15983, 15968, 16080, 15983, 16098, 16941, 16869, 17025, 20790, - 20747, 20650, 20650, 20747, 20552, 19749, 20077, 19903, 20773, 20747, 20790, 28805, 28908, - 28818, 28818, 28879, 28734, 28734, 28947, 28759, 28759, 28947, 28754, 28754, 28944, 28753, - 28753, 28946, 28778, 28778, 28994, 28821, 28821, 28932, 28771, 28833, 28908, 28805, 28868, - 28908, 28833, 28868, 28833, 28766, 28868, 28766, 29038, 12857, 12683, 12865, 12865, 12653, - 12987, 13052, 12710, 13203, 12589, 12683, 12857, 12679, 12857, 12797, 12679, 12797, 12846, - 12679, 12846, 12657, 12846, 12845, 12657, 12845, 12587, 12657, 20844, 20790, 21179, 28908, - 28879, 28818, 12983, 12853, 12693, 20383, 20460, 20495, 20495, 20527, 21160, 20192, 20246, - 20195, 29038, 28766, 29037, 18442, 18460, 18484, 18038, 18218, 17907, 18442, 18484, 18363, - 19813, 20192, 20195, 28558, 28765, 28749, 12683, 12653, 12865, 19715, 20195, 19865, 26627, - 26797, 26762, 28879, 28947, 28734, 12693, 12853, 12647, 27554, 27483, 27499, 28947, 28944, - 28754, 13339, 13262, 13327, 13459, 13318, 13658, 14172, 14586, 14021, 15799, 15650, 15968, - 22291, 22327, 22449, 22311, 22327, 22291, 27521, 26899, 27158, 25932, 26072, 25811, 26797, - 26951, 26790, 27568, 27683, 27271, 27554, 27917, 27483, 27766, 27650, 27528, 27872, 27650, - 27766, 20077, 20412, 19903, 17869, 17978, 17989, 22097, 22274, 22185, 20844, 20703, 20773, - 14478, 14401, 14572, 13653, 13667, 13847, 14406, 14401, 14478, 16368, 16451, 16613, 15337, - 15531, 15306, 16368, 16613, 16538, 16313, 16305, 16411, 15897, 15942, 15910, 28944, 28946, - 28753, 29180, 28493, 28586, 13721, 14434, 13953, 13459, 13168, 13318, 13653, 13669, 13511, - 26951, 27004, 26932, 13667, 13555, 13722, 18825, 19307, 19101, 18218, 18442, 18363, 23166, - 23094, 23065, 22553, 22518, 22555, 22518, 22399, 22535, 23087, 23094, 23166, 22831, 23093, - 22983, 22743, 22556, 22719, 16703, 16586, 16761, 17105, 16941, 17025, 17685, 17905, 17978, - 13318, 13262, 13339, 13157, 12931, 13099, 13114, 13262, 13318, 13414, 13431, 13562, 17869, - 17685, 17978, 17978, 18112, 18004, 28533, 28653, 28570, 28695, 28653, 28533, 12647, 12853, - 12816, 12774, 12816, 12803, 28790, 28851, 28664, 28900, 28851, 28790, 22719, 22556, 22497, - 28466, 28558, 28368, 28811, 28558, 28749, 28994, 28932, 28821, 18279, 18314, 18513, 22518, - 22535, 22555, 21464, 21627, 21179, 28810, 28802, 28570, 26512, 26638, 26627, 26627, 26862, - 26797, 26797, 26924, 26951, 26951, 26924, 27004, 26445, 26530, 26512, 26267, 26192, 26281, - 13953, 14434, 14173, 14646, 14462, 14603, 15483, 15897, 15910, 16055, 16305, 16313, 15022, - 15058, 15316, 14955, 15058, 15022, 14955, 15022, 14981, 26530, 26638, 26512, 22901, 22813, - 22833, 28840, 28810, 28570, 28811, 28695, 28533, 14862, 14955, 14981, 26145, 26022, 25756, - 13262, 13140, 13327, 13037, 13140, 12929, 16015, 16305, 16055, 16428, 16884, 16760, 16760, - 16884, 16935, 17888, 18038, 17907, 18218, 18038, 18442, 18686, 18513, 18576, 16835, 16761, - 16869, 13037, 12990, 13296, 13667, 13501, 13555, 13555, 13414, 13562, 13273, 13168, 13459, - 13721, 13653, 13847, 14295, 14411, 14401, 23094, 22901, 22833, 15199, 14853, 15315, 15007, - 14853, 15199, 14761, 14862, 14972, 14866, 14862, 14761, 15650, 15531, 15623, 15799, 15968, - 15983, 15987, 15983, 16080, 28840, 28570, 28653, 28867, 28900, 28790, 12677, 12803, 12453, - 18166, 18004, 18112, 28867, 28609, 28802, 13356, 13414, 13555, 14462, 14406, 14478, 14195, - 14406, 14238, 16085, 15987, 16080, 15897, 16015, 15942, 15554, 16015, 15897, 14853, 14773, - 14883, 25811, 25864, 25806, 26356, 26072, 25969, 26975, 26924, 26797, 27568, 27226, 27574, - 16941, 16835, 16869, 17028, 16835, 16941, 17248, 17401, 17685, 17743, 17685, 17869, 16428, - 16760, 16522, 28020, 27872, 27766, 27650, 27748, 27554, 27117, 26923, 26899, 12780, 13181, - 13160, 12875, 12931, 13157, 22717, 22553, 22555, 22518, 22534, 22399, 17805, 17743, 17869, - 23680, 23732, 23559, 22675, 22717, 22901, 24108, 24476, 25067, 19538, 19167, 19553, 19322, - 19167, 19538, 28974, 28867, 28802, 28949, 28840, 28653, 16586, 16368, 16538, 16263, 16368, - 16332, 18279, 18166, 18112, 18004, 17989, 17978, 18179, 18166, 18279, 20747, 20703, 20552, - 20773, 20703, 20747, 20844, 20850, 20812, 29031, 28586, 28771, 28020, 27831, 27872, 12683, - 12589, 12653, 12139, 12710, 13052, 12449, 12589, 12857, 12449, 12857, 12679, 12641, 12679, - 12611, 12679, 12657, 12611, 12401, 12359, 12611, 14406, 14295, 14401, 14113, 14295, 14195, - 16131, 16080, 16451, 15987, 15799, 15983, 22743, 22975, 22831, 24902, 24680, 24468, 22894, - 22975, 22743, 28868, 28989, 28908, 29170, 29140, 28879, 29108, 28944, 28947, 29108, 29059, - 28944, 28944, 29059, 28946, 28946, 28994, 28778, 29038, 28989, 28868, 28766, 28784, 29037, - 27872, 27748, 27650, 12845, 12693, 12587, 21983, 21774, 21920, 12587, 12693, 12647, 20324, - 20347, 20460, 20460, 20527, 20495, 22391, 22497, 22327, 18976, 19307, 18825, 25898, 25864, - 25811, 29037, 28784, 29010, 17966, 17989, 18004, 18711, 18976, 18825, 22553, 22534, 22518, - 22901, 22717, 22813, 22581, 22717, 22675, 22391, 22719, 22497, 22311, 22291, 22042, 22424, - 22311, 22042, 13653, 13501, 13667, 13114, 13140, 13262, 13511, 13501, 13653, 18711, 18630, - 18315, 29140, 28947, 28879, 28932, 29031, 28771, 29010, 28784, 28851, 29010, 28851, 29147, - 28882, 28802, 28810, 16305, 16428, 16522, 15554, 16428, 16305, 28996, 28851, 28900, 16085, - 15972, 15987, 16368, 16131, 16451, 16263, 16131, 16368, 26638, 26862, 26627, 26530, 26678, - 26638, 26281, 26536, 26445, 12990, 12875, 13157, 13140, 13037, 13296, 13114, 13318, 13168, - 15003, 15007, 15199, 14853, 14738, 14773, 14773, 14646, 14603, 15199, 15486, 15259, 17743, - 17709, 17685, 17595, 17709, 17634, 13459, 13431, 13273, 15058, 15348, 15677, 14955, 14919, - 15058, 14866, 14919, 14955, 14866, 14955, 14862, 26816, 26356, 26172, 26072, 25898, 25811, - 26128, 26129, 26018, 26267, 26281, 26222, 25158, 24680, 25252, 12931, 12780, 13160, 12862, - 12780, 12931, 22311, 22391, 22327, 22424, 22391, 22311, 27872, 27831, 27748, 27748, 27958, - 27554, 27822, 27831, 28054, 12647, 12816, 12774, 12647, 12774, 12615, 12877, 12875, 12990, - 15007, 14872, 14853, 14742, 14866, 14761, 19167, 18686, 18923, 17966, 17805, 17989, 17805, - 17709, 17743, 22719, 22724, 22743, 22709, 22724, 22719, 25252, 24680, 24902, 29139, 28994, - 28946, 13356, 13431, 13414, 14872, 14738, 14853, 16486, 16368, 16586, 16131, 15972, 16085, - 16486, 16586, 16703, 29109, 28996, 28900, 13894, 13953, 14173, 14113, 14411, 14295, 14738, - 14646, 14773, 12813, 12862, 12931, 12615, 12774, 12677, 16201, 15972, 16131, 22581, 22534, - 22553, 22148, 21983, 21920, 22581, 22553, 22717, 12615, 12677, 12453, 13471, 13356, 13555, - 13669, 13653, 13721, 17369, 17248, 17685, 28994, 29031, 28932, 13953, 13669, 13721, 17248, - 17033, 17105, 12875, 12813, 12931, 13037, 12877, 12990, 12929, 12877, 13037, 12875, 12877, - 12796, 23246, 23165, 23707, 22724, 22894, 22743, 22803, 22894, 22724, 25864, 25950, 25403, - 26128, 25898, 26072, 13471, 13555, 13501, 12929, 13140, 13114, 18315, 18630, 18460, 22274, - 22097, 22399, 28840, 28882, 28810, 28867, 29022, 28900, 28949, 28882, 28840, 28949, 28653, - 28695, 19569, 19715, 19865, 23165, 23093, 23707, 27246, 27157, 27004, 27585, 27787, 27545, - 28037, 28377, 28025, 28558, 28466, 28765, 28558, 28811, 28533, 27246, 27004, 26924, 14021, - 14586, 13995, 14586, 14115, 13995, 22355, 22274, 22399, 22675, 22901, 22725, 12453, 12803, - 12780, 27831, 27822, 27748, 28020, 27766, 28220, 12447, 13560, 12653, 13203, 12718, 13347, - 22355, 22399, 22534, 20812, 20703, 20844, 12343, 12449, 12428, 12641, 12449, 12679, 12589, - 12394, 12653, 12449, 12641, 12428, 12401, 12657, 12587, 12490, 12587, 12647, 12449, 12522, - 12589, 20703, 20732, 20552, 20812, 20732, 20703, 21627, 21774, 21179, 15007, 14965, 14872, - 14872, 14757, 14738, 14738, 14700, 14646, 15259, 15486, 15531, 15972, 15799, 15987, 15733, - 15799, 15839, 16201, 16131, 16263, 19546, 19569, 19865, 21179, 21774, 21983, 26536, 26678, - 26530, 26281, 26557, 26536, 26482, 26557, 26281, 26482, 26281, 26354, 26557, 26678, 26536, - 15003, 14965, 15007, 15096, 15259, 15147, 26354, 26281, 26192, 26678, 26710, 26638, 29170, - 28879, 28908, 29059, 29139, 28946, 28994, 29093, 29031, 29170, 28908, 28989, 29250, 28989, - 29038, 29078, 29038, 29037, 29078, 29037, 29224, 13511, 13471, 13501, 13159, 13114, 13168, - 13167, 13471, 13511, 13494, 13511, 13669, 14406, 14462, 14269, 14195, 14295, 14406, 13953, - 13790, 13669, 16703, 16761, 16835, 17248, 17154, 17033, 17206, 17154, 17248, 17083, 17154, - 17024, 20347, 20349, 20460, 20246, 20349, 20347, 20309, 20349, 20246, 20309, 20246, 20192, - 20309, 20192, 20155, 14113, 13894, 14173, 17028, 16941, 17033, 26215, 26354, 26192, 26710, - 26862, 26638, 27683, 27787, 27585, 27719, 27787, 27683, 12796, 12813, 12875, 12862, 12654, - 12780, 13273, 13431, 13356, 22391, 22709, 22719, 23707, 23093, 23497, 22424, 22709, 22391, - 28390, 28904, 28765, 20155, 20192, 20044, 29140, 29108, 28947, 29224, 29037, 29010, 29147, - 28851, 28996, 17083, 17028, 17033, 21983, 22148, 22093, 22404, 22355, 22534, 25067, 24776, - 25062, 22725, 22901, 23087, 28974, 29022, 28867, 29018, 28949, 28695, 25945, 25756, 25671, - 26862, 26975, 26797, 19307, 19546, 19865, 19813, 20195, 19715, 19813, 19715, 19737, 28974, - 28802, 28990, 25252, 25672, 25158, 13217, 13273, 13356, 22148, 22185, 22093, 26356, 26128, - 26072, 25898, 25950, 25864, 26406, 26259, 26129, 25945, 26145, 25756, 12301, 12929, 13114, - 18686, 18435, 18513, 18379, 18435, 18686, 18379, 18686, 18794, 29200, 29139, 29059, 29031, - 29180, 28586, 22093, 22185, 22215, 28990, 28802, 28882, 29109, 29147, 28996, 12686, 12654, - 12862, 12686, 12862, 12813, 22495, 22424, 22042, 12649, 12796, 12877, 28811, 28885, 28695, - 29086, 28990, 28882, 28603, 28315, 28181, 12384, 12490, 12647, 12498, 12647, 12615, 13894, - 13790, 13953, 13879, 13790, 13894, 29139, 29128, 28994, 29109, 28900, 29079, 14269, 14462, - 14646, 13798, 13879, 13894, 26018, 25950, 25898, 26975, 27246, 26924, 29128, 29093, 28994, - 22107, 22093, 22215, 21007, 21026, 21179, 29079, 28900, 29022, 29086, 28882, 28949, 13576, - 13494, 13669, 13094, 13217, 13356, 17154, 17083, 17033, 16293, 16332, 16356, 17595, 17685, - 17709, 12416, 12447, 12653, 16884, 17140, 17203, 19470, 19546, 19307, 16428, 16857, 16884, - 17140, 16857, 16867, 15554, 16305, 16015, 19641, 19715, 19569, 28220, 27470, 28182, 27822, - 27958, 27748, 29079, 29022, 29152, 16486, 16332, 16368, 16703, 16835, 17028, 27568, 27719, - 27683, 28164, 27849, 27768, 13273, 13159, 13168, 13094, 13356, 13471, 17805, 17869, 17989, - 28164, 27768, 28088, 15259, 14998, 15003, 15003, 14974, 14965, 14965, 14757, 14872, 15096, - 14998, 15259, 15259, 15531, 15337, 26710, 26915, 26862, 26862, 26915, 26975, 26975, 27005, - 27246, 26678, 26622, 26710, 26557, 26622, 26678, 26482, 26622, 26557, 26418, 26622, 26482, - 26418, 26482, 26354, 26418, 26354, 26331, 12474, 12498, 12615, 14998, 14974, 15003, 15531, - 15650, 15584, 19903, 20412, 20397, 16904, 16703, 17028, 26331, 26354, 26215, 26331, 26215, - 26233, 17966, 18004, 18166, 14049, 13894, 14113, 14497, 14269, 14646, 14172, 14281, 14586, - 14742, 14823, 14919, 14230, 14281, 14172, 12649, 12686, 12813, 12453, 12474, 12615, 12649, - 12813, 12796, 12654, 12686, 12554, 14865, 14757, 14965, 15584, 15650, 15799, 26233, 26215, - 26145, 12453, 12780, 12654, 13995, 14115, 13732, 14757, 14700, 14738, 16303, 16201, 16263, - 16303, 16263, 16332, 18435, 18179, 18279, 18379, 18179, 18435, 26119, 26233, 26145, 14049, - 14113, 14195, 13576, 13384, 13494, 28904, 28390, 28315, 28749, 28885, 28811, 16857, 17140, - 16884, 19495, 19641, 19546, 14700, 14517, 14646, 25945, 26119, 26145, 12449, 12343, 12522, - 12522, 12394, 12589, 12428, 12641, 12345, 12641, 12611, 12345, 12611, 12359, 12345, 12343, - 12385, 12522, 14269, 14238, 14406, 14036, 14238, 14100, 19546, 19641, 19569, 19495, 19546, - 19470, 29152, 29022, 28974, 29152, 28974, 28990, 29250, 29170, 28989, 29140, 29204, 29108, - 29108, 29200, 29059, 29139, 29226, 29128, 29128, 29211, 29093, 29250, 29038, 29078, 29250, - 29078, 29393, 29010, 29263, 29224, 12657, 12401, 12611, 29010, 29147, 29263, 12587, 12490, - 12401, 12385, 12394, 12522, 20812, 20677, 20732, 20732, 20397, 20552, 21026, 20850, 20844, - 21026, 20844, 21179, 29170, 29204, 29140, 12401, 12490, 12441, 12394, 12344, 12653, 12710, - 12694, 13203, 12564, 12694, 12505, 23892, 23226, 23732, 22581, 22573, 22534, 22355, 22404, - 22274, 28948, 28885, 28749, 22840, 22975, 22894, 26029, 25945, 25907, 25672, 25945, 25671, - 28020, 28054, 27831, 28220, 28054, 28020, 12344, 12416, 12653, 12631, 12674, 12694, 15733, - 15584, 15799, 20155, 20254, 20309, 20309, 20254, 20349, 20349, 20527, 20460, 20091, 20254, - 20155, 20044, 20192, 19931, 21148, 21357, 21310, 22107, 21983, 22093, 25950, 25455, 25403, - 26128, 26018, 25898, 26128, 26406, 26129, 13217, 13159, 13273, 13094, 13159, 13217, 13094, - 13471, 13167, 17595, 17369, 17685, 17083, 16904, 17028, 17805, 17634, 17709, 17844, 17634, - 17805, 19931, 20192, 19813, 18315, 18460, 18442, 24108, 23892, 23732, 24071, 23892, 24108, - 13732, 14115, 13570, 14001, 14230, 14172, 15839, 15799, 15972, 16293, 16303, 16332, 16332, - 16486, 16356, 29274, 29200, 29108, 29263, 29147, 29295, 18819, 18686, 19167, 18179, 17966, - 18166, 27574, 27226, 27157, 28088, 27768, 27787, 27574, 27157, 27246, 12441, 12490, 12384, - 29266, 29147, 29109, 25945, 25672, 25907, 27986, 27958, 27822, 12384, 12647, 12498, 19931, - 19813, 19879, 29200, 29226, 29139, 29093, 29232, 29031, 29176, 28220, 28182, 12554, 12617, - 12654, 12273, 12384, 12498, 12649, 12877, 12929, 22573, 22404, 22534, 28981, 29018, 28695, - 29086, 29152, 28990, 29233, 29266, 29109, 12686, 12649, 12349, 22709, 22803, 22724, 22664, - 22803, 22709, 22495, 22709, 22424, 23497, 23093, 22975, 28885, 28981, 28695, 28765, 28948, - 28749, 28980, 28948, 28765, 19737, 19715, 19641, 29226, 29211, 29128, 15839, 15972, 15778, - 28750, 28182, 28493, 28054, 27986, 27822, 28369, 28164, 28311, 28377, 28603, 28181, 15096, - 15095, 14998, 14998, 14887, 14974, 14974, 14865, 14965, 14757, 14592, 14700, 14700, 14592, - 14517, 15147, 15095, 15096, 15147, 15259, 15185, 15259, 15337, 15185, 14887, 14865, 14974, - 14036, 14195, 14238, 14919, 14823, 15058, 14742, 14919, 14866, 14742, 14761, 14193, 15185, - 15337, 15306, 17531, 17369, 17595, 17531, 17595, 17634, 14036, 14049, 14195, 13167, 13511, - 13384, 14497, 14646, 14517, 17024, 16904, 17083, 12245, 12384, 12273, 14193, 14761, 14281, - 15306, 15531, 15584, 22215, 22185, 22274, 26808, 26915, 26710, 26808, 26710, 26622, 26808, - 26622, 26863, 26327, 26418, 26331, 26327, 26331, 26233, 26327, 26233, 26181, 12524, 12554, - 12686, 12617, 12453, 12654, 22634, 22495, 22042, 29018, 29086, 28949, 29062, 28981, 28885, - 15274, 15306, 15351, 14823, 15348, 15058, 16867, 17005, 17140, 17521, 18038, 17888, 26181, - 26233, 26119, 26915, 27005, 26975, 12694, 12674, 13203, 12694, 12710, 12451, 14001, 14172, - 14021, 15490, 15391, 15584, 15778, 15972, 16201, 16082, 16201, 16303, 22803, 22840, 22894, - 22664, 22840, 22803, 28111, 27986, 28054, 26816, 26172, 26899, 29211, 29232, 29093, 29233, - 29109, 29079, 29233, 29079, 29181, 14506, 14592, 14757, 26091, 26181, 26119, 19749, 19322, - 19538, 19257, 19322, 19749, 20892, 20850, 21026, 22404, 22215, 22274, 28682, 28603, 28377, - 28948, 29062, 28885, 19521, 19737, 19641, 19470, 19641, 19495, 29181, 29079, 29152, 14592, - 14497, 14517, 15348, 15483, 15910, 27917, 27554, 27958, 26018, 26043, 25950, 26029, 26091, - 25945, 25945, 26091, 26119, 22675, 22573, 22581, 22404, 22270, 22215, 22725, 22573, 22675, - 22495, 22652, 22709, 22634, 22652, 22495, 29232, 29180, 29031, 29202, 29086, 29018, 29144, - 29018, 28981, 17139, 17024, 17154, 16356, 16486, 16703, 25907, 25672, 25888, 17984, 17966, - 18179, 17369, 17206, 17248, 17844, 17966, 17984, 13511, 13494, 13384, 13159, 12896, 13114, - 12524, 12617, 12554, 17622, 17531, 17634, 29186, 29181, 29152, 12428, 12240, 12343, 12343, - 12240, 12385, 12385, 12282, 12394, 12394, 12252, 12344, 12344, 12312, 12416, 12416, 12022, - 12447, 12231, 12240, 12428, 12231, 12428, 12345, 12231, 12345, 12292, 12345, 12359, 12292, - 12359, 12330, 12292, 12240, 12282, 12385, 16356, 16703, 16273, 20850, 20677, 20812, 20892, - 20677, 20850, 20892, 21026, 21007, 12359, 12401, 12330, 12330, 12401, 12156, 12282, 12252, - 12394, 12451, 12710, 12419, 13851, 14021, 13995, 14049, 13798, 13894, 14100, 14238, 14269, - 13980, 14001, 14021, 14671, 14765, 14742, 12718, 13203, 12674, 21007, 21032, 20942, 24175, - 24287, 23707, 22652, 22664, 22709, 22634, 22664, 22652, 26002, 25907, 25888, 12276, 12401, - 12441, 12252, 12312, 12344, 12524, 12453, 12617, 12245, 12276, 12441, 12524, 12686, 12352, - 12312, 12319, 12416, 20254, 20276, 20349, 20091, 20276, 20254, 20091, 20155, 20044, 20091, - 20044, 20030, 21007, 21148, 21032, 27986, 28069, 27958, 28111, 28069, 27986, 29204, 29274, - 29108, 29200, 29328, 29226, 29226, 29316, 29211, 29211, 29282, 29232, 29232, 29409, 29180, - 29354, 29274, 29204, 29368, 29204, 29170, 29433, 29170, 29250, 29323, 29078, 29224, 29323, - 29224, 29263, 29323, 29263, 29295, 29147, 29313, 29295, 15028, 14887, 15095, 15095, 14887, - 14998, 14865, 14715, 14757, 14427, 14376, 14497, 15028, 15095, 15147, 15028, 15147, 15185, - 15028, 15185, 15274, 15721, 15733, 15839, 15274, 15185, 15306, 26923, 26816, 26899, 29285, - 28750, 28493, 27978, 27958, 28069, 29274, 29328, 29200, 29147, 29266, 29313, 12445, 12718, - 12674, 14887, 14715, 14865, 14264, 14100, 14269, 14823, 14795, 15348, 15348, 15004, 15483, - 14742, 14765, 14823, 14193, 14281, 14230, 27521, 27233, 27483, 28982, 28904, 28315, 14103, - 14193, 14230, 15778, 15721, 15839, 15351, 15306, 15434, 20030, 20044, 19931, 17966, 17844, - 17805, 17984, 18179, 18094, 12419, 12710, 12263, 12564, 12631, 12694, 12410, 12631, 12564, - 23087, 22901, 23094, 22573, 22620, 22404, 22215, 22270, 22107, 28980, 29062, 28948, 29086, - 29186, 29152, 12245, 12441, 12384, 13669, 13790, 13576, 13576, 13790, 13879, 13397, 14117, - 13497, 14001, 14103, 14230, 15434, 15306, 15584, 16136, 16356, 16273, 16293, 16082, 16303, - 17388, 17206, 17369, 16136, 16275, 16356, 17388, 17369, 17531, 19438, 19470, 19336, 19737, - 19879, 19813, 29407, 29186, 29086, 29313, 29266, 29233, 29328, 29316, 29226, 29313, 29233, - 29507, 17498, 17388, 17531, 12273, 12498, 12474, 14265, 14269, 14497, 13608, 13576, 13879, - 14671, 14783, 14765, 14056, 14103, 14001, 15310, 15434, 15391, 28131, 28009, 28076, 27656, - 27574, 27246, 13094, 12982, 13159, 12896, 12982, 13094, 13798, 14049, 14036, 17844, 17622, - 17634, 11906, 12273, 11537, 20397, 20412, 20552, 19521, 19879, 19737, 29316, 29282, 29211, - 29180, 29285, 28493, 29303, 29233, 29181, 12391, 12524, 12352, 11983, 12185, 11906, 14506, - 14497, 14592, 29062, 29144, 28981, 13732, 13851, 13995, 13980, 14056, 14001, 14671, 14742, - 14193, 14376, 14265, 14497, 26129, 26043, 26018, 26102, 26043, 26129, 25907, 26002, 26029, - 26029, 26135, 26091, 26091, 26387, 26181, 26181, 26650, 26327, 26863, 26622, 26418, 26915, - 27235, 27005, 27005, 27235, 27246, 25888, 25672, 25252, 12829, 12896, 13094, 13384, 13251, - 13167, 13153, 13251, 13097, 17287, 17139, 17206, 17206, 17139, 17154, 17104, 17139, 17181, - 28164, 28369, 28037, 29265, 28980, 28904, 28088, 27787, 28009, 12451, 12505, 12694, 12445, - 12563, 12718, 12410, 12505, 12332, 22665, 22620, 22573, 22665, 22573, 22725, 22042, 22291, - 21624, 22664, 22634, 22840, 12789, 13397, 13497, 13632, 13980, 13851, 12739, 13347, 12718, - 13963, 13798, 14036, 14265, 14264, 14269, 14887, 14958, 14715, 14715, 14506, 14757, 14376, - 14427, 14265, 14112, 14028, 14264, 15028, 14958, 14887, 15274, 14958, 15028, 15228, 14958, - 15274, 15228, 15274, 15351, 16356, 16275, 16293, 15347, 15351, 15434, 16273, 16904, 16868, - 18094, 18179, 18379, 17844, 17831, 17622, 17287, 17206, 17388, 17831, 17984, 17881, 26863, - 26418, 26650, 27978, 27917, 27958, 28111, 28054, 28220, 28904, 28980, 28765, 29062, 29199, - 29144, 28982, 28315, 28603, 12263, 12710, 12139, 14671, 14408, 14581, 13851, 13980, 14021, - 13899, 13980, 13591, 22431, 22270, 22404, 14765, 14783, 14823, 14193, 14103, 14135, 14135, - 14103, 14056, 15347, 15228, 15351, 15347, 15434, 15310, 26923, 27165, 26816, 26406, 26128, - 26356, 27340, 27117, 26899, 28082, 28310, 28193, 28009, 27787, 27719, 29186, 29303, 29181, - 29388, 29303, 29186, 29202, 29018, 29144, 12231, 12189, 12240, 12240, 12189, 12282, 12282, - 12167, 12252, 12252, 12182, 12312, 12312, 12137, 12319, 12319, 12022, 12416, 12292, 12189, - 12231, 11971, 12189, 12292, 12156, 12292, 12330, 12156, 12401, 12276, 12156, 12276, 12081, - 12189, 12167, 12282, 13899, 14135, 14056, 22767, 22665, 22725, 22498, 22431, 22404, 27917, - 27521, 27483, 29393, 29433, 29250, 29274, 29486, 29328, 29328, 29416, 29316, 29316, 29499, - 29282, 29393, 29078, 29323, 29393, 29323, 29443, 29323, 29295, 29443, 20677, 20529, 20732, - 20653, 20529, 20677, 20856, 20677, 20892, 20856, 20892, 21007, 20276, 20527, 20349, 20191, - 20527, 20276, 20191, 20276, 20091, 29433, 29368, 29170, 12167, 12182, 12252, 20529, 20397, - 20732, 20942, 20856, 21007, 14347, 14188, 14260, 15644, 15733, 15721, 29199, 29202, 29144, - 29368, 29354, 29204, 12185, 12276, 12245, 12185, 12245, 12273, 12182, 12137, 12312, 13963, - 14036, 14100, 13097, 13251, 13384, 13963, 14100, 14006, 16275, 16082, 16293, 16136, 16082, - 16275, 26043, 25455, 25950, 23892, 23087, 23166, 29443, 29295, 29523, 24018, 23087, 23892, - 27917, 28172, 27521, 28111, 27978, 28069, 28076, 27719, 27568, 27739, 27568, 27574, 14506, - 14427, 14497, 20030, 20191, 20091, 20030, 19931, 19954, 26406, 26356, 26816, 26043, 26244, - 25455, 17139, 17104, 17024, 17498, 17531, 17622, 17984, 17831, 17844, 18094, 18379, 18456, - 16082, 15778, 16201, 29486, 29416, 29328, 29282, 29409, 29232, 29523, 29295, 29635, 28088, - 28311, 28164, 28369, 28682, 28377, 28431, 28311, 28088, 22498, 22404, 22620, 22882, 22767, - 22725, 22270, 22238, 22107, 22498, 22620, 22698, 19470, 19438, 19641, 19336, 19470, 19307, - 21850, 22042, 21624, 26259, 26102, 26129, 26002, 26135, 26029, 25888, 26135, 26002, 19954, - 19931, 19879, 25455, 25067, 25062, 24902, 24999, 25252, 24576, 24999, 24902, 24287, 24248, - 23707, 12310, 12474, 12453, 12982, 12896, 13159, 12986, 13094, 13167, 13153, 13167, 13251, - 19830, 19954, 19879, 13097, 13040, 13002, 14006, 14100, 14264, 13980, 13899, 14056, 14651, - 14783, 14671, 13632, 13851, 13732, 18038, 18315, 18442, 18015, 18315, 18038, 17521, 17888, - 17140, 19438, 19521, 19641, 18976, 19336, 19307, 13397, 13570, 14115, 12524, 12391, 12453, - 12352, 12686, 12349, 22698, 22620, 22665, 22380, 22238, 22270, 29370, 29199, 29062, 29407, - 29388, 29186, 29303, 29388, 29233, 29265, 29062, 28980, 22767, 22698, 22665, 23087, 22882, - 22725, 22980, 22882, 23087, 27219, 27235, 26915, 26979, 26863, 26650, 14651, 14795, 14783, - 14783, 14795, 14823, 14651, 14671, 14581, 15766, 15644, 15721, 15766, 15721, 15778, 26135, - 26387, 26091, 25976, 25888, 25987, 12419, 12229, 12451, 12445, 12674, 12631, 12139, 13052, - 12447, 13608, 13879, 13798, 13664, 13608, 13798, 29499, 29409, 29282, 15347, 15235, 15228, - 15228, 14768, 14958, 14331, 14347, 14260, 14506, 14347, 14427, 15310, 15235, 15347, 26259, - 26355, 26102, 26102, 26252, 26043, 26621, 26406, 26816, 27219, 26915, 26808, 12349, 12649, - 12328, 12047, 12276, 12185, 12445, 12631, 12410, 13397, 13311, 13570, 17831, 17498, 17622, - 24673, 24071, 24108, 28756, 28682, 28369, 12410, 12564, 12505, 14028, 14006, 14264, 13689, - 13664, 13798, 14331, 14265, 14427, 15391, 15434, 15584, 15925, 15766, 15778, 15925, 15778, - 16082, 16703, 16904, 16273, 14506, 14188, 14347, 15584, 15733, 15490, 12263, 12229, 12419, - 12197, 12229, 12263, 22380, 22270, 22431, 22380, 22431, 22417, 29409, 29392, 29180, 12739, - 12809, 13497, 15490, 15733, 15644, 28682, 28837, 28603, 12026, 12276, 12047, 12268, 12349, - 12328, 12332, 12505, 12149, 22922, 22698, 22767, 22922, 22767, 22882, 29407, 29086, 29202, - 20529, 20551, 20397, 20397, 20184, 19903, 18819, 19167, 19322, 20856, 20653, 20677, 20942, - 20653, 20856, 27978, 28091, 27917, 27504, 27340, 26899, 28111, 28082, 27978, 28091, 28082, - 28193, 29433, 29469, 29368, 29368, 29547, 29354, 29354, 29486, 29274, 29416, 29540, 29316, - 29409, 29550, 29392, 29621, 29469, 29433, 29621, 29433, 29393, 29474, 29393, 29443, 20653, - 20551, 20529, 27656, 27739, 27574, 28009, 28131, 28088, 28311, 28431, 28369, 29469, 29503, - 29368, 12182, 12058, 12137, 12067, 12139, 12447, 12167, 12058, 12182, 11938, 12058, 12167, - 11971, 12167, 12189, 11971, 12292, 12156, 20551, 20456, 20397, 22417, 22431, 22498, 21007, - 21179, 21148, 29503, 29547, 29368, 18819, 18934, 18857, 17246, 17344, 17320, 15455, 15490, - 15644, 21357, 21148, 21179, 13153, 12986, 13167, 12268, 12352, 12349, 13056, 13097, 13002, - 17498, 17287, 17388, 17181, 17287, 17196, 22292, 22107, 22238, 29523, 29474, 29443, 12097, - 12319, 12137, 12332, 12423, 12410, 13043, 13201, 13397, 13914, 14048, 13899, 19468, 19521, - 19438, 19468, 19438, 19336, 29550, 29405, 29392, 29392, 29405, 29180, 28082, 28111, 28310, - 12563, 12739, 12718, 12809, 12789, 13497, 12723, 12739, 12605, 12739, 12563, 12623, 12026, - 12081, 12276, 12453, 12391, 12310, 12058, 12097, 12137, 29597, 29486, 29354, 13201, 13311, - 13397, 12310, 12391, 12233, 13608, 13545, 13576, 13813, 13798, 13963, 16904, 17024, 16868, - 15766, 15657, 15644, 20030, 20123, 20191, 20191, 20123, 20527, 20974, 21624, 21160, 19954, - 20123, 20030, 19830, 20123, 19954, 29486, 29458, 29416, 29635, 29295, 29614, 12233, 12391, - 12352, 16023, 15925, 16082, 18628, 18976, 18711, 12139, 12158, 12263, 11972, 12158, 12139, - 14795, 15009, 15348, 16867, 16857, 16742, 14671, 14193, 14408, 14193, 14135, 14048, 19270, - 19468, 19336, 19521, 19830, 19879, 11983, 12047, 12185, 29458, 29540, 29416, 12689, 12789, - 12809, 14048, 14135, 13899, 14637, 15009, 14795, 12097, 12022, 12319, 27583, 27656, 27246, - 26979, 27219, 26808, 26979, 26808, 26863, 29540, 29499, 29316, 14006, 13813, 13963, 14112, - 14264, 14265, 13632, 13732, 13489, 27583, 27246, 27235, 28076, 28009, 27719, 29453, 29407, - 29202, 29388, 29507, 29233, 29545, 29407, 29453, 12013, 12026, 12047, 12268, 12233, 12352, - 12649, 12929, 12328, 12739, 12723, 12809, 12519, 12563, 12445, 16136, 16023, 16082, 15925, - 15657, 15766, 15898, 16023, 15984, 13664, 13545, 13608, 13481, 13545, 13664, 28082, 28091, - 27978, 26385, 26355, 26458, 28115, 28091, 28193, 28076, 27568, 27739, 28979, 28982, 28837, - 13097, 12986, 13153, 13056, 12986, 13097, 17287, 17181, 17139, 17196, 17287, 17498, 14347, - 14331, 14427, 14768, 14715, 14958, 15171, 15228, 15235, 15171, 15235, 15310, 15171, 15310, - 15183, 26406, 26355, 26259, 25189, 24955, 25067, 26621, 26816, 27165, 26164, 26387, 26135, - 26164, 26135, 25888, 27504, 26899, 27521, 12022, 12103, 12447, 23497, 22975, 22840, 25976, - 26164, 25888, 23497, 22840, 22634, 12423, 12519, 12445, 12423, 12445, 12410, 18819, 19322, - 18934, 17344, 17196, 17498, 24071, 24018, 23892, 24673, 24046, 24071, 24018, 24046, 24190, - 25888, 25252, 25987, 27833, 27504, 27521, 29479, 29507, 29388, 12519, 12623, 12563, 28837, - 28982, 28603, 28979, 28837, 28682, 12203, 12451, 12229, 12197, 12263, 12055, 23340, 22980, - 23087, 22417, 22292, 22380, 29231, 29265, 28904, 13489, 13732, 13570, 12055, 12263, 12158, - 22380, 22292, 22238, 22417, 22498, 22698, 12103, 12067, 12447, 14028, 13813, 14006, 13689, - 13813, 13824, 29569, 29550, 29409, 29405, 29285, 29180, 14331, 14112, 14265, 12723, 12689, - 12809, 12789, 13043, 13397, 13280, 13570, 13311, 13280, 13489, 13570, 12605, 12689, 12723, - 12328, 12929, 12301, 12013, 12047, 11983, 12149, 12505, 12451, 18819, 18794, 18686, 18857, - 18794, 18819, 26650, 26418, 26327, 28076, 27739, 28004, 26650, 26181, 26387, 29545, 29479, - 29388, 29545, 29388, 29407, 14651, 14637, 14795, 14458, 14637, 14651, 14458, 14651, 14581, - 14408, 14193, 13921, 12986, 12829, 13094, 13097, 13384, 13040, 13481, 13576, 13545, 24287, - 24576, 24248, 11783, 11971, 12156, 12058, 11926, 12097, 12097, 11986, 12022, 12022, 11995, - 12103, 12103, 11995, 12067, 11922, 12156, 12081, 11922, 12081, 12026, 11922, 12026, 12013, - 11971, 11938, 12167, 29469, 29566, 29503, 29503, 29664, 29547, 29547, 29597, 29354, 29486, - 29623, 29458, 29458, 29623, 29540, 29540, 29623, 29499, 29499, 29569, 29409, 29725, 29566, - 29469, 29621, 29393, 29474, 29621, 29474, 29577, 29474, 29601, 29577, 12197, 12203, 12229, - 12014, 12203, 12197, 16868, 17024, 17104, 17146, 17196, 17142, 26540, 26650, 26387, 26159, - 25976, 26217, 20456, 20384, 20397, 20551, 20408, 20456, 20653, 20408, 20551, 20497, 20408, - 20653, 20951, 20653, 20942, 20951, 20942, 21032, 29474, 29523, 29601, 26336, 26387, 26164, - 12454, 12519, 12347, 12454, 12623, 12519, 12454, 12605, 12623, 12623, 12605, 12739, 13849, - 13914, 13899, 13096, 13311, 13201, 16023, 15898, 15925, 15183, 15310, 15391, 16072, 16023, - 16136, 20408, 20384, 20456, 28091, 28115, 27917, 29230, 28182, 28750, 29664, 29597, 29547, - 29601, 29523, 29635, 12652, 12829, 12986, 15183, 15391, 15363, 14331, 14260, 14112, 12273, - 11906, 12185, 11898, 11926, 12058, 20384, 20184, 20397, 21145, 21148, 21310, 29295, 29313, - 29614, 12474, 11537, 12273, 12301, 13114, 12896, 13591, 13980, 13632, 15815, 15657, 15925, - 12310, 12233, 12161, 11926, 11986, 12097, 11924, 12055, 12158, 15363, 15391, 15490, 22801, - 22417, 22698, 21164, 21145, 21310, 29597, 29623, 29486, 12689, 12659, 12789, 12643, 12659, - 12689, 24046, 24018, 24071, 22980, 22922, 22882, 24955, 24108, 25067, 29584, 29559, 29405, - 29584, 29405, 29550, 29614, 29313, 29507, 29453, 29202, 29538, 12161, 12233, 12268, 29614, - 29507, 29571, 13489, 13591, 13632, 13630, 13591, 13528, 23752, 23497, 23648, 24287, 24410, - 24576, 29294, 29126, 28750, 15455, 15363, 15490, 26355, 26385, 26102, 26621, 26355, 26406, - 26923, 27117, 27165, 13011, 13481, 13664, 13689, 13798, 13813, 17116, 17104, 17181, 15898, - 15815, 15925, 28115, 28156, 27917, 28310, 28111, 28674, 29571, 29507, 29479, 13921, 14193, - 14048, 13630, 13849, 13899, 13056, 12900, 12986, 13040, 13384, 13576, 12651, 13043, 12789, - 15554, 15897, 15483, 19244, 19270, 19109, 15397, 15483, 15367, 17196, 17146, 17181, 17498, - 17831, 17881, 22843, 22922, 22980, 13027, 13096, 13201, 15396, 15644, 15657, 15396, 15455, - 15644, 15367, 15483, 15004, 26385, 26252, 26102, 25976, 26210, 26164, 26159, 26210, 25976, - 28410, 28431, 28088, 28410, 28088, 28131, 17142, 17246, 17031, 28830, 28756, 28369, 29496, - 29370, 29265, 13118, 13280, 13311, 11782, 11995, 12022, 29849, 29569, 29499, 11972, 12139, - 12067, 12203, 12149, 12451, 12482, 12689, 12605, 16273, 16072, 16136, 15984, 16072, 15880, - 19468, 19376, 19521, 18976, 19270, 19336, 18628, 18711, 18315, 28204, 28076, 28004, 27583, - 27235, 27219, 29538, 29202, 29199, 29820, 29571, 29811, 29370, 29062, 29265, 12829, 12740, - 12896, 12602, 12740, 12829, 12659, 12707, 12789, 12643, 12707, 12659, 12519, 12423, 12283, - 17264, 17521, 17140, 26166, 26159, 26217, 13824, 13813, 14028, 14041, 14028, 14112, 15984, - 15815, 15898, 12225, 12423, 12332, 12028, 12161, 12268, 12109, 12161, 12028, 12093, 12149, - 12203, 14906, 14768, 15228, 14906, 15228, 15171, 15012, 15171, 15183, 15224, 15183, 15363, - 18934, 19322, 19123, 18794, 18456, 18379, 29661, 29571, 29820, 12082, 12225, 12332, 29426, - 29285, 29405, 29426, 29405, 29559, 29089, 28979, 28682, 13969, 14048, 13914, 15004, 15348, - 15009, 27165, 27117, 27340, 26385, 26299, 26252, 13863, 13969, 13914, 13863, 13914, 13849, - 13630, 13899, 13591, 15397, 15554, 15483, 15501, 15554, 15397, 13002, 12900, 13056, 12848, - 12900, 13002, 13040, 13576, 13481, 17146, 17116, 17181, 17142, 17116, 17146, 17142, 17196, - 17344, 17005, 17054, 17140, 16928, 17054, 17005, 13002, 13040, 12848, 13043, 13027, 13201, - 13096, 13118, 13311, 13663, 13630, 13528, 12899, 13027, 13043, 13591, 13313, 13528, 17116, - 16868, 17104, 16742, 16857, 16676, 18857, 18772, 18794, 18799, 18772, 18857, 28076, 28169, - 28131, 28204, 28169, 28076, 17054, 17264, 17140, 24175, 24410, 24287, 25987, 25252, 25514, - 12871, 13118, 13096, 20974, 21160, 20527, 22042, 22072, 22634, 20664, 20527, 20123, 29705, - 29584, 29550, 14188, 14506, 14715, 15455, 15224, 15363, 15396, 15224, 15455, 22417, 22368, - 22292, 22427, 22368, 22417, 11971, 11833, 11938, 11938, 11874, 12058, 11926, 11825, 11986, - 11986, 11825, 12022, 11722, 11833, 11971, 11722, 11971, 11783, 11904, 11922, 12013, 11904, - 12013, 11766, 11833, 11873, 11938, 12225, 12283, 12423, 12082, 12283, 12225, 12454, 12482, - 12605, 12824, 12899, 13043, 12347, 12482, 12454, 14373, 14581, 14408, 13747, 13863, 13849, - 29566, 29664, 29503, 29597, 29723, 29623, 29623, 29665, 29499, 29569, 29705, 29550, 29735, - 29725, 29469, 29735, 29469, 29621, 29735, 29621, 29692, 29621, 29577, 29692, 29577, 29601, - 29692, 29601, 29832, 29692, 17521, 17546, 18038, 17264, 17404, 17521, 29601, 29635, 29657, - 11873, 11874, 11938, 29773, 29664, 29566, 21018, 20951, 21032, 20352, 20261, 20384, 20384, - 20261, 20184, 21018, 21032, 21148, 29664, 29723, 29597, 29657, 29635, 29798, 11806, 11972, - 12067, 12014, 12093, 12203, 12149, 12114, 12332, 11900, 11972, 11806, 11874, 11898, 12058, - 15004, 15009, 14844, 20184, 19945, 19903, 20352, 20384, 20408, 21145, 21018, 21148, 26252, - 26244, 26043, 26458, 26299, 26385, 26166, 26336, 26210, 26210, 26336, 26164, 27138, 27318, - 26979, 27318, 27583, 27219, 26166, 26210, 26159, 27852, 27583, 27919, 11766, 12013, 11983, - 12482, 12643, 12689, 16072, 15984, 16023, 15572, 15396, 15657, 15880, 16072, 16273, 17378, - 17546, 17521, 20261, 20189, 20184, 22922, 22801, 22698, 22843, 22801, 22922, 29231, 28904, - 28982, 29661, 29614, 29571, 12014, 12197, 12055, 21983, 21357, 21179, 22540, 22427, 22417, - 11898, 11825, 11926, 13630, 13747, 13849, 14373, 14408, 14311, 13711, 13747, 13663, 29723, - 29665, 29623, 29823, 29657, 29798, 29479, 29811, 29571, 28193, 28194, 28115, 26454, 26619, - 26561, 28674, 28111, 28220, 11972, 11924, 12158, 11900, 11924, 11972, 14260, 14041, 14112, - 12848, 13040, 12664, 15572, 15657, 15667, 21850, 22038, 22042, 24936, 24999, 24576, 29584, - 29562, 29559, 29666, 29562, 29584, 17776, 18015, 18038, 28979, 29231, 28982, 13027, 12871, - 13096, 13663, 13747, 13630, 12651, 12789, 12707, 16867, 16928, 17005, 17054, 17184, 17264, - 17378, 17521, 17404, 17580, 17678, 17546, 16909, 16928, 16867, 17116, 16961, 16868, 16868, - 16565, 16273, 17881, 17984, 18094, 16676, 16083, 16592, 16676, 16857, 16428, 17546, 17776, - 18038, 17678, 17776, 17546, 24825, 24936, 24576, 11608, 12474, 12310, 12466, 12651, 12707, - 14373, 14458, 14581, 14048, 13969, 13921, 15419, 15501, 15397, 15292, 15397, 15367, 18015, - 18628, 18315, 19257, 19749, 19903, 18772, 18456, 18794, 19270, 19376, 19468, 19244, 19376, - 19270, 22038, 22072, 22042, 22801, 22540, 22417, 22986, 22843, 22980, 29518, 29426, 29671, - 29285, 29294, 28750, 28674, 28261, 28310, 28261, 28194, 28193, 28169, 28348, 28131, 29119, - 29089, 28756, 28756, 29089, 28682, 28979, 29089, 29231, 27970, 27739, 27656, 13711, 13969, - 13863, 15012, 14906, 15171, 14768, 14188, 14715, 14260, 14080, 14041, 15012, 15183, 15124, - 12740, 12602, 12896, 12652, 12602, 12829, 12652, 12986, 12900, 15124, 15183, 15224, 14707, - 15009, 14637, 29479, 29545, 29811, 19346, 19257, 19903, 19109, 19270, 18976, 29436, 29294, - 29285, 12327, 12347, 12519, 12482, 12443, 12643, 12643, 12443, 12707, 12363, 12347, 12327, - 15069, 15124, 15224, 15667, 15657, 15815, 14104, 14188, 14768, 15069, 15224, 15396, 12161, - 12109, 12310, 12028, 12268, 12328, 12093, 12114, 12149, 11843, 12114, 11714, 29370, 29538, - 29199, 29496, 29538, 29370, 18799, 18456, 18772, 18799, 18857, 18934, 29771, 29705, 29569, - 29518, 29436, 29426, 17776, 17839, 18015, 18015, 17979, 18628, 17580, 17546, 17378, 23497, - 23932, 23707, 24558, 24825, 24576, 24030, 23932, 24024, 14041, 13824, 14028, 14188, 14080, - 14260, 15004, 15192, 15367, 26621, 26458, 26355, 26299, 26314, 26252, 27165, 27954, 27601, - 26276, 26430, 26336, 26336, 26430, 26387, 26276, 26336, 26166, 28194, 28156, 28115, 28310, - 28261, 28193, 29230, 28750, 29126, 28204, 28348, 28169, 28425, 28348, 28204, 12899, 12871, - 13027, 12651, 12824, 13043, 12781, 12824, 12568, 16928, 16996, 17054, 16742, 16909, 16867, - 16875, 16909, 16735, 24558, 24576, 24410, 24936, 25064, 24999, 13747, 13711, 13863, 13489, - 13313, 13591, 15682, 15667, 15815, 15069, 15012, 15124, 15880, 15815, 15984, 12762, 12652, - 12900, 13011, 13664, 13689, 24825, 25064, 24936, 15192, 15292, 15367, 15475, 16428, 15554, - 18833, 18799, 18934, 26458, 26314, 26299, 26217, 26276, 26166, 24018, 23340, 23087, 23725, - 23340, 24018, 23932, 24175, 23707, 12347, 12363, 12482, 12411, 12363, 12287, 18260, 17881, - 18094, 18260, 18094, 18456, 17774, 17839, 17776, 17774, 17776, 17678, 29366, 29230, 29126, - 29426, 29436, 29285, 29294, 29366, 29126, 29426, 29559, 29671, 11642, 12014, 12055, 12327, - 12519, 12043, 11900, 12055, 11924, 19257, 19123, 19322, 19070, 19123, 19257, 18628, 19109, - 18976, 19227, 19109, 19224, 28314, 28156, 28194, 11873, 11768, 11874, 11613, 11758, 11898, - 11898, 11758, 11825, 11825, 11713, 12022, 11833, 11768, 11873, 11722, 11768, 11833, 12156, - 11803, 11783, 12156, 11922, 11803, 21119, 20497, 20951, 20951, 20497, 20653, 20261, 20352, - 20189, 19166, 19070, 19257, 21145, 20951, 21018, 29664, 29901, 29723, 29723, 29747, 29665, - 29904, 29771, 29569, 29725, 29773, 29566, 29772, 29773, 29725, 29772, 29725, 29735, 29772, - 29735, 29822, 29735, 29692, 29822, 29822, 29692, 29832, 11803, 11922, 11904, 11803, 11904, - 11731, 13117, 13280, 12908, 13622, 13921, 13969, 13622, 13969, 13711, 15292, 15419, 15397, - 26314, 26244, 26252, 25987, 26217, 25976, 29832, 29601, 29757, 11731, 11904, 11766, 20497, - 20352, 20408, 12411, 12443, 12482, 14458, 14521, 14637, 15004, 15046, 15192, 15192, 15218, - 15292, 15292, 15349, 15419, 14442, 14521, 14365, 14313, 14458, 14373, 17316, 17404, 17264, - 28348, 28410, 28131, 28434, 28410, 28348, 28830, 28369, 28431, 29504, 29496, 29265, 29705, - 29666, 29584, 29771, 29666, 29705, 14521, 14707, 14637, 27885, 27340, 27504, 26458, 26454, - 26314, 26314, 26454, 26244, 29757, 29601, 29657, 11766, 11983, 11906, 12301, 12028, 12328, - 12301, 12896, 12602, 14707, 14844, 15009, 11766, 11906, 11684, 11613, 11898, 11533, 22295, - 22292, 22368, 29901, 29747, 29723, 29823, 29757, 29657, 29635, 29614, 29798, 19123, 19037, - 18934, 18799, 18514, 18456, 19070, 19037, 19123, 13935, 13824, 14041, 13921, 14311, 14408, - 14906, 14541, 14768, 13884, 13935, 14080, 14080, 13935, 14041, 15012, 14979, 14906, 15069, - 14979, 15012, 15462, 15396, 15572, 14844, 14973, 15004, 15487, 15462, 15572, 15487, 15572, - 15667, 28172, 27833, 27521, 11758, 11805, 11825, 12824, 12781, 12899, 12727, 12824, 12651, - 17142, 16961, 17116, 17031, 16961, 17142, 16909, 16996, 16928, 16875, 16996, 16909, 29798, - 29614, 29661, 11806, 12067, 11995, 12781, 12871, 12899, 25189, 25067, 25448, 12539, 12727, - 12651, 16996, 17184, 17054, 13663, 13486, 13711, 13313, 13117, 13254, 11982, 12310, 12109, - 11805, 11713, 11825, 12363, 12411, 12482, 12480, 12539, 12651, 12082, 12332, 12114, 14973, - 15046, 15004, 17681, 17774, 17678, 17839, 17979, 18015, 17681, 17678, 17580, 28261, 28314, - 28194, 28156, 28172, 27917, 28387, 28314, 28261, 17184, 17316, 17264, 29820, 29798, 29661, - 11843, 12082, 12114, 12114, 12093, 11748, 29659, 29559, 29562, 29436, 29366, 29294, 29504, - 29265, 29231, 29811, 29545, 29825, 11981, 11982, 12109, 15046, 15142, 15192, 22427, 22398, - 22368, 22536, 22540, 22635, 22986, 22801, 22843, 26430, 26540, 26387, 26526, 26540, 26430, - 26526, 26430, 26276, 19244, 19383, 19376, 19376, 19383, 19521, 21850, 21981, 22038, 22038, - 21981, 22072, 19227, 19383, 19244, 19227, 19244, 19109, 27852, 27970, 27656, 27852, 27656, - 27583, 11713, 11782, 12022, 15142, 15218, 15192, 16676, 16909, 16742, 12091, 12301, 12602, - 11990, 11981, 12109, 12134, 12327, 12105, 12411, 12426, 12443, 16115, 15880, 16273, 17748, - 17979, 17839, 17748, 17839, 17774, 28337, 28172, 28156, 29545, 29453, 29825, 19224, 19109, - 19112, 29830, 29659, 29562, 29830, 29562, 29666, 11684, 11628, 11766, 11990, 12109, 12028, - 15880, 15682, 15815, 15390, 15069, 15396, 19037, 18833, 18934, 19055, 18833, 19037, 27970, - 28004, 27739, 28336, 28004, 27970, 12211, 12426, 12411, 17705, 17681, 17580, 18704, 18514, - 18799, 17031, 16800, 16961, 23340, 22986, 22980, 23082, 22986, 23158, 14104, 14080, 14188, - 12664, 13040, 12585, 12762, 12848, 12664, 12652, 12511, 12602, 16961, 16800, 16868, 17142, - 17344, 17246, 16996, 17127, 17184, 17127, 17378, 17316, 17316, 17378, 17404, 15554, 15501, - 15443, 28763, 28830, 28431, 28691, 28431, 28410, 17246, 17320, 17261, 24955, 24673, 24108, - 29849, 29499, 29665, 16735, 16676, 16592, 17106, 17246, 17143, 14707, 14759, 14844, 14844, - 14829, 14973, 14973, 14970, 15046, 15046, 15033, 15142, 15142, 15144, 15218, 14521, 14608, - 14707, 14442, 14608, 14521, 25448, 25067, 25455, 24955, 24938, 24673, 27318, 27219, 26979, - 13313, 13489, 13117, 13528, 13505, 13663, 14313, 14373, 14311, 14365, 14521, 14458, 28190, - 27885, 27833, 28314, 28337, 28156, 28387, 28337, 28314, 12018, 11990, 12028, 11684, 11906, - 11537, 12464, 12511, 12652, 13473, 13505, 13528, 17127, 17316, 17184, 24473, 24190, 24046, - 29526, 29366, 29436, 29021, 28674, 28220, 29526, 29436, 29518, 12327, 12287, 12363, 12134, - 12287, 12327, 14759, 14829, 14844, 29565, 29526, 29644, 14829, 14970, 14973, 15443, 15501, - 15419, 19994, 20184, 20189, 18833, 18704, 18799, 19830, 19521, 19383, 20474, 20664, 20123, - 11722, 11710, 11768, 11533, 11898, 11874, 11758, 11613, 11805, 11805, 11648, 11713, 11713, - 11654, 11782, 11783, 11710, 11722, 11669, 11710, 11783, 11669, 11783, 11803, 11669, 11803, - 11628, 11803, 11731, 11628, 29773, 29901, 29664, 29747, 29849, 29665, 29772, 29913, 29773, - 30004, 29913, 29772, 29882, 29772, 29822, 29882, 29822, 29855, 29822, 29832, 29855, 29832, - 29757, 29855, 29757, 30097, 29855, 11628, 11731, 11766, 29757, 29823, 29872, 14541, 14104, - 14768, 15390, 15396, 15462, 14800, 14541, 14906, 20664, 20974, 20527, 29913, 29901, 29773, - 29872, 29823, 29798, 11782, 11806, 11995, 11642, 11748, 12014, 12171, 12211, 12287, 11656, - 11806, 11782, 29771, 29759, 29666, 29659, 29671, 29559, 30002, 29759, 29771, 29658, 29453, - 29538, 29948, 29872, 29798, 12310, 11982, 11804, 11845, 12018, 12028, 11883, 12018, 11845, - 18812, 18704, 18833, 18514, 18445, 18456, 12848, 12762, 12900, 12664, 12514, 12633, 12781, - 12778, 12871, 12871, 12751, 13118, 12724, 12778, 12781, 12568, 12824, 12727, 12707, 12443, - 12466, 16875, 17127, 16996, 16676, 16735, 16909, 15349, 15292, 15218, 25063, 24938, 24955, - 24673, 24473, 24046, 11982, 11981, 11883, 11528, 11874, 11768, 12466, 12443, 12400, 15033, - 15144, 15142, 16709, 17127, 16875, 19070, 19055, 19037, 19140, 19055, 19070, 22540, 22398, - 22427, 22536, 22398, 22540, 24672, 24473, 24673, 27138, 26979, 26650, 26468, 26526, 26276, - 26468, 26276, 26217, 29903, 29671, 29659, 29838, 29658, 29538, 29838, 29538, 29496, 29176, - 28182, 29230, 11613, 11648, 11805, 21145, 21119, 20951, 20027, 19994, 20111, 20352, 19994, - 20189, 21983, 22107, 21357, 12287, 12211, 12411, 12519, 12283, 12043, 19112, 19109, 19005, - 17681, 17748, 17774, 17705, 17748, 17681, 17705, 17580, 17378, 22072, 22269, 22634, 24614, - 24558, 24175, 21854, 21981, 21850, 29759, 29830, 29666, 29843, 29830, 29926, 12400, 12443, - 12426, 11883, 11981, 11990, 11648, 11654, 11713, 19994, 20352, 20111, 21357, 22107, 22011, - 25962, 25674, 25455, 25189, 25063, 24955, 26454, 26458, 26619, 26513, 26468, 26217, 29948, - 29798, 29820, 18704, 18552, 18514, 18637, 18552, 18704, 19994, 19945, 20184, 22011, 22107, - 22292, 22398, 22295, 22368, 22635, 22540, 22801, 22635, 22801, 22909, 22801, 22986, 22909, - 29946, 29849, 29747, 13313, 13355, 13528, 13505, 13486, 13663, 13254, 13355, 13313, 26070, - 25455, 26244, 28337, 28327, 28172, 27833, 27885, 27504, 26455, 26244, 26454, 28387, 28327, - 28337, 12260, 12400, 12426, 19945, 19346, 19903, 19055, 18812, 18833, 13473, 13486, 13505, - 15268, 15349, 15218, 11654, 11656, 11782, 25674, 25448, 25455, 29849, 29904, 29569, 12043, - 12283, 12002, 12211, 12260, 12426, 12002, 12283, 12082, 14365, 14458, 14313, 14608, 14759, - 14707, 14829, 14759, 14970, 14970, 15033, 15046, 15144, 15268, 15218, 14800, 14906, 14979, - 29461, 29504, 29231, 29461, 29231, 29613, 14313, 14311, 14160, 26654, 26650, 26540, 26654, - 26540, 26526, 13117, 13489, 13280, 12568, 12724, 12781, 12568, 12727, 12539, 12568, 12539, - 12480, 14160, 14311, 13765, 14661, 14759, 14608, 19346, 19309, 19257, 19140, 19309, 19395, - 19427, 19830, 19383, 19224, 19383, 19227, 29658, 29825, 29453, 29952, 29948, 29820, 30006, - 29825, 29658, 12480, 12651, 12466, 17246, 17106, 17031, 17031, 17106, 16800, 16800, 16653, - 16868, 17344, 17498, 17320, 17757, 17705, 17695, 18061, 18628, 17979, 24677, 24672, 24673, - 24473, 24470, 24190, 24677, 24673, 24938, 24825, 24930, 25064, 25987, 26513, 26217, 24175, - 24558, 24410, 24780, 24558, 24802, 18941, 18812, 19055, 23725, 24018, 24001, 22310, 22295, - 22398, 25186, 25063, 25189, 15487, 15390, 15462, 15069, 14800, 14979, 15487, 15667, 15682, - 15487, 15682, 15538, 15349, 15443, 15419, 15272, 15443, 15349, 28190, 27833, 28172, 14927, - 14800, 15069, 12762, 12464, 12652, 12511, 12091, 12602, 12429, 12466, 12400, 12429, 12480, - 12466, 17320, 17498, 17881, 13355, 13473, 13528, 13280, 13118, 12908, 13486, 13622, 13711, - 13200, 13473, 13355, 25256, 25186, 25189, 28674, 28387, 28261, 28327, 28316, 28172, 28004, - 28425, 28204, 29613, 29231, 29089, 28477, 28425, 28514, 28434, 28425, 28477, 19309, 19166, - 19257, 19140, 19166, 19309, 17846, 17979, 17748, 22310, 22398, 22536, 29542, 29176, 29230, - 28500, 28372, 28530, 29557, 29230, 29366, 29557, 29366, 29615, 20974, 21796, 21850, 24030, - 24175, 23932, 13435, 13622, 13486, 14629, 15033, 14970, 15390, 14927, 15069, 15538, 15682, - 15880, 15443, 15475, 15554, 15442, 15475, 15443, 25464, 25313, 25448, 25448, 25313, 25189, - 26513, 26654, 26526, 26513, 26526, 26468, 28434, 28556, 28410, 29119, 28756, 28830, 29667, - 29714, 29496, 12018, 11883, 11990, 11845, 12028, 12301, 11748, 12093, 12014, 12055, 11900, - 11642, 12134, 12171, 12287, 11942, 12171, 12134, 12105, 12327, 12043, 17705, 17846, 17748, - 24001, 24018, 24190, 18552, 18445, 18514, 18478, 18445, 18552, 18280, 18445, 18408, 23158, - 22986, 23340, 22563, 22310, 22536, 13430, 13510, 13824, 12762, 12415, 12464, 14104, 13884, - 14080, 13973, 13884, 14104, 21796, 21854, 21850, 11657, 11804, 11982, 19224, 19427, 19383, - 19005, 19109, 18628, 21173, 21310, 21299, 22563, 22536, 22635, 28372, 28316, 28327, 28372, - 28327, 28387, 12193, 12260, 12211, 13254, 13200, 13355, 13473, 13435, 13486, 12751, 12871, - 12778, 25674, 25464, 25448, 25626, 25464, 25674, 28425, 28434, 28348, 28477, 28514, 28545, - 11710, 11592, 11768, 11613, 11585, 11648, 11648, 11556, 11654, 11654, 11556, 11656, 11425, - 11592, 11710, 11425, 11710, 11669, 11425, 11669, 11472, 11517, 11628, 11684, 29930, 30004, - 29772, 29913, 29974, 29901, 29901, 29935, 29747, 29849, 30009, 29904, 29930, 29772, 29882, - 29930, 29882, 30098, 29930, 30098, 30103, 29882, 29855, 30097, 11592, 11528, 11768, 13510, - 13689, 13824, 12724, 12775, 12778, 12588, 12775, 12724, 12751, 12775, 12588, 12724, 12478, - 12588, 13779, 13824, 13935, 24672, 24470, 24473, 24945, 24677, 24938, 24945, 24938, 25063, - 24945, 25063, 25077, 25063, 25181, 25077, 24558, 24780, 24825, 23932, 23752, 24024, 25256, - 25189, 25313, 26236, 26070, 26244, 29176, 29021, 28220, 11528, 11533, 11874, 30004, 29974, - 29913, 13884, 13779, 13935, 15033, 15268, 15144, 16083, 16676, 16428, 16735, 16692, 16875, - 17695, 17705, 17601, 17705, 17757, 17846, 16665, 16653, 16800, 17261, 17143, 17246, 17132, - 17143, 17261, 21854, 21924, 21981, 24579, 24470, 24672, 28691, 28763, 28431, 28691, 28410, - 28556, 28978, 29119, 28830, 12171, 12193, 12211, 11933, 12105, 12043, 11642, 11900, 11806, - 11903, 12002, 12082, 11547, 11806, 11490, 19112, 19125, 19224, 19010, 19005, 18955, 11533, - 11585, 11613, 21173, 21119, 21164, 21164, 21119, 21145, 19994, 20027, 19945, 21173, 21164, - 21310, 21310, 21357, 21299, 29974, 29935, 29901, 29926, 29830, 29759, 11903, 12082, 11843, - 12464, 12435, 12511, 12415, 12435, 12464, 17291, 17320, 17508, 18445, 18280, 18456, 18637, - 18704, 18812, 23384, 23158, 23340, 22946, 22909, 22986, 23082, 23158, 23019, 24470, 24238, - 24190, 25321, 25256, 25313, 28826, 28691, 28556, 11498, 11517, 11684, 13126, 13200, 13254, - 13126, 13254, 13117, 22011, 22292, 22132, 22132, 22292, 22295, 22132, 22295, 22213, 25482, - 25321, 25313, 25810, 25626, 25674, 28425, 28004, 28514, 26654, 27138, 26650, 28316, 28190, - 28172, 28316, 28372, 28500, 29935, 29946, 29747, 29830, 29843, 29659, 13242, 13435, 13473, - 14268, 14365, 14313, 14467, 14661, 14608, 14759, 14629, 14970, 15272, 15349, 15268, 14467, - 14608, 14442, 14351, 14442, 14365, 14351, 14365, 14268, 26070, 25962, 25455, 11585, 11556, - 11648, 19945, 19395, 19346, 20111, 20352, 20262, 21277, 21299, 21399, 29946, 30009, 29849, - 11883, 11755, 11982, 11800, 11845, 12301, 11750, 11903, 11843, 18915, 18637, 18812, 18941, - 19055, 19031, 22946, 22986, 23082, 22076, 22072, 21981, 19140, 19070, 19166, 22011, 21967, - 21357, 22364, 22295, 22310, 21924, 22076, 21981, 30002, 29771, 30087, 29565, 29366, 29526, - 16300, 16322, 16592, 15272, 15442, 15443, 15387, 15442, 15369, 26070, 25999, 25962, 26455, - 26236, 26244, 26458, 26835, 26619, 29526, 29518, 29644, 29176, 29663, 29021, 11556, 11563, - 11656, 12664, 12542, 12762, 12633, 12542, 12664, 14800, 14622, 14541, 13942, 13973, 14104, - 13884, 13862, 13779, 14863, 14927, 14746, 18280, 18260, 18456, 18196, 18260, 18280, 24677, - 24579, 24672, 24344, 24225, 24238, 24945, 24858, 24677, 24839, 24858, 24974, 28925, 28978, - 28830, 29667, 29504, 29461, 28925, 28830, 28763, 29805, 29518, 29671, 29952, 29820, 29811, - 29952, 29811, 30174, 12775, 12751, 12778, 12429, 12568, 12480, 16665, 16800, 16724, 14863, - 14800, 14927, 16565, 16653, 16665, 16592, 16692, 16735, 16709, 16692, 16592, 28884, 28925, - 28763, 25962, 25810, 25674, 25626, 25603, 25464, 25077, 24858, 24945, 25871, 25810, 25962, - 12163, 12429, 12400, 12062, 12193, 12171, 11942, 12134, 12105, 11933, 12043, 11855, 25634, - 25603, 25626, 11804, 11608, 12310, 11329, 11608, 11804, 11599, 11642, 11806, 11748, 11714, - 12114, 28691, 28801, 28763, 28884, 28801, 28912, 11688, 11714, 11748, 11903, 11894, 12002, - 12151, 12400, 12260, 13942, 14104, 14541, 13779, 13430, 13824, 22909, 22563, 22635, 29863, - 29805, 29671, 18637, 18478, 18552, 18310, 18478, 18637, 22909, 22601, 22563, 23019, 22946, - 23082, 23596, 23340, 23725, 29805, 29644, 29518, 29667, 29496, 29504, 29667, 29940, 29848, - 26236, 26075, 26070, 13973, 13862, 13884, 12514, 12664, 12585, 24238, 24225, 24190, 24554, - 24238, 24470, 26458, 26621, 26835, 26236, 26384, 26075, 25252, 24999, 25514, 26654, 26905, - 27138, 22076, 22269, 22072, 29843, 29903, 29659, 29960, 29903, 29843, 29557, 29542, 29230, - 29565, 29615, 29366, 29643, 29615, 29565, 23848, 23632, 23725, 29610, 29542, 29557, 30174, - 29811, 29825, 11845, 11755, 11883, 11666, 11755, 11689, 26137, 25999, 26075, 26075, 25999, - 26070, 25810, 25823, 25626, 25514, 24999, 25064, 28292, 28190, 28316, 27000, 26621, 27165, - 28292, 28316, 28359, 18478, 18408, 18445, 17291, 17132, 17320, 18310, 18408, 18478, 26561, - 26455, 26454, 29247, 29089, 29119, 29714, 29838, 29496, 24225, 24001, 24190, 24011, 24024, - 23752, 24802, 24930, 24780, 24780, 24930, 24825, 12381, 12415, 12762, 12106, 12091, 12511, - 12533, 12633, 12514, 12967, 13126, 13117, 12494, 12724, 12568, 24614, 24175, 24354, 11608, - 11537, 12474, 11329, 11537, 11608, 12429, 12494, 12568, 12478, 12494, 12361, 14268, 14313, - 14160, 15212, 15272, 14889, 14351, 14467, 14442, 19395, 19309, 19346, 18941, 18915, 18812, - 19005, 19125, 19112, 19010, 19125, 19005, 22563, 22364, 22310, 22029, 21967, 22011, 22213, - 22364, 22354, 28978, 29116, 29119, 29115, 29116, 28978, 29115, 28978, 28925, 30087, 29771, - 29904, 14311, 13921, 13765, 16653, 16565, 16868, 17132, 17106, 17143, 17132, 17261, 17320, - 12533, 12762, 12542, 17841, 17881, 18260, 29116, 29247, 29119, 30004, 30103, 29974, 30137, - 30050, 29935, 29935, 30050, 29946, 29946, 30050, 30009, 30162, 30087, 29904, 29930, 30103, - 30004, 30098, 29882, 30205, 29757, 29872, 30097, 30097, 29872, 30054, 26455, 26312, 26236, - 11472, 11669, 11628, 11592, 11449, 11528, 11528, 11449, 11533, 11533, 11445, 11585, 11585, - 11495, 11556, 11556, 11484, 11563, 11472, 11628, 11517, 11387, 11449, 11592, 11490, 11806, - 11656, 11714, 11750, 11843, 11643, 11750, 11714, 13551, 13921, 13622, 14863, 14758, 14800, - 13973, 13693, 13862, 14927, 15256, 14746, 19830, 20474, 20123, 20664, 20474, 20974, 21764, - 21854, 21796, 21764, 22009, 21854, 21854, 22009, 21924, 21924, 22009, 22076, 22076, 22130, - 22269, 20239, 20474, 19830, 25154, 25227, 25064, 11490, 11656, 11563, 11642, 11688, 11748, - 13200, 13242, 13473, 13435, 13551, 13622, 12908, 13118, 12751, 22029, 22011, 22132, 28434, - 28568, 28556, 28801, 28884, 28763, 28004, 28336, 28514, 30002, 29926, 29759, 30096, 29926, - 30150, 11449, 11445, 11533, 11855, 12043, 12002, 12193, 12151, 12260, 28359, 28316, 28500, - 27000, 27165, 27076, 11498, 11472, 11517, 30054, 29872, 29948, 11432, 11688, 11642, 14758, - 14863, 14746, 19140, 19031, 19055, 18915, 19031, 19004, 19131, 19427, 19224, 18955, 19005, - 18628, 11650, 11894, 11903, 12477, 12908, 12751, 13330, 13551, 13435, 15442, 15387, 15475, - 15272, 15268, 14889, 19131, 19224, 19125, 21764, 21796, 21452, 24011, 24033, 24024, 11307, - 11498, 11684, 11310, 11495, 11585, 20262, 20352, 20497, 20027, 19934, 19945, 20262, 20497, - 20506, 21184, 21119, 21173, 21184, 21173, 21299, 21277, 21184, 21299, 26640, 26704, 26654, - 28545, 28568, 28477, 26640, 26654, 26513, 30134, 29935, 29974, 12042, 12151, 12193, 24225, - 24062, 24001, 23821, 23596, 23632, 23632, 23596, 23725, 22601, 22364, 22563, 24154, 24062, - 24225, 24839, 24677, 24858, 24024, 24033, 24030, 23932, 23497, 23752, 21399, 21299, 21357, - 11755, 11657, 11982, 11307, 11346, 11498, 11666, 11657, 11755, 18762, 18955, 18628, 19010, - 19131, 19125, 19010, 18955, 19018, 26455, 26541, 26312, 26561, 26514, 26455, 27165, 27356, - 27076, 26617, 26640, 26513, 12633, 12533, 12542, 12415, 12265, 12435, 13011, 13689, 13510, - 12588, 12557, 12751, 12494, 12478, 12724, 12492, 12478, 12361, 25063, 25186, 25181, 25186, - 25256, 25181, 24930, 25154, 25064, 24614, 24802, 24558, 11547, 11599, 11806, 11479, 11599, - 11547, 12492, 12557, 12588, 13242, 13330, 13435, 12908, 12967, 13117, 13076, 12967, 12902, - 16565, 16115, 16273, 16724, 16800, 17106, 16692, 16709, 16875, 16714, 16709, 16525, 20111, - 19934, 20027, 21577, 21399, 21357, 22009, 22130, 22076, 22227, 22130, 22084, 25181, 25256, - 25258, 28477, 28568, 28434, 27852, 28162, 27970, 30139, 30054, 29948, 30139, 29948, 29952, - 11933, 11942, 12105, 11861, 11942, 11933, 23848, 23725, 24001, 24761, 24579, 24677, 11894, - 11855, 12002, 11785, 11855, 11894, 11650, 11903, 11750, 11643, 11714, 11688, 13299, 13430, - 13779, 13320, 13430, 13299, 18408, 18196, 18280, 16860, 16724, 17106, 18310, 18196, 18408, - 25999, 25871, 25962, 26384, 26137, 26075, 26384, 26236, 26312, 29644, 29643, 29565, 29615, - 29610, 29557, 29826, 29643, 29644, 29929, 29644, 29805, 29863, 29671, 29992, 25313, 25464, - 25558, 25207, 25154, 24930, 25227, 25514, 25064, 25987, 26617, 26513, 28826, 28801, 28691, - 29116, 29188, 29247, 11318, 11484, 11556, 12210, 12494, 12429, 12007, 12062, 12171, 24013, - 23848, 24001, 23821, 23848, 24013, 26619, 26514, 26561, 12215, 12265, 12415, 17508, 17320, - 17881, 22364, 22213, 22295, 21967, 21776, 21357, 22601, 22909, 22580, 25558, 25464, 25603, - 28767, 28826, 28556, 30096, 29960, 29843, 30096, 29843, 29926, 11657, 11329, 11804, 11672, - 11755, 11845, 11405, 11643, 11688, 11658, 11800, 11633, 23019, 22909, 22946, 30007, 29671, - 29903, 14467, 14324, 14661, 14351, 14400, 14467, 14268, 14400, 14351, 14213, 14400, 14268, - 14213, 14268, 14160, 15387, 15423, 15475, 15268, 15033, 14889, 30162, 29904, 30009, 16031, - 16115, 16565, 25390, 25514, 25227, 14758, 14622, 14800, 14746, 14622, 14758, 14530, 14622, - 14589, 18044, 17841, 18260, 23596, 23384, 23340, 23506, 23384, 23596, 28507, 27885, 28190, - 26655, 26541, 26514, 29542, 29673, 29176, 28372, 28387, 28530, 29799, 29610, 29615, 29799, - 29615, 29643, 11672, 11689, 11755, 11666, 11511, 11657, 29851, 29838, 29714, 29851, 29714, - 29667, 21881, 21776, 21967, 21452, 21796, 20974, 12557, 12477, 12751, 12478, 12492, 12588, - 12210, 12429, 12163, 16665, 16549, 16565, 17071, 17106, 17132, 16681, 16724, 16700, 24839, - 24761, 24677, 24579, 24554, 24470, 25077, 24974, 24858, 25034, 24974, 25077, 25034, 25077, - 25181, 29105, 29115, 28925, 29620, 29613, 29089, 28983, 28925, 28884, 12106, 12511, 12435, - 11800, 11672, 11845, 12062, 12042, 12193, 11932, 12042, 12062, 12007, 12171, 11942, 15272, - 15369, 15442, 15322, 15369, 15212, 23220, 23019, 23158, 23497, 23263, 23648, 24354, 24175, - 24030, 12533, 12381, 12762, 12265, 12164, 12435, 12437, 12381, 12533, 24974, 24761, 24839, - 23554, 23506, 23596, 29115, 29188, 29116, 16681, 16549, 16665, 29013, 28983, 28884, 13908, - 13942, 14541, 27000, 26835, 26621, 25973, 25999, 26137, 12308, 12215, 12415, 12163, 12400, - 12151, 24765, 24554, 24579, 25973, 25871, 25999, 25321, 25258, 25256, 25823, 25871, 26053, - 28292, 28359, 28190, 28387, 28674, 28530, 19018, 19131, 19010, 20022, 20239, 19830, 18061, - 17979, 17846, 22152, 22029, 22132, 22601, 22354, 22364, 22580, 22354, 22601, 25794, 25634, - 25626, 28568, 28650, 28556, 28826, 28912, 28801, 27583, 27318, 27919, 29960, 30007, 29903, - 30032, 29826, 29644, 30040, 30007, 29960, 11401, 11490, 11563, 11599, 11432, 11642, 25482, - 25258, 25321, 25154, 25283, 25227, 25207, 25283, 25154, 25390, 25283, 25234, 28873, 28912, - 28826, 11273, 11307, 11299, 11658, 11672, 11800, 12208, 12164, 12265, 12032, 12163, 12151, - 15369, 15423, 15387, 15322, 15423, 15369, 23821, 23632, 23848, 23274, 23220, 23158, 30097, - 30205, 29882, 30098, 30205, 30103, 30103, 30198, 29974, 30050, 30212, 30009, 30406, 30205, - 30097, 30434, 30097, 30054, 11445, 11310, 11585, 11495, 11318, 11556, 11484, 11401, 11563, - 11449, 11387, 11445, 11219, 11387, 11592, 11219, 11592, 11180, 11346, 11425, 11472, 30309, - 30198, 30103, 11891, 12007, 11942, 12042, 12032, 12151, 11861, 11933, 11751, 17705, 17378, - 17601, 24013, 24001, 24062, 24011, 24048, 24033, 23497, 22634, 23263, 22227, 22269, 22130, - 18196, 18044, 18260, 18915, 18310, 18637, 18915, 18941, 19031, 23274, 23158, 23384, 23111, - 22580, 22909, 29929, 29805, 29863, 19597, 19830, 19427, 18862, 19018, 18955, 30007, 29992, - 29671, 30024, 29992, 30007, 29838, 30006, 29658, 11498, 11346, 11472, 11307, 11684, 11537, - 11387, 11310, 11445, 13551, 13765, 13921, 13300, 13765, 13551, 21182, 21119, 21184, 20506, - 20497, 21119, 20111, 19961, 19934, 19124, 19031, 19140, 21182, 21184, 21277, 21182, 21277, - 21326, 26640, 26860, 26704, 26905, 27268, 27138, 27073, 27120, 27065, 30198, 30134, 29974, - 30150, 29926, 30002, 20262, 20223, 20111, 25871, 25823, 25810, 25634, 25558, 25603, 25973, - 26137, 26261, 27356, 27601, 27538, 28512, 28500, 28530, 27268, 27318, 27138, 28545, 28650, - 28568, 30134, 30137, 29935, 11633, 11800, 12301, 12164, 12106, 12435, 17542, 17508, 17881, - 17542, 17881, 17841, 23990, 24048, 24011, 11490, 11479, 11547, 11643, 11650, 11750, 11321, - 11479, 11490, 22152, 22132, 22213, 21326, 21277, 21399, 22152, 22213, 22362, 30150, 30002, - 30087, 11511, 11666, 11689, 21326, 21399, 21513, 25794, 25558, 25634, 28688, 28650, 28545, - 30137, 30181, 30050, 13430, 13320, 13510, 13623, 13779, 13862, 13076, 13200, 13126, 13076, - 13126, 12967, 11405, 11650, 11643, 12902, 12967, 12908, 12210, 12361, 12494, 12372, 12361, - 12269, 12585, 13040, 13481, 12381, 12308, 12415, 12215, 12208, 12265, 12164, 12066, 12106, - 16724, 16681, 16665, 16549, 16031, 16565, 17071, 17132, 17291, 16709, 16714, 17127, 16525, - 16709, 16592, 28983, 29105, 28925, 29115, 29184, 29188, 29188, 29319, 29247, 29013, 29105, - 28983, 29013, 28884, 28912, 21513, 21399, 21577, 30181, 30212, 30050, 12266, 12308, 12381, - 12742, 12585, 13481, 17292, 17071, 17291, 19395, 19945, 19934, 24354, 24030, 24033, 28873, - 29013, 28912, 29381, 29319, 29361, 29838, 30053, 30006, 29992, 29932, 29863, 30095, 29932, - 29992, 11932, 12032, 12042, 12163, 12060, 12210, 11751, 11933, 11855, 23426, 23274, 23384, - 23821, 23554, 23596, 23721, 23554, 23821, 26905, 26654, 26704, 19237, 19395, 19387, 21577, - 21357, 21776, 22362, 22213, 22354, 11287, 11318, 11495, 11650, 11785, 11894, 23111, 22909, - 23019, 23258, 23274, 23426, 14622, 14530, 14541, 15256, 15390, 15487, 18489, 18762, 18628, - 17601, 17378, 17354, 27000, 27059, 26835, 25938, 25794, 25823, 28450, 28190, 28359, 29620, - 29089, 29247, 24554, 24344, 24238, 24505, 24344, 24554, 24765, 24579, 24761, 25034, 24761, - 24974, 25034, 25181, 25258, 24048, 24354, 24033, 28921, 28873, 28826, 13320, 13011, 13510, - 12372, 12557, 12492, 16115, 15813, 15880, 16030, 15813, 16115, 25558, 25482, 25313, 25823, - 25794, 25626, 26791, 26619, 26835, 21577, 21776, 21656, 21204, 21452, 20974, 22084, 22130, - 22009, 21204, 20974, 20474, 27076, 27059, 27000, 30212, 30162, 30009, 13330, 13300, 13551, - 13076, 13242, 13200, 15813, 15538, 15880, 26384, 26312, 26388, 11910, 12301, 12091, 11672, - 11511, 11689, 29848, 29851, 29667, 21859, 22009, 21764, 23111, 23019, 23220, 29932, 29978, - 29863, 30095, 29978, 29932, 30040, 29960, 30096, 30143, 30040, 30249, 15256, 14927, 15390, - 27059, 26991, 26835, 26860, 26905, 26704, 11318, 11401, 11484, 12049, 12066, 12164, 12106, - 11917, 12091, 11932, 12062, 12007, 21656, 21776, 21881, 24344, 24154, 24225, 25771, 25482, - 25558, 28650, 28767, 28556, 28816, 28767, 28650, 30126, 30139, 29952, 30126, 29952, 30174, - 16322, 16525, 16592, 15212, 15369, 15272, 26541, 26455, 26514, 26617, 27073, 26768, 26768, - 26640, 26617, 26768, 26860, 26640, 11861, 11891, 11942, 11597, 11891, 11861, 21881, 22029, - 21899, 21881, 21967, 22029, 23263, 22634, 22269, 23752, 23990, 24011, 24048, 24206, 24354, - 30174, 29825, 30182, 11785, 11751, 11855, 11597, 11751, 11785, 29826, 29799, 29643, 28906, - 28795, 28684, 29990, 29799, 29826, 12514, 12437, 12533, 12308, 12208, 12215, 12333, 12437, - 12514, 12333, 12514, 12585, 12361, 12372, 12492, 12269, 12361, 12210, 29105, 29184, 29115, - 29593, 29620, 29247, 29480, 29184, 29105, 29361, 29184, 29480, 29239, 29013, 28873, 16681, - 16528, 16549, 16700, 16528, 16681, 17354, 17378, 17127, 16592, 16083, 16300, 28500, 28512, - 28359, 28530, 28684, 28622, 12437, 12266, 12381, 11505, 11511, 11672, 11980, 11917, 12106, - 11658, 11557, 11672, 11980, 12106, 12066, 11821, 11932, 12007, 12032, 12045, 12163, 13942, - 13693, 13973, 13320, 13246, 13011, 13649, 13693, 13942, 17508, 17292, 17291, 16860, 16700, - 16724, 17798, 17542, 17841, 18044, 18196, 18146, 16664, 17127, 16714, 18061, 17846, 17757, - 17759, 17757, 17695, 19183, 19427, 19131, 24049, 24013, 24062, 23258, 23220, 23274, 23866, - 23990, 23752, 25850, 25987, 25514, 27832, 27919, 27318, 28864, 28921, 28767, 29940, 29667, - 29461, 29381, 29247, 29319, 11655, 11633, 12301, 23258, 23111, 23220, 23384, 23506, 23426, - 29851, 29944, 29838, 29988, 29848, 29940, 16428, 15475, 16083, 12142, 12208, 12308, 26384, - 26261, 26137, 25973, 26053, 25871, 25794, 25771, 25558, 26382, 26261, 26384, 11355, 11432, - 11599, 11165, 11597, 11785, 11355, 11599, 11479, 13693, 13623, 13862, 19395, 19124, 19140, - 18146, 18196, 18310, 19237, 19124, 19395, 30040, 30024, 30007, 29978, 29929, 29863, 30143, - 30024, 30040, 11401, 11321, 11490, 21781, 21881, 21899, 22408, 22354, 22580, 21719, 21859, - 21764, 25283, 25390, 25227, 25207, 24930, 24989, 24930, 24802, 24892, 24802, 24614, 24892, - 28767, 28921, 28826, 28688, 28545, 28514, 30312, 30150, 30087, 11974, 12045, 12032, 18146, - 18310, 18051, 30091, 29929, 29978, 17547, 17759, 17695, 18061, 17759, 17918, 25635, 25850, - 25514, 27356, 27165, 27601, 28906, 28684, 28530, 11180, 11592, 11425, 11387, 11288, 11310, - 11310, 11258, 11495, 11318, 11131, 11401, 11401, 11111, 11321, 11253, 11425, 11346, 11253, - 11346, 11273, 30198, 30281, 30134, 30134, 30281, 30137, 30137, 30219, 30181, 30181, 30233, - 30212, 30212, 30320, 30162, 30162, 30251, 30087, 30205, 30309, 30103, 30390, 30309, 30406, - 30311, 30054, 30139, 11273, 11346, 11307, 13215, 13246, 13320, 13011, 12742, 13481, 21859, - 21934, 22009, 23712, 23746, 23648, 26727, 26514, 26619, 28450, 28359, 28512, 27076, 27129, - 27059, 26937, 26791, 26991, 26991, 26791, 26835, 27268, 27463, 27318, 27471, 27403, 27268, - 27070, 27268, 26905, 27018, 26905, 26860, 27919, 28150, 27852, 28162, 28150, 28659, 30182, - 29825, 30006, 30126, 30311, 30139, 27403, 27463, 27268, 11432, 11411, 11688, 11380, 11411, - 11432, 19124, 19004, 19031, 19113, 19004, 19124, 22446, 22408, 22580, 11299, 11307, 11537, - 11175, 11288, 11387, 11917, 11910, 12091, 11936, 11980, 12066, 18907, 19131, 19018, 21719, - 22056, 21859, 21859, 22056, 21934, 24013, 23905, 23821, 24154, 24049, 24062, 24036, 24049, - 24154, 24505, 24154, 24344, 30368, 30281, 30198, 14530, 14266, 14541, 13649, 13547, 13623, - 14639, 14589, 14622, 14639, 14622, 14746, 16345, 16031, 16549, 16860, 17106, 17071, 16525, - 16664, 16714, 16435, 16664, 16525, 25652, 25034, 25258, 24718, 24796, 24617, 11288, 11258, - 11310, 12179, 12269, 12210, 12468, 12902, 12908, 17004, 16860, 17071, 17292, 17508, 17317, - 30281, 30219, 30137, 16246, 16424, 16322, 16322, 16424, 16525, 24892, 24614, 24910, 25390, - 25635, 25514, 14545, 14639, 14746, 10828, 11299, 11537, 12208, 12049, 12164, 12266, 12142, - 12308, 12333, 12142, 12266, 12333, 12266, 12437, 15538, 15256, 15487, 15122, 15256, 15538, - 15730, 15538, 15813, 16083, 15475, 15976, 14889, 15033, 14629, 14759, 14661, 14629, 26224, - 26053, 25973, 26541, 26388, 26312, 26613, 26388, 26541, 28150, 28162, 27852, 28580, 28786, - 29012, 29361, 29319, 29188, 29361, 29188, 29184, 30219, 30233, 30181, 29988, 29944, 29851, - 29988, 29851, 29848, 29669, 29613, 29620, 15278, 15423, 15322, 11258, 11287, 11495, 11399, - 11405, 11411, 11411, 11405, 11688, 11355, 11479, 11123, 13028, 13110, 13242, 13110, 13300, - 13330, 12477, 12557, 12275, 18044, 17925, 17841, 18051, 17925, 18044, 21326, 21253, 21182, - 20312, 20173, 20262, 20262, 20173, 20223, 19387, 19395, 19629, 21513, 21253, 21326, 21482, - 21253, 21513, 21482, 21513, 21577, 21482, 21577, 21663, 21577, 21656, 21663, 26224, 25973, - 26261, 28622, 28450, 28512, 28849, 28688, 28514, 29480, 29105, 29013, 30024, 30095, 29992, - 30224, 30095, 30024, 30040, 30096, 30249, 12142, 12049, 12208, 12045, 12060, 12163, 11859, - 12060, 12045, 11974, 12032, 11932, 11821, 12007, 11891, 11821, 11567, 11724, 17317, 17508, - 17523, 11850, 11910, 11917, 11850, 11917, 11980, 11908, 11821, 11724, 23426, 23506, 23554, - 22437, 22446, 22580, 24036, 23905, 24013, 24036, 24013, 24049, 22056, 22084, 21934, 21934, - 22084, 22009, 30233, 30320, 30212, 26937, 26991, 27129, 26768, 26873, 26860, 27065, 26873, - 26768, 12783, 12742, 13011, 13623, 13299, 13779, 13246, 13064, 13011, 13547, 13299, 13623, - 13110, 13330, 13242, 14324, 14467, 14400, 15212, 15278, 15322, 16345, 16549, 16528, 15976, - 15475, 15423, 28162, 28336, 27970, 28580, 28336, 28786, 21781, 21656, 21881, 30320, 30293, - 30162, 11633, 11557, 11658, 11511, 11329, 11657, 11576, 11557, 11633, 11908, 11974, 11932, - 23990, 24206, 24048, 24109, 24206, 23990, 24273, 24206, 24139, 18762, 18862, 18955, 18750, - 18862, 18762, 11123, 11479, 11321, 19961, 20111, 20223, 18051, 18310, 18957, 30466, 30182, - 30006, 30258, 30311, 30126, 14629, 14661, 14324, 15212, 15210, 15278, 26791, 26727, 26619, - 26388, 26382, 26384, 28530, 28622, 28512, 27538, 27350, 27356, 29673, 29542, 29610, 30293, - 30251, 30162, 30258, 30126, 30174, 12269, 12222, 12372, 12179, 12222, 12269, 12078, 12210, - 12060, 24641, 24614, 24354, 25456, 25635, 25390, 25234, 25283, 25207, 27065, 26895, 26873, - 28688, 28816, 28650, 28864, 28816, 28849, 11910, 11767, 12301, 11744, 11767, 11910, 23905, - 23721, 23821, 23840, 23721, 23905, 29799, 29781, 29610, 29990, 29781, 29799, 30032, 29644, - 29929, 13299, 13215, 13320, 13098, 13215, 13299, 17523, 17508, 17542, 18957, 18915, 19004, - 16860, 16706, 16700, 16087, 16030, 16031, 17051, 17004, 17071, 17051, 17071, 17292, 25034, - 24765, 24761, 24718, 24765, 25089, 30251, 30312, 30087, 12275, 12557, 12372, 13649, 13623, - 13693, 25195, 25234, 25207, 26727, 26655, 26514, 11821, 11908, 11932, 12009, 12078, 12060, - 11821, 11891, 11567, 19237, 19169, 19124, 19221, 19169, 19237, 29781, 29673, 29610, 29593, - 29669, 29620, 30277, 30096, 30150, 30095, 30091, 29978, 12101, 12078, 12009, 24765, 24505, - 24554, 11560, 11576, 11633, 11323, 11329, 11511, 29944, 30053, 29838, 29940, 29461, 29844, - 14370, 14266, 14530, 14370, 14530, 14589, 14370, 14589, 14465, 27356, 27258, 27076, 26791, - 26937, 26727, 26775, 26613, 26655, 28507, 28190, 28450, 14465, 14589, 14639, 21899, 22029, - 22229, 22029, 22152, 22229, 27350, 27258, 27356, 30416, 30258, 30174, 16030, 15730, 15813, - 14545, 14465, 14639, 16030, 16115, 16031, 12049, 11936, 12066, 11950, 11936, 12049, 11950, - 12049, 12142, 13215, 13087, 13246, 13098, 13087, 13215, 13028, 13242, 12920, 14213, 14160, - 13400, 12784, 13076, 12902, 17523, 17542, 17798, 24206, 24273, 24354, 23746, 23752, 23648, - 11355, 11380, 11432, 10867, 11165, 11650, 11186, 11380, 11355, 22446, 22354, 22408, 16345, - 16528, 16700, 16083, 16211, 16300, 16246, 16435, 16424, 16424, 16435, 16525, 15611, 15976, - 15423, 17759, 18061, 17757, 17918, 17759, 17878, 17354, 17127, 16664, 23305, 22580, 23111, - 23721, 23426, 23554, 23840, 23426, 23721, 11767, 11655, 12301, 11647, 11744, 11636, 23263, - 22269, 23015, 26895, 27018, 26860, 27803, 27832, 27463, 27463, 27832, 27318, 26895, 26860, - 26873, 27803, 27463, 27749, 30322, 30091, 30095, 11253, 11180, 11425, 11219, 11175, 11387, - 11288, 11125, 11258, 11258, 11197, 11287, 11287, 11131, 11318, 11126, 11180, 11253, 11126, - 11253, 11163, 11253, 11273, 11163, 11180, 11127, 11219, 29844, 29461, 29613, 30045, 30053, - 29944, 30416, 30357, 30258, 11163, 11273, 11056, 11127, 11171, 11219, 30309, 30368, 30198, - 30281, 30432, 30219, 30219, 30388, 30233, 30233, 30388, 30320, 30320, 30407, 30293, 30293, - 30407, 30251, 30251, 30413, 30312, 30406, 30309, 30205, 30406, 30097, 30434, 30434, 30054, - 30360, 30394, 30277, 30150, 30143, 30224, 30024, 30394, 30150, 30312, 11171, 11175, 11219, - 11936, 11850, 11980, 12357, 12333, 12585, 11936, 11877, 11850, 12543, 12585, 12742, 17838, - 17841, 17925, 24388, 24036, 24154, 23866, 24109, 23990, 24892, 24989, 24930, 25234, 25310, - 25390, 24910, 24989, 24892, 24400, 24354, 24273, 27129, 26991, 27059, 26126, 25987, 25850, - 30390, 30368, 30309, 11505, 11672, 11557, 11380, 11399, 11411, 11186, 11399, 11380, 12101, - 12179, 12210, 12275, 12481, 12477, 12101, 12210, 12078, 23296, 23111, 23258, 29480, 29013, - 29726, 29381, 29593, 29247, 11066, 11163, 11056, 16246, 16322, 16300, 24989, 25195, 25207, - 11175, 11125, 11288, 13087, 13064, 13246, 13031, 13064, 13087, 30368, 30432, 30281, 12117, - 12101, 11994, 12925, 12783, 13011, 17115, 17051, 17292, 16467, 16345, 16700, 16810, 17051, - 17115, 29484, 29505, 29381, 30114, 29988, 29940, 13042, 13098, 12938, 13908, 13649, 13942, - 20506, 21119, 21182, 20506, 20946, 20644, 21381, 21253, 21482, 21381, 21482, 21474, 30360, - 30054, 30311, 23015, 22269, 22227, 21603, 21764, 21452, 11370, 11505, 11557, 11308, 11505, - 11370, 30045, 29944, 29988, 11125, 11197, 11258, 20693, 21204, 20474, 26613, 26541, 26655, - 26396, 26382, 26388, 25938, 25771, 25794, 30432, 30388, 30219, 11647, 11655, 11767, 11647, - 11767, 11744, 18750, 18907, 18862, 17878, 17759, 17680, 11482, 11950, 11450, 11443, 11560, - 11655, 24236, 24400, 24273, 18862, 18907, 19018, 21467, 21603, 21204, 18750, 18762, 18489, - 12559, 12543, 12742, 24109, 24139, 24206, 23746, 23866, 23752, 23928, 23866, 23746, 23426, - 23296, 23258, 23330, 23296, 23426, 22060, 22227, 22084, 19629, 19395, 19934, 18051, 18044, - 18146, 22056, 22060, 22084, 21952, 22060, 22056, 30277, 30249, 30096, 30403, 30249, 30497, - 20173, 19961, 20223, 21663, 21656, 21781, 21663, 21781, 21899, 30357, 30360, 30311, 30357, - 30311, 30258, 24092, 24139, 24109, 12771, 12761, 12783, 12783, 12761, 12742, 13219, 13299, - 13547, 26382, 26224, 26261, 26295, 26224, 26382, 28606, 28507, 28450, 28606, 28450, 28622, - 11197, 11131, 11287, 12925, 13011, 13064, 26775, 26655, 26727, 28816, 28864, 28767, 28849, - 28816, 28688, 28849, 28514, 28580, 30416, 30174, 30539, 30114, 30045, 29988, 30114, 29940, - 30047, 30492, 30407, 30320, 27350, 27450, 27258, 27297, 27129, 27076, 26877, 26775, 26727, - 27601, 27954, 27765, 16435, 16577, 16664, 16517, 16577, 16457, 24989, 25135, 25195, 24845, - 24910, 24614, 24845, 24614, 24641, 25099, 25135, 24989, 25195, 25243, 25234, 27105, 27018, - 26895, 27165, 27340, 27954, 12101, 12117, 12179, 12147, 12372, 12222, 12477, 12481, 12908, - 12009, 12060, 11859, 11724, 11974, 11908, 14545, 14746, 14543, 14370, 14008, 14266, 13305, - 13515, 13297, 16706, 16860, 16810, 15670, 15577, 15730, 21204, 21603, 21452, 24505, 24388, - 24154, 24036, 23840, 23905, 24765, 24718, 24505, 25652, 25258, 25482, 25167, 25243, 25195, - 29505, 29593, 29381, 29361, 29484, 29381, 29480, 29484, 29361, 30407, 30413, 30251, 30416, - 30539, 30456, 17933, 17838, 17925, 17115, 17292, 17149, 16810, 16860, 17004, 19113, 19124, - 19169, 17547, 17695, 17601, 18489, 18628, 18061, 23263, 23712, 23648, 23866, 23977, 24109, - 11655, 11560, 11633, 11744, 11910, 11636, 15577, 15538, 15730, 14543, 14746, 14682, 27297, - 27076, 27258, 27105, 27070, 27018, 27018, 27070, 26905, 25825, 25850, 25635, 28659, 28150, - 28501, 27471, 27463, 27403, 11597, 11861, 11751, 17457, 17547, 17354, 26775, 26491, 26613, - 26613, 26491, 26388, 11859, 12045, 11974, 12147, 12222, 12179, 16056, 16211, 16083, 16056, - 16083, 15976, 15911, 15976, 15824, 29484, 29593, 29505, 21937, 21663, 21899, 30413, 30369, - 30312, 12468, 12784, 12902, 13110, 13156, 13300, 19387, 19221, 19237, 19288, 19221, 19387, - 25897, 25825, 25635, 28580, 28514, 28336, 29239, 28873, 28921, 13098, 13031, 13087, 13042, - 13031, 13098, 12920, 13242, 13076, 28684, 28606, 28622, 27954, 27340, 27885, 11505, 11323, - 11511, 11066, 11126, 11163, 11308, 11323, 11505, 13239, 13765, 13300, 15113, 15210, 15212, - 17957, 18061, 17918, 19183, 19597, 19427, 30091, 30032, 29929, 29766, 29663, 29673, 30327, - 30032, 30091, 30224, 30143, 30387, 30466, 30006, 30053, 29844, 29613, 29669, 21603, 21719, - 21764, 24092, 23977, 24035, 30369, 30394, 30312, 30191, 30053, 30045, 11950, 11877, 11936, - 11769, 11877, 11950, 11759, 11877, 11769, 12357, 12585, 12543, 11724, 11859, 11974, 12761, - 12559, 12742, 12590, 12559, 12761, 29673, 29663, 29176, 29766, 29673, 29781, 14959, 15212, - 14889, 26491, 26396, 26388, 25938, 25823, 26053, 26564, 26396, 26679, 19221, 19113, 19169, - 19201, 19113, 19221, 22446, 22362, 22354, 22437, 22362, 22446, 11636, 11910, 11850, 11370, - 11557, 11576, 17838, 17798, 17841, 17871, 17798, 17838, 18957, 18310, 18915, 23763, 23840, - 24106, 22645, 22437, 22580, 29923, 29844, 29669, 30032, 29990, 29826, 13649, 13515, 13547, - 13908, 14541, 14266, 12071, 12147, 12179, 12071, 12179, 12117, 11994, 12101, 12009, 13031, - 12925, 13064, 12815, 12925, 13031, 13036, 13156, 13110, 12784, 12920, 13076, 12863, 12920, - 12784, 12863, 12784, 12745, 15825, 15730, 16030, 16810, 17004, 17051, 16345, 16276, 16031, - 27634, 27538, 27601, 28530, 29352, 28906, 12147, 12275, 12372, 17292, 17317, 17274, 24641, - 24354, 24400, 24910, 25099, 24989, 25167, 25310, 25243, 25243, 25310, 25234, 24641, 24400, - 24592, 12721, 12771, 12783, 25938, 26053, 26035, 30300, 29766, 29781, 29844, 30047, 29940, - 30114, 30191, 30045, 11171, 11060, 11175, 11175, 11037, 11125, 11125, 11107, 11197, 11197, - 11107, 11131, 11127, 11062, 11171, 11180, 11062, 11127, 11066, 11062, 11180, 11066, 11180, - 11126, 11273, 11299, 11056, 11056, 10828, 10969, 13036, 13110, 13028, 16467, 16276, 16345, - 16211, 16246, 16300, 17457, 17680, 17547, 16056, 16246, 16211, 20506, 21182, 20946, 20173, - 20154, 19961, 19487, 19365, 19387, 21182, 21253, 20946, 25167, 25195, 25135, 30406, 30480, - 30390, 30390, 30681, 30368, 30625, 30388, 30681, 30625, 30492, 30388, 30388, 30492, 30320, - 30407, 30512, 30413, 30413, 30512, 30369, 30369, 30512, 30394, 30434, 30480, 30406, 30680, - 30480, 30846, 30618, 30434, 30360, 30519, 30360, 30357, 11062, 11060, 11171, 11796, 11994, - 12009, 17274, 17317, 17523, 21571, 21482, 21663, 23305, 23111, 23296, 24718, 24573, 24505, - 24617, 24573, 24718, 24236, 24273, 24139, 30403, 30143, 30249, 30032, 30227, 29990, 11056, - 11299, 10828, 11060, 11037, 11175, 13515, 13419, 13547, 14668, 14959, 14889, 26877, 26727, - 26937, 26035, 26053, 26224, 20506, 20312, 20262, 16276, 16087, 16031, 15423, 15447, 15611, - 15911, 16056, 15976, 20312, 20154, 20173, 11481, 11576, 11560, 11323, 11286, 11329, 13400, - 14160, 13765, 14668, 14885, 14959, 17233, 17274, 17523, 24573, 24388, 24505, 27538, 27450, - 27350, 27129, 27127, 26937, 27515, 27450, 27538, 27885, 28126, 27954, 27070, 27471, 27268, - 27236, 27471, 27070, 11418, 11597, 11140, 11675, 11796, 11859, 11828, 11960, 11994, 11785, - 11650, 11165, 14213, 14324, 14400, 18051, 17933, 17925, 17798, 17643, 17523, 17783, 17933, - 18051, 17878, 17957, 17918, 17793, 17957, 17878, 17680, 17759, 17547, 27450, 27331, 27258, - 11037, 11107, 11125, 11048, 11123, 11321, 12745, 12784, 12468, 12941, 13036, 13028, 16517, - 16664, 16577, 25089, 24765, 25034, 26035, 26224, 26295, 14008, 13908, 14266, 13305, 13324, - 13419, 14407, 14370, 14465, 14492, 14407, 14465, 14492, 14465, 14545, 27331, 27297, 27258, - 28528, 28507, 28606, 29121, 28580, 29012, 27755, 27749, 27463, 14959, 15091, 15212, 14885, - 15091, 14959, 11443, 11481, 11560, 12925, 12721, 12783, 12989, 13098, 13299, 12941, 13028, - 12920, 13156, 13239, 13300, 28795, 28528, 28606, 28795, 28606, 28684, 28892, 28580, 29121, - 29239, 28921, 28864, 27297, 27238, 27129, 30388, 30432, 30681, 30497, 30249, 30277, 16087, - 15913, 16030, 15258, 15278, 15210, 11111, 11401, 11131, 19629, 19934, 19961, 17783, 17871, - 17933, 11877, 11759, 11850, 11647, 11593, 11655, 11769, 11950, 11609, 12532, 12543, 12559, - 14746, 15256, 14682, 14492, 14543, 14493, 27238, 27127, 27129, 27065, 27105, 26895, 28126, - 28485, 28218, 16403, 16577, 16435, 16403, 16435, 16246, 16403, 16256, 16376, 25006, 24910, - 24845, 25006, 25099, 24910, 11928, 12071, 12117, 12147, 12175, 12275, 12275, 12102, 12481, - 11960, 12117, 11994, 28855, 28864, 28849, 29484, 29670, 29593, 29593, 29885, 29669, 11208, - 11286, 11323, 11358, 11370, 11576, 15091, 15113, 15212, 14923, 15113, 15091, 18369, 18489, - 18061, 18750, 18824, 18907, 30121, 30191, 30114, 30121, 30114, 30047, 30121, 30550, 30624, - 15978, 16246, 16056, 21571, 21474, 21482, 22229, 22152, 22362, 11928, 11960, 11828, 18793, - 18824, 18750, 26126, 26617, 25987, 19365, 19288, 19387, 19360, 19288, 19365, 22208, 22229, - 22357, 22144, 22229, 22208, 30481, 30277, 30394, 30224, 30322, 30095, 11636, 11593, 11647, - 11481, 11358, 11576, 17933, 17871, 17838, 18957, 19004, 19113, 25825, 26126, 25850, 26074, - 26126, 25825, 25456, 25390, 25310, 12516, 12532, 12559, 12673, 12721, 12925, 28892, 28855, - 28849, 18018, 18141, 18061, 18018, 18061, 17957, 21758, 21571, 21663, 23646, 23330, 23426, - 23646, 23426, 23840, 30416, 30519, 30357, 30456, 30519, 30416, 11663, 11636, 11850, 17274, - 17149, 17292, 16803, 16704, 16810, 16506, 16467, 16706, 15926, 16087, 15973, 15926, 15913, - 16087, 15926, 15825, 15913, 17233, 17149, 17274, 23928, 23977, 23866, 24965, 25006, 24845, - 23928, 23746, 23712, 23015, 22227, 22060, 15113, 15258, 15210, 15115, 15258, 15113, 12590, - 12761, 12771, 11759, 11663, 11850, 30615, 30512, 30407, 11123, 11186, 11355, 11048, 11186, - 11123, 30403, 30387, 30143, 30457, 30387, 30403, 11208, 11323, 11308, 11208, 11308, 11370, - 11209, 11358, 11481, 21747, 21603, 21467, 18489, 18793, 18750, 18515, 18793, 18489, 30539, - 30174, 30182, 30313, 30047, 29844, 30604, 30322, 30224, 29990, 30300, 29781, 26775, 26817, - 26491, 26892, 26877, 26937, 11609, 11950, 11482, 24092, 24236, 24139, 30512, 30481, 30394, - 30466, 30053, 30191, 15324, 15423, 15278, 15911, 15909, 16056, 26295, 26382, 26396, 25938, - 25765, 25771, 12619, 12590, 12721, 12721, 12590, 12771, 15913, 15825, 16030, 16467, 16700, - 16706, 15681, 15824, 15976, 17680, 17793, 17878, 18141, 18369, 18061, 17650, 17793, 17680, - 28855, 29004, 28864, 29081, 29004, 28855, 11593, 11443, 11655, 11357, 11443, 11232, 11391, - 11593, 11636, 11991, 12039, 12071, 12071, 12039, 12147, 11928, 12117, 11960, 15258, 15324, - 15278, 15205, 15324, 15258, 17835, 18018, 17957, 25099, 25167, 25135, 24592, 24845, 24641, - 26397, 26295, 26396, 12035, 12175, 12147, 16704, 16706, 16810, 17354, 17547, 17601, 16403, - 16457, 16577, 16376, 16457, 16403, 25122, 25167, 25099, 13419, 13324, 13547, 12692, 12673, - 12925, 13305, 13419, 13515, 14668, 14889, 14629, 11796, 12009, 11859, 27450, 27476, 27331, - 27331, 27372, 27297, 27297, 27315, 27238, 27238, 27315, 27127, 27127, 26892, 26937, 27634, - 27515, 27538, 27634, 27601, 27765, 10800, 11111, 11131, 19660, 19629, 19961, 21719, 21824, - 22056, 21747, 21824, 21719, 21747, 21719, 21603, 21204, 20693, 21260, 27515, 27476, 27450, - 27840, 27765, 27954, 27698, 27634, 27765, 11206, 11208, 11370, 10969, 11066, 11056, 11286, - 11208, 11206, 11609, 11663, 11759, 17354, 16664, 16517, 23977, 24092, 24109, 24438, 24592, - 24400, 23928, 23712, 23818, 27476, 27372, 27331, 27749, 27755, 27803, 28580, 28892, 28849, - 27471, 27755, 27463, 27675, 27755, 27471, 27236, 27070, 27105, 18237, 18369, 18141, 24573, - 24617, 24388, 23763, 23646, 23840, 25652, 25482, 25771, 24438, 24400, 24236, 27890, 27840, - 27954, 25445, 25456, 25310, 11066, 10958, 11062, 11062, 10945, 11060, 11060, 10945, 11037, - 11037, 10613, 11107, 11107, 10800, 11131, 10969, 10958, 11066, 11537, 11329, 10751, 21824, - 21952, 22056, 13324, 13219, 13547, 14543, 14492, 14545, 14166, 14008, 14370, 13192, 13219, - 13324, 13104, 12989, 13219, 14682, 15256, 14695, 27120, 27236, 27105, 27120, 27105, 27065, - 28128, 27890, 27954, 11155, 11329, 11286, 12815, 13031, 13042, 12863, 12745, 12920, 13036, - 12941, 13156, 12468, 12908, 12481, 15825, 15670, 15730, 15723, 15670, 15825, 15611, 15681, - 15976, 15824, 15909, 15911, 15576, 15681, 15611, 29081, 28892, 29094, 12745, 12941, 12920, - 15324, 15447, 15423, 15371, 15447, 15324, 11675, 11859, 11724, 11567, 11891, 11597, 24214, - 24438, 24236, 20312, 20250, 20154, 19727, 19660, 19961, 20506, 20250, 20312, 20452, 20250, - 20506, 21253, 21381, 20946, 11111, 11048, 11321, 11418, 11567, 11597, 10800, 11048, 11111, - 11405, 10867, 11650, 12590, 12516, 12559, 12532, 12357, 12543, 11769, 11609, 11759, 12405, - 12516, 12590, 12118, 12468, 12481, 15973, 16087, 16079, 15919, 15909, 15749, 17871, 17643, - 17798, 16803, 16810, 17115, 17783, 17643, 17871, 19201, 19221, 19288, 17793, 17835, 17957, - 18152, 18237, 18141, 17549, 17650, 17680, 17549, 17680, 17457, 19629, 19487, 19387, 19361, - 19487, 19463, 23818, 23712, 23263, 24092, 24214, 24236, 30481, 30497, 30277, 30421, 30327, - 30322, 15506, 15538, 15577, 14923, 15115, 15113, 18369, 18515, 18489, 18152, 18141, 18018, - 28126, 27885, 28485, 11536, 11675, 11724, 17340, 17354, 17111, 12175, 12077, 12275, 12039, - 12035, 12147, 11991, 12035, 12039, 11991, 12071, 11928, 11828, 11994, 11796, 25006, 25122, - 25099, 25167, 25445, 25310, 25075, 25122, 25006, 24965, 24845, 24592, 30492, 30615, 30407, - 30512, 30630, 30481, 30481, 30639, 30497, 30681, 30432, 30368, 30680, 30390, 30480, 30618, - 30360, 30519, 24924, 24965, 24592, 29480, 29640, 29484, 29726, 29640, 29480, 29239, 28864, - 29004, 19487, 19360, 19365, 19361, 19360, 19487, 22229, 22144, 21899, 21571, 21413, 21474, - 22229, 22362, 22357, 15610, 15506, 15577, 15610, 15577, 15670, 15681, 15656, 15824, 15447, - 15530, 15611, 15371, 15530, 15447, 27073, 27065, 26768, 25897, 26074, 25825, 25897, 25635, - 25710, 28530, 28674, 29352, 28218, 28128, 28126, 28836, 28795, 28906, 26877, 26817, 26775, - 27282, 26892, 27127, 15742, 15723, 15825, 30625, 30615, 30492, 30708, 30618, 30519, 30708, - 30519, 30456, 11627, 11828, 11796, 18272, 18515, 18369, 19131, 18907, 19047, 25428, 25445, - 25167, 30322, 30327, 30091, 30457, 30224, 30387, 15115, 15205, 15258, 11206, 11155, 11286, - 11206, 11370, 11209, 11567, 11536, 11724, 11405, 11399, 10867, 17650, 17835, 17793, 18571, - 18698, 18515, 17577, 17835, 17650, 23840, 24036, 24106, 22357, 22362, 22437, 22144, 21937, - 21899, 23369, 23296, 23330, 26892, 26817, 26877, 25765, 25938, 26149, 11443, 11357, 11481, - 11232, 11443, 11593, 17354, 17549, 17457, 23487, 23369, 23330, 12516, 12357, 12532, 12334, - 12357, 12516, 12619, 12721, 12673, 15926, 15742, 15825, 16079, 16087, 16276, 16079, 16276, - 16467, 29229, 29239, 29004, 27476, 27492, 27372, 27372, 27315, 27297, 26892, 26911, 26817, - 27515, 27529, 27476, 27745, 27529, 27515, 27745, 27515, 27634, 27698, 27765, 27848, 27765, - 27840, 27848, 14720, 14695, 15256, 15723, 15610, 15670, 15742, 15610, 15723, 27529, 27492, - 27476, 27848, 27840, 27949, 11663, 11530, 11636, 11601, 11609, 11482, 12746, 13239, 13156, - 13893, 14540, 14324, 14324, 14540, 14629, 15011, 15159, 15115, 15115, 15159, 15205, 13275, - 13239, 12660, 13156, 12941, 12746, 19360, 19201, 19288, 19240, 19201, 19360, 27949, 27840, - 27890, 28128, 27954, 28126, 29815, 29885, 29593, 30327, 30296, 30032, 28674, 29021, 29716, - 30352, 30296, 30327, 30886, 30466, 30894, 30783, 30466, 30886, 30615, 30630, 30512, 30647, - 30457, 30403, 12989, 12938, 13098, 12989, 13299, 13219, 14492, 14379, 14407, 14493, 14379, - 14492, 14493, 14543, 14682, 27492, 27315, 27372, 12035, 12077, 12175, 11792, 11991, 11928, - 11882, 11991, 11792, 11571, 11796, 11675, 16803, 17115, 17149, 18840, 18824, 18793, 21824, - 21844, 21952, 23889, 23818, 23444, 17070, 16803, 17149, 17585, 17783, 17689, 24035, 24214, - 24092, 24808, 24924, 24592, 23818, 23263, 23444, 17233, 17523, 17643, 29640, 29670, 29484, - 29726, 29670, 29640, 22645, 22357, 22437, 23646, 23487, 23330, 23341, 23487, 23457, 23305, - 23296, 23369, 22091, 21937, 22144, 30647, 30403, 30497, 11339, 11536, 11212, 29885, 29923, - 29669, 30078, 29923, 29885, 13819, 14324, 14213, 27236, 27675, 27471, 27167, 27120, 27073, - 27885, 28507, 28485, 11209, 11370, 11358, 10798, 10940, 10969, 15955, 16079, 16063, 15816, - 15742, 15926, 18515, 18698, 18793, 18272, 18369, 18237, 19047, 18907, 18824, 21747, 21844, - 21824, 30611, 30421, 30322, 30630, 30639, 30481, 12692, 12619, 12673, 12938, 12815, 13042, - 12850, 12815, 12938, 15576, 15656, 15681, 15909, 15919, 16056, 16457, 16376, 16517, 17354, - 17577, 17549, 15576, 15611, 15530, 15371, 15324, 15205, 25710, 25635, 25456, 26320, 26617, - 26126, 28795, 28836, 28528, 29021, 29663, 29716, 11357, 11209, 11481, 11232, 11209, 11357, - 18152, 18272, 18237, 18152, 18018, 17835, 14720, 15256, 14903, 14540, 14668, 14629, 28720, - 28507, 28528, 22177, 22144, 22208, 30639, 30653, 30497, 30466, 30539, 30182, 10958, 10945, - 11062, 10969, 10940, 10958, 11090, 11329, 11155, 10940, 10945, 10958, 13515, 13649, 13297, - 14923, 15091, 14885, 15749, 15909, 15824, 17222, 17233, 17643, 25765, 25652, 25771, 23341, - 23369, 23487, 26422, 26035, 26295, 30846, 30480, 30434, 30625, 30769, 30615, 30615, 30755, - 30630, 30630, 30688, 30639, 30639, 30688, 30653, 30846, 30434, 30618, 17783, 17667, 17643, - 17603, 17667, 17783, 13297, 13649, 13644, 30911, 30681, 30390, 12815, 12692, 12925, 12670, - 12692, 12815, 25897, 26117, 26074, 28789, 28720, 28528, 29716, 29663, 29769, 16704, 16506, - 16706, 16734, 16506, 16704, 16734, 16704, 16803, 23341, 23305, 23369, 24538, 24388, 24617, - 25652, 25089, 25034, 11934, 12077, 12035, 12468, 12373, 12745, 12102, 12077, 11934, 16256, - 16403, 16246, 11023, 11090, 11155, 11023, 11155, 11206, 11609, 11530, 11663, 11601, 11530, - 11609, 12142, 11450, 11950, 12333, 12357, 11820, 15867, 15926, 15973, 14903, 15256, 15122, - 15867, 15973, 16079, 15919, 15978, 16056, 15656, 15749, 15824, 15634, 15749, 15656, 24035, - 23977, 23928, 24965, 25075, 25006, 25330, 25428, 25167, 25445, 25547, 25456, 25897, 26005, - 26117, 24808, 24592, 24732, 26564, 26397, 26396, 26396, 26491, 26828, 28789, 28528, 28836, - 13305, 13192, 13324, 12849, 12850, 12938, 25330, 25167, 25122, 19597, 20022, 19830, 21747, - 21699, 21844, 30681, 30769, 30625, 14166, 14370, 14407, 13305, 13258, 13192, 14166, 14407, - 14379, 19463, 19487, 19629, 19201, 18957, 19113, 27698, 27745, 27634, 27529, 27730, 27492, - 27730, 27282, 27315, 26828, 26491, 26817, 27848, 27745, 27698, 27949, 27745, 27848, 27949, - 27890, 28051, 30726, 30647, 30653, 30653, 30647, 30497, 30699, 30352, 30421, 14277, 14166, - 14379, 30296, 30227, 30032, 30421, 30352, 30327, 30553, 30224, 30457, 30769, 30755, 30615, - 15697, 15978, 15919, 25428, 25547, 25445, 28051, 27890, 28128, 28051, 28128, 28119, 10988, - 11023, 11206, 10708, 10798, 10969, 10988, 11206, 11019, 18698, 18840, 18793, 19597, 19444, - 20022, 18689, 18840, 18698, 13258, 13104, 13192, 13192, 13104, 13219, 15471, 15576, 15530, - 14668, 14923, 14885, 28720, 28485, 28507, 15371, 15205, 15174, 15749, 15697, 15919, 17549, - 17577, 17650, 18272, 18402, 18515, 17340, 17577, 17354, 21260, 21467, 21204, 23889, 24035, - 23818, 27205, 27301, 27236, 29094, 28892, 29121, 27205, 27236, 27120, 28222, 28128, 28218, - 17889, 18152, 17835, 19361, 19240, 19360, 22357, 22177, 22208, 22091, 22177, 22625, 23763, - 23487, 23646, 22625, 22177, 22357, 30437, 30227, 30296, 12334, 12516, 12405, 12961, 12938, - 12989, 15106, 15205, 15159, 28720, 28672, 28485, 28906, 28789, 28836, 14695, 14493, 14682, - 14480, 14493, 14695, 27167, 27205, 27120, 25652, 25641, 25089, 26149, 25938, 26035, 11240, - 11232, 11593, 12509, 12619, 12692, 11536, 11571, 11675, 11453, 11571, 11339, 11536, 11567, - 11212, 18238, 18402, 18272, 14923, 15011, 15115, 24924, 25075, 24965, 25553, 25710, 25547, - 24808, 25075, 24924, 29239, 29726, 29013, 29670, 29815, 29593, 30539, 30708, 30456, 30664, - 30708, 30539, 30664, 30539, 30783, 12077, 12102, 12275, 11882, 12035, 11991, 16376, 16372, - 16517, 15978, 16256, 16246, 16372, 16256, 16169, 25089, 24796, 24718, 24962, 24796, 24985, - 24732, 24592, 24438, 29726, 29815, 29670, 12850, 12670, 12815, 12734, 12670, 12850, 15576, - 15634, 15656, 15371, 15382, 15530, 15174, 15382, 15371, 24538, 24036, 24388, 15471, 15634, - 15576, 28892, 29081, 28855, 29839, 29755, 29726, 29094, 29167, 29162, 11439, 11636, 11530, - 13644, 13649, 13908, 13041, 12961, 12989, 19727, 19961, 19863, 19361, 19463, 19240, 19961, - 20154, 19863, 21758, 21663, 21937, 21867, 21758, 21937, 22645, 22580, 23061, 23763, 23457, - 23487, 28404, 28305, 28218, 28404, 28218, 28485, 24638, 24732, 24438, 23818, 24035, 23928, - 22060, 22039, 23015, 29923, 30078, 29844, 30335, 30078, 29885, 17233, 17070, 17149, 15955, - 15867, 16079, 17195, 17070, 17233, 30647, 30652, 30457, 30352, 30437, 30296, 30718, 30652, - 30647, 13041, 12989, 13104, 15011, 15106, 15159, 26397, 26422, 26295, 26911, 26892, 27017, - 28956, 28672, 28720, 21960, 21867, 21937, 21960, 21937, 22091, 30598, 30437, 30352, 30227, - 30300, 29990, 31102, 30688, 30630, 12405, 12590, 12619, 25547, 25710, 25456, 26320, 26126, - 26074, 25553, 25547, 25428, 13297, 13258, 13305, 15538, 15506, 15122, 27282, 27127, 27315, - 28461, 28404, 28485, 17487, 17222, 17643, 17195, 17222, 17352, 15382, 15471, 15530, 15634, - 15697, 15749, 15437, 15471, 15382, 19240, 18957, 19201, 19341, 18957, 19240, 18840, 19047, - 18824, 18689, 19047, 18840, 30652, 30553, 30457, 30690, 30553, 30652, 22091, 22144, 22177, - 30790, 30664, 30783, 10940, 10798, 10945, 10393, 10800, 11107, 10828, 11537, 10751, 14008, - 13644, 13908, 13297, 13089, 13258, 14166, 14156, 14008, 14249, 14156, 14166, 14277, 14379, - 14383, 20946, 21381, 21101, 21381, 21474, 21413, 21571, 21758, 21413, 12432, 12405, 12619, - 12961, 12849, 12938, 12687, 12849, 12961, 15106, 15174, 15205, 26564, 26422, 26397, 26645, - 26422, 26564, 26911, 26828, 26817, 28591, 28461, 28485, 12509, 12692, 12591, 15437, 15697, - 15634, 29081, 29229, 29004, 29162, 29229, 29081, 11792, 11928, 11828, 21413, 21758, 21789, - 11847, 11934, 12035, 12102, 12118, 12481, 16256, 16372, 16376, 16329, 16372, 16289, 18507, - 18571, 18515, 18507, 18515, 18402, 18238, 18272, 18152, 11623, 11792, 11828, 13526, 13644, - 13758, 14383, 14379, 14493, 28051, 28070, 27949, 27949, 28040, 27745, 27730, 27315, 27492, - 26911, 27024, 26828, 28119, 28070, 28051, 28119, 28128, 28222, 28218, 28305, 28222, 31059, - 30846, 30618, 30680, 30911, 30390, 30681, 31025, 30769, 30769, 31025, 30755, 31296, 30786, - 30688, 31059, 30618, 30708, 10887, 11399, 11186, 11515, 11627, 11796, 10887, 11186, 10803, - 11601, 11439, 11530, 11482, 11439, 11601, 11929, 12118, 12102, 17889, 18238, 18152, 17475, - 17835, 17577, 19660, 19463, 19629, 19635, 19463, 19660, 30688, 30726, 30653, 30786, 30726, - 30688, 14480, 14383, 14493, 27730, 27529, 27745, 28222, 28305, 28286, 30553, 30604, 30224, - 30692, 30604, 30553, 11515, 11796, 11571, 17070, 16998, 16803, 16969, 16998, 17070, 24808, - 24818, 25075, 25651, 25553, 25428, 24638, 24438, 24497, 13258, 13041, 13104, 12937, 13041, - 12950, 15122, 15506, 15354, 14582, 14480, 14695, 15506, 15610, 15354, 25931, 26005, 25897, - 25717, 25553, 25625, 12591, 12692, 12670, 12734, 12850, 12849, 14582, 14695, 14720, 20693, - 20474, 20239, 21467, 21699, 21747, 25714, 25897, 25710, 27301, 27675, 27236, 27205, 27391, - 27301, 26320, 26074, 26117, 28286, 28305, 28376, 28786, 28336, 28162, 12687, 12734, 12849, - 22580, 23305, 23061, 21789, 21758, 21867, 26235, 26320, 26117, 30726, 30694, 30647, 30786, - 30694, 30726, 11453, 11515, 11571, 17603, 17643, 17667, 17222, 17195, 17233, 18238, 18507, - 18402, 18956, 19183, 19047, 24796, 24538, 24617, 23583, 23473, 23457, 24746, 24538, 24796, - 17539, 17603, 17585, 14681, 14582, 14720, 23473, 23305, 23341, 23473, 23341, 23457, 25717, - 25714, 25710, 26149, 25727, 25765, 24985, 24796, 25089, 26828, 26679, 26396, 26868, 26679, - 26828, 30437, 30353, 30227, 28956, 28720, 28789, 28757, 28591, 28672, 30500, 30353, 30556, - 21789, 21867, 21960, 17111, 17354, 16517, 18605, 18571, 18507, 11934, 11929, 12102, 11882, - 11847, 12035, 11685, 11847, 11882, 11685, 11882, 11792, 11623, 11828, 11627, 13239, 13275, - 13765, 14686, 14923, 14668, 14686, 15011, 14923, 14686, 15000, 15011, 15011, 15000, 15106, - 15106, 15000, 15174, 12373, 12941, 12745, 12373, 12468, 12090, 27282, 27017, 26892, 30263, - 29663, 29766, 10751, 11329, 11090, 10988, 11090, 11023, 29726, 29755, 29815, 29815, 30012, - 29885, 29839, 29726, 29239, 29312, 29239, 29229, 11742, 11929, 11934, 12734, 12591, 12670, - 12529, 12591, 12734, 27295, 27205, 27167, 26005, 26235, 26117, 26318, 26235, 26283, 12509, - 12432, 12619, 12405, 12296, 12334, 11317, 11482, 11241, 12320, 12432, 12509, 25714, 25931, - 25897, 11019, 11206, 10881, 11019, 10881, 10865, 11532, 11623, 11627, 16768, 16872, 16969, - 16998, 16872, 16803, 16734, 16872, 16768, 24732, 24818, 24808, 25553, 25717, 25710, 25714, - 25717, 25931, 24682, 24818, 24732, 30604, 30611, 30322, 30759, 30611, 30604, 19047, 19183, - 19131, 20022, 20693, 20239, 18689, 18698, 18571, 30694, 30718, 30647, 30828, 30718, 30694, - 10613, 11037, 10945, 15354, 15610, 15596, 14903, 14749, 14720, 19863, 20154, 20086, 19463, - 19341, 19240, 21677, 21699, 21467, 14681, 14749, 14578, 30500, 30300, 30227, 30500, 30227, - 30353, 30078, 30313, 29844, 30382, 30313, 30503, 11165, 11140, 11597, 11515, 11532, 11627, - 11092, 11140, 10667, 23583, 23457, 23657, 11453, 11532, 11515, 24497, 24438, 24214, 24497, - 24214, 24481, 27460, 27675, 27301, 17603, 17487, 17643, 17539, 17487, 17603, 17340, 17540, - 17577, 24538, 24106, 24036, 16079, 16467, 16063, 22048, 21789, 21960, 22048, 21960, 22091, - 14383, 14249, 14277, 14277, 14249, 14166, 13758, 13644, 14008, 14150, 14249, 14383, 14421, - 14383, 14480, 14421, 14480, 14582, 30718, 30690, 30652, 30844, 30690, 30718, 10988, 10889, - 11090, 10889, 11019, 10865, 18605, 18689, 18571, 18605, 18507, 18541, 26907, 26868, 26828, - 25727, 25652, 25765, 28461, 28523, 28404, 28672, 28591, 28485, 28956, 28789, 28906, 13644, - 13526, 13297, 13041, 12937, 12961, 14009, 14008, 14156, 27295, 27391, 27205, 27295, 27167, - 27366, 19727, 19635, 19660, 17539, 17365, 17487, 29537, 28956, 28906, 30664, 30790, 30708, - 30783, 30539, 30466, 11820, 12357, 12334, 11439, 11391, 11636, 11339, 11571, 11536, 12432, - 12296, 12405, 12320, 12296, 12432, 29298, 29312, 29229, 29162, 29081, 29094, 27073, 26617, - 26320, 16372, 16329, 16517, 17340, 17394, 17540, 16169, 16256, 15978, 16169, 16053, 16133, - 16133, 16370, 16289, 30690, 30692, 30553, 30598, 30353, 30437, 30844, 30692, 30690, 19635, - 19539, 19463, 22060, 21952, 22039, 10798, 10709, 10945, 10708, 10709, 10798, 13089, 13041, - 13258, 12320, 12181, 12296, 15978, 15697, 16053, 16872, 16734, 16803, 16872, 16998, 16969, - 20846, 20693, 20716, 21336, 21677, 21467, 26645, 26564, 26679, 24332, 24185, 24106, 26868, - 26720, 26679, 29755, 29877, 29815, 29951, 29877, 29755, 10328, 10708, 10969, 20644, 20452, - 20506, 19727, 19565, 19635, 19635, 19565, 19539, 20822, 20516, 20644, 20881, 20644, 20946, - 20881, 20946, 21078, 13275, 13400, 13765, 13241, 13400, 13275, 28222, 28323, 28119, 28323, - 28040, 28070, 28070, 28040, 27949, 27464, 27024, 27017, 27017, 27024, 26911, 26868, 26941, - 26720, 28376, 28305, 28404, 20516, 20452, 20644, 21101, 21381, 21413, 30960, 30911, 30967, - 30911, 30680, 30967, 18956, 19444, 19183, 18541, 18507, 18238, 11482, 11391, 11439, 17487, - 17365, 17222, 17352, 17365, 17398, 17360, 17394, 17300, 17540, 17475, 17577, 14817, 14749, - 14903, 15596, 15610, 15742, 15663, 15596, 15742, 16063, 16467, 16506, 25330, 25122, 25075, - 24638, 24682, 24732, 24659, 24682, 24638, 26235, 26318, 26320, 26283, 26235, 26005, 26529, - 26318, 26579, 12108, 12468, 12118, 15816, 15926, 15867, 29312, 29839, 29239, 28659, 28786, - 28162, 22154, 22048, 22091, 21457, 21101, 21413, 22625, 22357, 22645, 30624, 30191, 30121, - 30967, 30680, 30846, 13121, 13241, 12735, 21457, 21413, 21583, 28523, 28461, 28591, 28523, - 28376, 28404, 10803, 11186, 11048, 30692, 30759, 30604, 30806, 30759, 30692, 15174, 15437, - 15382, 14686, 14668, 14540, 26720, 26645, 26679, 26594, 26645, 26883, 28956, 28757, 28672, - 28820, 28757, 28903, 12296, 12181, 12334, 11482, 11317, 11391, 12320, 12509, 12223, 15955, - 15816, 15867, 24481, 24214, 24035, 26149, 26035, 26422, 25330, 25075, 25057, 31102, 30630, - 30755, 13139, 13089, 13297, 12223, 12509, 12591, 14749, 14681, 14720, 14817, 14903, 15122, - 22039, 21952, 21844, 27123, 27024, 27199, 23015, 23400, 23263, 24301, 24481, 24035, 28501, - 28150, 27919, 29162, 29298, 29229, 29716, 29352, 28674, 30263, 29769, 29663, 11192, 11567, - 11418, 11453, 11361, 11532, 11361, 11685, 11623, 11866, 11929, 11742, 11866, 11952, 11929, - 11929, 11952, 12118, 11192, 11418, 11140, 12814, 12961, 12937, 14249, 14009, 14156, 13526, - 13139, 13297, 14150, 14009, 14249, 17300, 17394, 17340, 16169, 16289, 16372, 16289, 16169, - 16133, 17365, 17352, 17222, 17603, 17783, 17585, 21583, 21413, 21789, 25057, 25075, 24818, - 24822, 24818, 24682, 29288, 29298, 29162, 30786, 30828, 30694, 31032, 30828, 30786, 12373, - 12746, 12941, 25604, 24985, 25089, 24962, 24932, 24796, 26645, 26588, 26422, 26594, 26588, - 26645, 27024, 26907, 26828, 11685, 11792, 11623, 12485, 12595, 12746, 29877, 30012, 29815, - 29951, 30012, 29877, 20086, 20154, 20250, 17783, 17730, 17689, 21689, 21583, 21789, 27391, - 27460, 27301, 27832, 28501, 27919, 27366, 27460, 27391, 27366, 27391, 27295, 23378, 23061, - 23305, 21808, 21689, 21789, 23378, 23305, 23473, 23457, 23763, 23657, 11019, 10889, 10988, - 10551, 10643, 10708, 11206, 11209, 10881, 30828, 30844, 30718, 30699, 30421, 30611, 31032, - 30844, 30828, 11952, 12108, 12118, 25727, 25641, 25652, 25894, 25641, 25727, 26283, 26005, - 26234, 25651, 25625, 25553, 11092, 11192, 11140, 30313, 30476, 30047, 30601, 30382, 30555, - 13089, 12950, 13041, 12922, 12950, 13089, 21699, 21795, 21844, 21336, 21467, 21260, 28757, - 28646, 28591, 28820, 28646, 28757, 11192, 11212, 11567, 11361, 11623, 11532, 19341, 19463, - 19539, 17394, 17475, 17540, 17360, 17475, 17394, 23400, 23444, 23263, 23740, 23444, 23602, - 26588, 26149, 26422, 29121, 29167, 29094, 29463, 29839, 29312, 29206, 29167, 29121, 30699, - 30611, 30806, 30300, 30263, 29766, 15354, 15265, 15122, 15178, 15265, 15354, 15178, 15354, - 15356, 27803, 28501, 27832, 14384, 14421, 14582, 14578, 14582, 14681, 21677, 21795, 21699, - 23740, 23889, 23444, 29769, 29352, 29716, 10889, 10751, 11090, 10881, 11209, 10904, 10887, - 10867, 11399, 10838, 10867, 10887, 10803, 11048, 10515, 11391, 11240, 11593, 11241, 11482, - 11450, 11221, 11317, 11241, 30550, 30121, 30047, 30806, 30611, 30759, 12950, 12814, 12937, - 12839, 12814, 12950, 28903, 28757, 28956, 27803, 28307, 28501, 19706, 19565, 19727, 11676, - 11685, 11562, 11979, 12090, 12108, 11742, 11934, 11847, 12997, 12823, 12820, 16734, 16063, - 16506, 15756, 15663, 15816, 15816, 15663, 15742, 16969, 17070, 17195, 16969, 17195, 17352, - 24985, 24932, 24962, 24882, 24932, 24976, 10688, 10803, 10404, 23657, 23763, 24106, 30382, - 30476, 30313, 30479, 30476, 30382, 19565, 19558, 19539, 11221, 11240, 11391, 17539, 17398, - 17365, 17362, 17398, 17539, 17300, 17340, 17111, 17475, 17889, 17835, 10708, 10643, 10709, - 10709, 10613, 10945, 10551, 10328, 10428, 10643, 10648, 10709, 10648, 10613, 10709, 10855, - 10881, 10770, 10690, 10751, 10889, 12814, 12687, 12961, 12575, 12687, 12814, 17323, 16969, - 17352, 20881, 20822, 20644, 20516, 20646, 20452, 20086, 19808, 19863, 19863, 19713, 19727, - 19565, 19554, 19558, 20906, 20822, 20881, 20906, 20881, 21078, 20946, 21101, 21078, 24932, - 24746, 24796, 26567, 26113, 26149, 26883, 26645, 26720, 21078, 21101, 21112, 30911, 31025, - 30681, 30967, 30846, 31059, 31022, 30708, 30790, 30699, 30598, 30352, 30500, 30574, 30300, - 28646, 28523, 28591, 28367, 28323, 28286, 28323, 28070, 28119, 27123, 26941, 26907, 26907, - 26941, 26868, 28774, 28523, 28646, 12108, 12090, 12468, 11979, 12108, 11952, 21112, 21101, - 21197, 21795, 22039, 21844, 10803, 10838, 10887, 10909, 11092, 10667, 10688, 10838, 10803, - 21689, 21457, 21583, 21197, 21101, 21257, 28323, 28222, 28286, 24497, 24659, 24638, 25330, - 25651, 25428, 24301, 24035, 23889, 14119, 14150, 14383, 12957, 12997, 12820, 14119, 14383, - 14259, 29012, 29206, 29121, 29167, 29288, 29162, 29297, 29206, 29012, 31049, 31025, 30911, - 27123, 26907, 27024, 27803, 27755, 28307, 28786, 29043, 29012, 17485, 17889, 17475, 18956, - 19047, 18689, 23493, 23378, 23473, 21808, 21789, 22048, 24185, 23657, 24106, 26318, 26529, - 26320, 26005, 25931, 26234, 28911, 29043, 28786, 30637, 30479, 30623, 30476, 30550, 30047, - 17783, 18051, 17730, 17398, 17323, 17352, 19558, 19341, 19539, 19554, 19341, 19558, 15756, - 15816, 15955, 14969, 14817, 15122, 11685, 11676, 11847, 11866, 11840, 11952, 11361, 11453, - 11045, 29440, 29312, 29298, 30012, 30190, 29885, 11676, 11742, 11847, 23493, 23473, 23583, - 30598, 30556, 30353, 30748, 30556, 30598, 30572, 30550, 30476, 30894, 30466, 30191, 30783, - 31022, 30790, 21192, 21336, 21260, 21677, 21614, 21795, 21795, 22012, 22039, 21192, 21260, - 20693, 27073, 27366, 27167, 27460, 27550, 27675, 28367, 28286, 28489, 29839, 29951, 29755, - 30966, 30806, 30692, 30699, 30748, 30598, 30915, 30806, 30966, 10855, 10831, 10881, 11317, - 11221, 11391, 11820, 12334, 12181, 17362, 17323, 17398, 17360, 17335, 17475, 17111, 16517, - 16652, 11937, 11820, 12181, 11937, 12181, 12320, 11602, 11840, 11866, 16768, 16063, 16734, - 15893, 16063, 16768, 16863, 16768, 16969, 14969, 15122, 15265, 24726, 24822, 24682, 25625, - 25830, 25717, 30046, 30030, 30012, 11823, 11979, 11952, 12485, 12746, 12375, 25454, 25651, - 25330, 15498, 15354, 15596, 15663, 15498, 15596, 15606, 15498, 15663, 29206, 29288, 29167, - 29350, 29288, 29206, 20086, 20250, 20452, 16652, 16517, 16329, 24481, 24659, 24497, 24591, - 24659, 24481, 11016, 11092, 10909, 11192, 11110, 11212, 11212, 11045, 11339, 28614, 28501, - 28474, 28839, 28911, 28786, 29043, 29157, 29012, 10831, 10889, 10865, 15163, 14969, 15265, - 14635, 14578, 14749, 19808, 19713, 19863, 22625, 22645, 23061, 23562, 23493, 23583, 23654, - 22625, 23061, 23562, 23583, 23657, 28820, 28774, 28646, 28523, 28531, 28376, 29008, 28903, - 28956, 28839, 28786, 28659, 30556, 30581, 30500, 30733, 30581, 30556, 30738, 30764, 30624, - 30620, 30572, 30476, 30620, 30476, 30479, 13139, 12997, 13089, 12687, 12529, 12734, 13758, - 14008, 13812, 14635, 14749, 14817, 26669, 27073, 26320, 28774, 28531, 28523, 19713, 19706, - 19727, 30190, 30335, 29885, 16289, 16370, 16329, 16169, 15978, 16053, 26529, 26669, 26320, - 26234, 25931, 26032, 30738, 30624, 30550, 10881, 10831, 10865, 11209, 11232, 10904, 15437, - 15634, 15471, 29288, 29440, 29298, 29463, 29440, 29462, 13812, 14008, 14009, 13812, 14009, - 13930, 13930, 14009, 14150, 12746, 12660, 13239, 13121, 13229, 13400, 13893, 14686, 14540, - 12746, 12373, 12375, 26579, 26669, 26529, 30030, 30190, 30012, 29951, 30046, 30012, 30022, - 30046, 29951, 30015, 29951, 29839, 13925, 13930, 14150, 28040, 27730, 27745, 27926, 27730, - 28040, 28367, 28040, 28323, 11831, 12373, 12090, 11840, 11823, 11952, 11626, 11823, 11840, - 11602, 11866, 11742, 11620, 11742, 11676, 12997, 12922, 13089, 12957, 12922, 12997, 13542, - 14213, 13400, 15132, 15437, 15174, 28501, 28651, 28659, 28911, 29157, 29043, 17730, 18051, - 17874, 17585, 17362, 17539, 17062, 16863, 16969, 17730, 17775, 17639, 23654, 23061, 23378, - 23641, 23562, 23657, 30668, 30738, 30550, 30637, 30620, 30479, 14259, 14383, 14421, 27489, - 27550, 27460, 28501, 28614, 28651, 27489, 27460, 27366, 30827, 30191, 30624, 17453, 17362, - 17585, 24659, 24726, 24682, 24822, 25057, 24818, 24591, 24726, 24659, 30247, 30190, 30030, - 30623, 30479, 30382, 31047, 31022, 30783, 10904, 11232, 10619, 10831, 10690, 10889, 14384, - 14259, 14421, 27611, 27489, 27366, 27550, 27777, 27799, 10643, 10551, 10648, 10648, 10519, - 10613, 10613, 10389, 11107, 10551, 10708, 10328, 10551, 10519, 10648, 20822, 20646, 20516, - 19808, 19862, 19713, 19713, 19763, 19706, 20910, 20646, 20822, 20910, 20822, 20906, 20910, - 20906, 21078, 20910, 21078, 21197, 10619, 11232, 11240, 12922, 12839, 12950, 12731, 12839, - 12922, 28489, 28286, 28376, 28881, 28774, 28820, 28881, 28820, 28903, 28651, 28839, 28659, - 28796, 28839, 28651, 30869, 30748, 30699, 30686, 30263, 30300, 30764, 30827, 30624, 30668, - 30550, 30572, 15132, 15174, 15000, 21197, 21078, 21112, 25913, 25931, 25717, 26283, 26579, - 26318, 25913, 25717, 25830, 12575, 12529, 12687, 14523, 14384, 14578, 14578, 14384, 14582, - 15178, 15163, 15265, 15356, 15163, 15178, 15356, 15354, 15498, 26275, 26579, 26283, 26669, - 26625, 27073, 11450, 12142, 12333, 11221, 11087, 11240, 13121, 13400, 13241, 28489, 28376, - 28531, 31528, 31059, 30708, 30967, 31291, 30960, 30960, 31049, 30911, 10838, 10688, 10867, - 10515, 11048, 10800, 25830, 25625, 25651, 31317, 31049, 30960, 31025, 31102, 30755, 30806, - 30915, 30699, 11092, 11110, 11192, 11016, 11110, 11092, 11562, 11620, 11676, 12448, 12660, - 12595, 12735, 13241, 13275, 14635, 14817, 14754, 20188, 20086, 20452, 21257, 21101, 21457, - 21257, 21457, 21350, 21232, 21192, 21151, 21336, 21491, 21677, 19444, 19597, 19183, 28499, - 28489, 28608, 30299, 30015, 30302, 30270, 30291, 30190, 30623, 30382, 30601, 30710, 30668, - 30572, 12595, 12660, 12746, 12090, 11979, 11895, 26789, 26149, 26588, 26149, 26113, 25727, - 25641, 25604, 25089, 26941, 26883, 26720, 27116, 26883, 26941, 29008, 28881, 28903, 28774, - 28993, 28531, 10700, 10690, 10831, 10904, 10770, 10881, 30812, 30827, 30764, 30812, 30764, - 30738, 16573, 16652, 16370, 16370, 16652, 16329, 17111, 17198, 17300, 17300, 17335, 17360, - 16177, 16370, 16133, 24813, 25057, 24822, 21350, 21457, 21689, 24304, 24301, 23889, 24726, - 24813, 24822, 23444, 23400, 23363, 23400, 23015, 23291, 30710, 30572, 30620, 23638, 23378, - 23493, 28307, 27755, 28170, 11045, 11453, 11339, 17062, 16969, 17323, 15831, 15756, 15955, - 26789, 26588, 26594, 24332, 24538, 24667, 24332, 24106, 24538, 12839, 12575, 12814, 12223, - 11937, 12320, 11191, 11133, 11241, 12731, 12575, 12839, 21192, 21491, 21336, 26883, 26789, - 26594, 26820, 26789, 26883, 28881, 28920, 28774, 29537, 29008, 28956, 29064, 29008, 29537, - 29537, 30239, 29791, 31164, 31102, 31025, 12223, 12591, 12529, 12997, 13139, 12912, 15831, - 15955, 16063, 24301, 24591, 24481, 25930, 25830, 25651, 26263, 26275, 26234, 26234, 26275, - 26283, 27464, 27017, 27282, 30574, 30500, 30581, 30190, 30291, 30335, 30270, 30190, 30247, - 17689, 17612, 17585, 17362, 17062, 17323, 18051, 18957, 17874, 20086, 19862, 19808, 19706, - 19554, 19565, 23291, 23015, 23117, 24301, 24624, 24591, 30733, 30574, 30581, 30767, 30710, - 30620, 30503, 30078, 30335, 10700, 10831, 10855, 10751, 10480, 10828, 30966, 30692, 30844, - 30748, 30733, 30556, 30827, 30894, 30191, 30886, 31047, 30783, 30859, 30894, 30827, 30812, - 30738, 30810, 13930, 13782, 13812, 13812, 13782, 13758, 12700, 12820, 12823, 13925, 13782, - 13930, 13925, 14150, 14119, 13925, 14119, 13970, 13331, 13542, 13400, 13331, 13400, 13229, - 13970, 14119, 14259, 31326, 31032, 30786, 30791, 30733, 30748, 30767, 30620, 30637, 15304, - 15356, 15498, 14754, 14817, 14969, 27550, 27489, 27595, 26032, 25931, 25913, 19862, 19763, - 19713, 14754, 14969, 14732, 13735, 13970, 14259, 11620, 11602, 11742, 11301, 11562, 11685, - 11895, 11979, 11823, 13170, 13259, 13152, 13259, 13331, 13229, 29075, 29157, 28911, 29440, - 29463, 29312, 29075, 28911, 29103, 11241, 11133, 11221, 10742, 10855, 10770, 10742, 10700, - 10855, 11191, 11241, 11142, 15756, 15606, 15663, 17178, 17198, 17111, 18541, 18689, 18605, - 25930, 26032, 25913, 29350, 29440, 29288, 30380, 30338, 30335, 11459, 11602, 11620, 16053, - 16177, 16133, 16652, 16785, 17111, 13259, 13229, 13152, 16444, 16573, 16370, 28170, 27755, - 27675, 28614, 28721, 28651, 27806, 27675, 27799, 30810, 30738, 30668, 10296, 10480, 10751, - 10742, 10770, 10695, 16662, 16785, 16652, 30915, 30932, 30699, 30954, 30932, 30915, 30890, - 30859, 30827, 31159, 31047, 30886, 27730, 27464, 27282, 28144, 27464, 27730, 28527, 28040, - 28367, 29008, 28920, 28881, 28489, 28499, 28367, 29064, 28920, 29008, 17730, 17723, 17689, - 17639, 17723, 17730, 30720, 30767, 30637, 30710, 30810, 30668, 30503, 30313, 30078, 11743, - 11895, 11823, 22154, 21808, 22048, 28608, 28489, 28531, 28307, 28474, 28501, 16785, 16985, - 17111, 30247, 30030, 30046, 30291, 30380, 30335, 30338, 30503, 30335, 30022, 29951, 30015, - 30720, 30637, 30623, 24538, 24746, 24667, 23562, 23641, 23493, 29355, 29350, 29206, 30292, - 30022, 30299, 30460, 30503, 30338, 12735, 13275, 12660, 12324, 12375, 12373, 31032, 30966, - 30844, 31081, 31220, 31108, 10656, 10751, 10690, 19633, 19554, 19706, 28993, 28608, 28531, - 30974, 30886, 30894, 31022, 31528, 30708, 30935, 30890, 30827, 30935, 30827, 30812, 23117, - 23015, 22039, 23740, 24304, 23889, 26113, 25894, 25727, 25886, 25894, 26004, 10551, 10428, - 10519, 10519, 10450, 10613, 10326, 10428, 10328, 10428, 10450, 10519, 11133, 11087, 11221, - 11450, 12333, 11820, 18005, 18238, 17889, 16985, 17178, 17111, 30408, 30380, 30291, 10376, - 10515, 10800, 11140, 11165, 10667, 18541, 18238, 18005, 30974, 30894, 31028, 11247, 11450, - 11820, 16573, 16662, 16652, 16902, 17137, 16985, 16985, 17137, 17178, 16181, 16444, 16370, - 27123, 27116, 26941, 26789, 26567, 26149, 27464, 27199, 27024, 28677, 28721, 28614, 29157, - 29297, 29012, 30022, 30015, 30299, 30270, 30408, 30291, 11602, 11626, 11840, 12138, 12324, - 12038, 11459, 11626, 11602, 11459, 11620, 11562, 16177, 16181, 16370, 15437, 16053, 15697, - 11110, 11045, 11212, 11361, 11301, 11685, 11165, 10867, 10667, 12200, 12223, 12529, 11005, - 11249, 11450, 12200, 12529, 12172, 12735, 12660, 12571, 11831, 12090, 11895, 17723, 17612, - 17689, 17639, 17612, 17723, 20086, 19817, 19862, 19862, 19817, 19763, 19763, 19643, 19706, - 20646, 20188, 20452, 19897, 20188, 20074, 20188, 20301, 20074, 21147, 20910, 21197, 21350, - 21197, 21257, 29350, 29462, 29440, 29322, 29297, 29157, 23802, 23641, 23657, 22625, 22154, - 22091, 30752, 30720, 30623, 30767, 30810, 30710, 30752, 30623, 30601, 30752, 30601, 30757, - 15520, 15529, 15606, 15606, 15529, 15498, 15356, 15082, 15163, 15520, 15606, 15756, 15831, - 16063, 15893, 29493, 29462, 29350, 10695, 10770, 10904, 10700, 10656, 10690, 17335, 17300, - 17198, 21192, 21232, 21491, 21491, 21614, 21677, 20846, 21192, 20693, 30932, 30869, 30699, - 30733, 30832, 30574, 30956, 30869, 30932, 31028, 30894, 30859, 30871, 30935, 30812, 11075, - 11087, 11133, 11075, 11133, 11191, 17137, 17335, 17198, 17137, 17198, 17178, 24185, 23802, - 23657, 24667, 24746, 24882, 24333, 24304, 23740, 24591, 24813, 24726, 25057, 25370, 25330, - 25830, 25930, 25913, 29001, 28911, 28839, 30588, 30460, 30338, 30588, 30338, 30380, 22371, - 22154, 22625, 21808, 21350, 21689, 28527, 28367, 28499, 28340, 27926, 28040, 27176, 27116, - 27199, 23291, 23363, 23400, 23298, 23363, 23291, 24759, 24813, 24591, 27199, 27116, 27123, - 27092, 27116, 27176, 27799, 27675, 27550, 28307, 28360, 28474, 28474, 28677, 28614, 27550, - 27595, 27777, 28721, 28796, 28651, 28897, 28796, 28966, 30250, 30247, 30046, 30908, 30791, - 30748, 30574, 30686, 30300, 30904, 30810, 30767, 13925, 13733, 13782, 12820, 12731, 12957, - 12957, 12731, 12922, 13838, 13970, 13735, 14523, 14578, 14635, 26625, 26669, 26579, 28235, - 28170, 27675, 31028, 30859, 30890, 21147, 21348, 21135, 31102, 31296, 30688, 31049, 31164, - 31025, 31230, 31164, 31345, 31291, 30967, 31358, 11249, 11142, 11241, 24882, 24746, 24932, - 24374, 24624, 24301, 30448, 30408, 30270, 13331, 13170, 13542, 13542, 13819, 14213, 12660, - 12448, 12571, 28427, 28360, 28307, 13526, 12974, 12912, 12595, 12485, 12448, 15383, 15304, - 15498, 28796, 28876, 28839, 28897, 28876, 28796, 29297, 29355, 29206, 30292, 30257, 30022, - 29380, 29355, 29297, 29380, 29297, 29406, 10592, 10656, 10700, 10589, 10695, 10904, 24116, - 23802, 24185, 23641, 23638, 23493, 23638, 23802, 23837, 26275, 26625, 26579, 26543, 26625, - 26275, 26095, 26234, 26032, 31021, 30871, 30810, 30555, 30382, 30503, 30555, 30503, 30554, - 17612, 17453, 17585, 17639, 17453, 17612, 17335, 17485, 17475, 17259, 17485, 17335, 30554, - 30503, 30460, 10592, 10700, 10742, 19850, 19817, 19897, 17874, 18957, 18024, 21492, 21614, - 21491, 28360, 28465, 28474, 30966, 30954, 30915, 30869, 30908, 30748, 31081, 30954, 30966, - 23363, 23445, 23444, 24304, 24374, 24301, 23352, 23445, 23363, 16053, 16181, 16177, 16738, - 16985, 16785, 16084, 16181, 16053, 16084, 16053, 15444, 25410, 25370, 25057, 25454, 25370, - 25410, 10689, 11301, 11361, 10374, 10589, 10904, 11088, 11075, 11191, 11016, 11045, 11110, - 24333, 24374, 24304, 24624, 24759, 24591, 25638, 25604, 25641, 25886, 25641, 25894, 13152, - 13229, 13121, 12448, 12485, 12281, 14732, 14969, 14875, 28876, 29001, 28839, 28897, 29001, - 28876, 24976, 24932, 24985, 24667, 24499, 24332, 31002, 30908, 30869, 30878, 30832, 30733, - 11626, 11743, 11823, 12281, 12485, 12375, 11726, 11743, 11693, 15893, 16768, 16863, 15529, - 15383, 15498, 19817, 19643, 19763, 10656, 10497, 10751, 10482, 10592, 10742, 10589, 10742, - 10695, 15304, 15082, 15356, 15520, 15383, 15529, 29355, 29493, 29350, 29492, 29493, 29355, - 30954, 30956, 30932, 31081, 30956, 30954, 31010, 31028, 30890, 30974, 31098, 30886, 31010, - 30890, 30935, 31010, 30935, 30953, 11016, 10717, 11045, 10667, 10867, 10220, 18957, 19341, - 18967, 17047, 17062, 17362, 30904, 30767, 30720, 30555, 30757, 30601, 30679, 30757, 30555, - 24786, 24759, 24624, 30588, 30554, 30460, 30247, 30448, 30270, 30527, 30448, 30247, 30250, - 30046, 30022, 13152, 13121, 12979, 12281, 12375, 12324, 23445, 23602, 23444, 24374, 24553, - 24624, 23620, 23602, 23461, 26999, 26820, 26883, 27092, 26883, 27116, 29001, 29103, 28911, - 29122, 29103, 29001, 30484, 30380, 30408, 19643, 19633, 19706, 11726, 11831, 11895, 26004, - 25894, 26113, 25454, 25930, 25651, 13733, 13758, 13782, 12731, 12576, 12575, 31190, 31098, - 30974, 31358, 30967, 31059, 31028, 31078, 30974, 30871, 30812, 30810, 10619, 11240, 11087, - 11142, 11088, 11191, 11042, 11088, 11142, 13838, 13733, 13925, 13838, 13925, 13970, 16662, - 16573, 16601, 17485, 18005, 17889, 24596, 24499, 24667, 24536, 24553, 24374, 30904, 30720, - 30752, 12038, 12324, 12373, 13735, 13617, 13614, 13596, 13819, 13542, 14686, 15132, 15000, - 13170, 13331, 13259, 28360, 28427, 28465, 28781, 28796, 28721, 28170, 28334, 28307, 27806, - 28235, 27675, 28048, 28235, 27806, 27844, 27806, 27799, 29212, 29157, 29075, 30257, 30250, - 30022, 10428, 10326, 10450, 10450, 10349, 10613, 10328, 10969, 10828, 10328, 10828, 10260, - 16181, 16318, 16444, 15444, 16053, 15437, 25370, 25454, 25330, 25410, 25057, 25399, 24786, - 24813, 24759, 31358, 31059, 31457, 10326, 10349, 10450, 13819, 13893, 14324, 27595, 27489, - 27611, 28235, 28334, 28170, 15649, 15520, 15756, 15172, 15082, 15304, 26046, 26095, 26032, - 27751, 27595, 27735, 26046, 26032, 25930, 10349, 10389, 10613, 20103, 20693, 20022, 21232, - 21312, 21491, 27176, 27199, 27291, 28598, 28474, 28465, 29103, 29212, 29075, 29254, 29212, - 29103, 16601, 16573, 16444, 24846, 24596, 24667, 25282, 24976, 24985, 25571, 24985, 25604, - 29463, 29462, 29881, 30448, 30484, 30408, 13121, 12735, 12702, 21614, 22012, 21795, 21690, - 22012, 21614, 25760, 25638, 25641, 27595, 27611, 27735, 28334, 28427, 28307, 17047, 17362, - 17453, 19247, 19341, 19554, 23802, 23638, 23641, 24289, 24185, 24332, 23602, 23630, 23740, - 23620, 23630, 23602, 10260, 10828, 10480, 20846, 21151, 21192, 12538, 12735, 12571, 24499, - 24289, 24332, 24527, 24289, 24499, 24265, 24333, 24114, 24553, 24786, 24624, 31071, 31078, - 31028, 30871, 30953, 30935, 11831, 12038, 12373, 11743, 11726, 11895, 11559, 11743, 11626, - 12402, 12538, 12571, 12580, 12538, 12500, 26206, 26004, 26113, 25886, 25760, 25641, 27092, - 26999, 26883, 12143, 12281, 12324, 11930, 12038, 11893, 21151, 21312, 21232, 28608, 28527, - 28499, 27291, 27199, 27526, 27092, 27083, 26999, 28993, 28527, 28608, 28993, 28774, 28920, - 28427, 28598, 28465, 29380, 29492, 29355, 29483, 29492, 29380, 12143, 12324, 12138, 15172, - 15304, 15383, 14754, 14523, 14635, 29122, 29001, 28897, 29290, 29322, 29212, 29212, 29322, - 29157, 10995, 11042, 11142, 10979, 11087, 11075, 11249, 11241, 11450, 17677, 17453, 17639, - 15831, 15649, 15756, 24903, 24667, 24882, 30575, 30484, 30448, 30554, 30679, 30555, 30757, - 30814, 30752, 31172, 31071, 30953, 31164, 31230, 31102, 31345, 31164, 31049, 26206, 26113, - 26340, 26118, 26046, 25930, 26263, 26543, 26275, 19579, 19247, 19554, 28598, 28677, 28474, - 10979, 11075, 11088, 10592, 10497, 10656, 14875, 14969, 15163, 17874, 17775, 17730, 17735, - 17775, 17874, 21312, 21492, 21491, 22749, 23117, 22039, 23638, 23654, 23378, 24116, 23837, - 23802, 24116, 24185, 24169, 28966, 29122, 28897, 30878, 30733, 30791, 29537, 28906, 29352, - 31014, 30791, 30908, 24169, 24185, 24289, 30665, 30679, 30554, 11337, 11459, 11562, 11337, - 11562, 11301, 11337, 11301, 11278, 16662, 16738, 16785, 16223, 16318, 16181, 10482, 10497, - 10592, 11247, 11820, 11937, 11687, 11937, 12223, 11459, 11559, 11626, 12036, 12138, 12038, - 16318, 16601, 16444, 25638, 25571, 25604, 24976, 24903, 24882, 25680, 25571, 25638, 29609, - 29462, 29493, 30250, 30391, 30247, 31081, 30966, 31220, 31070, 31002, 30869, 31071, 31028, - 31010, 31098, 31159, 30886, 31071, 31010, 30953, 10389, 10393, 11107, 10515, 10404, 10803, - 28677, 28781, 28721, 17137, 17259, 17335, 17130, 17259, 17137, 30741, 30588, 30766, 30484, - 30588, 30380, 10205, 10404, 10515, 12500, 12538, 12402, 12036, 12143, 12138, 11700, 11831, - 11726, 14438, 15132, 14686, 16084, 16223, 16181, 26263, 26234, 26095, 29492, 29609, 29493, - 29322, 29406, 29297, 29500, 29406, 29322, 26220, 26263, 26095, 11559, 11693, 11743, 16601, - 16738, 16662, 25116, 24903, 24976, 24533, 24169, 24289, 25852, 25760, 25886, 15082, 14875, - 15163, 13530, 13637, 13645, 14732, 14875, 14605, 29122, 29254, 29103, 29243, 29254, 29122, - 13735, 13637, 13733, 13733, 13637, 13758, 14523, 14754, 14732, 13819, 13718, 13893, 13893, - 13888, 14686, 13107, 13596, 13542, 13107, 13542, 13170, 27844, 27799, 27777, 27844, 28048, - 27806, 28235, 28355, 28334, 28334, 28355, 28427, 28726, 28677, 28598, 28902, 28781, 28677, - 28902, 28923, 28781, 27844, 27777, 27751, 12820, 12704, 12731, 12700, 12704, 12820, 27199, - 27464, 27526, 26340, 26113, 26567, 28781, 28966, 28796, 28923, 28966, 28781, 31091, 30869, - 30956, 31165, 31159, 31098, 31021, 30953, 30871, 10393, 10376, 10800, 15520, 15493, 15383, - 15893, 15649, 15831, 19817, 19674, 19643, 19643, 19674, 19633, 19633, 19579, 19554, 19748, - 19674, 19817, 19817, 20086, 19897, 24571, 24786, 24553, 25780, 26118, 25930, 26046, 26220, - 26095, 24536, 24374, 24333, 24536, 24333, 24420, 27751, 27777, 27595, 31165, 31098, 31190, - 17775, 17677, 17639, 17735, 17677, 17775, 30679, 30814, 30757, 30909, 30814, 30679, 24527, - 24499, 24596, 23948, 23654, 23837, 27850, 27751, 27735, 30832, 30686, 30574, 30918, 30686, - 30832, 30588, 30665, 30554, 30741, 30665, 30588, 29406, 29483, 29380, 29500, 29483, 29406, - 19674, 19579, 19633, 19247, 18967, 19341, 12704, 12576, 12731, 12622, 12576, 12704, 12538, - 12580, 12735, 13152, 13069, 13170, 12402, 12448, 12281, 14557, 14523, 14732, 11042, 10979, - 11088, 10995, 10979, 11042, 11377, 11541, 11559, 11559, 11541, 11693, 11278, 11301, 11085, - 15649, 15493, 15520, 14605, 14557, 14732, 16043, 16223, 16084, 16318, 16043, 16601, 16999, - 16902, 16491, 17665, 18005, 17485, 16932, 17130, 17137, 16902, 16985, 16738, 19335, 18967, - 19247, 18541, 18956, 18689, 19444, 20103, 20022, 18662, 18956, 18541, 24740, 24527, 24596, - 24333, 23740, 24114, 31310, 31022, 31047, 31190, 30974, 31078, 10296, 10260, 10480, 10565, - 10482, 10742, 10565, 10742, 10589, 12702, 12979, 13121, 23117, 23298, 23291, 23248, 23298, - 23117, 23352, 23298, 23248, 31050, 31021, 30810, 31200, 31190, 31229, 31081, 31091, 30956, - 30947, 30878, 30791, 31108, 31091, 31081, 11377, 11559, 11459, 11693, 11700, 11726, 16728, - 15893, 16863, 15252, 15172, 15493, 16833, 16863, 17062, 25571, 25282, 24985, 24903, 24846, - 24667, 25760, 25680, 25638, 25744, 25680, 25760, 25744, 25760, 25852, 30257, 30391, 30250, - 30404, 30391, 30257, 30742, 29769, 30263, 31291, 31317, 30960, 31232, 31047, 31159, 10349, - 10231, 10389, 10389, 10226, 10393, 10393, 10297, 10376, 10326, 10231, 10349, 10096, 10231, - 9962, 10260, 10326, 10328, 11541, 11700, 11693, 12143, 12170, 12281, 23837, 23654, 23638, - 20646, 20910, 20774, 23948, 23837, 24116, 24189, 24116, 24169, 23461, 23602, 23445, 31014, - 30908, 31002, 30814, 30904, 30752, 30944, 30904, 30989, 30781, 30679, 30665, 31237, 31232, - 31159, 31165, 31190, 31227, 16902, 16738, 16491, 24527, 24533, 24289, 25042, 24846, 24903, - 11893, 12038, 11831, 12172, 12529, 12575, 12036, 12170, 12143, 23793, 23740, 23630, 29483, - 29609, 29492, 29642, 29609, 29483, 29290, 29212, 29254, 30686, 30729, 30263, 30913, 30729, - 30686, 10436, 10565, 10589, 10464, 10751, 10497, 31456, 31317, 31291, 31230, 31301, 31102, - 10220, 10867, 10688, 10909, 10675, 11016, 23298, 23352, 23363, 23461, 23352, 23248, 31256, - 31014, 31002, 10464, 10497, 10423, 19476, 20103, 19444, 21169, 21312, 21151, 21169, 21385, - 21312, 21312, 21385, 21492, 28966, 29243, 29122, 29192, 29243, 28966, 16924, 17047, 17453, - 24536, 24571, 24553, 25399, 25057, 25274, 24420, 24571, 24536, 31317, 31345, 31049, 12912, - 13139, 13526, 12184, 12172, 12575, 27176, 27083, 27092, 27526, 27464, 28144, 27730, 27926, - 28144, 28615, 28598, 28427, 21169, 21151, 20846, 21492, 21690, 21614, 25049, 24813, 24786, - 25458, 25282, 25571, 30015, 29839, 30302, 30766, 30588, 30484, 13637, 13530, 13758, 13735, - 13733, 13838, 28048, 28165, 28235, 28050, 28152, 28048, 28050, 28048, 27844, 27850, 27844, - 27751, 11930, 12036, 12038, 12402, 12571, 12448, 12702, 13069, 12979, 11939, 12036, 11930, - 17677, 17715, 17453, 17865, 17735, 17874, 23620, 23793, 23630, 24265, 24420, 24333, 23526, - 23793, 23620, 23793, 24114, 23740, 28152, 28165, 28048, 31237, 31159, 31165, 31091, 31070, - 30869, 31178, 31070, 31091, 13735, 14259, 13617, 13596, 13718, 13819, 13284, 13718, 13596, - 25282, 25116, 24976, 24846, 24740, 24596, 30450, 30404, 30257, 11787, 11893, 11831, 27083, - 26820, 26999, 25680, 25458, 25571, 26263, 26326, 26543, 27366, 27073, 27611, 26118, 26220, - 26046, 27073, 27575, 27611, 28165, 28355, 28235, 29243, 29290, 29254, 29412, 29290, 29243, - 12700, 12622, 12704, 12628, 12622, 12700, 25852, 25886, 26097, 23352, 23461, 23445, 23248, - 23117, 23080, 24251, 24420, 24265, 24571, 24684, 24786, 30527, 30247, 30391, 10423, 10497, - 10482, 30404, 30527, 30391, 19674, 19687, 19579, 19579, 19696, 19247, 19897, 20086, 20188, - 27575, 27931, 27868, 12979, 13069, 13152, 12702, 12735, 12580, 27865, 27611, 27868, 10189, - 10297, 10393, 10376, 10205, 10515, 10460, 10506, 10667, 19850, 19748, 19817, 17865, 17715, - 17735, 31345, 31301, 31230, 12402, 12281, 12170, 13617, 14259, 13958, 14605, 14875, 14807, - 27239, 27083, 27176, 11249, 10995, 11142, 10979, 10918, 11087, 10382, 10423, 10482, 10903, - 10995, 10893, 16902, 16932, 17137, 17247, 17485, 17259, 16999, 16932, 16902, 24713, 24740, - 24793, 24849, 24684, 24571, 30729, 30590, 30263, 30785, 30590, 30729, 30918, 30832, 30878, - 30918, 30878, 31020, 15493, 15172, 15383, 15252, 15493, 15427, 10464, 10296, 10751, 10382, - 10482, 10565, 11721, 11687, 12223, 12184, 12575, 12576, 12974, 13526, 13758, 12196, 12184, - 12576, 17735, 17715, 17677, 17865, 17874, 18024, 28340, 28040, 28396, 27291, 27239, 27176, - 30947, 30791, 31014, 31326, 30966, 31032, 31086, 30947, 31116, 31227, 31237, 31165, 31306, - 31310, 31047, 31227, 31190, 31200, 31078, 31229, 31190, 19748, 19687, 19674, 24420, 24423, - 24571, 24114, 24188, 24265, 24309, 24188, 24141, 24251, 24188, 24309, 30741, 30781, 30665, - 31078, 31294, 31229, 30931, 30781, 30741, 31301, 31296, 31102, 11700, 11787, 11831, 11879, - 11939, 11930, 12235, 12402, 12170, 11615, 11787, 11700, 11362, 11700, 11541, 26220, 26326, - 26263, 25780, 25930, 25454, 31020, 30947, 31086, 11337, 11278, 11459, 11085, 11301, 10689, - 30292, 30450, 30257, 30404, 30548, 30527, 30739, 30766, 30484, 30302, 29839, 29463, 30302, - 29463, 29881, 12912, 12823, 12997, 10903, 10918, 10979, 12380, 12702, 12580, 11939, 12170, - 12036, 13614, 13645, 13735, 14807, 14875, 15082, 24793, 24740, 24846, 25282, 25198, 25116, - 25450, 25198, 25282, 30411, 30450, 30292, 30575, 30448, 30527, 31306, 31047, 31232, 31050, - 30810, 30904, 23461, 23526, 23620, 23080, 22749, 22955, 12823, 12741, 12700, 12340, 12580, - 12500, 30297, 29352, 30524, 29064, 28993, 28920, 26097, 25886, 26004, 25605, 25458, 25680, - 26203, 26004, 26206, 31306, 31232, 31413, 26567, 26789, 26820, 26243, 26326, 26220, 10503, - 10675, 10909, 10506, 10909, 10667, 20103, 20716, 20693, 30548, 30575, 30527, 18024, 18957, - 18967, 16924, 16833, 17047, 30947, 31020, 30878, 30918, 30887, 30686, 31139, 31002, 31070, - 30989, 30904, 30814, 30909, 30679, 30781, 30909, 30781, 30931, 31670, 31457, 31059, 31358, - 31456, 31291, 31317, 31459, 31345, 31345, 31705, 31301, 31301, 31740, 31296, 24188, 24251, - 24265, 24423, 24251, 24309, 31327, 31232, 31237, 31078, 31071, 31294, 10030, 10296, 10464, - 12741, 12628, 12700, 29171, 28993, 29064, 31310, 31433, 31022, 31327, 31237, 31227, 12966, - 12974, 13758, 12912, 12858, 12823, 12823, 12760, 12741, 12741, 12601, 12628, 13735, 13645, - 13637, 13530, 13645, 13532, 27918, 27844, 27850, 27918, 28050, 27844, 28152, 28297, 28165, - 28430, 28520, 28355, 28355, 28520, 28427, 27918, 27850, 27962, 27918, 27962, 28002, 31595, - 31456, 31721, 27850, 27735, 27962, 31108, 31178, 31091, 31254, 31178, 31108, 10128, 10225, - 10389, 10096, 10389, 10231, 10231, 10326, 9962, 31456, 31418, 31317, 13069, 13107, 13170, - 12297, 13107, 13069, 28358, 28355, 28165, 29529, 29412, 29243, 10698, 10619, 11087, 10995, - 10903, 10979, 10893, 10995, 11249, 24740, 24630, 24527, 24713, 24630, 24740, 30671, 30739, - 30484, 10225, 10226, 10389, 11879, 11930, 11893, 12402, 12340, 12500, 11879, 11893, 11746, - 21385, 21690, 21492, 20716, 21169, 20846, 26629, 26567, 26820, 26340, 26203, 26206, 26629, - 27144, 26773, 31418, 31459, 31317, 31296, 31326, 30786, 31472, 31326, 31602, 25410, 25653, - 25454, 26118, 26243, 26220, 25049, 25057, 24813, 25049, 24786, 24684, 30731, 30548, 30404, - 30575, 30671, 30484, 30299, 30411, 30292, 29881, 29462, 29609, 27259, 27239, 27291, 12966, - 13758, 13138, 28520, 28615, 28427, 30402, 30411, 30299, 31172, 30953, 31021, 31430, 31327, - 31227, 11278, 11377, 11459, 11394, 11377, 11085, 11721, 12223, 12200, 12461, 12576, 12622, - 14884, 14807, 15082, 13532, 13645, 13614, 29290, 29412, 29322, 29529, 29243, 29192, 26332, - 26203, 26340, 30973, 30887, 30918, 30973, 30918, 31020, 30797, 30741, 30766, 31392, 31172, - 31021, 10698, 11087, 10918, 10423, 10308, 10464, 10362, 10436, 10589, 23080, 23117, 22749, - 24188, 24114, 24141, 31178, 31139, 31070, 31209, 31139, 31178, 31050, 30904, 30944, 24251, - 24423, 24420, 23227, 23461, 23248, 19836, 19897, 19901, 19850, 19759, 19748, 19748, 19759, - 19687, 17880, 18024, 18007, 22337, 21808, 22154, 30477, 30404, 30450, 30739, 30797, 30766, - 17865, 17845, 17715, 19696, 19579, 19687, 29537, 29171, 29064, 12876, 12858, 12912, 12628, - 12461, 12622, 28615, 28726, 28598, 31381, 31220, 30966, 12235, 12340, 12402, 11746, 11893, - 11787, 15010, 14884, 15082, 15427, 15493, 15649, 15427, 15649, 15379, 16833, 17062, 17047, - 14523, 14391, 14384, 15010, 15082, 15172, 29412, 29500, 29322, 29529, 29500, 29412, 12858, - 12760, 12823, 24286, 24189, 24169, 25042, 24903, 25116, 25042, 25116, 25198, 25042, 25198, - 25138, 28726, 28902, 28677, 30774, 30671, 30575, 10297, 10189, 10376, 10132, 10189, 10393, - 11842, 12200, 12172, 11584, 11615, 11362, 19897, 19759, 19850, 21361, 21690, 21385, 26203, - 26097, 26004, 26293, 26097, 26203, 26332, 26340, 26548, 29859, 29881, 29609, 31086, 30973, - 31020, 30909, 30989, 30814, 31033, 30989, 30909, 24533, 24527, 24630, 22337, 22371, 23205, - 31220, 31295, 31108, 31116, 30947, 31014, 31349, 31295, 31220, 31430, 31227, 31200, 31172, - 31294, 31071, 31430, 31294, 31707, 23797, 22625, 23654, 30411, 30477, 30450, 30548, 30774, - 30575, 30302, 30402, 30299, 30606, 30402, 30302, 31393, 31327, 31430, 31401, 31433, 31310, - 10460, 10667, 10213, 11085, 11377, 11278, 12760, 12601, 12741, 12184, 11842, 12172, 18024, - 17961, 17865, 17880, 17961, 18024, 30989, 31050, 30944, 11377, 11394, 11541, 10717, 11016, - 10675, 25399, 25653, 25410, 25780, 25653, 25598, 10903, 10824, 10918, 10784, 10824, 10903, - 24653, 24533, 24630, 30590, 30742, 30263, 30913, 30785, 30729, 30913, 30686, 30887, 30857, - 30797, 30739, 30857, 30739, 30671, 15252, 15010, 15172, 14557, 14391, 14523, 26629, 26820, - 27144, 13532, 13426, 13530, 12974, 12876, 12912, 12858, 12737, 12760, 12760, 12570, 12601, - 14553, 14391, 14557, 14605, 14553, 14557, 28396, 28527, 28860, 28396, 28040, 28527, 27379, - 27259, 27495, 28264, 28297, 28152, 28520, 28572, 28615, 28615, 28744, 28726, 28726, 29046, - 28902, 28094, 28152, 28050, 28002, 28050, 27918, 12380, 12340, 12235, 12702, 12407, 13069, - 11618, 11746, 11787, 11618, 11787, 11615, 26548, 26340, 26567, 14605, 14807, 14734, 25680, - 25744, 25605, 24653, 24449, 24533, 26099, 25852, 26097, 24849, 25049, 24684, 27962, 27735, - 27865, 28860, 28527, 29091, 28297, 28358, 28165, 31401, 31310, 31306, 12479, 12461, 12601, - 12601, 12461, 12628, 14734, 14807, 14884, 23080, 23227, 23248, 24423, 24849, 24571, 23151, - 23227, 23080, 26773, 26610, 26629, 27259, 27291, 27495, 27575, 27868, 27611, 27865, 27735, - 27611, 28358, 28430, 28355, 31295, 31254, 31108, 31349, 31254, 31295, 13138, 13758, 13530, - 26428, 26543, 26326, 10189, 10205, 10376, 31413, 31401, 31306, 10761, 10893, 10777, 16924, - 17453, 16936, 15252, 15071, 15010, 24189, 23948, 24116, 24331, 23948, 24189, 25042, 24793, - 24846, 24533, 24286, 24169, 24369, 24849, 24423, 30731, 30774, 30548, 10506, 10503, 10909, - 10460, 10503, 10506, 10824, 10698, 10918, 10372, 10382, 10436, 10594, 10698, 10824, 10327, - 10717, 10675, 17961, 17845, 17865, 17880, 17845, 17961, 24449, 24286, 24533, 24141, 24114, - 23984, 30958, 30913, 30887, 30958, 30887, 31090, 30965, 30931, 30797, 30797, 30931, 30741, - 31605, 31392, 31050, 12966, 12876, 12974, 13718, 13888, 13893, 15444, 16043, 16084, 13284, - 13888, 13718, 12170, 11492, 12235, 13107, 13284, 13596, 26293, 26099, 26097, 26629, 26548, - 26567, 26610, 26548, 26629, 29500, 29642, 29483, 29881, 30393, 30302, 29784, 29642, 29750, - 10092, 10096, 9960, 10225, 10150, 10226, 10226, 10151, 10393, 10189, 10161, 10205, 18956, - 19476, 19444, 20103, 20579, 20716, 18904, 19476, 18956, 10096, 10128, 10389, 29192, 28966, - 28923, 28572, 28744, 28615, 10436, 10382, 10565, 9962, 10326, 9916, 10372, 10436, 10362, - 31254, 31209, 31178, 31341, 31209, 31254, 10893, 10784, 10903, 11584, 11618, 11615, 12170, - 11939, 11492, 15379, 15649, 15893, 15010, 15071, 14884, 26254, 26243, 26118, 29784, 29859, - 29609, 30774, 30857, 30671, 11687, 11247, 11937, 10893, 10761, 10784, 30402, 30477, 30411, - 31216, 31107, 30857, 30606, 30477, 30402, 31418, 31505, 31459, 31459, 31471, 31345, 31341, - 31261, 31209, 31456, 31505, 31418, 31595, 31505, 31456, 31456, 31358, 31721, 31528, 31022, - 31433, 10128, 10150, 10225, 12684, 12737, 12858, 25653, 25780, 25454, 25598, 25653, 25399, - 25274, 25057, 25049, 31393, 31413, 31232, 31510, 31528, 31433, 31393, 31232, 31327, 31505, - 31471, 31459, 31116, 31014, 31256, 10150, 10151, 10226, 10362, 10589, 10374, 10382, 10308, - 10423, 12737, 12570, 12760, 12461, 12350, 12576, 11195, 11138, 11247, 21169, 21361, 21385, - 23494, 23526, 23227, 20579, 21361, 21169, 20579, 21169, 20716, 24309, 24369, 24423, 25039, - 25274, 25049, 24141, 24369, 24309, 26243, 26428, 26326, 26322, 26428, 26243, 31209, 31261, - 31139, 31349, 31220, 31381, 16999, 17259, 17130, 31256, 31002, 31139, 31381, 30966, 31472, - 26293, 26203, 26332, 24653, 24713, 24704, 12570, 12479, 12601, 16936, 17453, 17416, 15293, - 15379, 15374, 10151, 10132, 10393, 10220, 10688, 10404, 19759, 19696, 19687, 19897, 19836, - 19759, 21147, 21197, 21350, 13426, 13202, 13530, 12966, 12840, 12876, 12876, 12684, 12858, - 12737, 12541, 12570, 12570, 12377, 12479, 13317, 13202, 13426, 13317, 13426, 13532, 13552, - 13532, 13614, 13617, 13552, 13614, 28340, 28144, 27926, 28596, 28144, 28340, 27911, 28144, - 28031, 27973, 28002, 27962, 27973, 28094, 28002, 28002, 28094, 28050, 28297, 28399, 28358, - 28358, 28535, 28430, 28430, 28572, 28520, 27973, 27962, 28028, 28421, 28399, 28297, 31510, - 31433, 31401, 31430, 31200, 31229, 31430, 31229, 31294, 13202, 13138, 13530, 28028, 27962, - 27865, 10372, 10308, 10382, 10374, 10904, 10619, 10604, 10619, 10698, 16223, 16043, 16318, - 16932, 16999, 17130, 15444, 15437, 15132, 25605, 25744, 26054, 24331, 24189, 24286, 23948, - 23853, 23654, 23924, 23853, 23948, 24630, 24713, 24653, 10594, 10604, 10698, 10594, 10824, - 10784, 13138, 13054, 12966, 15123, 15071, 15252, 13958, 14259, 14384, 15123, 15252, 15427, - 23984, 24114, 23793, 24791, 25049, 24849, 26820, 27083, 27144, 26548, 26447, 26332, 27083, - 27239, 27310, 28535, 28572, 28430, 29192, 28923, 28902, 31041, 31000, 30785, 31000, 30742, - 30590, 31090, 30887, 30973, 31090, 30973, 31110, 30931, 31033, 30909, 31486, 31294, 31172, - 30965, 31033, 30931, 30965, 30797, 31107, 31510, 31401, 31544, 12377, 12350, 12479, 12479, - 12350, 12461, 12340, 12380, 12580, 11939, 11879, 11564, 14935, 14734, 14884, 29046, 28726, - 28744, 29642, 29784, 29609, 10220, 10404, 9958, 10503, 10327, 10675, 23227, 23526, 23461, - 22039, 22012, 22749, 27240, 26625, 26543, 24713, 24793, 24704, 10132, 10161, 10189, 30477, - 30731, 30404, 31077, 30731, 30477, 10161, 10147, 10205, 26099, 26068, 25852, 26265, 26068, - 26099, 31544, 31401, 31413, 11564, 11879, 11746, 12840, 12684, 12876, 10870, 10893, 11249, - 15071, 14935, 14884, 15187, 15123, 15427, 29750, 29642, 29500, 30269, 30393, 29881, 24791, - 24849, 24369, 23845, 23984, 23793, 24417, 24331, 24286, 24417, 24286, 24449, 31318, 31050, - 30989, 31107, 30797, 30857, 17845, 17880, 17715, 18155, 18024, 18967, 11618, 11561, 11746, - 11362, 11615, 11700, 11362, 11541, 11394, 12684, 12541, 12737, 16728, 16863, 16833, 29041, - 29046, 28744, 29529, 29750, 29500, 10689, 11361, 11045, 10689, 11045, 10717, 14734, 14553, - 14605, 14606, 14553, 14734, 25458, 25450, 25282, 25389, 25450, 25506, 31392, 31021, 31050, - 31535, 31544, 31413, 10327, 10689, 10717, 25138, 24793, 25042, 24148, 24369, 24141, 26254, - 26322, 26243, 31535, 31413, 31393, 10128, 10092, 10150, 10150, 10043, 10151, 10151, 10043, - 10132, 10132, 10056, 10161, 10161, 10038, 10147, 10096, 10092, 10128, 10326, 10260, 9916, - 10314, 10308, 10372, 10314, 10372, 10362, 22749, 22012, 22705, 24130, 24078, 23984, 31261, - 31256, 31139, 31244, 31110, 31086, 31349, 31341, 31254, 31411, 31341, 31349, 31351, 31256, - 31261, 31505, 31586, 31471, 31471, 31705, 31345, 31721, 31358, 31457, 31628, 31059, 31528, - 31628, 31528, 31607, 25304, 25138, 25198, 31000, 30590, 30785, 29717, 29339, 29171, 30785, - 30913, 31143, 11963, 11842, 12184, 10652, 10744, 10761, 11721, 11842, 11795, 21147, 21350, - 21348, 22337, 22154, 22371, 26671, 26447, 26548, 27310, 27239, 27259, 31595, 31586, 31505, - 11174, 11362, 11394, 26671, 26548, 26610, 25605, 25450, 25458, 28399, 28535, 28358, 29110, - 29041, 28744, 28094, 28264, 28152, 28203, 28264, 28094, 28203, 28094, 28122, 31707, 31535, - 31393, 31607, 31528, 31588, 20301, 20188, 20646, 19836, 19696, 19759, 28122, 28094, 27973, - 28264, 28421, 28297, 31586, 31608, 31471, 10604, 10488, 10619, 10476, 10488, 10420, 23984, - 24078, 24141, 23845, 23793, 23526, 31110, 30973, 31086, 31472, 30966, 31326, 16924, 16728, - 16833, 16854, 16728, 16924, 12235, 12399, 12380, 12380, 12399, 12702, 12407, 12399, 12218, - 14273, 14318, 14391, 20074, 19995, 19897, 27635, 27291, 27526, 24539, 24417, 24449, 24331, - 23924, 23948, 24539, 24449, 24653, 28439, 28535, 28399, 10255, 10314, 10362, 9886, 10260, - 10296, 22955, 23088, 23080, 23007, 23088, 22955, 9993, 10043, 10150, 31528, 31510, 31588, - 23151, 23494, 23227, 12684, 12604, 12541, 12196, 12576, 12350, 13054, 12840, 12966, 12835, - 12840, 13054, 13058, 13054, 13138, 13058, 13138, 13202, 13317, 13532, 13552, 19995, 19901, - 19897, 31381, 31411, 31349, 31341, 31351, 31261, 31550, 31411, 31381, 31588, 31510, 31576, - 10761, 10744, 10784, 11005, 11450, 11247, 17416, 17453, 17715, 16491, 16738, 16601, 25123, - 24704, 24793, 11842, 11721, 12200, 12377, 12570, 12541, 30225, 30269, 29859, 29981, 29750, - 29966, 27379, 27310, 27259, 11002, 11005, 11247, 10043, 10056, 10132, 10147, 10025, 10205, - 11195, 11247, 11687, 11584, 11561, 11618, 11497, 11561, 11584, 26447, 26293, 26332, 26484, - 26293, 26447, 26265, 26293, 26469, 26428, 26674, 26543, 28416, 28264, 28203, 26254, 26118, - 25780, 10488, 10397, 10619, 10476, 10397, 10488, 23853, 23924, 23654, 24129, 23924, 24331, - 24539, 24331, 24417, 23831, 23845, 23526, 25740, 25598, 25610, 10030, 10464, 10308, 10230, - 10255, 10362, 11005, 10870, 11249, 23088, 23151, 23080, 24006, 24130, 23845, 23098, 23151, - 23088, 31451, 31351, 31525, 31244, 31086, 31116, 31576, 31510, 31544, 12637, 12604, 12684, - 22705, 22323, 22658, 27699, 27635, 27526, 27379, 27353, 27310, 29046, 29192, 28902, 29110, - 28744, 28572, 10346, 10374, 10619, 10621, 10594, 10784, 10621, 10784, 10744, 12205, 12196, - 12350, 22423, 22337, 23205, 10056, 10038, 10161, 19768, 19696, 19836, 26322, 26515, 26428, - 16936, 16854, 16924, 15293, 15187, 15379, 16820, 16854, 16936, 31351, 31334, 31256, 31451, - 31334, 31351, 10038, 10025, 10147, 31588, 31576, 31735, 31909, 31576, 31544, 11553, 11426, - 11687, 11553, 11687, 11721, 26293, 26265, 26099, 25450, 25304, 25198, 25123, 24772, 24704, - 26671, 26610, 26773, 25878, 26254, 25780, 26522, 26674, 26515, 27310, 27144, 27083, 27329, - 27144, 27310, 31602, 31326, 31296, 31451, 31322, 31334, 31144, 30913, 30958, 31244, 31116, - 31303, 12604, 12377, 12541, 11809, 11795, 11842, 27635, 27495, 27291, 29085, 29192, 29046, - 10200, 10230, 10362, 10397, 10346, 10619, 10392, 10346, 10397, 13391, 13317, 13552, 12840, - 12637, 12684, 12604, 12313, 12377, 31303, 31116, 31256, 25744, 25852, 26054, 26054, 25852, - 26068, 25274, 25598, 25399, 24148, 24141, 24078, 28421, 28439, 28399, 29110, 29085, 29041, - 29041, 29085, 29046, 28416, 28439, 28421, 28416, 28421, 28264, 28122, 27973, 28028, 13046, - 13058, 13202, 28028, 27865, 27868, 10420, 10488, 10604, 10652, 10621, 10744, 11963, 12184, - 12196, 15123, 14935, 15071, 14553, 14273, 14391, 13958, 14384, 14391, 14966, 14935, 15123, - 15187, 15427, 15379, 13958, 14391, 14318, 27931, 28028, 27868, 11639, 11553, 11721, 15379, - 15893, 15374, 10164, 10308, 10314, 10092, 10018, 10150, 10043, 10001, 10056, 10056, 9908, - 10038, 10038, 9908, 10025, 9962, 9960, 10096, 9958, 10404, 9851, 10316, 10327, 10503, - 10870, 10777, 10893, 10712, 10777, 10696, 10777, 10870, 10696, 11002, 11247, 11138, 11195, - 11687, 11235, 12059, 11963, 12196, 14320, 14273, 14553, 18076, 18155, 18223, 17880, 17416, - 17715, 27495, 27353, 27379, 29171, 29339, 28993, 28144, 27911, 27526, 29791, 29171, 29537, - 31334, 31322, 31256, 31483, 31341, 31411, 31670, 31059, 31628, 31799, 31721, 31966, 31595, - 31724, 31586, 31586, 31728, 31608, 31608, 31681, 31471, 31670, 31628, 31683, 31628, 31607, - 31683, 9960, 10018, 10092, 27635, 27547, 27495, 27495, 27427, 27353, 28596, 28340, 28396, - 27575, 27073, 27351, 31721, 31667, 31595, 31667, 31724, 31595, 20774, 20301, 20646, 19943, - 19901, 19995, 19943, 19821, 19901, 19901, 19821, 19836, 21348, 21350, 21778, 31724, 31728, - 31586, 31683, 31607, 31807, 10420, 10604, 10459, 23845, 24130, 23984, 24148, 24130, 24051, - 23845, 23860, 24006, 29091, 28527, 28993, 10321, 10392, 10397, 10346, 10236, 10374, 31472, - 31550, 31381, 31615, 31550, 31472, 26675, 26671, 26909, 27353, 27329, 27310, 27352, 27329, - 27353, 9941, 9993, 10150, 10153, 10213, 9709, 11553, 11456, 11426, 11795, 11639, 11721, - 11661, 11639, 11795, 12526, 12637, 12840, 12205, 12059, 12196, 13946, 13958, 14318, 26671, - 26773, 26909, 25573, 25506, 25605, 26515, 26674, 26428, 26522, 26515, 26322, 26522, 26322, - 26391, 27911, 27699, 27526, 31728, 31681, 31608, 10220, 10213, 10667, 10404, 10205, 9851, - 18155, 18007, 18024, 18076, 18007, 18155, 31322, 31303, 31256, 31235, 31090, 31110, 31504, - 31303, 31322, 31895, 31602, 31296, 31681, 31705, 31471, 31727, 31607, 31588, 11359, 11456, - 11313, 24704, 24772, 24653, 25123, 24793, 25138, 25389, 25304, 25450, 25605, 25506, 25450, - 26054, 26068, 26092, 29161, 29091, 28993, 29110, 28572, 28535, 29966, 29750, 29529, 22749, - 22839, 22955, 22705, 22012, 22323, 25532, 25304, 25389, 31550, 31483, 31411, 31615, 31483, - 31550, 9993, 10001, 10043, 12205, 12350, 12377, 11963, 11809, 11842, 11235, 11687, 11426, - 11316, 11497, 11584, 12218, 12399, 12235, 11085, 11174, 11394, 11148, 11174, 10942, 11174, - 11085, 10801, 30269, 29881, 29859, 31216, 30857, 31266, 29859, 29784, 30189, 10325, 10321, - 10397, 10557, 10604, 10594, 10557, 10594, 10621, 17692, 17416, 17880, 24130, 24148, 24078, - 23526, 23494, 23831, 10265, 10236, 10346, 10325, 10397, 10476, 18609, 18155, 18967, 20018, - 19995, 20074, 31705, 31740, 31301, 12399, 12407, 12702, 11564, 11746, 11561, 27351, 27073, - 26625, 29339, 29161, 28993, 29446, 29161, 29339, 11836, 11809, 11963, 11639, 11552, 11553, - 26092, 26068, 26265, 30447, 30269, 30225, 10347, 10557, 10621, 10712, 10761, 10777, 11497, - 11564, 11561, 24772, 24539, 24653, 23205, 22371, 22625, 24129, 24539, 25286, 26674, 26730, - 26543, 26682, 26522, 26708, 10265, 10346, 10392, 10255, 10230, 10314, 18007, 17996, 17880, - 18076, 17996, 18007, 19821, 19768, 19836, 31735, 31727, 31588, 31735, 31576, 31909, 31544, - 31535, 31909, 22705, 22807, 22749, 13317, 13250, 13202, 13058, 12906, 13054, 13391, 13250, - 13317, 13391, 13552, 13334, 28439, 28582, 28535, 28302, 28416, 28203, 28302, 28203, 28230, - 28203, 28122, 28230, 28122, 28028, 28230, 13250, 13103, 13202, 13183, 13391, 13334, 28230, - 28028, 27990, 13103, 13046, 13202, 12313, 12205, 12377, 27990, 28028, 27931, 28416, 28582, - 28439, 12180, 12218, 12107, 27547, 27427, 27495, 26659, 26675, 26721, 13046, 12906, 13058, - 31707, 31393, 31430, 16854, 16820, 16728, 16970, 16820, 16936, 24783, 24791, 24369, 25598, - 25878, 25780, 31144, 30958, 31090, 30742, 30805, 29769, 31144, 31090, 31235, 12906, 12835, - 13054, 27836, 28031, 28134, 28432, 28031, 28144, 27911, 27836, 27699, 27720, 27547, 27635, - 28396, 28641, 28596, 27717, 27990, 27931, 10200, 10362, 10374, 31235, 31110, 31300, 31525, - 31351, 31341, 10321, 10265, 10392, 10236, 10200, 10374, 10420, 10325, 10476, 10315, 10325, - 10420, 24148, 24783, 24369, 23831, 23494, 23626, 22807, 22839, 22749, 9944, 10030, 10308, - 10557, 10459, 10604, 10367, 10459, 10557, 10965, 11002, 11138, 10965, 11138, 10980, 11235, - 11426, 11251, 11809, 11661, 11795, 11652, 11661, 11809, 11836, 11963, 11853, 25294, 25123, - 25138, 25506, 25532, 25389, 25940, 25573, 25605, 26682, 26730, 26674, 26682, 26674, 26522, - 30393, 30606, 30302, 31318, 30989, 31033, 30580, 30606, 30393, 31143, 31144, 31273, 12313, - 12604, 12228, 11853, 11963, 12059, 14740, 14606, 14734, 13943, 13946, 14318, 13605, 13517, - 13617, 14740, 14734, 14935, 14740, 14935, 14839, 12180, 12249, 12218, 11148, 11584, 11362, - 31051, 30805, 30742, 28031, 27836, 27911, 26073, 25878, 25740, 10843, 10870, 11005, 25294, - 25138, 25304, 31871, 31615, 31472, 31656, 31525, 31341, 31871, 31472, 31602, 10230, 10164, - 10314, 10179, 10200, 10236, 9962, 9902, 9960, 9960, 9902, 10018, 10018, 9941, 10150, - 9993, 9867, 10001, 9886, 9916, 10260, 14198, 14318, 14273, 22839, 23007, 22955, 19841, - 20579, 20103, 22323, 22012, 21690, 22705, 22658, 22807, 22807, 22763, 22839, 22839, 22763, - 23007, 19841, 20103, 19476, 11359, 11426, 11456, 26054, 25940, 25605, 26469, 26092, 26265, - 26675, 26447, 26671, 9916, 9902, 9962, 31721, 31799, 31667, 31667, 31870, 31724, 31724, - 31870, 31728, 31728, 31853, 31681, 31681, 31812, 31705, 31705, 31806, 31740, 31740, 31895, - 31296, 31966, 31721, 31457, 31941, 31457, 31670, 31837, 31670, 31683, 31837, 31683, 31811, - 10712, 10652, 10761, 27352, 27144, 27329, 27352, 27353, 27427, 26708, 26522, 26632, 26730, - 27240, 26543, 10316, 10503, 10460, 11836, 11775, 11809, 11313, 11456, 11553, 11781, 11775, - 11836, 14606, 14468, 14553, 14839, 14935, 14966, 20774, 20910, 21147, 19821, 19926, 19768, - 24006, 24051, 24130, 24122, 24051, 24006, 30297, 29537, 29352, 31799, 31870, 31667, 10280, - 10265, 10321, 10280, 10321, 10325, 10280, 10325, 10315, 10153, 10316, 10460, 10153, 10460, - 10213, 23380, 23494, 23151, 29085, 29175, 29192, 29110, 29175, 29085, 31144, 31143, 30913, - 31000, 31051, 30742, 31110, 31244, 31300, 31870, 31853, 31728, 31811, 31683, 31807, 9854, - 9941, 10018, 10001, 9908, 10056, 11552, 11639, 11661, 15374, 15280, 15109, 14576, 14468, - 14606, 13888, 14438, 14686, 16043, 15997, 16601, 14174, 14438, 13888, 27249, 27240, 26730, - 28613, 28324, 27990, 23007, 23098, 23088, 23173, 23098, 23043, 11002, 10927, 11005, 10712, - 10596, 10652, 10885, 10927, 11002, 11138, 11195, 11105, 20301, 20018, 20074, 18609, 18967, - 19335, 25573, 25532, 25506, 25453, 25532, 25573, 31853, 31812, 31681, 11105, 11195, 11038, - 10224, 10179, 10236, 10200, 10164, 10230, 16820, 16792, 16728, 17416, 16970, 16936, 17003, - 16970, 17416, 17996, 17692, 17880, 19247, 19696, 19335, 24791, 25039, 25049, 24700, 24783, - 24148, 31143, 31041, 30785, 31267, 31033, 30965, 10927, 10843, 11005, 12526, 12604, 12637, - 11824, 11853, 12059, 12407, 12297, 13069, 12218, 12249, 12407, 11465, 11939, 11564, 25532, - 25294, 25304, 27720, 27635, 27699, 11143, 11195, 11235, 13391, 13183, 13250, 13250, 13032, - 13103, 13103, 12907, 13046, 13046, 12907, 12906, 12906, 12859, 12835, 12625, 12526, 12840, - 13334, 13552, 13451, 28416, 28714, 28582, 28582, 29110, 28535, 28302, 28401, 28416, 28278, - 28401, 28302, 28278, 28302, 28230, 28278, 28230, 28324, 30857, 30774, 31266, 30471, 30504, - 30393, 30447, 30393, 30269, 20018, 19943, 19995, 31812, 31806, 31705, 31807, 31607, 31802, - 31607, 31727, 31802, 13451, 13552, 13617, 28324, 28230, 27990, 10843, 10696, 10870, 10315, - 10420, 10240, 13032, 12907, 13103, 13617, 13958, 13605, 13517, 13451, 13617, 14966, 15123, - 15187, 14740, 14576, 14606, 11497, 11485, 11564, 11316, 11485, 11497, 11148, 11362, 11174, - 26675, 26484, 26447, 26092, 26133, 26054, 26659, 26484, 26675, 31802, 31727, 31735, 11202, - 11143, 11235, 10801, 11085, 10385, 29981, 29784, 29750, 13605, 13958, 13707, 31300, 31244, - 31397, 31252, 31045, 31041, 31244, 31303, 31436, 10194, 10224, 10236, 10420, 10459, 10240, - 11181, 11251, 11129, 11359, 11251, 11426, 12079, 12059, 12205, 17750, 17692, 17996, 23831, - 23860, 23845, 24051, 24122, 24148, 23841, 23860, 23831, 31436, 31303, 31504, 14320, 14198, - 14273, 14320, 14553, 14468, 9867, 9908, 10001, 13707, 13958, 13846, 19692, 19841, 19476, - 18662, 18541, 18005, 23098, 23142, 23151, 23173, 23142, 23098, 31656, 31341, 31483, 31504, - 31525, 31656, 31806, 31782, 31740, 31925, 31802, 31909, 30774, 30731, 31266, 10145, 10164, - 10200, 10194, 10236, 10265, 11552, 11661, 11555, 14599, 15444, 15132, 18076, 17919, 17996, - 18131, 17919, 18076, 31504, 31322, 31451, 13846, 13958, 13946, 12313, 12079, 12205, 11996, - 12079, 12313, 13943, 13846, 13946, 14235, 14320, 14332, 27485, 27352, 27427, 27240, 27351, - 26625, 27411, 27351, 27240, 11652, 11809, 11775, 11652, 11775, 11781, 14839, 14825, 14740, - 15293, 14966, 15187, 16970, 16802, 16820, 15293, 15374, 14966, 17003, 16802, 16970, 29966, - 29529, 30014, 31041, 31045, 31000, 30524, 29352, 29769, 31252, 31041, 31143, 12625, 12840, - 12835, 13707, 13846, 13684, 27836, 27817, 27699, 27547, 27536, 27427, 27982, 27817, 27836, - 28396, 28860, 28641, 30014, 29529, 29883, 29428, 29110, 29425, 10927, 10810, 10843, 10626, - 10596, 10696, 10965, 10885, 11002, 10950, 10885, 10965, 10980, 11138, 11105, 10980, 11105, - 10982, 15444, 15997, 16043, 16999, 17247, 17259, 11148, 11316, 11584, 12180, 12297, 12249, - 26484, 26469, 26293, 26509, 26469, 26484, 30158, 30189, 29784, 10145, 10200, 10179, 11038, - 11195, 11143, 30504, 30580, 30393, 30568, 30580, 30504, 30471, 30393, 30447, 10146, 10194, - 10265, 10224, 10145, 10179, 10367, 10557, 10347, 10596, 10712, 10696, 31235, 31273, 31144, - 31454, 31273, 31235, 31454, 31235, 31300, 31107, 31267, 30965, 31318, 31267, 31342, 19335, - 19696, 19768, 27817, 27720, 27699, 11202, 11235, 11251, 11109, 11038, 11143, 30568, 30471, - 30447, 10146, 10265, 10280, 12079, 11987, 12059, 12008, 11987, 12079, 23860, 24122, 24006, - 23496, 23626, 23494, 31436, 31397, 31244, 31491, 31397, 31436, 10687, 10696, 10843, 11181, - 11202, 11251, 26373, 26133, 26092, 25532, 25453, 25294, 12526, 12228, 12604, 12249, 12297, - 12407, 11465, 11564, 11485, 27720, 27649, 27547, 27128, 26773, 27144, 11781, 11836, 11853, - 11552, 11313, 11553, 11350, 11465, 11485, 26469, 26373, 26092, 27311, 27144, 27352, 31877, - 31707, 31294, 31486, 31172, 31392, 31525, 31504, 31451, 31656, 31483, 32040, 31605, 31486, - 31392, 16802, 16792, 16820, 16821, 16792, 16802, 17003, 17416, 17415, 31045, 31051, 31000, - 31141, 31051, 31045, 10030, 9904, 10296, 9733, 9904, 10030, 11987, 11824, 12059, 12008, - 11824, 11987, 13451, 13234, 13334, 13334, 13234, 13183, 13183, 13032, 13250, 12907, 12859, - 12906, 12023, 12085, 12228, 13467, 13234, 13451, 13467, 13451, 13517, 13467, 13517, 13605, - 13467, 13605, 13679, 21135, 20774, 21147, 20301, 20164, 20018, 20018, 20037, 19943, 21348, - 20774, 21135, 27351, 27433, 27575, 26953, 27249, 26730, 26838, 26730, 26682, 28641, 28957, - 28809, 27817, 27971, 27720, 27720, 27971, 27649, 28860, 29275, 29213, 9902, 9854, 10018, - 9941, 9867, 9993, 9916, 9848, 9902, 9759, 9848, 9916, 31799, 31954, 31870, 31870, - 31954, 31853, 31853, 31919, 31812, 31812, 31919, 31806, 31806, 31914, 31782, 32043, 31913, - 31799, 31941, 31670, 31837, 31941, 31837, 31943, 31837, 31811, 31943, 15374, 15893, 15280, - 14966, 14825, 14839, 23841, 24122, 23860, 29378, 29091, 29161, 30524, 29769, 30603, 29456, - 29446, 29339, 30189, 30225, 29859, 30158, 30225, 30189, 9848, 9854, 9902, 12107, 12218, - 12235, 27649, 27536, 27547, 27589, 27536, 27590, 29717, 29171, 29791, 31913, 31954, 31799, - 10469, 10621, 10652, 10070, 10145, 10054, 16624, 17247, 16999, 12913, 12859, 12907, 13679, - 13605, 13707, 13679, 13707, 13684, 17919, 17750, 17996, 17767, 17750, 17919, 31943, 31811, - 31929, 31811, 31925, 31929, 20299, 20164, 20301, 19943, 19926, 19821, 10885, 10810, 10927, - 10596, 10490, 10652, 10757, 10810, 10885, 10950, 10965, 10980, 10950, 10980, 10818, 10982, - 11105, 11038, 12859, 12669, 12835, 25601, 25453, 25573, 25294, 25295, 25123, 25123, 25270, - 24772, 9854, 9827, 9941, 9891, 10213, 10220, 10741, 10687, 10843, 11652, 11555, 11661, - 11109, 10982, 11038, 10868, 11555, 11652, 14703, 14825, 14966, 13684, 13846, 13690, 20164, - 20115, 20018, 25453, 25295, 25294, 23797, 23654, 23924, 26708, 26838, 26682, 26322, 26254, - 26391, 24700, 24791, 24783, 31811, 31807, 31925, 17607, 17416, 17692, 24342, 24700, 24148, - 12669, 12625, 12835, 11641, 11781, 11824, 14318, 14198, 13943, 10069, 10145, 10224, 10164, - 10026, 10308, 10197, 10280, 10315, 27536, 27485, 27427, 27358, 27485, 27469, 27411, 27433, - 27351, 27411, 27240, 27300, 11555, 11313, 11552, 26659, 26509, 26484, 26133, 25940, 26054, - 26533, 26509, 26721, 30242, 30158, 29981, 29981, 30158, 29784, 9827, 9867, 9941, 11824, - 11781, 11853, 12008, 12079, 11996, 14632, 14576, 14740, 31925, 31807, 31802, 13943, 14198, - 13933, 32146, 31919, 31853, 31782, 31876, 31740, 22323, 21975, 22235, 23827, 23841, 23626, - 23626, 23841, 23831, 31267, 31318, 31033, 31342, 31267, 31107, 17750, 17701, 17692, 17767, - 17701, 17750, 17247, 17665, 17485, 19987, 19926, 19943, 23380, 23151, 23142, 24122, 24342, - 24148, 31919, 31914, 31806, 31909, 31802, 31735, 11129, 11251, 11359, 24700, 25039, 24791, - 24961, 25039, 24700, 11996, 12313, 12085, 27300, 27240, 27249, 18609, 18361, 18155, 18263, - 18361, 18328, 23043, 23098, 23007, 9904, 9886, 10296, 9500, 9886, 9904, 26391, 26254, - 25878, 27387, 27300, 27249, 10205, 10025, 9851, 10316, 10037, 10327, 10385, 11085, 10689, - 17836, 18662, 18005, 22658, 22763, 22807, 23164, 22763, 22658, 14235, 14198, 14320, 17003, - 16821, 16802, 15109, 14990, 15374, 16915, 16821, 17003, 31914, 31876, 31782, 10810, 10741, - 10843, 10687, 10626, 10696, 10950, 10757, 10885, 10818, 10757, 10950, 32002, 31871, 31602, - 10757, 10741, 10810, 27358, 27311, 27352, 27358, 27352, 27485, 26953, 26730, 26838, 30526, - 29717, 29791, 29446, 29378, 29161, 11109, 11143, 11202, 20088, 20270, 20579, 22323, 21690, - 21975, 19559, 19692, 19476, 26112, 25940, 26133, 25453, 25504, 25295, 26373, 26469, 26533, - 31266, 30731, 31355, 30471, 30568, 30504, 30499, 30568, 30447, 30350, 30447, 30225, 31876, - 31895, 31740, 10622, 10626, 10687, 10070, 10026, 10164, 10070, 10164, 10145, 10240, 10459, - 10367, 10256, 10240, 10367, 12180, 12159, 12297, 12297, 12031, 13107, 12107, 12159, 12180, - 18361, 18223, 18155, 18263, 18223, 18361, 23173, 23278, 23142, 23043, 23278, 23173, 12681, - 12629, 12669, 12669, 12629, 12625, 12625, 12440, 12526, 13234, 13032, 13183, 12913, 13032, - 13155, 13032, 13234, 13155, 13155, 13467, 13322, 13518, 13679, 13684, 26800, 26953, 26838, - 26800, 26838, 26708, 11129, 11043, 11070, 11359, 11313, 11178, 11129, 11359, 11178, 11070, - 11109, 11181, 11181, 11109, 11202, 30603, 29769, 30805, 30297, 30239, 29537, 10153, 10152, - 10316, 10037, 10152, 9523, 11492, 12107, 12235, 11316, 11350, 11485, 11225, 11350, 11316, - 11225, 11316, 11113, 21778, 21350, 21808, 24129, 24331, 24539, 23496, 23678, 23626, 23841, - 24127, 24122, 28278, 28607, 28401, 28401, 28607, 28416, 27717, 27931, 27575, 27717, 27575, - 27433, 27443, 27433, 27411, 31273, 31252, 31143, 31051, 31141, 30805, 31373, 31252, 31273, - 31491, 31300, 31397, 31491, 31436, 31563, 30881, 30606, 30580, 31563, 31436, 31504, 31883, - 31909, 31535, 31883, 31535, 31707, 10575, 10490, 10596, 11492, 11939, 11465, 29717, 29456, - 29339, 12681, 12669, 12859, 28199, 28134, 28031, 28432, 28144, 28596, 28563, 28596, 28689, - 10868, 10880, 11043, 26533, 26469, 26509, 30158, 30350, 30225, 30242, 30350, 30158, 30499, - 30350, 30529, 9926, 9944, 10308, 10069, 10224, 10194, 10421, 10469, 10652, 16821, 16778, - 16792, 16915, 16778, 16821, 17607, 17692, 17701, 18223, 18131, 18076, 18263, 18131, 18223, - 23424, 23380, 23278, 23278, 23380, 23142, 31252, 31141, 31045, 18662, 18904, 18956, 19333, - 18904, 18168, 28134, 27982, 27836, 10240, 10197, 10315, 10221, 10197, 10240, 23827, 23626, - 23678, 23962, 24127, 23841, 31941, 31966, 31457, 31913, 31970, 31954, 31954, 31970, 31853, - 31919, 32010, 31914, 31914, 32010, 31876, 31876, 32102, 31895, 32045, 31966, 31941, 32045, - 31941, 31975, 31941, 31943, 31975, 31943, 31987, 31975, 10347, 10256, 10367, 12008, 11813, - 11824, 12085, 12313, 12228, 14332, 14320, 14468, 13943, 13690, 13846, 14332, 14468, 14405, - 14468, 14576, 14405, 24127, 24342, 24122, 27387, 27443, 27411, 27387, 27411, 27300, 31304, - 31342, 31107, 31318, 31605, 31050, 31877, 31883, 31707, 31304, 31107, 31216, 31966, 32043, - 31799, 10757, 10622, 10741, 10492, 10575, 10626, 10626, 10575, 10596, 10490, 10421, 10652, - 10982, 10818, 10980, 10539, 10818, 10982, 10873, 10982, 11109, 10192, 10689, 10327, 25601, - 25504, 25453, 25295, 25270, 25123, 25391, 25504, 25601, 10197, 10146, 10280, 18131, 17767, - 17919, 23653, 23827, 23678, 27311, 27128, 27144, 27293, 27128, 27311, 32043, 31970, 31913, - 31943, 31929, 31987, 13845, 13690, 13943, 30568, 30719, 30580, 30705, 30719, 30568, 26721, - 26509, 26659, 26373, 26196, 26133, 9851, 10025, 9604, 9827, 9761, 9867, 9867, 9757, - 9908, 9854, 9773, 9827, 9662, 9773, 9854, 9730, 9854, 9848, 31987, 31929, 32089, - 19338, 19335, 19768, 25740, 25878, 25598, 25598, 25274, 25610, 30483, 30239, 30297, 29275, - 29378, 29402, 30740, 30603, 31132, 10469, 10347, 10621, 10622, 10687, 10741, 15997, 16491, - 16601, 17247, 17058, 17665, 16624, 16491, 16593, 22763, 23043, 23007, 23380, 23496, 23494, - 23308, 23043, 23164, 32040, 31483, 31615, 31947, 31615, 31871, 32148, 31987, 32089, 10069, - 10054, 10145, 9926, 10308, 9889, 23585, 23496, 23424, 31656, 31563, 31504, 31532, 31454, - 31300, 31252, 31299, 31141, 14055, 13933, 14198, 14405, 14576, 14507, 14740, 14825, 14703, - 27589, 27485, 27536, 9773, 9761, 9827, 20115, 20037, 20018, 19926, 19869, 19768, 20164, - 20037, 20115, 20299, 20037, 20164, 20299, 20301, 20774, 11129, 11070, 11181, 11178, 10868, - 11043, 26410, 26196, 26373, 30350, 30499, 30447, 29192, 29175, 29428, 9604, 10025, 9908, - 14438, 14599, 15132, 16593, 16491, 16176, 14174, 14599, 14438, 20037, 19987, 19943, 21778, - 21808, 22337, 26345, 26112, 26196, 26909, 26721, 26675, 26909, 26773, 27128, 29428, 29175, - 29110, 31532, 31300, 31491, 10400, 10421, 10490, 14055, 14198, 14074, 29456, 29378, 29446, - 29378, 29515, 29402, 29435, 29110, 29276, 31581, 31605, 31318, 31386, 31304, 31453, 19987, - 19869, 19926, 11313, 10868, 11178, 14703, 14966, 14990, 14074, 14198, 14235, 26089, 26391, - 25878, 27393, 27387, 27249, 28689, 28596, 28809, 28134, 28114, 27982, 27703, 27536, 27649, - 28324, 28607, 28278, 28638, 28607, 28704, 13032, 12913, 12907, 12212, 12228, 12526, 13155, - 13234, 13467, 13467, 13679, 13322, 13322, 13679, 13518, 28563, 28432, 28596, 28607, 28714, - 28416, 23496, 23544, 23678, 23827, 23962, 23841, 24127, 24193, 24342, 23585, 23544, 23496, - 12440, 12625, 12629, 10868, 11652, 10999, 14074, 14235, 14200, 13518, 13684, 13690, 32105, - 32010, 31919, 32002, 31947, 31871, 10294, 10347, 10469, 10256, 10221, 10240, 10048, 10069, - 10146, 9963, 10070, 10054, 26073, 26089, 25878, 25819, 25740, 25610, 12913, 12681, 12859, - 13518, 13690, 13442, 10022, 10026, 10070, 9958, 9891, 10220, 9709, 9891, 9958, 10539, - 10622, 10757, 10575, 10400, 10490, 10294, 10251, 10347, 10539, 10757, 10818, 10400, 10218, - 10361, 25504, 25391, 25295, 25601, 25573, 25940, 10801, 10942, 11174, 11350, 11492, 11465, - 10502, 10942, 10292, 30978, 30477, 30606, 30809, 30705, 30568, 30840, 30705, 30926, 28432, - 28199, 28031, 14632, 14703, 14659, 27072, 26909, 27128, 26570, 26373, 26533, 27072, 27128, - 27222, 29966, 30090, 29981, 30332, 30090, 30195, 10622, 10492, 10626, 11113, 11316, 10953, - 26391, 26632, 26522, 26894, 27023, 27101, 30483, 30297, 30524, 30129, 30242, 29981, 10044, - 10221, 10256, 9963, 10022, 10070, 13845, 13943, 13933, 13871, 13845, 13933, 14200, 14235, - 14332, 14200, 14332, 14263, 26196, 26112, 26133, 26570, 26533, 26591, 25819, 26089, 26073, - 27971, 27817, 27982, 28199, 28114, 28134, 14632, 14507, 14576, 17767, 17607, 17701, 17415, - 17607, 17506, 18151, 17767, 18131, 23895, 23962, 23827, 25610, 25274, 25039, 31373, 31299, - 31252, 31598, 31532, 31491, 31598, 31491, 31661, 10069, 10194, 10146, 18416, 18361, 18609, - 22301, 21778, 22337, 9889, 10308, 10026, 9944, 9876, 10030, 10116, 10146, 10197, 31512, - 31318, 31342, 32035, 31602, 31895, 31701, 31491, 31563, 31877, 31294, 31486, 32148, 31975, - 31987, 30740, 30483, 30524, 30740, 30524, 30603, 30603, 30805, 31132, 32102, 32025, 31895, - 13738, 13845, 13871, 14263, 14332, 14405, 27589, 27469, 27485, 27590, 27469, 27589, 28114, - 27971, 27982, 26909, 26821, 26721, 26898, 26821, 26909, 26632, 26800, 26708, 27443, 27717, - 27433, 26894, 26800, 27023, 30090, 30129, 29981, 30809, 30568, 30499, 30332, 30129, 30090, - 30840, 30580, 30719, 31479, 31512, 31342, 27390, 27311, 27358, 10022, 9889, 10026, 9982, - 9963, 10054, 18263, 18151, 18131, 18198, 18151, 18263, 26732, 26533, 26721, 10221, 10116, - 10197, 10069, 9982, 10054, 10091, 10116, 9860, 10251, 10256, 10347, 25270, 24539, 24772, - 22423, 22301, 22337, 23962, 24112, 24127, 24031, 24112, 23962, 13933, 14055, 13871, 29428, - 29466, 29192, 29429, 29425, 29110, 30705, 30840, 30719, 30529, 30350, 30242, 32025, 32035, - 31895, 9886, 9759, 9916, 9641, 9757, 9761, 9761, 9757, 9867, 9670, 9759, 9432, - 10047, 10048, 10146, 24129, 23797, 23924, 27469, 27390, 27358, 27455, 27390, 27469, 27029, - 27249, 26953, 31701, 31563, 31856, 31373, 31273, 31454, 31966, 32119, 32043, 32043, 32077, - 31970, 31970, 32146, 31853, 32010, 32102, 31876, 32025, 32091, 32035, 32045, 32119, 31966, - 32062, 32119, 32045, 32062, 32045, 31975, 32062, 31975, 32148, 9759, 9730, 9848, 32119, - 32077, 32043, 31373, 31454, 31641, 32077, 32146, 31970, 31929, 31925, 32089, 12159, 12086, - 12297, 12107, 12086, 12159, 12019, 12086, 12107, 20181, 20299, 20228, 20037, 20050, 19987, - 19987, 19932, 19869, 19869, 19338, 19768, 18587, 18519, 18609, 20299, 20774, 20517, 27971, - 27703, 27649, 29425, 29466, 29428, 10492, 10400, 10575, 10136, 10400, 10492, 11015, 11109, - 11070, 32089, 31925, 32432, 32167, 31877, 31486, 11159, 11492, 11350, 11176, 11350, 11225, - 14703, 14632, 14740, 14507, 14333, 14405, 13871, 14055, 14060, 14556, 14632, 14659, 19324, - 19338, 19869, 26894, 27029, 26953, 26894, 26953, 26800, 28432, 28308, 28199, 28199, 28251, - 28114, 28114, 28237, 27971, 27971, 28023, 27703, 28563, 28689, 28432, 28809, 28596, 28641, - 29435, 29429, 29110, 29425, 29451, 29466, 28607, 28638, 28714, 28704, 28607, 28324, 31925, - 31909, 32432, 13155, 12852, 12913, 12769, 12598, 12681, 12681, 12598, 12629, 13322, 13149, - 13155, 13247, 13149, 13322, 13247, 13322, 13303, 26821, 26732, 26721, 26842, 26732, 26821, - 26898, 26909, 27006, 28957, 28641, 29213, 30129, 30288, 30242, 30332, 30288, 30129, 9795, - 9876, 9944, 9947, 9889, 10022, 9947, 10022, 9857, 18519, 18416, 18609, 12977, 13247, - 13023, 29213, 28641, 28860, 28860, 29091, 29275, 27390, 27293, 27311, 27375, 27293, 27390, - 12491, 12598, 12465, 28459, 28308, 28432, 16491, 16624, 16999, 17665, 17836, 18005, 16491, - 15997, 15675, 20299, 20050, 20037, 32148, 32381, 32221, 27703, 27590, 27536, 27939, 27590, - 27703, 31386, 31342, 31304, 31605, 31749, 31486, 11178, 11043, 11129, 11822, 12008, 11996, - 11822, 11996, 12085, 26057, 25601, 25940, 26570, 26410, 26373, 26551, 26410, 26570, 30545, - 30529, 30242, 9795, 9944, 9926, 10116, 10047, 10146, 10048, 9982, 10069, 10091, 10047, - 10116, 23805, 23895, 23827, 24517, 24700, 24342, 23653, 23678, 23544, 28308, 28251, 28199, - 31562, 31454, 31532, 31453, 31304, 31216, 31479, 31386, 31476, 9641, 9761, 9773, 9851, - 9780, 9958, 12398, 12440, 12629, 26258, 25940, 26112, 25391, 25433, 25295, 29275, 29091, - 29378, 30840, 30881, 30580, 31019, 30881, 30990, 30881, 30978, 30606, 9857, 10022, 9963, - 9889, 9816, 9926, 18416, 18328, 18361, 17506, 17607, 17767, 18209, 18328, 18416, 27006, - 26909, 27072, 26732, 26591, 26533, 27393, 27498, 27387, 26800, 26904, 27023, 9604, 9780, - 9851, 10294, 10469, 10421, 11890, 11822, 12085, 22317, 22301, 22423, 20517, 20774, 20611, - 23424, 23496, 23380, 23424, 23278, 23308, 25465, 25433, 25391, 31856, 31563, 31656, 31598, - 31562, 31532, 31856, 31656, 32118, 31709, 31749, 31605, 32035, 32002, 31602, 32091, 32002, - 32035, 14632, 14489, 14507, 13845, 13738, 13690, 27288, 27222, 27293, 27293, 27222, 27128, - 26836, 26591, 26732, 26410, 26345, 26196, 32146, 32105, 31919, 12440, 12212, 12526, 29378, - 29696, 29515, 25433, 25270, 25295, 21660, 21348, 21778, 22451, 22317, 22423, 21690, 21361, - 21975, 10047, 9982, 10048, 10047, 10091, 9860, 10152, 10037, 10316, 9523, 10152, 10153, - 9709, 10213, 9891, 14065, 14074, 14200, 29456, 29792, 29696, 29378, 29456, 29696, 31733, - 31562, 31598, 14333, 14263, 14405, 13378, 14174, 13888, 15586, 15997, 15444, 27590, 27455, - 27469, 27486, 27455, 27655, 27387, 27498, 27443, 27393, 27249, 27214, 10400, 10361, 10421, - 10251, 10044, 10256, 10539, 10492, 10622, 11043, 11015, 11070, 10873, 11015, 10880, 18328, - 18198, 18263, 18209, 18198, 18328, 26423, 26345, 26410, 32105, 32102, 32010, 9826, 9982, - 10047, 23585, 23653, 23544, 24193, 24127, 24112, 23627, 23653, 23585, 26371, 26184, 26345, - 26898, 26842, 26821, 26989, 26842, 26898, 27006, 27072, 27222, 31856, 31661, 31701, 31701, - 31661, 31491, 31581, 31709, 31605, 31749, 31852, 31486, 31581, 31318, 31512, 14358, 14333, - 14507, 14632, 14556, 14489, 14659, 14703, 14990, 12212, 12023, 12228, 11822, 11813, 12008, - 12086, 12051, 12297, 12019, 12051, 12086, 14060, 14055, 14074, 29429, 29451, 29425, 29835, - 29529, 29192, 10361, 10294, 10421, 10953, 11316, 11148, 11236, 12019, 12107, 10953, 11148, - 10942, 14358, 14507, 14489, 14263, 14065, 14200, 27455, 27375, 27390, 27486, 27375, 27455, - 27498, 27717, 27443, 27214, 27249, 27029, 25740, 25819, 26073, 26800, 26632, 26904, 27101, - 27214, 27029, 24031, 23962, 23895, 25601, 25465, 25391, 25433, 25407, 25270, 25407, 25465, - 25890, 28594, 28459, 28432, 28282, 28237, 28251, 28251, 28237, 28114, 28809, 28797, 28689, - 28907, 28797, 28809, 28907, 28809, 28957, 29168, 28957, 29213, 29168, 29213, 29337, 30978, - 31077, 30477, 31762, 31581, 31512, 31133, 31077, 31156, 31019, 30978, 30881, 11956, 12019, - 11834, 27715, 27717, 27498, 28594, 28432, 28689, 23976, 24031, 23895, 31479, 31342, 31386, - 31453, 31216, 31266, 9885, 9816, 9889, 9571, 9670, 9432, 9885, 9889, 9947, 12031, - 12297, 12051, 12005, 13284, 13107, 27288, 27006, 27222, 26423, 26410, 26551, 12212, 12057, - 12023, 12440, 12335, 12212, 12598, 12491, 12629, 12769, 12681, 12913, 12852, 13155, 12880, - 13155, 13149, 12880, 13149, 12977, 12880, 13284, 13378, 13888, 23627, 23805, 23653, 23653, - 23805, 23827, 31661, 31716, 31598, 31552, 31377, 31373, 31824, 31716, 31661, 10037, 10192, - 10327, 11113, 11176, 11225, 26345, 26184, 26112, 26570, 26591, 26551, 30813, 30526, 30239, - 31132, 30805, 31141, 31426, 31141, 31299, 31377, 31299, 31373, 31677, 31454, 31562, 31476, - 31453, 31460, 32196, 32091, 32025, 31815, 31733, 31716, 9730, 9681, 9854, 9552, 9604, - 9908, 9759, 9670, 9730, 9733, 10030, 9713, 32119, 32178, 32077, 32077, 32162, 32146, - 32146, 32332, 32105, 32105, 32187, 32102, 32102, 32187, 32025, 32184, 32178, 32119, 32184, - 32119, 32202, 32119, 32062, 32202, 32062, 32148, 32221, 32202, 32062, 32221, 9670, 9682, - 9730, 32221, 32381, 32258, 9682, 9681, 9730, 14556, 14358, 14489, 14333, 14065, 14263, - 29835, 29192, 29466, 30545, 30540, 30529, 30529, 30540, 30499, 32178, 32162, 32077, 12491, - 12398, 12629, 28282, 28251, 28308, 29337, 29213, 29275, 29337, 29275, 29402, 9681, 9662, - 9854, 32258, 32381, 32375, 20088, 20579, 19841, 20088, 19841, 19692, 23308, 23278, 23043, - 31864, 31852, 31749, 32258, 32202, 32221, 31864, 31749, 31709, 9795, 9779, 9876, 9785, - 9885, 9947, 11065, 11159, 11176, 10861, 10953, 10795, 20299, 20181, 20050, 20050, 19932, - 19987, 18447, 18209, 18416, 22024, 21778, 22301, 26836, 26732, 26842, 29515, 29337, 29402, - 30545, 30242, 30472, 20181, 20108, 20050, 19559, 20088, 19692, 19559, 19476, 18904, 17607, - 17415, 17416, 14990, 14966, 15374, 14556, 14498, 14358, 17506, 17767, 17777, 24091, 24193, - 24031, 24031, 24193, 24112, 23916, 23895, 23805, 11720, 11813, 11822, 12017, 12085, 12023, - 14060, 14065, 14124, 13149, 13247, 12977, 29761, 29835, 29466, 9614, 9641, 9773, 24193, - 24517, 24342, 27006, 26989, 26898, 27026, 26989, 27006, 27288, 27293, 27375, 28237, 28023, - 27971, 29451, 29684, 29466, 28898, 28582, 28714, 28898, 28714, 28638, 30195, 30090, 29966, - 30195, 29966, 30014, 23733, 23916, 23805, 31716, 31733, 31598, 31615, 31947, 32040, 27101, - 27029, 26894, 27393, 27459, 27498, 30990, 30881, 30840, 31077, 31112, 30731, 9795, 9926, - 9766, 25173, 25610, 25039, 26632, 26824, 26904, 20108, 19932, 20050, 31133, 31112, 31077, - 12075, 12057, 12212, 11956, 12031, 12051, 11956, 12051, 12019, 29456, 29717, 29792, 30663, - 30809, 30499, 30663, 30499, 30540, 32132, 31947, 32002, 32312, 31883, 31877, 31844, 31864, - 31709, 31844, 31709, 31581, 31844, 31581, 31767, 27655, 27455, 27590, 27261, 27459, 27393, - 28803, 28704, 28656, 29835, 29883, 29529, 30016, 29883, 29835, 10192, 10385, 10689, 9713, - 10030, 9876, 9766, 9926, 9816, 11015, 10873, 11109, 10361, 10218, 10294, 10758, 10873, - 10880, 26423, 26371, 26345, 26184, 26258, 26112, 26476, 26371, 26423, 30661, 30663, 30540, - 12057, 12017, 12023, 11813, 11641, 11824, 11338, 12107, 11492, 11292, 11338, 11492, 11159, - 11350, 11176, 27214, 27261, 27393, 26391, 26824, 26632, 30472, 30242, 30288, 30019, 30195, - 30014, 11065, 11176, 11113, 11065, 11113, 10861, 13518, 13303, 13322, 12294, 12335, 12398, - 12398, 12335, 12440, 12057, 11940, 12017, 13690, 13738, 13442, 16624, 17058, 17247, 15586, - 15444, 15186, 23916, 23976, 23895, 24193, 24441, 24517, 23733, 23976, 23916, 28704, 28324, - 28656, 28704, 28745, 28638, 31733, 31758, 31562, 31783, 31758, 31733, 9713, 9876, 9779, - 12852, 12769, 12913, 13442, 13738, 13463, 28395, 28282, 28308, 28237, 28161, 28023, 28845, - 28594, 28689, 28845, 28689, 28797, 28907, 28957, 29129, 28907, 28853, 28845, 28957, 29168, - 29270, 28745, 28898, 28638, 32180, 32132, 32002, 32200, 32002, 32091, 16593, 17058, 16624, - 23164, 23043, 22763, 23424, 23627, 23585, 29883, 29957, 30014, 30073, 29957, 29883, 30019, - 30278, 30199, 26836, 26842, 26989, 26836, 26551, 26591, 30472, 30288, 30332, 11832, 11890, - 12017, 12017, 11890, 12085, 17058, 17836, 17665, 23454, 23627, 23424, 31901, 31824, 32308, - 31856, 31824, 31661, 31762, 31512, 31730, 32167, 31486, 31852, 31476, 31386, 31453, 9706, - 9766, 9816, 9691, 9713, 9779, 9706, 9816, 9885, 9857, 9963, 9982, 9857, 9982, - 9826, 28487, 28308, 28459, 28023, 27939, 27703, 10758, 10539, 10982, 9826, 10047, 9860, - 24517, 24961, 24700, 24878, 24961, 24517, 31377, 31426, 31299, 31552, 31426, 31377, 31156, - 31077, 30978, 30926, 30990, 30840, 30926, 30705, 30809, 30926, 30809, 30905, 31270, 31132, - 31141, 31460, 31453, 31266, 31094, 30978, 31019, 32271, 32187, 32529, 30800, 30809, 30663, - 11159, 11292, 11492, 11236, 11834, 12019, 11277, 11292, 11132, 12294, 12398, 12491, 13303, - 13442, 13463, 14990, 15109, 14912, 14256, 14065, 14333, 14065, 14060, 14074, 27722, 27715, - 27459, 26745, 26847, 26824, 28282, 28161, 28237, 11890, 11720, 11822, 11637, 11720, 11709, - 14256, 14333, 14358, 9411, 9517, 9706, 10861, 11113, 10953, 23308, 23347, 23424, 23350, - 23347, 23308, 30661, 30800, 30663, 30535, 30472, 30332, 30317, 30332, 30195, 17415, 16915, - 17003, 17862, 17767, 18151, 18209, 18151, 18198, 23976, 24091, 24031, 24227, 24091, 23976, - 23733, 23805, 23627, 27494, 27288, 27375, 27494, 27375, 27486, 29957, 30019, 30014, 29552, - 29451, 29429, 19333, 19559, 18904, 26179, 26258, 26476, 26371, 26258, 26184, 26258, 26371, - 26476, 30661, 30540, 30545, 32187, 32196, 32025, 12335, 12148, 12212, 29276, 29110, 28582, - 32078, 32040, 31947, 32078, 31947, 32132, 9432, 9759, 9886, 9691, 9779, 9728, 9779, - 9795, 9728, 23664, 23733, 23627, 31577, 31552, 31373, 31497, 31270, 31141, 31641, 31454, - 31677, 31355, 30731, 31112, 31824, 31815, 31716, 31901, 31815, 31824, 24961, 25173, 25039, - 26391, 26745, 26824, 25197, 25173, 24961, 31287, 31355, 31112, 22077, 22024, 22301, 22077, - 22301, 22220, 32196, 32215, 32091, 30667, 30661, 30545, 12148, 12075, 12212, 29435, 29552, - 29429, 9682, 9564, 9681, 9681, 9564, 9662, 9662, 9614, 9773, 9670, 9571, 9682, - 9628, 9904, 9733, 11720, 11641, 11813, 11637, 11641, 11720, 32178, 32295, 32162, 32529, - 32187, 32105, 32187, 32271, 32196, 32196, 32271, 32215, 32184, 32295, 32178, 32202, 32295, - 32184, 32258, 32295, 32202, 31909, 31883, 32169, 20611, 20823, 20695, 20181, 20194, 20108, - 20108, 20031, 19932, 9571, 9564, 9682, 9552, 9908, 9757, 32169, 31883, 32312, 9728, - 9795, 9717, 9646, 9628, 9733, 20517, 20228, 20299, 19932, 19324, 19869, 23347, 23454, - 23424, 23350, 23454, 23347, 30019, 30199, 30195, 30472, 30552, 30545, 30307, 30199, 30278, - 31355, 31460, 31266, 22024, 21660, 21778, 22220, 22301, 22317, 32271, 32200, 32215, 32215, - 32200, 32091, 20228, 20194, 20181, 28141, 27939, 28023, 29552, 29637, 29451, 31730, 31512, - 31479, 31730, 31479, 31949, 14852, 14990, 14912, 13386, 13463, 13368, 30569, 30552, 30472, - 31133, 31287, 31112, 31465, 31591, 31460, 30990, 31094, 31019, 31309, 31094, 30990, 31191, - 31094, 31202, 30990, 30926, 30949, 30926, 30905, 30949, 9493, 9614, 9662, 9780, 9709, - 9958, 31191, 31156, 30978, 31552, 31507, 31426, 31677, 31562, 31758, 27655, 27494, 27486, - 26948, 26836, 26989, 31815, 31783, 31733, 31901, 31783, 31815, 20194, 20031, 20108, 25465, - 25407, 25433, 25270, 25286, 24539, 24129, 23756, 23797, 22451, 22220, 22317, 25890, 25465, - 25601, 31269, 31287, 31133, 9646, 9733, 9676, 12977, 12782, 12880, 12880, 12782, 12852, - 12852, 12655, 12769, 12769, 12597, 12598, 12335, 12127, 12148, 12148, 12127, 12075, 12655, - 12782, 12757, 21802, 21660, 21965, 22451, 22423, 22489, 28907, 28845, 28797, 28594, 28487, - 28459, 28282, 28329, 28161, 28161, 28155, 28023, 29270, 29168, 29337, 32200, 32161, 32002, - 32307, 32161, 32200, 9676, 9733, 9713, 9717, 9795, 9766, 11956, 11881, 12031, 12031, - 12005, 13107, 13284, 13261, 13378, 11236, 12107, 11338, 30526, 29791, 30239, 29414, 29270, - 29337, 30239, 30483, 30813, 29637, 29684, 29451, 12565, 12597, 12769, 17128, 16915, 17415, - 12597, 12465, 12598, 28539, 28487, 28594, 9857, 9785, 9947, 10156, 10251, 10294, 11292, - 11277, 11338, 11046, 11292, 11159, 30199, 30317, 30195, 30307, 30317, 30199, 10873, 10758, - 10982, 10880, 11015, 11043, 27026, 27006, 27169, 26258, 26147, 25940, 28487, 28395, 28308, - 9422, 9564, 9571, 9676, 9713, 9659, 32161, 32180, 32002, 31874, 31777, 31783, 32307, - 32180, 32161, 31936, 31852, 31864, 31936, 31864, 31844, 27459, 27715, 27498, 27185, 27214, - 27101, 29684, 29761, 29466, 9659, 9713, 9691, 9706, 9717, 9766, 12433, 12294, 12491, - 11709, 11720, 11890, 13442, 13303, 13518, 13463, 13738, 13581, 13738, 13871, 13581, 28395, - 28329, 28282, 27839, 27655, 27590, 29414, 29337, 29515, 10136, 10218, 10400, 10156, 10218, - 10136, 31777, 31677, 31758, 31641, 31577, 31373, 31767, 31936, 31844, 31767, 31730, 31922, - 31479, 31476, 31949, 10868, 11313, 11555, 10795, 10953, 10942, 11065, 11046, 11159, 31655, - 31577, 31641, 12294, 12127, 12335, 10676, 10854, 10880, 14498, 14556, 14659, 22133, 22024, - 22077, 28329, 28155, 28161, 29579, 29414, 29515, 9659, 9691, 9627, 9500, 9904, 9527, - 18609, 19335, 18587, 17506, 17128, 17415, 11940, 12057, 12075, 27169, 27006, 27288, 27965, - 27590, 27939, 31156, 31269, 31133, 31465, 31460, 31355, 31094, 31191, 30978, 30809, 30800, - 30905, 31767, 31581, 31762, 27404, 27288, 27494, 26476, 26423, 26551, 30317, 30344, 30332, - 30905, 30800, 30661, 30367, 30344, 30317, 28155, 28141, 28023, 31754, 31507, 31552, 14774, - 15444, 14599, 16593, 16176, 17058, 15675, 15586, 15186, 30667, 30545, 30552, 31132, 31270, - 30740, 31497, 31141, 31426, 31202, 31269, 31156, 30577, 30569, 30472, 23205, 22625, 23797, - 22220, 22133, 22077, 10385, 10290, 10801, 10192, 10313, 10385, 10290, 10313, 9961, 9806, - 10192, 10037, 26476, 26551, 26662, 31015, 30905, 30661, 12127, 11940, 12075, 29786, 29579, - 29696, 29696, 29579, 29515, 31677, 31655, 31641, 31577, 31754, 31552, 31826, 31655, 31677, - 31777, 31758, 31783, 32118, 31656, 32040, 23283, 23350, 23308, 23454, 23575, 23627, 23733, - 24227, 23976, 24091, 24227, 24193, 23164, 22658, 22650, 9539, 9757, 9641, 10974, 11046, - 11065, 10502, 10795, 10942, 26662, 26551, 26836, 32332, 32146, 32162, 32349, 32078, 32132, - 9482, 9709, 9780, 18587, 19335, 19338, 32287, 32132, 32180, 9599, 9628, 9646, 9627, - 9691, 9728, 9627, 9728, 9661, 9860, 10116, 9784, 9661, 9728, 9717, 24484, 23756, - 24129, 11940, 11832, 12017, 11834, 11881, 11956, 11807, 11881, 11631, 11236, 11338, 11277, - 27987, 27965, 27939, 26896, 26948, 27104, 10974, 11065, 10833, 11132, 11236, 11277, 14590, - 14498, 14659, 27026, 26948, 26989, 27646, 27494, 27655, 26089, 26525, 26391, 27023, 27185, - 27101, 27147, 27185, 27023, 30344, 30535, 30332, 30073, 30019, 29957, 30813, 30483, 30740, - 30367, 30535, 30344, 30569, 30667, 30552, 12465, 12433, 12491, 11730, 11762, 12127, 12127, - 11762, 11940, 11653, 11709, 11832, 12597, 12565, 12465, 12782, 12655, 12852, 12757, 12782, - 12977, 13023, 13247, 13303, 28898, 29276, 28582, 29435, 29482, 29552, 29679, 29833, 29637, - 29637, 29833, 29684, 29912, 30016, 29761, 28745, 29048, 28898, 28704, 28803, 28745, 28656, - 28324, 28613, 27990, 28008, 28613, 28845, 28643, 28594, 28487, 28577, 28395, 28395, 28269, - 28329, 28329, 28269, 28155, 28155, 28330, 28141, 28141, 28080, 27939, 29129, 28853, 28907, - 29129, 28957, 29270, 29129, 29270, 29225, 12655, 12565, 12769, 28853, 28643, 28845, 27990, - 27717, 28008, 13065, 13023, 13095, 13386, 13303, 13463, 20611, 20774, 20823, 20517, 20428, - 20228, 20228, 20186, 20194, 20194, 20186, 20031, 19672, 19324, 19932, 28643, 28539, 28594, - 28008, 27717, 27715, 29558, 29270, 29414, 32295, 32362, 32162, 32258, 32362, 32295, 32375, - 32362, 32258, 10218, 10156, 10294, 10136, 10492, 10539, 10295, 10539, 10259, 14304, 14256, - 14358, 20611, 20521, 20517, 26825, 26662, 26836, 30099, 30073, 29883, 30016, 29835, 29761, - 30687, 30667, 30569, 20521, 20428, 20517, 32381, 32148, 32089, 9564, 9493, 9662, 9614, - 9539, 9641, 9422, 9493, 9564, 9599, 9646, 9597, 9706, 9885, 9785, 9597, 9646, - 9676, 12565, 12433, 12465, 20428, 20364, 20228, 27965, 27839, 27590, 27987, 27839, 27965, - 30116, 29792, 29717, 29579, 29558, 29414, 32362, 32332, 32162, 32432, 32381, 32089, 9706, - 9785, 9411, 18519, 18447, 18416, 18209, 17938, 18151, 18411, 18447, 18519, 22192, 22133, - 22220, 20823, 20774, 21066, 22192, 22220, 22265, 23664, 24227, 23733, 25975, 25819, 25610, - 31730, 31767, 31762, 31591, 31476, 31460, 29132, 29276, 28898, 20364, 20186, 20228, 26179, - 26147, 26258, 25407, 25509, 25270, 26182, 26147, 26179, 26057, 26147, 26209, 10313, 10290, - 10385, 9769, 10313, 10192, 32308, 31824, 31856, 31928, 31826, 31677, 11046, 11132, 11292, - 12005, 11958, 11807, 10974, 11132, 11046, 27185, 27261, 27214, 26904, 27147, 27023, 30535, - 30577, 30472, 30307, 30367, 30317, 30384, 30367, 30307, 13581, 13871, 13832, 28374, 28269, - 28395, 29276, 29377, 29435, 10156, 10044, 10251, 26948, 26825, 26836, 26182, 26179, 26380, - 26896, 26825, 26948, 26904, 27082, 27147, 25567, 25610, 25173, 30716, 30577, 30535, 27839, - 27752, 27655, 27827, 27752, 27839, 9597, 9676, 9485, 9576, 9676, 9659, 9625, 9661, - 9717, 13832, 13871, 14060, 14498, 14304, 14358, 19941, 19932, 20031, 20774, 21348, 21066, - 22265, 22220, 22451, 27539, 27404, 27494, 32271, 32307, 32200, 32322, 32307, 32271, 9438, - 9539, 9614, 29641, 29558, 29579, 23756, 23205, 23797, 23350, 23575, 23454, 22650, 22658, - 22323, 23520, 23575, 23350, 10880, 10854, 10758, 10156, 10029, 10044, 11652, 11781, 11124, - 11574, 11641, 11637, 31665, 30813, 30740, 29786, 29696, 29792, 9527, 9904, 9628, 9576, - 9659, 9627, 22376, 22265, 22451, 21348, 21660, 21377, 32307, 32287, 32180, 32038, 31874, - 32310, 32322, 32287, 32307, 11525, 11574, 11637, 11709, 11890, 11832, 11881, 11958, 12031, - 13378, 13261, 14174, 11958, 11881, 11807, 14124, 14065, 14256, 28330, 28080, 28141, 29833, - 29761, 29684, 30278, 30384, 30307, 9518, 9576, 9627, 9706, 9625, 9717, 9568, 9625, - 9706, 9539, 9552, 9757, 9353, 9482, 9250, 9784, 10116, 10221, 9826, 9783, 9857, - 31901, 31874, 31783, 31655, 31826, 31577, 31507, 31497, 31426, 32118, 32040, 32078, 27324, - 27261, 27185, 27324, 27185, 27147, 31465, 31355, 31287, 31191, 31202, 31156, 31309, 31202, - 31094, 31346, 31202, 31309, 30990, 30949, 31309, 31015, 30661, 30667, 23164, 23283, 23308, - 23416, 23283, 23164, 26147, 26057, 25940, 26179, 26476, 26380, 27363, 27169, 27404, 28080, - 27987, 27939, 30577, 30687, 30569, 30716, 30687, 30577, 30621, 30535, 30367, 32349, 32118, - 32078, 23575, 23664, 23627, 23520, 23664, 23575, 14304, 14124, 14256, 26380, 26476, 26571, - 30016, 30099, 29883, 30138, 30099, 30130, 9527, 9628, 9554, 19324, 18587, 19338, 18447, - 18411, 18209, 32280, 32167, 31852, 32169, 32350, 31909, 32084, 31852, 31936, 28803, 28895, - 28745, 29441, 29482, 29377, 29679, 29637, 29552, 28656, 28895, 28803, 28844, 28895, 28656, - 28844, 28656, 28613, 11762, 11832, 11940, 12565, 12636, 12433, 12655, 12636, 12565, 12757, - 12636, 12655, 12757, 12977, 13023, 13023, 13303, 13095, 28895, 29048, 28745, 29482, 29435, - 29377, 29048, 29132, 28898, 10854, 10728, 10758, 10640, 10728, 10676, 13095, 13303, 13182, - 13303, 13386, 13182, 24227, 24441, 24193, 24258, 24441, 24227, 27404, 27169, 27288, 26825, - 26734, 26662, 27104, 27169, 27229, 28539, 28577, 28487, 28269, 28330, 28155, 28080, 28100, - 27987, 28807, 28577, 28539, 28807, 28539, 28643, 29056, 28643, 28853, 29056, 28853, 29304, - 29437, 29225, 29270, 30278, 30019, 30073, 31907, 31677, 31777, 31270, 31665, 30740, 31893, - 31777, 31874, 27104, 26948, 27026, 32038, 31893, 31874, 10058, 10136, 9989, 9770, 9783, - 9860, 25293, 25197, 25143, 31594, 31497, 31507, 13182, 13386, 13368, 11525, 11709, 11542, - 11124, 11781, 11641, 14124, 13832, 14060, 29833, 29912, 29761, 30138, 30278, 30073, 29889, - 29912, 29833, 9554, 9628, 9599, 9554, 9599, 9447, 9518, 9627, 9661, 9676, 9576, - 9555, 13368, 13463, 13581, 12939, 13261, 13284, 21660, 21459, 21377, 23101, 22489, 22423, - 10076, 10029, 10156, 31465, 31287, 31366, 32299, 32312, 32167, 13287, 13368, 13581, 28374, - 28330, 28269, 27363, 27404, 27539, 29441, 29377, 29276, 15586, 15675, 15997, 18168, 18662, - 17836, 14774, 14599, 14633, 9511, 9599, 9597, 32515, 32350, 32169, 25499, 25567, 25173, - 26824, 26847, 26904, 14990, 14590, 14659, 14498, 14279, 14304, 13989, 13890, 14124, 13590, - 13502, 13832, 14852, 14590, 14990, 20611, 20557, 20521, 20521, 20557, 20428, 20428, 20436, - 20364, 20364, 20293, 20186, 20186, 20094, 20031, 21536, 21459, 21660, 27169, 27104, 27026, - 26571, 26476, 26662, 27655, 27752, 27646, 9376, 9432, 9886, 9493, 9438, 9614, 9539, - 9451, 9552, 9376, 9886, 9319, 9471, 9500, 9527, 11709, 11525, 11637, 11487, 11525, - 11542, 20695, 20557, 20611, 21802, 21536, 21660, 27591, 27722, 27459, 27591, 27459, 27261, - 9432, 9422, 9571, 20557, 20436, 20428, 18440, 18411, 18587, 11958, 12005, 12031, 11881, - 11834, 11631, 18587, 18411, 18519, 18209, 18411, 18139, 23205, 23101, 22423, 23622, 23101, - 23205, 22785, 23101, 22904, 27646, 27752, 27827, 29558, 29437, 29270, 29786, 29641, 29579, - 29786, 29792, 29857, 30138, 30073, 30099, 30851, 30716, 30535, 31875, 31754, 31577, 31893, - 31907, 31777, 32038, 31907, 31893, 26525, 26089, 25975, 30687, 30820, 30667, 30621, 30367, - 30384, 26571, 26662, 26646, 26182, 26209, 26147, 26057, 25890, 25601, 9422, 9438, 9493, - 9552, 9400, 9604, 9860, 9783, 9826, 9770, 9860, 9784, 31875, 31577, 31826, 31591, - 31748, 31476, 31366, 31287, 31269, 31591, 31751, 31748, 31346, 31269, 31202, 20141, 20094, - 20186, 29482, 29679, 29552, 30085, 30099, 30016, 27827, 27839, 28100, 27722, 28008, 27715, - 27474, 27591, 27261, 26734, 26825, 26902, 25975, 26089, 25819, 32167, 32312, 31877, 32084, - 31936, 32122, 32450, 32322, 32271, 32287, 32338, 32132, 32038, 31928, 31907, 32122, 31936, - 31767, 9438, 9450, 9539, 11132, 11053, 11236, 10833, 11065, 10861, 10963, 10974, 10833, - 21965, 21660, 22024, 27243, 27324, 27147, 27082, 26904, 26847, 28007, 28008, 27722, 29857, - 29792, 30116, 10136, 10076, 10156, 9784, 10221, 10044, 10058, 10076, 10136, 31497, 31630, - 31270, 31747, 31594, 31507, 9450, 9451, 9539, 22133, 22187, 21965, 31907, 31928, 31677, - 31754, 31747, 31507, 31874, 31901, 32308, 9485, 9511, 9597, 9554, 9471, 9527, 9485, - 9676, 9555, 21975, 21361, 21734, 23283, 23416, 23350, 21361, 21030, 21734, 20579, 20270, - 20366, 32322, 32338, 32287, 26902, 26825, 26896, 27041, 26896, 27104, 27229, 27169, 27328, - 26525, 26745, 26391, 30716, 30820, 30687, 30851, 30820, 30716, 9952, 10044, 10029, 9517, - 9568, 9706, 27646, 27539, 27494, 27776, 27539, 27646, 30278, 30422, 30384, 30085, 30016, - 29912, 31262, 30949, 30905, 25567, 25975, 25610, 26525, 26651, 26745, 29132, 29220, 29276, - 29482, 29719, 29679, 29222, 29220, 29132, 29222, 29132, 29048, 29222, 29048, 29201, 22376, - 22192, 22265, 22376, 22451, 22489, 32466, 32432, 31909, 32579, 32477, 32375, 32375, 32477, - 32362, 32362, 32577, 32332, 32529, 32450, 32271, 32322, 32412, 32338, 32466, 31909, 32350, - 26330, 26321, 25975, 25197, 25499, 25173, 25293, 25499, 25197, 26344, 26209, 26380, 26380, - 26209, 26182, 26344, 26380, 26412, 32004, 31747, 31754, 31697, 31751, 31591, 31949, 31922, - 31730, 31697, 31591, 31465, 9525, 9661, 9625, 9414, 9471, 9554, 22358, 22376, 22482, - 29304, 28853, 29129, 28577, 28374, 28395, 29459, 29437, 29558, 29459, 29558, 29641, 29220, - 29441, 29276, 30049, 30085, 29912, 10963, 11053, 11132, 27328, 27169, 27363, 10728, 10640, - 10758, 10676, 10728, 10854, 11124, 11641, 11574, 14633, 14599, 13996, 9525, 9568, 9517, - 28330, 28341, 28080, 28692, 28374, 28577, 32280, 32299, 32167, 32673, 32466, 32680, 21965, - 22024, 22133, 32515, 32169, 32312, 9447, 9599, 9511, 9518, 9555, 9576, 31949, 31476, - 31748, 32084, 32280, 31852, 10076, 9974, 10029, 10295, 10136, 10539, 31699, 31616, 31594, - 31594, 31616, 31497, 13396, 13287, 13581, 13368, 13283, 13182, 12898, 12915, 13095, 12915, - 12757, 13065, 13065, 12757, 13023, 12127, 12294, 11730, 13502, 13581, 13832, 28374, 28341, - 28330, 10868, 10676, 10880, 26734, 26646, 26662, 26755, 26646, 26734, 26580, 26651, 26525, - 26963, 27082, 26847, 23388, 23416, 23164, 23664, 24258, 24227, 24878, 25197, 24961, 11525, - 11487, 11574, 12294, 12433, 11730, 29889, 29833, 29679, 30138, 30422, 30278, 9447, 9511, - 9425, 10974, 10963, 11132, 11050, 11834, 11236, 10833, 10861, 10403, 22187, 22133, 22192, - 27324, 27337, 27261, 27756, 28007, 27722, 26850, 26847, 26745, 27256, 27337, 27324, 30515, - 30422, 30138, 26209, 26108, 26057, 26344, 26108, 26209, 31346, 31366, 31269, 32037, 31949, - 31748, 31458, 31366, 31346, 31015, 30667, 30820, 16728, 15280, 15893, 13590, 13832, 13610, - 15785, 15280, 16728, 26852, 26850, 26745, 11999, 12433, 12636, 11745, 11807, 11631, 11869, - 12939, 13284, 13832, 14124, 13890, 20366, 20270, 20088, 23388, 23520, 23416, 10292, 10942, - 10801, 10292, 10801, 10290, 26412, 26380, 26571, 18139, 18047, 18209, 18440, 18587, 18486, - 23416, 23520, 23350, 22443, 22323, 22235, 17391, 17128, 17506, 17492, 17391, 17506, 20823, - 20753, 20695, 20695, 20753, 20557, 20557, 20585, 20436, 20436, 20378, 20364, 18611, 18587, - 18847, 20878, 20753, 20823, 20878, 20823, 21066, 21348, 21377, 21066, 21377, 21340, 21066, - 21459, 21340, 21377, 30154, 30130, 30085, 30085, 30130, 30099, 31992, 31875, 31826, 31699, - 31630, 31616, 32308, 31856, 32118, 32579, 32375, 32381, 32577, 32477, 32579, 20753, 20585, - 20557, 9425, 9511, 9485, 9525, 9518, 9661, 9525, 9625, 9568, 9319, 9886, 9500, - 9266, 9295, 9422, 9422, 9379, 9438, 9438, 9382, 9450, 9450, 9311, 9451, 19941, - 20031, 20094, 21459, 21542, 21340, 32378, 32280, 32084, 32299, 32377, 32312, 20585, 20378, - 20436, 29304, 29129, 29225, 28374, 28495, 28341, 11762, 11653, 11832, 13095, 12975, 12898, - 12915, 13065, 13095, 11469, 11542, 11653, 13283, 13368, 13287, 14124, 14304, 14059, 19559, - 19333, 20088, 18168, 18904, 18662, 18168, 17751, 18073, 20378, 20293, 20364, 21459, 21536, - 21542, 21975, 22110, 22235, 24878, 24517, 24441, 26321, 26580, 25975, 25975, 26580, 26525, - 26852, 26963, 26850, 26777, 26580, 26711, 29786, 29758, 29641, 29349, 29304, 29225, 30116, - 29717, 30724, 30116, 30165, 30089, 31096, 31015, 30820, 31616, 31630, 31497, 31699, 31594, - 31850, 32529, 32807, 32625, 32338, 32349, 32132, 29056, 28807, 28643, 28804, 28844, 28613, - 29220, 29362, 29441, 29441, 29548, 29482, 28858, 28844, 28804, 29084, 29048, 28895, 9295, - 9379, 9422, 9523, 10153, 9709, 20293, 20141, 20186, 27148, 27041, 27104, 26690, 26412, - 26571, 27496, 27328, 27363, 27496, 27363, 27539, 27839, 27987, 28100, 30422, 30482, 30384, - 30474, 30482, 30422, 14774, 15186, 15444, 13996, 14599, 14174, 27148, 27104, 27229, 13283, - 13287, 13396, 13261, 13616, 14174, 11869, 13284, 12005, 28807, 28692, 28577, 9379, 9382, - 9438, 32399, 32377, 32299, 9425, 9485, 9555, 9408, 9402, 9500, 22110, 22157, 22235, - 32450, 32412, 32322, 32606, 32412, 32450, 10058, 9974, 10076, 9785, 9338, 9411, 9989, - 9974, 10058, 10539, 10758, 10259, 11499, 11542, 11469, 11653, 11542, 11709, 11487, 11334, - 11574, 10599, 10533, 10676, 14279, 14498, 14590, 16792, 15785, 16728, 18047, 17938, 18209, - 17974, 17938, 18047, 26902, 26755, 26734, 31935, 31697, 31465, 31922, 32122, 31767, 29703, - 29459, 29641, 29362, 29548, 29441, 10259, 10758, 10640, 21763, 21536, 21802, 26221, 26036, - 26108, 26108, 26036, 26057, 26432, 26108, 26344, 24233, 24258, 23664, 31992, 31826, 31928, - 31843, 31748, 31751, 13396, 13581, 13409, 29548, 29639, 29482, 25890, 25509, 25407, 9857, - 9783, 9481, 9455, 9425, 9555, 23101, 22785, 22489, 21830, 21763, 21965, 21965, 21763, - 21802, 23622, 23205, 23756, 27337, 27474, 27261, 27082, 27243, 27147, 27223, 27243, 27082, - 26963, 26847, 26850, 30482, 30621, 30384, 30474, 30621, 30482, 30756, 30621, 30818, 28100, - 28080, 28217, 29857, 29758, 29786, 29857, 30116, 30089, 27041, 26902, 26896, 26690, 26571, - 26646, 27134, 26902, 27041, 27148, 27229, 27161, 26852, 26745, 26651, 30756, 30851, 30535, - 27606, 27496, 27539, 27256, 27474, 27337, 14633, 15186, 14774, 15675, 16176, 16491, 26690, - 26646, 26755, 11745, 11909, 12005, 11745, 12005, 11807, 13409, 13581, 13502, 13409, 13502, - 13590, 29639, 29719, 29482, 17938, 17862, 18151, 17391, 17286, 17128, 17974, 17862, 17938, - 24484, 23622, 23756, 9455, 9555, 9518, 9408, 9500, 9471, 9408, 9471, 9414, 11050, - 11236, 11053, 13293, 13409, 13590, 18847, 18587, 19324, 18440, 18139, 18411, 23622, 22904, - 23101, 22187, 22192, 22376, 26869, 26690, 26755, 32280, 32399, 32299, 32377, 32515, 32312, - 32579, 32808, 32765, 32378, 32399, 32280, 11320, 11334, 11487, 10172, 10259, 10640, 11499, - 11487, 11542, 14279, 14315, 14185, 27827, 27776, 27646, 27714, 27776, 27875, 22187, 22376, - 22358, 31850, 31594, 31747, 31630, 31665, 31270, 9712, 9784, 10044, 9434, 9806, 10037, - 9780, 9604, 9400, 17375, 17286, 17391, 16572, 16778, 16915, 24258, 24434, 24441, 24607, - 24434, 24233, 17777, 17492, 17506, 9414, 9554, 9416, 9446, 9455, 9518, 22335, 22443, - 22235, 23520, 23600, 23664, 26902, 26913, 26755, 27266, 27229, 27328, 27266, 27328, 27406, - 30621, 30756, 30535, 30474, 30422, 30515, 10934, 11050, 11053, 10934, 11053, 10963, 14258, - 14279, 14185, 30221, 30138, 30130, 11466, 11631, 11834, 17862, 17777, 17767, 18320, 18139, - 18440, 23354, 23388, 23204, 28217, 28080, 28341, 29770, 29889, 29679, 9554, 9447, 9416, - 10295, 9989, 10136, 9974, 9952, 10029, 10533, 10640, 10676, 10170, 10292, 10290, 10403, - 10861, 10795, 26036, 25890, 26057, 26221, 25890, 26036, 26432, 26344, 26412, 31262, 31309, - 30949, 31366, 31556, 31465, 31262, 30905, 31015, 31096, 30820, 30851, 31309, 31458, 31346, - 31697, 31843, 31751, 27223, 27256, 27243, 27243, 27256, 27324, 26777, 26852, 26651, 26777, - 26651, 26580, 17834, 17777, 17862, 12757, 12599, 12636, 12716, 12599, 12757, 12716, 12757, - 12915, 12716, 12915, 12856, 12915, 12898, 12856, 29056, 29016, 28807, 28807, 28888, 28692, - 28692, 28495, 28374, 29304, 29016, 29056, 29225, 29437, 29349, 29222, 29362, 29220, 29655, - 29719, 29639, 29655, 29770, 29719, 29719, 29770, 29679, 29102, 29084, 28895, 29102, 28895, - 28844, 9680, 9783, 9770, 9525, 9446, 9518, 9400, 9552, 9318, 18611, 18486, 18587, - 18585, 18486, 18611, 31458, 31556, 31366, 32675, 32349, 32338, 32038, 31992, 31928, 13182, - 12975, 13095, 29084, 29201, 29048, 31953, 31843, 31935, 31949, 32000, 31922, 27776, 27606, - 27539, 27714, 27606, 27776, 9318, 9552, 9451, 13182, 13086, 12975, 32529, 32875, 32807, - 32412, 32568, 32338, 13218, 13616, 13261, 14378, 15370, 15186, 27756, 27722, 27591, 27555, - 27591, 27474, 13182, 13283, 13086, 13283, 13396, 13171, 13086, 13283, 13171, 9447, 9425, - 9419, 9416, 9447, 9419, 10599, 10676, 10868, 16572, 16915, 17128, 14279, 14590, 14315, - 27406, 27328, 27496, 27134, 26913, 26902, 27052, 27082, 26963, 32141, 31992, 32038, 32052, - 31850, 31747, 32037, 32000, 31949, 32529, 32493, 32450, 17286, 16572, 17128, 17492, 17375, - 17391, 17366, 17375, 17492, 23388, 23500, 23520, 23354, 23500, 23388, 10705, 10833, 10403, - 27055, 27052, 26963, 9928, 9989, 10295, 18964, 18847, 19324, 20753, 20603, 20585, 20585, - 20603, 20378, 20305, 20119, 20293, 20293, 20119, 20141, 20141, 20119, 20094, 20733, 20603, - 20753, 20733, 20753, 20810, 20753, 20878, 20810, 20878, 20988, 20810, 20878, 21066, 20988, - 32479, 32515, 32377, 32451, 32378, 32478, 32477, 32577, 32362, 32529, 32625, 32493, 32381, - 32896, 32808, 20988, 21066, 21025, 32673, 32432, 32466, 13171, 13396, 13293, 28718, 28495, - 28692, 28100, 28098, 27827, 10478, 10599, 10576, 11320, 11499, 11283, 27544, 27555, 27474, - 29889, 30049, 29912, 29941, 30049, 29889, 9266, 9422, 9432, 9379, 9307, 9382, 9382, - 9311, 9450, 9266, 9432, 9376, 9319, 9500, 9402, 9319, 9402, 9322, 19333, 20366, - 20088, 22087, 22157, 22110, 22087, 22276, 22157, 22157, 22276, 22235, 21025, 21066, 21340, - 9419, 9425, 9455, 9322, 9402, 9331, 11124, 11574, 11334, 25975, 26187, 26330, 26852, - 27055, 26963, 25329, 25499, 25293, 13101, 13171, 13274, 13881, 13832, 13890, 13029, 13218, - 13261, 13029, 13261, 12939, 12842, 12939, 12396, 11725, 11909, 11745, 9240, 9307, 9379, - 9913, 9952, 9974, 16425, 16572, 17286, 20305, 20293, 20378, 31699, 31838, 31630, 31978, - 31754, 31875, 10403, 10795, 10502, 9961, 10170, 10290, 11499, 11320, 11487, 11289, 11320, - 11283, 13989, 13881, 13890, 14258, 14304, 14279, 18139, 17974, 18047, 17629, 17366, 17492, - 18032, 17974, 18139, 18032, 18139, 18320, 22376, 22489, 22482, 21680, 21542, 21536, 30049, - 30154, 30085, 30875, 30818, 30621, 30246, 30154, 30049, 9307, 9311, 9382, 10833, 10934, - 10963, 11708, 11745, 11631, 11050, 10934, 10928, 11708, 11725, 11745, 11708, 11631, 11437, - 27266, 27161, 27229, 26532, 26432, 26412, 27406, 27161, 27266, 27532, 27496, 27606, 27256, - 27544, 27474, 27052, 27223, 27082, 27113, 27223, 27052, 29920, 29758, 29857, 29655, 29639, - 29548, 14315, 14852, 14697, 32000, 32122, 31922, 32186, 32122, 32000, 31992, 31972, 31875, - 32141, 31972, 31992, 9402, 9336, 9331, 27134, 27041, 27148, 9654, 9680, 9770, 9654, - 9770, 9784, 26532, 26412, 26690, 9402, 9408, 9336, 9352, 9419, 9455, 9446, 9525, - 9517, 22087, 22110, 21975, 23204, 23388, 23164, 28288, 28217, 28341, 9408, 9345, 9336, - 9470, 9446, 9517, 18847, 18683, 18611, 18572, 18683, 18714, 25143, 25329, 25293, 25475, - 25329, 25279, 13881, 13610, 13832, 14059, 13989, 14124, 27936, 27776, 27827, 27555, 27756, - 27591, 28858, 29102, 28844, 27645, 27756, 27555, 30154, 30221, 30130, 30756, 30818, 30851, - 30246, 30221, 30154, 9408, 9414, 9345, 9311, 9318, 9451, 9434, 9523, 9403, 21680, - 21536, 21763, 9482, 9523, 9709, 9523, 9482, 9403, 15109, 15080, 14912, 14989, 15080, - 15109, 17974, 17834, 17862, 17375, 17366, 17286, 18032, 17834, 17974, 28217, 28098, 28100, - 29201, 29333, 29222, 29084, 29174, 29201, 28613, 28008, 28804, 30089, 29920, 29857, 30089, - 30165, 30061, 29962, 29941, 29889, 29962, 29889, 29770, 22276, 22335, 22235, 22410, 22335, - 22276, 29102, 29174, 29084, 27161, 27206, 27148, 27441, 27406, 27496, 30928, 30818, 30875, - 21830, 21680, 21763, 29016, 28888, 28807, 28495, 28472, 28341, 28217, 28209, 28098, 29101, - 28888, 29016, 29437, 29459, 29349, 28804, 28008, 28347, 29349, 29459, 29616, 29174, 29333, - 29201, 9989, 9913, 9974, 9952, 9712, 10044, 9928, 9913, 9989, 9928, 9811, 9881, - 10172, 10640, 10533, 31850, 31846, 31699, 31952, 31846, 31850, 11469, 11653, 11762, 12558, - 12367, 12599, 12856, 12558, 12716, 12898, 12795, 12856, 12975, 12795, 12898, 12698, 12795, - 12975, 13101, 12975, 13086, 13101, 13086, 13171, 11869, 12005, 11909, 28888, 28850, 28692, - 28347, 28008, 28007, 29703, 29641, 29758, 29333, 29362, 29222, 18683, 18585, 18611, 18572, - 18585, 18683, 9345, 9414, 9348, 9680, 9654, 9478, 9411, 9470, 9517, 11289, 11124, - 11334, 11289, 11334, 11320, 14258, 14059, 14304, 13750, 13610, 13881, 14073, 14059, 14258, - 31972, 31978, 31875, 32144, 31978, 31972, 31993, 32037, 31748, 31953, 31748, 31843, 13750, - 13881, 13797, 29788, 29703, 29758, 30061, 30165, 30043, 31556, 31625, 31465, 31458, 31474, - 31556, 31309, 31474, 31458, 31718, 31474, 31309, 19480, 18964, 19324, 32535, 32377, 32399, - 32422, 32399, 32378, 32422, 32378, 32451, 12842, 13029, 12939, 13294, 13996, 13616, 23500, - 23600, 23520, 22650, 22323, 22443, 31619, 31625, 31556, 21959, 21830, 21965, 25475, 25567, - 25499, 27009, 27055, 26852, 31935, 31843, 31697, 9367, 9470, 9411, 9072, 9352, 9455, - 9348, 9414, 9416, 13293, 13396, 13409, 28718, 28472, 28495, 29897, 29758, 29991, 29693, - 29655, 29548, 32378, 32421, 32478, 15370, 16176, 15675, 13568, 13293, 13590, 13797, 13881, - 13989, 26432, 26221, 26108, 25510, 25286, 25509, 25509, 25286, 25270, 26589, 26532, 26690, - 26935, 26755, 26913, 26321, 26582, 26580, 27534, 27544, 27256, 26962, 26852, 26777, 28060, - 27936, 28098, 28098, 27936, 27827, 27734, 27532, 27606, 30818, 30858, 30851, 30928, 30858, - 30818, 32654, 32479, 32377, 32680, 32466, 32350, 9348, 9416, 9252, 22489, 22641, 22482, - 21917, 21959, 22032, 22187, 21959, 21965, 32666, 32625, 32807, 32493, 32606, 32450, 32310, - 32141, 32038, 14059, 13797, 13989, 14185, 14073, 14258, 27406, 27206, 27161, 27734, 27606, - 27714, 27534, 27256, 27497, 27756, 28347, 28007, 32308, 32118, 32555, 31978, 32004, 31754, - 17629, 17492, 17777, 17629, 17777, 17834, 18320, 18440, 18486, 18320, 18486, 18396, 25971, - 25509, 25890, 22489, 22785, 22641, 9352, 9416, 9419, 9806, 9762, 10192, 9586, 9762, - 9806, 10599, 10478, 10533, 10576, 10599, 10868, 26592, 26711, 26580, 32136, 32004, 31978, - 32037, 32088, 32000, 31953, 31993, 31748, 31973, 31993, 31953, 32612, 32596, 32479, 32535, - 32451, 32478, 11725, 11791, 11909, 11466, 11834, 11223, 13568, 13590, 13610, 22511, 22650, - 22443, 22511, 22443, 22335, 28472, 28288, 28341, 9218, 9319, 9322, 9110, 9376, 9319, - 9110, 9266, 9376, 9295, 9240, 9379, 9307, 9251, 9311, 9311, 9267, 9318, 9218, - 9322, 9331, 9218, 9331, 9183, 9331, 9336, 9228, 10401, 10439, 10478, 12367, 12636, - 12599, 17733, 17629, 17834, 20603, 20305, 20378, 20119, 19941, 20094, 20733, 20700, 20603, - 20810, 20700, 20733, 20841, 20700, 20810, 20841, 20810, 20988, 20841, 20988, 20868, 21340, - 21487, 21025, 21542, 21487, 21340, 27936, 27875, 27776, 28016, 27875, 27936, 30221, 30341, - 30138, 30175, 30246, 30049, 30175, 30049, 29941, 32555, 32118, 32349, 21542, 21524, 21487, - 27441, 27206, 27406, 27441, 27496, 27532, 21841, 22087, 21975, 32625, 32606, 32493, 9266, - 9240, 9295, 9190, 9224, 9400, 10928, 10991, 11050, 10928, 10934, 10705, 21542, 21680, - 21524, 27510, 27441, 27532, 31625, 31935, 31465, 26325, 26221, 26432, 26325, 26432, 26520, - 28288, 28209, 28217, 29970, 29962, 29770, 31474, 31619, 31556, 32064, 31973, 31935, 31718, - 31619, 31474, 27134, 26935, 26913, 9240, 9251, 9307, 23354, 23600, 23500, 23508, 23600, - 23354, 12558, 12599, 12716, 12558, 12856, 12795, 12558, 12795, 12634, 18512, 18486, 18585, - 18032, 17733, 17834, 23077, 23204, 23164, 25329, 25475, 25499, 26321, 26443, 26582, 26582, - 26592, 26580, 24607, 24441, 24434, 26330, 26443, 26321, 29578, 29596, 29362, 29362, 29596, - 29548, 29655, 29793, 29770, 29174, 29267, 29333, 29102, 29267, 29174, 28858, 29123, 29102, - 29145, 29123, 28858, 29267, 29123, 29309, 32606, 32568, 32412, 27875, 27734, 27714, 27945, - 27734, 27875, 30246, 30341, 30221, 30383, 30341, 30246, 12634, 12795, 12698, 9251, 9267, - 9311, 20305, 20008, 20119, 18714, 18683, 18847, 24233, 24434, 24258, 32369, 32144, 32141, - 32141, 32144, 31972, 11549, 11469, 11762, 11223, 11834, 11050, 13507, 13568, 13610, 13293, - 13274, 13171, 13507, 13610, 13750, 30089, 30061, 29920, 29717, 30526, 30724, 20008, 19941, - 20119, 28850, 28791, 28692, 28472, 28460, 28288, 28288, 28294, 28209, 28945, 28791, 28850, - 28945, 28850, 28888, 29101, 29016, 29427, 29427, 29304, 29349, 29616, 29459, 29703, 9762, - 9769, 10192, 10705, 10934, 10833, 9586, 9769, 9762, 24607, 24878, 24441, 32103, 32052, - 32004, 32004, 32052, 31747, 31846, 31838, 31699, 9913, 9845, 9952, 9928, 10295, 9811, - 10478, 10439, 10533, 10576, 10868, 10457, 11652, 11124, 10999, 26869, 26589, 26690, 26605, - 26592, 26582, 27009, 27113, 27055, 27055, 27113, 27052, 31952, 31838, 31846, 9072, 9455, - 9446, 9228, 9336, 9239, 11375, 11437, 11466, 10502, 10309, 10403, 9336, 9345, 9239, - 10502, 10292, 10309, 21524, 21680, 21595, 26935, 26869, 26755, 27206, 27134, 27148, 27183, - 27134, 27206, 27183, 27206, 27383, 27009, 26852, 26962, 28791, 28718, 28692, 29788, 29616, - 29703, 29490, 29362, 29333, 30858, 31036, 30851, 30875, 30621, 30877, 18168, 17836, 17751, - 20697, 20746, 20366, 23204, 23235, 23354, 24831, 24811, 24607, 23256, 23235, 23204, 23077, - 23164, 22650, 27544, 27645, 27555, 27534, 27645, 27544, 30341, 30515, 30138, 30383, 30515, - 30341, 30383, 30246, 30405, 21595, 21680, 21635, 28166, 28060, 28098, 27734, 27510, 27532, - 28166, 28098, 28209, 29596, 29693, 29548, 9928, 9845, 9913, 10999, 11124, 10986, 26958, - 26869, 26935, 32051, 31952, 31850, 22785, 22904, 22641, 21635, 21680, 21733, 32680, 32350, - 32756, 32579, 32765, 32577, 32529, 32105, 32875, 32625, 32665, 32606, 32606, 32665, 32568, - 32350, 32515, 32713, 11841, 11730, 12433, 11527, 11791, 11708, 11708, 11791, 11725, 12932, - 13048, 13029, 28565, 28460, 28472, 29897, 29788, 29758, 9470, 9367, 9446, 9785, 9857, - 9300, 9783, 9680, 9481, 18714, 18847, 18964, 17782, 17733, 18032, 32052, 32051, 31850, - 32144, 32136, 31978, 32209, 32136, 32144, 31993, 32088, 32037, 32205, 32088, 31993, 31973, - 31953, 31935, 32308, 32310, 31874, 32356, 32310, 32308, 15785, 16792, 16778, 14315, 14590, - 14852, 13443, 13314, 13568, 15255, 15280, 15301, 26221, 25971, 25890, 26520, 26432, 26532, - 26520, 26532, 26589, 26443, 26605, 26582, 26962, 26777, 26711, 26187, 25975, 26143, 9239, - 9345, 9246, 9345, 9348, 9246, 9769, 9961, 10313, 32596, 32515, 32479, 10986, 11124, - 11021, 11730, 11699, 11762, 13314, 13274, 13293, 13314, 13293, 13568, 28460, 28366, 28288, - 29991, 29758, 29920, 32535, 32399, 32422, 32535, 32422, 32451, 9523, 9434, 10037, 9250, - 9780, 9400, 11343, 11499, 11469, 27871, 27510, 27734, 26719, 26589, 26869, 28016, 27936, - 28060, 27497, 27256, 27223, 29145, 28858, 29002, 27497, 27223, 27196, 26962, 26711, 26881, - 30928, 31036, 30858, 31023, 31036, 30928, 32072, 32051, 32052, 32137, 31973, 32064, 26686, - 26520, 26589, 26686, 26589, 26719, 31096, 31262, 31015, 31770, 31935, 31625, 17629, 17471, - 17366, 15295, 15785, 15542, 18234, 18032, 18320, 9246, 9348, 9252, 18572, 18512, 18585, - 18774, 18512, 18572, 32378, 32084, 32421, 11699, 11549, 11762, 13797, 14059, 13895, 28366, - 28294, 28288, 30043, 29920, 30061, 30043, 29991, 29920, 13895, 14059, 14073, 21917, 21830, - 21959, 22641, 22904, 22954, 22410, 22511, 22335, 30877, 30621, 30474, 30109, 29941, 29962, - 32654, 32612, 32479, 32783, 32673, 32680, 9252, 9416, 9352, 32105, 32332, 32875, 32592, - 32555, 32349, 11549, 11457, 11469, 11466, 11437, 11631, 11223, 11050, 11006, 13507, 13443, - 13568, 24878, 25143, 25197, 26462, 26435, 26330, 24607, 24811, 24878, 24233, 23664, 24105, - 28294, 28166, 28209, 30724, 30526, 30813, 29970, 30109, 29962, 30564, 30474, 30515, 31036, - 31096, 30851, 32136, 32103, 32004, 32209, 32103, 32136, 14852, 14912, 14697, 28347, 27756, - 27834, 27196, 27223, 27113, 31361, 30724, 31963, 29427, 29016, 29304, 28791, 28730, 28718, - 28718, 28716, 28472, 28460, 28565, 28366, 28380, 28328, 28294, 28294, 28328, 28166, 29612, - 29349, 29616, 29612, 29616, 29724, 29616, 29788, 29878, 29788, 29897, 29878, 29123, 29267, - 29102, 29596, 29578, 29693, 29693, 29793, 29655, 27756, 27645, 27782, 9190, 9400, 9318, - 12290, 12145, 12367, 11598, 11705, 11730, 11730, 11705, 11699, 11699, 11417, 11549, 11379, - 11356, 11457, 12698, 12975, 13101, 12698, 13101, 12353, 13101, 13274, 13255, 32666, 32665, - 32625, 9360, 9411, 9338, 9072, 9252, 9352, 18512, 18396, 18486, 18292, 18396, 18512, - 22891, 23077, 22650, 23235, 23390, 23354, 17733, 17718, 17629, 17782, 17718, 17733, 13255, - 13274, 13314, 22954, 22904, 23622, 21959, 22187, 22032, 22511, 22567, 22650, 26212, 25971, - 26221, 26212, 26221, 26325, 29073, 28945, 28888, 29473, 29490, 29333, 27009, 27196, 27113, - 26881, 26711, 26592, 31083, 31096, 31036, 13957, 13895, 14073, 13618, 13507, 13750, 13616, - 13996, 14174, 15186, 15370, 15675, 13294, 13616, 13218, 13048, 13218, 13029, 20700, 20305, - 20603, 20008, 20012, 19941, 20841, 20780, 20700, 20868, 20780, 20841, 20868, 20988, 21025, - 20868, 21025, 20926, 21025, 21012, 20926, 32808, 32579, 32381, 32666, 32738, 32665, 32381, - 32432, 32896, 21595, 21487, 21524, 24998, 25143, 24878, 29921, 29897, 29991, 29490, 29578, - 29362, 31838, 31665, 31630, 32235, 31665, 31838, 32235, 31838, 31952, 32072, 31952, 32051, - 11356, 11343, 11457, 11457, 11343, 11469, 13618, 13750, 13797, 13443, 13255, 13314, 30043, - 30029, 29991, 30724, 30165, 30116, 30109, 30175, 29941, 30383, 30564, 30515, 30310, 30175, - 30109, 32753, 32432, 32673, 15280, 15255, 15109, 15785, 16778, 16572, 26330, 26435, 26443, - 25975, 25567, 26143, 20731, 20305, 20700, 18855, 18714, 18964, 11791, 11869, 11909, 11625, - 11869, 11791, 28730, 28716, 28718, 9093, 9190, 9318, 9251, 9188, 9267, 9240, 9188, - 9251, 8861, 9188, 9240, 9058, 9188, 8861, 9178, 9319, 9218, 9178, 9218, 9118, - 9331, 9228, 9183, 19816, 19932, 19941, 14868, 14912, 15080, 14185, 13957, 14073, 24105, - 23664, 23600, 25199, 25279, 25143, 32088, 32186, 32000, 32205, 32186, 32088, 32137, 31993, - 31973, 9353, 9403, 9482, 9371, 9586, 9806, 32421, 32084, 32122, 32735, 32713, 32885, - 12932, 13029, 12842, 15255, 14989, 15109, 26520, 26534, 26325, 26534, 26686, 26612, 26435, - 26605, 26443, 28716, 28565, 28472, 29578, 29793, 29693, 9072, 9446, 9367, 9183, 9228, - 9171, 11343, 11283, 11499, 10337, 10401, 10576, 11266, 11283, 11343, 11006, 11050, 10991, - 11437, 11527, 11708, 10847, 10991, 10928, 13146, 13255, 13443, 13601, 13618, 13797, 13767, - 13797, 13895, 20305, 20012, 20008, 28215, 28060, 28166, 28215, 28016, 28060, 26719, 26869, - 26958, 9845, 9712, 9952, 9928, 9881, 9845, 9811, 10295, 9912, 10172, 10533, 10439, - 11021, 11124, 11289, 10576, 10401, 10478, 30823, 30564, 30383, 30875, 31023, 30928, 9228, - 9239, 9171, 11999, 12636, 12367, 10391, 10401, 10337, 10309, 10292, 9972, 10705, 10847, - 10928, 14989, 14868, 15080, 26605, 26881, 26592, 26962, 27196, 27009, 32783, 32753, 32673, - 32713, 32515, 32596, 32713, 32596, 32810, 11386, 11527, 11437, 13529, 13443, 13507, 18396, - 18234, 18320, 18292, 18234, 18396, 23077, 23256, 23204, 23284, 23256, 23077, 32500, 32421, - 32122, 11283, 11199, 11289, 11108, 11199, 11047, 28016, 27945, 27875, 28215, 27945, 28016, - 30175, 30405, 30246, 30494, 30405, 30175, 19894, 19816, 19941, 22187, 22358, 22032, 30837, - 30877, 30474, 31023, 30877, 30968, 17471, 17286, 17366, 15255, 15108, 14989, 14989, 14900, - 14868, 15785, 15301, 15280, 32654, 32377, 32535, 32617, 32535, 32607, 9171, 9239, 9246, - 14868, 14697, 14912, 14151, 13957, 14185, 14483, 14697, 14868, 32796, 32783, 32680, 9250, - 9482, 9780, 27782, 27645, 27534, 27782, 27534, 27622, 30201, 30029, 30043, 30075, 30029, - 30201, 15155, 15108, 15255, 26686, 26534, 26520, 26935, 27081, 26958, 32103, 32072, 32052, - 32220, 32072, 32103, 32356, 32141, 32310, 31770, 31625, 31619, 32519, 32500, 32122, 31718, - 31309, 31776, 31369, 31262, 31487, 9146, 9171, 9246, 11199, 11021, 11289, 10391, 10359, - 10401, 11108, 11021, 11199, 19816, 19672, 19932, 18714, 18774, 18572, 21030, 21361, 20579, - 22331, 22410, 22276, 22511, 22410, 22567, 23140, 23284, 23077, 21841, 21734, 21739, 32828, - 32796, 32680, 22331, 22276, 22087, 23256, 23390, 23235, 23284, 23390, 23256, 28945, 28730, - 28791, 28716, 28730, 28565, 28380, 28294, 28366, 29101, 29073, 28888, 29268, 29073, 29101, - 29427, 29349, 29581, 29002, 28858, 28804, 29267, 29473, 29333, 29490, 29715, 29578, 29578, - 29715, 29793, 29363, 29427, 29633, 32675, 32338, 32568, 12290, 12367, 12558, 12698, 12630, - 12634, 12404, 12630, 12353, 17718, 17471, 17629, 17854, 17782, 18032, 28815, 29002, 28804, - 29454, 29473, 29267, 29793, 29970, 29770, 11417, 11457, 11549, 11417, 11699, 11705, 11226, - 11466, 11223, 11226, 11375, 11466, 10401, 10359, 10439, 10868, 10999, 10607, 26935, 27134, - 27183, 12145, 11999, 12367, 21734, 21841, 21975, 32875, 32332, 33008, 32873, 32675, 32568, - 9411, 9360, 9367, 9146, 9183, 9171, 9481, 9680, 9478, 10706, 10847, 10448, 32607, - 32535, 32478, 27021, 27196, 26962, 30877, 31023, 30875, 31083, 31023, 31129, 11999, 11841, - 12433, 28965, 28730, 28945, 9881, 9778, 9845, 9811, 9778, 9881, 25143, 25279, 25329, - 26435, 26602, 26605, 26605, 26602, 26881, 26881, 27021, 26962, 24998, 24878, 24811, 24831, - 24607, 24233, 25286, 24484, 24129, 25159, 24484, 25286, 25510, 25509, 25971, 32780, 32568, - 32665, 9224, 9250, 9400, 9089, 9318, 9267, 22032, 22358, 22271, 22358, 22482, 22450, - 32807, 32738, 32666, 14151, 14185, 14315, 13618, 13529, 13507, 12404, 12456, 12630, 27558, - 27534, 27497, 32748, 32356, 32308, 11139, 11226, 11223, 13601, 13529, 13618, 24877, 24831, - 24928, 32369, 32209, 32144, 32137, 32205, 31993, 32644, 32607, 32478, 12976, 13294, 13218, - 12396, 12932, 12842, 12396, 12939, 11869, 11625, 11791, 11527, 11625, 11527, 11581, 27206, - 27441, 27644, 23390, 23508, 23354, 23284, 23508, 23390, 31369, 31309, 31262, 32137, 32225, - 32205, 26366, 26212, 26325, 26366, 26325, 26424, 26612, 26686, 26719, 26143, 25567, 25837, - 9508, 9654, 9784, 17782, 17663, 17718, 17812, 17663, 17782, 17854, 18032, 18234, 21733, - 21787, 21619, 32738, 32780, 32665, 11386, 11437, 11375, 29921, 29878, 29897, 31771, 31770, - 31619, 32735, 32756, 32713, 32713, 32756, 32350, 32644, 32478, 32700, 10257, 10172, 10439, - 26187, 26462, 26330, 31339, 31262, 31096, 9147, 9250, 9224, 9778, 9712, 9845, 9648, - 9712, 9778, 18861, 18855, 18937, 14697, 14339, 14315, 14215, 14339, 14276, 12456, 12634, - 12630, 13767, 13601, 13797, 13767, 13895, 13957, 30075, 29921, 29991, 30075, 29991, 30029, - 29899, 29970, 29793, 30837, 30474, 30564, 31023, 31083, 31036, 30837, 30564, 30823, 9972, - 10292, 10170, 10399, 10847, 10705, 9972, 10170, 9752, 10847, 10864, 10991, 11006, 10864, - 10875, 20868, 20926, 20780, 20780, 20731, 20700, 20006, 19894, 20012, 20012, 19894, 19941, - 19816, 19646, 19672, 21012, 21025, 21487, 21012, 21487, 21061, 21487, 21595, 21061, 26887, - 26612, 26719, 26506, 26602, 26435, 33008, 32332, 32577, 32807, 32822, 32738, 32738, 32842, - 32780, 32808, 32819, 32765, 32972, 32819, 32808, 32896, 32432, 32753, 32896, 32753, 32961, - 9158, 9110, 9319, 9188, 9089, 9267, 9158, 9319, 9178, 9158, 9178, 9144, 21680, - 21830, 21733, 9371, 9806, 9434, 9769, 9632, 9961, 9288, 9434, 9403, 9358, 9403, - 9353, 9520, 9508, 9784, 18855, 18774, 18714, 18861, 18774, 18855, 9300, 9338, 9785, - 9146, 9246, 8770, 9279, 9338, 9284, 9260, 9358, 9353, 18430, 18292, 18512, 32448, - 32369, 32582, 32661, 32592, 32349, 32661, 32349, 32675, 32700, 32478, 32421, 32596, 32612, - 32810, 11047, 11199, 11283, 11434, 11417, 11705, 30201, 30043, 30165, 32209, 32220, 32103, - 32072, 32235, 31952, 32240, 32220, 32382, 32369, 32141, 32356, 32535, 32617, 32654, 32961, - 32753, 32783, 10359, 10257, 10439, 10607, 10999, 10835, 10866, 10986, 11021, 11266, 11343, - 11356, 13101, 13255, 13146, 13752, 13767, 13957, 9144, 9178, 9118, 9218, 9183, 9118, - 32961, 32783, 32796, 9118, 9183, 9146, 9058, 9089, 9188, 9190, 9134, 9224, 10835, - 10999, 10986, 14339, 14151, 14315, 13932, 14151, 13903, 27196, 27558, 27497, 27782, 27834, - 27756, 29244, 29145, 29002, 27622, 27558, 27624, 30823, 30383, 30405, 11417, 11379, 11457, - 11187, 11386, 11375, 11187, 11375, 11226, 28380, 28366, 28492, 27945, 27871, 27734, 30449, - 30201, 30165, 30062, 30201, 30449, 26212, 26114, 25971, 26366, 26114, 26212, 26185, 26143, - 26151, 26408, 26506, 26462, 26462, 26506, 26435, 29427, 29268, 29101, 29073, 28998, 28945, - 28730, 28965, 28565, 29363, 29268, 29427, 29349, 29612, 29581, 29612, 29724, 29581, 29878, - 29724, 29616, 29244, 29309, 29123, 29473, 29715, 29490, 29244, 29123, 29145, 29244, 29002, - 29293, 32654, 32617, 32607, 32756, 32828, 32680, 11999, 11886, 11841, 11461, 11434, 11705, - 11417, 11378, 11379, 12456, 12558, 12634, 13443, 13529, 13146, 25451, 25159, 25286, 25837, - 25567, 25475, 25092, 25199, 25143, 24998, 24811, 24831, 28815, 28804, 28347, 29777, 29652, - 29724, 31770, 32064, 31935, 32205, 32263, 32186, 13583, 13529, 13601, 20006, 20012, 20305, - 19672, 19480, 19324, 29309, 29454, 29267, 15051, 15370, 14378, 17751, 17836, 17545, 15664, - 15051, 15631, 31718, 31771, 31619, 31770, 32176, 32064, 31776, 31771, 31718, 18064, 17854, - 18234, 17663, 17471, 17718, 9358, 9288, 9403, 9268, 9288, 9358, 18292, 18173, 18234, - 18064, 18173, 18037, 23735, 24105, 23600, 22891, 22650, 22567, 22891, 22567, 22826, 29235, - 28998, 29073, 29878, 29921, 30062, 10864, 11006, 10991, 10967, 11006, 10875, 28192, 27871, - 27945, 26958, 26887, 26719, 27622, 27834, 27782, 9246, 9252, 8770, 15108, 14900, 14989, - 15301, 15155, 15255, 15017, 15155, 15301, 15005, 15155, 15017, 26408, 26462, 26187, 27449, - 27558, 27196, 11734, 11886, 11999, 28998, 28965, 28945, 30062, 29921, 30075, 29454, 29715, - 29473, 29970, 30038, 30109, 11194, 11266, 11379, 11379, 11266, 11356, 11108, 10866, 11021, - 28328, 28215, 28166, 28351, 28215, 28328, 22069, 22331, 22087, 9508, 9478, 9654, 9404, - 9478, 9508, 17562, 17471, 17663, 23735, 23600, 23508, 9089, 9086, 9318, 8905, 9260, - 9353, 21733, 21830, 21917, 21733, 21886, 21787, 22826, 22567, 22643, 32733, 32654, 32607, - 32782, 32654, 32733, 32920, 32577, 32765, 32780, 32842, 32568, 24877, 24998, 24831, 26185, - 26191, 26143, 32064, 32225, 32137, 32245, 32225, 32345, 9912, 10295, 10259, 9712, 9520, - 9784, 9725, 9811, 9698, 10391, 10257, 10359, 10271, 10257, 10391, 15005, 14900, 15108, - 27644, 27441, 27510, 26424, 26325, 26534, 29715, 29899, 29793, 9274, 9367, 9360, 9086, - 9093, 9318, 19894, 19646, 19816, 18774, 18430, 18512, 22450, 22482, 22641, 22954, 22450, - 22641, 10967, 11139, 11223, 13543, 13583, 13601, 13543, 13601, 13767, 23803, 23735, 23508, - 23272, 23508, 23284, 10851, 10866, 10955, 10457, 10337, 10576, 14151, 13932, 13957, 13855, - 13932, 13903, 11625, 11630, 11869, 11398, 11581, 11527, 11398, 11527, 11386, 10457, 10868, - 10607, 32875, 32822, 32807, 9338, 9274, 9360, 9279, 9274, 9338, 22891, 22958, 23077, - 22826, 22958, 22891, 32843, 32661, 32675, 32736, 32308, 32555, 32751, 32555, 32592, 27624, - 27558, 27449, 26143, 26191, 26187, 26353, 26191, 26185, 32245, 32263, 32205, 32245, 32205, - 32225, 32878, 32828, 32756, 32785, 32810, 32612, 10851, 10835, 10866, 11598, 11730, 11841, - 30201, 30062, 30075, 30449, 30165, 30724, 29899, 30038, 29970, 32878, 32756, 32735, 26353, - 26408, 26187, 30837, 30968, 30877, 31083, 31339, 31096, 31788, 31776, 31309, 31066, 30968, - 31183, 17836, 17211, 17545, 18168, 18343, 19333, 10866, 10835, 10986, 11047, 11283, 11266, - 27558, 27622, 27534, 27834, 28071, 28347, 26881, 26602, 27021, 10568, 10457, 10607, 24998, - 25092, 25143, 25048, 25092, 24998, 24831, 24233, 24928, 27183, 27081, 26935, 27159, 27081, - 27162, 9288, 9209, 9434, 8905, 9353, 9250, 32661, 32683, 32592, 32981, 32683, 32661, - 9026, 9134, 9190, 14215, 14151, 14339, 15155, 15005, 15108, 14971, 15005, 15017, 19646, - 19480, 19672, 21841, 22050, 22087, 22643, 22567, 22410, 21909, 22050, 21841, 20746, 20579, - 20366, 32822, 32842, 32738, 11187, 11398, 11386, 28215, 28192, 27945, 27871, 27644, 27510, - 28492, 28366, 28565, 18937, 18855, 18964, 17812, 17782, 17854, 17812, 17562, 17663, 25887, - 25510, 25971, 25159, 24912, 24484, 22552, 22271, 22450, 25525, 25510, 25887, 32782, 32785, - 32612, 32890, 32878, 32735, 32782, 32612, 32654, 11139, 11187, 11226, 11006, 10967, 11223, - 10706, 10864, 10847, 12404, 12290, 12456, 13855, 13752, 13957, 13855, 13957, 13932, 20926, - 20731, 20780, 19604, 19518, 19646, 19646, 19518, 19480, 20969, 20731, 20926, 20969, 20926, - 21012, 20969, 21012, 21061, 19116, 20366, 19333, 32819, 32920, 32765, 33080, 32934, 32822, - 32822, 32934, 32842, 32972, 32920, 32819, 32972, 32808, 32896, 12456, 12290, 12558, 11772, - 11734, 11999, 11522, 11598, 11841, 13146, 13529, 13583, 29268, 29343, 29073, 28998, 29242, - 28965, 28581, 28492, 28565, 29457, 29343, 29268, 29457, 29268, 29363, 29633, 29427, 29581, - 29633, 29581, 29652, 9134, 9135, 9224, 11630, 12396, 11869, 12976, 13218, 13048, 11630, - 11625, 11596, 22050, 22069, 22087, 21987, 22069, 22050, 29343, 29235, 29073, 10337, 10271, - 10391, 10257, 10129, 10172, 10277, 10271, 10337, 21061, 21595, 21431, 29652, 29581, 29724, - 9811, 9725, 9778, 9698, 9811, 9608, 12976, 13048, 12932, 21619, 21595, 21635, 28380, - 28351, 28328, 28418, 28351, 28380, 30038, 30310, 30109, 10457, 10277, 10337, 10517, 10568, - 10607, 10399, 10705, 10403, 25475, 25620, 25837, 25048, 24877, 24928, 33021, 32700, 32421, - 32264, 32225, 32064, 32890, 32735, 32885, 32700, 32607, 32644, 33107, 32972, 32896, 9300, - 9857, 9481, 8992, 8848, 8864, 9300, 9481, 9339, 18073, 18343, 18168, 22958, 23140, - 23077, 24144, 24233, 24105, 23222, 23140, 22958, 8861, 9240, 9266, 9089, 9010, 9086, - 8937, 9026, 9093, 9093, 9026, 9190, 9134, 9028, 9135, 9001, 9266, 9110, 8987, - 9110, 8989, 9030, 9158, 9144, 9030, 9144, 9018, 17471, 16425, 17286, 17812, 17854, - 18064, 32713, 32810, 32885, 33153, 32961, 32796, 29715, 29765, 29899, 30363, 30389, 30038, - 30389, 30365, 30310, 29454, 29765, 29715, 29530, 29765, 29454, 29530, 29454, 29309, 29530, - 29309, 29244, 10910, 11187, 11139, 10849, 10875, 10864, 14339, 14697, 14276, 13752, 13543, - 13767, 32135, 32176, 31770, 31891, 31776, 32005, 11596, 11625, 11581, 10910, 11139, 10967, - 26424, 26534, 26649, 27021, 26602, 27032, 26191, 26353, 26187, 25279, 25452, 25475, 11596, - 11581, 11462, 9018, 9144, 9118, 9018, 9118, 8918, 22480, 22410, 22331, 9028, 9147, - 9135, 9135, 9147, 9224, 33062, 32796, 32828, 32885, 32810, 32959, 9404, 9481, 9478, - 9072, 9367, 9274, 9260, 9268, 9358, 8896, 9268, 9260, 11734, 11841, 11886, 11079, - 11047, 11266, 10835, 10699, 10607, 11577, 11596, 11462, 23140, 23272, 23284, 23222, 23272, - 23140, 32327, 32186, 32263, 32959, 32810, 32785, 9499, 9520, 9712, 14836, 14868, 14900, - 32345, 32327, 32263, 32345, 32263, 32245, 11378, 11417, 11434, 13535, 13543, 13752, 13535, - 13752, 13519, 15005, 14971, 14900, 14836, 14971, 14963, 30310, 30494, 30175, 30365, 30494, - 30310, 33062, 32828, 32878, 9377, 9404, 9508, 10955, 10866, 11108, 13885, 13903, 14151, - 32519, 32122, 32480, 9147, 9137, 9250, 9043, 9137, 9147, 11598, 11461, 11705, 32959, - 32785, 32782, 33025, 33062, 32878, 9725, 9648, 9778, 9912, 10259, 10172, 24877, 25048, - 24998, 24144, 24105, 23944, 25510, 25451, 25286, 25525, 25451, 25510, 32852, 32733, 32607, - 21733, 21619, 21635, 21733, 21917, 21886, 21030, 21639, 21734, 22069, 22200, 22331, 10129, - 9912, 10172, 10174, 10277, 10098, 10277, 10097, 10098, 11461, 11378, 11434, 13543, 13146, - 13583, 27796, 27644, 27871, 28581, 28565, 28965, 18064, 18234, 18173, 15017, 15301, 15785, - 18073, 18261, 18343, 17836, 17058, 16931, 21886, 21917, 22032, 21639, 21739, 21734, 11047, - 10955, 11108, 10985, 10955, 11047, 32842, 32873, 32568, 32963, 32873, 32842, 9622, 9648, - 9725, 31884, 31770, 31771, 26602, 26792, 27032, 25279, 25199, 25296, 30968, 31066, 31023, - 31183, 30968, 31054, 10851, 10699, 10835, 10678, 10699, 10851, 10706, 10746, 10864, 10875, - 10931, 10967, 11462, 11581, 11398, 10632, 10746, 10706, 25174, 25199, 25092, 28192, 28215, - 28411, 26649, 26534, 26612, 27622, 27933, 27834, 26506, 26792, 26602, 31776, 31884, 31771, - 31891, 31884, 31776, 22045, 21886, 22032, 22271, 22358, 22450, 26134, 25971, 26114, 27159, - 26958, 27081, 28492, 28418, 28380, 23944, 24105, 23735, 32500, 32603, 32421, 32837, 32852, - 32607, 32480, 32122, 32186, 32603, 32519, 32716, 27162, 27081, 27183, 29343, 29242, 29235, - 29235, 29242, 28998, 28492, 28581, 28418, 29633, 29457, 29363, 29675, 29457, 29633, 11772, - 11999, 12145, 11598, 11493, 11461, 11461, 11224, 11378, 12353, 12630, 12698, 18037, 18173, - 18115, 19032, 18937, 18964, 19032, 18964, 19480, 29497, 29242, 29343, 8986, 9093, 9086, - 19604, 19646, 19894, 21739, 21909, 21841, 29777, 29724, 29871, 33080, 32822, 32875, 9300, - 9284, 9338, 9279, 9161, 9274, 9217, 9284, 9300, 10849, 10931, 10875, 18796, 18774, - 18861, 27886, 27933, 27622, 9648, 9592, 9712, 9520, 9427, 9508, 9404, 9339, 9481, - 25048, 25091, 25092, 24928, 25091, 25048, 32220, 32240, 32072, 30237, 30374, 30253, 32382, - 32220, 32209, 32235, 32240, 32387, 32209, 32448, 32382, 12202, 12145, 12290, 29871, 29878, - 29980, 29871, 29724, 29878, 11378, 11194, 11379, 10609, 10678, 10851, 11007, 11194, 11008, - 26134, 26114, 26171, 24990, 24912, 25159, 30724, 30813, 32346, 30494, 30628, 30405, 30389, - 30310, 30038, 9117, 9161, 9279, 14971, 14836, 14900, 13752, 13855, 13625, 17500, 17471, - 17562, 32934, 32963, 32842, 29980, 29878, 30062, 32873, 32843, 32675, 32981, 32843, 33286, - 9994, 10399, 10403, 10746, 10849, 10864, 10448, 10399, 9994, 31066, 31129, 31023, 31281, - 31129, 31183, 9369, 9427, 9520, 9648, 9563, 9592, 9592, 9499, 9712, 9698, 9622, - 9725, 9657, 9622, 9698, 9586, 9632, 9769, 9305, 9632, 9586, 11596, 11577, 11630, - 11630, 12271, 12396, 12965, 12976, 12932, 11462, 11398, 11017, 20731, 20613, 20305, 20879, - 20613, 20731, 20879, 20731, 20969, 20879, 20969, 20921, 20969, 21061, 20921, 21061, 21034, - 20921, 25174, 25296, 25199, 28350, 28815, 28347, 30156, 30038, 29899, 30035, 29980, 30062, - 9110, 9158, 8989, 8987, 9001, 9110, 9058, 8996, 9089, 9158, 8992, 8989, 10632, - 10849, 10746, 11477, 11462, 11327, 11194, 11079, 11266, 10985, 11079, 11007, 21800, 21619, - 21787, 9026, 9028, 9134, 9137, 9055, 9250, 9004, 9028, 9026, 9158, 9030, 8992, - 17751, 17930, 18073, 21539, 21518, 21688, 17997, 17930, 17904, 9428, 9499, 9592, 24990, - 25159, 25451, 32264, 32345, 32225, 32264, 32064, 32176, 26367, 26408, 26353, 28049, 28071, - 27933, 31350, 31339, 31083, 8992, 9030, 8936, 20746, 21030, 20579, 21639, 21757, 21739, - 21739, 21757, 21909, 18330, 19333, 18343, 10129, 10257, 10271, 10910, 10967, 10931, 22952, - 23222, 22958, 23272, 23230, 23508, 22897, 22958, 22826, 26171, 26114, 26366, 26171, 26366, - 26383, 25837, 26151, 26143, 26185, 26367, 26353, 25998, 26151, 25837, 31884, 31979, 31770, - 31788, 31309, 31369, 9317, 9339, 9404, 9284, 9117, 9279, 16931, 17058, 16720, 26202, - 26367, 26185, 21987, 22200, 22069, 21987, 22050, 21909, 33244, 33008, 32577, 32934, 33014, - 32963, 33244, 32577, 32920, 33107, 32920, 32972, 25091, 25174, 25092, 25296, 25452, 25279, - 25196, 25174, 25091, 32240, 32235, 32072, 32209, 32369, 32448, 32396, 32264, 32176, 13004, - 12951, 13146, 12257, 12202, 12404, 13519, 13752, 13625, 14088, 14151, 14215, 30365, 30628, - 30494, 30707, 30628, 30365, 9030, 9018, 8936, 13294, 12981, 13996, 12250, 12932, 12396, - 27422, 27449, 27196, 27933, 28071, 27834, 10699, 10517, 10607, 10174, 10129, 10271, 10609, - 10851, 10585, 27383, 27162, 27183, 27159, 26887, 26958, 27869, 27796, 27889, 27383, 27206, - 27581, 8883, 8996, 9058, 10174, 10271, 10277, 9028, 9043, 9147, 8963, 9043, 9028, - 22954, 23622, 24090, 21886, 21800, 21787, 17930, 18261, 18073, 18330, 18261, 18203, 23222, - 23230, 23272, 25346, 25296, 25174, 23195, 23230, 23222, 9427, 9377, 9508, 9399, 9377, - 9427, 9209, 9371, 9434, 9209, 9288, 9268, 16720, 17058, 16176, 8996, 9010, 9089, - 9622, 9563, 9648, 9369, 9399, 9427, 9608, 9657, 9698, 25358, 25452, 25296, 10789, - 10910, 10931, 10789, 10931, 10849, 27729, 27622, 27624, 32751, 32592, 32683, 32519, 32603, - 32500, 32480, 32186, 32327, 32480, 32327, 32414, 9010, 8986, 9086, 10277, 10457, 10097, - 27112, 26887, 27159, 12404, 12202, 12290, 11734, 11646, 11841, 12353, 13101, 13146, 29457, - 29497, 29343, 28652, 28581, 29487, 27744, 27673, 27796, 29675, 29497, 29457, 29675, 29633, - 29652, 29675, 29652, 29828, 29652, 29777, 29828, 29293, 29530, 29244, 29293, 29002, 28815, - 11476, 12271, 11630, 11503, 11630, 11577, 30294, 29293, 29506, 12257, 12353, 12092, 29828, - 29777, 29880, 29777, 29871, 29880, 30156, 29899, 30122, 10399, 10448, 10847, 9994, 10403, - 10309, 14483, 14276, 14697, 27162, 27112, 27159, 27581, 27206, 27644, 10541, 10632, 10706, - 27796, 27673, 27644, 27581, 27673, 27598, 27449, 27636, 27624, 27535, 27636, 27449, 11884, - 11772, 12145, 11079, 10985, 11047, 29975, 29871, 29980, 32981, 32751, 32683, 32736, 32751, - 32945, 9339, 9217, 9300, 9037, 9072, 9274, 9175, 9217, 9339, 17812, 17657, 17562, - 18064, 17788, 17812, 17950, 17788, 18064, 26151, 26202, 26185, 26672, 26506, 26408, 27422, - 27535, 27449, 26050, 25998, 25837, 26134, 25887, 25971, 25525, 25720, 25451, 26434, 26366, - 26424, 9752, 10170, 9961, 11772, 11646, 11734, 19281, 19032, 19480, 18937, 18796, 18861, - 19398, 19480, 19518, 21833, 21800, 21886, 21664, 21757, 21639, 22200, 22480, 22331, 26649, - 26434, 26424, 27216, 27112, 27162, 26725, 26649, 26612, 31339, 31487, 31262, 31129, 31350, - 31083, 31281, 31350, 31129, 31129, 31066, 31183, 31891, 31979, 31884, 32005, 31979, 31891, - 33008, 33080, 32875, 32963, 33185, 32873, 10962, 11398, 11187, 10733, 10789, 10849, 9377, - 9317, 9404, 9428, 9520, 9499, 32414, 32327, 32345, 32414, 32345, 32443, 32582, 32369, - 32356, 32443, 32345, 32264, 11646, 11522, 11841, 14250, 14255, 14276, 14963, 15017, 14764, - 15370, 15929, 16176, 15664, 15929, 15370, 26725, 26612, 26887, 32924, 32959, 32782, 33025, - 32878, 32890, 32837, 32607, 32700, 32837, 32700, 32976, 9302, 9317, 9377, 19491, 19604, - 19588, 22045, 21833, 21886, 9037, 9274, 9161, 8951, 9055, 9137, 8951, 9137, 9043, - 19032, 18949, 18937, 18961, 18949, 19032, 22377, 22480, 22200, 11522, 11493, 11598, 11462, - 11477, 11577, 10962, 11187, 10874, 30167, 30035, 30062, 10733, 10787, 10789, 10448, 10541, - 10706, 10522, 10541, 10305, 14255, 14088, 14215, 13004, 13146, 13543, 14255, 14215, 14276, - 27673, 27581, 27644, 27383, 27216, 27162, 27744, 27796, 27869, 27636, 27729, 27624, 27422, - 27196, 27021, 18115, 18173, 18292, 25452, 25461, 25475, 25358, 25461, 25452, 24928, 24233, - 24837, 31469, 31487, 31339, 33080, 33014, 32934, 33025, 32890, 32885, 32961, 33107, 32896, - 31350, 31455, 31339, 30823, 30405, 30628, 11007, 11079, 11194, 10678, 10517, 10699, 17788, - 17657, 17812, 17853, 17657, 17788, 12976, 13001, 13294, 12671, 12965, 12932, 30035, 30167, - 30237, 30449, 30167, 30062, 30122, 29899, 29765, 30707, 30763, 30628, 32924, 32782, 32733, - 32924, 32975, 33053, 8894, 9004, 9026, 22083, 22032, 22271, 22083, 22045, 22032, 21757, - 21987, 21909, 33014, 33000, 32963, 22480, 22643, 22410, 22466, 22643, 22480, 32924, 32733, - 32852, 9657, 9563, 9622, 9608, 9563, 9657, 9608, 9811, 9533, 9811, 9912, 9782, - 26672, 26408, 26367, 9399, 9302, 9377, 9317, 9235, 9339, 9108, 9117, 9284, 9229, - 9302, 9399, 12965, 13001, 12976, 28550, 28581, 28652, 9462, 9428, 9592, 16931, 17211, - 17836, 17997, 18261, 17930, 16548, 16720, 16176, 24883, 24928, 24837, 23944, 23735, 23938, - 9001, 8869, 9266, 8996, 8883, 9010, 9010, 8883, 8986, 8986, 8922, 9093, 8939, - 8869, 9001, 8939, 9001, 8895, 9001, 8987, 8895, 8987, 8989, 8895, 13625, 13855, - 13903, 30707, 30365, 30389, 8895, 8989, 8892, 26575, 26383, 26434, 26434, 26383, 26366, - 26177, 25887, 26134, 26575, 26434, 26649, 27034, 26887, 27112, 31760, 31788, 31369, 32467, - 32443, 32264, 18037, 17950, 18064, 18066, 17950, 18037, 9004, 9009, 9028, 8860, 9009, - 9004, 19437, 19398, 19518, 18949, 18796, 18937, 22059, 22083, 22552, 8892, 8989, 8912, - 8869, 8861, 9266, 14088, 13885, 14151, 14483, 14868, 14836, 20879, 20722, 20613, 19491, - 19437, 19604, 19604, 19437, 19518, 21034, 21061, 21431, 21034, 21218, 21006, 21619, 21431, - 21595, 21800, 21833, 21772, 27726, 27729, 27636, 27252, 27422, 27021, 31054, 30968, 30837, - 31281, 31455, 31350, 31487, 31760, 31369, 32060, 31760, 31487, 8912, 8989, 8992, 14011, - 13885, 14088, 18261, 18330, 18343, 17930, 17751, 17638, 22059, 21833, 22045, 27182, 27216, - 27383, 28467, 28351, 28418, 27726, 27636, 27535, 28071, 28350, 28347, 18826, 18796, 18949, - 23938, 23735, 23803, 8864, 8912, 8992, 14533, 14483, 14836, 24928, 25196, 25091, 27641, - 27383, 27581, 28581, 28467, 28418, 32235, 32674, 31665, 32382, 32387, 32240, 32442, 32387, - 32382, 32442, 32382, 32448, 9009, 8963, 9028, 8860, 8963, 9009, 15017, 14963, 14971, - 14676, 14963, 14764, 19398, 19281, 19480, 19298, 19281, 19398, 21987, 22219, 22200, 27034, - 26725, 26887, 33055, 33025, 32885, 8936, 9018, 8918, 33168, 33107, 32961, 33008, 33093, - 33080, 33080, 33141, 33014, 33014, 33164, 33000, 33168, 32961, 33153, 11772, 11649, 11646, - 11646, 11419, 11522, 11522, 11319, 11493, 11034, 11194, 11378, 12202, 11884, 12145, 11870, - 11884, 12202, 12257, 12404, 12353, 12176, 12257, 12092, 25461, 25620, 25475, 25998, 26202, - 26151, 25580, 25620, 25461, 10789, 10787, 10910, 10733, 10849, 10632, 13588, 13625, 13903, - 12176, 12202, 12257, 27886, 28049, 27933, 30763, 30823, 30628, 30952, 30823, 31009, 11884, - 11817, 11772, 29828, 29803, 29675, 29675, 29803, 29497, 28548, 28550, 28652, 28581, 28550, - 28467, 29880, 29803, 29828, 29880, 29871, 29975, 8896, 9209, 9268, 9371, 9305, 9586, - 8890, 9250, 9055, 17950, 17853, 17788, 17657, 17500, 17562, 17882, 17853, 17950, 29975, - 29980, 30086, 8861, 8883, 9058, 16960, 17211, 16931, 9108, 9284, 9115, 8918, 9118, - 9146, 25346, 25358, 25296, 10609, 10517, 10678, 9782, 9912, 9617, 10851, 10955, 10766, - 14033, 14011, 14088, 13686, 13588, 13903, 14033, 14088, 14255, 27744, 27598, 27673, 27727, - 27598, 27744, 30086, 29980, 30035, 31183, 31196, 31281, 30823, 31054, 30837, 8918, 8770, - 8805, 21030, 21453, 21639, 21757, 21957, 21987, 22253, 22377, 22219, 21566, 21453, 21539, - 32497, 32442, 32448, 32694, 32705, 32480, 32480, 32716, 32519, 32396, 32176, 32540, 9229, - 9235, 9317, 9229, 9317, 9302, 17624, 17500, 17657, 8936, 8918, 8771, 12250, 12671, - 12932, 12965, 12768, 13001, 12250, 12396, 12271, 30237, 30086, 30035, 30112, 30086, 30124, - 10522, 10733, 10632, 10874, 11187, 10910, 10522, 10632, 10541, 28049, 28078, 28071, 27729, - 27886, 27622, 28121, 27886, 28043, 8963, 8951, 9043, 8940, 8951, 8963, 11319, 11461, - 11493, 26050, 26202, 25998, 27632, 27519, 27422, 27422, 27519, 27535, 26050, 25837, 25923, - 22643, 22897, 22826, 22621, 22897, 22643, 25923, 25837, 25620, 31788, 32005, 31776, 32112, - 32005, 32181, 32005, 31788, 32181, 32959, 33055, 32885, 32975, 32924, 32852, 32976, 32700, - 33021, 32135, 31770, 31979, 8883, 8922, 8986, 21453, 21664, 21639, 22928, 22952, 22897, - 32005, 32135, 31979, 33153, 32796, 33062, 33153, 33062, 33083, 11419, 11319, 11522, 30156, - 30304, 30038, 30314, 30122, 29765, 30314, 30294, 30489, 30314, 30489, 30528, 18250, 18115, - 18292, 17853, 17882, 17657, 18430, 18774, 18796, 32751, 32736, 32555, 32981, 32661, 32843, - 26429, 26672, 26367, 19281, 18961, 19032, 19298, 18961, 19281, 33110, 33055, 32959, 8922, - 8937, 9093, 9014, 9305, 9371, 9484, 9752, 9961, 33794, 33093, 33008, 33000, 33185, - 32963, 33083, 33062, 33025, 9428, 9369, 9520, 9314, 9369, 9428, 27252, 27021, 27032, - 31054, 31179, 31183, 31130, 31179, 31054, 31196, 31179, 31241, 28411, 28215, 28351, 28510, - 28351, 28467, 11319, 11224, 11461, 30122, 30304, 30156, 14483, 14377, 14276, 14503, 14377, - 14483, 17211, 17441, 17545, 17422, 17441, 17263, 22897, 22952, 22958, 22466, 22480, 22377, - 26672, 26792, 26506, 32705, 32716, 32480, 32480, 32414, 32694, 10053, 10129, 10174, 10766, - 10955, 10985, 10766, 10985, 10844, 27182, 27112, 27216, 27182, 27034, 27112, 27889, 27796, - 27871, 33093, 33141, 33080, 15929, 16548, 16176, 16720, 16960, 16931, 9563, 9462, 9592, - 10457, 10104, 10097, 8951, 9005, 9055, 8868, 9005, 8951, 22377, 22200, 22219, 9115, - 9284, 9217, 9117, 9037, 9161, 9175, 9339, 9170, 18115, 18066, 18037, 18009, 18066, - 18115, 18330, 19116, 19333, 17638, 17751, 17545, 28965, 29487, 28581, 30304, 30363, 30038, - 9170, 9339, 9235, 17587, 17638, 17545, 8937, 8894, 9026, 10053, 10098, 10027, 26177, - 26171, 26383, 27641, 27581, 27598, 26792, 26998, 27032, 33141, 33164, 33014, 10844, 10985, - 11007, 28121, 28078, 28049, 28121, 28049, 27886, 8979, 9037, 9117, 18568, 18430, 18796, - 22952, 23045, 23222, 22928, 23045, 22952, 12176, 12056, 12202, 11884, 11870, 11817, 11817, - 11649, 11772, 11160, 11119, 11224, 12353, 13146, 12951, 25358, 25580, 25461, 25196, 25346, - 25174, 25278, 25346, 25196, 25161, 25196, 24928, 24233, 24737, 24837, 12056, 11870, 12202, - 13543, 13535, 13352, 13686, 13903, 13885, 13625, 13457, 13519, 14377, 14250, 14276, 31179, - 31196, 31183, 31281, 31196, 31434, 9617, 9912, 10129, 28550, 28510, 28467, 28187, 27889, - 27871, 18961, 18826, 18949, 18944, 18826, 18961, 19604, 19894, 19588, 22083, 22059, 22045, - 22552, 22083, 22271, 22466, 22621, 22643, 22524, 22621, 22466, 32748, 32582, 32356, 33164, - 33162, 33000, 33133, 33083, 33025, 26177, 26134, 26171, 24090, 23622, 24484, 26575, 26649, - 26670, 9191, 9229, 9399, 9136, 9229, 9149, 23938, 24144, 23944, 32442, 32516, 32387, - 30237, 30167, 30374, 32582, 32497, 32448, 11870, 11649, 11817, 11034, 11008, 11194, 26750, - 26649, 26725, 31403, 31455, 31281, 17638, 17904, 17930, 18203, 18337, 18330, 8869, 8853, - 8861, 8861, 8648, 8883, 8883, 8807, 8922, 8922, 8807, 8937, 8937, 8786, 8894, - 8939, 8853, 8869, 8738, 8853, 8939, 8842, 8939, 8895, 8842, 8895, 8849, 8895, - 8892, 8849, 8892, 8830, 8849, 8912, 8830, 8892, 13803, 13885, 14011, 8894, 8860, - 9004, 8850, 8860, 8894, 8912, 8808, 8830, 8864, 8808, 8912, 27034, 26750, 26725, - 8864, 8800, 8808, 9175, 9115, 9217, 9006, 8979, 9117, 9136, 9170, 9235, 9486, - 9462, 9563, 9486, 9563, 9608, 11119, 11378, 11224, 10874, 10910, 10787, 11477, 11503, - 11577, 17441, 17587, 17545, 17638, 17808, 17904, 17422, 17587, 17441, 23803, 23508, 23230, - 24978, 25161, 24928, 28510, 28411, 28351, 32396, 32467, 32264, 32540, 32467, 32396, 32736, - 32748, 32308, 32945, 32748, 32736, 18203, 18261, 17997, 23045, 23195, 23222, 23067, 23195, - 23045, 32924, 32986, 32959, 33165, 33133, 33025, 33053, 32986, 32924, 8864, 8848, 8800, - 11327, 11503, 11477, 20921, 20794, 20879, 21034, 21006, 20921, 21431, 21619, 21800, 28965, - 29242, 29487, 28550, 28548, 28510, 28510, 28457, 28411, 29880, 30336, 29803, 29975, 30112, - 29880, 30086, 30112, 29975, 30449, 30374, 30167, 33551, 33244, 33673, 33093, 33213, 33141, - 33141, 33213, 33164, 33164, 33213, 33162, 33244, 32920, 33673, 33233, 33107, 33168, 33233, - 33168, 33153, 25397, 25580, 25358, 26050, 26248, 26202, 26202, 26429, 26367, 26672, 26611, - 26792, 27126, 27252, 26998, 25397, 25358, 25346, 8992, 8936, 8848, 8860, 8919, 8963, - 8850, 8919, 8860, 10098, 10053, 10174, 10457, 10568, 10104, 10573, 10517, 10609, 10585, - 10851, 10766, 19437, 19298, 19398, 19418, 19298, 19437, 33165, 33025, 33055, 33247, 33233, - 33153, 8848, 8936, 8771, 14250, 14033, 14255, 27727, 27641, 27598, 26585, 26670, 26604, - 27727, 27744, 27869, 11017, 11327, 11462, 10601, 10874, 10787, 10962, 11017, 11398, 10641, - 10787, 10733, 16795, 16960, 16720, 28411, 28313, 28192, 28458, 28313, 28411, 9136, 9115, - 9175, 9503, 9486, 9608, 10743, 10585, 10766, 13457, 13535, 13519, 13803, 13686, 13885, - 18066, 17882, 17950, 14503, 14533, 14676, 17816, 17882, 18066, 18250, 18292, 18430, 18250, - 18430, 18359, 25302, 25397, 25346, 28187, 27871, 28192, 8771, 8918, 8805, 18359, 18430, - 18520, 21539, 21453, 21030, 18175, 18203, 18020, 18281, 18203, 18175, 32674, 32235, 32387, - 8919, 8940, 8963, 9005, 8890, 9055, 9209, 9014, 9371, 8776, 8940, 8919, 25161, - 25278, 25196, 24883, 24978, 24928, 25053, 24978, 24883, 33247, 33153, 33083, 33113, 33165, - 33055, 10252, 10568, 10517, 14377, 14330, 14250, 14122, 13929, 14033, 14676, 14533, 14836, - 14503, 14403, 14369, 8918, 9146, 8770, 21772, 21431, 21800, 26585, 26383, 26575, 26585, - 26177, 26383, 26162, 26248, 26050, 26162, 26050, 25923, 32135, 32540, 32176, 32005, 32112, - 32135, 32181, 31788, 32060, 26301, 26429, 26202, 10528, 10573, 10585, 11215, 11224, 11319, - 13457, 13625, 13582, 13582, 13625, 13588, 28454, 28187, 28313, 28313, 28187, 28192, 8770, - 9072, 8804, 8770, 9252, 9072, 21664, 21670, 21757, 21453, 21566, 21664, 19116, 18330, - 18337, 25923, 25620, 25834, 25284, 25278, 25161, 22253, 22219, 22183, 22862, 22928, 22897, - 26750, 26670, 26649, 26882, 26750, 27109, 33419, 32843, 32873, 33110, 33113, 33055, 32975, - 32852, 32837, 32975, 32837, 32976, 10585, 10573, 10609, 10743, 10766, 10680, 10305, 10541, - 10448, 9994, 10309, 9972, 13686, 13582, 13588, 13929, 13803, 14011, 13929, 14011, 14033, - 8659, 8807, 8883, 21566, 21670, 21664, 31455, 31469, 31339, 31434, 31403, 31281, 31130, - 31054, 30952, 33247, 33083, 33305, 11119, 11034, 11378, 29242, 29497, 29685, 32694, 32414, - 32791, 32414, 32443, 32791, 24737, 24233, 24144, 24978, 25284, 25161, 12092, 11976, 12056, - 12056, 11976, 11870, 11870, 11801, 11649, 11649, 11419, 11646, 11119, 11160, 11034, 11848, - 11976, 11819, 11976, 11837, 11870, 33110, 32959, 32986, 33211, 33083, 33133, 33211, 33133, - 33165, 10946, 11007, 11008, 13457, 13352, 13535, 13415, 13582, 13686, 18020, 17997, 17904, - 17263, 17441, 17211, 28078, 28350, 28071, 27857, 27886, 27729, 27726, 27535, 27519, 27726, - 27519, 27632, 11476, 11630, 11503, 11846, 12250, 12271, 12671, 12768, 12965, 15186, 14633, - 14378, 25720, 25525, 25887, 24990, 24484, 24912, 21146, 21218, 21431, 22666, 22897, 22621, - 23637, 23803, 23230, 24582, 24737, 24144, 32497, 32516, 32442, 32598, 32516, 32497, 32598, - 32497, 32582, 32421, 32603, 33021, 33175, 33110, 32986, 10097, 10027, 10098, 10053, 9847, - 10129, 9533, 9503, 9608, 9995, 10027, 10097, 10863, 11017, 10962, 11327, 11311, 11503, - 10863, 10962, 10874, 28548, 28457, 28510, 8807, 8786, 8937, 8940, 8868, 8951, 8776, - 8868, 8940, 10573, 10396, 10517, 10528, 10396, 10573, 13803, 13777, 13686, 14122, 14033, - 14250, 22377, 22524, 22466, 22401, 22524, 22377, 27570, 27182, 27383, 27889, 27727, 27869, - 28247, 27727, 27889, 28189, 27889, 28187, 27252, 27032, 26998, 30952, 31054, 30823, 33187, - 33211, 33165, 33175, 32986, 33053, 11589, 11419, 11649, 19588, 19894, 20006, 18783, 18796, - 18826, 33162, 33195, 33000, 33310, 33213, 33093, 26248, 26301, 26202, 27126, 26998, 26792, - 25620, 25580, 25834, 26207, 26301, 26248, 10522, 10641, 10733, 14533, 14503, 14483, 15017, - 15295, 14764, 27570, 27383, 27641, 26531, 26672, 26429, 31009, 30823, 30763, 31403, 31469, - 31455, 31494, 31469, 31403, 11296, 11311, 11327, 12981, 13294, 13001, 16487, 16541, 16548, - 16548, 16795, 16720, 16960, 17012, 17211, 22928, 23067, 23045, 22862, 23067, 22928, 25590, - 25580, 25397, 25590, 25397, 25533, 26510, 26531, 26429, 30253, 30124, 30086, 30112, 30185, - 29880, 28548, 28557, 28457, 30253, 30086, 30237, 32112, 32168, 32135, 32292, 32168, 32112, - 10743, 10528, 10585, 10925, 10946, 11008, 10925, 11008, 11034, 30363, 30707, 30389, 30629, - 30707, 30363, 30436, 30363, 30304, 30314, 30304, 30122, 32887, 32603, 32716, 32791, 32443, - 32769, 16541, 16795, 16548, 32704, 32582, 32781, 32704, 32598, 32582, 22524, 22638, 22621, - 22468, 22638, 22524, 8804, 9072, 8584, 26006, 25720, 25887, 26420, 25887, 26177, 26585, - 26575, 26670, 11419, 11215, 11319, 30374, 30703, 30487, 30436, 30314, 30528, 33139, 32945, - 32751, 33139, 32751, 32981, 32516, 32517, 32387, 32608, 32517, 32516, 28274, 28350, 28121, - 27527, 27632, 27422, 31130, 31241, 31179, 31274, 31241, 31130, 8842, 8738, 8939, 8853, - 8737, 8861, 8807, 8754, 8786, 8451, 8738, 8842, 8451, 8842, 8849, 8730, 8849, - 8830, 8730, 8830, 8808, 8730, 8808, 8800, 8730, 8800, 8848, 8730, 8848, 8394, - 8848, 8771, 8733, 8738, 8737, 8853, 8786, 8850, 8894, 8754, 8850, 8786, 9170, - 9136, 9175, 9006, 9117, 9108, 9229, 9136, 9235, 9191, 9399, 9211, 9399, 9369, - 9211, 9486, 9443, 9462, 9533, 9811, 9782, 10946, 10844, 11007, 10783, 10844, 10946, - 13415, 13352, 13457, 12092, 12056, 12176, 13415, 13457, 13582, 25302, 25346, 25278, 28121, - 28350, 28078, 27857, 27729, 27726, 33213, 33195, 33162, 14369, 14330, 14377, 13929, 13777, - 13803, 32060, 31788, 31760, 31241, 31434, 31196, 9006, 9108, 9003, 11215, 11160, 11224, - 19212, 18961, 19298, 18009, 17816, 18066, 18203, 18281, 18337, 18203, 17997, 18020, 17638, - 17627, 17808, 30424, 30374, 30487, 30314, 30436, 30304, 33095, 33175, 33053, 32725, 32716, - 32705, 8737, 8722, 8861, 21006, 20919, 20921, 21043, 20919, 21006, 21043, 21006, 21218, - 8868, 8890, 9005, 8780, 8890, 8868, 22638, 22666, 22621, 22823, 22666, 22638, 33095, - 33053, 32975, 33187, 33165, 33113, 21218, 21034, 21431, 8733, 8771, 8805, 33187, 33113, - 33612, 9503, 9443, 9486, 21772, 21833, 22059, 27150, 27126, 26792, 27953, 27705, 27786, - 28457, 28458, 28411, 29685, 29497, 29803, 16862, 17012, 16960, 16862, 16960, 16795, 24837, - 25053, 24883, 24582, 24144, 24475, 17012, 17263, 17211, 32835, 32725, 32705, 32835, 32705, - 32694, 10844, 10680, 10766, 10396, 10252, 10517, 10590, 10680, 10844, 17882, 17813, 17657, - 18009, 18115, 18250, 25471, 24990, 25451, 9633, 9752, 9484, 10522, 10511, 10641, 9097, - 9632, 9305, 26301, 26510, 26429, 26531, 26611, 26672, 26162, 26207, 26248, 26245, 26207, - 26162, 26343, 26207, 26245, 17638, 17587, 17627, 21688, 21518, 21804, 8850, 8776, 8919, - 8708, 8776, 8850, 10125, 10252, 10187, 9617, 9533, 9782, 11837, 11801, 11870, 11419, - 11396, 11215, 11215, 11096, 11160, 11976, 11848, 11837, 12092, 12353, 12561, 14330, 14122, - 14250, 19313, 19212, 19298, 19451, 19437, 19491, 22183, 22219, 21987, 33195, 33185, 33000, - 33415, 33612, 33562, 11848, 11801, 11837, 11976, 12092, 11921, 13904, 13777, 13929, 27705, - 27857, 27726, 27705, 27726, 27632, 28652, 28557, 28548, 14503, 14369, 14377, 14330, 14169, - 14122, 14676, 14836, 14963, 25053, 25284, 24978, 25590, 25834, 25580, 11801, 11589, 11649, - 10883, 10925, 11034, 8657, 8733, 8805, 8657, 8805, 8693, 9503, 9424, 9443, 9424, - 9533, 9394, 19212, 19062, 18961, 17741, 17813, 17816, 19081, 19062, 19212, 21670, 21957, - 21757, 21566, 21539, 21670, 21488, 21518, 21539, 8890, 8905, 9250, 8851, 8905, 8890, - 11311, 11476, 11503, 11276, 11476, 11311, 11296, 11327, 11017, 12250, 12436, 12671, 12314, - 12436, 12250, 22666, 22862, 22897, 23637, 23230, 23195, 22823, 22862, 22666, 33415, 33305, - 33187, 33157, 33095, 32975, 33157, 32975, 32976, 10883, 11034, 10896, 10125, 10104, 10252, - 10808, 10863, 10874, 10808, 10874, 10601, 17816, 17813, 17882, 18009, 18250, 18109, 17627, - 17587, 17422, 23637, 23195, 23182, 28557, 28458, 28457, 26670, 26750, 26882, 8734, 8804, - 8584, 9003, 9108, 9115, 9314, 9462, 9443, 9314, 9428, 9462, 9136, 9003, 9115, - 11345, 11396, 11419, 16885, 16862, 16795, 17012, 16979, 17263, 17646, 17627, 17422, 24737, - 24816, 24837, 24745, 24816, 24737, 30124, 30185, 30112, 28712, 28597, 28557, 28557, 28597, - 28458, 30284, 30185, 30124, 30284, 30124, 30253, 32781, 32582, 32991, 32598, 32608, 32516, - 9633, 9994, 9972, 14925, 14490, 14560, 25302, 25533, 25397, 25302, 25278, 25284, 27857, - 28043, 27886, 27527, 27422, 27252, 9072, 9037, 8584, 22253, 22401, 22377, 22339, 22401, - 22253, 9396, 9314, 9443, 16487, 16548, 16288, 32517, 32618, 32387, 32691, 32608, 32598, - 32725, 32887, 32716, 32872, 32887, 32725, 10894, 11296, 11017, 10601, 10787, 10641, 10863, - 10894, 11017, 10452, 10511, 10522, 29765, 30294, 30314, 27845, 28043, 27857, 8480, 8754, - 8807, 8776, 8780, 8868, 20006, 20305, 20613, 26207, 26343, 26301, 27126, 27170, 27252, - 26245, 26162, 25923, 18109, 18250, 18359, 19116, 18337, 18281, 17969, 18020, 17904, 17969, - 17904, 17808, 8724, 8780, 8692, 17813, 17624, 17657, 17741, 17624, 17813, 17646, 17422, - 17249, 19062, 18944, 18961, 19019, 18944, 19062, 25533, 25574, 25590, 25413, 25302, 25284, - 26604, 26670, 26882, 25471, 25038, 24990, 27034, 27182, 27254, 26343, 26510, 26301, 21688, - 21957, 21670, 33213, 33325, 33195, 33195, 33329, 33185, 33419, 33286, 32843, 33432, 33310, - 33093, 33432, 33093, 33794, 33591, 33107, 33233, 33447, 33233, 33247, 33305, 33083, 33211, - 9191, 9149, 9229, 9141, 9211, 9369, 24816, 25053, 24837, 24475, 24144, 23938, 30528, - 30453, 30436, 30436, 30453, 30363, 31117, 31131, 30952, 30952, 31131, 31130, 29028, 28815, - 28350, 28160, 28274, 28121, 33181, 33157, 32976, 33187, 33612, 33415, 31009, 30763, 30707, - 31599, 31494, 31434, 31434, 31494, 31403, 10252, 10104, 10568, 10528, 10743, 10680, 31316, - 31434, 31241, 14139, 14169, 14210, 14369, 14169, 14330, 13351, 13415, 13342, 14764, 14925, - 14560, 19588, 19451, 19491, 33310, 33325, 33213, 16288, 16548, 15929, 16885, 16979, 16862, - 16862, 16979, 17012, 9533, 9424, 9503, 9092, 9191, 9211, 9943, 10053, 10027, 17856, - 17969, 17808, 18040, 18281, 18175, 18040, 17969, 17947, 25542, 25574, 25533, 25676, 25574, - 25554, 30453, 30629, 30363, 11921, 11819, 11976, 11848, 11611, 11801, 11801, 11667, 11589, - 11589, 11345, 11419, 11921, 11857, 11799, 12353, 12951, 12561, 13004, 13543, 13352, 8754, - 8708, 8850, 10856, 10894, 10863, 10511, 10601, 10641, 10569, 10601, 10511, 11611, 11667, - 11801, 11096, 11034, 11160, 13548, 13415, 13686, 13904, 13929, 14122, 19451, 19418, 19437, - 20794, 20722, 20879, 19588, 19530, 19451, 19451, 19530, 19418, 20794, 20921, 20919, 20794, - 20919, 20864, 20919, 20949, 20864, 28454, 28189, 28187, 28454, 28313, 28458, 33325, 33329, - 33195, 33187, 33305, 33211, 33194, 33175, 33095, 20919, 21043, 20949, 33157, 33194, 33095, - 33232, 33181, 32976, 10104, 9995, 10097, 26611, 27150, 26792, 27705, 27845, 27857, 28043, - 28160, 28121, 8737, 8635, 8722, 8722, 8648, 8861, 8754, 8673, 8708, 8555, 8635, - 8737, 8555, 8737, 8738, 8555, 8738, 8451, 20949, 21043, 21060, 8780, 8851, 8890, - 8905, 8896, 9260, 8724, 8851, 8780, 11667, 11535, 11589, 18944, 18783, 18826, 18848, - 18783, 18944, 8635, 8662, 8722, 10925, 10783, 10946, 11250, 11215, 11396, 10856, 10863, - 10808, 13220, 13004, 13352, 28712, 28557, 28652, 32424, 32540, 32135, 32564, 32540, 32670, - 8662, 8648, 8722, 16885, 16795, 16587, 24582, 24745, 24737, 24612, 24745, 24582, 27953, - 27845, 27705, 31131, 31274, 31130, 31117, 31274, 31131, 32704, 32691, 32598, 32833, 32781, - 32928, 32793, 32781, 32833, 32769, 32443, 32467, 32887, 33021, 32603, 19418, 19313, 19298, - 19519, 19313, 19418, 21957, 22183, 21987, 22468, 22823, 22638, 22862, 22846, 23067, 24744, - 24794, 24745, 26466, 26611, 26510, 26510, 26611, 26531, 26105, 26245, 25923, 32042, 31487, - 31469, 9092, 9149, 9191, 9271, 9369, 9314, 32835, 32872, 32725, 8648, 8659, 8883, - 9015, 9271, 9314, 24794, 25053, 24816, 32608, 32618, 32517, 32805, 32691, 32704, 8664, - 9003, 8622, 9006, 8866, 8979, 26585, 26471, 26177, 26471, 26604, 26568, 26466, 26510, - 26343, 31494, 31560, 31469, 31690, 31560, 31494, 10481, 10528, 10680, 9821, 9943, 9874, - 22468, 22524, 22401, 8913, 8866, 9006, 8834, 8896, 8905, 25676, 25834, 25590, 25676, - 25590, 25574, 10768, 10783, 10883, 10883, 10783, 10925, 10720, 10856, 10808, 11345, 11250, - 11396, 12436, 12513, 12671, 12314, 12513, 12436, 12314, 12250, 11846, 12271, 11420, 11846, - 11311, 11296, 11276, 30336, 29685, 29803, 30424, 30284, 30253, 30424, 30253, 30374, 22183, - 22282, 22253, 33329, 33335, 33185, 32691, 32618, 32608, 25542, 25533, 25302, 30374, 30449, - 30703, 9995, 9943, 10027, 9847, 9943, 9821, 9994, 10305, 10448, 10601, 10720, 10808, - 31274, 31316, 31241, 31584, 31316, 31752, 18783, 18568, 18796, 17929, 17741, 17816, 18730, - 18568, 18783, 22282, 22339, 22253, 22823, 22846, 22862, 22851, 22846, 22823, 14561, 14503, - 14676, 11041, 11296, 10907, 10659, 10720, 10601, 15017, 15785, 15295, 17929, 17816, 18009, - 32989, 33021, 32887, 16587, 16795, 16541, 17249, 17422, 17263, 24745, 24794, 24816, 25413, - 25542, 25302, 24043, 23938, 23803, 32781, 32793, 32704, 32691, 32815, 32618, 32805, 32793, - 32833, 10305, 10452, 10522, 11250, 11096, 11215, 12513, 12768, 12671, 18240, 18109, 18359, - 30703, 31174, 31056, 30770, 31009, 30707, 30453, 30669, 30629, 29765, 29530, 30294, 32791, - 32835, 32694, 33047, 32989, 32887, 32829, 32835, 32791, 9424, 9396, 9443, 9394, 9396, - 9424, 25554, 25542, 25557, 8693, 8805, 8770, 8733, 8616, 8848, 8734, 8770, 8804, - 21539, 21688, 21670, 21957, 22016, 22183, 22183, 22172, 22282, 22282, 22172, 22339, 18040, - 18175, 18020, 8683, 9014, 9209, 27150, 27170, 27126, 27382, 27170, 27150, 8584, 9037, - 8979, 19081, 19019, 19062, 19081, 19212, 19313, 22339, 22453, 22401, 22428, 22453, 22339, - 8539, 8693, 8492, 9847, 9617, 10129, 9752, 9633, 9972, 10063, 10275, 10305, 9484, - 9961, 9632, 22552, 21772, 22059, 22552, 22450, 22954, 8709, 8834, 8905, 8896, 8762, - 9209, 8709, 8905, 8851, 18568, 18520, 18430, 18405, 18520, 18461, 32181, 32292, 32112, - 32540, 32648, 32467, 32288, 32292, 32181, 33203, 33194, 33157, 33203, 33157, 33181, 10187, - 10252, 10396, 10750, 10590, 10844, 10750, 10844, 10783, 10767, 10894, 10856, 10569, 10659, - 10601, 13415, 13351, 13352, 11799, 11819, 11921, 13220, 13351, 13342, 30770, 30707, 30629, - 25754, 25876, 25834, 25834, 25876, 25923, 26245, 26466, 26343, 27562, 27426, 27681, 25754, - 25834, 25676, 32564, 32648, 32540, 32042, 32060, 31487, 31828, 31469, 31560, 8866, 8785, - 8979, 9003, 8913, 9006, 8823, 8913, 9003, 17969, 18040, 18020, 17646, 17808, 17627, - 17006, 17263, 16979, 30336, 29880, 30185, 30295, 30185, 30284, 30295, 30284, 30420, 22453, - 22468, 22401, 22696, 22468, 22604, 11096, 10896, 11034, 28597, 28592, 28458, 26420, 26471, - 26568, 28779, 28712, 28652, 31361, 30449, 30724, 30420, 30284, 30424, 30669, 30770, 30629, - 25554, 25574, 25542, 25730, 25754, 25676, 29685, 29487, 29242, 9149, 9032, 9136, 9141, - 9092, 9211, 9141, 9369, 9271, 9014, 9097, 9305, 9943, 9847, 10053, 9939, 9995, - 10104, 32793, 32805, 32704, 33139, 32748, 32945, 11535, 11486, 11589, 11004, 10992, 11096, - 11096, 10992, 10896, 11667, 11486, 11535, 11611, 11486, 11667, 11611, 11848, 11819, 11611, - 11819, 11799, 19611, 19530, 19588, 33325, 33374, 33329, 33329, 33347, 33335, 33362, 33139, - 32981, 33310, 33432, 33325, 33470, 33432, 33794, 18520, 18405, 18359, 18109, 17929, 18009, - 18321, 18405, 18461, 18240, 18405, 18321, 33113, 33110, 33612, 33298, 33203, 33181, 10590, - 10481, 10680, 10546, 10481, 10590, 10767, 10856, 10684, 10452, 10569, 10511, 10542, 10569, - 10433, 30294, 29530, 29293, 28086, 28160, 28043, 27953, 28043, 27845, 11486, 11345, 11589, - 12513, 12582, 12768, 10856, 10720, 10684, 25413, 25284, 25053, 8652, 8780, 8776, 8638, - 8776, 8708, 10896, 10768, 10883, 10850, 10768, 10896, 10684, 10720, 10512, 12768, 12981, - 13001, 16587, 16541, 16487, 12709, 12981, 12768, 23375, 22552, 22954, 28712, 28592, 28597, - 28595, 28592, 28779, 8566, 8673, 8489, 14764, 14561, 14676, 13342, 13415, 13392, 14560, - 14561, 14764, 21810, 22016, 21957, 11041, 11276, 11296, 18091, 17929, 18109, 16572, 15795, - 15785, 18621, 19116, 18281, 17856, 17947, 17969, 30420, 30424, 30487, 32873, 33185, 33419, - 10187, 10396, 10528, 30613, 30420, 30487, 22016, 22135, 22183, 33432, 33374, 33325, 33305, - 33415, 33247, 33524, 33415, 33562, 20722, 20647, 20613, 20794, 20647, 20722, 20621, 20647, - 20794, 20866, 20794, 20864, 25643, 25413, 25053, 32769, 32829, 32791, 32424, 32135, 32168, - 8635, 8555, 8662, 8662, 8589, 8648, 8648, 8495, 8659, 8489, 8673, 8754, 8511, - 8555, 8295, 8616, 8733, 8657, 10099, 10187, 10528, 10768, 10750, 10783, 10633, 10750, - 10768, 10512, 10720, 10659, 11041, 11267, 11276, 26604, 26471, 26585, 24990, 24404, 24484, - 28247, 27889, 28189, 26288, 26245, 26105, 26288, 26466, 26245, 25923, 25876, 26105, 25876, - 26042, 26105, 28592, 28454, 28458, 28595, 28454, 28592, 32333, 32424, 32168, 32268, 32288, - 32181, 21060, 21043, 21218, 21060, 21218, 21146, 9349, 9484, 9632, 10569, 10452, 10433, - 10512, 10542, 10433, 16885, 17006, 16979, 17646, 17856, 17808, 16775, 17006, 16885, 16587, - 16487, 16288, 33047, 32887, 32872, 33021, 33232, 32976, 32667, 32467, 32648, 8555, 8589, - 8662, 20949, 21060, 20866, 12253, 12582, 12513, 9092, 9032, 9149, 9076, 9032, 9092, - 8673, 8638, 8708, 8566, 8638, 8673, 33374, 33347, 33329, 32333, 32168, 32292, 17857, - 17856, 17646, 18082, 18281, 18040, 23182, 23195, 23067, 24794, 24853, 25053, 23182, 23067, - 22846, 22851, 22823, 22738, 8834, 8762, 8896, 9014, 8488, 9097, 8724, 8709, 8851, - 8639, 8709, 8724, 8913, 8785, 8866, 8539, 8657, 8693, 8823, 8785, 8913, 18848, - 18944, 19019, 18405, 18240, 18359, 33407, 33185, 33335, 9939, 9943, 9995, 10127, 10187, - 10099, 11004, 11096, 11250, 12582, 12709, 12768, 13351, 13220, 13352, 13415, 13548, 13392, - 20418, 20006, 20613, 19099, 19081, 19313, 23637, 24043, 23803, 30765, 30613, 30703, 30703, - 30613, 30487, 32650, 32667, 32648, 32650, 32648, 32564, 9045, 9141, 9015, 9357, 9394, - 9533, 9366, 9394, 9357, 10032, 10104, 10125, 9847, 9582, 9617, 9996, 10032, 10125, - 10992, 10888, 10896, 10750, 10546, 10590, 30528, 30669, 30453, 30770, 31275, 31009, 31009, - 31117, 30952, 30489, 30669, 30528, 9270, 9314, 9396, 8688, 8823, 8664, 22696, 22823, - 22468, 32928, 32781, 32991, 32805, 32815, 32691, 32618, 32674, 32387, 8638, 8652, 8776, - 8604, 8652, 8638, 10032, 9939, 10104, 19519, 19418, 19530, 17857, 18040, 17947, 11233, - 11004, 11345, 11004, 10762, 10992, 10992, 10762, 10888, 12561, 12951, 13004, 24043, 24475, - 23938, 8539, 8616, 8657, 8693, 8770, 8492, 10633, 10546, 10750, 10569, 10542, 10659, - 11296, 10894, 10907, 10452, 10305, 10275, 12960, 12561, 13004, 14139, 14122, 14169, 15631, - 15929, 15664, 17885, 17857, 17773, 32667, 32769, 32467, 32740, 32769, 32667, 27426, 27252, - 27170, 27786, 27705, 27632, 25876, 25754, 25730, 10888, 10850, 10896, 10762, 10850, 10888, - 33047, 32872, 32835, 33047, 32835, 33054, 33481, 33447, 33247, 33432, 33470, 33374, 33374, - 33470, 33347, 33481, 33247, 33415, 33481, 33569, 33447, 25730, 25554, 25557, 25730, 25676, - 25554, 32288, 32333, 32292, 32776, 32650, 32564, 32341, 32333, 32288, 32341, 32288, 32268, - 31599, 31434, 31316, 27527, 27252, 27426, 28764, 28350, 28274, 8652, 8692, 8780, 8601, - 8692, 8652, 33499, 33407, 33335, 33499, 33335, 33347, 15051, 15664, 15370, 8504, 8539, - 8492, 11276, 11267, 11476, 12460, 12577, 12582, 12582, 12577, 12709, 10894, 10767, 10794, - 15631, 16288, 15929, 21688, 21804, 21957, 22016, 22034, 22135, 22135, 22172, 22183, 21539, - 21030, 21488, 32611, 32540, 32424, 33414, 33194, 33203, 28266, 28247, 28189, 28266, 28189, - 28454, 31275, 31117, 31009, 8785, 8584, 8979, 8622, 9136, 9032, 25557, 25542, 25413, - 28779, 28592, 28712, 33251, 33232, 33021, 21804, 21810, 21957, 33407, 33419, 33185, 33046, - 32991, 33106, 33065, 32820, 32833, 33460, 33419, 33407, 9141, 9076, 9092, 9045, 9076, - 9141, 24475, 24612, 24582, 24593, 24612, 24475, 24744, 24612, 24593, 24475, 24513, 24593, - 16587, 16775, 16885, 17006, 16775, 16912, 32833, 32820, 32805, 32582, 32748, 32991, 9939, - 9874, 9943, 9695, 9582, 9847, 9808, 9874, 9939, 9931, 9939, 10032, 10127, 10125, - 10187, 17814, 17624, 17741, 14210, 14169, 14369, 30669, 31275, 30770, 28385, 28274, 28160, - 33275, 33251, 33021, 33054, 32835, 32829, 32853, 32829, 32769, 9394, 9366, 9396, 9357, - 9533, 9617, 25633, 25557, 25413, 14403, 14503, 14561, 27660, 27681, 27557, 31584, 31599, - 31316, 32650, 32740, 32667, 32853, 32740, 32888, 27953, 28086, 28043, 27980, 28086, 27953, - 8692, 8639, 8724, 8709, 8694, 8834, 8553, 8639, 8692, 19081, 18848, 19019, 18730, - 18848, 18890, 12960, 13004, 13220, 13222, 13220, 13342, 12253, 12513, 12314, 12709, 12690, - 12981, 14014, 14633, 13996, 21810, 22034, 22016, 33551, 33008, 33244, 14560, 14403, 14561, - 31690, 31828, 31560, 9695, 9847, 9821, 26471, 26420, 26177, 26750, 27034, 27109, 32562, - 32528, 32424, 32518, 32341, 32605, 32815, 32674, 32618, 14014, 13996, 13265, 18461, 18520, - 18568, 17900, 17825, 17929, 17929, 17825, 17741, 25730, 26042, 25876, 26105, 26194, 26288, - 27562, 27681, 27692, 26194, 26042, 26156, 30698, 30498, 30420, 30347, 30336, 30295, 30295, - 30336, 30185, 28773, 28779, 28931, 28931, 28779, 28652, 30936, 30765, 30703, 8480, 8807, - 8659, 22034, 22147, 22135, 10542, 10512, 10659, 10305, 9754, 10063, 13392, 13222, 13342, - 20647, 20418, 20613, 18697, 18730, 18890, 20866, 20621, 20794, 20866, 20864, 20949, 20866, - 21060, 21146, 28257, 28385, 28160, 18848, 18730, 18783, 19611, 19588, 19822, 22428, 22468, - 22453, 22851, 23182, 22846, 24612, 24744, 24745, 24475, 24043, 24513, 27109, 27034, 27254, - 32991, 33301, 33214, 32820, 32815, 32805, 20621, 20418, 20647, 21146, 21431, 21772, 10341, - 10528, 10481, 10449, 10481, 10546, 14139, 13904, 14122, 14038, 13904, 14139, 25471, 25451, - 25720, 33050, 32815, 32820, 8589, 8495, 8648, 8555, 8511, 8589, 8451, 8849, 8730, - 8451, 8730, 8347, 32423, 32424, 32333, 25038, 24404, 24990, 10331, 10275, 10137, 27947, - 27980, 27953, 28086, 28257, 28160, 33621, 32920, 33107, 33621, 33107, 33622, 11857, 11921, - 12092, 11233, 11345, 11486, 14403, 14210, 14369, 27527, 27786, 27632, 27681, 27426, 27557, - 31828, 32042, 31469, 31599, 31690, 31494, 31713, 31690, 31599, 8566, 8604, 8638, 8601, - 8604, 8285, 10850, 10633, 10768, 11004, 11250, 11345, 12561, 11857, 12092, 11420, 12271, - 11476, 11420, 11476, 11267, 18091, 18109, 18240, 17856, 17857, 17947, 16923, 17263, 17006, - 20804, 21146, 21472, 20450, 20425, 20528, 22147, 22172, 22135, 28663, 28266, 28454, 29741, - 29487, 29685, 32253, 32042, 31828, 33232, 33298, 33181, 33259, 33251, 33275, 33622, 33107, - 33591, 11144, 11420, 11267, 8382, 8495, 8589, 33591, 33447, 33569, 33591, 33233, 33447, - 9249, 9349, 9632, 9463, 9994, 9633, 9249, 9632, 9097, 24404, 24090, 24484, 33282, - 33298, 33232, 8639, 8694, 8709, 8599, 8694, 8639, 22696, 22738, 22823, 22702, 22738, - 22696, 10907, 10894, 10794, 10331, 10433, 10452, 13548, 13686, 13777, 13222, 13154, 13220, - 27570, 27641, 27928, 28343, 28266, 28502, 28373, 28257, 28346, 29331, 29293, 28815, 30347, - 30295, 30498, 33470, 33499, 33347, 33362, 32981, 33286, 33597, 33499, 33735, 11846, 12253, - 12314, 13265, 13996, 12981, 9015, 9141, 9271, 9076, 8981, 9032, 13904, 13874, 13777, - 14121, 14038, 14139, 12460, 12709, 12577, 31752, 31316, 31274, 31690, 31842, 31828, 31713, - 31584, 31729, 8978, 8981, 9076, 33462, 33286, 33419, 32928, 33065, 32833, 25891, 25471, - 25720, 26822, 26568, 26604, 26822, 26604, 26882, 8604, 8601, 8652, 8519, 8601, 8285, - 32740, 32853, 32769, 33270, 33232, 33251, 32888, 32740, 32650, 8823, 8760, 8785, 8688, - 8760, 8823, 8560, 8762, 8834, 8560, 8834, 8694, 32341, 32423, 32333, 32528, 32611, - 32424, 32518, 32423, 32341, 10767, 10651, 10794, 20697, 21030, 20746, 21804, 21872, 21810, - 21810, 21906, 22034, 22034, 22070, 22147, 22070, 22298, 22172, 33569, 33481, 33546, 10762, - 10633, 10850, 10415, 10633, 10424, 32423, 32562, 32424, 8539, 8504, 8616, 8492, 8770, - 8459, 8450, 8480, 8659, 33546, 33481, 33524, 11446, 11486, 11611, 8601, 8553, 8692, - 8519, 8553, 8601, 22172, 22428, 22339, 22298, 22428, 22172, 33499, 33460, 33407, 33597, - 33460, 33499, 18148, 18091, 18240, 18730, 18461, 18568, 18697, 18461, 18730, 9366, 9270, - 9396, 9582, 9357, 9617, 32707, 32611, 32528, 8480, 8489, 8754, 33524, 33481, 33415, - 13840, 13874, 13904, 13169, 13154, 13222, 11777, 11799, 11857, 13169, 13222, 13392, 27641, - 27727, 27928, 10767, 10684, 10651, 18148, 18240, 18321, 17825, 17814, 17741, 33270, 33282, - 33232, 33110, 33718, 33612, 33270, 33251, 33259, 14490, 14403, 14560, 14077, 14210, 14403, - 14077, 14121, 14210, 14210, 14121, 14139, 13739, 13624, 13874, 27928, 27727, 28196, 27426, - 27562, 27527, 28158, 28257, 28086, 26560, 26466, 26288, 31584, 31713, 31599, 32518, 32548, - 32423, 31842, 31713, 31848, 8981, 8900, 9032, 8971, 8978, 9076, 8971, 9076, 9045, - 13600, 13548, 13777, 24513, 24043, 24419, 24744, 24853, 24794, 25981, 26042, 25730, 23182, - 22851, 22738, 32376, 30813, 31665, 30498, 30295, 30420, 32991, 33046, 32928, 32815, 33050, - 32674, 33106, 32991, 33214, 32939, 33054, 32829, 32939, 32829, 32853, 8459, 8770, 8734, - 19822, 19588, 20006, 21518, 21872, 21804, 9357, 9270, 9366, 9207, 9463, 9484, 8841, - 9249, 9097, 32611, 32670, 32540, 32970, 32888, 32650, 10820, 10794, 10710, 33493, 33362, - 33286, 14014, 14378, 14633, 19611, 19519, 19530, 21872, 21906, 21810, 27570, 27254, 27182, - 33175, 33718, 33110, 10633, 10449, 10546, 10415, 10449, 10633, 11799, 11674, 11611, 11777, - 11674, 11799, 11777, 11410, 11605, 11605, 11410, 11430, 13292, 13169, 13392, 28257, 28373, - 28385, 28158, 28086, 27980, 11674, 11590, 11611, 12960, 13220, 13154, 32674, 32376, 31665, - 32363, 32376, 32486, 26042, 26194, 26105, 25981, 25730, 25861, 8553, 8599, 8639, 8519, - 8599, 8553, 22428, 22604, 22468, 22409, 22604, 22428, 33460, 33462, 33419, 33565, 33462, - 33460, 18091, 17900, 17929, 17937, 17900, 18091, 33414, 33203, 33298, 33021, 33328, 33275, - 25861, 25730, 25795, 27562, 27786, 27527, 27856, 27786, 27692, 32423, 32548, 32562, 32562, - 32707, 32528, 32795, 32776, 32670, 32181, 32060, 32268, 26890, 26882, 27109, 26890, 26822, - 26882, 26006, 25887, 26420, 28779, 28773, 28595, 28266, 28343, 28247, 28931, 28652, 29487, - 31056, 30936, 30703, 13548, 13292, 13392, 13874, 13600, 13777, 13624, 13600, 13874, 9996, - 9931, 10032, 9874, 9695, 9821, 9094, 9263, 9357, 9996, 10125, 10127, 22845, 23182, - 22738, 31713, 31842, 31690, 31729, 31584, 31752, 8978, 8900, 8981, 8917, 8971, 8942, - 16912, 16923, 17006, 16912, 16775, 16718, 16775, 16508, 16718, 16587, 16508, 16775, 16306, - 16508, 16587, 24593, 24767, 24744, 24513, 24767, 24593, 25633, 25730, 25557, 9734, 9695, - 9874, 9357, 9263, 9270, 11041, 11144, 11267, 11420, 11529, 11846, 11818, 12460, 12253, - 11077, 11144, 10971, 10822, 11041, 10907, 30465, 29741, 29685, 30420, 30613, 30698, 33414, - 33298, 33282, 8394, 8616, 8308, 8394, 8848, 8616, 8511, 8382, 8589, 8495, 8450, - 8659, 8480, 8447, 8489, 20621, 20609, 20418, 20418, 20355, 20006, 19611, 19676, 19519, - 20804, 20609, 20621, 20804, 20621, 20866, 20804, 20866, 21146, 19116, 20697, 20366, 21518, - 21618, 21872, 22019, 22070, 21906, 20987, 20913, 21105, 10433, 10370, 10512, 10794, 10820, - 10907, 10275, 10331, 10452, 10063, 9754, 10011, 13422, 13292, 13548, 12970, 12960, 13154, - 16923, 17249, 17263, 17857, 17885, 18040, 20804, 20450, 20528, 28644, 28454, 28595, 27189, - 27109, 27254, 33724, 33673, 33621, 33621, 33673, 32920, 33551, 33794, 33008, 33724, 33621, - 33635, 33621, 33622, 33635, 33622, 33591, 33635, 33591, 33629, 33635, 33569, 33629, 33591, - 12970, 13154, 12985, 20528, 20355, 20418, 28773, 28644, 28595, 28758, 28644, 28773, 30698, - 30613, 30765, 33912, 33631, 33551, 33569, 33798, 33629, 17900, 17814, 17825, 17937, 17814, - 17900, 18148, 18321, 18257, 17773, 17857, 17646, 25643, 25633, 25413, 33428, 33414, 33282, - 33184, 32989, 33047, 8358, 8382, 8511, 8489, 8314, 8566, 9931, 9808, 9939, 16572, - 16230, 15795, 13739, 13874, 13840, 8382, 8430, 8495, 28196, 27727, 28247, 27110, 26890, - 27109, 27786, 27947, 27953, 27856, 27947, 27786, 33428, 33282, 33270, 33569, 33546, 33798, - 8568, 8584, 8785, 8568, 8785, 8760, 9647, 9734, 9618, 9971, 9996, 10127, 19099, - 18848, 19081, 32253, 32268, 32042, 31752, 31274, 31117, 33462, 33493, 33286, 33106, 33065, - 33046, 33545, 33493, 33462, 8398, 8616, 8504, 8398, 8504, 8492, 11595, 11605, 11430, - 12985, 13154, 13169, 13068, 12985, 13169, 13432, 13422, 13548, 13432, 13548, 13600, 22070, - 22172, 22147, 22604, 22702, 22696, 22070, 22034, 21906, 28343, 28196, 28247, 28291, 28196, - 28343, 28145, 28158, 27980, 33707, 33546, 33524, 33652, 33612, 33834, 26487, 26420, 26568, - 25038, 24683, 24404, 24404, 23957, 24090, 32670, 32776, 32564, 33125, 33094, 33054, 33054, - 33094, 33047, 32795, 32670, 32611, 8430, 8450, 8495, 12253, 12460, 12582, 14459, 14794, - 14378, 11818, 12253, 11846, 17471, 17500, 16425, 30923, 30698, 30765, 30923, 30765, 30936, - 17210, 17322, 17249, 17682, 17773, 17646, 16288, 15631, 15881, 24767, 24853, 24744, 24719, - 24853, 24767, 33046, 33065, 32928, 33050, 33065, 33098, 26037, 26156, 25981, 25981, 26156, - 26042, 27150, 26611, 27382, 25934, 25981, 25861, 8917, 8900, 8978, 8917, 8978, 8971, - 24419, 24043, 24234, 32939, 32853, 32888, 8998, 9015, 9314, 8998, 9314, 9270, 32970, - 32939, 32888, 17885, 18082, 18040, 17682, 17646, 17322, 20987, 21488, 21030, 33184, 33021, - 32989, 33360, 33428, 33270, 18439, 18321, 18461, 19519, 19099, 19313, 18504, 18439, 18461, - 19025, 19099, 19147, 22298, 22319, 22428, 22333, 22319, 22298, 25795, 25730, 25633, 25795, - 25934, 25861, 26822, 26856, 26568, 27110, 27109, 27189, 33735, 33499, 33857, 10651, 10684, - 10416, 20102, 19822, 20006, 33707, 33524, 33761, 10449, 10341, 10481, 10424, 10633, 10442, - 10633, 10582, 10442, 33199, 33184, 33047, 28064, 28145, 27980, 27692, 27786, 27562, 28064, - 27980, 27947, 8303, 8398, 8492, 8450, 8447, 8480, 9459, 9357, 9582, 9459, 9582, - 9695, 9808, 9734, 9874, 9734, 9808, 9702, 16425, 17500, 16671, 17500, 17624, 16671, - 25643, 25795, 25633, 27189, 27254, 27414, 31729, 31848, 31713, 31859, 31848, 31729, 8285, - 8604, 8566, 8496, 8560, 8694, 11777, 11605, 11674, 11674, 11595, 11590, 11590, 11446, - 11611, 12661, 12561, 12960, 22319, 22409, 22428, 23861, 24043, 23637, 22333, 22409, 22319, - 12460, 12690, 12709, 28502, 28291, 28343, 29751, 28931, 29487, 11595, 11446, 11590, 17913, - 18082, 17885, 17322, 17646, 17249, 33360, 33270, 33259, 33652, 33683, 33612, 33360, 33259, - 33275, 11446, 11233, 11486, 15734, 15631, 15479, 17210, 17249, 16959, 28764, 28385, 28373, - 28764, 28274, 28385, 30489, 30789, 30669, 28346, 28257, 28158, 33065, 33050, 32820, 32748, - 33301, 32991, 10415, 10341, 10449, 9702, 9808, 9931, 10307, 10341, 10415, 32748, 33139, - 33301, 33266, 33125, 33054, 33094, 33199, 33047, 33514, 33360, 33275, 14490, 14349, 14403, - 14771, 14349, 14490, 33683, 33524, 33562, 33683, 33562, 33612, 16671, 17624, 17814, 33597, - 33565, 33460, 33493, 33519, 33362, 33642, 33565, 33597, 10416, 10684, 10512, 16759, 16923, - 16912, 33327, 33199, 33316, 32017, 31752, 31117, 13068, 13169, 13144, 13904, 14038, 13840, - 28177, 28346, 28158, 27856, 28064, 27947, 28107, 28064, 27856, 8471, 8694, 8599, 8762, - 8683, 9209, 18586, 18461, 18697, 18148, 17937, 18091, 32548, 32573, 32562, 32933, 32970, - 32650, 33266, 33257, 33125, 32268, 32060, 32042, 31828, 31842, 31956, 8254, 8459, 8734, - 26890, 26856, 26822, 26865, 26856, 26888, 31956, 31842, 31848, 15295, 15222, 14764, 15795, - 15542, 15785, 15393, 15542, 15465, 26611, 26466, 26749, 25934, 26037, 25981, 25783, 26037, - 25934, 26560, 26497, 26691, 32518, 32573, 32548, 32026, 31956, 31848, 30294, 30617, 30489, - 8664, 8823, 9003, 8237, 8303, 8210, 18087, 17937, 18148, 19099, 18890, 18848, 18665, - 18890, 18871, 28143, 27934, 27928, 27414, 27254, 27570, 27110, 27054, 26890, 28663, 28454, - 28644, 28177, 28158, 28145, 31174, 30703, 30449, 31174, 30449, 31361, 15031, 15631, 15051, - 32721, 32707, 32562, 8622, 9003, 9136, 8942, 8971, 9045, 8942, 9045, 9015, 24513, - 24648, 24767, 24853, 25643, 25053, 23861, 23637, 23579, 22019, 21906, 21872, 22637, 22702, - 22604, 27934, 27570, 27928, 33175, 33194, 33718, 8519, 8471, 8599, 8449, 8471, 8346, - 9463, 9633, 9484, 10370, 10416, 10512, 13840, 14038, 13974, 13432, 13292, 13422, 12970, - 12785, 12960, 22637, 22604, 22409, 28143, 27928, 28196, 33565, 33545, 33462, 33717, 33545, - 33565, 9263, 9198, 9270, 9094, 9198, 9263, 15734, 15881, 15631, 32814, 32795, 32611, - 10341, 10099, 10528, 10633, 10762, 10582, 10370, 10433, 10331, 13432, 13600, 13549, 20609, - 20528, 20418, 20355, 20140, 20006, 19822, 19773, 19611, 20804, 20528, 20609, 22139, 21772, - 22552, 27728, 27677, 27570, 31242, 31174, 31519, 31956, 32253, 31828, 31752, 31859, 31729, - 31905, 31859, 31752, 32856, 32650, 32776, 33327, 33184, 33199, 8451, 8295, 8555, 8382, - 8366, 8430, 8430, 8297, 8450, 8450, 8363, 8447, 8447, 8314, 8489, 8266, 8295, - 8451, 8347, 8730, 8394, 8347, 8394, 8359, 10710, 10822, 10820, 10820, 10822, 10907, - 11144, 11077, 11420, 12600, 13265, 12690, 10710, 10794, 10651, 8295, 8358, 8511, 13549, - 13600, 13624, 28406, 28253, 28291, 28291, 28253, 28196, 28107, 28177, 28145, 28863, 28764, - 28731, 28107, 28145, 28064, 8611, 8568, 8760, 8542, 8475, 8526, 33806, 33652, 33762, - 33328, 33021, 33184, 33328, 33184, 33327, 20346, 20289, 20355, 33199, 33094, 33316, 8359, - 8394, 8308, 8358, 8366, 8382, 20289, 20140, 20355, 33635, 33811, 33724, 33724, 33909, - 33673, 33673, 33912, 33551, 33638, 33519, 33545, 33748, 33811, 33635, 33748, 33635, 33907, - 33635, 33868, 33907, 18439, 18257, 18321, 16343, 16230, 16425, 18312, 18257, 18439, 27640, - 27414, 27570, 8366, 8297, 8430, 8471, 8481, 8694, 8449, 8481, 8471, 9647, 9459, - 9695, 9647, 9695, 9734, 10484, 10710, 10651, 26624, 26487, 26568, 26764, 26568, 26856, - 26764, 26856, 26865, 30584, 30505, 30498, 30498, 30505, 30347, 30465, 29685, 30336, 30975, - 30923, 30936, 30975, 30936, 31042, 33798, 33546, 33754, 15393, 15339, 15295, 13974, 14038, - 14121, 15222, 15339, 15311, 32845, 32856, 32776, 26624, 26764, 26865, 32376, 32363, 30813, - 32352, 32363, 32440, 8308, 8616, 8330, 10416, 10580, 10651, 10234, 10370, 10331, 11605, - 11595, 11674, 11446, 11366, 11233, 10582, 10762, 11004, 11777, 11857, 11410, 32996, 32743, - 33236, 33106, 33098, 33065, 33205, 33098, 33106, 33754, 33546, 33707, 33194, 33414, 33718, - 11351, 11366, 11446, 30505, 30336, 30347, 28319, 28143, 28253, 8330, 8398, 8303, 8330, - 8616, 8398, 13631, 13549, 13624, 14077, 14403, 14196, 16718, 16759, 16912, 16306, 16587, - 16288, 33301, 33446, 33405, 32707, 32814, 32611, 32795, 32845, 32776, 32573, 32721, 32562, - 32729, 32721, 32573, 32584, 32573, 32518, 10267, 10099, 10341, 12879, 12970, 12985, 13631, - 13624, 13739, 28253, 28143, 28196, 27934, 27728, 27570, 27677, 27640, 27570, 28758, 28773, - 28931, 8297, 8363, 8450, 14196, 14403, 14349, 18665, 18586, 18697, 18665, 18697, 18890, - 33545, 33519, 33493, 33499, 33470, 33857, 8611, 8760, 8688, 8611, 8688, 8542, 9702, - 9931, 9723, 22070, 22333, 22298, 23579, 23637, 23182, 33794, 33551, 33900, 16425, 16230, - 16572, 17898, 17814, 17937, 16140, 16306, 16288, 33257, 33316, 33125, 32856, 32933, 32650, - 32973, 32933, 32856, 8303, 8492, 8459, 30584, 30498, 30698, 32729, 32814, 32707, 10307, - 10267, 10341, 10307, 10415, 10424, 13134, 13265, 12600, 12690, 13265, 12981, 14818, 15031, - 15051, 10352, 10580, 10416, 12879, 12785, 12970, 12879, 12985, 13068, 29023, 28758, 28931, - 28764, 28373, 28731, 8363, 8328, 8447, 19834, 19773, 19822, 21488, 21618, 21518, 22070, - 22204, 22333, 21607, 21618, 21488, 30732, 30584, 30698, 33900, 33551, 33631, 33754, 33707, - 33761, 9723, 9931, 9755, 33735, 33642, 33597, 33723, 33642, 34084, 8249, 8683, 8762, - 8481, 8496, 8694, 8449, 8496, 8481, 18257, 18087, 18148, 18586, 18504, 18461, 18601, - 18504, 18586, 8998, 8942, 9015, 8622, 9032, 8900, 9198, 9139, 9270, 9070, 9139, - 9198, 13635, 13631, 13739, 13169, 13292, 13144, 13635, 13739, 13840, 16508, 16759, 16718, - 17885, 17773, 17891, 16672, 16759, 16508, 23579, 23182, 23422, 24419, 24487, 24513, 32838, - 32845, 32795, 14020, 13974, 14077, 14077, 13974, 14121, 27798, 27728, 28026, 26856, 26890, - 27054, 27640, 27728, 27798, 26288, 26194, 26560, 29051, 29028, 28764, 8303, 8459, 8210, - 19773, 19676, 19611, 33761, 33524, 33769, 8210, 8459, 8254, 8542, 8688, 8664, 18136, - 18087, 18257, 15339, 15222, 15295, 15393, 15295, 15542, 14794, 15051, 14378, 16134, 16140, - 16128, 15881, 16140, 16288, 26487, 26006, 26420, 26764, 26624, 26568, 27110, 27237, 27054, - 10582, 11004, 10624, 12785, 12661, 12960, 13292, 13432, 13144, 28758, 28663, 28644, 28835, - 28663, 28758, 15311, 15393, 15415, 32605, 32584, 32518, 32904, 32838, 32814, 32814, 32838, - 32795, 32605, 32341, 32268, 23861, 24234, 24043, 33214, 33205, 33106, 33550, 33139, 33362, - 33316, 33094, 33125, 33486, 33514, 33275, 33769, 33683, 33806, 32939, 32970, 33161, 8328, - 8314, 8447, 14619, 14196, 14349, 27110, 27189, 27237, 33642, 33723, 33565, 33405, 33306, - 33301, 33799, 33723, 34084, 26296, 26006, 26487, 25471, 25394, 25038, 16306, 16419, 16508, - 16140, 15881, 16128, 25891, 25394, 25471, 24090, 23834, 22954, 27237, 27189, 27414, 33769, - 33524, 33683, 33683, 33652, 33806, 8734, 8258, 8254, 8622, 8900, 8629, 10484, 10691, - 10710, 10710, 10691, 10822, 10971, 11144, 11041, 18087, 17898, 17937, 18136, 17898, 18087, - 23422, 23182, 22845, 24605, 24368, 24561, 8819, 8900, 8917, 24683, 23957, 24404, 12729, - 12661, 12785, 13144, 13432, 12991, 22467, 22637, 22409, 22467, 22409, 22333, 30789, 31275, - 30669, 33723, 33717, 33565, 33799, 33717, 33723, 10099, 9971, 10127, 9965, 9971, 10099, - 10108, 10099, 10267, 9702, 9618, 9734, 9647, 9473, 9459, 9459, 9094, 9357, 9616, - 9618, 9594, 21618, 22019, 21872, 27728, 27640, 27677, 27728, 27934, 28026, 28011, 28107, - 27856, 26560, 26194, 26156, 33414, 33572, 33583, 8942, 8819, 8917, 8782, 8819, 8942, - 33098, 33611, 33050, 33317, 33205, 33214, 16536, 16671, 17814, 15465, 15542, 15473, 10624, - 11004, 10507, 10442, 10330, 10424, 24234, 24368, 24419, 24487, 24368, 24605, 28663, 28502, - 28266, 29751, 29023, 28931, 28764, 29028, 28350, 31017, 30789, 30617, 30617, 30789, 30489, - 28306, 28346, 28177, 31042, 30936, 31056, 30788, 30732, 30698, 31042, 31056, 31123, 32845, - 32973, 32856, 32729, 32707, 32721, 33301, 33306, 33214, 33550, 33362, 33705, 33572, 33428, - 33530, 33071, 32970, 32933, 9139, 8998, 9270, 8923, 8998, 9139, 33717, 33680, 33545, - 33799, 33680, 33717, 10370, 10352, 10416, 10484, 10740, 10691, 10137, 10234, 10331, 12618, - 12661, 12729, 13512, 13432, 13549, 13512, 13549, 13631, 13635, 13840, 13619, 28648, 28502, - 28663, 8295, 8192, 8358, 8162, 8204, 8366, 8366, 8204, 8297, 8297, 8204, 8363, - 8363, 8244, 8328, 8328, 8244, 8314, 8139, 8266, 8451, 8139, 8451, 8347, 8269, - 8347, 8359, 8269, 8359, 8308, 8269, 8308, 8253, 20528, 20425, 20355, 20289, 20265, - 20140, 20140, 20102, 20006, 19773, 19717, 19676, 20265, 20425, 20450, 34011, 33912, 33673, - 33799, 33638, 33680, 33909, 33724, 33887, 33724, 33811, 33887, 33811, 33748, 33887, 33748, - 33907, 33887, 33868, 33635, 33629, 33888, 33868, 33629, 20425, 20346, 20355, 20697, 20987, - 21030, 21618, 21759, 22019, 20230, 20697, 19116, 26497, 26560, 26156, 25783, 25934, 25795, - 8376, 8762, 8560, 9207, 9484, 8901, 15393, 15311, 15339, 13848, 14132, 13737, 15542, - 15795, 15473, 8806, 9349, 9249, 10063, 10011, 10275, 10971, 10822, 10740, 10971, 11041, - 10822, 26560, 26749, 26466, 12729, 12879, 12790, 31242, 31056, 31174, 33798, 33888, 33629, - 33414, 33428, 33572, 33798, 33980, 33888, 32838, 32973, 32845, 16188, 15795, 16230, 27860, - 27856, 27692, 33275, 33328, 33486, 14459, 13912, 14413, 15031, 15065, 15631, 27054, 26888, - 26856, 26865, 26840, 26624, 26296, 25891, 26006, 27237, 26888, 27054, 32363, 32352, 30813, - 32486, 32376, 32610, 8346, 8471, 8519, 8496, 8422, 8560, 10740, 10822, 10691, 18601, - 18665, 18871, 18312, 18136, 18257, 18890, 19099, 19025, 33680, 33638, 33545, 33898, 33470, - 33794, 33583, 33718, 33414, 8253, 8308, 8330, 8253, 8330, 8237, 8162, 8366, 8358, - 8262, 8285, 8566, 20187, 20102, 20140, 14196, 14132, 14077, 14925, 14764, 15222, 26006, - 25891, 25720, 26296, 26487, 26840, 32584, 32729, 32573, 33109, 33060, 32973, 32902, 32729, - 32584, 32026, 31848, 31859, 33931, 33900, 33631, 33754, 33982, 33798, 8230, 8566, 8314, - 24368, 24487, 24419, 24648, 24487, 24605, 28502, 28406, 28291, 28409, 28406, 28553, 33754, - 33761, 33831, 33882, 33762, 33652, 30698, 30923, 30873, 30788, 30698, 30873, 30584, 30571, - 30505, 29910, 29751, 29741, 29741, 29751, 29487, 28869, 28835, 28758, 28972, 28758, 29023, - 33761, 34009, 33831, 23957, 23834, 24090, 23852, 23834, 23957, 23852, 23957, 23854, 33344, - 33328, 33327, 33060, 32933, 32973, 33060, 33071, 32933, 33385, 33344, 33327, 8237, 8330, - 8303, 16343, 16479, 16344, 18423, 18439, 18504, 30873, 30923, 30975, 31017, 30617, 30294, - 33669, 33362, 33519, 33583, 33877, 33718, 33530, 33428, 33360, 33831, 34009, 33939, 33385, - 33327, 33316, 9754, 10305, 9994, 13619, 13840, 13764, 13144, 12991, 13068, 19984, 19834, - 19822, 20987, 21607, 21488, 22255, 22467, 22333, 27461, 27237, 27414, 28171, 27934, 28143, - 27681, 27725, 27692, 27660, 27725, 27681, 32022, 31905, 31752, 32026, 32022, 32098, 10345, - 10330, 10442, 10234, 10352, 10370, 10291, 10352, 10234, 28406, 28319, 28253, 28835, 28648, - 28663, 28869, 28648, 28835, 31029, 30873, 30975, 31519, 31174, 31361, 10484, 10651, 10580, - 31187, 30975, 31042, 10169, 10108, 10267, 9755, 9931, 9996, 28409, 28319, 28406, 28107, - 28306, 28177, 28206, 28306, 28107, 8584, 8321, 8258, 8204, 8244, 8363, 8998, 8782, - 8942, 8819, 8629, 8900, 8475, 8542, 8664, 8766, 8782, 8718, 15311, 15245, 15222, - 15415, 15245, 15311, 15415, 15393, 15465, 33638, 33669, 33519, 33743, 33669, 33638, 9075, - 9094, 9080, 9755, 9996, 9971, 9526, 9754, 9994, 20450, 20804, 21472, 23854, 23957, - 24047, 24487, 24648, 24513, 24368, 24234, 24561, 33477, 33486, 33328, 33514, 33530, 33360, - 14794, 14818, 15051, 14739, 14818, 14794, 26749, 26848, 26611, 26744, 26848, 26749, 26744, - 26749, 26560, 16671, 16479, 16425, 16343, 16344, 16277, 17913, 17885, 17891, 17773, 17682, - 17891, 17682, 17322, 17476, 22845, 22738, 22702, 23579, 23762, 23861, 22802, 22702, 22637, - 10582, 10463, 10442, 10924, 11004, 11233, 11295, 11233, 11366, 11351, 11446, 11595, 10330, - 10307, 10424, 10261, 10307, 10330, 33392, 33317, 33214, 33205, 33317, 33098, 33446, 33301, - 33139, 33392, 33405, 33466, 33402, 33385, 33316, 33344, 33477, 33328, 12133, 11857, 12561, - 11430, 11351, 11595, 22204, 22070, 22019, 8526, 8568, 8611, 33761, 33769, 34009, 34005, - 33806, 33762, 33882, 33652, 33834, 11351, 11295, 11366, 16343, 16188, 16230, 16140, 16134, - 16306, 16128, 15881, 15857, 32904, 32973, 32838, 33266, 33054, 32939, 28409, 28171, 28319, - 28319, 28171, 28143, 8449, 8422, 8496, 8305, 8422, 8449, 8346, 8519, 8285, 18480, - 18423, 18504, 16479, 16536, 16344, 18601, 18586, 18665, 33669, 33705, 33362, 33859, 33705, - 33669, 30584, 30722, 30571, 30465, 30505, 30571, 30465, 30336, 30505, 10624, 10513, 10582, - 10463, 10513, 10395, 10414, 10580, 10352, 10414, 10484, 10580, 14132, 14020, 14077, 13848, - 14020, 14132, 27725, 27860, 27692, 27382, 27426, 27170, 29149, 28972, 29023, 28553, 28406, - 28502, 29028, 29331, 28815, 28863, 29051, 28764, 31905, 32026, 31859, 32026, 31905, 32022, - 9616, 9647, 9618, 9594, 9618, 9702, 14453, 14459, 14413, 27461, 27414, 27876, 26840, - 26487, 26624, 27414, 27640, 27876, 8175, 8230, 8314, 10923, 11104, 11077, 11077, 11104, - 11420, 10923, 11077, 10971, 10923, 10971, 10749, 30584, 30732, 30722, 34087, 33898, 33794, - 8542, 8526, 8611, 8475, 8664, 8622, 18082, 18200, 18281, 17249, 16923, 16959, 10307, - 10169, 10267, 10108, 9965, 10099, 9581, 9594, 9702, 10155, 10169, 10207, 13344, 13580, - 14014, 12600, 12690, 12460, 30732, 30788, 30849, 30722, 30732, 30849, 8488, 8841, 9097, - 8847, 8841, 8554, 24648, 24719, 24767, 24605, 24719, 24648, 33392, 33214, 33306, 33161, - 32970, 33071, 8258, 8734, 8584, 25108, 25643, 24853, 26987, 27382, 26611, 10513, 10463, - 10582, 10363, 10463, 10395, 10749, 10971, 10740, 10258, 10414, 10352, 28972, 28869, 28758, - 29024, 28869, 28972, 29006, 28863, 28731, 28731, 28373, 28702, 31242, 31123, 31056, 31268, - 31123, 31242, 16479, 16343, 16425, 15707, 15473, 15795, 16188, 16343, 16277, 17329, 17210, - 17064, 18423, 18312, 18439, 18480, 18312, 18423, 30849, 30788, 30873, 33060, 33161, 33071, - 33625, 33477, 33344, 33361, 33402, 33316, 9894, 9965, 9957, 13635, 13512, 13631, 12661, - 12133, 12561, 13619, 13512, 13635, 27853, 27860, 27725, 27853, 27725, 27660, 32532, 32605, - 32268, 32729, 32902, 32814, 33610, 33595, 33161, 8267, 8346, 8285, 26848, 26987, 26611, - 26691, 26744, 26560, 31912, 31519, 31361, 32743, 32376, 32674, 33857, 33642, 33735, 8230, - 8262, 8566, 12618, 12133, 12661, 31029, 30849, 30873, 8458, 8475, 8406, 8321, 8584, - 8568, 17913, 18078, 18082, 17552, 17891, 17682, 33590, 33530, 33486, 33486, 33530, 33514, - 33572, 33633, 33583, 26849, 26987, 26848, 32496, 32440, 32363, 33909, 34011, 33673, 33912, - 33931, 33631, 33900, 34156, 33794, 33976, 34011, 33909, 33976, 33909, 33887, 33976, 33887, - 33907, 33976, 33907, 33943, 33907, 33868, 33943, 15245, 15099, 15222, 15415, 15473, 15406, - 33646, 32674, 33050, 8169, 8139, 8347, 8266, 8192, 8295, 8033, 8175, 7965, 8244, - 8175, 8314, 8230, 8127, 8262, 8169, 8347, 8269, 8169, 8269, 8201, 8269, 8253, - 8201, 8253, 8037, 8201, 8096, 8192, 8266, 8841, 8997, 9249, 9463, 9526, 9994, - 10011, 10137, 10275, 10202, 10120, 10186, 10169, 10155, 10108, 10463, 10345, 10442, 10363, - 10345, 10463, 16959, 16923, 16759, 15718, 15881, 15734, 17431, 17476, 17322, 27438, 27557, - 27382, 27382, 27557, 27426, 28553, 28502, 28648, 28171, 28233, 27934, 32346, 30813, 32352, - 33601, 33477, 33625, 8192, 8162, 8358, 8253, 8237, 8160, 20346, 20265, 20289, 20102, - 19984, 19822, 19099, 19519, 19147, 20425, 20265, 20346, 23375, 22954, 23834, 33943, 33868, - 33980, 22086, 22204, 22019, 22467, 22802, 22637, 29317, 29028, 29051, 29317, 29331, 29028, - 33898, 33857, 33470, 34042, 33857, 33898, 8422, 8376, 8560, 8344, 8376, 8422, 32440, - 32346, 32352, 20265, 20187, 20140, 32903, 32902, 33004, 34099, 33931, 33912, 8782, 8766, - 8819, 8718, 8782, 8701, 22530, 22802, 22467, 24561, 24234, 24418, 33257, 33361, 33316, - 33601, 33590, 33477, 33291, 33266, 32939, 33257, 33266, 33381, 8160, 8237, 8210, 8643, - 8629, 8819, 33405, 33392, 33306, 33317, 33371, 33098, 33567, 33139, 33550, 33567, 33550, - 33878, 13512, 12991, 13432, 13764, 13840, 13974, 13764, 13974, 14020, 31187, 31042, 31123, - 31187, 31029, 30975, 33980, 33868, 33888, 33980, 33798, 33982, 9581, 9702, 9723, 9616, - 9473, 9647, 10202, 10291, 10234, 10749, 10740, 10655, 22204, 22255, 22333, 32098, 32253, - 31956, 9094, 9070, 9198, 9075, 9070, 9094, 25643, 25783, 25795, 25416, 25783, 25643, - 32919, 32904, 32814, 33760, 33550, 33705, 20026, 19984, 20102, 17210, 17431, 17322, 17476, - 17552, 17682, 17329, 17431, 17210, 33567, 33446, 33139, 19717, 19773, 19834, 18216, 17898, - 18136, 22802, 22845, 22702, 22747, 22845, 22802, 33530, 33633, 33572, 33732, 33633, 33530, - 33799, 33743, 33638, 33838, 33743, 33799, 33982, 33754, 33831, 28831, 28553, 28648, 29751, - 29149, 29023, 11430, 11252, 11351, 11351, 11154, 11295, 10395, 10513, 10624, 11865, 11410, - 11857, 33834, 33612, 33718, 11104, 11529, 11420, 10960, 11529, 11104, 27343, 27438, 27382, - 27846, 27853, 27660, 28373, 28346, 28702, 14916, 15065, 15031, 14916, 15031, 14818, 14916, - 14818, 14739, 26497, 26156, 26414, 26744, 26849, 26848, 26987, 27131, 27382, 13544, 12991, - 13512, 11389, 11252, 11410, 28409, 28233, 28171, 29032, 28648, 28869, 26691, 26849, 26744, - 32440, 32434, 32346, 31205, 31268, 31416, 32486, 32496, 32363, 32610, 32496, 32486, 8701, - 8782, 8998, 8766, 8643, 8819, 15473, 15415, 15465, 15998, 15795, 16188, 8024, 8160, - 8210, 8131, 8210, 8254, 8676, 8643, 8766, 8458, 8448, 8475, 19909, 19717, 19834, - 24719, 24801, 24853, 24801, 24605, 24561, 33381, 33361, 33257, 33477, 33590, 33486, 33291, - 32939, 33161, 11529, 11818, 11846, 12729, 12785, 12879, 11749, 12600, 12460, 14739, 14794, - 14685, 13619, 13544, 13512, 13760, 13764, 14020, 18601, 18480, 18504, 18482, 18480, 18601, - 19147, 19519, 19443, 23852, 23854, 23834, 23766, 23854, 23968, 29149, 29024, 28972, 28863, - 29006, 29051, 28206, 28107, 28011, 30709, 30562, 30571, 30571, 30562, 30465, 30587, 29910, - 29741, 29164, 29024, 29149, 29164, 29032, 29024, 30709, 30571, 30722, 30709, 30722, 30927, - 33884, 33834, 33718, 33939, 33982, 33831, 28473, 28233, 28409, 28011, 27856, 27860, 17884, - 18078, 17913, 17884, 17913, 17891, 9817, 9755, 9971, 9894, 9971, 9965, 10740, 10484, - 10655, 21607, 21759, 21618, 22204, 22086, 22255, 22255, 22530, 22467, 21506, 21759, 21607, - 21911, 21759, 21596, 30683, 30709, 30927, 32026, 32098, 31956, 32022, 31752, 32017, 33769, - 33806, 34009, 17418, 17552, 17476, 16672, 16508, 16547, 33392, 33371, 33317, 33446, 33466, - 33405, 33578, 33466, 33446, 33475, 33466, 33594, 9387, 9526, 9463, 9954, 10137, 10011, - 10137, 10202, 10234, 8958, 8923, 9139, 10207, 10169, 10307, 10261, 10330, 10345, 8321, - 8568, 8448, 8568, 8526, 8448, 9070, 8958, 9139, 9080, 9094, 9459, 9080, 8873, - 8969, 15659, 15718, 15734, 16419, 16306, 16134, 22395, 22530, 22255, 24234, 23861, 24418, - 32904, 33109, 32973, 32902, 32919, 32814, 32903, 32919, 32902, 32902, 32584, 33004, 32903, - 33004, 32987, 8175, 8244, 7965, 8262, 8116, 8285, 8251, 8305, 8449, 10395, 10624, - 10507, 12790, 12879, 13068, 12618, 12264, 12133, 12790, 13068, 12885, 31416, 31268, 31242, - 30927, 30722, 30849, 31963, 30724, 32346, 34009, 33806, 34005, 8448, 8526, 8475, 8251, - 8449, 8346, 8416, 8488, 8683, 9559, 9581, 9723, 10655, 10484, 10526, 17418, 17476, - 17431, 33344, 33385, 33625, 33877, 33884, 33718, 8158, 8131, 8254, 8525, 8622, 8629, - 10033, 9965, 10108, 9466, 9536, 9581, 13764, 13544, 13619, 13760, 13544, 13764, 16419, - 16134, 16216, 17481, 17697, 17552, 33429, 33291, 33574, 33625, 33385, 33402, 16807, 16959, - 16759, 33475, 33371, 33392, 32804, 32610, 32376, 27941, 27853, 27846, 27846, 27557, 27438, - 32471, 31963, 32346, 32404, 32268, 32253, 32217, 32022, 32204, 19025, 18871, 18890, 18920, - 18871, 19025, 10155, 10033, 10108, 10363, 10261, 10345, 10184, 10261, 10363, 12729, 12553, - 12618, 12885, 13068, 12991, 28702, 28346, 28593, 28346, 28306, 28593, 16216, 16134, 16128, - 10039, 10033, 10155, 15415, 15099, 15245, 15090, 15099, 15068, 8179, 8158, 8254, 8175, - 8127, 8230, 10322, 10484, 10414, 10258, 10352, 10291, 15099, 14925, 15222, 15479, 15659, - 15734, 14794, 14453, 14685, 21759, 21996, 22019, 32512, 32434, 32440, 32604, 32610, 32686, - 34005, 33882, 33993, 34005, 33762, 33882, 8305, 8344, 8422, 8199, 8344, 8305, 26840, - 26865, 26888, 25405, 25260, 25394, 26840, 26888, 26983, 33859, 33760, 33705, 33466, 33475, - 33392, 33859, 33669, 33743, 9207, 9387, 9463, 14794, 14459, 14453, 26849, 26947, 26987, - 27045, 26947, 26849, 27045, 26849, 26982, 8075, 8267, 8285, 33877, 34032, 34033, 8158, - 7964, 8083, 8258, 8179, 8254, 8127, 8116, 8262, 16277, 16042, 16188, 18216, 18136, - 18312, 21996, 22086, 22019, 26947, 27131, 26987, 32512, 32440, 32496, 18078, 18200, 18082, - 17697, 17884, 17891, 17697, 17891, 17552, 23766, 23675, 23834, 23766, 23834, 23854, 33590, - 33732, 33530, 33703, 33732, 33590, 8383, 8525, 8629, 8498, 8629, 8643, 8676, 8766, - 8718, 33625, 33402, 33553, 10261, 10207, 10307, 10184, 10207, 10261, 10291, 10202, 10186, - 10202, 10137, 10120, 12773, 12553, 12729, 12688, 12885, 12678, 28344, 28306, 28206, 34011, - 34050, 33912, 33931, 34083, 33900, 33933, 33838, 34054, 34034, 34050, 34011, 34034, 34011, - 33976, 34034, 33976, 34141, 33976, 33943, 34035, 33943, 34048, 34035, 34055, 34048, 33943, - 8139, 8096, 8266, 8192, 7846, 8162, 7965, 8244, 8204, 8175, 8033, 8127, 8127, - 8033, 8116, 8010, 8096, 8139, 8062, 8139, 8169, 8062, 8169, 8201, 8062, 8201, - 7963, 8253, 8080, 8037, 8160, 8080, 8253, 33980, 34055, 33943, 9075, 8958, 9070, - 8613, 8676, 8718, 9536, 9616, 9594, 15718, 15857, 15881, 15479, 15631, 15065, 32919, - 33040, 32904, 32404, 32253, 32435, 27853, 28011, 27860, 28042, 28011, 27853, 18480, 18216, - 18312, 18482, 18216, 18480, 18118, 18200, 18078, 8160, 8024, 8080, 8592, 8676, 8472, - 9581, 9536, 9594, 9559, 9723, 9755, 16959, 17064, 17210, 16672, 16807, 16759, 16737, - 16807, 16672, 16547, 16508, 16419, 24605, 24801, 24719, 27326, 27247, 27174, 23762, 23422, - 23488, 28157, 28344, 28206, 32383, 32253, 32098, 33429, 33381, 33266, 33429, 33266, 33291, - 16375, 16547, 16419, 10924, 11233, 11295, 22530, 22747, 22802, 22595, 22747, 22530, 31268, - 31187, 31123, 31205, 31187, 31268, 33977, 33877, 34033, 33993, 33882, 33834, 33980, 34108, - 34055, 33578, 33446, 33567, 32686, 32610, 32804, 34099, 34083, 33931, 33980, 33982, 34108, - 8969, 8958, 9075, 10884, 11104, 10923, 10884, 10960, 11104, 11529, 11749, 11818, 10884, - 10923, 10614, 10923, 10749, 10614, 15655, 15857, 15718, 8806, 9484, 9349, 8841, 8847, - 8997, 8488, 9014, 8683, 15267, 15099, 15415, 16479, 16671, 16536, 16151, 16216, 16128, - 19443, 19519, 19676, 18549, 18482, 18601, 19984, 19909, 19834, 19717, 19688, 19676, 20187, - 20026, 20102, 20450, 20026, 20187, 20450, 20187, 20265, 33993, 33834, 33884, 34077, 33982, - 33939, 8406, 8475, 8622, 8448, 8283, 8321, 8083, 7964, 7972, 8406, 8622, 8525, - 23675, 23375, 23834, 24683, 25038, 25260, 28344, 28593, 28306, 9817, 9894, 9957, 9817, - 9971, 9894, 9556, 9559, 9755, 10933, 10924, 11295, 11252, 11430, 11410, 10631, 10749, - 10655, 30709, 30683, 30562, 30587, 29741, 30465, 30927, 30849, 30995, 8210, 8131, 8024, - 20026, 19944, 19984, 33690, 33578, 33567, 33601, 33703, 33590, 33940, 33884, 33877, 33497, - 33402, 33361, 34077, 33939, 34009, 12773, 12729, 12790, 29389, 29149, 29751, 29024, 29032, - 28869, 28671, 28473, 28409, 18049, 18118, 18078, 21105, 21607, 20987, 18049, 18078, 17884, - 23418, 23375, 23675, 8267, 8251, 8346, 8416, 8683, 8228, 7907, 8251, 8267, 15099, - 15090, 14925, 13848, 13760, 14020, 15998, 16188, 16042, 14916, 15076, 15065, 15659, 15655, - 15718, 14744, 15076, 14916, 33838, 33799, 34054, 33760, 33878, 33550, 32610, 32604, 32496, - 32434, 32541, 32346, 32376, 32743, 32804, 8024, 8131, 8083, 12688, 12787, 12885, 12787, - 12773, 12790, 14132, 14196, 13737, 19944, 19909, 19984, 16102, 15998, 16042, 28344, 28365, - 28593, 28011, 28157, 28206, 28042, 28157, 28011, 15660, 15406, 15473, 14378, 13912, 14459, - 14739, 14698, 14916, 32604, 32512, 32496, 32404, 32532, 32268, 33381, 33497, 33361, 33574, - 33291, 33595, 10080, 10039, 10155, 10080, 10155, 10207, 16807, 17064, 16959, 16737, 17064, - 16807, 17348, 17064, 17114, 23762, 23579, 23422, 26414, 26037, 25783, 33531, 33497, 33381, - 10186, 10258, 10291, 10137, 9954, 10120, 12787, 12790, 12885, 11389, 11410, 11865, 8371, - 8283, 8448, 8415, 8406, 8525, 9468, 9473, 9536, 9536, 9473, 9616, 9080, 8969, - 9075, 9468, 9536, 9466, 14378, 14014, 13710, 17348, 17431, 17329, 27131, 27247, 27382, - 27174, 27247, 27131, 26156, 26037, 26414, 18347, 18482, 18453, 16536, 17814, 17010, 22369, - 22395, 22255, 23371, 23422, 22845, 33940, 33993, 33884, 34052, 34077, 34009, 33817, 33633, - 33732, 10526, 10631, 10655, 18621, 18281, 18200, 17866, 18049, 17884, 22139, 21146, 21772, - 23522, 23418, 23745, 17064, 17348, 17329, 8083, 8131, 8158, 8179, 7868, 7964, 19729, - 19688, 19717, 18549, 18601, 18871, 32903, 33040, 32919, 32987, 33040, 32903, 27247, 27343, - 27382, 9957, 9965, 10033, 10262, 10184, 10363, 9934, 9957, 10033, 10262, 10363, 10395, - 10322, 10526, 10484, 9631, 9711, 9954, 10631, 10526, 10500, 11389, 11619, 11239, 12750, - 12787, 12688, 29032, 28831, 28648, 28233, 28026, 27934, 29033, 28831, 29032, 29331, 29506, - 29293, 32204, 32022, 32017, 29006, 29317, 29051, 29136, 29317, 29006, 29136, 29006, 28731, - 29136, 28731, 28995, 29136, 28995, 29215, 13760, 13496, 13544, 13748, 13737, 13668, 34052, - 34009, 34005, 33838, 33859, 33743, 33933, 33859, 33838, 33697, 33703, 33601, 33697, 33601, - 33625, 8371, 8448, 8458, 33745, 33817, 33732, 8676, 8592, 8643, 8211, 8371, 8458, - 8701, 8998, 8645, 25260, 25038, 25394, 23745, 23418, 23675, 8158, 8179, 7964, 7965, - 8204, 7846, 8116, 8056, 8285, 22086, 22074, 22255, 21996, 22074, 22086, 21759, 21911, - 21996, 18289, 18200, 18183, 26414, 25783, 26392, 27247, 27326, 27343, 32604, 32599, 32512, - 32804, 33034, 32816, 34156, 34087, 33794, 12618, 12553, 12487, 10611, 10507, 11004, 12487, - 12553, 12773, 17814, 17898, 17010, 16277, 16102, 16042, 15998, 15780, 15795, 11252, 11154, - 11351, 22395, 22595, 22530, 22421, 22595, 22395, 10322, 10414, 10258, 10011, 9754, 9487, - 33475, 33608, 33371, 33578, 33594, 33466, 33690, 33594, 33578, 14698, 14739, 14685, 15469, - 15479, 15213, 15076, 15479, 15065, 15974, 16151, 16128, 16737, 16672, 16547, 19688, 19443, - 19676, 30587, 30465, 30562, 30683, 30587, 30562, 30779, 30587, 30683, 34087, 34042, 33898, - 34174, 34052, 34127, 34052, 34005, 34127, 18183, 18200, 18118, 18183, 18118, 18145, 17866, - 17884, 17697, 28412, 28026, 28233, 28157, 28365, 28344, 27941, 28042, 27853, 16287, 16102, - 16277, 28731, 28702, 28995, 31146, 30995, 31029, 31416, 31242, 31519, 31416, 31519, 31912, - 31361, 31963, 31912, 9934, 10033, 10039, 9466, 9581, 9559, 22595, 22697, 22747, 22623, - 22697, 22595, 33977, 33940, 33877, 8218, 8371, 8211, 8179, 8258, 7868, 8645, 8998, - 8923, 9181, 9080, 9459, 9473, 9181, 9459, 9556, 9755, 9458, 14453, 14698, 14685, - 13710, 14014, 13580, 15479, 15655, 15659, 17840, 17866, 17714, 27343, 27482, 27438, 27045, - 27131, 26947, 33040, 33109, 32904, 32803, 32584, 32605, 33877, 33583, 34032, 33703, 33745, - 33732, 21911, 22074, 21996, 24683, 24047, 23957, 33957, 34015, 33745, 33689, 33697, 33625, - 33553, 33402, 33497, 33553, 33497, 33531, 8096, 7874, 8192, 8062, 8010, 8139, 7963, - 8010, 8062, 7963, 8201, 8006, 8201, 8037, 8006, 8037, 8080, 8006, 23236, 22552, - 23375, 20026, 19939, 19944, 19944, 19939, 19909, 19909, 19823, 19717, 19688, 19494, 19443, - 34303, 34308, 34050, 34050, 34099, 33912, 34083, 34156, 33900, 34087, 34353, 34042, 34121, - 34141, 33976, 34121, 33976, 34160, 33976, 34035, 34160, 34035, 34178, 34160, 34048, 34178, - 34035, 16344, 16287, 16277, 18217, 17898, 18216, 18482, 18217, 18216, 18347, 18217, 18482, - 18289, 18621, 18200, 18145, 18118, 18049, 23406, 23236, 23375, 23218, 23236, 23406, 30995, - 30849, 31029, 34048, 34114, 34178, 8033, 8056, 8116, 7969, 8056, 8033, 8006, 8080, - 7948, 34308, 34099, 34050, 34048, 34055, 34114, 27368, 27482, 27343, 33174, 33109, 33040, - 8530, 8498, 8643, 8530, 8643, 8592, 33531, 33381, 33429, 33583, 33633, 34032, 34127, - 34005, 34143, 16163, 16287, 16410, 34114, 34055, 34520, 10631, 10614, 10749, 10884, 10902, - 10960, 10960, 10937, 11529, 11818, 11749, 12460, 10500, 10614, 10631, 10193, 10258, 10186, - 29317, 29506, 29331, 29543, 29506, 29317, 31146, 31029, 31187, 34099, 34177, 34083, 34108, - 33982, 34077, 13848, 13748, 13760, 14771, 14490, 14925, 27846, 27660, 27557, 28381, 28365, - 28157, 15090, 14811, 14925, 15267, 15068, 15099, 15267, 15415, 15406, 15267, 15406, 15290, - 22907, 22845, 22747, 33611, 33098, 33371, 32697, 32599, 32604, 32532, 32803, 32605, 32987, - 33174, 33040, 32941, 32803, 32867, 32727, 32532, 32404, 14910, 14811, 15090, 26983, 26888, - 27237, 26013, 25394, 25891, 15869, 15998, 16102, 26724, 26849, 26691, 27326, 27368, 27343, - 25035, 24853, 24801, 24907, 24801, 24736, 8383, 8415, 8525, 10120, 10193, 10186, 10212, - 10193, 10113, 12787, 12750, 12773, 12555, 12750, 12688, 17348, 17418, 17431, 18210, 18289, - 18183, 17265, 17418, 17348, 16737, 16547, 16643, 31205, 31146, 31187, 32541, 32434, 32512, - 33804, 33690, 33855, 33594, 33608, 33475, 33957, 33745, 33703, 34166, 33940, 34248, 33553, - 33689, 33625, 14385, 14698, 14453, 15692, 15857, 15655, 26724, 26691, 26497, 32697, 32604, - 32789, 7948, 8080, 8024, 7948, 7917, 7939, 10611, 11004, 10924, 9959, 9934, 10039, - 10339, 10500, 10526, 20450, 19939, 20026, 18468, 18621, 18289, 18468, 18289, 18395, 22697, - 22907, 22747, 22623, 22907, 22697, 7972, 8024, 8083, 19939, 19916, 19909, 19443, 19108, - 19147, 34177, 34156, 34083, 8056, 8075, 8285, 8762, 8376, 8249, 7952, 8075, 8056, - 22074, 22369, 22255, 27135, 27174, 27131, 27984, 28062, 27941, 32599, 32541, 32512, 16375, - 16419, 16216, 24736, 24801, 24561, 33073, 33004, 32584, 33574, 33531, 33429, 8669, 8923, - 8958, 8498, 8383, 8629, 8472, 8530, 8592, 8376, 8184, 8249, 8806, 9249, 8997, - 16737, 17114, 17064, 33670, 33608, 33594, 19916, 19823, 19909, 27335, 27368, 27326, 18621, - 18817, 19116, 17968, 18049, 17866, 23236, 22996, 22552, 23218, 22996, 23236, 33974, 33933, - 34146, 34084, 33642, 34131, 33859, 33974, 33760, 11389, 11239, 11252, 11252, 11158, 11154, - 11154, 11022, 11295, 11865, 11857, 12133, 15974, 16128, 15857, 15974, 15857, 15692, 19823, - 19729, 19717, 22369, 22421, 22395, 32022, 32217, 32098, 31017, 31275, 30789, 34174, 34108, - 34077, 34174, 34077, 34052, 8969, 8932, 8958, 8907, 8932, 8969, 9957, 9831, 9817, - 10080, 10207, 10184, 11239, 11158, 11252, 28381, 28157, 28262, 29136, 29215, 29317, 28062, - 28042, 27941, 8211, 8458, 8406, 8453, 8383, 8498, 8376, 8344, 8199, 11158, 11022, - 11154, 10212, 10322, 10258, 29389, 29164, 29149, 28671, 28409, 28553, 28995, 28702, 28834, - 10772, 10902, 10884, 14014, 13265, 13344, 10937, 10902, 10772, 10532, 10614, 10466, 9420, - 9556, 9458, 9332, 9181, 9473, 10094, 10080, 10184, 9332, 9473, 9468, 8806, 8997, - 8691, 9299, 9487, 9526, 15068, 14910, 15090, 14811, 14771, 14925, 15083, 14910, 15068, - 15083, 15068, 15267, 16120, 15869, 16102, 15780, 15869, 15827, 26554, 26724, 26497, 27045, - 27135, 27131, 27174, 27335, 27326, 26554, 26497, 26414, 7846, 8204, 8162, 11365, 11749, - 10912, 26763, 26554, 26802, 30587, 30676, 29910, 29910, 29389, 29751, 30927, 30779, 30683, - 30855, 30779, 30865, 30779, 31026, 30865, 33933, 33974, 33859, 33690, 33674, 33594, 33642, - 33857, 34131, 8701, 8613, 8718, 8423, 8453, 8498, 8350, 8613, 8387, 8488, 8554, - 8841, 7959, 8554, 8488, 14806, 14771, 14811, 24907, 25035, 24801, 24940, 25035, 24907, - 26840, 26798, 26296, 26968, 26983, 27049, 10507, 10262, 10395, 10140, 10262, 10103, 12555, - 12487, 12773, 12555, 12773, 12750, 24047, 23968, 23854, 24216, 23968, 24047, 24216, 24047, - 24683, 29164, 29146, 29032, 26968, 26798, 26983, 29216, 29146, 29164, 15412, 15290, 15406, - 24418, 24736, 24561, 33553, 33658, 33689, 33957, 33703, 33697, 33649, 33531, 33644, 17840, - 17968, 17866, 17866, 17697, 17714, 33934, 33878, 33760, 16151, 16375, 16216, 17001, 17265, - 17114, 17114, 17265, 17348, 16355, 16375, 16290, 27846, 27438, 27672, 12054, 11865, 12133, - 9934, 9831, 9957, 9834, 9831, 9934, 27115, 27135, 27045, 27368, 27475, 27482, 32305, - 31912, 31963, 31360, 31146, 31205, 8082, 8321, 8283, 8218, 8283, 8371, 19582, 19494, - 19688, 34005, 33993, 34143, 18706, 18817, 18621, 18706, 18621, 18679, 34131, 33857, 34042, - 8294, 8406, 8415, 8423, 8498, 8530, 16780, 17114, 16737, 33608, 33611, 33371, 33802, - 33674, 33690, 32217, 32252, 32098, 32259, 32252, 32217, 10839, 10611, 10924, 30560, 31017, - 30294, 30560, 30294, 29506, 32541, 32557, 32346, 32578, 32557, 32541, 32578, 32541, 32599, - 10080, 9959, 10039, 9895, 9959, 10080, 16247, 16410, 16837, 15707, 15780, 15827, 18549, - 18871, 18792, 22462, 22139, 22552, 23406, 23375, 23418, 10193, 10212, 10258, 10322, 10339, - 10526, 10113, 10193, 10120, 12487, 12369, 12618, 12885, 12991, 12678, 29146, 29033, 29032, - 29096, 29033, 29146, 29215, 29367, 29317, 28834, 28702, 28593, 28834, 28593, 28604, 8551, - 8645, 8923, 8873, 8907, 8969, 33004, 33174, 32987, 33160, 33174, 33004, 33160, 33004, - 33237, 8294, 8415, 8383, 8199, 8305, 8251, 8416, 8152, 8488, 8199, 8251, 7907, - 18581, 18621, 18468, 17481, 17552, 17418, 18679, 18621, 18581, 17445, 17481, 17418, 8082, - 8258, 8321, 9556, 9466, 9559, 9420, 9466, 9556, 22782, 22552, 22996, 8513, 8472, - 8676, 8296, 8294, 8383, 8513, 8676, 8613, 25035, 25108, 24853, 25056, 25108, 25035, - 33659, 33611, 33608, 32789, 32604, 32686, 13053, 13134, 12779, 14413, 14385, 14453, 32252, - 32383, 32098, 32017, 31117, 31921, 8010, 7874, 8096, 7877, 7874, 8010, 7877, 8010, - 7923, 8010, 7963, 7923, 7790, 7811, 7923, 7790, 7923, 7963, 15869, 15780, 15998, - 16102, 16287, 16163, 10140, 10094, 10262, 10262, 10094, 10184, 12388, 12369, 12487, 12678, - 12991, 12756, 13668, 13760, 13748, 29535, 29389, 30072, 31360, 31205, 31416, 8006, 7948, - 7939, 8011, 8267, 8075, 34141, 34265, 34034, 34099, 34256, 34177, 34177, 34232, 34156, - 34149, 34054, 34084, 34121, 34265, 34141, 34222, 34265, 34121, 34222, 34121, 34160, 34222, - 34160, 34272, 34160, 34178, 34272, 34178, 34212, 34272, 7948, 8024, 7917, 8427, 8423, - 8530, 8788, 8958, 8932, 9487, 9754, 9526, 33674, 33670, 33594, 33802, 33670, 33674, - 33649, 33658, 33553, 34143, 33993, 34166, 33649, 33553, 33531, 34178, 34114, 34212, 7924, - 7969, 8033, 7924, 8033, 7965, 33993, 33940, 34166, 34212, 34114, 34608, 34055, 34108, - 34192, 13737, 13748, 13848, 14910, 14806, 14811, 14899, 14806, 14910, 15083, 15267, 15105, - 18145, 18049, 17968, 22914, 22782, 22996, 26983, 26798, 26840, 26983, 27237, 27461, 34031, - 33934, 33760, 33855, 33690, 33567, 34084, 34054, 33799, 34353, 34087, 34156, 9299, 9526, - 9176, 20230, 20987, 20697, 22254, 22369, 22074, 22344, 22445, 22369, 22369, 22445, 22421, - 20230, 19116, 19218, 18832, 18817, 18706, 32447, 32383, 32252, 34325, 34256, 34099, 34192, - 34108, 34174, 32816, 32686, 32804, 32557, 32544, 32346, 10310, 10339, 10322, 10310, 10322, - 10212, 34256, 34228, 34177, 11022, 10933, 11295, 11158, 11059, 11022, 11239, 11173, 11158, - 11120, 11173, 11239, 11059, 11173, 10914, 7969, 7952, 8056, 7924, 7952, 7969, 8296, - 8383, 8453, 15692, 15655, 15469, 17102, 17445, 17265, 17265, 17445, 17418, 15655, 15479, - 15469, 17481, 17714, 17697, 17981, 18145, 17968, 16780, 16737, 16643, 23522, 23406, 23418, - 23218, 23113, 22996, 24246, 24216, 24683, 33855, 33567, 33923, 32699, 32578, 32599, 34228, - 34232, 34177, 28604, 28593, 28365, 28995, 29112, 29215, 17981, 17968, 17840, 23675, 23766, - 23745, 22907, 23371, 22845, 24958, 24940, 24736, 24736, 24940, 24907, 23095, 23371, 22907, - 23488, 23371, 23534, 11010, 10933, 11022, 10055, 10140, 10059, 10902, 10937, 10960, 10772, - 10884, 10532, 19108, 19025, 19147, 16287, 16344, 16410, 30855, 30676, 30587, 30855, 30587, - 30779, 8907, 8788, 8932, 9132, 8873, 9080, 9132, 9080, 9181, 33291, 33161, 33595, - 32941, 32584, 32803, 8472, 8427, 8530, 8338, 8296, 8453, 8350, 8513, 8613, 8472, - 8350, 8339, 9458, 9755, 9817, 9844, 9834, 9934, 9844, 9934, 9959, 16643, 16547, - 16588, 26886, 26763, 26802, 24418, 23861, 24253, 28262, 28157, 28042, 28262, 28042, 28062, - 10532, 10884, 10614, 10144, 10310, 10212, 12264, 12369, 12388, 27935, 27798, 28026, 29389, - 29216, 29164, 29096, 29216, 29240, 9466, 9393, 9468, 9323, 9393, 9466, 10933, 10839, - 10924, 10614, 10500, 10466, 27316, 27335, 27174, 27316, 27174, 27135, 26982, 26849, 26724, - 27672, 27438, 27482, 31088, 30927, 30995, 32720, 32544, 32557, 7917, 8024, 7785, 19308, - 19108, 19443, 34189, 34192, 34174, 33633, 34015, 34032, 8339, 8427, 8472, 33670, 33659, - 33608, 32996, 32804, 32743, 33774, 33659, 33670, 33633, 33817, 34015, 33060, 33610, 33161, - 7919, 8024, 7972, 19729, 19686, 19688, 19494, 19543, 19443, 19823, 19838, 19729, 19916, - 19838, 19823, 19939, 19838, 19916, 19806, 19838, 19939, 19685, 19838, 19806, 8044, 8082, - 8283, 7905, 7919, 7972, 8268, 8211, 8406, 8268, 8406, 8294, 8836, 8788, 8907, - 15780, 15707, 15795, 16344, 16536, 16410, 15479, 15076, 15087, 16355, 16547, 16375, 17535, - 17714, 17481, 17981, 17714, 17972, 16536, 16837, 16410, 8044, 8283, 8218, 18549, 18536, - 18482, 18598, 18536, 18549, 33817, 33745, 34015, 8199, 8184, 8376, 8249, 8228, 8683, - 8055, 8184, 8199, 23056, 23113, 23299, 23745, 23766, 23968, 23371, 23488, 23422, 22623, - 22595, 22421, 34031, 33760, 33974, 33804, 33802, 33690, 7952, 8011, 8075, 7866, 8011, - 7952, 8338, 8453, 8423, 9458, 9817, 9310, 22254, 22074, 22098, 32544, 32471, 32346, - 31354, 31088, 31146, 32383, 32435, 32253, 32447, 32435, 32383, 33891, 33802, 33804, 34451, - 34131, 34042, 34186, 33923, 33934, 34189, 34174, 34127, 9332, 9468, 9393, 9034, 9132, - 9181, 8873, 8836, 8907, 26554, 26763, 26724, 25285, 25643, 25108, 32830, 32816, 32938, - 32697, 32699, 32599, 32580, 32539, 32544, 32544, 32539, 32471, 32867, 32803, 32532, 13737, - 14196, 14356, 12388, 12487, 12555, 19838, 19686, 19729, 27640, 27798, 27876, 26013, 25891, - 26296, 26763, 26982, 26724, 28381, 28604, 28365, 28270, 28262, 28062, 31921, 31117, 31275, - 32204, 32259, 32217, 32830, 32789, 32686, 31146, 31088, 30995, 31360, 31375, 31354, 19108, - 18920, 19025, 18838, 18920, 19023, 22782, 22462, 22552, 19806, 19939, 20033, 22602, 22462, - 22782, 26982, 27115, 27045, 27335, 27475, 27368, 28207, 28270, 28062, 32779, 32699, 32697, - 34116, 33940, 33977, 34235, 34189, 34127, 16780, 17001, 17114, 16375, 16151, 16290, 24940, - 25056, 25035, 24958, 25056, 24940, 33595, 33610, 33691, 33634, 33574, 33744, 18536, 18453, - 18482, 18490, 18453, 18536, 18210, 18395, 18289, 18679, 18676, 18706, 18210, 18183, 18145, - 23113, 23218, 23299, 34033, 34116, 33977, 33697, 34372, 33957, 33689, 34163, 33697, 10094, - 10041, 10080, 10262, 10507, 10103, 9987, 10113, 10120, 10310, 10282, 10339, 9987, 10120, - 9954, 12779, 13134, 12600, 12779, 12600, 12141, 13710, 13912, 14378, 13727, 13912, 13710, - 16866, 17001, 16780, 19686, 19582, 19688, 28834, 29112, 28995, 28574, 28604, 28381, 33634, - 33644, 33531, 8211, 8125, 8218, 8145, 8268, 8164, 33923, 33567, 33878, 18421, 18217, - 18347, 15725, 15660, 15707, 16130, 16151, 15974, 26013, 26296, 26400, 24216, 24138, 23968, - 15993, 16130, 15974, 15087, 15076, 14744, 17714, 17981, 17840, 18145, 17981, 18140, 33689, - 33658, 33779, 9323, 9332, 9393, 27115, 27316, 27135, 7905, 7972, 7964, 19582, 19543, - 19494, 24253, 23861, 23762, 34235, 34127, 34143, 19806, 20033, 19663, 22730, 22602, 22782, - 22445, 22623, 22421, 22593, 22623, 22445, 15993, 15974, 15693, 8773, 8836, 8873, 8788, - 8669, 8958, 15707, 15660, 15473, 14619, 14349, 14771, 15827, 15869, 15914, 10140, 10041, - 10094, 9718, 9817, 9831, 9420, 9323, 9466, 10055, 10041, 10140, 27935, 28026, 28221, - 27394, 27475, 27335, 32470, 32305, 31963, 32720, 32557, 32578, 7868, 7905, 7964, 12388, - 12555, 12488, 14619, 14771, 14806, 13659, 13727, 13710, 14111, 14385, 14413, 28553, 28831, - 28792, 32470, 31963, 32471, 32270, 32259, 32204, 33289, 33073, 32941, 9895, 9844, 9959, - 28792, 28831, 29033, 32028, 31921, 32013, 32017, 32270, 32204, 10933, 10779, 10839, 10103, - 10181, 9900, 11173, 11059, 11158, 11619, 11389, 11865, 24246, 24138, 24216, 23299, 23218, - 23406, 33855, 33835, 33804, 33774, 33646, 33659, 33592, 33276, 33236, 33946, 33835, 33855, - 33923, 33878, 33934, 34031, 33974, 34123, 34195, 34116, 34032, 33779, 33658, 33649, 11059, - 11010, 11022, 34131, 34149, 34084, 34190, 34149, 34131, 10144, 10282, 10310, 12369, 12264, - 12618, 12555, 12688, 12488, 16355, 16588, 16547, 16643, 16866, 16780, 17001, 17102, 17265, - 16407, 16588, 16355, 25056, 25087, 25108, 25016, 25087, 25056, 31360, 31553, 31375, 15725, - 15827, 15914, 16654, 16866, 16643, 9718, 9831, 9834, 27475, 27672, 27482, 29262, 29112, - 29067, 32614, 32470, 32471, 15105, 15267, 15290, 14899, 15083, 15075, 32699, 32711, 32578, - 32539, 32614, 32471, 32779, 32711, 32699, 32816, 32830, 32686, 33050, 33611, 33646, 16213, - 16290, 16130, 16130, 16290, 16151, 8164, 8268, 8294, 8427, 8338, 8423, 8339, 8338, - 8427, 8472, 8513, 8350, 10113, 10144, 10212, 9988, 9987, 9946, 12141, 12600, 11749, - 13344, 13265, 13134, 14722, 14619, 14806, 18581, 18676, 18679, 18224, 18210, 18140, 18210, - 18145, 18140, 29017, 28792, 29033, 29096, 29146, 29216, 33646, 33611, 33659, 32941, 33073, - 32584, 32867, 32532, 32727, 33759, 33779, 33649, 33759, 33649, 33644, 33634, 33531, 33574, - 34146, 33933, 34054, 34303, 34050, 34034, 34256, 34325, 34228, 34228, 34307, 34232, 34232, - 34285, 34156, 34303, 34034, 34265, 34303, 34265, 34331, 34265, 34322, 34331, 34222, 34322, - 34265, 34272, 34322, 34222, 34272, 34212, 34322, 34322, 34212, 34608, 7923, 7811, 7877, - 7877, 7718, 7874, 7874, 7846, 8192, 7790, 7963, 7731, 7963, 8006, 7731, 8006, - 7939, 7827, 7939, 7805, 7827, 7600, 7846, 7874, 30676, 30712, 29910, 30855, 30795, - 30676, 31026, 30779, 30927, 31026, 30927, 31088, 34331, 34322, 34435, 7939, 7917, 7805, - 7859, 7868, 7771, 7837, 7868, 7859, 8125, 8211, 8145, 7806, 7924, 7965, 7800, - 8055, 8199, 34274, 34235, 34143, 34435, 34835, 34514, 34299, 34143, 34166, 34116, 34033, - 34032, 18581, 18468, 18505, 7917, 7791, 7805, 13496, 13760, 13668, 10755, 11010, 10792, - 18963, 19116, 18817, 22098, 22074, 21911, 32779, 32697, 32789, 34445, 34325, 34099, 13648, - 13496, 13668, 13648, 13668, 13737, 13727, 13866, 13912, 13344, 13134, 13053, 28473, 28412, - 28233, 28552, 28412, 28473, 15693, 15974, 15692, 8145, 8211, 8268, 23965, 23745, 23968, - 23113, 22914, 22996, 30994, 31026, 31157, 8152, 8228, 7949, 8691, 8997, 8847, 8055, - 8249, 8184, 13659, 13866, 13727, 27935, 27876, 27798, 27905, 27876, 27935, 8646, 8669, - 8788, 8655, 8773, 8873, 8655, 8873, 9132, 9034, 9181, 9332, 8691, 8847, 8426, - 9176, 9526, 9387, 9988, 10113, 9987, 21335, 21607, 21105, 23534, 23762, 23488, 24971, - 24736, 24597, 26400, 26296, 26798, 27049, 26798, 26968, 27049, 26983, 27461, 34325, 34307, - 34228, 10772, 10848, 10937, 10937, 10848, 11529, 10466, 10500, 10358, 10500, 10339, 10358, - 9930, 9895, 10080, 9219, 9323, 9320, 9930, 10080, 10041, 28792, 28671, 28553, 28629, - 28671, 28783, 10052, 10144, 10113, 12054, 12133, 12264, 12472, 12488, 12688, 18792, 18598, - 18549, 16247, 16207, 16410, 18792, 18871, 18920, 18832, 18963, 18817, 18505, 18468, 18395, - 23056, 22914, 23113, 22426, 22139, 22462, 26886, 26921, 26763, 24971, 24958, 24736, 23893, - 23762, 23534, 29240, 29216, 29271, 29067, 29112, 28834, 28270, 28381, 28262, 33774, 33670, - 33802, 33109, 33610, 33060, 34149, 34146, 34054, 34190, 34146, 34149, 34195, 34032, 34362, - 7917, 7785, 7791, 21193, 21335, 21105, 33109, 33357, 33610, 8613, 8701, 8387, 8164, - 8294, 8296, 33891, 33774, 33802, 33891, 33804, 33835, 33891, 33835, 33946, 33855, 34045, - 33946, 33779, 34163, 33689, 34195, 34248, 34116, 33824, 33759, 33644, 22254, 22344, 22369, - 22332, 22344, 22254, 8024, 7919, 7785, 10358, 10339, 10282, 15827, 15725, 15707, 16120, - 16102, 16163, 16207, 16163, 16410, 21335, 21506, 21607, 34307, 34285, 34232, 18421, 18347, - 18453, 23534, 23371, 23459, 13580, 13659, 13710, 13306, 13344, 13119, 27984, 27941, 27846, - 7785, 7919, 7837, 12756, 12991, 13544, 13627, 13648, 13737, 13462, 13659, 13580, 27943, - 27984, 27846, 32259, 32374, 32252, 32171, 32270, 32017, 34285, 34316, 34156, 10181, 10611, - 10839, 13685, 13627, 13737, 15083, 14899, 14910, 15105, 15290, 15242, 18598, 18490, 18536, - 18641, 18490, 18598, 18832, 18706, 18784, 18224, 18505, 18395, 18224, 18395, 18210, 23893, - 24253, 23762, 33855, 33923, 34089, 7938, 8267, 8011, 10233, 10358, 10282, 14899, 14722, - 14806, 27115, 27152, 27316, 27316, 27394, 27335, 27740, 27759, 27672, 27672, 27759, 27846, - 26982, 27152, 27115, 26763, 26921, 26982, 25285, 25108, 25087, 32727, 32404, 32755, 33691, - 33574, 33595, 15412, 15406, 15660, 7773, 7866, 7952, 7806, 7952, 7924, 18706, 18676, - 18784, 26921, 27152, 26982, 32848, 32779, 32789, 32711, 32720, 32578, 32848, 32789, 32830, - 8646, 8788, 8836, 27878, 27759, 27740, 19686, 19685, 19582, 19582, 19613, 19543, 19023, - 18920, 19108, 19838, 19685, 19686, 22426, 22462, 22602, 34316, 34353, 34156, 24958, 25016, - 25056, 24971, 25016, 24958, 14111, 14413, 13912, 15562, 15693, 15692, 14449, 14385, 14274, - 29262, 29367, 29215, 32028, 32017, 31921, 29262, 29215, 29112, 31360, 31354, 31146, 31360, - 31416, 31553, 32895, 32720, 32711, 32470, 32433, 32305, 32257, 32214, 31912, 16290, 16407, - 16355, 16654, 17102, 16866, 18140, 17981, 17972, 16213, 16407, 16290, 16213, 16130, 15993, - 25216, 25285, 25087, 18490, 18421, 18453, 18562, 18421, 18490, 22914, 22730, 22782, 23299, - 23406, 23480, 8125, 8044, 8218, 8164, 8296, 7951, 12243, 12264, 12388, 12756, 13544, - 13176, 23745, 23662, 23522, 24138, 23965, 23968, 24246, 23965, 24138, 24246, 24683, 24512, - 7837, 7919, 7905, 7837, 7905, 7868, 22707, 22907, 22623, 24066, 24597, 24253, 28412, - 28221, 28026, 27876, 27790, 27461, 28168, 28221, 28339, 28629, 28473, 28671, 29067, 28834, - 29025, 27984, 28207, 28062, 28398, 28207, 28287, 11010, 10779, 10933, 10755, 10779, 11010, - 12243, 12388, 12213, 10682, 10772, 10662, 10682, 10848, 10772, 10441, 10532, 10466, 30901, - 30795, 30855, 30901, 30855, 30865, 30901, 30865, 30994, 9320, 9323, 9420, 8593, 8646, - 8836, 9718, 9834, 9844, 9768, 9844, 9895, 32714, 32580, 32544, 8669, 8551, 8923, - 7951, 8296, 8338, 8531, 8551, 8669, 16207, 16120, 16163, 15422, 15412, 15660, 16076, - 16120, 16207, 28000, 27905, 27935, 27878, 27943, 27846, 27878, 27846, 27759, 32270, 32374, - 32259, 32458, 32374, 32270, 12213, 12388, 12488, 30994, 30865, 31026, 7866, 7938, 8011, - 7830, 7938, 7866, 19447, 19443, 19543, 18963, 19218, 19116, 18784, 18676, 18581, 22344, - 22593, 22445, 22332, 22593, 22344, 34116, 34248, 33940, 34055, 34192, 34520, 34195, 34362, - 34398, 9992, 9930, 10041, 9992, 10041, 10055, 7868, 8258, 7771, 19613, 19447, 19543, - 8052, 8044, 8125, 8034, 8164, 7951, 8600, 8646, 8593, 8806, 8901, 9484, 8426, - 8847, 8554, 9899, 10103, 9900, 29096, 29141, 29033, 29535, 29216, 29389, 28834, 28939, - 29025, 33891, 33972, 33774, 33774, 33951, 33646, 34173, 33934, 34031, 8052, 8125, 8145, - 23890, 23662, 23745, 26392, 26554, 26414, 26921, 27190, 27152, 27525, 27672, 27475, 32747, - 32714, 32720, 32720, 32714, 32544, 33051, 32938, 32816, 33034, 32804, 32996, 14744, 14916, - 14698, 33123, 33034, 32996, 33051, 33034, 33123, 7938, 7870, 8267, 7853, 7870, 7938, - 14858, 14614, 14722, 14722, 14614, 14619, 14858, 14722, 14899, 14858, 14899, 14907, 18838, - 18792, 18920, 18710, 18792, 18838, 18760, 18784, 18581, 18832, 18913, 18963, 18887, 18784, - 18760, 27011, 27049, 27125, 32938, 32848, 32830, 34451, 34190, 34131, 34254, 34123, 33974, - 8741, 8901, 8633, 26566, 26392, 26421, 17010, 17898, 17160, 15648, 15660, 15725, 9768, - 9718, 9844, 19447, 19411, 19443, 21978, 22098, 21911, 10358, 10441, 10466, 10233, 10441, - 10358, 15914, 15869, 16120, 17714, 17535, 17972, 23480, 23406, 23522, 22960, 22730, 22914, - 34254, 33974, 34146, 28142, 28207, 27984, 28834, 28604, 28939, 27394, 27316, 27152, 32374, - 32447, 32252, 32458, 32447, 32374, 34308, 34445, 34099, 34325, 34620, 34307, 34307, 34465, - 34285, 34285, 34388, 34316, 34316, 34379, 34353, 34303, 34378, 34308, 34331, 34378, 34303, - 34435, 34378, 34331, 34192, 34189, 34447, 7601, 7718, 7811, 7811, 7718, 7877, 7732, - 7806, 7368, 7715, 7811, 7790, 7715, 7790, 7731, 8006, 7827, 7731, 7827, 7743, - 7731, 7734, 7743, 7827, 34378, 34364, 34308, 34274, 34189, 34235, 9930, 9768, 9895, - 10103, 10059, 10140, 10016, 10059, 10103, 10144, 10111, 10282, 9988, 10052, 10113, 9954, - 10011, 9631, 12678, 12472, 12688, 12186, 12054, 12264, 12608, 12472, 12678, 28783, 28671, - 28792, 28221, 28000, 27935, 29240, 29141, 29096, 29203, 29141, 29240, 28604, 28574, 28939, - 34364, 34445, 34308, 34559, 34451, 34042, 7725, 7859, 7771, 7805, 7734, 7827, 19411, - 19308, 19443, 22098, 22186, 22254, 27457, 27394, 27359, 32747, 32720, 32895, 32614, 32485, - 32470, 34299, 34274, 34143, 34445, 34444, 34325, 7870, 7907, 8267, 7862, 7907, 7870, - 22960, 22914, 23056, 8034, 8052, 8145, 7771, 8258, 7618, 7707, 7734, 7805, 7791, - 7707, 7805, 21021, 21193, 21105, 21465, 21596, 21506, 21506, 21596, 21759, 22098, 22167, - 22186, 21465, 21193, 21383, 7732, 7521, 7610, 19308, 19170, 19108, 9176, 9387, 9207, - 27457, 27525, 27475, 18887, 18832, 18784, 17481, 17445, 17535, 25016, 25216, 25087, 26972, - 26802, 26874, 24597, 24736, 24418, 25016, 24971, 25079, 33634, 33744, 33644, 33759, 34012, - 33779, 33691, 33744, 33574, 33174, 33357, 33109, 7791, 7744, 7707, 10173, 10233, 10111, - 12186, 12264, 12243, 13524, 13833, 13866, 14657, 14744, 14698, 13344, 13306, 13580, 13119, - 13344, 13053, 13119, 12958, 12998, 30072, 29389, 29910, 29353, 29367, 29262, 29353, 29543, - 29367, 29367, 29543, 29317, 32028, 32171, 32017, 31921, 31275, 32013, 33174, 33160, 33324, - 10059, 9992, 10055, 10016, 9992, 10059, 10111, 10233, 10282, 9946, 9987, 9810, 29209, - 29017, 29141, 29141, 29017, 29033, 28381, 28270, 28398, 29273, 29353, 29262, 13648, 13464, - 13496, 14356, 14196, 14619, 27905, 27790, 27876, 28168, 28000, 28221, 28552, 28473, 28629, - 34324, 34195, 34398, 34297, 34299, 34166, 15562, 15692, 15469, 16654, 16643, 16588, 7791, - 7785, 7744, 34620, 34465, 34307, 28670, 28552, 28629, 32013, 31275, 31017, 15922, 16213, - 15993, 26013, 25405, 25394, 23965, 23890, 23745, 25366, 25405, 25512, 33237, 33004, 33073, - 7806, 7773, 7952, 7732, 7773, 7806, 22167, 22332, 22186, 22186, 22332, 22254, 22707, - 23095, 22907, 7744, 7785, 7837, 33034, 33051, 32816, 32938, 33078, 32848, 32747, 32580, - 32714, 33123, 32996, 33253, 34465, 34388, 34285, 14845, 14744, 14640, 15087, 15213, 15479, - 12213, 12488, 12472, 12213, 12186, 12243, 11977, 12141, 11749, 23662, 23480, 23522, 23152, - 22960, 23056, 24285, 23890, 23965, 34185, 34089, 33923, 33946, 33972, 33891, 32614, 32539, - 32580, 32614, 32580, 32747, 10779, 10753, 10839, 10914, 11010, 11059, 11619, 11865, 12054, - 8228, 8152, 8416, 7949, 8228, 8249, 8002, 8249, 8055, 19685, 19613, 19582, 19447, - 19459, 19411, 19411, 19394, 19308, 19308, 19280, 19170, 21972, 21146, 22139, 21465, 21506, - 21335, 24512, 24683, 25021, 34041, 33972, 33946, 10848, 10912, 11529, 10419, 10772, 10532, - 10419, 10532, 10441, 23152, 23056, 23299, 22704, 22426, 22602, 23584, 23480, 23662, 33289, - 33237, 33073, 33426, 33535, 33442, 34123, 34173, 34031, 34194, 34173, 34310, 34254, 34146, - 34277, 34277, 34146, 34190, 10004, 10144, 10052, 9810, 9987, 9954, 13176, 13544, 13496, - 29025, 29155, 29067, 28398, 28270, 28207, 27984, 27943, 28142, 16000, 15914, 16120, 16076, - 16207, 16247, 15693, 15922, 15993, 15888, 15922, 15693, 7773, 7830, 7866, 7800, 8002, - 8055, 7732, 7830, 7773, 8991, 9176, 8741, 9631, 10011, 9512, 19190, 19023, 19170, - 19170, 19023, 19108, 18792, 18641, 18598, 16000, 16076, 15810, 22704, 22602, 22730, 32755, - 32404, 32435, 32755, 32435, 32583, 34393, 34447, 34189, 34297, 34166, 34248, 34388, 34379, - 34316, 30795, 30898, 30676, 30901, 30888, 30795, 31157, 31026, 31088, 31157, 31088, 31364, - 13485, 13464, 13648, 13485, 13648, 13627, 13306, 13462, 13580, 13375, 13462, 13306, 28484, - 28221, 28412, 26286, 26400, 26628, 29535, 29271, 29216, 28670, 28484, 28552, 28552, 28484, - 28412, 29307, 29271, 29535, 33237, 33324, 33160, 8387, 8701, 8645, 8164, 8034, 8145, - 8387, 8645, 8551, 9631, 9512, 9605, 13128, 13119, 12998, 28783, 28792, 28919, 12001, - 11619, 12054, 32485, 32433, 32470, 32504, 32433, 32485, 34379, 34380, 34353, 9323, 9219, - 9332, 9320, 9420, 9458, 9320, 9458, 9310, 27525, 27740, 27672, 27394, 27457, 27475, - 27190, 27394, 27152, 26972, 26921, 26886, 7951, 8338, 8339, 7771, 7618, 7619, 18887, - 18913, 18832, 18096, 18505, 18224, 34148, 34045, 34089, 34089, 34045, 33855, 34324, 34297, - 34248, 34393, 34189, 34274, 22707, 22623, 22593, 24597, 24418, 24253, 7800, 8199, 7717, - 17102, 17001, 16866, 18140, 18120, 18224, 29003, 28792, 29017, 34173, 34186, 33934, 34194, - 34186, 34173, 7725, 7744, 7837, 7725, 7837, 7859, 10388, 10419, 10293, 10173, 10441, - 10233, 15075, 15083, 15105, 13343, 13176, 13464, 15914, 15648, 15725, 15914, 15653, 15648, - 16000, 15810, 15769, 19806, 19613, 19685, 31364, 31088, 31354, 33324, 33357, 33174, 29271, - 29203, 29240, 29307, 29203, 29271, 9310, 9817, 9718, 32711, 32779, 32895, 34393, 34274, - 34396, 7830, 7853, 7938, 7741, 7853, 7830, 9711, 9810, 9954, 9946, 9830, 9988, - 9620, 9631, 9605, 13464, 13176, 13496, 13485, 13685, 13343, 15075, 15105, 15242, 14744, - 14845, 15087, 14657, 14698, 14449, 26392, 26802, 26554, 25416, 25643, 25285, 28142, 27943, - 28059, 14518, 14619, 14614, 15242, 15290, 15412, 14845, 15056, 15087, 32895, 32779, 32848, - 32743, 33592, 33236, 9090, 9034, 9219, 9219, 9034, 9332, 8646, 8600, 8669, 14449, - 14698, 14385, 8655, 8836, 8773, 9992, 9880, 9930, 9899, 10016, 10103, 15422, 15242, - 15412, 15056, 15213, 15087, 19613, 19459, 19447, 26628, 26400, 26798, 28079, 27905, 28000, - 33253, 33236, 33276, 34396, 34274, 34458, 14111, 13912, 13977, 26972, 27190, 26921, 27653, - 27740, 27525, 8002, 7977, 8249, 7800, 7977, 8002, 9880, 9768, 9930, 9700, 9810, - 9711, 28783, 28670, 28629, 28484, 28339, 28221, 28889, 28670, 28783, 33744, 33824, 33644, - 34195, 34324, 34248, 33851, 33824, 33744, 33851, 33744, 33691, 33851, 33691, 34007, 34186, - 34185, 33923, 34194, 34185, 34186, 32214, 31416, 31912, 32676, 32504, 32485, 32527, 32504, - 32637, 8405, 8387, 8551, 7889, 7987, 8034, 7853, 7862, 7870, 7613, 7862, 7853, - 18908, 18710, 18838, 18908, 18838, 19023, 22720, 22704, 22848, 22064, 22053, 22139, 22559, - 22704, 22720, 22418, 22707, 22593, 22418, 22593, 22332, 34458, 34274, 34299, 34457, 34324, - 34394, 15564, 15422, 15660, 15564, 15660, 15648, 27190, 27359, 27394, 33078, 32938, 33051, - 32727, 33009, 32867, 33426, 33377, 33324, 33324, 33377, 33357, 32583, 32435, 32447, 32296, - 32270, 32171, 8082, 7629, 7704, 19459, 19394, 19411, 34458, 34299, 34453, 31912, 32305, - 32257, 16076, 16000, 16120, 17898, 18217, 17160, 12756, 12608, 12678, 12186, 12072, 12054, - 12592, 12608, 12756, 29209, 29141, 29203, 29209, 29003, 29017, 34378, 34501, 34364, 34364, - 34495, 34445, 34445, 34504, 34444, 34444, 34516, 34325, 34465, 34515, 34388, 34388, 34515, - 34379, 34379, 34512, 34380, 34514, 34501, 34378, 34514, 34378, 34435, 34435, 34768, 34835, - 34192, 34535, 34520, 34192, 34447, 34535, 10755, 10753, 10779, 11120, 10914, 11173, 10686, - 10914, 10673, 15653, 15564, 15648, 33426, 33324, 33237, 33357, 33706, 33610, 34501, 34495, - 34364, 14123, 14111, 14015, 13186, 13375, 13306, 13128, 13306, 13119, 28168, 28079, 28000, - 28605, 28339, 28484, 28782, 28484, 28670, 32304, 32296, 32171, 32166, 32171, 32028, 34495, - 34504, 34445, 10914, 10792, 11010, 13372, 13659, 13462, 18710, 18641, 18792, 18764, 18641, - 18710, 19394, 19280, 19308, 21978, 22167, 22098, 34504, 34516, 34444, 23890, 23816, 23662, - 23480, 23348, 23299, 23868, 23816, 23890, 23584, 23816, 23868, 32468, 32458, 32270, 9620, - 9700, 9711, 9810, 9830, 9946, 9620, 9711, 9631, 28398, 28574, 28381, 28939, 29155, - 29025, 28590, 28574, 28398, 10792, 10753, 10755, 30998, 30888, 30901, 30998, 30901, 30994, - 30998, 30994, 31044, 33972, 34059, 33774, 34045, 34041, 33946, 34119, 34041, 34045, 7715, - 7683, 7811, 7239, 7965, 7846, 7731, 7683, 7715, 7664, 7683, 7731, 7664, 7731, - 7743, 7664, 7743, 7548, 7743, 7734, 7548, 7734, 7707, 7548, 10682, 10618, 10848, - 10419, 10662, 10772, 10618, 10662, 10534, 30712, 30072, 29910, 30991, 30998, 31044, 25079, - 25216, 25016, 24253, 23893, 24066, 23893, 23534, 24066, 7548, 7707, 7327, 7568, 7683, - 7548, 7987, 8044, 8052, 19280, 19190, 19170, 18913, 19218, 18963, 18887, 19218, 18913, - 34536, 34353, 34380, 34536, 34042, 34353, 34254, 34294, 34123, 34453, 34299, 34387, 34535, - 34447, 34725, 17972, 18120, 18140, 18084, 18120, 17972, 23584, 23348, 23480, 27653, 27525, - 27457, 7959, 8426, 8554, 8633, 8901, 8408, 9114, 9299, 9176, 8130, 8426, 8007, - 9838, 9880, 9992, 9768, 9644, 9718, 9787, 9880, 9838, 9809, 9830, 9810, 15052, - 14907, 15075, 15075, 14907, 14899, 14858, 14518, 14614, 15240, 15075, 15242, 15240, 15242, - 15422, 16654, 16588, 16407, 16654, 16407, 16551, 15888, 16213, 15922, 23145, 23371, 23095, - 26802, 26972, 26886, 27190, 27274, 27359, 27621, 27653, 27457, 26874, 26802, 26739, 29003, - 28919, 28792, 28889, 28919, 29003, 33096, 33078, 33051, 33103, 33051, 33123, 33253, 33103, - 33123, 33253, 32996, 33236, 34578, 34277, 34190, 34185, 34148, 34089, 14601, 14518, 14858, - 14657, 14640, 14744, 15032, 15145, 15056, 15056, 15145, 15213, 14449, 14527, 14657, 14505, - 14527, 14449, 15567, 15888, 15693, 15032, 15056, 14950, 33276, 33592, 33416, 12413, 12213, - 12472, 29289, 29521, 29390, 34447, 34393, 34725, 34387, 34299, 34297, 34387, 34297, 34466, - 8034, 7987, 8052, 8015, 8339, 8350, 34249, 34148, 34185, 21596, 21978, 21911, 21193, - 21465, 21335, 20913, 20987, 20230, 26400, 26286, 26013, 24285, 23965, 24246, 27011, 26798, - 27049, 27200, 27274, 27190, 32906, 32895, 32848, 32747, 32676, 32614, 34620, 34515, 34465, - 9738, 9644, 9768, 9320, 9225, 9219, 9699, 9809, 9810, 10011, 9487, 9512, 13119, - 13053, 12958, 14123, 14197, 14111, 13186, 13128, 13109, 32257, 32305, 32481, 32527, 32433, - 32504, 8600, 8531, 8669, 8387, 8245, 8350, 8593, 8531, 8600, 15562, 15469, 15213, - 34041, 34059, 33972, 34207, 34059, 34041, 34393, 34396, 34480, 32676, 32485, 32614, 32458, - 32489, 32447, 32583, 32489, 32476, 8602, 8655, 9132, 14111, 14197, 14385, 13323, 13462, - 13375, 15564, 15472, 15422, 15456, 15472, 15564, 7600, 7874, 7718, 7862, 7740, 7907, - 9699, 9810, 9700, 10111, 10144, 10004, 22313, 22418, 22332, 22925, 23145, 23095, 22299, - 22332, 22167, 32079, 32013, 32246, 32296, 32361, 32270, 34480, 34396, 34458, 34466, 34297, - 34457, 12470, 12413, 12472, 12209, 12072, 12186, 12470, 12472, 12608, 12470, 12608, 12592, - 16058, 16407, 16213, 33824, 34012, 33759, 33952, 33851, 34007, 34515, 34512, 34379, 33920, - 34012, 33824, 34480, 34458, 34496, 8655, 8593, 8836, 9310, 9225, 9320, 8602, 8562, - 8655, 15456, 15653, 15568, 15769, 15653, 15914, 27501, 27457, 27359, 28059, 27943, 27878, - 8531, 8405, 8551, 8298, 8405, 8324, 15888, 16058, 16213, 16018, 16058, 15888, 7732, - 7741, 7830, 7613, 7741, 7610, 19133, 18908, 19023, 18641, 18562, 18490, 22704, 22537, - 22426, 22559, 22537, 22704, 34277, 34294, 34254, 34422, 34294, 34277, 34422, 34277, 34795, - 34457, 34297, 34324, 34496, 34458, 34453, 9620, 9624, 9700, 9290, 9487, 9299, 13128, - 13186, 13306, 13323, 13186, 13109, 31553, 31364, 31375, 32473, 32257, 32481, 22704, 22730, - 22848, 23816, 23584, 23662, 24683, 25260, 25021, 34148, 34119, 34045, 34310, 34173, 34397, - 10052, 9915, 10004, 28339, 28079, 28168, 28300, 28079, 28339, 28059, 27878, 27740, 31375, - 31364, 31354, 31553, 31416, 32272, 12209, 12186, 12213, 12592, 12756, 12794, 12756, 13176, - 12794, 29092, 29155, 28939, 30435, 30560, 29506, 29158, 29155, 29092, 27374, 27501, 27274, - 27274, 27501, 27359, 26739, 26802, 26392, 32013, 32149, 32028, 32079, 32149, 32013, 33354, - 33096, 33103, 33103, 33096, 33051, 32906, 32883, 32895, 32895, 32883, 32747, 33258, 33103, - 33253, 14527, 14640, 14657, 15480, 15562, 15213, 14469, 14640, 14527, 14950, 15056, 14845, - 9114, 9290, 9299, 9114, 9176, 8991, 14274, 14385, 14197, 14345, 14505, 14449, 18760, - 18581, 18573, 20929, 20913, 20805, 23152, 23299, 23348, 34496, 34453, 34490, 34394, 34324, - 34398, 34596, 34536, 34380, 14360, 14356, 14518, 15332, 15240, 15422, 15332, 15422, 15472, - 32743, 33714, 33592, 9716, 9830, 9809, 10052, 9988, 9915, 12209, 12213, 12413, 31364, - 31553, 31498, 23224, 23152, 23417, 22925, 23095, 22707, 8205, 8245, 8387, 26728, 26739, - 26566, 25030, 25079, 24971, 24904, 24971, 24597, 7977, 7949, 8249, 7901, 7949, 7977, - 14085, 14274, 14197, 23459, 24066, 23534, 32906, 32848, 33011, 32481, 32305, 32433, 34032, - 34015, 34362, 33952, 33920, 33824, 33952, 33824, 33851, 33416, 33258, 33276, 34244, 34119, - 34148, 12084, 12209, 12413, 12794, 13176, 12894, 10662, 10618, 10682, 10427, 10662, 10419, - 10427, 10419, 10388, 21826, 21978, 21596, 22618, 22925, 22707, 30998, 30991, 30888, 30888, - 30898, 30795, 31044, 30994, 31157, 31044, 31157, 31124, 33377, 33484, 33357, 33289, 32941, - 32867, 33468, 33426, 33442, 34194, 34197, 34185, 34310, 34197, 34194, 34536, 34559, 34042, - 9373, 9512, 9487, 9605, 9624, 9620, 13186, 13323, 13375, 13053, 12717, 12958, 28142, - 28287, 28207, 28085, 28287, 28142, 32304, 32361, 32296, 32489, 32583, 32447, 18908, 18764, - 18710, 20913, 20230, 20805, 18573, 18581, 18505, 18096, 18224, 18120, 18084, 17972, 17899, - 22848, 22730, 22960, 34453, 34387, 34490, 34015, 33957, 34362, 30984, 31044, 31124, 12084, - 12413, 12470, 24398, 24512, 24526, 23017, 22960, 23152, 29273, 29262, 29067, 29273, 29067, - 29158, 9606, 9624, 9605, 12421, 12779, 12141, 32079, 32166, 32149, 32149, 32166, 32028, - 9225, 9214, 9219, 8655, 8562, 8593, 9180, 9214, 9225, 13977, 13912, 13866, 16200, - 16551, 16407, 15896, 16018, 15888, 27830, 28059, 27740, 27830, 27740, 27653, 19459, 19404, - 19394, 19394, 19404, 19280, 19280, 19293, 19190, 19190, 19133, 19023, 18908, 19133, 18764, - 19613, 19404, 19459, 19663, 19404, 19613, 19663, 19613, 19806, 22139, 22426, 22064, 22426, - 22452, 22064, 8593, 8324, 8531, 8405, 8298, 8387, 8602, 9132, 8717, 15154, 15213, - 15145, 33468, 33484, 33377, 10419, 10441, 10293, 7601, 7600, 7718, 7601, 7811, 7568, - 7811, 7683, 7568, 9880, 9787, 9768, 9155, 9180, 9225, 9838, 9992, 10016, 28919, - 28889, 28783, 29196, 28889, 29003, 29289, 29203, 29307, 29289, 29390, 29341, 7369, 7744, - 7725, 7613, 7740, 7862, 7613, 7853, 7741, 20230, 20314, 20805, 21465, 21630, 21596, - 34387, 34526, 34490, 34163, 33779, 34012, 34516, 34620, 34325, 34515, 34638, 34512, 34512, - 34596, 34380, 34536, 34563, 34559, 34504, 34623, 34516, 34495, 34623, 34504, 34501, 34623, - 34495, 34688, 34623, 34501, 34688, 34501, 34835, 34608, 34114, 34520, 7771, 7615, 7725, - 7619, 7615, 7771, 10293, 10201, 10318, 10293, 10441, 10173, 19404, 19293, 19280, 34466, - 34526, 34387, 34813, 34608, 34520, 34197, 34249, 34185, 34464, 34249, 34197, 34244, 34249, - 34298, 7548, 7683, 7664, 20913, 20931, 21105, 29307, 29521, 29289, 29158, 29067, 29155, - 34623, 34603, 34516, 13833, 13977, 13866, 32949, 32676, 32747, 20931, 21021, 21105, 24685, - 24904, 24597, 25416, 25285, 25216, 34007, 33691, 33910, 34111, 34163, 34012, 14594, 14706, - 14640, 14640, 14706, 14845, 15032, 15154, 15145, 14469, 14527, 14505, 14345, 14449, 14274, - 14345, 14283, 14409, 33096, 33082, 33078, 32883, 32926, 32747, 33230, 33082, 33096, 14706, - 14950, 14845, 21021, 21141, 21193, 27200, 27190, 26972, 25416, 25216, 25250, 10293, 10173, - 10201, 7717, 8199, 7907, 13841, 14015, 13977, 12998, 13109, 13128, 12958, 13109, 12998, - 14996, 15154, 15032, 25250, 25216, 25079, 32166, 32304, 32171, 32361, 32468, 32270, 32340, - 32304, 32166, 32495, 32468, 32361, 33276, 33258, 33253, 32674, 33714, 32743, 34603, 34620, - 34516, 7327, 7707, 7744, 7618, 8258, 7704, 22126, 22299, 22167, 22126, 22167, 21978, - 34813, 34520, 34535, 34466, 34477, 34526, 14518, 14356, 14619, 14601, 14858, 14785, 14085, - 14197, 14123, 33011, 32848, 33078, 7604, 7725, 7615, 18244, 18562, 18764, 18764, 18562, - 18641, 22426, 22537, 22452, 23017, 22848, 22960, 23017, 23152, 23224, 22538, 22707, 22418, - 23145, 23459, 23371, 34637, 34393, 34480, 9884, 9899, 9900, 15456, 15332, 15472, 14785, - 14858, 14907, 15456, 15564, 15653, 29289, 29209, 29203, 29341, 29209, 29289, 29092, 28939, - 28574, 9727, 9738, 9787, 9787, 9738, 9768, 9624, 9699, 9700, 9606, 9699, 9624, - 12894, 13176, 13026, 12084, 12072, 12209, 28889, 28782, 28670, 29196, 28782, 28889, 32246, - 32013, 32342, 32762, 32637, 32676, 32676, 32637, 32504, 31371, 31364, 31498, 32476, 32489, - 32458, 21141, 21383, 21193, 7949, 7702, 8152, 7800, 7901, 7977, 34249, 34244, 34148, - 33951, 33774, 34059, 34173, 34123, 34397, 7704, 8258, 8082, 7619, 7604, 7615, 19293, - 19133, 19190, 22299, 22313, 22332, 22328, 22313, 22299, 27001, 26972, 26874, 34496, 34637, - 34480, 34466, 34457, 34477, 8015, 7951, 8339, 7629, 8082, 8044, 7863, 7951, 7765, - 24398, 24285, 24246, 24398, 24246, 24512, 15769, 15914, 16000, 33484, 33706, 33357, 33426, - 33468, 33377, 33009, 32727, 32755, 17535, 17445, 17102, 16673, 17102, 16654, 23282, 23459, - 23145, 24887, 25030, 24904, 7860, 8044, 7987, 34578, 34190, 34451, 34607, 34451, 34559, - 12084, 12001, 12072, 12072, 12001, 12054, 10914, 10686, 10792, 10181, 10839, 10753, 9884, - 9823, 9899, 12084, 11925, 11872, 11365, 11977, 11749, 34730, 34638, 34515, 24904, 25030, - 24971, 24685, 24597, 24604, 9214, 9090, 9219, 9310, 9718, 9306, 9899, 9838, 10016, - 9823, 9838, 9899, 13866, 13659, 13524, 13977, 14015, 14111, 27501, 27621, 27457, 28059, - 28085, 28142, 29238, 29092, 28574, 25030, 25250, 25079, 26728, 26851, 26739, 34612, 34637, - 34496, 34477, 34457, 34550, 34457, 34394, 34550, 21383, 21630, 21465, 28216, 28085, 28059, - 33191, 33009, 33196, 32468, 32476, 32458, 32566, 32476, 32585, 32340, 32361, 32304, 24848, - 24863, 24887, 30984, 30898, 30888, 30984, 30888, 30991, 30984, 30991, 31044, 12794, 12666, - 12592, 13343, 13464, 13485, 12717, 13053, 12779, 13372, 13462, 13323, 8324, 8405, 8531, - 8324, 8593, 8386, 10618, 10597, 10848, 10534, 10597, 10618, 10534, 10662, 10427, 10534, - 10427, 10356, 31124, 31157, 31222, 29353, 29491, 29543, 29554, 29491, 29353, 29554, 29353, - 29273, 29554, 29273, 29158, 21630, 21718, 21596, 34638, 34596, 34512, 7740, 7717, 7907, - 7800, 7730, 7901, 7670, 7717, 7740, 10369, 10388, 10318, 10369, 10427, 10388, 23152, - 23348, 23417, 22537, 22559, 22452, 26739, 26851, 26874, 27603, 27784, 27621, 26739, 26392, - 26566, 15075, 15240, 15052, 14785, 14907, 14931, 13685, 13485, 13627, 22313, 22538, 22418, - 22925, 23282, 23145, 22618, 22538, 22328, 27210, 27049, 27564, 25366, 25260, 25405, 27790, - 27905, 28079, 26939, 27001, 26874, 34550, 34394, 34541, 34612, 34496, 34490, 13372, 13323, - 13109, 27784, 27830, 27653, 27784, 27653, 27621, 34360, 34123, 34294, 14950, 14996, 15032, - 15154, 15480, 15213, 16034, 16058, 16018, 15025, 14996, 14954, 14621, 14950, 14706, 14469, - 14505, 14345, 14469, 14345, 14409, 23417, 23348, 23521, 25405, 25846, 25512, 27011, 26628, - 26798, 14085, 14123, 14015, 27001, 27200, 26972, 32906, 32926, 32883, 33112, 33011, 33078, - 33112, 33078, 33082, 33132, 32755, 32583, 21718, 21826, 21596, 31157, 31364, 31371, 31222, - 31157, 31371, 33951, 34059, 34207, 33230, 33112, 33082, 15810, 16076, 15838, 15456, 15449, - 15332, 9915, 9988, 9855, 9512, 9442, 9605, 9855, 9988, 9830, 9373, 9435, 9512, - 9373, 9487, 9290, 10318, 10388, 10293, 13685, 13737, 14356, 13010, 13372, 13109, 31553, - 32506, 31498, 34612, 34490, 34526, 34541, 34394, 34398, 12792, 12666, 12794, 13166, 13026, - 13176, 16034, 16407, 16058, 15567, 15693, 15562, 28782, 28605, 28484, 28683, 28605, 28782, - 34207, 34041, 34119, 34210, 34119, 34244, 8524, 8602, 8407, 33598, 33706, 33484, 33535, - 33426, 33237, 22559, 22469, 22452, 23348, 23584, 23521, 34422, 34360, 34294, 34486, 34360, - 34422, 8243, 8205, 8387, 8243, 8387, 8298, 24685, 24848, 24904, 25323, 25325, 25250, - 24848, 24685, 24863, 25250, 25325, 25416, 25483, 25325, 25323, 7951, 7889, 8034, 7863, - 7889, 7951, 17124, 17535, 17102, 34318, 34210, 34244, 34207, 34210, 34318, 9180, 9090, - 9214, 9016, 9090, 9155, 9572, 9644, 9738, 9176, 9207, 8741, 13954, 14085, 14015, - 13841, 13977, 13833, 10201, 10173, 10107, 22720, 22746, 22559, 19404, 19593, 19293, 19293, - 19593, 19133, 34693, 34563, 34536, 9690, 9727, 9787, 9690, 9787, 9838, 12792, 12794, - 12894, 9855, 9830, 9716, 10107, 10173, 10111, 29209, 29196, 29003, 29196, 29341, 29310, - 34111, 34012, 33920, 34074, 33920, 33952, 7610, 7741, 7732, 15643, 15568, 15653, 10107, - 10111, 10034, 31416, 32214, 32272, 22720, 22848, 22746, 21826, 22126, 21978, 28300, 27790, - 28079, 27830, 28216, 28059, 29166, 29092, 29238, 27603, 27621, 27501, 34360, 34367, 34123, - 34486, 34367, 34360, 34372, 34362, 33957, 32534, 32340, 32166, 32476, 32566, 32583, 32495, - 32340, 32534, 9716, 9809, 9699, 9293, 9373, 9290, 14601, 14360, 14518, 15052, 15240, - 15332, 27001, 27071, 27200, 27577, 27603, 27501, 26851, 26939, 26874, 26857, 26939, 26851, - 26392, 25783, 26421, 7836, 7860, 7987, 8015, 8350, 8245, 10591, 10753, 10792, 10034, - 10111, 9967, 9606, 9605, 9442, 10111, 10004, 9967, 12095, 12421, 12141, 12958, 13010, - 13109, 12095, 12141, 11977, 14469, 14594, 14640, 15020, 15480, 15154, 14425, 14594, 14469, - 27210, 27125, 27049, 27011, 27030, 26628, 27107, 27071, 27001, 32449, 32214, 32257, 33202, - 32926, 32906, 33354, 33103, 33258, 33598, 33484, 33468, 34210, 34207, 34119, 34298, 34249, - 34464, 34612, 34526, 34834, 34362, 34541, 34398, 7596, 7604, 7619, 7596, 7619, 7618, - 7596, 7618, 7586, 34526, 34477, 34834, 34603, 34710, 34620, 34620, 34730, 34515, 34868, - 34693, 34596, 34596, 34693, 34536, 34623, 34688, 34603, 34835, 34501, 34514, 34435, 34322, - 34768, 33910, 33691, 33610, 7600, 7507, 7846, 7186, 7507, 7600, 7239, 7507, 7042, - 7600, 7601, 7186, 7601, 7568, 7106, 12895, 12792, 12894, 12593, 12470, 12592, 12895, - 12894, 13026, 21021, 21019, 21141, 21141, 21137, 21383, 21665, 21755, 21630, 21630, 21755, - 21718, 21718, 21755, 21826, 21826, 21868, 22126, 20931, 20929, 21021, 20913, 20929, 20931, - 18718, 19218, 18887, 34007, 34074, 33952, 25731, 25783, 25416, 33416, 33369, 33258, 33456, - 33369, 33416, 14564, 14360, 14601, 13343, 13166, 13176, 14283, 14345, 14274, 14283, 14274, - 14225, 20929, 21019, 21021, 8205, 8103, 8245, 8149, 8243, 8298, 25512, 25565, 25479, - 25405, 26013, 25846, 33850, 33910, 33610, 21019, 21137, 21141, 34765, 34710, 34603, 18084, - 18096, 18120, 18760, 18659, 18887, 18088, 18096, 18084, 23868, 23890, 24101, 22746, 22848, - 22977, 23890, 24285, 24101, 30435, 29506, 30222, 34367, 34397, 34123, 34542, 34397, 34367, - 7604, 7369, 7725, 7586, 7618, 7474, 9967, 10004, 9953, 10673, 10914, 11094, 11741, - 11619, 12001, 34563, 34607, 34559, 34712, 34607, 34563, 34587, 34477, 34550, 34637, 34725, - 34393, 34710, 34730, 34620, 33202, 32906, 33011, 32481, 32433, 32527, 10686, 10591, 10792, - 18096, 18573, 18505, 31207, 30984, 31124, 31097, 30993, 30984, 30984, 30993, 30898, 30898, - 30712, 30676, 31207, 31124, 31222, 31207, 31222, 31371, 8500, 8593, 8562, 28398, 28287, - 28590, 30222, 29506, 29543, 10912, 11749, 11529, 10534, 10543, 10597, 10435, 10543, 10534, - 10356, 10427, 10369, 10356, 10369, 10269, 10369, 10318, 10269, 10318, 10201, 10269, 7836, - 7987, 7889, 7836, 7889, 7765, 8602, 8500, 8562, 8524, 8500, 8602, 13055, 13166, - 13343, 15025, 15154, 14996, 24101, 24285, 24229, 32481, 32527, 32637, 33442, 33598, 33468, - 33706, 33850, 33610, 33535, 33598, 33442, 34464, 34197, 34310, 7466, 7586, 7474, 7596, - 7466, 7604, 27784, 27828, 27830, 27577, 27501, 27374, 34607, 34578, 34451, 34762, 34578, - 34607, 9685, 9738, 9727, 9567, 9572, 9738, 9442, 9512, 9435, 9953, 10004, 9915, - 12593, 12592, 12666, 13062, 12895, 13026, 9306, 9718, 9644, 8717, 9132, 9034, 9378, - 9442, 9435, 9261, 9293, 9290, 10269, 10201, 10057, 9873, 9915, 9855, 12593, 12666, - 12792, 32585, 32476, 32468, 33009, 33289, 32867, 18642, 18659, 18573, 17899, 18088, 18084, - 17899, 17972, 17535, 22848, 23017, 22977, 23882, 23521, 23584, 34397, 34410, 34310, 34542, - 34410, 34397, 7537, 7670, 7740, 7717, 7677, 7800, 7537, 7740, 7613, 25204, 25021, - 25260, 8149, 8103, 8205, 8149, 8205, 8243, 10201, 10107, 10079, 15088, 15052, 15332, - 15769, 15643, 15653, 15810, 15643, 15769, 23017, 23135, 22977, 9823, 9690, 9838, 9796, - 9690, 9823, 9658, 9716, 9699, 12791, 12593, 12792, 17160, 18217, 18421, 13755, 13841, - 13833, 13755, 13833, 13524, 27767, 27828, 27784, 15896, 16034, 16018, 16551, 16673, 16654, - 25366, 25315, 25260, 25366, 25512, 25479, 25325, 25483, 25416, 25323, 25250, 25030, 10079, - 10107, 10034, 14594, 14621, 14706, 14404, 14621, 14594, 14425, 14469, 14409, 26939, 27107, - 27001, 27374, 27274, 27200, 27603, 27767, 27784, 26728, 26857, 26851, 26729, 26857, 26728, - 26729, 26728, 26566, 33029, 32949, 32926, 33304, 33230, 33096, 33191, 33289, 33009, 15449, - 15456, 15568, 14785, 14564, 14601, 14954, 14996, 14950, 15480, 15567, 15562, 27125, 27211, - 27011, 27564, 27049, 27461, 33369, 33354, 33258, 33489, 33354, 33369, 7474, 7618, 7704, - 7765, 7889, 7863, 34298, 34318, 34244, 34207, 34787, 33951, 33592, 33456, 33416, 34403, - 34318, 34298, 21972, 22139, 22053, 20033, 19939, 20450, 17179, 18421, 17464, 16790, 16837, - 16877, 21972, 22053, 22014, 21665, 21630, 21383, 22328, 22538, 22313, 22538, 22618, 22707, - 32473, 32449, 32257, 32762, 32481, 32637, 32949, 32747, 32926, 9572, 9495, 9644, 9483, - 9495, 9572, 12895, 12791, 12792, 13166, 13062, 13026, 12942, 13062, 13055, 9215, 9261, - 9124, 8741, 9207, 8901, 8806, 8408, 8901, 14225, 14274, 14085, 18074, 17899, 17991, - 18635, 18573, 18455, 26262, 26421, 25783, 32674, 33646, 33714, 15838, 15965, 15800, 15508, - 15449, 15568, 21755, 21868, 21826, 32566, 32712, 32583, 32737, 32712, 32566, 34868, 34596, - 34638, 9690, 9685, 9727, 10103, 10507, 10181, 9674, 9685, 9690, 12421, 12717, 12779, - 12663, 12717, 12640, 8500, 8386, 8593, 8137, 8149, 8298, 9016, 9034, 9090, 9155, - 9090, 9180, 9155, 9225, 9127, 15508, 15568, 15643, 27374, 27200, 27272, 33198, 33011, - 33112, 33577, 33592, 33775, 7521, 7732, 7368, 22178, 22299, 22126, 24863, 24685, 24604, - 24981, 25323, 25030, 24526, 24285, 24398, 25479, 25315, 25366, 25232, 25342, 25235, 24887, - 24904, 24848, 26505, 26642, 26421, 17010, 16837, 16536, 17160, 18421, 17179, 22014, 22053, - 22064, 34163, 34372, 33697, 34074, 34111, 33920, 34180, 34111, 34074, 34036, 34074, 34007, - 34036, 34007, 34154, 34924, 34725, 34637, 34834, 34637, 34612, 7670, 7677, 7717, 8806, - 8691, 8408, 7559, 7677, 7492, 34795, 34486, 34422, 34530, 34464, 34310, 34795, 34277, - 34874, 23868, 23882, 23584, 23017, 23224, 23135, 24926, 24512, 25021, 9127, 9225, 9310, - 15394, 15567, 15480, 27577, 27767, 27603, 28216, 28287, 28085, 32949, 32841, 32676, 10012, - 10079, 10034, 10012, 10034, 9967, 12015, 11897, 12001, 12015, 12001, 12084, 12015, 12084, - 11868, 33925, 33850, 33706, 33716, 33706, 33598, 9658, 9729, 9716, 9716, 9772, 9855, - 9378, 9435, 9373, 9378, 9373, 9243, 34693, 34675, 34563, 9729, 9772, 9716, 29341, - 29196, 29209, 27892, 27564, 27790, 27790, 27564, 27461, 29307, 29535, 29521, 29092, 29166, - 29158, 28216, 27830, 27828, 28289, 28216, 28105, 31095, 30712, 30898, 31097, 30898, 30993, - 10591, 10555, 10753, 10686, 10583, 10591, 10602, 10673, 11094, 34541, 34587, 34550, 34580, - 34587, 34541, 34580, 34541, 34749, 9495, 9306, 9644, 9685, 9567, 9738, 9497, 9567, - 9685, 12942, 12791, 12895, 12942, 12895, 13062, 13685, 14356, 14360, 8691, 8426, 8130, - 9243, 9373, 9293, 14626, 14564, 14785, 14931, 14907, 15052, 33230, 33217, 33112, 32949, - 32954, 32841, 33304, 33217, 33230, 33304, 33096, 33354, 33489, 33369, 33456, 7730, 7949, - 7901, 10583, 10555, 10591, 10543, 10577, 10597, 10435, 10577, 10543, 10435, 10534, 10356, - 10435, 10356, 10248, 15088, 14931, 15052, 15025, 15020, 15154, 14621, 14954, 14950, 14948, - 14954, 14630, 21868, 22094, 22126, 27272, 27200, 27071, 27577, 27582, 27767, 26642, 26729, - 26566, 26642, 26566, 26421, 34675, 34712, 34563, 10248, 10356, 10269, 9953, 10012, 9967, - 11897, 11741, 12001, 11718, 12015, 11868, 13954, 14225, 14085, 14283, 14425, 14409, 13524, - 13659, 13372, 32876, 32762, 32841, 32841, 32762, 32676, 14225, 14425, 14283, 10248, 10269, - 10057, 33559, 33489, 33456, 25315, 25204, 25260, 25232, 25204, 25315, 34154, 34007, 33910, - 34318, 34403, 34207, 33592, 33577, 33456, 34530, 34310, 34410, 7610, 7537, 7613, 7459, - 7537, 7610, 18573, 18659, 18760, 18074, 18096, 18088, 23224, 23417, 23135, 22452, 22209, - 22064, 24991, 24926, 25021, 24981, 24887, 24863, 34587, 34677, 34477, 34677, 34580, 34749, - 9873, 9953, 9915, 9658, 9699, 9606, 34768, 34322, 34608, 34688, 34765, 34603, 34710, - 34776, 34730, 34730, 34776, 34638, 34693, 34797, 34675, 34675, 34934, 34712, 7586, 7466, - 7596, 7474, 7417, 7376, 22205, 22209, 22383, 22094, 22178, 22126, 8103, 8100, 8245, - 8137, 8298, 8324, 10912, 10848, 10597, 13783, 14015, 13841, 16034, 16200, 16407, 15989, - 16200, 16034, 31247, 31207, 31328, 30984, 31207, 31247, 32449, 32473, 32494, 33714, 33646, - 33951, 33289, 33535, 33237, 34269, 34180, 34412, 33696, 33535, 33653, 34919, 34765, 34688, - 10181, 10507, 10611, 9884, 9796, 9823, 10057, 10201, 10079, 9873, 9855, 9772, 29166, - 29554, 29158, 29468, 29554, 29166, 9290, 9124, 9261, 9584, 9658, 9606, 32340, 32495, - 32361, 33196, 33009, 32755, 32246, 32166, 32079, 9567, 9483, 9572, 9497, 9483, 9567, - 34486, 34542, 34367, 34570, 34542, 34486, 34813, 34768, 34608, 34813, 34535, 34725, 9290, - 9114, 9124, 13755, 13783, 13841, 13416, 13524, 13372, 15567, 15896, 15888, 15989, 15896, - 15915, 33029, 32954, 32949, 21137, 21171, 21383, 21755, 21773, 21868, 21868, 21894, 22094, - 22212, 22264, 22178, 21019, 21171, 21137, 21022, 21171, 21019, 20932, 21019, 20929, 34872, - 34776, 34710, 8524, 8386, 8500, 8407, 8386, 8524, 8717, 9034, 9016, 15093, 15088, - 15332, 15646, 15508, 15643, 15646, 15643, 15810, 33796, 33714, 33886, 33696, 33716, 33598, - 20935, 20033, 20450, 17179, 17232, 17165, 21472, 21146, 21972, 21171, 21300, 21383, 10555, - 10181, 10753, 9775, 9873, 9772, 9584, 9606, 9534, 24101, 23882, 23868, 24041, 23882, - 24101, 9775, 9772, 9751, 10057, 10079, 9746, 29521, 29535, 29998, 29083, 28683, 28782, - 22264, 22328, 22178, 22178, 22328, 22299, 24597, 24066, 24604, 9155, 8973, 9016, 9184, - 9127, 9310, 13613, 13783, 13755, 8149, 8100, 8103, 8009, 8100, 7864, 16385, 16673, - 16551, 17899, 18074, 18088, 16385, 16551, 16200, 24887, 24981, 25030, 26760, 26642, 26684, - 24066, 23459, 23650, 24964, 24844, 24926, 24926, 24844, 24512, 26013, 26286, 25846, 34036, - 34180, 34074, 34111, 34203, 34163, 33960, 33910, 33850, 17569, 17899, 17535, 15702, 15646, - 15810, 8973, 8717, 9016, 13636, 13685, 14360, 14931, 14626, 14785, 14772, 14626, 14931, - 15332, 15449, 15093, 23135, 23417, 23451, 22642, 22469, 22559, 33217, 33198, 33112, 33510, - 33304, 33354, 33534, 33354, 33489, 33559, 33456, 33577, 9483, 9429, 9495, 9301, 9291, - 9286, 12962, 13010, 12958, 13990, 13954, 13817, 12663, 12958, 12717, 28289, 28590, 28287, - 28289, 28287, 28216, 32494, 32473, 32576, 32722, 32481, 32762, 33386, 33198, 33217, 33196, - 32755, 33132, 33535, 33696, 33598, 9429, 9306, 9495, 25846, 26286, 26527, 28105, 28216, - 27828, 28105, 27828, 27767, 32495, 32585, 32468, 32746, 32585, 32806, 33925, 33960, 33850, - 35033, 34813, 34725, 14892, 15088, 15093, 26421, 26477, 26505, 26992, 26939, 26857, 7629, - 8044, 7860, 7629, 7860, 7594, 9863, 9796, 9884, 9863, 9884, 9900, 29390, 29310, - 29341, 29383, 29310, 29390, 11718, 11741, 11897, 11718, 11897, 12015, 26992, 26857, 26729, - 12640, 12717, 12408, 21444, 21665, 21383, 7527, 7730, 7800, 7559, 7800, 7677, 33715, - 33559, 33577, 34464, 34403, 34298, 33715, 33534, 33559, 34635, 34403, 34464, 15093, 15449, - 15508, 15838, 16076, 15965, 28300, 28339, 28683, 26846, 26286, 26628, 27374, 27582, 27577, - 33017, 32876, 32841, 33202, 33029, 32926, 7668, 7860, 7836, 21665, 21773, 21755, 7368, - 7806, 7227, 7492, 7677, 7670, 22642, 22559, 22746, 22014, 21928, 21972, 10555, 10301, - 10181, 9714, 9674, 9796, 10673, 10583, 10686, 10602, 10583, 10673, 33716, 33925, 33706, - 33653, 33535, 33869, 31168, 31097, 30984, 29481, 29521, 29602, 31095, 31097, 31168, 21773, - 21894, 21868, 8100, 8015, 8245, 8009, 8015, 8100, 14212, 14404, 14425, 14584, 14954, - 14621, 13783, 13954, 14015, 13509, 13755, 13524, 25218, 25021, 25204, 25218, 25204, 25232, - 25416, 25483, 25731, 23282, 22925, 23169, 34269, 34203, 34111, 34269, 34111, 34180, 13348, - 13416, 13372, 13348, 13372, 13136, 22711, 22642, 22746, 22014, 22064, 22209, 22912, 22746, - 22977, 23417, 23521, 23451, 7426, 7369, 7604, 7227, 7806, 7140, 7426, 7604, 7466, - 22014, 22209, 22205, 23693, 23521, 23882, 34557, 34372, 34163, 34712, 34754, 34607, 34581, - 34530, 34410, 34868, 34797, 34693, 7959, 8488, 8152, 15896, 15989, 16034, 15915, 15896, - 15567, 14948, 15025, 14954, 34570, 34410, 34542, 9746, 10012, 9638, 10435, 10057, 10577, - 10577, 10912, 10597, 17075, 17160, 17179, 16837, 16790, 16247, 17082, 17124, 17102, 17082, - 17102, 16974, 24618, 24526, 24512, 26760, 26992, 26729, 27374, 27431, 27582, 26760, 26729, - 26642, 26992, 27107, 26939, 14499, 14360, 14564, 12791, 12586, 12593, 22209, 22452, 22383, - 33017, 32841, 32954, 9796, 9674, 9690, 9210, 9310, 9306, 9863, 9900, 9858, 15088, - 14892, 14931, 14626, 14499, 14564, 15560, 15508, 15646, 15020, 14948, 14982, 25483, 25586, - 25695, 7521, 7459, 7610, 7409, 7459, 7521, 18659, 18718, 18887, 18642, 18718, 18659, - 18642, 18635, 18640, 27221, 27272, 27071, 28093, 28105, 27767, 34580, 34677, 34587, 34749, - 34541, 34746, 9764, 9863, 9802, 11852, 12095, 11977, 12663, 12962, 12958, 11852, 11977, - 11441, 29535, 30072, 30180, 29329, 28782, 29196, 15838, 15702, 15810, 15800, 15702, 15838, - 27211, 27125, 27210, 25235, 25218, 25232, 25483, 25323, 25586, 33775, 33592, 33714, 33559, - 33534, 33489, 33202, 33011, 33198, 33261, 33017, 33029, 33029, 33017, 32954, 7492, 7670, - 7537, 23169, 22925, 23106, 22606, 22618, 22328, 7330, 7426, 7466, 7376, 7466, 7474, - 27400, 27431, 27374, 7864, 8100, 8149, 7632, 7765, 7951, 8137, 8324, 8189, 7642, - 7959, 8152, 7702, 7949, 7730, 13055, 13062, 13166, 12714, 12962, 12663, 25232, 25315, - 25342, 24844, 24618, 24512, 7668, 7765, 7632, 7417, 7474, 7704, 16995, 16837, 17010, - 24991, 24964, 24926, 34203, 34437, 34163, 34317, 34180, 34036, 34154, 33910, 33960, 8717, - 8407, 8602, 8362, 8407, 8260, 33995, 33925, 33716, 33869, 33535, 33289, 9210, 9184, - 9310, 9048, 8973, 9155, 9106, 9184, 9071, 9534, 9606, 9449, 9658, 9671, 9729, - 9873, 9775, 9953, 9261, 9243, 9293, 9124, 9114, 8962, 9114, 8991, 8962, 8716, - 8787, 8962, 18642, 18573, 18635, 20042, 20230, 19974, 32746, 32737, 32566, 33651, 33869, - 33289, 32746, 32566, 32585, 9048, 9155, 9127, 33202, 33198, 33337, 20230, 19218, 19974, - 21241, 21444, 21300, 21300, 21444, 21383, 21665, 21696, 21773, 21773, 21963, 21894, 22383, - 22403, 22316, 22383, 22452, 22469, 34934, 34754, 34712, 9606, 9442, 9449, 9751, 9772, - 9729, 12408, 12717, 12421, 29521, 29383, 29390, 29481, 29383, 29521, 32331, 32272, 32214, - 32331, 32214, 32449, 32473, 32481, 32576, 32320, 32246, 32342, 34765, 34872, 34710, 34776, - 34868, 34638, 34797, 34934, 34675, 34835, 34919, 34688, 35016, 34919, 34835, 35016, 34835, - 34953, 17160, 17075, 17010, 16995, 17075, 17053, 17124, 17275, 17535, 16974, 17102, 16804, - 24526, 24229, 24285, 24742, 24618, 24844, 24643, 24604, 24066, 25316, 25323, 24981, 8286, - 8324, 8386, 16901, 16804, 16673, 15378, 15915, 15567, 24835, 24981, 24863, 7559, 7527, - 7800, 7503, 7527, 7559, 8407, 8286, 8386, 33714, 33951, 33886, 33775, 33796, 33914, - 34985, 34872, 34765, 22212, 22178, 22094, 21963, 22094, 21894, 34904, 34762, 34754, 34754, - 34762, 34607, 9106, 9048, 9127, 22951, 22912, 22977, 22951, 22977, 23135, 34746, 34541, - 34362, 34677, 34834, 34477, 34953, 34835, 34768, 11120, 11239, 11619, 11868, 11872, 11810, - 13003, 13055, 13343, 11770, 11868, 11810, 32576, 32481, 32722, 24547, 24229, 24526, 9203, - 9243, 9261, 9301, 9306, 9429, 9724, 9714, 9796, 9764, 9796, 9863, 9746, 10079, - 10012, 9671, 9751, 9729, 9671, 9658, 9578, 13817, 13954, 13783, 14404, 14594, 14425, - 13136, 13372, 13010, 13136, 13010, 12946, 28683, 28339, 28605, 14672, 14499, 14626, 12867, - 12817, 13055, 14772, 14931, 14892, 25147, 24991, 25021, 24865, 24742, 24844, 24618, 24547, - 24526, 25342, 25315, 25382, 27462, 27211, 27210, 27462, 27210, 27564, 27272, 27400, 27374, - 27107, 27221, 27071, 27294, 27221, 27107, 27294, 27107, 27068, 26723, 26992, 26760, 26684, - 26642, 26505, 9449, 9442, 9308, 10583, 10443, 10555, 11120, 11619, 11741, 12640, 12714, - 12663, 12502, 12714, 12640, 22711, 22469, 22642, 25147, 25021, 25218, 31168, 30984, 31247, - 32542, 32331, 32449, 34843, 34834, 34677, 31097, 31095, 30898, 31371, 31328, 31207, 14964, - 15093, 15508, 14948, 15020, 15025, 13990, 14225, 13954, 26504, 26684, 26505, 34842, 34570, - 34486, 34530, 34635, 34464, 21241, 21300, 21171, 27410, 27400, 27272, 27431, 27605, 27582, - 28847, 29238, 28590, 33510, 33354, 33534, 33337, 33198, 33386, 32722, 32762, 33059, 9429, - 9483, 9370, 9184, 9106, 9127, 8991, 8374, 8535, 9215, 9203, 9261, 7382, 7492, - 7537, 7382, 7537, 7459, 10394, 10443, 10583, 23178, 22951, 23135, 22912, 22711, 22746, - 31247, 31328, 31224, 34749, 34843, 34677, 34680, 34746, 34362, 34680, 34362, 34888, 11711, - 11120, 11741, 12084, 11872, 11868, 11382, 11977, 11365, 12295, 12408, 12421, 17075, 16995, - 17010, 15965, 16076, 16247, 15702, 15560, 15646, 16877, 16995, 17053, 17157, 17275, 17124, - 16804, 17102, 16673, 24865, 24844, 24964, 24604, 24754, 24863, 24643, 24754, 24604, 8200, - 8408, 8691, 8200, 8691, 8130, 21444, 21555, 21665, 33775, 33715, 33577, 11711, 11741, - 11718, 31371, 31551, 31328, 7450, 7704, 7629, 7239, 7846, 7507, 9751, 9679, 9775, - 9578, 9658, 9584, 12295, 12421, 12095, 28590, 29238, 28574, 30222, 29543, 29491, 32320, - 32319, 32246, 28668, 28590, 28289, 15965, 16247, 16591, 25695, 25731, 25483, 25658, 25731, - 25695, 33995, 33716, 33696, 35041, 34868, 34776, 9569, 9685, 9674, 13474, 13524, 13416, - 12946, 13010, 12962, 12837, 12962, 12714, 17157, 17124, 17082, 32494, 32624, 32449, 32722, - 33037, 32693, 15179, 15394, 15480, 16077, 16200, 15989, 25731, 26262, 25783, 33796, 33775, - 33714, 33886, 34040, 33998, 7668, 7594, 7860, 7668, 7836, 7765, 12502, 12837, 12714, - 34570, 34581, 34410, 34716, 34581, 34570, 34862, 34843, 34749, 34649, 34362, 34372, 13474, - 13416, 13348, 9216, 9210, 9306, 9308, 9442, 9378, 9547, 9578, 9584, 9102, 9203, - 9215, 9102, 9215, 9124, 13357, 13474, 13348, 21928, 21753, 21972, 21869, 21753, 21928, - 21869, 21928, 21968, 21928, 22014, 21968, 33132, 32583, 32712, 32806, 32585, 32495, 7341, - 7417, 7169, 25280, 25147, 25218, 24991, 25071, 24964, 25078, 25147, 25280, 25315, 25479, - 25382, 25565, 25512, 25846, 25007, 25316, 24981, 34267, 34154, 34282, 34269, 34350, 34203, - 7369, 7327, 7744, 7263, 7327, 7369, 7330, 7369, 7426, 7330, 7466, 7335, 22014, - 22205, 22113, 21968, 22014, 22113, 9650, 9569, 9674, 9650, 9674, 9714, 9671, 9679, - 9751, 9547, 9584, 9534, 16995, 16877, 16837, 17179, 17009, 17053, 17039, 17157, 17082, - 16974, 16804, 16901, 34412, 34350, 34269, 15732, 15560, 15702, 15732, 15702, 15800, 34040, - 33951, 34107, 9932, 9900, 10181, 29403, 29196, 29310, 30229, 30072, 30361, 29238, 29468, - 29166, 8137, 8047, 8149, 7632, 7951, 7616, 7974, 8047, 8137, 16591, 16247, 16790, - 25497, 25565, 25631, 25731, 25994, 26262, 25316, 25586, 25323, 28014, 27892, 27790, 28014, - 27790, 28300, 7368, 7409, 7521, 7354, 7409, 7368, 7951, 8015, 7616, 23282, 23650, - 23459, 23106, 22925, 22618, 22347, 22328, 22264, 33694, 33534, 33715, 33694, 33510, 33534, - 33202, 33290, 33029, 33858, 33715, 33775, 22113, 22205, 22302, 21696, 21963, 21773, 34868, - 34911, 34797, 34762, 34865, 34578, 14212, 14425, 14225, 15020, 15179, 15480, 23926, 23693, - 23882, 22712, 22711, 22816, 24296, 24101, 24229, 24547, 24618, 24627, 23169, 23650, 23282, - 24754, 24835, 24863, 26684, 26723, 26760, 27221, 27410, 27272, 26504, 26723, 26684, 26477, - 26421, 26262, 33386, 33217, 33304, 17053, 17009, 16762, 17039, 17082, 16974, 18573, 18096, - 18455, 24627, 24618, 24742, 13136, 13238, 13348, 12837, 12946, 12962, 12955, 12946, 12837, - 13268, 13238, 13112, 13474, 13509, 13524, 13990, 14024, 14225, 29403, 29310, 29383, 32417, - 32534, 32166, 32417, 32166, 32246, 32576, 32624, 32494, 33049, 32876, 33017, 27211, 27030, - 27011, 27600, 27462, 27564, 32889, 32712, 32737, 34317, 34267, 34282, 32889, 32737, 32746, - 21963, 21990, 22094, 34911, 34934, 34797, 34834, 34924, 34637, 35033, 34924, 35265, 15830, - 15732, 15800, 9764, 9724, 9796, 9642, 9724, 9764, 22711, 22912, 22816, 11770, 11711, - 11718, 11770, 11718, 11868, 9490, 9497, 9569, 9569, 9497, 9685, 9286, 9216, 9306, - 13357, 13509, 13474, 32013, 31017, 31717, 32908, 32889, 32746, 7273, 7702, 7730, 7492, - 7503, 7559, 7430, 7503, 7492, 8286, 8189, 8324, 8407, 8362, 8286, 8260, 8407, - 8717, 8802, 8717, 8973, 8885, 8973, 9048, 9068, 9048, 9106, 13776, 14024, 13990, - 32889, 33132, 32712, 7335, 7466, 7376, 7335, 7376, 7341, 22302, 22205, 22383, 24422, - 24296, 24547, 25078, 25071, 25147, 25497, 25382, 25479, 25497, 25479, 25565, 34581, 34635, - 34530, 34716, 34635, 34581, 12817, 12791, 12942, 10443, 10301, 10555, 10602, 10477, 10583, - 10350, 10477, 10602, 11094, 10914, 11120, 11094, 11120, 10957, 10821, 10912, 10550, 10912, - 10577, 10550, 18642, 18640, 18718, 18096, 18309, 18455, 34862, 34749, 34746, 34862, 34746, - 34892, 8962, 8991, 8716, 9547, 9679, 9578, 9724, 9650, 9714, 9642, 9650, 9724, - 9578, 9679, 9671, 9378, 9193, 9308, 10477, 10394, 10583, 12408, 12442, 12640, 11964, - 12295, 12095, 11964, 12095, 11852, 13742, 13817, 13783, 17179, 17053, 17075, 15819, 15830, - 15965, 15965, 15830, 15800, 16877, 17053, 16762, 18455, 18309, 18426, 16901, 17039, 16974, - 16077, 15989, 15979, 21990, 22212, 22094, 24600, 24643, 24472, 25611, 25658, 25586, 25586, - 25658, 25695, 25763, 25658, 25639, 33886, 33914, 33796, 33998, 33914, 33886, 34350, 34437, - 34203, 34539, 34437, 34350, 34919, 34985, 34765, 35057, 35041, 34776, 34868, 34955, 34911, - 34911, 34943, 34934, 34953, 34768, 35162, 35016, 34942, 34919, 35087, 34768, 34813, 20805, - 20932, 20929, 21444, 21696, 21555, 21555, 21696, 21665, 21963, 21966, 21990, 21990, 22143, - 22212, 20955, 20932, 20805, 34942, 34985, 34919, 9071, 9068, 9106, 9286, 9306, 9301, - 9301, 9429, 9291, 11538, 11120, 11711, 13238, 13357, 13348, 13509, 13613, 13755, 13268, - 13357, 13238, 12955, 13136, 12946, 9102, 9243, 9203, 20932, 21022, 21019, 32319, 32417, - 32246, 32659, 32806, 32495, 32407, 32417, 32319, 30222, 29491, 29554, 22316, 22302, 22383, - 22223, 22246, 22212, 22212, 22246, 22264, 27369, 27030, 27211, 35030, 34904, 34754, 35030, - 34754, 34934, 7409, 7382, 7459, 7354, 7382, 7409, 19974, 19218, 19771, 17535, 17275, - 17569, 33337, 33323, 33202, 33510, 33386, 33304, 33345, 33386, 33463, 34892, 34746, 34680, - 35265, 34924, 34834, 7668, 7539, 7594, 7341, 7376, 7417, 7799, 8015, 8009, 7425, - 7730, 7527, 7959, 8007, 8426, 7429, 7527, 7503, 8274, 8189, 8286, 7840, 7799, - 8009, 9071, 9184, 9210, 8962, 9054, 9124, 13558, 13613, 13509, 24547, 24296, 24229, - 22403, 22469, 22711, 22403, 22383, 22469, 25071, 24991, 25147, 27821, 27600, 27564, 27462, - 27369, 27211, 27944, 28014, 27985, 34437, 34557, 34163, 27400, 27410, 27431, 30306, 30358, - 29468, 27294, 27410, 27221, 27107, 26992, 27068, 30513, 30222, 29554, 33345, 33323, 33337, - 7186, 7601, 7106, 7133, 7548, 7187, 19218, 19263, 19771, 21022, 21241, 21171, 12295, - 12442, 12408, 12284, 12442, 12295, 25218, 25235, 25280, 19218, 18718, 19093, 7263, 7210, - 7327, 7417, 7704, 7450, 7886, 8007, 7959, 8716, 8991, 8685, 15979, 15989, 15915, - 15378, 15567, 15394, 23451, 23521, 23693, 22246, 22347, 22264, 23169, 23104, 23650, 22223, - 22347, 22246, 25631, 25565, 25798, 25280, 25235, 25342, 34904, 34865, 34762, 34968, 34865, - 35075, 11441, 11964, 11852, 23700, 23451, 23693, 14993, 15179, 15020, 14584, 14621, 14404, - 14584, 14404, 14142, 14035, 14024, 13776, 26395, 26477, 26262, 24643, 24715, 24754, 24600, - 24715, 24643, 24835, 24715, 24752, 9071, 8974, 9068, 9370, 9483, 9497, 21530, 21783, - 21564, 21530, 21472, 21753, 21753, 21472, 21972, 17179, 17165, 17009, 21753, 21869, 21783, - 21869, 21968, 21918, 21968, 22113, 21918, 19093, 18718, 18982, 17569, 17275, 17343, 34874, - 34277, 34578, 9423, 9370, 9497, 13055, 12817, 12942, 12728, 12817, 12867, 9054, 9102, - 9124, 15732, 15728, 15560, 14964, 14892, 15093, 14964, 14772, 14892, 14499, 13636, 14360, - 16591, 16790, 16656, 21918, 22113, 22054, 25658, 25763, 25731, 25611, 25586, 25316, 8857, - 8885, 9048, 8362, 8274, 8286, 8974, 9048, 9068, 22164, 22113, 22302, 22321, 22436, - 22341, 8138, 8274, 8362, 15179, 15378, 15394, 17343, 17275, 17157, 17023, 17157, 17039, - 9449, 9547, 9534, 10012, 9953, 9638, 9453, 9547, 9449, 32659, 32495, 32534, 31717, - 31017, 30560, 21410, 21696, 21444, 35057, 34776, 34872, 32080, 31717, 31902, 35007, 34716, - 34570, 34040, 33886, 33951, 34795, 34842, 34486, 35018, 34842, 34795, 7450, 7629, 7594, - 7263, 7369, 7330, 7864, 8047, 7787, 7864, 8149, 8047, 13613, 13742, 13783, 13558, - 13742, 13613, 13558, 13509, 13357, 16656, 16790, 16877, 25280, 25342, 25382, 24909, 24865, - 24964, 34865, 34874, 34578, 34968, 34874, 34865, 8088, 8200, 8130, 7500, 7886, 7959, - 34154, 34267, 34036, 34731, 34372, 34557, 34282, 34154, 33960, 33960, 33925, 34282, 8088, - 8130, 8007, 8965, 9066, 9054, 9054, 9066, 9102, 33914, 33858, 33775, 34207, 34403, - 34787, 14212, 14225, 14024, 15179, 15281, 15378, 16385, 16901, 16673, 24909, 24964, 25071, - 24296, 24041, 24101, 24715, 24835, 24754, 24643, 24066, 24472, 9370, 9291, 9429, 9071, - 9210, 9216, 9264, 9291, 9275, 9193, 9378, 9243, 12826, 12955, 12837, 12395, 12640, - 12442, 14964, 15508, 15430, 32693, 32624, 32576, 32331, 32506, 32272, 32693, 32576, 32722, - 13045, 13238, 13136, 16077, 16385, 16200, 15873, 15979, 15784, 26395, 26504, 26477, 25539, - 25611, 25316, 32889, 32994, 33132, 32559, 32534, 32417, 7263, 7174, 7094, 9937, 9932, - 10181, 9650, 9490, 9569, 27732, 27767, 27582, 27068, 26992, 26723, 33323, 33290, 33202, - 33386, 33345, 33337, 33399, 33345, 33463, 35041, 34955, 34868, 34924, 35033, 34725, 35052, - 34834, 34843, 9603, 9642, 9764, 14786, 14964, 15430, 7632, 7539, 7668, 7489, 7539, - 7632, 24161, 24041, 24296, 23451, 23178, 23135, 12817, 12586, 12791, 11770, 11538, 11711, - 12728, 12586, 12817, 32320, 32407, 32319, 32559, 32407, 32320, 7209, 7354, 7368, 7285, - 7430, 7492, 14035, 14212, 14024, 22347, 22606, 22328, 22413, 22606, 22347, 31095, 30980, - 30712, 31140, 30980, 31095, 31224, 31095, 31168, 31224, 31168, 31247, 33399, 33290, 33323, - 7285, 7492, 7382, 23377, 23178, 23451, 13776, 13990, 13817, 13187, 13558, 13357, 22164, - 22302, 22300, 22302, 22316, 22300, 21696, 21966, 21963, 26477, 26504, 26505, 26395, 26262, - 26174, 27605, 27431, 27410, 30513, 30654, 30222, 8081, 8088, 7653, 15830, 15728, 15732, - 15819, 15728, 15830, 34024, 33858, 33914, 34652, 34403, 34635, 9932, 9858, 9900, 31328, - 31551, 31357, 13776, 13817, 13742, 27821, 27564, 27892, 27030, 26846, 26628, 27821, 27892, - 27944, 27613, 27605, 27410, 7263, 7330, 7174, 10394, 10301, 10443, 9932, 9883, 9858, - 10237, 10301, 10394, 10350, 10394, 10477, 21966, 22006, 21990, 32506, 31553, 32272, 34955, - 34943, 34911, 34024, 33914, 34057, 12174, 12284, 12295, 12174, 12295, 11964, 7267, 7450, - 7594, 7341, 7225, 7335, 7974, 8137, 8189, 7686, 7616, 8015, 13268, 13187, 13357, - 12955, 13045, 13136, 12944, 13045, 12955, 32624, 32542, 32449, 33059, 32762, 32876, 32813, - 32659, 32534, 24257, 24161, 24296, 25078, 24909, 25071, 25280, 24909, 25078, 27764, 27821, - 27944, 27944, 27892, 28014, 9740, 9802, 9858, 9858, 9802, 9863, 9642, 9490, 9650, - 24041, 23926, 23882, 24627, 24742, 24687, 12586, 12497, 12593, 13003, 13343, 13685, 22006, - 22143, 21990, 32593, 32542, 32708, 34943, 35030, 34934, 34874, 34920, 34795, 30361, 30072, - 30833, 29481, 29602, 29383, 25611, 25639, 25658, 25577, 25639, 25611, 7686, 8015, 7799, - 7539, 7070, 7594, 24687, 24742, 24865, 24752, 24600, 24644, 25526, 25539, 25316, 22300, - 22316, 22321, 22143, 22223, 22212, 7568, 7548, 7133, 7106, 7568, 7133, 7165, 7357, - 7354, 9426, 9490, 9436, 12284, 12395, 12442, 12219, 12395, 12284, 11257, 11382, 10895, - 10895, 11365, 10912, 14772, 14672, 14626, 14653, 14672, 14772, 14653, 14772, 14786, 14584, - 14630, 14954, 15378, 15784, 15915, 14466, 14630, 14584, 14142, 14404, 14212, 30229, 30180, - 30072, 8885, 8802, 8973, 9071, 9216, 9053, 9216, 9286, 9053, 14426, 13636, 14499, - 33210, 33049, 33017, 34985, 35057, 34872, 35041, 35053, 34955, 34955, 35118, 34943, 34943, - 35049, 35030, 34942, 35102, 34985, 35016, 35102, 34942, 35227, 35102, 35016, 35227, 35016, - 34953, 7548, 7327, 7187, 21022, 21089, 21241, 21241, 21410, 21444, 21696, 21953, 21966, - 21966, 21953, 22006, 22006, 21953, 22143, 22143, 22211, 22223, 20932, 20955, 21022, 20770, - 20955, 20805, 20750, 20805, 20314, 27369, 27462, 27509, 27298, 26846, 27030, 25576, 25280, - 25382, 29998, 29602, 29521, 33290, 33261, 33029, 33345, 33399, 33323, 33694, 33386, 33510, - 8088, 8081, 8200, 8200, 8136, 8408, 7561, 8088, 8007, 14982, 14993, 15020, 20955, - 21089, 21022, 35157, 35057, 34985, 22321, 22316, 22403, 7354, 7357, 7382, 7315, 7429, - 7503, 7702, 7642, 8152, 7806, 7965, 7140, 11382, 11441, 11977, 34990, 34920, 34874, - 34842, 34933, 34570, 13045, 13112, 13238, 13643, 13776, 13742, 14861, 14948, 14630, 12882, - 13112, 13045, 23899, 23926, 24041, 22712, 22403, 22711, 23899, 24041, 24205, 24422, 24257, - 24296, 32659, 32730, 32806, 32931, 32908, 32746, 33614, 33191, 33620, 33869, 33696, 33653, - 32901, 32730, 32659, 33479, 33261, 33290, 34716, 34652, 34635, 34845, 34652, 34716, 34731, - 34649, 34372, 34862, 34892, 34843, 34853, 34557, 34437, 7187, 7327, 7210, 7864, 7840, - 8009, 7821, 7840, 7864, 25576, 25382, 25497, 24909, 24687, 24865, 24627, 24422, 24547, - 34267, 34317, 34036, 33289, 33191, 33614, 16591, 16037, 15965, 16762, 16656, 16877, 18244, - 18421, 18562, 34317, 34412, 34180, 16108, 16037, 16147, 15728, 15430, 15560, 26676, 27068, - 26723, 27613, 27732, 27605, 25994, 25731, 25763, 33614, 33620, 33651, 9264, 9286, 9291, - 8965, 9054, 8962, 9102, 9193, 9243, 9386, 9453, 9449, 32818, 32746, 32806, 9490, - 9423, 9497, 9426, 9423, 9490, 9547, 9453, 9679, 9386, 9449, 9313, 12540, 12497, - 12586, 10739, 10350, 10602, 12540, 12586, 12728, 12395, 12502, 12640, 12417, 12502, 12395, - 7140, 6963, 7012, 8857, 9048, 8974, 8857, 8802, 8885, 8069, 7974, 8189, 11554, - 11538, 11770, 21472, 21149, 20450, 21422, 21403, 21472, 21422, 21472, 21530, 21422, 21530, - 21564, 21753, 21783, 21530, 22912, 23012, 22816, 21869, 21903, 21783, 27821, 27764, 27600, - 28014, 28300, 28276, 27605, 27732, 27582, 27613, 27410, 27556, 7324, 7503, 7430, 7653, - 8041, 8081, 24397, 24647, 24390, 24600, 24752, 24715, 24472, 24066, 23650, 23106, 22618, - 22606, 34483, 34539, 34350, 34996, 34892, 34972, 6974, 7187, 6961, 7190, 7210, 7263, - 8069, 8189, 8274, 15892, 15819, 15965, 21918, 21903, 21869, 8081, 8136, 8200, 21918, - 22054, 21903, 35033, 35087, 34813, 35301, 35087, 35422, 7227, 7231, 7368, 7357, 7285, - 7382, 6992, 7231, 7227, 34652, 34666, 34403, 34845, 34666, 34652, 35075, 34865, 34904, - 34983, 34933, 34842, 35075, 34904, 35030, 8852, 8857, 8974, 28276, 28300, 28635, 10057, - 10435, 10248, 11382, 11372, 11441, 30833, 30072, 30712, 30229, 30361, 30180, 31224, 31140, - 31095, 31357, 31140, 31224, 31357, 31224, 31328, 24397, 24422, 24627, 24205, 24041, 24161, - 9275, 9291, 9370, 8710, 8852, 8974, 12177, 11569, 12087, 13112, 13187, 13268, 12826, - 12944, 12955, 12826, 12837, 12614, 29602, 29403, 29383, 29608, 29403, 29602, 13017, 13187, - 13112, 18597, 18640, 18635, 20160, 20314, 20042, 33191, 33196, 33620, 32730, 32818, 32806, - 32901, 32818, 32730, 32559, 32417, 32407, 35057, 35053, 35041, 17569, 17991, 17899, 18455, - 18597, 18635, 18011, 17991, 17828, 7202, 7285, 7357, 9953, 9775, 9638, 9313, 9449, - 9308, 12084, 12470, 11925, 12867, 12540, 12728, 18309, 18096, 18074, 22970, 23106, 22606, - 26676, 26723, 26504, 32521, 32559, 32320, 32994, 32889, 32908, 8138, 8069, 8274, 25925, - 25994, 25763, 26395, 26578, 26504, 25925, 25763, 25639, 33858, 33694, 33715, 33399, 33479, - 33290, 34024, 33694, 33858, 33694, 33463, 33386, 33321, 33059, 33049, 7169, 7225, 7341, - 7105, 7225, 7169, 7231, 7209, 7368, 7165, 7209, 7231, 34968, 35025, 34874, 35059, - 35025, 34968, 12470, 12593, 11925, 22113, 22153, 22054, 15013, 15281, 15179, 14861, 14982, - 14948, 14142, 14212, 14035, 7528, 7642, 7506, 8081, 8041, 8136, 7425, 7527, 7429, - 34853, 34731, 34557, 34519, 34483, 34350, 34519, 34350, 34412, 34519, 34412, 34562, 8946, - 9193, 9102, 8792, 8965, 8962, 27819, 28093, 27767, 28105, 28419, 28289, 27819, 27767, - 27732, 22113, 22164, 22153, 29682, 29608, 29602, 30833, 30712, 30980, 35053, 35118, 34955, - 8119, 8260, 7944, 8260, 8717, 8370, 26379, 26578, 26395, 12174, 12219, 12284, 12417, - 12219, 12323, 11478, 11964, 11220, 29403, 29329, 29196, 29365, 29329, 29403, 34649, 34888, - 34362, 34798, 34731, 35191, 27397, 27410, 27294, 7285, 7304, 7430, 7271, 7304, 7285, - 18492, 18597, 18455, 18011, 18309, 18074, 35018, 34795, 34920, 35025, 34990, 34874, 35059, - 34990, 35025, 15819, 15726, 15728, 15892, 15726, 15819, 15892, 15965, 16037, 24448, 24472, - 24275, 25801, 25925, 25639, 34040, 34136, 33998, 34253, 34107, 34348, 7255, 7425, 7429, - 9775, 9679, 9638, 7094, 7190, 7263, 8945, 9102, 9066, 21729, 21953, 21696, 22223, - 22211, 22347, 8260, 8138, 8362, 9386, 8914, 9453, 9277, 9313, 9308, 15013, 15179, - 14993, 16020, 16385, 16077, 16901, 17023, 17039, 34030, 33914, 33998, 33869, 33995, 33696, - 33941, 33995, 33869, 9164, 9277, 9193, 8991, 8535, 8685, 13643, 13742, 13558, 27880, - 27819, 27732, 28635, 28300, 28683, 32818, 32931, 32746, 32910, 32931, 32818, 11257, 11372, - 11382, 7174, 7330, 7091, 22153, 22164, 22263, 22164, 22300, 22263, 7556, 7686, 7799, - 7467, 7489, 7632, 7787, 7821, 7864, 7787, 8047, 7974, 7891, 7974, 8069, 22912, - 22951, 23012, 22951, 23178, 23012, 34391, 34282, 33925, 7556, 7799, 7840, 9603, 9490, - 9642, 9287, 9275, 9370, 9264, 9208, 9286, 9603, 9764, 9802, 16656, 16510, 16591, - 19133, 18879, 18244, 34853, 34437, 34539, 34562, 34412, 34679, 7304, 7324, 7430, 7245, - 7324, 7304, 29998, 29535, 30180, 29083, 28785, 28683, 7467, 7632, 7616, 34176, 34030, - 33998, 15975, 15892, 16037, 25798, 25565, 25846, 24390, 24515, 24396, 23700, 23899, 23761, - 7091, 7330, 7335, 7091, 7335, 7105, 10015, 9937, 10181, 10015, 10181, 10301, 10957, - 11120, 11255, 22341, 22300, 22321, 27944, 27708, 27764, 27509, 27462, 27600, 25841, 25798, - 25901, 28077, 27985, 28014, 35158, 35049, 34943, 14786, 14772, 14964, 14672, 14526, 14499, - 12805, 12867, 13055, 14526, 14653, 14786, 14982, 15013, 14993, 14901, 14861, 14847, 22436, - 22321, 22403, 23899, 23693, 23926, 27509, 27600, 27708, 27613, 27880, 27732, 27068, 27397, - 27294, 27502, 27397, 27546, 34990, 35044, 34920, 35085, 35044, 34990, 9287, 9370, 9423, - 9313, 8914, 9386, 9193, 9277, 9308, 8957, 9066, 8965, 12805, 13055, 13003, 11573, - 11554, 11810, 13187, 13385, 13558, 12944, 12882, 13045, 12506, 12837, 12502, 12506, 12502, - 12417, 29083, 28782, 29329, 28276, 28077, 28014, 32813, 32901, 32659, 32931, 32994, 32908, - 21953, 22211, 22143, 9937, 9883, 9932, 11810, 11554, 11770, 12528, 12497, 12540, 20314, - 20230, 20042, 20955, 21150, 21089, 21089, 21287, 21241, 21953, 22117, 22211, 30563, 29998, - 30180, 7186, 7042, 7507, 6959, 7042, 7186, 6959, 7186, 6912, 7186, 7106, 6912, - 7106, 6934, 6912, 7187, 7210, 6961, 7075, 7190, 7094, 9150, 9208, 9275, 9607, - 9603, 9802, 13776, 14142, 14035, 13907, 14142, 13776, 14901, 15013, 14982, 20750, 20770, - 20805, 26578, 26676, 26504, 26702, 26676, 26578, 26174, 26262, 25994, 27708, 27600, 27764, - 27502, 27556, 27410, 35249, 35227, 34953, 35102, 35187, 34985, 35506, 35352, 35053, 35053, - 35185, 35118, 35118, 35158, 34943, 7324, 7315, 7503, 7506, 7642, 7410, 7245, 7315, - 7324, 25316, 25007, 25526, 34107, 34136, 34040, 34253, 34136, 34107, 12763, 12528, 12540, - 12417, 12395, 12219, 29365, 29403, 29619, 29178, 29083, 29329, 35227, 35187, 35102, 8772, - 8957, 8965, 33049, 33059, 32876, 32708, 32542, 32624, 31428, 31357, 31551, 33210, 33017, - 33292, 33167, 32994, 33044, 20160, 20042, 20118, 20042, 19974, 20118, 35187, 35157, 34985, - 15873, 16077, 15979, 18492, 18426, 18412, 15338, 15378, 15281, 20118, 19974, 19876, 21403, - 21149, 21472, 21235, 21149, 21403, 21235, 21403, 21306, 21403, 21427, 21306, 21422, 21427, - 21403, 21564, 21427, 21422, 21783, 21643, 21564, 21015, 21150, 20955, 7174, 7075, 7094, - 7105, 7335, 7225, 7140, 7965, 6963, 7165, 7202, 7357, 8741, 8633, 8364, 8787, - 8792, 8962, 10739, 10602, 11094, 9937, 9792, 9883, 18492, 18455, 18426, 18011, 18074, - 17991, 24205, 24161, 24257, 24257, 24422, 24295, 27985, 27708, 27944, 27723, 27708, 27985, - 31122, 30833, 30980, 29756, 29682, 29900, 31122, 30980, 31140, 34348, 34107, 34399, 35024, - 34845, 34716, 35007, 34570, 34933, 34798, 34850, 34649, 35271, 35162, 35301, 34798, 34649, - 34731, 35049, 35075, 35030, 35260, 35075, 35049, 24960, 24835, 24752, 19876, 19974, 19771, - 21783, 21727, 21643, 35087, 35162, 34768, 34996, 34843, 34892, 10350, 10237, 10394, 32506, - 32331, 32542, 21783, 21903, 21727, 21150, 21287, 21089, 10237, 10182, 10301, 11255, 11120, - 11538, 18764, 19133, 18244, 16762, 16510, 16656, 16461, 17023, 16901, 29619, 29403, 29608, - 32559, 32571, 32534, 31717, 32342, 32013, 32521, 32342, 32365, 32342, 31717, 32365, 17828, - 17991, 17569, 18982, 18718, 18640, 22436, 22403, 22712, 21922, 21903, 22054, 22436, 22712, - 22470, 25631, 25576, 25497, 25766, 25798, 25841, 7042, 6996, 7239, 8857, 8852, 8802, - 8260, 8119, 8138, 8710, 8974, 8743, 8744, 8792, 8787, 9275, 9208, 9264, 9287, - 9423, 9426, 12826, 12882, 12944, 12851, 12882, 12826, 26249, 26174, 25994, 26379, 26174, - 26249, 28785, 28635, 28683, 28927, 28635, 28785, 28927, 28785, 29083, 33292, 33017, 33261, - 33479, 33399, 33463, 33479, 33463, 33588, 33964, 33694, 34024, 34057, 33914, 34030, 34138, - 34057, 34030, 7165, 7354, 7209, 18868, 18982, 18640, 18412, 18426, 18309, 23377, 23012, - 23178, 22656, 22970, 22606, 23106, 23104, 23169, 35044, 35018, 34920, 35048, 35018, 35044, - 34972, 34892, 34680, 9272, 9287, 9426, 12506, 12614, 12837, 12417, 12614, 12506, 32708, - 32624, 32693, 32708, 32693, 32847, 32521, 32571, 32559, 32901, 32910, 32818, 19793, 19876, - 19771, 21287, 21410, 21241, 22893, 23104, 22970, 34850, 34888, 34649, 34702, 34539, 34483, - 7169, 7417, 7450, 6947, 7075, 7174, 7408, 7467, 7616, 7267, 7169, 7450, 7379, - 7467, 7408, 14653, 14526, 14672, 15508, 15560, 15430, 19725, 19793, 19771, 18868, 18640, - 18597, 19263, 19218, 19093, 21410, 21601, 21696, 21922, 22054, 22153, 22470, 22712, 22562, - 33614, 33651, 33289, 34533, 34391, 34643, 33366, 33196, 33132, 15430, 15728, 15726, 28255, - 28077, 28469, 34136, 34176, 33998, 34253, 34176, 34136, 16657, 16510, 16762, 15892, 15835, - 15726, 27369, 27298, 27030, 27509, 27435, 27369, 27481, 27435, 27610, 27342, 27435, 27481, - 27397, 27502, 27410, 27697, 27880, 27613, 27819, 27983, 28093, 27546, 27397, 27323, 27397, - 27068, 27323, 33588, 33694, 33964, 33588, 33463, 33694, 10895, 11382, 11365, 11478, 12174, - 11964, 10771, 10912, 10821, 21922, 22153, 22263, 35089, 34888, 34850, 7202, 7271, 7285, - 7323, 7730, 7425, 7130, 7271, 6918, 11925, 12593, 12497, 11554, 11431, 11538, 22970, - 23104, 23106, 25526, 25577, 25539, 22260, 22347, 22211, 29998, 29682, 29602, 29365, 29178, - 29329, 29619, 29682, 29728, 35018, 34983, 34842, 35048, 34983, 35018, 34996, 35052, 34843, - 35003, 34972, 34680, 16108, 15975, 16037, 25766, 25576, 25631, 25766, 25631, 25798, 25539, - 25577, 25611, 24644, 24600, 24472, 17009, 16812, 16762, 16657, 16812, 17009, 6992, 7165, - 7231, 6992, 7227, 7140, 8716, 8744, 8787, 8364, 8633, 8157, 33389, 33366, 33132, - 33167, 33132, 32994, 35075, 35059, 34968, 35212, 35059, 35311, 21601, 21729, 21696, 35352, - 35185, 35053, 8370, 8717, 8392, 8138, 8019, 8069, 7573, 7556, 7840, 33651, 33941, - 33869, 33037, 32722, 33059, 32593, 32506, 32542, 8772, 8945, 8957, 8957, 8945, 9066, - 8772, 8965, 8792, 13017, 13385, 13187, 13017, 13112, 12882, 21729, 21827, 21953, 8852, - 8750, 8802, 8710, 8750, 8852, 27697, 27613, 27556, 28093, 28419, 28105, 33321, 33149, - 33059, 33444, 33292, 33261, 11573, 11431, 11554, 12063, 11925, 12497, 12063, 12497, 12126, - 19404, 19663, 19593, 24480, 24448, 24275, 8119, 8019, 8138, 8136, 8041, 8408, 7561, - 8007, 7886, 12614, 12851, 12826, 12323, 12219, 12174, 15263, 15338, 15281, 15263, 15281, - 15013, 15263, 15013, 14901, 14982, 14861, 14901, 26174, 26379, 26395, 26249, 25994, 26084, - 29485, 29178, 29365, 28469, 28077, 28276, 32632, 32506, 32593, 6947, 7174, 7091, 7267, - 7594, 7070, 35059, 35115, 34990, 35212, 35115, 35059, 17578, 17828, 17569, 18011, 18127, - 18309, 19263, 19093, 19164, 23899, 23700, 23693, 22330, 22341, 22436, 24205, 24257, 24295, - 11573, 11810, 11607, 22263, 22300, 22341, 22263, 22341, 22330, 34282, 34391, 34317, 34519, - 34702, 34483, 34391, 34751, 34643, 27880, 27983, 27819, 6947, 7091, 6830, 7642, 7528, - 7959, 7323, 7425, 7255, 9883, 9792, 9858, 9603, 9436, 9490, 9938, 9792, 9937, - 10429, 10550, 10577, 10429, 10577, 10057, 9164, 9313, 9277, 11790, 11810, 11872, 35185, - 35158, 35118, 10550, 10653, 10821, 31279, 31122, 31140, 29485, 29619, 29728, 31320, 31140, - 31357, 35115, 35085, 34990, 35212, 35085, 35115, 9101, 9164, 9193, 12867, 12763, 12540, - 12763, 12805, 13003, 12695, 12851, 12614, 32571, 32813, 32534, 32817, 32813, 32907, 7271, - 7245, 7304, 7130, 7245, 7271, 8157, 8633, 8408, 9208, 9053, 9286, 9150, 9053, - 9208, 9150, 9275, 9166, 15784, 15979, 15915, 17225, 17343, 17037, 17948, 18011, 17828, - 19593, 19663, 20033, 32817, 32910, 32901, 35064, 35052, 34996, 34994, 35003, 34680, 34994, - 34680, 34888, 34994, 35141, 35067, 24295, 24422, 24397, 27435, 27342, 27369, 27298, 27342, - 27493, 31428, 31320, 31357, 33479, 33444, 33261, 34138, 34024, 34057, 7255, 7429, 7315, - 22562, 22816, 22842, 24000, 23761, 23899, 31363, 31140, 31320, 32708, 32632, 32593, 32757, - 32632, 32708, 8672, 8744, 8716, 8946, 9101, 9193, 8374, 8991, 8741, 24448, 24644, - 24472, 24480, 24644, 24448, 9792, 9740, 9858, 33044, 32994, 32931, 35064, 34996, 35072, - 8019, 7891, 8069, 34176, 34138, 34030, 34787, 34403, 34666, 28065, 28135, 27983, 27710, - 27697, 27556, 27546, 27556, 27502, 6963, 7965, 7239, 7118, 7255, 7245, 19250, 19263, - 19164, 18412, 18597, 18492, 7042, 6670, 6996, 6996, 6922, 7239, 7106, 7133, 6934, - 7070, 7539, 7489, 6961, 7190, 7075, 7379, 7489, 7467, 17948, 18127, 18011, 17343, - 17157, 17023, 35095, 35007, 34933, 34845, 34787, 34666, 35095, 34933, 34983, 34994, 35089, - 35141, 35072, 34996, 34972, 35227, 35282, 35187, 35187, 35282, 35157, 35506, 35053, 35057, - 35185, 35309, 35158, 35316, 35249, 34953, 35316, 34953, 35271, 35271, 34953, 35162, 6934, - 7133, 6981, 15338, 15784, 15378, 14861, 14630, 14466, 6981, 7133, 7187, 21149, 20935, - 20450, 21036, 20935, 21149, 21036, 21149, 21235, 21036, 21235, 21048, 21235, 21128, 21048, - 20770, 20992, 20955, 21150, 21272, 21287, 21287, 21272, 21410, 21410, 21429, 21601, 21601, - 21700, 21729, 21729, 21871, 21827, 20991, 20992, 20770, 20991, 20770, 20799, 20297, 20750, - 20314, 20297, 20314, 20160, 20297, 20160, 20131, 20160, 20118, 20131, 20118, 19876, 20131, - 35369, 35282, 35227, 7408, 7616, 7388, 9154, 9101, 9021, 10444, 10429, 10270, 11862, - 11790, 11872, 11862, 11872, 11925, 15835, 15430, 15726, 16147, 16037, 16591, 16147, 16591, - 16366, 16591, 16510, 16366, 16461, 16901, 16385, 20131, 19876, 19873, 21427, 21564, 21643, - 20992, 21015, 20955, 24397, 24627, 24687, 24205, 24072, 23899, 25007, 24981, 24835, 26084, - 25994, 25925, 34472, 34412, 34317, 35220, 34787, 34845, 10182, 10015, 10301, 9792, 9653, - 9740, 9978, 10015, 10182, 10100, 10182, 10237, 10266, 10237, 10350, 10266, 10350, 10739, - 11381, 11538, 11431, 11381, 11431, 11444, 35301, 35162, 35087, 35072, 34972, 35003, 8672, - 8716, 8685, 22712, 22816, 22562, 21632, 21427, 21643, 21871, 21953, 21827, 22117, 22260, - 22211, 24480, 24697, 24644, 35087, 35033, 35265, 28356, 28093, 28290, 28356, 28419, 28093, - 32910, 33044, 32931, 33108, 33044, 32910, 6841, 6981, 6884, 19873, 19876, 19793, 15835, - 15892, 15975, 14786, 14450, 14526, 26379, 26702, 26578, 26084, 25925, 26017, 34226, 34138, - 34176, 7891, 7787, 7974, 15325, 15784, 15338, 15873, 16020, 16077, 24644, 24697, 24752, - 24472, 23650, 24275, 25682, 24909, 25280, 25798, 25846, 25901, 21121, 21272, 21150, 35265, - 34834, 35533, 7245, 7255, 7315, 7410, 7642, 7702, 7010, 7202, 7165, 12177, 12627, - 12614, 12177, 12323, 12174, 12174, 11569, 12177, 32342, 32521, 32320, 32813, 32817, 32901, - 32365, 31717, 32309, 30560, 30435, 30945, 9653, 9607, 9740, 9740, 9607, 9802, 8364, - 8374, 8741, 8535, 8532, 8685, 8282, 8374, 8364, 27342, 27298, 27369, 27435, 27509, - 27610, 27509, 27708, 27610, 35167, 35048, 35044, 35007, 35024, 34716, 35167, 35044, 35085, - 11444, 11431, 11573, 19725, 19873, 19793, 21632, 21643, 21727, 21272, 21429, 21410, 27610, - 27708, 27723, 33366, 33620, 33196, 34158, 34046, 33941, 34533, 34472, 34391, 33758, 33620, - 33366, 33389, 33132, 33167, 17464, 17232, 17179, 17165, 16657, 17009, 24272, 24072, 24205, - 23377, 23451, 23441, 24272, 24390, 24255, 8041, 8157, 8408, 8068, 8157, 7822, 14466, - 14584, 14142, 15263, 15325, 15338, 6932, 6992, 7140, 6954, 7140, 7012, 22260, 22413, - 22347, 22348, 22413, 22260, 6961, 7210, 7190, 6961, 7075, 6762, 12805, 12763, 12867, - 11607, 11444, 11573, 13003, 13685, 13636, 13003, 13636, 13575, 14426, 14499, 14526, 12952, - 13017, 12882, 13385, 13643, 13558, 12952, 12882, 12851, 29178, 28927, 29083, 29259, 28927, - 29348, 29619, 29608, 29682, 34391, 34472, 34317, 34046, 33995, 33941, 7573, 7840, 7821, - 8384, 8532, 8535, 8946, 9102, 8945, 27723, 27985, 28047, 33321, 33049, 33210, 33529, - 33444, 33479, 33529, 33479, 33588, 15899, 16020, 15873, 15899, 15873, 15784, 18127, 18412, - 18309, 17822, 17948, 17828, 9607, 9524, 9603, 9532, 9524, 9607, 11607, 11810, 11790, - 29682, 29756, 29728, 7005, 7105, 7169, 6853, 6922, 6996, 21727, 21903, 21835, 21429, - 21700, 21601, 34179, 34046, 34209, 18298, 18412, 18127, 19263, 19250, 19771, 35067, 35072, - 35003, 35533, 34834, 35052, 35067, 35003, 34994, 34702, 34519, 34562, 33421, 33210, 33292, - 7410, 7702, 7273, 7528, 7500, 7959, 34775, 34702, 34562, 8532, 8672, 8685, 33444, - 33421, 33292, 7025, 7005, 7169, 6992, 7010, 7165, 6932, 7010, 6992, 10653, 10771, - 10821, 10550, 10444, 10653, 9154, 9313, 9164, 23679, 23700, 23761, 21835, 21903, 21922, - 31122, 31323, 30833, 31363, 31279, 31140, 31363, 31320, 31428, 6922, 6963, 7239, 21835, - 21922, 22263, 10739, 10957, 10402, 10739, 11094, 10957, 9445, 9436, 9524, 11255, 11538, - 11381, 25588, 25280, 25576, 25901, 25846, 26527, 31371, 31498, 31551, 33685, 33529, 33588, - 34253, 34226, 34176, 34399, 34107, 33951, 15189, 15325, 15263, 24272, 24205, 24295, 24272, - 24295, 24397, 26249, 26350, 26379, 26169, 26350, 26249, 10499, 10771, 10653, 31551, 31498, - 32797, 7388, 7616, 7686, 7379, 7317, 7489, 6840, 7025, 7169, 7273, 7730, 7323, - 22330, 21835, 22263, 21700, 21871, 21729, 24697, 24960, 24752, 26017, 25925, 25801, 24275, - 24183, 24276, 34702, 34853, 34539, 8392, 8717, 8802, 8119, 7973, 8019, 8019, 7910, - 7891, 7891, 7733, 7787, 8743, 8974, 9071, 8854, 9071, 9053, 9524, 9436, 9603, - 9653, 9580, 9588, 12126, 12497, 12528, 13404, 13643, 13385, 29619, 29485, 29365, 29476, - 29485, 29600, 10771, 10895, 10912, 31409, 31514, 31400, 23826, 23679, 23761, 35140, 35024, - 35007, 34365, 34284, 34348, 6830, 7091, 7105, 6978, 7025, 6840, 9166, 9275, 9287, - 9101, 9154, 9164, 8946, 8945, 8908, 18851, 18868, 18671, 22470, 22330, 22436, 22842, - 22816, 23012, 33037, 32847, 32693, 32684, 31498, 32506, 32794, 32813, 32571, 33044, 33108, - 33167, 8772, 8792, 8744, 33149, 33037, 33059, 33218, 33037, 33149, 9297, 9272, 9426, - 35203, 35052, 35064, 15866, 15835, 15975, 16366, 16510, 16494, 34472, 34679, 34412, 34702, - 34775, 34853, 34213, 33925, 33995, 9938, 9937, 10015, 11374, 11255, 11381, 11757, 11607, - 11790, 8392, 8802, 8572, 14474, 14450, 14786, 14426, 14450, 14474, 14435, 14466, 14203, - 15158, 15189, 15263, 25639, 25577, 25801, 34284, 34226, 34253, 24873, 24960, 24697, 10090, - 9978, 10182, 16020, 16111, 16385, 17790, 17822, 17623, 15941, 15899, 15740, 14435, 14847, - 14861, 15740, 15899, 15784, 6963, 6950, 7012, 8765, 8772, 8744, 22413, 22656, 22606, - 22685, 22656, 22413, 27643, 27546, 27781, 27323, 27068, 27141, 27697, 27915, 27880, 33964, - 34024, 34463, 33444, 33566, 33421, 33421, 33321, 33210, 35311, 35059, 35075, 35154, 35095, - 34983, 35260, 35049, 35158, 35352, 35309, 35185, 7255, 7103, 7323, 7002, 7130, 6918, - 7118, 7130, 7002, 35154, 34983, 35048, 35072, 35203, 35064, 34994, 34888, 35089, 23441, - 23451, 23700, 24000, 23826, 23761, 24000, 23899, 24072, 9978, 9938, 10015, 27610, 27687, - 27481, 27481, 27493, 27342, 26527, 26286, 26846, 27694, 27723, 28047, 27643, 27710, 27556, - 21871, 22117, 21953, 25715, 25576, 25766, 26527, 26846, 27384, 34463, 34024, 34138, 34348, - 34284, 34253, 34399, 33951, 34595, 8946, 9021, 9101, 9638, 9679, 9230, 8931, 9021, - 8946, 13017, 13015, 13385, 12695, 12952, 12851, 12695, 12614, 12627, 28419, 28668, 28289, - 28555, 28668, 28419, 9272, 9166, 9287, 8545, 8750, 8710, 9172, 9166, 9272, 9297, - 9426, 9436, 7954, 7973, 8119, 7404, 7518, 7556, 11374, 11381, 11444, 34046, 34179, - 33995, 34213, 34179, 34209, 8772, 8908, 8945, 28135, 28093, 27983, 33229, 33108, 32910, - 34158, 33941, 33651, 6978, 7105, 7005, 19164, 19093, 19001, 35309, 35260, 35158, 7130, - 7118, 7245, 7271, 6882, 6918, 16657, 16762, 16812, 15960, 15975, 16108, 23441, 23700, - 23679, 35089, 34850, 35191, 35176, 35203, 35072, 35249, 35369, 35227, 35282, 35344, 35157, - 35309, 35406, 35260, 35437, 35369, 35249, 35437, 35249, 35316, 35336, 35316, 35271, 35336, - 35271, 35382, 6912, 6911, 6959, 6757, 6853, 6996, 6922, 6824, 6963, 6963, 6831, - 6950, 6934, 6911, 6912, 6865, 6911, 6934, 6865, 6934, 6981, 6865, 6981, 6841, - 7187, 6884, 6981, 7556, 7518, 7686, 7408, 7317, 7379, 7573, 7821, 7583, 9588, - 9607, 9653, 9255, 9297, 9381, 12063, 11862, 11925, 11268, 11374, 11444, 11829, 11862, - 12063, 12126, 12528, 12379, 20948, 20880, 20935, 20935, 20701, 20033, 20948, 20935, 21036, - 20948, 21036, 21048, 21183, 21128, 21235, 21427, 21412, 21306, 24960, 25007, 24835, 24898, - 25007, 24960, 24873, 24697, 24480, 30654, 30435, 30222, 32521, 32646, 32571, 33303, 33222, - 33229, 32365, 32646, 32521, 35382, 35271, 35301, 7322, 7317, 7408, 7025, 6978, 7005, - 25715, 25766, 25841, 23727, 23441, 23679, 24275, 23650, 24183, 21427, 21593, 21412, 21015, - 21121, 21150, 21272, 21242, 21429, 21429, 21515, 21700, 21700, 21786, 21871, 21871, 21962, - 22117, 20992, 20991, 21015, 20741, 20770, 20750, 20741, 20750, 20297, 20162, 20297, 20131, - 20162, 20131, 20007, 35369, 35344, 35282, 11268, 11444, 11335, 7187, 6974, 6884, 21427, - 21632, 21593, 23231, 22842, 23012, 22516, 22330, 22470, 21593, 21632, 21727, 35212, 35167, - 35085, 35312, 35167, 35212, 6862, 6954, 7012, 6862, 7012, 6950, 20007, 20131, 19873, - 19001, 19093, 18982, 19001, 18982, 18868, 19001, 18868, 18851, 15960, 16108, 16147, 20007, - 19873, 19962, 20991, 21121, 21015, 25966, 25715, 25841, 25691, 25715, 25857, 34365, 34399, - 34498, 34284, 34443, 34226, 35422, 35382, 35301, 28065, 27983, 27880, 33474, 33321, 33421, - 33037, 33031, 32847, 7443, 7388, 7686, 7410, 7399, 7506, 7437, 7500, 7528, 7340, - 7399, 7410, 8493, 8569, 8532, 8532, 8569, 8672, 8672, 8569, 8744, 8687, 8931, - 8908, 8068, 8282, 8364, 8068, 8364, 8157, 14450, 14426, 14526, 12379, 12528, 12763, - 14474, 14786, 14464, 6884, 6974, 6910, 7118, 7100, 7255, 7002, 7100, 7118, 8572, - 8802, 8750, 7882, 7954, 8119, 8572, 8750, 8545, 9638, 9230, 9574, 12952, 13015, - 13017, 12614, 12417, 12177, 19962, 19873, 19725, 21121, 21242, 21272, 23727, 23679, 23826, - 23377, 23231, 23012, 35176, 35072, 35067, 35321, 35487, 35339, 35366, 35087, 35265, 35366, - 35422, 35087, 10771, 10634, 10895, 12639, 12893, 12695, 10429, 10444, 10550, 10270, 10429, - 10057, 12893, 13015, 12952, 14110, 14466, 14142, 6954, 6932, 7140, 6859, 6932, 6954, - 22516, 22470, 22562, 22296, 22348, 22260, 24276, 24394, 24275, 22296, 22260, 22117, 6910, - 6974, 6762, 27723, 27687, 27610, 27694, 27687, 27723, 27985, 28077, 28255, 27915, 28065, - 27880, 27546, 27643, 27556, 27736, 27643, 27781, 35176, 35067, 35320, 26169, 26451, 26350, - 25624, 25577, 25526, 24167, 24000, 24072, 24167, 24072, 24272, 6762, 6974, 6961, 10266, - 10100, 10237, 9978, 9879, 9938, 9580, 9653, 9792, 10133, 10100, 10266, 10133, 10266, - 10021, 10133, 10021, 10046, 21593, 21727, 21835, 24275, 24394, 24480, 23650, 23955, 24183, - 28214, 28290, 28135, 28135, 28290, 28093, 28905, 28847, 28668, 33108, 33222, 33167, 33222, - 33108, 33229, 7583, 7821, 7787, 7197, 7322, 7219, 9746, 9708, 10057, 9708, 9667, - 9694, 7627, 7733, 7891, 7910, 7954, 7882, 8854, 9053, 8670, 8384, 8535, 8374, - 19725, 19771, 19250, 18868, 18597, 18671, 27384, 26846, 27298, 35260, 35311, 35075, 35392, - 35311, 35260, 10100, 10090, 10182, 16124, 15960, 16147, 14220, 14474, 14464, 25715, 25588, - 25576, 25691, 25588, 25715, 6757, 6996, 6670, 21362, 21593, 22207, 21242, 21515, 21429, - 7100, 7103, 7255, 7057, 7103, 7100, 25707, 25624, 25526, 24675, 24873, 24480, 29485, - 29476, 29178, 29998, 29900, 29682, 28847, 28590, 28668, 30513, 29554, 30358, 35533, 35366, - 35265, 35320, 35067, 35321, 6853, 6824, 6922, 7910, 8019, 7973, 28905, 28668, 28806, - 34399, 34365, 34348, 34443, 34365, 34498, 27915, 27697, 27710, 28290, 28555, 28356, 6840, - 7169, 7267, 6947, 6879, 7075, 9580, 9792, 9938, 21279, 21412, 21408, 22610, 22516, - 22562, 22733, 22562, 22842, 9166, 8915, 9150, 9255, 9172, 9272, 9255, 9272, 9297, - 9746, 9638, 9667, 8908, 8931, 8946, 8765, 8908, 8772, 35506, 35057, 35157, 7116, - 7273, 7323, 17155, 16657, 17165, 16124, 15866, 15960, 18244, 17464, 18421, 17357, 17464, - 17470, 7388, 7322, 7408, 7317, 7070, 7489, 7443, 7686, 7518, 6824, 6831, 6963, - 7057, 7173, 7103, 35384, 35052, 35203, 7103, 7173, 7323, 7202, 6882, 7271, 14426, - 14097, 13636, 15710, 15430, 15835, 14466, 14435, 14861, 14947, 15263, 14901, 14110, 14142, - 13907, 17879, 17822, 17790, 17948, 17879, 18127, 18050, 18298, 18127, 35024, 35220, 34845, - 35269, 35140, 35007, 35166, 35007, 35095, 35154, 35048, 35256, 35256, 35048, 35167, 12379, - 12763, 13003, 11862, 11757, 11790, 18528, 18597, 18412, 19725, 19250, 19181, 34463, 34138, - 34589, 33529, 33566, 33444, 7437, 7528, 7506, 7437, 7506, 7266, 8641, 8765, 8744, - 34651, 34679, 34472, 35321, 35141, 35089, 35321, 35067, 35141, 34651, 34472, 34698, 9588, - 9532, 9607, 9452, 9532, 9588, 11829, 11757, 11862, 11061, 10957, 11255, 8569, 8641, - 8744, 8292, 8384, 8236, 8429, 8384, 8292, 33964, 33685, 33588, 6831, 6869, 6950, - 21786, 21962, 21871, 22685, 22893, 22656, 7350, 7443, 7518, 7404, 7556, 7573, 15960, - 15866, 15975, 16124, 16147, 16366, 15899, 15941, 16020, 15312, 15784, 15325, 24873, 24898, - 24960, 24931, 24898, 24873, 25326, 25526, 25007, 26451, 26379, 26350, 8429, 8493, 8532, - 27548, 27493, 27481, 28276, 28635, 28819, 27643, 27736, 27710, 28065, 28214, 28135, 26249, - 26084, 26169, 33321, 33218, 33149, 33685, 33566, 33529, 13249, 13404, 13385, 12695, 12893, - 12952, 12417, 12323, 12177, 11205, 11964, 11441, 17464, 17357, 17232, 17311, 17357, 17437, - 23290, 23231, 23441, 23441, 23231, 23377, 24255, 24167, 24272, 23727, 23826, 23775, 35154, - 35166, 35095, 35323, 35166, 35154, 35312, 35212, 35380, 7099, 7340, 7410, 7099, 7410, - 7273, 8915, 9053, 9150, 9532, 9445, 9524, 8527, 8743, 8543, 9384, 9445, 9532, - 11170, 11255, 11374, 12016, 11829, 12063, 29348, 28927, 29178, 30180, 30361, 30753, 33384, - 33218, 33321, 32757, 32506, 32632, 8572, 8196, 8392, 7882, 8119, 7944, 8654, 8545, - 8710, 9381, 9297, 9436, 27807, 27915, 27710, 32646, 32655, 32571, 32731, 32655, 32646, - 32731, 32646, 32365, 33581, 33474, 33421, 7954, 7910, 7973, 7490, 7583, 7787, 8260, - 8370, 7944, 14947, 14901, 14847, 26169, 26084, 26017, 34179, 34213, 33995, 33825, 33651, - 33620, 6830, 6879, 6947, 21962, 22095, 22117, 24931, 25000, 24898, 35542, 35406, 35309, - 22911, 22733, 22842, 21306, 21412, 21279, 31279, 31323, 31122, 31363, 31409, 31279, 31428, - 31409, 31363, 31514, 31409, 31428, 32757, 32708, 32868, 34679, 34775, 34562, 34698, 34472, - 34533, 7469, 7583, 7513, 15866, 15710, 15835, 16114, 16124, 16366, 15941, 16111, 16020, - 15937, 16111, 15941, 6820, 7010, 6932, 7173, 7116, 7323, 6801, 6862, 6950, 8743, - 8654, 8710, 8765, 8687, 8908, 9667, 9574, 9656, 8520, 8641, 8569, 10100, 10085, - 10090, 10090, 9968, 9978, 11635, 11607, 11757, 33474, 33365, 33321, 33222, 33389, 33167, - 33303, 33389, 33222, 35406, 35392, 35260, 17155, 17165, 17232, 24898, 25000, 25007, 24467, - 24480, 24394, 34814, 34775, 34679, 7322, 7215, 7317, 6978, 6830, 7105, 7197, 7215, - 7322, 7322, 7388, 7219, 9445, 9381, 9436, 9384, 9381, 9445, 20880, 20701, 20935, - 20813, 20701, 20880, 20813, 20880, 20986, 20880, 20948, 20986, 20948, 21048, 20986, 21306, - 21183, 21235, 20569, 20741, 20297, 20991, 21051, 21121, 21121, 21107, 21242, 21647, 21786, - 21515, 21515, 21786, 21700, 21962, 21946, 22095, 20767, 20741, 20720, 20216, 20162, 20007, - 23775, 23826, 24000, 24390, 24272, 24397, 22893, 22970, 22656, 25801, 25577, 25624, 26216, - 26169, 26017, 29728, 29600, 29485, 29732, 29600, 29728, 35369, 35444, 35344, 35344, 35506, - 35157, 35352, 35542, 35309, 35406, 35466, 35392, 35336, 35437, 35316, 35496, 35437, 35336, - 35496, 35336, 35382, 35496, 35382, 35436, 21306, 21279, 21183, 20741, 20799, 20770, 35437, - 35444, 35369, 6911, 6791, 6959, 6853, 6757, 6824, 6824, 6758, 6831, 6831, 6744, - 6869, 6869, 6801, 6950, 6865, 6791, 6911, 6809, 6791, 6865, 6809, 6865, 6841, - 6809, 6841, 6776, 6841, 6884, 6776, 10133, 10085, 10100, 35436, 35382, 35432, 25707, - 25801, 25624, 20799, 20975, 20991, 26702, 26379, 26451, 27141, 27068, 26676, 27736, 27807, - 27710, 33921, 33825, 33875, 6776, 6884, 6767, 12126, 12024, 12063, 12098, 12006, 11830, - 20975, 21051, 20991, 21593, 21408, 21412, 22973, 22911, 22842, 22973, 22842, 23231, 22685, - 22413, 22348, 27548, 27481, 27687, 27384, 27493, 27451, 32868, 32708, 32847, 33031, 33037, - 33226, 32655, 32794, 32571, 32731, 32794, 32655, 35380, 35212, 35311, 6674, 6830, 6978, - 6767, 6884, 6910, 6862, 6859, 6954, 6723, 6859, 6862, 14435, 14726, 14847, 14834, - 14726, 14767, 22095, 22296, 22117, 22061, 22296, 22095, 9544, 9580, 9938, 21321, 21408, - 21362, 32080, 32309, 31717, 35432, 35382, 35422, 8546, 8687, 8641, 8384, 8429, 8532, - 8384, 8374, 8236, 22330, 22389, 21835, 35853, 35432, 35422, 8594, 8743, 8527, 8743, - 8854, 8543, 8854, 8743, 9071, 33229, 32910, 33172, 33875, 33825, 33620, 14814, 14947, - 14847, 15189, 15312, 15325, 34643, 34698, 34533, 33921, 34158, 33651, 6767, 6910, 6762, - 22330, 22516, 22444, 34365, 34443, 34284, 34595, 33951, 34736, 27781, 27807, 27736, 27996, - 28214, 28065, 33365, 33384, 33321, 33474, 33596, 33365, 33566, 33581, 33421, 33701, 33581, - 33566, 33701, 33566, 33685, 33701, 33685, 33742, 6762, 7075, 6879, 18298, 18528, 18412, - 19250, 19164, 19181, 18319, 18528, 18298, 17879, 17948, 17822, 19164, 19134, 19181, 22444, - 22516, 22610, 30654, 30782, 30435, 30475, 30513, 30358, 34651, 34814, 34679, 34852, 34698, - 34805, 7044, 7116, 7173, 11829, 11635, 11757, 11550, 11635, 11829, 14947, 15158, 15263, - 24390, 24647, 24515, 23775, 24000, 23996, 7822, 8157, 8041, 7266, 7506, 7399, 7266, - 7399, 7340, 34736, 33951, 34871, 22610, 22562, 22733, 35392, 35327, 35311, 35466, 35327, - 35392, 33758, 33366, 33389, 33172, 32910, 32817, 6670, 6352, 6488, 11268, 11170, 11374, - 6938, 7057, 7002, 7002, 7057, 7100, 15196, 15312, 15189, 15312, 15740, 15784, 17822, - 17828, 17623, 34575, 34498, 34399, 33734, 33701, 33742, 35166, 35278, 35007, 34764, 34736, - 34871, 35312, 35256, 35167, 35412, 35256, 35312, 6802, 6762, 6879, 12627, 12639, 12695, - 12964, 13385, 13015, 10932, 11257, 10895, 18938, 19001, 18851, 35639, 35506, 35344, 30753, - 30361, 30833, 27451, 27548, 27513, 9667, 9708, 9746, 10444, 10499, 10653, 8914, 9021, - 8637, 11335, 11444, 11607, 18788, 18938, 18851, 12866, 13015, 12893, 27996, 28065, 27915, - 28847, 28905, 29238, 6946, 7108, 7116, 7116, 7108, 7273, 6757, 6758, 6824, 6938, - 7034, 7057, 21316, 21515, 21242, 22296, 22685, 22348, 27493, 27384, 27298, 25966, 25841, - 25901, 25588, 25682, 25280, 27548, 27687, 27694, 7219, 7388, 7262, 6816, 6840, 6772, - 7561, 7886, 7500, 24276, 24467, 24394, 25326, 25707, 25526, 24358, 24467, 24276, 13907, - 13776, 13643, 14726, 14814, 14847, 14947, 14834, 15158, 15158, 15196, 15189, 29695, 29476, - 29600, 7057, 7034, 7173, 7202, 7010, 6882, 14834, 14814, 14726, 16461, 16385, 16111, - 18528, 18671, 18597, 24000, 24167, 23996, 22574, 22610, 22716, 32794, 32907, 32813, 32880, - 32907, 32794, 6758, 6744, 6831, 7387, 7404, 7573, 7469, 7573, 7583, 16657, 16494, - 16510, 16124, 16114, 15866, 16330, 16494, 16327, 16400, 16461, 16240, 18050, 18319, 18298, - 20234, 19593, 20033, 32907, 33172, 32817, 33758, 33389, 33648, 34852, 34814, 34651, 34850, - 34798, 35191, 34852, 34651, 34698, 35176, 35384, 35203, 35521, 35436, 35509, 34731, 34853, - 35191, 13676, 13907, 13643, 21183, 21279, 21181, 22973, 22733, 22911, 28271, 28283, 28214, - 27323, 27781, 27546, 27837, 27781, 27960, 33581, 33596, 33474, 34589, 34226, 34443, 9381, - 9163, 9255, 9452, 9384, 9532, 9452, 9588, 9580, 9804, 10270, 10057, 29756, 29732, - 29728, 29744, 29732, 29756, 31400, 31323, 31279, 31400, 31279, 31409, 7291, 7561, 7500, - 7238, 7500, 7437, 25966, 25901, 26015, 26052, 26216, 26017, 26569, 26702, 26451, 25326, - 25007, 25200, 31514, 31428, 31551, 16631, 16722, 17023, 24675, 24931, 24873, 7944, 8370, - 7908, 7910, 7850, 7891, 8506, 8572, 8545, 8594, 8545, 8654, 26402, 26451, 26169, - 31559, 31514, 31685, 34158, 34209, 34046, 34345, 34209, 34291, 33921, 33651, 33825, 21786, - 21946, 21962, 10085, 9968, 10090, 10133, 10046, 10085, 10021, 10266, 10402, 11061, 11255, - 11170, 33734, 33596, 33581, 7108, 7138, 7273, 7065, 7138, 7108, 23955, 23650, 23104, - 25070, 25061, 24931, 24317, 24183, 24268, 7070, 7317, 7215, 6830, 6802, 6879, 7561, - 7653, 8088, 25857, 25966, 25951, 35327, 35380, 35311, 35866, 35380, 35327, 6820, 6932, - 6859, 7065, 7099, 7138, 10046, 9968, 10085, 23603, 23290, 23441, 30839, 30782, 30654, - 30839, 30654, 30768, 7004, 7070, 7215, 7262, 7388, 7443, 7845, 7850, 7910, 15299, - 15709, 15740, 16529, 16631, 16461, 15229, 15196, 15158, 26216, 26402, 26169, 17879, 18050, - 18127, 17623, 17828, 17578, 23727, 23603, 23441, 24277, 24167, 24255, 24277, 24255, 24390, - 31402, 30753, 30833, 8743, 8594, 8654, 9166, 9172, 8915, 28555, 28419, 28356, 28555, - 28290, 28405, 33226, 33037, 33218, 32757, 32684, 32506, 6677, 6802, 6830, 6709, 6801, - 6869, 28283, 28290, 28214, 16494, 16330, 16366, 16268, 16330, 16327, 17311, 17232, 17357, - 33031, 32868, 32847, 35191, 34853, 35213, 34391, 33925, 34751, 7513, 7583, 7490, 7404, - 7350, 7518, 16159, 16114, 16366, 19134, 19164, 19001, 18377, 18671, 18528, 18788, 18671, - 18685, 34498, 34510, 34443, 34595, 34575, 34399, 35220, 35024, 35140, 35278, 35166, 35323, - 34866, 34643, 34912, 26052, 26017, 25801, 6904, 7350, 7404, 17578, 17569, 17343, 16461, - 16631, 17023, 15777, 15941, 15740, 24931, 25061, 25000, 25707, 25719, 25801, 24675, 24480, - 24467, 33389, 33303, 33420, 26702, 27141, 26676, 27996, 27915, 27807, 26910, 27141, 26702, - 26569, 26451, 26402, 35323, 35154, 35256, 34926, 34775, 34814, 35509, 35756, 35691, 35539, - 35466, 35406, 35397, 35269, 35278, 7138, 7099, 7273, 7044, 7173, 7034, 15709, 15777, - 15740, 17610, 17464, 18244, 24396, 24277, 24390, 24183, 24317, 24276, 24358, 24317, 24268, - 25949, 25719, 25743, 34701, 34575, 34595, 8641, 8687, 8765, 8520, 8313, 8388, 8292, - 8493, 8429, 27837, 27807, 27781, 33478, 33384, 33365, 7129, 7215, 7197, 7129, 7197, - 7166, 6984, 7044, 7034, 8236, 8374, 8171, 8374, 8282, 8171, 11117, 11061, 11170, - 11117, 11170, 11268, 11335, 11607, 11635, 17790, 17870, 17879, 17343, 17023, 17037, 30358, - 29554, 29468, 35444, 35639, 35344, 35506, 35542, 35352, 35437, 35526, 35444, 35577, 35526, - 35437, 35577, 35437, 35496, 35577, 35496, 35566, 35496, 35521, 35566, 35496, 35436, 35521, - 12379, 12024, 12126, 12016, 12024, 12098, 20799, 20767, 20975, 20975, 21070, 21051, 21051, - 21107, 21121, 21786, 21754, 21946, 20741, 20767, 20799, 20216, 20297, 20162, 20216, 20007, - 19962, 32900, 32684, 32757, 35436, 35432, 35509, 6791, 6697, 6959, 6757, 6673, 6758, - 6758, 6673, 6744, 6744, 6700, 6869, 6718, 6697, 6791, 6718, 6791, 6809, 6718, - 6809, 6612, 6809, 6776, 6612, 6776, 6767, 6612, 6612, 6767, 6602, 21120, 21183, - 21181, 21120, 21128, 21183, 21120, 20986, 21128, 21128, 20986, 21048, 20813, 20739, 20701, - 20701, 20334, 20033, 21279, 21321, 21181, 30563, 29900, 29998, 29732, 29695, 29600, 35432, - 35719, 35509, 24826, 24675, 24467, 20767, 21070, 20975, 35384, 35176, 35413, 19134, 19001, - 18938, 19999, 20216, 19962, 27960, 27781, 27912, 33596, 33478, 33365, 33701, 33734, 33581, - 33742, 33685, 34328, 19999, 19962, 19989, 21279, 21408, 21321, 21070, 21107, 21051, 7850, - 7627, 7891, 9708, 9694, 10057, 9667, 9638, 9574, 26438, 26569, 26402, 25953, 26052, - 25801, 31600, 31717, 30560, 32844, 32731, 32365, 34626, 34510, 34498, 21408, 21593, 21362, - 35278, 35269, 35007, 35412, 35312, 35380, 7850, 7478, 7627, 7882, 7845, 7910, 7720, - 7845, 7706, 26438, 26402, 26216, 34209, 34319, 34213, 34345, 34319, 34209, 21593, 21835, - 22207, 21107, 21316, 21242, 6723, 6862, 6801, 6691, 6820, 6859, 6918, 6938, 7002, - 8594, 8506, 8545, 8527, 8506, 8594, 20420, 20569, 20216, 18816, 19134, 18938, 18788, - 18851, 18671, 25085, 25007, 25000, 25719, 25953, 25801, 25085, 25000, 25061, 27837, 27996, - 27807, 34852, 34926, 34814, 34819, 34805, 34698, 34819, 34698, 34643, 6820, 6882, 7010, - 23153, 22973, 23231, 22389, 22330, 22444, 23153, 23231, 23290, 23603, 23727, 23775, 29900, - 29744, 29756, 29775, 29744, 29900, 35451, 35412, 35380, 35413, 35176, 35320, 7166, 7197, - 7219, 17037, 17023, 16722, 24397, 24687, 24647, 23742, 23603, 23775, 25682, 25588, 25691, - 25070, 25085, 25061, 24317, 24358, 24276, 23955, 23104, 23393, 7469, 7387, 7573, 7350, - 7262, 7443, 7490, 7787, 7733, 8914, 9154, 9021, 16400, 16529, 16461, 16842, 17037, - 16722, 17596, 17610, 17944, 17311, 17155, 17232, 17623, 17870, 17790, 17225, 17578, 17343, - 22515, 22444, 22610, 24121, 23955, 24217, 21956, 22095, 21946, 25200, 25085, 25117, 33163, - 32731, 33264, 33464, 33277, 33172, 33420, 33303, 33229, 34575, 34626, 34498, 34736, 34745, - 34595, 34764, 34745, 34736, 35342, 35220, 35140, 15299, 15740, 15312, 15777, 15937, 15941, - 25966, 25857, 25715, 25951, 25966, 26015, 6756, 6938, 6665, 6946, 7065, 7108, 23996, - 24167, 24277, 33719, 33478, 33596, 33296, 33226, 33218, 32905, 32900, 32868, 32868, 32900, - 32757, 10270, 10499, 10444, 10634, 10499, 10387, 9763, 10057, 9694, 31323, 31402, 30833, - 31400, 31380, 31323, 31514, 31533, 31400, 31559, 31533, 31514, 11550, 11335, 11635, 30782, - 30945, 30435, 30977, 30945, 30782, 35412, 35353, 35256, 35269, 35342, 35140, 35451, 35353, - 35412, 35659, 35533, 35052, 35503, 35413, 35320, 35339, 35320, 35321, 12087, 12639, 12627, - 13898, 14110, 13907, 12087, 12627, 12177, 29744, 29695, 29732, 29775, 29695, 29744, 30563, - 30180, 30753, 6670, 6673, 6757, 8520, 8569, 8313, 8171, 8282, 8063, 14110, 14203, - 14466, 14814, 14834, 14947, 15196, 15229, 15312, 13898, 14076, 14110, 14203, 14076, 13898, - 21316, 21647, 21515, 33296, 33218, 33384, 22574, 22515, 22610, 22610, 22733, 22716, 17610, - 17470, 17464, 17596, 17470, 17610, 23955, 24121, 24183, 25070, 24931, 24950, 24224, 23955, - 23998, 31685, 31514, 31551, 32905, 32868, 33031, 32731, 32880, 32794, 32980, 32880, 33163, - 7908, 8370, 8392, 7602, 7733, 7627, 7356, 7387, 7360, 14354, 14726, 14435, 17059, - 17155, 17204, 16330, 16159, 16366, 33420, 33229, 33277, 34291, 34209, 34158, 21647, 21754, - 21786, 9968, 9955, 9978, 9942, 9955, 9968, 10021, 9968, 10046, 10266, 10739, 10402, - 30768, 30513, 30475, 30768, 30654, 30513, 7360, 7387, 7469, 7490, 7733, 7602, 16114, - 16013, 15866, 16268, 16159, 16330, 28555, 28806, 28668, 30543, 30768, 30475, 28283, 28405, - 28290, 28444, 28405, 28283, 33277, 33229, 33172, 34931, 34926, 34852, 34866, 34819, 34643, - 25085, 25200, 25007, 25949, 25953, 25719, 24931, 24675, 24950, 34931, 34852, 34805, 17579, - 17870, 17623, 18050, 17870, 17936, 23440, 23153, 23290, 35353, 35323, 35256, 35459, 35323, - 35353, 7602, 7627, 7441, 15782, 15937, 15777, 16100, 15937, 15962, 25742, 25682, 25691, - 34745, 34701, 34595, 34589, 34138, 34226, 34755, 34701, 34745, 9955, 9879, 9978, 9052, - 9172, 9255, 29468, 30217, 30306, 34751, 33925, 34213, 34291, 34158, 34306, 6840, 6774, - 6978, 6455, 6602, 6477, 6816, 6774, 6840, 6840, 7267, 6772, 20869, 21071, 20939, - 22716, 22733, 22973, 6904, 7262, 7350, 7129, 7004, 7215, 6965, 7266, 7340, 7561, - 7321, 7653, 8063, 8282, 8068, 7087, 7266, 6857, 12024, 12016, 12063, 12098, 12024, - 12379, 11732, 11814, 11697, 6673, 6700, 6744, 6575, 6665, 6882, 9544, 9452, 9580, - 9656, 9763, 9694, 9656, 9694, 9667, 11732, 11550, 11829, 11335, 11117, 11268, 21754, - 21956, 21946, 30834, 30563, 31055, 35698, 35542, 35506, 35466, 35582, 35327, 7720, 7850, - 7845, 25857, 25742, 25691, 26015, 25901, 26527, 27067, 26527, 27384, 26163, 25953, 26007, - 26163, 26438, 26216, 34689, 34626, 34575, 6990, 7004, 7129, 6946, 7116, 7044, 8687, - 8546, 8931, 8569, 8493, 8313, 14953, 15229, 15158, 16327, 16494, 16657, 17470, 17437, - 17357, 17479, 17437, 17470, 26163, 26216, 26052, 26569, 26748, 26702, 27360, 27781, 27323, - 28118, 28214, 27996, 28444, 28630, 28405, 35086, 34853, 34775, 33226, 33239, 33031, 33584, - 33296, 33384, 33932, 33875, 33758, 33158, 33172, 32907, 6674, 6677, 6830, 6772, 7267, - 6891, 18377, 18528, 18319, 20569, 20297, 20216, 22389, 22444, 22515, 22617, 22716, 22690, - 22657, 22685, 22312, 7161, 7166, 7219, 16629, 16722, 16631, 17379, 17511, 17578, 16629, - 16631, 16529, 6700, 6709, 6869, 6906, 6984, 6756, 6938, 6984, 7034, 35542, 35539, - 35406, 6946, 6984, 6906, 11205, 11372, 11257, 32900, 32728, 32684, 32905, 32728, 32900, - 14203, 14354, 14435, 14834, 14953, 15158, 14203, 14110, 14076, 13907, 13676, 13898, 16240, - 16461, 16111, 16100, 16111, 15937, 7822, 8041, 7524, 8388, 8494, 8520, 12866, 12893, - 12639, 16197, 16100, 15962, 27548, 27451, 27493, 27854, 27548, 27694, 34871, 33951, 34787, - 34701, 34689, 34575, 8494, 8546, 8641, 8494, 8641, 8520, 28819, 28635, 28927, 35659, - 35052, 35751, 9679, 9453, 9230, 11184, 11117, 11335, 29468, 29790, 30217, 6674, 6978, - 6774, 6891, 7267, 7070, 33758, 33875, 33620, 33451, 33389, 33420, 16607, 16629, 16529, - 25200, 25348, 25326, 24950, 24675, 24826, 25851, 25742, 25857, 24647, 24687, 24676, 25851, - 25857, 25951, 34806, 34689, 34701, 6593, 6891, 7070, 35323, 35397, 35278, 35040, 34871, - 35298, 35459, 35397, 35323, 35413, 35513, 35384, 35487, 35321, 35089, 24121, 24268, 24183, - 24217, 24268, 24121, 6709, 6723, 6801, 12747, 12866, 12639, 28047, 27854, 27694, 29065, - 28819, 28927, 28630, 28806, 28555, 28630, 28555, 28405, 32880, 32980, 32907, 33170, 32980, - 33163, 33274, 33239, 33226, 33478, 33600, 33384, 33296, 33274, 33226, 33734, 33773, 33596, - 33773, 34221, 33879, 33685, 33964, 34328, 7841, 7822, 7578, 26771, 26748, 26569, 26910, - 26748, 26771, 35006, 34931, 34819, 34306, 34158, 33921, 8914, 9313, 9154, 20775, 20813, - 20869, 20775, 20739, 20813, 17479, 17596, 17944, 20813, 20986, 20869, 20986, 21071, 20869, - 21120, 21071, 20986, 21181, 21071, 21120, 20767, 20793, 21070, 21070, 21166, 21107, 21107, - 21166, 21316, 21509, 21637, 21647, 21647, 21637, 21754, 21754, 21817, 21956, 20569, 20720, - 20741, 19725, 19181, 19165, 35526, 35642, 35444, 35542, 35667, 35539, 35577, 35626, 35526, - 35566, 35626, 35577, 35631, 35626, 35566, 35631, 35566, 35521, 35631, 35521, 35691, 7262, - 7161, 7219, 7055, 6990, 7129, 7004, 6593, 7070, 7003, 7161, 7262, 7166, 7161, - 7003, 7404, 7387, 7356, 11550, 11491, 11335, 12016, 11732, 11829, 14097, 14426, 14220, - 20739, 20511, 20701, 19165, 19181, 19134, 21181, 21321, 21071, 20720, 20793, 20767, 29348, - 29178, 29476, 29873, 29775, 29900, 35626, 35642, 35526, 35691, 35521, 35509, 20511, 20477, - 20701, 21071, 21321, 20939, 31533, 31380, 31400, 31549, 31380, 31533, 20477, 20334, 20701, - 25905, 26015, 26016, 28819, 28469, 28276, 28255, 28047, 27985, 35642, 35639, 35444, 35756, - 35509, 35719, 20334, 20234, 20033, 22389, 22515, 22505, 27925, 28047, 27995, 6674, 6774, - 6608, 6723, 6691, 6859, 19095, 19165, 19134, 31685, 31551, 33066, 31446, 30560, 30945, - 31446, 31600, 30560, 33170, 33158, 32980, 31446, 30945, 31407, 30782, 30839, 30977, 35616, - 35582, 35466, 35616, 35466, 35539, 7706, 7845, 7882, 7469, 7513, 7360, 7706, 7882, - 7944, 10402, 10957, 10780, 9955, 9875, 9879, 9879, 9544, 9938, 10499, 10634, 10771, - 10387, 10499, 10270, 10932, 10634, 10638, 9927, 10273, 10387, 17870, 18050, 17879, 18788, - 18816, 18938, 17936, 17772, 17973, 17623, 17578, 17579, 35397, 35386, 35269, 35592, 35386, - 35397, 6602, 6767, 6762, 6718, 6543, 6697, 6559, 6670, 6488, 6673, 6522, 6700, - 6530, 6631, 6709, 6709, 6631, 6723, 6723, 6631, 6691, 21234, 21166, 21070, 21956, - 22061, 22095, 16170, 16268, 16274, 16159, 16013, 16114, 16492, 16607, 16529, 16749, 16842, - 16722, 16100, 16240, 16111, 16197, 16240, 16100, 34764, 34755, 34745, 35040, 35298, 35045, - 34926, 35086, 34775, 34819, 34931, 34805, 34358, 34319, 34345, 10021, 9942, 9968, 16170, - 16013, 16159, 34686, 34510, 34626, 35038, 34755, 34764, 19989, 19962, 19791, 7266, 7234, - 7437, 7087, 7234, 7266, 7340, 7099, 6965, 16492, 16529, 16400, 25070, 25117, 25085, - 25953, 26163, 26052, 25012, 25117, 25070, 6499, 6762, 6802, 6608, 6774, 6816, 6719, - 6816, 6772, 7055, 7129, 7166, 6984, 6946, 7044, 6984, 6938, 6756, 8506, 8196, - 8572, 8915, 9172, 9052, 8637, 9021, 8474, 8151, 8292, 8236, 17610, 18244, 17944, - 17059, 17040, 17155, 24403, 23996, 24277, 23085, 22973, 23153, 22505, 22574, 22617, 24403, - 24277, 24396, 35523, 35451, 35380, 9163, 9381, 9384, 9163, 9384, 9269, 19791, 19962, - 19725, 32980, 33158, 32907, 33439, 33451, 33420, 32880, 32731, 33163, 12866, 12964, 13015, - 12861, 12964, 12866, 16013, 15710, 15866, 24687, 24909, 24676, 25905, 25851, 25951, 25905, - 25951, 26015, 29371, 29238, 28905, 27960, 27996, 27837, 31582, 31533, 31559, 33235, 32905, - 33031, 6646, 6802, 6677, 7042, 6352, 6670, 11531, 11491, 11550, 11106, 10952, 11061, - 16749, 16722, 16629, 8171, 8151, 8236, 8063, 8151, 8171, 14220, 14426, 14474, 26016, - 26015, 26665, 27684, 27513, 27548, 27684, 27548, 27854, 22505, 22515, 22574, 22574, 22716, - 22617, 18227, 18377, 18319, 17578, 17225, 17379, 19781, 19791, 19725, 13676, 13643, 13404, - 14203, 14430, 14354, 14354, 14430, 14726, 8670, 8543, 8854, 12964, 13249, 13385, 18227, - 18319, 18050, 19165, 19781, 19725, 33417, 33420, 33277, 34291, 34358, 34345, 34419, 34306, - 34452, 34306, 33921, 34452, 9269, 9384, 9452, 25719, 25707, 25743, 11106, 11061, 11117, - 19090, 19781, 19165, 21509, 21647, 21316, 17183, 17225, 17037, 7003, 7055, 7166, 6990, - 6929, 7004, 7513, 7490, 7434, 11184, 11106, 11117, 11732, 11531, 11550, 11697, 11531, - 11732, 17043, 17183, 17037, 20800, 20869, 20862, 22716, 22973, 22905, 24647, 24676, 24671, - 27995, 28047, 28198, 28047, 27925, 27854, 27360, 27323, 27141, 26910, 26702, 26748, 33742, - 33773, 33734, 33239, 33235, 33031, 34686, 34626, 34689, 7434, 7490, 7602, 16268, 16170, - 16159, 16013, 15565, 15710, 17040, 16657, 17155, 16560, 16749, 16629, 17018, 17043, 17037, - 16325, 16492, 16400, 15782, 15777, 15709, 15782, 15709, 15703, 7234, 7238, 7437, 7087, - 7238, 7234, 16325, 16400, 16240, 34419, 34358, 34291, 7360, 7223, 7278, 12919, 13205, - 13249, 12754, 12747, 12562, 12861, 12754, 12919, 34755, 34806, 34701, 34937, 34806, 34755, - 34820, 34806, 34937, 11184, 11335, 11282, 29348, 29476, 29737, 28540, 28479, 28469, 28469, - 28479, 28255, 35386, 35342, 35269, 35592, 35342, 35386, 35451, 35459, 35353, 35720, 35459, - 35451, 8396, 8373, 8527, 8527, 8373, 8506, 8494, 8431, 8546, 8313, 8493, 8292, - 16560, 16629, 16607, 25743, 25707, 25326, 24826, 24467, 24358, 24378, 24358, 24268, 27960, - 28118, 27996, 33741, 33719, 33596, 33587, 33648, 33389, 8698, 8670, 9053, 8462, 8396, - 8527, 8576, 8670, 8698, 33451, 33587, 33389, 33454, 33417, 33277, 35915, 35698, 35506, - 35674, 35523, 35380, 18685, 18816, 18788, 20869, 20939, 20862, 22905, 22973, 23085, 23228, - 23225, 23085, 25826, 25682, 25742, 25892, 25905, 26016, 26007, 25949, 25922, 26771, 26569, - 26635, 34820, 34686, 34689, 11282, 11335, 11491, 11814, 11732, 12016, 11835, 12098, 11830, - 11282, 11491, 11508, 17294, 17379, 17225, 18017, 18050, 17936, 18142, 18227, 18050, 18377, - 18407, 18671, 17294, 17225, 17183, 24224, 24217, 23955, 24299, 24217, 24224, 17155, 17311, - 17204, 17018, 17037, 16842, 24515, 24403, 24396, 25826, 25742, 25851, 33719, 33600, 33478, - 33571, 33587, 33451, 14221, 14430, 14203, 14221, 14203, 13898, 18142, 18050, 18017, 31380, - 31408, 31323, 29737, 29695, 29775, 29124, 29065, 29241, 31549, 31408, 31380, 31549, 31533, - 31582, 30977, 30839, 30880, 31600, 31902, 31717, 35339, 35503, 35320, 35575, 35503, 35339, - 35487, 35089, 35483, 8155, 8313, 8292, 7625, 8063, 8068, 7841, 8068, 7822, 12098, - 12379, 12006, 14464, 14786, 15430, 31582, 31559, 31685, 35698, 35667, 35542, 10780, 10957, - 11061, 9922, 9875, 9942, 10780, 11061, 10952, 10780, 10952, 10879, 31498, 32684, 32797, - 31446, 31604, 31600, 10879, 10952, 11106, 11508, 11491, 11531, 26665, 26527, 27067, 27843, - 27684, 27854, 27671, 27684, 27783, 30376, 30306, 30217, 30880, 30839, 30768, 16170, 16168, - 16013, 14968, 14464, 15430, 16544, 16327, 16657, 16492, 16560, 16607, 16907, 17018, 16842, - 16135, 16325, 16240, 16135, 16240, 16197, 29259, 29065, 28927, 29476, 29695, 29737, 33464, - 33454, 33277, 33417, 33439, 33420, 32365, 32309, 32844, 12747, 12861, 12866, 13480, 13676, - 13404, 12747, 12187, 12562, 32797, 32684, 32728, 33431, 33274, 33296, 32940, 32797, 32728, - 7524, 8041, 7653, 9163, 9052, 9255, 9177, 9269, 9234, 9875, 9955, 9942, 14631, - 14767, 14726, 26569, 26438, 26496, 27960, 28005, 28118, 7167, 7291, 7500, 6966, 7099, - 7065, 15299, 15312, 15229, 21817, 22061, 21956, 30880, 30768, 30930, 31710, 31857, 31600, - 34806, 34820, 34689, 34676, 34443, 34510, 35038, 34764, 34871, 8934, 9052, 9163, 29737, - 29775, 29739, 6617, 6719, 6772, 6591, 6646, 6677, 6608, 6719, 6640, 7736, 7706, - 7944, 7720, 7478, 7850, 14870, 14953, 14834, 26496, 26438, 26163, 28540, 28469, 28819, - 29120, 28905, 28806, 28271, 28444, 28283, 28617, 28444, 28585, 33571, 33439, 33454, 34676, - 34510, 34686, 33773, 33741, 33596, 33780, 33589, 33600, 6843, 6966, 7065, 6832, 7065, - 6946, 9922, 9942, 10021, 18017, 17936, 17973, 18227, 18407, 18377, 24217, 24299, 24268, - 24378, 24299, 24433, 30543, 30475, 30358, 31857, 31902, 31600, 8053, 8292, 8151, 8388, - 8431, 8494, 13205, 13404, 13249, 28198, 28047, 28255, 33879, 33741, 33773, 33584, 33431, - 33296, 6591, 6677, 6674, 6691, 6549, 6820, 6530, 6709, 6453, 6938, 6918, 6665, - 35667, 35616, 35539, 35719, 35432, 35853, 35751, 35052, 35384, 7055, 6929, 6990, 6949, - 7003, 6875, 7003, 7262, 6875, 16907, 16842, 16749, 17035, 17294, 17183, 17579, 17578, - 17511, 25949, 26007, 25953, 25348, 25200, 25117, 25348, 25117, 25012, 20800, 20592, 20739, - 20739, 20592, 20511, 20511, 20410, 20477, 20477, 20410, 20334, 20334, 20353, 20234, 20234, - 20149, 19593, 20800, 20739, 20775, 20800, 20775, 20869, 21835, 22389, 22207, 20793, 20894, - 21070, 21166, 21509, 21316, 21637, 21711, 21754, 20720, 20694, 20793, 20569, 20628, 20720, - 20420, 20628, 20569, 20420, 20152, 20348, 20420, 20348, 20406, 19999, 19989, 19871, 29873, - 29900, 29964, 32940, 32728, 32905, 35642, 35837, 35639, 35639, 35915, 35506, 35698, 35849, - 35667, 35667, 35803, 35616, 35626, 35778, 35642, 35631, 35778, 35626, 35812, 35778, 35631, - 35812, 35631, 35691, 14953, 15166, 15229, 22550, 22389, 22505, 26758, 26496, 26163, 20592, - 20410, 20511, 20628, 20406, 20714, 19989, 19791, 19871, 20839, 20894, 20793, 23153, 23228, - 23085, 22617, 22550, 22505, 35625, 35327, 35582, 35459, 35592, 35397, 6612, 6543, 6718, - 6670, 6522, 6673, 6494, 6543, 6612, 6521, 6612, 6602, 20410, 20353, 20334, 6482, - 6521, 6602, 6567, 6591, 6674, 8372, 8196, 8506, 8462, 8527, 8543, 8576, 8543, - 8670, 8327, 8431, 8388, 11512, 11508, 11531, 10879, 11106, 11013, 11512, 11531, 11697, - 35616, 35625, 35582, 35803, 35625, 35616, 35422, 35366, 35853, 10634, 10932, 10895, 10057, - 9763, 9804, 16327, 16274, 16268, 16281, 16274, 16327, 20353, 20149, 20234, 25012, 25070, - 24950, 34871, 34787, 35298, 35038, 35040, 35045, 35853, 36233, 36080, 18187, 18407, 18227, - 17579, 17511, 17491, 33589, 33384, 33600, 33020, 32940, 32905, 7434, 7360, 7513, 7360, - 7434, 7223, 7167, 7500, 7238, 15782, 15962, 15937, 16455, 16560, 16492, 15845, 15962, - 15782, 34751, 34213, 34319, 35114, 35086, 34926, 16455, 16492, 16325, 35114, 34926, 34931, - 15166, 15299, 15229, 17035, 17183, 17043, 17424, 17294, 17123, 24671, 24403, 24515, 24671, - 24515, 24647, 24299, 24378, 24268, 23104, 22893, 23393, 27232, 27360, 27141, 27089, 27141, - 26910, 26879, 26910, 26771, 30376, 30543, 30358, 30376, 30358, 30306, 17491, 17511, 17379, - 15299, 15703, 15709, 25905, 25826, 25851, 25892, 25826, 25905, 6499, 6802, 6569, 12919, - 13249, 12964, 13480, 13205, 13088, 14767, 14870, 14834, 14953, 15061, 15166, 15166, 15061, - 15299, 14430, 14631, 14726, 14708, 14631, 14644, 14631, 14430, 14644, 28819, 29065, 29124, - 28540, 28819, 29118, 28540, 28362, 28479, 28479, 28362, 28255, 33780, 33600, 33719, 34463, - 34289, 33964, 33663, 33584, 33589, 34334, 34572, 34508, 34823, 34686, 34820, 8372, 8506, - 8373, 24378, 24826, 24358, 6425, 6959, 6697, 21234, 21509, 21166, 7706, 7638, 7720, - 7908, 7736, 7944, 14708, 14870, 14767, 18162, 18227, 18142, 17772, 17936, 17870, 34358, - 34493, 34319, 34306, 34419, 34291, 34134, 33921, 33875, 34134, 33875, 34216, 33758, 33648, - 33832, 35483, 35089, 35191, 35503, 35513, 35413, 27689, 27912, 27781, 6559, 6522, 6670, - 21509, 21616, 21637, 18162, 18142, 18017, 19045, 19095, 19134, 6966, 6965, 7099, 7134, - 7321, 7291, 6906, 6832, 6946, 6756, 6832, 6906, 7657, 7638, 7706, 17596, 17479, - 17470, 16281, 16168, 16274, 18879, 19133, 19593, 17579, 17772, 17870, 17424, 17491, 17379, - 17424, 17379, 17294, 26496, 26635, 26569, 26879, 26635, 26758, 26635, 26496, 26758, 29120, - 28806, 28887, 34419, 34493, 34358, 7003, 6929, 7055, 6949, 6929, 7003, 16274, 16168, - 16170, 16678, 16657, 17040, 17035, 17043, 17018, 16129, 16135, 16197, 16129, 16197, 15962, - 29737, 29587, 29348, 29964, 29900, 30834, 35040, 35038, 34871, 34787, 35480, 35298, 8698, - 9053, 8915, 8396, 8372, 8373, 29065, 29259, 29320, 28444, 28617, 28630, 28271, 28214, - 28118, 8335, 8372, 8396, 31408, 31402, 31323, 31524, 31402, 31408, 31524, 31408, 31549, - 31524, 31549, 31687, 31524, 31618, 31520, 31604, 31710, 31600, 31857, 31899, 31902, 31446, - 31527, 31604, 31253, 31407, 30945, 31527, 31407, 31610, 31075, 30977, 30880, 30930, 30768, - 30807, 22690, 22550, 22617, 22690, 22716, 22905, 31524, 31687, 31618, 7291, 7321, 7561, - 7167, 7238, 6956, 35038, 34937, 34755, 9804, 9763, 9721, 21616, 21711, 21637, 22657, - 22893, 22685, 31527, 31710, 31604, 32844, 32309, 32790, 10402, 9922, 10021, 9234, 9269, - 9452, 9765, 9922, 9861, 10387, 10479, 10634, 35700, 35513, 35503, 24676, 24909, 25682, - 27671, 27451, 27513, 34877, 34823, 34820, 21711, 21817, 21754, 6719, 6608, 6816, 6569, - 6802, 6646, 6640, 6719, 6617, 8322, 8462, 8543, 19233, 18879, 19593, 28223, 28271, - 28118, 10479, 10638, 10634, 11205, 11441, 11372, 9269, 9177, 9163, 9052, 8775, 8915, - 9765, 9879, 9875, 11106, 11184, 11013, 12098, 11814, 12016, 11835, 11814, 12098, 29873, - 29739, 29775, 29892, 29739, 29873, 8548, 8775, 8615, 8257, 8335, 8462, 29320, 29259, - 29348, 28887, 28806, 28630, 29249, 29120, 29264, 8196, 7908, 8392, 7575, 7720, 7638, - 7722, 7908, 8196, 8232, 8196, 8372, 33832, 33648, 33860, 34419, 34548, 34493, 6832, - 6843, 7065, 6743, 6843, 6832, 8775, 8698, 8915, 17479, 17361, 17437, 17281, 17361, - 17479, 17035, 17018, 16917, 17683, 17772, 17579, 17973, 18162, 18017, 24939, 25012, 24826, - 22685, 22296, 22312, 6569, 6646, 6464, 8313, 8327, 8388, 8063, 8053, 8151, 8005, - 8053, 8063, 8005, 8063, 7667, 9721, 9763, 9656, 9721, 9456, 9542, 27684, 27671, - 27513, 27843, 27854, 27925, 27843, 27925, 27895, 27925, 27995, 28046, 30807, 30768, 30543, - 34289, 34334, 33964, 34572, 34289, 34753, 6838, 6965, 6966, 17204, 17311, 17437, 16690, - 16749, 16560, 24676, 25682, 24797, 22715, 22690, 22817, 7206, 7524, 7653, 34823, 34676, - 34686, 34860, 34751, 34648, 34493, 34751, 34319, 34866, 35006, 34819, 8053, 8155, 8292, - 9721, 9656, 9456, 14631, 14708, 14767, 14870, 15061, 14953, 15845, 15782, 15703, 15943, - 16129, 15962, 14221, 13920, 14199, 17683, 17579, 17491, 20629, 20592, 20710, 23775, 23996, - 23742, 22312, 22296, 22061, 28255, 28362, 28198, 28046, 27995, 28198, 34134, 34452, 33921, - 8122, 8546, 8431, 11184, 11080, 11013, 15845, 15703, 15761, 16518, 16690, 16560, 30666, - 30807, 30543, 30666, 30543, 30730, 34970, 35006, 34866, 35555, 35483, 35191, 6464, 6646, - 6591, 33589, 33584, 33384, 32952, 32940, 33020, 33780, 33719, 33741, 33439, 33571, 33451, - 33454, 33439, 33417, 33172, 33158, 33464, 15761, 15703, 15299, 25472, 25743, 25326, 25472, - 25326, 25348, 25012, 24950, 24826, 17059, 16678, 17040, 16280, 16325, 16135, 24815, 24826, - 24781, 28198, 28362, 28424, 28585, 28794, 28617, 27912, 28005, 27960, 28148, 28005, 27912, - 28110, 28005, 28219, 33781, 33648, 33587, 11184, 11282, 11185, 30730, 30543, 30376, 11205, - 11257, 10932, 6608, 6567, 6674, 6617, 6772, 6891, 18407, 18685, 18671, 18543, 18685, - 18540, 6843, 6867, 6966, 6743, 6867, 6843, 6918, 6882, 6665, 17746, 18162, 17973, - 22657, 23393, 22893, 35720, 35592, 35459, 35674, 35451, 35523, 25821, 25682, 25826, 26061, - 26016, 26665, 28417, 28424, 28546, 29520, 29320, 29348, 32483, 32080, 31902, 6549, 6691, - 6631, 8462, 8335, 8396, 8257, 8462, 8322, 8209, 8327, 8313, 11185, 11282, 11508, - 13205, 13480, 13404, 12919, 12964, 12861, 17772, 17754, 17973, 17707, 17683, 17491, 17754, - 17707, 17746, 17123, 17294, 17035, 23393, 23881, 23955, 24224, 24433, 24299, 28424, 28362, - 28540, 28110, 28223, 28118, 33879, 33780, 33741, 33679, 33587, 33571, 33679, 33781, 33587, - 34676, 34589, 34443, 35213, 34853, 35086, 35487, 35575, 35339, 6875, 7262, 6904, 6540, - 6617, 6520, 7278, 7356, 7360, 16907, 16917, 17018, 24531, 23996, 24403, 25821, 25826, - 25892, 6453, 6709, 6700, 19712, 19233, 19593, 17281, 17204, 17361, 33464, 33158, 33541, - 20628, 20694, 20720, 20894, 21234, 21070, 21509, 21466, 21616, 21616, 21534, 21711, 21711, - 21807, 21817, 20714, 20694, 20628, 19871, 19791, 19781, 35778, 35872, 35642, 35866, 35674, - 35380, 35812, 35872, 35778, 35812, 35691, 35756, 35812, 35756, 35982, 35756, 35719, 35982, - 20353, 20253, 20149, 20149, 19988, 19593, 20410, 20431, 20353, 20592, 20490, 20410, 20629, - 20490, 20592, 21321, 21673, 20939, 20694, 20839, 20793, 6792, 7004, 6929, 6547, 6567, - 6608, 35866, 35327, 35625, 6543, 6448, 6697, 6559, 6476, 6522, 6382, 6453, 6700, - 6494, 6448, 6543, 6494, 6612, 6413, 6494, 6413, 6393, 11814, 11512, 11697, 11545, - 11512, 11814, 11478, 11569, 12174, 11421, 11569, 11478, 20490, 20431, 20410, 21321, 21362, - 21673, 29739, 29587, 29737, 29892, 29587, 29739, 30834, 29900, 30563, 31942, 31867, 31685, - 33235, 33274, 33485, 33632, 33431, 33584, 35366, 35533, 36233, 22207, 22389, 22550, 35872, - 35837, 35642, 15097, 15430, 15710, 16358, 16281, 16327, 16129, 16280, 16135, 16717, 16907, - 16749, 16096, 16280, 16129, 35038, 35074, 34937, 34937, 34877, 34820, 34823, 34974, 34676, - 34676, 34759, 34589, 34787, 35220, 35480, 35006, 35114, 34931, 35126, 35114, 35006, 6530, - 6549, 6631, 6453, 6549, 6530, 7223, 7434, 7602, 7478, 7720, 7575, 15862, 15943, - 15962, 15862, 15962, 15845, 36087, 35751, 35384, 35685, 35384, 35513, 6482, 6602, 6455, - 20431, 20253, 20353, 35837, 35855, 35639, 7625, 8068, 7841, 8053, 8073, 8155, 8126, - 8209, 8313, 7657, 7706, 7736, 29118, 28819, 29124, 33684, 33679, 33571, 35907, 35575, - 35487, 16678, 16544, 16657, 16635, 16544, 16678, 16635, 16678, 17059, 16455, 16518, 16560, - 20253, 20209, 20149, 35219, 35213, 35086, 27671, 27597, 27451, 27843, 27783, 27684, 27913, - 27783, 27843, 27895, 27925, 28046, 27895, 28239, 27913, 6867, 6838, 6966, 6956, 7238, - 7087, 7321, 7206, 7653, 6813, 6838, 6867, 17361, 17204, 17437, 17944, 18244, 18879, - 24528, 24433, 24198, 14736, 15061, 14870, 14199, 14644, 14430, 15628, 15761, 15237, 20908, - 21234, 20894, 22090, 22312, 22061, 26061, 25821, 25892, 25860, 25821, 26061, 34976, 34877, - 34937, 34751, 34912, 34643, 34821, 34912, 34751, 35909, 35533, 35659, 31055, 30563, 30753, - 31524, 31520, 31402, 31549, 31582, 31687, 31407, 31527, 31446, 31710, 31803, 31857, 31253, - 30945, 30977, 31075, 30880, 30930, 31075, 31170, 31113, 23922, 23998, 23881, 23881, 23998, - 23955, 11162, 11185, 11508, 10954, 11205, 10932, 19045, 19134, 18816, 19045, 18816, 18767, - 22010, 22061, 21817, 23385, 23608, 23393, 23969, 24065, 23998, 29320, 29241, 29065, 29223, - 29241, 29320, 29120, 29249, 28905, 28887, 28630, 28794, 28794, 28630, 28617, 27693, 27815, - 27696, 11569, 11706, 12087, 11421, 11706, 11569, 16717, 16749, 16690, 16917, 17123, 17035, - 24551, 24826, 24378, 25012, 25421, 25348, 7908, 7657, 7736, 7536, 7449, 7373, 10387, - 10475, 10479, 10479, 10536, 10638, 10707, 10890, 10932, 10355, 10475, 10387, 10355, 10387, - 10273, 31854, 31803, 31710, 34452, 34548, 34419, 34636, 34548, 34452, 34636, 34452, 34566, - 33932, 33758, 33832, 33860, 33648, 33781, 6352, 7042, 6959, 29587, 29520, 29348, 29846, - 29520, 29587, 31075, 30930, 30979, 30730, 30807, 30666, 31803, 31899, 31857, 7478, 7441, - 7627, 7383, 7441, 7478, 34860, 34821, 34751, 6602, 6762, 6477, 6762, 6499, 6477, - 6488, 6476, 6559, 18732, 17944, 18879, 19090, 19871, 19781, 21234, 21466, 21509, 6547, - 6608, 6475, 8335, 8232, 8372, 8257, 8232, 8335, 8540, 8576, 8698, 8126, 8313, - 8155, 8637, 8474, 8612, 19095, 19090, 19165, 18767, 18816, 18685, 28354, 28444, 28271, - 28005, 28110, 28118, 27689, 27781, 27360, 28354, 28415, 28504, 33780, 33663, 33589, 33966, - 33879, 34221, 33897, 33879, 33966, 33895, 33860, 33781, 11205, 11220, 11964, 11044, 11220, - 11205, 29790, 29468, 29238, 7657, 7575, 7638, 9922, 9765, 9875, 9861, 9922, 10007, - 10354, 10402, 10780, 10853, 10780, 10879, 10853, 10879, 10876, 14736, 14870, 14708, 6477, - 6499, 6424, 6575, 6882, 6820, 6756, 6743, 6832, 21466, 21534, 21616, 24531, 24403, - 24671, 22690, 22715, 22550, 6857, 7266, 6965, 7988, 8053, 8005, 25052, 25421, 25012, - 25743, 25812, 25949, 35045, 35051, 35038, 35279, 35051, 35045, 17057, 17123, 16917, 17683, - 17754, 17772, 18162, 18187, 18227, 24433, 24551, 24378, 23998, 24065, 24224, 23922, 23881, - 23798, 24613, 24531, 24671, 24613, 24671, 24676, 24815, 24939, 24826, 24559, 24551, 24528, - 15774, 15862, 15845, 15943, 16096, 16129, 16280, 16455, 16325, 16574, 16717, 16690, 16907, - 17057, 16917, 15774, 15845, 15761, 16281, 16248, 16168, 16544, 16471, 16327, 16496, 16471, - 16544, 16574, 16455, 16096, 34912, 34970, 34866, 35114, 35219, 35086, 35313, 34970, 35304, - 35213, 35555, 35191, 35700, 35503, 35575, 35206, 35219, 35114, 6540, 6608, 6640, 6424, - 6499, 6368, 6540, 6640, 6617, 11134, 11333, 11220, 11220, 11333, 11478, 6464, 6591, - 6496, 8548, 8540, 8698, 8428, 8540, 8389, 8775, 8666, 8615, 10876, 10879, 11013, - 16574, 16690, 16518, 21534, 21807, 21711, 24781, 24939, 24815, 28887, 29042, 29120, 29249, - 29371, 28905, 28354, 28271, 28223, 33797, 33895, 33781, 33454, 33684, 33571, 33729, 33464, - 33541, 33557, 33464, 33729, 34877, 34915, 34823, 34328, 33964, 34334, 34960, 34915, 34877, - 8202, 8431, 8327, 29264, 29371, 29249, 14221, 13898, 13920, 14644, 14736, 14708, 35700, - 35685, 35513, 35700, 35863, 35833, 27693, 27597, 27783, 27783, 27597, 27671, 27693, 27783, - 27913, 21807, 21815, 21817, 10929, 10876, 11013, 11080, 11184, 11185, 10707, 10932, 10638, - 30632, 30730, 30376, 30979, 31048, 31170, 8209, 8202, 8327, 7988, 8073, 8053, 7578, - 7822, 7524, 33830, 33663, 33780, 33557, 33684, 33454, 6838, 6775, 6965, 6732, 6743, - 6756, 11797, 11835, 11830, 11162, 11080, 11185, 32940, 32952, 32797, 33235, 33239, 33274, - 14648, 14736, 14644, 15628, 15774, 15761, 6949, 6858, 6929, 6875, 6858, 6949, 7404, - 7356, 6904, 7441, 7223, 7602, 7339, 7383, 7478, 8967, 9230, 9453, 10387, 10270, - 9927, 34821, 35122, 34912, 34648, 34751, 34493, 35915, 35849, 35698, 8073, 8126, 8155, - 25421, 25472, 25348, 25570, 25472, 25421, 33860, 33932, 33832, 34548, 34648, 34493, 34001, - 33932, 33860, 34970, 35126, 35006, 35168, 35126, 35313, 9610, 9544, 9879, 10890, 10954, - 10932, 16471, 16358, 16327, 16496, 16358, 16471, 16635, 16903, 16636, 17754, 17683, 17707, - 17491, 17555, 17707, 18251, 18187, 18162, 24531, 23742, 23996, 18743, 18767, 18685, 19045, - 19090, 19095, 22817, 22690, 22905, 22817, 22905, 22838, 7391, 7578, 7524, 7159, 7223, - 7119, 16096, 16455, 16280, 16455, 16574, 16518, 15094, 15299, 15061, 28870, 29042, 28887, - 28870, 28887, 28794, 34328, 34334, 34508, 35106, 34976, 34937, 21815, 22010, 21817, 22312, - 22579, 22657, 33485, 33274, 33431, 35849, 35803, 35667, 16496, 16635, 16636, 24939, 25052, - 25012, 24812, 25052, 24939, 24781, 24826, 24551, 12639, 12187, 12747, 12754, 12861, 12747, - 13920, 13898, 13734, 33879, 33897, 33780, 33302, 33154, 33235, 34463, 34589, 34759, 33797, - 33781, 33679, 11162, 11508, 11297, 10954, 11112, 11205, 12639, 12087, 11912, 11622, 11545, - 11814, 31687, 31582, 31867, 33154, 33020, 32905, 6382, 6700, 6522, 6440, 6575, 6820, - 6496, 6591, 6567, 6520, 6617, 6486, 6743, 6813, 6867, 6732, 6813, 6743, 6732, - 6756, 6650, 22838, 22905, 23011, 20800, 20862, 20834, 31055, 30753, 31402, 31582, 31685, - 31867, 31685, 33066, 31942, 36087, 35909, 35751, 35748, 35833, 35836, 35379, 35213, 35219, - 10540, 10354, 10780, 9765, 9610, 9879, 10600, 10780, 10853, 10823, 10853, 10876, 10475, - 10536, 10479, 10890, 10944, 10954, 10954, 10987, 11112, 10270, 9804, 9790, 24559, 24781, - 24551, 24551, 24433, 24528, 31075, 31253, 30977, 32046, 31899, 31803, 32046, 32033, 31899, - 31113, 31253, 31075, 31687, 31867, 31798, 6496, 6567, 6394, 10007, 9922, 10402, 28415, - 28354, 28223, 26879, 26771, 26635, 30979, 30930, 30807, 33815, 33797, 33684, 33684, 33797, - 33679, 10929, 10823, 10876, 11297, 11508, 11324, 34974, 34823, 34915, 14968, 15430, 15097, - 14220, 13791, 14097, 10440, 10536, 10475, 31899, 32033, 31902, 33464, 33557, 33454, 32046, - 31803, 31894, 35168, 35206, 35114, 35168, 35114, 35126, 6448, 6408, 6697, 6488, 6366, - 6476, 6227, 6382, 6522, 6279, 6408, 6448, 6393, 6448, 6494, 6612, 6521, 6413, - 6521, 6482, 6413, 6482, 6364, 6413, 6486, 6617, 6436, 6394, 6567, 6547, 6440, - 6820, 6549, 7167, 7134, 7291, 7068, 7134, 7167, 8073, 8027, 8126, 8126, 8027, - 8209, 7904, 7988, 8005, 20710, 20800, 20834, 20710, 20592, 20800, 20490, 20548, 20431, - 20431, 20376, 20253, 20253, 20206, 20209, 20209, 20029, 20149, 20862, 20939, 20834, 20834, - 20939, 20820, 20839, 20908, 20894, 21234, 21416, 21466, 21466, 21416, 21534, 21534, 21675, - 21807, 21807, 21897, 21815, 21897, 22090, 22010, 20694, 20714, 20839, 20406, 20628, 20420, - 20216, 20152, 20420, 22599, 22550, 22715, 23011, 22905, 23085, 26665, 26015, 26527, 28239, - 28046, 28198, 28417, 28198, 28424, 29241, 29223, 29124, 29631, 29223, 29320, 29631, 29320, - 29520, 29892, 29873, 29964, 29371, 29790, 29238, 29042, 29264, 29120, 29072, 29264, 29042, - 29874, 29892, 29958, 35051, 35074, 35038, 34976, 34960, 34877, 35279, 35074, 35051, 6408, - 6425, 6697, 22599, 22715, 22681, 20714, 20819, 20839, 11421, 11478, 11333, 14777, 14648, - 14667, 20601, 20406, 20348, 20819, 20908, 20839, 35855, 35915, 35639, 36169, 36022, 35803, - 35837, 35932, 35855, 35872, 35980, 35837, 36055, 35980, 35872, 36055, 35872, 35812, 35982, - 35719, 35853, 35982, 36137, 36086, 6425, 6352, 6959, 14736, 14777, 15061, 14271, 14648, - 14644, 13088, 13205, 12919, 20453, 20376, 20431, 19233, 18732, 18879, 6482, 6455, 6364, - 6475, 6608, 6540, 16717, 16666, 16907, 16666, 16574, 16580, 6455, 6269, 6364, 30632, - 30376, 30464, 31012, 30979, 30807, 32922, 32797, 32952, 33235, 33154, 32905, 33485, 33431, - 33630, 35980, 35932, 35837, 25821, 25860, 25682, 23290, 23603, 23440, 26061, 25892, 26016, - 25745, 25812, 25743, 25922, 25812, 25745, 25743, 25472, 25570, 6813, 6754, 6838, 6682, - 6754, 6813, 10929, 11013, 11080, 11324, 11508, 11512, 35909, 35659, 35751, 28354, 28585, - 28444, 7657, 7536, 7575, 7575, 7272, 7478, 7159, 7089, 7223, 7536, 7657, 7449, - 26758, 26163, 26007, 28354, 28504, 28585, 6455, 6240, 6269, 35932, 35915, 35855, 10536, - 10707, 10638, 22681, 22715, 22817, 23225, 23011, 23085, 6858, 6792, 6929, 6917, 7356, - 7278, 6789, 6857, 6965, 18909, 19090, 19045, 18909, 19045, 18767, 34039, 34001, 33895, - 33895, 34001, 33860, 33932, 34216, 33875, 20082, 20029, 20209, 11835, 11797, 11814, 11545, - 11324, 11512, 12379, 13003, 12006, 29583, 29790, 29371, 6341, 6366, 6488, 6264, 6440, - 6549, 20029, 19988, 20149, 10929, 11080, 11069, 31572, 31402, 31520, 9324, 9234, 9452, - 9324, 9452, 9544, 11341, 11324, 11545, 11069, 11080, 11162, 6499, 6569, 6368, 21281, - 21416, 21234, 29223, 29118, 29124, 29151, 29118, 29223, 8322, 8543, 8576, 8232, 8072, - 8196, 8428, 8576, 8540, 33897, 33830, 33780, 33966, 33830, 33897, 35206, 35379, 35219, - 35313, 35126, 34970, 33541, 33170, 33163, 34092, 34039, 33895, 7223, 7089, 7278, 7223, - 7441, 7226, 7134, 7189, 7321, 7068, 7189, 7134, 35074, 35106, 34937, 35223, 35106, - 35074, 11069, 11162, 11152, 11393, 11421, 11333, 10799, 10944, 10890, 6754, 6775, 6838, - 7188, 7321, 7189, 6682, 6775, 6754, 16358, 16248, 16281, 16635, 16496, 16544, 16635, - 17059, 16903, 35807, 35220, 35342, 35738, 35342, 35592, 35720, 35451, 35674, 21416, 21675, - 21534, 22359, 22579, 22312, 6264, 6549, 6453, 6650, 6756, 6473, 11797, 11622, 11814, - 13791, 13636, 14097, 20216, 19999, 20152, 18876, 18909, 18767, 18876, 18767, 18743, 25812, - 25922, 25949, 25570, 25421, 25572, 35223, 34960, 34976, 11044, 11205, 11112, 27265, 27689, - 27360, 12802, 13088, 12919, 12676, 12919, 12754, 28219, 28223, 28110, 28808, 28870, 28794, - 29264, 29527, 29371, 30464, 30376, 30217, 7606, 7625, 7841, 7606, 7841, 7578, 26914, - 27089, 26910, 26914, 26910, 26879, 14464, 13791, 14220, 23228, 23153, 23440, 22681, 22817, - 22756, 24632, 23742, 24531, 35870, 35720, 35674, 35866, 35625, 36022, 7464, 7606, 7578, - 14648, 14777, 14736, 16096, 15943, 15862, 14667, 14648, 14271, 26807, 26914, 26879, 34566, - 34452, 34622, 34860, 35122, 34821, 7991, 8027, 8073, 7991, 8073, 7988, 18251, 18407, - 18187, 19999, 19871, 20152, 17746, 17973, 17754, 22817, 22838, 22756, 22090, 22061, 22010, - 31618, 31572, 31520, 31698, 31572, 31618, 31698, 31618, 31687, 31698, 31687, 31798, 6368, - 6569, 6464, 6368, 6464, 6267, 11912, 12087, 11706, 33048, 32952, 33020, 33632, 33584, - 33663, 6956, 7087, 6766, 6682, 6732, 6573, 11152, 11297, 11324, 11152, 11162, 11297, - 10987, 11044, 11112, 30660, 30464, 30217, 10355, 10336, 10475, 10536, 10649, 10707, 10707, - 10745, 10890, 10944, 10987, 10954, 9790, 9804, 9542, 6875, 6792, 6858, 6823, 6792, - 6875, 24797, 24613, 24676, 24781, 24812, 24939, 24433, 24224, 24198, 11421, 11544, 11706, - 11424, 11544, 11421, 10273, 10336, 10355, 7536, 7468, 7575, 7373, 7468, 7536, 25980, - 26758, 26007, 34636, 34648, 34548, 6272, 6522, 6476, 8257, 8128, 8232, 8548, 8698, - 8775, 11694, 11622, 11797, 12383, 12006, 13003, 33746, 33632, 33663, 8026, 8128, 8112, - 28148, 28219, 28005, 33830, 33902, 33663, 34221, 33773, 33742, 33830, 33966, 33953, 6353, - 6593, 7004, 6358, 6475, 6540, 6738, 6823, 6875, 7226, 7441, 7383, 17491, 17424, - 17555, 9861, 9767, 9765, 9745, 9767, 9861, 10204, 10402, 10354, 10600, 10853, 10823, - 10817, 10823, 10929, 9542, 9804, 9721, 10336, 10440, 10475, 18116, 18251, 18162, 22756, - 22838, 22982, 23440, 23603, 23742, 32790, 32309, 32080, 31854, 31710, 31527, 31610, 31407, - 31522, 31407, 31253, 31522, 31253, 31113, 31302, 31012, 30730, 30816, 35700, 35748, 35685, - 35748, 35700, 35833, 6358, 6540, 6520, 19114, 18732, 19233, 17125, 17059, 17204, 20214, - 20264, 20152, 18543, 18743, 18685, 20820, 20710, 20834, 22838, 23011, 22982, 35976, 35866, - 36014, 11044, 11134, 11220, 11025, 11134, 11044, 17281, 17479, 17858, 16496, 16248, 16358, - 6267, 6464, 6208, 6382, 6349, 6453, 9767, 9750, 9765, 7188, 7206, 7321, 6789, - 6965, 6775, 25860, 24797, 25682, 27384, 27451, 27067, 11694, 11797, 11830, 28546, 28424, - 28540, 27693, 27696, 27597, 28219, 28415, 28223, 28808, 28794, 28585, 29892, 29874, 29587, - 28393, 28239, 28417, 30051, 29892, 29964, 33953, 33902, 33830, 10440, 10649, 10536, 6732, - 6682, 6813, 6650, 6473, 6573, 21897, 22010, 21815, 22982, 23011, 23225, 22207, 22550, - 22599, 6681, 6789, 6775, 12562, 12676, 12754, 14199, 14430, 14221, 12626, 12676, 12562, - 28541, 28585, 28504, 30914, 30650, 30981, 12255, 12626, 12562, 11134, 11230, 11333, 11025, - 11230, 11134, 17555, 17424, 17319, 17746, 18116, 18162, 23798, 23881, 23393, 23969, 23922, - 23937, 29321, 29527, 29264, 7667, 8063, 7625, 7667, 7904, 8005, 27025, 27089, 26914, - 27241, 27232, 27089, 27089, 27232, 27141, 28578, 28445, 28379, 28259, 28445, 28415, 27913, - 27843, 27895, 34165, 34216, 33932, 34636, 34836, 34648, 34165, 33932, 34001, 10649, 10745, - 10707, 7272, 7339, 7478, 36087, 35384, 35685, 6745, 7087, 6857, 6935, 7068, 7167, - 7904, 7991, 7988, 8764, 8967, 8914, 8914, 8967, 9453, 14777, 15094, 15061, 13676, - 13734, 13898, 25572, 25421, 25355, 27007, 26807, 26977, 26959, 27025, 26914, 24755, 24781, - 24559, 26807, 26879, 26758, 28239, 27895, 28046, 34622, 34452, 34134, 35326, 35206, 35168, - 8428, 8322, 8576, 8340, 8322, 8428, 28445, 28504, 28415, 28445, 28541, 28504, 33557, - 33815, 33684, 33784, 33815, 33557, 10998, 10817, 10929, 10727, 10817, 10608, 10745, 10799, - 10890, 6408, 6279, 6425, 6425, 6281, 6352, 6352, 6341, 6488, 6366, 6272, 6476, - 6382, 6319, 6349, 6284, 6279, 6448, 6284, 6448, 6393, 6284, 6393, 6413, 6284, - 6413, 6310, 6413, 6364, 6310, 20819, 20806, 20908, 20908, 20996, 21234, 21416, 21625, - 21675, 21675, 21897, 21807, 20714, 20740, 20819, 20406, 20601, 20714, 19090, 19029, 19871, - 20601, 20740, 20714, 36053, 36055, 35812, 35980, 36236, 35932, 35932, 36236, 35915, 36169, - 35803, 36671, 36053, 35812, 36068, 6279, 6281, 6425, 7013, 7188, 7189, 7380, 7464, - 7578, 7606, 7462, 7625, 9456, 9656, 9574, 8202, 8209, 8086, 20376, 20206, 20253, - 20029, 19952, 19988, 19988, 19712, 19593, 20629, 20548, 20490, 20710, 20548, 20629, 20820, - 20548, 20710, 22754, 22599, 22681, 20740, 20806, 20819, 33138, 33048, 33020, 33138, 33020, - 33154, 33508, 33235, 33485, 33508, 33485, 33536, 35326, 35379, 35206, 34836, 34860, 34648, - 20548, 20453, 20431, 36068, 35812, 35982, 8026, 8072, 8128, 8128, 8072, 8232, 7229, - 7226, 7339, 11458, 11341, 11545, 11230, 11393, 11333, 11388, 11393, 11230, 19090, 18909, - 19029, 20806, 20996, 20908, 26959, 26807, 27007, 36086, 36068, 35982, 23194, 22982, 23225, - 23574, 23440, 23742, 35720, 35738, 35592, 35924, 35738, 35720, 6310, 6364, 6269, 17125, - 17281, 16944, 35379, 35555, 35213, 20281, 20206, 20376, 19029, 18909, 18841, 20996, 21144, - 21234, 23922, 23969, 23998, 23798, 23608, 23835, 9002, 9163, 9177, 9002, 9177, 9007, - 29029, 29072, 28870, 28870, 29072, 29042, 33630, 33431, 33632, 6455, 6477, 6240, 6792, - 6353, 7004, 6917, 7278, 7089, 6917, 7089, 7007, 7339, 7226, 7383, 7119, 7226, - 7030, 16636, 16474, 16496, 17125, 16903, 17059, 20206, 20082, 20209, 23728, 23574, 23742, - 24803, 24797, 24968, 33496, 33302, 33235, 34960, 34974, 34915, 35081, 34974, 34960, 35223, - 34976, 35106, 35279, 35045, 35298, 6436, 6617, 6891, 6359, 6394, 6547, 6240, 6477, - 6424, 6436, 6891, 6395, 22756, 22754, 22681, 23313, 23225, 23228, 35866, 35870, 35674, - 35976, 35870, 35866, 14721, 15094, 14777, 16574, 16666, 16717, 22090, 22359, 22312, 22509, - 22359, 22232, 27659, 27451, 27597, 26061, 25941, 25860, 35108, 34759, 34676, 33953, 33904, - 33902, 6206, 6341, 6352, 8548, 8389, 8540, 8112, 8128, 8257, 12676, 12802, 12919, - 12574, 12802, 12676, 21144, 21281, 21234, 28676, 28808, 28585, 28676, 28585, 28541, 33746, - 33630, 33632, 33904, 33663, 33902, 11622, 11458, 11545, 11341, 11152, 11324, 11354, 11458, - 11367, 11458, 11428, 11367, 11393, 11424, 11421, 11388, 11424, 11393, 29874, 29846, 29587, - 30176, 30051, 29964, 30176, 29964, 30323, 32790, 32080, 32483, 10799, 10987, 10944, 21281, - 21404, 21416, 30464, 30650, 30632, 30829, 30650, 30914, 29583, 29371, 29527, 31942, 31798, - 31867, 33302, 33138, 33154, 23728, 23809, 23670, 23355, 23313, 23228, 6956, 6951, 7167, - 7068, 6968, 7189, 6825, 6951, 6956, 31302, 31113, 31277, 32483, 31902, 32033, 35391, - 35279, 35298, 6296, 6424, 6368, 6341, 6272, 6366, 19952, 19898, 19988, 6359, 6547, - 6475, 10303, 10204, 10354, 9767, 9749, 9750, 18841, 18909, 18876, 18841, 18876, 18743, - 18841, 18743, 18723, 31564, 31055, 31402, 31698, 31666, 31572, 31551, 32797, 32922, 31610, - 31854, 31527, 13100, 13480, 13088, 14667, 14696, 14777, 16542, 16474, 16636, 13640, 13575, - 13791, 6323, 6359, 6475, 6486, 6436, 6430, 10336, 10342, 10440, 10417, 10625, 10649, - 10649, 10625, 10745, 10745, 10625, 10799, 10799, 10650, 10987, 10273, 10250, 10336, 10198, - 10250, 10273, 12802, 13100, 13088, 17281, 17125, 17204, 16903, 16721, 16636, 16948, 17125, - 16944, 24198, 24224, 24065, 27696, 27659, 27597, 27754, 27659, 27696, 27815, 27693, 27913, - 28415, 28219, 28259, 31277, 31113, 31170, 32922, 32952, 33048, 31854, 31894, 31803, 33953, - 33966, 34073, 35870, 35794, 35720, 35976, 35794, 35870, 6756, 6402, 6473, 6682, 6681, - 6775, 6592, 6745, 6857, 6176, 6575, 6440, 6258, 6453, 6349, 23969, 24095, 24065, - 23937, 24095, 23969, 9327, 9324, 9544, 9637, 9765, 9750, 26031, 25941, 26061, 28239, - 28198, 28417, 27870, 27815, 28013, 31170, 31075, 30979, 34540, 34622, 34134, 34661, 34836, - 34636, 34461, 34134, 34216, 29072, 29321, 29264, 29372, 29321, 29358, 29029, 28870, 28808, - 11912, 11706, 11544, 12725, 13059, 13100, 16816, 16721, 16903, 19898, 19712, 19988, 21563, - 21625, 21416, 30051, 29958, 29892, 30131, 29958, 30051, 33147, 32922, 33048, 33334, 33147, - 33138, 33138, 33147, 33048, 33508, 33496, 33235, 33630, 33536, 33485, 33520, 33536, 33686, - 9745, 9749, 9767, 31048, 30979, 31012, 23355, 23228, 23440, 24632, 24531, 24613, 7524, - 7206, 7192, 7391, 7143, 7347, 8086, 8027, 7894, 26807, 26959, 26914, 27241, 27265, - 27232, 28259, 28219, 28148, 25980, 26007, 25922, 29372, 29583, 29527, 9749, 9637, 9750, - 31564, 31402, 31572, 31012, 30807, 30730, 8288, 8340, 8389, 8389, 8340, 8428, 8288, - 8389, 8270, 28578, 28676, 28541, 28578, 28541, 28445, 33904, 33746, 33663, 10727, 10600, - 10823, 11354, 11152, 11341, 8072, 7722, 8196, 8112, 8257, 8322, 29151, 28540, 29118, - 34092, 33895, 33797, 33853, 33797, 33815, 6358, 6520, 6486, 6267, 6296, 6368, 18723, - 18743, 18543, 20264, 20348, 20152, 7180, 7206, 7188, 9637, 9610, 9765, 10727, 10823, - 10817, 10342, 10649, 10440, 11264, 11388, 11230, 15565, 16013, 16168, 21625, 21897, 21675, - 24095, 24198, 24065, 24133, 24198, 24095, 23798, 23835, 23900, 30816, 30730, 30632, 30816, - 30632, 30650, 34661, 34636, 34566, 6584, 6681, 6682, 7007, 7089, 7159, 6951, 6935, - 7167, 6825, 6935, 6951, 6917, 6904, 7356, 6823, 6703, 6792, 9159, 9177, 9234, - 9206, 9234, 9324, 29958, 29846, 29874, 29995, 29846, 29958, 7119, 7223, 7226, 7119, - 7007, 7159, 25570, 25745, 25743, 25572, 25745, 25570, 24755, 24559, 24528, 35279, 35223, - 35074, 34974, 35108, 34676, 6464, 6496, 6208, 6227, 6319, 6382, 9456, 9574, 9415, - 9790, 9927, 10270, 10998, 10929, 11069, 23937, 23798, 23900, 9091, 9206, 9324, 23355, - 23440, 23601, 22926, 22754, 22756, 35748, 35836, 35685, 35700, 35575, 35863, 8213, 8112, - 8322, 8086, 8209, 8027, 8086, 7928, 8049, 34221, 33742, 34328, 33904, 33954, 33746, - 16721, 16670, 16636, 16474, 16248, 16496, 16564, 16670, 16721, 15628, 15862, 15774, 18685, - 18407, 18540, 20152, 20104, 20214, 18116, 17746, 17914, 35875, 35480, 35220, 35460, 35230, - 35223, 35505, 35658, 35549, 32844, 33264, 32731, 7229, 7339, 7272, 7046, 7180, 7188, - 25655, 24797, 25860, 26081, 26031, 26061, 25919, 26031, 26081, 33541, 33158, 33170, 35223, - 35081, 34960, 34572, 34334, 34289, 6291, 6496, 6394, 6319, 6258, 6349, 9415, 9230, - 8921, 9415, 9574, 9230, 30919, 30816, 30829, 34667, 34461, 34216, 34622, 34661, 34566, - 7484, 7667, 7625, 7462, 7606, 7464, 34289, 34463, 34753, 14271, 14696, 14667, 13438, - 13676, 13480, 13177, 13480, 13100, 27659, 27067, 27451, 27815, 27754, 27696, 27870, 27754, - 27815, 9002, 8934, 9163, 8340, 8213, 8322, 9007, 8934, 9002, 6738, 6703, 6823, - 6430, 6358, 6486, 9091, 9159, 9206, 9206, 9159, 9234, 11458, 11354, 11341, 11152, - 10998, 11069, 11694, 11830, 11774, 11424, 11452, 11544, 11025, 11044, 10987, 22926, 22756, - 22982, 24963, 24755, 24528, 24401, 24528, 24198, 28259, 28148, 28379, 29159, 29321, 29072, - 29321, 29372, 29527, 30323, 29964, 30834, 33784, 33853, 33815, 34039, 34165, 34001, 34425, - 34221, 34328, 17706, 17746, 17707, 23112, 22926, 22982, 23601, 23440, 23574, 23601, 23574, - 23728, 35836, 35897, 35685, 35863, 35575, 35907, 35487, 35483, 35731, 7364, 7462, 7464, - 7380, 7578, 7391, 14721, 14696, 14693, 15237, 15761, 15299, 34683, 34661, 34622, 6935, - 6920, 7068, 6773, 6920, 6935, 27241, 27025, 27096, 25355, 25421, 25052, 16360, 16248, - 16474, 35492, 35391, 35298, 35190, 35084, 35081, 34128, 34165, 34039, 22268, 22207, 22599, - 6983, 7013, 7189, 7347, 7380, 7391, 29631, 29151, 29223, 28013, 27815, 27913, 29631, - 29520, 29846, 7192, 7206, 7180, 9021, 8931, 8474, 30829, 30816, 30650, 29029, 28808, - 28861, 6592, 6857, 6789, 16670, 16542, 16636, 16564, 16542, 16670, 31666, 31564, 31572, - 30131, 30051, 30176, 31666, 31698, 31798, 31666, 31798, 31834, 31911, 31798, 31942, 31854, - 32059, 31894, 31894, 32059, 32046, 33777, 33541, 33264, 31610, 31704, 31854, 31522, 31704, - 31610, 31522, 31253, 31302, 31522, 31302, 31404, 31302, 31277, 31404, 31277, 31329, 31404, - 31170, 31048, 31150, 6430, 6436, 6395, 6359, 6291, 6394, 9593, 9790, 9542, 9720, - 9927, 9790, 10250, 10342, 10336, 22754, 22787, 22599, 23194, 23225, 23313, 31099, 31048, - 31012, 9397, 9327, 9544, 11009, 10998, 11152, 9927, 10198, 10273, 11264, 11452, 11388, - 20806, 20925, 20996, 20996, 21132, 21144, 21144, 21157, 21281, 21281, 21290, 21404, 21404, - 21563, 21416, 21625, 21672, 21897, 20740, 20667, 20806, 20601, 20667, 20740, 20348, 20667, - 20601, 20470, 20667, 20348, 20264, 20374, 20470, 31985, 31911, 31942, 36055, 36103, 35980, - 36053, 36103, 36055, 36206, 36103, 36215, 36215, 36053, 36068, 35982, 35853, 36137, 11388, - 11452, 11424, 11025, 10987, 10681, 21176, 20820, 20939, 20548, 20395, 20453, 20453, 20395, - 20376, 20206, 20124, 20082, 20082, 19952, 20029, 19898, 19908, 19712, 6281, 6216, 6352, - 6341, 6194, 6272, 6272, 6227, 6522, 6319, 6227, 6258, 6117, 6216, 6281, 6117, - 6281, 6279, 6117, 6279, 6284, 6235, 6284, 6310, 6235, 6310, 6191, 6310, 6269, - 6191, 8270, 8389, 8548, 33853, 34092, 33797, 33729, 33784, 33557, 34080, 33784, 34101, - 8202, 8122, 8431, 8027, 7991, 7894, 28693, 28808, 28676, 27265, 27360, 27232, 35833, - 35897, 35836, 35731, 35483, 35555, 11489, 11912, 11544, 12626, 12574, 12676, 20820, 20395, - 20548, 20395, 20281, 20376, 18834, 19029, 18841, 35081, 35084, 34974, 35108, 35084, 35310, - 34959, 35122, 34836, 34836, 35122, 34860, 35649, 35731, 35555, 36137, 35853, 36080, 17319, - 17424, 17123, 23798, 23937, 23922, 24133, 23937, 24016, 35649, 35555, 35379, 9749, 9652, - 9637, 9637, 9609, 9610, 9610, 9397, 9544, 10007, 9745, 9861, 10007, 10402, 10204, - 10540, 10780, 10600, 10540, 10600, 10525, 10300, 10342, 10250, 6191, 6269, 6240, 20925, - 21132, 20996, 24797, 24803, 24613, 25919, 25860, 25941, 24755, 24812, 24781, 25019, 24812, - 24963, 6146, 6206, 6352, 10508, 10799, 10625, 20281, 20124, 20206, 19712, 19506, 19233, - 16816, 16948, 16944, 16464, 16360, 16542, 21132, 21157, 21144, 23393, 23608, 23798, 35853, - 35366, 36233, 36022, 35625, 35803, 35794, 35924, 35720, 9745, 9652, 9749, 6240, 6424, - 6125, 6424, 6296, 6212, 8049, 8122, 8202, 21157, 21290, 21281, 33953, 33954, 33904, - 33520, 33508, 33536, 33520, 33496, 33508, 34073, 33954, 33953, 36137, 36080, 36160, 34461, - 34540, 34134, 34661, 34840, 34836, 34667, 34540, 34461, 7816, 7722, 8072, 7976, 8072, - 8026, 8025, 8026, 8112, 8194, 8213, 8123, 9159, 9007, 9177, 8988, 9007, 9159, - 30037, 29995, 29958, 30323, 30921, 30259, 6904, 6738, 6875, 6917, 6837, 6904, 6817, - 6837, 6760, 6763, 6917, 7007, 6948, 7007, 7119, 6766, 6825, 6956, 6920, 6968, - 7068, 6206, 6194, 6341, 7013, 7046, 7188, 6773, 6968, 6920, 9652, 9609, 9637, - 9199, 9091, 9324, 10525, 10600, 10727, 20124, 19952, 20082, 23342, 23194, 23313, 23670, - 23601, 23728, 27241, 27089, 27025, 25980, 25922, 25745, 30919, 31099, 31012, 30919, 31012, - 30816, 33536, 33630, 33767, 32922, 33066, 31551, 34508, 34425, 34328, 34221, 34073, 33966, - 34616, 34572, 34753, 35194, 34970, 34912, 7272, 7575, 7468, 27402, 27067, 27659, 27724, - 27870, 27851, 12255, 12574, 12626, 28693, 28676, 28578, 6658, 6789, 6681, 6627, 6766, - 6745, 6745, 6766, 7087, 35480, 35505, 35298, 35190, 35081, 35223, 35807, 35342, 35738, - 6263, 6291, 6359, 6154, 6453, 6258, 6154, 6264, 6453, 6650, 6573, 6732, 8637, - 8764, 8914, 8612, 8764, 8637, 19952, 19908, 19898, 27724, 27659, 27754, 34540, 34683, - 34622, 35746, 35649, 35379, 6943, 7046, 7013, 15237, 15299, 15094, 16666, 17057, 16907, - 26031, 25919, 25941, 26081, 26061, 26227, 35122, 35194, 34912, 35304, 35194, 35340, 6323, - 6263, 6359, 6395, 6891, 6593, 23937, 24133, 24095, 22359, 22090, 22232, 35976, 35924, - 35794, 36185, 35924, 35976, 6212, 6296, 6267, 21290, 21563, 21404, 8288, 8213, 8340, - 8775, 9052, 8666, 28379, 28445, 28259, 28813, 28693, 28578, 7449, 7657, 7908, 14696, - 14721, 14777, 14271, 14644, 14199, 14149, 14199, 13920, 6241, 6395, 6128, 6603, 6738, - 6904, 19908, 19742, 19712, 21563, 21672, 21625, 29790, 29583, 29779, 30217, 29790, 30520, - 36438, 35849, 35915, 11774, 11830, 12006, 11354, 11260, 11152, 10998, 10608, 10817, 11774, - 12006, 12099, 33334, 33138, 33302, 7051, 7192, 7180, 35084, 35108, 34974, 35223, 35279, - 35460, 30323, 30834, 30970, 6323, 6475, 6358, 6353, 6792, 6703, 23342, 23313, 23355, - 22926, 22787, 22754, 6957, 6948, 7119, 7351, 7306, 7468, 7392, 7484, 7462, 7462, - 7484, 7625, 7894, 7991, 7687, 8086, 8049, 8202, 7143, 7391, 7524, 14721, 14926, - 15094, 29029, 29159, 29072, 29358, 29159, 29236, 33575, 33334, 33302, 33840, 33630, 33746, - 33264, 33541, 33163, 34100, 34092, 33853, 34829, 34683, 35017, 33503, 33264, 32844, 9368, - 9397, 9610, 9456, 9415, 9542, 8921, 9230, 8967, 29779, 29583, 29699, 15928, 16096, - 15862, 16580, 16059, 16603, 35313, 35326, 35168, 35333, 35326, 35313, 6756, 6665, 6402, - 8050, 8025, 8112, 8474, 8931, 8421, 7894, 7661, 7854, 13059, 13177, 13100, 33954, - 33840, 33746, 34072, 34073, 34170, 6323, 6358, 6225, 6184, 6212, 6267, 16651, 17057, - 16666, 24722, 24632, 24613, 23112, 22982, 23194, 24722, 24613, 24803, 36022, 36067, 35866, - 36120, 36067, 36169, 6136, 6227, 6272, 6968, 6983, 7189, 7046, 7051, 7180, 6787, - 6983, 6968, 6943, 6983, 6887, 6935, 6825, 6773, 15036, 15097, 15565, 16542, 16360, - 16474, 16948, 16903, 17125, 25572, 25749, 25745, 25818, 25749, 25572, 25849, 25749, 25818, - 35194, 35304, 34970, 35335, 35304, 35340, 35505, 35492, 35298, 35549, 35492, 35505, 7306, - 7272, 7468, 11428, 11458, 11622, 13640, 13791, 14464, 15097, 15710, 15565, 30323, 30131, - 30176, 29995, 29937, 29846, 30259, 30131, 30323, 11694, 11428, 11622, 13575, 13636, 13791, - 29586, 29583, 29372, 9397, 9329, 9327, 6208, 6496, 6251, 13606, 14149, 13920, 14721, - 14803, 14926, 16580, 16651, 16666, 25849, 25980, 25745, 35230, 35190, 35223, 34753, 34463, - 34759, 35978, 35897, 35833, 35978, 35833, 35863, 35978, 35863, 35962, 14149, 14271, 14199, - 34572, 34616, 34508, 34753, 34759, 35211, 27870, 27724, 27754, 28084, 27913, 28239, 28546, - 28540, 29151, 6251, 6496, 6291, 6336, 6358, 6430, 9828, 10007, 10204, 9745, 9591, - 9652, 9652, 9591, 9609, 9609, 9514, 9610, 9397, 9223, 9329, 10303, 10354, 10540, - 36067, 36046, 35866, 36185, 35807, 35738, 36120, 36046, 36067, 31564, 31679, 31055, 31666, - 31834, 31564, 31911, 31834, 31798, 31679, 31834, 31889, 31704, 31841, 31854, 31522, 31841, - 31704, 32053, 31841, 31522, 31277, 31170, 31329, 31170, 31246, 31329, 28483, 28546, 28529, - 7364, 7464, 7380, 27007, 27025, 26959, 28148, 27912, 27689, 13438, 13734, 13676, 10198, - 10229, 10250, 10342, 10417, 10649, 9833, 10229, 10198, 9833, 10198, 9927, 31048, 31099, - 31150, 31841, 32059, 31854, 6573, 6584, 6682, 6445, 6584, 6573, 10990, 11009, 11152, - 17260, 17319, 17123, 17555, 17706, 17707, 18540, 18407, 18251, 17260, 17123, 17057, 7373, - 7351, 7468, 7306, 7043, 7272, 7504, 7449, 7908, 7504, 7908, 7722, 10229, 10300, - 10250, 14534, 14693, 14696, 14926, 15030, 15094, 27093, 27007, 26977, 31150, 31099, 31134, - 34683, 34840, 34661, 34829, 34840, 34683, 34402, 34216, 34165, 8666, 9052, 8934, 7996, - 7976, 8025, 8666, 8934, 8700, 8764, 8745, 8967, 8931, 8546, 8421, 12574, 12573, - 12802, 11912, 12187, 12639, 11216, 12187, 11912, 12321, 12476, 12512, 11544, 11452, 11489, - 7472, 7904, 7667, 8421, 8546, 8105, 13640, 14152, 13466, 28231, 28084, 28239, 6584, - 6658, 6681, 16816, 16832, 16729, 23670, 23468, 23601, 24712, 24722, 24968, 11367, 11260, - 11354, 11383, 11428, 11407, 30131, 30037, 29958, 30245, 30037, 30131, 33147, 33070, 32922, - 33254, 33070, 33147, 22830, 22926, 23112, 22830, 22787, 22926, 22207, 21673, 21362, 36046, - 36014, 35866, 36120, 36014, 36046, 36160, 36080, 36233, 35962, 35863, 35907, 17567, 17706, - 17555, 18723, 18834, 18841, 22509, 22579, 22359, 24963, 24812, 24755, 36185, 35738, 35924, - 36113, 35746, 36078, 35907, 35487, 35731, 35335, 35333, 35313, 35335, 35313, 35304, 8460, - 8745, 8764, 7242, 7351, 7373, 7347, 7353, 7380, 7236, 7353, 7347, 7143, 7524, - 7192, 34067, 33840, 33954, 33520, 33686, 33496, 34072, 33954, 34073, 7030, 7229, 6971, - 7030, 7226, 7229, 6666, 6642, 6738, 9498, 9591, 9745, 27093, 27096, 27007, 25749, - 25849, 25745, 25019, 25052, 24812, 31099, 30919, 31134, 31246, 31150, 31134, 35177, 34759, - 35108, 35460, 35279, 35391, 8025, 7976, 8026, 8050, 8112, 8213, 32483, 32033, 32419, - 6251, 6291, 6165, 16816, 16564, 16721, 16360, 16371, 16248, 16980, 17145, 17057, 16096, - 16580, 16574, 16651, 16580, 16603, 9591, 9514, 9609, 9199, 9324, 9327, 10608, 10525, - 10727, 18540, 18251, 18432, 22488, 22268, 22599, 23468, 23355, 23601, 6971, 7229, 7272, - 6943, 7051, 7046, 6943, 7013, 6983, 24983, 24968, 24797, 26227, 26061, 26665, 26227, - 26460, 26311, 6047, 6117, 6284, 6216, 6146, 6352, 6206, 6129, 6194, 6020, 6136, - 6272, 6047, 6284, 6235, 6190, 6235, 6191, 6190, 6191, 6240, 6190, 6017, 6102, - 17514, 17567, 17555, 17145, 17260, 17057, 30037, 29937, 29995, 30102, 29937, 30037, 36103, - 36236, 35980, 36215, 36103, 36053, 36215, 36068, 36086, 36215, 36086, 36210, 36086, 36137, - 36210, 23728, 23742, 23809, 36210, 36137, 36160, 35907, 35731, 35992, 6117, 6166, 6216, - 20264, 20470, 20348, 20843, 20925, 20806, 21132, 21233, 21157, 21157, 21233, 21290, 21290, - 21245, 21563, 21563, 21609, 21672, 20214, 20104, 20178, 35909, 36233, 35533, 6244, 6291, - 6263, 6125, 6424, 6212, 8194, 8050, 8213, 22488, 22599, 22787, 34170, 34073, 34240, - 34124, 34092, 34100, 34128, 34092, 34124, 20752, 20806, 20667, 36206, 36236, 36103, 6402, - 6119, 6280, 6504, 6592, 6658, 6445, 6473, 6416, 8421, 8332, 8468, 8612, 8460, - 8764, 12187, 12255, 12562, 13177, 13438, 13480, 11264, 11230, 11025, 18432, 18251, 18294, - 17514, 17555, 17319, 23900, 24016, 23937, 23855, 24016, 23900, 21825, 21897, 21672, 6738, - 6642, 6703, 6241, 6336, 6430, 6323, 6244, 6263, 6817, 6904, 6837, 17858, 17944, - 18732, 16948, 16816, 16903, 6166, 6146, 6216, 9199, 9327, 9329, 35909, 36280, 36233, - 12512, 12573, 12574, 33864, 33767, 33630, 33864, 33630, 33840, 8270, 8213, 8288, 8874, - 8934, 9007, 20124, 19998, 19952, 19952, 19967, 19908, 19908, 19786, 19742, 19742, 19636, - 19712, 20281, 20212, 20124, 20245, 20212, 20281, 20245, 20281, 20395, 20245, 20395, 20820, - 20152, 19871, 20104, 29953, 29631, 29846, 6241, 6430, 6395, 18543, 18834, 18723, 18251, - 18116, 18294, 27724, 27586, 27659, 28013, 27851, 27870, 28013, 27913, 28084, 28013, 28084, - 28226, 34735, 34425, 34508, 34735, 34508, 34616, 6146, 6129, 6206, 6665, 6119, 6402, - 21046, 21233, 21132, 35685, 36193, 36087, 6760, 6837, 6917, 6760, 6917, 6763, 9514, - 9368, 9610, 32419, 32033, 32046, 35492, 35460, 35391, 35549, 35460, 35492, 6969, 7143, - 7192, 36078, 35379, 35326, 35340, 35454, 35489, 6125, 6212, 6072, 20212, 19998, 20124, - 21233, 21245, 21290, 7854, 7928, 7894, 7364, 7392, 7462, 7364, 7380, 7353, 27007, - 27096, 27025, 27959, 27689, 27442, 26807, 26758, 26977, 28231, 28239, 28267, 35177, 35108, - 35315, 35253, 35190, 35230, 34840, 34910, 34836, 34910, 35015, 34959, 8270, 8548, 8312, - 16531, 16464, 16564, 16564, 16464, 16542, 19998, 19967, 19952, 36087, 36193, 36230, 7030, - 6957, 7119, 6948, 6957, 6808, 7026, 7113, 7143, 6773, 6825, 6643, 9091, 9020, - 9159, 8988, 9020, 8858, 11383, 11260, 11367, 10660, 10608, 10730, 11383, 11367, 11428, - 11428, 11694, 11407, 11279, 11264, 11183, 30245, 30259, 30610, 29937, 29953, 29846, 35332, - 35253, 35464, 17349, 17514, 17319, 16980, 17057, 16882, 35685, 35897, 36193, 7894, 7928, - 8086, 7472, 7667, 7484, 13279, 13438, 13177, 14323, 14271, 14149, 14534, 14696, 14500, - 14778, 14721, 14693, 18294, 18116, 18057, 17349, 17319, 17260, 28393, 28417, 28546, 17746, - 17706, 17914, 18566, 18834, 18543, 22729, 22488, 22787, 23342, 23112, 23194, 6658, 6592, - 6789, 6504, 6658, 6122, 8474, 8460, 8612, 8546, 8122, 8105, 19967, 19786, 19908, - 21245, 21609, 21563, 33767, 33686, 33536, 33903, 33686, 33767, 26081, 26047, 25919, 26227, - 26665, 26460, 7113, 7236, 7347, 7113, 7347, 7143, 22729, 22787, 22830, 22268, 22067, - 22207, 21825, 22090, 21897, 28483, 28393, 28546, 27689, 27265, 27442, 29099, 29159, 29029, - 29159, 29358, 29321, 34092, 34128, 34039, 33853, 34080, 34100, 8312, 8548, 8615, 23809, - 23742, 23858, 23468, 23342, 23355, 23742, 24241, 23858, 34019, 33864, 33840, 34019, 33840, - 34067, 35746, 35731, 35649, 36239, 35897, 35978, 9020, 8988, 9159, 7918, 7752, 7848, - 8935, 8988, 8858, 11147, 10990, 11152, 11407, 11694, 11539, 31441, 31523, 31329, 31329, - 31523, 31404, 31404, 31523, 31522, 31841, 32053, 32059, 32360, 32419, 32046, 31246, 31170, - 31150, 33575, 33302, 33496, 33070, 33066, 32922, 18566, 18543, 18540, 17914, 17706, 17472, - 6184, 6267, 6208, 6184, 6208, 6171, 6763, 7007, 6948, 6817, 6672, 6904, 35340, - 35194, 35454, 35727, 35326, 35333, 6473, 6445, 6573, 6136, 6258, 6227, 35489, 35333, - 35335, 6431, 6672, 6817, 6225, 6358, 6336, 16531, 16371, 16464, 16464, 16371, 16360, - 35658, 35505, 35744, 35332, 35190, 35253, 6225, 6244, 6323, 6225, 6336, 6139, 18566, - 18540, 18452, 9223, 9199, 9329, 11147, 11152, 11260, 27930, 27586, 27724, 27897, 27724, - 27851, 27897, 27851, 28013, 28226, 28084, 28231, 12725, 13100, 12802, 12725, 12802, 12573, - 12512, 12574, 12255, 6020, 6272, 6194, 19699, 19636, 19742, 21609, 21825, 21672, 7449, - 7242, 7373, 7351, 7242, 7306, 7292, 7504, 7722, 7816, 8072, 7976, 7996, 8025, - 8050, 7996, 8050, 8194, 27586, 27402, 27659, 9496, 9593, 9542, 10177, 10342, 10300, - 11279, 11452, 11264, 9496, 9542, 9415, 9496, 9415, 9363, 31134, 30919, 30957, 26083, - 26047, 26081, 26083, 26081, 26227, 27407, 27265, 27241, 6603, 6666, 6738, 8988, 8874, - 9007, 8935, 8874, 8988, 11256, 11147, 11260, 11539, 11694, 11774, 11322, 11489, 11452, - 10417, 10342, 10177, 23666, 23342, 23468, 22948, 22729, 22830, 24712, 24632, 24722, 24963, - 24528, 24401, 23393, 22657, 23385, 24198, 24133, 24401, 25849, 25818, 25980, 30245, 30102, - 30037, 28483, 28267, 28393, 30245, 30131, 30259, 29099, 29029, 28861, 30957, 30919, 30829, - 12612, 12512, 12476, 28813, 28808, 28693, 28813, 28578, 28832, 10177, 10300, 10229, 19636, - 19506, 19712, 30957, 30829, 30914, 27959, 28148, 27689, 36169, 36067, 36022, 36014, 36146, - 35976, 35744, 35505, 35480, 7428, 7472, 7484, 7258, 7364, 7353, 7258, 7353, 7117, - 34829, 34910, 34840, 34910, 34829, 35015, 32790, 32832, 32844, 32744, 32832, 32790, 32744, - 32790, 32483, 10417, 10508, 10625, 32600, 32419, 32546, 8270, 8123, 8213, 8580, 8615, - 8666, 28861, 28813, 28832, 17477, 17706, 17567, 17212, 17349, 17260, 17212, 17260, 17145, - 16882, 17057, 16651, 16580, 16096, 16059, 24968, 24722, 24803, 28393, 28267, 28239, 28546, - 29095, 28708, 6635, 6825, 6766, 6685, 6969, 7051, 6627, 6745, 6592, 14778, 14803, - 14721, 14696, 14271, 14500, 14158, 14165, 14323, 6171, 6208, 6251, 6539, 6703, 6642, - 11369, 11539, 11463, 11256, 11260, 11383, 22520, 22067, 22268, 22948, 22830, 23112, 23666, - 23468, 23670, 23075, 23342, 23279, 33334, 33254, 33147, 33558, 33254, 33334, 33575, 33496, - 33686, 36120, 36146, 36014, 36187, 36146, 36120, 6665, 6575, 6119, 6504, 6627, 6592, - 10608, 10998, 10730, 10525, 10422, 10540, 9498, 9514, 9591, 9335, 9368, 9514, 9226, - 9223, 9368, 9368, 9223, 9397, 10422, 10608, 10474, 23835, 23855, 23900, 23838, 23855, - 23835, 30650, 30464, 30981, 6171, 6251, 6165, 21818, 22067, 22520, 6787, 6887, 6983, - 25623, 25818, 25572, 27096, 27260, 27241, 11256, 11383, 11407, 6666, 6539, 6642, 6672, - 6603, 6904, 6614, 6603, 6672, 6616, 6627, 6531, 8421, 8468, 8474, 8032, 8122, - 7955, 15928, 15862, 15628, 7918, 7996, 8194, 28708, 28991, 28633, 34128, 34245, 34165, - 34245, 34124, 34230, 8700, 8580, 8666, 7777, 7871, 7918, 29358, 29586, 29372, 29699, - 29586, 29718, 29236, 29159, 29099, 6165, 6291, 6147, 6030, 6154, 6258, 29985, 29790, - 29779, 36230, 36244, 35909, 36230, 35909, 36087, 6969, 7192, 7051, 14803, 15030, 14926, - 24983, 24797, 25655, 26311, 26083, 26227, 20584, 20470, 20374, 18452, 18540, 18432, 18452, - 18432, 18294, 17186, 17212, 17145, 17477, 17567, 17514, 16964, 17145, 16980, 7428, 7484, - 7392, 7955, 8122, 8049, 7428, 7392, 7344, 20584, 20752, 20667, 20925, 21046, 21132, - 21267, 21368, 21245, 21245, 21368, 21609, 21609, 21526, 21825, 20584, 20667, 20470, 20264, - 20214, 20374, 20374, 20214, 20178, 36206, 36348, 36236, 36671, 35803, 35849, 36215, 36307, - 36206, 36315, 36307, 36215, 36315, 36215, 36210, 36315, 36210, 36352, 36210, 36160, 36352, - 6550, 6539, 6666, 10998, 11009, 10730, 11200, 11256, 11407, 11489, 11269, 11912, 11183, - 11264, 11025, 16745, 16882, 16651, 20752, 20843, 20806, 30970, 30834, 31055, 30102, 30028, - 29937, 33092, 33066, 33070, 7423, 7428, 7344, 8856, 8935, 8858, 8874, 8778, 8934, - 9498, 9745, 9488, 19871, 20112, 20104, 20843, 20980, 20925, 36263, 36160, 36233, 7955, - 8049, 7928, 28529, 28708, 28633, 13575, 12535, 13003, 14152, 14464, 14968, 13522, 13640, - 13466, 20212, 20001, 19998, 19998, 20001, 19967, 19967, 19973, 19786, 19786, 19699, 19742, - 19636, 19596, 19506, 20897, 20245, 20820, 20980, 21046, 20925, 6038, 6047, 6235, 5892, - 6146, 6166, 5981, 6129, 6146, 5981, 6056, 6129, 6129, 6056, 6194, 6136, 6030, - 6258, 6038, 6235, 6190, 6038, 6190, 6102, 6240, 6017, 6190, 13196, 13734, 13438, - 14803, 14828, 15030, 15217, 15237, 15152, 15030, 15237, 15094, 19871, 19029, 20112, 26977, - 26758, 26626, 27959, 28101, 28148, 31834, 31679, 31564, 31889, 31834, 31985, 31985, 31834, - 31911, 35310, 35084, 35190, 34073, 34221, 34564, 35310, 35190, 35332, 6685, 7051, 6943, - 6773, 6787, 6968, 6472, 6787, 6773, 15518, 15928, 15628, 16603, 16745, 16651, 23075, - 22948, 23112, 22729, 22773, 22488, 23075, 23112, 23342, 32151, 31985, 32545, 6240, 6125, - 6106, 20166, 20104, 20112, 6147, 6291, 6177, 6106, 6125, 6072, 9593, 9720, 9790, - 10523, 10650, 10508, 9496, 9720, 9593, 19432, 19114, 19506, 19506, 19114, 19233, 16816, - 16729, 16564, 36280, 36263, 36233, 36001, 35978, 35962, 7687, 7991, 7904, 13522, 13478, - 13575, 28280, 28267, 28483, 28280, 28226, 28267, 28267, 28226, 28231, 27354, 27309, 27402, - 26460, 26665, 26565, 6212, 6019, 6072, 6363, 6614, 6672, 6603, 6550, 6666, 6363, - 6672, 6431, 6763, 6948, 6808, 6627, 6616, 6766, 6658, 6584, 6122, 20245, 20001, - 20212, 29114, 29236, 29099, 28861, 28808, 28813, 32682, 32744, 32483, 33853, 33784, 34080, - 33807, 33575, 33686, 33254, 33092, 33070, 33903, 33767, 33864, 33954, 34072, 34170, 36280, - 35909, 36244, 17477, 17514, 17349, 23599, 23608, 23385, 24260, 24133, 24016, 23619, 23608, - 23599, 22232, 22090, 21825, 35907, 36001, 35962, 36121, 36001, 35907, 7260, 7242, 7449, - 7260, 7449, 7228, 14650, 14778, 14693, 9020, 9091, 9023, 11279, 11322, 11452, 11183, - 11322, 11279, 5981, 6146, 5892, 20001, 19973, 19967, 21219, 21245, 21233, 6402, 6416, - 6473, 6299, 6416, 6402, 8021, 8105, 8032, 8032, 8105, 8122, 13059, 13279, 13177, - 12612, 12725, 12573, 12612, 12573, 12512, 17436, 17477, 17349, 17226, 17349, 17212, 28832, - 28986, 28866, 28832, 28578, 28379, 34073, 34564, 34240, 6212, 6044, 6019, 6177, 6291, - 6244, 6177, 6244, 6062, 7996, 7871, 7976, 7816, 7871, 7777, 13196, 13279, 13047, - 34124, 34245, 34128, 33729, 34101, 33784, 6056, 6020, 6194, 18383, 18452, 18268, 18566, - 18593, 18834, 21368, 21481, 21609, 22910, 22773, 22729, 23666, 23670, 23809, 36342, 36280, - 36578, 6458, 6504, 6122, 15237, 15435, 15628, 15518, 15435, 15341, 17858, 17479, 17944, - 15565, 16168, 16248, 16882, 16964, 16980, 16798, 16745, 16794, 23858, 23666, 23809, 24838, - 24968, 24972, 25019, 25355, 25052, 23943, 24016, 23855, 35253, 35551, 35464, 9488, 9745, - 10007, 8856, 8778, 8935, 8921, 8967, 8745, 32360, 32046, 32059, 32419, 32600, 32483, - 31246, 31441, 31329, 31134, 31259, 31246, 31153, 31259, 31134, 31153, 31134, 30957, 31441, - 31259, 31248, 21481, 21526, 21609, 10608, 10422, 10525, 11027, 10990, 11147, 17945, 17858, - 18732, 23742, 24632, 24241, 23608, 23619, 23835, 22657, 22579, 23385, 6184, 6044, 6212, - 6076, 6177, 6062, 36438, 35915, 36236, 35744, 35480, 35875, 36336, 36193, 36335, 36342, - 36263, 36280, 6064, 6044, 6184, 22067, 21673, 22207, 21735, 21673, 22067, 7854, 7955, - 7928, 8935, 8778, 8874, 7871, 7996, 7918, 8700, 8778, 8706, 28708, 28529, 28546, - 28546, 29151, 29095, 30208, 30028, 30102, 30208, 30102, 30245, 35211, 34759, 35177, 34735, - 34616, 34753, 33729, 33541, 34101, 6128, 6395, 6593, 6808, 6957, 7030, 35340, 35489, - 35335, 35746, 35992, 35731, 35454, 35194, 35122, 7428, 7423, 7472, 7502, 7687, 7904, - 7788, 7913, 7955, 7344, 7392, 7364, 7344, 7364, 7258, 14534, 14650, 14693, 14778, - 14828, 14803, 14323, 14149, 14158, 27260, 27407, 27241, 27442, 27407, 27420, 6616, 6635, - 6766, 7353, 7236, 7117, 6566, 6635, 6616, 35549, 35621, 35460, 36185, 35976, 36146, - 11200, 11027, 11147, 11200, 11147, 11256, 10905, 10948, 10773, 19921, 19699, 19786, 28861, - 29114, 29099, 29718, 29586, 29358, 29586, 29699, 29583, 28976, 29114, 28861, 34019, 33903, - 33864, 34069, 33903, 34019, 7502, 7904, 7472, 28012, 27897, 28013, 28012, 28013, 28252, - 29783, 29699, 29718, 7236, 7113, 7117, 14323, 14500, 14271, 13478, 13332, 13575, 13640, - 13522, 13575, 13332, 13466, 13132, 34288, 34165, 34245, 34288, 34402, 34165, 34910, 34959, - 34836, 6171, 6064, 6184, 6539, 6353, 6703, 6450, 6550, 6603, 6497, 6550, 6450, - 16729, 16661, 16564, 16774, 16661, 16729, 24963, 25002, 25019, 27260, 27096, 27093, 25176, - 25002, 24963, 10730, 11009, 10990, 10508, 10650, 10799, 10471, 10508, 10417, 33503, 32844, - 33473, 32053, 31522, 31523, 28832, 28509, 28986, 34170, 34067, 33954, 32863, 32832, 32744, - 34230, 34288, 34245, 7228, 7449, 7504, 7043, 6971, 7272, 6943, 6887, 6685, 14504, - 14650, 14534, 35015, 34829, 35017, 30028, 29953, 29937, 30093, 29953, 30028, 6171, 6082, - 6064, 6176, 6440, 6264, 5995, 6030, 6136, 7871, 7816, 7976, 8123, 7752, 7918, - 13522, 13332, 13478, 28675, 28280, 28483, 28279, 28280, 28675, 34230, 34124, 34100, 7043, - 7306, 7242, 6685, 6887, 6645, 24972, 24968, 24983, 26665, 27067, 27188, 35310, 35315, - 35108, 35329, 35315, 35310, 10905, 10730, 10990, 32600, 32682, 32483, 6282, 6353, 6539, - 7026, 7117, 7113, 14607, 14828, 14778, 6165, 6076, 6082, 6171, 6165, 6082, 8468, - 8460, 8474, 8110, 8332, 8421, 8110, 8421, 8105, 19596, 19432, 19506, 19114, 18919, - 18732, 33401, 33092, 33254, 33903, 33807, 33686, 33833, 33807, 34004, 16968, 16944, 17281, - 16798, 16964, 16882, 17951, 18057, 17914, 18383, 18593, 18452, 16798, 16882, 16745, 15996, - 16096, 15928, 15996, 15928, 15885, 15518, 15628, 15435, 25176, 25355, 25019, 34311, 34230, - 34100, 12725, 12650, 13059, 14158, 14149, 14043, 12476, 12321, 12341, 6458, 6531, 6504, - 6504, 6531, 6627, 6176, 6264, 5908, 23018, 22948, 23075, 24583, 24632, 24712, 36001, - 36126, 35978, 36121, 35992, 36191, 22910, 22729, 22948, 22910, 22948, 23018, 31464, 30970, - 31055, 31889, 31813, 31679, 31779, 31813, 31896, 31813, 31889, 31962, 36169, 36187, 36120, - 36595, 36187, 36169, 31755, 32053, 31523, 32600, 32689, 32682, 6165, 6147, 6076, 8575, - 8921, 8745, 32211, 32151, 32335, 33558, 33334, 33575, 8778, 8700, 8934, 9091, 9199, - 9023, 6325, 6445, 6416, 6635, 6643, 6825, 16661, 16531, 16564, 16618, 16531, 16661, - 35551, 35230, 35460, 35875, 35220, 35807, 7117, 6958, 7050, 6969, 7026, 7143, 15217, - 15435, 15237, 35621, 35549, 35658, 35280, 34735, 34753, 34170, 34264, 34067, 35283, 35177, - 35315, 27407, 27442, 27265, 27260, 27093, 27299, 6076, 6147, 6177, 9833, 10177, 10229, - 9833, 9927, 9720, 29442, 29151, 29631, 31259, 31441, 31246, 31153, 30957, 31038, 26758, - 25980, 26626, 5908, 6264, 6154, 7687, 7661, 7894, 8355, 8468, 8332, 7534, 7661, - 7687, 7660, 7661, 7534, 7472, 7355, 7421, 7423, 7355, 7472, 7344, 7355, 7423, - 11200, 11407, 11369, 11027, 10905, 10990, 17186, 17226, 17212, 17186, 17145, 16964, 18452, - 18593, 18566, 18057, 18116, 17914, 23279, 23342, 23382, 21818, 21735, 22067, 27897, 27930, - 27724, 28252, 28013, 28226, 28252, 28226, 28280, 9498, 9477, 9514, 9828, 9488, 10007, - 10303, 10540, 10422, 10303, 10422, 10244, 10608, 10660, 10474, 10474, 10660, 10553, 17472, - 17706, 17477, 32242, 32360, 32059, 16944, 16832, 16816, 16968, 16832, 16944, 16794, 16745, - 16603, 24968, 24838, 24712, 26200, 26047, 26083, 8355, 8460, 8468, 8021, 8032, 7932, - 33807, 33713, 33575, 33833, 33713, 33807, 33807, 33903, 34004, 6280, 6299, 6402, 6249, - 6299, 6280, 7260, 7112, 7242, 7145, 7228, 7504, 9023, 9199, 9119, 29700, 29442, - 29631, 30286, 30208, 30245, 20752, 20783, 20843, 20843, 20960, 20980, 20980, 20960, 21046, - 21046, 21219, 21233, 21368, 21409, 21481, 21481, 21543, 21526, 20749, 20783, 20752, 20593, - 20752, 20584, 20488, 20584, 20374, 20488, 20374, 20325, 20374, 20178, 20325, 15152, 15237, - 15030, 20325, 20178, 20166, 21814, 22232, 21825, 21814, 21825, 21526, 27309, 27067, 27402, - 26311, 26200, 26083, 28279, 28252, 28280, 36542, 36348, 36206, 36448, 36206, 36307, 36448, - 36307, 36315, 36352, 36160, 36263, 20166, 20178, 20104, 20783, 20960, 20843, 36348, 36361, - 36236, 9488, 9477, 9498, 32360, 32430, 32419, 16059, 15885, 15801, 15518, 15885, 15928, - 16328, 16794, 16603, 6566, 6643, 6635, 6566, 6616, 6531, 29699, 29783, 29779, 29718, - 29358, 29455, 29358, 29236, 29455, 35815, 35621, 35658, 9119, 9199, 9223, 20112, 19029, - 20063, 36469, 36352, 36421, 36342, 36578, 36451, 7913, 8032, 7955, 12612, 12650, 12725, - 12646, 12650, 12612, 12255, 12321, 12512, 28832, 28866, 28861, 28509, 28379, 28148, 25942, - 25980, 25818, 6763, 6716, 6760, 6550, 6497, 6539, 6971, 6808, 7030, 6590, 6808, - 6597, 25946, 25942, 25818, 35489, 35727, 35333, 35841, 35454, 35878, 5892, 6166, 6117, - 6056, 5984, 6020, 6020, 5984, 6136, 5615, 5643, 6154, 5892, 5528, 5678, 5802, - 6047, 6038, 5802, 6038, 6102, 6017, 6240, 6106, 6017, 6106, 5972, 6106, 6072, - 5972, 6072, 6019, 5972, 6019, 5819, 5972, 7060, 6877, 6847, 7918, 8194, 8123, - 10553, 10660, 10730, 10177, 10471, 10417, 10681, 11183, 11025, 18736, 19029, 18834, 20960, - 21219, 21046, 31248, 31153, 31038, 32430, 32546, 32419, 32682, 32863, 32744, 35744, 35761, - 35658, 35815, 35761, 35744, 23553, 23599, 23385, 23619, 23838, 23835, 25623, 25572, 25355, - 36121, 36126, 36001, 36421, 36342, 36451, 36121, 35907, 35992, 21219, 21267, 21245, 17192, - 17186, 16964, 17436, 17472, 17477, 17192, 16964, 16982, 30208, 30093, 30028, 29972, 30093, - 30196, 19973, 19921, 19786, 19699, 19596, 19636, 20001, 19928, 19973, 20245, 19928, 20001, - 19826, 20107, 19589, 6299, 6325, 6416, 6198, 6325, 6299, 10471, 10523, 10508, 17436, - 17349, 17226, 26360, 26200, 26311, 26360, 26311, 26460, 35332, 35329, 35310, 35464, 35329, - 35332, 14828, 14921, 15030, 15217, 15173, 15435, 14753, 14921, 14828, 14607, 14778, 14650, - 14504, 14534, 14500, 14305, 14500, 14323, 6062, 6244, 6225, 6019, 6044, 5978, 6139, - 6336, 6241, 6450, 6603, 6614, 6128, 6139, 6241, 15565, 16248, 15814, 16832, 16774, - 16729, 16889, 16774, 16832, 16059, 16096, 15996, 24766, 24583, 24712, 25860, 25919, 25655, - 35952, 35875, 35807, 6128, 6593, 6045, 18268, 18452, 18294, 18593, 18738, 18834, 18268, - 18294, 18057, 8312, 8615, 8580, 8483, 8580, 8700, 34732, 34221, 34425, 6044, 6064, - 5978, 8102, 8355, 8332, 8460, 8377, 8745, 19928, 19921, 19973, 29896, 29631, 29953, - 28675, 28483, 28529, 36244, 36578, 36280, 29783, 29985, 29779, 29455, 29236, 29394, 8102, - 8110, 8090, 8021, 8110, 8105, 11269, 11489, 11322, 13047, 13279, 13059, 29442, 29095, - 29151, 5917, 5984, 6056, 21409, 21543, 21481, 31464, 31055, 31679, 32546, 32689, 32600, - 34402, 34667, 34216, 34959, 35876, 35122, 34837, 34667, 35005, 34667, 34402, 35005, 28012, - 27930, 27897, 27989, 27930, 28012, 27989, 28012, 28252, 36126, 36239, 35978, 36231, 36121, - 36191, 5978, 6064, 6082, 5986, 6062, 6225, 6808, 6716, 6763, 6590, 6716, 6808, - 14921, 15152, 15030, 35338, 35283, 35315, 7117, 7026, 6941, 6404, 6566, 6531, 7661, - 7660, 7854, 7344, 7147, 7355, 27952, 28101, 27959, 27602, 27959, 27442, 27420, 27407, - 27260, 30093, 29972, 29953, 29933, 29972, 30196, 29856, 29985, 29783, 35017, 34683, 34540, - 8856, 8706, 8778, 9023, 8858, 9020, 8789, 8858, 8763, 11369, 11407, 11539, 10905, - 10737, 10730, 10681, 10987, 10650, 18651, 18738, 18593, 18383, 18268, 18334, 36187, 36185, - 36146, 36595, 36185, 36187, 24766, 24712, 24838, 23382, 23342, 23556, 10773, 10737, 10905, - 10523, 10681, 10650, 17472, 17951, 17914, 17192, 17436, 17226, 17626, 17436, 17253, 25942, - 26030, 25980, 25946, 26030, 25942, 26115, 26030, 26122, 5978, 6082, 5967, 19921, 19679, - 19699, 19432, 19303, 19114, 16889, 16618, 16774, 7228, 7112, 7260, 7145, 7112, 7228, - 7722, 7816, 7419, 28675, 28529, 28633, 31813, 31779, 31679, 31962, 31889, 31985, 32151, - 31962, 31985, 6122, 6584, 6445, 16774, 16618, 16661, 16968, 17077, 16976, 24923, 24766, - 24838, 26014, 25919, 26047, 35761, 35815, 35658, 35464, 35338, 35329, 35329, 35338, 35315, - 35875, 35856, 35744, 35952, 35856, 35875, 5984, 5995, 6136, 19679, 19596, 19699, 21543, - 21814, 21526, 23553, 23838, 23599, 23599, 23838, 23619, 23943, 23838, 23876, 9131, 9119, - 9223, 32689, 32863, 32682, 34080, 34311, 34100, 26200, 26232, 26047, 26407, 26360, 26460, - 35253, 35230, 35551, 5986, 5989, 6062, 5963, 6128, 5996, 6176, 6119, 6575, 6325, - 6186, 6445, 5705, 6119, 6176, 23342, 23666, 23556, 22910, 22945, 22773, 7033, 7043, - 7242, 13158, 12535, 13575, 13158, 13575, 13332, 12476, 12646, 12612, 12341, 12646, 12476, - 13132, 13158, 13332, 13332, 13522, 13466, 28866, 28976, 28861, 29762, 29856, 29783, 28986, - 28976, 28866, 35254, 35211, 35283, 35283, 35211, 35177, 34264, 34170, 34240, 18651, 18593, - 18471, 29972, 29896, 29953, 29607, 28991, 29095, 29933, 29896, 29972, 31038, 30957, 30914, - 29762, 29783, 29718, 32995, 32844, 32832, 34705, 34402, 34288, 24445, 24241, 24632, 24445, - 24632, 24583, 16889, 16968, 16976, 24923, 24838, 24972, 10474, 10244, 10422, 10303, 9828, - 10204, 9398, 9335, 9477, 9477, 9335, 9514, 10335, 10244, 10474, 35454, 35512, 35489, - 35727, 35512, 35745, 6119, 6249, 6280, 7344, 7258, 7086, 7258, 7050, 7086, 7788, - 7955, 7684, 8110, 8102, 8332, 7932, 7913, 7788, 23223, 23018, 23075, 23556, 23666, - 23729, 7421, 7502, 7472, 20749, 20593, 20832, 18471, 18593, 18383, 18471, 18383, 18334, - 7258, 7117, 7050, 13196, 13438, 13279, 15103, 15173, 15152, 27364, 27420, 27260, 29296, - 29114, 29190, 27299, 27093, 26977, 31153, 31248, 31259, 31441, 31755, 31523, 32488, 32430, - 32360, 32488, 32524, 32430, 32430, 32524, 32546, 32546, 32581, 32689, 32947, 32962, 32863, - 31038, 30914, 30981, 32242, 32059, 32053, 6497, 6381, 6539, 6407, 6450, 6363, 6381, - 6450, 6407, 8789, 8706, 8856, 8789, 8856, 8858, 10563, 10553, 10737, 10737, 10553, - 10730, 11463, 11539, 11774, 26030, 26115, 25980, 25946, 25818, 25623, 35551, 35460, 35621, - 35363, 35254, 35283, 5967, 6082, 6076, 5967, 6076, 5989, 19503, 19345, 19432, 7502, - 7534, 7687, 27314, 27309, 27354, 28163, 27989, 28252, 28163, 28252, 28279, 28991, 28708, - 29095, 29394, 29236, 29296, 27402, 27586, 27354, 27364, 27299, 27376, 34837, 35017, 34540, - 35015, 35103, 34959, 34837, 34540, 34667, 8090, 8110, 8021, 8028, 8377, 8460, 12535, - 12383, 13003, 12267, 12383, 12438, 32863, 32995, 32832, 32962, 32995, 32863, 8419, 8483, - 8700, 9479, 9477, 9488, 8959, 8858, 9023, 29888, 29762, 29718, 30981, 30464, 30660, - 5989, 6076, 6062, 19345, 19303, 19432, 7112, 7033, 7242, 6597, 6808, 6971, 7751, - 7816, 7777, 7026, 6845, 6941, 24080, 23989, 23858, 24546, 24445, 24583, 35171, 35103, - 35015, 15152, 15173, 15217, 15885, 16059, 15996, 15103, 15152, 15085, 16968, 16889, 16832, - 15036, 14968, 15097, 16968, 17255, 17077, 26565, 26407, 26460, 26360, 26232, 26200, 24775, - 24583, 24766, 24775, 24546, 24583, 36231, 36239, 36126, 36231, 36126, 36121, 9335, 9226, - 9368, 10905, 11027, 10948, 24080, 23858, 24241, 23838, 23943, 23855, 22314, 22509, 22232, - 30117, 29985, 29856, 7767, 7751, 7777, 7848, 7777, 7918, 13047, 13059, 12732, 20783, - 20884, 20960, 20960, 21081, 21219, 21219, 21409, 21267, 21267, 21409, 21368, 21543, 21610, - 21814, 20488, 20593, 20584, 20380, 20593, 20488, 20832, 20593, 20682, 20488, 20325, 20380, - 18736, 18834, 18738, 20593, 20749, 20752, 12099, 11463, 11774, 11369, 11169, 11200, 36499, - 36448, 36315, 36348, 36501, 36361, 36361, 36438, 36236, 36499, 36315, 36352, 36499, 36352, - 36469, 21814, 22279, 22232, 22314, 22279, 22214, 7067, 7033, 7112, 20749, 20884, 20783, - 36542, 36501, 36348, 36501, 36493, 36361, 26115, 26269, 25980, 25176, 25019, 25002, 35355, - 35283, 35338, 35662, 35551, 35621, 5981, 5917, 6056, 5984, 5919, 5995, 5892, 6117, - 5560, 5804, 5892, 5782, 5802, 6017, 5806, 6017, 5972, 5806, 36352, 36263, 36421, - 18651, 18736, 18738, 18202, 18268, 18057, 25263, 25176, 24792, 35856, 35815, 35744, 35964, - 35815, 35856, 36421, 36263, 36342, 29114, 28976, 29190, 29296, 29236, 29114, 29455, 29888, - 29718, 33713, 33558, 33575, 32092, 31896, 31962, 34069, 34019, 34172, 34019, 34067, 34172, - 7869, 8123, 8270, 12732, 13059, 12650, 12732, 12650, 12646, 29896, 29700, 29631, 29789, - 29700, 29896, 17626, 17951, 17472, 18057, 17951, 18202, 16964, 16798, 16982, 23223, 23075, - 23279, 20669, 19928, 20245, 23729, 23666, 23738, 23385, 22579, 22509, 8102, 8018, 8355, - 7975, 8090, 8021, 7932, 8032, 7913, 24208, 24080, 24241, 23738, 23666, 23858, 24923, - 24972, 24983, 26316, 26232, 26360, 26316, 26360, 26407, 26122, 26269, 26115, 34264, 34594, - 34340, 35355, 35338, 35504, 35211, 35243, 34753, 5804, 5917, 5981, 5615, 6154, 6030, - 36244, 36230, 36514, 6249, 6198, 6299, 6186, 6198, 6054, 6198, 6249, 6097, 24416, - 24241, 24445, 10210, 9828, 10303, 9335, 9231, 9226, 10210, 10303, 10244, 9546, 9833, - 9720, 10177, 10340, 10471, 10471, 10340, 10523, 10523, 10434, 10681, 9546, 9720, 9496, - 9546, 9496, 9363, 31962, 31896, 31813, 31779, 31464, 31679, 30286, 30093, 30208, 31942, - 33066, 33216, 6450, 6381, 6497, 6817, 6760, 6431, 8706, 8705, 8700, 8959, 9023, - 9119, 11234, 11169, 11369, 21083, 21409, 21219, 25076, 24923, 24983, 36105, 35952, 36165, - 33225, 33066, 33092, 34369, 34288, 34230, 35017, 35171, 35015, 14165, 14305, 14323, 14043, - 14149, 13939, 14149, 13606, 13939, 27420, 27573, 27442, 27434, 27573, 27420, 27364, 27260, - 27299, 30286, 30245, 30423, 6031, 6225, 6139, 5967, 5819, 5978, 6031, 6139, 6128, - 5963, 6031, 6128, 23223, 23279, 23382, 32303, 31755, 32019, 32019, 31755, 31932, 14175, - 14305, 14165, 27434, 27364, 27376, 36565, 36438, 36361, 36336, 36230, 36193, 32752, 32863, - 32689, 32174, 32242, 32053, 7955, 7854, 7671, 34831, 34425, 34735, 15801, 15885, 15518, - 27188, 26565, 26665, 35504, 35338, 35464, 5917, 5887, 5984, 14305, 14504, 14500, 15173, - 15341, 15435, 19921, 19826, 19679, 19679, 19621, 19596, 19596, 19503, 19432, 19345, 19261, - 19303, 19928, 19826, 19921, 21176, 20939, 21673, 21409, 21610, 21543, 27309, 27188, 27067, - 27314, 27188, 27309, 36191, 36354, 36305, 36335, 36193, 35897, 10268, 10210, 10244, 10948, - 11027, 11200, 32581, 32546, 32524, 33220, 33473, 32844, 5989, 5938, 5967, 5894, 5986, - 6225, 36335, 35897, 36239, 8483, 8312, 8580, 8212, 8312, 8242, 8972, 8959, 9119, - 9828, 9479, 9488, 10335, 10474, 10553, 33503, 33777, 33264, 33688, 33777, 33503, 5887, - 5919, 5984, 12383, 12099, 12006, 11227, 11234, 11369, 12438, 12383, 12535, 19826, 19734, - 19679, 28832, 28379, 28509, 29394, 29475, 29455, 30106, 30117, 29856, 33837, 33558, 33713, - 34069, 34004, 33903, 33947, 34004, 34251, 35551, 35518, 35464, 35662, 35518, 35551, 35662, - 35621, 36157, 6381, 6282, 6539, 11057, 10948, 11200, 11227, 11369, 11463, 11183, 11269, - 11322, 11114, 11269, 11183, 11114, 11183, 10681, 30921, 30323, 30970, 22806, 22488, 22773, - 23180, 23223, 23358, 23018, 23223, 23074, 6810, 6971, 7043, 7145, 7067, 7112, 7060, - 7067, 7145, 7145, 7504, 6877, 7026, 6969, 6845, 7235, 7326, 7355, 7355, 7326, - 7421, 7421, 7338, 7502, 7671, 7660, 7456, 7671, 7854, 7660, 6787, 6472, 6645, - 6643, 6566, 6469, 14528, 14607, 14650, 9479, 9398, 9477, 32394, 32488, 32360, 33837, - 33713, 33833, 5919, 5883, 5995, 22945, 22910, 23018, 29501, 29095, 29442, 27354, 27586, - 27607, 29501, 29442, 29700, 29501, 29700, 29656, 28509, 28148, 28101, 34264, 34172, 34067, - 24775, 24416, 24546, 24546, 24416, 24445, 25103, 25076, 24983, 26146, 26047, 26232, 35952, - 35964, 35856, 36105, 35964, 35952, 7848, 7767, 7777, 7694, 7767, 7752, 12881, 12499, - 12535, 16371, 15814, 16248, 28370, 28509, 28101, 9131, 9223, 9226, 8628, 8705, 8706, - 10563, 10335, 10553, 11057, 11200, 11169, 15103, 15341, 15173, 26565, 26316, 26407, 26178, - 26316, 26378, 10563, 10737, 10657, 10110, 10340, 10177, 19734, 19621, 19679, 17017, 16976, - 17077, 32488, 32581, 32524, 36495, 36335, 36607, 36191, 35992, 36354, 6469, 6566, 6404, - 35377, 35240, 35254, 35254, 35240, 35211, 34264, 34239, 34172, 35363, 35283, 35355, 8628, - 8706, 8789, 30286, 30196, 30093, 30231, 30196, 30286, 33558, 33401, 33254, 19621, 19503, - 19596, 7975, 8018, 8090, 7420, 7534, 7502, 18649, 18736, 18651, 18649, 18651, 18471, - 28991, 28675, 28633, 34352, 34311, 34080, 6810, 7043, 6615, 6381, 6300, 6282, 12267, - 12099, 12383, 12160, 12099, 12267, 16889, 16859, 16618, 19056, 19114, 19303, 29789, 29896, - 29933, 28503, 28279, 28675, 29582, 29475, 29546, 29546, 29475, 29394, 6404, 6531, 6458, - 7235, 7355, 7147, 7071, 7086, 7050, 13920, 13734, 13606, 14158, 14175, 14165, 14305, - 14344, 14504, 14504, 14528, 14650, 27573, 27602, 27442, 27587, 27602, 27573, 27434, 27420, - 27364, 8090, 8018, 8102, 7975, 8021, 7932, 12321, 12255, 12187, 13402, 13734, 13196, - 14044, 14175, 14158, 14607, 14753, 14828, 27376, 27299, 26977, 29138, 29190, 28976, 29138, - 28976, 28986, 16371, 16282, 15814, 30115, 29789, 29933, 35590, 35363, 35355, 6645, 6887, - 6787, 10657, 10737, 10773, 26178, 26146, 26232, 26178, 26232, 26316, 26269, 26626, 25980, - 25946, 26122, 26030, 26219, 26122, 25946, 32581, 32752, 32689, 33220, 32844, 32995, 23943, - 24260, 24016, 26219, 26189, 26122, 23702, 23876, 23838, 23702, 23838, 23553, 23385, 23241, - 23368, 27188, 26677, 26565, 27586, 27930, 27902, 23499, 23385, 23368, 6363, 6450, 6614, - 6122, 6404, 6458, 20325, 20166, 20380, 18608, 18649, 18471, 12537, 12732, 12646, 30106, - 29856, 30017, 31759, 31706, 31248, 33220, 32995, 33152, 34500, 34369, 34460, 7697, 7816, - 7751, 6919, 7043, 7033, 6958, 7071, 7050, 6958, 7117, 6941, 11234, 11057, 11169, - 10726, 10657, 10773, 11227, 11057, 11234, 11216, 12321, 12187, 11011, 11114, 10645, 14344, - 14528, 14504, 33295, 33225, 33092, 8797, 8763, 8858, 9174, 9131, 9226, 10788, 10773, - 10948, 30520, 29790, 29985, 7767, 7697, 7751, 7694, 7697, 7767, 7456, 7660, 7534, - 7753, 7975, 7932, 6919, 7033, 7067, 35619, 35464, 35518, 35524, 35504, 35464, 24899, - 24766, 24923, 24080, 24050, 23989, 24899, 24923, 25076, 19390, 19261, 19345, 16976, 16859, - 16889, 17017, 16859, 16976, 31063, 30921, 30970, 32151, 32092, 31962, 32211, 32092, 32151, - 36281, 36239, 36231, 36665, 36421, 36451, 6839, 6958, 6941, 14675, 14753, 14607, 23385, - 23499, 23553, 22314, 22232, 22279, 31755, 32174, 32053, 32242, 32394, 32360, 32758, 32741, - 32581, 32581, 32741, 32752, 32313, 32174, 32303, 34004, 33947, 33833, 33295, 33092, 33401, - 33295, 33216, 33225, 34266, 34004, 34069, 34266, 34069, 34172, 29789, 29656, 29700, 29501, - 29607, 29095, 29731, 29656, 29742, 32020, 31779, 31896, 30196, 30177, 29933, 32752, 32947, - 32863, 32879, 32947, 32752, 6472, 6773, 6643, 6814, 6845, 6727, 6472, 6643, 6469, - 34311, 34369, 34230, 34101, 33541, 33777, 36157, 35621, 35815, 8264, 8377, 8028, 7810, - 7932, 7788, 29546, 29394, 29296, 30017, 29856, 29762, 29272, 29138, 28917, 29138, 28986, - 28917, 34191, 34101, 34411, 36448, 36542, 36206, 36501, 36542, 36493, 36493, 36565, 36361, - 36695, 36542, 36448, 36695, 36448, 36499, 36597, 36499, 36469, 36526, 36469, 36421, 36526, - 36421, 36665, 30610, 30423, 30245, 32174, 32394, 32242, 20884, 21081, 20960, 21409, 21437, - 21610, 22028, 22279, 21814, 20749, 20875, 20884, 20832, 20875, 20749, 20166, 20112, 20165, - 6407, 6300, 6381, 5921, 5986, 5851, 6431, 6760, 6716, 6544, 6716, 6590, 20875, - 21081, 20884, 23074, 22945, 23018, 23074, 23223, 23180, 6839, 6845, 6814, 21081, 21083, - 21219, 25010, 24899, 25076, 26378, 26316, 26565, 26122, 26189, 26269, 25263, 25355, 25176, - 7326, 7338, 7421, 7275, 7338, 7326, 7344, 7086, 7147, 7086, 7071, 7147, 14043, - 14044, 14158, 14550, 14675, 14528, 14528, 14675, 14607, 13606, 13734, 13402, 5921, 5938, - 5989, 5921, 5989, 5986, 6128, 5923, 5996, 21694, 21814, 21610, 5892, 5804, 5981, - 5917, 5780, 5887, 5887, 5856, 5919, 5919, 5856, 5883, 5883, 5849, 5995, 5802, - 6102, 6017, 7147, 6976, 7022, 9131, 8972, 9119, 9398, 9341, 9335, 8898, 8903, - 8972, 9479, 9409, 9398, 9344, 9409, 9479, 9805, 9479, 9828, 9805, 9828, 10061, - 10268, 10244, 10335, 10268, 10335, 10563, 10190, 10268, 10159, 10882, 10788, 10948, 10882, - 10948, 11057, 21405, 21176, 21673, 19826, 19650, 19734, 19734, 19650, 19621, 19621, 19650, - 19503, 19503, 19461, 19345, 21405, 21673, 21735, 27602, 27952, 27959, 27434, 27587, 27573, - 27466, 27587, 27434, 36305, 36281, 36231, 36305, 36231, 36191, 36578, 36244, 36610, 7697, - 7419, 7816, 7338, 7420, 7502, 7756, 7810, 7788, 35132, 34831, 34735, 35243, 35211, - 35240, 35243, 35240, 35377, 7684, 7955, 7671, 6806, 7071, 6958, 27320, 26677, 27188, - 27320, 27354, 27607, 24208, 24050, 24080, 24208, 24241, 24416, 23876, 24076, 23943, 24025, - 24076, 23876, 6285, 6300, 6407, 7420, 7456, 7534, 26014, 26047, 26146, 34831, 34732, - 34425, 8529, 8419, 8700, 8312, 8212, 8270, 8763, 8628, 8789, 9409, 9341, 9398, - 10117, 10563, 10559, 11149, 11227, 11463, 30423, 30231, 30286, 30359, 30231, 30423, 5806, - 5972, 5699, 8242, 8312, 8483, 7697, 7532, 7419, 21818, 21405, 21735, 36620, 36565, - 36493, 36438, 36671, 35849, 36165, 35952, 36284, 12376, 12537, 12646, 12943, 13025, 13047, - 11216, 11912, 11269, 22520, 22268, 22488, 23358, 23382, 23556, 5819, 6019, 5978, 5894, - 6225, 6031, 35878, 35454, 35876, 35512, 35727, 35489, 35232, 35171, 35017, 35113, 35017, - 34837, 15720, 15801, 15522, 15085, 15152, 14921, 15085, 14921, 14893, 21502, 21437, 21409, - 36565, 36544, 36438, 8460, 8355, 7945, 8355, 8018, 7945, 15336, 15518, 15341, 16059, - 16328, 16603, 18202, 18334, 18268, 33664, 33688, 33503, 33548, 33503, 33473, 35745, 35512, - 35841, 10961, 10882, 11057, 10788, 10726, 10773, 9341, 9231, 9335, 23738, 23858, 23989, - 23499, 23702, 23553, 23551, 23702, 23499, 5819, 5967, 5796, 12376, 12646, 12341, 34340, - 34239, 34264, 33295, 33401, 33472, 36514, 36230, 36336, 16371, 16531, 16282, 24792, 25176, - 24963, 26214, 26014, 26146, 26214, 26146, 26178, 7060, 6919, 7067, 6597, 6544, 6590, - 6908, 6919, 6852, 14202, 14305, 14175, 35377, 35254, 35363, 35377, 35363, 35439, 7752, - 7767, 7848, 7499, 7684, 7671, 7810, 7753, 7932, 36580, 36431, 36336, 36580, 36336, - 36335, 5780, 5856, 5887, 9231, 9174, 9226, 8797, 8858, 8959, 10340, 10434, 10523, - 12242, 12376, 12321, 10302, 10434, 10340, 10110, 10177, 10064, 33152, 32995, 32962, 32633, - 32581, 32488, 6593, 6353, 6045, 6198, 6186, 6325, 6419, 6472, 6469, 6097, 6249, - 6119, 18202, 18231, 18366, 18649, 18608, 18736, 24320, 24208, 24416, 23851, 23738, 23989, - 8377, 8575, 8745, 30231, 30177, 30196, 30216, 30177, 30231, 10920, 10961, 10984, 10841, - 10726, 10788, 30921, 30610, 30259, 30693, 30610, 30921, 33225, 33216, 33066, 33401, 33558, - 33755, 33032, 32962, 32947, 15209, 15336, 15341, 15209, 15341, 15103, 24854, 24775, 24766, - 25103, 25010, 25076, 26677, 26378, 26565, 26189, 26359, 26269, 26219, 26359, 26189, 5856, - 5849, 5883, 19589, 19650, 19826, 16968, 17281, 17255, 6845, 6839, 6941, 6845, 6969, - 6727, 35590, 35355, 35504, 7869, 7752, 8123, 7684, 7756, 7788, 32741, 32879, 32752, - 23851, 23989, 24050, 23729, 23640, 23556, 33688, 33820, 33777, 34101, 34352, 34080, 33785, - 33820, 33688, 36344, 35992, 35746, 36607, 36335, 36239, 11680, 11149, 11463, 10949, 10882, - 10961, 12499, 12438, 12535, 12535, 13158, 12881, 13640, 14464, 14152, 12321, 12376, 12341, - 13911, 14044, 13939, 11093, 11269, 11114, 5763, 5938, 5921, 6045, 6353, 5926, 7420, - 7336, 7456, 7456, 7499, 7671, 7566, 7753, 7756, 7338, 7237, 7420, 7235, 7275, - 7326, 7022, 7275, 7235, 7237, 7275, 7045, 7419, 7292, 7722, 7123, 7292, 7419, - 7532, 7697, 7694, 13939, 14044, 14043, 13196, 13047, 13025, 18382, 18608, 18471, 18202, - 18129, 18231, 6419, 6469, 6277, 6628, 6969, 6685, 13047, 12732, 12943, 14128, 14202, - 14175, 14893, 14921, 14753, 6597, 6971, 6810, 6363, 6285, 6407, 35799, 35745, 35841, - 36078, 35746, 35379, 8529, 8700, 8705, 8903, 8959, 8972, 11011, 11093, 11114, 32095, - 32020, 32092, 33837, 33833, 33947, 5643, 5908, 6154, 10061, 9828, 10210, 9344, 9237, - 9341, 9341, 9237, 9231, 9231, 9237, 9174, 10095, 10210, 10190, 14893, 14654, 14797, - 16859, 16834, 16618, 19210, 19303, 19261, 24076, 24260, 23943, 24192, 24260, 24076, 24854, - 24766, 24899, 23909, 23851, 24050, 27320, 27188, 27314, 26359, 26626, 26269, 30117, 30234, - 29985, 30017, 29762, 29888, 32092, 32020, 31896, 32151, 32545, 32335, 32879, 32936, 32947, - 33552, 33548, 33473, 33664, 33548, 33656, 32092, 32211, 32170, 14831, 14968, 15036, 14325, - 14344, 14305, 27354, 27320, 27314, 27902, 27930, 27989, 28403, 28163, 28279, 28503, 28675, - 28621, 29731, 29501, 29656, 33944, 33837, 34150, 34594, 34264, 34240, 34191, 34352, 34101, - 34369, 34500, 34288, 35662, 35619, 35518, 35677, 35619, 35969, 5796, 5967, 5938, 5796, - 5938, 5763, 19650, 19461, 19503, 6277, 6469, 6404, 5957, 6097, 5906, 5926, 6353, - 6282, 6330, 6285, 6363, 23738, 23640, 23729, 23738, 23851, 23812, 25655, 26014, 26358, - 25655, 25919, 26014, 25655, 25103, 24983, 24934, 24854, 24899, 14481, 14550, 14528, 24259, - 24401, 24260, 23379, 23368, 23241, 23551, 23368, 23439, 34732, 34564, 34221, 34594, 34564, - 34811, 34564, 34732, 35132, 35280, 34753, 35243, 10841, 10788, 10882, 10841, 10882, 10949, - 32936, 33032, 32947, 12438, 12160, 12267, 12096, 12160, 12438, 29742, 29656, 29789, 29742, - 29789, 30115, 34266, 34172, 34239, 10190, 10210, 10268, 10064, 10177, 9833, 11011, 11157, - 11093, 19461, 19390, 19345, 11093, 11157, 11269, 10645, 10681, 10434, 30610, 30359, 30423, - 30216, 30359, 30502, 15148, 15209, 15103, 15720, 15805, 15801, 15148, 15103, 15085, 35619, - 35524, 35464, 35388, 35280, 35243, 7612, 7694, 7752, 8614, 8705, 8628, 13019, 13158, - 13132, 30106, 30234, 30117, 29582, 29455, 29475, 29296, 29448, 29546, 33548, 33664, 33503, - 34411, 34101, 34120, 33656, 33548, 33552, 34448, 34266, 34239, 34448, 34239, 34340, 33981, - 33777, 33820, 13466, 13019, 13132, 12943, 12732, 12719, 24260, 24401, 24133, 24025, 23876, - 23898, 34460, 34311, 34352, 34460, 34369, 34311, 10042, 10190, 10159, 10110, 10183, 10340, - 31872, 31464, 31779, 32394, 32633, 32488, 32741, 32897, 32879, 32879, 33023, 32936, 32936, - 33075, 33032, 32628, 32633, 32394, 32313, 32394, 32174, 32174, 31755, 32303, 17017, 16834, - 16859, 16921, 16834, 17017, 24934, 24899, 25010, 24431, 24320, 24416, 36078, 35326, 35727, - 26214, 26178, 26378, 25059, 24934, 25010, 25360, 25623, 25355, 26359, 26556, 26626, 25360, - 25355, 25263, 8993, 8972, 9131, 8578, 8614, 8628, 9143, 9131, 9174, 10042, 10095, - 10190, 10949, 10961, 10920, 33032, 33152, 32962, 33134, 33152, 33032, 18382, 18471, 18334, - 36607, 36239, 36281, 36665, 36451, 36616, 36394, 36281, 36305, 6628, 6685, 6645, 6122, - 6445, 6067, 25592, 25360, 25460, 6239, 6282, 6300, 23898, 23876, 23702, 9344, 9341, - 9409, 10183, 10302, 10340, 32633, 32687, 32581, 5894, 6031, 5963, 5894, 5963, 5799, - 6285, 6239, 6300, 6431, 6330, 6363, 6839, 6806, 6958, 6628, 6645, 6451, 8578, - 8628, 8763, 14956, 14893, 14797, 19390, 19210, 19261, 30171, 30234, 30106, 34426, 34460, - 34352, 35590, 35439, 35363, 13743, 13911, 13939, 14044, 14128, 14175, 14202, 14325, 14305, - 14344, 14481, 14528, 14893, 14753, 14654, 13743, 13939, 13606, 20380, 20166, 20165, 20875, - 20899, 21081, 21081, 21092, 21083, 21083, 21092, 21409, 21437, 21694, 21610, 13749, 13743, - 13628, 20832, 20899, 20875, 28010, 27902, 27989, 28010, 27989, 28163, 27623, 27952, 27602, - 27623, 27602, 27587, 36597, 36695, 36499, 36744, 36620, 36493, 36565, 36651, 36544, 36597, - 36469, 36526, 36597, 36526, 36715, 6615, 6597, 6810, 6201, 6285, 6330, 6908, 7043, - 6919, 14018, 14128, 14044, 26328, 26214, 26378, 26328, 26378, 26633, 26378, 26677, 26633, - 25805, 26219, 25946, 27080, 27376, 26977, 34705, 34288, 34500, 35005, 35113, 34837, 35841, - 35512, 35454, 20165, 20117, 20220, 29296, 29190, 29448, 30017, 30171, 30106, 32687, 32758, - 32581, 5896, 5963, 5996, 8903, 8797, 8959, 8816, 8797, 8903, 11149, 11057, 11227, - 10268, 10117, 10159, 27952, 28133, 28101, 12376, 12403, 12537, 12188, 12242, 12321, 14128, - 14325, 14202, 27466, 27376, 27453, 20165, 20063, 20117, 21002, 21092, 21081, 29582, 29888, - 29455, 33837, 33790, 33558, 33755, 33790, 33938, 36451, 36578, 36616, 23368, 23551, 23499, - 23694, 23551, 23439, 19210, 19056, 19303, 5804, 5782, 5917, 5856, 5726, 5849, 5849, - 5726, 5995, 5678, 5782, 5892, 6117, 6047, 5560, 5778, 5802, 5806, 5778, 5806, - 5699, 13162, 13402, 13196, 13063, 13196, 13025, 25059, 25010, 25103, 24320, 24050, 24208, - 6097, 6054, 6198, 6004, 6054, 6097, 9237, 9143, 9174, 14423, 14481, 14344, 32758, - 32897, 32741, 35388, 35243, 35377, 36744, 36493, 36542, 36544, 36701, 36438, 15801, 15518, - 15522, 15801, 15805, 16059, 15027, 15148, 15085, 15027, 15085, 14893, 35453, 35388, 35377, - 35524, 35590, 35504, 35677, 35590, 35524, 8614, 8529, 8705, 7612, 7752, 7603, 8521, - 8529, 8614, 36514, 36336, 36431, 15119, 14831, 15036, 16282, 16531, 16618, 15518, 15336, - 15522, 18366, 18382, 18334, 18366, 18334, 18202, 18608, 18556, 18736, 25623, 25805, 25946, - 25592, 25805, 25623, 25592, 25623, 25360, 6419, 6384, 6472, 6306, 6384, 6419, 15805, - 16045, 16059, 7612, 7532, 7694, 6852, 6919, 7060, 8270, 8212, 7869, 19056, 18958, - 19114, 28621, 28675, 28639, 36641, 36514, 36431, 6852, 7060, 6847, 35403, 35388, 35467, - 21092, 21502, 21409, 36620, 36651, 36565, 36610, 36616, 36578, 16045, 16328, 16059, 23812, - 23640, 23738, 23074, 23089, 22945, 23812, 23851, 23909, 23551, 23694, 23702, 24025, 24192, - 24076, 24401, 24792, 24963, 23385, 22509, 23241, 36354, 36394, 36305, 36495, 36580, 36335, - 5739, 5972, 5819, 5713, 5780, 5917, 6004, 6107, 6054, 29448, 29190, 29272, 29801, - 29956, 29888, 32020, 31991, 31779, 32170, 32095, 32092, 32170, 32211, 32335, 32170, 32261, - 32095, 32095, 31991, 32020, 31942, 32545, 31985, 16052, 15739, 15814, 17255, 17281, 17858, - 29100, 28675, 28991, 30115, 29933, 30177, 30115, 30177, 30216, 5755, 5739, 5819, 5790, - 5851, 5986, 18958, 18919, 19114, 31706, 31932, 31755, 32633, 32660, 32687, 32687, 32773, - 32758, 32758, 32849, 32897, 8242, 8483, 8419, 12968, 12881, 13019, 13019, 12881, 13158, - 12256, 12096, 12438, 11920, 11463, 12099, 12499, 12881, 12358, 12459, 12732, 12537, 6054, - 6107, 6186, 6097, 6119, 5906, 24034, 24192, 24025, 6588, 6628, 6451, 9363, 9415, - 8921, 10110, 10135, 10183, 10183, 10112, 10302, 12242, 12403, 12376, 12309, 12403, 12242, - 18530, 18556, 18608, 18202, 17951, 18129, 23358, 23223, 23382, 26214, 26358, 26014, 25105, - 25059, 25103, 26633, 26677, 27320, 15119, 15036, 15565, 21502, 21694, 21437, 36651, 36701, - 36544, 36601, 36610, 36244, 8287, 8379, 8529, 9143, 8993, 9131, 33023, 32879, 32897, - 33023, 33075, 32936, 33552, 33473, 33459, 6201, 6239, 6285, 6431, 6716, 6544, 24416, - 24775, 24431, 25105, 25103, 25164, 30234, 30520, 29985, 30372, 30520, 30234, 30660, 30520, - 30578, 32313, 32427, 32394, 8529, 8379, 8419, 8578, 8763, 8675, 30216, 30231, 30359, - 31343, 30970, 31464, 33664, 33785, 33688, 34191, 34426, 34352, 33406, 33220, 33152, 5780, - 5726, 5856, 7275, 7237, 7338, 7022, 7235, 7147, 6806, 6839, 6814, 27466, 27623, - 27587, 28679, 28370, 28715, 28133, 28370, 28101, 27466, 27434, 27376, 10042, 10061, 10095, - 10095, 10061, 10210, 9513, 9344, 9479, 9237, 9169, 9143, 8877, 8898, 8993, 10559, - 10726, 10841, 9986, 10064, 9703, 10302, 10274, 10434, 7224, 7336, 7420, 7756, 7753, - 7810, 8377, 8264, 8575, 27902, 27607, 27586, 27998, 28010, 28210, 24775, 24854, 24952, - 23640, 23358, 23556, 26977, 26626, 27080, 27453, 27376, 27413, 7585, 7756, 7684, 7737, - 9363, 8921, 34585, 34426, 34654, 34460, 34487, 34500, 6143, 6431, 6544, 6143, 6112, - 6100, 8993, 8898, 8972, 8824, 8898, 8877, 13482, 13428, 13194, 13402, 13428, 13606, - 13743, 13749, 13911, 14018, 14325, 14128, 14223, 14423, 14325, 14325, 14423, 14344, 22806, - 22773, 22945, 21405, 21062, 21176, 19589, 19469, 19650, 19650, 19469, 19461, 19461, 19469, - 19390, 19390, 19260, 19210, 19210, 19117, 19056, 19056, 19117, 18958, 18958, 18870, 18919, - 33075, 33134, 33032, 33088, 33134, 33075, 9242, 9344, 9138, 10064, 10135, 10110, 15814, - 15739, 15565, 16282, 16618, 16834, 15805, 15832, 16045, 16045, 16046, 16328, 15522, 15336, - 15436, 5719, 5763, 5851, 5923, 5896, 5996, 5923, 6128, 6045, 6628, 6727, 6969, - 15156, 15336, 15209, 14956, 15027, 14893, 14675, 14654, 14753, 18530, 18608, 18382, 17626, - 17472, 17436, 26667, 26633, 26954, 14018, 14044, 13911, 35263, 35232, 35017, 35263, 35017, - 35113, 6451, 6645, 6120, 6594, 6717, 6727, 6242, 6277, 6168, 6067, 6445, 6186, - 24952, 24854, 24934, 24192, 24259, 24260, 24261, 24259, 24192, 8742, 8763, 8797, 10949, - 10781, 10841, 10984, 11149, 11030, 5755, 5819, 5796, 5755, 5796, 5680, 7422, 7499, - 7456, 15156, 15209, 15148, 28471, 28403, 28503, 28503, 28403, 28279, 28186, 28133, 27952, - 29801, 29888, 29582, 29272, 29190, 29138, 32628, 32660, 32633, 34694, 34705, 34500, 36621, - 36601, 36244, 36567, 36580, 36495, 36701, 36671, 36438, 35964, 36105, 35815, 6622, 6615, - 7043, 7060, 7145, 6877, 7504, 7292, 6877, 33790, 33755, 33558, 33944, 33790, 33837, - 33837, 33947, 34150, 33656, 33785, 33664, 33771, 33785, 33656, 8898, 8816, 8903, 8824, - 8816, 8898, 25059, 24952, 24934, 25032, 25105, 25164, 25059, 25105, 25032, 35952, 35807, - 36284, 35619, 35677, 35524, 5763, 5921, 5851, 6107, 6067, 6186, 6004, 5957, 5922, - 10112, 10274, 10302, 12241, 12459, 12403, 12403, 12459, 12537, 12943, 13063, 13025, 12309, - 12242, 12188, 17192, 17226, 17186, 21062, 20820, 21176, 21694, 22028, 21814, 23731, 23358, - 23640, 24218, 23909, 24050, 23694, 23898, 23702, 23939, 23898, 23694, 31513, 31343, 31464, - 36607, 36567, 36495, 36344, 36354, 35992, 7499, 7585, 7684, 12916, 13063, 12943, 23731, - 23640, 23812, 23180, 23089, 23074, 23241, 22509, 23100, 28639, 28675, 28729, 35672, 35531, - 35439, 35779, 35677, 35784, 36452, 36281, 36394, 36621, 36244, 36514, 6717, 6806, 6814, - 6717, 6814, 6727, 10274, 10360, 10434, 8578, 8521, 8614, 8246, 8242, 8419, 8479, - 8521, 8578, 30115, 30141, 29742, 28729, 28675, 29100, 30693, 30359, 30610, 33459, 33473, - 33220, 17945, 18732, 18531, 17945, 17255, 17858, 17077, 16921, 17017, 8824, 8742, 8816, - 8816, 8742, 8797, 10984, 10961, 11057, 31063, 30693, 30921, 30520, 30660, 30217, 29956, - 30017, 29888, 36284, 35807, 36667, 34585, 34487, 34426, 34426, 34487, 34460, 6277, 6306, - 6419, 6242, 6306, 6277, 35745, 35799, 35727, 36113, 36344, 35746, 35122, 35876, 35454, - 19469, 19260, 19390, 36621, 36514, 36652, 18530, 18382, 18291, 18382, 18366, 18291, 5858, - 5923, 5740, 5790, 5986, 5894, 23379, 23439, 23368, 23404, 23439, 23379, 5957, 6004, - 6097, 6168, 6277, 6404, 5906, 6119, 5836, 7336, 7422, 7456, 7499, 7444, 7585, - 7237, 7224, 7420, 7045, 7224, 7237, 8246, 8419, 8379, 13628, 13606, 13482, 13628, - 13743, 13606, 34799, 35005, 34705, 34705, 35005, 34402, 7879, 7869, 8212, 6877, 7292, - 7123, 12241, 12309, 12188, 12923, 13162, 13063, 29801, 29582, 29708, 28917, 28986, 28509, - 6878, 7147, 7071, 15027, 15156, 15148, 14675, 14550, 14654, 14550, 14496, 14654, 5829, - 5926, 6282, 6109, 6201, 6330, 6109, 6330, 6431, 36151, 36078, 35727, 35427, 35263, - 35113, 35862, 35103, 35171, 36652, 36514, 36641, 20832, 20801, 20899, 20899, 20999, 21081, - 21092, 21005, 21502, 21502, 21762, 21694, 22108, 22214, 22028, 20380, 20682, 20593, 20614, - 20682, 20380, 20220, 20380, 20165, 7253, 7422, 7336, 8146, 8107, 8242, 8742, 8675, - 8763, 8573, 8675, 8742, 11149, 10984, 11057, 10268, 10563, 10117, 12096, 12099, 12160, - 10645, 11114, 10681, 31263, 31063, 30970, 32914, 33023, 32897, 33406, 33459, 33220, 34594, - 34448, 34340, 34594, 34240, 34564, 35420, 34735, 35280, 35403, 35280, 35388, 20801, 20999, - 20899, 31991, 31872, 31779, 31343, 31263, 30970, 32095, 32125, 31991, 32261, 32125, 32095, - 31942, 33216, 32545, 20165, 20112, 20063, 18291, 18366, 18231, 32125, 32012, 31991, 32313, - 32492, 32427, 32427, 32530, 32394, 32660, 32773, 32687, 31441, 31706, 31755, 7510, 7532, - 7612, 6622, 7043, 6908, 21620, 21062, 21405, 19469, 19391, 19260, 20999, 21002, 21081, - 35453, 35377, 35531, 5969, 6067, 5886, 16628, 16798, 16794, 18164, 18291, 18231, 16628, - 16794, 16328, 32012, 31872, 31991, 32545, 33216, 32594, 5782, 5713, 5917, 5780, 5668, - 5726, 5615, 6030, 5995, 5655, 6047, 5802, 5655, 5802, 5651, 5802, 5778, 5651, - 18747, 18732, 18919, 18557, 18736, 18556, 13063, 13162, 13196, 12916, 12943, 12864, 34663, - 34694, 34500, 5799, 5963, 5896, 5651, 5778, 5700, 6819, 6908, 6852, 14956, 15156, - 15027, 15668, 15832, 15720, 15720, 15832, 15805, 15336, 15156, 15273, 25032, 24952, 25059, - 23815, 23812, 23909, 25103, 25276, 25164, 36641, 36580, 36567, 36641, 36431, 36580, 23898, - 24034, 24025, 25460, 25360, 25263, 23939, 24034, 23898, 36620, 36830, 36651, 36651, 36769, - 36701, 36701, 36797, 36671, 37091, 36744, 36542, 36822, 36542, 36695, 36822, 36695, 36881, - 36715, 36526, 36665, 36715, 36665, 36711, 36665, 36616, 36711, 36616, 36610, 36711, 36610, - 36878, 36711, 33284, 33216, 33339, 32492, 32530, 32427, 12390, 12438, 12499, 5778, 5699, - 5700, 8242, 8107, 8212, 8287, 8529, 8521, 15903, 15832, 15918, 33023, 33088, 33075, - 33131, 33088, 33023, 34344, 34004, 34266, 33560, 33472, 33401, 36610, 36601, 36764, 35531, - 35377, 35439, 16011, 16046, 16045, 10657, 10559, 10563, 10805, 11030, 11349, 23149, 23089, - 23180, 20851, 20897, 21062, 23149, 23180, 23295, 23731, 23812, 23815, 33560, 33401, 33863, - 33406, 33152, 33134, 33647, 33771, 33656, 33785, 33981, 33820, 34879, 34799, 34694, 5972, - 5739, 5699, 10061, 9843, 9805, 10949, 10920, 10781, 10274, 10206, 10360, 10360, 10645, - 10434, 10135, 10112, 10183, 10064, 10060, 10135, 9986, 10060, 10064, 32530, 32628, 32394, - 35799, 36011, 35727, 35402, 35171, 35232, 12719, 12732, 12459, 28621, 28471, 28503, 27998, - 27902, 28010, 27998, 27607, 27902, 29501, 29731, 29650, 35132, 34732, 34831, 34448, 34321, - 34266, 12358, 12390, 12499, 12256, 12390, 12358, 34344, 34321, 34395, 16046, 16404, 16328, - 33647, 33656, 33552, 5577, 5713, 5782, 36764, 36601, 36734, 5836, 6119, 5705, 6004, - 5922, 6107, 9344, 9242, 9237, 9138, 9344, 9439, 10781, 10920, 10984, 10060, 10112, - 10135, 23815, 23997, 23784, 36354, 36452, 36394, 36587, 36452, 36354, 6976, 7045, 7022, - 6588, 6727, 6628, 8877, 8993, 9143, 8573, 8479, 8578, 17255, 17041, 17077, 16989, - 17041, 17193, 5699, 5739, 5603, 36862, 36769, 36651, 36667, 36907, 36896, 36571, 36344, - 36632, 13749, 13843, 13911, 13706, 13843, 13749, 13606, 13428, 13482, 7289, 7444, 7422, - 7022, 7045, 7275, 6878, 7071, 6806, 9242, 9169, 9237, 13843, 14018, 13911, 28010, - 28163, 28210, 26358, 26214, 26328, 32628, 32773, 32660, 5858, 5799, 5896, 5858, 5896, - 5923, 13428, 13402, 13194, 17803, 17951, 17626, 18530, 18557, 18556, 23089, 22806, 22945, - 23295, 23180, 23358, 28210, 28163, 28303, 12489, 12719, 12459, 13133, 13402, 13162, 12489, - 12459, 12241, 24925, 24431, 24775, 26667, 26328, 26633, 5713, 5668, 5780, 8573, 8578, - 8675, 27080, 26626, 27111, 27466, 27537, 27623, 27623, 27721, 27952, 29546, 29448, 29632, - 13133, 13162, 12923, 28303, 28163, 28403, 5603, 5739, 5605, 5680, 5796, 5763, 7603, - 7510, 7612, 7999, 7879, 8212, 7999, 8212, 8107, 33826, 33647, 33459, 32773, 32849, - 32758, 36769, 36797, 36701, 36734, 36601, 36775, 10805, 10781, 10984, 10559, 10781, 10805, - 33339, 33216, 33295, 33339, 33295, 33472, 6847, 6819, 6852, 7510, 7419, 7532, 6739, - 6878, 6693, 19117, 18870, 18958, 19117, 19210, 19260, 35263, 35402, 35232, 35427, 35402, - 35263, 35427, 35113, 35602, 36801, 36641, 36567, 36775, 36601, 36621, 5906, 5891, 5957, - 5822, 5891, 5906, 17670, 17803, 17626, 17861, 17803, 17670, 24218, 24050, 24320, 23483, - 23295, 23358, 26606, 26667, 26954, 8287, 8246, 8379, 16046, 16064, 16404, 16404, 16628, - 16328, 15832, 16011, 16045, 15903, 16011, 15832, 26333, 26556, 26219, 24463, 24401, 24259, - 29582, 29546, 29708, 30171, 30318, 30325, 34694, 34799, 34705, 34663, 34500, 34487, 20107, - 19826, 19928, 6645, 6472, 6120, 6168, 6404, 6022, 6404, 6122, 6022, 18521, 18557, - 18530, 18129, 18164, 18231, 20851, 21062, 21426, 23483, 23358, 23731, 23100, 22509, 22314, - 23439, 23425, 23694, 23404, 23241, 23381, 12719, 12864, 12943, 12241, 12403, 12309, 36047, - 36011, 35799, 36623, 36571, 36704, 35876, 34959, 35862, 17041, 16921, 17077, 16989, 16921, - 17041, 17041, 17255, 17193, 31513, 31263, 31343, 31063, 31257, 30693, 30440, 30275, 30216, - 32849, 32914, 32897, 36165, 36253, 36105, 36105, 36157, 35815, 35531, 35467, 35453, 36731, - 36169, 36671, 6704, 6819, 6847, 24034, 24261, 24192, 24135, 24261, 24034, 26556, 26359, - 26219, 35403, 35420, 35280, 35453, 35467, 35388, 35439, 35590, 35672, 7603, 7752, 7662, - 34585, 34663, 34487, 18870, 18747, 18919, 18885, 18747, 18870, 30216, 30275, 30115, 30502, - 30359, 30693, 33945, 33981, 33785, 33459, 33647, 33552, 33406, 33134, 33390, 32634, 32428, - 32545, 33523, 33339, 33472, 36278, 36253, 36165, 6615, 6586, 6597, 6580, 6586, 6615, - 6472, 6384, 6120, 6693, 6878, 6624, 26667, 26425, 26328, 26550, 26425, 26667, 31263, - 31186, 31063, 35672, 35590, 35764, 36864, 36731, 36671, 5675, 5790, 5894, 5728, 5858, - 5740, 7662, 7752, 7869, 8046, 7999, 8107, 12096, 11920, 12099, 12111, 11920, 12096, - 18521, 18530, 18291, 17861, 18129, 17951, 23241, 23404, 23379, 22214, 22279, 22028, 33944, - 33938, 33790, 34251, 34150, 33947, 34344, 34266, 34321, 7835, 7869, 7879, 12748, 12864, - 12719, 28471, 28303, 28403, 29650, 29731, 29742, 34184, 33938, 33944, 33945, 33785, 33771, - 5675, 5894, 5799, 32261, 32110, 32125, 32125, 32110, 32012, 32012, 31964, 31872, 31872, - 31746, 31464, 31263, 31257, 31186, 32261, 32170, 32335, 32428, 32335, 32545, 12390, 12256, - 12438, 12968, 13019, 13466, 12489, 12549, 12719, 11216, 11269, 11157, 34395, 34321, 34448, - 34395, 34448, 34531, 32110, 31964, 32012, 31441, 31248, 31706, 32474, 32492, 32313, 32530, - 32595, 32628, 32929, 32857, 32773, 32773, 32857, 32849, 32849, 32968, 32914, 31759, 31855, - 31706, 19589, 19391, 19469, 36775, 36621, 36652, 16011, 16064, 16046, 15668, 15720, 15522, - 15668, 15522, 15539, 31038, 31759, 31248, 32594, 33216, 33326, 7510, 7123, 7419, 6704, - 6622, 6819, 7342, 7123, 7510, 8391, 8573, 8742, 8479, 8287, 8521, 8146, 8046, - 8107, 8870, 8877, 9143, 13584, 13706, 13628, 13628, 13706, 13749, 13843, 13844, 14018, - 14797, 15156, 14956, 13484, 13628, 13482, 24925, 24775, 24952, 23568, 23483, 23731, 24925, - 24952, 25032, 33119, 33131, 33023, 33013, 33023, 32914, 8671, 8742, 8824, 15436, 15336, - 15273, 6828, 6976, 7147, 7096, 7336, 7224, 6828, 7147, 6878, 8402, 8287, 8479, - 14831, 14152, 14968, 14616, 14152, 14831, 15119, 15565, 15739, 27418, 27537, 27453, 27453, - 27537, 27466, 29956, 30171, 30017, 29546, 29632, 29708, 36242, 36157, 36105, 32595, 32492, - 32474, 6588, 6594, 6727, 35779, 35590, 35677, 5719, 5680, 5763, 5891, 5922, 5957, - 5788, 5922, 5891, 6739, 6828, 6878, 10060, 10083, 10112, 10333, 10645, 10360, 11011, - 11031, 11157, 9703, 10064, 9833, 12923, 13063, 12916, 12469, 12549, 12489, 18521, 18291, - 18388, 21762, 22028, 21694, 23568, 23731, 23784, 23174, 23089, 23149, 23404, 23425, 23439, - 23381, 23425, 23404, 27080, 27413, 27376, 27418, 27413, 27355, 28210, 28197, 27998, 27998, - 28090, 27607, 26606, 26550, 26667, 28471, 28621, 28524, 32041, 31746, 31872, 31932, 31706, - 31946, 33326, 33216, 33284, 35528, 35420, 35403, 35484, 35420, 35529, 35675, 35467, 35531, - 36009, 35876, 35862, 35598, 35427, 35602, 35113, 35005, 35294, 14481, 14496, 14550, 36047, - 35799, 35841, 35862, 35171, 35402, 25276, 25103, 25655, 36262, 36242, 36253, 36253, 36242, - 36105, 10206, 10274, 10112, 9986, 10083, 10060, 7422, 7444, 7499, 7585, 7566, 7756, - 7945, 8018, 7975, 9546, 9703, 9833, 7253, 7336, 7096, 12923, 12916, 12864, 28524, - 28621, 28639, 8146, 8242, 8246, 7999, 7930, 7879, 22214, 22244, 22314, 28917, 28509, - 28370, 36748, 36652, 36641, 36748, 36775, 36652, 7793, 7930, 7832, 11920, 11680, 11463, - 12256, 12111, 12096, 11968, 12111, 11875, 34150, 34184, 33944, 34344, 34251, 34004, 34281, - 34251, 34344, 11000, 11031, 11011, 20682, 20801, 20832, 20999, 21005, 21002, 21002, 21005, - 21092, 22214, 22108, 22244, 20393, 20614, 20380, 20393, 20380, 20220, 20614, 20748, 20682, - 29950, 29650, 29742, 28631, 28524, 28639, 30490, 30502, 30559, 30440, 30490, 30268, 33863, - 33755, 33938, 33863, 33401, 33755, 33443, 33326, 33284, 20748, 20801, 20682, 36881, 36695, - 36892, 36744, 36830, 36620, 36769, 36916, 36797, 36797, 36864, 36671, 36695, 36597, 36892, - 36597, 36715, 36892, 36911, 36910, 36892, 37066, 36911, 36715, 21062, 20897, 20820, 19589, - 19205, 19391, 23174, 23149, 23295, 36610, 36764, 36878, 10159, 10010, 10042, 10042, 10010, - 10061, 8870, 9143, 8948, 8855, 8840, 8877, 10559, 10657, 10726, 10559, 10841, 10781, - 31746, 31513, 31464, 6101, 6109, 5991, 6201, 6071, 6239, 6478, 6580, 6615, 6622, - 6908, 6819, 20231, 20393, 20220, 18239, 18291, 18164, 19029, 18736, 20063, 24261, 24463, - 24259, 24595, 24463, 24261, 25214, 25276, 25224, 26633, 27320, 26954, 26333, 26219, 25805, - 25621, 25805, 25592, 35672, 35675, 35531, 35784, 35677, 35969, 7945, 7975, 7802, 34017, - 33863, 33938, 36878, 36764, 36898, 5759, 5836, 5705, 23265, 23174, 23295, 23784, 23731, - 23815, 12715, 12358, 12881, 34373, 34395, 34531, 12854, 12923, 12864, 33443, 33284, 33339, - 5537, 5719, 5851, 5680, 5719, 5595, 19205, 19117, 19260, 18747, 18531, 18732, 19205, - 19260, 19391, 36898, 36764, 36965, 36872, 36748, 36875, 36607, 36281, 36452, 10068, 10206, - 10112, 32695, 32773, 32628, 20063, 19700, 20020, 15990, 16064, 16011, 17803, 17861, 17951, - 18129, 18239, 18164, 15990, 16011, 15903, 15990, 15903, 15918, 25114, 25460, 25263, 15436, - 15539, 15522, 15637, 15485, 15585, 5584, 5636, 5651, 5651, 5636, 5655, 5655, 5560, - 6047, 5678, 5577, 5782, 5713, 5626, 5668, 5584, 5651, 5700, 5584, 5700, 5593, - 5700, 5699, 5593, 18596, 18736, 18557, 36940, 36595, 36169, 36284, 36278, 36165, 36900, - 36607, 36452, 6101, 5991, 5956, 5969, 6122, 6067, 6152, 6384, 6306, 6588, 6506, - 6594, 6067, 6107, 5886, 25164, 25137, 25032, 24431, 24218, 24320, 26358, 26328, 26425, - 30502, 30440, 30216, 30440, 30502, 30490, 30171, 30372, 30234, 30325, 30372, 30171, 5523, - 5577, 5462, 5615, 5995, 5726, 36922, 36830, 36744, 36731, 36940, 36169, 7444, 7566, - 7585, 12549, 12748, 12719, 12758, 12748, 12469, 12469, 12489, 12364, 14481, 14423, 14496, - 28679, 28917, 28370, 34663, 34879, 34694, 34411, 34426, 34191, 13706, 13844, 13843, 13592, - 13844, 13706, 13484, 13482, 13376, 13402, 13133, 13194, 26411, 26358, 26425, 26411, 26425, - 26550, 33390, 33088, 33131, 33390, 33134, 33088, 33872, 33945, 33771, 33981, 34120, 33777, - 35420, 35132, 34735, 35484, 35132, 35420, 5593, 5699, 5603, 5836, 5822, 5906, 5759, - 5822, 5836, 17670, 17626, 17253, 30268, 30115, 30275, 30318, 30171, 29956, 29396, 29448, - 29272, 34198, 34184, 34150, 34198, 34150, 34251, 36830, 36862, 36651, 5886, 6107, 5870, - 7444, 7289, 7566, 7096, 7224, 7079, 7224, 7045, 7079, 7930, 7835, 7879, 7603, - 7465, 7510, 7793, 7835, 7930, 11779, 12188, 12321, 13194, 13115, 13189, 28303, 28197, - 28210, 28179, 28197, 28414, 28414, 28303, 28471, 28917, 29396, 29272, 7911, 7930, 7999, - 8124, 8146, 8246, 8074, 8146, 8124, 8402, 8479, 8573, 33872, 33771, 33647, 27413, - 27418, 27453, 27537, 27721, 27623, 27313, 27413, 27080, 5739, 5755, 5605, 24064, 24218, - 24142, 32968, 33013, 32914, 36764, 36966, 36965, 5626, 5726, 5668, 16584, 16628, 16404, - 36443, 36278, 36284, 36242, 36368, 36157, 35784, 35764, 35779, 23265, 23295, 23483, 23265, - 23483, 23465, 12945, 13133, 12923, 5527, 5626, 5713, 27218, 27313, 27080, 7726, 7662, - 7869, 26562, 26606, 26652, 29255, 29100, 28991, 35779, 35764, 35590, 35619, 36118, 35969, - 11031, 11216, 11157, 10900, 11216, 11031, 10869, 11011, 10645, 32106, 32008, 31983, 30211, - 29956, 29801, 10862, 10869, 10845, 16243, 16584, 16404, 15918, 15832, 15637, 15832, 15668, - 15637, 35895, 35841, 35878, 36571, 36587, 36354, 35895, 35878, 35876, 36011, 36151, 35727, - 33013, 33119, 33023, 5605, 5755, 5680, 32227, 32041, 31964, 31964, 32041, 31872, 31746, - 31951, 31513, 32444, 32261, 32335, 32444, 32335, 32428, 32227, 32261, 32238, 36870, 36734, - 36775, 36870, 36775, 36872, 23997, 23815, 23909, 36571, 36354, 36344, 9615, 9703, 9546, - 9986, 10019, 10083, 10083, 10068, 10112, 10862, 11000, 10869, 12911, 12968, 13466, 19117, - 18885, 18870, 19038, 18885, 19117, 28631, 28639, 28729, 32008, 32019, 31932, 32008, 32096, - 32019, 32019, 32096, 32303, 32492, 32595, 32530, 32857, 32968, 32849, 33013, 33192, 33119, - 32008, 31932, 31983, 26770, 26626, 26556, 26928, 27111, 26626, 32227, 31964, 32110, 30502, - 30693, 30559, 31932, 31946, 31983, 16989, 16282, 16834, 16989, 16834, 16921, 36106, 35895, - 35876, 5858, 5728, 5799, 5612, 5605, 5680, 5740, 5718, 5709, 18045, 18239, 18129, - 18521, 18596, 18557, 18045, 18129, 17861, 23009, 22806, 23089, 23614, 23483, 23568, 17230, - 17255, 17740, 16883, 16982, 16798, 16883, 16798, 16628, 7802, 7975, 7588, 12111, 11968, - 11920, 12272, 12111, 12256, 12272, 12256, 12358, 29396, 29632, 29448, 29708, 29774, 29801, - 29712, 29632, 29592, 33945, 34056, 33981, 34063, 34056, 33945, 33872, 33647, 33826, 32464, - 32313, 32303, 8877, 8840, 8824, 9143, 9169, 8948, 10805, 10984, 11030, 7375, 7465, - 7603, 6704, 6847, 6877, 12758, 12854, 12748, 12748, 12854, 12864, 6101, 6071, 6201, - 6101, 6201, 6109, 6152, 6306, 6242, 6014, 6022, 5939, 6022, 6122, 5939, 6152, - 6242, 6168, 6594, 6542, 6717, 7079, 7045, 6639, 7835, 7726, 7869, 7662, 7375, - 7603, 7742, 7726, 7835, 10869, 11000, 11011, 10222, 10360, 10206, 12153, 12272, 12358, - 15060, 15273, 15156, 15060, 15156, 14797, 16243, 16404, 16064, 25276, 25137, 25164, 24218, - 23997, 23909, 25083, 25137, 25276, 25083, 25276, 25214, 26562, 26411, 26550, 26562, 26550, - 26606, 34395, 34373, 34344, 34531, 34448, 34640, 34120, 34101, 33777, 36278, 36262, 36253, - 36457, 36262, 36278, 36942, 36864, 36797, 6704, 6877, 6699, 6544, 6597, 6112, 35708, - 35675, 35672, 35708, 35672, 35764, 10078, 10010, 10159, 10078, 10159, 10117, 33826, 33459, - 33874, 17253, 17436, 17192, 36900, 36801, 36607, 36872, 36775, 36748, 36571, 36632, 36704, - 9906, 10078, 10119, 23790, 23939, 23694, 23328, 23381, 23241, 36864, 36837, 36731, 6739, - 6976, 6828, 7253, 7248, 7422, 7588, 7975, 7753, 14223, 14325, 14018, 13484, 13584, - 13628, 13376, 13584, 13484, 13376, 13482, 13194, 28197, 28097, 27998, 28179, 28097, 28197, - 23009, 23089, 23107, 16093, 16243, 16064, 15637, 15668, 15539, 25460, 25621, 25592, 25967, - 25621, 25493, 25807, 25967, 26045, 15641, 15637, 15585, 7120, 7248, 7253, 13189, 13376, - 13194, 5829, 6282, 6239, 17740, 17255, 17945, 16373, 16052, 16282, 17189, 17253, 17192, - 17189, 17192, 16982, 6451, 6506, 6588, 16723, 16883, 16628, 16516, 16628, 16584, 26683, - 26770, 26556, 5612, 5680, 5595, 6073, 6152, 6168, 6465, 6542, 6506, 6630, 6806, - 6717, 27330, 27355, 27313, 27313, 27355, 27413, 27418, 27436, 27537, 27218, 27080, 27111, - 8291, 8402, 8206, 7911, 7999, 8046, 29712, 29774, 29708, 29712, 29708, 29632, 29632, - 29396, 29592, 34056, 34120, 33981, 34145, 34120, 34056, 7726, 7639, 7662, 7911, 8046, - 7896, 34407, 34281, 34344, 34341, 34017, 33938, 33863, 34017, 33560, 33523, 33443, 33339, - 34407, 34344, 34373, 7248, 7289, 7422, 23615, 23614, 23568, 23107, 23089, 23174, 24064, - 23997, 24218, 23790, 23694, 23425, 33506, 33390, 33131, 32929, 32968, 32857, 5740, 5923, - 5718, 5595, 5719, 5567, 18388, 18596, 18521, 17779, 18045, 17861, 17779, 17861, 17670, - 23381, 23438, 23425, 23328, 23438, 23381, 33506, 33131, 33119, 34597, 34411, 34356, 18703, - 18554, 18747, 18703, 18747, 18885, 18388, 18291, 18239, 34341, 33938, 34184, 32739, 32634, - 32594, 5719, 5537, 5567, 6071, 5829, 6239, 6478, 6586, 6580, 36262, 36274, 36242, - 36368, 36274, 36459, 36801, 36567, 36607, 6699, 6877, 7123, 6622, 6478, 6615, 27149, - 27218, 27111, 7465, 7370, 7510, 7643, 7639, 7726, 28960, 28631, 28729, 28414, 28197, - 28303, 29607, 29255, 28991, 29607, 29501, 29650, 34640, 34448, 34740, 7342, 7370, 7375, - 12854, 12945, 12923, 12758, 12945, 12854, 12748, 12549, 12469, 12241, 12311, 12489, 28960, - 28729, 29100, 35132, 34811, 34564, 34740, 34925, 34791, 35528, 35403, 35467, 35619, 36194, - 36118, 5675, 5799, 5728, 19071, 19205, 19589, 20748, 20728, 20801, 20801, 20776, 20999, - 22740, 23100, 22314, 20614, 20728, 20748, 20480, 20728, 20614, 20480, 20614, 20393, 20231, - 20220, 20174, 20220, 20117, 20174, 5532, 5636, 5477, 5532, 5655, 5636, 5532, 5560, - 5655, 5577, 5527, 5713, 5636, 5584, 5533, 5584, 5593, 5533, 5593, 5478, 5533, - 5603, 5556, 5593, 5870, 6107, 5922, 6022, 6073, 6168, 5870, 5922, 5788, 6561, - 6630, 6717, 6542, 6594, 6506, 14223, 14018, 14106, 15724, 15823, 15637, 17230, 17193, - 17255, 17213, 17193, 17230, 17074, 17189, 16982, 17550, 17779, 17670, 16723, 16982, 16883, - 20728, 20776, 20801, 20897, 20669, 20245, 21620, 21405, 21818, 36892, 36912, 36881, 36881, - 36912, 36822, 37388, 36922, 36744, 36830, 36990, 36862, 36862, 36916, 36769, 36864, 36942, - 36837, 36910, 36912, 36892, 36892, 36715, 36911, 36711, 37066, 36715, 5702, 5675, 5728, - 18554, 18531, 18747, 18703, 18531, 18554, 23107, 23174, 23133, 22806, 22671, 22488, 36727, - 36452, 36587, 25137, 24925, 25032, 25083, 24925, 25137, 33523, 33472, 33560, 5705, 6176, - 5908, 5599, 5908, 5643, 23615, 23568, 23784, 23615, 23784, 23903, 5560, 5528, 5892, - 5440, 5615, 5726, 20174, 20117, 20020, 20776, 21005, 20999, 25621, 25807, 25805, 24792, - 24401, 24463, 36711, 36878, 37066, 5788, 5891, 5822, 24142, 24218, 24431, 23939, 24135, - 24034, 23953, 24135, 23939, 8840, 8671, 8824, 9138, 9169, 9242, 20020, 20117, 20063, - 7793, 7742, 7835, 8074, 8046, 8146, 12241, 12188, 12311, 29060, 28960, 29100, 34341, - 34198, 34281, 34281, 34198, 34251, 33721, 33523, 33560, 35895, 36047, 35841, 36011, 36176, - 36151, 36344, 36660, 36632, 36235, 36047, 36106, 37003, 36878, 36898, 36875, 36748, 36641, - 5603, 5486, 5556, 8124, 8246, 8287, 8207, 8287, 8402, 7737, 8921, 8575, 7945, - 8028, 8460, 7802, 8028, 7945, 37003, 36898, 36965, 7832, 7742, 7793, 7375, 7370, - 7465, 34481, 34407, 34373, 34481, 34373, 34531, 6561, 6542, 6466, 35784, 35708, 35764, - 5952, 6073, 6022, 6465, 6506, 6451, 19700, 20063, 19551, 32261, 32227, 32110, 32041, - 31951, 31746, 32444, 32428, 32634, 37091, 36542, 36822, 7588, 7753, 7566, 7248, 7247, - 7289, 7096, 7120, 7253, 7079, 7120, 7096, 7045, 6976, 6639, 6878, 6806, 6624, - 18596, 18636, 18736, 18211, 18388, 18239, 18211, 18239, 18045, 22899, 22671, 22806, 23133, - 23174, 23265, 23147, 23100, 23028, 23790, 23953, 23939, 28090, 27592, 27607, 28414, 28471, - 28524, 28414, 28524, 28710, 32008, 32106, 32096, 32339, 32464, 32303, 32595, 32695, 32628, - 31706, 31855, 31946, 30520, 30372, 30578, 32634, 32545, 32594, 32339, 32303, 32096, 5462, - 5577, 5678, 5440, 5726, 5626, 8870, 8855, 8877, 19205, 19038, 19117, 19071, 19038, - 19205, 30517, 30372, 30325, 32464, 32474, 32313, 36922, 36990, 36830, 14106, 14018, 13831, - 14018, 13844, 13831, 13377, 13584, 13376, 13194, 13133, 13071, 27392, 27436, 27355, 27355, - 27436, 27418, 27330, 27313, 27218, 27330, 27218, 27149, 32739, 32594, 33326, 33443, 33523, - 33709, 35528, 35467, 35633, 8291, 8207, 8402, 30440, 30268, 30275, 29060, 28916, 28960, - 30693, 30670, 30559, 30211, 30318, 29956, 13071, 13133, 12945, 23465, 23133, 23265, 23986, - 23784, 23997, 28798, 28524, 28631, 31038, 31389, 31759, 33501, 33326, 33443, 5556, 5486, - 5478, 12921, 13071, 12945, 12311, 12188, 12089, 34740, 34594, 34811, 34740, 34448, 34594, - 36990, 36943, 36862, 6624, 6806, 6630, 24064, 23986, 23997, 24542, 24142, 24431, 26928, - 26626, 26770, 35633, 35467, 35675, 35427, 35598, 35402, 35294, 35005, 34799, 34879, 34663, - 34767, 10010, 9923, 10061, 8870, 8846, 8855, 9977, 9923, 10010, 9977, 10010, 10078, - 31038, 30981, 31389, 32715, 32695, 32595, 32968, 33192, 33013, 5523, 5527, 5577, 36943, - 36916, 36862, 36837, 36999, 36731, 19038, 18946, 18885, 19051, 18946, 19038, 36998, 36875, - 36641, 36764, 36734, 36966, 6526, 6478, 6622, 13115, 13071, 13005, 34767, 34663, 34585, - 34561, 34426, 34411, 22899, 22806, 23009, 23465, 23483, 23614, 9923, 9977, 9850, 9906, - 9977, 10078, 9852, 10019, 9986, 9852, 9986, 9703, 31389, 30981, 30660, 7911, 7832, - 7930, 7375, 7662, 7406, 7819, 7832, 7911, 7896, 8046, 8074, 7247, 7566, 7289, - 29704, 29607, 29650, 28960, 28916, 28631, 36734, 36919, 36966, 6571, 6624, 6630, 6561, - 6717, 6542, 30517, 30578, 30372, 9513, 9479, 9805, 10019, 10068, 10083, 12364, 12311, - 12366, 18169, 17740, 17945, 18454, 17945, 18531, 17550, 17670, 17347, 5426, 5605, 5612, - 5567, 5612, 5595, 16093, 16064, 15990, 17189, 17074, 17253, 15823, 15990, 15918, 15823, - 15918, 15637, 21005, 21762, 21502, 8207, 8124, 8287, 8120, 8124, 8207, 12921, 12945, - 12758, 12311, 12089, 12366, 34640, 34481, 34531, 34407, 34558, 34281, 33721, 33560, 34017, - 34558, 34481, 34628, 34597, 34561, 34411, 34063, 33945, 33872, 5715, 5702, 5728, 5537, - 5851, 5790, 5715, 5728, 5740, 5715, 5740, 5709, 18186, 18211, 18124, 18388, 18636, - 18596, 23100, 23328, 23241, 23147, 23328, 23100, 9138, 9044, 9169, 8391, 8402, 8573, - 10068, 10149, 10206, 32695, 32929, 32773, 34182, 34063, 33872, 36734, 36870, 36919, 6511, - 6526, 6622, 6511, 6622, 6704, 6465, 6451, 5954, 14654, 14788, 14797, 14544, 14788, - 14654, 26965, 26928, 26770, 36304, 35662, 36157, 35784, 36153, 35708, 35742, 35529, 35528, - 6120, 6384, 6152, 5939, 6122, 5969, 5939, 5969, 5826, 16243, 16516, 16584, 24773, - 24542, 24431, 25429, 25312, 25224, 5615, 5599, 5643, 5652, 5788, 5822, 5787, 5807, - 5886, 5432, 5599, 5615, 22899, 23009, 22995, 27524, 27721, 27436, 27436, 27721, 27537, - 30511, 30517, 30318, 27524, 27436, 27458, 6698, 6976, 6739, 7036, 7247, 7248, 6698, - 6739, 6693, 6698, 6693, 6599, 8671, 8840, 8855, 29950, 29704, 29650, 31257, 31263, - 31513, 30318, 30517, 30325, 31866, 31855, 31759, 30211, 29801, 29774, 34718, 34740, 34791, - 37119, 36942, 36797, 36667, 36443, 36284, 36919, 37029, 37090, 9044, 8948, 9169, 10149, - 10222, 10206, 5652, 5822, 5759, 14353, 14496, 14423, 13831, 13844, 13592, 13377, 13376, - 13189, 36571, 36623, 36587, 36998, 36988, 36875, 36706, 36660, 36344, 7375, 7406, 7299, - 7823, 7896, 7762, 7819, 7896, 7823, 33709, 33501, 33443, 34341, 34184, 34198, 5537, - 5790, 5488, 5923, 6045, 5718, 5599, 5705, 5908, 36988, 36872, 36875, 37029, 36870, - 37084, 34145, 34224, 34270, 6599, 6693, 6624, 6040, 6152, 5920, 6607, 6699, 6480, - 7342, 7510, 7370, 6599, 6624, 6572, 35528, 35529, 35420, 35484, 35553, 35132, 35633, - 35675, 35814, 36047, 36143, 36011, 36235, 36143, 36047, 7036, 7248, 7120, 13071, 13115, - 13194, 12483, 12758, 12469, 18773, 18703, 18885, 18773, 18885, 18946, 5826, 5969, 5886, - 17489, 17213, 17230, 17193, 17148, 16989, 17148, 17213, 17241, 24595, 24792, 24463, 26965, - 27040, 26928, 24595, 24261, 24135, 35807, 36907, 36667, 36274, 36368, 36242, 12311, 12364, - 12489, 10862, 11031, 11000, 21762, 22108, 22028, 36942, 36999, 36837, 6571, 6630, 6561, - 16362, 16516, 16243, 14353, 14423, 14223, 35742, 35633, 35814, 7643, 7742, 7832, 11349, - 11030, 11149, 11875, 11920, 11968, 12550, 12921, 12758, 28317, 28370, 28133, 6101, 5956, - 6071, 5991, 6109, 6431, 6597, 6586, 6339, 6014, 5952, 6022, 5840, 5952, 6014, - 24142, 23986, 24064, 23682, 23465, 23614, 22995, 23009, 23107, 24044, 23986, 24142, 23588, - 23425, 23438, 23588, 23438, 23328, 36998, 36641, 36801, 36113, 36706, 36344, 8948, 8846, - 8870, 23682, 23614, 23615, 9789, 9513, 9805, 9138, 9047, 9044, 9044, 9047, 8948, - 8948, 8719, 8846, 9843, 10061, 9923, 9843, 9923, 9850, 18474, 18636, 18388, 18296, - 18388, 18211, 20464, 20669, 20851, 23193, 23107, 23133, 32227, 32065, 32041, 32397, 32238, - 32261, 32455, 32261, 32444, 32455, 32444, 32692, 32464, 32565, 32474, 32474, 32565, 32595, - 32695, 32877, 32929, 32106, 32212, 32096, 32128, 32212, 32106, 32128, 32106, 31983, 32128, - 31983, 31946, 32128, 31946, 31923, 31946, 31855, 31923, 32397, 32453, 32358, 36999, 36989, - 36731, 15318, 15119, 15739, 12446, 12715, 12765, 16052, 15814, 16282, 26411, 26562, 26358, - 27592, 27320, 27607, 32218, 32065, 32227, 31923, 31855, 31866, 6333, 6308, 6478, 6663, - 6511, 6704, 6409, 6571, 6561, 6466, 6542, 6465, 7896, 7819, 7911, 7896, 8074, - 7979, 11923, 11875, 12111, 12153, 12111, 12272, 12715, 12881, 12968, 15119, 14616, 14831, - 26928, 27040, 27111, 26333, 25805, 25807, 29607, 29508, 29255, 30141, 30115, 30268, 29592, - 29396, 29651, 7946, 8575, 8264, 10019, 9841, 10068, 10068, 10081, 10149, 10298, 10333, - 10222, 32703, 32565, 32464, 34063, 34145, 34056, 33459, 33406, 33778, 33826, 33874, 33935, - 7643, 7726, 7742, 14039, 13466, 14152, 29060, 29100, 29255, 28234, 28097, 28179, 28090, - 27998, 28097, 35137, 35294, 34799, 34654, 34767, 34585, 34654, 34426, 34561, 5939, 5789, - 6014, 5787, 5886, 5870, 5787, 5870, 5788, 9789, 9843, 9850, 9651, 9852, 9703, - 17213, 17148, 17193, 17241, 17213, 17489, 24773, 24431, 24925, 25066, 24925, 25083, 32065, - 31951, 32041, 31866, 31759, 31882, 32565, 32715, 32595, 36989, 36940, 36731, 7530, 7643, - 7832, 12412, 12153, 12358, 34481, 34558, 34407, 34718, 34481, 34640, 34718, 34640, 34740, - 16634, 16723, 16516, 16516, 16723, 16628, 18186, 18296, 18211, 15485, 15637, 15539, 20851, - 20669, 20897, 22520, 22488, 22671, 36912, 37091, 36822, 36922, 37015, 36990, 36990, 37015, - 36943, 36943, 37047, 36916, 36916, 37119, 36797, 36942, 37049, 36999, 36999, 37017, 36989, - 36989, 37017, 36940, 37026, 37091, 36912, 37026, 36912, 36910, 37026, 36910, 37129, 36910, - 36911, 37129, 36878, 37003, 37066, 37003, 37007, 37066, 6339, 6586, 6478, 6040, 6120, - 6152, 10845, 10869, 10627, 10333, 10360, 10222, 15060, 14797, 14788, 32692, 32444, 32634, - 33709, 33721, 34427, 5560, 5273, 5528, 5528, 5482, 5678, 5523, 5446, 5527, 5532, - 5471, 5560, 5507, 5471, 5532, 5507, 5532, 5477, 20215, 20231, 20174, 20342, 20480, - 20231, 20231, 20480, 20393, 20885, 20933, 20776, 20776, 20933, 21005, 21005, 21017, 21762, - 21762, 21925, 22108, 20215, 20174, 20020, 5718, 6045, 5673, 5589, 5675, 5702, 14184, - 14353, 14223, 13592, 13706, 13584, 13377, 13189, 13115, 20606, 20776, 20728, 23297, 23588, - 23328, 30514, 30243, 30268, 30514, 30268, 30490, 31389, 31467, 31518, 35137, 34799, 34879, - 35862, 34959, 35103, 37003, 37086, 37007, 36727, 36587, 36623, 36113, 36078, 36842, 7079, - 7028, 7120, 7083, 7588, 7566, 6574, 7028, 7079, 7036, 7028, 6574, 6512, 6698, - 6599, 14616, 14039, 14152, 28234, 28179, 28275, 28275, 28179, 28414, 27721, 28186, 27952, - 28317, 28186, 28229, 6571, 6572, 6624, 6409, 6466, 5954, 5477, 5636, 5533, 5477, - 5533, 5358, 5273, 5482, 5528, 5527, 5440, 5626, 5589, 5702, 5578, 19851, 19071, - 19589, 18703, 18454, 18531, 19948, 20215, 20020, 12364, 12483, 12469, 12921, 13005, 13071, - 12366, 12483, 12364, 34740, 34811, 34925, 34597, 34654, 34561, 34767, 35019, 34879, 8846, - 8671, 8855, 7979, 8074, 8124, 8391, 8671, 8478, 26436, 26333, 26464, 35689, 35602, - 35113, 5482, 5462, 5678, 5578, 5702, 5715, 18523, 18454, 18703, 9050, 9047, 9138, - 19071, 19051, 19038, 18852, 19051, 19071, 30655, 30559, 30670, 36727, 36623, 36740, 37003, - 36965, 37086, 5478, 5593, 5556, 6699, 6663, 6704, 6308, 6339, 6478, 6607, 6663, - 6699, 6607, 6480, 6516, 12874, 13005, 12921, 14496, 14544, 14654, 14184, 14223, 14106, - 35602, 35608, 35598, 37388, 37015, 36922, 36965, 37054, 37086, 5845, 5829, 6071, 5845, - 6071, 5956, 16723, 17074, 16982, 17089, 17074, 16766, 24631, 24595, 24135, 24792, 25114, - 25263, 24631, 24135, 24083, 30202, 30211, 29774, 29651, 29396, 29624, 29768, 29738, 29908, - 5709, 5578, 5715, 5673, 6045, 5926, 5462, 5446, 5523, 37015, 37047, 36943, 14782, - 15060, 14788, 25214, 25066, 25083, 26954, 26652, 26606, 26499, 25655, 26358, 5607, 5787, - 5788, 5807, 5826, 5886, 5920, 6152, 6073, 5652, 5759, 5642, 5759, 5705, 5590, - 30419, 30141, 30243, 30243, 30141, 30268, 29060, 28798, 28916, 29768, 29774, 29712, 30728, - 30660, 30578, 37047, 37071, 36916, 6409, 6572, 6571, 6512, 6572, 6383, 14388, 14544, - 14496, 19051, 18943, 18946, 18852, 18943, 19051, 22683, 22520, 22671, 22683, 22671, 22899, - 27040, 27149, 27111, 27031, 27149, 27040, 28916, 28798, 28631, 29060, 29255, 29260, 15823, - 15802, 15990, 15746, 15724, 15641, 18211, 18045, 18124, 19551, 20063, 18736, 23465, 23193, - 23133, 23110, 23193, 23136, 23903, 23784, 23986, 23903, 23986, 24012, 23028, 23100, 22740, - 23588, 23790, 23425, 36143, 36176, 36011, 36235, 36176, 36143, 5486, 5603, 5605, 30728, - 30578, 30517, 37071, 37119, 36916, 36965, 36966, 37054, 6143, 5991, 6431, 5924, 5991, - 5934, 30425, 30511, 30318, 33192, 32968, 33104, 34876, 34767, 34848, 36457, 36274, 36262, - 35553, 35600, 35692, 36457, 36278, 36443, 5590, 5705, 5524, 23668, 23790, 23588, 36740, - 36623, 36704, 36740, 36704, 36632, 5346, 5486, 5605, 5488, 5790, 5675, 5441, 5537, - 5468, 37010, 36998, 36801, 37054, 36966, 37094, 36966, 36919, 37094, 5744, 5826, 5660, - 5826, 5807, 5621, 12483, 12550, 12758, 12366, 12550, 12483, 24896, 24773, 24925, 24595, - 24738, 24792, 24631, 24738, 24595, 26722, 26965, 26770, 29808, 29607, 29704, 6478, 6526, - 6333, 26333, 26436, 26556, 26539, 26436, 26464, 7819, 7766, 7832, 7406, 7662, 7639, - 7979, 8124, 8087, 30538, 30517, 30511, 29738, 29768, 29712, 28913, 28917, 28679, 34628, - 34281, 34558, 34568, 34341, 34281, 18418, 18474, 18388, 18124, 18045, 17860, 23147, 23297, - 23328, 23281, 23297, 23147, 26761, 26559, 26652, 28234, 28090, 28097, 28201, 28090, 28234, - 28275, 28414, 28456, 33332, 33192, 33320, 36706, 36842, 36934, 8120, 8207, 8291, 5496, - 5612, 5567, 37094, 36919, 37090, 28201, 28321, 28178, 28186, 28317, 28133, 28229, 28186, - 27721, 27355, 27330, 27392, 36574, 36457, 36443, 27392, 27330, 27149, 35529, 35600, 35484, - 35611, 35600, 35529, 36153, 35784, 36330, 32238, 32278, 32227, 32065, 32231, 31951, 30670, - 30693, 31257, 32455, 32397, 32261, 32739, 33326, 33501, 32212, 32339, 32096, 32749, 32877, - 32715, 33104, 32968, 32929, 32226, 32339, 32212, 32226, 32212, 32128, 32226, 32128, 31923, - 32226, 31923, 31984, 9513, 9439, 9344, 9565, 9439, 9513, 9363, 9615, 9546, 10081, - 10222, 10149, 18943, 18773, 18946, 17489, 17230, 17740, 18852, 18773, 18943, 22748, 22683, - 22899, 22520, 22242, 21818, 32397, 32278, 32238, 32278, 32218, 32227, 5357, 5440, 5527, - 37119, 37049, 36942, 36574, 36459, 36457, 36919, 36870, 37029, 6663, 6554, 6511, 6351, - 6348, 6480, 7299, 7342, 7375, 9841, 10019, 9852, 10862, 10900, 11031, 10505, 10869, - 10645, 24357, 24142, 24542, 23110, 22995, 23107, 27458, 27392, 27553, 8391, 8742, 8671, - 8087, 8120, 8066, 11779, 12321, 11216, 36413, 36078, 36151, 36106, 36047, 35895, 5591, - 5578, 5709, 5591, 5709, 5718, 9843, 9789, 9805, 9850, 9977, 9906, 18418, 18388, - 18296, 17737, 18045, 17779, 36870, 36872, 37084, 13080, 13377, 13115, 14144, 14184, 14106, - 14353, 14388, 14496, 12550, 12874, 12921, 12397, 12874, 12550, 28317, 28715, 28370, 34876, - 35019, 34767, 35634, 35608, 35602, 35763, 35862, 35608, 34270, 34120, 34145, 10078, 10117, - 10119, 9651, 9841, 9852, 33971, 32739, 33501, 33709, 33523, 33721, 36009, 36106, 35876, - 6572, 6512, 6599, 6409, 6561, 6466, 16373, 16282, 16989, 17489, 17504, 17440, 24488, - 24357, 24542, 36868, 36740, 36632, 36413, 36151, 36321, 10333, 10468, 10645, 10366, 10468, - 10333, 30141, 29950, 29742, 30333, 29950, 30141, 30655, 30490, 30559, 34280, 34270, 34224, - 34336, 34270, 34280, 10119, 10117, 10559, 37084, 36872, 36988, 10845, 10900, 10862, 10786, - 10900, 10845, 25066, 24896, 24925, 24773, 24488, 24542, 26559, 26358, 26562, 30538, 30728, - 30517, 30538, 30511, 30425, 36389, 36304, 36157, 36457, 36459, 36274, 37064, 36595, 36940, - 7406, 7639, 7643, 17347, 17670, 17253, 17089, 17253, 17074, 34848, 34767, 34654, 37010, - 37121, 36998, 37121, 37084, 36988, 36760, 36632, 36660, 6112, 6143, 6544, 6333, 6526, - 6397, 26652, 26559, 26562, 26954, 27320, 27592, 26436, 26539, 26556, 27251, 27392, 27149, - 26464, 26333, 26339, 34356, 34411, 34120, 35862, 35402, 35598, 35862, 35598, 35608, 9047, - 8976, 8948, 9439, 9050, 9138, 35410, 35113, 35294, 37049, 37017, 36999, 10468, 10505, - 10645, 10570, 10505, 10410, 35585, 35410, 35294, 35137, 34879, 35019, 9841, 10081, 10068, - 24663, 24488, 24773, 23808, 23615, 23903, 28275, 28201, 28234, 28090, 27758, 27592, 28710, - 28524, 28798, 28710, 28798, 28793, 6120, 5889, 6451, 5920, 6073, 5952, 15724, 15802, - 15823, 15746, 15802, 15724, 15724, 15637, 15641, 36384, 36157, 36368, 25212, 24896, 25066, - 34718, 34628, 34481, 34925, 34811, 35078, 34738, 34848, 34654, 34876, 34952, 35019, 37121, - 36988, 36998, 17135, 16989, 17148, 15119, 14598, 14616, 12911, 13466, 12994, 15966, 16093, - 15990, 36479, 36384, 36368, 36321, 36151, 36176, 36321, 36176, 36235, 36321, 36396, 36334, - 7028, 7036, 7120, 6639, 6976, 6698, 18418, 18296, 18322, 18296, 18186, 18322, 20480, - 20606, 20728, 20933, 21017, 21005, 23490, 23570, 23297, 20573, 20606, 20480, 20342, 20231, - 20215, 23110, 23107, 23193, 22605, 22500, 22520, 23193, 23463, 23136, 31063, 31186, 31257, - 31882, 31759, 31652, 30425, 30318, 30211, 29908, 29774, 29768, 5559, 5591, 5718, 5441, - 5567, 5537, 5441, 5496, 5567, 5673, 5926, 5829, 5652, 5607, 5788, 5840, 5920, - 5952, 5558, 5705, 5464, 20606, 20885, 20776, 24083, 24135, 23953, 23297, 23570, 23588, - 23668, 23570, 23681, 10081, 10115, 10222, 14144, 14106, 14032, 14544, 14570, 14788, 17241, - 17135, 17148, 18169, 17945, 18454, 27392, 27458, 27436, 27524, 27737, 27721, 28317, 28788, - 28715, 27251, 27149, 27151, 35638, 35634, 35602, 11875, 11680, 11920, 9748, 9774, 9906, - 11849, 11680, 11875, 11923, 12111, 12153, 11923, 12153, 11945, 20485, 20342, 20067, 29738, - 29712, 29592, 34270, 34336, 34120, 34597, 34738, 34654, 33935, 33872, 33826, 10570, 10627, - 10505, 10505, 10627, 10869, 12412, 12358, 12715, 20885, 21017, 20933, 36194, 35619, 35662, - 5537, 5488, 5468, 5991, 5924, 5956, 5934, 5991, 6143, 16162, 16362, 16243, 25224, - 25276, 25429, 25214, 25212, 25066, 37017, 37064, 36940, 5507, 5417, 5471, 5213, 5320, - 5482, 5320, 5357, 5462, 5462, 5357, 5446, 5446, 5357, 5527, 5477, 5417, 5507, - 5418, 5417, 5477, 5418, 5477, 5358, 5533, 5478, 5358, 29908, 30202, 29774, 37172, - 37129, 36911, 37026, 37258, 37091, 37673, 37160, 37015, 37015, 37160, 37047, 37047, 37160, - 37071, 37071, 37160, 37119, 37119, 37180, 37049, 37049, 37180, 37017, 37017, 37177, 37064, - 37172, 36911, 37066, 37172, 37066, 37463, 37066, 37007, 37391, 37007, 37086, 37171, 37086, - 37054, 37171, 37054, 37094, 37171, 37094, 37245, 37171, 6607, 6554, 6663, 6516, 6554, - 6607, 14272, 14388, 14353, 35712, 35763, 35608, 36285, 36106, 36009, 37094, 37090, 37245, - 20485, 20480, 20342, 18322, 18186, 18195, 22605, 22520, 22683, 23682, 23615, 23808, 16766, - 17074, 16723, 18195, 18186, 18124, 24738, 25022, 24792, 23911, 23953, 23790, 35137, 34952, - 35181, 35069, 34952, 34876, 36778, 36667, 36896, 36576, 36389, 36384, 5358, 5478, 5388, - 5675, 5589, 5488, 26539, 26683, 26556, 26511, 26683, 26539, 37293, 37090, 37029, 37010, - 36801, 37296, 5478, 5369, 5388, 5590, 5642, 5759, 5548, 5642, 5590, 23808, 23903, - 24012, 23570, 23668, 23588, 23281, 23147, 23210, 30655, 30514, 30490, 29950, 29808, 29704, - 30674, 30514, 30655, 33778, 33406, 33390, 8719, 8671, 8846, 7762, 7896, 7979, 7762, - 7766, 7823, 7823, 7766, 7819, 10627, 10692, 10845, 11455, 11779, 11216, 10487, 10692, - 10627, 16500, 16634, 16516, 24724, 25022, 24738, 34427, 33721, 34017, 34368, 34017, 34341, - 36628, 36574, 36443, 5478, 5486, 5369, 5320, 5462, 5482, 5548, 5581, 5642, 8755, - 8719, 8948, 10115, 10298, 10222, 33192, 33332, 33119, 32877, 32695, 32715, 6112, 6597, - 6339, 6112, 6339, 6308, 16093, 16162, 16243, 16362, 16500, 16516, 15802, 15966, 15990, - 15436, 15485, 15539, 36252, 36235, 36106, 36252, 36106, 36285, 32278, 32323, 32218, 32218, - 32314, 32065, 32397, 32358, 32278, 32453, 32397, 32455, 32692, 32634, 32732, 15846, 15966, - 15802, 36304, 36194, 35662, 36384, 36389, 36157, 36476, 36368, 36459, 5369, 5486, 5324, - 5488, 5589, 5429, 8087, 8124, 8120, 9615, 9651, 9703, 10028, 10115, 10081, 10028, - 10165, 10115, 10115, 10165, 10298, 9475, 9651, 9615, 9475, 9615, 9363, 10921, 11216, - 10900, 12366, 12397, 12550, 18384, 18276, 18454, 18670, 18703, 18773, 17737, 17779, 17717, - 20342, 20215, 20067, 22605, 22683, 22748, 22748, 22899, 22921, 23463, 23193, 23465, 30071, - 29808, 29950, 30077, 30264, 30202, 29651, 29738, 29592, 31984, 31923, 31866, 32749, 32715, - 32565, 31984, 31866, 31882, 34336, 34356, 34120, 34513, 34356, 34336, 35611, 35529, 35726, - 36356, 36194, 36304, 37388, 36744, 37091, 32732, 32634, 32739, 7802, 7946, 8028, 9031, - 9475, 9363, 7083, 7566, 7247, 11779, 12089, 12188, 13080, 13115, 13005, 29603, 29508, - 29607, 34791, 34628, 34718, 36586, 36476, 36459, 5612, 5496, 5426, 27758, 26954, 27592, - 25226, 25212, 25224, 9906, 9774, 9850, 9850, 9774, 9789, 9789, 9565, 9513, 8872, - 8976, 9050, 9050, 8976, 9047, 10119, 10559, 10157, 31759, 31389, 31652, 33971, 32732, - 32739, 5642, 5581, 5652, 5607, 5581, 5502, 17717, 17779, 17550, 23682, 23463, 23465, - 24012, 23986, 24044, 24663, 24357, 24488, 24663, 24773, 24694, 28167, 27758, 28090, 28178, - 28090, 28201, 27651, 27737, 27524, 29651, 29893, 29738, 27651, 27524, 27458, 35600, 35553, - 35484, 34800, 34706, 34628, 35528, 35633, 35742, 10692, 10786, 10845, 10704, 10786, 10692, - 26683, 26722, 26770, 26213, 26333, 25807, 13439, 13377, 13270, 14184, 14272, 14353, 8183, - 8120, 8291, 24631, 24724, 24738, 25022, 25114, 24792, 24851, 24724, 24631, 30514, 30419, - 30243, 30536, 30419, 30514, 31652, 31389, 31518, 30264, 30425, 30211, 30264, 30211, 30202, - 36584, 36479, 36476, 36667, 36644, 36443, 36778, 36644, 36667, 18802, 18852, 19071, 22899, - 22995, 22921, 36900, 36452, 36727, 37181, 37029, 37084, 5426, 5496, 5402, 14032, 14106, - 13831, 14388, 14461, 14544, 30660, 31467, 31389, 32703, 32464, 32339, 35675, 35708, 35814, - 35689, 35638, 35602, 35634, 35712, 35608, 35809, 35906, 35862, 35689, 35113, 35410, 17207, - 17347, 17253, 17207, 17253, 17089, 36706, 36760, 36660, 37024, 36900, 36727, 36914, 36760, - 36934, 36868, 36914, 36957, 18276, 18169, 18454, 18230, 18169, 18276, 18636, 19551, 18736, - 18125, 18195, 18124, 22314, 22244, 22740, 23668, 23911, 23790, 36836, 36727, 36740, 7080, - 7123, 7342, 7305, 7406, 7643, 12446, 12412, 12715, 11923, 11849, 11875, 25045, 25114, - 25022, 37181, 37084, 37153, 6554, 6468, 6511, 7080, 7342, 7109, 14144, 14272, 14184, - 35726, 35742, 35814, 35638, 35712, 35634, 26954, 26761, 26652, 26694, 26761, 26713, 26697, - 26722, 26683, 5465, 5589, 5578, 5402, 5496, 5413, 7232, 7342, 7299, 18852, 18777, - 18773, 29107, 28798, 29060, 34952, 35137, 35019, 35069, 34876, 34848, 5581, 5607, 5652, - 5705, 5599, 5464, 8904, 8976, 8872, 8567, 8478, 8671, 8391, 8206, 8402, 15436, - 15273, 15485, 15746, 15846, 15802, 15947, 16162, 16093, 17228, 17207, 17188, 17860, 18125, - 18124, 17566, 17717, 17550, 21816, 21925, 21762, 23783, 23911, 23668, 30660, 31319, 31467, - 32877, 32988, 32929, 34088, 34182, 33935, 34532, 34738, 34597, 34224, 34145, 34063, 34182, - 33872, 33935, 36389, 36410, 36304, 35726, 35529, 35742, 36496, 36410, 36389, 36479, 36368, - 36476, 36868, 36836, 36740, 37242, 37180, 37119, 37064, 37773, 36595, 10786, 10921, 10900, - 10704, 10921, 10786, 31257, 31513, 31548, 6516, 6468, 6554, 14415, 14461, 14388, 27031, - 27040, 26965, 5432, 5615, 5440, 18474, 18418, 18356, 17860, 18045, 17737, 5944, 5934, - 6143, 5618, 5673, 5829, 5591, 5546, 5578, 5813, 5934, 5843, 5744, 5939, 5826, - 5954, 6466, 6465, 6088, 6112, 6308, 15947, 16093, 15966, 26464, 26511, 26539, 26045, - 26213, 25807, 36100, 36009, 35862, 36760, 36706, 36934, 36586, 36459, 36574, 29498, 29360, - 29508, 30419, 30333, 30141, 30536, 30333, 30419, 30077, 30202, 29908, 30773, 30728, 30538, - 33778, 33390, 33692, 5698, 5807, 5787, 8640, 8671, 8719, 10366, 10333, 10298, 10366, - 10505, 10468, 29508, 29360, 29255, 29603, 29607, 29808, 34532, 34597, 34356, 7088, 7232, - 7299, 32988, 33104, 32929, 5845, 5956, 5924, 5491, 5698, 5787, 17489, 17257, 17241, - 17440, 17257, 17489, 17428, 17566, 17550, 16766, 16723, 16634, 18777, 18670, 18773, 17334, - 17135, 17257, 22921, 23110, 22913, 22921, 22995, 23110, 5828, 5845, 5924, 16302, 16500, - 16362, 25224, 25212, 25214, 26498, 26358, 26559, 26694, 26498, 26559, 26694, 26559, 26761, - 26339, 26511, 26464, 26722, 27031, 26965, 6355, 6639, 6698, 6383, 6409, 6052, 27020, - 27031, 26722, 35809, 35862, 35763, 10157, 10559, 10289, 10559, 10805, 10289, 10028, 10081, - 9925, 30773, 30538, 30425, 17717, 17860, 17737, 17428, 17550, 17347, 5559, 5546, 5591, - 5558, 5524, 5705, 5511, 5621, 5698, 5399, 5524, 5558, 13377, 13592, 13584, 14144, - 14234, 14272, 14272, 14415, 14388, 13439, 13592, 13377, 23607, 23463, 23682, 23367, 23463, - 23607, 23281, 23490, 23297, 23210, 23490, 23281, 12316, 11945, 12153, 12765, 12715, 12968, - 12911, 12930, 12703, 29260, 29107, 29060, 35302, 34811, 35132, 34507, 34376, 34341, 28321, - 28275, 28456, 28321, 28201, 28275, 26713, 26761, 26954, 28066, 28229, 27721, 29738, 29893, - 29908, 28066, 27721, 27737, 27651, 27458, 27553, 35553, 35394, 35132, 35473, 35394, 35699, - 35692, 35600, 35611, 8478, 8380, 8391, 8442, 8380, 8478, 22913, 23110, 23066, 5496, - 5441, 5413, 5441, 5392, 5413, 5135, 5432, 5440, 28788, 28679, 28715, 34568, 34281, - 34628, 37180, 37198, 37017, 37153, 37084, 37121, 37153, 37121, 37214, 13947, 14032, 13794, - 27553, 27392, 27578, 35709, 35692, 35611, 36153, 35987, 35814, 35638, 35882, 35712, 35712, - 35809, 35763, 35800, 35689, 35410, 12316, 12153, 12412, 29360, 29260, 29255, 29690, 29603, - 29922, 33104, 33320, 33192, 34706, 34568, 34628, 8087, 7873, 7979, 7766, 7530, 7832, - 7024, 7109, 7032, 7892, 7873, 8087, 15691, 15846, 15746, 16501, 16708, 16500, 15691, - 15746, 15641, 34513, 34532, 34356, 34182, 34224, 34063, 34206, 34224, 34182, 15485, 15273, - 15077, 14570, 14544, 14461, 17257, 17135, 17241, 17489, 17740, 17504, 25967, 25807, 25621, - 26213, 26339, 26333, 5744, 5789, 5939, 5660, 5789, 5744, 5660, 5826, 5621, 6397, - 6526, 6511, 16708, 16634, 16500, 16708, 16766, 16634, 17591, 17717, 17566, 36644, 36628, - 36443, 36784, 36628, 36644, 35708, 36153, 35814, 5441, 5468, 5392, 22353, 22242, 22520, - 18802, 18777, 18852, 18802, 18670, 18777, 18678, 18591, 18670, 22353, 22520, 22500, 22353, - 22500, 22458, 22500, 22461, 22458, 37198, 37177, 37017, 37165, 37010, 37296, 37165, 37121, - 37010, 32358, 32323, 32278, 32597, 32453, 32455, 32323, 32453, 32509, 32455, 32692, 32597, - 18670, 18523, 18703, 18591, 18523, 18670, 32453, 32323, 32358, 26511, 26697, 26683, 26251, - 26339, 26213, 12439, 12316, 12412, 20485, 20573, 20480, 20606, 20888, 20885, 20885, 20888, - 21017, 21017, 21313, 21762, 18418, 18322, 18356, 23911, 24083, 23953, 24724, 25045, 25022, - 25493, 25621, 25460, 23904, 24083, 23911, 32323, 32314, 32218, 36836, 37024, 36727, 36760, - 36868, 36632, 36334, 36413, 36321, 18356, 18322, 18195, 20673, 20888, 20606, 33506, 33119, - 33332, 34071, 34088, 33935, 37129, 37258, 37026, 37160, 37242, 37119, 37180, 37279, 37198, - 37198, 37313, 37177, 37463, 37258, 37129, 37463, 37129, 37172, 37391, 37007, 37171, 37245, - 37090, 37293, 8699, 8640, 8719, 33320, 33368, 33332, 14234, 14415, 14272, 32719, 32703, - 32339, 32877, 32932, 32988, 32988, 33176, 33104, 33104, 33215, 33320, 33320, 33387, 33368, - 32321, 32339, 32226, 32247, 32226, 32206, 32226, 31984, 32206, 31832, 31882, 31652, 36341, - 36118, 36194, 35882, 35809, 35712, 36313, 36235, 36252, 5845, 5618, 5829, 5813, 5828, - 5924, 5813, 5924, 5934, 6025, 6100, 6112, 5789, 5840, 6014, 5889, 6120, 6040, - 25312, 25226, 25224, 24694, 24773, 24896, 36496, 36392, 36410, 36410, 36392, 36304, 36825, - 36586, 36574, 7080, 6909, 7123, 6261, 6397, 6468, 6468, 6397, 6511, 7232, 7109, - 7342, 7109, 7232, 7088, 29005, 28793, 28798, 28827, 28793, 28891, 28583, 28788, 28317, - 5392, 5468, 5403, 22500, 22605, 22461, 32703, 32749, 32565, 5417, 5307, 5471, 5357, - 5263, 5440, 5309, 5307, 5417, 5309, 5417, 5418, 5309, 5418, 5245, 5309, 5245, - 5271, 5358, 5388, 5319, 5388, 5369, 5319, 5369, 5269, 5319, 25429, 25276, 25466, - 26713, 26927, 26885, 26766, 26697, 26511, 27031, 27151, 27149, 18523, 18384, 18454, 18499, - 18384, 18523, 22740, 22244, 22459, 23490, 23681, 23570, 23210, 23028, 23064, 34513, 34336, - 34280, 34738, 34769, 34848, 34455, 34280, 34224, 5486, 5346, 5324, 5273, 5560, 5471, - 6088, 6025, 6112, 6480, 6468, 6516, 6409, 6383, 6572, 6747, 7083, 7247, 5889, - 6040, 5727, 8640, 8567, 8671, 8369, 8206, 8391, 10281, 10366, 10298, 10570, 10487, - 10627, 14415, 14570, 14461, 24694, 24857, 24785, 27020, 27151, 27031, 30333, 30071, 29950, - 29498, 29260, 29360, 30566, 30071, 30333, 30536, 30514, 30582, 29893, 30077, 29908, 30264, - 30431, 30425, 29977, 30077, 29893, 32274, 31513, 31951, 33498, 33506, 33368, 33368, 33506, - 33332, 35807, 37037, 36907, 36629, 36584, 36813, 5605, 5426, 5346, 5403, 5468, 5366, - 5506, 5559, 5718, 5366, 5468, 5488, 5465, 5559, 5422, 5524, 5548, 5590, 5399, - 5548, 5524, 17591, 17860, 17717, 18213, 18356, 18195, 17428, 17347, 17228, 22605, 22748, - 22692, 22461, 22605, 22692, 23530, 23681, 23490, 32899, 32932, 32877, 17228, 17347, 17207, - 16138, 16362, 16162, 24851, 25045, 24724, 25096, 25045, 25170, 8369, 8391, 8380, 33778, - 33874, 33459, 34088, 34144, 34182, 33892, 33874, 33778, 15846, 15865, 15966, 15688, 15691, - 15641, 15688, 15641, 15585, 18055, 17740, 18169, 16824, 17089, 16766, 36496, 36389, 36576, - 36396, 36321, 36235, 36313, 36252, 36285, 30226, 30431, 30264, 34133, 34144, 34088, 6088, - 6308, 5910, 15077, 15273, 15060, 26045, 26100, 26213, 26766, 26707, 26697, 26160, 26100, - 26045, 36100, 35862, 35906, 31617, 31832, 31652, 31617, 31652, 31518, 32932, 33045, 32988, - 18213, 18195, 18125, 23028, 23210, 23147, 22244, 22108, 22459, 27651, 27793, 27737, 28922, - 28913, 28788, 27792, 27793, 27651, 28178, 28167, 28090, 28456, 28414, 28710, 5426, 5303, - 5346, 5366, 5488, 5429, 10366, 10410, 10505, 11136, 11455, 11216, 11888, 12037, 12089, - 22748, 22921, 22913, 22692, 22748, 22913, 33712, 33549, 33506, 33506, 33549, 33390, 37296, - 36801, 36900, 37293, 37029, 37181, 14570, 14782, 14788, 5828, 5777, 5845, 5843, 5934, - 5944, 24857, 24896, 25084, 25276, 25655, 25466, 8976, 8904, 8948, 8640, 8596, 8567, - 8872, 9050, 9088, 9748, 9789, 9774, 28698, 28456, 28710, 29005, 29260, 29351, 33045, - 33176, 32988, 27627, 27553, 27578, 28827, 28710, 28793, 5402, 5303, 5426, 23681, 23783, - 23668, 23723, 23783, 23681, 8206, 8183, 8291, 7873, 7762, 7979, 8168, 8183, 8206, - 8442, 8478, 8393, 23607, 23682, 23808, 25269, 25212, 25226, 30431, 30773, 30425, 36778, - 36784, 36644, 36503, 36356, 36392, 36896, 36784, 36778, 7828, 7762, 7873, 5402, 5283, - 5303, 5429, 5589, 5169, 7688, 7530, 7766, 10073, 10028, 9925, 10165, 10188, 10298, - 10366, 10281, 10410, 11945, 11849, 11923, 12061, 11849, 11945, 13466, 14039, 12994, 12446, - 12439, 12412, 12316, 12061, 11945, 17440, 17334, 17257, 15366, 15318, 16052, 16052, 15318, - 15739, 17387, 17334, 17440, 29253, 29396, 28917, 30077, 30226, 30264, 30431, 30854, 30773, - 31467, 31617, 31518, 33176, 33215, 33104, 35809, 35928, 35906, 35957, 35882, 35638, 35928, - 35882, 35957, 35585, 35294, 35137, 25045, 25096, 25114, 24851, 24631, 24371, 5361, 5464, - 5329, 5464, 5599, 5329, 8393, 8478, 8567, 10338, 10487, 10410, 10410, 10487, 10570, - 18384, 18230, 18276, 18375, 18230, 18384, 20610, 20656, 20485, 18235, 18213, 18125, 18354, - 18213, 18235, 33549, 33692, 33390, 34271, 34206, 34144, 33699, 33692, 33549, 7943, 7892, - 8087, 34144, 34206, 34182, 34133, 34088, 34137, 14782, 14891, 15060, 26692, 26713, 26885, - 26499, 26358, 26498, 27627, 27792, 27553, 26697, 26707, 26722, 26297, 26511, 26339, 36102, - 36100, 35906, 37358, 37242, 37160, 35807, 36185, 37037, 34864, 34769, 34738, 34884, 34769, - 34966, 15582, 15688, 15585, 15691, 15865, 15846, 15582, 15585, 15485, 26100, 26251, 26213, - 25493, 25460, 25114, 36392, 36356, 36304, 36384, 36479, 36576, 8904, 8755, 8948, 9742, - 9748, 9906, 11349, 11149, 11680, 15717, 15865, 15691, 31745, 31467, 31540, 33215, 33313, - 33320, 36584, 36476, 36586, 12911, 12765, 12968, 28788, 28913, 28679, 28583, 28317, 28229, - 23367, 23136, 23463, 5413, 5283, 5402, 5944, 6143, 6100, 5910, 6308, 5885, 26160, - 26251, 26100, 37293, 37181, 37337, 5944, 6100, 6025, 5813, 5777, 5828, 8183, 8066, - 8120, 7943, 8066, 7937, 15947, 16138, 16162, 16708, 16824, 16766, 25312, 25269, 25226, - 26499, 26498, 26694, 36793, 36574, 36628, 8334, 8369, 8442, 8442, 8369, 8380, 24142, - 24357, 24044, 5789, 5644, 5840, 5840, 5685, 5920, 5621, 5807, 5698, 5787, 5607, - 5491, 16605, 16824, 16708, 17428, 17591, 17566, 24371, 24631, 24083, 25377, 25493, 25114, - 8755, 8699, 8719, 10130, 10188, 10165, 17188, 17207, 17089, 33313, 33387, 33320, 5413, - 5392, 5283, 22242, 21984, 21818, 22160, 21984, 22242, 22160, 22242, 22305, 22242, 22353, - 22305, 22353, 22308, 22305, 37400, 37181, 37153, 5465, 5578, 5546, 5283, 5392, 5215, - 9925, 10081, 9841, 10028, 10073, 10165, 7946, 8264, 8028, 14570, 14701, 14782, 14782, - 14792, 14891, 15478, 15582, 15485, 14542, 14701, 14570, 14542, 14570, 14415, 14542, 14415, - 14299, 22950, 22740, 22993, 23210, 23530, 23490, 7024, 7080, 7109, 7762, 7688, 7766, - 7630, 7688, 7762, 7828, 7873, 7892, 26692, 26499, 26694, 26692, 26694, 26713, 34376, - 34368, 34341, 32597, 32692, 32732, 34568, 34507, 34341, 34613, 34507, 34568, 34628, 34791, - 34800, 32323, 32351, 32314, 32314, 32279, 32065, 32509, 32351, 32323, 32860, 32681, 32563, - 7825, 7828, 7892, 13794, 14032, 13831, 13080, 13005, 12874, 12037, 12366, 12089, 16302, - 16501, 16500, 28321, 28167, 28178, 28331, 28167, 28321, 28331, 28321, 28388, 32351, 32279, - 32314, 31882, 32133, 32138, 31984, 31882, 32138, 32206, 31984, 32138, 32703, 32899, 32749, - 32749, 32899, 32877, 33001, 33143, 33045, 33045, 33143, 33176, 33176, 33219, 33215, 33215, - 33309, 33313, 33313, 33418, 33387, 35302, 35078, 34811, 35699, 35394, 35553, 35770, 35553, - 35692, 35709, 35611, 35726, 35709, 35726, 35869, 6574, 6639, 6355, 34800, 34791, 34925, - 32279, 32231, 32065, 31882, 31832, 31920, 7024, 6909, 7080, 6397, 5930, 6333, 7299, - 7111, 7088, 37358, 37279, 37180, 17372, 17591, 17428, 24044, 24357, 24249, 24357, 24663, - 24563, 35987, 35726, 35814, 36868, 36957, 36836, 37165, 37214, 37121, 36914, 36868, 36760, - 8699, 8596, 8640, 10188, 10281, 10298, 10130, 10281, 10188, 33457, 33498, 33387, 33387, - 33498, 33368, 33809, 33892, 33778, 5559, 5465, 5546, 5506, 5718, 5673, 9742, 9906, - 9731, 8904, 8837, 8755, 8755, 8686, 8699, 8699, 8544, 8596, 31920, 31832, 31617, - 32967, 32899, 32703, 10487, 10704, 10692, 10473, 10704, 10487, 33809, 33778, 33692, 30674, - 30655, 30670, 29498, 29508, 29603, 30674, 30670, 30794, 34864, 34738, 34532, 34006, 33935, - 33874, 20107, 19928, 20669, 17544, 17504, 17740, 22353, 22458, 22308, 23066, 23110, 23136, - 22751, 22913, 23066, 6480, 6699, 6351, 5392, 5403, 5215, 22458, 22465, 22308, 34769, - 34884, 34848, 34455, 34224, 34337, 36472, 36396, 36313, 36313, 36396, 36235, 36232, 36102, - 35906, 15717, 15947, 15865, 15865, 15947, 15966, 16138, 16302, 16362, 15478, 15485, 15077, - 36650, 36078, 36413, 36285, 36009, 36283, 5502, 5581, 5548, 17228, 17372, 17428, 17068, - 17188, 17089, 17068, 17089, 16993, 37313, 37064, 37177, 36629, 36576, 36584, 25328, 25269, - 25312, 26499, 25466, 25655, 25377, 25114, 25096, 26188, 26297, 26251, 36584, 36576, 36479, - 36496, 36503, 36392, 35784, 35969, 36330, 36793, 36628, 36784, 36961, 36793, 36784, 7299, - 7406, 7111, 29005, 28798, 29107, 29005, 29107, 29260, 16373, 16989, 16562, 26251, 26297, - 26339, 27392, 27251, 27578, 26160, 26045, 25967, 36283, 36009, 36100, 36549, 36194, 36356, - 35882, 35928, 35809, 35957, 35638, 35689, 5303, 5141, 5253, 5215, 5403, 5366, 22458, - 22461, 22465, 37279, 37313, 37198, 18591, 18499, 18523, 18599, 18499, 18591, 22740, 22934, - 23028, 23783, 23904, 23911, 22950, 22934, 22740, 11673, 11468, 11680, 11673, 11680, 11849, - 11436, 11455, 11130, 18114, 18169, 18230, 17334, 17321, 17135, 23643, 23607, 23808, 23161, - 23530, 23210, 24012, 23960, 23808, 24563, 24663, 24694, 34485, 34368, 34376, 34485, 34376, - 34507, 34337, 34224, 34206, 37025, 37024, 36836, 5307, 5273, 5471, 5320, 5231, 5357, - 5163, 5273, 5307, 5271, 5307, 5309, 5418, 5358, 5245, 5358, 5319, 5245, 5319, - 5195, 5245, 5324, 5269, 5369, 20888, 21041, 21017, 20573, 20656, 20606, 20485, 20656, - 20573, 18354, 18474, 18356, 20656, 20673, 20606, 25328, 25312, 25429, 34133, 34271, 34144, - 33892, 34006, 33874, 33973, 34006, 33892, 8774, 8872, 8731, 33001, 33045, 32932, 33712, - 33699, 33549, 37258, 37388, 37091, 37242, 37358, 37180, 37279, 37349, 37313, 37578, 37388, - 37258, 37391, 37171, 37245, 21161, 20464, 20851, 21836, 21818, 21984, 22005, 21984, 22096, - 7111, 7406, 7172, 12765, 12578, 12446, 12703, 12578, 12765, 12703, 12765, 12911, 29498, - 29603, 29690, 35302, 35132, 35394, 34613, 34485, 34507, 34884, 35069, 34848, 35181, 35069, - 35172, 7588, 7946, 7802, 6960, 7946, 7588, 11794, 12089, 11779, 20891, 21041, 20888, - 25468, 25425, 25466, 26713, 26954, 26927, 29351, 29498, 29690, 34246, 34271, 34133, 22305, - 22239, 22160, 22465, 22461, 22627, 22461, 22692, 22627, 37407, 37214, 37165, 37380, 37391, - 37245, 14701, 14656, 14782, 13947, 14144, 14032, 5273, 5213, 5482, 8523, 8567, 8596, - 8523, 8393, 8567, 8369, 8168, 8206, 7571, 7630, 7828, 33712, 33506, 33498, 8872, - 8837, 8904, 33143, 33219, 33176, 5213, 5207, 5320, 16993, 17089, 16824, 17219, 17372, - 17228, 16993, 16824, 16815, 22934, 23064, 23028, 22950, 23064, 22934, 24785, 24563, 24694, - 5324, 5268, 5269, 5622, 5644, 5660, 5660, 5644, 5789, 6355, 6698, 6512, 5768, - 5944, 6025, 5843, 5777, 5813, 5843, 5944, 5722, 23530, 23723, 23681, 25170, 25377, - 25096, 23688, 23723, 23530, 35770, 35699, 35553, 35562, 35302, 35394, 35770, 35692, 35709, - 28698, 28710, 28827, 28388, 28321, 28456, 28167, 27957, 27758, 10281, 10338, 10410, 9925, - 9841, 9612, 15556, 15691, 15688, 15077, 15060, 14891, 15556, 15688, 15582, 17504, 17387, - 17440, 17396, 17387, 17504, 17219, 17228, 17188, 18235, 18125, 18001, 26188, 26160, 25967, - 27020, 26722, 26707, 31467, 31573, 31617, 31745, 31573, 31467, 33219, 33309, 33215, 36957, - 37025, 36836, 36557, 36413, 36334, 5207, 5231, 5320, 12578, 12439, 12446, 13794, 13831, - 13592, 13794, 13592, 13768, 27793, 28066, 27737, 27553, 27792, 27651, 26766, 26511, 26519, - 28913, 29253, 28917, 29651, 29977, 29893, 31745, 31888, 31573, 29133, 29253, 28913, 30536, - 30566, 30333, 30794, 30670, 31257, 34006, 34071, 33935, 34058, 34071, 34006, 35885, 35770, - 35709, 12940, 13080, 12874, 8393, 8334, 8442, 8250, 8334, 8281, 33699, 33809, 33692, - 33822, 33809, 33699, 5324, 5346, 5268, 5231, 5263, 5357, 7688, 7487, 7530, 7828, - 7630, 7762, 7825, 7892, 7943, 30118, 29977, 30005, 32509, 32597, 32563, 34613, 34568, - 34717, 34455, 34513, 34280, 34598, 34513, 34455, 34337, 34206, 34271, 35987, 35869, 35726, - 35885, 35869, 35947, 5753, 5777, 5843, 16145, 16302, 16138, 25425, 25328, 25429, 24857, - 24694, 24896, 25269, 25328, 25425, 18213, 18354, 18356, 18125, 17860, 18001, 7943, 8087, - 8066, 22308, 22239, 22305, 22627, 22692, 22751, 34246, 34337, 34271, 8680, 8686, 8755, - 10073, 10130, 10165, 11136, 11216, 10921, 33309, 33418, 33313, 28891, 28793, 29005, 28780, - 28698, 28827, 34717, 34568, 34706, 35266, 35302, 35393, 5404, 5506, 5204, 5465, 5169, - 5589, 17068, 17067, 17188, 16605, 16708, 16501, 24115, 23960, 24044, 24044, 23960, 24012, - 24896, 25212, 25084, 12226, 12178, 12316, 12037, 12125, 12366, 12190, 12125, 12100, 32351, - 32372, 32279, 32279, 32237, 32231, 30847, 30582, 30674, 34427, 34017, 34368, 30674, 30582, - 30514, 32274, 31951, 32231, 34071, 34137, 34088, 34252, 34137, 34071, 36961, 36825, 36793, - 36541, 36496, 36576, 37037, 36185, 36595, 6765, 6694, 6909, 6348, 6365, 6480, 7088, - 7032, 7109, 7069, 7032, 7088, 16405, 16605, 16501, 22751, 22692, 22913, 22375, 22239, - 22308, 23136, 23172, 23066, 26871, 26766, 26601, 28924, 28891, 28985, 28780, 28891, 28924, - 32465, 32372, 32351, 32247, 32321, 32226, 32899, 33001, 32932, 33143, 33297, 33219, 33412, - 33457, 33309, 33309, 33457, 33418, 32256, 32321, 32247, 32256, 32247, 32206, 32256, 32206, - 32201, 35069, 35181, 34952, 35255, 35181, 35347, 8686, 8544, 8699, 19551, 18636, 19327, - 5464, 5399, 5558, 5621, 5622, 5660, 5329, 5599, 5205, 19327, 18636, 18474, 17465, - 17860, 17591, 17465, 17591, 17372, 32372, 32237, 32279, 32325, 32256, 32201, 9748, 9634, - 9789, 8872, 8774, 8837, 8837, 8680, 8755, 8686, 8501, 8544, 9742, 9634, 9748, - 9906, 10119, 9731, 36541, 36503, 36496, 36541, 36576, 36629, 36584, 36586, 36813, 36570, - 36557, 36334, 36472, 36334, 36396, 36472, 36313, 36589, 36313, 36285, 36589, 5268, 5346, - 5253, 5346, 5303, 5253, 37380, 37245, 37293, 37380, 37293, 37337, 11468, 11349, 11680, - 11703, 11673, 11849, 34485, 34634, 34368, 34800, 34925, 35204, 34513, 34611, 34532, 34598, - 34611, 34513, 34598, 34455, 34737, 9634, 9742, 9640, 11509, 11349, 11468, 19343, 18802, - 19071, 18375, 18114, 18230, 37215, 37296, 36900, 37215, 36900, 37024, 5399, 5502, 5548, - 7305, 7643, 7530, 23723, 23904, 23783, 26188, 26251, 26160, 23771, 23904, 23723, 37038, - 37025, 36957, 37038, 36957, 36914, 5677, 5753, 5843, 5693, 5618, 5845, 8501, 8523, - 8544, 8544, 8523, 8596, 7937, 8066, 7985, 16302, 16405, 16501, 15947, 16145, 16138, - 15882, 16145, 15947, 36557, 36650, 36413, 5303, 5283, 5141, 19784, 19854, 19948, 35214, - 34925, 35078, 38103, 37358, 37160, 37773, 37037, 36595, 37337, 37181, 37400, 33087, 33001, - 32899, 34013, 33973, 33892, 34137, 34246, 34133, 34058, 33973, 34013, 33457, 33387, 33418, - 27809, 28066, 27793, 27809, 27793, 27792, 5539, 5622, 5621, 5644, 5683, 5840, 14542, - 14656, 14701, 15478, 15556, 15582, 14532, 14656, 14542, 16993, 16937, 17068, 16605, 16815, - 16824, 16937, 16815, 16852, 18375, 18384, 18499, 24115, 24044, 24249, 25084, 25212, 25269, - 26871, 27020, 26707, 35255, 35585, 35137, 35928, 36030, 35906, 14002, 14234, 14144, 13768, - 13592, 13672, 13270, 13377, 13080, 27791, 27809, 27792, 7571, 7487, 7630, 7630, 7487, - 7688, 8250, 8369, 8334, 34252, 34246, 34137, 13232, 13270, 13080, 28601, 28388, 28456, - 28331, 28349, 28167, 28713, 28456, 28698, 5215, 5366, 5429, 31888, 31920, 31617, 32133, - 32157, 32191, 37400, 37153, 37214, 18802, 18678, 18670, 18599, 18284, 18287, 22375, 22308, - 22465, 23136, 23367, 23172, 27304, 27251, 27151, 35699, 35792, 35473, 35770, 35743, 35699, - 35869, 35885, 35709, 35947, 35869, 36003, 5614, 5683, 5644, 12178, 12061, 12316, 12439, - 12226, 12316, 12534, 12226, 12439, 12534, 12439, 12578, 8731, 8872, 8759, 9612, 9841, - 9651, 10073, 10000, 10130, 11136, 10943, 11071, 18055, 17544, 17740, 17387, 17321, 17334, - 24357, 24563, 24249, 37318, 37064, 37313, 36813, 36586, 36820, 37486, 37215, 37024, 37057, - 37038, 36914, 6480, 6365, 6468, 5677, 5693, 5753, 6699, 7123, 6351, 7123, 6909, - 6694, 13960, 14144, 13947, 35983, 35957, 35689, 37358, 37349, 37279, 5361, 5399, 5464, - 5502, 5491, 5607, 5344, 5399, 5361, 18114, 18055, 18169, 18147, 18055, 18114, 27207, - 27304, 27151, 26766, 26871, 26707, 26452, 26511, 26297, 26452, 26297, 26361, 28713, 28780, - 28733, 28891, 28780, 28827, 29603, 29808, 29922, 30847, 30950, 30934, 35181, 35255, 35137, - 35172, 35069, 35155, 11455, 11436, 11779, 12125, 12397, 12366, 11136, 11071, 11130, 15468, - 15556, 15478, 29977, 30118, 30077, 30005, 29977, 29651, 30005, 29651, 29959, 36768, 36789, - 36650, 36283, 36100, 36102, 11524, 11794, 11779, 18678, 18599, 18591, 18496, 18599, 18287, - 34613, 34634, 34485, 34800, 34717, 34706, 34790, 34717, 34800, 27130, 27151, 27020, 36021, - 36030, 35928, 10338, 10281, 10247, 12120, 12061, 12178, 11673, 11510, 11468, 35155, 35069, - 35063, 8650, 8680, 8837, 8281, 8334, 8393, 22375, 22465, 22356, 37349, 37318, 37313, - 37407, 37400, 37214, 37407, 37165, 37450, 5683, 5647, 5840, 5568, 5647, 5683, 5614, - 5644, 5622, 23495, 23367, 23607, 22239, 22375, 22241, 24588, 24563, 24785, 5506, 5422, - 5559, 5404, 5422, 5506, 18599, 18496, 18499, 18335, 18496, 18287, 23064, 23161, 23210, - 22459, 22108, 22247, 14888, 15077, 14891, 14792, 14782, 14656, 36232, 36283, 36102, 5273, - 5163, 5213, 5213, 5191, 5207, 5207, 5149, 5231, 5231, 5188, 5263, 5263, 5135, - 5440, 5094, 5163, 5307, 5170, 5307, 5271, 5170, 5271, 5245, 5170, 5245, 5195, - 5319, 5140, 5195, 14299, 14532, 14542, 20673, 20835, 20888, 21313, 21816, 21762, 20656, - 20610, 20673, 20571, 20610, 20433, 19784, 20020, 19700, 27015, 27130, 27020, 36341, 35969, - 36118, 8281, 8393, 8368, 6747, 7247, 7036, 12190, 12397, 12125, 22239, 22216, 22134, - 37450, 37165, 37418, 6639, 6574, 7079, 6355, 6512, 6276, 13794, 13960, 13947, 14234, - 14299, 14415, 13448, 13592, 13439, 13448, 13439, 13298, 28625, 28583, 28229, 27809, 27963, - 28066, 27814, 27963, 27809, 27791, 27792, 27627, 27791, 27627, 27578, 35820, 35743, 35770, - 35302, 35266, 35078, 35820, 35770, 35885, 28353, 28349, 28388, 28388, 28349, 28331, 33412, - 33309, 33219, 34715, 34337, 34699, 5163, 5191, 5213, 11703, 11510, 11673, 9640, 9742, - 9731, 11794, 11888, 12089, 11436, 11524, 11779, 11582, 11524, 11347, 32133, 31920, 32157, - 29702, 29651, 29624, 34717, 34634, 34613, 34790, 34634, 34717, 34611, 34671, 34532, 34737, - 34455, 34742, 34252, 34071, 34058, 37541, 37391, 37380, 37886, 37463, 37391, 37391, 37463, - 37066, 37388, 37578, 37015, 37358, 38307, 37349, 37899, 37773, 38036, 37541, 37380, 37337, - 37541, 37337, 37607, 24768, 24588, 24785, 24768, 24785, 24857, 24768, 24857, 24829, 36842, - 36706, 36113, 37401, 37024, 37025, 36789, 36078, 36650, 13792, 13960, 13794, 27578, 27251, - 27304, 32597, 32509, 32453, 32372, 32390, 32237, 32237, 32274, 32231, 32563, 32681, 32649, - 5191, 5149, 5207, 18496, 18375, 18499, 17541, 17396, 17544, 18335, 18375, 18496, 20464, - 20107, 20669, 20057, 20107, 20464, 21836, 21984, 22005, 23643, 23808, 23774, 22950, 23078, - 23064, 22993, 23078, 22950, 32509, 32465, 32351, 5693, 5845, 5777, 5693, 5777, 5753, - 11729, 11888, 11794, 29624, 29396, 29253, 5727, 6040, 5920, 15556, 15570, 15691, 16852, - 16815, 16763, 15384, 15468, 15478, 32465, 32390, 32372, 32321, 32558, 32339, 33579, 33730, - 33457, 32256, 32325, 32321, 32201, 32206, 32138, 5685, 5727, 5920, 23774, 23808, 23960, - 23774, 23960, 23782, 23161, 23688, 23530, 24039, 24308, 24083, 36574, 36793, 36825, 36541, - 36532, 36503, 36549, 36341, 36194, 5319, 5269, 5140, 5269, 5129, 5140, 15077, 15002, - 15478, 14567, 14792, 14656, 14567, 14656, 14532, 36030, 36232, 35906, 5412, 5491, 5146, - 5647, 5685, 5840, 6365, 6261, 6468, 6909, 7024, 6765, 9634, 9565, 9789, 8774, - 8650, 8837, 9640, 9565, 9634, 10119, 9800, 9731, 17544, 17396, 17504, 17321, 17396, - 17383, 27439, 27578, 27304, 37170, 37057, 36914, 28780, 28713, 28698, 29351, 29260, 29498, - 5149, 5188, 5231, 8250, 8168, 8369, 7943, 7723, 7825, 8104, 8168, 8250, 9731, - 9800, 9689, 26188, 25967, 26272, 27195, 27207, 27130, 27130, 27207, 27151, 32133, 31882, - 31920, 32133, 32201, 32138, 36549, 36356, 36503, 36445, 36374, 36441, 36283, 36374, 36285, - 36768, 36650, 36758, 7985, 8066, 8183, 34058, 34006, 33973, 13232, 13439, 13270, 12012, - 12125, 12037, 30566, 30536, 30582, 5677, 5843, 5722, 36784, 36896, 37082, 36570, 36334, - 36472, 6331, 6261, 6365, 14141, 14299, 14234, 36429, 36339, 36232, 35957, 36021, 35928, - 36090, 36021, 35957, 35800, 35410, 35585, 35373, 35585, 35255, 5399, 5288, 5502, 5135, - 5599, 5432, 10289, 10805, 10286, 22005, 22096, 22025, 23495, 23172, 23367, 23078, 23161, - 23064, 22993, 23161, 23078, 30226, 30077, 30118, 5088, 5215, 5104, 12930, 12911, 12994, - 12120, 11985, 12061, 11985, 11703, 11849, 28985, 28891, 29005, 35562, 35394, 35473, 5269, - 5268, 5129, 5126, 5169, 5465, 5204, 5506, 5673, 5412, 5539, 5621, 16815, 16937, - 16993, 16815, 16605, 16763, 23643, 23495, 23607, 23685, 23774, 23782, 23688, 23771, 23723, - 23894, 23771, 23688, 24459, 24249, 24563, 25084, 25269, 25177, 33730, 33712, 33498, 33730, - 33498, 33457, 14792, 14888, 14891, 15002, 14888, 14881, 7571, 7828, 7673, 7111, 7069, - 7088, 11510, 11509, 11468, 11518, 11703, 11442, 11888, 12012, 12037, 11524, 11621, 11794, - 11582, 11621, 11524, 19665, 19784, 19700, 18317, 18474, 18354, 19948, 19968, 20067, 34598, - 34671, 34611, 34737, 34671, 34598, 5470, 5614, 5622, 25425, 25429, 25466, 25466, 25757, - 25468, 37082, 36896, 36907, 36789, 36842, 36078, 37170, 37182, 37057, 5491, 5511, 5698, - 5412, 5511, 5491, 17396, 17321, 17387, 17541, 17544, 17501, 24459, 24563, 24588, 24021, - 24083, 23904, 27015, 27020, 26871, 36153, 36135, 35987, 36209, 36135, 36153, 34993, 34864, - 34671, 34013, 33892, 33809, 7172, 7069, 7111, 35266, 35214, 35078, 35347, 35373, 35255, - 35063, 35069, 34884, 5129, 5268, 5173, 7319, 7305, 7530, 13232, 13080, 12940, 12000, - 12012, 11729, 29959, 30107, 30005, 29701, 29624, 29253, 34671, 34864, 34532, 36696, 36541, - 36803, 36696, 36532, 36541, 36003, 35987, 36212, 36541, 36629, 36803, 36589, 36570, 36472, - 36789, 36854, 36842, 25718, 25967, 25493, 26903, 27015, 26871, 10247, 10281, 10142, 11136, - 11130, 11455, 33712, 33822, 33699, 33730, 33822, 33712, 5173, 5268, 5253, 9925, 9903, - 10073, 9862, 9903, 9925, 9612, 9651, 9522, 13232, 13090, 13298, 13768, 13792, 13794, - 13960, 14002, 14144, 13448, 13672, 13592, 21984, 22160, 22096, 22160, 22239, 22096, 21313, - 21017, 21041, 5487, 5645, 5889, 5568, 5685, 5647, 26696, 26499, 26692, 25170, 25045, - 24851, 36758, 36650, 36557, 6833, 7024, 7032, 6348, 6331, 6365, 12305, 12397, 12190, - 13604, 13792, 13768, 14881, 14888, 14714, 28138, 28229, 28066, 27791, 27814, 27809, 27888, - 27814, 27791, 27888, 27791, 27914, 26927, 26954, 27042, 28601, 28353, 28388, 28601, 28456, - 28713, 35743, 35889, 35699, 35266, 35393, 35214, 35933, 35820, 35885, 27207, 27276, 27304, - 26519, 26511, 26452, 26501, 26519, 26452, 34966, 35063, 34884, 5073, 5173, 5253, 17067, - 17219, 17188, 16763, 16605, 16405, 6694, 6351, 7123, 5885, 6308, 6333, 6276, 6512, - 6383, 6574, 6747, 7036, 13792, 14002, 13960, 28733, 28780, 28924, 28748, 28601, 28713, - 28138, 28066, 27963, 36003, 35869, 35987, 5329, 5344, 5361, 5248, 5344, 5329, 8168, - 7985, 8183, 7723, 7828, 7825, 8035, 7985, 8168, 18375, 18147, 18114, 18335, 18147, - 18375, 30794, 30847, 30674, 31548, 30794, 31257, 37182, 37025, 37038, 37182, 37038, 37057, - 8680, 8501, 8686, 8731, 8650, 8774, 17067, 17068, 16937, 24308, 24371, 24083, 24297, - 24371, 24308, 7723, 7943, 7798, 7487, 7319, 7530, 11518, 11509, 11510, 11518, 11510, - 11703, 30005, 30107, 30118, 29959, 29651, 29702, 8368, 8393, 8523, 25004, 24829, 24857, - 24768, 24459, 24588, 25425, 25177, 25269, 24869, 25170, 24851, 33822, 33849, 33809, 34956, - 34864, 34993, 34406, 33849, 33822, 36825, 36820, 36586, 36961, 36820, 36825, 37136, 37088, - 36934, 36954, 36854, 36937, 34932, 34790, 34951, 34634, 34664, 34368, 22096, 22239, 22134, - 6256, 6331, 6348, 28985, 29205, 29069, 28985, 28733, 28924, 35347, 35181, 35172, 35347, - 35172, 35155, 7798, 7943, 7937, 10628, 10921, 10704, 12000, 12100, 12012, 27500, 27245, - 27042, 23771, 24021, 23904, 23894, 24021, 23771, 24039, 24021, 24028, 12012, 12100, 12125, - 11729, 11794, 11621, 15468, 15570, 15556, 15495, 15570, 15468, 15002, 15077, 14888, 22096, - 22134, 22025, 35063, 35153, 35155, 34864, 34966, 34769, 34956, 34966, 34864, 34246, 34699, - 34337, 23685, 23495, 23643, 22241, 22216, 22239, 23685, 23643, 23774, 23960, 24115, 24212, - 12703, 12534, 12578, 12658, 12534, 12703, 27195, 27276, 27207, 27195, 27130, 27015, 28985, - 29005, 29205, 5722, 5944, 5574, 5693, 5583, 5618, 5204, 5342, 5404, 25425, 25368, - 25177, 26696, 25466, 26499, 26519, 26601, 26766, 26188, 26361, 26297, 26501, 26361, 26273, - 26452, 26361, 26501, 36954, 36972, 36854, 36570, 36758, 36557, 32325, 32558, 32321, 32567, - 32558, 32547, 32420, 32325, 32201, 32191, 32201, 32133, 33849, 34013, 33809, 34728, 34013, - 34406, 16852, 17067, 16937, 16405, 16302, 16214, 8650, 8501, 8680, 24829, 24459, 24768, - 24249, 24459, 24349, 5166, 5141, 5283, 5166, 5283, 5215, 5032, 5135, 5263, 9088, - 9050, 9439, 8650, 8603, 8501, 9640, 9595, 9565, 9689, 9595, 9640, 9689, 9640, - 9731, 9522, 9651, 9475, 10383, 10487, 10338, 32390, 32274, 32237, 32409, 32274, 32390, - 32409, 32390, 32465, 32563, 32465, 32509, 9905, 10119, 10157, 11985, 11849, 12061, 11347, - 11524, 11436, 30107, 30226, 30118, 29945, 29959, 29702, 30082, 29959, 29945, 5614, 5568, - 5683, 5645, 5954, 5889, 5889, 5954, 6451, 5457, 5568, 5614, 5611, 5568, 5474, - 5622, 5539, 5470, 5611, 5727, 5685, 14340, 14532, 14299, 16562, 16989, 17135, 13787, - 14039, 14616, 16562, 17135, 17136, 26718, 26696, 26692, 26718, 26692, 26885, 26501, 26601, - 26519, 35170, 35153, 35063, 17976, 17544, 18055, 17219, 17465, 17372, 17243, 17465, 17219, - 24021, 24039, 24083, 24371, 24458, 24851, 23894, 23688, 23758, 30252, 30226, 30107, 37170, - 36914, 36934, 36934, 36842, 37120, 5141, 5166, 5069, 10805, 10977, 10286, 18147, 17976, - 18055, 18006, 17976, 18147, 28017, 28138, 27963, 29701, 29702, 29624, 27888, 27963, 27814, - 31888, 31617, 31573, 22577, 22993, 22740, 13232, 13298, 13439, 13573, 13604, 13672, 13672, - 13604, 13768, 14030, 14141, 14002, 14002, 14141, 14234, 12940, 12874, 12847, 7432, 7487, - 7378, 7432, 7319, 7487, 7305, 7172, 7406, 7069, 6921, 7032, 29922, 29808, 30071, - 35913, 35840, 35820, 35820, 35840, 35743, 34951, 34790, 34800, 35933, 35885, 35947, 35933, - 35947, 36003, 35983, 35800, 35966, 35754, 35800, 35585, 36349, 36283, 36232, 36441, 36374, - 36283, 36374, 36445, 36285, 36905, 36768, 36758, 8501, 8395, 8523, 8104, 8035, 8168, - 7985, 7798, 7937, 8290, 8395, 8501, 33297, 33143, 33001, 20610, 20679, 20673, 20754, - 20679, 20610, 35650, 35562, 35718, 8104, 8250, 8281, 7378, 7487, 7571, 10473, 10628, - 10704, 11130, 11179, 11436, 10281, 10130, 10142, 20679, 20835, 20673, 22247, 22108, 21925, - 35987, 36135, 36212, 20835, 20891, 20888, 7622, 7798, 7985, 30706, 30566, 30582, 30706, - 30582, 30847, 12120, 12178, 12226, 13787, 14616, 14598, 12847, 12874, 12397, 12305, 12190, - 12152, 15570, 15717, 15691, 15590, 15717, 15570, 35562, 35493, 35302, 36532, 36549, 36503, - 36803, 36629, 36832, 16965, 17067, 16852, 17219, 17067, 17126, 37234, 37082, 37540, 36832, - 36629, 36813, 37150, 37082, 37234, 36972, 36842, 36854, 5079, 5094, 5170, 5170, 5094, - 5307, 5012, 5095, 5191, 5191, 5095, 5149, 5149, 5108, 5188, 5188, 5032, 5263, - 5079, 5170, 5195, 5079, 5195, 4772, 5195, 5140, 4772, 5140, 5129, 5080, 5129, - 5173, 5080, 5043, 5191, 5163, 6355, 5895, 6574, 6052, 6276, 6383, 14030, 14002, - 13792, 15384, 15495, 15468, 36209, 36153, 36330, 36653, 36549, 36532, 7126, 7172, 7305, - 26954, 27500, 27042, 26601, 26903, 26871, 27914, 27791, 27578, 37082, 36961, 36784, 5078, - 5205, 5599, 5344, 5239, 5399, 5613, 5583, 5693, 5768, 6025, 6088, 8395, 8368, - 8523, 8290, 8368, 8395, 11302, 11349, 11509, 9936, 10073, 9903, 5404, 5342, 5422, - 5204, 5077, 5183, 22241, 22375, 22356, 24212, 24115, 24249, 24349, 24212, 24249, 24857, - 25084, 25004, 24039, 24164, 24308, 24029, 24164, 24039, 5080, 5173, 5073, 5095, 5108, - 5149, 5885, 6333, 5930, 36349, 36232, 36339, 12930, 12658, 12703, 35485, 35393, 35302, - 9088, 9439, 9480, 9612, 9862, 9925, 30660, 30728, 31319, 33238, 33297, 33001, 37407, - 37450, 37400, 37418, 37165, 37296, 37418, 37296, 37468, 14191, 14340, 14299, 15309, 15384, - 15478, 5613, 5693, 5677, 8035, 7997, 7985, 8023, 7997, 8035, 11422, 11302, 11509, - 11422, 11509, 11518, 19784, 19948, 20020, 18317, 18354, 18235, 7084, 7126, 7305, 7673, - 7828, 7723, 7673, 7723, 7678, 5205, 5248, 5329, 5185, 5248, 5205, 5239, 5248, - 5136, 9862, 9936, 9903, 18599, 18434, 18284, 17553, 17501, 17544, 18001, 18317, 18235, - 18001, 17860, 17769, 33297, 33412, 33219, 10943, 11136, 10921, 11729, 12012, 11888, 10943, - 10921, 10628, 10247, 10383, 10338, 10263, 10383, 10247, 6871, 6921, 7069, 6174, 6256, - 6126, 6351, 6256, 6348, 6871, 7069, 6895, 12120, 12226, 12041, 11729, 11621, 11698, - 14714, 14888, 14792, 21931, 21925, 21816, 23758, 23688, 23633, 25518, 25368, 25468, 26995, - 26718, 26885, 35180, 35170, 35063, 35319, 35347, 35155, 34455, 34337, 34742, 36232, 36030, - 36429, 37468, 37296, 37215, 14340, 14447, 14532, 36330, 35969, 36397, 22465, 22475, 22356, - 24143, 23782, 23960, 17136, 17135, 17321, 14598, 15119, 15318, 17136, 17321, 17383, 36854, - 36789, 36937, 36789, 36935, 36937, 9936, 10000, 10073, 21836, 21620, 21818, 18176, 18147, - 18335, 21708, 21620, 21836, 21708, 21836, 21919, 21836, 22005, 21919, 31319, 30728, 30773, - 37088, 37170, 36934, 37182, 37401, 37025, 37225, 37170, 37227, 14141, 14191, 14299, 14340, - 14432, 14447, 13573, 13672, 13448, 13573, 13448, 13298, 13090, 13232, 13008, 35904, 35889, - 35840, 35840, 35889, 35743, 35541, 35485, 35493, 35493, 35485, 35302, 35913, 35820, 35933, - 35913, 35933, 36173, 36696, 36653, 36532, 36397, 35969, 36341, 36832, 36813, 36986, 15495, - 15590, 15570, 17126, 17067, 16965, 15309, 15478, 15002, 36445, 36589, 36285, 36662, 36589, - 36445, 12152, 12190, 12100, 21919, 22005, 22025, 35082, 35063, 34966, 7678, 7723, 7798, - 8368, 8104, 8281, 8290, 8104, 8368, 10383, 10473, 10487, 10351, 10473, 10383, 14598, - 15318, 15366, 12930, 12766, 12658, 35904, 36134, 36054, 35800, 35983, 35689, 35754, 35585, - 35508, 26927, 26995, 26885, 27957, 28167, 28349, 27957, 28349, 28475, 28349, 28353, 28429, - 28353, 28601, 28429, 36481, 36341, 36549, 35904, 35840, 35913, 10977, 10805, 11349, 11442, - 11422, 11518, 13083, 12994, 14039, 12011, 12120, 12041, 30226, 30348, 30431, 29959, 30082, - 30107, 29701, 29253, 29528, 34790, 34664, 34634, 34932, 34664, 34790, 34742, 34337, 34715, - 34956, 35082, 34966, 34808, 34737, 34906, 34406, 33822, 33730, 5583, 5517, 5618, 5521, - 5613, 5677, 5517, 5613, 5481, 5568, 5611, 5685, 5412, 5621, 5511, 25468, 25368, - 25425, 24212, 24143, 23960, 25518, 25468, 25595, 25518, 25595, 25457, 33412, 33579, 33457, - 5930, 6397, 6261, 6245, 6256, 6199, 13744, 14030, 13792, 11698, 11621, 11582, 12000, - 12152, 12100, 36757, 36481, 36549, 36551, 36441, 36540, 36349, 36441, 36283, 7475, 7673, - 7552, 7204, 7305, 7319, 11071, 11179, 11130, 11095, 11179, 11071, 30252, 30348, 30226, - 24028, 23894, 23758, 24386, 24458, 24371, 32597, 32860, 32563, 32274, 31548, 31513, 32558, - 32719, 32339, 33297, 33404, 33412, 33412, 33458, 33579, 32547, 32558, 32325, 32547, 32325, - 32420, 32201, 32191, 32420, 32567, 32719, 32558, 32420, 32536, 32538, 12370, 12847, 12397, - 34951, 34800, 35204, 35541, 35493, 35562, 9480, 9439, 9565, 8214, 8290, 8501, 9501, - 9565, 9595, 9501, 9595, 9573, 25004, 25084, 25177, 32556, 32409, 32465, 32547, 32538, - 32591, 5073, 5253, 5141, 5073, 5141, 5069, 23172, 22895, 23066, 21634, 21931, 21816, - 37607, 37337, 37400, 37463, 37578, 37258, 37607, 37400, 37601, 5248, 5239, 5344, 5185, - 5205, 5082, 5288, 5491, 5502, 9573, 9595, 9689, 9715, 9794, 9862, 9862, 9815, - 9936, 9936, 9918, 10000, 9031, 9522, 9475, 14025, 14191, 14141, 14447, 14567, 14532, - 15507, 15495, 15384, 17126, 17243, 17219, 16302, 16145, 16214, 24541, 24349, 24459, 6921, - 6833, 7032, 7204, 7319, 7432, 10000, 10142, 10130, 10017, 10142, 10000, 11442, 11392, - 11422, 11947, 12120, 12011, 31955, 31548, 32274, 35267, 35082, 35264, 35319, 35155, 35153, - 10473, 10494, 10628, 10418, 10494, 10473, 36972, 37120, 36842, 36789, 36768, 36935, 10832, - 10943, 10628, 30321, 29922, 30071, 30736, 30706, 30852, 9528, 9573, 9689, 36180, 36030, - 36021, 6765, 6833, 6871, 35319, 35153, 35170, 23172, 23495, 23598, 37418, 37519, 37450, - 37509, 37468, 37479, 32990, 33087, 32899, 14291, 14432, 14340, 15507, 15590, 15495, 15309, - 15002, 15019, 36874, 36653, 36696, 5239, 5288, 5399, 23894, 24028, 24021, 25718, 25493, - 25377, 24029, 24028, 24196, 24029, 24329, 24297, 8603, 8650, 8731, 7678, 7622, 7560, - 10142, 10227, 10247, 10195, 10227, 10124, 5069, 5166, 5110, 7475, 7378, 7571, 7475, - 7571, 7673, 14810, 15002, 14881, 23611, 23495, 23685, 29205, 29005, 29351, 28429, 28601, - 28620, 30321, 30071, 30566, 33087, 33238, 33001, 34737, 34808, 34671, 34252, 34699, 34246, - 18176, 18006, 18147, 19851, 19589, 20107, 17769, 17860, 17465, 19968, 19948, 19854, 11076, - 11244, 11179, 11179, 11244, 11436, 30362, 30321, 30566, 30082, 30252, 30107, 31335, 31319, - 30773, 30395, 30252, 30260, 25230, 25004, 25177, 26717, 26696, 26718, 35180, 35063, 35082, - 35330, 35319, 35170, 7183, 7204, 7432, 6871, 6833, 6921, 17383, 17396, 17541, 17427, - 17484, 17465, 16965, 16852, 16893, 24297, 24308, 24164, 26705, 26952, 26601, 26601, 26952, - 26903, 28922, 28788, 28583, 9088, 8759, 8872, 33238, 33288, 33297, 34252, 34058, 34729, - 13490, 13573, 13401, 13604, 13677, 13792, 14030, 14025, 14141, 14519, 14567, 14432, 15366, - 16052, 15871, 16052, 16373, 15871, 14432, 14567, 14447, 14610, 14567, 14519, 35889, 35792, - 35699, 35893, 35792, 35889, 35904, 36054, 35893, 35508, 35373, 35452, 35508, 35585, 35373, - 35983, 36090, 35957, 5910, 5768, 6088, 6245, 6261, 6331, 28601, 28748, 28620, 28852, - 28922, 28583, 27439, 27304, 27276, 36212, 36135, 36209, 36017, 35966, 35800, 29069, 28733, - 28985, 35718, 35562, 35473, 34925, 35214, 35204, 36935, 36768, 36905, 37109, 37120, 36972, - 36758, 37083, 36905, 37187, 37083, 36758, 10106, 9905, 10157, 10977, 11349, 11302, 10227, - 10263, 10247, 10629, 10832, 10628, 11116, 11347, 11244, 10195, 10263, 10227, 31335, 30773, - 31290, 32547, 32420, 32538, 9794, 9815, 9862, 17553, 17544, 17976, 17427, 17465, 17243, - 24028, 24029, 24039, 23161, 22993, 23062, 33288, 33404, 33297, 23661, 23611, 23685, 23661, - 23685, 23782, 5110, 5166, 5215, 12305, 12277, 12397, 13490, 13677, 13573, 12201, 12152, - 12068, 11798, 12000, 11729, 35267, 35180, 35082, 35452, 35373, 35347, 35650, 35541, 35562, - 35452, 35347, 35476, 6256, 6245, 6331, 6199, 6256, 6174, 36275, 36090, 35983, 20891, - 21313, 21041, 20835, 20763, 20891, 20679, 20754, 20835, 20595, 20754, 20610, 20067, 20215, - 19948, 20754, 20763, 20835, 4787, 5043, 5163, 5095, 4930, 5108, 5108, 5032, 5188, - 5048, 5163, 5094, 5048, 5094, 5079, 5048, 4772, 4785, 5140, 5080, 4989, 8704, - 8603, 8731, 10106, 10157, 10289, 9815, 9918, 9936, 14610, 14714, 14792, 14610, 14792, - 14567, 27042, 26995, 26927, 26985, 26995, 27042, 26903, 26952, 27015, 26361, 26188, 26272, - 33404, 33458, 33412, 36330, 36292, 36209, 36481, 36397, 36341, 36370, 36397, 36446, 37673, - 37578, 38010, 37150, 36961, 37082, 5669, 5768, 5910, 7798, 7622, 7678, 6999, 7084, - 7204, 8035, 8104, 8023, 11422, 11392, 11302, 11442, 11703, 11985, 11244, 11347, 11436, - 11095, 11071, 10938, 15590, 15571, 15717, 15454, 15507, 15384, 15571, 15507, 15454, 34808, - 34993, 34671, 34906, 34742, 34896, 28625, 28229, 28293, 35476, 35347, 35319, 11312, 11698, - 11582, 32649, 32556, 32563, 35768, 35393, 35485, 5088, 5110, 5215, 5014, 5080, 5073, - 5043, 5012, 5191, 5391, 5470, 5539, 5918, 6052, 5571, 5457, 5470, 5365, 10263, - 10351, 10383, 10235, 10351, 10263, 25297, 25177, 25368, 24829, 24820, 24459, 24349, 24143, - 24212, 36961, 37101, 36820, 36803, 36861, 36696, 37150, 37101, 36961, 36907, 37540, 37082, - 37109, 36972, 36954, 37170, 37225, 37182, 36986, 36813, 37114, 36653, 36762, 36549, 5014, - 5073, 4989, 8023, 8104, 8290, 10938, 11071, 10943, 19784, 19755, 19854, 9918, 10017, - 10000, 15871, 16373, 16562, 17501, 17383, 17541, 17553, 17383, 17501, 17310, 17427, 17243, - 17484, 17769, 17465, 17310, 17243, 17126, 24541, 24143, 24349, 37227, 37170, 37088, 7183, - 7432, 7378, 7204, 7084, 7305, 6256, 6351, 6126, 12120, 11947, 11985, 12455, 12534, - 12658, 29551, 29351, 29627, 20723, 20057, 20464, 21426, 21062, 21620, 21426, 21620, 21548, - 21620, 21678, 21548, 21708, 21678, 21620, 20763, 21313, 20891, 22577, 22740, 22459, 5613, - 5517, 5583, 5104, 5215, 5429, 5521, 5677, 5722, 25457, 25368, 25518, 25457, 25297, - 25368, 36937, 37109, 36954, 36551, 36445, 36441, 19784, 19665, 19755, 10629, 10628, 10494, - 26823, 26717, 26718, 26823, 26718, 26995, 8214, 8023, 8290, 32719, 32967, 32703, 33087, - 33240, 33238, 33238, 33240, 33288, 33288, 33379, 33404, 33404, 33379, 33458, 32567, 32723, - 32719, 32591, 32723, 32567, 32591, 32567, 32547, 32531, 32536, 32420, 26952, 27195, 27015, - 32191, 32531, 32420, 36370, 36292, 36330, 36370, 36330, 36397, 4983, 5032, 5108, 4993, - 5098, 5288, 5391, 5539, 5289, 5078, 5599, 5135, 18284, 18434, 18301, 17736, 17553, - 17976, 21708, 21858, 21678, 21919, 21858, 21708, 32409, 32469, 32274, 32563, 32556, 32465, - 34828, 34368, 34664, 32157, 31888, 31997, 4989, 5073, 4907, 5465, 5422, 5126, 7737, - 9031, 9363, 9794, 9918, 9815, 9794, 9909, 9918, 9918, 9909, 10017, 9082, 9031, - 7624, 9501, 9480, 9565, 8711, 8704, 8759, 8759, 8704, 8731, 9528, 9480, 9501, - 9528, 9501, 9573, 32556, 32469, 32409, 32912, 32967, 32719, 37234, 37540, 37387, 37098, - 36861, 36832, 12152, 12277, 12305, 12201, 12277, 12152, 28017, 28213, 28138, 28017, 27963, - 27888, 35792, 35786, 35473, 35650, 35670, 35541, 34828, 34839, 34930, 35930, 35786, 35792, - 35893, 35889, 35904, 13573, 13677, 13604, 13573, 13298, 13401, 20057, 19851, 20107, 19700, - 19614, 19665, 21919, 22040, 21858, 27914, 28017, 27888, 30321, 30067, 29922, 29627, 29351, - 29690, 30392, 30067, 30321, 30362, 30566, 30736, 34932, 34839, 34664, 35632, 35485, 35541, - 36173, 35933, 36385, 35786, 35718, 35473, 5470, 5457, 5614, 5954, 6052, 6409, 5539, - 5412, 5289, 32469, 32343, 32274, 30736, 30566, 30706, 32967, 32990, 32899, 7475, 7268, - 7378, 7678, 7552, 7673, 7560, 7552, 7678, 30706, 30847, 30934, 30252, 30395, 30348, - 30160, 30252, 30082, 29945, 29702, 29701, 24029, 24297, 24164, 25718, 25377, 25589, 22577, - 22459, 22336, 37386, 37227, 37088, 37509, 37519, 37468, 37136, 36934, 37120, 12994, 12909, - 12930, 13083, 13060, 12994, 13083, 14039, 13302, 28429, 28475, 28349, 26985, 26823, 26995, - 28748, 28713, 28733, 30186, 29945, 30206, 28293, 28229, 28138, 5768, 5574, 5944, 19551, - 19327, 19614, 19700, 19551, 19614, 21919, 22025, 22040, 9905, 9800, 10119, 10286, 10106, - 10289, 10139, 10106, 10286, 31319, 31540, 31467, 31485, 31540, 31319, 14714, 14810, 14881, - 14291, 14340, 14191, 22247, 21925, 21931, 37468, 37519, 37418, 37541, 37886, 37391, 37468, - 37215, 37479, 5126, 5422, 5342, 5185, 5136, 5248, 5023, 5136, 5185, 6245, 6114, - 6261, 5481, 5521, 5512, 5512, 5521, 5574, 6765, 7024, 6833, 13941, 14025, 14030, - 18287, 18176, 18335, 18284, 18176, 18287, 28963, 28733, 29069, 28963, 28748, 28733, 33245, - 33240, 33087, 34252, 34729, 34699, 10832, 10938, 10943, 11312, 11582, 11347, 11686, 11729, - 11698, 12201, 12370, 12277, 10834, 10938, 10832, 10629, 10494, 10418, 18474, 18317, 19327, - 30847, 30794, 30950, 24869, 24851, 24458, 26952, 27225, 27195, 36540, 36441, 36349, 36540, - 36349, 36529, 37097, 37109, 36937, 36662, 36570, 36589, 29627, 29690, 29861, 5204, 5673, - 5077, 5155, 5204, 5183, 19327, 19381, 19516, 22040, 22025, 22134, 27195, 27439, 27276, - 27225, 27439, 27195, 36292, 36212, 36209, 36353, 36212, 36292, 36090, 36180, 36021, 36312, - 36180, 36275, 36180, 36090, 36275, 35983, 35966, 36275, 36017, 35754, 36147, 5332, 5412, - 5264, 7069, 7172, 6895, 7172, 6856, 6895, 5914, 6747, 6574, 7083, 6960, 7588, - 5916, 6355, 6276, 10087, 10227, 10142, 10087, 10142, 10017, 24711, 24820, 24859, 25004, - 24820, 24829, 24733, 24869, 24458, 37601, 37400, 37450, 37401, 37182, 37225, 24297, 24386, - 24371, 24329, 24386, 24297, 5169, 5104, 5429, 5193, 5126, 5342, 8603, 8445, 8501, - 8537, 8704, 8455, 9849, 9800, 9905, 14610, 14810, 14714, 14755, 14810, 14610, 25595, - 25757, 25683, 25297, 25230, 25177, 26985, 27042, 27245, 33240, 33379, 33288, 37097, 36937, - 36935, 7552, 7481, 7475, 7560, 7481, 7552, 29133, 28913, 28922, 10418, 10473, 10351, - 5889, 5727, 5424, 7172, 7126, 6856, 12277, 12370, 12397, 12152, 12000, 12068, 15507, - 15571, 15590, 15454, 15384, 15309, 29340, 29205, 29351, 5017, 5069, 5110, 5017, 5110, - 5088, 25494, 25377, 25338, 36832, 36861, 36803, 36813, 36820, 37106, 37601, 37450, 37519, - 9892, 9849, 9905, 10124, 10235, 10195, 10195, 10235, 10263, 17736, 17976, 18006, 17383, - 16796, 17136, 36551, 36662, 36445, 37096, 37097, 36935, 36719, 36662, 36551, 37398, 37401, - 37225, 37398, 37225, 37227, 25400, 25457, 25595, 25338, 25377, 25170, 37106, 36820, 37101, - 14291, 14519, 14432, 13677, 13744, 13792, 13232, 12940, 13008, 28213, 28293, 28138, 28625, - 28852, 28583, 28099, 28293, 28213, 28099, 28213, 28017, 13060, 12909, 12994, 13302, 14039, - 13787, 13008, 12940, 12847, 13490, 13744, 13677, 14072, 14191, 14025, 15307, 15454, 15309, - 27968, 27914, 27578, 28620, 28475, 28429, 28707, 28475, 28620, 28707, 28620, 28748, 36446, - 36397, 36568, 37127, 37136, 37120, 37127, 37120, 37109, 9862, 9515, 9715, 5264, 5412, - 5146, 24820, 24541, 24459, 23765, 23661, 23782, 22627, 22475, 22465, 24456, 24541, 24711, - 5112, 5104, 5169, 36529, 36349, 36339, 37589, 37601, 37519, 37486, 37479, 37215, 6747, - 6960, 7083, 11686, 11698, 11408, 12819, 13008, 12847, 11179, 11095, 11076, 30542, 30392, - 30362, 30023, 29922, 30067, 29983, 29690, 29922, 29551, 29340, 29351, 30950, 30794, 31548, - 13021, 12909, 13060, 13744, 13941, 14030, 35766, 35670, 35650, 35813, 35650, 35718, 35871, - 35718, 35786, 35930, 35792, 35893, 35930, 35893, 36054, 17605, 18317, 18001, 22475, 22307, - 22356, 16214, 16145, 15882, 17518, 17769, 17484, 25400, 25230, 25297, 37143, 37106, 37101, - 37096, 36935, 36905, 30589, 30431, 30348, 29945, 30160, 30082, 30260, 30160, 30186, 34839, - 34828, 34664, 35022, 34839, 34932, 11076, 11095, 10938, 35204, 35214, 35375, 35330, 35476, - 35319, 35452, 35693, 35508, 34906, 34993, 34808, 34906, 34737, 34742, 6856, 7126, 6915, - 7622, 7985, 7997, 7622, 7997, 7669, 10834, 11076, 10938, 10834, 10832, 10672, 6199, - 6114, 6245, 6174, 6114, 6199, 6351, 6694, 6126, 12909, 12766, 12930, 11701, 11442, - 11985, 13941, 14072, 14025, 29082, 29069, 29205, 29082, 28963, 29069, 28536, 28852, 28625, - 5044, 5078, 5135, 5264, 5289, 5332, 4770, 5044, 5135, 22751, 22475, 22627, 22001, - 22247, 21931, 22577, 23062, 22993, 26954, 27758, 27500, 25468, 25757, 25595, 33971, 33501, - 33709, 32556, 32616, 32469, 32469, 32431, 32343, 32343, 31955, 32274, 32538, 32536, 32591, - 32591, 32766, 32723, 32912, 32978, 32967, 32967, 32978, 32990, 32990, 33140, 33087, 33240, - 33272, 33379, 32157, 31920, 31888, 36880, 36762, 36653, 36874, 36696, 36861, 36874, 36861, - 36939, 12041, 12226, 12534, 9898, 10139, 10286, 30023, 30067, 30392, 35375, 35214, 35527, - 20763, 20797, 21313, 21313, 21634, 21816, 20754, 20709, 20763, 20571, 20595, 20610, 20610, - 20485, 20433, 20485, 20257, 20433, 20067, 20257, 20485, 20095, 20257, 20067, 20095, 20067, - 19968, 20095, 19968, 19992, 32616, 32431, 32469, 32882, 32719, 32723, 19890, 19968, 19854, - 5391, 5365, 5470, 5457, 5474, 5568, 5332, 5289, 5412, 5491, 5288, 5146, 5574, - 5521, 5722, 5574, 5483, 5512, 9907, 10087, 10017, 10235, 10418, 10351, 10105, 10418, - 10235, 12766, 12455, 12658, 14072, 14291, 14191, 15307, 15309, 15200, 19792, 19890, 19854, - 25494, 25589, 25377, 26782, 26705, 26501, 25530, 25589, 25494, 25338, 25170, 25237, 28852, - 29133, 28922, 30934, 30852, 30706, 31006, 30852, 30934, 35330, 35170, 35180, 5298, 5365, - 5391, 37138, 37127, 37109, 37430, 37398, 37227, 37578, 37673, 37015, 38010, 37578, 37463, - 9480, 9528, 9448, 9506, 9528, 9689, 9480, 9140, 9088, 23598, 23495, 23611, 32978, - 33140, 32990, 33730, 33579, 33641, 37589, 37519, 37509, 38047, 37886, 37541, 5012, 4930, - 5095, 5032, 4770, 5135, 5043, 4944, 5012, 4878, 4944, 5043, 4878, 5043, 4848, - 19755, 19792, 19854, 5078, 5082, 5205, 5007, 5082, 5078, 22978, 23062, 22577, 5155, - 5193, 5342, 5049, 5112, 5169, 5155, 5342, 5204, 23765, 23782, 24143, 33140, 33245, - 33087, 37401, 37486, 37024, 37652, 37589, 37509, 37386, 37088, 37136, 4944, 4930, 5012, - 19755, 19665, 19792, 5405, 5474, 5457, 16893, 16852, 16763, 15882, 15947, 15717, 15882, - 15717, 15571, 25237, 25170, 24869, 24733, 24458, 24556, 37083, 37096, 36905, 37097, 37138, - 37109, 36758, 36570, 37187, 11913, 11985, 11947, 10106, 9892, 9905, 30119, 30023, 30392, - 33579, 33458, 33641, 35341, 35330, 35180, 26501, 26705, 26601, 27968, 28099, 27914, 26827, - 26705, 26782, 4930, 4983, 5108, 5006, 5017, 5088, 5014, 4989, 5080, 5006, 5088, - 5104, 6871, 6821, 6765, 6821, 6895, 6781, 11259, 11302, 11392, 9448, 9528, 9506, - 10087, 10124, 10227, 11076, 11116, 11244, 10859, 11116, 11076, 27500, 27758, 27957, 27019, - 27225, 26952, 29522, 29340, 29551, 29522, 29551, 29627, 33641, 33458, 33693, 35082, 34956, - 35215, 31997, 31745, 31906, 31997, 31888, 31745, 35904, 36173, 36134, 35670, 35632, 35541, - 13090, 13008, 13161, 11686, 11798, 11729, 11496, 11798, 11686, 21426, 21390, 20851, 19963, - 19562, 19851, 21420, 21390, 21426, 21420, 21426, 21548, 21420, 21548, 21559, 21548, 21678, - 21559, 21678, 21770, 21559, 21858, 21770, 21678, 35930, 35871, 35786, 5049, 5169, 5126, - 13090, 13401, 13298, 13759, 13853, 13744, 13744, 13853, 13941, 13941, 13860, 14072, 14416, - 14439, 14291, 12386, 12370, 12286, 18599, 18678, 18434, 17912, 17736, 18006, 23062, 23175, - 23161, 23613, 23175, 23414, 13759, 13744, 13490, 19640, 19665, 19614, 22134, 22151, 22040, - 16893, 16763, 16405, 24507, 24458, 24386, 37150, 37247, 37101, 36939, 36861, 37098, 36907, - 37037, 37540, 5298, 5427, 5365, 5365, 5427, 5457, 36762, 36757, 36549, 37114, 36813, - 37106, 37247, 37143, 37101, 5049, 5065, 5112, 5183, 5077, 5070, 17565, 16796, 17383, - 18080, 18006, 18176, 17518, 17484, 17427, 19327, 19516, 19614, 22307, 22241, 22356, 24250, - 23765, 24143, 24456, 24143, 24541, 23633, 23688, 23161, 14439, 14610, 14519, 14439, 14519, - 14291, 22134, 22216, 22151, 35766, 35632, 35670, 36886, 36757, 36762, 36370, 36353, 36292, - 12011, 11913, 11947, 12346, 12041, 12534, 11887, 12068, 12000, 24196, 24329, 24029, 26827, - 27019, 26952, 29588, 29522, 29627, 35215, 34956, 34993, 36598, 36397, 36481, 8704, 8537, - 8603, 8507, 8537, 8455, 9862, 9612, 9515, 9909, 9907, 10017, 10087, 10051, 10124, - 31906, 31745, 31540, 21602, 21634, 21313, 22247, 22336, 22459, 4907, 5073, 4910, 4959, - 5006, 5104, 37642, 37589, 37710, 37601, 37931, 37607, 25457, 25400, 25297, 24711, 24541, - 24820, 26696, 26717, 26794, 26717, 26823, 26794, 30119, 29983, 30023, 31006, 31160, 31080, - 37259, 37114, 37106, 37096, 37138, 37097, 37456, 37386, 37136, 37187, 36570, 36662, 11442, - 11259, 11392, 11036, 11259, 11172, 27916, 27500, 27957, 26794, 26823, 26985, 27916, 27957, - 28506, 28707, 28748, 28736, 28748, 28963, 28736, 30160, 30260, 30252, 30186, 30160, 29945, - 36180, 36312, 36030, 36722, 36719, 36551, 36017, 35800, 35754, 35754, 35508, 35823, 35568, - 35476, 35330, 8537, 8482, 8603, 30023, 29983, 29922, 30321, 30362, 30392, 32031, 31906, - 32044, 34633, 34427, 34368, 34951, 35022, 34932, 35116, 35022, 34951, 35116, 34951, 35204, - 30589, 30348, 30395, 5049, 5126, 5038, 5112, 5065, 5104, 5397, 5618, 5517, 11259, - 10977, 11302, 30415, 30589, 30395, 17310, 17518, 17427, 16871, 16893, 16736, 16987, 16893, - 16871, 11927, 11913, 12011, 11798, 11887, 12000, 12286, 12370, 12025, 11784, 11887, 11798, - 26705, 26827, 26952, 26782, 26501, 26698, 25967, 25718, 26272, 35267, 35341, 35180, 35145, - 35215, 34993, 35145, 34993, 35109, 36429, 36529, 36339, 6895, 6821, 6871, 7126, 7084, - 6915, 12455, 12346, 12534, 12041, 11927, 12011, 12462, 12346, 12455, 12326, 12346, 12232, - 12455, 12766, 12462, 29133, 29234, 29253, 29195, 29234, 29133, 29195, 29133, 28852, 28383, - 28625, 28293, 28099, 28017, 27914, 27578, 27439, 27968, 27921, 28044, 27968, 9864, 9907, - 9909, 10124, 10071, 10235, 11214, 11347, 11116, 33527, 33458, 33379, 36444, 36353, 36370, - 36444, 36370, 36446, 37284, 37138, 37096, 19640, 19516, 19508, 36874, 36880, 36653, 36568, - 36444, 36446, 37089, 36880, 36874, 34766, 34368, 34828, 13083, 13021, 13060, 13184, 13302, - 13366, 13302, 13546, 13366, 16796, 16562, 17136, 27334, 27225, 27019, 32786, 32591, 32536, - 32786, 32766, 32591, 32978, 33178, 33140, 33140, 33178, 33245, 33245, 33272, 33240, 32531, - 32191, 32337, 32191, 32157, 32337, 35930, 35958, 35871, 35813, 35766, 35650, 35904, 35913, - 36173, 32766, 32882, 32723, 4928, 5069, 5017, 22151, 22216, 22241, 22151, 22241, 22307, - 7183, 7378, 7268, 32431, 32406, 32343, 32649, 32616, 32556, 32681, 32616, 32649, 32882, - 32912, 32719, 35527, 35214, 35393, 35527, 35393, 35753, 35350, 35341, 35267, 14063, 14179, - 14072, 13454, 13759, 13490, 13401, 13090, 13165, 5521, 5481, 5613, 5770, 5910, 5885, - 9448, 9389, 9480, 8537, 8507, 8482, 9689, 9800, 9506, 11214, 11312, 11347, 10832, - 10629, 10486, 30260, 30415, 30395, 29961, 29945, 29701, 32337, 32157, 32348, 35022, 34930, - 34839, 34897, 34930, 35002, 34715, 34896, 34742, 35215, 35264, 35082, 35004, 34896, 34715, - 6068, 5930, 6261, 6068, 6261, 6114, 36598, 36481, 36757, 36026, 35930, 36054, 29082, - 29205, 29340, 29347, 29340, 29522, 35813, 35718, 35871, 5674, 5770, 5885, 7268, 7475, - 7481, 7268, 7481, 7217, 9506, 9800, 9735, 18154, 18080, 18176, 17565, 17383, 17553, - 18184, 18176, 18284, 17912, 18080, 18154, 29983, 29861, 29690, 30119, 29861, 29983, 32590, - 32406, 32431, 33012, 33178, 32978, 35456, 35116, 35204, 34973, 34993, 34906, 37564, 37486, - 37696, 37548, 37401, 37398, 6369, 6694, 6354, 6696, 6765, 6821, 37143, 37259, 37106, - 37098, 36832, 36986, 37234, 37247, 37150, 37387, 37247, 37234, 23598, 23611, 23661, 4993, - 5239, 5136, 5289, 5282, 5391, 24820, 24916, 24859, 23673, 23598, 23661, 25440, 25530, - 25338, 26272, 26051, 26180, 24329, 24507, 24386, 24436, 24507, 24329, 24556, 24507, 24662, - 9735, 9800, 9849, 9735, 9849, 9760, 32127, 31997, 32031, 32127, 32157, 31997, 9990, - 10051, 10087, 5427, 5405, 5457, 5424, 5727, 5611, 5294, 5405, 5427, 6105, 6068, - 6114, 7669, 7997, 8023, 10486, 10629, 10418, 6737, 6696, 6821, 6999, 6915, 7084, - 12140, 11927, 12041, 11172, 11259, 11242, 11259, 11036, 10977, 12326, 12041, 12346, 11887, - 11949, 12068, 11784, 11949, 11887, 29847, 29588, 29627, 33178, 33272, 33245, 35244, 35264, - 35215, 19508, 19516, 19426, 16987, 17126, 16965, 6781, 6895, 6856, 29347, 29082, 29340, - 18080, 17912, 18006, 18678, 18802, 18434, 23673, 23661, 23765, 36741, 36598, 36757, 36874, - 36939, 37089, 5126, 5193, 5038, 4932, 4928, 5017, 5082, 5023, 5185, 4918, 5007, - 5078, 4918, 5078, 5044, 5770, 5669, 5910, 5664, 5669, 5770, 5664, 5770, 5674, - 5437, 5611, 5474, 6052, 5918, 6276, 6747, 6084, 6960, 11312, 11408, 11698, 11400, - 11408, 11312, 24820, 25004, 24916, 27063, 26985, 27245, 30362, 30736, 30542, 29539, 29522, - 29588, 34896, 34973, 34906, 35145, 35221, 35215, 35083, 34973, 35076, 36722, 36551, 36540, - 37268, 37127, 37138, 36666, 36540, 36529, 30542, 30736, 30815, 31006, 30934, 30950, 30276, - 30415, 30260, 30854, 31290, 30773, 30276, 30260, 30186, 5264, 5282, 5289, 5098, 5282, - 5264, 9892, 10106, 10139, 9794, 9814, 9909, 9907, 9990, 10087, 9407, 9612, 9522, - 24507, 24556, 24458, 24196, 24028, 23758, 32031, 31997, 31906, 31906, 31540, 32044, 10529, - 10486, 10176, 11245, 11214, 10997, 10071, 10124, 10051, 20595, 20709, 20754, 20531, 20709, - 20595, 20531, 20595, 20571, 20531, 20571, 20433, 20531, 20433, 20405, 20433, 20257, 20405, - 20257, 20279, 20405, 34427, 34323, 33709, 34351, 34323, 34389, 20257, 20095, 20279, 12878, - 12766, 12909, 20279, 20095, 20125, 4787, 5163, 5048, 4944, 4874, 4930, 4930, 4851, - 4983, 4660, 4770, 5032, 7183, 6999, 7204, 6915, 6781, 6856, 6881, 6999, 7183, - 22475, 22751, 22895, 22001, 22336, 22247, 23175, 23633, 23161, 22001, 21931, 21634, 35218, - 35221, 35145, 20125, 20095, 19992, 14179, 14291, 14072, 17055, 16987, 16871, 4878, 4874, - 4944, 5405, 5436, 5474, 5223, 5436, 5405, 8482, 8445, 8603, 8711, 8759, 9088, - 9715, 9814, 9794, 23613, 23633, 23175, 23873, 24196, 23758, 26827, 26906, 27019, 25718, - 25803, 26051, 31485, 31319, 31335, 35693, 35452, 35476, 36676, 36666, 36529, 35693, 35476, - 35635, 35330, 35491, 35568, 36886, 36762, 36880, 36436, 36212, 36353, 36676, 36529, 36429, - 28099, 28383, 28293, 29854, 29961, 29701, 28318, 28383, 28099, 35766, 35780, 35632, 36026, - 35958, 35930, 36436, 36353, 36444, 4874, 4851, 4930, 19992, 19968, 19890, 21390, 21161, - 20851, 21238, 21161, 21390, 21238, 21390, 21460, 21390, 21420, 21460, 21420, 21559, 21460, - 21559, 21540, 21460, 13302, 13021, 13083, 12878, 13021, 12971, 35958, 35813, 35871, 35139, - 35022, 35116, 4932, 5017, 5006, 4772, 5048, 5079, 21858, 21891, 21770, 28623, 27957, - 28475, 28959, 28736, 28963, 29019, 28963, 29082, 29019, 29082, 29245, 8507, 8445, 8482, - 9814, 9864, 9909, 19792, 19992, 19890, 19792, 19665, 19640, 30983, 31006, 31080, 5007, - 5023, 5082, 4922, 5023, 5007, 16893, 16987, 16965, 15882, 15571, 15489, 18434, 18802, - 18590, 24456, 24250, 24143, 25418, 25230, 25400, 37268, 37136, 37127, 37268, 37138, 37284, - 6068, 5748, 5930, 6174, 6105, 6114, 6027, 6105, 6174, 36017, 36275, 35966, 5294, - 5298, 5223, 5035, 5298, 5391, 11496, 11784, 11798, 10840, 11076, 10834, 21858, 22040, - 21891, 26273, 26272, 26180, 27084, 27063, 27245, 27084, 27245, 27230, 34930, 34897, 34828, - 35097, 34930, 35022, 35139, 35116, 35328, 36604, 36568, 36397, 36598, 36604, 36397, 36902, - 36886, 36880, 36902, 36880, 37089, 37284, 37096, 37083, 4910, 5073, 5069, 4904, 4932, - 5006, 21891, 22040, 22007, 22895, 22751, 23066, 37589, 37642, 37601, 37652, 37509, 37479, - 37652, 37479, 37734, 5481, 5397, 5517, 5070, 5193, 5155, 5483, 5574, 5768, 15489, - 15571, 15454, 29347, 29522, 29539, 29854, 29701, 29884, 35456, 35204, 35375, 35491, 35341, - 35350, 34973, 35109, 34993, 35083, 35109, 34973, 35244, 35215, 35221, 5098, 5146, 5288, - 17055, 17310, 17126, 19516, 19381, 19426, 24426, 24250, 24456, 22512, 22372, 22475, 30188, - 29861, 30119, 29539, 29588, 29576, 30815, 30736, 30852, 34729, 34058, 34728, 33852, 33730, - 33641, 9914, 9892, 10139, 9914, 10139, 9898, 19640, 19614, 19516, 21476, 21602, 21313, - 15019, 15002, 14810, 13860, 13941, 13853, 13860, 13853, 13759, 9283, 9140, 9480, 8311, - 8329, 8445, 9283, 9480, 9389, 9283, 9389, 9285, 9389, 9448, 9375, 9375, 9506, - 9464, 32912, 33012, 32978, 33178, 33255, 33272, 32882, 32869, 32912, 32766, 32869, 32882, - 32811, 32786, 32536, 32811, 32536, 32531, 32523, 32531, 32337, 32523, 32337, 32429, 32786, - 32869, 32766, 5353, 5397, 5481, 5223, 5437, 5436, 5436, 5437, 5474, 9140, 9060, - 9088, 25534, 25418, 25400, 25534, 25400, 25595, 32860, 32597, 33971, 32616, 32590, 32431, - 31160, 30950, 31236, 35356, 35244, 35221, 5070, 5155, 5183, 5065, 4959, 5104, 17565, - 17553, 17736, 18301, 18184, 18284, 18295, 18184, 18301, 29076, 29195, 28852, 32681, 32590, - 32616, 32869, 33012, 32912, 33272, 33513, 33379, 35491, 35330, 35341, 7411, 7669, 7501, - 7622, 7580, 7560, 10486, 10672, 10832, 10529, 10672, 10486, 31006, 30900, 30852, 30983, - 30900, 31006, 32429, 32337, 32348, 30854, 30431, 30589, 32348, 32157, 32127, 30854, 30589, - 30761, 9864, 9990, 9907, 22040, 22151, 22007, 26960, 26794, 26985, 26960, 26985, 27063, - 36554, 36436, 36444, 36741, 36604, 36598, 36429, 36030, 36312, 36666, 36722, 36540, 37456, - 37284, 37481, 5077, 5673, 5016, 32348, 32441, 32438, 14179, 14416, 14291, 17565, 17736, - 17625, 24635, 24426, 24456, 25179, 25004, 25230, 36554, 36444, 36568, 37540, 37037, 37760, - 37247, 37377, 37143, 19226, 19381, 19327, 22372, 22151, 22307, 5298, 5294, 5427, 5223, - 5298, 5035, 25418, 25179, 25230, 37268, 37456, 37136, 37284, 37083, 37481, 23832, 23673, - 23765, 24635, 24456, 24711, 24196, 24436, 24329, 24966, 24869, 24733, 24662, 24436, 24318, - 32348, 32127, 32441, 37386, 37430, 37227, 37398, 37430, 37543, 6733, 6781, 6790, 6354, - 6694, 6765, 6737, 6781, 6733, 7414, 7481, 7560, 11214, 11400, 11312, 13165, 13090, - 13161, 11245, 11400, 11214, 11701, 11985, 11913, 12326, 12140, 12041, 12232, 12140, 12326, - 29627, 29861, 29847, 30074, 30206, 29945, 30074, 29945, 29961, 35350, 35267, 35264, 12201, - 12025, 12370, 14362, 14485, 14416, 36134, 36026, 36054, 35985, 35802, 35813, 35813, 35802, - 35766, 35933, 36003, 36385, 6354, 6765, 6491, 11701, 11913, 11907, 18184, 18154, 18176, - 18159, 18154, 18184, 34897, 34766, 34828, 35043, 34766, 34897, 9990, 10071, 10051, 11907, - 11913, 11927, 18317, 19226, 19327, 29528, 29253, 29234, 15019, 14810, 14755, 26272, 26273, - 26361, 28130, 27968, 28044, 25530, 25494, 25338, 28709, 28475, 28707, 28709, 28707, 28736, - 28709, 28736, 28929, 28318, 28312, 28408, 28383, 28536, 28625, 13021, 12878, 12909, 13184, - 13021, 13302, 28959, 28963, 29019, 35985, 35813, 35958, 34782, 34707, 34766, 34323, 34351, - 33709, 34389, 34323, 34427, 27230, 27245, 27500, 36630, 36554, 36568, 36385, 36003, 36212, - 4886, 4959, 5065, 4910, 5069, 4928, 4921, 5065, 5049, 7669, 7580, 7622, 7301, - 7580, 7296, 10672, 10840, 10834, 10859, 10840, 10747, 30900, 30815, 30852, 30542, 30525, - 30392, 30862, 30815, 30900, 30761, 30589, 30614, 34707, 34633, 34368, 37744, 37479, 37486, - 5059, 5077, 5016, 5512, 5353, 5481, 5290, 5353, 5512, 5483, 5768, 5669, 6105, - 5951, 6068, 5975, 6027, 6174, 25418, 25383, 25179, 25683, 25534, 25595, 25466, 26696, - 25757, 24717, 24733, 24556, 4958, 5038, 5193, 5061, 5077, 5059, 17807, 17736, 17912, - 21602, 22001, 21634, 22978, 23175, 23062, 23633, 23753, 23758, 33515, 33513, 33272, 29245, - 28959, 29019, 5781, 5885, 5930, 14755, 14610, 14638, 36855, 36722, 36666, 36855, 36666, - 36676, 35244, 35350, 35264, 35356, 35350, 35244, 35218, 35145, 35109, 24875, 24635, 24711, - 25179, 24916, 25004, 24875, 24916, 24995, 31438, 31485, 31335, 31438, 31335, 31290, 5061, - 5193, 5070, 37696, 37486, 37401, 36275, 36340, 36312, 36343, 36340, 36275, 36343, 36275, - 36538, 35823, 35508, 35693, 35635, 35476, 35568, 35635, 35568, 35995, 4910, 4928, 4826, - 33513, 33527, 33379, 12870, 12462, 12766, 11702, 11519, 11701, 36041, 36225, 36237, 4849, - 4918, 4831, 5023, 4993, 5136, 10176, 10486, 10418, 34511, 34389, 34427, 32860, 32702, - 32681, 11242, 11259, 11442, 9866, 9760, 9892, 11242, 11442, 11519, 14485, 14610, 14439, - 14485, 14439, 14416, 27085, 26960, 27063, 27085, 27063, 27084, 29955, 30074, 29961, 30614, - 30589, 30415, 29955, 29961, 29854, 35004, 34973, 34896, 35004, 34715, 34699, 4782, 4928, - 4932, 9892, 9760, 9849, 9914, 9898, 9866, 33527, 33693, 33458, 36340, 36429, 36312, - 15321, 15489, 15307, 15307, 15489, 15454, 16893, 16713, 16736, 15200, 15309, 15019, 32438, - 32429, 32348, 31365, 31438, 31290, 37098, 36986, 37263, 36918, 36741, 36757, 36604, 36630, - 36568, 30815, 30662, 30542, 30862, 30662, 30815, 30276, 30186, 30206, 31410, 31365, 31290, - 34633, 34582, 34427, 34766, 34707, 34368, 35002, 34930, 35097, 37263, 36986, 37114, 6781, - 6737, 6821, 6781, 6915, 6790, 12462, 12232, 12346, 35768, 35485, 35632, 11496, 11686, - 11408, 11496, 11408, 11400, 11214, 11116, 10997, 22978, 22577, 22789, 4918, 4923, 5007, - 5146, 5098, 5264, 4849, 4923, 4918, 15321, 15200, 15241, 22789, 22577, 22425, 8445, - 8214, 8501, 8455, 8445, 8507, 37387, 37377, 37247, 37521, 37377, 37387, 17466, 17769, - 17518, 16987, 17055, 17126, 16405, 16214, 16107, 24875, 24711, 24859, 23832, 23765, 23917, - 24875, 24859, 24916, 12878, 12870, 12766, 12227, 12198, 12232, 14237, 13787, 14598, 13401, - 13454, 13490, 12386, 12847, 12370, 13248, 13454, 13401, 14362, 14416, 14329, 14755, 14835, - 15019, 20709, 20797, 20763, 22245, 22336, 22001, 20531, 20627, 20709, 20561, 20627, 20531, - 20561, 20531, 20405, 20561, 20405, 20437, 20405, 20360, 20437, 19884, 20125, 19992, 19884, - 19992, 19792, 19884, 19792, 19577, 27599, 27230, 27500, 5140, 4989, 4772, 4785, 4787, - 5048, 4878, 4810, 4874, 4874, 4687, 4851, 4660, 5032, 4983, 13184, 12971, 13021, - 13454, 13641, 13759, 28452, 28536, 28383, 29195, 29528, 29234, 31955, 32343, 32406, 35780, - 35768, 35632, 35998, 35985, 35958, 35998, 35958, 36026, 36098, 36026, 36134, 36254, 36173, - 36310, 4787, 4848, 5043, 36918, 36757, 36886, 36554, 36718, 36436, 22475, 22372, 22307, - 22895, 23172, 23598, 29300, 29245, 29082, 29847, 29861, 30188, 29411, 29528, 29195, 37373, - 37259, 37143, 4772, 4989, 4479, 4848, 4810, 4878, 33012, 33255, 33178, 33513, 33515, - 33527, 33527, 33787, 33693, 32869, 33169, 33012, 32786, 32839, 32869, 32811, 32839, 32786, - 32811, 32531, 32642, 32531, 32523, 32642, 32523, 32636, 32642, 4923, 4922, 5007, 4913, - 4922, 4923, 13641, 13860, 13759, 19343, 19071, 19851, 17887, 17807, 17912, 32523, 32429, - 32636, 37543, 37548, 37398, 37543, 37430, 37526, 8329, 8214, 8445, 10286, 10977, 10782, - 23765, 24250, 24311, 23613, 23616, 23633, 24662, 24717, 24556, 23420, 23616, 23613, 8960, - 8711, 9060, 8711, 8455, 8704, 8329, 8311, 8214, 9375, 9448, 9506, 9506, 9735, - 9587, 10959, 10977, 11036, 11519, 11442, 11701, 11496, 11245, 11198, 30439, 30276, 30398, - 30074, 30276, 30206, 32590, 32572, 32406, 32681, 32702, 32590, 33971, 33709, 34351, 35097, - 35022, 35139, 35083, 35218, 35109, 35350, 35781, 35491, 35073, 35004, 35121, 21161, 20909, - 20464, 21282, 21114, 21161, 21282, 21161, 21238, 21380, 21238, 21460, 21380, 21460, 21540, - 21559, 21682, 21540, 32702, 32572, 32590, 32446, 32502, 32441, 11907, 11927, 12140, 35076, - 35218, 35083, 7580, 7414, 7560, 6629, 6649, 6737, 7301, 7414, 7580, 30458, 30614, - 30415, 31547, 31365, 31410, 34982, 34782, 34766, 34707, 34582, 34633, 6027, 5951, 6105, - 6008, 5951, 6027, 6126, 6694, 6369, 9587, 9735, 9683, 9082, 9407, 9522, 9715, - 9507, 9814, 9814, 9672, 9864, 9853, 10071, 9990, 9853, 10105, 10071, 10071, 10105, - 10235, 9515, 9407, 9157, 13860, 14063, 14072, 27916, 27599, 27500, 28092, 27599, 27916, - 28623, 28475, 28709, 28623, 28709, 28738, 32572, 32491, 32406, 33169, 33255, 33012, 35328, - 35097, 35139, 35780, 35766, 35802, 36340, 36432, 36429, 36885, 36855, 36676, 36432, 36343, - 36433, 37869, 37755, 37642, 37642, 37755, 37601, 37710, 37589, 37652, 37710, 37652, 37734, - 5360, 5483, 5411, 5743, 5781, 5930, 14484, 14638, 14485, 14485, 14638, 14610, 36725, - 36630, 36604, 31732, 31540, 31485, 4759, 4989, 4907, 21559, 21770, 21682, 24662, 24507, - 24436, 4922, 4972, 5023, 4913, 4972, 4922, 11955, 11907, 12140, 12198, 12140, 12232, - 18434, 18295, 18301, 18357, 18295, 18434, 35218, 35356, 35221, 35635, 35823, 35693, 37377, - 37376, 37143, 37373, 37376, 37521, 25534, 25383, 25418, 25757, 26696, 26794, 25757, 26573, - 26027, 34389, 34377, 34351, 34847, 34582, 34707, 19577, 19792, 19640, 19426, 19640, 19508, - 5571, 6052, 5954, 5877, 5918, 5798, 5424, 5611, 5437, 6737, 6649, 6696, 7095, - 7183, 7268, 9407, 9515, 9612, 12201, 12068, 12025, 12068, 11949, 12025, 14604, 14237, - 14598, 13621, 13697, 13503, 17565, 17161, 16796, 17887, 17912, 18154, 22165, 22129, 22372, - 24311, 24250, 24426, 23616, 23753, 23633, 23871, 23753, 23750, 33255, 33352, 33272, 35073, - 35076, 35004, 4993, 5288, 5239, 5294, 5223, 5405, 24370, 24311, 24426, 24622, 24426, - 24635, 37744, 37486, 37564, 37526, 37430, 37386, 37456, 37268, 37284, 21682, 21770, 21725, - 9510, 9587, 9600, 25520, 25383, 25534, 33352, 33515, 33272, 7217, 7095, 7268, 21725, - 21770, 21891, 34517, 34511, 34641, 35002, 35043, 34897, 35070, 35097, 35179, 35004, 35076, - 34973, 35728, 35781, 35356, 33852, 33641, 33693, 4943, 4921, 5049, 4959, 4904, 5006, - 4910, 4759, 4907, 4943, 5049, 5038, 5061, 5070, 5077, 7414, 7325, 7481, 7301, - 7325, 7414, 22978, 23234, 23175, 23034, 23234, 22978, 30439, 30458, 30415, 30697, 30854, - 30761, 30439, 30415, 30276, 4830, 4904, 4959, 5781, 5674, 5885, 5625, 5674, 5781, - 6790, 6915, 6999, 12227, 12232, 12462, 14329, 14416, 14179, 30188, 30119, 30525, 28929, - 28736, 28959, 30119, 30392, 30525, 29528, 29884, 29701, 29955, 29884, 30000, 28195, 28318, - 28099, 28536, 29076, 28852, 26906, 26827, 26782, 36254, 36098, 36134, 35985, 35973, 35802, - 36254, 36134, 36173, 13165, 13248, 13401, 13454, 13458, 13641, 13641, 13563, 13860, 14134, - 14179, 14063, 14134, 14329, 14179, 12819, 13161, 13008, 16107, 16214, 15882, 17466, 17518, - 17310, 24995, 24916, 25179, 28408, 28452, 28383, 36098, 35998, 36026, 35768, 35753, 35393, - 5673, 5045, 5016, 5618, 5045, 5673, 6246, 6126, 6369, 5667, 5743, 5930, 6246, - 6369, 6193, 17807, 17625, 17736, 16309, 15871, 16562, 17687, 17625, 17807, 23753, 23873, - 23758, 23871, 23873, 23753, 35998, 35973, 35985, 10859, 11076, 10840, 9777, 9990, 9864, - 5534, 5669, 5664, 8309, 8455, 8277, 7244, 7301, 7296, 19963, 19851, 20057, 36902, - 37072, 36886, 36741, 36725, 36604, 37098, 37089, 36939, 37145, 37089, 37098, 37263, 37114, - 37259, 37734, 37479, 37743, 5483, 5382, 5512, 15958, 16107, 15882, 15200, 15321, 15307, - 15241, 15200, 15019, 15241, 15019, 15121, 25352, 24995, 25179, 25683, 25520, 25534, 27051, - 26794, 26960, 4921, 4886, 5065, 4869, 4943, 5038, 23234, 23414, 23175, 23237, 23414, - 23234, 35961, 35780, 35802, 35635, 36225, 36041, 36041, 35823, 35635, 5748, 6068, 5951, - 5674, 5625, 5664, 5975, 6008, 6027, 8455, 8311, 8445, 15958, 15882, 15796, 25566, - 25520, 25683, 26273, 26698, 26501, 26405, 26698, 26273, 26272, 25718, 26051, 34582, 34511, - 34427, 34929, 34707, 34782, 22425, 22577, 22336, 22425, 22336, 22245, 35804, 35753, 35768, - 5061, 4958, 5193, 4806, 4817, 4889, 7325, 7217, 7481, 6881, 6790, 6999, 7244, - 7217, 7325, 30697, 30761, 30614, 30104, 30276, 30074, 35070, 35043, 35002, 35070, 35002, - 35097, 4660, 4983, 4851, 11245, 11496, 11400, 12386, 12819, 12847, 10859, 10747, 10898, - 17164, 17310, 17055, 22129, 22007, 22151, 22129, 22151, 22372, 31438, 31547, 31485, 30646, - 30614, 30458, 36343, 36432, 36340, 37187, 36662, 36719, 36433, 36343, 36538, 16963, 17164, - 17055, 16713, 16893, 16405, 24717, 24966, 24733, 24959, 24966, 24717, 10840, 10672, 10747, - 23414, 23420, 23613, 24318, 24436, 24196, 23412, 23420, 23414, 9914, 9866, 9892, 10959, - 11036, 11172, 16963, 17055, 16871, 32511, 31955, 32406, 30983, 30862, 30900, 33847, 33852, - 33693, 37773, 37064, 37318, 37376, 37373, 37143, 5035, 5391, 5282, 19562, 19343, 19851, - 18159, 17887, 18154, 18971, 19075, 19208, 22895, 23598, 23309, 25128, 25237, 24869, 26709, - 26906, 26782, 37455, 37373, 37521, 12025, 11949, 11716, 4831, 4918, 5044, 4972, 4993, - 5023, 5098, 5035, 5282, 23309, 23598, 23673, 23780, 23673, 23832, 23917, 23765, 24311, - 22789, 22888, 22978, 22735, 22888, 22789, 37743, 37479, 37744, 14362, 14484, 14485, 13934, - 14063, 13860, 33121, 33169, 32869, 33255, 33353, 33352, 33352, 33507, 33515, 33626, 33787, - 33527, 32811, 32942, 32839, 32642, 32770, 32811, 32657, 32770, 32642, 32657, 32642, 32636, - 9283, 9096, 9140, 8455, 8309, 8311, 9303, 9285, 9389, 9303, 9389, 9375, 9303, - 9375, 9292, 32636, 32429, 32438, 32942, 32869, 32839, 37089, 37072, 36902, 36385, 36527, - 36422, 37145, 37072, 37089, 9464, 9506, 9587, 32491, 32511, 32406, 32572, 32622, 32491, - 32702, 32622, 32572, 32826, 32622, 32702, 4933, 4958, 5061, 5290, 5397, 5353, 17223, - 17466, 17310, 15796, 15882, 15694, 14835, 14755, 14638, 37072, 36918, 36886, 6126, 5975, - 6174, 6765, 6696, 6491, 13161, 13248, 13165, 13073, 13248, 13161, 28318, 28408, 28383, - 28452, 28559, 28536, 28195, 28099, 27968, 32622, 32511, 32491, 35823, 36147, 35754, 13248, - 13458, 13454, 28130, 28195, 27968, 36098, 36092, 35998, 36092, 35961, 35973, 35973, 35961, - 35802, 35780, 35804, 35768, 36212, 36527, 36385, 5382, 5290, 5512, 5321, 5290, 5382, - 5321, 5382, 5220, 16609, 16713, 16405, 15450, 15489, 15321, 37361, 37263, 37259, 11716, - 11949, 11784, 12354, 12819, 12386, 29082, 29347, 29300, 28567, 28559, 28452, 30454, 30458, - 30439, 4824, 4886, 4921, 4782, 4826, 4928, 4869, 4921, 4943, 22888, 22965, 22978, - 22885, 22965, 22888, 37744, 37564, 37791, 35043, 34982, 34766, 35456, 35375, 35527, 35076, - 35404, 35218, 36401, 36167, 36147, 35121, 35004, 34699, 4782, 4932, 4904, 9510, 9464, - 9587, 16881, 16963, 16871, 17164, 17223, 17310, 16617, 16713, 16609, 25352, 25179, 25383, - 24875, 24622, 24635, 32441, 32127, 32446, 33393, 33353, 33255, 36952, 36719, 36722, 37696, - 37401, 37548, 10981, 10959, 11172, 10919, 10959, 10981, 11330, 11242, 11519, 11702, 11701, - 11907, 10859, 10997, 11116, 12194, 12286, 12025, 10898, 10997, 10859, 24660, 24622, 24690, - 24966, 25128, 24869, 24085, 24196, 23873, 23753, 23616, 23750, 30454, 30646, 30458, 29955, - 29854, 29884, 37456, 37526, 37386, 6491, 6696, 6649, 6491, 6649, 6538, 12971, 12870, - 12878, 10919, 10782, 10959, 12662, 12870, 12738, 13252, 12971, 13184, 12239, 12386, 12286, - 36092, 35973, 35998, 35883, 35456, 35527, 28130, 28312, 28195, 26698, 26709, 26782, 26563, - 26709, 26698, 30104, 29955, 30000, 36885, 36676, 36429, 36718, 36554, 36630, 9683, 9735, - 9760, 33353, 33507, 33352, 20405, 20279, 20360, 20627, 20797, 20709, 20279, 20125, 20360, - 20285, 20351, 20142, 20561, 20797, 20627, 34511, 34377, 34389, 34517, 34377, 34511, 37455, - 37363, 37373, 37373, 37363, 37259, 4787, 4679, 4848, 4848, 4679, 4810, 4810, 4687, - 4874, 4785, 4720, 4787, 4702, 4720, 4785, 4702, 4785, 4668, 4651, 4679, 4787, - 6538, 6649, 6533, 20360, 20458, 20437, 21114, 20909, 21161, 19282, 19314, 19343, 20947, - 20909, 21114, 20947, 21114, 21011, 21114, 21282, 21011, 21380, 21282, 21238, 21394, 21282, - 21380, 35945, 35804, 35780, 4720, 4702, 4658, 19481, 19640, 19426, 21540, 21394, 21380, - 31034, 30862, 30983, 29576, 29347, 29539, 4849, 4913, 4923, 4767, 4913, 4849, 18159, - 18184, 18295, 17625, 17687, 17565, 22965, 23034, 22978, 22969, 23034, 22965, 37577, 37548, - 37543, 5918, 5877, 6276, 5798, 5918, 5688, 21540, 21682, 21725, 36674, 36885, 36429, - 36167, 36275, 36017, 6881, 7183, 6836, 35847, 35527, 35753, 4611, 4687, 4810, 4689, - 4831, 4559, 37005, 36725, 36741, 6629, 6737, 6733, 29576, 29588, 29847, 5019, 5424, - 4984, 37164, 36927, 36918, 36918, 36927, 36741, 37291, 37145, 37098, 37291, 37098, 37263, - 15317, 15450, 15321, 15317, 15321, 15241, 21979, 22001, 21602, 25718, 25589, 25803, 25440, - 25338, 25237, 9600, 9557, 9505, 9630, 9683, 9760, 21725, 21891, 21828, 38047, 38100, - 38085, 38606, 37318, 37349, 37931, 37601, 37755, 37869, 37642, 37710, 37869, 37710, 37856, - 37710, 37734, 37856, 16881, 16871, 16736, 16881, 16736, 16617, 16736, 16713, 16617, 24959, - 25128, 24966, 30525, 30542, 30599, 30599, 30542, 30662, 31410, 31290, 31422, 30634, 30454, - 30439, 35179, 34982, 35043, 35179, 35043, 35070, 36941, 36927, 37178, 18393, 18357, 18434, - 4933, 5061, 5059, 4933, 5059, 4937, 4752, 4993, 4972, 5019, 5325, 5424, 20797, - 21476, 21313, 4743, 4782, 4904, 4826, 4759, 4910, 4830, 4959, 4886, 6790, 6629, - 6733, 8311, 8163, 8214, 8711, 9088, 9060, 34406, 34013, 33849, 33626, 33527, 33515, - 37526, 37577, 37543, 37591, 37577, 37526, 6836, 7183, 7095, 6577, 6533, 6629, 6836, - 7095, 6886, 10959, 10782, 10977, 11702, 11907, 11660, 11955, 12140, 12198, 31365, 31547, - 31438, 31290, 31185, 31422, 25271, 25440, 25237, 37363, 37361, 37259, 37455, 37361, 37363, - 5514, 5625, 5781, 5514, 5781, 5743, 5792, 5951, 6008, 14574, 14835, 14638, 14484, - 14362, 14381, 12070, 11955, 12198, 13546, 13302, 13787, 28567, 28685, 28559, 28559, 28685, - 28536, 28195, 28312, 28318, 27439, 27225, 27334, 36147, 36167, 36017, 36041, 36147, 35823, - 35961, 35945, 35780, 35804, 35824, 35753, 36226, 36092, 36098, 36226, 36098, 36294, 36310, - 36173, 36414, 6113, 6069, 6126, 6113, 6126, 6246, 6314, 6369, 6354, 6314, 6354, - 6337, 6354, 6491, 6387, 14237, 13546, 13787, 13321, 13546, 13319, 13458, 13563, 13641, - 13446, 13563, 13458, 13446, 13458, 13333, 27334, 27019, 26906, 36414, 36173, 36385, 6387, - 6491, 6345, 23034, 23237, 23234, 24662, 24959, 24717, 23415, 23237, 23266, 28567, 28452, - 28408, 29955, 30104, 30074, 33787, 33847, 33693, 37856, 37734, 37842, 37734, 37743, 37842, - 6069, 5975, 6126, 12227, 12462, 12392, 16405, 16107, 16609, 17171, 17223, 17164, 29599, - 29576, 29720, 30826, 30599, 30662, 31160, 31006, 30950, 31034, 31080, 31114, 6452, 6491, - 6538, 27203, 27230, 27308, 27203, 27085, 27230, 27230, 27085, 27084, 29009, 28929, 28959, - 29009, 28959, 29245, 36226, 35945, 35961, 4958, 4869, 5038, 4937, 5059, 5016, 21828, - 21891, 22007, 21828, 22007, 21905, 24199, 23917, 24311, 22165, 22007, 22129, 24370, 24426, - 24477, 23421, 23616, 23420, 37577, 37696, 37548, 32631, 32636, 32441, 30697, 30614, 30646, - 26180, 26369, 26273, 27050, 27334, 26906, 25803, 25589, 25530, 5424, 5487, 5889, 5325, - 5487, 5424, 5877, 5931, 6276, 9082, 9522, 9031, 5801, 5931, 5877, 13725, 13934, - 13860, 17293, 17223, 17171, 19226, 19481, 19381, 24477, 24426, 24622, 26237, 26369, 26180, - 33169, 33246, 33255, 33533, 33626, 33507, 34051, 33987, 33787, 33787, 33987, 33847, 32770, - 32942, 32811, 32971, 32942, 32770, 32971, 32770, 33063, 32636, 32438, 32441, 4889, 4937, - 5016, 5220, 5382, 5219, 28506, 27957, 28623, 25734, 25566, 25683, 24622, 24875, 24690, - 24660, 24477, 24622, 33971, 32597, 32732, 32622, 32601, 32511, 32511, 32638, 31955, 36725, - 36718, 36630, 36983, 36718, 36725, 37339, 37291, 37263, 37162, 36918, 37072, 36927, 36941, - 36741, 22727, 22475, 22895, 30000, 29884, 29763, 30656, 30697, 30646, 32942, 33121, 32869, - 6533, 6649, 6629, 6385, 6452, 6538, 28685, 29076, 28536, 35936, 35824, 35804, 34949, - 34929, 34982, 7580, 7669, 7411, 10975, 11198, 11245, 10747, 10672, 10501, 30656, 30646, - 30454, 34982, 34929, 34782, 35179, 35097, 35328, 17887, 17687, 17807, 18357, 18159, 18295, - 18205, 18159, 18357, 23237, 23412, 23414, 23372, 23412, 23237, 5625, 5534, 5664, 5450, - 5534, 5509, 37162, 37072, 37145, 8960, 9060, 9140, 9303, 9232, 9285, 9464, 9292, - 9375, 9232, 9292, 9356, 9292, 9464, 9356, 32658, 32601, 32622, 31732, 31485, 31547, - 5571, 5954, 5645, 13934, 14134, 14063, 4852, 4869, 4958, 5045, 5397, 5036, 6577, - 6629, 6557, 6800, 6790, 6881, 12638, 12462, 12870, 12194, 12239, 12286, 13333, 13458, - 13248, 12194, 12025, 11854, 23871, 23979, 23873, 25128, 25124, 25237, 23967, 23979, 23871, - 29510, 29300, 29347, 4913, 4767, 4972, 4831, 5044, 4675, 22810, 22727, 22837, 22687, - 22735, 22789, 22687, 22789, 22425, 31080, 31034, 30983, 30468, 30283, 30188, 29599, 29510, - 29576, 29421, 29117, 29300, 30950, 31839, 31236, 37891, 37931, 37755, 37842, 37743, 37944, - 19381, 19481, 19426, 19226, 19173, 19225, 24951, 24959, 24662, 26158, 26096, 26051, 36674, - 36429, 36432, 37283, 37187, 36719, 36923, 36885, 37244, 4852, 4958, 4933, 23412, 23421, - 23420, 23372, 23421, 23412, 24370, 24199, 24311, 23917, 23780, 23832, 25566, 25383, 25520, - 27050, 26906, 26709, 4697, 4759, 4826, 4697, 4826, 4695, 31662, 31732, 31547, 31566, - 31547, 31410, 4824, 4830, 4886, 11578, 11435, 11702, 11435, 11330, 11519, 12227, 12070, - 12198, 22735, 22885, 22888, 22791, 22885, 22735, 37891, 37755, 37950, 37944, 37743, 37744, - 5411, 5483, 5669, 5321, 5244, 5290, 26369, 26405, 26273, 26051, 26096, 26180, 25803, - 25530, 25440, 30826, 30662, 30862, 31185, 31290, 30854, 30634, 30656, 30454, 36952, 36722, - 36855, 37456, 37591, 37526, 6193, 6314, 6210, 6193, 6369, 6314, 6175, 6113, 6246, - 5882, 5937, 5975, 5975, 5937, 6008, 6354, 6387, 6337, 13563, 13725, 13860, 14093, - 14231, 14134, 13333, 13248, 13130, 6337, 6387, 6340, 28738, 28587, 28623, 28738, 28709, - 28929, 6886, 7095, 6991, 26302, 26405, 26369, 34377, 33971, 34351, 34641, 34511, 34582, - 9683, 9600, 9587, 9557, 9683, 9630, 23979, 24085, 23873, 23967, 24085, 23979, 27921, - 27968, 27439, 28130, 28154, 28312, 28435, 28567, 28408, 29574, 29411, 29517, 36294, 36098, - 36254, 36029, 35936, 35945, 35945, 35936, 35804, 36422, 36414, 36385, 6345, 6491, 6452, - 6345, 6452, 6401, 19343, 19314, 18802, 19282, 19343, 19562, 19379, 19226, 19225, 22189, - 22165, 22284, 29049, 28738, 28929, 37755, 37869, 37950, 11716, 11784, 11586, 10693, 10747, - 10501, 10672, 10529, 10501, 25734, 25683, 25757, 14894, 15121, 15019, 16609, 16107, 16005, - 14381, 14362, 14329, 14231, 14329, 14134, 27085, 27051, 26960, 27308, 27230, 27599, 38103, - 37160, 37673, 37521, 37376, 37377, 37459, 37339, 37263, 5882, 5975, 5947, 5450, 5411, - 5669, 5931, 5916, 6276, 5825, 5916, 5931, 5801, 5877, 5798, 36527, 36212, 36436, - 36527, 36436, 36945, 36923, 36952, 36855, 36923, 36855, 36885, 6401, 6452, 6385, 16881, - 16765, 16963, 19379, 19481, 19226, 15882, 15489, 15694, 22885, 22969, 22965, 23421, 23750, - 23616, 22836, 22969, 22885, 29117, 29245, 29300, 29117, 29009, 29245, 36226, 35961, 36092, - 35824, 35847, 35753, 37677, 37591, 37709, 37998, 37771, 37696, 37696, 37771, 37564, 4695, - 4826, 4782, 21979, 22245, 22001, 5937, 5792, 6008, 5679, 5801, 5798, 37521, 37387, - 37540, 37333, 37162, 37145, 35920, 35847, 35824, 20909, 20723, 20464, 20815, 20723, 20909, - 20815, 20909, 20984, 20909, 20947, 20984, 20947, 21011, 20984, 21011, 21045, 20984, 21282, - 21045, 21011, 31034, 30826, 30862, 30950, 31548, 31839, 34847, 34641, 34582, 32826, 32702, - 32860, 34847, 34707, 34929, 4658, 4651, 4720, 4720, 4651, 4787, 4679, 4611, 4810, - 4494, 4660, 4851, 4658, 4702, 4668, 4785, 4772, 4668, 20458, 20547, 20437, 20437, - 20547, 20561, 20561, 20547, 20797, 21264, 21415, 21476, 21476, 21979, 21602, 20458, 20360, - 20351, 20142, 20351, 20360, 21282, 21127, 21045, 37886, 38010, 37463, 38053, 38010, 37886, - 4668, 4772, 4558, 19577, 19640, 19481, 24172, 24199, 24330, 23994, 24199, 24070, 38047, - 38041, 37886, 37950, 37869, 38045, 4558, 4772, 4377, 4560, 4611, 4679, 5252, 5571, - 5645, 11435, 11519, 11702, 10530, 9898, 10286, 18159, 17832, 17887, 18042, 17832, 18159, - 21540, 21587, 21394, 27122, 27051, 27085, 27122, 27085, 27203, 38010, 38011, 37673, 4743, - 4695, 4782, 4775, 4824, 4921, 4775, 4921, 4869, 4699, 4767, 4849, 4562, 5035, - 5098, 4699, 4849, 4831, 18590, 18393, 18434, 21394, 21587, 21364, 38011, 37976, 37673, - 5220, 5244, 5321, 5450, 5669, 5534, 29510, 29347, 29576, 31092, 30826, 31034, 37339, - 37145, 37291, 36941, 37005, 36741, 5792, 5748, 5951, 14093, 14134, 13949, 6557, 6629, - 6790, 6836, 6800, 6881, 6761, 6800, 6836, 12239, 12261, 12386, 11245, 10997, 10975, - 28928, 29076, 28685, 29076, 29411, 29195, 30104, 30183, 30276, 33626, 33515, 33507, 33847, - 33987, 33852, 4743, 4904, 4830, 4697, 4614, 4759, 5382, 5483, 5219, 5509, 5534, - 5451, 14894, 15019, 14835, 14574, 14638, 14484, 15788, 15871, 16309, 26475, 26563, 26405, - 26405, 26563, 26698, 28053, 28154, 28044, 26237, 26180, 26096, 16617, 16765, 16881, 16005, - 16107, 15958, 24959, 25124, 25128, 24951, 25124, 24959, 37459, 37263, 37361, 37742, 37521, - 37540, 37541, 38100, 38047, 33121, 33246, 33169, 32942, 33058, 33121, 33063, 32770, 32657, - 33063, 32657, 33068, 32971, 33058, 32942, 4657, 4743, 4830, 4698, 4775, 4757, 4852, - 4933, 4937, 18393, 18348, 18357, 18285, 18348, 18393, 21905, 21725, 21828, 33099, 33246, - 33121, 34728, 34058, 34013, 35568, 35491, 35781, 6113, 6091, 6069, 5937, 5852, 5792, - 5428, 5624, 5748, 6193, 6175, 6246, 6210, 6175, 6193, 6210, 6314, 6337, 6210, - 6337, 6196, 13546, 13321, 13366, 13366, 13252, 13184, 12227, 12050, 12070, 11578, 11702, - 11660, 13252, 13321, 13319, 13405, 13725, 13563, 13073, 13161, 12819, 23994, 23780, 23917, - 22189, 22007, 22165, 23555, 23750, 23421, 24085, 24318, 24196, 28587, 28506, 28623, 28723, - 28506, 28587, 28723, 28587, 28738, 35936, 35920, 35824, 36294, 36254, 36310, 36294, 36310, - 36428, 36424, 36310, 36414, 36420, 36414, 36422, 37773, 37760, 37037, 37818, 37760, 37773, - 37683, 37696, 37577, 38045, 37869, 37856, 24102, 24318, 24085, 32502, 32631, 32441, 31185, - 30854, 30697, 5748, 5667, 5930, 5616, 5667, 5624, 14308, 14381, 14329, 14308, 14329, - 14231, 27215, 27319, 27217, 6196, 6337, 6340, 9096, 9283, 9285, 7669, 8023, 7501, - 9232, 9303, 9292, 9356, 9464, 9410, 21264, 21476, 20797, 28044, 28154, 28130, 27921, - 27439, 27816, 37178, 37005, 36941, 36952, 37283, 36719, 37677, 37683, 37591, 36674, 36432, - 36433, 37541, 37607, 38100, 37973, 37856, 37842, 37975, 37931, 38005, 9410, 9464, 9510, - 9410, 9510, 9529, 32127, 32301, 32446, 5947, 5975, 6069, 5821, 5895, 5916, 5916, - 5895, 6355, 5825, 5931, 5801, 10913, 10997, 10898, 12738, 12870, 12971, 13405, 13563, - 13446, 28053, 27921, 27950, 35196, 35179, 35268, 35404, 35076, 35073, 36669, 36674, 36433, - 7301, 7244, 7325, 8023, 7498, 7501, 10981, 11172, 11242, 10981, 11242, 11330, 10693, - 10913, 10898, 10693, 10898, 10747, 35091, 34949, 34982, 6800, 6690, 6790, 6991, 7095, - 7217, 11907, 11955, 11660, 9529, 9510, 9600, 31869, 31540, 31732, 18348, 18205, 18357, - 17832, 17687, 17887, 18285, 18205, 18348, 4695, 4614, 4697, 4761, 4830, 4824, 5679, - 5825, 5801, 6385, 6538, 6533, 6340, 6401, 6318, 10530, 10286, 10782, 29009, 29049, - 28929, 29834, 29720, 29576, 31662, 31869, 31732, 36962, 36436, 36718, 4889, 4852, 4937, - 4698, 4761, 4824, 14501, 14574, 14484, 14535, 14574, 14501, 17744, 17687, 17832, 27248, - 27122, 27203, 25867, 25734, 26027, 27248, 27203, 27308, 32301, 32127, 32031, 15121, 15317, - 15241, 15353, 15317, 15153, 8163, 8311, 8309, 15694, 15489, 15450, 25566, 25551, 25383, - 24199, 23994, 23917, 27061, 26794, 27051, 25859, 25803, 25569, 32826, 32860, 32955, 34948, - 34847, 34929, 37459, 37361, 37511, 37162, 37164, 36918, 6761, 6690, 6800, 11586, 11784, - 11496, 12194, 12261, 12239, 37591, 37683, 37577, 37677, 37709, 37728, 5451, 5534, 5625, - 5377, 5286, 5411, 5219, 5483, 5360, 9505, 9529, 9600, 9515, 9507, 9715, 9157, - 9507, 9515, 8575, 7946, 7737, 33533, 33507, 33353, 34406, 33730, 33852, 12119, 12261, - 12194, 13949, 14134, 13934, 23415, 23372, 23237, 22396, 22687, 22425, 22812, 22687, 22797, - 36538, 36275, 36167, 4494, 4851, 4687, 19379, 19577, 19481, 19173, 19300, 19225, 22189, - 21905, 22007, 22810, 22475, 22727, 23237, 23034, 23266, 23750, 23967, 23871, 32044, 32301, - 32031, 31566, 31662, 31547, 32044, 31540, 31869, 11198, 11284, 11496, 11161, 11284, 11198, - 11058, 10981, 11330, 9630, 9793, 9492, 10983, 10975, 10830, 10913, 10975, 10997, 34949, - 34948, 34929, 35196, 35091, 34982, 35196, 34982, 35179, 22837, 22727, 22895, 24070, 24199, - 24172, 23856, 23967, 23750, 24819, 24951, 24662, 26009, 25943, 25859, 31160, 31114, 31080, - 29847, 29834, 29576, 31839, 31548, 31955, 4764, 5098, 4993, 4675, 5044, 4770, 22837, - 22895, 23309, 22687, 22791, 22735, 22812, 22791, 22687, 4752, 4972, 4767, 5679, 5688, - 5579, 14228, 14308, 14231, 14613, 14894, 14835, 16609, 16765, 16617, 16752, 16765, 16609, - 24819, 24662, 24318, 29879, 29834, 29847, 6886, 6761, 6836, 6340, 6345, 6401, 6796, - 6761, 6886, 6991, 7217, 7244, 11447, 11578, 11494, 11435, 11360, 11330, 12157, 12354, - 12261, 11471, 11586, 11496, 29763, 29884, 29528, 31756, 31566, 31574, 31422, 31566, 31410, - 30031, 30000, 30172, 6175, 6091, 6113, 5882, 5852, 5937, 5514, 5451, 5625, 6079, - 6091, 6175, 6079, 6175, 6210, 6387, 6345, 6340, 7411, 7296, 7580, 7318, 7296, - 7411, 8225, 8277, 8455, 10501, 10529, 10176, 13321, 13252, 13366, 12662, 12638, 12870, - 13319, 13546, 13436, 12713, 13073, 12819, 13333, 13405, 13446, 13725, 13883, 13934, 14228, - 14293, 14308, 23372, 23491, 23421, 23415, 23491, 23372, 28435, 28408, 28312, 28435, 28312, - 28200, 13173, 13405, 13333, 31879, 32044, 31869, 31185, 30697, 31154, 6533, 6417, 6385, - 25943, 26158, 26051, 27816, 27439, 27334, 26237, 26158, 26198, 28690, 28776, 28685, 5946, - 5947, 6069, 27921, 28053, 28044, 27816, 27688, 27829, 36294, 36682, 36226, 36029, 35920, - 35936, 35328, 35116, 35587, 36702, 36420, 36422, 36424, 36420, 36519, 5045, 5618, 5397, - 5286, 5360, 5411, 15796, 15848, 15958, 15633, 15694, 15450, 15353, 15450, 15317, 19173, - 19305, 19300, 37005, 36983, 36725, 37326, 37164, 37162, 4689, 4699, 4831, 4643, 4699, - 4565, 17863, 17744, 17832, 19314, 18590, 18802, 18545, 18590, 18749, 22284, 22165, 22372, - 23309, 23673, 23780, 8277, 8163, 8309, 6385, 6417, 6318, 12738, 12638, 12662, 27122, - 27061, 27051, 27215, 27248, 27308, 5791, 5852, 5882, 5895, 5914, 6574, 5825, 5821, - 5916, 5735, 5821, 5825, 5688, 5918, 5571, 13762, 13883, 13725, 27050, 26709, 26834, - 37381, 37244, 37392, 36654, 36538, 36167, 4698, 4824, 4775, 5397, 5290, 5036, 23964, - 24070, 24172, 23273, 23309, 23535, 23967, 24102, 24085, 23856, 24102, 23967, 30737, 30697, - 30656, 34923, 35121, 34699, 34923, 34728, 34858, 37339, 37333, 37145, 37511, 37361, 37455, - 37511, 37455, 37612, 4660, 4675, 4770, 17293, 17466, 17223, 22512, 22475, 22810, 38005, - 37931, 37891, 38005, 37891, 38082, 37791, 37564, 37771, 5377, 5411, 5450, 5616, 5743, - 5667, 14535, 14835, 14574, 14484, 14381, 14501, 23491, 23555, 23421, 23519, 23555, 23491, - 37998, 37791, 37771, 6854, 6991, 7244, 11514, 11712, 11586, 10975, 11089, 11198, 10983, - 11089, 10975, 35107, 34948, 34949, 35883, 35527, 35847, 5171, 5290, 5244, 6656, 6690, - 6761, 6656, 6790, 6690, 12638, 12392, 12462, 12261, 12354, 12386, 11771, 12025, 11716, - 11712, 11716, 11586, 36029, 35945, 36226, 11447, 11360, 11435, 11447, 11435, 11578, 30031, - 30183, 30104, 30031, 30104, 30000, 35587, 35116, 35456, 4775, 4751, 4757, 4356, 4614, - 4695, 9898, 9793, 9866, 10785, 10782, 10919, 10785, 10919, 10981, 9672, 9777, 9864, - 18590, 18500, 18393, 18545, 18500, 18590, 31868, 31662, 31756, 31868, 31869, 31662, 33246, - 33393, 33255, 33058, 33099, 33121, 32971, 32979, 33058, 33063, 32979, 32971, 33151, 32979, - 33063, 32615, 32631, 32502, 32498, 32502, 32446, 32498, 32446, 32454, 37481, 37083, 37187, - 37683, 37998, 37696, 37920, 37944, 37744, 32979, 33099, 33058, 10782, 10785, 10612, 34696, - 34517, 34641, 35107, 34949, 35091, 9232, 9096, 9285, 8412, 8225, 8455, 8277, 8092, - 8163, 9033, 9096, 9156, 9244, 9232, 9356, 9343, 9356, 9410, 9343, 9410, 9359, - 4657, 4695, 4743, 38082, 37891, 38106, 11471, 11496, 11284, 27091, 27061, 27122, 26834, - 26709, 26563, 37020, 36983, 37005, 32601, 32658, 32511, 32826, 32658, 32622, 35013, 34641, - 34847, 34482, 34406, 34302, 33398, 33393, 33246, 4651, 4536, 4679, 4611, 4477, 4687, - 4660, 4494, 4675, 4490, 4536, 4651, 4490, 4651, 4658, 4558, 4658, 4668, 20723, - 20635, 20057, 20777, 20635, 20723, 20777, 20723, 20815, 20777, 20815, 20984, 20777, 20984, - 20857, 20984, 21045, 21127, 21282, 21394, 21127, 4536, 4560, 4679, 5252, 5645, 5487, - 21127, 21394, 21364, 9777, 9853, 9990, 10830, 10975, 10913, 9430, 9410, 9529, 10176, - 10418, 10105, 37976, 38103, 37673, 38011, 38121, 37976, 38010, 38142, 38011, 38265, 38142, - 38010, 38053, 37886, 38041, 38053, 38187, 38153, 38041, 38047, 38146, 4670, 4657, 4830, - 4775, 4869, 4751, 5377, 5450, 5509, 5220, 5171, 5244, 5424, 5437, 4984, 26158, - 26237, 26096, 25943, 26051, 25803, 37973, 38045, 37856, 38020, 37920, 37744, 4543, 4989, - 4759, 5275, 5219, 5360, 20547, 20874, 20797, 22836, 22885, 22791, 20458, 20351, 20547, - 20360, 20125, 20142, 20125, 19884, 20142, 19400, 19577, 19379, 25271, 25237, 25124, 38146, - 38047, 38176, 38142, 38121, 38011, 5352, 5509, 5451, 5352, 5377, 5509, 32454, 32446, - 32301, 33393, 33533, 33353, 21540, 21725, 21587, 5167, 5171, 5220, 25734, 25681, 25566, - 25738, 25681, 25734, 6091, 5955, 6069, 5947, 5791, 5882, 6196, 6079, 6210, 5765, - 6079, 5837, 6161, 6196, 6340, 13073, 13130, 13248, 13593, 13762, 13725, 13084, 13130, - 12918, 28567, 28690, 28685, 28776, 28928, 28685, 28200, 28312, 28154, 28200, 28154, 28053, - 27950, 27921, 27816, 6079, 5955, 6091, 5624, 5667, 5748, 13436, 13546, 13621, 13252, - 12738, 12971, 12338, 12270, 12392, 38121, 38103, 37976, 29221, 29049, 29117, 29117, 29049, - 29009, 27215, 27091, 27248, 27248, 27091, 27122, 30907, 30599, 30826, 28618, 28690, 28567, - 32359, 32454, 32301, 36420, 36424, 36414, 36428, 36424, 36519, 32311, 31839, 31955, 31236, - 31265, 31160, 31756, 31662, 31566, 32289, 32359, 32301, 37607, 38127, 38100, 5748, 5792, - 5731, 4670, 4830, 4761, 4751, 4869, 4729, 6784, 6796, 6886, 5701, 5955, 5765, - 10612, 10785, 10731, 11911, 11955, 12070, 11246, 11471, 11284, 12467, 12819, 12354, 12467, - 12713, 12819, 11246, 11284, 11161, 12495, 12738, 12744, 12392, 12270, 12227, 12467, 12354, - 12527, 28690, 28928, 28776, 30183, 30398, 30276, 31574, 31566, 31422, 29763, 29528, 29574, - 21587, 21725, 21749, 18042, 18159, 18205, 15764, 15788, 16118, 37760, 37819, 37540, 37916, - 37818, 37773, 5847, 5791, 5947, 13883, 13949, 13934, 13593, 13725, 13405, 27829, 27950, - 27816, 37919, 37481, 37187, 37283, 36952, 37276, 9760, 9866, 9630, 9557, 9600, 9683, - 32289, 32301, 32044, 6991, 6784, 6886, 7296, 7196, 7244, 7501, 7318, 7411, 34948, - 34870, 34847, 35034, 34870, 34948, 35202, 35091, 35196, 11771, 11716, 11712, 35905, 35883, - 35847, 35328, 35268, 35179, 36116, 36029, 36400, 13736, 13949, 13883, 36538, 36669, 36433, - 36654, 36669, 36538, 6796, 6656, 6761, 11603, 11771, 11712, 21749, 21725, 21905, 21749, - 21905, 21944, 29574, 29528, 29411, 32087, 32289, 32044, 31574, 31422, 31580, 8163, 8040, - 8214, 8092, 8225, 8109, 9630, 9866, 9793, 32087, 32044, 32142, 14293, 14381, 14308, - 15153, 15317, 15121, 23964, 23780, 23994, 22837, 22824, 22810, 23964, 23994, 24070, 27319, - 27204, 27217, 25867, 25738, 25734, 5219, 5167, 5220, 5247, 5275, 5360, 5247, 5360, - 5286, 5247, 5286, 5200, 37485, 37333, 37339, 37164, 37178, 36927, 37510, 37339, 37459, - 25157, 25271, 25124, 24609, 24819, 24318, 24211, 24318, 24102, 12544, 12392, 12638, 15018, - 15121, 14894, 15694, 15848, 15796, 26237, 26302, 26369, 27981, 28053, 27950, 26198, 26302, - 26237, 26475, 26302, 26348, 37607, 37931, 38127, 37931, 37975, 38127, 15745, 15848, 15694, - 23720, 23856, 23750, 23720, 23750, 23555, 24660, 24370, 24477, 25709, 25738, 25867, 5688, - 5679, 5798, 5579, 5688, 5543, 31839, 31265, 31236, 11471, 11514, 11586, 10736, 10913, - 10693, 10736, 10693, 10572, 5362, 5352, 5451, 9557, 9492, 9437, 11161, 11198, 11089, - 14821, 15018, 14894, 17171, 17164, 16963, 16752, 16963, 16765, 21944, 21905, 21998, 37309, - 37178, 37164, 36519, 36420, 36702, 38127, 37975, 38082, 9853, 10066, 10105, 31879, 31869, - 31868, 31756, 31574, 31737, 4670, 4761, 4638, 4614, 4543, 4759, 10572, 10693, 10501, - 37973, 37842, 37944, 37973, 37944, 37920, 37973, 37920, 38020, 12173, 12050, 12227, 35905, - 35847, 35920, 37612, 37455, 37665, 4729, 4869, 4852, 4638, 4761, 4698, 4827, 4852, - 4889, 4676, 4752, 4767, 4643, 4767, 4699, 11771, 11854, 12025, 11305, 11514, 11471, - 23266, 23034, 22969, 22425, 22245, 22396, 35865, 35587, 35456, 8092, 8040, 8163, 31879, - 31868, 31863, 5616, 5514, 5743, 5415, 5514, 5616, 5731, 5792, 5852, 14228, 14231, - 14093, 14535, 14613, 14835, 13130, 13173, 13333, 13762, 13736, 13883, 13949, 14058, 14093, - 13084, 13173, 13130, 13130, 13073, 12918, 13073, 12713, 12918, 28435, 28618, 28567, 28690, - 28970, 28928, 29517, 29411, 29076, 28628, 28618, 28435, 5791, 5731, 5852, 5955, 5946, - 6069, 5701, 5946, 5955, 6318, 6401, 6385, 5850, 5914, 5895, 5850, 5895, 5821, - 12495, 12544, 12738, 12738, 12544, 12638, 12270, 12173, 12227, 13621, 13546, 14237, 25551, - 25566, 25681, 27981, 27950, 27829, 27981, 28200, 28053, 36424, 36428, 36310, 36058, 35905, - 35920, 36962, 36718, 36983, 37818, 37819, 37760, 37985, 37819, 37818, 16740, 16752, 16530, - 33099, 33398, 33246, 33393, 33702, 33533, 32979, 33151, 33099, 32657, 32636, 33068, 32615, - 32502, 32498, 32615, 32498, 32454, 32615, 32454, 32462, 32454, 32359, 32462, 4638, 4698, - 4617, 4381, 4543, 4349, 9096, 9073, 9140, 8225, 8092, 8277, 9033, 9073, 9096, - 9244, 9356, 9343, 9244, 9343, 9359, 9529, 9505, 9430, 7737, 7946, 7163, 9507, - 9672, 9814, 9777, 9736, 9853, 9853, 9710, 10066, 22835, 22824, 22837, 22835, 22837, - 23031, 21979, 21476, 21415, 31265, 31114, 31160, 31289, 31114, 31265, 5946, 5847, 5947, - 5760, 5850, 5821, 9082, 9157, 9407, 14604, 14598, 15366, 13564, 13593, 13405, 27816, - 27334, 27688, 32658, 32717, 32511, 31283, 31092, 31114, 34696, 34377, 34517, 25097, 25124, - 24951, 25097, 24951, 24819, 6656, 6557, 6790, 6329, 6557, 6656, 6329, 6656, 6398, - 11959, 12070, 12050, 11959, 11911, 12070, 11261, 11330, 11360, 11780, 11854, 11771, 19300, - 19400, 19225, 16752, 17171, 16963, 29421, 29300, 29510, 30188, 30525, 30468, 37819, 37742, - 37540, 37677, 37733, 37683, 37728, 37733, 37677, 4479, 4543, 4303, 21714, 21979, 21415, - 38082, 37975, 38005, 13214, 13252, 13319, 29421, 29510, 29594, 5200, 5286, 5158, 5153, - 5167, 5219, 5171, 5036, 5290, 4817, 4827, 4889, 5286, 5377, 5158, 16309, 16796, - 17161, 18285, 18042, 18205, 18285, 18393, 18500, 23415, 23519, 23491, 23856, 23863, 24102, - 23505, 23519, 23415, 33461, 33398, 33099, 34923, 34729, 34728, 38036, 37773, 37318, 5153, - 5219, 5275, 15848, 16005, 15958, 15633, 15745, 15694, 15633, 15450, 15353, 26302, 26475, - 26405, 26198, 26158, 26009, 35502, 35268, 35520, 5775, 5731, 5791, 5609, 5735, 5679, - 5679, 5735, 5825, 9430, 9505, 9437, 32761, 32717, 32658, 14343, 14381, 14293, 14343, - 14501, 14381, 15197, 15633, 15353, 25734, 25757, 26027, 28494, 27916, 28506, 11246, 11344, - 11471, 11514, 11603, 11712, 11161, 11344, 11246, 11161, 11089, 11033, 10736, 10830, 10913, - 10572, 10830, 10736, 35202, 35107, 35091, 34810, 34696, 34914, 34923, 34699, 34729, 36041, - 36237, 36147, 33852, 33987, 34406, 19225, 19400, 19379, 18317, 19173, 19226, 6417, 6533, - 6577, 19014, 18590, 19314, 22284, 22179, 22189, 23031, 22837, 23309, 22812, 22836, 22791, - 22797, 22836, 22812, 38106, 37891, 37950, 38020, 37744, 37791, 32717, 32638, 32511, 32366, - 32359, 32289, 5514, 5362, 5451, 5415, 5362, 5514, 5415, 5616, 5067, 25709, 25551, - 25681, 25709, 25681, 25738, 37511, 37510, 37459, 37013, 37020, 37190, 37621, 37510, 37511, - 4889, 5016, 4806, 4617, 4698, 4757, 4567, 4764, 4993, 5100, 5252, 5325, 31863, - 31868, 31756, 32283, 32366, 32289, 31863, 31756, 31737, 13856, 14058, 13949, 10066, 10176, - 10105, 10211, 10176, 10066, 11911, 11660, 11955, 10612, 10530, 10782, 11723, 11660, 11911, - 11668, 11603, 11514, 12527, 12713, 12467, 19741, 19282, 19562, 19407, 19300, 19305, 22284, - 22372, 22512, 11261, 11360, 11447, 18042, 17943, 17832, 18034, 17943, 18042, 31114, 31092, - 31034, 30969, 31092, 31074, 33787, 33626, 34051, 6557, 6417, 6577, 12338, 12173, 12270, - 29594, 29510, 29599, 29736, 29599, 29720, 35938, 35865, 35456, 35257, 35202, 35268, 36058, - 35920, 36116, 24690, 24875, 24995, 23247, 23273, 23535, 38073, 38020, 38077, 37709, 37591, - 37456, 4543, 4614, 4349, 4617, 4757, 4561, 18545, 18537, 18500, 18602, 18537, 18545, - 9359, 9430, 9372, 9372, 9430, 9413, 14877, 14604, 15366, 15788, 15366, 15871, 14551, - 14613, 14535, 14551, 14535, 14501, 37190, 37020, 37005, 37005, 37178, 37190, 22512, 22810, - 22824, 38106, 37950, 38045, 5543, 5688, 5571, 14109, 14228, 14093, 32283, 32289, 32087, - 31580, 31422, 31614, 11668, 11780, 11603, 10972, 11089, 10983, 10972, 10983, 10830, 30305, - 30398, 30183, 30305, 30183, 30031, 30305, 30031, 30172, 4806, 5016, 5045, 4827, 4729, - 4852, 5247, 5153, 5275, 4705, 4609, 4621, 5250, 5377, 5352, 24330, 24199, 24370, - 26475, 26834, 26563, 26009, 26158, 25943, 32283, 32087, 32193, 35268, 35202, 35196, 35107, - 35034, 34948, 35257, 35268, 35502, 11953, 11959, 12050, 15745, 15859, 15848, 15153, 15121, - 15018, 28970, 29076, 28928, 7498, 8023, 7851, 7318, 7196, 7296, 6164, 6318, 6417, - 13173, 13345, 13405, 13593, 13736, 13762, 14058, 14109, 14093, 12527, 12354, 12157, 17943, - 17863, 17832, 17817, 17863, 17943, 20635, 20343, 20057, 20777, 20675, 20635, 20857, 20675, - 20777, 20857, 20984, 21127, 20857, 21127, 21004, 21127, 21364, 21309, 21364, 21356, 21309, - 21356, 21201, 21309, 23519, 23720, 23555, 23536, 23720, 23519, 37899, 37916, 37773, 37819, - 37955, 37742, 38014, 37916, 37899, 20675, 20546, 20635, 38053, 38175, 38010, 38142, 38168, - 38121, 38121, 38240, 38103, 38696, 38036, 37318, 38258, 38175, 38053, 38053, 38041, 38187, - 38041, 38146, 38187, 38146, 38165, 38187, 38295, 38165, 38146, 13224, 13345, 13173, 4558, - 4490, 4658, 4428, 4462, 4560, 4560, 4462, 4611, 4559, 4699, 4689, 4377, 4490, - 4558, 4428, 4560, 4536, 4614, 4356, 4349, 4646, 4757, 4751, 4559, 4831, 4675, - 4752, 4567, 4993, 14796, 15153, 15018, 20546, 20463, 20635, 21529, 21365, 21356, 20543, - 20874, 20547, 20543, 20547, 20351, 19884, 19856, 20142, 28935, 28723, 28738, 28935, 28738, - 29049, 37276, 36952, 36923, 37481, 37709, 37456, 38265, 38157, 38142, 11551, 11578, 11660, - 11551, 11494, 11578, 4462, 4477, 4611, 20463, 20343, 20635, 38157, 38168, 38142, 13447, - 13564, 13405, 25352, 24690, 24995, 27119, 27061, 27091, 36116, 35920, 36029, 36702, 36422, - 36527, 7155, 7196, 7318, 9430, 9437, 9413, 10731, 10785, 10981, 20142, 19856, 20144, - 31092, 30969, 30826, 31289, 31265, 31839, 35028, 35034, 35225, 38085, 38176, 38047, 28973, - 28935, 29049, 35781, 35350, 35356, 36669, 36763, 36674, 32193, 32087, 32203, 14613, 14821, - 14894, 14338, 14343, 14293, 14338, 14293, 14228, 19407, 19577, 19400, 26140, 26009, 25900, - 25080, 25097, 24819, 33702, 33626, 33533, 37013, 36962, 36983, 38322, 38280, 38176, 24351, - 24330, 24370, 25352, 25383, 25551, 5731, 5428, 5748, 5197, 5247, 5200, 5847, 5775, - 5791, 5701, 5775, 5847, 5701, 5847, 5946, 6161, 6340, 6318, 5735, 5760, 5821, - 5850, 5864, 5914, 5648, 5760, 5735, 13540, 13736, 13593, 14712, 14821, 14613, 36790, - 36702, 36527, 36585, 36654, 36167, 38176, 38280, 38295, 21979, 22396, 22245, 23139, 23266, - 22969, 22654, 22396, 22523, 12119, 12194, 11854, 11780, 11771, 11603, 11838, 11723, 11911, - 11305, 11471, 11344, 21905, 22189, 21998, 20874, 21264, 20797, 29421, 29342, 29117, 30283, - 29847, 30188, 18537, 18285, 18500, 18390, 18285, 18537, 37485, 37326, 37333, 37020, 37013, - 36983, 37665, 37455, 37521, 37665, 37521, 37742, 37840, 37683, 37733, 38172, 38106, 38045, - 8109, 8225, 8185, 7851, 8023, 8214, 9561, 9672, 9354, 32203, 32087, 32142, 4693, - 4729, 4827, 5111, 5171, 5167, 23309, 23780, 23535, 24351, 24370, 24660, 31283, 31390, - 31308, 36654, 36763, 36669, 12173, 11953, 12050, 11634, 11707, 11723, 12544, 12338, 12392, - 12495, 12338, 12544, 12173, 12338, 12113, 29344, 29342, 29533, 22788, 22512, 22824, 21998, - 22189, 22179, 22868, 22824, 22835, 38085, 38322, 38176, 38172, 38045, 37973, 11764, 11876, - 11780, 10531, 10972, 10830, 10462, 10501, 10211, 30398, 30634, 30439, 32266, 32283, 32193, - 30737, 30634, 30493, 35121, 35299, 35073, 35150, 35299, 35121, 35404, 35299, 35495, 38192, - 38127, 38082, 31737, 31580, 31720, 11167, 11261, 11291, 11494, 11261, 11447, 30468, 30821, - 30640, 30468, 30525, 30599, 30172, 30000, 29763, 14343, 14551, 14501, 14588, 14551, 14343, - 36962, 36945, 36436, 37326, 37162, 37333, 5197, 5153, 5247, 5197, 5200, 5158, 9672, - 9736, 9777, 26198, 26348, 26302, 25943, 25803, 25859, 26338, 26348, 26198, 37626, 37339, - 37510, 9073, 8960, 9140, 9033, 8960, 9073, 9096, 9232, 9156, 33151, 33461, 33099, - 33398, 33702, 33393, 33068, 32636, 32631, 33068, 32631, 32615, 32462, 32359, 32366, 32462, - 32366, 32367, 4643, 4676, 4767, 4522, 4676, 4643, 5579, 5609, 5679, 5543, 5609, - 5579, 5543, 5272, 5423, 9156, 9232, 9179, 14037, 14109, 14058, 24118, 23964, 24172, - 23139, 22969, 22836, 25080, 25157, 25097, 38307, 37358, 38103, 37955, 37665, 37742, 25097, - 25157, 25124, 23863, 23856, 23720, 37985, 37818, 37916, 37316, 37164, 37326, 5113, 5111, - 5167, 11707, 11551, 11660, 11707, 11660, 11723, 17713, 17687, 17744, 15765, 15859, 15745, - 16752, 16740, 17171, 15765, 15745, 15633, 15197, 15353, 15153, 15197, 15153, 15048, 9179, - 9244, 9202, 9179, 9232, 9244, 11876, 11854, 11780, 11876, 12119, 11854, 37316, 37309, - 37164, 37283, 37346, 37187, 37350, 37276, 37244, 4693, 4827, 4817, 23769, 23863, 23720, - 9359, 9410, 9430, 32638, 32709, 31955, 32717, 32764, 32638, 32826, 32761, 32658, 32858, - 32761, 32826, 23247, 23031, 23273, 24389, 24351, 24660, 24328, 24351, 24389, 4543, 4479, - 4989, 4436, 4670, 4638, 4436, 4638, 4617, 4297, 4494, 4687, 10211, 10501, 10176, - 5050, 5036, 5171, 4705, 4693, 4817, 13736, 13856, 13949, 13564, 13540, 13593, 13345, - 13447, 13405, 13084, 13224, 13173, 12926, 13224, 13084, 12918, 12713, 12675, 28618, 28636, - 28690, 29989, 30172, 29763, 28200, 28628, 28435, 28636, 28628, 28470, 28106, 28200, 27981, - 36237, 36401, 36147, 36654, 36752, 36763, 36585, 36401, 36596, 5252, 5487, 5325, 14187, - 14338, 14228, 14588, 14712, 14613, 14187, 14228, 14109, 37189, 36945, 36962, 36899, 36945, - 37068, 4505, 4559, 4401, 5311, 5415, 5067, 14796, 14712, 14793, 37301, 37190, 37178, - 4729, 4646, 4751, 5746, 5864, 5850, 5914, 5839, 6747, 5746, 5850, 5760, 5746, - 5760, 5648, 13360, 13447, 13345, 28935, 28737, 28723, 27215, 27378, 27319, 28973, 28737, - 28935, 9557, 9437, 9505, 33639, 33702, 33398, 11305, 11344, 11161, 12119, 12157, 12261, - 29342, 29221, 29117, 29834, 29736, 29720, 29740, 29736, 29834, 35728, 35356, 35218, 11261, - 11058, 11330, 9630, 9492, 9557, 11167, 11058, 11261, 10972, 11033, 11089, 11101, 11033, - 10972, 30468, 30599, 30821, 30179, 29879, 29847, 35299, 35404, 35073, 35150, 35121, 34923, - 5736, 5746, 5648, 28768, 28970, 28690, 10378, 10530, 10612, 11101, 11305, 11161, 16530, - 16752, 16609, 19208, 19173, 18971, 21998, 22179, 22118, 22179, 22163, 22118, 30493, 30634, - 30398, 30634, 30737, 30656, 30316, 30289, 30516, 37728, 37840, 37733, 37903, 37709, 37890, - 22654, 22797, 22687, 23266, 23505, 23415, 22654, 22687, 22396, 5334, 5352, 5362, 5153, - 5113, 5167, 5111, 5050, 5171, 7501, 7155, 7318, 6329, 6417, 6557, 7851, 8214, - 8040, 9836, 10211, 10066, 10462, 10572, 10501, 35028, 34847, 34870, 35028, 34870, 35034, - 13720, 13856, 13736, 27688, 27334, 27419, 29344, 29221, 29342, 36702, 36802, 36519, 36116, - 36400, 36241, 36899, 36790, 36527, 37843, 37840, 37728, 14796, 15018, 14821, 15859, 16005, - 15848, 27215, 27217, 27091, 27308, 27795, 27505, 10364, 10572, 10462, 15620, 15765, 15633, - 22179, 22284, 22163, 25654, 25352, 25551, 25757, 26794, 26573, 31283, 31074, 31092, 31283, - 31114, 31289, 32367, 32366, 32283, 32367, 32283, 32266, 35225, 35034, 35107, 35013, 35028, - 35225, 17863, 17817, 17744, 18285, 18034, 18042, 18351, 18034, 18285, 23360, 23505, 23266, - 23863, 24211, 24102, 38036, 38014, 37899, 38065, 38014, 38036, 11291, 11261, 11494, 11838, - 11911, 11959, 11935, 12157, 12119, 11413, 11668, 11514, 30179, 29847, 30283, 29736, 29594, - 29599, 5311, 5334, 5362, 5311, 5362, 5415, 37309, 37301, 37178, 37189, 36962, 37013, - 36865, 36802, 36790, 37325, 37301, 37309, 37621, 37511, 37612, 11954, 12119, 11876, 27419, - 27334, 27050, 35905, 36069, 35883, 36294, 36428, 36682, 15889, 16005, 15859, 19300, 19407, - 19400, 17605, 18001, 17769, 22163, 22284, 22304, 37626, 37621, 37859, 37626, 37859, 37729, - 7982, 7851, 8040, 8412, 8455, 8711, 18749, 18602, 18545, 19014, 19314, 19282, 23031, - 22868, 22835, 23031, 23309, 23273, 22797, 22847, 22836, 22864, 22847, 22797, 32044, 31879, - 32142, 34696, 33971, 34377, 4531, 4561, 4646, 4705, 4817, 4806, 11058, 10731, 10981, - 11291, 11494, 11551, 30379, 30418, 30640, 30468, 30418, 30283, 30493, 30398, 30305, 31580, - 31737, 31574, 34406, 34858, 34728, 34733, 34858, 34406, 19173, 19208, 19249, 22109, 22158, - 22156, 23505, 23536, 23519, 23565, 23536, 23505, 37709, 37843, 37728, 38077, 38020, 37791, - 37940, 37843, 37903, 11572, 11291, 11551, 11973, 11953, 12173, 13353, 13319, 13436, 13353, - 13436, 13453, 11764, 11954, 11876, 29740, 29834, 29879, 29740, 29594, 29736, 25654, 25551, - 25709, 4559, 4565, 4699, 4676, 4568, 4752, 4505, 4565, 4559, 31862, 31737, 31720, - 12675, 12713, 12635, 13360, 13540, 13447, 13447, 13540, 13564, 12431, 12527, 12157, 17466, - 17605, 17769, 28628, 28636, 28618, 30316, 30172, 30289, 28470, 28628, 28200, 28106, 27981, - 27829, 38106, 38192, 38082, 38386, 38192, 38106, 38073, 37973, 38020, 13503, 13436, 13621, - 13621, 14237, 13697, 5197, 5113, 5153, 4816, 4806, 5045, 4966, 5113, 4919, 15765, - 15889, 15859, 15197, 15620, 15633, 32142, 31879, 31998, 4531, 4646, 4523, 4883, 5045, - 5036, 13697, 14237, 13850, 13360, 13345, 13224, 13856, 14037, 14058, 14588, 14613, 14551, - 14712, 14796, 14821, 15741, 15765, 15620, 23981, 24211, 23863, 28225, 28106, 27829, 37301, - 37329, 37190, 37492, 37316, 37326, 37276, 37346, 37283, 37350, 37346, 37276, 37276, 36923, - 37244, 18034, 17817, 17943, 17971, 17817, 18034, 4477, 4297, 4687, 4401, 4559, 4675, - 4462, 4362, 4477, 4490, 4428, 4536, 4345, 4428, 4490, 20755, 20591, 20675, 20675, - 20591, 20546, 20546, 20415, 20463, 20463, 20415, 20343, 20343, 20218, 20057, 20755, 20675, - 20807, 20675, 20857, 20807, 20857, 21004, 20807, 21201, 21004, 21127, 21201, 21127, 21309, - 21356, 21364, 21587, 38175, 38265, 38010, 38157, 38427, 38168, 38168, 38240, 38121, 38394, - 38265, 38389, 38258, 38053, 38153, 38258, 38153, 38330, 38153, 38187, 38330, 38187, 38165, - 38330, 4966, 5050, 5111, 6164, 6161, 6318, 5067, 5616, 5180, 6784, 6991, 6854, - 12144, 12431, 12157, 11668, 11764, 11780, 11682, 11764, 11668, 11682, 11668, 11413, 11101, - 11161, 11033, 12744, 12738, 13252, 16497, 16530, 16609, 15884, 15889, 15765, 18602, 18390, - 18537, 18403, 18390, 18602, 20285, 20543, 20351, 20874, 21057, 21264, 22523, 22396, 22315, - 20274, 20543, 20285, 20274, 20285, 20142, 20274, 20142, 20144, 19856, 20185, 20144, 21356, - 21587, 21529, 21991, 22118, 22109, 24328, 24172, 24330, 24328, 24330, 24351, 25768, 25654, - 25709, 25768, 25709, 25867, 29891, 29740, 29879, 37621, 37626, 37510, 37485, 37626, 37729, - 20591, 20415, 20546, 20543, 20915, 20874, 33063, 33183, 33151, 33425, 33068, 33135, 33068, - 32615, 33135, 32373, 32462, 32367, 13850, 14237, 13889, 13540, 13720, 13736, 36790, 36802, - 36702, 36865, 36790, 36899, 36951, 36752, 36981, 36889, 36752, 36883, 38295, 38146, 38176, - 32761, 32764, 32717, 33041, 32955, 32860, 5250, 5158, 5377, 5428, 5731, 5472, 14588, - 14343, 14290, 17466, 17293, 17507, 16497, 16609, 16005, 24897, 25080, 24819, 25157, 25287, - 25271, 26199, 26338, 26198, 20415, 20269, 20343, 19856, 20163, 20185, 21944, 21971, 21749, - 32203, 32266, 32193, 31998, 31879, 31863, 32955, 32858, 32826, 20269, 20218, 20343, 19249, - 19407, 19305, 38396, 38240, 38168, 10636, 10731, 10615, 11572, 11551, 11707, 11838, 11959, - 11953, 12495, 12304, 12338, 27204, 27119, 27217, 29221, 28973, 29049, 29533, 29342, 29421, - 29533, 29421, 29594, 30418, 30308, 30283, 30379, 30308, 30418, 30172, 30316, 30305, 31862, - 31863, 31737, 29517, 29076, 29335, 36058, 36069, 35905, 36682, 36428, 36519, 11055, 11058, - 11167, 18839, 18994, 18813, 21944, 21998, 21971, 32858, 32764, 32761, 35898, 35937, 35781, - 35303, 35150, 34923, 38240, 38249, 38103, 38249, 38271, 38103, 18390, 18351, 18285, 18403, - 18351, 18390, 22847, 23139, 22836, 23769, 23981, 23863, 23119, 23139, 22847, 37998, 37683, - 37840, 24389, 24660, 24479, 24660, 24692, 24479, 8418, 8412, 8711, 7982, 8040, 8092, - 8418, 8711, 8579, 8956, 8960, 9033, 8956, 9033, 9156, 8956, 9156, 8955, 9156, - 9042, 8955, 32764, 32709, 32638, 7982, 8092, 8109, 14187, 14343, 14338, 21971, 21998, - 21991, 21998, 22118, 21991, 27217, 27119, 27091, 28506, 28723, 28494, 32039, 31998, 31863, - 32208, 32266, 32203, 31580, 31614, 31720, 38085, 38100, 38322, 29495, 29533, 29594, 29890, - 29594, 29740, 29335, 29076, 28970, 36241, 36069, 36058, 35028, 35013, 34847, 34696, 34781, - 33971, 35257, 35107, 35202, 38100, 38259, 38293, 38322, 38100, 38293, 5250, 5352, 5334, - 4887, 4935, 4894, 26573, 26794, 26876, 25654, 25367, 25352, 26348, 26338, 26475, 27688, - 27785, 27829, 26140, 26198, 26009, 5158, 5250, 4955, 5311, 5250, 5334, 25866, 25768, - 25867, 37316, 37325, 37309, 37501, 37325, 37316, 37903, 37843, 37709, 36885, 37392, 37244, - 9372, 9247, 9359, 9793, 9433, 9492, 25080, 25153, 25157, 25005, 25153, 25080, 4646, - 4561, 4757, 4321, 4345, 4181, 4646, 4729, 4523, 23535, 23780, 23964, 22788, 22824, - 22868, 21308, 21415, 21264, 6854, 7244, 7196, 7155, 7501, 7203, 11115, 11055, 11167, - 11115, 11167, 11291, 11072, 11101, 10964, 10531, 10830, 10572, 13453, 13436, 13503, 13337, - 13214, 13353, 13353, 13214, 13319, 12495, 12422, 12304, 30373, 30493, 30305, 30373, 30305, - 30316, 38250, 37998, 37840, 37940, 37840, 37843, 38271, 38307, 38103, 38100, 38127, 38259, - 11973, 11838, 11953, 11973, 12173, 12113, 35781, 35995, 35568, 35654, 35218, 35404, 28636, - 28768, 28690, 29015, 28768, 28962, 35268, 35328, 35520, 24204, 24118, 24172, 24204, 24389, - 24479, 5746, 5736, 5864, 5864, 5839, 5914, 5648, 5735, 5637, 13660, 13503, 13697, - 13660, 13453, 13503, 8412, 8185, 8225, 9793, 9543, 9433, 4935, 5050, 4894, 5050, - 4935, 5036, 4599, 4729, 4693, 14588, 14793, 14712, 14796, 14826, 15153, 15741, 15884, - 15765, 14826, 14793, 14728, 30308, 30179, 30283, 30443, 30179, 30308, 34914, 34696, 34641, - 34914, 34641, 35013, 36904, 36674, 36763, 29376, 28973, 29221, 28883, 29007, 28872, 29221, - 29344, 29376, 28768, 28987, 28970, 38259, 38127, 38244, 5637, 5735, 5530, 4410, 4505, - 4369, 4510, 4568, 4435, 19014, 18749, 18590, 18647, 18749, 18839, 22654, 22660, 22797, - 22655, 22660, 22654, 38219, 38172, 37973, 38219, 37973, 38198, 4377, 4772, 4479, 4621, - 4693, 4705, 38739, 38065, 38036, 38090, 37985, 37916, 10311, 9898, 10530, 38244, 38127, - 38192, 12518, 12422, 12495, 12144, 12157, 11935, 13266, 13360, 13224, 13683, 13856, 13720, - 11935, 11954, 11764, 32208, 32203, 32142, 31422, 31185, 31614, 11737, 11634, 11723, 11737, - 11723, 11838, 11413, 11514, 11305, 13889, 14237, 14604, 30136, 29891, 29879, 36815, 36682, - 36519, 36032, 35883, 36069, 36899, 36527, 36945, 36752, 36889, 36763, 36883, 36752, 36951, - 24777, 24897, 24819, 25803, 25440, 25569, 24609, 24318, 24367, 23720, 23536, 23769, 23565, - 23505, 23360, 38090, 37916, 38014, 22788, 22868, 23036, 27416, 27419, 27050, 25287, 25157, - 25153, 37626, 37485, 37339, 37189, 37013, 37273, 37492, 37485, 37645, 25169, 25287, 25153, - 26876, 26794, 27061, 28494, 28723, 28842, 7968, 7982, 8109, 6854, 7155, 6601, 11935, - 12119, 11954, 18749, 18654, 18602, 18351, 18021, 18034, 18647, 18654, 18749, 23036, 22868, - 23031, 23268, 23031, 23247, 32208, 32142, 31998, 15788, 15764, 15366, 16309, 16562, 16796, - 17565, 17687, 17161, 25569, 25440, 25271, 34810, 34781, 34696, 34939, 35100, 34961, 18243, - 18021, 18351, 13683, 14037, 13856, 13629, 13720, 13540, 37329, 37301, 37325, 5437, 5223, - 4984, 5530, 5735, 5609, 4984, 5035, 4562, 30070, 29890, 29891, 30640, 30418, 30468, - 30826, 30969, 30907, 30516, 30373, 30316, 31614, 31185, 31529, 29763, 29574, 29989, 37501, - 37329, 37325, 31916, 32039, 31863, 30697, 30737, 31154, 25308, 25569, 25271, 12113, 12338, - 12304, 11558, 11935, 11764, 33068, 33183, 33063, 34739, 34733, 34406, 33425, 33183, 33068, - 35937, 35995, 35781, 36318, 35995, 35937, 22660, 22864, 22797, 22765, 22864, 22660, 38386, - 38244, 38192, 38198, 37973, 38073, 9372, 9347, 9247, 9202, 9359, 9247, 9202, 9244, - 9359, 8166, 8057, 8185, 8185, 8057, 8109, 24204, 24172, 24328, 24204, 24328, 24389, - 23981, 24087, 24211, 24170, 24087, 23981, 4822, 4816, 5045, 14136, 14187, 14109, 24897, - 25005, 25080, 25287, 25308, 25271, 24798, 25005, 24897, 26834, 26475, 26338, 29015, 28941, - 28768, 5749, 5864, 5736, 5749, 5839, 5864, 5749, 5736, 5649, 28842, 28723, 28737, - 28883, 28737, 28973, 4522, 4643, 4565, 18021, 17971, 18034, 18048, 17971, 18021, 24118, - 23535, 23964, 23280, 23266, 23139, 31199, 31283, 31308, 32764, 32862, 32709, 32858, 32859, - 32764, 33041, 32859, 32858, 33041, 32858, 32955, 33041, 32860, 33971, 19173, 19249, 19305, - 17293, 17171, 17269, 24367, 24318, 24211, 37709, 37990, 37890, 38236, 38198, 38281, 38291, - 38106, 38172, 5771, 5749, 5649, 12409, 12274, 12422, 12422, 12274, 12304, 13453, 13337, - 13353, 13373, 13337, 13453, 12527, 12431, 12635, 12713, 12527, 12635, 12926, 13084, 12918, - 14037, 14136, 14109, 32311, 31955, 32709, 36815, 36802, 36970, 36815, 36519, 36802, 4935, - 4883, 5036, 4887, 4883, 4935, 5111, 5113, 4966, 17713, 17744, 17817, 25380, 25308, - 25287, 31916, 31863, 31862, 31154, 30737, 31001, 34406, 33987, 34302, 34858, 35133, 34923, - 35495, 35654, 35404, 12220, 12431, 12144, 29495, 29344, 29533, 28987, 29137, 28970, 28768, - 28941, 28987, 28768, 28636, 28962, 9372, 9413, 9347, 4505, 4504, 4565, 4410, 4504, - 4505, 38219, 38291, 38172, 38077, 37791, 37998, 28494, 28092, 27916, 11634, 11572, 11707, - 11826, 11737, 11838, 11826, 11838, 11973, 26140, 26199, 26198, 26065, 26199, 26140, 25900, - 26009, 25859, 25900, 25859, 25912, 29015, 29137, 28987, 25739, 25859, 25569, 9347, 9413, - 9437, 17269, 17171, 17174, 25899, 25866, 25867, 24660, 24690, 24692, 26876, 27061, 27119, - 26876, 27119, 27078, 30907, 30969, 31119, 30136, 29879, 30179, 29887, 29495, 29594, 35245, - 35225, 35107, 35520, 35328, 35710, 35456, 35883, 35938, 4609, 4705, 4806, 25716, 25654, - 25768, 23434, 23247, 23535, 27378, 27215, 27308, 31189, 30969, 31074, 36889, 36904, 36763, - 36585, 36167, 36401, 37273, 37013, 37190, 36899, 36970, 36865, 35728, 35654, 36114, 7163, - 7946, 6321, 9354, 9507, 9157, 9354, 9672, 9507, 9672, 9561, 9736, 15889, 15884, - 16005, 16530, 16697, 16740, 15135, 15620, 15197, 14826, 14796, 14793, 31916, 31862, 31720, - 32266, 32373, 32367, 4568, 4567, 4752, 4510, 4567, 4568, 9276, 9347, 9350, 9347, - 9437, 9433, 10636, 10612, 10731, 12744, 13252, 12807, 12064, 12220, 12144, 35995, 36225, - 35635, 36202, 36225, 35995, 38065, 38090, 38014, 37501, 37492, 37654, 38278, 38090, 38065, - 38250, 38077, 37998, 14566, 14793, 14588, 27078, 27119, 27204, 26492, 26834, 26338, 4504, - 4522, 4565, 4410, 4522, 4504, 18470, 18403, 18602, 18470, 18602, 18654, 22864, 23119, - 22847, 23057, 23119, 22864, 4377, 4479, 4251, 4428, 4362, 4462, 38265, 38427, 38157, - 38240, 38396, 38249, 38249, 38416, 38271, 38271, 38416, 38307, 38389, 38265, 38175, 38389, - 38175, 38258, 38389, 38258, 38457, 38165, 38462, 38330, 38295, 38462, 38165, 38280, 38387, - 38295, 38322, 38387, 38280, 38322, 38328, 38387, 4345, 4362, 4428, 20269, 20280, 20218, - 20218, 19963, 20057, 20415, 20280, 20269, 20591, 20562, 20415, 20688, 20562, 20591, 20688, - 20591, 20755, 20688, 20755, 20807, 20688, 20807, 20789, 21158, 21004, 21201, 21365, 21201, - 21356, 20274, 20514, 20543, 20543, 20713, 20915, 20915, 20982, 20874, 20275, 20514, 20274, - 20275, 20274, 20144, 20275, 20144, 20185, 34939, 34781, 34810, 34939, 34810, 34914, 38394, - 38427, 38265, 38307, 38606, 37349, 7203, 7498, 7297, 13850, 13660, 13697, 13966, 13889, - 14061, 20861, 20982, 20915, 25380, 25578, 25308, 24609, 24777, 24819, 24478, 24777, 24609, - 24798, 24777, 24734, 23769, 23536, 23565, 27419, 27785, 27688, 27561, 27785, 27419, 31283, - 31189, 31074, 31199, 31189, 31283, 30841, 30737, 30493, 31702, 31916, 31720, 11737, 11572, - 11634, 10989, 10731, 11058, 11826, 11572, 11737, 36032, 36069, 36097, 20386, 20280, 20415, - 19577, 19856, 19884, 20982, 21057, 20874, 38322, 38293, 38328, 12274, 12113, 12304, 19577, - 19407, 19856, 29890, 29740, 29891, 38427, 38396, 38168, 31702, 31720, 31614, 32208, 32373, - 32266, 35495, 35299, 35150, 34051, 33626, 33702, 14290, 14566, 14588, 14224, 14343, 14187, - 27209, 27204, 27319, 27209, 27078, 27204, 4597, 4609, 4806, 4386, 4523, 4729, 4599, - 4609, 4600, 7982, 7922, 7851, 8265, 8185, 8412, 33919, 34051, 33702, 20096, 20049, - 20218, 21057, 21308, 21264, 23652, 23769, 23565, 38396, 38416, 38249, 13993, 14136, 14037, - 37176, 37068, 36945, 35502, 35351, 35257, 35710, 35328, 35587, 4335, 4356, 4695, 4523, - 4561, 4531, 20049, 19963, 20218, 21529, 21587, 21749, 21529, 21749, 21713, 26199, 26347, - 26338, 26229, 26347, 26199, 26065, 26140, 25900, 25739, 25569, 25578, 30443, 30308, 30379, - 30907, 30821, 30599, 30917, 30821, 30907, 30804, 30841, 30493, 30804, 30493, 30516, 35494, - 35351, 35502, 4984, 5223, 5035, 5637, 5736, 5648, 35224, 34914, 35013, 33038, 33041, - 33111, 22487, 22523, 22315, 23119, 23280, 23139, 36241, 36058, 36116, 35865, 35710, 35587, - 8057, 7968, 8109, 14826, 15048, 15153, 14930, 15048, 14826, 32208, 31998, 32082, 36487, - 36401, 36237, 38328, 38293, 38358, 38293, 38259, 38358, 5772, 6084, 6747, 5749, 5771, - 5839, 5609, 5473, 5530, 13337, 13223, 13214, 11951, 11826, 12113, 13141, 13223, 13337, - 35874, 35710, 35865, 35654, 35728, 35218, 36225, 36487, 36237, 35133, 34858, 34998, 4562, - 5098, 4764, 25912, 25739, 25927, 28883, 28842, 28737, 28494, 28352, 28092, 27505, 27378, - 27308, 28872, 28842, 28883, 24777, 24798, 24897, 24367, 24211, 24170, 35245, 35107, 35257, - 37940, 38250, 37840, 37890, 38212, 38029, 37187, 37346, 37919, 16412, 16497, 16005, 16697, - 16610, 16748, 13360, 13452, 13540, 13266, 13452, 13360, 12832, 12918, 12675, 22118, 22163, - 22109, 21713, 21749, 21971, 12355, 12635, 12431, 18403, 18243, 18351, 17778, 17713, 17817, - 18419, 18243, 18403, 23057, 23280, 23119, 27308, 27599, 27795, 26942, 27416, 27050, 26942, - 27050, 26834, 17778, 17817, 17971, 26492, 26942, 26834, 5609, 5543, 5473, 9736, 9665, - 9853, 10211, 10364, 10462, 9354, 9084, 9227, 13781, 13850, 13889, 13781, 13660, 13850, - 13452, 13629, 13540, 17174, 17171, 16740, 24170, 24211, 24087, 24170, 23981, 23913, 38358, - 38259, 38473, 4883, 4822, 5045, 5113, 5197, 4919, 29495, 29470, 29344, 30532, 30379, - 30640, 36032, 35938, 35883, 5473, 5543, 5423, 13966, 13781, 13889, 32082, 31998, 32039, - 31694, 31702, 31614, 31238, 31185, 31154, 34482, 34739, 34406, 34549, 34739, 34482, 36883, - 36904, 36889, 37244, 37424, 37350, 36951, 36904, 36883, 8348, 8265, 8412, 7989, 7922, - 7968, 9042, 9156, 9179, 9042, 9179, 9202, 9042, 9202, 9151, 18243, 18119, 18021, - 18191, 18119, 18243, 22523, 22655, 22654, 22594, 22655, 22523, 23280, 23360, 23266, 23324, - 23360, 23280, 32859, 32862, 32764, 32859, 33041, 33038, 33183, 33461, 33151, 34051, 34302, - 33987, 33425, 33461, 33183, 38236, 38291, 38219, 38236, 38219, 38198, 38198, 38073, 38281, - 36032, 36094, 35938, 36400, 36029, 36226, 36782, 36226, 36682, 36318, 36202, 35995, 9561, - 9665, 9736, 33818, 33639, 33461, 32082, 32039, 32003, 34229, 34302, 34051, 11572, 11115, - 11291, 11063, 10936, 10877, 38488, 38358, 38473, 9276, 9247, 9347, 9151, 9202, 9247, - 27302, 27209, 27319, 27078, 27095, 26876, 25865, 25899, 26026, 27228, 27209, 27302, 37903, - 37986, 37940, 37424, 37346, 37350, 10989, 11058, 11055, 35502, 35543, 35494, 35225, 35245, - 35231, 35359, 35245, 35351, 35351, 35245, 35257, 35225, 35226, 35013, 37485, 37492, 37326, - 37273, 37176, 37189, 37189, 37176, 36945, 37955, 37819, 38098, 4814, 4822, 4883, 33038, - 32862, 32859, 33461, 33639, 33398, 4919, 5197, 4955, 4833, 4814, 4883, 5197, 5158, - 4955, 25899, 25867, 26027, 25899, 26027, 26026, 5543, 5571, 5272, 17269, 17507, 17293, - 16748, 17174, 16740, 23434, 23535, 23606, 22163, 22158, 22109, 24692, 24690, 25184, 38098, - 37819, 37985, 11558, 11997, 11935, 11935, 11997, 12144, 12220, 12355, 12431, 11177, 11413, - 11305, 11072, 11305, 11101, 11889, 11997, 11558, 15048, 15135, 15197, 14728, 14930, 14826, - 14728, 14793, 14566, 14224, 14187, 14136, 18603, 18647, 18700, 22655, 22765, 22660, 22594, - 22765, 22655, 32862, 32759, 32709, 36241, 36097, 36069, 35502, 35520, 35688, 37420, 37424, - 37244, 32003, 32039, 31916, 32615, 32462, 33135, 4599, 4693, 4621, 4599, 4621, 4609, - 18119, 18048, 18021, 18099, 18048, 18119, 10504, 10378, 10612, 10138, 10364, 10211, 31176, - 30917, 30907, 30821, 30775, 30640, 31283, 31289, 31390, 31125, 31238, 31154, 31702, 32003, - 31916, 34998, 34858, 34733, 22109, 22156, 22052, 4899, 4894, 5050, 8813, 8960, 8956, - 7968, 7922, 7982, 9433, 9437, 9492, 5349, 5423, 5326, 14051, 14224, 14136, 26858, - 26573, 26876, 27795, 27599, 28092, 37273, 37190, 37448, 36970, 36802, 36865, 37392, 36885, - 36674, 4435, 4568, 4676, 4567, 4455, 4764, 4401, 4675, 4304, 38291, 38386, 38106, - 38281, 38073, 38316, 4657, 4670, 4335, 8265, 8166, 8185, 12807, 13214, 13141, 12807, - 13252, 13214, 10989, 11063, 10877, 13214, 13223, 13141, 17266, 17507, 17269, 23268, 23247, - 23434, 38256, 38098, 37985, 38256, 37985, 38090, 11063, 10989, 11055, 10636, 10504, 10612, - 11063, 11055, 11115, 16497, 16697, 16530, 17174, 17266, 17269, 16697, 16497, 16610, 34739, - 34998, 34733, 34302, 34549, 34482, 34409, 34549, 34302, 31119, 30969, 31189, 12744, 12518, - 12495, 36970, 36899, 37155, 36186, 36145, 36097, 4427, 4676, 4522, 4833, 4883, 4887, - 4600, 4609, 4597, 4436, 4617, 4437, 31238, 31529, 31185, 4437, 4617, 4561, 4966, - 4899, 5050, 4894, 4833, 4887, 4955, 5250, 4971, 12832, 12675, 12607, 13514, 13629, - 13452, 13514, 13683, 13629, 13629, 13683, 13720, 15079, 15135, 15048, 15079, 15048, 14930, - 18647, 18470, 18654, 18603, 18470, 18647, 25354, 24690, 25352, 27095, 27078, 27209, 25739, - 25912, 25859, 26347, 26492, 26338, 26065, 25912, 25927, 25569, 25308, 25578, 29137, 29335, - 28970, 30841, 31001, 30737, 29237, 29335, 29137, 29015, 28987, 28941, 28200, 28106, 28470, - 31199, 31119, 31189, 31308, 31119, 31199, 35231, 35226, 35225, 34989, 33971, 34781, 35520, - 35710, 35688, 37156, 36899, 37068, 37176, 37161, 37068, 37508, 37190, 37329, 9543, 9793, - 9898, 4335, 4695, 4657, 19208, 19209, 19249, 19075, 19209, 19208, 35728, 35898, 35781, - 36415, 35898, 36388, 4730, 4816, 4822, 4370, 4437, 4561, 24367, 24478, 24609, 23913, - 23981, 23769, 23652, 23565, 23587, 4815, 4899, 4966, 37381, 37420, 37244, 38141, 38029, - 38212, 37440, 37420, 37381, 13781, 13646, 13660, 14061, 13889, 14604, 13842, 13966, 13887, - 29698, 29470, 29495, 28825, 28352, 28494, 29541, 29470, 29698, 4510, 4499, 4567, 4390, - 4499, 4510, 23587, 23565, 23360, 4436, 4335, 4670, 4352, 4437, 4370, 4709, 4822, - 4814, 4709, 4730, 4822, 18470, 18419, 18403, 18483, 18419, 18470, 22971, 23057, 22864, - 22971, 22864, 22765, 38316, 38073, 38323, 38492, 38386, 38291, 7989, 7968, 8057, 4345, - 4321, 4362, 4362, 4260, 4477, 4181, 4345, 4490, 4216, 4321, 4181, 4303, 4543, - 4381, 4303, 4381, 4185, 20564, 20632, 20514, 20514, 20632, 20543, 20982, 20990, 21057, - 21057, 21014, 21308, 22194, 22396, 21979, 20564, 20514, 20411, 20514, 20275, 20411, 21276, - 21201, 21365, 20789, 20807, 21004, 20562, 20386, 20415, 20280, 20096, 20218, 20049, 19938, - 19963, 19963, 19920, 19562, 21276, 21365, 21353, 21365, 21529, 21353, 20632, 20713, 20543, - 35447, 35495, 35150, 35133, 34998, 35750, 38427, 38565, 38396, 38396, 38507, 38416, 38590, - 38479, 38307, 38394, 38481, 38427, 38389, 38481, 38394, 38457, 38481, 38389, 38457, 38258, - 38330, 38457, 38330, 38589, 38295, 38452, 38462, 4321, 4260, 4362, 20411, 20275, 20387, - 20713, 20792, 20915, 25716, 25768, 25866, 23535, 24118, 23947, 38029, 37986, 37903, 38029, - 37903, 37890, 38559, 38571, 38452, 38295, 38387, 38452, 20387, 20275, 20163, 20792, 20861, - 20915, 30516, 30493, 30373, 31692, 31694, 31529, 35688, 35710, 35922, 35303, 34923, 35133, - 10615, 10504, 10636, 11826, 11973, 12113, 30775, 30532, 30640, 30775, 30821, 30889, 29989, - 29574, 29517, 35874, 35865, 36070, 20668, 20386, 20562, 20163, 20275, 20185, 4815, 4833, - 4894, 27228, 27095, 27209, 27319, 27378, 27302, 36904, 37392, 36674, 5423, 5349, 5473, - 5473, 5375, 5530, 5641, 5736, 5637, 5641, 5649, 5736, 5375, 5349, 5326, 5571, - 5157, 5272, 10378, 10311, 10530, 10615, 10731, 10989, 12204, 12113, 12274, 19856, 19407, - 19249, 27416, 27561, 27419, 27584, 27561, 27416, 27584, 27416, 27399, 34961, 34781, 34939, - 35359, 35231, 35245, 35584, 35303, 35133, 36097, 36145, 36032, 36094, 36145, 36186, 37257, - 37161, 37176, 30443, 30136, 30179, 36042, 35865, 35938, 20200, 20096, 20280, 38569, 38507, - 38396, 38387, 38328, 38512, 4613, 4806, 4816, 4370, 4561, 4523, 8924, 8813, 8956, - 8265, 8064, 8166, 8166, 8064, 8057, 8924, 8956, 8955, 8924, 8955, 8995, 8955, - 9042, 8995, 17915, 17778, 17971, 17713, 17438, 17687, 14061, 14328, 14007, 17915, 17971, - 18048, 38492, 38291, 38236, 38323, 38073, 38077, 12744, 12545, 12518, 12518, 12409, 12422, - 13373, 13453, 13660, 12607, 12675, 12635, 12355, 12220, 12064, 5765, 5955, 6079, 6079, - 6196, 5837, 6656, 6796, 6398, 5771, 5689, 5839, 5641, 5484, 5564, 8995, 9042, - 8891, 12926, 13266, 13224, 21353, 21529, 21382, 25912, 26065, 25900, 25153, 25005, 25090, - 28825, 28494, 28842, 36815, 36782, 36682, 37146, 36782, 36815, 37146, 36815, 36970, 38512, - 38328, 38358, 8810, 8801, 8726, 12606, 12545, 12744, 29335, 29357, 29517, 28470, 28106, - 28225, 36558, 36487, 36225, 36981, 36752, 36654, 36904, 37059, 37392, 36596, 36487, 36558, - 37492, 37501, 37316, 37257, 37156, 37161, 37645, 37485, 37729, 20096, 19938, 20049, 21713, - 21971, 21811, 4304, 4675, 4138, 4343, 4427, 4522, 8579, 8711, 8960, 10390, 10311, - 10378, 22194, 21979, 21714, 25865, 25716, 25866, 25865, 25866, 25899, 31542, 31529, 31238, - 31529, 31694, 31614, 32251, 32373, 32208, 4058, 4297, 4477, 4730, 4613, 4816, 4623, - 4613, 4730, 6398, 6796, 6434, 6854, 7196, 7155, 14224, 14290, 14343, 14051, 14290, - 14224, 13993, 14037, 13683, 19938, 19920, 19963, 12545, 12409, 12518, 12531, 12355, 12166, - 29015, 29237, 29137, 13694, 13646, 13781, 32759, 32311, 32709, 32862, 32871, 32759, 32916, - 32871, 32862, 35224, 35013, 35226, 36981, 36654, 36585, 4343, 4522, 4315, 18419, 18191, - 18243, 18329, 18191, 18419, 24118, 24204, 24256, 21811, 21971, 21991, 23057, 23324, 23280, - 23652, 23913, 23769, 23203, 23324, 23057, 38432, 38236, 38281, 38346, 38323, 38353, 30889, - 30821, 30917, 30532, 30443, 30379, 30889, 30917, 31037, 17778, 17675, 17713, 17797, 17675, - 17778, 23825, 23913, 23652, 24170, 24375, 24367, 30551, 30443, 30532, 29541, 29376, 29470, - 4401, 4359, 4505, 4294, 4359, 4401, 4386, 4729, 4599, 4542, 4597, 4806, 10504, - 10390, 10378, 10564, 10615, 10408, 10615, 10989, 10816, 17169, 17266, 17174, 17507, 17605, - 17466, 16748, 16740, 16697, 22487, 22594, 22523, 22548, 22594, 22487, 24271, 24375, 24170, - 30910, 31001, 30841, 30910, 30841, 30804, 30910, 30804, 30802, 35494, 35359, 35351, 35370, - 35224, 35226, 35543, 35359, 35494, 35543, 35502, 35688, 38432, 38281, 38316, 11063, 11115, - 10936, 12409, 12204, 12274, 29470, 29376, 29344, 30070, 29891, 30136, 29306, 29357, 29335, - 38590, 38307, 38416, 38488, 38512, 38358, 13966, 13842, 13781, 14061, 14007, 13887, 9665, - 9710, 9853, 9629, 9710, 9665, 9629, 9665, 9561, 33639, 33919, 33702, 35594, 34998, - 34739, 34130, 33919, 34188, 32251, 32208, 32082, 21811, 21991, 22052, 14290, 14494, 14566, - 16412, 16005, 15884, 14341, 14494, 14290, 27302, 27378, 27415, 26026, 26027, 26453, 30324, - 30070, 30136, 10564, 10390, 10504, 9350, 9347, 9433, 35370, 35226, 35231, 4427, 4435, - 4676, 4371, 4562, 4764, 4343, 4435, 4427, 23324, 23331, 23360, 23203, 23331, 23324, - 4352, 4335, 4436, 4320, 4381, 4349, 4352, 4436, 4437, 6329, 6164, 6417, 12204, - 11951, 12113, 37621, 37612, 37859, 37612, 37665, 37859, 7203, 7501, 7498, 8111, 8064, - 8265, 9354, 8835, 9084, 5349, 5375, 5473, 5100, 5325, 5019, 14604, 14328, 14061, - 16412, 16249, 16331, 37161, 37156, 37068, 37155, 37156, 37246, 37176, 37359, 37257, 38346, - 38316, 38323, 37547, 37346, 37424, 22052, 21991, 22109, 38473, 38259, 38244, 4684, 4709, - 4814, 4613, 4542, 4806, 4684, 4814, 4833, 4815, 4894, 4899, 15741, 15620, 15548, - 15548, 15620, 15135, 17478, 17507, 17433, 17478, 17605, 17507, 25367, 25354, 25352, 27037, - 26876, 27095, 5013, 5100, 4990, 5100, 5019, 4803, 31845, 32003, 31702, 31845, 31702, - 31694, 37420, 37547, 37424, 37559, 37547, 37420, 37440, 37381, 37392, 17066, 17169, 17174, - 24375, 24478, 24367, 24511, 24478, 24375, 24168, 24170, 23913, 4320, 4349, 4356, 8064, - 7989, 8057, 4359, 4369, 4505, 4290, 4369, 4359, 5472, 5731, 5775, 5837, 6196, - 6161, 5689, 5786, 5839, 5689, 5771, 5649, 12832, 12926, 12918, 13410, 13514, 13452, - 12806, 12926, 12832, 31276, 31542, 31238, 30802, 30804, 30516, 35495, 36114, 35654, 36558, - 36225, 36202, 35303, 35447, 35150, 35584, 35447, 35303, 35584, 35133, 35750, 13373, 13141, - 13337, 12807, 12606, 12744, 12545, 12606, 12409, 12409, 12129, 12204, 12204, 11943, 11951, - 13373, 13660, 13646, 13694, 13781, 13842, 28225, 27829, 27785, 29257, 29306, 29237, 29237, - 29306, 29335, 36145, 36094, 36032, 35666, 35543, 35688, 36186, 36097, 36264, 5899, 5837, - 6161, 22163, 22304, 22158, 24256, 24204, 24479, 24610, 24479, 24692, 25090, 25005, 24798, - 26065, 26088, 26199, 29007, 28883, 28973, 27415, 27378, 27505, 29007, 28973, 29398, 31125, - 31154, 31001, 35100, 34939, 34914, 22512, 22304, 22284, 27142, 27037, 27095, 27142, 27095, - 27228, 37447, 37440, 37392, 38586, 38473, 38611, 11101, 10926, 10964, 12064, 11997, 11889, - 12064, 12144, 11997, 12355, 12531, 12635, 34130, 34229, 34051, 31276, 31125, 31293, 13410, - 13452, 13266, 36951, 37059, 36904, 36770, 36981, 36585, 18971, 19173, 18317, 17433, 17507, - 17266, 18839, 18749, 19014, 18099, 17915, 18048, 22512, 22788, 22304, 29694, 29989, 29517, - 29257, 29237, 29015, 36264, 36400, 36467, 36462, 36400, 36226, 25367, 25654, 25716, 29544, - 29517, 29357, 36070, 36042, 36221, 36094, 36042, 35938, 35090, 35100, 35431, 35224, 35100, - 34914, 4464, 4599, 4600, 4471, 4542, 4613, 13887, 13694, 13842, 17332, 17433, 17266, - 16997, 17066, 17174, 16997, 17174, 16748, 24743, 24610, 24692, 37194, 37059, 36951, 18099, - 18119, 18191, 16118, 15788, 16309, 23331, 23587, 23360, 23512, 23587, 23331, 38739, 38278, - 38065, 38098, 38223, 37955, 5157, 5571, 5252, 5641, 5689, 5649, 27795, 28092, 28462, - 4284, 4320, 4356, 4284, 4356, 4186, 22304, 22788, 22700, 22161, 22194, 21714, 23002, - 22971, 22765, 25726, 25927, 25739, 27561, 27746, 27785, 37859, 37665, 38350, 37605, 37508, - 37501, 6321, 7946, 6960, 7737, 7624, 9031, 35361, 35231, 35359, 33111, 33041, 33971, - 5772, 6747, 5839, 29887, 29594, 29890, 29387, 29544, 29357, 4464, 4600, 4597, 18603, - 18483, 18470, 18612, 18483, 18603, 23002, 22765, 22890, 33661, 33425, 33772, 33919, 34130, - 34051, 32104, 32251, 32082, 31692, 31845, 31694, 31692, 31529, 31631, 8418, 8348, 8412, - 8064, 7899, 7989, 8813, 8579, 8960, 8679, 8579, 8813, 8810, 8813, 8924, 8810, - 8924, 8801, 9247, 9276, 9151, 9151, 9098, 9074, 35922, 35710, 35874, 11101, 10697, - 10926, 26940, 26858, 26876, 25705, 25367, 25716, 26940, 26876, 27037, 5472, 5775, 5701, - 4919, 4815, 4966, 14061, 13887, 13966, 17438, 17713, 17675, 13814, 13993, 13683, 15343, - 15548, 15135, 27690, 27795, 28462, 37156, 37155, 36899, 37176, 37273, 37359, 32104, 32082, - 32003, 34229, 34409, 34302, 34470, 34409, 34229, 4632, 4623, 4730, 4666, 4815, 4919, - 4186, 4356, 4335, 17644, 17438, 17675, 18971, 18317, 17605, 17332, 17266, 17191, 23036, - 23031, 23268, 22194, 22267, 22396, 24993, 25090, 24798, 25578, 25665, 25739, 23992, 24168, - 23913, 7498, 7851, 7525, 6329, 6158, 6164, 9350, 9433, 9340, 10615, 10564, 10504, - 10816, 10989, 10877, 32871, 32855, 32759, 34979, 34781, 34961, 35461, 35361, 35359, 8410, - 8348, 8418, 7525, 7851, 7739, 33038, 32916, 32862, 6434, 6796, 6784, 5747, 5765, - 5837, 36264, 36097, 36241, 36042, 36070, 35865, 4632, 4730, 4709, 16412, 16610, 16497, - 17191, 17266, 17169, 16331, 16610, 16412, 24993, 24798, 24847, 23022, 23036, 23219, 22997, - 23036, 23022, 38346, 38432, 38316, 38611, 38473, 38244, 38126, 37940, 37986, 4455, 4567, - 4499, 4455, 4499, 4390, 16873, 16997, 16748, 24809, 24743, 24692, 24543, 24256, 24479, - 38029, 38126, 37986, 38141, 38126, 38029, 5266, 5326, 5423, 5013, 5157, 5252, 5165, - 5157, 5057, 27191, 27228, 27302, 27191, 27142, 27228, 37405, 37447, 37392, 37559, 37581, - 37547, 37547, 37581, 37346, 9898, 10311, 10024, 19185, 19856, 19249, 18971, 17605, 17710, - 22267, 22315, 22396, 32916, 32855, 32871, 4260, 4058, 4477, 4213, 4304, 4138, 4321, - 4216, 4260, 4181, 4490, 4168, 4490, 4377, 4168, 4479, 4245, 4251, 5266, 5423, - 5272, 20688, 20668, 20562, 20386, 20241, 20280, 20096, 19935, 19938, 19938, 19935, 19920, - 19920, 19741, 19562, 20789, 20668, 20688, 20789, 21004, 21158, 21201, 21276, 21158, 21276, - 21322, 21158, 21353, 21322, 21276, 21382, 21322, 21353, 21382, 21529, 21740, 21529, 21713, - 21740, 20861, 20990, 20982, 22194, 22161, 22267, 22267, 22288, 22315, 20792, 20829, 20861, - 20713, 20829, 20792, 20632, 20654, 20713, 20564, 20654, 20632, 20550, 20654, 20564, 20550, - 20564, 20411, 20550, 20411, 20476, 20411, 20387, 20476, 27399, 27416, 26942, 37508, 37329, - 37501, 38481, 38540, 38427, 38507, 38607, 38416, 38457, 38594, 38481, 38647, 38594, 38457, - 38589, 38330, 38462, 38589, 38462, 38682, 38462, 38452, 38571, 38387, 38559, 38452, 4479, - 4303, 4245, 9710, 9722, 10066, 9566, 9629, 9561, 20476, 20387, 20163, 21740, 21713, - 21811, 20654, 20829, 20713, 4815, 4684, 4833, 20444, 20476, 20163, 25354, 25184, 24690, - 25924, 25716, 25865, 25169, 25380, 25287, 31390, 31289, 32302, 30551, 30136, 30443, 30027, - 29887, 30070, 30070, 29887, 29890, 31631, 31529, 31542, 32229, 32104, 32145, 38705, 38540, - 38481, 38479, 38606, 38307, 5765, 5650, 5701, 5586, 5650, 5765, 5747, 5691, 5586, - 5786, 5772, 5839, 5637, 5530, 5336, 5899, 6161, 6164, 5696, 5772, 5786, 12926, - 13129, 13266, 13514, 13657, 13683, 12680, 12806, 12832, 12607, 12635, 12531, 20668, 20340, - 20386, 20829, 20990, 20861, 28872, 28825, 28842, 28967, 28825, 28872, 36487, 36596, 36401, - 36981, 37194, 36951, 36770, 36596, 36716, 38540, 38565, 38427, 38387, 38525, 38559, 5323, - 5530, 5375, 20340, 20241, 20386, 20990, 21014, 21057, 12759, 12606, 12807, 11115, 11064, - 10936, 12759, 12807, 12855, 12807, 13141, 12855, 12279, 12607, 12531, 29398, 28973, 29376, - 20241, 20200, 20280, 38565, 38569, 38396, 4315, 4522, 4410, 4675, 4494, 4138, 4469, - 4464, 4597, 4469, 4597, 4480, 13129, 13410, 13266, 17621, 17605, 17478, 17191, 17169, - 17066, 19185, 19249, 19209, 17621, 17478, 17473, 22315, 22407, 22487, 22387, 22407, 22315, - 24543, 24479, 24610, 24168, 24271, 24170, 24163, 24271, 24168, 23825, 23652, 23587, 23825, - 23587, 23696, 29541, 29398, 29376, 30691, 30532, 30775, 38232, 38223, 38098, 16249, 16412, - 15773, 15079, 14930, 14984, 26453, 26027, 26573, 26453, 26573, 26516, 21849, 21740, 21811, - 17915, 17797, 17778, 17755, 17797, 17915, 23203, 23057, 22971, 4185, 4320, 4139, 4289, - 4370, 4214, 14728, 14566, 14494, 14728, 14494, 14444, 23002, 23203, 22971, 29306, 29387, - 29357, 29544, 29694, 29517, 29080, 29257, 29015, 29080, 29015, 28962, 37533, 37420, 37440, - 38513, 38492, 38236, 38387, 38512, 38525, 38353, 38323, 38077, 9629, 9722, 9710, 21912, - 21849, 21811, 31957, 32003, 31845, 33661, 33461, 33425, 38641, 38685, 38525, 5326, 5339, - 5375, 5165, 5266, 5272, 11072, 11177, 11305, 11068, 11177, 11072, 27690, 27415, 27505, - 27099, 26940, 27037, 27690, 27505, 27795, 5489, 5472, 5701, 4971, 5250, 5021, 13410, - 13657, 13514, 37648, 37492, 37645, 38284, 37665, 37955, 19996, 19935, 20096, 22052, 21912, - 21811, 38644, 38607, 38507, 38512, 38488, 38550, 4304, 4294, 4401, 4213, 4294, 4304, - 4480, 4597, 4542, 4626, 4632, 4709, 7851, 7922, 7739, 12216, 12129, 12409, 24993, - 25169, 25090, 25090, 25169, 25153, 29617, 29398, 29541, 29283, 29387, 29306, 31692, 31957, - 31845, 31651, 31631, 31542, 31276, 31238, 31125, 31125, 31001, 31293, 31001, 31120, 31293, - 35090, 34961, 35100, 35090, 34979, 34961, 14051, 14136, 13993, 17072, 17191, 17066, 16914, - 16873, 16748, 16914, 16748, 16561, 27099, 27037, 27142, 37648, 37645, 37782, 19935, 19923, - 19920, 38607, 38590, 38416, 38550, 38488, 38527, 30602, 30516, 30409, 13657, 13814, 13683, - 4315, 4410, 4369, 6398, 6294, 6329, 6434, 6294, 6398, 6434, 6784, 6375, 36221, - 36042, 36094, 35370, 35231, 35361, 35431, 35100, 35224, 16182, 16118, 16309, 17161, 17687, - 17438, 19146, 19209, 19075, 25398, 25501, 25380, 25380, 25501, 25578, 25927, 26088, 26065, - 4350, 4510, 4435, 7899, 7922, 7989, 17797, 17644, 17675, 17755, 17644, 17797, 18099, - 18191, 18329, 38278, 38256, 38090, 38377, 38256, 38278, 4289, 4308, 4370, 4584, 4613, - 4623, 7796, 7899, 8064, 36186, 36289, 36094, 36400, 36264, 36241, 36462, 36226, 36782, - 36462, 36591, 36467, 18839, 19014, 18994, 4245, 4303, 4206, 4303, 4185, 4206, 19923, - 19741, 19920, 27099, 27191, 27234, 27255, 27191, 27302, 37257, 37246, 37156, 37508, 37448, - 37190, 5156, 5339, 5326, 13887, 13964, 13694, 15169, 15366, 15764, 13775, 14051, 13993, - 28549, 28092, 28352, 35370, 35361, 35461, 33122, 33111, 33224, 5616, 5624, 5180, 4626, - 4709, 4684, 4541, 4623, 4632, 12279, 12680, 12607, 10531, 10572, 10364, 22052, 21980, - 21912, 22156, 21980, 22052, 25983, 26088, 25927, 26716, 26858, 26893, 26716, 26573, 26858, - 26026, 25924, 25865, 30937, 30876, 30943, 31176, 30907, 31119, 37782, 37645, 37806, 37508, - 37515, 37448, 4343, 4350, 4435, 4313, 4350, 4343, 18329, 18419, 18483, 38513, 38236, - 38432, 38613, 38353, 38077, 18839, 18720, 18647, 18734, 18720, 18839, 38513, 38432, 38556, - 4583, 4584, 4623, 4583, 4623, 4541, 38126, 38250, 37940, 37990, 37709, 37481, 6230, - 6158, 6329, 14728, 14984, 14930, 15079, 15062, 15135, 15062, 14984, 14915, 16412, 15884, - 15773, 16469, 16331, 16249, 26893, 26858, 26940, 4381, 4320, 4185, 6625, 6784, 6854, - 6294, 6230, 6329, 22156, 22158, 22181, 31330, 31119, 31308, 31218, 31176, 31119, 35461, - 35359, 35543, 36596, 36770, 36585, 37525, 37533, 37447, 36558, 36202, 36795, 38527, 38488, - 38473, 13609, 13775, 13814, 13814, 13775, 13993, 13609, 13814, 13657, 12897, 13129, 12926, - 12897, 12926, 12806, 12680, 12832, 12607, 17473, 17478, 17433, 17336, 17433, 17332, 17066, - 16997, 17072, 23825, 23992, 23913, 24734, 24777, 24478, 23842, 23992, 23825, 12606, 12216, - 12409, 13373, 13646, 13349, 11682, 11558, 11764, 4407, 4599, 4464, 4414, 4480, 4542, - 17152, 17161, 17438, 17561, 17438, 17644, 17332, 17191, 17235, 23036, 23268, 23219, 24757, - 24543, 24610, 24757, 24610, 24743, 25184, 25354, 25386, 13349, 13646, 13521, 29590, 29694, - 29544, 29257, 29283, 29306, 28962, 28636, 28470, 36318, 35937, 35898, 37448, 37359, 37273, - 37535, 37359, 37448, 4185, 4139, 4176, 8810, 8726, 8813, 8579, 8410, 8418, 8348, - 8276, 8265, 8801, 8924, 8995, 22181, 22304, 22281, 22181, 22158, 22304, 38586, 38527, - 38473, 4231, 4290, 4359, 4252, 4359, 4294, 8570, 8477, 8579, 8891, 9042, 8926, - 8891, 8801, 8995, 18720, 18700, 18647, 18734, 18700, 18720, 38054, 37990, 37481, 37447, - 37533, 37440, 37525, 37447, 37724, 8477, 8410, 8579, 8926, 9042, 9151, 23203, 23512, - 23331, 23529, 23512, 23543, 32302, 31289, 31839, 32916, 32969, 32855, 33038, 33035, 32916, - 34989, 34781, 34979, 29325, 29283, 29257, 37238, 36970, 37155, 36219, 35922, 36070, 6138, - 6230, 6294, 32311, 32759, 32915, 4308, 4335, 4352, 33111, 33035, 33038, 38611, 38244, - 38609, 8226, 8276, 8348, 7899, 7739, 7922, 33035, 32969, 32916, 6434, 6228, 6294, - 6730, 6625, 6854, 6518, 6625, 6578, 11572, 11064, 11115, 10162, 10311, 10390, 11826, - 11951, 11943, 23992, 24068, 24168, 25593, 25665, 25501, 23842, 24068, 23992, 30602, 30802, - 30516, 31658, 31651, 31542, 30988, 30802, 30937, 35991, 35666, 35688, 35922, 35874, 36070, - 38605, 38250, 38126, 4584, 4471, 4613, 4626, 4684, 4616, 24734, 24478, 24511, 25983, - 26229, 26088, 4290, 4315, 4369, 4231, 4315, 4290, 11682, 11413, 11558, 38609, 38244, - 38386, 38499, 38432, 38346, 38499, 38346, 38353, 10964, 11068, 11072, 10939, 11068, 10964, - 38809, 38606, 38479, 38609, 38386, 38492, 4616, 4684, 4666, 5157, 5165, 5272, 5266, - 5156, 5326, 5013, 5252, 5100, 10138, 10531, 10364, 14051, 14341, 14290, 14428, 14341, - 13945, 26088, 26229, 26199, 25665, 25578, 25501, 35580, 35461, 35543, 35079, 34979, 35090, - 8276, 8111, 8265, 15331, 15169, 15764, 26110, 25924, 26026, 26716, 26516, 26573, 26689, - 26516, 26716, 27099, 27142, 27191, 26317, 26492, 26347, 27584, 27746, 27561, 37648, 37654, - 37492, 37782, 37654, 37648, 38223, 38201, 37955, 37815, 37645, 37729, 38238, 38201, 38223, - 38232, 38098, 38256, 23512, 23549, 23587, 23529, 23549, 23512, 26225, 26026, 26453, 9722, - 9744, 10066, 9629, 9675, 9722, 9566, 9675, 9629, 9566, 9561, 9388, 14007, 13964, - 13887, 13962, 13964, 14007, 27454, 27746, 27584, 37378, 37246, 37257, 37370, 37257, 37359, - 22997, 22788, 23036, 21613, 21415, 21308, 22890, 22765, 22594, 15169, 14877, 15366, 37533, - 37559, 37420, 37567, 37559, 37533, 11558, 11413, 11145, 29887, 29698, 29495, 29066, 28967, - 29007, 29007, 28967, 28872, 28825, 28967, 28352, 29986, 29698, 29887, 29590, 29544, 29387, - 35079, 34989, 34979, 35079, 35090, 35431, 36415, 36318, 35898, 36114, 35495, 36107, 4370, - 4308, 4352, 4407, 4464, 4469, 23268, 23434, 23219, 22548, 22487, 22407, 31390, 31330, - 31308, 30792, 30691, 30889, 30889, 30691, 30775, 31394, 31330, 31390, 25924, 25705, 25716, - 25398, 25380, 25169, 4441, 4407, 4469, 4441, 4469, 4480, 24068, 24163, 24168, 24226, - 24163, 24068, 33961, 33919, 33639, 35810, 35584, 35750, 33818, 33461, 33661, 38422, 38232, - 38256, 22700, 22281, 22304, 27234, 27191, 27255, 27302, 27415, 27255, 37600, 37515, 37508, - 37584, 37525, 37724, 4350, 4390, 4510, 4455, 4371, 4764, 4691, 5019, 4984, 4313, - 4390, 4350, 5689, 5696, 5786, 5772, 5672, 6084, 6084, 6321, 6960, 5641, 5602, - 5689, 5564, 5602, 5641, 5323, 5375, 5339, 5602, 5696, 5689, 9675, 9744, 9722, - 12759, 12603, 12606, 13061, 12855, 13141, 13061, 13141, 13131, 12935, 13061, 13013, 23549, - 23696, 23587, 23529, 23696, 23549, 37550, 37370, 37359, 12855, 12603, 12759, 6625, 6518, - 6784, 6730, 6854, 6601, 10162, 10390, 10208, 11943, 12204, 12129, 11145, 11413, 11177, - 10697, 11101, 10972, 10697, 10972, 10531, 25318, 25398, 25169, 24511, 24375, 24271, 31037, - 30917, 31176, 10390, 10564, 10408, 22114, 22181, 22281, 23947, 24118, 24256, 31118, 31037, - 31176, 4626, 4541, 4632, 4483, 4471, 4584, 4666, 4684, 4815, 25318, 25169, 25303, - 37919, 37346, 37581, 38141, 38162, 38126, 18971, 19146, 19075, 19027, 19146, 18971, 4181, - 4151, 4216, 4216, 4132, 4260, 4168, 4151, 4181, 4168, 4377, 4072, 4377, 4251, - 4143, 4251, 4092, 4143, 4151, 4132, 4216, 20668, 20645, 20340, 20340, 20237, 20241, - 20241, 20237, 20200, 20200, 19996, 20096, 19935, 19996, 19923, 19923, 19801, 19741, 19741, - 19499, 19282, 20696, 20645, 20668, 20696, 20668, 20789, 20696, 20789, 20818, 20696, 20818, - 20576, 21158, 20978, 20789, 21322, 21382, 21468, 21382, 21740, 21617, 21740, 21849, 21765, - 21849, 21912, 21765, 21765, 21912, 21980, 20829, 20979, 20990, 20990, 20979, 21014, 21014, - 21152, 21308, 20654, 20712, 20829, 20550, 20712, 20654, 20676, 20712, 20550, 20676, 20550, - 20444, 20550, 20476, 20444, 35431, 35224, 35370, 33179, 33122, 33224, 38594, 38705, 38481, - 38540, 38683, 38565, 38565, 38683, 38569, 38569, 38644, 38507, 38607, 38631, 38590, 38590, - 38754, 38479, 38647, 38705, 38594, 38647, 38457, 38589, 38647, 38589, 38734, 38462, 38571, - 38682, 38571, 38697, 38682, 38559, 38697, 38571, 38685, 38697, 38559, 38685, 38559, 38525, - 36289, 36186, 36264, 35580, 35443, 35461, 35461, 35443, 35370, 38641, 38525, 38512, 4251, - 4145, 4092, 20883, 20979, 20829, 27178, 27399, 26942, 26229, 26317, 26347, 26093, 26317, - 26229, 25983, 25927, 25726, 37732, 37605, 37501, 37815, 37729, 37948, 38735, 38683, 38540, - 20459, 20237, 20340, 20979, 21008, 21014, 25726, 25739, 25665, 31330, 31218, 31119, 31394, - 31218, 31330, 30988, 31001, 30910, 31950, 31957, 31692, 30988, 30910, 30802, 38550, 38641, - 38512, 14984, 15062, 15079, 14915, 14984, 14873, 26516, 26426, 26453, 25587, 25503, 25705, - 26661, 26689, 26812, 18901, 19027, 18971, 17235, 17336, 17332, 16914, 16997, 16873, 16469, - 16610, 16331, 24543, 24306, 24256, 24521, 24306, 24543, 24163, 24282, 24271, 24226, 24282, - 24163, 36462, 36467, 36400, 36591, 36462, 36600, 37146, 36970, 37238, 38683, 38681, 38569, - 4242, 4186, 4335, 4251, 4245, 4145, 4138, 4494, 4297, 4315, 4313, 4343, 14877, - 14328, 14604, 13131, 13141, 13373, 19146, 19185, 19209, 17710, 17605, 17621, 22340, 22387, - 22315, 23703, 23842, 23696, 22288, 22267, 22161, 27454, 27399, 27468, 17764, 17755, 17915, - 17161, 16896, 16309, 14491, 14877, 15169, 17764, 17915, 18013, 38967, 38377, 38278, 4246, - 4242, 4335, 4214, 4370, 4523, 23606, 23219, 23434, 22114, 22281, 22360, 38563, 38499, - 38353, 38566, 38609, 38492, 38556, 38499, 38563, 25755, 25726, 25665, 5265, 5323, 5339, - 4691, 4984, 4364, 20126, 19996, 20200, 17764, 17698, 17755, 37600, 37708, 37675, 37515, - 37523, 37448, 38681, 38644, 38569, 38550, 38726, 38641, 38527, 38726, 38550, 7796, 7739, - 7899, 7525, 7297, 7498, 4368, 4541, 4626, 15884, 15741, 15773, 25386, 25354, 25367, - 25503, 25367, 25705, 4483, 4584, 4583, 4407, 4386, 4599, 5156, 5266, 5165, 12048, - 11943, 12129, 13362, 13657, 13410, 14341, 14444, 14494, 13085, 13410, 13129, 12897, 12806, - 12680, 12897, 12680, 12733, 16561, 16748, 16610, 24920, 24809, 24692, 24734, 24847, 24798, - 25398, 25593, 25501, 24679, 24847, 24734, 29698, 29617, 29541, 29662, 29617, 29698, 30937, - 30802, 30602, 29519, 29590, 29387, 29519, 29387, 29283, 29325, 29257, 29080, 28962, 28470, - 28799, 36467, 36405, 36264, 38299, 38162, 38141, 38644, 38631, 38607, 38483, 38422, 38377, - 4245, 4105, 4145, 4246, 4335, 4308, 4213, 4219, 4294, 4135, 4219, 4213, 22387, - 22548, 22407, 22340, 22548, 22387, 10738, 10615, 10816, 10685, 10738, 10816, 10685, 10816, - 10877, 11145, 11177, 11068, 10406, 10697, 10531, 38527, 38586, 38726, 7198, 7297, 7525, - 30691, 30551, 30532, 30792, 30551, 30691, 30792, 30889, 31037, 32104, 32229, 32251, 31651, - 31692, 31631, 8748, 8726, 8801, 8748, 8679, 8726, 8726, 8679, 8813, 8477, 8404, - 8410, 8410, 8365, 8348, 8276, 8197, 8111, 8111, 8098, 8064, 8748, 8801, 8739, - 25933, 25705, 25924, 8739, 8801, 8891, 4360, 4386, 4407, 5276, 5624, 5428, 4754, - 4666, 4919, 4316, 4482, 4146, 5276, 5428, 5241, 5428, 5472, 5241, 5701, 5650, - 5494, 5765, 5747, 5586, 8439, 8404, 8477, 14428, 14444, 14341, 17473, 17609, 17621, - 17166, 17235, 17191, 17755, 17698, 17644, 18612, 18603, 18700, 23696, 23842, 23825, 24282, - 24511, 24271, 23512, 23203, 23202, 27099, 27003, 26940, 27255, 27415, 27690, 37370, 37378, - 37257, 37592, 37523, 37515, 38232, 38238, 38223, 37943, 37729, 37859, 38483, 38238, 38232, - 4206, 4105, 4245, 7163, 7624, 7737, 9675, 9663, 9744, 6220, 7624, 7163, 19996, - 19801, 19923, 21366, 21613, 21308, 38726, 38586, 38663, 10738, 10408, 10615, 35580, 35543, - 35666, 4219, 4252, 4294, 4142, 4252, 4219, 5747, 5837, 5691, 8404, 8365, 8410, - 8882, 8926, 9151, 22548, 22613, 22594, 22340, 22613, 22548, 32915, 32759, 32855, 33035, - 33179, 32969, 33111, 33122, 33035, 33111, 33341, 33224, 32462, 32701, 33135, 36381, 36289, - 36264, 35629, 35580, 35666, 37565, 37378, 37370, 38566, 38492, 38513, 4206, 4158, 4105, - 19801, 19719, 19741, 8365, 8226, 8348, 26549, 26426, 26516, 26549, 26516, 26689, 37732, - 37501, 37654, 37605, 37600, 37508, 37806, 37815, 37948, 5899, 6164, 5998, 6164, 6158, - 5998, 12362, 12216, 12606, 12855, 12804, 12603, 13061, 12935, 12855, 13131, 13373, 13193, - 12166, 12355, 12064, 11860, 12064, 11889, 5696, 5672, 5772, 5580, 5672, 5696, 5580, - 5696, 5602, 29066, 29007, 29189, 28799, 28470, 28699, 5484, 5641, 5637, 13646, 13694, - 13647, 13070, 13085, 13129, 5021, 5250, 5311, 15062, 15343, 15135, 14873, 14984, 14728, - 37559, 37697, 37581, 37699, 37697, 37559, 37567, 37533, 37525, 4206, 4185, 4158, 21980, - 22156, 22114, 22156, 22181, 22114, 21613, 21714, 21415, 33818, 33961, 33639, 34130, 34470, - 34229, 4364, 4984, 4562, 4056, 4313, 3867, 4482, 4483, 4583, 4414, 4441, 4480, - 4482, 4583, 4541, 10050, 10138, 10211, 9579, 9566, 9388, 25184, 24920, 24692, 24757, - 24521, 24543, 24306, 23947, 24256, 24809, 24920, 24830, 32966, 32855, 32969, 5494, 5489, - 5701, 13647, 13694, 13964, 13085, 13362, 13410, 14429, 14428, 13956, 4252, 4231, 4359, - 4082, 4231, 4252, 18813, 18734, 18839, 38628, 38566, 38513, 38663, 38586, 38611, 38556, - 38432, 38499, 5276, 5180, 5624, 5067, 5021, 5311, 5083, 5180, 5276, 5323, 5341, - 5530, 4963, 5156, 5165, 7739, 7405, 7525, 8197, 8098, 8111, 10939, 10964, 10926, - 17698, 17561, 17644, 17691, 17561, 17698, 17473, 17433, 17336, 24209, 23947, 24306, 27399, - 27454, 27584, 27468, 27399, 27178, 36322, 36221, 36094, 4158, 4185, 4176, 11064, 11572, - 11826, 12362, 12606, 12603, 29345, 29325, 29080, 30172, 29989, 30289, 4414, 4542, 4438, - 5489, 5425, 5472, 17072, 17166, 17191, 17410, 17473, 17336, 17072, 16997, 16914, 24757, - 24743, 24809, 24226, 24511, 24282, 25521, 25593, 25398, 37206, 37194, 36981, 37116, 36981, - 36770, 36716, 36596, 36558, 4939, 5021, 4915, 27234, 27003, 27099, 27057, 27003, 27234, - 37732, 37654, 37844, 37523, 37535, 37448, 37584, 37567, 37525, 10697, 10809, 10926, 10939, - 10809, 10620, 25169, 24993, 25072, 25828, 26093, 25983, 25983, 26093, 26229, 27178, 26942, - 26492, 6601, 7155, 7203, 6518, 6375, 6784, 33961, 34188, 33919, 35629, 35666, 35759, - 35443, 35547, 35370, 4320, 4284, 4139, 6435, 6375, 6518, 38663, 38611, 38781, 4139, - 4284, 4141, 4188, 4246, 4308, 4188, 4308, 4244, 4308, 4289, 4244, 9566, 9663, - 9675, 32145, 32104, 32003, 32145, 32003, 31957, 5998, 6158, 5965, 12216, 12048, 12129, - 29325, 29519, 29283, 5233, 5341, 5323, 31658, 31542, 31276, 31836, 31651, 31658, 4284, - 4186, 4141, 22788, 22997, 22700, 22997, 23022, 23108, 38738, 38611, 38609, 14643, 14873, - 14728, 14341, 14051, 13945, 27234, 27255, 27187, 37585, 37535, 37523, 4438, 4542, 4471, - 4368, 4626, 4616, 4270, 4360, 4318, 4341, 4407, 4441, 17229, 17336, 17235, 19053, - 19098, 19027, 37943, 37859, 38115, 38377, 38422, 38256, 38696, 37318, 38606, 26426, 26225, - 26453, 25150, 24920, 25184, 26365, 26225, 26426, 26549, 26689, 26661, 37815, 37806, 37645, - 37600, 37592, 37515, 37955, 38201, 38284, 5965, 6158, 6230, 11665, 11860, 11889, 11665, - 11889, 11558, 26365, 26549, 26274, 36289, 36322, 36094, 35991, 35688, 35922, 36405, 36381, - 36264, 36482, 36381, 36405, 36591, 36405, 36467, 37379, 37246, 37378, 4244, 4289, 4214, - 4141, 4186, 4028, 16469, 16561, 16610, 17166, 17229, 17235, 15773, 15741, 15548, 18734, - 18612, 18700, 18701, 18612, 18734, 22613, 22890, 22594, 24824, 24679, 24658, 23123, 22890, - 23118, 25072, 24993, 24847, 4186, 4242, 4028, 5156, 5265, 5339, 13928, 13962, 14007, - 13928, 14007, 14328, 13647, 13962, 13858, 23108, 23022, 23219, 32462, 32373, 32701, 31960, - 32145, 31957, 37428, 37379, 37378, 4438, 4471, 4483, 4292, 4455, 4390, 5013, 5057, - 5157, 5175, 5233, 5265, 16850, 17072, 16914, 26110, 25933, 25924, 38260, 38201, 38238, - 38421, 38260, 38238, 8098, 7796, 8064, 6495, 6653, 6502, 15037, 15343, 15062, 14643, - 14728, 14444, 23947, 23606, 23535, 23604, 23606, 23947, 23202, 23203, 23002, 3926, 4138, - 4297, 4227, 4288, 4313, 10738, 10510, 10408, 10084, 10024, 10162, 10811, 11064, 10664, - 10809, 10939, 10926, 10973, 10729, 10993, 6730, 6653, 6625, 6375, 6228, 6434, 6578, - 6653, 6495, 29989, 29752, 30289, 4754, 4919, 4955, 4799, 4955, 4971, 10162, 10024, - 10311, 8625, 8748, 8739, 10208, 10390, 10408, 5542, 5580, 5602, 5742, 6321, 6084, - 5542, 5602, 5564, 5484, 5637, 5398, 12935, 12804, 12855, 12216, 12130, 12048, 12959, - 12804, 12935, 13013, 13061, 13131, 13013, 13131, 13193, 18612, 18463, 18483, 18701, 18463, - 18612, 22890, 22963, 23002, 23123, 22963, 22890, 29040, 29345, 29080, 29645, 29590, 29519, - 28225, 27785, 27746, 36490, 36322, 36289, 38566, 38630, 38609, 38563, 38353, 38650, 13193, - 13373, 13349, 13569, 13609, 13657, 13085, 13208, 13362, 12897, 13070, 13129, 12733, 13070, - 12897, 5586, 5494, 5650, 5489, 5350, 5425, 5697, 5691, 5837, 5697, 5837, 5899, - 36859, 36716, 36558, 36859, 36558, 36795, 5336, 5530, 5341, 5541, 6084, 5672, 13350, - 13193, 13349, 13070, 13208, 13085, 37675, 37592, 37600, 37535, 37550, 37359, 37567, 37699, - 37559, 38242, 38212, 37990, 37990, 38212, 37890, 37405, 37392, 37059, 37213, 37059, 37194, - 32373, 32251, 32701, 31950, 31960, 31957, 31950, 31692, 31836, 12365, 12362, 12603, 10811, - 10877, 10936, 22224, 22288, 22161, 16477, 16561, 16469, 16477, 16469, 16249, 4313, 4288, - 4390, 4227, 4313, 4056, 28616, 28225, 28436, 37238, 37155, 37246, 36381, 36490, 36289, - 37238, 37246, 37379, 4270, 4299, 4360, 4316, 4438, 4483, 4414, 4438, 4358, 24830, - 24757, 24809, 24336, 24209, 24306, 25386, 25367, 25503, 24511, 24679, 24734, 24226, 24068, - 23842, 25587, 25386, 25503, 25318, 25375, 25398, 25593, 25755, 25665, 25303, 25375, 25318, - 4126, 4242, 4246, 4214, 4523, 4236, 4523, 4386, 4236, 8625, 8679, 8748, 8625, - 8570, 8679, 8679, 8570, 8579, 8404, 8345, 8365, 8365, 8345, 8226, 8226, 8197, - 8276, 7655, 7663, 7796, 8891, 8926, 8739, 8739, 8926, 8799, 8570, 8439, 8477, - 8882, 9151, 8983, 32251, 32229, 32385, 33818, 33969, 33961, 33961, 33969, 34188, 4126, - 4246, 4129, 14967, 15062, 14915, 19027, 19098, 19146, 19053, 19027, 18901, 22288, 22340, - 22315, 26225, 26110, 26026, 25684, 25587, 25705, 26549, 26365, 26426, 26689, 26716, 26812, - 5233, 5323, 5265, 5246, 5336, 5341, 13962, 13647, 13964, 13338, 13657, 13362, 14741, - 14967, 14873, 14873, 14967, 14915, 37229, 37238, 37396, 37206, 37213, 37194, 4168, 4026, - 4151, 4151, 4026, 4132, 4132, 4058, 4260, 4006, 4026, 4168, 4006, 4168, 4072, - 4377, 3938, 4072, 4143, 3938, 4377, 4092, 4087, 4143, 4145, 4087, 4092, 3976, - 4087, 4145, 3976, 4145, 4105, 8439, 8345, 8404, 20712, 20791, 20829, 20979, 21077, - 21008, 21008, 21100, 21014, 21613, 21527, 21714, 21714, 22123, 22161, 22288, 22303, 22340, - 20444, 20163, 19756, 38705, 38735, 38540, 38683, 38755, 38681, 38681, 38772, 38644, 38644, - 38837, 38631, 38917, 38696, 38606, 38647, 38758, 38705, 38734, 38758, 38647, 38734, 38589, - 38682, 38734, 38810, 38830, 38682, 38810, 38734, 38697, 38685, 38747, 38685, 38748, 38747, - 9836, 10066, 9744, 20237, 20126, 20200, 19996, 19837, 19801, 19801, 19837, 19719, 18318, - 18329, 18463, 20645, 20576, 20340, 20696, 20576, 20645, 20818, 20789, 20978, 21158, 21131, - 20978, 21740, 21765, 21617, 21617, 21765, 21876, 20676, 20791, 20712, 26893, 26940, 27003, - 37675, 37585, 37592, 37943, 37948, 37729, 38115, 37948, 37943, 4158, 4017, 4105, 20576, - 20459, 20340, 20791, 20883, 20829, 37585, 37550, 37535, 37585, 37523, 37592, 38801, 38735, - 38705, 4158, 4176, 4017, 9701, 9836, 9744, 32385, 32229, 32236, 31836, 31692, 31651, - 38735, 38755, 38683, 38685, 38641, 38748, 8983, 9151, 9074, 33122, 33179, 33035, 32993, - 33179, 33146, 32229, 32145, 32236, 4261, 4371, 4455, 10024, 9543, 9898, 32222, 32145, - 31960, 6653, 6578, 6625, 6435, 6578, 6495, 10811, 10685, 10877, 10811, 10664, 10715, - 30988, 31120, 31001, 29989, 29694, 29752, 21077, 21100, 21008, 4138, 4135, 4213, 4038, - 4135, 4138, 4288, 4292, 4390, 4225, 4292, 4288, 4803, 4990, 5100, 8345, 8197, - 8226, 9151, 9276, 9098, 15600, 15773, 15548, 18013, 17915, 18099, 17200, 17152, 17438, - 13928, 14328, 13975, 19098, 19185, 19146, 17710, 17621, 17609, 27057, 26893, 27003, 26812, - 26893, 27057, 35284, 34549, 34409, 33661, 33969, 33818, 37770, 37699, 37567, 37697, 37699, - 37817, 38754, 38590, 38631, 5246, 5233, 5145, 18463, 18329, 18483, 19014, 19282, 18994, - 22963, 23202, 23002, 24824, 24847, 24679, 23123, 23202, 22963, 38613, 38077, 38250, 38688, - 38630, 38566, 38748, 38641, 38794, 20147, 20126, 20237, 21100, 21152, 21014, 31082, 31120, - 30988, 34470, 34130, 34188, 38755, 38772, 38681, 9098, 9276, 9350, 17194, 17166, 17072, - 17194, 17229, 17166, 16527, 16477, 16430, 32993, 32966, 32969, 3611, 4058, 4132, 21152, - 21305, 21308, 29752, 29694, 29590, 29752, 29590, 29645, 29346, 29519, 29325, 9663, 9701, - 9744, 9566, 9579, 9663, 9227, 9561, 9354, 21305, 21366, 21308, 38641, 38726, 38794, - 4135, 4142, 4219, 4033, 4142, 4135, 9121, 9098, 9350, 4990, 5057, 5013, 25375, - 25521, 25398, 27454, 27468, 27746, 25303, 25521, 25375, 31658, 31276, 31385, 31950, 31971, - 31960, 37428, 37238, 37379, 37654, 37782, 37937, 10239, 10208, 10408, 9189, 9340, 9192, - 31344, 31118, 31176, 30324, 30027, 30070, 31538, 31394, 31390, 31538, 31390, 32302, 38837, - 38754, 38631, 38794, 38726, 38663, 4129, 4246, 4117, 4299, 4386, 4360, 18329, 18197, - 18099, 18318, 18197, 18329, 17573, 17710, 17609, 17194, 17072, 16850, 4341, 4441, 4414, - 5580, 5554, 5672, 5363, 5542, 5564, 5363, 5564, 5484, 5398, 5637, 5336, 17764, - 17691, 17698, 17620, 17691, 17764, 17573, 17609, 17473, 28799, 28901, 28962, 28961, 28901, - 28799, 5421, 5494, 5373, 5425, 5241, 5472, 4915, 5021, 5067, 5598, 5586, 5691, - 20016, 19837, 19996, 21876, 21765, 21980, 21876, 21980, 22101, 5818, 5697, 5899, 5818, - 5899, 5998, 4246, 4188, 4117, 4017, 4176, 4030, 19661, 19741, 19719, 38688, 38566, - 38628, 26270, 26225, 26365, 26270, 26110, 26225, 26270, 26365, 26274, 5494, 5350, 5489, - 5221, 5398, 5336, 5246, 5341, 5233, 13193, 13221, 13013, 13013, 12959, 12935, 12365, - 12331, 12362, 13521, 13350, 13349, 13208, 13338, 13362, 14643, 14444, 14429, 13231, 13338, - 13208, 13231, 13208, 13070, 4176, 4139, 4030, 6578, 6435, 6518, 6653, 6730, 6502, - 10685, 10586, 10738, 11210, 11943, 12048, 14051, 13775, 13945, 16226, 16157, 16204, 37898, - 37782, 37806, 12362, 12331, 12216, 12130, 12331, 12237, 29040, 29080, 28962, 35580, 35547, - 35443, 35079, 35448, 34989, 35759, 35666, 35929, 9354, 9157, 8835, 38260, 38284, 38201, - 37708, 37605, 37732, 38395, 38284, 38260, 38421, 38238, 38458, 26971, 26492, 26795, 28961, - 29040, 28901, 37919, 37581, 37832, 38162, 38361, 38126, 13928, 13975, 13858, 13487, 13521, - 13647, 13647, 13521, 13646, 13338, 13569, 13657, 19837, 19661, 19719, 31836, 31971, 31950, - 31385, 31276, 31293, 37238, 37229, 37146, 36600, 36462, 36895, 37428, 37378, 37539, 4030, - 4139, 4141, 4117, 4188, 4018, 18813, 18707, 18734, 18873, 18707, 18813, 38628, 38513, - 38556, 38850, 38781, 38611, 38628, 38556, 38733, 5021, 4939, 4971, 5026, 5067, 5180, - 14429, 14444, 14428, 5831, 5818, 5998, 36219, 36070, 36221, 36462, 37224, 36895, 4839, - 4803, 4721, 4292, 4261, 4455, 4225, 4261, 4292, 17410, 17573, 17473, 18984, 19098, - 19053, 4358, 4341, 4414, 4358, 4438, 4316, 4483, 4482, 4316, 9543, 9340, 9433, - 9236, 9340, 9189, 17455, 17438, 17561, 16527, 16914, 16561, 17229, 17410, 17336, 19661, - 19622, 19741, 25386, 25324, 25184, 25684, 25705, 25854, 5316, 5241, 5425, 5175, 5265, - 5156, 4030, 4141, 3997, 19622, 19499, 19741, 3997, 4141, 4028, 4018, 4188, 4244, - 4129, 4117, 4041, 4236, 4386, 4241, 18707, 18701, 18734, 18197, 18013, 18099, 17691, - 17455, 17561, 18740, 18701, 18707, 30378, 30409, 30289, 29575, 29645, 29519, 36591, 36482, - 36405, 38738, 38609, 38630, 38675, 38556, 38563, 18248, 18013, 18197, 5083, 5026, 5180, - 13945, 13775, 13716, 35205, 34470, 34980, 9836, 10050, 10211, 10334, 10406, 10531, 9664, - 10050, 9836, 9701, 9663, 9491, 26274, 26549, 26658, 25854, 25705, 25933, 37832, 37581, - 37697, 37832, 37697, 37817, 4988, 5175, 5156, 10715, 10586, 10685, 9236, 9350, 9340, - 10715, 10685, 10811, 13858, 13810, 13714, 13716, 13775, 13609, 24824, 25072, 24847, 23703, - 23696, 23529, 31664, 31833, 31658, 30937, 30951, 30988, 30943, 30951, 30937, 30409, 30516, - 30289, 38212, 38299, 38141, 38162, 38299, 38420, 4318, 4360, 4407, 17620, 17455, 17691, - 25446, 25324, 25386, 23970, 23604, 23947, 25446, 25386, 25587, 31833, 31971, 31836, 32385, - 32701, 32251, 31833, 31836, 31658, 8503, 8625, 8582, 8503, 8570, 8625, 8503, 8522, - 8570, 8570, 8522, 8439, 8439, 8367, 8345, 8345, 8367, 8197, 8799, 8926, 8882, - 8799, 8882, 8983, 8799, 8983, 8751, 8983, 9074, 8977, 11440, 11665, 11558, 12020, - 12166, 12064, 11145, 11068, 10973, 26893, 26812, 26716, 26658, 26812, 26943, 4341, 4318, - 4407, 4482, 4541, 4368, 35629, 35547, 35580, 35736, 35547, 35629, 38091, 37898, 37948, - 38483, 38232, 38422, 8522, 8367, 8439, 7655, 7796, 8098, 6601, 7203, 6232, 4242, - 4126, 4028, 6149, 6228, 6375, 10973, 11068, 10939, 22191, 22123, 22066, 23118, 22890, - 22613, 30378, 30289, 29752, 38738, 38630, 38688, 36716, 37116, 36770, 37213, 37405, 37059, - 37307, 37116, 36716, 4241, 4386, 4299, 3986, 4315, 4231, 5697, 5598, 5691, 5305, - 5316, 5350, 5350, 5316, 5425, 5526, 5598, 5570, 5598, 5697, 5570, 9069, 9074, - 9098, 23606, 23604, 23219, 24306, 24521, 24336, 23202, 23543, 23512, 23270, 23543, 23202, - 29345, 29346, 29325, 28901, 29040, 28962, 28961, 28799, 28699, 13465, 13221, 13350, 13350, - 13221, 13193, 13465, 13350, 13521, 13569, 13716, 13609, 13338, 13427, 13569, 13271, 13231, - 13044, 26123, 25933, 26110, 5093, 5083, 5276, 5186, 5276, 5241, 4823, 4799, 4971, - 5026, 4915, 5067, 4914, 4915, 5026, 22123, 22224, 22161, 37708, 37600, 37605, 37756, - 37565, 37550, 37898, 37806, 37948, 31118, 30792, 31037, 29189, 29007, 29398, 31557, 31538, - 31646, 5421, 5350, 5494, 13487, 13465, 13521, 13271, 13427, 13338, 32966, 32915, 32855, - 33179, 32993, 32969, 33111, 34429, 33341, 37116, 37206, 36981, 12331, 12130, 12216, 12365, - 12603, 12804, 12020, 12064, 11860, 17397, 17410, 17229, 18984, 19053, 18901, 17536, 17410, - 17397, 16527, 16561, 16477, 24336, 24521, 24640, 24058, 24226, 23842, 29604, 29346, 29460, - 29645, 29800, 29752, 30324, 30136, 30595, 28967, 28968, 28352, 16226, 16477, 16249, 16157, - 16249, 15773, 3926, 4038, 4138, 4142, 4082, 4252, 9121, 9069, 9098, 9121, 9350, - 9236, 18984, 19185, 19098, 18971, 17710, 18901, 32993, 32915, 32966, 4227, 4225, 4288, - 4803, 5019, 4649, 4056, 4225, 4227, 10586, 10510, 10738, 10811, 10936, 11064, 23543, - 23703, 23529, 23429, 23703, 23543, 38671, 38613, 38250, 38733, 38738, 38688, 5439, 5580, - 5542, 5246, 5256, 5336, 5145, 5256, 5246, 37206, 37405, 37213, 15062, 14967, 15037, - 15548, 15343, 15346, 16157, 16121, 16204, 10483, 10809, 10697, 11145, 11440, 11558, 11665, - 12020, 11860, 11506, 12020, 11665, 29346, 29575, 29519, 26270, 26123, 26110, 26658, 26549, - 26661, 38115, 37859, 38348, 23604, 23108, 23219, 22997, 23108, 22984, 22303, 22613, 22340, - 4892, 4971, 4939, 9543, 10024, 10020, 9227, 9388, 9561, 8835, 9157, 9082, 4126, - 4129, 4048, 4028, 4126, 4048, 38758, 38801, 38705, 38735, 38861, 38755, 38755, 38836, - 38772, 38772, 38837, 38644, 38754, 38790, 38479, 38734, 38822, 38758, 38830, 38822, 38734, - 38682, 38697, 38810, 38697, 38819, 38810, 4026, 3611, 4132, 4058, 3926, 4297, 4006, - 3994, 4026, 3877, 3994, 4006, 3877, 4006, 4072, 3938, 4143, 3921, 4143, 4087, - 3921, 4087, 3976, 3921, 20459, 20303, 20237, 20126, 20016, 19996, 19837, 19783, 19661, - 19661, 19630, 19622, 19622, 19630, 19499, 20576, 20500, 20459, 20818, 20500, 20576, 20634, - 20500, 20818, 21158, 21322, 21131, 31385, 31293, 31120, 32685, 32701, 32385, 38822, 38801, - 38758, 4823, 4892, 4701, 4915, 4892, 4939, 5189, 5186, 5241, 13928, 13858, 13962, - 14328, 14116, 13975, 20500, 20440, 20459, 37403, 36782, 37146, 36490, 36381, 36482, 37565, - 37370, 37550, 38801, 38861, 38735, 4914, 5026, 4934, 6228, 6138, 6294, 6096, 6138, - 6228, 6061, 6138, 6096, 30595, 30136, 30551, 4197, 4241, 4299, 4029, 4244, 4214, - 4195, 4318, 4341, 4316, 4341, 4358, 21468, 21382, 21617, 24640, 24521, 24757, 24209, - 23970, 23947, 25150, 25184, 25324, 31082, 30988, 30951, 31359, 31385, 31120, 35547, 35431, - 35370, 35534, 35431, 35547, 38669, 38483, 39306, 38421, 38395, 38260, 38739, 38036, 38696, - 38861, 38836, 38755, 38697, 38747, 38819, 25521, 25755, 25593, 25669, 25755, 25521, 25303, - 25169, 25072, 20440, 20303, 20459, 21152, 21231, 21305, 21305, 21237, 21366, 21366, 21527, - 21613, 22123, 22191, 22224, 21100, 21085, 21152, 20883, 21077, 20979, 20961, 21077, 20883, - 20961, 20883, 20791, 20961, 20791, 20598, 4197, 4299, 4270, 4105, 4017, 3976, 4048, - 4129, 4041, 19499, 18994, 19282, 18306, 18318, 18463, 17239, 17200, 17455, 19297, 18994, - 19499, 19756, 20163, 19856, 18901, 17710, 17649, 20303, 20147, 20237, 21077, 21085, 21100, - 38819, 38747, 38748, 18306, 18463, 18495, 23123, 23126, 23202, 23118, 23126, 23123, 38650, - 38675, 38563, 38947, 38819, 38748, 16226, 16430, 16477, 16753, 16850, 16914, 21085, 21231, - 21152, 25129, 25150, 25202, 25150, 25324, 25236, 10020, 10024, 10084, 9084, 9256, 9227, - 32236, 32145, 32222, 33135, 33455, 33425, 33661, 33772, 33969, 35277, 35284, 34470, 16753, - 16914, 16527, 25129, 24830, 24920, 24658, 24679, 24511, 24915, 24824, 24706, 24058, 23842, - 23703, 38465, 38395, 38421, 38420, 38361, 38162, 38916, 38733, 38926, 38242, 38299, 38212, - 4017, 3886, 3976, 20147, 20016, 20126, 21231, 21237, 21305, 22224, 22303, 22288, 38794, - 38663, 38832, 5072, 5093, 5276, 13221, 12959, 13013, 13106, 12959, 13221, 13106, 13221, - 13465, 28699, 28470, 28225, 29604, 29575, 29346, 29710, 29800, 29575, 31443, 31218, 31394, - 3949, 4033, 4135, 3949, 4135, 4038, 5174, 5189, 5241, 5186, 5072, 5276, 5373, - 5494, 5586, 5526, 5586, 5598, 6061, 5965, 6230, 10556, 10510, 10586, 10454, 10510, - 10556, 19756, 19856, 19185, 17649, 17710, 17573, 17649, 17573, 17536, 29662, 29398, 29617, - 29986, 29887, 30027, 29979, 29986, 30108, 30303, 30027, 30324, 30943, 31082, 30951, 30937, - 30602, 30876, 36395, 36221, 36322, 36490, 36395, 36322, 36599, 36482, 36591, 36207, 35898, - 35728, 35495, 36065, 36107, 38733, 38688, 38628, 38986, 38837, 38772, 10084, 10162, 10208, - 12278, 12279, 11733, 12166, 12279, 12531, 13444, 13569, 13427, 12279, 12166, 11733, 17455, - 17200, 17438, 17152, 16920, 17161, 17620, 17764, 17630, 18318, 18248, 18197, 18306, 18248, - 18318, 4799, 4754, 4955, 4727, 4754, 4799, 4823, 4971, 4892, 17536, 17573, 17410, - 10454, 10239, 10408, 26363, 26123, 26270, 26363, 26270, 26274, 26658, 26661, 26812, 25828, - 25983, 25726, 28616, 28699, 28225, 25828, 25726, 25755, 33111, 33971, 34429, 35678, 35534, - 35547, 10334, 10531, 10138, 9491, 9663, 9579, 4017, 4030, 3874, 20016, 19788, 19837, - 37750, 37550, 37585, 37937, 37844, 37654, 37937, 37782, 37898, 37770, 37567, 37584, 37919, - 38054, 37481, 38837, 38790, 38754, 4122, 4214, 4236, 3925, 4030, 3997, 4033, 4082, - 4142, 3978, 4082, 4033, 18994, 18873, 18813, 18866, 18873, 18994, 5256, 5221, 5336, - 5439, 5554, 5580, 5097, 5221, 5256, 5145, 5233, 5175, 5145, 5027, 5097, 13714, - 13487, 13647, 37396, 37146, 37229, 37445, 37396, 37238, 37445, 37238, 37428, 25978, 25854, - 25933, 25873, 25828, 25784, 38423, 38054, 37919, 9256, 9388, 9227, 19788, 19783, 19837, - 6138, 6061, 6230, 5570, 5697, 5818, 6293, 6375, 6435, 17397, 17229, 17353, 16650, - 16753, 16527, 38574, 38242, 37990, 38671, 38650, 38613, 38451, 38420, 38299, 8582, 8625, - 8739, 8522, 8195, 8367, 7655, 8098, 8197, 8582, 8739, 8585, 8739, 8799, 8740, - 8799, 8751, 8740, 37864, 37708, 37732, 37804, 37770, 37824, 9074, 9069, 8977, 4149, - 4122, 4236, 4149, 4236, 4241, 3925, 3997, 3902, 38790, 38809, 38479, 10122, 10084, - 10208, 9189, 9125, 9236, 3960, 3997, 4028, 4018, 4041, 4117, 4934, 5026, 5083, - 5114, 5189, 5174, 4963, 5165, 5057, 4963, 5057, 4856, 5057, 4990, 4856, 8977, - 9069, 9056, 13858, 13714, 13647, 14328, 14488, 14211, 13945, 13956, 14428, 14741, 14873, - 14643, 13444, 13716, 13569, 13271, 13338, 13231, 18873, 18740, 18707, 18866, 18740, 18873, - 22984, 22700, 22997, 22984, 23108, 23314, 29821, 29662, 29698, 29821, 29698, 29986, 39102, - 38739, 38696, 4195, 4197, 4270, 4195, 4270, 4318, 17764, 18013, 17630, 17359, 17620, - 17538, 38483, 38458, 38238, 38350, 37665, 38284, 38669, 38458, 38483, 6601, 6232, 6510, - 31636, 31664, 31385, 32222, 31971, 32134, 30715, 30602, 30409, 32993, 33018, 32915, 32371, - 32302, 32311, 35522, 35079, 35431, 19783, 19630, 19661, 21866, 21876, 22101, 30792, 30689, - 30551, 30938, 30689, 30792, 30378, 30715, 30409, 30876, 31093, 30943, 35759, 35736, 35629, - 36219, 35991, 35922, 36219, 36221, 36395, 33224, 33146, 33179, 7663, 7739, 7796, 4649, - 4721, 4803, 19630, 19511, 19499, 38675, 38733, 38556, 38832, 38663, 38781, 38650, 38353, - 38613, 38832, 38781, 38850, 5114, 5072, 5186, 13810, 13975, 14003, 36566, 36490, 36482, - 9056, 9069, 9121, 9056, 9121, 9125, 33146, 33018, 32993, 31538, 31557, 31394, 5570, - 5818, 5767, 5421, 5305, 5350, 5189, 5114, 5186, 5363, 5484, 5398, 5363, 5398, - 5194, 16597, 16650, 16527, 16157, 16226, 16249, 15037, 14967, 14820, 25183, 25303, 25072, - 24915, 25072, 24824, 29066, 28968, 28967, 29143, 28968, 29066, 38850, 38611, 38816, 4165, - 4241, 4197, 4652, 4892, 4645, 4539, 4649, 5019, 5217, 5398, 5221, 9125, 9121, - 9236, 17229, 17202, 17353, 17649, 18942, 18901, 17194, 17202, 17229, 23919, 24058, 23703, - 32302, 31839, 32311, 37770, 37817, 37699, 37832, 38423, 37919, 37804, 37817, 37770, 38350, - 38284, 38395, 37844, 37864, 37732, 5831, 5998, 5965, 12616, 12365, 12804, 10664, 10556, - 10715, 12237, 12365, 12348, 13106, 13465, 13310, 13674, 13487, 13714, 29478, 29189, 29398, - 13044, 13231, 13070, 24336, 24269, 24209, 24714, 24640, 24757, 24714, 24757, 24830, 25129, - 24920, 25150, 3924, 4018, 4244, 3960, 4028, 4048, 4029, 4214, 4122, 9340, 9543, - 9192, 11051, 11440, 11145, 12279, 12733, 12680, 10993, 11145, 10973, 37750, 37675, 37708, - 37750, 37585, 37675, 38531, 38250, 38605, 5097, 5256, 5145, 5097, 5217, 5221, 4839, - 4856, 4990, 5145, 4988, 5027, 6214, 6403, 6347, 6495, 6403, 6435, 5872, 5831, - 5965, 31359, 31120, 31082, 30715, 30876, 30602, 29800, 29645, 29575, 37405, 37724, 37447, - 37206, 37365, 37405, 37498, 37365, 37206, 37462, 37365, 37500, 33007, 32311, 32915, 32222, - 31960, 31971, 31971, 31833, 32134, 6601, 6502, 6730, 6510, 6502, 6601, 10084, 10122, - 10020, 10239, 10219, 10208, 10510, 10454, 10408, 10556, 10586, 10715, 10334, 10138, 10050, - 31344, 31176, 31218, 35918, 35736, 35759, 35534, 35522, 35431, 35678, 35711, 35694, 10729, - 10973, 10939, 30689, 30595, 30551, 29302, 29182, 29189, 30605, 30595, 30760, 35495, 35447, - 36065, 36708, 36202, 36318, 3960, 4048, 3975, 3861, 3926, 3554, 4082, 3986, 4231, - 22043, 22123, 21714, 23126, 23270, 23202, 38816, 38738, 38857, 38816, 38611, 38738, 22869, - 22984, 23060, 21533, 21617, 21876, 36286, 36504, 36369, 36600, 36599, 36591, 36761, 36599, - 36600, 36612, 36599, 36761, 17548, 18942, 17649, 17536, 17397, 17459, 38605, 38126, 38361, - 38671, 38531, 38854, 37529, 37445, 37428, 25446, 25587, 25599, 38465, 38350, 38395, 10368, - 10219, 10239, 31557, 31443, 31394, 31473, 31443, 31557, 22191, 22303, 22224, 25599, 25587, - 25684, 25599, 25684, 25829, 30396, 30303, 30324, 4064, 4149, 4241, 4616, 4342, 4368, - 4616, 4666, 4342, 7655, 8197, 7909, 17092, 16920, 17152, 17092, 17152, 17200, 16896, - 16920, 16973, 24544, 24269, 24336, 24953, 24714, 24830, 31664, 31658, 31385, 4823, 4727, - 4799, 4701, 4727, 4823, 14741, 14643, 14655, 14643, 14454, 14655, 27057, 27234, 27187, - 26123, 25978, 25933, 38050, 37937, 37898, 38091, 37948, 38115, 5872, 5965, 6061, 29979, - 29821, 29986, 29710, 29575, 29604, 36612, 36566, 36482, 26363, 25978, 26123, 13975, 13810, - 13858, 14328, 14877, 14488, 22345, 23118, 22613, 37529, 37539, 37575, 37565, 37539, 37378, - 14655, 14454, 14585, 37994, 37864, 37844, 38857, 38738, 38733, 7663, 7577, 7739, 20729, - 20634, 20818, 20500, 20413, 20440, 20440, 20379, 20303, 20303, 20298, 20147, 20147, 20182, - 20016, 20016, 20059, 19788, 19788, 19681, 19783, 19783, 19681, 19630, 19630, 19594, 19511, - 20602, 20634, 20729, 31359, 31082, 31177, 38801, 38935, 38861, 38861, 38887, 38836, 38836, - 38942, 38772, 39158, 38914, 38790, 38790, 38914, 38809, 38822, 38912, 38801, 38901, 38912, - 38822, 38901, 38822, 38830, 38901, 38830, 38956, 38830, 38810, 38902, 38810, 38947, 38902, - 38819, 38947, 38810, 38794, 38947, 38748, 38794, 39454, 38947, 38912, 38935, 38801, 4316, - 4195, 4341, 6403, 6293, 6435, 6229, 6293, 6214, 11826, 11210, 11064, 10454, 10368, - 10239, 10334, 10223, 10357, 10357, 10483, 10406, 10406, 10483, 10697, 24544, 24336, 24640, - 3994, 3749, 4026, 3852, 3877, 4072, 3852, 4072, 3870, 4072, 3938, 3870, 3938, - 3868, 3870, 20634, 20413, 20500, 19043, 19185, 18984, 21077, 20961, 21085, 21085, 21227, - 21231, 21231, 21227, 21237, 21237, 21243, 21366, 22191, 22066, 22303, 38935, 38887, 38861, - 38809, 38904, 38606, 3938, 3921, 3868, 20413, 20379, 20440, 20598, 20791, 20676, 5979, - 5872, 6061, 30203, 29986, 30027, 5363, 5439, 5542, 5554, 5541, 5672, 5504, 5439, - 5393, 12901, 12733, 12551, 13271, 13290, 13427, 20379, 20298, 20303, 31939, 32134, 31833, - 38887, 38942, 38836, 38794, 38832, 38874, 29346, 29345, 29460, 28225, 28496, 28436, 3868, - 3921, 3688, 3975, 4048, 4041, 3975, 4041, 3871, 3926, 3949, 4038, 3861, 3949, - 3926, 5504, 5541, 5554, 8887, 8844, 8927, 29189, 29143, 29066, 26943, 27057, 27187, - 29182, 29143, 29189, 29189, 29478, 29302, 3921, 3976, 3842, 18495, 18463, 18701, 18735, - 18701, 18740, 18866, 18994, 18843, 20298, 20182, 20147, 25129, 24953, 24830, 24707, 24544, - 24640, 25236, 25202, 25150, 25236, 25324, 25446, 26971, 27178, 26492, 26492, 26317, 26795, - 25873, 26093, 25828, 30303, 30203, 30027, 30595, 30518, 30324, 30605, 30518, 30595, 30938, - 30792, 30941, 31443, 31344, 31218, 31511, 31344, 31443, 31177, 31082, 30943, 31177, 30943, - 31093, 35736, 35678, 35547, 35929, 35666, 35991, 36219, 36659, 36504, 36114, 36207, 35728, - 36161, 36207, 36114, 5373, 5305, 5421, 4934, 5083, 5093, 5373, 5586, 5526, 5373, - 5526, 5033, 4671, 4755, 4766, 8097, 8197, 8367, 7393, 7452, 7577, 8582, 8585, - 8503, 8740, 8585, 8739, 8470, 8585, 8740, 8751, 8983, 8977, 8751, 8977, 8720, - 13050, 13106, 13276, 33395, 33455, 33135, 36065, 35447, 35584, 33395, 33135, 33380, 32388, - 32385, 32236, 32388, 32236, 32244, 9388, 9391, 9579, 9328, 9391, 9388, 9328, 9388, - 9256, 9328, 9256, 9025, 16920, 16896, 17161, 17239, 17359, 17273, 38159, 38091, 38115, - 38458, 38465, 38421, 38669, 38465, 38458, 20961, 21227, 21085, 12365, 12237, 12331, 12812, - 12804, 12959, 36708, 36318, 36518, 3842, 3976, 3886, 13137, 13290, 13271, 21227, 21243, - 21237, 38874, 38832, 38936, 3949, 3978, 4033, 3727, 4371, 3560, 3847, 3978, 3949, - 8304, 8835, 9082, 5576, 7163, 6321, 18901, 18942, 18984, 17606, 17649, 17536, 38936, - 38832, 38850, 38916, 38857, 38733, 38733, 39187, 38926, 26658, 26439, 26274, 25340, 25236, - 25446, 26363, 26439, 26664, 29398, 29662, 29478, 30238, 30203, 30303, 32302, 31646, 31538, - 31825, 31939, 31833, 31545, 31636, 31385, 17239, 17455, 17359, 37756, 37750, 37828, 38050, - 38091, 38158, 4054, 4029, 4122, 4054, 4122, 4149, 23118, 23270, 23126, 24658, 24511, - 24226, 23150, 23270, 23118, 37365, 37460, 37405, 37462, 37460, 37365, 7452, 7405, 7577, - 7577, 7405, 7739, 6502, 6347, 6495, 9391, 9467, 9579, 9406, 9467, 9391, 21533, - 21468, 21617, 21533, 21876, 21780, 33018, 33057, 32915, 31511, 31473, 31646, 33146, 33145, - 33018, 33224, 33145, 33146, 33341, 33145, 33224, 38531, 38671, 38250, 38605, 38361, 38761, - 14488, 14877, 14491, 13050, 12959, 13106, 10353, 10368, 10454, 11826, 11943, 11210, 10483, - 10620, 10809, 10993, 11051, 11145, 11440, 11506, 11665, 10578, 10620, 10483, 22360, 22281, - 22700, 21243, 21527, 21366, 23238, 23429, 23270, 36286, 35929, 35991, 29800, 29853, 29752, - 29345, 29040, 29460, 36566, 36953, 36490, 36234, 35918, 35929, 36599, 36612, 36482, 37403, - 37146, 37396, 37403, 37396, 37597, 36518, 36318, 36415, 3871, 4041, 4018, 3886, 4017, - 3874, 19457, 19499, 19511, 33145, 33057, 33018, 4856, 4797, 4963, 5393, 5439, 5363, - 4803, 4839, 4990, 3662, 4261, 4225, 14741, 14820, 14967, 16338, 16430, 16226, 13956, - 13945, 13716, 28549, 28352, 28968, 36492, 36518, 36415, 36161, 36107, 36258, 37817, 38009, - 37832, 38574, 38336, 38242, 38242, 38336, 38299, 37724, 37770, 37584, 7008, 7203, 7297, - 6149, 6096, 6228, 10353, 10454, 10556, 10219, 10122, 10208, 10334, 9935, 10223, 31344, - 31285, 31118, 30518, 30396, 30324, 31240, 31285, 31325, 25684, 25854, 25829, 24986, 24953, - 25129, 38451, 38336, 38588, 5174, 5241, 5316, 24986, 25129, 25098, 24658, 24226, 24491, - 25784, 25828, 25755, 37539, 37529, 37428, 37575, 37539, 37565, 37750, 37708, 37828, 4030, - 3925, 3874, 19252, 19756, 19185, 9467, 9491, 9579, 9406, 9491, 9467, 32244, 32236, - 32222, 32244, 32222, 32134, 3922, 4054, 4149, 3933, 3924, 4244, 3874, 3925, 3819, - 5767, 5818, 5831, 6149, 6375, 6293, 19680, 19681, 19788, 30470, 30396, 30518, 29914, - 29821, 29979, 39086, 38790, 38837, 39306, 38483, 38377, 18866, 18735, 18740, 17170, 17092, - 17239, 18843, 18735, 18866, 25937, 25854, 25978, 29764, 29853, 29800, 31825, 31833, 31664, - 36492, 36415, 36388, 4195, 4165, 4197, 4064, 4165, 4068, 17459, 17606, 17536, 16809, - 16850, 16753, 16527, 16430, 16597, 24707, 24640, 24714, 23314, 23108, 23604, 38562, 38361, - 38420, 10304, 10122, 10219, 9125, 9038, 9056, 31646, 31473, 31557, 32371, 31646, 32302, - 35694, 35522, 35534, 35694, 35534, 35678, 4934, 5093, 4953, 37994, 37844, 37937, 37912, - 37724, 37405, 13740, 13956, 13716, 19681, 19594, 19630, 5767, 5831, 5872, 5305, 5174, - 5316, 11210, 12048, 12130, 13050, 12812, 12959, 13465, 13487, 13310, 5541, 5661, 6084, - 5439, 5504, 5554, 5393, 5123, 5240, 12812, 12616, 12804, 7405, 7198, 7525, 7264, - 7198, 7405, 34327, 33772, 34243, 32392, 32244, 32418, 13674, 13714, 13810, 3978, 3986, - 4082, 3820, 3986, 3978, 3867, 4313, 4315, 9122, 9189, 9192, 12616, 12348, 12365, - 23270, 23429, 23543, 23150, 23118, 23146, 29143, 29087, 28968, 30108, 29986, 30203, 30238, - 30108, 30203, 36388, 35898, 36207, 4342, 4666, 4337, 4068, 4165, 4195, 4652, 4701, - 4892, 5019, 4691, 4539, 5194, 5398, 5217, 10620, 10729, 10939, 10587, 10729, 10620, - 14670, 14820, 14741, 14798, 14820, 14670, 31163, 30792, 31118, 30396, 30238, 30303, 31163, - 31118, 31285, 16597, 16430, 16338, 24474, 24413, 24544, 25043, 24986, 25098, 24919, 24986, - 25043, 24915, 25060, 25072, 25134, 25060, 24915, 37597, 37396, 37445, 37579, 37445, 37529, - 26098, 25937, 25978, 25599, 25502, 25446, 26363, 26274, 26439, 25669, 25521, 25546, 31240, - 31163, 31285, 31622, 31668, 31636, 31668, 31825, 31664, 31093, 30876, 31155, 4342, 4266, - 4300, 19036, 19043, 18942, 17353, 17459, 17397, 32250, 32244, 32134, 31668, 31664, 31636, - 3902, 3960, 3754, 3902, 3997, 3960, 6229, 6149, 6293, 6096, 5979, 6061, 19594, - 19457, 19511, 21948, 22043, 21714, 30777, 30595, 30689, 36107, 36161, 36114, 36065, 35584, - 35975, 38936, 38850, 38877, 38850, 38883, 38877, 4953, 5093, 5072, 4914, 4790, 4915, - 5003, 5072, 5114, 14211, 14116, 14328, 14013, 14116, 14161, 4978, 4766, 4736, 13290, - 13444, 13427, 13137, 13444, 13290, 13539, 13444, 12999, 15331, 15764, 16118, 17239, 17092, - 17200, 17455, 17620, 17359, 24491, 24226, 24179, 37460, 37599, 37405, 37500, 37365, 37498, - 37206, 37495, 37498, 36795, 36202, 36708, 36795, 36708, 36728, 22984, 22869, 22700, 24294, - 24209, 24269, 33102, 33057, 33145, 35711, 35678, 35736, 35918, 35759, 35929, 37804, 37907, - 37817, 37724, 37824, 37770, 37907, 37824, 37921, 29460, 29040, 29397, 29710, 29764, 29800, - 31155, 30876, 31079, 36612, 36739, 36566, 36895, 36761, 36600, 36728, 36708, 36712, 25546, - 25521, 25303, 22043, 22066, 22123, 38850, 38816, 38883, 6011, 5979, 6096, 36293, 36388, - 36207, 36698, 36708, 36518, 13754, 13674, 13810, 10357, 10406, 10334, 10357, 10578, 10483, - 8927, 9256, 9084, 3813, 3861, 3646, 5979, 5767, 5872, 19457, 19297, 19499, 18735, - 18495, 18701, 38914, 38904, 38809, 38883, 38816, 38974, 3933, 4244, 4029, 3933, 4029, - 3875, 18462, 18495, 18735, 33455, 33772, 33425, 33135, 32701, 33084, 16204, 16121, 16148, - 16809, 17194, 16850, 32121, 32134, 31939, 31388, 31385, 31359, 38336, 38451, 38299, 38562, - 38451, 38588, 26664, 26439, 26658, 25829, 25502, 25599, 32685, 32385, 32520, 10871, 11051, - 10993, 10587, 10520, 10642, 15346, 15343, 15269, 31177, 31215, 31359, 31215, 31462, 31388, - 35910, 35918, 36234, 6149, 6011, 6096, 6214, 6293, 6403, 6403, 6495, 6347, 30605, - 30470, 30518, 30938, 30777, 30689, 31008, 30777, 30938, 17092, 16973, 16920, 17044, 16973, - 17092, 24658, 24706, 24824, 25686, 25784, 25669, 24574, 24706, 24658, 37690, 37575, 37565, - 7570, 7577, 7663, 8809, 8977, 8888, 3883, 3960, 3975, 6347, 6502, 6510, 8367, - 8195, 8097, 38904, 38917, 38606, 38650, 38958, 38675, 38675, 39187, 38733, 38974, 38816, - 38983, 3871, 3883, 3975, 3922, 4029, 4054, 4064, 4241, 4165, 12298, 12130, 12237, - 10412, 10353, 10556, 10368, 10304, 10219, 10871, 10993, 10729, 36161, 36293, 36207, 36698, - 36518, 36668, 36351, 36293, 36161, 5504, 5461, 5541, 4797, 4856, 4839, 12348, 12298, - 12237, 12616, 12473, 12348, 12812, 12691, 12616, 12808, 12691, 12812, 12808, 12812, 13050, - 5371, 5461, 5504, 12567, 12473, 12616, 25873, 25985, 26093, 25669, 25784, 25755, 25183, - 25072, 25060, 8835, 8887, 9084, 8304, 9082, 7624, 22519, 22360, 22700, 19036, 18942, - 19024, 16809, 16753, 16783, 24413, 24294, 24269, 22240, 22101, 22360, 24413, 24269, 24544, - 24714, 24953, 24919, 12473, 12298, 12348, 13492, 13310, 13487, 14116, 14003, 13975, 14013, - 14003, 14116, 20634, 20602, 20413, 20413, 20321, 20379, 20379, 20321, 20298, 20298, 20321, - 20182, 20182, 20109, 20016, 19681, 19587, 19594, 19594, 19536, 19457, 19457, 19339, 19297, - 20729, 20818, 20978, 20729, 20978, 21131, 21322, 21468, 21131, 20444, 20598, 20676, 20961, - 21191, 21227, 21227, 21191, 21243, 21243, 21374, 21527, 21527, 21626, 21714, 22043, 22146, - 22066, 20663, 20598, 20444, 21131, 21379, 21123, 29182, 29177, 29143, 26943, 26664, 26658, - 29478, 29662, 29672, 29662, 29821, 29760, 38935, 39001, 38887, 39059, 38993, 38942, 38942, - 38993, 38772, 38914, 39105, 38904, 38904, 39061, 38917, 38912, 39001, 38935, 38901, 39001, - 38912, 38956, 39001, 38901, 38956, 38830, 38979, 38830, 38902, 38979, 39022, 39024, 38979, - 39022, 38979, 38902, 39142, 39057, 38947, 3877, 3749, 3994, 3770, 3749, 3877, 3770, - 3877, 3852, 3770, 3852, 3814, 3852, 3870, 3814, 3870, 3709, 3814, 3868, 3804, - 3870, 3718, 3804, 3868, 38874, 38936, 38987, 4680, 4797, 4839, 4680, 4839, 4721, - 16182, 16309, 16896, 3842, 3827, 3921, 38987, 38936, 38877, 3842, 3886, 3827, 33057, - 33007, 32915, 33102, 33007, 33057, 35448, 35079, 35522, 4068, 4195, 3890, 25327, 25183, - 25134, 13492, 13487, 13674, 20439, 20321, 20413, 3861, 3847, 3949, 3986, 3867, 4315, - 3753, 3847, 3861, 18942, 19043, 18984, 20622, 20663, 20565, 17516, 17606, 17459, 22345, - 22613, 22303, 23532, 23919, 23703, 29914, 29979, 30108, 37224, 36462, 36782, 36761, 36739, - 36612, 36843, 36895, 36909, 16973, 16888, 16896, 17022, 16888, 16973, 16783, 16753, 16650, - 16783, 16650, 16645, 20321, 20168, 20182, 21379, 21468, 21450, 39059, 38942, 38887, 25829, - 25854, 25937, 25395, 25546, 25303, 3827, 3886, 3778, 9122, 9038, 9125, 9122, 9125, - 9189, 20168, 20109, 20182, 20849, 21191, 20961, 23489, 23238, 23403, 38993, 38986, 38772, - 10578, 10587, 10620, 9836, 9701, 9664, 31163, 30941, 30792, 30777, 30760, 30595, 31282, - 30941, 31163, 31285, 31344, 31325, 36130, 36065, 36156, 5145, 5175, 4988, 13754, 13492, - 13674, 14670, 14741, 14655, 13444, 13539, 13716, 13044, 13070, 12901, 9472, 9701, 9491, - 21191, 21295, 21243, 31511, 31443, 31473, 31155, 31215, 31177, 30378, 29752, 29853, 33007, - 32371, 32311, 32244, 32392, 32388, 31819, 31939, 31825, 31819, 31825, 31668, 38091, 38050, - 37898, 37750, 37756, 37550, 38159, 38115, 38348, 10732, 10871, 10729, 11218, 11506, 11440, - 30750, 30760, 30777, 36561, 36492, 36388, 36130, 36258, 36107, 5447, 5661, 5541, 36843, - 36739, 36761, 36362, 36388, 36293, 36795, 37001, 36859, 4539, 4691, 4353, 38348, 37859, - 38573, 3871, 4018, 3924, 3778, 3886, 3786, 3871, 3785, 3793, 37828, 37708, 37954, - 37575, 37579, 37529, 21295, 21374, 21243, 8470, 8503, 8585, 9192, 9543, 9022, 17620, - 17630, 17538, 17409, 17516, 17459, 17175, 17202, 17194, 24093, 23970, 24209, 24919, 24953, - 24986, 23150, 23238, 23270, 25327, 25261, 25183, 22146, 22303, 22066, 23532, 23703, 23429, - 31546, 31511, 31583, 35694, 35686, 35522, 35711, 35686, 35694, 35910, 35736, 35918, 4988, - 5156, 4963, 4608, 4680, 4721, 25875, 25829, 25937, 37824, 37907, 37804, 37921, 37824, - 37724, 4776, 4790, 4914, 4978, 5003, 5114, 4978, 5114, 5174, 5174, 4766, 4978, - 14003, 13754, 13810, 13705, 13754, 14003, 13539, 13740, 13716, 30111, 30378, 29853, 36473, - 36362, 36460, 37690, 37579, 37575, 5661, 5742, 6084, 30194, 29914, 30108, 36668, 36518, - 36492, 21374, 21606, 21527, 17231, 17170, 17273, 19046, 18843, 18994, 19089, 18994, 19297, - 39278, 39141, 39370, 38883, 38987, 38877, 7655, 7570, 7663, 6347, 6510, 6232, 16204, - 16338, 16226, 16809, 17175, 17194, 16148, 16338, 16204, 14798, 15037, 14820, 25183, 25261, - 25303, 25183, 25060, 25134, 16645, 16650, 16597, 25129, 25202, 25098, 25202, 25236, 25340, - 3886, 3874, 3786, 21606, 21626, 21527, 4549, 4754, 4727, 3923, 4195, 4316, 4549, - 4727, 4701, 4776, 4914, 4934, 37787, 37690, 37565, 37954, 37708, 37864, 5003, 4953, - 5072, 3786, 3874, 3819, 5461, 5447, 5541, 5661, 5374, 5742, 5393, 5371, 5504, - 5240, 5371, 5393, 6229, 6011, 6149, 5979, 6011, 5767, 7264, 7405, 7452, 7570, - 7516, 7577, 10587, 10732, 10729, 11054, 11440, 11051, 10642, 10732, 10587, 12473, 12496, - 12298, 10412, 10664, 10547, 12691, 12567, 12616, 12696, 12808, 12730, 13276, 13106, 13310, - 13276, 13310, 12992, 21866, 21780, 21876, 24093, 24209, 24294, 22101, 21980, 22114, 24093, - 24294, 24038, 32520, 32385, 32388, 36065, 36130, 36107, 36473, 36388, 36362, 36245, 36130, - 36156, 7008, 7297, 7198, 17273, 17170, 17239, 16182, 15331, 16118, 17044, 17170, 17098, - 17409, 17459, 17353, 16622, 17175, 16809, 24179, 24226, 24058, 31927, 31819, 31668, 32392, - 32520, 32388, 36286, 35991, 36219, 38967, 38278, 38739, 38465, 38549, 38350, 38854, 38531, - 38827, 38974, 38987, 38883, 11054, 11051, 10871, 12901, 13070, 12733, 13539, 13746, 13740, - 29000, 29040, 28961, 29604, 29764, 29710, 28225, 27746, 28496, 27746, 27894, 28496, 29169, - 29177, 29417, 29302, 29177, 29182, 29177, 29302, 29417, 19680, 19587, 19681, 22101, 22114, - 22360, 38050, 38061, 37937, 38206, 38061, 38267, 38158, 38091, 38159, 5097, 5194, 5217, - 5120, 5194, 5097, 12810, 13276, 12992, 31215, 31388, 31359, 31545, 31388, 31462, 35169, - 33971, 34989, 35910, 35711, 35736, 38267, 38158, 38369, 8703, 8470, 8740, 7389, 7516, - 7570, 7389, 7366, 7516, 8703, 8740, 8751, 8703, 8751, 8720, 14643, 14429, 14454, - 38061, 37994, 37937, 7516, 7393, 7577, 7366, 7393, 7516, 3819, 3925, 3902, 3785, - 3924, 3933, 4064, 3922, 4149, 3836, 3922, 4064, 23238, 23511, 23429, 23919, 24179, - 24058, 23489, 23511, 23238, 3819, 3902, 3695, 19587, 19536, 19594, 21626, 21948, 21714, - 25784, 25968, 25873, 25737, 25968, 25784, 25686, 25669, 25546, 16783, 16633, 16809, 16533, - 16645, 16597, 16533, 16597, 16439, 24868, 24707, 24714, 25340, 25446, 25502, 38451, 38562, - 38420, 38588, 38336, 38574, 25697, 25340, 25502, 8720, 8977, 8809, 33007, 33227, 32371, - 35669, 35522, 35686, 4221, 4482, 4368, 17409, 17353, 17314, 17353, 17202, 17314, 22519, - 22700, 22568, 24362, 24294, 24413, 29914, 29760, 29821, 30377, 30238, 30396, 30470, 30605, - 30750, 30605, 30760, 30750, 31008, 30941, 31282, 8977, 9056, 8888, 14454, 14252, 14463, - 14454, 14429, 14252, 38574, 37990, 38054, 37967, 37921, 37724, 37599, 37460, 37462, 17170, - 17044, 17092, 17734, 17630, 18013, 32097, 32121, 31939, 32250, 32121, 32213, 9328, 9406, - 9391, 10671, 10807, 10732, 9374, 9406, 9365, 32537, 32520, 32392, 8888, 9056, 8982, - 25690, 25686, 25546, 25395, 25303, 25261, 4988, 4696, 4859, 29999, 29760, 29914, 29691, - 29764, 29604, 31155, 31177, 31093, 36728, 37001, 36795, 36698, 36712, 36708, 36787, 36712, - 36698, 36668, 36492, 36561, 23511, 23532, 23429, 23489, 23532, 23511, 3754, 3960, 3883, - 10732, 10807, 10871, 10587, 10578, 10520, 19536, 19339, 19457, 18406, 18306, 18495, 22240, - 22360, 22382, 21948, 22146, 22043, 8982, 9056, 9038, 8982, 9038, 8954, 8982, 8954, - 8889, 33223, 33102, 33145, 33395, 33380, 33455, 33061, 33084, 32701, 33061, 32701, 32943, - 31546, 31325, 31344, 31546, 31344, 31511, 31511, 31646, 31583, 4555, 4549, 4701, 4550, - 4776, 4934, 3586, 3867, 3986, 3717, 3813, 3646, 4696, 4963, 4797, 7251, 7264, - 7452, 7366, 7452, 7393, 9192, 9022, 9111, 9406, 9472, 9491, 12551, 12733, 12278, - 10807, 11054, 10871, 16439, 16597, 16338, 16645, 16633, 16783, 18462, 18735, 18631, 19196, - 19185, 19043, 17516, 17409, 17355, 19196, 19252, 19185, 19196, 19043, 19128, 23850, 24179, - 23919, 25327, 25395, 25261, 24868, 24714, 24919, 25340, 25098, 25202, 29764, 29968, 29853, - 31008, 30938, 30941, 30238, 30194, 30108, 32943, 32701, 32685, 36561, 36388, 36564, 37723, - 37597, 37445, 36895, 36843, 36761, 37787, 37565, 37756, 37822, 37756, 37828, 38642, 38549, - 38465, 38816, 38857, 38983, 16182, 16896, 16255, 14170, 14116, 14211, 13754, 13705, 13492, - 15269, 15343, 15037, 15024, 15037, 14798, 18765, 18735, 18843, 4649, 4608, 4721, 4680, - 4737, 4797, 4364, 4562, 3727, 4562, 4371, 3727, 14890, 15024, 14798, 26363, 26098, - 25978, 25829, 25875, 25502, 25616, 24996, 25098, 26943, 26812, 27057, 16255, 16896, 16483, - 16896, 16888, 16483, 16121, 16157, 15863, 24915, 25028, 25134, 15346, 15600, 15548, 25968, - 25985, 25873, 25778, 25985, 25968, 25737, 25784, 25686, 35711, 35669, 35686, 35668, 35669, - 35739, 24868, 24919, 24996, 4495, 4608, 4649, 27187, 27255, 27341, 5371, 5364, 5461, - 5240, 5364, 5371, 5125, 5363, 5194, 5125, 5194, 5120, 29177, 29087, 29143, 29169, - 29087, 29177, 13044, 13137, 13271, 12733, 12279, 12278, 33124, 32943, 32974, 19339, 19160, - 19297, 19128, 19043, 19036, 22700, 22869, 22568, 38983, 38916, 38926, 38983, 38857, 38916, - 5364, 5447, 5461, 5030, 5097, 5027, 13000, 13137, 13044, 27746, 27468, 27629, 29000, - 28961, 28699, 29925, 30111, 29968, 3820, 3978, 3847, 18462, 18406, 18495, 18466, 18406, - 18462, 25778, 25737, 25686, 14170, 14211, 14488, 29760, 29672, 29662, 30377, 30194, 30238, - 36362, 36293, 36460, 4642, 4737, 4680, 10807, 10617, 11054, 10520, 10578, 10357, 13746, - 13956, 13740, 14585, 14670, 14655, 27341, 27255, 27690, 29618, 29460, 29689, 31282, 31163, - 31240, 30470, 30377, 30396, 38002, 37954, 37864, 38002, 37864, 37994, 38002, 37994, 38148, - 38061, 38050, 38267, 3779, 3883, 3871, 3779, 3754, 3883, 3813, 3753, 3861, 19160, - 19089, 19297, 17649, 17606, 17548, 36728, 36712, 37001, 36716, 36859, 37307, 37206, 37116, - 37495, 10412, 10556, 10664, 10664, 11064, 10547, 31008, 30750, 30777, 20602, 20597, 20413, - 20321, 20135, 20168, 20168, 20135, 20109, 20109, 20059, 20016, 19587, 19680, 19536, 19536, - 19453, 19339, 19339, 19286, 19160, 19160, 19058, 19089, 20729, 20597, 20602, 20706, 20597, - 20729, 20706, 20729, 21131, 20706, 21131, 21123, 21468, 21379, 21131, 21450, 21468, 21533, - 20598, 20849, 20961, 21191, 21315, 21295, 21295, 21315, 21374, 21374, 21469, 21606, 21606, - 21644, 21626, 21626, 21744, 21948, 21948, 21977, 22146, 20663, 20444, 20565, 19415, 19756, - 19252, 19415, 19252, 19162, 21589, 21450, 21533, 35668, 35448, 35522, 39001, 39037, 38887, - 38993, 39113, 38986, 38986, 39084, 38837, 38956, 39037, 39001, 39024, 39037, 38956, 39024, - 38956, 38979, 38902, 39057, 39022, 16396, 16439, 16338, 16533, 16633, 16645, 16396, 16338, - 16148, 20663, 20849, 20598, 38549, 38544, 38350, 38714, 38544, 38746, 38009, 37817, 37907, - 38958, 38650, 38968, 38902, 38947, 39057, 29653, 29672, 29760, 29618, 29691, 29604, 36739, - 36953, 36566, 35739, 35669, 35711, 36909, 36895, 37062, 38947, 39282, 39142, 9543, 10020, - 9022, 3804, 3709, 3870, 3814, 3709, 3770, 3770, 3545, 3749, 3646, 3861, 3554, - 3813, 3701, 3753, 3718, 3709, 3804, 3718, 3868, 3645, 3921, 3827, 3688, 3827, - 3697, 3688, 3778, 3697, 3827, 4980, 5027, 4988, 4980, 5030, 5027, 24996, 24919, - 25043, 24669, 24474, 24544, 23314, 23604, 23456, 24996, 25043, 25098, 31583, 31786, 31757, - 31325, 31282, 31240, 31388, 31545, 31385, 32418, 32537, 32392, 32520, 32537, 32685, 30876, - 30715, 31079, 31155, 31079, 31239, 37606, 37599, 37462, 38669, 38642, 38465, 38746, 38642, - 38812, 39155, 39059, 38887, 39102, 38967, 38739, 3922, 3875, 4029, 3792, 3875, 3829, - 3703, 3820, 3753, 3753, 3820, 3847, 19058, 19046, 19089, 19089, 19046, 18994, 19162, - 19252, 19196, 17548, 17606, 17516, 15863, 16157, 15773, 7264, 7008, 7198, 7072, 7008, - 7264, 21638, 21589, 21533, 35415, 35169, 34989, 39071, 38874, 38987, 15771, 15863, 15773, - 15346, 15401, 15600, 15024, 15269, 15037, 15101, 15269, 15024, 14302, 14170, 14488, 30616, - 30377, 30470, 30194, 30155, 29914, 36351, 36161, 36258, 37001, 36993, 37111, 37895, 37822, - 37828, 37414, 37224, 37403, 3778, 3734, 3697, 20354, 20135, 20321, 4892, 4915, 4645, - 26415, 26098, 26363, 25875, 26098, 26079, 26363, 26664, 26415, 20135, 20059, 20109, 21168, - 21315, 21191, 39113, 39084, 38986, 3793, 3779, 3871, 3778, 3786, 3734, 13757, 13746, - 13516, 19046, 18905, 18843, 19017, 18905, 19046, 23604, 23644, 23456, 21780, 21638, 21533, - 38761, 38361, 38562, 38974, 39071, 38987, 17359, 17231, 17273, 17304, 17231, 17359, 18248, - 18172, 18013, 4645, 4915, 4790, 14463, 14670, 14585, 14789, 14670, 14678, 21866, 21638, - 21780, 21315, 21347, 21374, 37921, 38009, 37907, 37967, 38009, 37921, 39084, 39086, 38837, - 8176, 7887, 8059, 9365, 9406, 9162, 9406, 9374, 9472, 3662, 4225, 4056, 4476, - 4642, 4608, 4608, 4642, 4680, 23604, 23970, 23644, 38573, 37859, 38350, 38000, 37895, - 37828, 11210, 12130, 11579, 10353, 10304, 10368, 21866, 21791, 21638, 21347, 21469, 21374, - 23403, 23238, 23150, 30111, 29853, 29968, 10642, 10671, 10732, 12825, 12551, 12708, 10520, - 10671, 10642, 36130, 36245, 36258, 34998, 35653, 35750, 8195, 8522, 8503, 8195, 8503, - 8470, 8536, 8470, 8703, 8536, 8703, 8630, 8703, 8720, 8630, 8720, 8735, 8630, - 8809, 8735, 8720, 8809, 8888, 8735, 4093, 4221, 4368, 3825, 3836, 3741, 4300, - 4368, 4342, 16258, 16396, 16148, 17314, 17202, 17262, 16105, 16148, 16121, 3786, 3700, - 3734, 7485, 7570, 7655, 8735, 8888, 8746, 18905, 18880, 18843, 18951, 18880, 18905, - 21638, 21791, 21598, 22250, 22101, 22240, 23060, 22568, 22869, 29925, 29968, 29764, 33102, - 33173, 33007, 33341, 33382, 33145, 33537, 33382, 33341, 33084, 33380, 33135, 34998, 35594, - 35653, 33204, 33380, 33084, 33124, 33084, 33061, 33124, 33061, 32943, 12808, 12567, 12691, - 12696, 12567, 12808, 12808, 13050, 12730, 13705, 14003, 14013, 12020, 11733, 12166, 12901, - 13000, 13044, 13516, 13746, 13539, 35479, 35594, 34739, 6214, 6011, 6229, 5174, 5305, - 4766, 4550, 4934, 4953, 4431, 4645, 4439, 4776, 4645, 4790, 5255, 6011, 6214, - 6232, 6214, 6347, 29417, 29302, 29478, 29087, 28549, 28968, 29653, 29478, 29672, 37822, - 37787, 37756, 37794, 37787, 37822, 12956, 13000, 12901, 28999, 28549, 29087, 33382, 33256, - 33145, 4337, 4666, 4754, 22382, 22360, 22519, 21469, 21644, 21606, 5056, 5120, 5097, - 5123, 5393, 5363, 5370, 5456, 5447, 5056, 5097, 5030, 17355, 17548, 17516, 16633, - 16533, 16519, 24669, 24544, 24707, 24669, 24707, 24678, 33256, 33223, 33145, 36698, 36668, - 36787, 37500, 37606, 37462, 37987, 37967, 37724, 3786, 3819, 3700, 18880, 18765, 18843, - 18886, 18765, 18880, 20059, 19680, 19788, 21644, 21744, 21626, 7008, 6232, 7203, 7366, - 7251, 7452, 7082, 7251, 7366, 15334, 15401, 15346, 14890, 15101, 15024, 32418, 32244, - 32250, 32134, 32121, 32250, 35448, 35415, 34989, 35669, 35668, 35522, 35739, 35935, 35819, - 33537, 33364, 33382, 35500, 35415, 35448, 15334, 15346, 15269, 29907, 29925, 29764, 29460, - 29618, 29604, 29000, 28699, 28616, 37224, 36782, 37403, 36659, 36395, 36490, 36787, 36668, - 36561, 36564, 36388, 36473, 36460, 36564, 36473, 4549, 4337, 4754, 4652, 4555, 4701, - 4431, 4555, 4652, 33223, 33173, 33102, 3700, 3819, 3695, 21744, 21857, 21948, 37659, - 37606, 37500, 14170, 14161, 14116, 14146, 14161, 14170, 4014, 4337, 4549, 26098, 25875, - 25937, 26415, 26664, 26855, 10381, 10304, 10353, 10398, 10547, 11064, 11218, 11440, 11054, - 10223, 10520, 10357, 36245, 36325, 36258, 36144, 36156, 36065, 16519, 16533, 16439, 16519, - 16439, 16449, 23314, 23060, 22984, 24038, 23970, 24093, 23532, 23739, 23919, 24574, 24658, - 24491, 22345, 22303, 22146, 24806, 24996, 25462, 38629, 38693, 38562, 38629, 38562, 38588, - 3695, 3902, 3754, 3785, 3871, 3924, 3785, 3933, 3875, 16182, 15392, 15331, 14491, - 14302, 14488, 17022, 16973, 17044, 25690, 25778, 25686, 25737, 25778, 25968, 24574, 24491, - 24626, 4978, 4953, 5003, 4696, 4988, 4963, 4495, 4649, 4539, 36953, 36739, 36843, - 36391, 36325, 36245, 38206, 37994, 38061, 10381, 10353, 10412, 35965, 35975, 35810, 35810, - 35975, 35584, 33201, 33124, 32974, 31622, 31636, 31545, 5305, 5373, 4766, 4871, 4980, - 4988, 17098, 17022, 17044, 18248, 18306, 18172, 24362, 24038, 24294, 24362, 24413, 24474, - 38827, 38531, 38605, 24678, 24707, 24868, 24626, 24491, 24179, 3695, 3754, 3704, 15771, - 15773, 15600, 19680, 19453, 19536, 31546, 31506, 31325, 30616, 30470, 30750, 30467, 30155, - 30377, 31565, 31583, 31757, 31603, 31622, 31545, 31239, 31215, 31155, 34549, 35284, 34739, - 18765, 18631, 18735, 18625, 18631, 18765, 31079, 30715, 30879, 29907, 29764, 29691, 36993, - 36787, 36873, 36873, 36787, 36561, 39102, 38696, 38917, 12730, 13050, 12810, 14491, 15169, - 15331, 3756, 3836, 3825, 23489, 23546, 23532, 23403, 23546, 23489, 19453, 19403, 19339, - 19162, 19196, 19128, 19162, 19128, 19142, 39191, 39105, 38914, 4696, 4797, 4737, 9192, - 9111, 9122, 10086, 10020, 10122, 38267, 38050, 38158, 12567, 12496, 12473, 13705, 14013, - 13876, 12560, 12496, 12567, 36909, 37021, 36843, 37445, 37579, 37723, 37289, 37307, 36859, - 37498, 37659, 37500, 37345, 37319, 37467, 4221, 4146, 4482, 4133, 4146, 4221, 4133, - 4221, 4093, 16449, 16439, 16396, 17262, 17202, 17175, 25028, 24915, 24706, 38693, 38761, - 38562, 38655, 38629, 38588, 13516, 13539, 12999, 14463, 14585, 14454, 14670, 14789, 14798, - 12825, 12956, 12901, 12825, 12901, 12551, 17538, 17367, 17359, 17447, 17367, 17538, 3820, - 3679, 3986, 3611, 4026, 3749, 3792, 3785, 3875, 3704, 3754, 3779, 19403, 19286, - 19339, 38639, 38574, 38054, 39105, 39061, 38904, 39089, 39071, 38974, 39089, 38974, 38983, - 14429, 13956, 14252, 15101, 15102, 15269, 15617, 15771, 15600, 30377, 30155, 30194, 30616, - 30817, 30702, 31376, 31282, 31325, 30244, 30378, 30111, 28549, 28462, 28092, 26855, 26664, - 26943, 28999, 28462, 28549, 29172, 29087, 29169, 28436, 28538, 28616, 29618, 29677, 29691, - 27629, 27468, 27178, 27629, 27178, 27257, 35668, 35569, 35448, 35156, 33971, 35169, 35739, - 35569, 35668, 37483, 37495, 37116, 37912, 37405, 37599, 17098, 17170, 17231, 24646, 24362, - 24474, 24996, 24678, 24868, 24646, 24678, 24806, 24574, 24771, 24706, 24626, 24771, 24574, - 5447, 5456, 5661, 5742, 5724, 6321, 5302, 5447, 5364, 5363, 5125, 5123, 5056, - 5030, 4994, 23177, 23060, 23314, 23963, 23644, 23970, 23963, 23970, 24038, 36325, 36351, - 36258, 36391, 36351, 36325, 36295, 36245, 36156, 36144, 36065, 35975, 26317, 26093, 26795, - 25546, 25395, 25690, 3704, 3779, 3693, 3717, 3701, 3813, 4187, 4353, 4364, 19142, - 19128, 19036, 32418, 32410, 32537, 32213, 32121, 32097, 32402, 32250, 32403, 39061, 39107, - 38917, 31565, 31506, 31583, 31583, 31506, 31546, 35750, 35785, 35810, 35835, 35785, 35750, - 4994, 5030, 4980, 4337, 4266, 4342, 4249, 4266, 4084, 4300, 4266, 4249, 14146, - 14013, 14161, 14326, 14491, 14396, 14252, 13956, 13906, 15863, 16105, 16121, 15617, 15600, - 15484, 25690, 25395, 25545, 38294, 38423, 37832, 37912, 37599, 37860, 23177, 23240, 23154, - 22394, 22382, 22519, 29999, 29653, 29760, 29689, 29677, 29618, 29925, 30083, 30111, 8097, - 7909, 8197, 8181, 8195, 8470, 8181, 8470, 8536, 8746, 8536, 8630, 17367, 17304, - 17359, 17447, 17304, 17367, 17262, 17175, 16622, 19024, 19142, 19036, 3701, 3703, 3753, - 19286, 19058, 19160, 17447, 17278, 17304, 19024, 18942, 17548, 22628, 22519, 22568, 22112, - 22345, 22146, 39126, 39089, 39141, 4900, 4994, 4980, 4871, 4988, 4859, 38795, 38761, - 38693, 38574, 38655, 38588, 38752, 38655, 38574, 20597, 20439, 20413, 20135, 20148, 20059, - 20059, 19775, 19680, 19366, 19403, 19453, 19366, 19286, 19403, 19366, 19174, 19286, 19286, - 19174, 19058, 20706, 20617, 20597, 20920, 20617, 20706, 20508, 20617, 20658, 21180, 21123, - 21379, 21421, 21379, 21450, 21421, 21450, 21589, 21421, 21589, 21598, 20849, 20953, 21191, - 21371, 21547, 21347, 21347, 21547, 21469, 21469, 21547, 21644, 21644, 21702, 21744, 21744, - 21724, 21857, 21857, 21977, 21948, 20663, 20622, 20849, 20565, 20444, 20441, 20444, 19756, - 20019, 19756, 19654, 19829, 7966, 7909, 8097, 19756, 19517, 19654, 23546, 23739, 23532, - 23634, 23739, 23546, 33173, 33227, 33007, 33223, 33197, 33173, 33256, 33355, 33223, 33382, - 33364, 33256, 35317, 35169, 35415, 34409, 34470, 35284, 29677, 29907, 29691, 20617, 20439, - 20597, 39059, 39113, 38993, 39084, 39228, 39086, 39086, 39158, 38790, 39105, 39114, 39061, - 39061, 39114, 39107, 39037, 39155, 38887, 39239, 39155, 39037, 39195, 39037, 39024, 39195, - 39024, 39022, 39195, 39022, 39180, 39022, 39057, 39180, 39180, 39057, 39142, 4066, 4042, - 4316, 4066, 4316, 4146, 17022, 16849, 16888, 14326, 14302, 14491, 17098, 16849, 17022, - 38795, 38693, 38629, 38968, 38650, 38671, 13757, 13956, 13746, 16630, 16809, 16633, 16026, - 16105, 15863, 20439, 20354, 20321, 37787, 37794, 37690, 38000, 37828, 37954, 38000, 37954, - 38002, 37659, 37599, 37606, 38544, 38573, 38350, 38352, 38158, 38159, 38714, 38573, 38544, - 38544, 38549, 38746, 39155, 39144, 39059, 38794, 38874, 39454, 26855, 26943, 26944, 24514, - 24646, 24806, 38195, 38148, 37994, 38352, 38159, 38348, 3693, 3779, 3793, 3829, 3875, - 3922, 3829, 3922, 3756, 23060, 22628, 22568, 23177, 23314, 23240, 3693, 3793, 3604, - 8889, 8888, 8982, 14789, 14890, 14798, 15771, 15833, 15863, 14854, 14890, 14789, 14678, - 14670, 14463, 19058, 19017, 19046, 18981, 19017, 19058, 19271, 19415, 19162, 17474, 19024, - 17548, 35965, 35810, 35785, 35997, 36144, 35975, 39194, 39102, 39107, 39107, 39102, 38917, - 38746, 38549, 38642, 3709, 3545, 3770, 3717, 3653, 3701, 3701, 3653, 3703, 3718, - 3612, 3709, 3627, 3612, 3718, 3627, 3718, 3645, 3868, 3688, 3645, 3688, 3676, - 3645, 3697, 3676, 3688, 3734, 3676, 3697, 38614, 38352, 38348, 39122, 38874, 39071, - 4791, 4871, 4859, 14146, 14170, 14302, 12999, 13137, 13000, 3734, 3557, 3676, 3501, - 3611, 3749, 31506, 31376, 31325, 30240, 30066, 30155, 31575, 31376, 31506, 31239, 31462, - 31215, 31545, 31462, 31603, 35946, 35965, 35785, 39206, 39113, 39059, 33355, 33197, 33223, - 14684, 14678, 14463, 38102, 38148, 38185, 30155, 30066, 29914, 29999, 30066, 29963, 30058, - 30083, 29925, 17304, 17278, 17231, 18306, 18406, 18172, 17314, 17355, 17409, 16630, 16633, - 16519, 24646, 24474, 24669, 23644, 23719, 23456, 24646, 24669, 24678, 36351, 36460, 36293, - 37134, 36859, 37001, 36640, 36460, 36351, 38761, 38827, 38605, 3696, 3793, 3785, 3734, - 3488, 3557, 19017, 18951, 18905, 18981, 18951, 19017, 5123, 5125, 5074, 5125, 5120, - 5074, 5120, 5010, 5074, 9472, 9540, 9701, 9406, 9328, 9162, 12696, 12560, 12567, - 11196, 11210, 11579, 12730, 12560, 12696, 18172, 18406, 18428, 23739, 23850, 23919, 23869, - 23850, 23739, 28538, 29000, 28616, 30058, 29925, 29907, 30058, 30146, 30083, 28538, 28436, - 28496, 37651, 37659, 37498, 37307, 37345, 37116, 37001, 36712, 36993, 8954, 9038, 9122, - 8954, 9122, 9111, 5120, 5056, 5010, 12956, 12924, 13000, 11218, 11054, 10669, 18466, - 18462, 18631, 5240, 5302, 5364, 29417, 29172, 29169, 29417, 29478, 29653, 35569, 35500, - 35448, 35530, 35500, 35569, 3700, 3695, 3550, 5010, 5056, 4965, 21598, 21589, 21638, - 28694, 28538, 28496, 39228, 39158, 39086, 4093, 4368, 4300, 37895, 37794, 37822, 38037, - 37794, 37895, 38552, 38369, 38352, 38642, 38669, 38798, 5456, 5374, 5661, 5302, 5370, - 5447, 29400, 29417, 29681, 38102, 38000, 38002, 38294, 37832, 38009, 37912, 37987, 37724, - 38125, 37987, 37912, 3756, 3922, 3836, 3945, 4066, 4146, 9022, 8954, 9111, 18951, - 18886, 18880, 18981, 18886, 18951, 23115, 22628, 23060, 21791, 21866, 21878, 19271, 19162, - 19197, 22250, 22240, 22382, 21168, 21347, 21315, 37752, 37579, 37690, 4249, 4211, 4300, - 4249, 4084, 4211, 12130, 12298, 11579, 10547, 10381, 10412, 10617, 10807, 10671, 10617, - 10671, 10520, 37243, 37062, 36895, 36234, 35711, 35910, 37021, 37062, 37253, 37134, 37251, - 37255, 32250, 32410, 32418, 32402, 32410, 32250, 35317, 35156, 35169, 3792, 3696, 3785, - 4064, 3741, 3836, 23312, 23403, 23150, 23312, 23150, 23146, 7486, 7485, 7655, 7251, - 7072, 7264, 15220, 15102, 15039, 14890, 15102, 15101, 36144, 36295, 36156, 35965, 35997, - 35975, 36004, 35997, 35965, 24305, 23963, 24038, 23177, 23115, 23060, 38272, 37994, 38206, - 38148, 38102, 38002, 38352, 38369, 38158, 38587, 38348, 38573, 4450, 4495, 4539, 4581, - 4696, 4737, 4450, 4539, 4353, 24514, 24549, 24443, 26944, 26943, 27187, 27341, 27690, - 27988, 3624, 3695, 3704, 4476, 4737, 4642, 4900, 4965, 4994, 14326, 14146, 14302, - 12810, 13050, 13276, 14491, 14516, 14396, 35798, 35835, 35750, 34470, 35205, 35277, 15484, - 15600, 15401, 16105, 16258, 16148, 31583, 31646, 31786, 30750, 31008, 31115, 35716, 35750, - 35653, 7485, 7389, 7570, 11210, 11040, 11064, 10304, 10086, 10122, 10384, 10287, 10284, - 9374, 9540, 9472, 16190, 16258, 16105, 16449, 16630, 16519, 25134, 25291, 25327, 24771, - 25028, 24706, 24891, 25028, 24771, 24626, 24179, 24376, 31927, 31668, 31810, 34826, 34980, - 34470, 37723, 37752, 37935, 37794, 37752, 37690, 3923, 4316, 4042, 3642, 3696, 3792, - 3589, 3624, 3704, 30066, 29999, 29914, 31008, 31282, 31115, 3901, 3923, 4042, 3890, - 3923, 3845, 4042, 4066, 3864, 4211, 4093, 4300, 4266, 3992, 4084, 16849, 16483, - 16888, 17278, 17098, 17231, 17069, 17098, 17278, 17447, 17538, 17467, 24362, 24305, 24038, - 24996, 24806, 24678, 24215, 24179, 23850, 26769, 26093, 25985, 25545, 25395, 25327, 38662, - 38587, 38573, 14146, 13876, 14013, 15392, 16182, 15851, 27421, 27341, 27988, 21950, 21977, - 21857, 31810, 31668, 31622, 31810, 31622, 31695, 39375, 39191, 38914, 38798, 39566, 38909, - 4696, 4791, 4859, 4788, 4791, 4733, 10384, 10381, 10547, 13878, 13876, 14146, 35997, - 36154, 36144, 37134, 37001, 37111, 36084, 36154, 35997, 12560, 12536, 12496, 13310, 13492, - 12992, 12278, 12708, 12551, 12825, 12924, 12956, 18663, 18625, 18765, 17611, 17538, 17630, - 18663, 18765, 18886, 30083, 30146, 30111, 29797, 29907, 29677, 3642, 3792, 3675, 3733, - 3825, 3741, 7909, 7824, 7655, 7485, 7486, 7389, 8195, 7966, 8097, 8089, 7966, - 8195, 8746, 8630, 8735, 8746, 8888, 8831, 11733, 12020, 11506, 12786, 12924, 12825, - 13906, 14217, 14252, 15102, 14890, 14854, 15220, 15269, 15102, 37134, 37289, 36859, 37345, - 37483, 37116, 36712, 36787, 36993, 37480, 37483, 37345, 38968, 38671, 38854, 3554, 3926, - 4058, 3703, 3679, 3820, 15220, 15334, 15269, 15617, 15833, 15771, 14217, 14463, 14252, - 21977, 22112, 22146, 35835, 35946, 35785, 35912, 35946, 35835, 35716, 35653, 35617, 39126, - 39122, 39071, 39126, 39071, 39089, 5074, 5001, 5123, 5274, 5302, 5240, 5274, 5331, - 5302, 5302, 5331, 5370, 4965, 5056, 4994, 36561, 36564, 36873, 39328, 38967, 39102, - 38868, 38662, 38573, 27341, 26944, 27187, 26362, 26079, 26415, 26795, 26093, 26769, 27629, - 27894, 27746, 4016, 4093, 4211, 7966, 7824, 7909, 17734, 18013, 18172, 17301, 17355, - 17314, 17301, 17314, 17262, 3728, 3829, 3756, 18625, 18466, 18631, 18588, 18466, 18625, - 19274, 19271, 19197, 19364, 19271, 19274, 39191, 39114, 39105, 4900, 4980, 4871, 29660, - 29689, 29460, 29397, 29040, 29000, 37062, 37021, 36909, 37243, 36895, 37224, 37414, 37403, - 37597, 37651, 37498, 37495, 8831, 8888, 8889, 8831, 8889, 8954, 32097, 31939, 31819, - 31695, 31622, 31603, 36369, 35929, 36286, 35519, 35317, 35415, 35617, 35653, 35594, 7233, - 7366, 7389, 7233, 7082, 7366, 9374, 9355, 9540, 9540, 9664, 9701, 8927, 9084, - 8887, 38000, 38074, 37895, 38272, 38206, 38334, 38206, 38267, 38334, 9797, 9664, 9489, - 23963, 23719, 23644, 23958, 23719, 23963, 23403, 23634, 23546, 23642, 23634, 23403, 32097, - 31819, 31927, 35284, 35479, 34739, 39070, 38968, 38854, 39141, 39089, 38983, 39070, 38854, - 38827, 38879, 38827, 38761, 15686, 15833, 15617, 16258, 16449, 16396, 17205, 17301, 17262, - 3646, 3653, 3717, 9022, 8831, 8954, 19500, 19453, 19680, 22394, 22250, 22382, 22394, - 22519, 22628, 39114, 39194, 39107, 38983, 38926, 39218, 4788, 4900, 4871, 4788, 4871, - 4791, 12999, 13444, 13137, 37021, 36953, 36843, 36873, 36564, 37124, 18466, 18428, 18406, - 18494, 18428, 18466, 23154, 23115, 23177, 36504, 36286, 36219, 10243, 10216, 10304, 10243, - 10304, 10381, 9935, 10334, 10050, 11403, 11733, 11506, 37102, 37292, 37290, 35946, 36004, - 35965, 35912, 36004, 35946, 8844, 8887, 8176, 19364, 19415, 19271, 16622, 16809, 16630, - 24514, 24305, 24362, 24514, 24362, 24646, 32408, 32410, 32402, 32664, 32537, 32410, 32664, - 32685, 32537, 34188, 34826, 34470, 35284, 35400, 35479, 3589, 3704, 3693, 39187, 38675, - 39172, 7082, 7072, 7251, 6768, 7072, 7082, 16465, 16483, 16849, 17069, 16849, 17098, - 16304, 16449, 16258, 13906, 13956, 13757, 15431, 15484, 15401, 14684, 14789, 14678, 17877, - 17734, 18172, 17290, 17069, 17278, 38164, 38009, 37967, 38655, 38795, 38629, 38125, 37967, - 37987, 4495, 4476, 4608, 4353, 4691, 4364, 20622, 20738, 20849, 21547, 21702, 21644, - 21977, 22089, 22112, 20643, 20738, 20622, 20643, 20622, 20565, 20441, 20444, 20304, 31115, - 31282, 31305, 38334, 38267, 38369, 38538, 38348, 38587, 38662, 38538, 38587, 38798, 38669, - 39566, 39211, 39195, 39180, 39211, 39239, 39195, 39195, 39239, 39037, 39155, 39225, 39144, - 39144, 39206, 39059, 39113, 39228, 39084, 39158, 39375, 38914, 39191, 39269, 39114, 39114, - 39269, 39194, 39211, 39180, 39208, 39180, 39142, 39208, 39142, 39282, 39208, 4733, 4791, - 4696, 20354, 20306, 20135, 20439, 20429, 20354, 20617, 20508, 20439, 20920, 20706, 21123, - 20920, 21123, 21180, 21379, 21421, 21180, 20738, 20785, 20849, 32030, 32097, 31927, 32403, - 32408, 32402, 35604, 35530, 35569, 35156, 35012, 33971, 35604, 35569, 35757, 35511, 35573, - 35479, 35479, 35573, 35594, 35716, 35798, 35750, 36295, 36144, 36296, 3535, 3545, 3709, - 3611, 3554, 4058, 3646, 3593, 3653, 3535, 3709, 3612, 3535, 3612, 3516, 3612, - 3491, 3516, 3627, 3645, 3582, 7824, 7486, 7655, 20304, 20444, 20019, 39239, 39225, - 39155, 39461, 39335, 39211, 3582, 3645, 3676, 15431, 15401, 15334, 15901, 16026, 15863, - 21180, 21421, 21274, 20785, 20953, 20849, 31565, 31575, 31506, 31786, 31646, 32297, 31810, - 32030, 31927, 31603, 31462, 31475, 35942, 35798, 35716, 22473, 22394, 22628, 23240, 23314, - 23456, 23240, 23456, 23514, 19174, 18981, 19058, 19107, 18981, 19174, 20363, 20306, 20354, - 20019, 19756, 19829, 22473, 22628, 22569, 21561, 21421, 21598, 39194, 39160, 39102, 39221, - 39160, 39194, 39556, 39461, 39211, 14382, 14684, 14463, 38102, 38076, 38000, 38305, 38195, - 37994, 12730, 12536, 12560, 12720, 12536, 12730, 20306, 20148, 20135, 37706, 37414, 37597, - 37185, 37044, 36953, 37723, 37579, 37752, 37483, 37620, 37495, 37319, 37345, 37307, 37319, - 37307, 37289, 37319, 37289, 37446, 37289, 37134, 37255, 39339, 39206, 39144, 37467, 37507, - 37491, 37467, 37480, 37345, 21866, 22101, 21878, 20953, 21168, 21191, 32403, 32250, 32254, - 35519, 35415, 35500, 33969, 34704, 34826, 8927, 9025, 9256, 9355, 9664, 9540, 5370, - 5327, 5456, 8176, 8887, 8835, 5274, 5240, 5091, 5000, 5074, 5010, 5000, 5010, - 4942, 5000, 4996, 5001, 29172, 28999, 29087, 29417, 29400, 29172, 29681, 29417, 29653, - 29963, 29653, 29999, 30168, 30244, 30146, 29807, 29397, 29570, 29660, 29807, 29829, 37466, - 37243, 37224, 38868, 38714, 39047, 3923, 3890, 4195, 3636, 3793, 3615, 3845, 3923, - 3901, 5010, 4965, 4942, 12924, 12999, 13000, 13836, 13906, 13757, 12786, 12999, 12924, - 12786, 12825, 12708, 37624, 37620, 37483, 38237, 38125, 38243, 19911, 20019, 19829, 3653, - 3679, 3703, 3538, 3679, 3653, 13836, 13757, 13516, 15039, 14854, 14719, 30146, 30244, - 30111, 29797, 29677, 29689, 23634, 23869, 23739, 25093, 25134, 25028, 25093, 25291, 25134, - 23642, 23869, 23634, 30879, 30715, 30378, 36214, 36144, 36154, 36214, 36154, 36084, 14326, - 14227, 14146, 12992, 13365, 13049, 14516, 14491, 14750, 38185, 38076, 38102, 37860, 37599, - 37659, 8749, 9022, 8833, 10384, 10243, 10381, 10216, 10243, 10217, 23514, 23456, 23719, - 22569, 22628, 22855, 23146, 23118, 22345, 22089, 22345, 22112, 39332, 39228, 39113, 37649, - 37651, 37495, 25093, 25028, 24987, 25774, 25985, 25778, 32254, 32250, 32213, 32210, 32207, - 32255, 32030, 31810, 32073, 35757, 35569, 35739, 35530, 35519, 35500, 35798, 35912, 35835, - 35573, 35617, 35594, 35664, 35617, 35573, 35819, 35757, 35739, 36659, 36219, 36395, 36659, - 36490, 36953, 3557, 3582, 3676, 19812, 19911, 19829, 39228, 39242, 39158, 15901, 15863, - 15833, 16552, 16622, 16630, 31757, 31575, 31565, 31801, 31575, 31757, 31475, 31462, 31414, - 35942, 35912, 35798, 38423, 38639, 38054, 3636, 3604, 3793, 3488, 3734, 3700, 3793, - 3696, 3615, 11864, 11733, 11403, 12645, 12786, 12708, 29660, 29797, 29689, 33201, 33204, - 33124, 32254, 32213, 32210, 35277, 35400, 35284, 35455, 35400, 35277, 3500, 3554, 3611, - 37915, 37752, 37794, 4458, 4476, 4495, 4301, 4353, 4187, 38261, 38185, 38195, 38195, - 38185, 38148, 38584, 38334, 38369, 7990, 8181, 8079, 8079, 8181, 8536, 7966, 7757, - 7824, 7824, 7641, 7486, 7294, 7389, 7486, 7294, 7233, 7389, 8181, 8089, 8195, - 9025, 9162, 9328, 10617, 10520, 10171, 14684, 14854, 14789, 15220, 15431, 15334, 15566, - 15686, 15617, 14719, 14684, 14579, 15474, 15431, 15044, 19904, 19775, 20059, 21371, 21702, - 21547, 25774, 25778, 25690, 27961, 27894, 27629, 30616, 30467, 30377, 30522, 30467, 30607, - 35161, 35156, 35317, 35161, 35012, 35156, 33364, 33355, 33256, 37044, 36659, 36953, 38068, - 38037, 37895, 38074, 38000, 38076, 3901, 4042, 3864, 3733, 3728, 3825, 24305, 24514, - 24443, 24305, 23958, 23963, 17734, 17611, 17630, 17700, 17611, 17734, 17877, 18172, 18254, - 24231, 23958, 24305, 30240, 29963, 30066, 3550, 3695, 3523, 3728, 3756, 3825, 33197, - 33294, 33173, 33937, 33537, 33341, 3695, 3624, 3523, 19517, 19415, 19364, 19517, 19756, - 19415, 21878, 22101, 22206, 22101, 22250, 22206, 21702, 21724, 21744, 4458, 4495, 4450, - 4788, 4718, 4900, 15566, 15617, 15484, 35683, 35519, 35530, 36234, 35929, 36369, 38305, - 37994, 38272, 38167, 38164, 37967, 38858, 38752, 38945, 38167, 37967, 38125, 32664, 32410, - 32408, 32210, 32213, 32097, 32210, 32097, 32030, 35400, 35463, 35479, 35968, 35942, 35716, - 35455, 35463, 35400, 36516, 36234, 36369, 36505, 36369, 36504, 36295, 36391, 36245, 36084, - 35997, 36004, 36296, 36214, 36402, 10548, 10617, 10171, 9935, 10050, 9797, 16552, 16449, - 16498, 16552, 16630, 16449, 17474, 17548, 17355, 22206, 22250, 22394, 36296, 36391, 36295, - 38798, 38812, 38642, 38538, 38614, 38348, 38909, 38812, 38798, 33502, 33355, 33364, 4064, - 4068, 3817, 23320, 23115, 23154, 23647, 23514, 23719, 18719, 18663, 18886, 18993, 18886, - 18981, 31805, 31810, 31695, 31414, 31462, 31239, 31414, 31239, 31079, 17474, 17355, 17374, - 21724, 21950, 21857, 15722, 15901, 15833, 17611, 17467, 17538, 17469, 17467, 17611, 17374, - 17355, 17301, 33355, 33294, 33197, 37620, 37649, 37495, 37651, 37721, 37659, 37480, 37624, - 37483, 37467, 37477, 37480, 37491, 37477, 37467, 37134, 37111, 37251, 37111, 36993, 37092, - 38031, 37915, 37794, 38173, 38074, 38076, 38831, 38662, 38868, 4612, 4733, 4696, 38031, - 37794, 38037, 3817, 4068, 3890, 3945, 4146, 4133, 5091, 5240, 5123, 5331, 5327, - 5370, 5001, 5074, 5000, 17377, 17278, 17447, 14443, 14516, 14546, 29400, 29315, 29172, - 29374, 29315, 29400, 4942, 4965, 4875, 37635, 37624, 37480, 5242, 5327, 5331, 37243, - 37253, 37062, 37466, 37253, 37243, 37466, 37224, 37414, 37021, 37302, 37185, 37092, 36993, - 37102, 33124, 33204, 33084, 32664, 32408, 32401, 4996, 4942, 4875, 35683, 35530, 35604, - 35683, 35604, 35782, 35463, 35511, 35479, 35664, 35511, 35613, 37736, 37649, 37620, 31801, - 31786, 32055, 31305, 31282, 31383, 3523, 3624, 3482, 3642, 3615, 3696, 4353, 4405, - 4450, 4581, 4612, 4696, 4301, 4405, 4353, 3675, 3792, 3829, 3817, 3890, 3776, - 29397, 29660, 29460, 29797, 29862, 29907, 31503, 31414, 31079, 28694, 29000, 28538, 4254, - 4458, 4450, 38173, 38068, 38074, 38375, 38305, 38272, 38436, 38272, 38334, 5374, 5724, - 5742, 3693, 3604, 3589, 3508, 3537, 3646, 19500, 19366, 19453, 19162, 19142, 19197, - 21950, 22089, 21977, 39345, 39269, 39191, 39160, 39328, 39102, 3967, 3945, 4133, 3967, - 4133, 4093, 4016, 4211, 4084, 4549, 4555, 4431, 16622, 17205, 17262, 16190, 16105, - 16127, 25545, 25774, 25690, 24891, 24771, 24626, 38847, 38795, 38655, 38752, 38574, 38639, - 16127, 16105, 16026, 15686, 15722, 15833, 15474, 15566, 15484, 15474, 15484, 15431, 38719, - 38614, 38538, 16127, 16026, 15944, 37466, 37414, 37713, 38051, 38031, 38037, 38068, 37895, - 38074, 38858, 38977, 38884, 3776, 3890, 3845, 3776, 3845, 3822, 17467, 17377, 17447, - 17469, 17377, 17467, 23869, 24215, 23850, 24195, 24215, 23869, 23642, 23403, 23481, 31585, - 31376, 31575, 29973, 29845, 29963, 37102, 36993, 36873, 36214, 36296, 36144, 36084, 36004, - 35912, 31805, 31695, 31603, 30879, 30378, 30485, 35942, 36084, 35912, 16182, 16255, 16265, - 14396, 14227, 14326, 29963, 29845, 29653, 30240, 30155, 30467, 29829, 29862, 29797, 31016, - 30879, 30899, 36733, 36505, 36504, 35782, 35604, 35757, 36516, 36505, 36733, 36564, 36460, - 36710, 38164, 38294, 38009, 38237, 38167, 38125, 3537, 3593, 3646, 3613, 4056, 3867, - 19197, 19142, 19024, 25545, 25327, 25291, 35308, 35161, 35317, 35739, 36036, 35935, 3675, - 3829, 3728, 3817, 3741, 4064, 18254, 18172, 18428, 17752, 17877, 17765, 23353, 23403, - 23312, 35775, 35716, 35617, 3589, 3604, 3515, 3604, 3636, 3515, 3593, 3538, 3653, - 19177, 19197, 19088, 10086, 10304, 10216, 8441, 8079, 8746, 29862, 30058, 29907, 3675, - 3728, 3546, 39172, 38675, 38958, 38947, 39454, 39282, 39172, 38958, 38968, 14419, 14227, - 14396, 37935, 37752, 37915, 38051, 38068, 38173, 23958, 23844, 23719, 24443, 24231, 24305, - 25340, 25616, 25098, 16304, 16498, 16449, 16552, 16570, 16622, 16304, 16258, 16190, 28124, - 27894, 27961, 27178, 26971, 27257, 19366, 19107, 19174, 26803, 26769, 26587, 39269, 39221, - 39194, 4431, 4652, 4645, 3822, 3845, 3901, 15944, 16026, 15901, 26587, 26769, 25985, - 25430, 25545, 25291, 25430, 25291, 25339, 29315, 28999, 29172, 27341, 27421, 26944, 29391, - 28999, 29315, 37649, 37721, 37651, 37624, 37736, 37620, 37477, 37635, 37480, 37507, 37467, - 37319, 37507, 37319, 37446, 17877, 17752, 17734, 18588, 18625, 18663, 38905, 38879, 38761, - 38905, 38761, 38795, 15039, 15431, 15220, 15566, 15722, 15686, 15039, 15102, 14854, 38614, - 38552, 38352, 38261, 38076, 38185, 38703, 38552, 38614, 38719, 38538, 38662, 4947, 5018, - 5001, 5001, 5018, 5123, 5274, 5242, 5331, 5327, 5206, 5456, 4996, 5000, 4942, - 13492, 13365, 12992, 12536, 11961, 12496, 12999, 12891, 13516, 13906, 13836, 14217, 12645, - 12708, 12278, 11864, 12278, 11733, 37629, 37635, 37477, 4439, 4645, 4776, 4736, 4953, - 4978, 20544, 20658, 20661, 20920, 20658, 20617, 20508, 20429, 20439, 20306, 20363, 20148, - 20148, 19904, 20059, 19775, 19500, 19680, 19273, 18996, 19107, 20658, 20678, 20661, 21561, - 21598, 21791, 20785, 20848, 20953, 20953, 21143, 21168, 21168, 21371, 21347, 21702, 21771, - 21724, 21724, 21888, 21950, 21950, 21888, 22089, 20738, 20671, 20785, 20441, 20643, 20565, - 20400, 20643, 20441, 20671, 20643, 20574, 20400, 20304, 20336, 20070, 20019, 19893, 19812, - 19829, 19772, 19829, 19654, 19772, 19654, 19547, 19772, 19517, 19547, 19654, 35664, 35573, - 35511, 35664, 35775, 35617, 38309, 38294, 38164, 38309, 38164, 38167, 39239, 39287, 39225, - 39225, 39339, 39144, 39206, 39352, 39113, 39228, 39356, 39242, 39242, 39375, 39158, 39269, - 39602, 39221, 39335, 39287, 39239, 39335, 39239, 39211, 39454, 39411, 39282, 39122, 39126, - 39362, 39287, 39305, 39225, 20658, 20429, 20508, 20671, 20848, 20785, 29845, 29681, 29653, - 30522, 30240, 30467, 23344, 23146, 23242, 20429, 20363, 20354, 4875, 4900, 4700, 4875, - 4965, 4900, 13492, 13705, 13365, 19107, 18993, 18981, 18996, 18993, 19107, 3491, 3612, - 3627, 3535, 3516, 3545, 3545, 3501, 3749, 3554, 3508, 3646, 3537, 3478, 3593, - 3593, 3360, 3538, 3491, 3627, 3511, 3627, 3582, 3511, 3416, 3414, 3511, 3288, - 3501, 3545, 39377, 39339, 39225, 37239, 37251, 37111, 37239, 37111, 37092, 3582, 3557, - 3494, 10217, 10086, 10216, 10384, 10398, 10332, 21027, 21143, 20953, 23396, 23353, 23146, - 30702, 30467, 30616, 31801, 31585, 31575, 31613, 31585, 31700, 4581, 4737, 4476, 15755, - 15722, 15566, 38764, 38719, 38831, 3494, 3557, 3488, 4718, 4788, 4733, 21143, 21229, - 21168, 37736, 37721, 37649, 39339, 39352, 39206, 39362, 39126, 39141, 3492, 3733, 3741, - 3592, 3675, 3546, 3864, 4066, 3945, 25502, 25875, 25697, 24137, 23844, 23958, 24215, - 24376, 24179, 24235, 24376, 24215, 24195, 23869, 23991, 29660, 29829, 29797, 30280, 30168, - 30058, 30485, 30378, 30244, 29807, 29660, 29397, 39352, 39332, 39113, 3595, 3636, 3615, - 3488, 3700, 3550, 3595, 3615, 3642, 17752, 17700, 17734, 17153, 16919, 17069, 17765, - 17700, 17752, 23320, 23154, 23240, 21710, 21561, 21791, 23320, 23240, 23514, 24137, 23958, - 24231, 33294, 33271, 33173, 33355, 33440, 33294, 33537, 33502, 33364, 33667, 33502, 33537, - 3642, 3675, 3592, 23392, 23320, 23514, 38752, 38847, 38655, 38858, 38847, 38752, 3501, - 3500, 3611, 21229, 21371, 21168, 39332, 39356, 39228, 30240, 30326, 29963, 30616, 30750, - 30817, 3811, 3864, 3945, 24693, 24891, 24626, 38868, 38573, 38714, 39306, 38377, 38967, - 39525, 39172, 38968, 39014, 38905, 38795, 35782, 35819, 35935, 35308, 35317, 35334, 33937, - 33667, 33537, 15902, 15944, 15901, 16144, 16304, 16190, 19905, 19904, 20079, 32401, 32408, - 32403, 32401, 32403, 32254, 35758, 35519, 35683, 34188, 33969, 34826, 37185, 36953, 37021, - 35739, 35711, 36036, 37935, 37915, 38084, 36640, 36351, 36517, 4458, 4433, 4476, 4405, - 4254, 4450, 3586, 3986, 3679, 3538, 3586, 3679, 3359, 3586, 3538, 14227, 14140, - 14146, 14168, 14140, 14227, 14419, 14396, 14516, 16255, 16483, 16265, 21710, 21791, 21878, - 22855, 22628, 23115, 38068, 38051, 38037, 38261, 38195, 38305, 33413, 33271, 33294, 10384, - 10332, 10287, 19904, 19815, 19775, 19517, 19364, 19471, 22206, 22394, 22473, 16265, 16483, - 16357, 38552, 38584, 38369, 38703, 38584, 38552, 38436, 38584, 38741, 30879, 31016, 31079, - 31805, 31603, 31726, 30168, 30146, 30058, 3747, 3822, 3901, 3546, 3733, 3492, 5373, - 5033, 4766, 5570, 5033, 5526, 4655, 4718, 4733, 4655, 4733, 4612, 23146, 23353, - 23312, 23396, 23344, 23492, 38064, 37915, 38031, 39070, 38827, 38879, 39187, 39218, 38926, - 3488, 3444, 3459, 19471, 19364, 19348, 4207, 4433, 4458, 9025, 9128, 9162, 9797, - 10050, 9664, 8927, 8844, 9025, 9059, 8944, 9067, 33271, 33227, 33173, 34175, 33455, - 33380, 32974, 32943, 32685, 38375, 38261, 38305, 38294, 38813, 38423, 38400, 38309, 38167, - 35205, 35229, 35277, 35250, 35229, 35205, 18993, 18719, 18886, 18888, 18719, 18993, 30280, - 30058, 29862, 30607, 30702, 30817, 30522, 30385, 30240, 21520, 21771, 21702, 31603, 31475, - 31726, 35572, 35511, 35463, 35775, 35968, 35716, 36402, 36214, 36332, 36402, 36391, 36296, - 36517, 36351, 36391, 3935, 3967, 4093, 3864, 3747, 3901, 3935, 4093, 4016, 4947, - 5001, 4996, 4968, 5091, 5018, 5018, 5091, 5123, 4947, 4996, 4850, 16919, 16849, - 17069, 16144, 16190, 16127, 16498, 16570, 16552, 19348, 19274, 19177, 37854, 37860, 37721, - 37491, 37629, 37477, 37446, 37289, 37441, 37289, 37255, 37364, 38847, 38908, 38795, 38752, - 38639, 38945, 9374, 9365, 9355, 11403, 11506, 11218, 12810, 12720, 12730, 12869, 12720, - 12810, 12872, 12810, 12992, 24891, 24987, 25028, 25545, 25537, 25774, 25121, 24987, 24891, - 24657, 24626, 24376, 31726, 31475, 31414, 5091, 5133, 5274, 37863, 37597, 37723, 37364, - 37255, 37251, 3444, 3550, 3397, 21771, 21888, 21724, 13049, 12872, 12992, 13341, 13836, - 13516, 3597, 3613, 3867, 5124, 5242, 5274, 23353, 23481, 23403, 23396, 23481, 23353, - 37383, 37364, 37251, 3992, 4266, 4337, 39365, 39218, 39187, 23764, 23647, 23719, 23001, - 22855, 23115, 24549, 24137, 24231, 3432, 3508, 3554, 3597, 3662, 3613, 3711, 3747, - 3864, 3741, 3817, 3656, 19815, 19500, 19775, 39522, 39375, 39242, 39221, 39328, 39160, - 30596, 30385, 30522, 30168, 30410, 30244, 10669, 11054, 10617, 12786, 12838, 12999, 29842, - 29681, 29845, 37208, 37092, 37290, 37208, 37239, 37092, 8833, 9022, 10020, 10284, 10217, - 10243, 10284, 10243, 10384, 15474, 15755, 15566, 16016, 16127, 15944, 16016, 16144, 16127, - 14719, 14854, 14684, 38584, 38436, 38334, 38450, 38633, 38583, 3508, 3478, 3537, 19348, - 19364, 19274, 19274, 19197, 19177, 39375, 39345, 39191, 14382, 14463, 14217, 37721, 37860, - 37659, 37639, 37624, 37635, 38276, 38064, 38051, 38051, 38064, 38031, 38450, 38375, 38272, - 3589, 3482, 3624, 3581, 3595, 3642, 3581, 3642, 3592, 18719, 18588, 18663, 18613, - 18588, 18719, 23001, 23115, 23320, 22366, 22206, 22473, 33969, 33772, 34370, 35440, 35455, - 35277, 37044, 37277, 36659, 37362, 37021, 37253, 3613, 3662, 4056, 3597, 3867, 3390, - 4429, 4581, 4366, 4819, 4850, 4875, 38173, 38076, 38261, 37472, 37362, 37466, 16389, - 16570, 16498, 16389, 16498, 16304, 3967, 3879, 3945, 4084, 3935, 4016, 15755, 15901, - 15722, 25339, 25291, 25093, 35367, 35277, 35229, 19088, 19024, 18638, 14546, 14516, 14750, - 12869, 12810, 12872, 17205, 17374, 17301, 23991, 23869, 23642, 25434, 25537, 25430, 30702, - 30607, 30467, 30385, 30326, 30240, 30817, 30750, 30992, 17290, 17278, 17377, 16887, 16919, - 16843, 8089, 7914, 7966, 8181, 7990, 8089, 8079, 8536, 8746, 18588, 18494, 18466, - 18613, 18494, 18588, 22474, 22473, 22569, 23086, 23001, 23320, 22761, 22569, 22855, 39278, - 39362, 39141, 7990, 7914, 8089, 23764, 23719, 23844, 33271, 33413, 33227, 33502, 33440, - 33355, 33937, 33341, 34429, 10171, 10520, 10223, 9128, 9365, 9162, 35819, 35782, 35757, - 35711, 36234, 36036, 37863, 37723, 37991, 38381, 38173, 38261, 7914, 7757, 7966, 11196, - 11040, 11210, 10217, 10088, 10086, 31383, 31282, 31376, 31613, 31376, 31585, 31757, 31786, - 31801, 32664, 32974, 32685, 32210, 32401, 32254, 32398, 32401, 32210, 35455, 35572, 35463, - 35959, 35968, 35775, 35703, 35572, 35455, 4580, 4655, 4612, 19088, 19197, 19024, 12720, - 12548, 12536, 12665, 12548, 12720, 12869, 12872, 12905, 12475, 12645, 12322, 37507, 37629, - 37491, 37617, 37629, 37507, 37617, 37507, 37446, 37441, 37289, 37364, 3728, 3733, 3546, - 3463, 3482, 3589, 30287, 30326, 30385, 30100, 30326, 30287, 7757, 7641, 7824, 7233, - 6768, 7082, 4470, 4550, 4736, 33667, 33440, 33502, 4102, 4187, 4364, 4182, 4254, - 4405, 4478, 4580, 4581, 4581, 4580, 4612, 4968, 4947, 4858, 5096, 5124, 5133, - 5133, 5124, 5274, 5096, 5133, 5091, 5242, 5224, 5327, 13705, 13876, 13365, 24195, - 24235, 24215, 24575, 24235, 24446, 29567, 29374, 29400, 27988, 27690, 28462, 29391, 29374, - 29567, 31646, 32371, 32297, 37383, 37441, 37364, 37383, 37251, 37239, 37636, 37639, 37635, - 38436, 38450, 38272, 38375, 38381, 38261, 38703, 38614, 38764, 39212, 39070, 38879, 39370, - 38983, 39218, 39370, 39141, 38983, 39048, 38879, 38905, 16265, 16060, 16182, 14486, 14419, - 14443, 16726, 16465, 16849, 38884, 38908, 38847, 38884, 38847, 38858, 30992, 30750, 31115, - 36402, 36332, 36510, 25430, 25537, 25545, 25339, 25093, 25254, 5178, 5224, 5242, 12905, - 13049, 13035, 18638, 19024, 18098, 33440, 33413, 33294, 37466, 37362, 37253, 36036, 36234, - 36270, 37723, 37935, 37991, 37639, 37736, 37624, 38243, 38125, 37912, 38764, 38614, 38719, - 16919, 16887, 16849, 17290, 17377, 17338, 24443, 24549, 24231, 23796, 23764, 23844, 26079, - 26098, 26415, 26079, 26362, 26085, 18254, 17765, 17877, 23605, 23392, 23514, 23796, 23844, - 24137, 35161, 35295, 35012, 35550, 35317, 35519, 35292, 35250, 35205, 20848, 21027, 20953, - 21143, 21116, 21229, 21229, 21331, 21371, 21371, 21520, 21702, 21771, 21840, 21888, 20643, - 20671, 20738, 20400, 20441, 20304, 20304, 20019, 20070, 19911, 19893, 20019, 19812, 19893, - 19911, 19789, 19893, 19812, 19789, 19812, 19772, 39305, 39377, 39225, 39339, 39408, 39352, - 39352, 39401, 39332, 39332, 39401, 39356, 39356, 39412, 39242, 39375, 39570, 39345, 39287, - 39441, 39305, 39335, 39441, 39287, 39461, 39441, 39335, 39211, 39208, 39556, 39411, 39208, - 39282, 4736, 4550, 4953, 4431, 4109, 4549, 3797, 3967, 3935, 5767, 5033, 5570, - 20079, 19904, 20148, 19505, 19500, 19815, 19337, 19402, 19500, 20429, 20473, 20363, 20658, - 20544, 20429, 21211, 20920, 21180, 21211, 21180, 21274, 39441, 39433, 39305, 3515, 3636, - 3493, 3817, 3776, 3656, 6232, 7008, 6509, 20544, 20473, 20429, 19682, 19789, 19772, - 35572, 35613, 35511, 35703, 35613, 35572, 35782, 35758, 35683, 37184, 37044, 37185, 37412, - 37208, 37290, 38084, 37915, 38064, 37846, 37854, 37721, 39433, 39377, 39305, 3636, 3595, - 3493, 4447, 4439, 4776, 14443, 14419, 14516, 14491, 15331, 14750, 13936, 14382, 14217, - 14719, 14713, 15039, 15808, 15712, 15776, 14579, 14515, 14688, 15755, 15712, 15808, 16236, - 16389, 16304, 19273, 19107, 19366, 17439, 17469, 17512, 19402, 19366, 19500, 30473, 30485, - 30410, 30410, 30485, 30244, 31503, 31726, 31414, 32255, 32398, 32210, 30280, 30410, 30168, - 30280, 30329, 30375, 39370, 39218, 39475, 39454, 38874, 39122, 20965, 21027, 20848, 39377, - 39408, 39339, 21027, 21116, 21143, 23396, 23146, 23344, 17469, 17611, 17700, 19542, 19292, - 19610, 16570, 17205, 16622, 16475, 17205, 16570, 34370, 33772, 34366, 34980, 35149, 35205, - 3511, 3414, 3491, 3491, 3393, 3516, 3516, 3393, 3545, 3343, 3554, 3238, 3343, - 3432, 3554, 3508, 3432, 3478, 3416, 3511, 3582, 3416, 3582, 3426, 3582, 3494, - 3426, 19471, 19547, 19517, 21274, 21421, 21561, 36373, 36084, 35942, 39454, 39122, 39362, - 5206, 5374, 5456, 9025, 8844, 8826, 30100, 29973, 29963, 29842, 29973, 30080, 37302, - 37184, 37185, 30287, 30385, 30596, 31161, 30992, 31115, 31161, 31115, 31305, 37412, 37383, - 37208, 36522, 36517, 36391, 3426, 3494, 3459, 3797, 3879, 3967, 3656, 3776, 3678, - 3811, 3879, 3505, 16465, 16357, 16483, 16437, 16357, 16465, 16726, 16849, 16887, 16236, - 16304, 16144, 21298, 21274, 21388, 35346, 35367, 35250, 35250, 35367, 35229, 38945, 38639, - 39216, 38908, 39014, 38795, 39537, 39401, 39352, 39543, 39454, 39362, 39365, 39187, 39172, - 16843, 16726, 16887, 7641, 7294, 7486, 21256, 21331, 21229, 23481, 23547, 23642, 39401, - 39394, 39356, 15902, 16016, 15944, 35950, 35758, 35782, 4223, 4405, 4301, 19471, 19348, - 19547, 39394, 39412, 39356, 32297, 32371, 32787, 31272, 31161, 31305, 35935, 35950, 35782, - 36516, 36369, 36505, 38703, 38656, 38584, 38463, 38381, 38375, 38741, 38656, 38703, 18996, - 18888, 18993, 18705, 18888, 18785, 3459, 3494, 3488, 19547, 19348, 19326, 35000, 35032, - 34826, 33159, 32974, 32664, 34826, 35027, 34980, 14750, 15331, 14805, 12905, 12872, 13049, - 14382, 14579, 14684, 15755, 15902, 15901, 14713, 14579, 14688, 38463, 38375, 38583, 38194, - 38084, 38064, 17290, 17153, 17069, 17138, 17153, 17290, 17469, 17700, 17765, 24806, 24549, - 24514, 35367, 35440, 35277, 36020, 35968, 35959, 35690, 35440, 35367, 3493, 3595, 3446, - 3776, 3822, 3678, 23605, 23514, 23647, 22887, 22761, 22855, 21874, 21710, 21878, 23605, - 23647, 23796, 22002, 22089, 21888, 37736, 37846, 37721, 37639, 38095, 37736, 37629, 37636, - 37635, 37441, 37617, 37446, 37788, 37617, 37441, 5178, 5206, 5224, 5224, 5206, 5327, - 4864, 5096, 5091, 4968, 5018, 4947, 38831, 38719, 38662, 4900, 4718, 4700, 4850, - 4996, 4875, 12844, 12665, 12869, 12869, 12665, 12720, 11579, 12298, 11629, 14146, 14140, - 13878, 12645, 12656, 12786, 12475, 12656, 12645, 37617, 37636, 37629, 3595, 3581, 3446, - 3444, 3488, 3550, 4700, 4718, 4655, 13878, 14140, 13900, 37863, 37706, 37597, 37362, - 37302, 37021, 37905, 37706, 37863, 39328, 39221, 39484, 39422, 39328, 39484, 38714, 38746, - 39047, 4478, 4581, 4454, 12298, 12496, 11629, 13900, 14140, 13994, 16357, 16269, 16265, - 16245, 16269, 16357, 16437, 16465, 16726, 16294, 16236, 16144, 16389, 16392, 16570, 16392, - 16236, 16294, 21790, 21710, 21874, 25254, 25093, 24987, 25537, 25800, 25774, 27257, 26971, - 26795, 24657, 24376, 24235, 30100, 29963, 30326, 31383, 31376, 31613, 35027, 35080, 34980, - 31680, 31383, 31613, 38309, 38400, 38294, 38243, 37912, 38485, 38243, 38485, 38397, 3879, - 3811, 3945, 3864, 3811, 3712, 5178, 5242, 5124, 37208, 37383, 37239, 36710, 36460, - 36640, 38095, 37846, 37736, 8441, 8746, 8831, 7782, 7812, 7914, 7914, 7812, 7757, - 7757, 7541, 7641, 7041, 6970, 7294, 7782, 7397, 7243, 36517, 36649, 36640, 36522, - 36649, 36517, 36522, 36391, 36402, 3550, 3523, 3397, 39392, 39362, 39278, 15808, 15902, - 15755, 35673, 35550, 35519, 35308, 35295, 35161, 35673, 35519, 35758, 4075, 4102, 3977, - 4187, 4223, 4301, 3385, 3867, 3586, 31808, 31700, 31801, 31801, 31700, 31585, 31503, - 31079, 31521, 33005, 32977, 32891, 3397, 3523, 3399, 3446, 3581, 3592, 7782, 7914, - 7990, 22887, 22855, 23001, 39328, 39350, 38967, 39422, 39350, 39328, 16712, 16437, 16726, - 18304, 18428, 18494, 24575, 24657, 24235, 30607, 30596, 30522, 29973, 29842, 29845, 37184, - 37277, 37044, 37310, 37302, 37321, 9059, 9128, 8826, 9113, 9128, 9059, 35080, 35149, - 34980, 3478, 3450, 3593, 3554, 3500, 3238, 4366, 4476, 4433, 4162, 4223, 4187, - 4478, 4700, 4655, 13574, 13365, 13876, 19326, 19348, 19177, 19326, 19177, 19088, 4371, - 4261, 3560, 14546, 14486, 14443, 14628, 14750, 14617, 14579, 14713, 14719, 14735, 14713, - 14688, 3523, 3482, 3399, 3432, 3450, 3478, 18705, 18613, 18719, 18705, 18719, 18888, - 30903, 30817, 30992, 36036, 35950, 35935, 35977, 35950, 36071, 36052, 35968, 36020, 36045, - 35968, 36052, 3597, 3547, 3662, 3412, 3547, 3334, 23392, 23086, 23320, 23796, 23647, - 23764, 23396, 23547, 23481, 23492, 23547, 23396, 14628, 14486, 14546, 13197, 13049, 13365, - 32210, 32030, 32207, 35334, 35295, 35308, 35741, 35673, 35758, 38378, 38400, 38167, 38378, - 38167, 38237, 4550, 4447, 4776, 4618, 4631, 4736, 4618, 4736, 4766, 9128, 9196, - 9365, 27894, 28124, 28496, 27257, 26795, 26803, 35334, 35317, 35567, 35149, 35292, 35205, - 39035, 39014, 38908, 39552, 39365, 39172, 39035, 38908, 38884, 25339, 25434, 25430, 25254, - 25434, 25339, 10284, 10148, 10217, 10384, 10547, 10398, 19905, 19815, 19904, 10171, 10223, - 9840, 12547, 12838, 12656, 10223, 9935, 9840, 31161, 31046, 30992, 31126, 31046, 31161, - 31126, 31161, 31272, 36510, 36522, 36402, 36649, 36710, 36640, 3678, 3822, 3747, 3362, - 3463, 3380, 17469, 17439, 17377, 17338, 17439, 17295, 10148, 10088, 10217, 24657, 24693, - 24626, 24575, 24693, 24657, 38824, 38741, 38703, 38583, 38375, 38450, 38746, 39127, 39047, - 18613, 18475, 18494, 18577, 18475, 18613, 30903, 30607, 30817, 30485, 30899, 30879, 30438, - 30280, 30375, 4439, 4347, 4431, 4376, 4447, 4550, 19402, 19273, 19366, 19326, 19292, - 19542, 29391, 29315, 29374, 28569, 28462, 28999, 24779, 24461, 24549, 36785, 36710, 36649, - 37912, 37860, 38485, 35567, 35317, 35550, 38194, 38064, 38276, 38051, 38173, 38276, 29567, - 29400, 29681, 29567, 29681, 29749, 29681, 29842, 29749, 12656, 12838, 12786, 12645, 12278, - 12322, 33314, 32371, 33227, 31700, 31680, 31613, 32073, 31810, 31805, 32977, 33159, 32664, - 4858, 4947, 4850, 4864, 5091, 4968, 5075, 5124, 5096, 5075, 5178, 5124, 5206, - 5164, 5374, 29749, 29842, 29814, 31800, 31805, 31726, 31800, 31918, 31805, 35968, 36045, - 35942, 35703, 35455, 35440, 4223, 4182, 4405, 4819, 4875, 4724, 4130, 4182, 4223, - 3399, 3482, 3463, 3589, 3515, 3463, 4102, 4162, 4187, 4075, 4162, 4102, 12230, - 11961, 12548, 12905, 12844, 12869, 13197, 13035, 13049, 13197, 13365, 13269, 14617, 14750, - 14805, 16843, 16919, 17019, 23408, 23086, 23392, 22592, 22474, 22569, 39442, 39365, 39770, - 39475, 39392, 39278, 17439, 17338, 17377, 17138, 17338, 17295, 14168, 14227, 14419, 14750, - 14628, 14546, 16209, 16265, 16269, 38450, 38436, 38633, 25434, 25486, 25537, 25491, 25486, - 25434, 30080, 29973, 30100, 37383, 37788, 37441, 37617, 38095, 37636, 38357, 37854, 37846, - 37290, 37092, 37102, 39216, 38639, 38423, 26415, 26841, 26362, 30438, 30473, 30410, 9196, - 9355, 9365, 3712, 3711, 3864, 3712, 3811, 3505, 5033, 4854, 4779, 4538, 4470, - 4736, 13574, 13876, 13878, 17042, 16919, 17153, 13873, 13900, 13994, 35292, 35346, 35250, - 35149, 35346, 35292, 35080, 35290, 35149, 35027, 35058, 35080, 34826, 35032, 35027, 33772, - 34327, 34366, 38276, 38173, 38545, 3463, 3515, 3380, 10287, 10148, 10284, 10398, 11064, - 11040, 36522, 36785, 36649, 36332, 36214, 36084, 39475, 39278, 39370, 23507, 23408, 23392, - 24162, 23796, 24137, 23709, 23796, 24015, 10088, 10005, 10086, 10166, 10148, 10287, 31521, - 31079, 31147, 4447, 4347, 4439, 4363, 4347, 4447, 26803, 26795, 26769, 38400, 38813, - 38294, 38355, 38378, 38237, 38355, 38237, 38243, 37302, 37310, 37184, 37472, 37302, 37362, - 37472, 37466, 37748, 37991, 37935, 38084, 37292, 37102, 36873, 37292, 36873, 37287, 32073, - 32207, 32030, 33350, 33159, 33542, 32073, 31805, 31918, 20400, 20574, 20643, 20671, 20887, - 20848, 21027, 21040, 21116, 21116, 21256, 21229, 21331, 21493, 21371, 20336, 20574, 20400, - 20336, 20304, 20313, 20304, 20070, 20313, 20070, 20151, 20313, 20122, 20151, 20070, 20604, - 20887, 20671, 4755, 4618, 4766, 20061, 20122, 20070, 20887, 20965, 20848, 37992, 37991, - 38129, 35032, 35058, 35027, 3414, 3393, 3491, 3432, 3343, 3450, 3289, 3393, 3414, - 3373, 3414, 3416, 3373, 3416, 3426, 3373, 3426, 3336, 3426, 3459, 3336, 3459, - 3365, 3336, 6509, 7008, 7072, 6768, 7233, 7294, 19893, 20061, 20070, 32055, 31808, - 31801, 31739, 31800, 31726, 3483, 3492, 3741, 3564, 3678, 3747, 19893, 19950, 20061, - 35637, 35567, 35550, 35637, 35550, 35673, 39408, 39480, 39352, 39401, 39537, 39394, 39394, - 39642, 39412, 39412, 39522, 39242, 39377, 39480, 39408, 39668, 39480, 39377, 39668, 39377, - 39433, 39668, 39433, 39441, 39668, 39441, 39461, 39556, 39208, 39411, 39556, 39411, 39656, - 10669, 11403, 11218, 19893, 19796, 19950, 30287, 30135, 30100, 30204, 30135, 30397, 30903, - 30992, 31104, 39480, 39537, 39352, 16236, 16392, 16389, 19531, 19547, 19326, 16294, 16144, - 16172, 16144, 16016, 16172, 25121, 25254, 24987, 26587, 25985, 25774, 25121, 24891, 24922, - 38288, 37991, 38084, 38545, 38173, 38381, 3459, 3444, 3365, 19950, 19796, 19985, 21040, - 21256, 21116, 22592, 22569, 22701, 22569, 22761, 22701, 39392, 39543, 39362, 39442, 39475, - 39218, 3711, 3629, 3747, 3797, 3935, 4084, 38746, 38812, 39127, 38741, 38584, 38656, - 25800, 25537, 25486, 38703, 38764, 38824, 38463, 38482, 38381, 19682, 19772, 19547, 32057, - 32073, 31918, 32401, 32891, 32664, 12322, 12278, 11864, 12838, 12891, 12999, 34505, 34370, - 34366, 35032, 35071, 35058, 33159, 33201, 32974, 5033, 5767, 4854, 4535, 4538, 4618, - 10548, 10669, 10617, 9813, 9935, 9797, 10203, 10166, 10287, 10661, 10398, 11040, 10380, - 10398, 10509, 21256, 21493, 21331, 31272, 31305, 31452, 36606, 36785, 36522, 36373, 36332, - 36084, 36373, 35942, 36045, 36733, 36504, 36659, 35977, 35741, 35758, 38523, 38482, 38463, - 4825, 4858, 4850, 4819, 4724, 4825, 5015, 5075, 5096, 5107, 5164, 5206, 3461, - 3592, 3546, 3365, 3444, 3358, 22701, 22761, 22887, 30473, 30899, 30485, 30280, 30438, - 30410, 30280, 29862, 30329, 3444, 3397, 3358, 4478, 4655, 4580, 9643, 9813, 9797, - 9196, 9103, 9355, 9128, 9113, 9196, 9128, 9025, 8826, 21493, 21520, 21371, 31104, - 30992, 31046, 30713, 30899, 30473, 31503, 31739, 31726, 31800, 31915, 31918, 31808, 31680, - 31700, 31814, 31680, 31808, 31521, 31739, 31503, 36606, 36522, 36510, 23507, 23392, 23605, - 23507, 23605, 23709, 33413, 33441, 33227, 32297, 32055, 31786, 33440, 33561, 33413, 33667, - 33561, 33440, 33937, 33561, 33667, 33971, 35012, 34429, 35381, 35295, 35334, 37713, 37414, - 37706, 37310, 37277, 37184, 39385, 39306, 38967, 39385, 38967, 39350, 4538, 4736, 4631, - 4538, 4631, 4618, 4581, 4476, 4366, 13900, 13873, 13878, 14168, 14419, 14284, 39636, - 39522, 39412, 38378, 38474, 38400, 38397, 38355, 38243, 37860, 38357, 38485, 13035, 12844, - 12905, 13197, 13143, 13035, 13269, 13143, 13197, 37992, 37905, 37863, 37992, 37863, 37991, - 16392, 16475, 16570, 15808, 16016, 15902, 33561, 33441, 33413, 34370, 34704, 33969, 38945, - 38977, 38858, 39014, 39048, 38905, 39035, 38977, 39140, 22887, 23001, 23086, 39484, 39221, - 39613, 16843, 16712, 16726, 16245, 16209, 16269, 16669, 16712, 16843, 17042, 17153, 17138, - 39035, 39048, 39014, 39365, 39442, 39218, 19591, 19682, 19547, 19591, 19547, 19531, 21710, - 21790, 21561, 20678, 20920, 21211, 20678, 20658, 20920, 20544, 20536, 20473, 20079, 20148, - 20363, 19402, 19337, 19273, 21874, 21878, 22206, 21874, 22206, 22237, 22473, 22474, 22366, - 39522, 39517, 39375, 35734, 35381, 35334, 35734, 35334, 35567, 35290, 35346, 35149, 35290, - 35080, 35058, 9489, 9664, 9355, 30897, 30596, 30607, 31808, 32055, 32018, 35775, 35664, - 35959, 9213, 9489, 9355, 25724, 25697, 25875, 25724, 25875, 26079, 35977, 35758, 35950, - 38155, 38194, 38327, 38155, 38084, 38194, 3358, 3270, 3276, 3483, 3741, 3656, 3571, - 3656, 3678, 19531, 19542, 19591, 22366, 22474, 22432, 22878, 22887, 23086, 23709, 23605, - 23796, 24267, 24446, 24195, 23146, 22345, 22827, 4207, 4458, 4254, 4162, 4130, 4223, - 4040, 4130, 4162, 17138, 17290, 17338, 18475, 18304, 18494, 18828, 18888, 18996, 18828, - 18996, 18978, 24446, 24235, 24195, 4207, 4254, 4182, 4724, 4875, 4700, 3977, 4102, - 4364, 4096, 4207, 4182, 38583, 38523, 38463, 38824, 38764, 38878, 33441, 33314, 33227, - 34704, 34908, 34826, 3450, 3360, 3593, 3068, 3500, 3501, 19531, 19326, 19542, 30645, - 30397, 30596, 31126, 31104, 31046, 31109, 31104, 31126, 31305, 31383, 31452, 4535, 4618, - 4755, 38888, 38764, 38831, 38888, 38831, 38868, 3391, 3399, 3463, 3391, 3397, 3399, - 3343, 3371, 3450, 34908, 35000, 34826, 39736, 39543, 39392, 39611, 39543, 39736, 23286, - 23086, 23408, 22432, 22474, 22572, 39281, 38968, 39070, 3706, 3797, 4084, 3564, 3571, - 3678, 4109, 4431, 4127, 4363, 4447, 4376, 16245, 16357, 16437, 14284, 14419, 14486, - 16532, 16437, 16712, 16503, 16532, 16712, 25254, 25491, 25434, 24864, 24891, 24693, 9813, - 9840, 9935, 12387, 12322, 11786, 9678, 9840, 9813, 32398, 32891, 32401, 31797, 31915, - 31800, 31797, 31800, 31739, 3629, 3711, 3712, 12475, 12547, 12656, 12387, 12547, 12475, - 37868, 37706, 38046, 37868, 37713, 37706, 4376, 4550, 4470, 13873, 13715, 13878, 14617, - 14486, 14628, 14983, 15431, 15039, 14735, 15039, 14713, 17138, 17019, 17042, 17042, 17019, - 16919, 25697, 25616, 25340, 25914, 25724, 26079, 32505, 32207, 32073, 35000, 35071, 35032, - 35690, 35703, 35440, 38500, 38397, 38716, 38355, 38474, 38378, 13994, 13715, 13873, 27257, - 27961, 27629, 28277, 28694, 28496, 27976, 28075, 28089, 38327, 38194, 38276, 38046, 37706, - 37905, 38545, 38381, 38482, 4819, 4825, 4850, 4858, 4864, 4968, 4724, 4463, 4604, - 12963, 12844, 13035, 12980, 13035, 13143, 3461, 3446, 3592, 3461, 3546, 3492, 3371, - 3360, 3450, 13135, 12980, 13143, 29626, 29391, 29567, 29585, 28999, 29391, 28940, 28569, - 28999, 26415, 26855, 26841, 29814, 29567, 29749, 29814, 29842, 30080, 23515, 23286, 23408, - 23515, 23709, 23786, 30204, 30100, 30135, 30135, 30287, 30397, 31452, 31383, 31477, 30897, - 30607, 30903, 4127, 4431, 4097, 4130, 4156, 4182, 4340, 4454, 4429, 4044, 4156, - 4130, 10203, 10287, 10332, 10148, 10005, 10088, 10203, 10332, 10249, 31147, 31079, 31016, - 31147, 31016, 30899, 38741, 38633, 38436, 38664, 38633, 38778, 4109, 4014, 4549, 14805, - 15331, 15392, 38678, 38523, 38583, 3560, 4261, 3355, 4075, 4040, 4162, 4261, 3662, - 3355, 13329, 13269, 13365, 16209, 16060, 16265, 16532, 16445, 16437, 16503, 16445, 16532, - 16238, 16475, 16392, 16238, 16392, 16294, 39048, 39212, 38879, 38977, 39035, 38884, 39129, - 39035, 39140, 3916, 3992, 4337, 25914, 26085, 25990, 4429, 4454, 4581, 4366, 4237, - 4265, 11629, 12496, 11961, 14168, 13994, 14140, 13147, 13135, 13269, 14105, 13994, 14168, - 16196, 16060, 16209, 25511, 25491, 25254, 28083, 27976, 28089, 35741, 35637, 35673, 34429, - 35012, 35458, 35771, 35637, 35741, 35690, 35367, 35346, 37472, 37321, 37302, 37351, 37321, - 37453, 31829, 31814, 31938, 32018, 31814, 31808, 31794, 31797, 31739, 31915, 32057, 31918, - 7812, 7541, 7757, 8079, 7782, 7990, 7541, 7782, 7243, 35012, 35295, 35458, 33561, - 33570, 33441, 33441, 33410, 33314, 3505, 3629, 3712, 3747, 3629, 3574, 24575, 24864, - 24693, 25121, 25180, 25254, 24731, 24864, 24575, 9113, 9103, 9196, 9489, 9643, 9797, - 8304, 7887, 8176, 5455, 5724, 5102, 38500, 38474, 38355, 3362, 3391, 3463, 3571, - 3483, 3656, 3380, 3515, 3493, 3381, 3483, 3293, 22474, 22592, 22572, 22592, 22701, - 22572, 34908, 34977, 35000, 35000, 35135, 35071, 34704, 34802, 34908, 34370, 34505, 34704, - 33455, 34243, 33772, 38824, 38808, 38741, 39034, 38888, 38868, 30397, 30287, 30596, 37290, - 37542, 37412, 37412, 37542, 37383, 38397, 38500, 38355, 37287, 36873, 37124, 36564, 36710, - 37124, 36606, 36510, 36699, 36373, 36045, 36177, 18374, 18304, 18475, 18577, 18613, 18705, - 20678, 21211, 21298, 21211, 21274, 21298, 21561, 21388, 21274, 20940, 21040, 20965, 20965, - 21040, 21027, 21256, 21436, 21493, 21493, 21436, 21520, 20574, 20604, 20671, 20533, 20604, - 20574, 20533, 20574, 20336, 20533, 20336, 20300, 20336, 20313, 20300, 20313, 20151, 20300, - 20151, 20156, 20300, 20122, 20156, 20151, 20116, 20156, 20122, 20116, 20122, 20061, 21561, - 21790, 21388, 3393, 3288, 3545, 3244, 3320, 3371, 3371, 3320, 3360, 2979, 3288, - 3393, 3289, 3414, 3298, 3414, 3373, 3298, 3373, 3228, 3298, 3336, 3228, 3373, - 20661, 20536, 20544, 19985, 20116, 20061, 35959, 35664, 35613, 22795, 22701, 22887, 22366, - 22237, 22206, 33678, 33570, 33561, 31829, 31663, 31814, 34505, 34650, 34704, 35071, 35290, - 35058, 39726, 39411, 39454, 39744, 39642, 39537, 39537, 39642, 39394, 39522, 39607, 39517, - 9059, 9103, 9113, 4091, 4433, 4207, 4838, 4858, 4825, 10023, 10005, 10148, 10380, - 10332, 10398, 19950, 19985, 20061, 20940, 20965, 20887, 21520, 21840, 21771, 23991, 23642, - 23547, 30897, 30903, 31104, 31663, 31383, 31680, 31226, 31147, 31106, 31794, 32057, 31797, - 30509, 30473, 30438, 36524, 36510, 36332, 3336, 3365, 3321, 19789, 19796, 19893, 27961, - 27976, 28124, 27961, 27883, 27976, 34650, 34802, 34704, 3321, 3365, 3273, 3937, 4040, - 4075, 4156, 4096, 4182, 4700, 4478, 4137, 4838, 4864, 4858, 10023, 10148, 10166, - 11521, 12322, 11864, 12547, 12726, 12838, 10669, 10548, 10407, 19789, 19716, 19796, 31814, - 31663, 31680, 32787, 32371, 33200, 4109, 4086, 4014, 4014, 3916, 4337, 4097, 4431, - 4347, 4080, 4096, 4156, 14617, 14284, 14486, 14723, 14805, 14804, 30897, 31104, 31109, - 38633, 38664, 38583, 38523, 38578, 38482, 38678, 38664, 38843, 25724, 25616, 25697, 25835, - 25616, 25724, 24795, 24922, 24864, 24864, 24922, 24891, 12620, 12726, 12547, 37713, 37847, - 37466, 38140, 37905, 37992, 38129, 37991, 38288, 3360, 3359, 3538, 3128, 3359, 3360, - 10180, 10548, 10171, 31109, 31126, 31272, 39500, 39385, 39350, 39306, 39544, 38669, 39602, - 39269, 39345, 39570, 39375, 39517, 3435, 3461, 3492, 18304, 18254, 18428, 16669, 16503, - 16712, 18258, 18254, 18304, 23243, 23286, 23515, 23408, 23507, 23515, 39511, 39350, 39422, - 3992, 3872, 4084, 3908, 3916, 4014, 3911, 3977, 4364, 38657, 38578, 38523, 33609, - 33410, 33441, 4285, 4478, 4454, 6970, 6768, 7294, 11961, 12536, 12548, 12980, 12963, - 13035, 12988, 12963, 12980, 13135, 13143, 13269, 19682, 19691, 19716, 19789, 19682, 19716, - 28277, 28496, 28124, 29814, 29711, 29567, 29767, 29711, 29814, 30080, 30100, 30204, 20079, - 20363, 20473, 21346, 21436, 21256, 24414, 24457, 24446, 31794, 31739, 31521, 31797, 32057, - 31915, 39744, 39537, 39943, 38329, 38327, 38276, 3380, 3493, 3326, 3273, 3365, 3213, - 19168, 18996, 19273, 26085, 25914, 26079, 26855, 26944, 27171, 38888, 38878, 38764, 39034, - 38878, 38888, 3574, 3564, 3747, 3453, 3435, 3492, 3574, 3629, 3505, 5033, 4671, - 4766, 4387, 4376, 4470, 4065, 4109, 4127, 4535, 4671, 4452, 5015, 5178, 5075, - 5107, 5206, 5178, 10661, 11040, 11196, 12548, 12665, 12230, 13878, 13715, 13574, 13329, - 13365, 13574, 17295, 17439, 17384, 16445, 16245, 16437, 24446, 24457, 24575, 23991, 23547, - 23791, 34802, 34977, 34908, 35703, 35959, 35613, 14222, 14284, 14218, 39140, 38977, 39279, - 37860, 37854, 38357, 19682, 19591, 19691, 21436, 21594, 21520, 30184, 30080, 30204, 30696, - 30645, 30596, 39642, 39636, 39412, 23472, 23547, 23492, 22827, 22345, 22231, 39385, 39458, - 39306, 39539, 39458, 39385, 3365, 3358, 3276, 16060, 15851, 16182, 16503, 16245, 16445, - 19691, 19591, 19542, 31452, 31336, 31272, 30897, 30696, 30596, 31489, 31336, 31452, 37124, - 36710, 37104, 36635, 36524, 36332, 34977, 35135, 35000, 4671, 4535, 4755, 13574, 13533, - 13403, 28083, 28277, 28124, 30184, 30204, 30397, 38298, 38084, 38155, 39035, 39117, 39048, - 39129, 39117, 39035, 3358, 3397, 3270, 3326, 3493, 3446, 8749, 8441, 9022, 10077, - 10023, 10166, 10077, 10166, 10203, 18828, 18785, 18888, 18660, 18785, 18828, 31663, 31644, - 31383, 31654, 31644, 31663, 37149, 36733, 36659, 36071, 35950, 36112, 3397, 3391, 3270, - 19088, 19292, 19326, 39636, 39607, 39522, 35950, 36036, 36270, 35637, 35734, 35567, 36635, - 36699, 36524, 35919, 35959, 35703, 4065, 4086, 4109, 3916, 3872, 3992, 4256, 4347, - 4363, 4265, 4340, 4366, 4040, 4044, 4130, 3919, 4044, 4040, 4520, 4470, 4538, - 4366, 4340, 4429, 4147, 4207, 4096, 3453, 3492, 3483, 3229, 3326, 3446, 14579, - 14382, 14515, 15776, 16172, 16016, 23344, 23472, 23492, 23791, 23472, 23795, 38329, 38315, - 38327, 38664, 38678, 38583, 38778, 38633, 38811, 21594, 21840, 21520, 27171, 26944, 27421, - 39543, 39611, 39454, 39580, 39392, 39475, 39580, 39475, 39442, 24457, 24628, 24575, 25511, - 25800, 25491, 24568, 24628, 24457, 24731, 24628, 24568, 39351, 39281, 39070, 3270, 3249, - 3211, 3376, 3446, 3461, 3359, 3385, 3586, 3125, 3385, 3359, 4465, 4520, 4538, - 13574, 13715, 13533, 22367, 22237, 22366, 22878, 22795, 22887, 22231, 22345, 22089, 27976, - 28083, 28124, 27961, 27257, 27883, 37321, 37277, 37310, 37269, 37277, 37351, 37292, 37327, - 37290, 36877, 36785, 36606, 39578, 39511, 39422, 39578, 39422, 39484, 19088, 18638, 19292, - 39607, 39570, 39517, 3707, 3872, 3685, 35135, 35290, 35071, 4771, 5015, 5096, 4726, - 4838, 4825, 4726, 4825, 4724, 16245, 16196, 16209, 16071, 16196, 16132, 16475, 16701, - 17205, 15776, 16016, 15808, 39127, 38812, 38909, 38808, 38633, 38741, 3391, 3362, 3306, - 3331, 3376, 3461, 3381, 3453, 3483, 4771, 5096, 4864, 18785, 18577, 18705, 17512, - 17469, 17765, 18660, 18577, 18785, 22957, 22878, 23086, 22367, 22366, 22432, 23243, 23086, - 23286, 29711, 29626, 29567, 28569, 27988, 28462, 29734, 29626, 29711, 33350, 33204, 33201, - 34505, 34609, 34650, 34650, 34825, 34802, 34802, 34893, 34977, 34977, 35247, 35135, 35135, - 35247, 35290, 9678, 9643, 9346, 9970, 10180, 10171, 35890, 35771, 35741, 36270, 36234, - 36749, 10661, 11196, 10718, 36524, 36699, 36510, 36736, 36699, 36635, 31644, 31477, 31383, - 30971, 30696, 30897, 31654, 31477, 31644, 36877, 36710, 36785, 38327, 38315, 38155, 38329, - 38276, 38545, 4376, 4256, 4363, 4327, 4256, 4376, 14284, 14222, 14168, 14218, 14284, - 14243, 14105, 14222, 14218, 35890, 35741, 35977, 5015, 5107, 5178, 8826, 8844, 8432, - 15860, 15851, 16060, 15712, 15755, 15302, 25491, 25800, 25486, 25180, 25121, 25015, 30612, - 30397, 30645, 29876, 29814, 30080, 29876, 29767, 29814, 29829, 29807, 30173, 29570, 29397, - 29000, 29807, 29949, 30173, 34630, 34609, 34505, 3306, 3362, 3278, 3244, 3371, 3343, - 3505, 3879, 3797, 3284, 3435, 3453, 10509, 10661, 10445, 13135, 12988, 12980, 12230, - 12665, 12844, 13147, 12988, 13135, 13147, 13269, 13329, 13147, 13329, 13315, 19505, 19337, - 19500, 24628, 24731, 24575, 24267, 24195, 23991, 36717, 36877, 36606, 39570, 39602, 39345, - 9103, 9095, 9355, 9059, 9067, 9103, 5150, 5374, 5164, 32018, 32055, 32117, 31908, - 31794, 31521, 32664, 32891, 32977, 33159, 33350, 33201, 31908, 31521, 32011, 34609, 34673, - 34650, 39511, 39500, 39350, 39566, 39127, 38909, 39577, 39500, 39511, 4086, 3951, 4014, - 4037, 4065, 4127, 5071, 5150, 5164, 14735, 14983, 15039, 14833, 14983, 14735, 38808, - 38824, 39007, 38678, 38657, 38523, 3977, 3937, 4075, 4032, 4147, 4096, 3889, 3937, - 3977, 19337, 19312, 19273, 39030, 38824, 38878, 4179, 4097, 4347, 4080, 4156, 4044, - 13793, 14217, 13836, 33570, 33609, 33441, 33410, 33378, 33314, 33678, 33609, 33570, 33678, - 33561, 33937, 38843, 38657, 38678, 31109, 31272, 31292, 3606, 4364, 3727, 3606, 3911, - 4364, 9067, 9095, 9103, 25015, 25121, 24922, 39290, 39351, 39070, 38977, 38945, 39279, - 35458, 35295, 35381, 35996, 35890, 35977, 25253, 25511, 25254, 19312, 19168, 19273, 22367, - 22432, 22572, 24099, 24267, 23991, 25211, 25253, 25180, 24414, 24384, 24490, 39212, 39048, - 39117, 40001, 39580, 39442, 37341, 37327, 37287, 37287, 37327, 37292, 37240, 37287, 37124, - 4256, 4179, 4347, 4178, 4179, 4256, 18577, 18374, 18475, 17138, 16669, 17019, 18509, - 18374, 18577, 4520, 4387, 4470, 4535, 4465, 4538, 4452, 4465, 4535, 4452, 4671, - 4488, 3412, 3662, 3547, 39303, 39212, 39117, 31314, 31272, 31336, 31314, 31336, 31395, - 36699, 36717, 36606, 37235, 37240, 37124, 36736, 36717, 36699, 33483, 33378, 33410, 32255, - 32505, 32398, 3334, 3547, 3597, 3390, 3867, 3385, 16068, 16238, 16172, 15302, 15755, - 15474, 31829, 31654, 31663, 31945, 31654, 31829, 22572, 22701, 22795, 30329, 29862, 29829, - 37277, 37269, 36659, 36749, 36234, 36516, 36071, 35996, 35977, 37351, 37277, 37321, 37847, - 37713, 37868, 37847, 37868, 37908, 37104, 36710, 36877, 4605, 4726, 4604, 4237, 4366, - 4433, 14222, 14105, 14168, 14723, 14617, 14805, 3331, 3461, 3435, 3278, 3362, 3380, - 3331, 3435, 3284, 28428, 27988, 28569, 38046, 37905, 38140, 38315, 38298, 38155, 38347, - 38298, 38315, 20604, 20831, 20887, 21040, 21215, 21256, 21436, 21346, 21594, 21594, 21777, - 21840, 20727, 20831, 20604, 20468, 20604, 20533, 20236, 20533, 20300, 20236, 20300, 20156, - 20236, 20156, 20075, 20156, 20116, 20075, 20116, 19985, 20075, 19985, 20023, 20075, 19796, - 19843, 19985, 39809, 39668, 39793, 39642, 39677, 39636, 39636, 39677, 39607, 39607, 39703, - 39570, 39570, 39746, 39602, 39668, 39461, 39793, 3278, 3380, 3202, 19168, 18978, 18996, - 39602, 39613, 39221, 39696, 39613, 39831, 4285, 4454, 4340, 4838, 4796, 4864, 5063, - 5071, 5107, 5107, 5071, 5164, 18137, 17765, 18254, 16196, 16071, 16060, 20831, 20940, - 20887, 21840, 22002, 21888, 24267, 24414, 24446, 24568, 24414, 24490, 32117, 32055, 32297, - 19796, 19716, 19843, 25180, 25253, 25254, 25015, 24922, 24886, 39544, 39306, 39458, 39047, - 39044, 38868, 39129, 39262, 39117, 39245, 39140, 39395, 39688, 39656, 39411, 3948, 3951, - 4065, 4065, 3951, 4086, 3872, 3796, 4084, 4037, 4127, 4097, 3795, 3919, 3937, - 3937, 3919, 4040, 4147, 4091, 4207, 3889, 3977, 3911, 3948, 4037, 4097, 3919, - 4080, 4044, 14677, 14833, 14735, 14983, 15044, 15431, 14677, 14735, 14688, 12726, 12891, - 12838, 12620, 12891, 12726, 12387, 12475, 12322, 38140, 37992, 38129, 39116, 39044, 39047, - 9067, 8944, 9095, 8176, 8835, 8304, 3831, 3889, 3690, 3941, 4091, 4147, 20536, - 20079, 20473, 19905, 19505, 19815, 19337, 19363, 19312, 19312, 19267, 19168, 19168, 19163, - 18978, 20331, 20079, 20536, 20756, 20536, 20661, 20756, 20661, 20678, 21790, 21568, 21388, - 19843, 19716, 19743, 21136, 21215, 21040, 39786, 39688, 39411, 39726, 39454, 39611, 3194, - 3278, 3202, 2813, 3390, 3385, 5576, 6321, 5724, 5063, 5107, 5015, 22706, 22572, - 22795, 23515, 23507, 23709, 37527, 37290, 37327, 37527, 37542, 37290, 39500, 39539, 39385, - 39596, 39539, 39500, 39736, 39580, 40115, 21790, 21892, 21568, 10380, 10249, 10332, 10023, - 10077, 10005, 10343, 10249, 10380, 10509, 10398, 10661, 11196, 11579, 11078, 31489, 31452, - 31477, 31109, 30971, 30897, 31489, 31477, 31654, 4397, 4387, 4520, 4179, 4178, 4097, - 13315, 13329, 13574, 12988, 12230, 12963, 13724, 13793, 13341, 38204, 38140, 38129, 38298, - 38288, 38084, 38545, 38482, 38578, 3321, 3228, 3336, 3298, 3124, 3289, 3289, 2979, - 3393, 3123, 3238, 3096, 3109, 3228, 3107, 3107, 3321, 3273, 3213, 3365, 3276, - 3213, 3276, 3211, 3276, 3270, 3211, 10196, 10077, 10203, 21932, 21874, 22023, 21215, - 21346, 21256, 39845, 39537, 39480, 3707, 3796, 3872, 11078, 10906, 10760, 36717, 36853, - 36877, 37240, 37341, 37287, 36845, 36853, 36717, 39525, 38968, 39281, 39299, 39290, 39070, - 39299, 39070, 39212, 22903, 22795, 22878, 22367, 22294, 22237, 39613, 39578, 39484, 39696, - 39578, 39613, 32018, 31938, 31814, 31945, 31938, 32117, 36796, 36516, 36733, 13403, 13315, - 13574, 19743, 19716, 19691, 19743, 19691, 19610, 39744, 39677, 39642, 3194, 3306, 3278, - 3381, 3293, 3303, 3571, 3293, 3483, 18258, 18137, 18254, 18258, 18304, 18374, 34366, - 34630, 34505, 34609, 34793, 34673, 34673, 34825, 34650, 34243, 33455, 34175, 35734, 35637, - 35771, 33609, 33483, 33410, 16172, 16238, 16294, 16068, 16172, 15776, 16068, 15776, 15797, - 37099, 37104, 36877, 5576, 5724, 5455, 19902, 19743, 19610, 24795, 24864, 24731, 40159, - 39726, 39611, 30375, 30509, 30438, 30173, 30329, 29829, 28915, 28694, 28277, 37269, 37149, - 36659, 37453, 37321, 37611, 37415, 37341, 37240, 4387, 4327, 4376, 4265, 4278, 4340, - 4233, 4278, 4265, 7782, 7541, 7812, 8441, 8831, 9022, 34521, 34630, 34366, 38778, - 38843, 38664, 38440, 38347, 38616, 38808, 38811, 38633, 38906, 38811, 39016, 4091, 4124, - 4433, 4080, 4032, 4096, 3941, 4032, 4080, 3795, 4080, 3919, 14804, 14805, 15084, - 13308, 13403, 13461, 14694, 14723, 14781, 21629, 21777, 21594, 24795, 24568, 24769, 39677, - 39703, 39607, 28083, 28089, 28277, 27883, 27257, 27910, 27883, 27910, 28075, 27769, 27910, - 27257, 25800, 25511, 25677, 38347, 38315, 38329, 38398, 38288, 38298, 9643, 9678, 9813, - 11271, 11864, 11403, 9346, 9643, 9489, 9085, 9355, 9095, 36270, 36112, 35950, 35890, - 35867, 35771, 24461, 24137, 24549, 23243, 22957, 23086, 25462, 24996, 25616, 25835, 25724, - 25914, 24414, 24568, 24457, 23472, 23344, 23242, 39525, 39281, 39496, 39320, 39299, 39212, - 31314, 31292, 31272, 31858, 31489, 31654, 3320, 3128, 3360, 3238, 3500, 3096, 3954, - 4124, 4091, 4704, 4796, 4838, 4731, 4838, 4726, 10509, 10343, 10380, 10249, 10196, - 10203, 10455, 10343, 10509, 11032, 11403, 10669, 13724, 13936, 13793, 14833, 15044, 14983, - 14219, 14515, 14382, 17679, 17512, 17765, 16669, 16843, 17019, 21777, 21901, 21840, 31395, - 31292, 31314, 30145, 30184, 30612, 33704, 33678, 33793, 33200, 32371, 33314, 34793, 34825, - 34673, 36177, 36020, 35959, 36045, 36052, 36177, 36052, 36020, 36177, 36853, 37099, 36877, - 4605, 4731, 4726, 12387, 12620, 12547, 13936, 14219, 14382, 18916, 18660, 18828, 17505, - 17384, 17512, 18916, 18828, 18978, 37611, 37321, 37663, 38016, 37908, 37868, 38016, 37868, - 38046, 38016, 38046, 38143, 11078, 11579, 10996, 30329, 30509, 30375, 37207, 37124, 37104, - 37207, 37235, 37124, 26303, 25990, 26085, 25908, 25990, 26082, 35544, 35346, 35290, 34825, - 34893, 34802, 3270, 3391, 3249, 3391, 3306, 3249, 19580, 19505, 19905, 39703, 39746, - 39570, 25426, 25511, 25253, 38545, 38578, 38689, 38251, 38204, 38129, 39044, 39034, 38868, - 39127, 39116, 39047, 39266, 39116, 39501, 39245, 39262, 39129, 39245, 39129, 39140, 4278, - 4285, 4340, 4124, 4237, 4433, 14555, 14284, 14617, 13936, 14217, 13793, 38689, 38578, - 38823, 3412, 3355, 3662, 3390, 3334, 3597, 3272, 2756, 3047, 33704, 33483, 33609, - 39643, 39544, 39458, 39643, 39458, 39539, 39577, 39511, 39578, 3238, 3244, 3343, 18660, - 18578, 18577, 18775, 18578, 18660, 21901, 22002, 21840, 35681, 35544, 35290, 39712, 39577, - 39578, 37461, 37327, 37341, 37461, 37527, 37327, 38357, 37846, 38402, 39136, 39034, 39044, - 36375, 36177, 35959, 17512, 17384, 17439, 17679, 17765, 17883, 30509, 30713, 30473, 39281, - 39497, 39496, 39303, 39320, 39212, 3249, 3306, 3194, 19505, 19363, 19337, 22002, 22140, - 22089, 28382, 28428, 28673, 27988, 27707, 27421, 29585, 29391, 29626, 29734, 29711, 29767, - 38251, 38129, 38288, 3951, 3908, 4014, 3796, 3706, 4084, 3815, 3908, 3951, 3948, - 4065, 4037, 10278, 10196, 10249, 9842, 10086, 10005, 10278, 10249, 10343, 9970, 10171, - 9840, 14723, 14694, 14617, 14805, 15392, 15084, 14515, 14677, 14688, 14660, 14677, 14515, - 18578, 18509, 18577, 18360, 18509, 18775, 22903, 22957, 23127, 22318, 22294, 22367, 30184, - 30397, 30612, 31489, 31395, 31336, 30612, 30645, 30824, 31609, 31395, 31489, 31945, 31829, - 31938, 37271, 37099, 36853, 36426, 36635, 36332, 36845, 36635, 36838, 37351, 37354, 37269, - 37748, 37466, 37847, 37415, 37461, 37341, 37415, 37240, 37235, 4233, 4285, 4278, 14660, - 14833, 14677, 13793, 13836, 13341, 27716, 27707, 28109, 35544, 35690, 35346, 35713, 35690, - 35544, 5724, 5374, 5102, 5374, 5150, 5102, 10445, 10455, 10509, 19363, 19267, 19312, - 13147, 13148, 12988, 13315, 13148, 13147, 14107, 13994, 14105, 14107, 14105, 14218, 16669, - 17138, 17295, 38398, 38298, 38347, 38417, 38251, 38288, 39262, 39303, 39117, 38813, 38400, - 38474, 4212, 4178, 4256, 3454, 3606, 3727, 3941, 4147, 4032, 3485, 3727, 3560, - 16132, 16196, 16245, 19610, 19691, 19542, 15797, 15776, 15712, 25630, 25462, 25616, 22903, - 22878, 22957, 36101, 36071, 36112, 36101, 35996, 36071, 36101, 36112, 36261, 3295, 3446, - 3376, 5089, 5150, 5071, 22318, 22367, 22572, 22140, 22231, 22089, 36845, 36717, 36736, - 37453, 37354, 37351, 18509, 18438, 18374, 18360, 18438, 18509, 39577, 39596, 39500, 39711, - 39596, 39577, 24568, 24795, 24731, 25223, 25426, 25253, 23791, 23547, 23472, 3707, 3706, - 3796, 6768, 6509, 7072, 4854, 5767, 4532, 6307, 6509, 6376, 25908, 25835, 25990, - 25990, 25835, 25914, 4796, 4771, 4864, 4628, 4771, 4796, 4704, 4838, 4731, 4605, - 4704, 4731, 3284, 3381, 3303, 3331, 3295, 3376, 23242, 23146, 22827, 4327, 4212, - 4256, 4183, 4212, 4327, 4183, 4327, 4387, 14243, 14107, 14218, 22483, 22318, 22572, - 27883, 28075, 27976, 28089, 28915, 28277, 30329, 30583, 30509, 30509, 30583, 30713, 27257, - 26803, 27208, 38440, 38398, 38347, 39580, 39736, 39392, 39351, 39290, 39453, 38211, 37748, - 37847, 37438, 37374, 37354, 38143, 38046, 38151, 38046, 38140, 38151, 38428, 38204, 38251, - 29876, 29734, 29767, 3223, 3295, 3331, 34327, 34521, 34366, 34630, 34793, 34609, 34825, - 34964, 34893, 35173, 35247, 34977, 34175, 34091, 34161, 34225, 34175, 34161, 34175, 33380, - 34091, 37394, 37207, 37104, 10371, 10278, 10343, 9842, 10005, 10077, 10371, 10343, 10455, - 37384, 36796, 36733, 4003, 4097, 4178, 3856, 3948, 3846, 3685, 3872, 3916, 14694, - 14555, 14617, 15084, 15392, 15452, 36261, 36112, 36270, 35996, 36016, 35890, 38811, 38843, - 38778, 38440, 38417, 38398, 38906, 38843, 38811, 39668, 39845, 39480, 39744, 39806, 39677, - 39677, 39806, 39703, 39703, 39789, 39746, 39793, 39461, 39556, 39793, 39556, 39656, 39793, - 39656, 39991, 39656, 39688, 39847, 39786, 39411, 39726, 4880, 5063, 5015, 30145, 30080, - 30184, 30145, 29876, 30080, 34467, 34521, 34327, 20236, 20468, 20533, 20831, 20860, 20940, - 20940, 21136, 21040, 21215, 21266, 21346, 21346, 21629, 21594, 21777, 21732, 21901, 21901, - 22058, 22002, 22175, 22251, 22140, 22140, 22251, 22231, 20435, 20468, 20236, 20023, 20236, - 20075, 20023, 19985, 19902, 20727, 20860, 20831, 3202, 3380, 3326, 39831, 39613, 39602, - 39771, 39602, 39746, 8176, 8217, 8844, 8826, 8944, 9059, 8059, 8172, 8176, 14600, - 14555, 14694, 8172, 8217, 8176, 13116, 13148, 13315, 13116, 13315, 13308, 17917, 17765, - 18137, 16667, 16669, 17295, 20860, 21136, 20940, 23791, 23921, 23991, 23795, 23921, 23791, - 24795, 24886, 24922, 25130, 24886, 24769, 29707, 29734, 29778, 32117, 31938, 32018, 31794, - 31908, 32057, 31226, 31521, 31147, 39434, 39303, 39262, 39453, 39290, 39299, 39453, 39299, - 39477, 8627, 8944, 8826, 9758, 9970, 9840, 32255, 32207, 32505, 37639, 37636, 38095, - 38500, 38716, 38474, 39434, 39421, 39303, 5063, 5089, 5071, 37788, 37383, 37542, 37461, - 37514, 37527, 37613, 37514, 37616, 3228, 3124, 3298, 3238, 3163, 3244, 3109, 3124, - 3228, 3228, 3321, 3107, 3273, 3213, 3107, 3213, 3147, 3107, 18438, 18258, 18374, - 18360, 18258, 18438, 22902, 23242, 22827, 3213, 3211, 3147, 3079, 3202, 3326, 19163, - 18916, 18978, 34747, 34793, 34630, 4604, 4726, 4724, 4237, 4233, 4265, 4124, 4166, - 4237, 4000, 4166, 4124, 3831, 3937, 3889, 19902, 19985, 19843, 19902, 19843, 19743, - 21136, 21266, 21215, 38485, 38716, 38397, 37374, 37149, 37269, 37374, 37269, 37354, 3211, - 3159, 3147, 4465, 4397, 4520, 4488, 4671, 5033, 9842, 10077, 9917, 7041, 7294, - 7641, 8217, 8432, 8844, 24381, 24461, 24655, 24779, 24549, 24806, 22903, 22706, 22795, - 24298, 24414, 24267, 39477, 39299, 39320, 8944, 9081, 9095, 9079, 9081, 8944, 18098, - 19024, 17474, 39943, 39806, 39744, 40159, 39786, 39726, 35690, 35919, 35703, 36426, 36332, - 36373, 35879, 35919, 35690, 39696, 39712, 39578, 39899, 39712, 39696, 3272, 3355, 3412, - 3272, 3412, 3334, 39525, 39552, 39172, 39497, 39281, 39351, 39523, 39116, 39127, 39596, - 39643, 39539, 39843, 39643, 39596, 21388, 21480, 21298, 20766, 20756, 20678, 19880, 19580, - 19905, 19505, 19436, 19363, 19363, 19351, 19267, 19267, 19163, 19168, 21892, 21790, 21874, - 21892, 21874, 21932, 4035, 4003, 4178, 4324, 4183, 4387, 4107, 4233, 4237, 31106, - 31147, 30899, 31106, 30899, 30713, 36635, 36845, 36736, 37394, 37415, 37207, 37207, 37415, - 37235, 36426, 36373, 36533, 3457, 3485, 3560, 3710, 3889, 3911, 15905, 15860, 16071, - 16071, 15860, 16060, 17412, 17295, 17384, 4452, 4397, 4465, 16132, 16245, 16503, 25835, - 25630, 25616, 25799, 25630, 25835, 38398, 38417, 38288, 38863, 38329, 38545, 15461, 15392, - 15851, 14804, 14781, 14723, 14787, 15044, 14833, 14660, 14515, 14395, 36642, 36426, 36533, - 3211, 3249, 3159, 21447, 21629, 21346, 22669, 22902, 22827, 14896, 14781, 14804, 14285, - 14243, 14284, 13533, 13715, 13638, 33483, 33509, 33378, 33704, 33509, 33483, 33704, 33609, - 33678, 5767, 6011, 4532, 4024, 4324, 4397, 10711, 11032, 10669, 12517, 12572, 12620, - 22957, 23243, 23127, 21874, 22237, 22023, 3795, 3831, 3690, 4166, 4107, 4237, 15257, - 15302, 15474, 9081, 9085, 9095, 10180, 10407, 10548, 9079, 9085, 9081, 4392, 4459, - 4463, 4644, 4804, 4771, 4771, 4804, 5015, 5040, 5102, 5089, 12230, 12844, 12963, - 10598, 10445, 10661, 12620, 12572, 12891, 13936, 13978, 14219, 12517, 12620, 12387, 29707, - 29585, 29734, 29734, 29585, 29626, 27565, 27421, 27707, 31109, 31307, 30971, 21629, 21732, - 21777, 27284, 27171, 27388, 28382, 27988, 28428, 36216, 36016, 35996, 33676, 33704, 33793, - 36216, 35996, 36101, 11961, 11789, 11629, 18258, 18065, 18137, 17679, 17505, 17512, 18128, - 18065, 18258, 38150, 37847, 37908, 38151, 38140, 38270, 39502, 39497, 39351, 39421, 39477, - 39320, 39421, 39320, 39303, 17412, 17505, 17616, 23921, 24099, 23991, 23942, 24099, 23921, - 32139, 32277, 32198, 31945, 31858, 31654, 3244, 3142, 3320, 3068, 3501, 3288, 3338, - 3564, 3574, 3685, 3916, 3908, 3856, 3951, 3948, 20021, 19905, 20079, 17954, 17917, - 18065, 17374, 18098, 17474, 22237, 22141, 22023, 39034, 39030, 38878, 38823, 38578, 38657, - 39136, 39030, 39034, 39136, 39044, 39243, 39806, 39789, 39703, 4183, 4324, 3964, 4397, - 4324, 4387, 4035, 4178, 4212, 13341, 13516, 12891, 28075, 28039, 28089, 26587, 25774, - 25800, 14285, 14284, 14555, 38823, 38657, 38843, 3159, 3249, 3131, 3123, 3163, 3238, - 9085, 9213, 9355, 9079, 9213, 9085, 15860, 15858, 15851, 16478, 16132, 16503, 16478, - 16503, 16669, 22237, 22294, 22141, 25211, 25180, 25015, 25211, 25015, 25130, 25015, 24886, - 25130, 35173, 34977, 34893, 35867, 35734, 35771, 36796, 36749, 36516, 37053, 36749, 36796, - 3381, 3284, 3453, 3174, 3194, 3202, 3131, 3249, 3194, 3571, 3564, 3338, 9758, - 9840, 9678, 18065, 17917, 18137, 17883, 17917, 17954, 39619, 39552, 39525, 40159, 39847, - 39786, 39619, 39525, 39629, 15751, 15858, 15905, 15696, 15797, 15712, 16206, 16475, 16238, - 23127, 23243, 23515, 22141, 22294, 22196, 24120, 24182, 24099, 22397, 22827, 22231, 39266, - 39044, 39116, 39712, 39711, 39577, 39791, 39711, 39878, 3163, 3142, 3244, 10035, 10077, - 10196, 10718, 11196, 11078, 10049, 10407, 10180, 19580, 19436, 19505, 22294, 22266, 22196, - 28746, 28428, 28569, 31109, 31292, 31307, 29570, 29000, 29418, 32353, 32057, 31908, 31027, - 31106, 30713, 39789, 39771, 39746, 24099, 24182, 24267, 24298, 24182, 24326, 3710, 3911, - 3607, 3345, 3457, 3560, 39502, 39351, 39453, 39434, 39262, 39245, 15084, 14896, 14804, - 14781, 14600, 14694, 15008, 14896, 15084, 39016, 38811, 38808, 39007, 38824, 39027, 13724, - 13978, 13936, 13891, 13978, 13869, 3831, 3795, 3937, 3710, 3552, 3690, 3795, 3941, - 4080, 14568, 14600, 14781, 14395, 14515, 14219, 15044, 15257, 15474, 15439, 15696, 15712, - 15114, 15257, 15044, 38716, 38813, 38474, 39499, 39427, 39309, 39027, 38824, 39030, 3131, - 3194, 3174, 22196, 22266, 22193, 35894, 35867, 35890, 35510, 35458, 35381, 35894, 35890, - 36016, 10598, 10718, 10603, 34521, 34747, 34630, 34793, 34964, 34825, 34243, 34467, 34327, - 34175, 34225, 34243, 33380, 33204, 34091, 34091, 33204, 33997, 37394, 37104, 37099, 37788, - 37542, 37684, 38417, 38338, 38251, 38440, 38338, 38417, 37542, 37527, 37684, 39039, 39499, - 39309, 3911, 3606, 3607, 4035, 4212, 4183, 4586, 4628, 4605, 3970, 4000, 4124, - 8217, 8343, 8432, 8432, 8411, 8826, 8172, 8060, 8217, 7887, 8304, 7714, 14414, - 14395, 14016, 16667, 16478, 16669, 17917, 17883, 17765, 18509, 18578, 18775, 34142, 34091, - 34064, 39168, 39027, 39030, 35510, 35381, 35734, 16041, 16238, 16068, 22483, 22572, 22647, - 39771, 39831, 39602, 16156, 16478, 16185, 15751, 15719, 15858, 24769, 24568, 24490, 16014, - 16041, 16068, 16014, 16068, 15797, 34591, 34747, 34521, 4628, 4796, 4704, 5089, 5102, - 5150, 4628, 4704, 4605, 13236, 13341, 12891, 12121, 12517, 12387, 24182, 24298, 24267, - 23795, 23472, 23540, 39502, 39453, 39529, 3229, 3446, 3295, 3142, 3128, 3320, 3355, - 3345, 3560, 5545, 6214, 6232, 4779, 4488, 5033, 4804, 4880, 5015, 19290, 19163, - 19267, 22058, 22140, 22002, 29585, 28940, 28999, 29778, 29734, 29876, 38150, 37908, 38016, - 37149, 37384, 36733, 38150, 38016, 38170, 37684, 37527, 37679, 3223, 3229, 3295, 4057, - 4107, 4166, 15858, 15719, 15851, 16156, 16071, 16132, 15439, 15712, 15302, 27910, 28039, - 28075, 28058, 28039, 27910, 26587, 26242, 26577, 30593, 30583, 30329, 37438, 37354, 37453, - 8132, 8343, 8217, 32505, 32073, 32057, 33740, 33823, 33350, 32505, 32057, 32475, 37613, - 37527, 37514, 3200, 3223, 3331, 3338, 3574, 3505, 10035, 10196, 10278, 10371, 10455, - 10445, 23540, 23472, 23242, 23942, 23795, 23918, 39629, 39525, 39496, 39552, 39770, 39365, - 38270, 38140, 38204, 8343, 8411, 8432, 22251, 22384, 22231, 33678, 33937, 33793, 32508, - 32117, 32297, 34902, 34964, 34793, 35826, 35713, 35681, 3846, 3948, 4097, 38948, 38889, - 38906, 38906, 38889, 38843, 38428, 38251, 38338, 39016, 38808, 39007, 26587, 25800, 26242, - 39021, 39016, 39007, 2869, 3174, 3202, 3200, 3331, 3284, 18850, 18660, 18916, 37616, - 37514, 37461, 3941, 3954, 4091, 4000, 4008, 4166, 3899, 3954, 3764, 3970, 3954, - 3899, 13148, 13116, 12988, 10760, 10906, 10813, 13308, 13315, 13403, 13994, 13638, 13715, - 38428, 38270, 38204, 38347, 38329, 38616, 38889, 38823, 38843, 3505, 3797, 3706, 3505, - 3706, 3526, 9213, 9254, 9489, 8812, 9079, 8944, 24461, 24381, 24137, 25322, 24806, - 25462, 24298, 24384, 24414, 24326, 24384, 24298, 25211, 25223, 25253, 25267, 25223, 25211, - 39529, 39453, 39477, 39702, 39629, 39496, 39529, 39477, 39421, 20766, 20678, 21298, 19580, - 19575, 19436, 19436, 19351, 19363, 20766, 21298, 21188, 21388, 21568, 21480, 21568, 21892, - 21784, 21892, 21932, 21784, 21932, 21999, 21784, 20860, 20989, 21136, 21325, 21447, 21266, - 21266, 21447, 21346, 21629, 21649, 21732, 21732, 22058, 21901, 22251, 22329, 22384, 20578, - 20727, 20604, 20578, 20604, 20468, 20578, 20468, 20435, 20236, 20023, 20435, 20724, 20615, - 20435, 20065, 20724, 20435, 21932, 22023, 21999, 3079, 3326, 3229, 3723, 3685, 3908, - 3710, 3690, 3889, 3402, 3727, 3485, 16041, 16122, 16238, 15904, 16014, 15797, 20023, - 19902, 19647, 22329, 22397, 22384, 22384, 22397, 22231, 32775, 32505, 32668, 36475, 36261, - 36270, 35867, 35839, 35734, 36216, 36266, 36170, 39355, 39168, 39030, 39027, 39021, 39007, - 39566, 38669, 39544, 39243, 39386, 39355, 3009, 3068, 3288, 3123, 3096, 3163, 3163, - 3055, 3142, 3142, 3055, 3128, 3009, 3288, 2979, 3043, 3124, 3109, 3043, 3109, - 3072, 3109, 3107, 3072, 2967, 2995, 3072, 3147, 3056, 3107, 20756, 20331, 20536, - 39395, 39434, 39245, 40014, 39845, 39668, 39989, 39875, 39789, 39789, 39875, 39771, 39771, - 39859, 39831, 40014, 39668, 39809, 40014, 39809, 39793, 3272, 3334, 2844, 3457, 3468, - 3485, 39625, 39496, 39497, 39691, 39757, 39552, 3993, 4008, 4000, 4392, 4463, 4724, - 4929, 5089, 5063, 5455, 5367, 5576, 11032, 11271, 11403, 10679, 11271, 11032, 14456, - 14285, 14555, 14456, 14555, 14600, 14879, 14781, 14896, 34964, 35173, 34893, 36533, 36373, - 36177, 13994, 14107, 13638, 13236, 12891, 12969, 14414, 14660, 14395, 3128, 3125, 3359, - 3067, 3125, 3128, 22647, 22572, 22706, 21999, 22023, 22141, 22647, 22706, 22575, 10489, - 10371, 10445, 10598, 10661, 10718, 10598, 10603, 10489, 25561, 25322, 25462, 26303, 26085, - 26362, 3147, 3041, 3056, 20331, 20021, 20079, 32027, 31858, 31945, 29860, 29778, 29876, - 32139, 31945, 32117, 34241, 34161, 34142, 32505, 32891, 32398, 35389, 35290, 35247, 39845, - 39943, 39537, 39786, 39847, 39688, 40159, 39611, 40331, 7041, 7641, 7541, 4150, 4488, - 4280, 35173, 35259, 35247, 3224, 3345, 3355, 37374, 37549, 37149, 37538, 37438, 37453, - 10718, 10760, 10603, 31609, 31292, 31395, 3147, 3159, 3041, 20021, 19880, 19905, 18864, - 18850, 18916, 21118, 21266, 21136, 19184, 18916, 19163, 21999, 22141, 22193, 22575, 22706, - 22903, 3187, 3200, 3284, 3338, 3293, 3571, 3526, 3706, 3707, 3179, 3187, 2765, - 13638, 13763, 13598, 24769, 24886, 24795, 23795, 23942, 23921, 23167, 23242, 22902, 25561, - 25462, 25630, 38616, 38329, 38863, 4784, 4929, 4880, 4880, 4929, 5063, 4285, 4233, - 4137, 33314, 33378, 33200, 18360, 18128, 18258, 17616, 17505, 17679, 17954, 18128, 18033, - 3995, 4233, 4107, 15127, 15008, 15084, 35259, 35389, 35247, 3340, 3468, 3457, 3856, - 3815, 3951, 3576, 3526, 3707, 3906, 3846, 4097, 3906, 4097, 4003, 3856, 3846, - 3821, 14587, 14787, 14660, 14660, 14787, 14833, 15956, 15904, 15939, 15737, 15904, 15797, - 13891, 14219, 13978, 16014, 15956, 16041, 15291, 15302, 15257, 39266, 39243, 39044, 39661, - 39544, 39643, 9079, 9204, 9213, 9105, 9204, 9079, 33200, 33378, 33450, 28984, 28940, - 29445, 29934, 29876, 30145, 15114, 15291, 15257, 26841, 26303, 26362, 25908, 25799, 25835, - 26841, 26855, 27171, 3954, 3970, 4124, 4008, 4057, 4166, 3993, 3970, 3899, 13531, - 13461, 13533, 14568, 14456, 14600, 26891, 27208, 26803, 18850, 18775, 18660, 18864, 18775, - 18850, 22397, 22669, 22827, 22415, 22669, 22397, 30593, 30734, 30583, 30583, 30734, 30713, - 32668, 32505, 32475, 30593, 30329, 30530, 37429, 37394, 37099, 37415, 37616, 37461, 37191, - 36853, 36845, 36838, 36635, 36426, 4784, 4880, 4804, 11271, 11521, 11864, 13240, 13236, - 12969, 30319, 29934, 30145, 37684, 37778, 37788, 37904, 38095, 37617, 37613, 37679, 37527, - 37660, 37679, 37613, 3068, 3096, 3500, 22141, 22196, 22193, 33450, 33378, 33509, 34225, - 34332, 34243, 34747, 34902, 34793, 34964, 35152, 35173, 35173, 35288, 35259, 35259, 35324, - 35389, 34241, 34332, 34225, 34241, 34225, 34161, 34161, 34091, 34142, 34332, 34467, 34243, - 39573, 39625, 39497, 39826, 39529, 39421, 39573, 39800, 39760, 3223, 3168, 3229, 3187, - 3284, 3303, 3575, 3607, 3512, 3954, 3941, 3764, 8059, 8060, 8172, 8343, 8272, - 8411, 8411, 8627, 8826, 7714, 8304, 7652, 7520, 7529, 7652, 34091, 33997, 34064, - 36261, 36216, 36101, 36475, 36270, 36749, 23942, 24120, 24099, 23972, 24120, 23942, 7887, - 7984, 8059, 34064, 33997, 34062, 34467, 34591, 34521, 3930, 4057, 4008, 3041, 3159, - 2958, 3159, 3131, 2958, 19880, 19575, 19580, 7984, 8060, 8059, 22669, 22753, 22902, - 22576, 22753, 22669, 34142, 34064, 34201, 5031, 5367, 5455, 4929, 5040, 5089, 9204, - 9254, 9213, 10365, 10711, 10407, 10407, 10711, 10669, 11638, 11786, 11521, 9105, 9254, - 9204, 36060, 35894, 36016, 35458, 35517, 34429, 36456, 36475, 37028, 37663, 37321, 37472, - 37663, 37472, 37748, 38016, 38143, 38170, 38367, 38151, 38270, 37627, 37616, 37415, 30762, - 30824, 30906, 32139, 32027, 31945, 32083, 32027, 32139, 37433, 37374, 37438, 16478, 16156, - 16132, 15001, 14879, 15008, 17412, 17384, 17505, 8060, 8132, 8217, 13869, 13978, 13724, - 12891, 12843, 12969, 26242, 25800, 25895, 26587, 26891, 26803, 24498, 24490, 24384, 35648, - 35510, 35734, 38435, 38428, 38338, 38516, 38338, 38440, 40129, 39789, 39806, 39831, 39882, - 39696, 39835, 39661, 39643, 10049, 10180, 9970, 34773, 34902, 34747, 25728, 25799, 25908, - 18128, 17954, 18065, 17872, 17954, 17953, 39791, 39596, 39711, 39691, 39552, 39619, 39691, - 39619, 39663, 22753, 22873, 22902, 23109, 22873, 22940, 13456, 13724, 13341, 27770, 27716, - 27879, 27614, 27716, 27770, 2999, 3041, 2958, 3096, 3055, 3163, 3364, 3340, 3268, - 3821, 3815, 3856, 4035, 4183, 3760, 15008, 14879, 14896, 15001, 15008, 15127, 15291, - 15439, 15302, 14787, 14895, 15044, 15226, 14737, 15202, 19575, 19477, 19436, 17872, 17883, - 17954, 22294, 22318, 22266, 21973, 22058, 21732, 39875, 39867, 39771, 17616, 17679, 17883, - 24381, 24162, 24137, 22266, 22318, 22483, 24335, 24162, 24381, 24779, 24806, 24988, 39573, - 39497, 39502, 25165, 24806, 25322, 38889, 38948, 38823, 38863, 38545, 38689, 39038, 38948, - 38906, 39168, 39021, 39027, 13533, 13461, 13403, 13308, 13198, 13116, 13116, 12230, 12988, - 14107, 14243, 14086, 14243, 14285, 14086, 13240, 13456, 13341, 19477, 19351, 19436, 39867, - 39859, 39771, 33704, 33676, 33509, 33793, 33937, 34605, 3970, 3993, 4000, 4586, 4605, - 4604, 3930, 3993, 3899, 14016, 14395, 14219, 27565, 27171, 27421, 26303, 26082, 25990, - 4628, 4644, 4771, 4949, 5024, 5040, 4512, 4644, 4628, 4586, 4604, 4463, 26280, - 26082, 26303, 39355, 39030, 39136, 39196, 39168, 39214, 3995, 4107, 4057, 38170, 38143, - 38302, 37904, 37617, 37788, 39039, 38423, 38813, 37778, 37684, 37679, 30824, 30645, 30696, - 30824, 30696, 30971, 30734, 30853, 30713, 30530, 30329, 30173, 37538, 37433, 37438, 37538, - 37453, 37611, 3293, 3187, 3303, 3158, 3168, 3223, 3179, 2765, 2815, 39661, 39750, - 39544, 39952, 39750, 39661, 40076, 39991, 40325, 39663, 39619, 39629, 3468, 3402, 3485, - 3364, 3402, 3468, 3340, 3457, 3345, 25292, 25165, 25322, 25292, 25322, 25402, 39353, - 39279, 38945, 39529, 39573, 39502, 39216, 38423, 39249, 5031, 5455, 5102, 6307, 6080, - 6509, 7243, 7041, 7541, 10598, 10489, 10445, 10067, 10035, 10278, 10718, 11078, 10760, - 19351, 19290, 19267, 22266, 22483, 22492, 22058, 22175, 22140, 33228, 32886, 32787, 33676, - 33564, 33509, 35236, 35152, 34964, 35826, 35879, 35713, 39859, 39854, 39831, 29647, 29585, - 29707, 29647, 29707, 29778, 29860, 29876, 29934, 29994, 29860, 29934, 37764, 37778, 37679, - 37660, 37613, 37616, 14086, 14285, 14253, 28039, 28058, 28089, 27769, 28058, 27910, 4024, - 4397, 4452, 3930, 3995, 4057, 14253, 14285, 14288, 24120, 24326, 24182, 24096, 24326, - 24120, 27614, 27565, 27716, 27716, 27565, 27707, 3268, 3340, 3345, 2874, 3385, 3125, - 15905, 15858, 15860, 15905, 16071, 16156, 3158, 3223, 3161, 19290, 19184, 19163, 22492, - 22483, 22647, 33564, 33450, 33509, 31904, 31858, 32027, 35152, 35288, 35173, 39896, 39711, - 39712, 39854, 39882, 39831, 37670, 37663, 37923, 37644, 37660, 37616, 30612, 30648, 30145, - 31787, 31489, 31858, 30746, 30853, 30734, 39680, 39663, 39629, 39770, 39552, 39798, 39680, - 39629, 39702, 27153, 27171, 27163, 27153, 26841, 27171, 3815, 3723, 3908, 3037, 3179, - 2815, 3614, 3723, 3815, 14895, 15114, 15044, 15226, 15114, 14737, 25267, 25426, 25223, - 27208, 27769, 27257, 2989, 3067, 3128, 22175, 22329, 22251, 22873, 23167, 22902, 35894, - 35839, 35867, 35510, 35517, 35458, 35925, 35839, 35894, 36170, 36016, 36216, 35713, 35879, - 35690, 35713, 35544, 35681, 39882, 39899, 39696, 8278, 8627, 8411, 35288, 35324, 35259, - 4035, 3906, 4003, 14647, 14568, 14781, 14855, 14781, 14879, 27163, 27171, 27284, 36839, - 36838, 36426, 37394, 37490, 37415, 5040, 5024, 5102, 4949, 5040, 4888, 13891, 14016, - 14219, 14587, 14895, 14787, 13753, 13869, 13724, 2999, 3056, 3041, 3161, 3223, 3200, - 23325, 23127, 23515, 23109, 23167, 22873, 31904, 31787, 31858, 32083, 32139, 32198, 39791, - 39843, 39596, 40021, 39843, 39791, 25165, 24988, 24806, 24088, 24015, 24162, 24162, 24015, - 23796, 25561, 25630, 25799, 25561, 25799, 25728, 25130, 25267, 25211, 25151, 25267, 25130, - 15226, 15439, 15291, 24326, 24338, 24384, 24187, 24338, 24326, 39750, 39566, 39544, 39748, - 39566, 39863, 39662, 39529, 39826, 15904, 15956, 16014, 15737, 15797, 15696, 25728, 25908, - 25824, 20727, 20842, 20860, 21447, 21649, 21629, 22058, 22149, 22175, 22547, 22485, 22329, - 20578, 20615, 20727, 20435, 20615, 20578, 19532, 19902, 19610, 36456, 36216, 36261, 36138, - 36170, 36195, 40076, 40014, 39793, 39845, 39982, 39943, 39943, 39958, 39806, 39875, 39989, - 39867, 39867, 39978, 39859, 39859, 39968, 39854, 39854, 39959, 39882, 39882, 40022, 39899, - 39991, 39656, 39847, 4137, 4478, 4285, 3993, 3930, 4008, 3552, 3795, 3690, 3552, - 3710, 3607, 22329, 22415, 22397, 22485, 22415, 22329, 27565, 27388, 27171, 27423, 27388, - 27565, 2859, 3008, 3096, 3096, 3008, 3055, 3055, 2989, 3128, 2979, 3289, 3124, - 2979, 3124, 3043, 2979, 2776, 2839, 3043, 3072, 2995, 20615, 20842, 20727, 20842, - 20989, 20860, 39552, 39757, 39798, 23705, 23918, 23795, 39798, 39920, 39885, 39702, 39496, - 39625, 3072, 3107, 2967, 3107, 3056, 2967, 9575, 9758, 9678, 9346, 9489, 9254, - 20989, 21039, 21136, 32023, 32083, 32093, 40014, 39982, 39845, 10067, 10278, 10371, 10760, - 10813, 10670, 30593, 30746, 30734, 30354, 30530, 30173, 37433, 37545, 37374, 37766, 37538, - 37611, 37505, 37490, 37394, 21039, 21118, 21136, 3576, 3707, 3685, 38716, 39115, 39124, - 39279, 39395, 39140, 3131, 2624, 2958, 3037, 3161, 3200, 3179, 3200, 3187, 8132, - 8272, 8343, 8060, 8071, 8132, 7984, 7920, 8060, 7887, 7916, 7984, 7396, 7520, - 7652, 34591, 34687, 34747, 35236, 35318, 35152, 35152, 35318, 35288, 35288, 35409, 35324, - 34467, 34479, 34591, 34332, 34414, 34467, 34241, 34414, 34332, 34258, 34414, 34241, 34258, - 34241, 34142, 34258, 34142, 34201, 39843, 39835, 39643, 39932, 39835, 39843, 39757, 39691, - 39920, 7654, 7652, 7529, 7714, 7858, 7887, 34414, 34479, 34467, 22575, 22492, 22647, - 7858, 7916, 7887, 33204, 33350, 33997, 21118, 21325, 21266, 13869, 14016, 13891, 27707, - 27988, 28159, 29418, 29000, 28694, 34479, 34687, 34591, 37928, 37904, 37788, 37928, 37788, - 37888, 37764, 37679, 37660, 13461, 13198, 13308, 13638, 13531, 13533, 13598, 13531, 13638, - 13638, 14107, 13763, 38999, 38689, 38823, 38302, 38143, 38151, 4137, 4233, 3987, 4529, - 4659, 4644, 4739, 4784, 4804, 24338, 24498, 24384, 24599, 24498, 24338, 37923, 37663, - 37748, 37663, 37670, 37611, 38367, 38270, 38428, 7920, 8071, 8060, 33997, 33350, 33823, - 34687, 34773, 34747, 40294, 39958, 39943, 4659, 4804, 4644, 3402, 3454, 3727, 3370, - 3454, 3402, 40329, 39395, 39279, 36838, 36936, 36845, 37095, 36936, 36987, 2967, 3056, - 2999, 3906, 3821, 3846, 3723, 3643, 3685, 3708, 3821, 3588, 15461, 15851, 15719, - 14288, 14285, 14456, 17786, 17616, 17883, 17121, 16667, 17295, 18722, 18360, 18775, 18950, - 18864, 18916, 21798, 21480, 21784, 21784, 21480, 21568, 20396, 20370, 20756, 20756, 20370, - 20331, 19690, 19880, 19644, 19690, 19575, 19880, 19541, 19477, 19575, 19541, 19351, 19477, - 19251, 19215, 19351, 19351, 19215, 19290, 19290, 19215, 19184, 19184, 18950, 18916, 21798, - 21784, 21999, 21798, 21999, 22022, 21999, 22193, 22022, 22022, 22193, 22166, 22962, 22575, - 22903, 24655, 24461, 24779, 22162, 22324, 22639, 23918, 23972, 23942, 23954, 23972, 23918, - 26446, 26280, 26303, 27153, 26973, 26841, 27075, 26973, 27153, 27163, 27284, 27306, 30824, - 30762, 30612, 30725, 30762, 30906, 30597, 30746, 30593, 31221, 31226, 31106, 30597, 30593, - 30530, 33823, 33740, 33856, 39038, 38906, 39016, 39038, 39016, 39021, 39038, 39021, 39196, - 39196, 39021, 39168, 28940, 28746, 28569, 28984, 28746, 28940, 29647, 29778, 29860, 16185, - 15905, 16156, 15751, 15461, 15719, 29810, 29949, 29807, 35859, 35648, 35734, 36138, 36060, - 36016, 37809, 37764, 37660, 39770, 39849, 39442, 39823, 39691, 39663, 3340, 3364, 3468, - 3268, 3345, 3259, 25133, 24988, 25165, 25133, 25165, 25172, 26446, 26303, 26841, 25172, - 25165, 25292, 27306, 27284, 27388, 35859, 35734, 35839, 8039, 8272, 8132, 32775, 32891, - 32505, 33623, 33005, 33500, 33958, 33823, 33856, 38454, 38367, 38428, 3174, 2624, 3131, - 21329, 21649, 21447, 29949, 30149, 30173, 38211, 37847, 38150, 39899, 39896, 39712, 40035, - 39896, 40105, 33676, 33643, 33564, 33564, 33580, 33450, 33450, 33599, 33200, 34605, 33937, - 34429, 3512, 3607, 3606, 14288, 14456, 14357, 27541, 27423, 27565, 27541, 27565, 27614, - 24705, 24655, 24779, 2859, 3096, 3068, 22193, 22266, 22166, 21649, 21760, 21732, 23972, - 24096, 24120, 24187, 24096, 24113, 23540, 23242, 23167, 23540, 23167, 23277, 39680, 39823, - 39663, 39760, 39702, 39625, 39760, 39625, 39573, 33793, 33643, 33676, 13340, 13198, 13461, - 13340, 13461, 13531, 13456, 13413, 13724, 13869, 14046, 14016, 13236, 13240, 13341, 13359, - 13240, 13213, 12572, 12843, 12891, 38454, 38435, 38604, 38516, 38435, 38338, 35925, 35859, - 35839, 36170, 36138, 36016, 36060, 36138, 36108, 36170, 36266, 36195, 3229, 3168, 3079, - 4949, 5064, 5024, 5024, 5064, 5102, 30149, 30354, 30173, 37490, 37627, 37415, 37610, - 37627, 37490, 25513, 25322, 25561, 24988, 24705, 24779, 10067, 10371, 10254, 8833, 10020, - 10086, 8441, 8115, 8079, 9870, 10049, 9970, 11638, 11521, 11285, 33643, 33580, 33564, - 35236, 34964, 34902, 35681, 35290, 35389, 19292, 19532, 19610, 19203, 19532, 19292, 21760, - 21973, 21732, 25915, 25908, 26082, 28159, 27988, 28382, 27691, 27769, 27208, 28936, 28915, - 28838, 36936, 37055, 36845, 37095, 37055, 36936, 35892, 35919, 35879, 40129, 39989, 39789, - 31060, 30906, 30971, 32023, 31904, 32027, 32023, 32027, 32083, 39009, 38485, 38357, 39216, - 39353, 38945, 38402, 37846, 38095, 3293, 2765, 3187, 3079, 3168, 3158, 13359, 13413, - 13456, 23705, 23540, 23672, 28438, 28159, 28382, 35925, 35894, 36037, 35648, 35517, 35510, - 35681, 35389, 35595, 3614, 3643, 3723, 3526, 2961, 3505, 26280, 26256, 26082, 26801, - 26446, 26841, 26801, 26841, 26973, 26801, 26973, 27062, 27306, 27388, 27432, 39355, 39136, - 39243, 39093, 38997, 38948, 38516, 38440, 38616, 30762, 30648, 30612, 30725, 30648, 30762, - 30354, 30597, 30530, 31027, 30713, 30853, 37443, 37505, 37394, 3079, 3158, 3044, 4529, - 4644, 4525, 4888, 5040, 4929, 4628, 4586, 4512, 22166, 22266, 22324, 24629, 24705, - 24735, 24350, 24335, 24381, 35318, 35409, 35288, 39989, 39978, 39867, 37191, 37271, 36853, - 4280, 4488, 4779, 3588, 3821, 3906, 3821, 3708, 3815, 6080, 6232, 6509, 29994, - 29647, 29860, 28746, 28673, 28428, 37904, 38012, 38095, 37799, 37788, 37778, 37799, 37778, - 37764, 37799, 37764, 37809, 38170, 38183, 38150, 38302, 38183, 38170, 38302, 38151, 38339, - 3764, 3941, 3207, 3930, 3881, 3995, 27244, 27306, 27325, 3584, 3576, 3685, 15594, - 15461, 15751, 15001, 14855, 14879, 15452, 15461, 15514, 15439, 15521, 15696, 15956, 16122, - 16041, 15319, 15521, 15439, 15226, 15291, 15114, 14046, 14414, 14016, 29311, 28915, 29208, - 29570, 29810, 29807, 29949, 30113, 30149, 30843, 30747, 30922, 30354, 30747, 30597, 37888, - 37799, 38042, 38339, 38151, 38367, 2928, 2989, 3055, 3224, 3047, 3116, 39978, 39968, - 39859, 3044, 3158, 3161, 39896, 39878, 39711, 39863, 39566, 39750, 40010, 39878, 39896, - 3987, 4233, 3995, 8812, 8944, 8627, 9064, 9105, 9079, 9758, 9870, 9970, 13763, - 14107, 14086, 13763, 14086, 13837, 15939, 16122, 15956, 25579, 25513, 25561, 24735, 24705, - 25050, 25579, 25561, 25728, 36037, 35894, 36060, 35762, 35517, 35648, 35826, 35892, 35879, - 35954, 35892, 35826, 17616, 17522, 17412, 18033, 18128, 18360, 23540, 23705, 23795, 22873, - 22753, 22744, 25298, 25172, 25292, 25677, 25511, 25426, 26577, 26891, 26587, 25201, 25151, - 25130, 25290, 25151, 25201, 25290, 25242, 25299, 28755, 28673, 28746, 10603, 10485, 10489, - 10996, 10906, 11078, 37429, 37443, 37394, 37888, 37788, 37799, 22324, 22266, 22492, 22324, - 22492, 22639, 23786, 23709, 24015, 39968, 39959, 39854, 24350, 24381, 24655, 24350, 24655, - 24629, 39702, 39823, 39680, 39662, 39573, 39529, 39662, 39826, 39819, 15521, 15737, 15696, - 39485, 39353, 39216, 10035, 9917, 10077, 10009, 9917, 10035, 3364, 3370, 3402, 3471, - 3552, 3575, 2965, 3125, 3067, 35762, 35648, 35859, 6509, 6768, 6376, 8071, 8039, - 8132, 8590, 8812, 8627, 7916, 7920, 7984, 7858, 7839, 7916, 7714, 7654, 7858, - 7652, 7654, 7714, 8304, 7396, 7652, 10049, 10365, 10407, 10246, 10365, 10049, 37271, - 37429, 37099, 37055, 37191, 36845, 37305, 37191, 37055, 4888, 4929, 4778, 5064, 5042, - 5102, 8304, 7194, 7396, 7654, 7839, 7858, 22485, 22669, 22415, 28673, 28438, 28382, - 27652, 27614, 27770, 27244, 27163, 27306, 30370, 30319, 30145, 30370, 30145, 30648, 38435, - 38454, 38428, 38997, 38823, 38948, 18864, 18722, 18775, 19880, 20021, 19644, 39959, 40022, - 39882, 6967, 7171, 7194, 8304, 7624, 7194, 7839, 7920, 7916, 34109, 34062, 33997, - 34109, 34201, 34062, 34062, 34201, 34064, 34258, 34459, 34414, 34414, 34488, 34479, 34479, - 35105, 34687, 35532, 35236, 35535, 35105, 35236, 34902, 35318, 35418, 35409, 3614, 3708, - 3588, 3643, 3584, 3685, 14939, 14855, 15001, 27075, 27163, 27244, 27075, 27153, 27163, - 26377, 26256, 26280, 31027, 30853, 30870, 33823, 33958, 33997, 35925, 35896, 35859, 36108, - 36037, 36060, 37545, 37433, 37538, 7163, 5576, 6220, 15452, 15127, 15084, 17872, 17786, - 17883, 17852, 17786, 17872, 23915, 23786, 24015, 39874, 39849, 39770, 39801, 39823, 39702, - 27388, 27423, 27432, 39181, 38948, 39038, 8003, 8039, 8071, 8233, 8411, 8272, 35595, - 35389, 35324, 35486, 35324, 35409, 10760, 10668, 10603, 22962, 22903, 23127, 30870, 30853, - 30746, 30747, 30746, 30597, 3575, 3552, 3607, 3512, 3606, 3210, 15461, 15452, 15392, - 15594, 15751, 15599, 26377, 26280, 26446, 25299, 25426, 25267, 3317, 3370, 3364, 4960, - 5042, 5064, 13198, 13230, 13116, 10760, 10670, 10668, 13577, 13340, 13531, 13577, 13531, - 13598, 13753, 14046, 13869, 13240, 13359, 13456, 11786, 12322, 11521, 25151, 25290, 25267, - 24490, 24498, 24769, 38717, 38516, 38616, 3899, 3881, 3930, 3764, 3881, 3899, 14510, - 14456, 14568, 23109, 23138, 23167, 24599, 24338, 24611, 23277, 23138, 23109, 25513, 25402, - 25322, 24629, 24655, 24705, 25696, 25579, 25728, 33542, 33757, 33740, 39874, 39770, 39798, - 23978, 23915, 24015, 24988, 25050, 24705, 39557, 39523, 39127, 39932, 39661, 39835, 8099, - 8233, 8272, 33350, 33542, 33740, 39991, 40076, 39793, 40294, 39943, 39982, 40294, 40129, - 39958, 40209, 39978, 39989, 40299, 40114, 39978, 39978, 40114, 39968, 39968, 40114, 39959, - 39959, 40114, 40022, 40325, 39991, 39847, 4659, 4739, 4804, 4949, 4960, 5064, 4512, - 4586, 4463, 29311, 29418, 28694, 29311, 28694, 28915, 17786, 17661, 17616, 17729, 17661, - 17786, 23786, 23325, 23515, 23978, 24015, 24088, 33828, 33740, 33757, 32475, 32057, 32353, - 37888, 38012, 37928, 37928, 38012, 37904, 37660, 37906, 37809, 4724, 4700, 4392, 4453, - 4512, 4463, 8812, 8920, 9079, 9105, 9346, 9254, 8947, 8920, 8933, 3346, 3512, - 3210, 10067, 10009, 10035, 9917, 9835, 9842, 39196, 39181, 39038, 39599, 39243, 39266, - 36987, 36936, 36838, 37423, 37429, 37271, 37616, 37627, 37644, 4566, 4739, 4659, 10679, - 11032, 10711, 29836, 29810, 29570, 37627, 37610, 37644, 4463, 4459, 4453, 13753, 13724, - 13665, 15850, 15939, 15737, 29445, 28940, 29585, 28632, 28508, 28438, 28943, 28984, 29131, - 33856, 33740, 33828, 38999, 38863, 38689, 13612, 13577, 13598, 30021, 29994, 29934, 30906, - 30824, 30971, 30123, 30354, 30149, 37586, 37545, 37538, 37586, 37538, 37766, 3037, 3044, - 3161, 2913, 2999, 2958, 3037, 3200, 3179, 23663, 23325, 23786, 39885, 39874, 39798, - 39849, 40001, 39442, 21118, 21224, 21325, 21325, 21329, 21447, 21649, 21622, 21760, 21760, - 21748, 21973, 22169, 22329, 22175, 21073, 21224, 21118, 21073, 21118, 21039, 20973, 21039, - 20989, 20973, 20989, 20842, 20973, 20842, 20724, 31609, 31489, 31787, 32139, 32117, 32277, - 36533, 36177, 36573, 35959, 35919, 36375, 2861, 2965, 3067, 19215, 18950, 19184, 22149, - 22058, 21973, 30120, 29934, 30319, 37610, 37505, 37593, 27541, 27614, 27652, 28943, 28755, - 28746, 38568, 38367, 38454, 38568, 38339, 38367, 38302, 38489, 38183, 37574, 37586, 37695, - 38604, 38435, 38516, 38411, 38402, 38095, 3224, 3355, 3047, 3268, 3317, 3364, 35105, - 34773, 34687, 3708, 3614, 3815, 3576, 3503, 3526, 3534, 3614, 3588, 39215, 39181, - 39196, 38997, 38999, 38823, 2872, 2920, 2995, 2995, 2920, 3043, 2979, 2718, 3009, - 2755, 2859, 2628, 3008, 2897, 3055, 2989, 2829, 3067, 2872, 2995, 2940, 2995, - 2967, 2940, 2967, 2913, 2940, 21480, 21337, 21298, 19215, 19137, 18950, 21504, 21337, - 21480, 21504, 21480, 21579, 21480, 21798, 21579, 21798, 21650, 21579, 21224, 21329, 21325, - 25290, 25299, 25267, 24326, 24096, 24187, 39557, 39127, 39747, 4778, 4929, 4784, 24088, - 24162, 24173, 23915, 23864, 23786, 24162, 24335, 24173, 30220, 30120, 30319, 14118, 14086, - 14253, 14647, 14510, 14568, 14647, 14781, 14855, 14647, 14855, 14776, 16122, 16206, 16238, - 15737, 15939, 15904, 15636, 15737, 15544, 26630, 26502, 26446, 27075, 27062, 26973, 27716, - 28109, 27879, 9145, 9346, 9105, 22485, 22576, 22669, 22547, 22576, 22485, 36037, 35896, - 35925, 36456, 36261, 36475, 2967, 2999, 2913, 21798, 21873, 21650, 3197, 3317, 3268, - 3465, 3471, 3512, 3534, 3584, 3643, 13665, 13724, 13413, 12843, 12572, 12517, 36995, - 36475, 36749, 2913, 2624, 2639, 3293, 2679, 2765, 40021, 39932, 39843, 40021, 39791, - 39878, 39920, 39798, 39757, 39946, 40001, 39849, 39920, 39691, 39942, 33580, 33599, 33450, - 33687, 33599, 33580, 33687, 33580, 33643, 33687, 33643, 33894, 35681, 35954, 35826, 35236, - 35418, 35318, 10254, 10371, 10489, 11404, 11789, 11679, 14118, 14253, 14288, 13665, 13413, - 13525, 30672, 30370, 30648, 31609, 31787, 32007, 30843, 30870, 30746, 32353, 31908, 32011, - 30843, 30746, 30747, 37334, 37271, 37191, 2639, 2665, 2838, 22022, 21923, 21873, 21798, - 22022, 21873, 4891, 4960, 4949, 5042, 5031, 5102, 30220, 30370, 30346, 37610, 37490, - 37505, 2848, 2859, 2724, 10009, 9835, 9917, 10254, 10489, 10306, 22022, 22030, 21923, - 21329, 21622, 21649, 32007, 31787, 31904, 37552, 37593, 37429, 36839, 36987, 36838, 8920, - 9064, 9079, 8947, 9064, 8920, 15452, 15130, 15127, 15525, 15594, 15599, 18835, 18722, - 18950, 18950, 18722, 18864, 36108, 35896, 36037, 34886, 34605, 34429, 36199, 35954, 36131, - 36642, 36839, 36426, 39355, 39324, 39168, 39397, 39324, 39355, 40105, 39896, 39899, 40096, - 39899, 40022, 13340, 13230, 13198, 13420, 13230, 13340, 13420, 13340, 13577, 12969, 13213, - 13240, 35418, 35486, 35409, 10485, 10603, 10668, 31370, 31307, 31292, 3224, 3259, 3345, - 3116, 3259, 3224, 24988, 25133, 25050, 24769, 24599, 24611, 23972, 23954, 24096, 39800, - 39662, 39819, 39942, 39691, 39823, 3202, 3079, 2869, 2859, 2864, 3008, 19644, 20021, - 19855, 17661, 17522, 17616, 17557, 17522, 17661, 18725, 18033, 18360, 23978, 24010, 23915, - 24173, 24335, 24313, 31221, 31106, 31027, 34022, 33856, 33828, 36456, 36266, 36216, 36195, - 36108, 36138, 16066, 16206, 16122, 25459, 25402, 25513, 25459, 25513, 25579, 25824, 25908, - 25915, 25299, 25442, 25426, 25356, 25442, 25299, 39523, 39501, 39116, 39571, 39501, 39523, - 39127, 39566, 39747, 2864, 2897, 3008, 4969, 5031, 5042, 10581, 10485, 10668, 10581, - 10668, 10670, 18098, 17374, 17251, 20724, 20842, 20615, 22022, 22079, 22030, 35486, 35595, - 35324, 37549, 37384, 37149, 36287, 36195, 36398, 37549, 37374, 37545, 38211, 38150, 38183, - 37593, 37443, 37429, 37593, 37505, 37443, 40035, 40010, 39896, 40148, 40010, 40035, 32277, - 32117, 32508, 32023, 32007, 31904, 36049, 35919, 35892, 4529, 4547, 4659, 4778, 4891, - 4888, 4888, 4891, 4949, 4960, 4969, 5042, 4527, 4547, 4529, 4525, 4644, 4512, - 4525, 4512, 4453, 4453, 4459, 4383, 12339, 12230, 13116, 29836, 29850, 29810, 29810, - 29850, 29949, 29532, 29311, 29384, 6376, 6768, 6970, 6376, 6970, 6312, 35954, 36049, - 35892, 36508, 36049, 36324, 14510, 14357, 14456, 15050, 15001, 15127, 27074, 27062, 27075, - 27074, 27075, 27244, 39181, 39093, 38948, 38717, 38604, 38516, 39149, 39093, 39181, 2897, - 2928, 3055, 4392, 4700, 4137, 19690, 19541, 19575, 22166, 22162, 22079, 22022, 22166, - 22079, 14587, 14414, 14348, 14587, 14660, 14414, 15939, 16066, 16122, 34886, 34429, 35517, - 39336, 39214, 39168, 39215, 39214, 39473, 39039, 39249, 38423, 39421, 39434, 39826, 39309, - 39249, 39039, 18033, 17953, 17954, 17852, 17530, 17729, 29580, 29570, 29418, 39946, 39849, - 39874, 39801, 39702, 39760, 3207, 3941, 3795, 3882, 3987, 3995, 3267, 3795, 3552, - 14595, 14357, 14510, 13763, 13612, 13598, 4275, 4392, 4094, 24313, 24335, 24350, 25171, - 25133, 25172, 24599, 24769, 24498, 23918, 23705, 23829, 28728, 28438, 28673, 28984, 28943, - 28746, 29445, 29585, 29647, 29753, 29647, 29994, 30021, 29934, 30120, 40010, 39972, 39878, - 39932, 39952, 39661, 40077, 39972, 40148, 24088, 24010, 23978, 24500, 24350, 24629, 23672, - 23540, 23621, 39800, 39801, 39760, 22079, 22162, 22021, 8039, 8099, 8272, 8233, 8278, - 8411, 7920, 8003, 8071, 7927, 8003, 7920, 7927, 7920, 7809, 7598, 7839, 7654, - 7598, 7654, 7529, 7598, 7529, 7497, 11579, 11629, 10996, 30870, 31089, 31027, 30922, - 30747, 30354, 34201, 34292, 34258, 35236, 35532, 35418, 35418, 35532, 35486, 35486, 35532, - 35595, 34082, 34109, 33997, 34082, 33997, 33958, 34082, 33958, 34022, 33958, 33856, 34022, - 37574, 37549, 37545, 30220, 30021, 30120, 30220, 30319, 30370, 30648, 30725, 30672, 29850, - 30113, 29949, 3496, 3503, 3576, 3496, 3576, 3584, 3512, 3471, 3575, 3465, 3512, - 3346, 3256, 3370, 3317, 15594, 15514, 15461, 15525, 15514, 15594, 36508, 36375, 35919, - 37305, 37055, 37095, 36887, 36839, 36642, 36675, 36642, 36533, 13595, 13612, 13763, 12339, - 12192, 12230, 13753, 13931, 14046, 13525, 13413, 13359, 7497, 7529, 7520, 6220, 5576, - 5913, 8003, 8099, 8039, 33542, 33159, 32977, 35956, 35762, 35859, 36238, 36108, 36195, - 36238, 36195, 36287, 2928, 2862, 2989, 3115, 3197, 3259, 14357, 14118, 14288, 22030, - 22079, 22021, 21940, 22149, 21973, 23277, 23167, 23138, 27707, 28159, 28109, 16206, 16453, - 16475, 16155, 16066, 16099, 25442, 25543, 25426, 25597, 25543, 25442, 25298, 25171, 25172, - 25298, 25292, 25402, 24827, 25201, 25130, 35956, 35859, 35896, 31609, 31370, 31292, 32198, - 32093, 32083, 32160, 32093, 32198, 39972, 40008, 39878, 40077, 40008, 39972, 39946, 39874, - 40027, 33005, 33542, 32977, 4778, 4784, 4640, 15525, 15404, 15514, 17953, 17852, 17872, - 17729, 17530, 17499, 17729, 17499, 17722, 23829, 23672, 23621, 31105, 30971, 31307, 30672, - 30725, 30801, 40027, 39874, 39885, 40108, 39942, 39823, 38467, 38211, 38183, 37586, 37574, - 37545, 38717, 38616, 38938, 40129, 39806, 39958, 26257, 26082, 26256, 39599, 39386, 39243, - 33005, 33623, 33542, 10721, 10581, 10670, 10485, 10306, 10489, 10003, 9985, 10067, 10721, - 10670, 10813, 27062, 26875, 26801, 26966, 26875, 27062, 5913, 5630, 5684, 4891, 4969, - 4960, 28109, 28159, 28245, 27325, 27074, 27244, 40008, 40021, 39878, 39569, 39545, 39386, - 40077, 40021, 40008, 3614, 3534, 3643, 3588, 3906, 3382, 14336, 14414, 14046, 15226, - 15319, 15439, 26630, 26446, 26801, 27432, 27423, 27541, 33307, 33500, 33005, 38938, 38616, - 38863, 39214, 39215, 39196, 39336, 39168, 39324, 17852, 17729, 17786, 18725, 18360, 18722, - 23672, 23829, 23705, 24187, 24611, 24338, 25356, 25242, 25201, 23277, 23109, 22940, 38604, - 38717, 38637, 10067, 9985, 10009, 10003, 10067, 10254, 3534, 3496, 3584, 2765, 2679, - 2651, 15514, 15404, 15452, 14647, 14595, 14510, 13837, 14086, 14118, 17295, 17412, 17121, - 26377, 26257, 26256, 31463, 31370, 31558, 33228, 32787, 33200, 33992, 33643, 33793, 19251, - 19137, 19215, 25201, 25242, 25290, 24827, 25130, 24769, 39747, 39566, 39748, 4547, 4566, - 4659, 4902, 4976, 4969, 4525, 4527, 4529, 4200, 4527, 4525, 4511, 4527, 4446, - 4525, 4453, 4383, 25597, 25575, 25543, 25543, 25575, 25426, 26805, 26891, 26577, 29532, - 29418, 29311, 38498, 38339, 38524, 38498, 38302, 38339, 4511, 4566, 4547, 29532, 29580, - 29418, 29850, 30101, 30113, 30922, 30896, 30843, 29311, 29305, 29384, 38012, 38080, 38095, - 38402, 38646, 38357, 37888, 38080, 38012, 38042, 38080, 37888, 38042, 37799, 37809, 38042, - 37809, 37906, 10535, 10306, 10485, 10996, 11629, 11404, 30893, 30725, 30906, 37766, 37611, - 37670, 37549, 37556, 37384, 37384, 37053, 36796, 37610, 37666, 37644, 37305, 37095, 37135, - 40331, 39611, 39736, 40027, 39885, 39920, 9064, 9145, 9105, 9346, 9575, 9678, 8933, - 8920, 8812, 30079, 29994, 30021, 30079, 29753, 29994, 28245, 28159, 28263, 30079, 30021, - 30220, 29580, 29836, 29570, 36136, 35956, 35896, 35676, 34886, 35517, 36136, 35896, 36108, - 38211, 37971, 37748, 31271, 31105, 31307, 3259, 3197, 3268, 2874, 3125, 2965, 32800, - 32775, 32668, 2829, 2861, 3067, 13595, 13557, 13612, 13612, 13557, 13577, 13420, 13557, - 13585, 13358, 13525, 13359, 13805, 13931, 13753, 13091, 13359, 13213, 13020, 13213, 12969, - 19137, 19020, 18950, 27718, 27652, 27770, 28159, 28438, 28508, 40192, 40096, 40022, 25447, - 25298, 25402, 26257, 25915, 26082, 27718, 27770, 27879, 39386, 39397, 39355, 39545, 39397, - 39386, 17729, 17722, 17661, 17537, 17722, 17499, 9639, 9575, 9509, 10453, 10679, 10711, - 21224, 21250, 21329, 21329, 21511, 21622, 21622, 21748, 21760, 20435, 20023, 20065, 32508, - 32297, 32787, 32093, 32007, 32023, 36375, 36573, 36177, 37135, 37095, 36987, 36636, 36573, - 36603, 36675, 36573, 36636, 12610, 12843, 12517, 12121, 12387, 11786, 20973, 21073, 21039, - 2920, 2838, 2818, 2776, 2920, 2818, 2776, 3043, 2920, 2776, 2979, 3043, 2859, - 2848, 2864, 2864, 2848, 2897, 2897, 2786, 2928, 2928, 2786, 2862, 2862, 2829, - 2989, 2872, 2838, 2920, 4640, 4784, 4739, 22682, 22753, 22576, 22547, 22329, 22169, - 2872, 2940, 2838, 10906, 10721, 10813, 10453, 10711, 10365, 21337, 21188, 21298, 19690, - 19624, 19541, 19541, 19251, 19351, 19137, 19119, 19020, 21339, 21188, 21337, 21339, 21337, - 21504, 21339, 21504, 21441, 21504, 21579, 21441, 21579, 21650, 21623, 21650, 21873, 21623, - 21873, 21819, 21623, 21073, 21206, 21224, 22169, 22175, 22149, 30544, 30346, 30370, 31013, - 30893, 30906, 30843, 30896, 30870, 31004, 30896, 30922, 40096, 40105, 39899, 26309, 26577, - 26242, 15130, 15050, 15127, 26257, 26165, 25915, 26502, 26377, 26446, 26875, 26630, 26801, - 26742, 26630, 26875, 26742, 26875, 26966, 3047, 3355, 3272, 24152, 24010, 24088, 24756, - 24500, 24629, 24756, 24629, 24735, 25050, 25133, 25171, 39662, 39800, 39573, 40219, 40002, - 39942, 40002, 40027, 39920, 39434, 39395, 39826, 2838, 2940, 2639, 12843, 13020, 12969, - 21206, 21250, 21224, 25696, 25728, 25785, 37431, 37053, 37384, 3810, 3995, 3881, 3810, - 3881, 3764, 9911, 9835, 10009, 9911, 10009, 9985, 9639, 9870, 9758, 21873, 21923, - 21819, 21923, 22021, 21819, 25785, 25728, 25824, 25785, 25824, 25909, 25575, 25677, 25426, - 25597, 25677, 25575, 15202, 15319, 15226, 15114, 14895, 14737, 26583, 26377, 26502, 26247, - 26309, 26242, 30544, 30370, 30672, 37028, 36995, 37053, 37810, 37766, 37670, 39447, 39336, - 39324, 39149, 38997, 39093, 10535, 10485, 10581, 17722, 17557, 17661, 17537, 17557, 17722, - 24152, 24088, 24173, 23829, 23954, 23918, 25356, 25597, 25442, 23910, 23954, 23829, 37135, - 36987, 37123, 17389, 17412, 17522, 15130, 14939, 15050, 25120, 25050, 25171, 2861, 2874, - 2965, 2797, 2874, 2861, 19020, 18835, 18950, 18927, 18835, 19020, 22547, 22611, 22576, - 22689, 22611, 22547, 2869, 3079, 2560, 21250, 21511, 21329, 40242, 39982, 40014, 40114, - 40192, 40022, 40096, 40195, 40105, 40275, 40014, 40076, 8000, 8182, 8099, 8099, 8182, - 8233, 7497, 7520, 7401, 40002, 39920, 39942, 40115, 39580, 40060, 7286, 7520, 7396, - 3730, 3810, 3764, 27619, 27432, 27541, 27484, 27432, 27619, 34109, 34220, 34314, 34292, - 34109, 34314, 34459, 34292, 34314, 34109, 34292, 34201, 34082, 34022, 34220, 33889, 33828, - 33757, 32277, 32160, 32198, 31175, 31060, 31105, 31105, 31060, 30971, 32173, 32160, 32291, - 36573, 36675, 36533, 36642, 36675, 36777, 4769, 5367, 5031, 7208, 7286, 7396, 4976, - 5031, 4969, 33482, 33200, 33599, 39580, 40001, 40060, 7208, 7396, 7194, 34605, 33992, - 33793, 35676, 35517, 35762, 39397, 39420, 39324, 39545, 39420, 39397, 31271, 31307, 31463, - 30893, 30801, 30725, 31004, 31089, 30870, 31004, 30870, 30896, 37451, 37423, 37271, 37593, - 37666, 37610, 4845, 4969, 4891, 11404, 11629, 11789, 10906, 10897, 10721, 10721, 10535, - 10581, 11789, 11961, 11679, 37717, 37666, 37707, 2560, 3079, 3044, 2815, 3044, 3037, - 7171, 7208, 7194, 8833, 10086, 9842, 18835, 18725, 18722, 18859, 18725, 18835, 21923, - 22030, 22021, 22611, 22682, 22576, 24125, 24113, 23954, 22689, 22682, 22611, 40060, 40001, - 40206, 3116, 3115, 3259, 3210, 3454, 3370, 3471, 3406, 3552, 3091, 3115, 3116, - 24409, 24611, 24187, 4566, 4585, 4739, 4778, 4845, 4891, 4527, 4511, 4547, 4383, - 4459, 4392, 6995, 7171, 6967, 23954, 24113, 24096, 24149, 24113, 24125, 29727, 29837, - 29836, 29836, 29837, 29850, 28915, 29034, 29208, 4275, 4383, 4392, 3808, 3882, 3995, - 13639, 13753, 13665, 13639, 13665, 13525, 27826, 27879, 27942, 27826, 27718, 27879, 40048, - 39952, 39932, 40048, 39932, 40021, 2859, 3068, 2628, 20370, 20021, 20331, 21517, 21748, - 21622, 4500, 4585, 4566, 4150, 4024, 4452, 3964, 4024, 3865, 5820, 6232, 6080, - 13557, 13420, 13577, 13595, 13763, 13687, 16066, 16155, 16206, 15964, 16066, 15939, 25298, - 25246, 25171, 25459, 25447, 25402, 25459, 25579, 25614, 28673, 28755, 28728, 39557, 39571, - 39523, 39751, 39571, 39557, 4275, 4094, 4194, 11285, 11521, 11271, 13113, 13091, 13020, - 29727, 29836, 29580, 37971, 37980, 37748, 38094, 37980, 37971, 38230, 37971, 38211, 38080, - 38184, 38095, 37906, 37660, 37644, 8749, 8115, 8441, 7927, 8099, 8003, 15050, 14939, - 15001, 15130, 15452, 15404, 22682, 22744, 22753, 22689, 22744, 22682, 27325, 27306, 27432, - 27106, 27062, 27074, 26630, 26583, 26502, 25909, 25824, 25915, 40134, 40126, 39736, 40075, - 40001, 39946, 10003, 9911, 9985, 8950, 8833, 9842, 9882, 9911, 9819, 9868, 9897, - 9870, 9870, 9897, 10049, 9639, 9758, 9575, 15636, 15850, 15737, 19644, 19624, 19690, - 22166, 22324, 22162, 26165, 26257, 26377, 32475, 32800, 32668, 33542, 33665, 33757, 32490, - 32800, 32475, 35887, 35676, 35762, 36195, 36266, 36398, 37053, 36995, 36749, 37570, 37549, - 37574, 37123, 36987, 37151, 37305, 37334, 37191, 7397, 8079, 8115, 8950, 9842, 9835, - 31013, 30801, 30893, 37695, 37570, 37574, 37695, 37586, 37766, 4392, 4137, 4094, 38568, - 38454, 38604, 38568, 38604, 38637, 15403, 15300, 15377, 15544, 15737, 15521, 12192, 11961, - 12230, 28728, 28755, 28943, 30254, 30079, 30220, 30033, 30079, 30254, 37980, 37923, 37748, - 37932, 37906, 37644, 8182, 8278, 8233, 8910, 9145, 9064, 27181, 27325, 27484, 31060, - 31013, 30906, 31463, 31307, 31370, 31089, 31221, 31027, 31184, 31221, 31089, 37423, 37552, - 37429, 37666, 37722, 37644, 37338, 37334, 37305, 2848, 2786, 2897, 40090, 40075, 39946, - 40108, 39823, 39801, 24871, 24756, 24735, 24361, 24313, 24350, 24871, 24735, 25050, 24611, - 24725, 24769, 24465, 24725, 24611, 39800, 39901, 39801, 39826, 40110, 40088, 2844, 3334, - 3390, 17557, 17389, 17522, 17537, 17389, 17557, 24113, 24149, 24187, 23621, 23540, 23455, - 38999, 38997, 39222, 40099, 39863, 40168, 13837, 14118, 13968, 12339, 13116, 13230, 13931, - 13886, 14046, 13537, 13639, 13525, 13091, 13213, 13020, 3317, 3197, 3104, 3256, 3317, - 3104, 3810, 3808, 3995, 4742, 4845, 4778, 15599, 15751, 15905, 15599, 15905, 15626, - 37923, 37810, 37670, 22492, 22575, 22639, 8803, 8933, 8812, 3882, 3783, 3987, 3730, - 3808, 3810, 39149, 39181, 39215, 39149, 39215, 39503, 5823, 5820, 6080, 6162, 6080, - 6307, 30787, 30544, 30672, 31175, 31013, 31060, 30123, 30149, 30113, 31731, 31521, 31226, - 37566, 37556, 37570, 37570, 37556, 37549, 37451, 37552, 37423, 15964, 16099, 16066, 18656, - 19012, 18638, 15964, 15939, 15850, 24901, 24871, 25050, 25614, 25579, 25696, 25614, 25696, - 25790, 3104, 3197, 3040, 13113, 13020, 12890, 29445, 29647, 29753, 28117, 27879, 28109, - 27181, 27074, 27325, 33623, 33665, 33542, 38782, 38637, 38717, 40155, 39747, 39748, 39599, - 39266, 39501, 22744, 22940, 22873, 22880, 22940, 22744, 37717, 37722, 37666, 40148, 39972, - 40010, 40099, 39995, 39863, 40195, 40035, 40105, 23864, 23663, 23786, 23864, 23915, 24010, - 23455, 23540, 23277, 39599, 39501, 39571, 39420, 39447, 39324, 31221, 31731, 31226, 31778, - 31731, 31980, 2786, 2829, 2862, 2874, 2813, 3385, 19413, 19251, 19541, 18725, 18761, - 18033, 22962, 23127, 23038, 22055, 22169, 22149, 24361, 24350, 24500, 24361, 24500, 24482, - 31271, 31175, 31105, 31571, 31370, 31609, 13440, 13230, 13420, 13968, 14118, 13897, 13639, - 13805, 13753, 13756, 13805, 13639, 3760, 3906, 4035, 3534, 3328, 3496, 3338, 3505, - 2572, 25246, 25298, 25447, 24725, 24827, 24769, 26949, 26805, 26861, 24861, 24827, 24725, - 24409, 24187, 24149, 27642, 27691, 27208, 26309, 26805, 26577, 26247, 26242, 25895, 32111, - 32007, 32093, 32173, 32093, 32160, 31731, 32011, 31521, 33665, 33623, 33695, 33005, 32891, - 33307, 37512, 37451, 37334, 37334, 37451, 37271, 36777, 36887, 36642, 36573, 36375, 36603, - 36375, 36562, 36603, 39910, 39901, 39800, 40329, 39279, 39353, 26776, 26583, 26630, 27181, - 27106, 27074, 27325, 27432, 27484, 39473, 39214, 39336, 14939, 14776, 14855, 15248, 15130, - 15404, 26776, 26630, 26742, 28508, 28263, 28159, 40090, 39946, 40027, 40134, 39736, 40115, - 40090, 40027, 40002, 10966, 10897, 10996, 10996, 10897, 10906, 4585, 4640, 4739, 4511, - 4500, 4566, 4446, 4500, 4511, 4481, 4500, 4446, 10775, 11285, 11271, 10246, 10453, - 10365, 13585, 13557, 13595, 11026, 10966, 10996, 29676, 29445, 29753, 28508, 28364, 28263, - 29194, 29611, 29207, 29532, 29727, 29580, 31085, 31089, 31004, 28915, 28936, 29034, 31085, - 31184, 31089, 30123, 30113, 30101, 37556, 37431, 37384, 37566, 37431, 37556, 37707, 37666, - 37593, 37338, 37305, 37135, 38055, 38080, 38042, 38055, 38184, 38080, 38055, 38042, 37906, - 27797, 28058, 27769, 36777, 36636, 36792, 3465, 3406, 3471, 3388, 3406, 3465, 26431, - 26165, 26377, 25895, 25800, 25677, 35887, 35762, 35956, 39645, 39447, 39420, 25228, 25246, - 25447, 25228, 25447, 25444, 4591, 4640, 4585, 17374, 17205, 17016, 15945, 15964, 15940, - 25790, 25696, 25785, 25356, 25299, 25242, 38498, 38489, 38302, 38407, 37810, 37923, 37698, - 38038, 37781, 38524, 38489, 38498, 38524, 38339, 38568, 39545, 39645, 39420, 39751, 39599, - 39571, 19251, 19119, 19137, 40256, 40192, 40114, 23961, 23864, 24010, 24482, 24500, 24756, - 24482, 24756, 24751, 4024, 3964, 4324, 3865, 4024, 3702, 13527, 13585, 13595, 13687, - 13763, 13837, 13358, 13537, 13525, 40077, 40048, 40021, 40163, 40048, 40077, 27642, 27208, - 27365, 7269, 7286, 7208, 7334, 7401, 7286, 7286, 7401, 7520, 7497, 7401, 7598, - 7809, 7920, 7839, 8182, 8106, 8278, 7269, 7208, 7107, 34292, 34459, 34258, 34109, - 34082, 34220, 34022, 33828, 33978, 4640, 4742, 4778, 4845, 4902, 4969, 4976, 4769, - 5031, 25120, 24901, 25050, 28909, 28728, 28943, 30101, 29850, 29837, 38721, 38524, 38568, - 38765, 38568, 38637, 38938, 38863, 39026, 30123, 30922, 30354, 15544, 15521, 15519, 15521, - 15319, 15519, 15319, 15403, 15519, 26064, 25909, 25915, 25722, 25895, 25677, 33889, 33757, - 33786, 31763, 31571, 31609, 31463, 31340, 31271, 37048, 36987, 36839, 37048, 36839, 36887, - 2829, 2849, 2861, 9911, 9882, 9835, 10003, 10254, 10306, 18638, 19012, 19292, 16206, - 16155, 16453, 40134, 40115, 40172, 7107, 7208, 7171, 7809, 7839, 7598, 8590, 8803, - 8812, 19647, 19902, 19532, 21247, 21206, 21073, 21389, 21345, 21206, 21206, 21345, 21250, - 21250, 21345, 21511, 21511, 21517, 21622, 21748, 21865, 21973, 23663, 23479, 23325, 23961, - 24010, 24152, 32886, 32508, 32787, 31790, 31763, 31609, 32482, 32508, 32574, 32353, 32490, - 32475, 32439, 32490, 32353, 40325, 40275, 40076, 40129, 40209, 39989, 40377, 40275, 40427, - 2744, 2718, 2979, 2848, 2766, 2786, 2786, 2608, 2829, 2829, 2698, 2849, 2744, - 2979, 2839, 2744, 2839, 2739, 2839, 2702, 2739, 2776, 2702, 2839, 2718, 2714, - 3009, 2776, 2712, 2702, 9897, 10246, 10049, 11989, 12121, 11570, 10168, 10246, 9897, - 20938, 20756, 20766, 19644, 19603, 19624, 19624, 19523, 19541, 19251, 19151, 19119, 20938, - 20766, 21188, 21175, 21188, 21339, 21175, 21339, 21307, 21579, 21562, 21441, 21623, 21562, - 21579, 40377, 40242, 40014, 6995, 7107, 7171, 2776, 2818, 2712, 39078, 38646, 38402, - 39249, 39485, 39216, 14780, 14776, 14939, 27106, 26966, 27062, 26080, 26064, 26165, 26165, - 26064, 25915, 26994, 26966, 27106, 40172, 40115, 40060, 40146, 40684, 40611, 2712, 2818, - 2665, 9509, 9575, 9476, 32354, 32160, 32277, 36636, 36777, 36675, 35752, 35681, 35595, - 39039, 38813, 39124, 36266, 36423, 36398, 36136, 36108, 36238, 35901, 35887, 35956, 28109, - 28245, 28117, 27541, 27652, 27619, 2662, 2797, 2849, 2849, 2797, 2861, 6967, 7194, - 6888, 19119, 18927, 19020, 19028, 18927, 19119, 40192, 40195, 40096, 40218, 40195, 40192, - 40126, 40331, 39736, 40172, 40060, 40182, 2654, 2712, 2665, 11363, 11679, 11415, 13834, - 13687, 13837, 21623, 21805, 21562, 39026, 38863, 38999, 40242, 40294, 39982, 3047, 3091, - 3116, 3210, 3606, 3454, 3022, 3091, 2931, 24152, 24173, 24313, 24751, 24756, 24871, - 39910, 39800, 39819, 39910, 39819, 39826, 25107, 25356, 25201, 25597, 25700, 25677, 25393, - 25356, 25107, 10588, 10535, 10721, 10588, 10721, 10897, 31980, 31731, 31623, 31731, 31778, - 32011, 32290, 32439, 32353, 30922, 31085, 31004, 31181, 31085, 30922, 6888, 7194, 6785, - 8000, 8106, 8182, 8933, 8803, 8947, 34752, 33992, 34605, 33687, 33731, 33599, 33894, - 33992, 34023, 34752, 34886, 35234, 4669, 4902, 4845, 28571, 28364, 28508, 30787, 30672, - 30801, 30787, 30801, 31013, 37722, 37852, 37644, 37562, 37593, 37552, 37562, 37552, 37451, - 21389, 21206, 21247, 24152, 24313, 24361, 23569, 23479, 23663, 27619, 27652, 27718, 18927, - 18859, 18835, 19028, 18859, 18927, 16109, 16155, 16099, 32508, 32461, 32277, 32482, 32461, - 32508, 6764, 6970, 7041, 21623, 21819, 21805, 21819, 21915, 21805, 36266, 36456, 36423, - 6785, 7194, 7624, 33992, 33894, 33643, 33786, 33757, 33665, 33786, 33665, 33695, 3210, - 3370, 3132, 3687, 3783, 3808, 15525, 15248, 15404, 14531, 14664, 14649, 16185, 16478, - 16349, 15945, 16109, 15964, 15964, 16109, 16099, 13886, 13931, 13805, 25909, 25814, 25785, - 25228, 25120, 25246, 25246, 25120, 25171, 24843, 24751, 24871, 26080, 26165, 26285, 11638, - 12121, 11786, 13091, 13113, 13359, 11271, 10679, 10775, 29384, 29549, 29532, 30123, 31072, - 30922, 29305, 29549, 29384, 29305, 29311, 29208, 2628, 3068, 3009, 21819, 22021, 21915, - 21345, 21517, 21511, 22800, 22689, 22630, 31211, 31221, 31184, 37512, 37562, 37451, 36984, - 37048, 36887, 4500, 4481, 4585, 4669, 4682, 4742, 4742, 4682, 4845, 4200, 4525, - 4383, 4274, 4383, 4275, 29549, 29727, 29532, 29382, 29305, 29208, 31571, 31558, 31370, - 31596, 31558, 31571, 32111, 32093, 32173, 3808, 3783, 3882, 3730, 3764, 3366, 12192, - 11679, 11961, 13440, 13420, 13585, 13527, 13440, 13585, 13897, 14004, 13997, 13756, 13886, - 13805, 13756, 13639, 13537, 38184, 38411, 38095, 37984, 38055, 37906, 4194, 4274, 4275, - 6771, 6785, 6647, 6344, 6785, 7624, 13527, 13595, 13687, 22630, 22547, 22169, 23250, - 23455, 23277, 23910, 24125, 23954, 29194, 29131, 28984, 28728, 28632, 28438, 29194, 28984, - 29445, 30001, 29753, 30079, 30940, 30787, 31013, 33894, 33810, 33687, 33695, 33623, 33619, - 38038, 37695, 38301, 36423, 36456, 36520, 38094, 37923, 37980, 38489, 38467, 38183, 38612, - 38467, 38489, 38721, 38489, 38524, 40219, 40090, 40002, 40025, 39910, 40012, 40134, 40214, - 40126, 40182, 40060, 40206, 40001, 40075, 40206, 2755, 2724, 2859, 32223, 32111, 32173, - 17389, 17121, 17412, 17852, 17745, 17530, 23810, 23829, 23621, 16349, 16478, 16667, 23569, - 23663, 23674, 23250, 23277, 22940, 29982, 30101, 29837, 39796, 39751, 39557, 39599, 39569, - 39386, 39796, 39557, 39747, 39995, 39748, 39863, 21915, 22021, 22162, 29131, 28909, 28943, - 40704, 40209, 40129, 14776, 14664, 14647, 14664, 14776, 14780, 26878, 26776, 26742, 26878, - 26742, 26966, 26878, 26966, 26994, 3040, 3197, 3115, 25447, 25459, 25444, 23663, 23864, - 23820, 23674, 23663, 23820, 33810, 33731, 33687, 32891, 32775, 33307, 35661, 35532, 35535, - 39745, 39569, 39599, 39447, 39473, 39336, 39176, 39026, 38999, 36288, 36136, 36238, 37028, - 37053, 37220, 18098, 18656, 18638, 19012, 19203, 19292, 40195, 40148, 40035, 39863, 39750, - 40168, 40236, 40148, 40195, 40373, 40214, 40134, 40206, 40075, 40146, 15395, 15248, 15525, - 15130, 14992, 14939, 32461, 32354, 32277, 32501, 32354, 32461, 36777, 36888, 36887, 36508, - 35919, 36049, 39503, 39473, 39447, 2724, 2766, 2848, 19605, 19603, 19644, 21669, 21865, - 21748, 4591, 4742, 4640, 10775, 10679, 10458, 28909, 28632, 28728, 28117, 28245, 28243, - 10228, 10121, 10306, 10663, 10588, 10897, 37698, 37566, 37570, 37698, 37570, 37695, 37338, - 37135, 37266, 37717, 37852, 37722, 19603, 19523, 19624, 22454, 21915, 22162, 21865, 21940, - 21973, 23038, 23127, 23325, 24152, 24361, 24220, 23455, 23594, 23621, 23541, 23594, 23455, - 36142, 36136, 36197, 35887, 35832, 35676, 24843, 24871, 24901, 3346, 3388, 3465, 3305, - 3388, 3346, 4094, 4137, 3969, 3267, 3552, 3406, 15964, 15850, 15940, 15403, 15319, - 15202, 26489, 26377, 26583, 25956, 25814, 25909, 24032, 24152, 24220, 32058, 31609, 32007, - 31340, 31175, 31271, 32058, 32007, 32111, 37048, 37151, 36987, 37236, 37151, 37222, 2691, - 2813, 2874, 3046, 3160, 3104, 2691, 2874, 2797, 22689, 22880, 22744, 23024, 22880, - 23035, 37858, 37852, 37717, 40146, 40075, 40090, 40282, 40134, 40172, 5820, 5545, 6232, - 5601, 5545, 5820, 13111, 13113, 12890, 32063, 32058, 32111, 39004, 38782, 38717, 38765, - 38782, 38807, 21940, 22055, 22149, 37266, 37135, 37123, 3132, 3370, 3256, 15850, 15636, - 15621, 36603, 36792, 36636, 36199, 36049, 35954, 33731, 33482, 33599, 33307, 33427, 33397, - 33307, 33250, 33283, 3104, 3160, 3256, 3040, 3115, 3022, 19523, 19413, 19541, 17425, - 17346, 17537, 34459, 34488, 34414, 34416, 34488, 34459, 34416, 34459, 34314, 34416, 34314, - 34441, 34022, 33978, 34220, 33889, 33978, 33828, 32354, 32291, 32160, 32425, 32291, 32354, - 36888, 36792, 36930, 3964, 3760, 4183, 3865, 3760, 3964, 7220, 7269, 7001, 7220, - 7286, 7269, 7220, 7334, 7286, 7401, 7179, 7598, 7927, 7931, 8099, 7269, 7107, - 7001, 7107, 6995, 7001, 6995, 6930, 7001, 13968, 13834, 13837, 12892, 12339, 13230, - 13897, 13834, 13968, 23038, 23325, 23395, 23395, 23325, 23479, 23820, 23864, 23867, 25956, - 25909, 26064, 24970, 24843, 24901, 26994, 27106, 27181, 28245, 28263, 28243, 31340, 31463, - 31558, 30001, 30079, 30033, 33889, 33786, 33978, 6248, 6162, 6307, 37858, 37707, 37873, - 37726, 37707, 37593, 7397, 7782, 8079, 6376, 6248, 6307, 6907, 7243, 6894, 6777, - 6967, 6888, 7572, 7809, 7598, 8590, 8627, 8278, 26590, 26489, 26583, 26010, 25956, - 26064, 27742, 27181, 27484, 13113, 13358, 13359, 14737, 14895, 14587, 4481, 4591, 4585, - 4196, 4446, 4527, 4200, 4383, 4274, 14664, 14595, 14647, 14531, 14595, 14664, 38356, - 38230, 38211, 38356, 38211, 38445, 17537, 17346, 17389, 18761, 18725, 18859, 40197, 39952, - 40048, 24220, 24361, 24482, 23867, 23864, 23961, 24970, 24901, 24984, 26590, 26583, 26776, - 40209, 40299, 39978, 40262, 40163, 40077, 7809, 7931, 7927, 33978, 33786, 33803, 29131, - 29142, 28909, 28666, 28571, 28632, 28378, 28263, 28364, 30346, 30254, 30220, 4440, 4591, - 4481, 30346, 30561, 30254, 30101, 30133, 30123, 32107, 32011, 31778, 29727, 29982, 29837, - 29954, 29982, 29727, 29687, 29727, 29549, 38234, 38094, 37971, 7931, 8000, 8099, 4094, - 3969, 4051, 22962, 22779, 22575, 23395, 23479, 23430, 28915, 28089, 28838, 29636, 29687, - 29549, 40282, 40172, 40182, 40025, 39801, 39901, 3388, 3330, 3406, 3305, 3330, 3388, - 15621, 15636, 15544, 14737, 14587, 14348, 32768, 32508, 32886, 36508, 36562, 36375, 36688, - 36562, 36508, 19413, 19151, 19251, 19080, 19203, 19012, 40299, 40256, 40114, 32223, 32173, - 32291, 31790, 31609, 32058, 31790, 31596, 31763, 31763, 31596, 31571, 37151, 37266, 37123, - 37502, 37512, 37334, 37236, 37266, 37151, 36888, 36777, 36792, 37781, 38038, 37801, 37566, - 37681, 37431, 23430, 23479, 23569, 24032, 23961, 24152, 23594, 23810, 23621, 24125, 24409, - 24149, 23541, 23810, 23594, 30081, 30133, 30101, 38055, 38289, 38184, 37932, 37984, 37906, - 37932, 37644, 37852, 4150, 4452, 4488, 13655, 13527, 13687, 13655, 13687, 13834, 16109, - 16092, 16155, 15621, 15544, 15540, 16539, 16349, 16667, 15512, 15395, 15599, 14118, 14357, - 14004, 25444, 25459, 25614, 28571, 28508, 28632, 27706, 27619, 27718, 32775, 33127, 33250, - 33803, 33786, 33695, 36006, 35956, 36142, 36006, 35901, 35956, 3722, 3987, 3783, 38757, - 38721, 38568, 38765, 38637, 38782, 3730, 3687, 3808, 3618, 3687, 3366, 27706, 27718, - 27826, 27691, 27797, 27769, 27365, 27208, 26891, 26949, 26891, 26805, 26805, 26309, 26372, - 26309, 26247, 26372, 31596, 31340, 31558, 30346, 30544, 30561, 32199, 32223, 32318, 36984, - 36888, 37074, 2608, 2698, 2829, 24222, 24409, 24125, 26372, 26247, 25895, 33803, 33695, - 33722, 40256, 40233, 40192, 37922, 37932, 37852, 37858, 37717, 37707, 40262, 40077, 40148, - 3160, 3132, 3256, 3196, 3305, 3346, 3022, 3115, 3091, 2844, 3390, 2813, 15540, - 15544, 15519, 24790, 24482, 24751, 24984, 24901, 25120, 25814, 25790, 25785, 26010, 26064, - 26080, 28666, 28632, 28752, 38807, 38782, 39004, 6785, 6771, 6888, 6344, 7624, 6220, - 8811, 8803, 8752, 23810, 23910, 23829, 23885, 23910, 23810, 33482, 33228, 33200, 36238, - 36287, 36411, 36142, 35956, 36136, 19151, 19028, 19119, 40233, 40218, 40192, 40282, 40182, - 40253, 40275, 40377, 40014, 40242, 40530, 40294, 40445, 40299, 40209, 40445, 40337, 40299, - 40299, 40337, 40256, 40256, 40386, 40233, 40233, 40386, 40218, 40325, 39847, 40159, 14348, - 14414, 14336, 15534, 15540, 15519, 26878, 26590, 26776, 26285, 26010, 26080, 26733, 26811, - 26738, 25700, 25597, 25523, 2744, 2673, 2718, 2718, 2596, 2714, 2714, 2628, 3009, - 2755, 2612, 2724, 2724, 2632, 2766, 2574, 2608, 2786, 2611, 2673, 2744, 2611, - 2744, 2739, 2611, 2739, 2654, 2739, 2702, 2654, 32290, 32353, 32011, 32107, 32159, - 32294, 32199, 32063, 32223, 32918, 32768, 32886, 26607, 26590, 26878, 39309, 39427, 39249, - 39124, 38813, 38716, 2654, 2702, 2712, 13437, 13756, 13537, 21098, 20938, 21188, 19605, - 19523, 19603, 19605, 19422, 19523, 19523, 19422, 19413, 19413, 19275, 19151, 19151, 18959, - 19028, 21098, 21188, 21175, 21098, 21175, 21153, 21175, 21307, 21153, 21441, 21307, 21339, - 21384, 21307, 21441, 28117, 27942, 27879, 27619, 27742, 27484, 27974, 27942, 28117, 40427, - 40325, 40818, 11026, 10996, 11404, 10588, 10574, 10535, 11026, 11404, 11166, 37873, 37707, - 37726, 2649, 2844, 2813, 23024, 23250, 22940, 23024, 22940, 22880, 33482, 33287, 33228, - 33731, 33538, 33482, 33810, 33747, 33731, 34023, 33747, 33810, 34023, 33810, 33894, 34752, - 34605, 34886, 34886, 35676, 35552, 33619, 33623, 33500, 2665, 2818, 2838, 21562, 21384, - 21441, 3046, 3132, 3160, 13358, 13437, 13537, 13113, 13210, 13358, 13111, 13210, 13113, - 13020, 12843, 12890, 28571, 28378, 28364, 39817, 39745, 39599, 39569, 39745, 39545, 40155, - 39796, 39747, 17346, 17121, 17389, 17256, 17121, 17346, 24409, 24465, 24611, 24562, 24465, - 24409, 32016, 31790, 32058, 31431, 31175, 31340, 32063, 32111, 32223, 39427, 39485, 39249, - 39910, 40025, 39901, 40012, 39910, 39826, 40218, 40236, 40195, 40360, 40236, 40218, 2639, - 2940, 2913, 21562, 21485, 21384, 15945, 16092, 16109, 15621, 15940, 15850, 15787, 15940, - 15621, 25393, 25597, 25356, 21200, 21049, 21056, 32501, 32461, 32482, 31181, 31184, 31085, - 36411, 36287, 36398, 35832, 35887, 35901, 37502, 37334, 37338, 36888, 36984, 36887, 37016, - 36984, 37074, 24790, 24751, 24843, 25228, 24984, 25120, 24790, 24984, 24927, 35532, 35661, - 35595, 37074, 36888, 36930, 35105, 34902, 34773, 29636, 29549, 29305, 29982, 30081, 30101, - 38310, 38289, 38055, 39115, 38716, 38485, 38310, 38055, 38296, 37977, 37984, 37932, 2505, - 2628, 2714, 21517, 21669, 21748, 21865, 21885, 21940, 21955, 22105, 22055, 22055, 22105, - 22169, 21345, 21389, 21517, 21247, 21073, 20973, 21599, 21389, 21247, 37465, 37338, 37266, - 22857, 22779, 22962, 23430, 23569, 23592, 23569, 23674, 23592, 40163, 40197, 40048, 39995, - 40136, 39748, 40266, 40197, 40163, 15534, 15519, 15403, 25960, 25790, 25814, 26431, 26377, - 26489, 32768, 32690, 32508, 32754, 32690, 32768, 36466, 36423, 36520, 13216, 13437, 13358, - 14336, 14046, 13886, 11363, 11404, 11679, 13897, 14118, 14004, 13877, 13897, 13997, 27867, - 27826, 27942, 27867, 27706, 27826, 27642, 27797, 27691, 29382, 29636, 29305, 27618, 27797, - 27642, 28378, 28243, 28263, 39222, 38997, 39149, 39503, 39215, 39473, 9639, 9469, 9870, - 10246, 10168, 10453, 9476, 9575, 9346, 29197, 29207, 29284, 29194, 29207, 29131, 28571, - 28513, 28378, 28378, 28285, 28243, 30544, 30787, 30754, 30787, 30940, 30754, 33397, 33500, - 33307, 33616, 33619, 33500, 35661, 35752, 35595, 2624, 2913, 2958, 2624, 3174, 2869, - 2628, 2612, 2755, 2616, 2691, 2797, 33228, 33033, 32886, 33136, 33033, 33228, 36131, - 35954, 35681, 40212, 40206, 40146, 40253, 40182, 40206, 40088, 40012, 39826, 2662, 2849, - 2698, 19028, 18761, 18859, 18959, 18761, 19028, 40323, 40331, 40126, 40253, 40206, 40212, - 2612, 2623, 2724, 21599, 21669, 21517, 31013, 31148, 30940, 25107, 25201, 24827, 25700, - 25722, 25677, 10694, 10663, 10897, 17852, 17953, 17745, 24790, 24843, 24970, 37698, 37701, - 37566, 37781, 37701, 37698, 2961, 3503, 3496, 3328, 3534, 3588, 23592, 23674, 23749, - 22857, 22962, 22991, 35832, 35901, 36007, 25960, 25814, 25956, 25827, 25722, 25761, 39817, - 39599, 39751, 2623, 2632, 2724, 13804, 13886, 13756, 15377, 15534, 15403, 24861, 25107, - 24827, 37222, 37151, 37048, 37222, 37048, 37218, 38765, 38757, 38568, 38445, 38211, 38467, - 38230, 38234, 37971, 37781, 37681, 37701, 38807, 38757, 38765, 26542, 26431, 26489, 26010, - 25960, 25956, 26542, 26489, 26590, 26542, 26590, 26607, 34326, 34314, 34220, 34326, 34441, - 34314, 34416, 34494, 34488, 34954, 35105, 34479, 35861, 35822, 35752, 34326, 34342, 34375, - 34220, 34342, 34326, 39637, 39503, 39447, 31790, 31897, 31596, 32063, 32016, 32058, 32086, - 32016, 32063, 28125, 28117, 28243, 28125, 27974, 28117, 27706, 27742, 27619, 32690, 32574, - 32508, 32619, 32574, 32677, 9920, 10168, 9897, 12610, 12517, 12121, 10796, 10694, 10897, - 13506, 13440, 13527, 37858, 37922, 37852, 37894, 37922, 37858, 37593, 37562, 37726, 7931, - 7867, 8000, 8000, 8013, 8106, 7809, 7792, 7931, 7572, 7792, 7809, 7775, 7792, - 7572, 7179, 7334, 7220, 22962, 23038, 22991, 34342, 33978, 34208, 34954, 34479, 34488, - 40323, 40126, 40214, 40108, 39801, 40025, 33033, 32918, 32886, 32999, 32918, 33033, 36199, - 36324, 36049, 36555, 36324, 36464, 6930, 6995, 6967, 39009, 38357, 38952, 39427, 39488, - 39485, 32107, 32290, 32011, 33471, 33397, 33427, 32294, 32290, 32107, 31181, 30922, 31158, - 3330, 3282, 3406, 3196, 3346, 3038, 13741, 13804, 13756, 13210, 13216, 13358, 12610, - 12121, 12094, 15758, 15787, 15621, 15403, 15202, 15300, 39671, 39645, 39545, 3040, 3046, - 3104, 3038, 3346, 3210, 2918, 3091, 3047, 2918, 3047, 2756, 6428, 6344, 6262, - 6905, 6930, 6967, 4792, 4976, 4902, 4792, 4902, 4734, 33619, 33722, 33695, 33500, - 33397, 33471, 19203, 19529, 19532, 19533, 19529, 19236, 19080, 19012, 19048, 19012, 18892, - 19048, 22991, 23038, 23079, 23749, 23674, 23820, 24562, 24861, 24465, 24465, 24861, 24725, - 23517, 23541, 23455, 23405, 23455, 23250, 6905, 6967, 6777, 7867, 8013, 8000, 17499, - 17425, 17537, 17121, 16805, 16667, 17530, 17425, 17499, 40168, 39750, 39952, 39796, 39817, - 39751, 40156, 40108, 40135, 31211, 31181, 31158, 4669, 4845, 4682, 4669, 4742, 4591, - 4440, 4481, 4446, 4440, 4325, 4338, 21153, 21307, 21200, 23038, 23395, 23079, 37726, - 37562, 37702, 40349, 40611, 40648, 40323, 40214, 40373, 19605, 19644, 19855, 15940, 16092, - 15945, 15787, 16092, 15940, 25393, 25523, 25597, 25585, 25523, 25393, 2887, 3046, 3040, - 3687, 3722, 3783, 4200, 4274, 4115, 3618, 3722, 3687, 13897, 13877, 13834, 14939, - 14978, 14780, 13741, 13756, 13470, 27967, 27867, 27942, 27967, 27942, 27974, 29905, 29954, - 29727, 29382, 29208, 29334, 38445, 38467, 38612, 32574, 32501, 32482, 32619, 32501, 32574, - 38612, 38489, 38849, 4274, 4194, 4115, 38356, 38234, 38230, 38289, 38411, 38184, 38370, - 38310, 38296, 37977, 37932, 37922, 32918, 32865, 32768, 33430, 33287, 33482, 33538, 33731, - 33666, 8910, 9064, 8947, 9509, 9469, 9639, 8811, 8947, 8803, 32999, 32865, 32918, - 36142, 36197, 36006, 36466, 36411, 36398, 36466, 36398, 36423, 6907, 6764, 7041, 6907, - 7041, 7243, 19422, 19392, 19413, 17324, 17256, 17425, 21955, 22055, 21940, 29194, 29445, - 29611, 29142, 29207, 29197, 34098, 34023, 33992, 38849, 38489, 38721, 15395, 15525, 15599, - 15905, 15927, 15626, 29905, 29727, 29687, 32016, 31897, 31790, 32086, 31897, 32016, 23079, - 23395, 23399, 21615, 21485, 21562, 40343, 40262, 40148, 40207, 40168, 39952, 40360, 40148, - 40236, 10663, 10574, 10588, 9153, 8950, 9835, 10796, 10897, 10966, 26431, 26285, 26165, - 26607, 26878, 26733, 37873, 37894, 37858, 37702, 37562, 37512, 4280, 4779, 4854, 12121, - 11638, 11570, 13470, 13756, 13437, 17079, 16805, 17121, 24984, 24790, 24970, 23867, 23749, - 23820, 25003, 24984, 25187, 25444, 25614, 25790, 25379, 25585, 25393, 24004, 24125, 23910, - 14348, 14611, 14737, 13926, 14336, 13886, 32318, 32223, 32291, 39358, 39222, 39471, 39471, - 39222, 39561, 38807, 38731, 38757, 38757, 38731, 38721, 2574, 2786, 2766, 2691, 2649, - 2813, 19392, 19275, 19413, 35105, 35535, 35236, 35752, 35822, 35681, 37489, 37502, 37338, - 37465, 37266, 37236, 40445, 40209, 40540, 40134, 40282, 40373, 6312, 6248, 6376, 6162, - 5823, 6080, 8590, 8278, 8356, 15905, 16185, 15927, 15758, 15621, 15540, 15300, 15202, - 15190, 39645, 39637, 39447, 39671, 39637, 39645, 39671, 39545, 39839, 39031, 38938, 39026, - 38952, 38357, 38646, 21615, 21562, 21805, 23399, 23395, 23430, 23399, 23430, 23586, 23184, - 23024, 23035, 23741, 23885, 23810, 4334, 4669, 4591, 2231, 2624, 2869, 40337, 40386, - 40256, 6344, 6647, 6785, 23867, 23961, 24032, 36288, 36197, 36136, 37028, 36475, 36995, - 39499, 39488, 39427, 39009, 39115, 38485, 39967, 39817, 39796, 9145, 9476, 9346, 9469, - 9476, 9027, 32501, 32425, 32354, 32619, 32425, 32501, 10647, 10574, 10663, 37598, 37702, - 37512, 38023, 37894, 37873, 17953, 18033, 18229, 17425, 17256, 17346, 15927, 16110, 15818, - 15927, 16185, 16110, 19012, 18656, 18892, 40282, 40253, 40349, 40373, 40282, 40349, 37977, - 37894, 38023, 33616, 33722, 33619, 33616, 33500, 33471, 32677, 32318, 32425, 33315, 33136, - 33228, 33315, 33228, 33287, 36288, 36238, 36411, 37016, 37048, 36984, 37502, 37598, 37512, - 10228, 10306, 10535, 7114, 7243, 7397, 14992, 15248, 15207, 14992, 15130, 15248, 14004, - 14357, 14180, 32199, 32086, 32063, 30940, 31148, 30982, 32230, 32086, 32199, 37763, 37053, - 37431, 36792, 36603, 36930, 13804, 13926, 13886, 13216, 13210, 13111, 23586, 23430, 23592, - 24220, 23867, 24032, 23741, 23810, 23541, 3053, 3328, 3588, 3466, 3906, 3760, 3660, - 3760, 3865, 14978, 14992, 14837, 26483, 26285, 26431, 26483, 26607, 26656, 39499, 39039, - 39124, 40110, 39826, 40121, 40012, 40088, 40025, 2608, 2662, 2698, 19130, 18959, 19151, - 18626, 18656, 18098, 2570, 2596, 2718, 2628, 2578, 2612, 2612, 2578, 2623, 2623, - 2578, 2632, 2632, 2574, 2766, 2608, 2480, 2662, 2570, 2718, 2673, 2570, 2673, - 2542, 2673, 2611, 2542, 2611, 2589, 2542, 2654, 2589, 2611, 6016, 5823, 6162, - 5255, 4532, 6011, 36946, 36520, 36456, 36408, 36288, 36411, 2654, 2665, 2589, 2589, - 2665, 2388, 20721, 20396, 20756, 19422, 19399, 19392, 19392, 19399, 19275, 19275, 19192, - 19151, 20721, 20756, 20938, 20968, 20938, 21056, 20938, 21098, 21056, 21098, 21200, 21056, - 33896, 33731, 33747, 33307, 33283, 33427, 36007, 35901, 36006, 35755, 35752, 35661, 37260, - 37218, 37016, 40325, 40427, 40275, 40646, 40129, 40294, 40337, 40445, 40386, 40818, 40325, - 40159, 40549, 40159, 40331, 22779, 22639, 22575, 10956, 10796, 10966, 10437, 10472, 10574, - 10074, 10003, 10121, 10956, 10966, 11026, 10458, 10679, 10453, 10458, 10453, 10168, 31181, - 31211, 31184, 31158, 30922, 31136, 37848, 37873, 37726, 37630, 37598, 37502, 2542, 2589, - 2388, 15758, 15540, 15619, 15190, 15202, 14737, 15190, 14737, 14716, 22779, 22772, 22639, - 26483, 26431, 26542, 25989, 26372, 25895, 26949, 27365, 26891, 25827, 25895, 25722, 25722, - 25700, 25667, 32425, 32318, 32291, 32574, 32690, 32754, 38310, 38411, 38289, 38370, 38411, - 38310, 40330, 40266, 40163, 40099, 40136, 39995, 40330, 40163, 40262, 2756, 3272, 2844, - 3022, 2887, 3040, 3196, 3282, 3305, 4051, 4194, 4094, 4661, 4902, 4669, 6248, - 6087, 6162, 5941, 6087, 6009, 16539, 16667, 16805, 15626, 15547, 15599, 29954, 30081, - 29982, 29875, 29905, 29687, 29875, 29687, 29636, 36204, 36007, 36006, 36408, 36411, 36497, - 38612, 38615, 38445, 38445, 38497, 38356, 38356, 38332, 38234, 37695, 38038, 37698, 37701, - 37681, 37566, 38624, 38615, 38612, 34441, 34494, 34416, 35714, 35755, 35535, 35535, 35755, - 35661, 34375, 34494, 34441, 34375, 34441, 34326, 34659, 34494, 34734, 2662, 2616, 2797, - 2480, 2616, 2662, 40349, 40253, 40212, 40465, 40476, 40331, 29207, 29142, 29131, 29753, - 29816, 29676, 29919, 30033, 30063, 30056, 30081, 29954, 8811, 8910, 8947, 8356, 8278, - 8106, 34220, 33978, 34342, 32775, 33250, 33307, 33127, 32775, 32800, 23885, 24004, 23910, - 24861, 24889, 25107, 23741, 24004, 23885, 40207, 39952, 40197, 39009, 39051, 39115, 39632, - 39499, 39124, 39052, 38952, 39159, 13877, 13655, 13834, 14357, 14595, 14180, 13741, 13926, - 13804, 13642, 13926, 13741, 15627, 15547, 15626, 39358, 39176, 38999, 38849, 38624, 38612, - 39358, 38999, 39222, 22779, 22857, 22772, 3969, 4137, 3798, 5255, 6214, 5545, 8013, - 7903, 8106, 7792, 7867, 7931, 7775, 7867, 7792, 7598, 7179, 7572, 6905, 7001, - 6930, 22772, 22857, 22991, 22772, 22991, 23047, 23586, 23592, 23749, 23306, 23405, 23250, - 23184, 23250, 23024, 28838, 28089, 28058, 28838, 28626, 28823, 40551, 40360, 40218, 40429, - 40360, 40551, 5235, 5255, 5545, 10121, 10003, 10306, 10228, 10535, 10472, 32754, 32865, - 32881, 32754, 32768, 32865, 5823, 5665, 5820, 6087, 6016, 6162, 5912, 6016, 5941, - 36204, 36006, 36197, 36497, 36411, 36466, 36497, 36466, 36520, 7333, 7132, 7397, 6295, - 6312, 6970, 6777, 6888, 6771, 10472, 10535, 10574, 2507, 2578, 2628, 6295, 6970, - 6479, 21669, 21766, 21865, 22105, 22121, 22169, 21389, 21599, 21517, 21247, 20973, 20724, - 19647, 19532, 19529, 19647, 19529, 19627, 33538, 33430, 33482, 32328, 32439, 32290, 33819, - 33722, 33616, 36357, 36197, 36288, 2918, 2931, 3091, 2809, 2931, 2918, 24280, 24562, - 24409, 14780, 14649, 14664, 14624, 14649, 14780, 14978, 14939, 14992, 3798, 4137, 3987, - 12610, 12890, 12843, 13057, 12890, 12910, 15207, 15248, 15395, 28971, 28632, 28909, 26656, - 26607, 26733, 31980, 32107, 31778, 37894, 37977, 37922, 37848, 37726, 37767, 39031, 38717, - 38938, 25817, 25444, 25790, 23833, 23749, 23867, 23833, 23586, 23749, 6735, 6777, 6771, - 6735, 6771, 6647, 21599, 21657, 21669, 34880, 34098, 33992, 34023, 33896, 33747, 33538, - 33525, 33430, 33967, 34086, 33942, 35552, 35676, 35858, 17199, 17530, 17745, 16853, 16539, - 16805, 13682, 13655, 13877, 13827, 13877, 13997, 18071, 18626, 18098, 15758, 15619, 15763, - 24668, 24782, 24562, 23405, 23517, 23455, 23394, 23517, 23405, 40266, 40207, 40197, 40374, - 40207, 40266, 3305, 3282, 3330, 3669, 3798, 3987, 3210, 3132, 3038, 15409, 15207, - 15395, 15540, 15466, 15619, 14280, 14348, 14336, 17158, 17121, 17256, 15627, 15512, 15547, - 15547, 15512, 15599, 10647, 10663, 10694, 19627, 19529, 19533, 21657, 21766, 21669, 32330, - 32328, 32294, 31136, 30922, 31072, 38365, 38094, 38234, 37598, 37674, 37702, 37786, 37674, - 37751, 37465, 37236, 37449, 6508, 6647, 6344, 6517, 6735, 6647, 33430, 33315, 33287, - 33372, 33315, 33430, 33605, 33616, 33471, 32800, 33056, 33127, 4792, 4769, 4976, 4661, - 4734, 4902, 4661, 4669, 4508, 28666, 28513, 28571, 30940, 30982, 30838, 20985, 21056, - 21049, 23047, 22991, 23079, 40465, 40331, 40323, 40349, 40212, 40611, 5601, 5665, 5703, - 36408, 36357, 36288, 36511, 36497, 36520, 36408, 36497, 36511, 20319, 20021, 20370, 17268, - 17324, 17199, 19529, 19203, 19236, 21766, 21885, 21865, 3038, 3132, 2930, 15409, 15512, - 15364, 39637, 39679, 39503, 39839, 39545, 39745, 39839, 39745, 39817, 24562, 24782, 24861, - 24222, 24125, 24004, 33967, 33896, 34023, 39826, 40177, 40121, 40108, 40219, 39942, 37016, - 37218, 37048, 36603, 36562, 36811, 24220, 24482, 24817, 23190, 23047, 23079, 2578, 2574, - 2632, 4498, 4280, 4854, 4150, 3853, 4024, 10089, 10074, 10121, 10003, 9819, 9911, - 10089, 10121, 10228, 11570, 11638, 11285, 19236, 19203, 19080, 21885, 21955, 21940, 24817, - 24482, 24790, 24056, 24222, 24004, 37399, 37236, 37222, 38572, 38497, 38445, 38580, 38445, - 38615, 40168, 40149, 40099, 40269, 40149, 40168, 40135, 40108, 40025, 38497, 38332, 38356, - 39147, 39052, 39159, 38191, 38055, 37984, 4200, 4196, 4527, 4175, 4196, 4200, 4115, - 4194, 4051, 29334, 29208, 29034, 29905, 30056, 29954, 30081, 30430, 30133, 38624, 38580, - 38615, 2494, 2649, 2691, 2494, 2691, 2616, 3366, 3687, 3730, 4059, 4115, 4051, - 13808, 13827, 13997, 16453, 16155, 16092, 19111, 19236, 19080, 36688, 36508, 36555, 3669, - 3987, 3722, 4734, 4769, 4792, 4639, 4769, 4734, 15787, 16112, 16092, 15779, 16112, - 15787, 28513, 28285, 28378, 32230, 32199, 32318, 30838, 30982, 30796, 31175, 31148, 31013, - 33605, 33471, 33586, 32800, 32490, 33056, 38124, 38191, 37984, 37767, 37726, 37702, 37767, - 37702, 37674, 3840, 4051, 3969, 30561, 30544, 30754, 29753, 30001, 29816, 29142, 28971, - 28909, 28666, 28724, 28513, 28296, 28228, 28285, 6517, 6508, 6493, 35822, 35979, 35681, - 35714, 35535, 35428, 16112, 16453, 16092, 4532, 4498, 4854, 4280, 4498, 4076, 10796, - 10647, 10694, 11415, 11679, 11480, 13506, 13527, 13655, 14180, 14595, 14531, 14978, 14824, - 14780, 14752, 14824, 14837, 14624, 14824, 14752, 15534, 15466, 15540, 25585, 25700, 25523, - 28859, 28838, 28823, 38124, 37984, 37977, 39681, 39353, 39485, 39244, 39124, 39115, 39967, - 39839, 39817, 29256, 28971, 29142, 32619, 32677, 32425, 32999, 33033, 33136, 3282, 3267, - 3406, 3208, 3267, 3282, 25992, 25960, 26010, 26607, 26483, 26542, 27967, 27706, 27867, - 19605, 19399, 19422, 21955, 22121, 22105, 40530, 40242, 40377, 40412, 40343, 40148, 13919, - 14280, 14336, 15763, 15779, 15758, 13919, 14336, 13926, 40429, 40148, 40360, 40269, 40136, - 40149, 33896, 33666, 33731, 32881, 32677, 32754, 35755, 35861, 35752, 11363, 11166, 11404, - 10214, 10101, 10228, 17530, 17324, 17425, 19013, 18761, 18959, 24222, 24280, 24409, 25379, - 25393, 25107, 24395, 24280, 24266, 23741, 23541, 23695, 40088, 40135, 40025, 39681, 39485, - 39655, 28971, 28752, 28632, 29191, 29334, 29034, 28058, 28626, 28838, 8752, 8910, 8811, - 10126, 10458, 10168, 8752, 8803, 8590, 33605, 33586, 33668, 33056, 32925, 33072, 13682, - 13506, 13655, 13682, 13877, 13827, 28228, 28125, 28243, 28228, 28243, 28285, 37681, 37763, - 37431, 38407, 37923, 38094, 37786, 37767, 37674, 37848, 38023, 37873, 39176, 39031, 39026, - 38665, 38572, 38580, 39157, 39031, 39176, 38952, 39051, 39009, 39052, 39051, 38952, 40465, - 40323, 40402, 15512, 15409, 15395, 15223, 15409, 15364, 15626, 15927, 15627, 39671, 39679, - 39637, 39900, 39679, 39671, 39655, 39485, 39488, 14624, 14531, 14649, 39123, 39244, 39115, - 37465, 37489, 37338, 37218, 37399, 37222, 37409, 37399, 37218, 34494, 34659, 34488, 36057, - 35979, 35861, 33427, 33586, 33471, 4338, 4591, 4440, 11052, 10956, 11026, 23190, 23079, - 23399, 21153, 21200, 21098, 23190, 23399, 23287, 30673, 30561, 30754, 38124, 38023, 38138, - 40343, 40330, 40262, 40420, 40330, 40343, 33666, 33525, 33538, 33616, 33605, 33668, 36131, - 35979, 36057, 35861, 35979, 35822, 25667, 25379, 25845, 37619, 37489, 37465, 3293, 3338, - 2732, 2815, 2560, 3044, 2414, 2542, 2388, 24220, 23833, 23867, 23482, 23351, 23361, - 23578, 23541, 23517, 40156, 40219, 40108, 40402, 40323, 40373, 40252, 40219, 40156, 19399, - 19192, 19275, 32754, 32677, 32574, 30940, 30838, 30754, 32999, 33136, 33171, 36555, 36508, - 36324, 37173, 37260, 37016, 40402, 40373, 40349, 33978, 33803, 33994, 25992, 26010, 26153, - 25003, 24927, 24984, 25827, 25872, 25895, 25948, 25872, 25827, 33186, 33136, 33315, 36511, - 36357, 36408, 35858, 35676, 35832, 36511, 36520, 36707, 17324, 17279, 17256, 17268, 17279, - 17324, 32294, 32328, 32290, 31731, 31221, 31623, 36858, 36930, 36603, 40149, 40136, 40099, - 40303, 40168, 40452, 40141, 40135, 40088, 7401, 7334, 7179, 7867, 7903, 8013, 7220, - 7019, 7179, 6711, 6905, 6777, 6532, 6777, 6735, 33819, 33803, 33722, 40110, 40141, - 40088, 40177, 39826, 39395, 3618, 3669, 3722, 3798, 3873, 3969, 3490, 3669, 3434, - 13808, 13682, 13827, 11975, 11679, 12192, 19192, 19130, 19151, 27972, 27967, 27974, 27972, - 27974, 28125, 30673, 30838, 30796, 33525, 33434, 33430, 20968, 21056, 20985, 23287, 23399, - 23361, 23035, 22880, 22800, 7775, 7903, 7867, 13057, 13216, 13111, 13057, 13111, 12890, - 39031, 39004, 38717, 39223, 39004, 39031, 26153, 26010, 26285, 26733, 26878, 26994, 29256, - 28953, 28971, 28971, 28953, 28752, 29816, 30001, 29919, 30001, 30033, 29919, 11989, 12094, - 12121, 11793, 12094, 11989, 38580, 38572, 38445, 38504, 38365, 38332, 37801, 37775, 37781, - 38721, 38731, 38792, 4325, 4440, 4446, 4325, 4446, 4196, 4325, 4196, 4153, 29628, - 29875, 29636, 29628, 29636, 29382, 29191, 29034, 28936, 38792, 38731, 38807, 19130, 19013, - 18959, 2542, 2501, 2570, 2570, 2501, 2596, 2596, 2540, 2714, 2578, 2280, 2574, - 2414, 2501, 2542, 2665, 2639, 2388, 2501, 2524, 2596, 13230, 13440, 12892, 11363, - 11231, 11166, 11166, 11052, 11026, 20900, 20938, 20968, 20900, 20721, 20938, 20396, 20319, - 20370, 19605, 19408, 19399, 19399, 19311, 19192, 19192, 19311, 19130, 19130, 19156, 19013, - 20900, 20968, 20985, 21200, 21307, 21384, 29875, 30056, 29905, 31367, 31221, 31211, 39078, - 38402, 38411, 38191, 38296, 38055, 38273, 38296, 38191, 2524, 2540, 2596, 36688, 36811, - 36562, 36808, 36811, 36688, 2540, 2505, 2714, 21268, 21200, 21384, 6016, 5912, 5823, - 5665, 5601, 5820, 5941, 6016, 6087, 6151, 6248, 6312, 21615, 21805, 21642, 32999, - 32946, 32865, 33115, 32946, 32999, 33434, 33372, 33430, 40427, 40530, 40377, 40646, 41176, - 40821, 40549, 40331, 40512, 2930, 3132, 3046, 3196, 3208, 3282, 2887, 3022, 2857, - 21642, 21805, 21915, 23361, 23399, 23482, 23184, 23306, 23250, 23201, 23306, 23184, 24681, - 24861, 24782, 25585, 25667, 25700, 31362, 31211, 31158, 37399, 37449, 37236, 37173, 37016, - 37074, 37173, 37074, 37144, 37555, 37449, 37399, 37751, 37674, 37598, 38138, 38023, 38166, - 38023, 38124, 37977, 10748, 10796, 10797, 10748, 10647, 10796, 20341, 20319, 20396, 22454, - 22162, 22639, 17279, 17158, 17256, 17268, 17158, 17279, 36025, 35832, 36007, 34098, 33967, - 34023, 33896, 33841, 33666, 33666, 33776, 33525, 33618, 33487, 33434, 33434, 33487, 33372, - 11243, 11231, 11363, 13216, 13470, 13437, 13374, 13470, 13216, 26811, 26994, 26990, 28296, - 28285, 28513, 28724, 28666, 28752, 39051, 39123, 39115, 39123, 39052, 39147, 40515, 40402, - 40694, 40512, 40331, 40476, 2809, 3022, 2931, 16453, 16701, 16475, 16509, 16701, 16453, - 16509, 16453, 16337, 22772, 22819, 22639, 29256, 29142, 29197, 28838, 28859, 28936, 27365, - 26949, 27132, 38919, 38792, 38807, 25960, 25817, 25790, 26153, 26285, 26090, 25872, 25989, - 25895, 25948, 25989, 25872, 34086, 34098, 34113, 11128, 11052, 11166, 37807, 37848, 37767, - 2417, 2466, 2628, 2574, 2510, 2608, 8753, 8752, 8647, 9027, 9476, 9145, 22772, - 23047, 22819, 23482, 23399, 23586, 23482, 23586, 23833, 40439, 40374, 40266, 40439, 40266, - 40330, 40218, 40386, 40551, 18759, 18892, 18656, 18759, 18656, 18626, 3840, 3873, 3826, - 28953, 28724, 28752, 2466, 2507, 2628, 23047, 23096, 22819, 31596, 31495, 31340, 32946, - 32881, 32865, 33115, 32881, 32946, 36464, 36324, 36199, 36811, 36858, 36603, 5761, 5665, - 5823, 5255, 4901, 4532, 6508, 6517, 6647, 6493, 6508, 6428, 10521, 10437, 10574, - 10521, 10574, 10647, 9469, 9509, 9476, 10976, 11570, 11285, 14824, 14624, 14780, 14004, - 13808, 13997, 15223, 14992, 15207, 15223, 15207, 15409, 14374, 14611, 14348, 15758, 15779, - 15787, 14716, 14611, 14471, 31072, 30123, 30430, 33967, 33841, 33896, 33348, 33186, 33315, - 36924, 36858, 36811, 37781, 37775, 37681, 38365, 38234, 38332, 37630, 37502, 37489, 26090, - 26375, 26183, 27920, 27706, 27967, 17158, 17079, 17121, 17050, 17079, 17158, 24280, 24668, - 24562, 24395, 24668, 24280, 24681, 24668, 24535, 13470, 13642, 13741, 13602, 13642, 13578, - 23047, 23190, 23096, 28228, 27972, 28125, 27999, 27972, 28228, 30838, 30673, 30754, 30547, - 30673, 30796, 18779, 18759, 18626, 40540, 40386, 40445, 3267, 3207, 3795, 3136, 3208, - 3196, 15627, 15927, 15818, 15377, 15466, 15534, 25667, 25761, 25722, 25845, 25761, 25667, - 2419, 2756, 2844, 2419, 2844, 2257, 5214, 5235, 5545, 10089, 9819, 10003, 10089, - 10003, 10074, 37792, 37807, 37786, 37260, 37409, 37218, 37343, 37409, 37260, 6428, 6508, - 6344, 16701, 17016, 17205, 16337, 16453, 16112, 33348, 33315, 33372, 33841, 33791, 33666, - 33668, 33819, 33616, 33427, 33467, 33586, 33283, 33394, 33427, 2765, 2614, 2815, 2651, - 2614, 2765, 23096, 23190, 23143, 23482, 23833, 23469, 10101, 10089, 10228, 39222, 39149, - 39561, 38930, 38849, 38792, 37073, 37074, 36930, 29494, 29628, 29382, 29875, 30197, 30056, - 31264, 31158, 31136, 29494, 29382, 29334, 4537, 4639, 4661, 4175, 4200, 4115, 29676, - 29611, 29445, 29113, 28542, 28724, 30033, 30254, 30400, 3038, 3176, 3196, 3136, 3176, - 3015, 5190, 5198, 5235, 5912, 5761, 5823, 5824, 5761, 5912, 10214, 10228, 10472, - 10797, 10796, 10956, 23190, 23287, 23143, 25939, 25817, 25960, 26738, 26483, 26656, 37018, - 37073, 36930, 36555, 36658, 36688, 36638, 36658, 36555, 40429, 40412, 40148, 40547, 40412, - 40429, 4022, 4175, 4115, 38535, 38332, 38497, 38624, 38665, 38580, 38777, 38665, 38803, - 38849, 38721, 38792, 31264, 31362, 31158, 31264, 31136, 31072, 10976, 11285, 10763, 12910, - 12890, 12610, 30400, 30254, 30561, 38535, 38497, 38572, 6144, 6344, 6220, 33250, 33262, - 33394, 33283, 33250, 33394, 8779, 9145, 8910, 2473, 2809, 2918, 2887, 2930, 3046, - 3840, 4059, 4051, 12892, 13440, 13506, 11243, 11128, 11231, 11231, 11128, 11166, 10825, - 10797, 10956, 13731, 13506, 13682, 17079, 17029, 16805, 17050, 17029, 17079, 16764, 17016, - 16701, 24668, 24681, 24782, 23767, 24004, 23741, 28859, 29191, 28936, 29179, 29191, 28859, - 40121, 40141, 40110, 40135, 40252, 40156, 40494, 40465, 40515, 40248, 40141, 40121, 13950, - 13808, 14004, 27972, 27920, 27967, 28542, 28296, 28513, 28542, 28513, 28724, 23433, 23578, - 23517, 23394, 23405, 23306, 34659, 34954, 34488, 35979, 36131, 35681, 34777, 34954, 34659, - 34503, 34494, 34375, 34503, 34375, 34418, 34375, 34342, 34418, 38296, 38494, 38370, 38231, - 38273, 38191, 38221, 38191, 38124, 33186, 33171, 33136, 33193, 33171, 33186, 40165, 39967, - 39796, 39839, 39909, 39671, 40321, 40269, 40168, 40168, 40207, 40452, 6479, 6970, 6764, - 8115, 8749, 8315, 7775, 7784, 7903, 7829, 8356, 8106, 7220, 7001, 7019, 6532, - 6735, 6517, 6532, 6517, 6462, 40512, 40476, 40494, 40476, 40465, 40494, 38919, 38807, - 39045, 34418, 34342, 34208, 6479, 6764, 6498, 33994, 33803, 33819, 33056, 33072, 33091, - 11243, 11363, 11415, 30547, 30400, 30561, 16395, 16337, 16227, 16680, 16764, 16701, 15377, - 15300, 15466, 25939, 25960, 25992, 33994, 33819, 33839, 35552, 35234, 34886, 33967, 33942, - 33841, 33841, 33927, 33791, 35430, 35234, 35552, 10748, 10521, 10647, 10724, 10521, 10748, - 37786, 37807, 37767, 37630, 37489, 37619, 3208, 3257, 3267, 3826, 3873, 3655, 3145, - 3257, 3208, 5235, 5198, 5255, 5190, 5235, 5214, 9868, 9920, 9897, 10763, 11285, - 10775, 26861, 26805, 26372, 26289, 26372, 25989, 40329, 40177, 39395, 39499, 39655, 39488, - 40057, 39655, 39499, 39632, 39124, 39244, 3905, 3853, 4150, 3801, 3853, 3809, 4150, - 4280, 3932, 3873, 3798, 3655, 3873, 3840, 3969, 7724, 7784, 7775, 28626, 28058, - 28440, 38930, 38919, 39046, 23578, 23695, 23541, 23590, 23695, 23578, 39430, 39157, 39176, - 39052, 39123, 39051, 38575, 38411, 38370, 2420, 2510, 2574, 10082, 10101, 10214, 10089, - 9919, 9819, 9969, 10126, 10168, 19555, 19408, 19605, 17014, 16853, 17029, 37619, 37449, - 37576, 37619, 37465, 37449, 40708, 40540, 40209, 40515, 40694, 40636, 5761, 5703, 5665, - 6048, 6087, 6248, 5758, 5913, 5684, 4740, 5367, 4769, 30673, 30547, 30561, 31251, - 31148, 31175, 31495, 31596, 31897, 33127, 33056, 33101, 33056, 33091, 33101, 37924, 38023, - 37848, 17029, 16853, 16805, 17324, 17530, 17199, 40359, 40252, 40135, 33776, 33666, 33791, - 33618, 33434, 33525, 35923, 35861, 35755, 37018, 36930, 36858, 37173, 37343, 37260, 37144, - 37073, 37223, 3176, 3136, 3196, 3113, 3136, 3015, 27365, 27618, 27642, 3853, 3763, - 4024, 12910, 12155, 12889, 14374, 14348, 14280, 19408, 19311, 19399, 19761, 19647, 19563, - 19761, 19861, 19647, 20290, 21247, 20724, 21599, 21785, 21657, 21657, 21785, 21766, 21766, - 21785, 21885, 21885, 21863, 21955, 21955, 21863, 22121, 19111, 19080, 19048, 19111, 19048, - 19002, 19048, 18892, 19002, 29113, 28724, 28953, 27999, 27920, 27972, 28440, 28058, 27797, - 40515, 40465, 40402, 31362, 31367, 31211, 31347, 31264, 31429, 37775, 37769, 37681, 37801, - 37769, 37775, 40231, 39748, 40136, 39561, 39149, 39503, 4661, 4639, 4734, 4334, 4591, - 4338, 11081, 10956, 11052, 10214, 10472, 10437, 23143, 23287, 23304, 21268, 21485, 21642, - 23287, 23361, 23304, 22800, 22880, 22689, 22689, 22547, 22630, 32086, 32230, 31897, 40412, - 40420, 40343, 40529, 40420, 40412, 2788, 2930, 2887, 15921, 16112, 15779, 2732, 3338, - 2572, 2388, 2639, 2039, 3526, 3503, 2961, 23695, 23767, 23741, 23718, 23767, 23695, - 40402, 40349, 40648, 6180, 6151, 6312, 6180, 6312, 6295, 32318, 32575, 32230, 33487, - 33348, 33372, 33516, 33348, 33487, 33262, 33250, 33127, 33839, 33819, 33899, 36407, 36204, - 36197, 36407, 36197, 36357, 5941, 5824, 5912, 5774, 5824, 5941, 13808, 13731, 13682, - 13800, 13731, 13808, 14180, 14531, 14366, 14837, 14824, 14978, 16185, 16349, 16110, 15466, - 15300, 15227, 15763, 15921, 15779, 14716, 14737, 14611, 25761, 25948, 25827, 25845, 25948, - 25761, 26023, 25948, 25880, 27999, 28228, 28296, 26733, 26738, 26656, 26153, 26090, 25992, - 36946, 36456, 37028, 40013, 39909, 39839, 39358, 39471, 39176, 29816, 29683, 29676, 29841, - 29683, 29816, 29869, 29816, 29919, 29869, 29919, 29967, 30033, 30330, 30063, 38707, 38535, - 38572, 37695, 37766, 38301, 38707, 38572, 38665, 38707, 38665, 38777, 16110, 16349, 16141, - 18033, 18761, 18368, 24266, 24280, 24222, 30200, 30197, 29875, 29419, 29494, 29334, 29419, - 29334, 29191, 28875, 28859, 28823, 40269, 40238, 40136, 40564, 40238, 40269, 3763, 3702, - 4024, 30033, 30400, 30330, 38535, 38504, 38332, 38541, 38494, 38296, 38567, 38494, 38541, - 14837, 14992, 14991, 13919, 13926, 13778, 2788, 2857, 2716, 2693, 2857, 2809, 2809, - 2857, 3022, 16680, 16701, 16509, 18779, 18892, 18759, 24984, 25228, 25187, 3985, 4022, - 4059, 4059, 4022, 4115, 4175, 4153, 4196, 4309, 4334, 4338, 9920, 9969, 10168, - 10763, 10775, 10666, 9868, 9969, 9920, 29438, 29284, 29207, 6462, 6517, 6493, 6462, - 6493, 6400, 34086, 33967, 34098, 33839, 33936, 33950, 35428, 35535, 35105, 2510, 2480, - 2608, 3257, 3264, 3267, 3167, 3264, 3257, 3113, 3208, 3136, 4309, 4338, 4325, - 19002, 18892, 18779, 30330, 30400, 30349, 21485, 21615, 21642, 23304, 23361, 23351, 23035, - 23201, 23184, 23239, 23201, 23039, 4635, 4740, 4769, 4635, 4769, 4639, 30491, 30400, - 30547, 32677, 32575, 32318, 38138, 38221, 38124, 37807, 37924, 37848, 38039, 37924, 37807, - 37220, 37132, 37028, 37073, 37144, 37074, 37812, 37792, 37786, 36808, 36688, 36658, 14366, - 14531, 14624, 6151, 6048, 6248, 6180, 6048, 6151, 8752, 8753, 8910, 9469, 9868, - 9870, 8647, 8752, 8590, 11128, 11081, 11052, 11265, 11243, 11415, 11975, 12192, 12339, - 30491, 30547, 30600, 31347, 31367, 31362, 31347, 31362, 31264, 33839, 33899, 33936, 33243, - 33262, 33127, 33243, 33127, 33101, 3015, 3176, 2734, 15513, 15364, 15512, 6633, 6764, - 6907, 6400, 6493, 6428, 33467, 33427, 33394, 18779, 18626, 18410, 40540, 40551, 40386, - 2501, 2414, 2524, 2524, 2451, 2540, 2540, 2451, 2505, 2505, 2417, 2628, 2466, - 2441, 2507, 2507, 2402, 2578, 2510, 2392, 2480, 2560, 2815, 2614, 20721, 20641, - 20396, 20319, 19855, 20021, 19408, 19428, 19311, 20704, 20641, 20721, 20704, 20721, 20833, - 20721, 20900, 20833, 20900, 20985, 20833, 20985, 20914, 20833, 21049, 21124, 20985, 21200, - 21124, 21049, 21200, 21268, 21124, 2414, 2451, 2524, 3702, 3660, 3865, 15908, 15921, - 15763, 16337, 16441, 16509, 15550, 15763, 15619, 20641, 20530, 20396, 21384, 21485, 21268, - 36633, 36638, 36555, 36808, 36638, 36754, 39123, 39450, 39244, 39064, 38952, 38646, 28735, - 28875, 28823, 28657, 28823, 28626, 38919, 38930, 38792, 39045, 38807, 39004, 2451, 2453, - 2505, 2453, 2417, 2505, 2562, 2560, 2614, 4334, 4508, 4669, 11121, 11081, 11128, - 10214, 10437, 10272, 20530, 20341, 20396, 22639, 22819, 22680, 23351, 23482, 23469, 23201, - 23254, 23306, 23767, 24056, 24004, 23239, 23254, 23201, 30895, 30547, 30796, 37132, 36946, - 37028, 38166, 38221, 38138, 40420, 40439, 40330, 40561, 40439, 40420, 2961, 3496, 3328, - 2376, 2562, 2614, 11695, 11975, 11739, 14062, 13950, 14004, 13602, 13926, 13642, 27920, - 27742, 27706, 27938, 27742, 27920, 27999, 28055, 27938, 27618, 27711, 27797, 27647, 27711, - 27618, 27647, 27618, 27365, 2208, 2388, 1921, 22819, 22854, 22680, 30982, 30895, 30796, - 33115, 32999, 33171, 33890, 33776, 33791, 37836, 37220, 37053, 37766, 37810, 38418, 37751, - 37598, 37630, 38340, 38231, 38262, 25948, 26023, 25989, 25845, 25379, 25880, 40013, 39900, - 39909, 39909, 39900, 39671, 40013, 39839, 40087, 6048, 6009, 6087, 5214, 5545, 5208, - 5988, 6009, 6048, 8753, 8779, 8910, 8761, 8779, 8753, 33340, 33193, 33186, 33340, - 33186, 33348, 33356, 33467, 33394, 32925, 33056, 32490, 40530, 40646, 40294, 40712, 40591, - 40551, 40980, 40530, 40427, 40703, 40159, 40549, 40612, 40549, 40624, 40549, 40512, 40624, - 3932, 3909, 3863, 3853, 3801, 3763, 3763, 3721, 3702, 3702, 3671, 3660, 13578, - 13642, 13470, 12910, 12610, 12155, 28706, 28657, 28626, 40238, 40231, 40136, 40452, 40207, - 40374, 22819, 23096, 22981, 19861, 20023, 19647, 19627, 19563, 19647, 19533, 19563, 19627, - 4508, 4537, 4661, 5198, 4901, 5255, 5703, 5761, 5824, 10775, 10458, 10666, 10036, - 9868, 9677, 2355, 2441, 2466, 2209, 2414, 2208, 2376, 2614, 2651, 22981, 23096, - 23143, 23469, 23833, 23545, 23254, 23394, 23306, 23239, 23394, 23254, 32575, 32677, 33209, - 37763, 37681, 37769, 37132, 37385, 36946, 40439, 40443, 40374, 40570, 40443, 40439, 8461, - 8749, 8833, 6609, 6633, 6907, 9153, 9835, 9882, 10101, 10082, 10089, 10724, 10748, - 10797, 37555, 37399, 37409, 2480, 2494, 2616, 2367, 2494, 2480, 6224, 6262, 6344, - 13374, 13216, 13195, 26811, 26733, 26994, 25003, 24817, 24927, 27999, 28087, 28055, 26990, - 26994, 27181, 34954, 35146, 35105, 34629, 34734, 34494, 34629, 34494, 34503, 34629, 34503, - 34576, 34503, 34418, 34576, 36196, 36025, 36007, 36196, 36007, 36204, 36407, 36357, 36484, - 14180, 14062, 14004, 14554, 14366, 14624, 14554, 14624, 14752, 13991, 14280, 13919, 14095, - 14374, 14280, 15227, 15300, 15190, 5600, 5703, 5604, 37144, 37343, 37173, 36638, 36808, - 36658, 36464, 36199, 36131, 2441, 2402, 2507, 34208, 33978, 33994, 35189, 35146, 34954, - 17268, 17050, 17158, 15098, 15175, 15364, 17199, 17050, 17268, 40363, 40231, 40238, 3264, - 3207, 3267, 3113, 3145, 3208, 3015, 3145, 3113, 3167, 3145, 2804, 15364, 15175, - 15223, 15609, 15512, 15627, 19918, 19855, 20319, 16929, 17014, 17050, 19533, 19540, 19563, - 16349, 16539, 16141, 33193, 33115, 33171, 33522, 33115, 33193, 33356, 33394, 33262, 32159, - 32107, 31980, 36602, 36464, 36627, 36633, 36464, 36622, 5987, 6220, 5913, 4537, 4635, - 4639, 10825, 10724, 10797, 31367, 31555, 31221, 30197, 30081, 30056, 37889, 37763, 37769, - 37823, 37763, 37889, 37719, 37751, 37630, 38166, 38023, 38218, 39872, 40107, 39990, 38981, - 38875, 38930, 2732, 2679, 3293, 12892, 13506, 13120, 11243, 11121, 11128, 11081, 10825, - 10956, 19533, 19442, 19540, 17796, 18098, 17647, 22981, 23143, 23469, 24889, 24861, 24681, - 23923, 24056, 23767, 29284, 29256, 29197, 29683, 29611, 29676, 29733, 29611, 29683, 29733, - 29683, 29841, 29967, 29919, 30063, 29967, 30063, 30039, 38494, 38575, 38370, 38567, 38575, - 38494, 38231, 38191, 38221, 38535, 38723, 38504, 38856, 38407, 38365, 38803, 38624, 38849, - 40303, 40321, 40168, 40505, 40321, 40303, 40551, 40547, 40429, 40591, 40547, 40551, 2857, - 2788, 2887, 2693, 2809, 2473, 40231, 40155, 39748, 40319, 40177, 40482, 40141, 40248, - 40135, 40636, 40494, 40515, 4022, 3998, 4175, 4334, 4422, 4508, 4508, 4521, 4537, - 4537, 4521, 4635, 3985, 3998, 4022, 3985, 4059, 3840, 4153, 4309, 4325, 6144, - 6220, 5987, 6144, 6224, 6344, 19236, 19442, 19533, 29611, 29438, 29207, 30157, 30063, - 30330, 30157, 30330, 30340, 33720, 33618, 33525, 23394, 23433, 23517, 23239, 23433, 23394, - 34880, 33992, 34752, 33942, 33927, 33841, 33776, 33814, 33525, 35558, 35430, 35552, 3905, - 3932, 3863, 29281, 29256, 29284, 28969, 29179, 28875, 28875, 29179, 28859, 29589, 29875, - 29628, 30349, 30400, 30491, 29589, 29628, 29494, 14832, 15190, 14716, 16395, 16441, 16337, - 21247, 21785, 21599, 26090, 26285, 26375, 3654, 3671, 3702, 3660, 3601, 3760, 3721, - 3763, 3801, 13195, 13216, 13057, 13602, 13778, 13926, 13700, 13778, 13602, 22630, 22169, - 22121, 33950, 33994, 33839, 34147, 34208, 33994, 35705, 35558, 35831, 40547, 40529, 40412, - 40443, 40452, 40374, 40591, 40529, 40547, 31148, 31084, 30982, 31193, 31084, 31148, 30430, - 30123, 30133, 11265, 11121, 11243, 19236, 19397, 19442, 21785, 21863, 21885, 30340, 30349, - 30508, 30197, 30430, 30081, 38039, 37807, 37792, 38930, 38875, 38849, 39045, 39004, 39223, - 5208, 5545, 5328, 3745, 3905, 3759, 17050, 17014, 17029, 18582, 19013, 18692, 37223, - 37343, 37144, 37827, 37812, 37751, 40319, 40248, 40121, 9589, 9882, 9819, 5600, 5552, - 5703, 6173, 6180, 6295, 6322, 6295, 6479, 6051, 6144, 5987, 33720, 33516, 33618, - 33618, 33516, 33487, 33356, 33262, 33269, 23433, 23590, 23578, 23718, 23590, 23433, 40570, - 40452, 40443, 6894, 7243, 7114, 15098, 15164, 15175, 16702, 16539, 16853, 32230, 31495, - 31897, 31534, 31555, 31367, 31623, 31555, 31534, 14157, 14062, 14180, 13950, 13800, 13808, - 14691, 14554, 14752, 14992, 15223, 15164, 19855, 19555, 19605, 19236, 19136, 19397, 40624, - 40512, 40494, 40624, 40494, 40636, 3181, 3207, 3264, 3167, 3257, 3145, 15164, 15223, - 15175, 14580, 14832, 14716, 14471, 14611, 14374, 26731, 26811, 26990, 26104, 26039, 26090, - 26747, 26861, 26372, 3745, 3809, 3853, 3655, 3798, 3495, 16764, 16892, 17016, 16337, - 16112, 16227, 26636, 26747, 26372, 24889, 24681, 24888, 3176, 3038, 2734, 14991, 15164, - 15098, 34981, 34752, 35234, 2280, 2420, 2574, 3548, 3601, 3660, 3548, 3660, 3671, - 14397, 14471, 14374, 13374, 13578, 13470, 19555, 19428, 19408, 19236, 19111, 19136, 40146, - 40611, 40212, 8310, 8647, 8590, 8779, 9027, 9145, 33516, 33340, 33348, 31391, 31500, - 31536, 33812, 33340, 33516, 33269, 33262, 33243, 33645, 33668, 33586, 33269, 33243, 33101, - 31431, 31251, 31175, 30340, 30330, 30349, 37751, 37812, 37786, 37719, 37630, 37619, 36946, - 36707, 36520, 36025, 35858, 35832, 36683, 36707, 36747, 36464, 36633, 36555, 36924, 37018, - 36858, 35923, 35755, 35714, 3404, 3466, 3760, 5703, 5552, 5601, 5774, 5941, 6009, - 14164, 14180, 14366, 28440, 28706, 28626, 28657, 28735, 28823, 27478, 27647, 27365, 3082, - 3181, 3167, 2606, 2693, 2473, 2716, 2693, 2606, 3739, 3721, 3801, 6633, 6498, - 6764, 16680, 16892, 16764, 19136, 19111, 19002, 22464, 22454, 22639, 22854, 22981, 23206, - 23143, 23304, 23469, 24927, 24817, 24790, 25815, 25444, 25817, 34086, 33927, 33942, 33645, - 33586, 33554, 35949, 35858, 36117, 39046, 39045, 39213, 39078, 39064, 38646, 39147, 39308, - 39123, 24056, 24266, 24222, 24104, 24266, 24056, 37343, 37442, 37409, 37532, 37442, 37518, - 6180, 5988, 6048, 6009, 5988, 5915, 8647, 8761, 8753, 33554, 33586, 33467, 33091, - 33269, 33101, 36484, 36357, 36559, 4355, 4422, 4334, 3998, 4153, 4175, 4005, 4153, - 3998, 6462, 6400, 6532, 7019, 7001, 6711, 7829, 7903, 7784, 7829, 8106, 7903, - 8647, 8665, 8761, 6303, 6400, 6428, 6303, 6428, 6262, 6303, 6262, 6153, 29438, - 29281, 29284, 29256, 29218, 28953, 29611, 29489, 29438, 29841, 29816, 29869, 29841, 29869, - 29967, 29841, 29967, 29997, 30063, 30157, 30039, 33927, 33890, 33791, 35940, 35923, 35714, - 30039, 30157, 30210, 38575, 39078, 38411, 38541, 38296, 38449, 38296, 38273, 38449, 16441, - 16680, 16509, 16227, 16112, 16004, 16112, 15921, 16004, 29560, 29489, 29611, 38707, 38723, - 38535, 38803, 38665, 38624, 38803, 38849, 38934, 40155, 40165, 39796, 39900, 40036, 39679, - 40301, 40165, 40155, 40368, 40155, 40231, 40363, 40238, 40564, 3601, 3519, 3760, 3415, - 3519, 3601, 13578, 13700, 13602, 40529, 40555, 40420, 40405, 40363, 40532, 40715, 40555, - 40529, 11975, 11480, 11679, 10272, 10521, 10386, 11332, 11480, 11464, 13272, 13450, 13578, - 13450, 13818, 13700, 12889, 13195, 13057, 12889, 13057, 12910, 12610, 12094, 12155, 17251, - 17374, 17016, 19034, 19136, 19002, 30895, 30982, 31003, 39064, 39159, 38952, 40482, 40177, - 40475, 39147, 39159, 39373, 3826, 3985, 3840, 29432, 29281, 29438, 38934, 38849, 38875, - 2847, 2961, 3328, 2384, 2359, 2679, 26039, 25939, 25992, 26039, 25992, 26090, 40087, - 39839, 39967, 2345, 2392, 2510, 11091, 11081, 11121, 10272, 10437, 10521, 10082, 9998, - 10089, 31193, 31087, 31084, 31495, 31431, 31340, 31500, 31431, 31495, 31353, 31431, 31391, - 38218, 38023, 37924, 37661, 37719, 37619, 40359, 40219, 40252, 36633, 36754, 36638, 36714, - 36754, 36633, 13991, 13919, 13778, 15416, 15550, 15466, 11332, 11265, 11415, 16880, 16702, - 16853, 18582, 18761, 19013, 17103, 17251, 17016, 17103, 17016, 16892, 40248, 40359, 40135, - 40392, 40359, 40248, 6153, 6224, 6144, 6153, 6262, 6224, 7724, 7775, 7675, 33890, - 33814, 33776, 35923, 36057, 35861, 2693, 2716, 2857, 2386, 2649, 2494, 3167, 3181, - 3264, 3490, 3798, 3669, 3146, 3181, 3082, 3809, 3739, 3801, 3553, 3548, 3671, - 3932, 3905, 4150, 5090, 5198, 5190, 15164, 14991, 14992, 14837, 14691, 14752, 14297, - 14164, 14366, 15609, 15627, 15818, 24535, 24668, 24395, 36924, 36811, 36808, 14062, 13800, - 13950, 14297, 14366, 14554, 28440, 27797, 27977, 27425, 27478, 27365, 27425, 27365, 27283, - 35561, 34981, 35234, 34086, 34097, 33927, 33927, 33975, 33890, 33890, 34016, 33814, 35462, - 35234, 35430, 35462, 35430, 35558, 19034, 19002, 18779, 36559, 36357, 36511, 36273, 36196, - 36204, 7001, 6905, 6711, 6777, 6532, 6711, 36158, 35940, 36063, 35923, 36073, 36057, - 34734, 34777, 34659, 34794, 34777, 34734, 34794, 34734, 34629, 34576, 34418, 34658, 40555, - 40561, 40420, 40584, 40561, 40555, 4406, 4422, 4355, 5987, 5913, 5909, 7397, 7076, - 7114, 6633, 6576, 6498, 6894, 6795, 6751, 11265, 11091, 11121, 35207, 35189, 34954, - 3654, 3702, 3721, 19063, 18998, 19110, 17251, 17647, 18098, 23773, 23923, 23767, 24266, - 24535, 24395, 23718, 23695, 23590, 34674, 34658, 34851, 33783, 33720, 33814, 33814, 33720, - 33525, 31536, 31611, 31508, 33950, 34147, 33994, 33554, 33467, 33356, 3466, 3382, 3906, - 3519, 3404, 3760, 3431, 3404, 3519, 13818, 13991, 13778, 13818, 13778, 13700, 16398, - 16680, 16441, 15550, 15619, 15466, 19034, 18998, 19063, 22464, 22639, 22680, 37442, 37555, - 37409, 37532, 37555, 37442, 40346, 40087, 39967, 5214, 5090, 5190, 5328, 5545, 5601, - 5328, 5601, 5552, 32158, 32159, 31980, 33375, 33554, 33356, 31623, 31221, 31555, 5656, - 5703, 5824, 4406, 4521, 4508, 20341, 20157, 20319, 19855, 19778, 19555, 19555, 19455, - 19428, 20530, 20496, 20341, 20641, 20496, 20530, 20662, 20496, 20641, 20662, 20641, 20704, - 20662, 20704, 20685, 21111, 20985, 21124, 21111, 21124, 21268, 38039, 37792, 37812, 37827, - 37751, 37719, 2417, 2347, 2466, 2441, 2355, 2402, 2402, 2299, 2578, 2420, 2345, - 2510, 2453, 2328, 2417, 2451, 2328, 2453, 2228, 2328, 2451, 2228, 2451, 2209, - 2451, 2414, 2209, 7675, 7775, 7572, 24425, 24535, 24266, 31534, 31367, 31347, 31429, - 31264, 31379, 35560, 35462, 35558, 35558, 35552, 35831, 40505, 40303, 40452, 40188, 40013, - 40087, 23039, 23201, 23035, 22953, 23035, 22800, 2328, 2357, 2417, 3729, 3739, 3809, - 13450, 13700, 13578, 12155, 12094, 11793, 20496, 20350, 20341, 29419, 29589, 29494, 30197, - 30451, 30430, 27797, 27711, 27977, 39045, 39046, 38919, 39223, 39031, 39157, 39223, 39157, - 39430, 2357, 2363, 2417, 32490, 32439, 32925, 36273, 36204, 36407, 36683, 36559, 36511, - 36683, 36511, 36707, 36707, 36946, 36747, 15552, 15609, 15818, 15809, 15818, 16110, 15227, - 15190, 14832, 16880, 16853, 17014, 16398, 16441, 16395, 17251, 17421, 17647, 22781, 22854, - 23206, 22565, 22464, 22680, 25187, 25228, 25444, 25815, 25187, 25444, 26731, 26483, 26738, - 2363, 2347, 2417, 7724, 7829, 7784, 20350, 20157, 20341, 21440, 21111, 21268, 21884, - 21642, 21915, 22565, 22680, 22781, 33375, 33356, 33269, 33899, 33819, 33668, 36273, 36407, - 36417, 14625, 14691, 14837, 14625, 14837, 14886, 31431, 31353, 31251, 31500, 31495, 31611, - 37857, 37827, 37719, 2347, 2355, 2466, 19990, 19861, 19711, 19990, 20065, 19861, 19861, - 20065, 20023, 22125, 21863, 22004, 22481, 22121, 22433, 19861, 19761, 19711, 19761, 19563, - 19711, 19563, 19704, 19711, 19540, 19704, 19563, 19424, 19704, 19540, 31087, 30982, 31084, - 5905, 5915, 6180, 5538, 5525, 5600, 6713, 6609, 6907, 14471, 14580, 14716, 14095, - 14397, 14374, 26811, 26731, 26738, 26990, 27181, 27612, 27938, 27920, 27999, 26101, 25989, - 26023, 26101, 26023, 26000, 3530, 3654, 3721, 3384, 3466, 3404, 3366, 3764, 3207, - 3860, 3944, 3985, 27810, 27711, 27647, 27530, 27647, 27478, 40561, 40570, 40439, 40584, - 40570, 40561, 19442, 19424, 19540, 22854, 22819, 22981, 22351, 21915, 22454, 22619, 22630, - 22481, 22630, 22121, 22481, 40712, 40551, 40540, 38775, 38707, 38777, 38775, 38723, 38707, - 38775, 38777, 38834, 29419, 29191, 29179, 30430, 31065, 31072, 29419, 29179, 29287, 38567, - 38679, 38575, 38449, 38273, 38455, 3384, 3382, 3466, 3431, 3519, 3415, 3075, 3366, - 3207, 5600, 5525, 5552, 5774, 6009, 5750, 5913, 5866, 5909, 6711, 6532, 6317, - 6609, 6576, 6633, 8950, 8558, 8833, 8461, 8558, 8508, 14164, 14157, 14180, 14201, - 14157, 14164, 14840, 15227, 14832, 16576, 16141, 16539, 17008, 17103, 16892, 20157, 19918, - 20319, 17063, 17050, 17199, 27425, 27530, 27478, 29281, 29218, 29256, 29489, 29432, 29438, - 29560, 29432, 29489, 29336, 29432, 29536, 29611, 29733, 29560, 29831, 29841, 29997, 28969, - 28875, 28735, 34880, 34113, 34098, 36196, 36117, 36025, 36465, 36407, 36484, 37563, 37576, - 37555, 36913, 36924, 36808, 36913, 36808, 36754, 40363, 40368, 40231, 40405, 40368, 40363, - 40646, 40704, 40129, 40821, 40704, 40646, 40703, 40549, 40702, 40549, 40612, 40702, 33346, - 33375, 33269, 32925, 32439, 32569, 36577, 36465, 36484, 36747, 36946, 37298, 36602, 36622, - 36464, 11480, 11332, 11415, 11265, 11280, 11091, 11091, 10825, 11081, 11464, 11480, 11695, - 38231, 38221, 38262, 38340, 38273, 38231, 19918, 19827, 19855, 40702, 40612, 40701, 29336, - 29218, 29281, 37555, 37576, 37449, 37223, 37073, 37256, 38981, 38934, 38875, 16702, 16576, - 16539, 16442, 16576, 16556, 23718, 23433, 23239, 24014, 24104, 23923, 23923, 24104, 24056, - 2383, 2386, 2494, 2367, 2480, 2392, 22630, 22673, 22800, 22619, 22673, 22630, 30600, - 30349, 30491, 31193, 31148, 31251, 30657, 31065, 30430, 38407, 38094, 38365, 37763, 37836, - 37053, 37941, 38039, 37812, 37941, 37812, 37827, 40611, 40684, 40686, 40701, 40612, 40698, - 34113, 34097, 34086, 30600, 30547, 30751, 38856, 38365, 38504, 38262, 38221, 38166, 19063, - 19397, 19136, 22476, 22454, 22464, 3579, 3553, 3671, 3932, 4280, 3909, 5201, 5328, - 5552, 32159, 32330, 32294, 32460, 32330, 32159, 31768, 31980, 31623, 37256, 37073, 37018, - 39430, 39176, 39471, 39046, 38981, 38930, 40036, 39900, 40013, 3415, 3601, 3433, 13948, - 13800, 14062, 14095, 14417, 14397, 14095, 13818, 13670, 15609, 15513, 15512, 15552, 15513, - 15609, 26039, 26157, 25939, 26183, 26104, 26090, 25880, 25948, 25845, 25667, 25585, 25379, - 24888, 24681, 24535, 27863, 27810, 27647, 31193, 31003, 31087, 33812, 33193, 33340, 31429, - 31534, 31347, 40062, 40036, 40013, 40062, 40013, 40204, 3905, 3745, 3853, 3540, 3579, - 3654, 3654, 3579, 3671, 5090, 5214, 5115, 28735, 28657, 28706, 28735, 28706, 28576, - 39056, 38981, 39046, 6197, 6400, 6303, 5913, 5758, 5866, 33346, 33269, 33091, 33899, - 33668, 33645, 40612, 40624, 40698, 33720, 33812, 33516, 34097, 33975, 33927, 33899, 33883, - 34070, 36355, 36464, 36131, 35428, 35105, 35146, 4540, 4740, 4635, 4422, 4406, 4508, - 4226, 4334, 4309, 4226, 4309, 4153, 4005, 3998, 3944, 10458, 10126, 10123, 10126, - 9969, 10036, 30751, 30547, 30895, 38318, 38262, 38166, 17063, 16929, 17050, 19130, 19311, - 19156, 32569, 32439, 32328, 33072, 33231, 33091, 40698, 40624, 40636, 32330, 32569, 32328, - 28576, 28706, 28440, 3181, 3146, 3207, 3038, 2930, 2745, 18071, 18098, 17796, 17095, - 17421, 17251, 26747, 26809, 26861, 27617, 27863, 27647, 26737, 26809, 26747, 14157, 14022, - 14062, 14261, 14297, 14513, 14164, 14297, 14201, 39872, 39561, 39503, 3434, 3669, 3618, - 3944, 3998, 3985, 3434, 3618, 3366, 33899, 33645, 33883, 39373, 39308, 39147, 40177, - 40319, 40121, 39373, 39429, 39541, 10623, 10825, 10723, 10214, 9998, 10082, 10036, 9969, - 9868, 15112, 15098, 15364, 6153, 6144, 6051, 4540, 4635, 4521, 19455, 19311, 19428, - 22565, 22476, 22464, 22781, 22688, 22570, 36577, 36484, 36559, 36273, 36320, 36196, 36577, - 36559, 36800, 40146, 40090, 40684, 40803, 40698, 40800, 5172, 5214, 5208, 37576, 37661, - 37619, 37518, 37442, 37343, 10160, 9998, 10214, 19586, 19455, 19555, 37689, 37661, 37576, - 38039, 38218, 37924, 40704, 40708, 40209, 40718, 40584, 40555, 40694, 40402, 40693, 5328, - 5261, 5208, 5154, 5261, 5201, 34016, 33783, 33814, 2672, 2930, 2788, 7074, 7565, - 7572, 7724, 7727, 7829, 6153, 6051, 6063, 15227, 15416, 15466, 15908, 16004, 15921, - 16227, 16398, 16395, 16823, 17008, 16892, 17570, 17666, 17421, 15457, 15416, 15141, 14417, - 14471, 14397, 23432, 23718, 23239, 24104, 24252, 24266, 35189, 35345, 35146, 34777, 35207, - 34954, 34674, 34794, 34629, 34674, 34629, 34576, 34674, 34851, 34833, 16929, 16880, 17014, - 16576, 16442, 16141, 15701, 15552, 15818, 15188, 15112, 15364, 17013, 16880, 16929, 3594, - 3826, 3655, 22784, 22953, 22800, 22784, 22800, 22673, 24157, 24252, 24104, 34794, 34674, - 34833, 38834, 38777, 38803, 38835, 38418, 38407, 38834, 38803, 39003, 38541, 38679, 38567, - 38704, 38679, 38541, 38591, 38541, 38449, 38591, 38449, 38582, 4489, 4540, 4415, 4590, - 4540, 4489, 31087, 31003, 30982, 31193, 31251, 31206, 31500, 31391, 31431, 31536, 31500, - 31611, 31534, 31682, 31623, 33072, 33064, 33097, 31379, 31264, 31072, 31534, 31429, 31632, - 37889, 37769, 37801, 37889, 37801, 38048, 37801, 38038, 38048, 37902, 37857, 37719, 38455, - 38273, 38340, 3983, 4226, 4153, 7076, 6894, 7114, 6324, 6498, 6576, 5261, 5328, - 5201, 6894, 7076, 6897, 11332, 11280, 11265, 11342, 11464, 11423, 38455, 38340, 38477, - 6063, 6051, 5985, 5576, 5630, 5913, 36417, 36320, 36273, 36800, 36559, 36683, 3490, - 3495, 3798, 3436, 3434, 3344, 3540, 3654, 3530, 3909, 4280, 3849, 27999, 28296, - 28087, 26731, 26714, 26483, 29218, 29113, 28953, 29432, 29336, 29281, 29831, 29733, 29841, - 29997, 30039, 30026, 30508, 30349, 30600, 3433, 3601, 3548, 3729, 3809, 3745, 15908, - 15763, 15642, 7565, 7675, 7572, 8227, 8310, 8356, 8583, 8665, 8647, 2152, 2345, - 2420, 38477, 38340, 38262, 6051, 5987, 5985, 8558, 8461, 8833, 8508, 8558, 8617, - 16198, 16398, 16227, 3790, 3759, 3905, 7675, 7727, 7724, 22953, 23039, 23035, 23033, - 23039, 22953, 26478, 26636, 26372, 26000, 25880, 26066, 29193, 29113, 29218, 29217, 29071, - 29014, 28969, 29071, 29179, 29419, 29553, 29589, 29589, 30200, 29875, 29071, 28969, 29014, - 26974, 26990, 27044, 23718, 23773, 23767, 23902, 23773, 23718, 4203, 4355, 4334, 30758, - 30508, 30600, 19455, 19156, 19311, 30912, 30751, 30895, 31206, 31251, 31353, 27016, 26949, - 26861, 26289, 25989, 26101, 24252, 24425, 24266, 24323, 24425, 24252, 27810, 27977, 27711, - 27016, 26861, 26809, 37532, 37563, 37555, 37902, 37941, 37857, 37594, 37563, 37532, 37518, - 37343, 37551, 37256, 37018, 37252, 5261, 5172, 5208, 4992, 4901, 5198, 5154, 5172, - 5261, 5988, 6180, 5915, 40435, 40319, 40482, 40359, 40490, 40219, 3759, 3729, 3745, - 6479, 6498, 6322, 36622, 36714, 36633, 36355, 36131, 36277, 8461, 8315, 8749, 8617, - 8558, 8623, 36417, 36407, 36465, 3436, 3495, 3490, 4992, 5198, 5090, 9677, 9868, - 9469, 8665, 8779, 8761, 39308, 39450, 39123, 39429, 39159, 39064, 18582, 18368, 18761, - 18692, 18368, 18582, 19034, 19063, 19136, 17666, 17796, 17647, 30912, 30895, 31003, 40838, - 40712, 40540, 40638, 40505, 40452, 26170, 26289, 26101, 37179, 37018, 36924, 3431, 3384, - 3404, 3186, 3053, 3588, 3383, 3384, 3431, 3548, 3553, 3498, 17421, 17666, 17647, - 17095, 17251, 17103, 40601, 40452, 40570, 40188, 40087, 40346, 16004, 16198, 16227, 16823, - 16892, 16680, 15555, 15763, 15550, 2269, 2367, 2392, 2473, 2918, 2756, 10386, 10521, - 10724, 8623, 8558, 8950, 10386, 10724, 10549, 37385, 37132, 37220, 38056, 38038, 38301, - 37857, 37941, 37827, 37902, 37719, 37661, 40693, 40402, 40648, 40693, 40920, 40924, 8333, - 8315, 8461, 9919, 10089, 9998, 36435, 36417, 36465, 36435, 36465, 36536, 30976, 30912, - 31003, 38057, 38218, 38039, 40406, 40392, 40248, 20685, 20704, 20833, 20496, 20537, 20350, - 20350, 20381, 20157, 20157, 20068, 19918, 19918, 19778, 19827, 19827, 19778, 19855, 19455, - 19393, 19156, 20685, 20833, 20914, 20985, 20943, 20914, 20985, 21111, 20943, 20662, 20537, - 20496, 18368, 18229, 18033, 18526, 18229, 18368, 40715, 40529, 40591, 2357, 2292, 2363, - 2363, 2190, 2347, 2347, 2278, 2355, 2207, 2299, 2402, 2345, 2269, 2392, 2328, - 2228, 2357, 2414, 2388, 2208, 5774, 5656, 5824, 5597, 5656, 5774, 15809, 16110, - 16141, 15098, 14886, 14991, 20943, 21111, 21047, 25880, 26000, 26023, 25379, 25107, 24889, - 33028, 33064, 32925, 32925, 33064, 33072, 33375, 33346, 33554, 32925, 33024, 33028, 37385, - 37688, 37573, 36602, 36714, 36622, 36891, 36714, 36602, 40605, 40155, 40368, 39872, 39740, - 39561, 2228, 2292, 2357, 2716, 2606, 2788, 2844, 2649, 2257, 20537, 20381, 20350, - 21047, 21111, 21440, 36117, 35858, 36025, 35475, 34880, 34981, 33783, 34016, 34283, 34450, - 34016, 34097, 34097, 34016, 33975, 33975, 34016, 33890, 36117, 36196, 36240, 3498, 3553, - 3579, 20065, 20290, 20724, 20097, 20290, 20065, 20097, 20065, 19997, 20065, 19990, 19997, - 20769, 20983, 20674, 26974, 26804, 26990, 28087, 28309, 28174, 27863, 27977, 27810, 39148, - 39056, 39046, 39003, 38803, 38934, 39783, 39430, 39471, 39740, 39471, 39561, 39541, 39450, - 39308, 39595, 39450, 39555, 22615, 22476, 22565, 22615, 22565, 22781, 27132, 27016, 27038, - 27038, 27016, 26809, 27617, 27647, 27530, 26478, 26372, 26289, 40915, 40648, 40611, 29997, - 29967, 30039, 29336, 29193, 29218, 29113, 29193, 28542, 30157, 30241, 30210, 30340, 30428, - 30157, 3530, 3721, 3739, 3495, 3594, 3655, 4226, 4190, 4334, 4173, 4190, 4226, - 3860, 3405, 3791, 29730, 29560, 29733, 38856, 38504, 38723, 39060, 38934, 38981, 5172, - 5115, 5214, 5154, 5115, 5172, 14095, 14280, 13991, 15416, 15457, 15550, 14095, 13991, - 13818, 23773, 24014, 23923, 24888, 25379, 24889, 23902, 24014, 23773, 30340, 30508, 30428, - 37563, 37689, 37576, 37397, 37343, 37223, 37397, 37223, 37256, 39082, 39078, 38575, 38591, - 38704, 38541, 38661, 38704, 38591, 38582, 38449, 38455, 3146, 3080, 3207, 3434, 3436, - 3490, 3495, 3476, 3594, 2804, 3082, 3167, 3065, 3082, 2973, 26804, 26714, 26731, - 26104, 26157, 26039, 26804, 26731, 26990, 2190, 2278, 2347, 9975, 9919, 9998, 19997, - 19990, 19872, 37703, 37689, 37563, 4540, 4521, 4415, 3934, 4153, 4005, 11464, 11342, - 11332, 11695, 11480, 11975, 30428, 30508, 30381, 30013, 30200, 29589, 38661, 38582, 38517, - 6322, 6498, 6324, 8333, 8461, 8508, 8781, 8623, 8950, 8310, 8590, 8356, 33231, - 33346, 33091, 34576, 34658, 34674, 37368, 37397, 37256, 6565, 6576, 6609, 31495, 31795, - 31611, 34880, 34752, 34981, 38418, 37810, 38407, 38218, 38318, 38166, 38069, 38057, 38039, - 38069, 38039, 37941, 3313, 3302, 3384, 3384, 3302, 3382, 12753, 13195, 12889, 14389, - 14095, 13985, 39595, 39632, 39244, 40584, 40600, 40570, 40720, 40600, 40584, 2367, 2383, - 2494, 2240, 2383, 2367, 3729, 3635, 3739, 3759, 3647, 3729, 3863, 3790, 3905, - 3802, 3790, 3863, 22781, 22680, 22854, 22476, 22412, 22454, 22121, 21863, 22125, 23039, - 23212, 23239, 26409, 26478, 26289, 40703, 40818, 40159, 40704, 40944, 40708, 40708, 40838, - 40540, 40812, 40818, 40703, 40812, 40703, 40702, 40812, 40702, 40810, 40702, 40701, 40810, - 40701, 40809, 40810, 10272, 10160, 10214, 10317, 10160, 10272, 10036, 10123, 10126, 9822, - 10123, 10036, 31415, 31206, 31353, 31193, 30976, 31003, 31743, 31554, 31611, 16199, 16198, - 16004, 16398, 16198, 16278, 24347, 24535, 24425, 26000, 26170, 26101, 30758, 30751, 30916, - 30758, 30600, 30751, 16556, 16576, 16702, 17224, 17063, 17199, 40564, 40269, 40321, 40564, - 40321, 40505, 40684, 40090, 40219, 40435, 40406, 40248, 40435, 40248, 40319, 5656, 5604, - 5703, 5597, 5604, 5656, 8712, 9027, 8779, 36714, 36856, 36754, 36891, 36856, 36714, - 41176, 40646, 40530, 40863, 40601, 40600, 3540, 3498, 3579, 3387, 3383, 3431, 3530, - 3498, 3540, 36435, 36320, 36417, 36110, 36117, 36240, 39213, 39045, 39223, 40701, 40805, - 40809, 3387, 3431, 3415, 27617, 27530, 27425, 28599, 28576, 28440, 29071, 29287, 29179, - 38892, 38723, 38775, 15141, 15416, 15227, 26183, 26157, 26104, 24842, 24220, 24817, 17892, - 18071, 17796, 17892, 17796, 17666, 40600, 40601, 40570, 40715, 40591, 40845, 35560, 35558, - 35705, 35560, 35234, 35462, 34794, 34875, 34777, 36277, 36131, 36057, 34833, 34875, 34794, - 33950, 33936, 34147, 34875, 35207, 34777, 2207, 2402, 2355, 10317, 10386, 10431, 19819, - 19778, 19918, 19156, 19044, 19013, 31415, 31353, 31391, 37836, 37763, 37823, 38056, 38048, - 38038, 38058, 38048, 38056, 34147, 33936, 34070, 3583, 3635, 3729, 35207, 35345, 35189, - 2299, 2280, 2578, 5443, 5538, 5604, 6322, 6173, 6295, 8485, 8508, 8617, 8665, - 8626, 8779, 8227, 8356, 8180, 19424, 19442, 19397, 19424, 19397, 19329, 40701, 40698, - 40805, 38406, 38318, 38218, 38319, 38218, 38057, 4945, 4992, 5090, 5201, 5552, 5335, - 6894, 6713, 6907, 5948, 5949, 6173, 6897, 7076, 6893, 7675, 7665, 7727, 7747, - 8356, 7829, 7074, 7572, 7179, 7526, 7565, 7074, 14417, 14580, 14471, 14389, 14580, - 14417, 22521, 22412, 22476, 24842, 24817, 25003, 22619, 22784, 22673, 22737, 22784, 22619, - 27016, 27132, 26949, 27038, 26809, 26814, 35345, 35428, 35146, 37689, 37753, 37661, 37686, - 37703, 37563, 37397, 37436, 37343, 37368, 37436, 37397, 17063, 17013, 16929, 16616, 17013, - 17224, 16823, 16680, 16585, 3082, 3065, 3146, 2973, 3082, 2646, 9919, 9786, 9819, - 10160, 9975, 9998, 9901, 9975, 9871, 14580, 14840, 14832, 26375, 26285, 26483, 26990, - 27612, 27044, 31632, 31682, 31534, 31379, 31072, 31065, 5604, 5538, 5600, 5838, 6009, - 5915, 36856, 36913, 36754, 37100, 36913, 37002, 3344, 3434, 3366, 3860, 3934, 3944, - 40805, 40698, 40803, 6751, 6713, 6894, 7565, 7665, 7675, 24014, 24157, 24104, 24213, - 24157, 24014, 35552, 35858, 35831, 40595, 40564, 40505, 5576, 4420, 5630, 5866, 5734, - 5909, 6099, 6197, 6303, 34070, 33936, 33899, 33097, 33231, 33072, 33097, 33064, 33028, - 39503, 40107, 39872, 40346, 39967, 40165, 40301, 40155, 40605, 15410, 15364, 15513, 14129, - 14022, 14157, 11739, 11975, 12339, 15410, 15513, 15552, 16858, 16702, 16880, 25815, 25817, - 25939, 3599, 3530, 3739, 3335, 3387, 3415, 28599, 28440, 28490, 39314, 39223, 39507, - 39314, 39213, 39223, 5985, 5987, 5903, 6713, 6619, 6609, 40698, 40636, 40800, 14201, - 14297, 14261, 27863, 27909, 27977, 27506, 27617, 27425, 31536, 31415, 31391, 31206, 30976, - 31193, 31508, 31415, 31536, 31648, 31379, 31384, 11793, 11989, 11570, 10763, 10793, 10976, - 10579, 10666, 10458, 30916, 30976, 31043, 40843, 40591, 40712, 40601, 40638, 40452, 11342, - 11280, 11332, 13506, 13731, 13120, 29746, 29730, 29831, 29831, 29730, 29733, 29560, 29536, - 29432, 29746, 29831, 29997, 30026, 30039, 30210, 30026, 30210, 30241, 3790, 3647, 3759, - 3635, 3599, 3739, 3849, 4280, 3927, 3751, 3909, 3725, 11695, 11423, 11464, 29730, - 29536, 29560, 30241, 30157, 30428, 6619, 6565, 6609, 35831, 35858, 35949, 19329, 19397, - 19063, 40636, 40694, 40792, 40800, 40636, 40940, 15425, 15410, 15552, 26157, 26106, 25939, - 26375, 26483, 26714, 26066, 26170, 26000, 26737, 26747, 26636, 26066, 25880, 25952, 3751, - 3802, 3863, 4190, 4203, 4334, 4589, 5367, 4740, 4173, 4203, 4190, 3934, 4005, - 3944, 11390, 11280, 11342, 17013, 16858, 16880, 16616, 16858, 17013, 17684, 17892, 17666, - 16351, 16680, 16398, 16351, 16398, 16278, 19176, 19329, 19063, 17570, 17460, 17614, 25014, - 24842, 25003, 29217, 29287, 29071, 31640, 31632, 31379, 30381, 30241, 30428, 38351, 38301, - 38579, 39062, 39003, 38934, 39060, 38981, 39056, 40684, 40219, 40898, 40177, 40462, 40475, - 40725, 40638, 40601, 24157, 24323, 24252, 24213, 24323, 24157, 36913, 37113, 36924, 37100, - 37113, 36913, 3220, 3219, 3302, 3433, 3548, 3498, 3436, 3430, 3495, 3189, 3344, - 3366, 6197, 6532, 6400, 5903, 5987, 5909, 7132, 7076, 7397, 8623, 8485, 8617, - 8333, 8485, 8438, 36073, 35923, 35940, 40715, 40718, 40555, 40846, 40718, 40715, 40359, - 40392, 40490, 36008, 35949, 36117, 35927, 35831, 35949, 5827, 5903, 5909, 4590, 4740, - 4540, 19534, 19393, 19455, 16616, 16556, 16858, 33645, 33554, 33883, 33028, 33024, 33128, - 40944, 40838, 40708, 40792, 40694, 40693, 4945, 5090, 5115, 4945, 5115, 5084, 9104, - 9677, 9469, 10123, 10579, 10458, 37436, 37551, 37343, 37537, 37551, 37436, 37594, 37532, - 37518, 4521, 4406, 4385, 38286, 38069, 38268, 38582, 38661, 38591, 39082, 38575, 38679, - 38444, 38477, 38262, 38368, 38262, 38318, 39161, 39060, 39056, 2672, 2745, 2930, 2688, - 2745, 2613, 16278, 16199, 16239, 16198, 16199, 16278, 40614, 40368, 40405, 40532, 40363, - 40564, 3186, 3588, 3382, 2961, 2572, 3505, 3219, 3382, 3302, 5335, 5552, 5525, - 19393, 19262, 19156, 18410, 18626, 18071, 27612, 27742, 27938, 26781, 26375, 26714, 27991, - 27938, 28055, 32925, 32911, 33024, 31379, 31632, 31429, 31682, 31632, 31766, 33554, 33346, - 33883, 37909, 37823, 37889, 36536, 36465, 36646, 37252, 37368, 37256, 40188, 40204, 40013, - 40211, 40204, 40188, 18451, 18410, 18358, 22784, 23033, 22953, 22737, 23033, 22784, 40924, - 40792, 40693, 40490, 40392, 40406, 3313, 3384, 3383, 14022, 13948, 14062, 14513, 14554, - 14691, 14837, 14991, 14886, 30916, 30912, 30976, 30916, 30751, 30912, 38406, 38368, 38318, - 39253, 39148, 39046, 39253, 39046, 39213, 40432, 40036, 40062, 5949, 5905, 6180, 5538, - 5443, 5525, 5949, 6180, 6173, 6303, 6153, 6099, 5888, 5903, 5827, 8310, 8583, - 8647, 9027, 9104, 9469, 8220, 8583, 8310, 36800, 36683, 36747, 2257, 2649, 2049, - 2152, 2269, 2345, 3311, 3313, 3383, 3530, 3433, 3498, 2911, 3433, 3530, 3341, - 3430, 3436, 19110, 19176, 19063, 24323, 24347, 24425, 24213, 24347, 24323, 24347, 24888, - 24535, 33433, 33346, 33231, 36110, 36008, 36117, 31768, 31623, 31682, 33097, 33128, 33231, - 10386, 10317, 10272, 9975, 9901, 9919, 10549, 10724, 10825, 37113, 37179, 36924, 37131, - 37179, 37113, 3311, 3383, 3387, 14129, 13948, 14022, 26831, 26714, 26804, 26183, 26106, - 26157, 25187, 25014, 25003, 3583, 3599, 3635, 13120, 13731, 13180, 31387, 30976, 31206, - 38418, 38301, 37766, 38015, 37909, 37889, 38892, 38775, 38834, 23033, 23212, 23039, 23070, - 23212, 23033, 40838, 40843, 40712, 36240, 36196, 36320, 37369, 37252, 37179, 36158, 36073, - 35940, 2375, 2419, 2293, 2745, 2688, 3038, 2672, 2788, 2606, 5905, 5838, 5915, - 5745, 5838, 5905, 8583, 8626, 8665, 8609, 8626, 8583, 37703, 37753, 37689, 37551, - 37594, 37518, 37691, 37594, 37551, 37537, 37436, 37368, 2380, 2672, 2235, 16442, 16233, - 16141, 16334, 16233, 16442, 16952, 17008, 16823, 17095, 17103, 17008, 15555, 15550, 15457, - 9871, 9975, 9964, 31766, 31768, 31682, 30451, 30197, 30200, 37865, 37753, 37703, 38444, - 38262, 38368, 2269, 2260, 2367, 3985, 3405, 3860, 4271, 4406, 4355, 19141, 19044, - 19156, 22521, 22476, 22615, 22521, 22615, 22588, 40777, 40611, 40686, 10623, 10549, 10825, - 11423, 11390, 11342, 11695, 11526, 11423, 11523, 11526, 11695, 2405, 2473, 2756, 3433, - 3335, 3415, 3311, 3335, 3064, 3476, 3826, 3594, 15536, 15555, 15457, 14934, 15227, - 14840, 26737, 26636, 26478, 27132, 27283, 27365, 26255, 26417, 26390, 40733, 40532, 40564, - 40524, 40737, 40614, 40720, 40584, 40718, 40594, 40490, 40406, 40594, 40406, 40435, 3430, - 3476, 3495, 4420, 5576, 5367, 4271, 4355, 4203, 9645, 9786, 9747, 10431, 10549, - 10430, 11788, 11739, 11918, 13180, 13731, 13800, 39321, 39314, 39452, 40852, 40720, 40718, - 2292, 2190, 2363, 2278, 2167, 2355, 2299, 2176, 2280, 2280, 2068, 2420, 2269, - 2162, 2260, 2228, 2209, 2292, 2639, 2624, 2074, 2869, 2155, 2231, 2515, 2572, - 2961, 2305, 2560, 2562, 3983, 4173, 4226, 7747, 7829, 7727, 11406, 11390, 11423, - 20381, 20229, 20157, 19778, 19586, 19555, 19393, 19279, 19262, 19262, 19141, 19156, 20537, - 20481, 20381, 20662, 20499, 20537, 20674, 20499, 20662, 20674, 20662, 20685, 20769, 20685, - 20914, 20769, 20914, 20983, 20914, 20943, 20983, 20943, 21047, 20983, 22588, 22615, 22781, - 25140, 25014, 25187, 36346, 36240, 36320, 38517, 38582, 38455, 38517, 38455, 38477, 38517, - 38477, 38444, 39353, 39681, 40329, 2869, 2560, 2155, 3065, 3080, 3146, 3344, 3341, - 3436, 3430, 3322, 3476, 2994, 3080, 3065, 3802, 3647, 3790, 3909, 3751, 3863, - 4280, 4076, 3927, 11137, 11570, 10976, 14389, 14840, 14580, 14886, 15098, 15112, 14201, - 14129, 14157, 14886, 15112, 15015, 20499, 20481, 20537, 26737, 26478, 26409, 27617, 27909, - 27863, 35514, 35618, 35428, 36327, 36299, 36073, 35514, 35428, 35345, 34875, 35183, 35207, - 34833, 34899, 34875, 34851, 34899, 34833, 34418, 34208, 34658, 31415, 31387, 31206, 32230, - 31795, 31495, 38015, 37889, 38048, 3219, 3186, 3382, 3053, 2952, 3328, 3135, 3186, - 3219, 3220, 3302, 3254, 27269, 27283, 27132, 39632, 39829, 39499, 39869, 39829, 39926, - 39595, 39244, 39450, 6619, 6470, 6565, 5623, 5750, 5686, 6713, 6626, 6619, 6751, - 6678, 6713, 6678, 6897, 6664, 34658, 34208, 34670, 2948, 2952, 3053, 15188, 15364, - 15410, 14473, 14934, 14840, 14389, 14417, 14095, 20481, 20229, 20381, 26409, 26289, 26170, - 37179, 37252, 37018, 36627, 36464, 36355, 2376, 2651, 2359, 2020, 2240, 2260, 2260, - 2240, 2367, 10793, 11137, 10976, 10579, 10763, 10666, 22412, 22351, 22454, 22588, 22570, - 22463, 21863, 21785, 22004, 30758, 30381, 30508, 30241, 30381, 30026, 29746, 29536, 29730, - 29326, 29336, 29536, 30999, 30381, 30758, 31043, 30758, 30916, 30771, 30451, 30609, 38444, - 38368, 38528, 2209, 2190, 2292, 5838, 5750, 6009, 6173, 6322, 6042, 6897, 6795, - 6894, 17095, 17008, 16952, 17892, 17988, 18071, 35029, 35035, 35138, 36656, 36627, 36355, - 29326, 29193, 29336, 29326, 29536, 29511, 29287, 29553, 29419, 29014, 28969, 28735, 29014, - 28735, 28918, 39161, 39062, 39060, 39060, 39062, 38934, 38992, 38892, 38834, 39161, 39056, - 39148, 3254, 3302, 3313, 13948, 13180, 13800, 14261, 14129, 14201, 27389, 27506, 27425, - 2190, 2167, 2278, 20229, 20068, 20157, 5888, 6063, 5985, 7565, 7526, 7665, 7665, - 7690, 7727, 7074, 7179, 7019, 15425, 15188, 15410, 26307, 26409, 26170, 36073, 36277, - 36057, 36299, 36277, 36073, 20097, 20249, 20290, 22004, 21785, 21247, 19872, 19990, 19711, - 19872, 19711, 19846, 19711, 19747, 19846, 19704, 19747, 19711, 4112, 4271, 4203, 30451, - 30657, 30430, 38319, 38057, 38069, 28918, 28735, 28576, 7526, 7690, 7665, 15817, 15809, - 16141, 22463, 22570, 22419, 22463, 22351, 22412, 35850, 35644, 35705, 35705, 35644, 35560, - 35560, 35561, 35234, 34450, 34097, 34113, 35850, 35705, 35831, 35850, 35831, 35927, 35949, - 36008, 35927, 38156, 38056, 38351, 38156, 38058, 38056, 40965, 40966, 40818, 40978, 40980, - 40427, 40821, 40944, 40704, 40838, 41000, 40843, 40965, 40818, 40812, 40965, 40812, 40961, - 40812, 40810, 40961, 40810, 40960, 40961, 40809, 40960, 40810, 40983, 40960, 40809, 16585, - 16680, 16351, 40532, 40524, 40405, 40301, 40346, 40165, 40595, 40505, 40730, 9901, 9786, - 9919, 9786, 9901, 9871, 37753, 37902, 37661, 37594, 37686, 37563, 37749, 37686, 37594, - 39555, 39450, 39649, 5597, 5443, 5604, 5084, 5115, 5154, 37478, 37537, 37368, 37002, - 36913, 36856, 2167, 2207, 2355, 9786, 9589, 9819, 19704, 19608, 19747, 37366, 37368, - 37252, 40805, 40983, 40809, 7690, 7747, 7727, 15616, 15701, 15711, 16858, 16556, 16702, - 17745, 17953, 18229, 40139, 39681, 39655, 40482, 40594, 40435, 2419, 2405, 2756, 2516, - 2380, 2387, 2375, 2405, 2419, 4271, 4385, 4406, 36435, 36346, 36320, 37314, 36800, - 36747, 36646, 36800, 36781, 40728, 40505, 40638, 26208, 26106, 26183, 26208, 26183, 26375, - 40283, 40139, 39655, 5750, 5597, 5774, 6470, 6576, 6565, 19704, 19424, 19608, 19424, - 19526, 19608, 19460, 19526, 19424, 39321, 39213, 39314, 39321, 39253, 39213, 40843, 40845, - 40591, 40863, 40725, 40601, 41000, 40845, 40843, 6527, 6470, 6619, 36008, 36110, 36079, - 35927, 36008, 36031, 2207, 2176, 2299, 19378, 19460, 19424, 40805, 40803, 40983, 3080, - 3075, 3207, 2943, 3075, 3080, 39829, 39892, 39499, 39869, 39892, 39829, 3271, 3341, - 3344, 3791, 3866, 3860, 28087, 28296, 28309, 26974, 26831, 26804, 37909, 37836, 37823, - 38058, 38015, 38048, 38078, 38015, 38058, 2804, 3145, 3015, 27044, 26831, 26974, 26925, - 26814, 26737, 26737, 26814, 26809, 27269, 27389, 27283, 27283, 27389, 27425, 2176, 2172, - 2280, 19819, 19689, 19778, 27168, 27132, 27038, 27780, 27909, 27617, 41092, 40944, 40821, - 40983, 40803, 40986, 4589, 4740, 4590, 4385, 4415, 4521, 36079, 36110, 36256, 19044, - 18692, 19013, 18953, 18692, 19044, 22695, 22737, 22619, 23432, 23736, 23718, 22695, 22619, - 22481, 5903, 5888, 5985, 5827, 5909, 5734, 5690, 5758, 5684, 37100, 37131, 37113, - 37369, 37131, 37340, 36891, 36602, 36817, 5623, 5597, 5750, 4589, 4590, 4467, 9153, - 8929, 8950, 7397, 8115, 7333, 15809, 15701, 15818, 15607, 15701, 15616, 19689, 19586, - 19778, 19329, 19378, 19424, 26106, 25815, 25939, 26208, 25815, 26106, 33028, 33128, 33097, - 34070, 34187, 34147, 33024, 32911, 33006, 36817, 36602, 36627, 38992, 38834, 39003, 39063, - 39003, 39062, 17821, 17988, 17892, 17821, 17892, 17684, 40863, 40600, 40720, 3153, 3254, - 3313, 3220, 3135, 3219, 3186, 3011, 3053, 3311, 3387, 3335, 3064, 3049, 3153, - 29338, 29287, 29217, 29338, 29553, 29287, 30451, 30771, 30657, 29338, 29217, 29187, 6470, - 6324, 6576, 5949, 5745, 5905, 19586, 19534, 19455, 19329, 19176, 19378, 40845, 40846, - 40715, 41096, 40846, 40845, 28309, 28296, 28542, 29746, 29997, 30026, 29148, 29217, 29014, - 39178, 39063, 39062, 38788, 38679, 38704, 38788, 38704, 38661, 38788, 38661, 38864, 10549, - 10431, 10386, 10825, 11091, 10723, 15188, 15015, 15112, 14513, 14691, 14625, 14513, 14297, - 14554, 15607, 15425, 15552, 26066, 26255, 26170, 26409, 26508, 26737, 26255, 26066, 25952, - 6715, 7074, 6711, 5734, 5866, 5758, 8510, 8609, 8583, 8626, 8712, 8779, 8220, - 8310, 8227, 36646, 36465, 36577, 36646, 36577, 36800, 3311, 3064, 3153, 19378, 19176, - 19110, 28045, 27909, 27780, 31508, 31387, 31415, 30644, 29746, 30026, 32575, 31784, 31795, - 32925, 32569, 32911, 31648, 31640, 31379, 36256, 36110, 36240, 37865, 37703, 37686, 37885, - 37902, 37753, 37865, 37686, 37795, 39926, 39829, 39632, 39541, 39308, 39373, 39253, 39161, - 39148, 39440, 39161, 39253, 2359, 2651, 2679, 19034, 18661, 18998, 17684, 17666, 17570, - 40725, 40727, 40638, 40734, 40524, 40532, 40867, 40727, 40725, 33999, 33883, 33346, 32158, - 31980, 31768, 36891, 37002, 36856, 37369, 37366, 37252, 37080, 37002, 36891, 40846, 40852, - 40718, 40909, 40852, 41024, 40684, 40777, 40686, 40792, 40940, 40636, 40898, 40777, 40684, - 40915, 40777, 41020, 18779, 18661, 19034, 20249, 21247, 20290, 2688, 2734, 3038, 2672, - 2613, 2745, 2246, 2606, 2473, 5384, 5335, 5443, 5443, 5335, 5525, 4992, 4546, - 4901, 40204, 40211, 40062, 40388, 40346, 40487, 40361, 40346, 40388, 2973, 2994, 3065, - 3271, 3374, 3341, 2891, 2994, 2973, 7747, 8180, 8356, 36403, 36256, 36240, 16278, - 16399, 16351, 17614, 17684, 17570, 16239, 16399, 16278, 15642, 15763, 15555, 28950, 28918, - 28576, 39078, 39217, 39064, 40475, 40496, 40482, 40329, 40462, 40177, 2516, 2734, 2688, - 4467, 4590, 4489, 15536, 15642, 15555, 40361, 40211, 40188, 39452, 39314, 39507, 3117, - 3220, 3254, 3117, 3135, 3220, 2717, 2709, 2961, 6099, 6063, 5888, 5690, 5734, - 5758, 5690, 5684, 5630, 8534, 8702, 8609, 8609, 8702, 8626, 14129, 14066, 13948, - 14850, 14625, 14886, 36543, 36346, 36435, 37356, 36946, 37385, 2231, 2158, 2624, 1994, - 1754, 1737, 2068, 2152, 2420, 2257, 2049, 2156, 7526, 7581, 7690, 7690, 7649, - 7747, 7747, 7658, 8180, 6711, 7074, 7019, 5869, 5888, 5827, 15026, 15015, 15188, - 3341, 3374, 3430, 3189, 3366, 3148, 39429, 39373, 39159, 18225, 17745, 18229, 15817, - 16141, 16233, 22737, 23070, 23033, 25041, 25086, 24888, 26390, 26307, 26255, 23000, 23070, - 22737, 40727, 40728, 40638, 40872, 40728, 40727, 5084, 5154, 5201, 8180, 8220, 8227, - 8191, 8220, 8180, 33212, 33231, 33128, 36277, 36372, 36355, 35618, 35714, 35428, 5181, - 5084, 5201, 3148, 3366, 2976, 31640, 31766, 31632, 31649, 31766, 31640, 31768, 31766, - 31881, 2152, 2162, 2269, 39783, 39471, 39740, 41001, 40940, 40792, 6795, 6678, 6751, - 6470, 6423, 6324, 6897, 6678, 6795, 8333, 8508, 8485, 2734, 2804, 3015, 26814, - 27010, 27038, 27678, 27617, 27506, 26255, 26307, 26170, 26508, 26307, 26390, 6678, 6626, - 6713, 6042, 5948, 6173, 6715, 7581, 7526, 35597, 35345, 35207, 35183, 34875, 34899, - 35183, 34899, 35151, 34899, 35029, 35151, 5640, 5690, 5630, 5734, 5869, 5827, 8702, - 8712, 8626, 12034, 11793, 11815, 8534, 8712, 8702, 4498, 4027, 4076, 3674, 3647, - 3802, 4173, 4112, 4203, 4271, 4306, 4385, 4374, 4489, 4415, 4374, 4467, 4489, - 3934, 3983, 4153, 3860, 3866, 3934, 3985, 3826, 3405, 5335, 5226, 5201, 5181, - 5226, 5335, 5384, 5443, 5340, 10935, 11091, 11280, 11526, 11406, 11423, 11640, 11739, - 11681, 11739, 11788, 11681, 11483, 11793, 11570, 13578, 13374, 13272, 10579, 10123, 10118, - 23070, 23168, 23212, 23121, 23168, 23070, 37478, 37366, 37419, 37202, 37100, 37002, 4498, - 4532, 4027, 3866, 3983, 3934, 9822, 10036, 9677, 11640, 11523, 11695, 38715, 38661, - 38517, 38286, 38319, 38069, 38406, 38319, 38415, 38715, 38517, 38444, 39204, 39361, 39217, - 19279, 19141, 19262, 18692, 18526, 18368, 18779, 18410, 18661, 22463, 22412, 22521, 22463, - 22521, 22588, 39068, 38992, 39003, 38579, 38301, 38418, 39068, 39003, 39063, 39068, 39063, - 39178, 40139, 40329, 39681, 40258, 40329, 40139, 3946, 4076, 3989, 3983, 3996, 4173, - 6042, 6322, 6324, 8438, 8485, 8623, 16399, 16585, 16351, 16199, 16004, 15908, 17570, - 17421, 17460, 18661, 18410, 18451, 23736, 23902, 23718, 36697, 36435, 36536, 36299, 36372, - 36277, 36371, 36372, 36299, 40728, 40730, 40505, 40874, 40730, 40728, 7581, 7649, 7690, - 28087, 27991, 28055, 28174, 27991, 28087, 27909, 28045, 27977, 27503, 27506, 27389, 39178, - 39062, 39161, 39361, 39429, 39217, 39217, 39429, 39064, 3996, 4112, 4173, 15026, 14920, - 15015, 15701, 15607, 15552, 16334, 16442, 16556, 38730, 38715, 38444, 39595, 39555, 39720, - 39632, 39595, 39720, 40057, 39499, 39892, 40352, 40258, 40139, 19141, 19026, 19044, 18071, - 18358, 18410, 22125, 22433, 22121, 2953, 3011, 3186, 2233, 2562, 2376, 27612, 27181, - 27742, 26831, 26866, 26714, 26925, 27010, 26814, 3135, 3032, 3186, 2996, 3032, 3135, - 3117, 3254, 3153, 12753, 12889, 12155, 14934, 15141, 15227, 27168, 27269, 27132, 39503, - 40133, 40107, 39720, 39555, 39765, 3674, 3802, 3751, 17224, 17013, 17063, 2233, 2305, - 2562, 2679, 2732, 2384, 15015, 14920, 14886, 15026, 15188, 15176, 20769, 20674, 20685, - 20499, 20586, 20481, 20481, 20244, 20229, 20229, 20203, 20068, 20068, 19819, 19918, 19689, - 19678, 19586, 19595, 19439, 19534, 19534, 19439, 19393, 19141, 19127, 19026, 20983, 21047, - 21440, 5460, 5443, 5597, 9017, 9104, 8928, 20674, 20586, 20499, 40978, 40427, 40818, - 40978, 40818, 40975, 40818, 40966, 40975, 40966, 40974, 40975, 40972, 40974, 40966, 5518, - 5640, 5630, 4306, 4415, 4385, 38015, 37997, 37909, 38351, 38056, 38301, 3153, 3313, - 3311, 8929, 8781, 8950, 8821, 8781, 8929, 8756, 8781, 8821, 9645, 9589, 9786, - 14261, 14066, 14129, 14189, 14066, 14261, 21440, 21268, 21642, 36879, 36817, 36627, 20392, - 20244, 20481, 19997, 20249, 20097, 22273, 22448, 22433, 20036, 20249, 19997, 20036, 19997, - 19964, 19997, 19872, 19964, 19872, 19810, 19964, 19846, 19810, 19872, 19747, 19810, 19846, - 19774, 19810, 19747, 19774, 19747, 19664, 19747, 19608, 19664, 2405, 2366, 2473, 2386, - 2049, 2649, 18071, 17988, 18358, 17460, 17421, 17095, 19015, 18953, 19026, 19026, 18953, - 19044, 22351, 21884, 21915, 23304, 23351, 23469, 40920, 40693, 40648, 40965, 40972, 40966, - 40920, 40648, 40915, 20244, 20203, 20229, 40971, 40972, 40965, 20203, 20084, 20068, 40961, - 40971, 40965, 35927, 36062, 35850, 35829, 35701, 35644, 35644, 35701, 35560, 36132, 36031, - 36008, 36132, 36008, 36079, 36132, 36079, 36314, 16417, 16585, 16399, 15674, 16199, 15908, - 16239, 16199, 16222, 19664, 19608, 19615, 39649, 39450, 39541, 40909, 40863, 40720, 40909, - 40720, 40852, 40867, 40863, 40902, 40961, 41078, 40971, 40961, 41156, 41078, 40915, 40611, - 40777, 2167, 2069, 2207, 2207, 2108, 2176, 2176, 2106, 2172, 2172, 2106, 2280, - 2152, 2085, 2162, 2048, 2069, 2167, 2048, 2167, 2190, 2048, 2190, 1968, 2190, - 1839, 1968, 5631, 5869, 5734, 5640, 5734, 5690, 8220, 8510, 8583, 8928, 9104, - 9027, 8473, 8510, 8466, 19615, 19608, 19526, 40800, 40986, 40803, 16616, 16608, 16556, - 16480, 16608, 16616, 16417, 16399, 16239, 25014, 25140, 24842, 25281, 25140, 25187, 25281, - 25187, 25815, 31554, 31387, 31508, 31554, 31508, 31611, 38156, 38078, 38058, 38344, 38078, - 38156, 40462, 40496, 40475, 40589, 40496, 40634, 40482, 40496, 40589, 2069, 2108, 2207, - 6099, 6153, 6063, 33883, 34187, 34070, 33999, 34187, 33883, 36314, 36079, 36256, 36756, - 36879, 36627, 36063, 35940, 35714, 40800, 40940, 40986, 2847, 3328, 2952, 2384, 2732, - 2572, 17988, 17847, 18358, 17390, 17460, 17095, 10935, 11280, 11390, 9975, 10160, 9964, - 38319, 38406, 38218, 38069, 37941, 38224, 20084, 19819, 20068, 19512, 19615, 19526, 22560, - 22695, 22481, 23941, 24213, 23902, 22560, 22481, 22433, 3374, 3322, 3430, 3110, 3271, - 3344, 3110, 3344, 3189, 3366, 3075, 2976, 39665, 39649, 39721, 39719, 39649, 39665, - 39869, 40043, 39892, 40011, 40043, 39869, 40011, 39869, 39996, 3011, 2948, 3053, 2805, - 2948, 3011, 2953, 3186, 3032, 10160, 10075, 9964, 14920, 14850, 14886, 14827, 14850, - 14920, 14743, 14850, 14710, 19460, 19512, 19526, 26919, 26866, 26831, 26919, 26831, 27044, - 27168, 27401, 27269, 27269, 27401, 27389, 27168, 27038, 27010, 31969, 32158, 31768, 33024, - 33212, 33128, 31379, 31065, 31356, 3849, 3725, 3909, 3927, 3858, 3849, 3805, 3858, - 3891, 3946, 3927, 4076, 11523, 11406, 11526, 11739, 11640, 11695, 12339, 12892, 12685, - 28490, 28440, 27977, 28918, 29148, 29014, 29338, 29187, 29553, 31649, 31648, 31634, 28490, - 27977, 28045, 4104, 4271, 4112, 4123, 4306, 4271, 4049, 4112, 3996, 3866, 3876, - 3983, 3405, 3826, 3476, 8510, 8534, 8609, 8473, 8534, 8510, 10323, 10317, 10431, - 11640, 11406, 11523, 37926, 37836, 37909, 36646, 36697, 36536, 36302, 36062, 36132, 37691, - 37551, 37537, 37885, 37865, 38032, 16827, 16952, 16823, 39097, 39082, 38679, 39151, 39082, - 39097, 39078, 39082, 39151, 19378, 19482, 19460, 19460, 19482, 19512, 2780, 2847, 2952, - 2943, 3080, 2994, 10623, 10430, 10549, 10323, 10430, 10544, 15081, 15141, 14473, 17821, - 17742, 17988, 26307, 26508, 26409, 25880, 25379, 25952, 27991, 27612, 27938, 28132, 27612, - 27991, 27503, 27678, 27506, 38406, 38528, 38368, 38030, 37941, 37902, 39872, 39783, 39740, - 39440, 39178, 39161, 39990, 39783, 39872, 40986, 41073, 41074, 40898, 41168, 41059, 40211, - 40446, 40062, 40346, 40361, 40188, 40614, 40405, 40524, 40564, 40595, 40733, 2375, 2366, - 2405, 2605, 2804, 2734, 2646, 3082, 2804, 2252, 2366, 2375, 2050, 2260, 2162, - 23902, 24213, 24014, 23239, 23212, 23432, 30451, 30364, 30609, 38078, 37997, 38015, 37995, - 37997, 38089, 37983, 38030, 37902, 32911, 32569, 32809, 38856, 38723, 38867, 39068, 39198, - 38992, 39452, 39253, 39321, 34899, 34851, 35029, 35618, 36063, 35714, 2038, 2106, 2176, - 1994, 2074, 2158, 2159, 2233, 2376, 7589, 8115, 7636, 6505, 6527, 6626, 6626, - 6527, 6619, 8333, 8147, 8315, 8255, 8147, 8333, 19378, 19396, 19482, 22124, 21884, - 22351, 35183, 35241, 35207, 40863, 40867, 40725, 40872, 40867, 40902, 37573, 37356, 37385, - 7298, 7333, 7424, 37067, 36781, 36800, 2158, 2074, 2624, 2155, 2560, 2305, 2106, - 2068, 2280, 19378, 19110, 19396, 28950, 29148, 28918, 40792, 40924, 41001, 1806, 2155, - 2305, 26334, 26208, 26375, 35597, 35514, 35345, 39719, 39765, 39555, 39719, 39555, 39649, - 35829, 35644, 35850, 32881, 33209, 32677, 36062, 35927, 36031, 36062, 36031, 36132, 36366, - 36371, 36299, 37691, 37537, 37623, 36327, 36073, 36158, 38178, 38224, 37941, 38502, 38461, - 38406, 16952, 16934, 17095, 17821, 17684, 17742, 16772, 16827, 16823, 16772, 16823, 16585, - 16417, 16239, 16222, 19595, 19534, 19586, 17224, 17199, 17745, 16480, 16334, 16608, 19396, - 19110, 19126, 20686, 22004, 21247, 40733, 40892, 40866, 40589, 40594, 40482, 40440, 40462, - 40329, 40440, 40329, 40660, 41001, 40924, 41004, 40867, 40872, 40727, 40874, 40872, 40890, - 2310, 2384, 2572, 2359, 2159, 2376, 6664, 6626, 6678, 5686, 5750, 5838, 7649, - 7648, 7747, 7581, 7542, 7649, 7512, 7542, 7581, 7543, 7542, 7512, 12584, 12753, - 12155, 15355, 15536, 15141, 12034, 12155, 11793, 28770, 28576, 28599, 28770, 28950, 28576, - 39204, 39217, 39078, 2996, 2953, 3032, 2727, 2717, 2847, 3094, 3135, 3117, 14547, - 14513, 14625, 14066, 13910, 13948, 14743, 14625, 14850, 27401, 27503, 27389, 27678, 27780, - 27617, 27143, 27168, 27010, 4104, 4112, 4049, 5518, 5630, 4420, 22695, 23000, 22737, - 22718, 23000, 22695, 33155, 33212, 33024, 32809, 32569, 32330, 40316, 40329, 40258, 2646, - 2891, 2973, 2605, 2734, 2472, 15375, 15425, 15607, 26538, 26334, 26375, 27121, 26919, - 27044, 26688, 26925, 26737, 40043, 40057, 39892, 40289, 40057, 40216, 19126, 19110, 18998, - 37997, 37926, 37909, 37573, 37344, 37356, 37995, 37926, 37997, 38252, 38268, 38224, 37865, - 37885, 37753, 37080, 36891, 36817, 7542, 7648, 7649, 14513, 14189, 14261, 27572, 27503, - 27401, 16608, 16334, 16556, 17224, 17745, 17533, 16222, 16199, 16266, 25193, 25255, 25217, - 22570, 22588, 22781, 5230, 5181, 5335, 5226, 5181, 5201, 5084, 4926, 4945, 5745, - 5949, 5948, 5367, 4589, 4420, 5869, 6099, 5888, 8781, 8756, 8623, 8821, 8929, - 9035, 15817, 15701, 15809, 36427, 36355, 36372, 40361, 40385, 40211, 40446, 40385, 40536, - 40403, 40316, 40258, 15375, 15188, 15425, 26508, 26688, 26737, 26390, 26688, 26508, 36371, - 36427, 36372, 36523, 36427, 36521, 5230, 5335, 5384, 4027, 4532, 4134, 2068, 2085, - 2152, 19439, 19279, 19393, 6527, 6423, 6470, 39507, 39223, 39568, 3064, 2911, 3019, - 3583, 3729, 3647, 27604, 27780, 27678, 2366, 2358, 2473, 2386, 2383, 2018, 23259, - 23212, 23168, 25086, 25379, 24888, 31387, 31539, 30976, 33720, 33783, 33812, 19016, 19126, - 18998, 17684, 17558, 17742, 4306, 4374, 4415, 38723, 38892, 38867, 16827, 16934, 16952, - 16614, 16772, 16585, 40614, 40605, 40368, 40917, 40605, 40614, 2300, 2358, 2366, 18781, - 18692, 18953, 40876, 40595, 40730, 2511, 2515, 2961, 2847, 2717, 2961, 2780, 2952, - 2948, 15279, 15375, 15607, 26781, 26714, 26866, 25193, 25281, 25255, 3692, 3725, 3849, - 3805, 3849, 3858, 4532, 4425, 4134, 36314, 36256, 36403, 35989, 36063, 35618, 38867, - 39073, 38984, 39193, 39068, 39178, 7424, 7333, 8115, 8547, 8438, 8623, 6032, 6099, - 5687, 4409, 4589, 4467, 8756, 8547, 8623, 9153, 9882, 9589, 33155, 33024, 33006, - 3725, 3674, 3751, 4546, 4992, 4749, 39256, 39193, 39315, 39649, 39541, 39721, 39926, - 39632, 39930, 28433, 28490, 28045, 39568, 39223, 39430, 39256, 39198, 39193, 40487, 40346, - 40301, 19016, 18998, 18931, 17684, 17614, 17558, 37478, 37368, 37366, 16334, 16284, 16233, - 15279, 15176, 15375, 16418, 16284, 16334, 16417, 16466, 16585, 15674, 15908, 15642, 19279, - 19127, 19141, 18998, 18661, 18931, 36063, 36083, 36158, 37749, 37795, 37686, 38178, 37941, - 38030, 2257, 2293, 2419, 2156, 2293, 2257, 10430, 10323, 10431, 9871, 9747, 9786, - 9602, 9153, 9589, 10544, 10430, 10623, 23736, 23847, 23902, 23874, 23847, 23736, 37983, - 37902, 37885, 38224, 38268, 38069, 40872, 40874, 40728, 41000, 40838, 41094, 3674, 3583, - 3647, 4306, 4322, 4374, 3876, 3996, 3983, 29098, 29187, 29148, 29148, 29187, 29217, - 29098, 29148, 28950, 39721, 39541, 39429, 39151, 39204, 39078, 39097, 38788, 38864, 37369, - 37179, 37131, 3110, 3322, 3271, 3271, 3322, 3374, 2943, 2976, 3075, 2943, 2994, - 2891, 39679, 40036, 40133, 39503, 39679, 40133, 39693, 39568, 39430, 40283, 40352, 40139, - 39632, 39720, 39930, 10075, 10160, 10317, 31648, 31649, 31640, 33003, 33006, 32911, 33003, - 33155, 33006, 31356, 31065, 30657, 37385, 37220, 37688, 38089, 37997, 38078, 38043, 37983, - 37885, 36767, 36697, 36646, 36767, 36646, 36781, 37344, 36946, 37356, 36879, 37080, 36817, - 36427, 36656, 36355, 36523, 36656, 36427, 40733, 40734, 40532, 40605, 40487, 40301, 40866, - 40734, 40733, 2805, 2780, 2948, 2939, 3011, 2953, 19127, 19015, 19026, 18702, 18661, - 18451, 22463, 22419, 22351, 24244, 23545, 23833, 26880, 26781, 26866, 26880, 26866, 26919, - 41094, 40838, 40944, 41004, 40924, 40920, 41004, 40920, 41062, 40898, 40219, 41168, 40634, - 40496, 40462, 40594, 40589, 40669, 3153, 3094, 3117, 3049, 3094, 3153, 14189, 14133, - 14066, 14182, 14133, 14189, 14182, 14189, 14513, 14547, 14625, 14743, 14547, 14743, 14612, - 39930, 39720, 39939, 23129, 23259, 23168, 23121, 23070, 23000, 38461, 38528, 38406, 41024, - 40852, 41169, 40673, 40490, 40594, 33003, 32911, 33016, 33433, 33999, 33346, 36996, 37080, - 36879, 3283, 3322, 3262, 3799, 3876, 3866, 39440, 39253, 39452, 39693, 39430, 39783, - 20244, 20150, 20203, 20203, 20150, 20084, 19820, 19744, 19819, 19819, 19744, 19689, 19439, - 19498, 19279, 18902, 19015, 19127, 18902, 18845, 19015, 20586, 20392, 20481, 20448, 20392, - 20586, 20448, 20586, 20674, 20448, 20674, 20566, 21768, 21642, 21884, 37220, 37836, 37688, - 37304, 37131, 37100, 15375, 15176, 15188, 15279, 15607, 15386, 23847, 23941, 23902, 23874, - 23941, 23847, 26970, 27143, 26925, 26925, 27143, 27010, 27381, 27572, 27401, 27503, 27572, - 27678, 24888, 24347, 24348, 40883, 40876, 40874, 40874, 40876, 40730, 41176, 41092, 40821, - 40978, 41084, 40980, 41083, 41084, 40978, 41083, 40978, 40975, 41083, 40975, 40974, 41083, - 40974, 41080, 40974, 40972, 41080, 40972, 41079, 41080, 40971, 41079, 40972, 38145, 38178, - 38030, 38415, 38319, 38286, 41062, 40920, 40915, 40971, 41078, 41079, 6187, 6042, 6324, - 6197, 6317, 6532, 5563, 5734, 5640, 36403, 36240, 36346, 8636, 8547, 8756, 7424, - 8115, 7589, 8636, 8756, 8821, 16106, 15817, 16233, 28910, 28770, 28848, 28667, 28770, - 28599, 36419, 36403, 36346, 37067, 36767, 36781, 38415, 38286, 38268, 40629, 40487, 40741, - 40133, 40036, 40432, 41156, 40961, 41175, 2069, 2048, 2108, 2108, 2038, 2176, 2106, - 1985, 2068, 2068, 1943, 2085, 1839, 2209, 2208, 40983, 41076, 40960, 38130, 38145, - 37983, 37983, 38145, 38030, 37691, 37749, 37594, 37825, 37749, 37853, 37623, 37537, 37478, - 40734, 40737, 40524, 40856, 40737, 40734, 24220, 24244, 23833, 21936, 21768, 21884, 22448, - 22560, 22433, 31781, 31881, 31766, 31781, 31766, 31649, 2074, 2039, 2639, 1905, 2039, - 2074, 5181, 5004, 5084, 4926, 5004, 4974, 5460, 5597, 5623, 37632, 37623, 37478, - 40983, 40986, 41076, 2516, 2688, 2613, 6706, 6664, 6897, 6527, 6399, 6423, 6423, - 6305, 6324, 7333, 7218, 7132, 8315, 7636, 8115, 15141, 15536, 15457, 15355, 15141, - 15081, 25220, 25086, 25041, 35740, 35561, 35701, 35701, 35561, 35560, 35829, 35850, 35953, - 35241, 35597, 35207, 35514, 35696, 35618, 36063, 36115, 36083, 35536, 35597, 35241, 35468, - 35241, 35183, 34851, 34658, 35029, 33433, 33231, 33212, 35953, 35850, 36062, 36543, 36435, - 36697, 3891, 3858, 3927, 3725, 3561, 3674, 3674, 3561, 3583, 3891, 3927, 3946, - 3891, 3946, 3989, 10886, 10935, 11390, 11640, 11681, 11406, 12685, 12892, 13120, 33373, - 33433, 33212, 32809, 32330, 32460, 37369, 37419, 37366, 37080, 37202, 37002, 37133, 37202, - 37080, 39509, 39452, 39507, 39918, 40201, 40082, 39973, 39930, 39939, 39721, 39429, 39928, - 41076, 40986, 41074, 3989, 4076, 4027, 3900, 3876, 3799, 6893, 7076, 7132, 8255, - 8333, 8306, 35597, 35696, 35514, 36521, 36427, 36371, 38856, 38845, 38407, 38351, 38344, - 38156, 38867, 38892, 39073, 39198, 39068, 39193, 3683, 3692, 3849, 2926, 2996, 3094, - 3051, 3189, 3148, 2850, 2943, 2891, 14710, 14850, 14827, 27612, 27121, 27044, 27047, - 27121, 27250, 26970, 26925, 26688, 28667, 28599, 28490, 39918, 39666, 39693, 40211, 40385, - 40446, 38252, 38224, 38178, 38430, 38415, 38268, 3855, 3989, 4027, 38873, 38845, 38856, - 3094, 2996, 3135, 2939, 2737, 2789, 9781, 9747, 9871, 10323, 10075, 10317, 9950, - 10075, 10040, 38043, 37885, 38032, 40289, 40283, 40057, 40634, 40462, 40663, 39926, 39996, - 39869, 39973, 39996, 39926, 2048, 2038, 2108, 2191, 2252, 2293, 11483, 11570, 11137, - 13272, 13374, 13195, 19718, 19664, 19615, 19718, 19774, 19664, 19718, 19803, 19774, 19774, - 19803, 19810, 19810, 19803, 19964, 19964, 20045, 20036, 20036, 20045, 20249, 22273, 22125, - 22004, 22273, 22433, 22125, 19718, 19615, 19618, 19615, 19512, 19446, 19512, 19482, 19446, - 19482, 19396, 19446, 39626, 39507, 39568, 38537, 38528, 38461, 38710, 38444, 38528, 39097, - 38679, 38788, 39730, 39429, 39361, 6664, 6505, 6626, 18845, 18953, 19015, 18845, 18781, - 18953, 22560, 22718, 22695, 23259, 23432, 23212, 22759, 22718, 22560, 26781, 26538, 26375, - 26240, 25815, 26208, 27047, 26880, 26919, 37434, 37419, 37369, 25088, 24842, 25140, 23476, - 23432, 23259, 23941, 24324, 24213, 40909, 40902, 40863, 40892, 40733, 40595, 41100, 40902, - 40909, 4104, 4123, 4271, 3833, 4049, 3996, 8306, 8333, 8438, 19820, 19819, 20084, - 19446, 19396, 19148, 7542, 7543, 7648, 7648, 7658, 7747, 7538, 7543, 7512, 35740, - 35829, 35842, 39720, 39765, 39939, 16870, 16934, 16827, 16870, 16827, 16772, 16466, 16417, - 16266, 26681, 26538, 26781, 25281, 25193, 25140, 40669, 40673, 40594, 40634, 40663, 40668, - 15817, 15711, 15701, 14827, 14920, 15026, 15678, 15711, 15817, 16106, 16233, 16284, 19744, - 19678, 19689, 22124, 22351, 22159, 19148, 19396, 19126, 18668, 18702, 18451, 18668, 18451, - 18398, 4077, 4123, 4104, 4374, 4409, 4467, 6505, 6399, 6527, 7543, 7658, 7648, - 11303, 11390, 11406, 30013, 29589, 29553, 30013, 29553, 29947, 2293, 2252, 2375, 2516, - 2613, 2380, 2383, 2240, 2018, 4373, 4409, 4374, 13867, 13180, 13948, 13910, 14066, - 14133, 17100, 16480, 16616, 16334, 16480, 16418, 16266, 16417, 16222, 26240, 26208, 26334, - 29061, 29098, 28950, 28910, 28950, 28770, 38283, 38252, 38178, 38502, 38537, 38461, 39666, - 39626, 39568, 39618, 39626, 39741, 40660, 40329, 40316, 9104, 9039, 9677, 11222, 11483, - 11137, 8928, 9027, 8712, 8473, 8712, 8534, 37344, 37298, 36946, 36625, 36543, 36697, - 37314, 37298, 37499, 37202, 37304, 37100, 37248, 37304, 37202, 36756, 36627, 36656, 2038, - 1985, 2106, 9950, 9871, 9964, 19678, 19595, 19586, 41176, 40530, 41290, 41169, 40852, - 40846, 7214, 7298, 7424, 8467, 8306, 8438, 8467, 8438, 8547, 35953, 36182, 36064, - 36625, 36697, 36794, 36188, 36158, 36083, 2717, 2615, 2709, 2548, 2615, 2717, 2727, - 2847, 2780, 6399, 6305, 6423, 5671, 5745, 5695, 35828, 35989, 35618, 40283, 39655, - 40057, 30920, 30026, 30381, 28309, 28542, 28634, 33812, 33783, 34283, 31881, 31969, 31768, - 32014, 31781, 32015, 38145, 38161, 38178, 38032, 37865, 37795, 38130, 38043, 38052, 37715, - 37691, 37623, 37632, 37478, 37587, 10935, 10723, 11091, 10075, 9950, 9964, 38640, 38579, - 38418, 37959, 37836, 37926, 38502, 38406, 38415, 40986, 40940, 41073, 40940, 41001, 41073, - 13180, 12685, 13120, 28667, 28490, 28573, 17558, 17614, 17460, 16757, 16870, 16772, 1994, - 2158, 1754, 1829, 1784, 1795, 2135, 2305, 2233, 2996, 2939, 2953, 3335, 2911, - 3064, 19148, 19126, 19016, 41092, 41094, 40944, 41073, 41001, 41144, 2135, 2159, 2045, - 2159, 2359, 2045, 2252, 2300, 2366, 2215, 2300, 2252, 14371, 14182, 14513, 15260, - 15026, 15176, 26743, 26970, 26688, 28433, 28045, 28335, 26417, 26688, 26390, 2511, 2961, - 2709, 5745, 5948, 5695, 13272, 13195, 12753, 28542, 29193, 29301, 36794, 36697, 36767, - 36358, 36314, 36403, 38447, 38502, 38415, 38217, 38161, 38145, 39939, 39765, 39719, 39482, - 39361, 39204, 14371, 14513, 14547, 4204, 4322, 4306, 10723, 10544, 10623, 22718, 23014, - 23000, 23906, 23874, 23736, 22759, 23014, 22718, 38430, 38268, 38252, 41030, 41020, 40777, - 41030, 40777, 40898, 15536, 15674, 15642, 16466, 16614, 16585, 15355, 15674, 15536, 25699, - 25952, 25379, 5448, 5460, 5623, 2621, 2727, 2780, 2478, 2511, 2709, 5340, 5230, - 5384, 4749, 4992, 4945, 6305, 6187, 6324, 9602, 9589, 9645, 22159, 22419, 22392, - 22159, 22351, 22419, 26538, 26467, 26334, 26880, 26681, 26781, 26984, 26681, 26880, 27047, - 26919, 27121, 36115, 36188, 36083, 37304, 37340, 37131, 37375, 37340, 37304, 28433, 28441, - 28573, 39618, 39509, 39507, 39618, 39507, 39626, 30025, 30013, 29947, 29947, 29553, 29916, - 29061, 28950, 28910, 3530, 3599, 2911, 3667, 3561, 3725, 3805, 3683, 3849, 3680, - 3683, 3805, 3767, 3805, 3891, 11918, 11739, 12339, 11681, 11591, 11406, 10606, 10567, - 10723, 10723, 10567, 10544, 31539, 31387, 31554, 39928, 39665, 39721, 38864, 38661, 38715, - 38710, 38528, 38537, 3876, 3900, 3996, 4049, 4077, 4104, 4123, 4204, 4306, 3799, - 3866, 3699, 38835, 38640, 38418, 38867, 38873, 38856, 38984, 38873, 38867, 38892, 38992, - 39170, 22392, 22419, 22541, 31898, 31969, 31881, 31898, 31881, 31781, 2050, 2162, 2085, - 17558, 17460, 17390, 18931, 19148, 19016, 40902, 40890, 40872, 40737, 40854, 40614, 41042, - 40890, 41101, 6187, 6086, 6042, 23014, 23121, 23000, 23076, 23121, 23014, 36779, 36756, - 36656, 36188, 36327, 36158, 5745, 5686, 5838, 5575, 5686, 5671, 8466, 8510, 8191, - 15549, 15607, 15616, 15260, 15279, 15221, 36779, 36656, 36523, 3667, 3725, 3692, 41059, - 41030, 40898, 40668, 40669, 40589, 40668, 40589, 40634, 37959, 37926, 37995, 36614, 36543, - 36625, 37587, 37478, 37419, 38043, 38130, 37983, 38579, 38344, 38351, 38825, 38344, 38579, - 38711, 38710, 38537, 38345, 38430, 38252, 38283, 38178, 38161, 40879, 40595, 40876, 3322, - 3283, 3476, 2972, 3148, 2976, 3833, 4077, 4049, 28877, 29061, 28910, 28573, 28564, - 28649, 32014, 31898, 31781, 30364, 30451, 30200, 4802, 4945, 4926, 3989, 3767, 3891, - 13450, 13670, 13818, 13654, 13670, 13477, 18931, 18661, 18702, 31795, 31743, 31611, 31784, - 31743, 31795, 38200, 38089, 38424, 37825, 37795, 37749, 41144, 41001, 41004, 8678, 8928, - 8712, 9316, 9822, 9677, 7218, 7333, 7298, 6916, 6944, 7132, 6664, 6553, 6505, - 6505, 6371, 6399, 6399, 6169, 6305, 6169, 6077, 6187, 6187, 6077, 6086, 7218, - 7298, 7214, 36327, 36366, 36299, 6944, 6893, 7132, 35597, 35721, 35696, 36150, 36115, - 35989, 35989, 36115, 36063, 36188, 36297, 36327, 36327, 36379, 36366, 34658, 35035, 35029, - 15861, 16266, 16199, 17390, 17095, 16934, 33331, 33212, 33155, 32460, 32159, 32158, 37340, - 37434, 37369, 37375, 37434, 37340, 23121, 23129, 23168, 25086, 25301, 25379, 23076, 23129, - 23121, 41096, 40845, 41000, 41020, 41062, 40915, 40771, 40490, 40673, 38835, 38407, 38845, - 38711, 38537, 38502, 1943, 2050, 2085, 2156, 2191, 2293, 2132, 2191, 2156, 2478, - 2709, 2615, 2789, 2805, 3011, 2789, 3011, 2939, 2943, 2884, 2976, 2850, 2884, - 2943, 6893, 6706, 6897, 8315, 8147, 7636, 14012, 13910, 14133, 11918, 12339, 12088, - 14536, 14371, 14547, 14612, 14743, 14710, 14827, 14612, 14710, 23476, 23736, 23432, 27250, - 27121, 27612, 35066, 35029, 35138, 35066, 35138, 35165, 40107, 40284, 39990, 40385, 40361, - 40536, 40361, 40388, 40536, 40536, 40388, 40629, 33142, 33155, 33003, 6706, 6600, 6664, - 12034, 12584, 12155, 12471, 12584, 12034, 28848, 28770, 28667, 4373, 4411, 4409, 4409, - 4411, 4589, 4373, 4374, 4322, 38412, 38283, 38161, 38430, 38447, 38415, 40798, 40673, - 40669, 40057, 40043, 40216, 40043, 40011, 40199, 40011, 39996, 40199, 40866, 40856, 40734, - 40897, 40856, 40866, 40883, 40874, 40890, 6600, 6553, 6664, 35829, 35740, 35701, 34807, - 34113, 34880, 36419, 36346, 36543, 28174, 28132, 27991, 29301, 29193, 29326, 36614, 36419, - 36543, 37314, 36747, 37298, 22541, 22570, 22688, 22541, 22419, 22570, 20686, 21247, 20249, - 4926, 5084, 5004, 37715, 37749, 37691, 38412, 38345, 38283, 37715, 37623, 37638, 5002, - 5004, 5181, 5159, 5181, 5230, 5340, 5443, 5460, 32317, 32460, 32158, 37499, 37298, - 37344, 38122, 37688, 37836, 2972, 3051, 3148, 5376, 5340, 5460, 9039, 9104, 9017, - 15279, 15260, 15176, 15678, 15616, 15711, 26503, 26467, 26538, 26503, 26538, 26681, 28045, - 28173, 28335, 26201, 26417, 26255, 26558, 26417, 26201, 31969, 32147, 32158, 32006, 31898, - 32014, 32927, 33016, 32911, 32927, 32911, 32809, 37741, 37344, 37573, 38089, 37959, 37995, - 38110, 37959, 38089, 38110, 38089, 38200, 20392, 20150, 20244, 19744, 19710, 19678, 19678, - 19710, 19595, 20566, 20674, 20764, 21683, 21642, 21768, 21683, 21768, 21936, 21884, 22124, - 21936, 28649, 28848, 28667, 28573, 28490, 28433, 41206, 41140, 40980, 41822, 41251, 41094, - 41206, 40980, 41084, 41206, 41084, 41205, 41084, 41083, 41205, 41083, 41191, 41205, 41080, - 41191, 41083, 41079, 41191, 41080, 41150, 41191, 41079, 17390, 16930, 17419, 18668, 18931, - 18702, 41042, 40883, 40890, 41078, 41150, 41079, 2050, 2020, 2260, 5518, 5563, 5640, - 7512, 7581, 7403, 5503, 5563, 5518, 7636, 8147, 7746, 8147, 8255, 8084, 7658, - 7646, 8180, 7543, 7538, 7658, 6032, 6197, 6099, 8663, 8636, 8821, 18451, 18358, - 18398, 21936, 22124, 22031, 22688, 22781, 23206, 36302, 36132, 36314, 36756, 36996, 36879, - 36967, 36996, 36756, 2246, 2473, 2358, 2605, 2598, 2804, 2246, 2358, 2215, 16224, - 16160, 16284, 16106, 16160, 16139, 20307, 20150, 20392, 18902, 19127, 19279, 36442, 36521, - 36371, 36442, 36371, 36366, 41290, 40530, 40980, 41391, 41096, 41000, 41078, 41156, 41150, - 2039, 1921, 2388, 2048, 1910, 2038, 2038, 1957, 1985, 1985, 1943, 2068, 2050, - 1898, 2020, 1595, 1921, 2039, 1839, 2190, 2209, 11788, 11616, 11681, 11624, 11616, - 11788, 11591, 11616, 11624, 31743, 31593, 31554, 31784, 31593, 31743, 38345, 38252, 38283, - 38345, 38447, 38430, 40960, 41175, 40961, 3683, 3667, 3692, 3806, 3767, 3989, 3900, - 3833, 3996, 4191, 4373, 4322, 3699, 3866, 3791, 10793, 10763, 10579, 30013, 30025, - 30200, 32006, 31969, 31898, 29553, 29187, 29916, 29187, 29098, 29248, 38873, 38886, 38845, - 39170, 38992, 39198, 2215, 2358, 2300, 3680, 3667, 3683, 2988, 3020, 3049, 8084, - 8255, 8306, 7538, 7646, 7658, 39256, 39170, 39198, 40856, 40854, 40737, 40897, 40854, - 40856, 40798, 40771, 40673, 40403, 40258, 40352, 19915, 20045, 19964, 19915, 19964, 19803, - 19915, 19803, 19718, 19915, 19718, 19618, 19615, 19446, 19464, 3051, 3110, 3189, 3699, - 3772, 3799, 28301, 28132, 28174, 28301, 28174, 28309, 40393, 40403, 40352, 18781, 18564, - 18692, 19498, 19439, 19595, 16581, 16614, 16466, 16772, 16614, 16620, 25193, 25088, 25140, - 25217, 25088, 25193, 40663, 40462, 40661, 28848, 28877, 28910, 27168, 27381, 27401, 29746, - 29511, 29536, 29379, 29511, 29512, 39666, 39568, 39693, 39440, 39193, 39178, 2620, 2621, - 2780, 2926, 2939, 2996, 3020, 3094, 3049, 35828, 35618, 35696, 40883, 40879, 40876, - 41045, 40879, 40883, 19464, 19446, 19148, 34807, 34880, 34962, 40960, 41076, 41175, 41076, - 41185, 41175, 9153, 9035, 8929, 8769, 9035, 8658, 9602, 9645, 9747, 14612, 14536, - 14547, 14897, 14827, 15026, 14897, 15026, 15260, 33016, 33142, 33003, 32825, 32927, 32809, - 40283, 40393, 40352, 39973, 39926, 39930, 29511, 29301, 29326, 1968, 1910, 2048, 1944, - 2018, 2020, 2020, 2018, 2240, 1997, 2215, 2252, 3599, 3583, 3462, 2875, 2972, - 2976, 3051, 3100, 3110, 2875, 2976, 2884, 5503, 5540, 5563, 4204, 4123, 3931, - 4425, 4532, 4901, 4802, 4749, 4945, 4722, 4749, 4802, 4841, 4802, 4926, 18845, - 18727, 18781, 18758, 18727, 18845, 23206, 22981, 23469, 22124, 22073, 22031, 23129, 23476, - 23259, 24348, 24347, 24213, 23162, 23476, 23129, 32006, 32147, 31969, 32799, 32825, 32809, - 30657, 30902, 31356, 37825, 37887, 37795, 37638, 37623, 37632, 37587, 37419, 37434, 37925, - 37887, 37825, 38217, 38145, 38130, 38711, 38730, 38710, 38710, 38730, 38444, 38711, 38502, - 38740, 39939, 39719, 39665, 39939, 39665, 39928, 39204, 39151, 39260, 41169, 41096, 41291, - 41045, 40892, 40879, 41076, 41204, 41185, 26294, 26240, 26334, 26637, 26503, 26681, 26984, - 26880, 27047, 1829, 1905, 2074, 1829, 2074, 1994, 22159, 22073, 22124, 16160, 16106, - 16284, 16418, 16480, 17100, 10040, 10075, 10323, 10567, 10323, 10544, 31593, 31539, 31554, - 32575, 31795, 32230, 37759, 37587, 37784, 38107, 38052, 38043, 2045, 2359, 2384, 2621, - 2717, 2727, 3203, 3262, 3171, 3110, 3262, 3322, 15141, 14934, 14473, 13033, 13272, - 12753, 13033, 12753, 12888, 39369, 39073, 39170, 39693, 40201, 39918, 40446, 40432, 40062, - 40629, 40388, 40487, 4425, 4901, 4546, 38740, 38502, 38447, 8473, 8514, 8712, 8928, - 8952, 9017, 8191, 8510, 8220, 36977, 36794, 36767, 36358, 36302, 36314, 36996, 37133, - 37080, 36521, 36779, 36523, 36678, 36779, 36521, 1910, 1957, 2038, 3480, 3583, 3561, - 19731, 19710, 19744, 39260, 39151, 39097, 41076, 41074, 41204, 19414, 19464, 19148, 17847, - 17988, 17742, 22609, 22759, 22560, 22883, 22759, 22609, 41209, 41062, 41020, 41209, 41020, - 41030, 17789, 17847, 17742, 16757, 16934, 16870, 24324, 23941, 24005, 40879, 40892, 40595, - 41013, 40487, 40605, 40897, 40892, 41114, 5695, 5948, 5751, 5448, 5376, 5460, 6169, - 6187, 6305, 5687, 6099, 5869, 36358, 36403, 36419, 36115, 36297, 36188, 24529, 24220, - 24842, 2472, 2598, 2605, 2472, 2734, 2516, 5260, 5159, 5230, 5575, 5623, 5686, - 26294, 26334, 26467, 37008, 37133, 36996, 19710, 19638, 19595, 28933, 28877, 28848, 28649, - 28667, 28573, 41204, 41216, 41230, 4421, 4425, 4546, 5260, 5230, 5340, 31620, 31539, - 31593, 33076, 33142, 33016, 32935, 32825, 32950, 3968, 4123, 4077, 10606, 10723, 10935, - 31539, 31043, 30976, 18727, 18564, 18781, 18691, 18564, 18727, 19638, 19498, 19595, 22159, - 22272, 22073, 36560, 36358, 36419, 36297, 36379, 36327, 41204, 41074, 41216, 3171, 3262, - 3110, 2630, 2850, 2891, 27193, 27250, 27560, 26393, 26294, 26467, 5671, 5686, 5745, - 5563, 5631, 5734, 5540, 5631, 5563, 8466, 8514, 8473, 8497, 8514, 8414, 27154, - 26984, 27047, 3020, 2926, 3094, 2707, 2780, 2805, 2905, 2926, 3020, 9635, 9602, - 9747, 9635, 9747, 9781, 37887, 38032, 37795, 37715, 37853, 37749, 37872, 37853, 37715, - 37638, 37632, 37587, 7015, 6916, 7132, 6944, 6903, 6893, 6893, 6692, 6706, 6706, - 6636, 6600, 6600, 6535, 6553, 6215, 6169, 6399, 7015, 7132, 7218, 7015, 7218, - 7029, 2159, 2135, 2233, 2310, 2572, 2261, 3447, 3480, 3561, 3767, 3680, 3805, - 3558, 3680, 3767, 7214, 7424, 7384, 11616, 11591, 11681, 11918, 11915, 11916, 12003, - 11915, 12088, 16106, 15959, 15817, 15883, 15959, 16001, 17597, 17742, 17558, 19618, 19464, - 19492, 22392, 22361, 22272, 22159, 22392, 22272, 24005, 23941, 23874, 24348, 24324, 24281, - 27168, 27143, 27381, 30850, 30803, 30609, 29135, 29098, 29061, 30148, 29947, 30236, 32147, - 32317, 32158, 30803, 30771, 30609, 35488, 35468, 35183, 36115, 36171, 36297, 36563, 36442, - 36379, 35488, 35183, 35151, 35066, 35151, 35029, 38059, 38032, 37887, 38052, 38217, 38130, - 38800, 38740, 38447, 39170, 39073, 38892, 38971, 38886, 38873, 38640, 38806, 38579, 39452, - 39584, 39440, 11483, 11815, 11793, 11760, 11815, 11412, 3799, 3772, 3900, 3405, 3476, - 3226, 11591, 11303, 11406, 37850, 37638, 37835, 34670, 35035, 34658, 33990, 33999, 33433, - 35468, 35536, 35241, 2598, 2646, 2804, 2403, 2472, 2516, 2707, 2805, 2789, 2630, - 2646, 2309, 15883, 15678, 15817, 26984, 26637, 26681, 14133, 14182, 14012, 39452, 39509, - 39584, 39248, 39260, 39097, 38864, 38715, 38730, 7384, 7394, 7265, 7384, 7424, 7589, - 16139, 16367, 16126, 18564, 18526, 18692, 18508, 18526, 18564, 36678, 36442, 36563, 36379, - 36442, 36366, 37375, 37248, 37133, 40661, 40462, 40440, 40668, 40798, 40669, 41168, 40219, - 41148, 40661, 40440, 40660, 3742, 3833, 3900, 13867, 13910, 13915, 14536, 14612, 14827, - 38971, 38873, 38984, 38927, 38864, 38730, 38740, 38730, 38711, 33076, 33016, 32927, 32935, - 32927, 32825, 37133, 37248, 37202, 36967, 36756, 36920, 1836, 1943, 1985, 22392, 22478, - 22361, 38107, 38217, 38052, 3447, 3561, 3667, 29511, 29379, 29301, 28634, 28301, 28309, - 27193, 27154, 27250, 29512, 29511, 29622, 4134, 3917, 4027, 3855, 3917, 3904, 38886, - 38835, 38845, 5631, 5687, 5869, 5565, 5540, 5503, 8636, 8557, 8547, 8663, 8557, - 8636, 8467, 8557, 8413, 37034, 36967, 37060, 7394, 7589, 7636, 35475, 34981, 35561, - 35717, 35561, 35740, 35842, 35829, 35953, 35842, 35953, 35941, 35717, 35842, 35941, 35848, - 35828, 35696, 13729, 14095, 13670, 16232, 16466, 16266, 16620, 16757, 16772, 25627, 25281, - 25815, 26393, 26467, 26503, 40575, 40432, 40446, 39918, 39741, 39666, 40566, 40446, 40536, - 40503, 40393, 40517, 40393, 40283, 40517, 40199, 39996, 40184, 2049, 2132, 2156, 2380, - 2613, 2672, 2049, 2386, 2018, 3262, 3203, 3283, 2896, 3051, 2972, 39666, 39741, - 39626, 39783, 39990, 40284, 8014, 8191, 8180, 13477, 13670, 13450, 13729, 13654, 13421, - 16620, 16614, 16581, 17390, 17597, 17558, 22972, 23076, 23014, 22883, 23014, 22759, 40808, - 40798, 40668, 3226, 3476, 3283, 39584, 39509, 39618, 2084, 2252, 2191, 7646, 7696, - 8180, 7538, 7553, 7646, 7403, 7581, 6715, 24324, 24348, 24213, 23906, 23736, 23476, - 40892, 40897, 40866, 40890, 40902, 41101, 10765, 10793, 10409, 30902, 30803, 30850, 22392, - 22541, 22478, 22517, 22273, 22447, 6032, 6317, 6197, 6046, 6317, 6032, 7512, 7553, - 7538, 25301, 25699, 25379, 27103, 27143, 26970, 25301, 25086, 25220, 40917, 40614, 40854, - 8541, 8663, 8769, 9878, 9871, 9950, 5376, 5260, 5340, 4974, 4872, 4926, 4749, - 4421, 4546, 5131, 5260, 5212, 8758, 8952, 8928, 10409, 10793, 10579, 8497, 8712, - 8514, 5002, 5181, 5159, 16418, 16224, 16284, 15747, 15549, 15678, 16139, 16224, 16418, - 25408, 25301, 25220, 40184, 39996, 39973, 40216, 40199, 40571, 2737, 2707, 2789, 2548, - 2717, 2621, 2503, 2478, 2615, 2261, 2572, 2515, 9807, 9878, 9950, 10683, 10606, - 10935, 15678, 15549, 15616, 15386, 15549, 15500, 23545, 23206, 23469, 22736, 22811, 22684, - 23076, 23162, 23129, 22972, 23162, 23076, 36967, 37008, 36996, 37850, 37715, 37638, 37034, - 37008, 36967, 40606, 40566, 40536, 35941, 35953, 36064, 36794, 36614, 36625, 36703, 36614, - 36713, 36419, 36614, 36703, 9781, 9878, 9739, 37959, 38122, 37836, 37228, 37067, 37314, - 38089, 38078, 38424, 38800, 38447, 38659, 38032, 38107, 38043, 38059, 38107, 38032, 37925, - 37825, 37853, 37872, 37715, 37850, 2836, 2875, 2884, 2836, 2884, 2850, 23891, 23906, - 23617, 26743, 26688, 26417, 41100, 40909, 41024, 1943, 1898, 2050, 7553, 7696, 7646, - 22721, 22541, 22688, 15047, 14897, 15260, 26558, 26743, 26417, 28933, 29135, 28877, 28173, - 28045, 27780, 5068, 5002, 5159, 2463, 2515, 2511, 17419, 17597, 17390, 16581, 16466, - 16232, 39722, 39618, 39797, 39722, 39584, 39618, 3064, 2988, 3049, 2926, 2737, 2939, - 3019, 2988, 3064, 13910, 13867, 13948, 14012, 14182, 14163, 31539, 31639, 31043, 31043, - 30999, 30758, 31784, 31620, 31593, 31639, 31620, 31773, 41062, 41144, 41004, 41361, 41144, - 41343, 15386, 15221, 15279, 26581, 26393, 26503, 25896, 25815, 26021, 25088, 24900, 24842, - 26581, 26503, 26637, 26581, 26637, 26912, 41169, 41100, 41024, 41169, 40846, 41096, 5575, - 5448, 5623, 5948, 6042, 5751, 6042, 6086, 5846, 3772, 3742, 3900, 3833, 3968, - 4077, 3641, 3347, 3502, 11303, 10886, 11390, 11591, 11467, 11303, 11624, 11467, 11591, - 11624, 11788, 11916, 11916, 11788, 11918, 41140, 41206, 41234, 41263, 41140, 41234, 41263, - 41290, 41140, 41140, 41290, 40980, 41251, 41000, 41094, 41206, 41223, 41234, 41205, 41223, - 41206, 41392, 41223, 41205, 41244, 41205, 41191, 41244, 41191, 41150, 41244, 41150, 41451, - 41321, 41150, 41156, 2132, 2084, 2191, 2672, 2606, 2235, 1901, 2084, 2132, 3641, - 3742, 3772, 12088, 12339, 12685, 17390, 16934, 16930, 18346, 18398, 18358, 19414, 19148, - 19317, 23906, 24005, 23874, 24348, 25041, 24888, 23891, 24005, 23906, 33142, 33331, 33155, - 32799, 32809, 32678, 33285, 33331, 33142, 39179, 38971, 38984, 38886, 38964, 38835, 39256, - 39271, 39170, 39315, 39271, 39256, 39315, 39193, 39440, 39604, 39482, 39204, 39319, 39248, - 39097, 39319, 39097, 38864, 41175, 41279, 41156, 1921, 1839, 2208, 1736, 1885, 1910, - 1910, 1885, 1957, 1957, 1836, 1985, 1943, 1860, 1898, 1609, 1839, 1595, 41175, - 41273, 41279, 2406, 2463, 2511, 2330, 2463, 2381, 2606, 2114, 2235, 2472, 2470, - 2598, 2749, 2836, 2850, 25699, 25729, 25952, 25687, 25729, 25699, 25687, 25699, 25301, - 1898, 1944, 2020, 1689, 1944, 1898, 2214, 2246, 2215, 19118, 18902, 19279, 18526, - 18404, 18229, 40820, 40808, 40668, 40526, 40316, 40403, 20448, 20307, 20392, 20134, 19820, - 20084, 19710, 19625, 19638, 19638, 19625, 19498, 19498, 19504, 19279, 20288, 20307, 20448, - 21440, 21642, 21683, 21440, 21683, 21544, 21683, 21716, 21544, 21936, 21716, 21683, 22031, - 22037, 21936, 3917, 3855, 4027, 3447, 3462, 3480, 3904, 3917, 3850, 3904, 3850, - 3757, 12088, 12136, 12073, 2980, 3100, 3051, 3203, 3226, 3283, 3502, 3347, 3396, - 20307, 20158, 20150, 4872, 4841, 4926, 4588, 4841, 4872, 32115, 32317, 32147, 32115, - 32147, 32006, 37925, 37872, 37850, 32014, 32115, 32006, 2071, 2214, 2215, 41175, 41185, - 41273, 40393, 40526, 40403, 40630, 40526, 40393, 41209, 41059, 41236, 41011, 40771, 40798, - 30902, 30657, 30771, 2493, 2548, 2621, 2588, 2737, 2495, 3480, 3462, 3583, 3447, - 3316, 3296, 3716, 3968, 3833, 4310, 4411, 4373, 5503, 5518, 5237, 5002, 4974, - 5004, 4998, 4974, 5002, 5068, 5159, 5131, 8557, 8467, 8547, 8663, 8821, 9035, - 14529, 14536, 14827, 14937, 14827, 14897, 15861, 16199, 15674, 16930, 16934, 16757, 27250, - 27154, 27047, 27250, 27612, 27615, 27572, 27604, 27678, 26826, 27103, 26970, 26826, 26970, - 26743, 33209, 32881, 33115, 33209, 33115, 33522, 40199, 40216, 40043, 40184, 39973, 40474, - 40820, 40668, 40663, 2875, 2896, 2972, 2630, 2891, 2646, 27103, 27381, 27143, 40112, - 39973, 39939, 38110, 38122, 37959, 38227, 38200, 38511, 38110, 38200, 38227, 2470, 2646, - 2598, 26837, 26826, 26743, 41019, 40917, 40854, 41042, 41045, 40883, 41112, 41045, 41042, - 2988, 2905, 3020, 2871, 2905, 2988, 2692, 2896, 2875, 12088, 12685, 12136, 14163, - 14182, 14371, 27608, 27604, 27572, 22031, 22073, 22037, 33522, 33193, 33812, 12244, 12471, - 12034, 11760, 12034, 11815, 30803, 30902, 30771, 30364, 30200, 30025, 30148, 30025, 29947, - 39604, 39204, 39260, 5131, 5159, 5260, 6916, 6903, 6944, 6827, 6903, 6916, 6827, - 6916, 7015, 7029, 7218, 7214, 7029, 7214, 7265, 41100, 41101, 40902, 41308, 41101, - 41100, 2620, 2780, 2707, 3052, 3171, 3110, 3052, 3110, 3100, 18902, 18758, 18845, - 18829, 18758, 18902, 22736, 22721, 22688, 22037, 22073, 22080, 26197, 26240, 26294, 26912, - 26637, 26984, 26201, 26255, 25952, 35848, 35955, 35828, 35828, 35955, 35989, 37034, 37375, - 37008, 35468, 35606, 35536, 35349, 35488, 35151, 35165, 35151, 35066, 20134, 20084, 20150, - 22073, 22201, 22080, 6903, 6692, 6893, 7265, 7214, 7384, 34147, 34670, 34208, 6692, - 6636, 6706, 34147, 34187, 34670, 2387, 2403, 2516, 2268, 2403, 2387, 2239, 2387, - 2380, 5540, 5565, 5631, 4589, 4411, 4420, 8361, 8466, 8191, 8361, 8514, 8466, - 33905, 33522, 33812, 2911, 3335, 3433, 13654, 13729, 13670, 13477, 13450, 13272, 1736, - 1910, 1968, 19820, 19731, 19744, 41273, 41185, 41230, 41185, 41204, 41230, 34670, 34703, - 34756, 35842, 35717, 35740, 34590, 34450, 34113, 36182, 36360, 36316, 26197, 26294, 26368, - 23206, 22736, 22688, 40837, 40820, 40663, 40808, 40943, 40798, 40837, 40663, 40661, 1905, - 1795, 2039, 1829, 1994, 1784, 4627, 4722, 4570, 4570, 4722, 4592, 4841, 4722, - 4802, 8108, 8084, 8306, 19148, 18931, 19149, 17704, 17419, 17554, 18758, 18691, 18727, - 18786, 18691, 18758, 22073, 22272, 22201, 22721, 22736, 22684, 36703, 36560, 36419, 37067, - 36800, 37314, 37872, 37925, 37853, 38107, 38412, 38217, 37375, 37304, 37248, 41074, 41073, - 41216, 2396, 2470, 2472, 15221, 15047, 15260, 15549, 15386, 15607, 15883, 15817, 15959, - 26368, 26294, 26393, 26055, 26201, 25952, 26553, 26201, 26437, 40580, 40575, 40566, 40566, - 40575, 40446, 40395, 40284, 40133, 40606, 40536, 40743, 1896, 2049, 1790, 1997, 2071, - 2215, 1896, 1790, 1886, 8769, 8658, 8595, 9878, 9781, 9871, 10040, 10323, 10141, - 9687, 9781, 9739, 32115, 32391, 32317, 32678, 32809, 32460, 32015, 31781, 31649, 31384, - 31379, 31356, 38227, 38122, 38110, 38806, 38640, 38835, 37925, 38059, 37887, 35953, 36062, - 36182, 35721, 35597, 35536, 37008, 37375, 37133, 36756, 36779, 36920, 19731, 19625, 19710, - 19464, 19618, 19615, 19937, 20255, 20045, 22517, 22456, 22273, 19148, 19149, 19317, 13151, - 13477, 13272, 27948, 28173, 27780, 28335, 28441, 28433, 27154, 27046, 26984, 26404, 26368, - 26393, 27893, 27612, 28132, 30228, 30148, 30236, 5544, 5448, 5575, 5582, 5575, 5671, - 4420, 4411, 4310, 6433, 6711, 6317, 37741, 37573, 37688, 36678, 36521, 36442, 36182, - 36062, 36302, 2588, 2620, 2707, 2493, 2620, 2479, 2831, 2926, 2905, 12685, 12207, - 12136, 14314, 14163, 14371, 14372, 14371, 14536, 22460, 22560, 22448, 23617, 23906, 23476, - 22456, 22448, 22273, 32678, 32460, 32663, 32935, 33076, 32927, 1757, 1836, 1957, 4310, - 4373, 4191, 19625, 19504, 19498, 41216, 41073, 41361, 31352, 31384, 31356, 30148, 30364, - 30025, 36182, 36302, 36360, 36713, 36614, 36794, 36563, 36379, 36468, 39184, 38984, 39073, - 39184, 39073, 39369, 39504, 39315, 39440, 41019, 40854, 40897, 41112, 40892, 41045, 41013, - 40741, 40487, 7696, 8014, 8180, 7553, 7607, 7696, 7403, 7607, 7553, 7403, 7553, - 7512, 24005, 24281, 24324, 24230, 24281, 24005, 35955, 36150, 35989, 3855, 3806, 3989, - 3806, 3904, 3757, 13822, 13985, 13729, 13729, 13985, 14095, 15296, 15861, 15674, 14790, - 15047, 14822, 26558, 26680, 26743, 26826, 26889, 27103, 27429, 27572, 27381, 27429, 27608, - 27572, 28588, 28441, 28392, 26553, 26680, 26558, 30364, 30586, 30609, 1836, 1826, 1943, - 22272, 22306, 22201, 26021, 25815, 26240, 26021, 26240, 26197, 40743, 40536, 40629, 41230, - 41216, 41777, 2114, 2606, 2246, 2403, 2396, 2472, 2125, 2246, 2214, 25011, 24900, - 25088, 25401, 25255, 25281, 22883, 22972, 23014, 22889, 22972, 22883, 41094, 41092, 41822, - 41329, 41112, 41042, 6371, 6505, 6553, 36150, 36171, 36115, 5212, 5260, 5376, 5068, - 4998, 5002, 10793, 10765, 11137, 10118, 10123, 10045, 10123, 9822, 10045, 30586, 30850, - 30609, 32950, 33076, 32935, 33331, 33373, 33212, 38921, 38806, 38835, 5953, 6086, 6077, - 5448, 5389, 5376, 17789, 17742, 17659, 22272, 22361, 22306, 36703, 36750, 36560, 36894, - 36713, 36794, 4131, 4322, 4204, 28392, 28441, 28335, 28564, 28441, 28588, 31352, 31356, - 31203, 9687, 9602, 9635, 8467, 8318, 8306, 8497, 8678, 8712, 8565, 8678, 8497, - 33285, 33373, 33331, 4722, 4627, 4749, 4906, 4872, 4974, 9781, 9687, 9635, 10323, - 10567, 10141, 37925, 38484, 38059, 37759, 37638, 37587, 2548, 2503, 2615, 2463, 2330, - 2515, 2443, 2503, 2548, 2842, 2980, 3051, 3098, 3226, 3203, 3006, 2980, 2933, - 2692, 2875, 2836, 2749, 2850, 2584, 26404, 26393, 26581, 17659, 17742, 17597, 17659, - 17597, 17704, 7895, 8147, 8084, 7895, 7746, 8147, 19149, 18931, 18969, 22478, 22541, - 22721, 25011, 25088, 25217, 34590, 34113, 34807, 4877, 4998, 5068, 18508, 18404, 18526, - 16001, 15959, 16106, 18508, 18564, 18691, 18346, 18358, 18226, 32663, 32460, 32513, 32824, - 32950, 32825, 32101, 32115, 32014, 24281, 24392, 24348, 24230, 24392, 24281, 38412, 38161, - 38217, 39658, 39634, 39482, 38412, 38107, 38059, 39482, 39634, 39361, 39464, 39260, 39248, - 2406, 2511, 2478, 1979, 2045, 2384, 5695, 5582, 5671, 5632, 5582, 5695, 8413, - 8318, 8467, 8048, 8361, 8191, 16139, 16160, 16224, 14674, 14937, 14790, 15125, 15674, - 15355, 16930, 16757, 16874, 25816, 25627, 25896, 25896, 25627, 25815, 25126, 25011, 25217, - 36977, 36894, 36794, 36713, 36750, 36703, 36977, 36767, 37067, 37034, 37745, 37375, 37784, - 37587, 37772, 36678, 36851, 36779, 36766, 36851, 36678, 2692, 2749, 2668, 14937, 14897, - 15047, 14529, 14372, 14536, 13180, 13867, 13553, 1733, 1860, 1943, 18895, 18931, 18668, - 27145, 27046, 27154, 26912, 27046, 27145, 6169, 5953, 6077, 34450, 34283, 34016, 15861, - 16232, 16266, 40982, 40943, 40808, 40941, 40837, 40901, 40660, 40316, 40657, 2503, 2406, - 2478, 2949, 3052, 3100, 3006, 3100, 2980, 10524, 10567, 10606, 26176, 26021, 26197, - 26176, 26197, 26368, 28634, 28542, 29301, 28232, 28301, 28407, 31620, 31639, 31539, 31773, - 31620, 31784, 31773, 32029, 31926, 40133, 40432, 40395, 40284, 40107, 40133, 39584, 39916, - 39440, 39730, 39928, 39429, 40517, 40289, 40571, 40517, 40283, 40289, 8678, 8758, 8928, - 8697, 8758, 8678, 14937, 15047, 14790, 33495, 33604, 33373, 32824, 32825, 32799, 3833, - 3742, 3686, 4123, 3968, 3896, 4172, 4131, 4063, 4063, 4131, 4204, 18398, 18607, - 18668, 18226, 18358, 18085, 18085, 18358, 17847, 17704, 17597, 17419, 23264, 23476, 23162, - 39797, 39618, 39741, 39634, 39730, 39361, 41502, 41092, 41176, 3019, 2871, 2988, 2620, - 2493, 2621, 2271, 2381, 2406, 2877, 2871, 3019, 2877, 3019, 2911, 13985, 14070, - 14389, 13870, 13822, 13729, 13909, 13822, 13870, 38971, 38964, 38886, 39369, 39170, 39271, - 39179, 39184, 39275, 1997, 2252, 2084, 2125, 2071, 2028, 24900, 25011, 24967, 22684, - 22811, 22708, 22684, 22478, 22721, 24832, 25041, 24348, 26736, 26837, 26680, 24979, 25041, - 24832, 40982, 40808, 40820, 41059, 41209, 41030, 31203, 31356, 30902, 30868, 30902, 30850, - 30364, 30521, 30586, 30148, 30228, 30364, 29135, 29061, 28877, 5582, 5544, 5575, 4872, - 4906, 4588, 5495, 5544, 5582, 8541, 8413, 8557, 7953, 7895, 8084, 8541, 8557, - 8663, 8452, 8414, 8326, 8361, 8414, 8514, 36819, 36750, 36713, 37081, 36977, 37142, - 36851, 36920, 36779, 36833, 36920, 36851, 12088, 11915, 11918, 11916, 11617, 11624, 11624, - 11348, 11467, 11203, 10886, 11303, 13867, 13864, 13728, 26912, 26404, 26581, 40289, 40216, - 40571, 32015, 32101, 32014, 32831, 32824, 32799, 32015, 31649, 31634, 3904, 3806, 3855, - 3850, 4134, 3748, 20255, 20249, 20045, 22972, 23264, 23162, 4998, 4906, 4974, 4627, - 4421, 4749, 4877, 5068, 4873, 35488, 35606, 35468, 36331, 36319, 36150, 36319, 36380, - 36171, 35305, 35349, 35151, 35305, 35151, 35165, 35305, 35165, 35138, 35305, 35273, 35364, - 38163, 37741, 37688, 38163, 37688, 38122, 37850, 37946, 37925, 37587, 37434, 37772, 18488, - 18607, 18398, 18085, 17847, 17928, 22959, 23264, 22972, 35305, 35138, 35273, 40219, 40490, - 41148, 3316, 3667, 3680, 13915, 14012, 14163, 4131, 4191, 4322, 4310, 4209, 4420, - 5394, 5475, 5503, 31203, 30902, 31195, 35574, 35606, 35488, 36468, 36379, 36297, 36380, - 36297, 36171, 2330, 2261, 2515, 1784, 1994, 1737, 2406, 2381, 2463, 2234, 2381, - 2271, 3098, 3203, 3171, 2949, 3006, 2933, 4400, 4421, 4351, 6636, 6535, 6600, - 6169, 6092, 5953, 6692, 6535, 6636, 6632, 6535, 6692, 6708, 6692, 6903, 6827, - 7015, 7029, 12888, 12753, 12584, 12888, 12584, 12594, 28441, 28564, 28573, 27948, 27780, - 27604, 35606, 35721, 35536, 39918, 39797, 39741, 39369, 39271, 39315, 40606, 40580, 40566, - 40741, 40743, 40629, 40833, 40743, 40741, 41290, 41454, 41176, 41334, 41322, 41290, 41334, - 41290, 41263, 41334, 41263, 41351, 41263, 41234, 41351, 41234, 41367, 41351, 41223, 41367, - 41234, 41385, 41367, 41223, 41385, 41223, 41392, 41392, 41205, 41244, 11348, 11303, 11467, - 41401, 41392, 41415, 17100, 16616, 17224, 15883, 15747, 15678, 41279, 41321, 41156, 41325, - 41321, 41279, 41273, 41325, 41279, 7394, 7384, 7589, 7394, 7636, 7454, 22863, 22811, - 22736, 22456, 22460, 22448, 35475, 34962, 34880, 34450, 34681, 34283, 35475, 35561, 35717, - 35827, 35717, 35941, 35721, 35848, 35696, 20307, 20288, 20158, 20158, 20134, 20150, 19820, - 19802, 19731, 19731, 19668, 19625, 19625, 19668, 19504, 19118, 18829, 18902, 20332, 20288, - 20448, 20566, 20764, 20759, 21328, 21440, 21544, 21716, 21936, 21821, 21936, 22037, 21821, - 22037, 21954, 21821, 33085, 33142, 33076, 32831, 32799, 32678, 41273, 41230, 41325, 2470, - 2255, 2646, 2313, 2396, 2403, 2391, 2396, 2313, 40746, 40580, 40606, 39940, 39838, - 39797, 33373, 33604, 33433, 33085, 33076, 32950, 36920, 37060, 36967, 37745, 37060, 37789, - 14372, 14314, 14371, 14674, 14529, 14827, 14364, 14529, 14445, 6535, 6371, 6553, 5438, - 5448, 5544, 14364, 14314, 14372, 40585, 40432, 40575, 10886, 10683, 10935, 23264, 23397, - 23476, 24126, 24230, 24005, 23257, 23397, 23264, 20288, 20134, 20158, 26680, 26837, 26743, - 26553, 26558, 26201, 27197, 27381, 27103, 28933, 28848, 28649, 7454, 7636, 7514, 8326, - 8414, 8361, 6715, 7526, 7074, 6715, 6711, 6433, 9807, 9739, 9878, 8769, 8663, - 9035, 10283, 10141, 10567, 9039, 9017, 8952, 19118, 19279, 19504, 17983, 17533, 17745, - 22460, 22609, 22560, 18225, 18229, 18404, 41329, 41042, 41101, 40917, 41013, 40605, 41308, - 41100, 41169, 6371, 6215, 6399, 34670, 34187, 34703, 26648, 26553, 26535, 33423, 33085, - 32950, 37759, 37835, 37638, 37820, 37835, 37759, 40657, 40316, 40526, 40982, 41011, 40943, - 40571, 40199, 40184, 2871, 2831, 2905, 2911, 3599, 2898, 13915, 13910, 14012, 28015, - 27893, 28132, 26381, 26368, 26404, 27608, 27948, 27604, 28564, 28933, 28649, 32513, 32460, - 32317, 32824, 32831, 32950, 31634, 31648, 31384, 38424, 38078, 38344, 38424, 38649, 38553, - 17928, 17847, 17789, 18488, 18398, 18392, 17928, 17789, 17818, 5438, 5389, 5448, 5632, - 5695, 5608, 8108, 8306, 8318, 8769, 8595, 8424, 8651, 9039, 8952, 8452, 8565, - 8497, 8452, 8497, 8414, 18829, 18786, 18758, 18675, 18786, 18618, 24836, 24842, 24900, - 22037, 22080, 22131, 33604, 33650, 33433, 33465, 33495, 33373, 2234, 2261, 2330, 2234, - 2330, 2381, 2866, 3171, 3052, 4131, 4172, 4191, 19971, 19802, 19820, 28640, 28933, - 28564, 36819, 36713, 36894, 35891, 35827, 36027, 36819, 36894, 37081, 36634, 36766, 36678, - 36634, 36678, 36563, 41325, 41230, 41777, 25879, 25816, 25896, 25401, 25335, 25255, 25879, - 25896, 26021, 26176, 26368, 26381, 40630, 40393, 40503, 2071, 2125, 2214, 1901, 2132, - 2049, 35037, 34590, 34807, 33955, 33905, 33812, 33522, 33789, 33209, 36251, 36182, 36316, - 41114, 41019, 40897, 1829, 1795, 1905, 1609, 1736, 1968, 1885, 1757, 1957, 1836, - 1757, 1826, 1826, 1733, 1943, 2231, 1754, 2158, 1711, 1736, 1455, 2049, 2018, - 1753, 19802, 19720, 19731, 38649, 38344, 38825, 38659, 38412, 38530, 3641, 3772, 3699, - 4191, 4209, 4310, 31515, 31634, 31384, 31195, 30902, 31031, 2396, 2391, 2470, 2933, - 2980, 2842, 2239, 2380, 2139, 26912, 26984, 27046, 40580, 40585, 40575, 40746, 40585, - 40580, 40829, 40606, 40743, 40656, 40630, 40503, 1979, 2384, 2015, 3699, 3347, 3641, - 11473, 11348, 11624, 10826, 10524, 10683, 11617, 11916, 11915, 12003, 12088, 12073, 39184, - 39179, 38984, 39369, 39315, 39383, 18786, 18675, 18691, 18508, 18675, 18618, 6021, 6092, - 6169, 11222, 11815, 11483, 11222, 11137, 10765, 19720, 19668, 19731, 22080, 22201, 22131, - 39582, 39440, 39723, 39628, 39319, 39633, 39634, 39833, 39730, 38927, 38730, 38740, 41361, - 41073, 41144, 3006, 2949, 3100, 2692, 2836, 2749, 3641, 3686, 3742, 28634, 29301, - 29111, 28301, 28232, 28132, 39179, 39080, 38971, 2018, 1944, 1753, 19414, 19350, 19488, - 17704, 17789, 17659, 5846, 6086, 5953, 13033, 13151, 13272, 12594, 12584, 12471, 29512, - 29301, 29379, 33955, 33812, 34139, 33209, 32864, 32575, 37081, 36894, 36977, 36302, 36546, - 36360, 37772, 37434, 37375, 36766, 36833, 36851, 36724, 36833, 36766, 11998, 12003, 12073, - 26889, 26826, 26837, 26889, 27197, 27103, 27955, 28102, 27948, 2231, 1702, 1754, 1736, - 1757, 1885, 2668, 2749, 2546, 19618, 19693, 19915, 22742, 22609, 22460, 22742, 22889, - 22609, 19492, 19632, 19618, 19492, 19464, 19488, 19464, 19414, 19488, 18346, 18392, 18398, - 22131, 22201, 22306, 27197, 27429, 27381, 3806, 3558, 3767, 3850, 3917, 4134, 37741, - 37499, 37344, 37803, 37499, 37741, 39080, 38964, 38971, 5389, 5300, 5376, 5308, 5300, - 5389, 8565, 8697, 8678, 8651, 8697, 8390, 27145, 27193, 27395, 27145, 27154, 27193, - 6092, 5990, 5953, 36319, 36171, 36150, 3447, 3369, 3462, 3296, 3369, 3447, 12207, - 12685, 12238, 18346, 18226, 18392, 22609, 22889, 22883, 24126, 24005, 23891, 23050, 22889, - 22742, 41391, 41291, 41096, 41391, 41000, 41251, 2125, 2114, 2246, 2028, 2114, 2125, - 24967, 24836, 24900, 24967, 25011, 25126, 40943, 41011, 40798, 40941, 40820, 40837, 2822, - 2831, 2871, 2822, 2871, 2877, 13728, 13553, 13867, 14147, 13915, 14163, 14147, 14163, - 14314, 13822, 13909, 13985, 13870, 13729, 13491, 19414, 19317, 19350, 2139, 2380, 2235, - 3716, 3907, 3968, 16139, 16001, 16106, 14529, 14364, 14372, 16126, 16001, 16139, 38964, - 38921, 38835, 38897, 38927, 38740, 26553, 26648, 26680, 26437, 26201, 26313, 25208, 25217, - 25255, 26139, 25879, 26021, 26139, 26021, 26176, 40901, 40837, 40661, 40630, 40657, 40526, - 2231, 2155, 1702, 2015, 2384, 2036, 23617, 23476, 23397, 26666, 26736, 26648, 23691, - 23617, 23397, 32513, 32317, 32391, 33085, 33285, 33142, 37820, 37784, 37797, 37835, 37946, - 37850, 19350, 19317, 19294, 29135, 29248, 29098, 30704, 30850, 30586, 29097, 29248, 29135, - 29097, 29135, 28933, 28335, 28173, 28281, 36380, 36468, 36297, 13022, 13151, 13033, 13022, - 13033, 12888, 18675, 18508, 18691, 18381, 18508, 18618, 19294, 19317, 19149, 18392, 18226, - 18161, 22889, 22959, 22972, 23050, 22959, 22889, 28232, 28015, 28132, 28108, 28015, 28232, - 31444, 30999, 31043, 31761, 31043, 31639, 39928, 40112, 39939, 40656, 40657, 40630, 40878, - 40660, 40657, 39970, 40112, 39928, 39970, 39928, 40081, 5300, 5212, 5376, 4592, 4722, - 4841, 5099, 5212, 5300, 26386, 26381, 26404, 33540, 33285, 33532, 33495, 33650, 33604, - 2305, 2135, 1830, 1757, 1733, 1826, 19294, 19149, 19321, 22306, 22361, 22309, 8651, - 8952, 8758, 5990, 5846, 5953, 5495, 5438, 5544, 8108, 8318, 8413, 12244, 12594, - 12471, 10118, 10409, 10579, 9623, 10045, 9822, 32777, 32678, 32663, 31419, 31384, 31352, - 31419, 31352, 31203, 35816, 35475, 35717, 34962, 35037, 34807, 5475, 5631, 5565, 6876, - 6827, 7029, 6320, 6275, 6371, 6371, 6275, 6215, 6215, 6021, 6169, 6092, 5880, - 5990, 5658, 5751, 5846, 6750, 6827, 6876, 7110, 7265, 7394, 35721, 35868, 35848, - 35848, 36035, 35955, 36380, 36478, 36468, 35796, 35868, 35721, 35349, 35574, 35488, 35305, - 35364, 35349, 35273, 35138, 35035, 35588, 35697, 35624, 35588, 35574, 35349, 24836, 24529, - 24842, 22309, 22361, 22478, 25704, 25627, 25712, 41019, 41013, 40917, 41118, 41013, 41019, - 41114, 40892, 41112, 1896, 1901, 2049, 1807, 1901, 1896, 23617, 23836, 23891, 23691, - 23836, 23617, 1830, 2135, 1875, 18895, 18668, 18754, 2036, 2384, 2310, 1875, 2135, - 1766, 2170, 2268, 2109, 1922, 1997, 2084, 5503, 5475, 5565, 5394, 5503, 5237, - 8697, 8651, 8758, 8014, 7696, 7390, 7696, 7607, 7458, 24230, 24447, 24392, 24334, - 24447, 24230, 33465, 33650, 33495, 41207, 41114, 41112, 4172, 4170, 4191, 3931, 4063, - 4204, 10143, 10409, 10118, 18508, 18373, 18404, 15840, 15807, 16001, 18381, 18373, 18508, - 18754, 18668, 18607, 18161, 18226, 18085, 30521, 30364, 30228, 14674, 14827, 14937, 39985, - 39797, 39918, 40613, 40395, 40432, 40613, 40432, 40585, 1907, 2036, 1961, 2352, 2406, - 2503, 2239, 2268, 2387, 2668, 2896, 2692, 2139, 2235, 2008, 25712, 25627, 25816, - 25712, 25816, 25839, 36109, 35941, 36064, 36251, 36064, 36182, 35730, 35721, 35606, 41226, - 40833, 40741, 40106, 39970, 40081, 2064, 2235, 2114, 5721, 5751, 5658, 5846, 5751, - 6042, 7458, 7607, 7403, 25401, 25281, 25627, 36478, 36634, 36468, 36468, 36634, 36563, - 37946, 37820, 38034, 40901, 40661, 40891, 9991, 9950, 10040, 9991, 10040, 10141, 10524, - 10606, 10683, 22309, 22478, 22386, 38227, 38190, 38122, 38279, 38190, 38227, 38163, 38190, - 38279, 41343, 41144, 41062, 41343, 41062, 41396, 9039, 9316, 9677, 37784, 37820, 37759, - 37996, 37798, 37938, 39797, 39838, 39722, 39985, 39918, 40082, 2588, 2707, 2737, 26648, - 26736, 26680, 27668, 27674, 27429, 24979, 25220, 25041, 11998, 11915, 12003, 11827, 11617, - 11915, 10826, 10683, 10886, 11998, 12073, 12136, 10819, 11222, 10765, 12948, 12888, 12822, - 30065, 30236, 29947, 6442, 6371, 6535, 13915, 13864, 13867, 13717, 13864, 13915, 13909, - 14070, 13985, 13421, 13654, 13477, 13421, 13477, 13151, 39319, 39464, 39248, 39628, 39464, - 39319, 18058, 18161, 18085, 16757, 16620, 16874, 16620, 16581, 16448, 16581, 16232, 16448, - 30236, 30521, 30228, 41148, 40490, 40771, 41148, 40771, 41159, 4010, 4170, 4172, 22708, - 22478, 22684, 31809, 31773, 31926, 5495, 5582, 5632, 33816, 33990, 33650, 32777, 32831, - 32678, 32115, 32101, 32179, 2135, 2045, 1766, 1925, 2036, 1907, 7514, 7636, 7558, - 24603, 24529, 24836, 24603, 24836, 24753, 24832, 24348, 24392, 29622, 29511, 29824, 28176, - 28108, 28232, 39275, 39111, 39179, 39179, 39111, 39080, 39080, 39111, 38964, 38964, 39095, - 38921, 39582, 39504, 39440, 26313, 26201, 26055, 5751, 5721, 5695, 5573, 5721, 5658, - 5466, 5687, 5631, 30558, 30704, 30586, 28102, 28173, 27948, 30677, 30558, 30567, 27948, - 27608, 27731, 2949, 2866, 3052, 3226, 3231, 3405, 2842, 3051, 2896, 2947, 2933, - 2852, 13495, 13553, 13728, 27615, 27612, 27893, 26386, 26176, 26381, 28407, 28301, 28634, - 27674, 27608, 27429, 7558, 7636, 7746, 7371, 7458, 7403, 36358, 36546, 36302, 18373, - 18225, 18404, 18381, 18225, 18373, 22959, 23257, 23264, 23836, 24126, 23891, 24447, 24516, - 24392, 23050, 23257, 22959, 3757, 3737, 3806, 4218, 4134, 4425, 4218, 4425, 4421, - 3907, 3896, 3968, 4063, 4010, 4172, 3768, 3896, 3907, 3716, 3833, 3686, 3716, - 3686, 3619, 30704, 30868, 30850, 32050, 32015, 31634, 38800, 38897, 38740, 38927, 39190, - 38864, 38447, 38345, 38659, 16001, 15807, 15883, 15747, 15807, 15840, 25208, 25126, 25217, - 25489, 25401, 25627, 25839, 25816, 25879, 26139, 26176, 26386, 40833, 40831, 40743, 40942, - 40831, 40833, 1901, 1922, 2084, 1902, 2028, 2071, 1807, 1922, 1901, 25489, 25627, - 25704, 40988, 40982, 40820, 40891, 40661, 40660, 40891, 40660, 40882, 41266, 41236, 41059, - 41159, 40771, 41011, 4148, 4191, 4170, 4148, 4209, 4191, 10045, 10143, 10118, 10409, - 10413, 10765, 9788, 10143, 10045, 41322, 41454, 41290, 41334, 41439, 41322, 41351, 41439, - 41334, 41531, 41439, 41351, 41531, 41351, 41367, 41531, 41367, 41385, 41401, 41385, 41392, - 41392, 41244, 41415, 41244, 41451, 41415, 20288, 20317, 20134, 20134, 19971, 19820, 19802, - 19853, 19720, 19720, 19752, 19668, 19668, 19318, 19504, 21196, 20983, 21440, 21196, 21440, - 21328, 21544, 21697, 21328, 21716, 21697, 21544, 21797, 21697, 21716, 7623, 7558, 7746, - 36560, 36617, 36546, 36358, 36560, 36546, 36155, 36150, 35955, 41520, 41454, 41322, 4592, - 4841, 4588, 4906, 4998, 4783, 5721, 5608, 5695, 5573, 5608, 5721, 7483, 7445, - 7558, 7876, 8108, 7986, 8108, 8413, 7986, 33905, 33911, 33522, 34139, 33812, 34283, - 33911, 33955, 33928, 33650, 33990, 33433, 33465, 33373, 33285, 2368, 2352, 2503, 1961, - 1798, 1815, 2423, 2443, 2548, 2495, 2737, 2926, 2495, 2926, 2831, 20566, 20332, - 20448, 26386, 26404, 26779, 27615, 27893, 27862, 32179, 32101, 32015, 32179, 32015, 32188, - 33423, 32950, 32831, 33540, 33465, 33285, 37395, 37228, 37314, 37395, 37314, 37614, 37820, - 37946, 37835, 37996, 37892, 37798, 40829, 40746, 40606, 41454, 41448, 41176, 41157, 41019, - 41114, 41515, 41391, 42044, 3098, 3231, 3226, 20332, 20317, 20288, 19937, 20045, 19915, - 19937, 19915, 19693, 19618, 19632, 19693, 19632, 19492, 19693, 19492, 19599, 19693, 41150, - 41321, 41451, 22736, 23206, 22863, 24753, 24836, 24967, 3896, 3931, 4123, 11203, 11303, - 11348, 38923, 38800, 38959, 27924, 27893, 28015, 27668, 27429, 27531, 26889, 26837, 26736, - 18058, 18085, 17928, 18754, 18607, 18645, 25208, 25255, 25244, 40988, 40820, 40941, 20317, - 20114, 20134, 21821, 21797, 21716, 32630, 32777, 32663, 37060, 36920, 37789, 41451, 41321, - 41460, 28391, 28407, 28476, 28027, 27924, 28015, 36560, 36750, 36617, 39693, 39783, 40201, - 39579, 39383, 39504, 20114, 20055, 20134, 18607, 18488, 18502, 19492, 19488, 19334, 23908, - 24126, 23836, 2423, 2548, 2493, 2911, 2822, 2877, 20055, 19971, 20134, 19488, 19350, - 19334, 22037, 22131, 21954, 26437, 26535, 26553, 26490, 26535, 26437, 27862, 27924, 28027, - 40747, 40613, 40585, 40201, 39783, 40284, 41460, 41321, 41325, 10065, 9991, 10141, 9583, - 9602, 9687, 31773, 31688, 31639, 29824, 29511, 29746, 31809, 31688, 31773, 3931, 4010, - 4063, 37798, 37797, 37772, 36319, 36478, 36380, 19971, 19886, 19802, 2230, 2406, 2352, - 2230, 2271, 2406, 15807, 15747, 15883, 16139, 16418, 16367, 16001, 16126, 15946, 25244, - 25255, 25335, 25656, 25489, 25704, 25656, 25704, 25712, 41091, 40988, 40941, 40656, 40503, - 40814, 41266, 41059, 41168, 41558, 41460, 41557, 41266, 41168, 41269, 19334, 19350, 19294, - 18502, 18488, 18392, 23206, 23289, 22863, 21954, 22131, 22278, 41396, 41062, 41209, 19886, - 19853, 19802, 41451, 41460, 41558, 1902, 2071, 1997, 2170, 2403, 2268, 16448, 16232, - 15841, 17766, 17818, 17789, 23206, 23545, 23289, 25068, 24753, 24967, 25068, 24967, 25126, - 38279, 38227, 38390, 39518, 39184, 39369, 39383, 39315, 39504, 39584, 39722, 39916, 1784, - 1648, 1795, 1795, 1595, 2039, 1736, 1711, 1757, 1757, 1723, 1733, 1622, 1648, - 1784, 1636, 1784, 1737, 1636, 1737, 1708, 2443, 2368, 2503, 2898, 3462, 3369, - 2898, 3599, 3462, 2933, 2947, 2949, 2850, 2630, 2584, 3652, 3737, 3757, 3652, - 3757, 3620, 3898, 4025, 4010, 3896, 3887, 3931, 3619, 3686, 3559, 11617, 11473, - 11624, 12207, 11998, 12136, 13399, 13421, 13151, 16648, 16448, 16566, 13022, 12888, 12948, - 13937, 13909, 13870, 19853, 19752, 19720, 22131, 22306, 22278, 25244, 25335, 25361, 28446, - 28476, 28525, 29824, 29746, 30261, 31419, 31203, 31423, 30798, 31031, 30868, 30521, 30558, - 30586, 30567, 30558, 30521, 30521, 30236, 30567, 36617, 36750, 36847, 40832, 40656, 40814, - 40571, 40184, 40474, 40982, 41064, 41011, 41033, 40941, 40901, 28588, 28640, 28564, 28560, - 28640, 28588, 28281, 28173, 28102, 31203, 31195, 31423, 32513, 32630, 32663, 39985, 39940, - 39797, 39957, 39940, 39985, 5463, 5495, 5632, 5438, 5308, 5389, 5550, 5632, 5608, - 8452, 8390, 8565, 9039, 8863, 9316, 8048, 8326, 8361, 8390, 8326, 8289, 37142, - 36977, 37067, 37142, 37067, 37228, 24126, 24158, 24230, 25640, 25687, 25408, 24219, 24158, - 24126, 4025, 4148, 4170, 5237, 5518, 4089, 4025, 4170, 4010, 22278, 22306, 22309, - 24220, 24529, 24244, 31031, 30902, 30868, 38163, 37803, 37741, 38163, 38122, 38190, 38530, - 38412, 38059, 37772, 37797, 37784, 36724, 36766, 36634, 1609, 1968, 1839, 1753, 1944, - 1689, 19334, 19294, 19321, 2584, 2630, 2389, 2470, 2391, 2255, 2045, 1979, 1833, - 1979, 2015, 1925, 1898, 1860, 1689, 1842, 1902, 1997, 3716, 3768, 3907, 6750, - 6708, 6903, 5658, 5846, 5776, 6750, 6903, 6827, 7029, 7052, 6876, 7265, 7052, - 7029, 7394, 7177, 7110, 12238, 12685, 12418, 35574, 35607, 35606, 35868, 36035, 35848, - 36319, 36506, 36478, 35364, 35588, 35349, 35021, 35035, 34670, 39937, 39722, 39838, 6708, - 6632, 6692, 7110, 7177, 7052, 26933, 26889, 26736, 27674, 27731, 27608, 35588, 35607, - 35574, 4351, 4421, 4627, 4240, 4400, 4228, 35607, 35730, 35606, 9583, 9687, 9739, - 36847, 36750, 36978, 13681, 13937, 13870, 27668, 27731, 27674, 6632, 6442, 6535, 35730, - 35796, 35721, 2399, 2423, 2493, 2443, 2276, 2368, 2479, 2620, 2588, 2479, 2588, - 2432, 14473, 14840, 14389, 41013, 41226, 40741, 40831, 40829, 40743, 40746, 40747, 40585, - 41157, 41118, 41019, 41328, 41169, 41291, 41161, 41064, 40982, 3782, 3887, 3896, 7365, - 7371, 7403, 6046, 6433, 6317, 7953, 8084, 8108, 7454, 7156, 7177, 7394, 7454, - 7177, 22386, 22478, 22506, 24244, 24529, 24424, 30798, 30868, 30704, 35475, 35093, 34962, - 35576, 35093, 35475, 35816, 35717, 35827, 35827, 35941, 36027, 36268, 36251, 36316, 36268, - 36316, 36360, 36268, 36360, 36489, 39604, 39658, 39482, 39970, 40106, 40112, 39604, 39260, - 39464, 39604, 39464, 39628, 1708, 1737, 1754, 22478, 22558, 22506, 2146, 2261, 2234, - 2206, 2230, 2352, 2169, 2230, 2095, 5687, 6046, 6032, 5475, 5466, 5631, 5518, - 4420, 4089, 37081, 37011, 36819, 37249, 37142, 37228, 40942, 40829, 40831, 24424, 24529, - 24548, 24529, 24603, 24548, 24158, 24334, 24230, 24219, 24334, 24158, 35117, 35021, 34967, - 36051, 36035, 35868, 1602, 1708, 1754, 1925, 2015, 2036, 1886, 1807, 1896, 1688, - 1807, 1886, 4240, 4218, 4421, 9820, 9807, 9950, 10163, 10065, 10141, 10283, 10567, - 10524, 18313, 18502, 18392, 17766, 17789, 17704, 23671, 23691, 23460, 23691, 23397, 23460, - 2947, 2866, 2949, 2726, 2842, 2896, 25178, 25068, 25126, 25361, 25335, 25401, 25361, - 25401, 25489, 7876, 7953, 8108, 36478, 36724, 36634, 37056, 36724, 36478, 36035, 36155, - 35955, 10143, 10413, 10409, 12244, 12034, 11919, 10491, 10413, 10209, 1723, 1860, 1733, - 18313, 18392, 18161, 19321, 19149, 18969, 25839, 25656, 25712, 26779, 26404, 26912, 27146, - 26912, 27145, 27560, 27250, 27615, 40756, 40508, 40395, 40815, 40747, 40746, 41515, 41328, - 41291, 41515, 41291, 41391, 32179, 32391, 32115, 32777, 32850, 32831, 32286, 32391, 32179, - 32647, 32630, 32513, 1806, 2305, 1830, 1711, 1723, 1757, 18931, 18895, 18969, 7458, - 7416, 7696, 7365, 7403, 7261, 5495, 5308, 5438, 5229, 5308, 5495, 2028, 2016, - 2114, 1926, 2016, 2028, 41118, 41119, 41013, 41147, 41119, 41118, 2668, 2726, 2896, - 2313, 2403, 2170, 6021, 6215, 6123, 2852, 2866, 2947, 3559, 3686, 3641, 2852, - 2933, 2842, 13553, 13346, 13180, 13495, 13346, 13553, 13495, 13728, 13589, 14147, 14314, - 14364, 17922, 18058, 17928, 17554, 17766, 17704, 17818, 17766, 17922, 30567, 30236, 30695, - 28250, 28281, 28102, 39940, 39937, 39838, 40508, 40284, 40395, 40081, 39928, 39730, 41269, - 41168, 41148, 41236, 41396, 41209, 2146, 2234, 2271, 2169, 2271, 2230, 2706, 2831, - 2822, 11448, 11473, 11617, 11340, 11473, 11448, 11915, 11998, 11827, 14822, 15221, 15181, - 22506, 22558, 22631, 24548, 24603, 24784, 24334, 24355, 24447, 26535, 26666, 26648, 24383, - 24355, 24334, 32651, 32850, 32777, 34881, 34670, 34756, 35117, 35035, 35021, 40756, 40395, - 40613, 41429, 41207, 41492, 3737, 3558, 3806, 3572, 3558, 3737, 6123, 6215, 6275, - 5348, 6046, 5687, 14431, 14147, 14364, 13937, 14070, 13909, 14057, 14070, 13937, 18969, - 18895, 18918, 27609, 27560, 27615, 27862, 27893, 27924, 28015, 28108, 28027, 36687, 36360, - 36546, 36647, 36546, 36617, 36155, 36331, 36150, 39095, 38806, 38921, 39518, 39275, 39184, - 39371, 39275, 39384, 39579, 39504, 39582, 1659, 1806, 1830, 1659, 1830, 1875, 18225, - 17983, 17745, 18618, 18786, 18776, 22742, 22460, 22517, 24383, 24516, 24355, 41328, 41308, - 41169, 41568, 41308, 41328, 2169, 2146, 2271, 2276, 2443, 2192, 5314, 5237, 5134, - 3898, 4010, 3931, 10320, 10283, 10524, 26028, 25879, 26139, 25178, 25126, 25208, 25687, - 25301, 25408, 31688, 31761, 31639, 31773, 31784, 32029, 3559, 3641, 3502, 3716, 3726, - 3768, 3768, 3782, 3896, 3887, 3784, 3931, 2268, 2239, 2109, 26386, 26028, 26139, - 25839, 25868, 25751, 40656, 40850, 40657, 40891, 41033, 40901, 40988, 41091, 40982, 40848, - 40850, 40656, 2479, 2399, 2493, 2697, 2706, 2822, 2697, 2822, 2911, 28391, 28232, - 28407, 27731, 27802, 27948, 27762, 27802, 27731, 27429, 27367, 27531, 3532, 3726, 3716, - 30558, 30677, 30704, 31423, 31515, 31419, 31419, 31515, 31384, 29187, 29248, 29916, 38982, - 38927, 38897, 39658, 39833, 39634, 5573, 5550, 5608, 5395, 5550, 5573, 23050, 23188, - 23257, 23073, 23188, 23050, 41411, 41396, 41236, 41295, 41269, 41148, 41295, 41148, 41389, - 4420, 4209, 4128, 5419, 5466, 5475, 37158, 37011, 37081, 37427, 37395, 37614, 3726, - 3782, 3768, 40747, 40751, 40613, 40815, 40751, 40747, 40752, 40751, 40806, 1723, 1689, - 1860, 2016, 2064, 2114, 1926, 2064, 2016, 10283, 10163, 10141, 9820, 9950, 9991, - 10131, 10163, 10283, 13421, 13491, 13729, 12034, 11760, 11919, 25178, 25208, 25244, 31423, - 31195, 31219, 1869, 1833, 1979, 1961, 2036, 2310, 23935, 23545, 24244, 24784, 24603, - 24753, 24355, 24516, 24447, 24219, 24126, 23908, 37372, 37249, 37395, 38200, 38424, 38511, - 11412, 11815, 11222, 11967, 11998, 12207, 13589, 13728, 13864, 13399, 13491, 13421, 40217, - 40201, 40447, 39957, 39937, 39940, 9820, 9991, 9999, 32068, 32050, 32024, 32533, 32647, - 32513, 32630, 32651, 32777, 37772, 37938, 37798, 37797, 38034, 37820, 18918, 18895, 18721, - 18895, 18754, 18721, 22478, 22708, 22558, 22708, 22710, 22558, 1842, 1997, 1922, 1753, - 1790, 2049, 1656, 1790, 1753, 5550, 5463, 5632, 4351, 4627, 4570, 5395, 5463, - 5550, 5419, 5475, 5394, 15747, 15589, 15549, 15946, 15840, 16001, 17100, 17224, 17533, - 18381, 18267, 18225, 18344, 18267, 18381, 25687, 25736, 25729, 25640, 25736, 25687, 33955, - 33911, 33905, 34139, 34283, 34436, 37158, 37081, 37142, 38800, 38923, 38897, 38659, 38345, - 38412, 40878, 40882, 40660, 41338, 41236, 41266, 41460, 41325, 41557, 25568, 25361, 25489, - 25568, 25489, 25656, 41105, 41033, 40891, 2584, 2546, 2749, 2389, 2546, 2584, 27560, - 27395, 27193, 27456, 27395, 27560, 41331, 41338, 41266, 41159, 41011, 41064, 14674, 14593, - 14529, 13717, 13589, 13864, 14460, 14593, 14539, 27172, 27146, 27145, 26028, 25839, 25879, - 40474, 39973, 40112, 40900, 40878, 40657, 40832, 40848, 40656, 8390, 8697, 8565, 9316, - 9623, 9822, 8390, 8452, 8326, 41439, 41520, 41322, 41454, 41628, 41448, 41448, 41510, - 41176, 41621, 41520, 41439, 41531, 41385, 41535, 41385, 41401, 41535, 41401, 41614, 41535, - 41415, 41614, 41401, 14842, 15125, 15081, 13892, 14057, 13937, 27779, 27615, 27862, 27779, - 27609, 27615, 27762, 27668, 27531, 28254, 28392, 28281, 41415, 41451, 41552, 1806, 1702, - 2155, 1602, 1702, 1487, 3748, 3620, 3850, 4400, 4240, 4421, 5131, 4873, 5068, - 18721, 18754, 18645, 20317, 20183, 20114, 20114, 20121, 20055, 20055, 19899, 19971, 19971, - 19899, 19886, 19886, 19899, 19853, 19853, 19728, 19752, 19752, 19728, 19668, 20332, 20367, - 20317, 20566, 20367, 20332, 20616, 20367, 20566, 20674, 20983, 20764, 21208, 21196, 21328, - 21208, 21328, 21303, 21328, 21697, 21462, 21462, 21697, 21537, 22708, 22811, 22710, 28476, - 28407, 28634, 28281, 28392, 28335, 27955, 27948, 27802, 31809, 31761, 31688, 31818, 31761, - 31809, 41552, 41451, 41558, 1869, 1979, 1925, 1961, 2310, 1798, 1842, 1922, 1683, - 17307, 17100, 17533, 41225, 41159, 41064, 20367, 20267, 20317, 41590, 41510, 41448, 36755, - 36647, 36617, 1595, 1839, 1921, 1711, 1625, 1723, 1723, 1625, 1689, 1595, 1795, - 1648, 1595, 1648, 1622, 1784, 1636, 1622, 20267, 20183, 20317, 35796, 35943, 35868, - 36035, 36201, 36155, 36155, 36178, 36331, 35730, 35846, 35796, 35607, 35624, 35730, 35588, - 35624, 35607, 35697, 35588, 35364, 39957, 39985, 40103, 5466, 5490, 5687, 5314, 5419, - 5394, 21697, 21684, 21537, 33911, 33789, 33522, 33948, 33789, 33911, 36978, 36750, 36819, - 37249, 37158, 37142, 37249, 37228, 37395, 41510, 41502, 41176, 3791, 3347, 3699, 2682, - 2726, 2668, 13508, 13681, 13491, 13491, 13681, 13870, 27896, 27955, 27802, 6442, 6420, - 6371, 5844, 5846, 5990, 6632, 6437, 6442, 6432, 6437, 6632, 6651, 6632, 6708, - 6651, 6708, 6750, 6651, 6750, 6876, 7052, 7265, 7110, 35117, 35273, 35035, 35021, - 34670, 34967, 35891, 35816, 35827, 35093, 35037, 34962, 35941, 36109, 36027, 35624, 35846, - 35730, 11473, 11340, 11348, 11967, 12207, 12122, 15081, 15125, 15355, 17922, 17766, 17632, - 14473, 14389, 14070, 26459, 26490, 26437, 40751, 40752, 40613, 40217, 40187, 40201, 40815, - 40746, 40951, 5131, 5212, 4999, 24237, 24244, 24424, 21697, 21797, 21684, 3619, 3532, - 3716, 3740, 3784, 3782, 3098, 3171, 2866, 6437, 6420, 6442, 7454, 7514, 7445, - 11275, 11203, 11348, 36064, 36251, 36109, 35846, 35943, 35796, 36331, 36506, 36319, 32050, - 32188, 32015, 32286, 32188, 32068, 38163, 38326, 37803, 38511, 38424, 38553, 29709, 29787, - 29697, 29111, 29301, 29395, 19937, 20048, 20255, 22866, 22742, 22762, 19693, 19983, 19937, - 20048, 19983, 19840, 19410, 19492, 19334, 19410, 19334, 19321, 19410, 19321, 19319, 41325, - 41777, 41557, 5880, 6092, 6021, 6420, 6320, 6371, 7445, 7514, 7558, 30677, 30798, - 30704, 31515, 31621, 31634, 29916, 29706, 29858, 34967, 34670, 34881, 36109, 36251, 36268, - 35943, 36051, 35868, 1798, 2310, 2261, 2206, 2352, 2368, 2109, 2239, 2139, 2313, - 2255, 2391, 2109, 2139, 1991, 15840, 15735, 15747, 15790, 15735, 15840, 25839, 26019, - 25868, 41188, 40942, 40833, 41226, 41013, 41119, 40900, 40657, 40850, 40882, 41105, 40891, - 41033, 41091, 40941, 40900, 40850, 40848, 1622, 1636, 1490, 3316, 3447, 3667, 3316, - 3680, 3212, 11827, 11967, 11946, 20121, 19899, 20055, 21842, 21797, 21821, 31057, 31195, - 31031, 39723, 39579, 39582, 38424, 38344, 38649, 41557, 41600, 41558, 17922, 17928, 17818, - 17419, 17519, 17554, 2752, 2852, 2842, 9999, 9991, 10065, 9807, 9583, 9739, 9999, - 10065, 10163, 19319, 19321, 18969, 18645, 18607, 18502, 28322, 28176, 28232, 28322, 28232, - 28391, 28129, 28250, 28102, 29097, 28933, 28640, 29709, 29824, 29787, 32029, 31784, 32575, - 35099, 35037, 35093, 33999, 34371, 34187, 36404, 36109, 36268, 38806, 39095, 38579, 40201, - 40187, 40082, 40217, 40447, 40372, 12822, 12888, 12594, 13022, 13399, 13151, 24450, 24237, - 24424, 25068, 24784, 24753, 24636, 24784, 24721, 25334, 25244, 25361, 40103, 39985, 40082, - 39916, 39723, 39440, 41207, 41157, 41114, 41278, 41157, 41207, 10951, 10826, 10886, 30700, - 30798, 30677, 21954, 21842, 21821, 41557, 41777, 41600, 5212, 5099, 5052, 4999, 5212, - 5052, 8048, 8191, 8014, 36978, 36819, 37011, 37314, 37499, 37614, 40814, 40503, 40517, - 39916, 39722, 39937, 6115, 6123, 6275, 7371, 7455, 7458, 7261, 7403, 6715, 6335, - 6715, 6433, 33999, 33990, 34371, 36201, 36178, 36155, 37772, 37375, 37938, 14593, 14445, - 14529, 14460, 14445, 14593, 14154, 14473, 14070, 14154, 14070, 14057, 27146, 27118, 26912, - 27395, 27172, 27145, 27280, 27172, 27395, 27456, 27560, 27682, 19899, 19728, 19853, 21954, - 22278, 21842, 34159, 34139, 34436, 36647, 36687, 36546, 36978, 37011, 37125, 27682, 27560, - 27609, 1869, 1925, 1907, 1869, 1907, 1815, 23785, 23836, 23691, 24516, 24832, 24392, - 3740, 3782, 3631, 3782, 3784, 3887, 5314, 5394, 5237, 5314, 5378, 5419, 38923, - 38982, 38897, 38959, 38982, 38923, 19319, 19172, 19306, 18664, 18645, 18551, 20686, 20249, - 20255, 23460, 23397, 23257, 1490, 1636, 1403, 22309, 22349, 22278, 7623, 7746, 7895, - 7623, 7895, 7745, 7365, 7455, 7371, 18206, 18313, 18161, 16874, 16620, 16448, 27842, - 27779, 27862, 28304, 28254, 28250, 27668, 27762, 27731, 27429, 27197, 27367, 33540, 33650, - 33465, 38070, 37925, 37946, 39814, 39833, 39658, 40106, 40481, 40112, 39814, 39658, 39604, - 29709, 29512, 29622, 28139, 28027, 28108, 39986, 39916, 39937, 40261, 40103, 40082, 40137, - 40081, 39730, 5300, 5308, 5099, 22309, 22386, 22349, 26490, 26666, 26535, 26614, 26666, - 26490, 25952, 25729, 26055, 33532, 33285, 33423, 32533, 32513, 32391, 32533, 32391, 32436, - 2170, 2142, 2313, 2008, 2235, 2064, 7712, 8048, 8014, 16367, 15946, 16126, 15735, - 15672, 15747, 16819, 16874, 16648, 24523, 24832, 24516, 25708, 25568, 25656, 25708, 25656, - 25751, 36847, 36755, 36617, 37278, 37011, 37158, 33672, 33540, 33532, 1914, 2142, 2170, - 15698, 15672, 15735, 40932, 40900, 40848, 41160, 41091, 41033, 18267, 18144, 18225, 18837, - 18786, 18829, 2301, 2432, 2226, 2443, 2423, 2263, 2165, 2276, 2192, 2663, 2697, - 2911, 4399, 4351, 4570, 3199, 3316, 3234, 4472, 4570, 4592, 4783, 4998, 4877, - 13495, 13441, 13346, 13717, 13915, 13983, 28139, 28108, 28176, 1774, 1766, 2045, 1815, - 1907, 1961, 1683, 1922, 1807, 1887, 2008, 2064, 2992, 3098, 2481, 24450, 24424, - 24548, 24450, 24548, 24636, 1926, 2028, 1902, 4714, 4783, 4877, 41105, 40882, 41106, - 41331, 41269, 41295, 24219, 24383, 24334, 23460, 23257, 23188, 41308, 41329, 41101, 41676, - 41329, 41308, 41331, 41266, 41269, 41216, 41361, 41669, 41331, 41295, 41389, 5907, 5880, - 6021, 5658, 5627, 5573, 2432, 2399, 2479, 1798, 1554, 1642, 26055, 25729, 25736, - 40752, 40756, 40613, 40187, 40261, 40082, 40951, 40746, 40829, 40951, 40829, 40942, 38459, - 38390, 38227, 37614, 37499, 37669, 38964, 39111, 39233, 11164, 11412, 11222, 12579, 12822, - 12594, 34068, 33928, 33955, 32034, 32029, 32085, 34159, 33955, 34139, 3559, 3596, 3619, - 3035, 3405, 3231, 11203, 10951, 10886, 10451, 10320, 10524, 11340, 11275, 11348, 11364, - 11275, 11340, 11827, 11998, 11967, 29097, 28640, 28560, 30567, 30700, 30677, 13399, 13022, - 13125, 13225, 13399, 13125, 13892, 14154, 14057, 28402, 28391, 28476, 28402, 28322, 28391, - 28250, 28254, 28281, 28129, 28102, 27955, 3502, 3596, 3559, 5880, 5844, 5990, 7483, - 7623, 7402, 7745, 7895, 7953, 14445, 14431, 14364, 14460, 14431, 14445, 18969, 18918, - 18924, 37249, 37278, 37158, 38326, 38163, 38279, 12507, 12594, 12244, 1835, 1926, 1743, - 2644, 2831, 2706, 3296, 3217, 3369, 3757, 3850, 3620, 12122, 12207, 12191, 13892, - 13937, 13882, 14473, 14842, 15081, 27367, 27197, 26889, 27993, 28129, 27955, 27367, 26889, - 27036, 29824, 29709, 29622, 31137, 30999, 31444, 41157, 41147, 41118, 41293, 41147, 41157, - 41298, 41161, 40982, 4134, 4218, 3748, 11135, 10951, 11203, 23671, 23785, 23691, 23591, - 23785, 23671, 30835, 30700, 30567, 30798, 31057, 31031, 32286, 32179, 32188, 25408, 25220, - 24979, 24300, 24383, 24219, 25524, 25334, 25361, 25751, 25656, 25839, 25408, 24979, 24814, - 1053, 1625, 999, 1510, 1656, 1283, 1790, 1688, 1886, 18918, 18721, 18865, 18924, - 18918, 18865, 22742, 23073, 23050, 23068, 23073, 22742, 4656, 4588, 4906, 32647, 32651, - 32630, 32286, 32463, 32379, 3199, 3217, 3296, 12685, 13180, 12418, 2697, 2644, 2706, - 2663, 2644, 2697, 27859, 27842, 27940, 28027, 27842, 27862, 27779, 27682, 27609, 27280, - 27118, 27172, 25839, 26028, 26019, 31621, 31515, 31423, 40799, 40756, 40752, 15672, 15589, - 15747, 15679, 15589, 15672, 26313, 26459, 26437, 25777, 26055, 25736, 5844, 5776, 5846, - 34218, 34371, 33990, 2008, 1991, 2139, 2109, 2056, 2170, 1958, 1991, 2008, 25524, - 25361, 25568, 5419, 5378, 5466, 6036, 6335, 6433, 4209, 4060, 4128, 8390, 8378, - 8651, 8651, 8863, 9039, 10413, 10491, 10765, 8048, 8239, 8326, 8259, 8239, 8048, - 37798, 37892, 37797, 37893, 37960, 37938, 22349, 22386, 22441, 22386, 22506, 22441, 31926, - 31818, 31809, 33843, 33209, 33789, 13190, 13180, 13346, 35816, 35576, 35475, 34681, 34450, - 34590, 35988, 35576, 35816, 35988, 35816, 35891, 35988, 35891, 36027, 35988, 36027, 36109, - 1774, 2045, 1833, 1702, 1602, 1754, 1774, 1654, 1668, 2111, 2313, 2142, 2111, - 2255, 2313, 2535, 2682, 2668, 2726, 2610, 2842, 13589, 13586, 13495, 13717, 13586, - 13589, 13412, 13508, 13491, 13412, 13491, 13399, 18618, 18344, 18381, 15651, 15790, 15826, - 18246, 18344, 18622, 18206, 18161, 18058, 18206, 18106, 18252, 23785, 23908, 23836, 23778, - 23908, 23785, 26287, 26459, 26313, 28322, 28139, 28176, 28453, 28139, 28322, 27993, 27955, - 27896, 28560, 28588, 28392, 40201, 40284, 40447, 39964, 39937, 39957, 41638, 41558, 41600, - 41389, 41148, 41159, 30962, 31057, 30798, 36721, 36755, 36827, 36755, 36847, 37004, 35125, - 34967, 35008, 35125, 35117, 34967, 35125, 35289, 35117, 35117, 35289, 35273, 35579, 35697, - 35364, 35944, 35970, 35846, 35846, 35970, 35943, 35943, 35970, 36051, 36051, 36201, 36035, - 34967, 34881, 35008, 35944, 35846, 35624, 36178, 36506, 36331, 4783, 4656, 4906, 4999, - 4873, 5131, 4962, 4873, 4999, 22441, 22506, 22631, 24636, 24548, 24784, 24383, 24523, - 24516, 24377, 24523, 24383, 1487, 1702, 1499, 19318, 19118, 19504, 22811, 22814, 22710, - 6036, 6433, 6046, 7345, 7416, 7455, 7177, 7023, 7052, 6634, 6651, 6876, 6297, - 6320, 6420, 6181, 6115, 6320, 6320, 6115, 6275, 6123, 5974, 6021, 5880, 5803, - 5844, 5844, 5659, 5776, 7156, 7023, 7177, 7156, 7454, 7213, 5378, 5490, 5466, - 4209, 4148, 4060, 8239, 8289, 8326, 8259, 8289, 8239, 13225, 13412, 13399, 12302, - 12507, 12244, 28560, 28392, 28481, 33540, 33816, 33650, 33672, 33816, 33540, 39723, 39728, - 39579, 39233, 39111, 39371, 39964, 39957, 40276, 38459, 38227, 38511, 39111, 39275, 39371, - 15589, 15500, 15549, 15946, 15790, 15840, 15698, 15790, 15651, 25708, 25524, 25568, 24721, - 24784, 24874, 27118, 27146, 27172, 35008, 34881, 34756, 27901, 27896, 27762, 27467, 27507, - 27669, 10451, 10524, 10826, 31057, 31219, 31195, 1656, 1753, 1283, 1835, 2064, 1926, - 18865, 18721, 18664, 18206, 18058, 18106, 23289, 23545, 23628, 23935, 24244, 24136, 27280, - 27395, 27446, 27682, 27779, 27761, 5776, 5627, 5658, 5510, 5627, 5776, 26448, 26287, - 26238, 26493, 26614, 26459, 24814, 24979, 24832, 2276, 2206, 2368, 2165, 2206, 2276, - 4351, 4228, 4400, 4588, 4472, 4592, 4417, 4472, 4588, 13441, 13190, 13346, 15503, - 15500, 15589, 27761, 27779, 27842, 28446, 28402, 28476, 27859, 27761, 27842, 32627, 32651, - 32647, 32379, 32436, 32391, 32379, 32391, 32286, 40081, 40143, 40106, 40571, 40814, 40517, - 40832, 40932, 40848, 40355, 40143, 40081, 40987, 40951, 40942, 40815, 40806, 40751, 1766, - 1659, 1875, 1674, 1774, 1668, 6432, 6420, 6437, 17519, 17419, 17215, 24136, 24244, - 24237, 36317, 36201, 36051, 4746, 4656, 4783, 32627, 32647, 32533, 37892, 38034, 37797, - 37996, 38034, 37892, 38459, 38511, 38701, 5099, 5308, 5142, 4714, 4746, 4783, 20764, - 20983, 21196, 20367, 20308, 20267, 20267, 20308, 20183, 20183, 20121, 20114, 19899, 19832, - 19728, 19728, 19318, 19668, 20764, 21196, 21095, 21196, 21208, 21095, 21208, 21236, 21095, - 21303, 21236, 21208, 21303, 21328, 21462, 21303, 21462, 21363, 21462, 21537, 21586, 21537, - 21684, 21586, 37669, 37499, 37901, 37417, 37372, 37395, 41520, 41628, 41454, 41510, 41617, - 41502, 41502, 41738, 41092, 41531, 41621, 41439, 41701, 41621, 41531, 41701, 41531, 41688, - 41614, 41415, 41552, 41614, 41552, 41638, 41552, 41558, 41638, 21586, 21684, 21751, 39986, - 40378, 40079, 41621, 41664, 41520, 41664, 41628, 41520, 2131, 2146, 2169, 18721, 18645, - 18664, 24165, 24136, 24237, 24784, 25068, 24874, 29916, 29918, 29947, 31142, 31167, 31057, - 31057, 31167, 31219, 30041, 29918, 29858, 41339, 41278, 41207, 41188, 41122, 40942, 10199, - 10283, 10320, 11275, 11135, 11203, 11364, 11135, 11275, 11448, 11617, 11827, 11946, 11967, - 12122, 41628, 41590, 41448, 2852, 2752, 2866, 2499, 2668, 2546, 13983, 13915, 14147, - 13586, 13441, 13495, 13983, 14147, 14099, 20282, 20308, 20367, 34606, 34187, 34371, 34606, - 34703, 34187, 33285, 33085, 33423, 37417, 37395, 37427, 41590, 41617, 41510, 39633, 39319, - 38864, 39833, 40137, 39730, 39685, 39628, 39633, 3834, 4148, 4025, 3596, 3532, 3619, - 3403, 3532, 3596, 3396, 3596, 3502, 3066, 3231, 3098, 18344, 18144, 18267, 18246, - 18144, 18344, 31219, 31448, 31423, 31481, 31448, 31432, 33928, 33948, 33911, 34681, 34590, - 35037, 39728, 39723, 39776, 39728, 39383, 39579, 21751, 21684, 21797, 41343, 41702, 41643, - 4140, 4228, 4351, 40790, 40761, 40508, 40958, 40806, 40815, 41189, 40814, 41340, 41106, - 40882, 40878, 41375, 41225, 41161, 5976, 5974, 6123, 7455, 7416, 7458, 7261, 7455, - 7365, 20308, 20121, 20183, 21842, 21751, 21797, 41617, 41637, 41502, 12123, 11946, 12122, - 12191, 12207, 12238, 11727, 11919, 11760, 39776, 39723, 39898, 39628, 39713, 39604, 3652, - 3572, 3737, 3316, 3199, 3296, 3748, 4218, 4071, 19118, 18837, 18829, 19078, 18837, - 19118, 18645, 18502, 18551, 19983, 20048, 19937, 19840, 19983, 19693, 19599, 19492, 19452, - 19492, 19410, 19452, 19410, 19306, 19452, 21842, 22278, 21751, 23935, 23628, 23545, 24427, - 24237, 24450, 41336, 41389, 41159, 41411, 41236, 41338, 41225, 41064, 41161, 2095, 2131, - 2169, 14539, 14593, 14674, 15790, 15698, 15735, 15679, 15698, 15651, 25507, 25524, 25708, - 26019, 26028, 26386, 2610, 2752, 2842, 12128, 12191, 12238, 13336, 13441, 13586, 13882, - 13937, 13681, 13022, 12949, 13125, 12579, 12594, 12507, 41411, 41338, 41436, 25373, 25524, - 25507, 5974, 5907, 6021, 7623, 7483, 7558, 8413, 8252, 7986, 8541, 8252, 8413, - 35099, 34681, 35037, 34606, 34614, 34655, 36201, 36506, 36178, 12418, 13180, 13190, 39825, - 39814, 39604, 18144, 18014, 18225, 18117, 18014, 18144, 20121, 19927, 19899, 23171, 23460, - 23188, 24741, 24814, 24523, 23171, 23188, 23073, 34159, 34068, 33955, 33948, 34068, 34227, - 39233, 39095, 38964, 38349, 38279, 38390, 41436, 41338, 41331, 41669, 41361, 41643, 5052, - 4962, 4999, 4954, 4962, 5052, 5495, 5463, 5229, 24636, 24427, 24450, 25178, 25244, - 25334, 41298, 40982, 41091, 18837, 18776, 18786, 18690, 18776, 18715, 22814, 22811, 22863, - 21751, 22278, 22434, 22814, 22863, 22856, 31481, 31621, 31423, 31481, 31423, 31448, 36721, - 36647, 36755, 37582, 37417, 37427, 37582, 37427, 37614, 40814, 40932, 40832, 42044, 41391, - 41251, 41339, 41293, 41278, 14790, 14822, 14709, 13354, 13336, 13586, 32068, 32188, 32050, - 32587, 32627, 32533, 33423, 32831, 32850, 38349, 38326, 38279, 38511, 38553, 38701, 4563, - 4534, 4656, 4656, 4534, 4588, 4472, 4408, 4570, 19927, 19832, 19899, 22278, 22349, - 22457, 27367, 27467, 27531, 28304, 28481, 28254, 26933, 26736, 26666, 32587, 32533, 32436, - 38034, 38070, 37946, 38659, 38959, 38800, 38067, 38070, 38034, 1970, 2056, 2109, 1835, - 1887, 2064, 1926, 1902, 1743, 25373, 25178, 25334, 5907, 5803, 5880, 34703, 34606, - 34655, 2992, 3066, 3098, 12424, 12418, 12667, 14539, 14790, 14699, 14257, 14147, 14431, - 14154, 14310, 14473, 17419, 16930, 17215, 13882, 13681, 13723, 27842, 28027, 27940, 27446, - 27395, 27456, 26246, 26019, 26278, 38699, 38553, 38649, 40481, 40474, 40112, 41105, 41106, - 41479, 40481, 40106, 40438, 4071, 4218, 4240, 30835, 30798, 30700, 39094, 38959, 39235, - 4714, 4877, 4873, 19410, 19319, 19306, 18551, 18502, 18535, 18502, 18427, 18535, 22457, - 22349, 22441, 22856, 22863, 23289, 28402, 28448, 28322, 28525, 28476, 28634, 1674, 1659, - 1766, 1674, 1766, 1774, 1656, 1688, 1790, 1587, 1688, 1656, 18014, 17983, 18225, - 18039, 17983, 18014, 23460, 23591, 23671, 24523, 24814, 24832, 23597, 23591, 23460, 1622, - 1490, 1595, 1205, 1455, 1609, 1609, 1455, 1736, 1403, 1636, 1415, 1636, 1708, - 1415, 22457, 22441, 22631, 36721, 36687, 36647, 36847, 36978, 37004, 26459, 26614, 26490, - 26287, 26313, 26055, 40806, 40799, 40752, 40934, 40799, 40806, 40793, 40799, 40934, 2492, - 2663, 2532, 2644, 2495, 2831, 2263, 2423, 2399, 2206, 2095, 2230, 3120, 3369, - 3217, 27896, 27802, 27762, 30041, 30065, 29918, 12503, 12579, 12507, 13723, 13681, 13508, - 39964, 39986, 39937, 40276, 39957, 40103, 40358, 40187, 40217, 41106, 40878, 40900, 3898, - 3931, 3719, 18969, 19172, 19319, 32034, 31818, 31926, 32034, 31926, 32029, 38737, 38699, - 38649, 4962, 4794, 4873, 5229, 5463, 5234, 15698, 15679, 15672, 15651, 15826, 15546, - 24440, 24427, 24636, 22923, 22856, 23004, 25178, 24874, 25068, 24300, 24219, 23908, 25777, - 25736, 25640, 41278, 41293, 41157, 41339, 41207, 41429, 3740, 3931, 3784, 8681, 8863, - 8651, 12112, 12027, 11970, 8319, 8390, 8289, 18502, 18313, 18427, 18969, 18924, 19172, - 22631, 22558, 22710, 23628, 23935, 23859, 3347, 3791, 3235, 3631, 3782, 3567, 10199, - 10320, 10245, 11664, 11448, 11827, 11364, 11448, 11664, 11827, 11946, 11811, 17726, 17307, - 17533, 23778, 24300, 23908, 29918, 30065, 29947, 29918, 29916, 29858, 34681, 34436, 34283, - 37278, 37249, 37372, 6855, 6876, 7052, 6115, 6098, 6123, 5974, 5976, 5907, 5907, - 5860, 5803, 6548, 6651, 6634, 35970, 36317, 36051, 36201, 36317, 36506, 35579, 35364, - 35273, 35401, 35273, 35289, 35401, 35289, 35445, 35401, 35445, 35593, 23859, 23935, 23949, - 39342, 39173, 39095, 38953, 38825, 38579, 39518, 39369, 39383, 39518, 39383, 39728, 41461, - 41436, 41331, 41643, 41361, 41343, 41461, 41331, 41389, 2263, 2399, 2266, 1798, 2261, - 1554, 25777, 25640, 25408, 8143, 8259, 7807, 37205, 37278, 37444, 37278, 37372, 37444, - 6367, 6432, 6632, 35008, 34756, 34895, 35806, 35944, 35624, 3234, 3316, 3212, 3572, - 3652, 3620, 3470, 3572, 3620, 18924, 19092, 19172, 29709, 29697, 29512, 29787, 29971, - 29868, 37765, 37669, 37901, 38459, 38349, 38390, 38333, 38349, 38495, 2309, 2389, 2630, - 2682, 2610, 2726, 2309, 2646, 2255, 6432, 6297, 6420, 14460, 14410, 14431, 14539, - 14410, 14460, 14539, 14674, 14790, 18924, 18865, 18811, 18427, 18313, 18252, 27522, 27456, - 27682, 27522, 27682, 27761, 36489, 36360, 36687, 36404, 35988, 36109, 35576, 35099, 35093, - 34681, 34750, 34436, 2491, 2495, 2644, 2389, 2499, 2546, 2945, 2550, 2694, 10199, - 10131, 10283, 10826, 10951, 10552, 27859, 27522, 27761, 31432, 31448, 31219, 32024, 32050, - 31634, 31601, 31481, 31719, 38953, 38579, 39095, 38495, 38349, 38459, 6297, 6209, 6320, - 3199, 3120, 3217, 11919, 12027, 12244, 12027, 11919, 11970, 29697, 29488, 29512, 39898, - 39723, 39916, 39814, 39917, 39833, 39713, 39825, 39604, 39772, 39825, 39713, 39685, 39713, - 39628, 38484, 38530, 38059, 2554, 2644, 2663, 2554, 2569, 2644, 13983, 13795, 13717, - 13441, 13267, 13190, 13965, 13795, 13983, 13892, 13976, 14154, 17519, 17632, 17554, 13723, - 13508, 13554, 12948, 12793, 13022, 27940, 28027, 28139, 27940, 28139, 28063, 1970, 2109, - 1991, 1958, 2008, 1887, 6209, 6181, 6320, 5395, 5573, 5627, 7213, 7454, 7445, - 24440, 24636, 24721, 26132, 25777, 26094, 24300, 24377, 24383, 24741, 24377, 24454, 2266, - 2399, 2432, 2164, 2309, 2255, 40799, 40793, 40756, 40958, 40815, 40970, 2063, 2095, - 2206, 1774, 1833, 1654, 2063, 2206, 2165, 5659, 5844, 5803, 4399, 4354, 4257, - 8259, 8319, 8289, 8143, 8319, 8259, 26779, 26912, 27118, 25507, 25708, 25703, 25524, - 25373, 25334, 25178, 25209, 24874, 24440, 24165, 24427, 18865, 18801, 18811, 18252, 18313, - 18206, 22866, 23068, 22742, 23591, 23597, 23785, 19524, 19318, 19728, 18622, 18344, 18618, - 18664, 18801, 18865, 1866, 1958, 1887, 3782, 3726, 3567, 3834, 4060, 4148, 10154, - 10413, 10143, 12154, 12302, 12244, 40004, 39898, 39916, 40004, 39916, 39986, 41146, 41160, - 41033, 41324, 41336, 41159, 41146, 41033, 41105, 6181, 6098, 6115, 7201, 7213, 7445, - 7402, 7445, 7483, 7416, 7390, 7696, 7191, 7261, 6519, 34756, 34703, 34792, 34895, - 34756, 34792, 9732, 9807, 9820, 28857, 28525, 28634, 28481, 28392, 28254, 36474, 36489, - 36841, 37009, 37004, 36978, 2581, 2610, 2682, 3834, 4025, 3898, 4013, 5134, 5237, - 10131, 9999, 10163, 9983, 9999, 10131, 40761, 40284, 40508, 18664, 18551, 18801, 41343, - 41827, 41702, 6098, 5976, 6123, 7261, 7345, 7455, 34792, 34703, 34655, 40970, 40815, - 40951, 1833, 1869, 1654, 1499, 1702, 1806, 4228, 4071, 4240, 3513, 3470, 3620, - 4417, 4408, 4472, 4417, 4588, 4534, 5062, 5052, 5099, 17554, 17632, 17766, 16930, - 16874, 16819, 22923, 22814, 22856, 23949, 23935, 24136, 12302, 12503, 12507, 23068, 23171, - 23073, 22935, 23171, 23068, 29395, 29301, 29512, 38382, 37803, 38326, 37205, 37125, 37011, - 1776, 1902, 1842, 41342, 41298, 41091, 41324, 41159, 41225, 41616, 41396, 41411, 9168, - 9623, 9316, 9168, 9316, 8863, 5229, 5142, 5308, 5101, 5142, 5229, 4052, 4420, - 4128, 5297, 5490, 5378, 6335, 6238, 6715, 5297, 5378, 5314, 7876, 7745, 7953, - 8252, 8541, 8403, 8319, 8378, 8390, 8143, 8378, 8319, 7345, 7390, 7416, 19318, - 19078, 19118, 17983, 17868, 17533, 34606, 34371, 34614, 36827, 36687, 36721, 26055, 25777, - 26132, 41250, 41106, 40900, 41452, 41375, 41298, 41512, 41538, 41405, 14410, 14257, 14431, - 15047, 15221, 14822, 40790, 40756, 40793, 40790, 40508, 40756, 13336, 13267, 13441, 12123, - 12122, 12191, 13586, 13717, 13597, 12948, 12822, 12793, 40358, 40261, 40187, 40276, 40261, - 40358, 2499, 2535, 2668, 2393, 2535, 2499, 2393, 2499, 2389, 3474, 3726, 3532, - 3235, 3791, 3405, 3035, 3231, 3066, 11448, 11364, 11340, 12128, 12238, 12418, 25708, - 25751, 25703, 24427, 24165, 24237, 39533, 39518, 39742, 39742, 39518, 39980, 39371, 39346, - 39233, 41479, 41146, 41105, 10917, 11164, 11222, 12027, 12154, 12244, 12368, 12484, 12503, - 1914, 2111, 2142, 2338, 2393, 2238, 1914, 2170, 2056, 1970, 1991, 1958, 5976, - 5860, 5907, 15679, 15503, 15589, 15651, 15503, 15679, 18690, 18618, 18776, 18801, 18551, - 18491, 18106, 18058, 18068, 33922, 33816, 33873, 34614, 34371, 34545, 41122, 40987, 40942, - 40923, 40790, 40793, 3743, 3898, 3719, 3743, 3834, 3898, 10451, 10826, 10552, 22631, - 22710, 22814, 22631, 22814, 22923, 2263, 2192, 2443, 2267, 2266, 2432, 2267, 2432, - 2301, 40934, 40806, 40958, 1499, 1806, 1505, 1654, 1869, 1673, 39384, 39346, 39371, - 41482, 41461, 41389, 2492, 2554, 2663, 3199, 3149, 3120, 3212, 3680, 3558, 30920, - 30381, 30999, 29697, 29630, 29488, 29488, 29395, 29512, 39190, 38927, 38982, 39825, 39917, - 39814, 39190, 38982, 39175, 2898, 3369, 3120, 2569, 2491, 2644, 2992, 3035, 3066, - 2475, 2561, 2682, 5330, 5395, 5407, 27480, 27446, 27522, 27312, 27175, 27280, 25373, - 25507, 25437, 28448, 28402, 28446, 28448, 28446, 28525, 28304, 28250, 28129, 27669, 27762, - 27531, 28041, 27896, 27901, 26933, 26666, 26614, 26493, 26459, 26287, 37205, 37011, 37278, - 36906, 36827, 36755, 20759, 20616, 20566, 20308, 20282, 20121, 20121, 20060, 19927, 19927, - 19917, 19832, 19832, 19769, 19728, 19318, 19000, 19078, 20798, 20616, 20759, 20798, 20759, - 20764, 20798, 20764, 20847, 20764, 20922, 20847, 21095, 20922, 20764, 21155, 20922, 21095, - 21155, 21095, 21236, 20534, 20686, 20255, 20283, 20255, 20193, 20255, 20048, 20193, 20048, - 20092, 20193, 19906, 20092, 20048, 30780, 30835, 30567, 30780, 30567, 30695, 41664, 41724, - 41628, 41912, 41795, 41590, 41590, 41695, 41617, 41617, 41695, 41637, 41637, 41742, 41502, - 41621, 41724, 41664, 41701, 41724, 41621, 41531, 41535, 41688, 41535, 41614, 41688, 41614, - 42037, 41688, 41688, 41863, 41761, 1637, 1776, 1842, 1835, 1866, 1887, 21303, 21155, - 21236, 41207, 41112, 41492, 41293, 41315, 41147, 41495, 41482, 41389, 41375, 41324, 41225, - 41375, 41161, 41298, 21303, 21363, 21155, 28678, 28448, 28525, 29722, 29630, 29697, 33423, - 32850, 32827, 32827, 32651, 32627, 32463, 32436, 32379, 34218, 33990, 33922, 41486, 41411, - 41436, 41701, 41688, 41761, 21462, 21586, 21363, 42037, 41863, 41688, 2075, 2164, 2255, - 26448, 26493, 26287, 20616, 20282, 20367, 19767, 19840, 19693, 18246, 18117, 18144, 16367, - 16418, 17100, 18039, 18117, 18246, 18551, 18535, 18491, 18068, 18058, 17922, 19599, 19767, - 19693, 41795, 41695, 41590, 41437, 41315, 41339, 4408, 4399, 4570, 4563, 4656, 4746, - 30860, 30962, 30798, 31481, 31601, 31621, 38349, 38333, 38326, 38701, 38553, 38699, 38701, - 38699, 38737, 39094, 38982, 38959, 31258, 31219, 31167, 1205, 1609, 1595, 1510, 1587, - 1656, 1589, 1683, 1807, 2685, 2694, 2550, 12214, 12128, 12418, 12793, 12822, 12579, - 12112, 12154, 12027, 19599, 19683, 19767, 21363, 21586, 21273, 29477, 29395, 29488, 39969, - 39917, 39825, 1572, 1807, 1688, 16874, 16448, 16648, 17923, 18068, 17922, 1806, 1520, - 1505, 1490, 1469, 1595, 18535, 18427, 18491, 19599, 19600, 19683, 21155, 21363, 21283, - 22856, 23105, 23004, 5138, 6036, 6046, 5134, 5297, 5314, 5322, 5297, 5243, 20161, - 20060, 20121, 34068, 33948, 33928, 34227, 34068, 34159, 34227, 34159, 34421, 36906, 36755, - 37004, 37516, 37372, 37417, 37582, 37614, 37676, 37375, 37893, 37938, 38070, 38484, 37925, - 39143, 39094, 39235, 41695, 41742, 41637, 9999, 9732, 9820, 9983, 9732, 9999, 24440, - 24721, 24504, 25703, 25751, 25868, 27175, 27118, 27280, 31820, 31634, 31621, 20060, 19942, - 19927, 22434, 22278, 22457, 10062, 9983, 10131, 10552, 10951, 10616, 30962, 31142, 31057, - 39175, 39094, 39143, 40987, 40970, 40951, 41153, 40970, 40987, 6651, 6548, 6632, 6432, - 6223, 6297, 6297, 6223, 6209, 6142, 6024, 6181, 6181, 6024, 6098, 6098, 5958, - 5976, 5976, 5732, 5860, 6855, 7052, 7023, 6855, 7023, 6851, 6855, 6851, 6746, - 14233, 14257, 14410, 14099, 14257, 14233, 17923, 17922, 17632, 18491, 18427, 18376, 27446, - 27456, 27522, 28063, 27522, 27859, 2261, 2146, 1812, 1673, 1798, 1642, 2550, 2945, - 2992, 39898, 40029, 39776, 40079, 40004, 39986, 35697, 35806, 35624, 36141, 36317, 35970, - 38193, 38067, 37996, 35401, 35579, 35273, 35593, 35579, 35401, 35281, 35125, 35186, 34975, - 35008, 34895, 34975, 34895, 34792, 34975, 34792, 34846, 35704, 35806, 35697, 41742, 41738, - 41502, 5041, 5062, 5099, 4961, 5062, 5041, 37676, 37614, 37669, 6548, 6367, 6632, - 19452, 19454, 19599, 17999, 18252, 18106, 35806, 35911, 35944, 1804, 1866, 1835, 2111, - 2075, 2255, 1743, 1902, 1776, 7750, 7745, 7876, 7750, 7876, 7672, 36906, 37004, - 37009, 2160, 2192, 2263, 2432, 2588, 2226, 2431, 2491, 2569, 2435, 2491, 2431, - 4855, 4794, 4962, 13882, 13976, 13892, 13723, 13976, 13882, 13508, 13412, 13325, 15221, - 15386, 15181, 26759, 26933, 26614, 1403, 1469, 1490, 6953, 7156, 7213, 19306, 19454, - 19452, 4036, 4071, 4228, 3215, 3212, 3558, 12793, 12579, 12484, 28988, 28634, 29111, - 27333, 27312, 27446, 29330, 29248, 29097, 28123, 28129, 27993, 28041, 27993, 27896, 31711, - 31621, 31601, 31711, 31820, 31621, 40261, 40276, 40103, 40358, 40217, 40372, 1590, 1659, - 1674, 1673, 1869, 1815, 23356, 23289, 23447, 24440, 24504, 24366, 5292, 5322, 5243, - 3670, 4052, 4060, 3719, 3931, 3740, 10451, 10245, 10320, 19306, 19382, 19454, 29134, - 28988, 29111, 2160, 2263, 2266, 2561, 2581, 2682, 2418, 2581, 2561, 2475, 2682, - 2535, 18715, 18776, 18837, 19000, 18837, 19078, 27669, 27531, 27467, 40563, 40447, 40765, - 40460, 40447, 40563, 41009, 40761, 40790, 41002, 40934, 41127, 1753, 1100, 1283, 1706, - 1743, 1776, 18979, 18811, 18746, 17660, 17923, 17632, 23402, 23597, 23460, 26238, 26055, - 26132, 23402, 23460, 23171, 41577, 41486, 41436, 41577, 41436, 41729, 1415, 1708, 1602, - 19306, 19172, 19229, 36978, 37125, 37137, 37009, 36978, 37137, 29916, 29248, 29706, 30835, - 30860, 30798, 31111, 31258, 31142, 1861, 1970, 1958, 9732, 9583, 9807, 9083, 9583, - 9732, 4667, 4563, 4746, 4154, 4140, 4351, 6142, 6181, 6209, 5407, 5395, 5627, - 4961, 4954, 5062, 5348, 5687, 5490, 7277, 7363, 7345, 7345, 7363, 7390, 8794, - 9168, 8863, 9623, 9788, 10045, 14769, 14699, 14709, 16367, 17100, 16623, 35023, 36269, - 35143, 35099, 35576, 36430, 36404, 36268, 36489, 36404, 36489, 36474, 37996, 38067, 38034, - 36833, 36724, 37056, 39376, 39095, 39233, 39533, 39384, 39275, 39533, 39275, 39518, 1637, - 1842, 1683, 1570, 1861, 1958, 3234, 3149, 3199, 3215, 3558, 3275, 16975, 16819, - 16648, 17600, 17660, 17632, 29706, 29248, 29513, 41339, 41315, 41293, 41592, 41328, 41515, - 41416, 41375, 41452, 41495, 41389, 41336, 41324, 41375, 41416, 5062, 4954, 5052, 4794, - 4714, 4873, 4855, 4954, 4908, 8378, 8681, 8651, 8794, 8681, 8491, 37765, 37676, - 37669, 37237, 37125, 37205, 1590, 1674, 1616, 1430, 1415, 1602, 16623, 17100, 17045, - 18690, 18622, 18618, 18623, 18622, 18690, 23717, 23628, 23859, 22631, 22504, 22457, 22517, - 22460, 22456, 42362, 41592, 41515, 3028, 3149, 3234, 6024, 5958, 6098, 29513, 29248, - 29330, 34846, 34792, 34655, 34846, 34655, 34816, 36489, 36687, 36841, 39685, 39772, 39713, - 40438, 40106, 40143, 39969, 39772, 39685, 39969, 39685, 40414, 17868, 17983, 17946, 1565, - 1637, 1683, 2196, 2389, 2309, 1900, 2075, 2111, 4036, 4140, 4039, 4071, 3980, - 3748, 9502, 9788, 9623, 11293, 11412, 11164, 12424, 12214, 12418, 13597, 13717, 13795, - 28123, 28304, 28129, 29330, 29269, 29439, 31137, 30920, 30999, 32085, 32029, 32864, 31820, - 32024, 31634, 32068, 32463, 32286, 31931, 32024, 31820, 38737, 38649, 38894, 38333, 38409, - 38326, 40079, 40029, 40004, 40460, 40358, 40372, 4732, 4714, 4794, 12484, 12579, 12503, - 13986, 14154, 13976, 37056, 36478, 36506, 33922, 33990, 33816, 34371, 34218, 34404, 36901, - 36687, 36827, 37137, 37125, 37237, 1587, 1572, 1688, 1516, 1572, 1587, 18039, 18014, - 18117, 23862, 23717, 23859, 31043, 31761, 31703, 29722, 29477, 29630, 29630, 29477, 29488, - 29214, 29134, 29111, 30780, 30860, 30835, 31719, 31711, 31601, 27446, 27312, 27280, 25863, - 25868, 25955, 28063, 27859, 27940, 7390, 7712, 8014, 7277, 7345, 7261, 12128, 12123, - 12191, 10827, 10951, 11135, 10451, 10299, 10245, 12214, 12123, 12128, 11727, 11760, 11412, - 12368, 12503, 12302, 11727, 11412, 11293, 29447, 29477, 29524, 29330, 29439, 29399, 36994, - 36827, 36906, 2196, 2309, 2164, 14257, 14099, 14147, 14233, 14410, 14287, 14699, 14790, - 14709, 19092, 18924, 18979, 18924, 18811, 18979, 15386, 15500, 15181, 26933, 27036, 26889, - 28041, 28123, 27993, 27139, 27036, 26933, 26759, 26614, 26493, 3375, 3596, 3396, 3375, - 3396, 3347, 3319, 3347, 3235, 10062, 10131, 10199, 10426, 10552, 10373, 39376, 39233, - 39346, 39094, 39175, 38982, 38959, 38659, 39235, 2449, 2475, 2535, 2418, 2752, 2610, - 7398, 7402, 7623, 34816, 34655, 34614, 10114, 10199, 10245, 31258, 31167, 31142, 12418, - 13190, 12667, 29369, 29330, 29399, 4954, 4855, 4962, 5330, 5463, 5395, 26287, 26055, - 26238, 26772, 26759, 26493, 37085, 36994, 36906, 37516, 37417, 37582, 1616, 1674, 1668, - 1616, 1668, 1654, 1572, 1589, 1807, 1532, 1589, 1572, 16975, 17215, 16930, 25239, - 25178, 25373, 23949, 23862, 23859, 32364, 32463, 32068, 32129, 32068, 32024, 37628, 37516, - 37662, 37372, 37516, 37484, 38495, 38409, 38333, 41002, 40923, 40934, 41188, 40833, 41275, - 4475, 4515, 4563, 4563, 4515, 4534, 4667, 4746, 4714, 1430, 1602, 1487, 1520, - 1806, 1659, 3664, 3719, 3740, 3670, 4060, 3834, 31040, 31142, 30962, 41592, 41568, - 41328, 41676, 41568, 41953, 1430, 1487, 1466, 29097, 29269, 29330, 28036, 28123, 28041, - 35023, 34750, 34681, 40474, 41195, 40571, 40137, 39833, 40053, 4662, 4667, 4714, 37938, - 37982, 37996, 39329, 39143, 39372, 38193, 37982, 38099, 2986, 2898, 3120, 12368, 12302, - 12154, 13412, 13225, 13325, 29447, 29111, 29395, 28988, 28857, 28634, 28448, 28453, 28322, - 26040, 26094, 25777, 5659, 5803, 5860, 5297, 5322, 5490, 4052, 4128, 4060, 37390, - 37237, 37205, 37085, 36906, 37009, 5732, 5659, 5860, 34750, 34604, 34436, 31994, 31933, - 32034, 4140, 4036, 4228, 4257, 4351, 4399, 18979, 18746, 18925, 17600, 17632, 17519, - 23949, 24136, 24117, 23447, 23289, 23628, 32034, 31933, 31818, 32395, 32153, 32152, 31840, - 31820, 31711, 31840, 31931, 31820, 38701, 38495, 38459, 38894, 38649, 38825, 39189, 38953, - 39095, 1798, 1673, 1815, 2146, 2131, 1812, 3235, 3405, 3035, 3631, 3664, 3740, - 3235, 3035, 3004, 41492, 41112, 41329, 41226, 41119, 41432, 3319, 3375, 3347, 39384, - 39470, 39346, 39173, 39189, 39095, 39980, 39728, 40150, 40029, 39898, 40004, 13986, 14310, - 14154, 13225, 13245, 13325, 2267, 2160, 2266, 2014, 2063, 2165, 2226, 2588, 2244, - 2588, 2495, 2244, 3375, 3403, 3596, 18106, 18068, 17999, 39533, 39470, 39384, 27507, - 27467, 27367, 27757, 27669, 27616, 27367, 27036, 27177, 29156, 28857, 28988, 40053, 39833, - 39917, 11858, 11811, 11946, 11664, 11811, 11606, 12074, 12368, 12154, 10819, 10765, 10491, - 30695, 30236, 30636, 30860, 31040, 30962, 30128, 30331, 30041, 29706, 29776, 29858, 29817, - 29776, 29706, 29817, 29706, 29513, 29369, 29513, 29330, 33816, 33672, 33873, 34404, 34545, - 34371, 3513, 3620, 3748, 3028, 3048, 3149, 3149, 3048, 3120, 3410, 3474, 3532, - 10377, 10819, 10491, 30236, 30065, 30636, 31719, 31840, 31711, 39470, 39376, 39346, 2205, - 2160, 2267, 1978, 2196, 2164, 2338, 2449, 2535, 1978, 2164, 2075, 15373, 15500, - 15503, 14287, 14410, 14539, 15373, 15503, 15451, 36141, 35970, 35944, 36050, 36141, 35911, - 35579, 35704, 35697, 35609, 35704, 35579, 35289, 35281, 35445, 35125, 35281, 35289, 40934, - 40923, 40793, 40447, 40460, 40372, 40934, 40958, 41127, 4515, 4417, 4534, 4475, 4417, - 4515, 6855, 6634, 6876, 6548, 6377, 6367, 6367, 6223, 6432, 5725, 5732, 5958, - 5958, 5732, 5976, 6536, 6634, 6589, 32463, 32587, 32436, 32827, 32587, 32772, 5330, - 5234, 5463, 4832, 4732, 4794, 4667, 4475, 4563, 5148, 5234, 5209, 33873, 33672, - 33532, 4354, 4399, 4408, 6536, 6377, 6548, 12949, 13022, 12793, 28295, 28481, 28304, - 27757, 27901, 27762, 35008, 35186, 35125, 38409, 38382, 38326, 38617, 38495, 38701, 1466, - 1487, 1374, 3028, 3234, 3212, 11727, 11970, 11919, 12811, 12949, 12793, 18910, 19000, - 18997, 18465, 18039, 18246, 17999, 18068, 17923, 1562, 1616, 1654, 1530, 1520, 1659, - 1457, 1487, 1499, 17451, 17600, 17519, 18026, 17999, 17964, 22600, 22631, 22923, 24117, - 24136, 24165, 35008, 34975, 35186, 38973, 38894, 38953, 38953, 38894, 38825, 38314, 38382, - 38493, 3474, 3567, 3726, 6192, 6223, 6367, 6036, 6238, 6335, 6159, 6238, 5871, - 31703, 31761, 31818, 33843, 33789, 33948, 1743, 1804, 1835, 1970, 1863, 2056, 1637, - 1666, 1776, 1552, 1666, 1637, 7515, 7398, 7623, 7402, 7201, 7445, 7672, 7876, - 7986, 35186, 34975, 35209, 34309, 34404, 34218, 37085, 37009, 37137, 41429, 41437, 41339, - 41504, 41437, 41429, 1664, 1804, 1743, 5041, 5099, 5142, 20616, 20424, 20282, 20282, - 20161, 20121, 20060, 19940, 19942, 19942, 19917, 19927, 20798, 20758, 20616, 20847, 20758, - 20798, 20934, 20758, 20847, 20934, 20847, 20922, 20934, 20922, 21155, 20934, 21155, 21159, - 41912, 41590, 41628, 41695, 41795, 41742, 41742, 41864, 41738, 41738, 41822, 41092, 41701, - 41861, 41724, 41761, 41861, 41701, 41638, 42072, 41614, 41600, 41960, 41638, 6223, 6142, - 6209, 12452, 12793, 12484, 20240, 20534, 20283, 20283, 20534, 20255, 22447, 22273, 21712, - 20240, 20283, 20193, 20240, 20193, 20211, 19906, 20048, 19840, 19906, 19840, 19805, 19840, - 19767, 19805, 19767, 19683, 19600, 19599, 19454, 19600, 28857, 28678, 28525, 29134, 29156, - 28988, 28857, 28760, 28678, 29477, 29447, 29395, 29722, 29697, 29787, 28295, 28304, 28123, - 34975, 34846, 34921, 39986, 39964, 40378, 40553, 40276, 40749, 41216, 41669, 41777, 1457, - 1499, 1505, 19000, 18945, 18837, 18910, 18945, 19000, 22600, 22504, 22631, 23628, 23717, - 23447, 20787, 22004, 20686, 23269, 23402, 23171, 42158, 41669, 41643, 21159, 21155, 21283, - 40563, 40765, 40598, 40481, 40486, 40474, 41336, 41324, 41530, 40433, 40438, 40143, 1530, - 1659, 1542, 1506, 1706, 1666, 1402, 1510, 1273, 3566, 3664, 3631, 3681, 3834, - 3743, 4832, 4794, 4855, 10552, 10426, 10451, 10827, 11135, 10891, 23447, 23717, 23567, - 23597, 23714, 23785, 22935, 23068, 22866, 29971, 29787, 29824, 31703, 31818, 31933, 39481, - 38864, 39190, 39969, 40053, 39917, 38484, 38070, 38429, 34816, 34614, 34647, 36141, 35944, - 35911, 8403, 8541, 8769, 20273, 20161, 20282, 34085, 33843, 33948, 34442, 34309, 34218, - 33915, 33873, 33532, 37232, 37085, 37137, 37484, 37444, 37372, 37718, 37582, 37676, 41912, - 41628, 41724, 21283, 21363, 21273, 41127, 40958, 40970, 41119, 41147, 41432, 23830, 23717, - 23862, 24366, 24117, 24165, 24366, 24165, 24440, 25239, 25373, 25437, 41671, 41343, 41396, - 41495, 41336, 41654, 41160, 41342, 41091, 5118, 5101, 5229, 5510, 5479, 5627, 5510, - 5776, 5659, 11901, 11858, 12123, 13122, 13190, 13267, 13122, 13267, 13336, 13965, 13983, - 14099, 12356, 12368, 12074, 21273, 21586, 21483, 22667, 22600, 22923, 29447, 29214, 29111, - 31719, 31481, 31432, 32364, 32587, 32463, 34647, 34614, 34545, 34404, 34309, 34439, 37232, - 37137, 37237, 40056, 40079, 40378, 41467, 41147, 41315, 41616, 41411, 41486, 22434, 22457, - 22504, 41795, 41858, 41742, 14287, 14539, 14361, 2301, 2205, 2267, 2435, 2495, 2491, - 26615, 26772, 26493, 24741, 24523, 24377, 10426, 10299, 10451, 9983, 9979, 9732, 8424, - 8403, 8769, 20024, 19940, 20060, 41858, 41864, 41742, 1673, 1630, 1654, 1542, 1659, - 1590, 1940, 2131, 2095, 2165, 2192, 2014, 1666, 1706, 1776, 1565, 1683, 1589, - 2431, 2569, 2554, 2663, 2911, 2532, 4154, 4039, 4140, 3413, 3513, 3748, 4417, - 4354, 4408, 4296, 4354, 4417, 7283, 7201, 7402, 7363, 7200, 7390, 7191, 7277, - 7261, 14096, 13965, 14099, 13820, 13986, 13976, 13820, 13976, 13723, 16819, 16975, 16930, - 17450, 17451, 17519, 16232, 15861, 15841, 15861, 15296, 15841, 27669, 27757, 27762, 27901, - 28036, 28041, 27507, 27367, 27177, 36474, 36463, 36404, 36404, 36537, 35988, 35099, 35023, - 34681, 34750, 34726, 34604, 36841, 36463, 36474, 36901, 36827, 36994, 38617, 38382, 38409, - 38409, 38495, 38617, 17868, 17726, 17533, 18465, 18246, 18622, 17923, 17842, 17964, 17999, - 17923, 17964, 23105, 22856, 23289, 23830, 23862, 23949, 41577, 41616, 41486, 13212, 13122, - 13336, 28515, 28453, 28554, 28678, 28453, 28448, 40375, 40355, 40081, 40375, 40081, 40137, - 2073, 2205, 2301, 19940, 19917, 19942, 19600, 19454, 19545, 41864, 41844, 41738, 32827, - 32850, 32651, 37958, 37499, 37803, 18945, 18715, 18837, 18910, 18715, 18945, 4677, 4662, - 4732, 5148, 5229, 5234, 37390, 37232, 37237, 37628, 37484, 37516, 5479, 5407, 5627, - 5359, 5407, 5479, 34257, 34227, 34421, 34421, 34159, 34436, 41844, 41840, 41738, 7623, - 7745, 7515, 7398, 7283, 7402, 3403, 3410, 3532, 3474, 3423, 3567, 3622, 3719, - 3664, 3368, 3410, 3403, 3319, 3286, 3375, 2945, 3035, 2992, 13696, 13597, 13795, - 28515, 28063, 28139, 25703, 25868, 25863, 27855, 28036, 27901, 40378, 39964, 40553, 40447, - 40284, 40765, 41160, 41146, 41342, 41729, 41436, 41461, 4732, 4662, 4714, 4832, 4855, - 4908, 38196, 37958, 37803, 11811, 11664, 11827, 10114, 10245, 10299, 11858, 11946, 12123, - 19917, 19769, 19832, 29971, 29824, 30261, 29447, 29332, 29214, 41840, 41822, 41738, 9788, - 10154, 10143, 10209, 10154, 9921, 3368, 3403, 3375, 10819, 10917, 11222, 12154, 12112, - 12074, 12356, 12452, 12368, 10516, 10917, 10819, 4154, 4351, 4257, 3681, 3719, 3622, - 3681, 3743, 3719, 22517, 22762, 22742, 22964, 22762, 22775, 1468, 1457, 1505, 1542, - 1590, 1432, 1510, 1516, 1587, 1402, 1516, 1510, 18039, 17946, 17983, 17770, 17946, - 17799, 41635, 41461, 41482, 41616, 41671, 41396, 5663, 5732, 5725, 7515, 7745, 7750, - 34647, 34545, 34695, 1694, 1958, 1866, 1863, 1861, 1742, 12288, 12214, 12424, 12288, - 12123, 12214, 28992, 28760, 28857, 29868, 29722, 29787, 3074, 3028, 3212, 3980, 4071, - 4036, 39376, 39342, 39095, 38617, 38701, 38893, 39405, 39342, 39376, 39405, 39376, 39540, - 39376, 39470, 39540, 40150, 39776, 40029, 41342, 41146, 41512, 5322, 5292, 5490, 5243, - 5297, 5196, 37390, 37205, 37444, 37019, 36901, 36994, 12217, 12288, 12424, 13523, 13354, - 13586, 13245, 13225, 13125, 13245, 13125, 12949, 28423, 28295, 28227, 28453, 28515, 28139, - 29156, 29134, 29214, 40355, 40433, 40143, 40438, 40486, 40481, 40568, 40433, 40355, 19382, - 19306, 19229, 19172, 19092, 19229, 41926, 41777, 41669, 41960, 41777, 41926, 4908, 4954, - 4961, 2014, 2192, 2160, 5101, 5041, 5142, 5118, 5041, 5101, 7302, 7515, 7395, - 9153, 8658, 9035, 14242, 14096, 14233, 15546, 15503, 15651, 15790, 15946, 15826, 27118, - 27175, 26779, 29564, 29524, 29477, 40900, 40932, 41250, 1468, 1505, 1520, 8140, 7986, - 8252, 34556, 34545, 34404, 34556, 34404, 34439, 34218, 33922, 34164, 31052, 31040, 30860, - 31111, 31040, 31052, 29817, 29858, 29776, 39342, 39259, 39173, 1924, 2014, 1858, 2226, - 2073, 2301, 2259, 2244, 2495, 31892, 31703, 31933, 30644, 30026, 30920, 31892, 31933, - 31994, 32129, 32024, 31931, 33766, 33532, 33423, 31432, 31219, 31258, 13597, 13523, 13586, - 13965, 13806, 13795, 14233, 14096, 14099, 14769, 14709, 14822, 27757, 27855, 27901, 28423, - 28589, 28295, 26772, 26933, 26759, 38429, 38070, 38067, 38429, 38067, 38193, 1260, 1468, - 1520, 1432, 1590, 1375, 1516, 1532, 1572, 1470, 1532, 1516, 23504, 23714, 23597, - 23504, 23597, 23402, 2475, 2418, 2561, 2338, 2535, 2393, 2393, 2389, 2238, 2418, - 2610, 2581, 13038, 13190, 13122, 13902, 13806, 13965, 13986, 13951, 14310, 13554, 13820, - 13723, 27788, 27855, 27757, 29534, 29332, 29447, 39969, 39825, 39772, 4232, 4154, 4257, - 4039, 3980, 4036, 4296, 4257, 4354, 4475, 4667, 4662, 5292, 5306, 5490, 5281, - 5243, 5196, 31994, 32034, 32085, 34227, 34085, 33948, 34257, 34085, 34227, 37557, 37390, - 37444, 37019, 36994, 37085, 37557, 37444, 37484, 37516, 37582, 37662, 39259, 39189, 39173, - 23105, 23289, 23356, 22531, 22434, 22504, 23105, 23356, 23343, 23830, 23949, 23929, 22762, - 22935, 22866, 22964, 22935, 22762, 13102, 13038, 13122, 13212, 13336, 13354, 26615, 26493, - 26448, 26463, 26448, 26238, 40923, 41009, 40790, 41127, 40970, 41208, 40987, 41122, 41153, - 41514, 41467, 41315, 41153, 41122, 41264, 41514, 41315, 41437, 41492, 41810, 41626, 41463, - 41452, 41298, 41659, 41635, 41495, 41703, 41616, 41577, 27333, 27175, 27312, 2063, 1940, - 2095, 1948, 1940, 2063, 1863, 1914, 2056, 15451, 15546, 15488, 15373, 15181, 15500, - 19229, 19092, 19258, 6634, 6536, 6548, 6377, 6192, 6367, 6223, 6192, 6142, 5890, - 5958, 6024, 6746, 6634, 6855, 7023, 7156, 6851, 7156, 6953, 6851, 7102, 6953, - 7213, 1580, 1630, 1673, 1580, 1673, 1642, 2532, 2911, 2455, 2270, 2259, 2495, - 2986, 3120, 3048, 13696, 13523, 13597, 13325, 13554, 13508, 13429, 13554, 13325, 40579, - 40486, 40438, 40579, 40438, 40433, 41504, 41492, 41626, 23567, 23539, 23443, 23714, 23778, - 23785, 23577, 23778, 23714, 36050, 35911, 35806, 35593, 35609, 35579, 35578, 35609, 35593, - 35578, 35593, 35445, 35578, 35445, 35396, 35445, 35281, 35396, 35281, 35357, 35396, 3972, - 3980, 4039, 9296, 9502, 9623, 8681, 8794, 8863, 8440, 8681, 8378, 12368, 12452, - 12484, 12112, 11970, 12074, 28554, 28453, 28678, 29160, 29156, 29214, 31994, 32085, 32152, - 31703, 31444, 31043, 35281, 35186, 35357, 37958, 37901, 37499, 37972, 37901, 37958, 37972, - 37958, 38109, 35209, 34975, 35228, 34002, 33922, 33873, 37019, 37085, 37232, 1520, 1530, - 1337, 1345, 1468, 1260, 3566, 3631, 3567, 6211, 6192, 6377, 7201, 7102, 7213, - 22531, 22504, 22600, 23343, 23356, 23447, 31592, 31444, 31703, 31286, 31432, 31258, 35818, - 35806, 35704, 38193, 37996, 37982, 1415, 1289, 1403, 1403, 1205, 1469, 1469, 1205, - 1595, 1352, 1402, 1273, 1382, 1363, 1415, 1382, 1415, 1430, 1382, 1430, 1466, - 1382, 1466, 1322, 19369, 19229, 19258, 5209, 5234, 5330, 4936, 4908, 4961, 5209, - 5330, 5407, 5510, 5659, 5562, 8219, 8140, 8252, 15372, 15181, 15373, 26290, 26463, - 26238, 33915, 34002, 33873, 33915, 33532, 33766, 41275, 40833, 41226, 7283, 7170, 7201, - 7201, 7170, 7102, 34846, 34816, 34921, 3241, 3286, 3319, 3410, 3442, 3474, 3241, - 3319, 3235, 3286, 3368, 3375, 29868, 29902, 29722, 29722, 29564, 29477, 29524, 29534, - 29447, 29332, 29160, 29214, 30644, 30920, 30701, 31138, 30920, 31137, 39235, 38659, 39341, - 37056, 36506, 37183, 7283, 7398, 7302, 13394, 13212, 13354, 12206, 12123, 12288, 12811, - 13245, 12949, 5562, 5659, 5536, 34921, 34816, 34838, 34442, 34439, 34309, 37065, 37128, - 37115, 37065, 37019, 37128, 36418, 36506, 36317, 2270, 2495, 2296, 2244, 2151, 2226, - 3074, 3212, 3045, 3386, 3442, 3410, 4247, 4475, 4662, 4062, 3972, 4039, 4677, - 4732, 4832, 16975, 17048, 17215, 17999, 18026, 18252, 15674, 15125, 15296, 17770, 17726, - 17868, 17770, 17868, 17946, 27480, 27333, 27446, 27480, 27522, 28063, 29399, 29817, 29513, - 31040, 31111, 31142, 29399, 29513, 29369, 37960, 37982, 37938, 41405, 41463, 41298, 41530, - 41324, 41416, 41405, 41298, 41342, 40324, 40247, 40137, 27079, 27139, 26933, 27507, 27616, - 27669, 27177, 27139, 27079, 27654, 27616, 27507, 27855, 27825, 28036, 28589, 28560, 28481, - 34816, 34647, 34838, 41492, 41504, 41429, 41323, 41275, 41226, 41514, 41504, 41576, 4936, - 4961, 5041, 10114, 10062, 10199, 8403, 8219, 8252, 10114, 10299, 10185, 1861, 1863, - 1970, 1900, 1978, 2075, 1694, 1866, 1804, 1664, 1743, 1497, 15296, 15125, 15203, - 41232, 41275, 41323, 1374, 1487, 1457, 3028, 2986, 3048, 2945, 3004, 3035, 2984, - 3004, 2902, 29818, 29564, 29722, 6926, 7102, 6835, 2365, 2431, 2492, 2492, 2431, - 2554, 5162, 5118, 5148, 5148, 5118, 5229, 8140, 8078, 7986, 8331, 8219, 8403, - 13806, 13696, 13795, 13523, 13394, 13354, 13761, 13696, 13806, 14047, 13965, 14096, 27079, - 26933, 26930, 25474, 25408, 24814, 34002, 34038, 33922, 33766, 33876, 33866, 41264, 41122, - 41188, 25516, 25437, 25507, 23929, 23949, 24117, 25516, 25507, 25703, 37901, 37808, 37765, - 38314, 37803, 38382, 37893, 37375, 37745, 5510, 5359, 5479, 5414, 5359, 5510, 22935, - 23269, 23171, 23029, 23269, 22935, 41703, 41671, 41616, 41635, 41482, 41495, 3518, 3566, - 3567, 7277, 7200, 7363, 7191, 7200, 7277, 7191, 6519, 7020, 22531, 22600, 22667, - 28589, 28481, 28295, 31076, 31138, 31260, 31260, 31138, 31137, 31052, 30860, 30780, 36425, - 35576, 35988, 36553, 36404, 36463, 36841, 36687, 36928, 40079, 40056, 40029, 39342, 39413, - 39259, 39259, 39201, 39189, 40528, 40358, 40460, 40247, 40375, 40137, 2014, 2160, 1858, - 1554, 1580, 1642, 1900, 2111, 1914, 2341, 2532, 2236, 40563, 40528, 40460, 40598, - 40528, 40563, 40284, 40896, 40765, 40923, 41002, 41009, 41189, 40932, 40814, 40568, 40579, - 40433, 1812, 2131, 1940, 1630, 1562, 1654, 1611, 1664, 1492, 16900, 17048, 16975, - 16900, 16975, 16648, 34838, 34647, 34695, 34545, 34556, 34695, 20534, 20702, 20686, 20638, - 20702, 20534, 20193, 20092, 20211, 20092, 19951, 20211, 19906, 19951, 20092, 41861, 41958, - 41724, 41795, 41873, 41858, 41858, 41866, 41864, 41864, 41865, 41844, 41844, 41872, 41840, - 41840, 41874, 41822, 41974, 41958, 41861, 41974, 41861, 41761, 41974, 41761, 41919, 41761, - 41863, 41919, 41919, 41863, 42037, 37956, 37808, 37901, 41960, 41600, 41777, 4106, 4296, - 4136, 4232, 4296, 4222, 18715, 18623, 18690, 18997, 19000, 19318, 22923, 22900, 22776, - 22667, 22923, 22776, 5281, 5306, 5292, 5281, 5292, 5243, 32864, 33209, 33991, 34726, - 34436, 34604, 38701, 38737, 38893, 37972, 38017, 37901, 3566, 3622, 3664, 4079, 4089, - 4052, 5196, 5297, 5134, 12452, 12811, 12793, 12074, 11970, 11896, 21090, 20934, 21159, - 21090, 20959, 20934, 20934, 20959, 20758, 20273, 20101, 20161, 20161, 20101, 20060, 19940, - 19979, 19917, 19917, 19979, 19769, 19769, 19524, 19728, 21090, 21159, 21273, 21159, 21283, - 21273, 29327, 29160, 29332, 29156, 28992, 28857, 33916, 34038, 34002, 33915, 33766, 33866, - 31931, 31961, 32129, 31840, 31937, 31961, 37662, 37582, 37718, 41958, 41912, 41724, 41822, - 41881, 41251, 23567, 23343, 23447, 23567, 23717, 23830, 19906, 19805, 19951, 1809, 1812, - 1940, 41229, 41002, 41127, 41275, 41232, 41188, 41432, 41147, 41467, 19767, 19600, 19805, - 21273, 21483, 21240, 1459, 1562, 1630, 1345, 1374, 1457, 2259, 2151, 2244, 2296, - 2495, 2435, 2259, 2270, 2157, 24721, 24874, 24504, 25337, 25516, 25612, 26839, 26779, - 27175, 27488, 27664, 27533, 34695, 34556, 34560, 41530, 41416, 41580, 20491, 20616, 20758, - 27139, 27177, 27036, 27616, 27788, 27757, 26615, 26448, 26463, 38196, 38109, 37958, 37960, - 38099, 37982, 38193, 38359, 38429, 38215, 38099, 37960, 41912, 41873, 41795, 1813, 1914, - 1863, 1813, 1900, 1914, 15546, 15451, 15503, 14913, 14769, 14822, 15488, 15546, 15826, - 28824, 28678, 28760, 2449, 2418, 2475, 2238, 2389, 2148, 2389, 2196, 2079, 27654, - 27788, 27616, 20101, 20024, 20060, 21090, 21273, 21084, 41873, 41866, 41858, 3368, 3386, - 3410, 3442, 3423, 3474, 3504, 3555, 3622, 3304, 3386, 3368, 3119, 3241, 3235, - 15116, 14822, 15181, 29971, 29902, 29868, 29564, 29534, 29524, 30531, 30261, 29746, 30531, - 29746, 30644, 3413, 3357, 3513, 3357, 3572, 3470, 4062, 4039, 4154, 30701, 30531, - 30644, 31774, 31660, 31703, 30929, 30701, 30920, 33924, 33843, 34085, 2984, 3235, 3004, - 2984, 3119, 3235, 5333, 5209, 5407, 5118, 4936, 5041, 4908, 4677, 4832, 5333, - 5407, 5359, 7182, 7191, 7020, 5196, 5134, 4853, 10373, 10299, 10426, 9153, 9602, - 8658, 11606, 11364, 11664, 11606, 11811, 11858, 20024, 19979, 19940, 19805, 19600, 19573, - 24454, 24377, 24300, 24454, 24300, 24412, 29210, 29156, 29160, 29210, 28992, 29156, 41504, - 41514, 41437, 41676, 41308, 41568, 41622, 41530, 41580, 41580, 41452, 41463, 41866, 41865, - 41864, 1352, 1565, 1589, 1689, 1100, 1753, 17923, 17660, 17842, 19573, 19600, 19545, - 23269, 23504, 23402, 23376, 23504, 23269, 41926, 41669, 42283, 41782, 41703, 41762, 1664, - 1694, 1804, 1611, 1694, 1664, 35023, 34726, 34750, 34560, 34556, 34439, 41250, 40932, - 41189, 3304, 3368, 3286, 30929, 30920, 30942, 30636, 30041, 30331, 30636, 30065, 30041, - 2986, 2870, 2898, 3028, 3003, 2986, 3357, 3470, 3513, 11901, 11606, 11858, 11901, - 12123, 12206, 30142, 29902, 29971, 2327, 2418, 2449, 40553, 39964, 40276, 41208, 40970, - 41153, 41865, 41872, 41844, 1345, 1457, 1468, 22923, 23004, 22900, 21084, 21240, 21133, - 4672, 4936, 5118, 37264, 37232, 37534, 37718, 37676, 37765, 37718, 37765, 37808, 4573, - 4677, 4908, 3386, 3423, 3442, 31076, 30920, 31138, 39540, 39470, 39588, 38973, 38737, - 38894, 19454, 19382, 19545, 26290, 26238, 26132, 26450, 26615, 26463, 41872, 41874, 41840, - 41827, 41343, 41671, 1352, 1589, 1532, 12927, 13038, 13102, 12217, 12424, 12515, 39329, - 39190, 39175, 40324, 40357, 40247, 40247, 40357, 40375, 39329, 39175, 39143, 41654, 41659, - 41495, 41635, 41729, 41461, 5663, 5659, 5732, 41874, 41878, 41822, 4296, 4232, 4257, - 4222, 4296, 4106, 38314, 38196, 37803, 38973, 38953, 39177, 1402, 1470, 1516, 1352, - 1470, 1402, 3423, 3518, 3567, 5348, 5490, 5306, 4089, 4420, 4052, 8077, 8078, - 8140, 7995, 8078, 8077, 19545, 19382, 19369, 17842, 17660, 17451, 21273, 21240, 21084, - 22900, 23004, 22949, 22949, 23004, 23105, 25178, 25239, 25209, 28874, 28824, 28760, 27488, - 27480, 27664, 28874, 28760, 28992, 31260, 31137, 31444, 30695, 31052, 30780, 31111, 31286, - 31258, 31774, 31703, 31892, 33916, 34002, 33915, 36141, 36308, 36317, 35609, 35818, 35704, - 35663, 35818, 35609, 35663, 35609, 35578, 35663, 35578, 35615, 35578, 35396, 35470, 35186, - 35235, 35357, 35209, 35235, 35186, 39201, 38953, 39189, 38659, 38530, 38804, 38530, 38484, - 38804, 40814, 40571, 41340, 41953, 41568, 41592, 41819, 41827, 41671, 13418, 13394, 13523, - 13761, 13523, 13696, 40664, 40568, 40355, 41384, 41189, 41766, 40397, 40355, 40375, 29915, - 29534, 29564, 35209, 35228, 35235, 38202, 38196, 38257, 37896, 37718, 37808, 41878, 41881, - 41822, 5893, 5890, 6142, 6170, 6211, 6156, 6211, 6377, 6156, 6589, 6634, 6746, - 6675, 6746, 6851, 6926, 6851, 6953, 4118, 4062, 4154, 3413, 3748, 3356, 2014, - 1948, 2063, 1554, 1539, 1580, 1924, 1948, 2014, 15203, 15125, 14842, 15841, 16566, - 16448, 14473, 14310, 14842, 14310, 14441, 14842, 26226, 26290, 26132, 41297, 41208, 41153, - 41264, 41188, 41232, 40474, 40486, 40776, 41523, 41432, 41467, 41523, 41467, 41656, 5209, - 5162, 5148, 5562, 5476, 5510, 5414, 5476, 5401, 19745, 19776, 19537, 34975, 34921, - 34947, 34442, 34560, 34439, 37019, 37065, 36901, 37557, 37484, 37583, 42158, 41643, 41702, - 2157, 2151, 2259, 2296, 2435, 2378, 38017, 37972, 38109, 37583, 37484, 37628, 2378, - 2435, 2431, 2378, 2431, 2365, 31372, 31260, 31444, 31052, 31286, 31111, 33866, 33916, - 33915, 38804, 39103, 38925, 1432, 1530, 1542, 18699, 18623, 18715, 18716, 18715, 18910, - 22434, 22531, 22624, 22949, 23105, 23083, 34921, 34889, 34947, 12515, 12424, 12667, 29364, - 29327, 29332, 14769, 14623, 14699, 14577, 14623, 14769, 38202, 38017, 38109, 41133, 41009, - 41229, 1375, 1590, 1616, 1337, 1432, 1333, 1539, 1630, 1580, 2365, 2492, 2341, - 19573, 19545, 19655, 17451, 17660, 17600, 17519, 17215, 17450, 27788, 27825, 27855, 27654, - 27825, 27788, 27654, 27507, 27177, 26933, 26772, 26930, 1284, 1289, 1415, 1284, 1415, - 1363, 1284, 1177, 1234, 1363, 1177, 1284, 19602, 19524, 19769, 19573, 19655, 19765, - 7102, 6926, 6953, 7302, 7398, 7515, 34921, 34838, 34889, 7807, 8259, 8048, 10241, - 10209, 10014, 34096, 33924, 34085, 34096, 34085, 34293, 34420, 34442, 34218, 32827, 32627, - 32587, 37583, 37628, 37685, 28687, 28554, 28678, 28687, 28678, 28824, 5476, 5414, 5510, - 5310, 5414, 5401, 7195, 7712, 7390, 34726, 34421, 34436, 34889, 34838, 34812, 34164, - 33922, 34038, 10154, 10209, 10413, 10917, 11293, 11164, 8817, 9168, 8794, 26839, 27175, - 27332, 27488, 27333, 27480, 31502, 31372, 31444, 18623, 18465, 18622, 17726, 17405, 17307, - 18699, 18465, 18623, 22531, 22667, 22699, 23370, 23105, 23343, 22775, 22762, 22517, 23504, - 23523, 23714, 12667, 13190, 13038, 1742, 1813, 1863, 1881, 1995, 1978, 38196, 38202, - 38109, 38617, 38493, 38382, 38560, 38493, 38617, 41229, 41009, 41002, 41381, 41264, 41232, - 7200, 7195, 7390, 5210, 5306, 5281, 31931, 31840, 31961, 1322, 1466, 1374, 1565, - 1552, 1637, 1570, 1742, 1861, 1443, 1552, 1565, 3670, 3834, 3681, 3555, 3681, - 3622, 25314, 25239, 25437, 23443, 23370, 23343, 25314, 25437, 25516, 41810, 41492, 41329, - 29902, 29818, 29722, 29534, 29364, 29332, 30261, 30193, 29971, 30399, 30193, 30261, 30501, - 30261, 30531, 30501, 30531, 30701, 30845, 30701, 30929, 30845, 30929, 30861, 30920, 31076, - 30942, 17799, 17946, 18039, 25337, 25314, 25516, 31934, 31742, 31606, 30695, 30799, 31052, - 30041, 29858, 30128, 30331, 30371, 30342, 8143, 8240, 8378, 8186, 8240, 8143, 37115, - 36901, 37065, 37558, 37583, 37685, 37628, 37662, 37685, 3748, 3543, 3356, 5414, 5333, - 5359, 4055, 4475, 4247, 5310, 5333, 5414, 7712, 7807, 8048, 7735, 7807, 7712, - 10616, 10827, 10701, 10891, 11135, 11364, 11364, 11606, 11001, 12206, 12288, 12217, 15753, - 15992, 15841, 13986, 13820, 13786, 13820, 13554, 13786, 22964, 23029, 22935, 22988, 23029, - 22964, 30942, 31194, 31011, 39405, 39413, 39342, 39742, 39470, 39533, 39468, 39190, 39329, - 39468, 39481, 39190, 7191, 7195, 7200, 31337, 31076, 31260, 31660, 31592, 31703, 31722, - 31592, 31660, 31774, 31892, 31989, 34838, 34695, 34812, 3074, 3003, 3028, 2974, 3003, - 3074, 2865, 3004, 2945, 3119, 3182, 3241, 3241, 3144, 3286, 3386, 3304, 3423, - 3329, 3398, 3518, 28952, 28874, 28992, 29984, 29818, 29902, 32864, 32029, 32575, 31840, - 31719, 31937, 31719, 31432, 31742, 38804, 38484, 38712, 39378, 39468, 39329, 12262, 12206, - 12217, 12927, 12667, 13038, 13122, 13212, 13102, 27332, 27488, 27533, 29210, 29160, 29327, - 40137, 40053, 40304, 40324, 40137, 40304, 3312, 3413, 3356, 10827, 10616, 10951, 31321, - 31260, 31372, 39540, 39413, 39405, 38973, 38893, 38737, 39372, 39143, 39235, 2161, 2270, - 2296, 2161, 2157, 2270, 1976, 2160, 2205, 14537, 14539, 14699, 2338, 2327, 2449, - 2798, 2865, 2945, 2079, 2196, 1995, 14069, 14047, 14096, 1995, 2196, 1978, 2889, - 2870, 2986, 2121, 2161, 2296, 2798, 2945, 2694, 15116, 15181, 15372, 14577, 14537, - 14623, 14623, 14537, 14699, 27231, 27079, 27028, 5890, 6024, 6142, 7395, 7515, 7477, - 34812, 34695, 34841, 41549, 41323, 41226, 41656, 41467, 41514, 41678, 41635, 41679, 41678, - 41729, 41635, 41885, 41819, 41671, 41654, 41336, 41530, 41654, 41530, 41630, 1554, 2261, - 1812, 41560, 41463, 41405, 41782, 41671, 41703, 41827, 41901, 41702, 5152, 5210, 5281, - 5152, 5281, 5196, 41381, 41323, 41549, 41264, 41297, 41153, 2308, 2327, 2338, 13774, - 13761, 13806, 39378, 39372, 39341, 40598, 40757, 40528, 39980, 39518, 39728, 40766, 40765, - 40896, 40757, 40765, 40766, 13786, 13554, 13429, 1948, 1809, 1940, 1840, 1809, 1948, - 15826, 15946, 16367, 26290, 26450, 26463, 25618, 25777, 25408, 31496, 31321, 31372, 31989, - 31892, 31994, 12262, 12217, 12515, 29915, 29364, 29534, 34841, 34695, 34560, 34509, 34560, - 34442, 36928, 36687, 36901, 34817, 34421, 34726, 34382, 34293, 34421, 36928, 36901, 37115, - 4062, 3800, 3972, 4232, 4118, 4154, 4118, 4222, 4106, 4118, 4081, 4061, 13102, - 13212, 13394, 12667, 12642, 12515, 28800, 28687, 28824, 28800, 28824, 28874, 40411, 40397, - 40375, 40659, 40486, 40579, 40411, 40375, 40357, 13761, 13418, 13523, 31502, 31444, 31592, - 39366, 39201, 39259, 17770, 17564, 17726, 17645, 17564, 17770, 38017, 37956, 37901, 38257, - 38196, 38314, 38257, 38314, 38374, 38099, 38215, 38193, 38247, 38215, 38239, 41762, 41703, - 41577, 41679, 41635, 41659, 19296, 18997, 19318, 17829, 17799, 18039, 2073, 2226, 2151, - 15372, 15373, 15451, 5333, 5162, 5209, 5278, 5162, 5333, 5222, 5348, 5306, 4853, - 5152, 5196, 34125, 34164, 34038, 34125, 34038, 33916, 37019, 37264, 37128, 29364, 29210, - 29327, 17234, 17297, 17450, 16900, 16566, 16583, 41538, 41560, 41405, 41654, 41679, 41659, - 41405, 41342, 41512, 41626, 41576, 41504, 41549, 41226, 41608, 41700, 41576, 41626, 41622, - 41630, 41530, 7659, 7672, 7986, 9979, 9983, 10062, 9979, 10062, 10114, 8240, 8440, - 8378, 8094, 8440, 8240, 20893, 20959, 21084, 20893, 20758, 20959, 20684, 20491, 20758, - 20101, 20100, 20024, 20024, 20100, 19979, 19885, 19602, 19769, 19524, 19349, 19318, 20959, - 21090, 21084, 20702, 20787, 20686, 20638, 20787, 20702, 20638, 20534, 20446, 20076, 20240, - 20211, 20076, 20211, 19951, 20076, 19951, 20000, 19951, 19858, 20000, 32152, 31989, 31994, - 31722, 31502, 31592, 32123, 31989, 32152, 32249, 32364, 32068, 31742, 31432, 31488, 39182, - 38893, 38973, 20491, 20424, 20616, 22667, 22776, 22699, 31722, 31660, 31774, 23443, 23343, - 23567, 22699, 22776, 22900, 23029, 23376, 23269, 24741, 25474, 24814, 23116, 23376, 23029, - 35986, 36050, 35818, 35818, 36050, 35806, 38247, 38255, 38215, 35986, 35818, 35663, 35470, - 35396, 35357, 35470, 35357, 35385, 35357, 35235, 35385, 35235, 35405, 35385, 38081, 37956, - 38017, 37558, 37390, 37557, 42072, 42037, 41614, 41919, 42113, 41974, 41974, 42325, 41958, - 42300, 42127, 41912, 42127, 42025, 41873, 41873, 42025, 41866, 41866, 42025, 41865, 41865, - 42025, 41872, 41872, 42033, 41874, 41874, 42033, 41878, 41878, 42051, 41881, 42113, 42037, - 42072, 41638, 41960, 42072, 1867, 1978, 1900, 1570, 1958, 1694, 2157, 2073, 2151, - 2189, 2296, 2378, 14319, 14242, 14287, 14287, 14242, 14233, 14047, 13902, 13965, 13761, - 13364, 13418, 14069, 14242, 14162, 27763, 27664, 27480, 26278, 26019, 26386, 41323, 41381, - 41232, 41226, 41432, 41608, 3099, 3119, 2982, 3099, 3182, 3119, 3504, 3622, 3566, - 10922, 11293, 10917, 12356, 12221, 12452, 29858, 29936, 30128, 31432, 31286, 31435, 2051, - 2073, 2157, 3275, 3572, 3357, 3275, 3558, 3572, 3003, 2889, 2986, 3275, 3357, - 3312, 13244, 13102, 13394, 12613, 12642, 12667, 12927, 13102, 13074, 20424, 20273, 20282, - 27079, 27231, 27177, 28295, 28123, 28227, 26930, 26772, 26615, 30193, 30142, 29971, 29818, - 29915, 29564, 28955, 28952, 29434, 30622, 30501, 30701, 30399, 30507, 30429, 30701, 30845, - 30808, 30929, 30942, 30861, 37558, 37557, 37583, 39250, 39177, 39201, 39540, 39588, 39413, - 39728, 39776, 40150, 25618, 25474, 25584, 26094, 26226, 26132, 14042, 13902, 14047, 22699, - 22900, 22672, 3253, 3141, 3152, 3144, 3304, 3286, 6589, 6675, 6660, 6722, 6675, - 6851, 5893, 6142, 6192, 17450, 17215, 17234, 18252, 18376, 18427, 39481, 39633, 38864, - 39729, 39633, 39481, 39729, 39481, 39764, 1758, 1840, 1948, 1420, 1140, 1198, 1805, - 1840, 1758, 12427, 12642, 12613, 15488, 15432, 15451, 14577, 14361, 14537, 15314, 15432, - 15488, 26278, 26386, 26779, 26231, 26226, 26094, 40304, 40053, 40365, 41349, 41297, 41264, - 20273, 20100, 20101, 19951, 19805, 19858, 19805, 19765, 19858, 33991, 33209, 33843, 34293, - 34085, 34257, 34293, 34257, 34421, 2341, 2492, 2532, 3013, 2974, 3074, 1265, 1322, - 1374, 1265, 1374, 1345, 1337, 1530, 1432, 2148, 2308, 2238, 2238, 2308, 2338, - 1783, 1900, 1813, 27028, 26930, 26703, 34975, 34947, 35228, 36255, 36308, 36141, 19805, - 19573, 19765, 2833, 2898, 2870, 4222, 4118, 4232, 4417, 4136, 4296, 41793, 41679, - 41935, 41580, 41416, 41452, 34947, 35124, 35222, 35228, 35222, 35314, 1506, 1743, 1706, - 2794, 2889, 3003, 2865, 2902, 3004, 2772, 2902, 2865, 25314, 25209, 25239, 23929, - 23567, 23830, 25337, 25209, 25314, 38546, 38314, 38493, 38320, 38081, 38017, 38215, 38255, - 38193, 37034, 37060, 37745, 41560, 41580, 41463, 41512, 41146, 41479, 42127, 41873, 41912, - 41881, 42044, 41251, 41739, 41656, 41576, 7659, 7986, 8078, 7216, 7170, 7283, 23083, - 22900, 22949, 24316, 24117, 24366, 23376, 23523, 23504, 23462, 23523, 23376, 34420, 34509, - 34442, 42134, 41901, 42123, 41762, 41577, 41729, 41762, 41729, 41763, 10185, 9979, 10114, - 31337, 31260, 31321, 31887, 31722, 31774, 30799, 30695, 30636, 6170, 6192, 6211, 5459, - 5476, 5562, 8440, 8491, 8681, 8499, 8491, 8223, 8186, 8143, 8043, 18836, 18716, - 18910, 18836, 18910, 18997, 23083, 23105, 23326, 41880, 41827, 41819, 17564, 17405, 17726, - 17373, 17405, 17564, 18026, 17964, 17908, 17234, 17215, 17048, 28063, 28515, 28208, 28952, - 28800, 28874, 28952, 28992, 29210, 40485, 40411, 40357, 40664, 40659, 40568, 40538, 40411, - 40485, 41679, 41654, 41809, 1138, 1205, 1289, 1289, 1205, 1403, 1175, 1289, 1284, - 2481, 2550, 2992, 11773, 11970, 11727, 17964, 17842, 17908, 42025, 42033, 41872, 8499, - 8817, 8794, 8043, 8143, 7875, 37685, 37662, 37779, 37896, 37808, 37956, 5890, 5867, - 5958, 34885, 34889, 34812, 36639, 36553, 36463, 36639, 36463, 36841, 36985, 36841, 36928, - 36985, 36928, 37058, 10446, 10373, 10552, 10446, 10552, 10616, 10446, 10616, 10566, 11677, - 11901, 12206, 10209, 10377, 10491, 10241, 10377, 10209, 4417, 4475, 4136, 5633, 5659, - 5663, 5222, 5306, 5210, 5222, 5210, 5127, 7701, 7735, 7712, 17908, 17842, 17851, - 25474, 25618, 25408, 25628, 25618, 25584, 34234, 34420, 34218, 34639, 34841, 34560, 34234, - 34218, 34164, 1333, 1432, 1375, 1616, 1562, 1375, 17456, 17842, 17451, 1182, 1265, - 1236, 1234, 1175, 1284, 18716, 18699, 18715, 18782, 18699, 18716, 22714, 22775, 22517, - 1805, 1812, 1809, 1413, 1506, 1666, 1413, 1666, 1552, 5867, 5725, 5958, 7216, - 7283, 7302, 7195, 7085, 7712, 7191, 7182, 7195, 7261, 6715, 6519, 41576, 41656, - 41514, 41700, 41626, 41810, 19655, 19545, 19537, 31742, 31937, 31719, 32249, 32068, 32129, - 33876, 33766, 33423, 31961, 31937, 31934, 42033, 42051, 41878, 12427, 12262, 12515, 12427, - 12515, 12642, 12074, 12221, 12356, 15432, 15372, 15451, 15314, 15372, 15432, 25612, 25516, - 25703, 26403, 26278, 26597, 26226, 26319, 26290, 26231, 26319, 26226, 13902, 13774, 13806, - 12613, 12667, 12755, 14242, 14069, 14096, 14361, 14539, 14537, 14913, 14822, 15116, 3398, - 3566, 3518, 5127, 5210, 5152, 10373, 10185, 10299, 2073, 1976, 2205, 2051, 1976, - 2073, 2051, 2157, 2011, 2327, 2307, 2418, 2148, 2389, 2079, 13901, 13774, 13902, - 13429, 13325, 13245, 19885, 19769, 19979, 38081, 37896, 37956, 38690, 38560, 38617, 42051, - 42053, 41881, 8658, 9602, 8795, 8424, 8331, 8403, 8658, 8399, 8409, 24504, 24316, - 24366, 38374, 38202, 38257, 36920, 36833, 37789, 5725, 5711, 5663, 7515, 7750, 7477, - 7395, 7216, 7302, 28123, 28036, 28227, 33991, 33843, 33924, 31989, 31887, 31774, 6159, - 6715, 6238, 4013, 5237, 4089, 34096, 33991, 33924, 34817, 34726, 35023, 34043, 33866, - 34028, 37058, 36928, 37115, 37779, 37662, 37839, 3959, 4079, 4052, 32249, 32129, 32232, - 1269, 1260, 1520, 1459, 1630, 1539, 1470, 1352, 1532, 1283, 1131, 1219, 41763, - 41729, 41915, 41885, 41880, 41819, 40365, 40053, 39969, 15170, 14913, 15116, 40765, 40757, - 40598, 41133, 40761, 41009, 3329, 3518, 3423, 3182, 3144, 3241, 3099, 3144, 3182, - 3119, 2984, 2982, 30501, 30399, 30261, 31337, 31321, 31440, 30331, 30342, 30636, 29858, - 29817, 29936, 3215, 3045, 3212, 2974, 2794, 3003, 2889, 2833, 2870, 3070, 3045, - 3215, 3253, 3215, 3275, 2982, 2984, 2937, 5711, 5633, 5663, 30267, 30142, 30193, - 29936, 29817, 29943, 3126, 3253, 3152, 1363, 1382, 1177, 25618, 25628, 25777, 25584, - 25474, 25305, 42053, 42044, 41881, 1506, 1497, 1743, 1701, 1783, 1742, 1452, 1497, - 1506, 3045, 3013, 3074, 2854, 2984, 2902, 2772, 2865, 2798, 3555, 3670, 3681, - 3570, 3670, 3555, 18376, 18252, 18026, 22775, 22988, 22964, 24412, 24300, 24059, 22858, - 22988, 22775, 29452, 29817, 29399, 39201, 39177, 38953, 38690, 38546, 38560, 39366, 39259, - 39519, 41564, 41580, 41560, 41809, 41654, 41815, 41915, 41729, 41678, 41564, 41560, 41538, - 41106, 41250, 41479, 1742, 1783, 1813, 1927, 2148, 2079, 1570, 1694, 1611, 32153, - 32123, 32152, 31496, 31372, 31502, 38804, 38925, 38659, 39372, 39378, 39329, 38712, 38484, - 38429, 38712, 38429, 38548, 41229, 41127, 41474, 41381, 41349, 41264, 41464, 41349, 41536, - 39699, 39588, 39470, 39699, 39470, 39742, 5138, 6046, 5348, 4853, 5127, 5152, 34125, - 34234, 34164, 34639, 34560, 34509, 1350, 1459, 1539, 1278, 1443, 1565, 11594, 11773, - 11727, 12074, 12146, 12221, 11896, 11773, 11736, 17450, 17456, 17451, 18043, 18376, 18026, - 17245, 17234, 16926, 17450, 17297, 17446, 41810, 41329, 41676, 41823, 41432, 41523, 25209, - 24504, 24874, 25868, 26019, 25955, 41384, 41250, 41189, 1382, 1322, 1217, 1177, 1382, - 1217, 1269, 1520, 1337, 1326, 1375, 1562, 5633, 5536, 5659, 7477, 7750, 7672, - 18516, 18039, 18465, 17045, 17100, 17307, 19509, 19349, 19524, 17524, 17645, 17829, 34639, - 34509, 34584, 37058, 37115, 37128, 41885, 41671, 41782, 41793, 41678, 41679, 8454, 8331, - 8424, 26319, 26450, 26290, 27361, 27654, 27231, 28227, 28036, 28032, 26308, 26450, 26319, - 27654, 27177, 27231, 29269, 29097, 28560, 37789, 36833, 37056, 38359, 38193, 38255, 8595, - 8454, 8424, 8595, 8658, 8409, 28515, 28554, 28719, 29434, 29210, 29364, 19776, 19765, - 19655, 18043, 18026, 17908, 20828, 20893, 20917, 23326, 23105, 23370, 23326, 23370, 23443, - 22988, 23116, 23029, 22858, 23116, 22988, 2736, 2833, 2889, 14361, 14319, 14287, 14069, - 14042, 14047, 14418, 14319, 14361, 19349, 19296, 19318, 3329, 3423, 3205, 10185, 10167, - 9979, 10373, 10167, 10185, 10891, 11001, 10901, 39341, 39372, 39235, 40485, 40324, 40304, - 2308, 2307, 2327, 2042, 2079, 1995, 27028, 27079, 26930, 38215, 37960, 38239, 1899, - 2042, 1995, 5536, 5459, 5562, 5310, 5278, 5333, 7496, 7477, 7672, 14874, 14577, - 14769, 37019, 37232, 37264, 41313, 41208, 41297, 8077, 8140, 8219, 34665, 34639, 34584, - 34043, 34125, 33916, 34043, 33916, 33866, 1497, 1492, 1664, 1452, 1492, 1497, 17045, - 17307, 17405, 14986, 14874, 14913, 14913, 14874, 14769, 38359, 38247, 38239, 2204, 2307, - 2308, 40276, 40358, 40749, 40896, 40284, 40761, 1217, 1322, 1265, 17799, 17645, 17770, - 18516, 18465, 18699, 24316, 23929, 24117, 23966, 23929, 24316, 32364, 32772, 32587, 32232, - 32129, 31961, 32232, 31961, 32061, 2866, 2481, 3098, 29452, 29439, 29444, 24337, 24504, - 24586, 23577, 23714, 23523, 1269, 1337, 1245, 1283, 1100, 1131, 1391, 1413, 1443, - 5890, 5848, 5867, 5867, 5754, 5725, 5725, 5716, 5711, 5711, 5629, 5633, 5633, - 5520, 5536, 5536, 5354, 5459, 6156, 6377, 6536, 6589, 6746, 6675, 6851, 6926, - 6835, 7102, 6997, 6835, 7170, 6997, 7102, 7170, 7216, 6997, 35405, 35470, 35385, - 35620, 35615, 35470, 35470, 35615, 35578, 36050, 36255, 36141, 36308, 36418, 36317, 35405, - 35235, 35228, 41885, 41782, 42059, 42072, 42390, 42256, 3398, 3504, 3566, 3481, 3959, - 4052, 10377, 10516, 10819, 9743, 10154, 9788, 15170, 15116, 15372, 27332, 27175, 27333, - 25955, 26019, 26246, 27332, 27333, 27488, 31496, 31502, 31722, 38690, 38617, 38893, 39519, - 39259, 39413, 39378, 39548, 39764, 39153, 39341, 38659, 1840, 1805, 1809, 1554, 1420, - 1539, 1758, 1948, 1924, 40659, 40579, 40568, 40355, 40397, 40664, 5354, 5401, 5459, - 5459, 5401, 5476, 35426, 35405, 35228, 34304, 34420, 34234, 37232, 37390, 37534, 2365, - 2189, 2378, 1639, 1758, 1924, 2455, 2911, 2898, 29269, 28560, 28589, 28032, 28036, - 27825, 40538, 40397, 40411, 11851, 11677, 12206, 12667, 12927, 12836, 12927, 12903, 12836, - 40358, 40528, 40749, 8174, 8077, 8219, 7995, 7659, 8078, 8174, 8219, 8331, 8186, - 8094, 8240, 8906, 8984, 8667, 7875, 8143, 7807, 7703, 7807, 7735, 34231, 34304, - 34234, 34028, 33866, 34076, 5927, 5893, 6192, 6997, 7216, 7162, 34885, 34812, 34841, - 1800, 1867, 1900, 1800, 1900, 1783, 15184, 15170, 15372, 23199, 23326, 23125, 20893, - 21084, 20917, 31785, 31496, 31722, 42136, 41953, 41592, 41960, 42390, 42072, 41893, 41782, - 41762, 41893, 41762, 41908, 21712, 22273, 22004, 7162, 7216, 7395, 7496, 7295, 7293, - 41712, 41630, 41622, 41625, 41564, 41538, 41625, 41538, 41512, 1450, 1570, 1611, 1443, - 1413, 1552, 1391, 1443, 1330, 3045, 2963, 3013, 3013, 2910, 2974, 3126, 3070, - 3215, 3126, 3215, 3253, 3312, 3357, 3413, 5893, 5848, 5890, 17305, 17045, 17405, - 15826, 15314, 15488, 30142, 30144, 29902, 30399, 30267, 30193, 30429, 30267, 30399, 30861, - 30942, 31011, 36553, 36537, 36404, 36639, 36537, 36553, 36639, 36841, 36956, 36841, 36985, - 36956, 41700, 41739, 41576, 41785, 41739, 41700, 38560, 38546, 38493, 37839, 37662, 37718, - 37685, 37779, 37558, 39182, 38973, 39177, 2236, 2282, 2341, 3012, 2963, 3045, 39588, - 39519, 39413, 39836, 39699, 39963, 40150, 40029, 40056, 4118, 4061, 4062, 4672, 5118, - 4774, 14319, 14162, 14242, 14418, 14162, 14319, 14418, 14361, 14577, 14418, 14298, 14183, - 38515, 38374, 38314, 39103, 39153, 38925, 38247, 38359, 38255, 38239, 37960, 38253, 2121, - 2157, 2161, 3748, 3980, 3665, 7293, 7395, 7477, 7701, 7703, 7735, 5254, 5348, - 5222, 13102, 13024, 13074, 21712, 22402, 22447, 20446, 20534, 20240, 20120, 20240, 20076, - 20120, 20076, 20000, 20120, 20000, 19895, 20000, 19858, 19787, 19858, 19765, 19787, 20893, - 20684, 20758, 20491, 20549, 20424, 20424, 20278, 20273, 20273, 20278, 20100, 19885, 19509, - 19602, 19602, 19509, 19524, 19349, 19359, 19296, 20828, 20684, 20893, 21084, 21133, 20917, - 26228, 26246, 26278, 24337, 24316, 24504, 30942, 31076, 31194, 36956, 36985, 37200, 2174, - 2189, 2365, 20684, 20549, 20491, 21244, 21240, 21402, 22531, 22699, 22624, 42037, 42113, - 41919, 42025, 42090, 42033, 42033, 42090, 42051, 42051, 42175, 42053, 42053, 42070, 42044, - 41702, 41901, 42158, 1245, 1337, 1333, 1182, 1217, 1265, 1326, 1333, 1375, 1283, - 1273, 1510, 1219, 1273, 1283, 1450, 1611, 1492, 39250, 39182, 39177, 39250, 39201, - 39366, 7801, 7659, 7995, 8156, 8174, 8331, 26323, 26228, 26278, 26703, 26930, 26615, - 26040, 26231, 26094, 26040, 25777, 25628, 41349, 41313, 41297, 41464, 41313, 41349, 41901, - 41827, 42123, 5401, 5278, 5310, 5354, 5278, 5401, 5176, 5254, 5222, 5176, 5222, - 5127, 7154, 7195, 7182, 17446, 17456, 17450, 17234, 17245, 17297, 16900, 17234, 17048, - 32249, 32357, 32364, 31934, 31937, 31742, 41712, 41622, 41580, 2710, 2772, 2798, 2982, - 2997, 3099, 3099, 2997, 3144, 3205, 3423, 3304, 3398, 3445, 3504, 2854, 2772, - 2710, 3665, 3980, 3972, 3205, 3304, 3162, 3445, 3570, 3555, 10312, 10516, 10377, - 11773, 11896, 11970, 12414, 12811, 12452, 11594, 11727, 11293, 22624, 22672, 22571, 39689, - 39519, 39588, 40339, 40150, 40056, 42314, 41912, 41958, 42044, 42199, 41515, 5704, 5716, - 5725, 7020, 7154, 7182, 28363, 28589, 28423, 27922, 28032, 27825, 28147, 28032, 27997, - 19787, 19765, 19776, 1265, 1345, 1236, 19064, 18836, 18997, 17524, 17373, 17564, 19064, - 18997, 19296, 23040, 22900, 23083, 21538, 21751, 22197, 23391, 23462, 23376, 23213, 23376, - 23116, 29439, 29452, 29399, 30301, 30371, 30128, 30128, 30371, 30331, 31201, 31286, 31052, - 28284, 28423, 28227, 13394, 13418, 13364, 12414, 12452, 12221, 40749, 40528, 40946, 40378, - 40339, 40056, 40485, 40357, 40324, 40428, 39969, 40414, 28326, 28284, 28227, 5871, 6238, - 6036, 4977, 5176, 5127, 18836, 18782, 18716, 18846, 18782, 18836, 22447, 22714, 22517, - 22402, 22714, 22447, 31496, 31440, 31321, 32123, 31887, 31989, 32153, 31887, 32123, 30591, - 30636, 30342, 34231, 34234, 34125, 34957, 34885, 34841, 34231, 34125, 34043, 15184, 15314, - 14999, 17524, 17564, 17645, 17456, 17851, 17842, 19382, 19229, 19369, 16566, 16900, 16648, - 37839, 37718, 37927, 37200, 36985, 37058, 3824, 3800, 4062, 4136, 4475, 4055, 37927, - 37718, 37896, 38546, 38515, 38314, 38691, 38690, 38749, 18925, 19258, 19092, 38555, 38515, - 38546, 25863, 25612, 25703, 26130, 25955, 26246, 34999, 34885, 34957, 37200, 37058, 37128, - 10279, 10167, 10373, 8409, 8454, 8595, 10279, 10373, 10446, 12430, 12262, 12427, 12430, - 12427, 12613, 25661, 25612, 25770, 25305, 25474, 24741, 24914, 24741, 24454, 29279, 29269, - 28589, 31484, 31440, 31496, 9296, 9623, 9168, 10312, 10527, 10516, 8984, 9168, 8817, - 18979, 18925, 19092, 42165, 42090, 42025, 23462, 23577, 23523, 23391, 23577, 23462, 41953, - 41937, 41676, 42136, 41937, 41953, 41885, 42056, 41880, 41908, 41762, 41763, 1236, 1345, - 1260, 2126, 2121, 2296, 1858, 2160, 1857, 2126, 2296, 2189, 2282, 2365, 2341, - 22714, 22815, 22775, 22750, 22815, 22714, 13364, 13761, 13567, 14690, 14577, 14874, 38253, - 37960, 37893, 38359, 38491, 38429, 1897, 1976, 2051, 1420, 1554, 1140, 1311, 1326, - 1562, 1881, 1899, 1995, 2092, 2204, 2148, 2148, 2204, 2308, 1701, 1800, 1783, - 15170, 14986, 14913, 16367, 16623, 16600, 26228, 26130, 26246, 26403, 26323, 26278, 26278, - 26779, 26597, 1633, 1812, 1805, 1184, 1236, 1260, 41741, 41712, 41580, 41913, 41908, - 41763, 41741, 41580, 41750, 2866, 2752, 2481, 2092, 2148, 1927, 40766, 40794, 40757, - 41034, 40896, 40761, 41034, 40761, 41133, 7703, 7875, 7807, 8499, 8794, 8491, 7691, - 7875, 7703, 12836, 12755, 12667, 14042, 14069, 14162, 35143, 34817, 35023, 34293, 34273, - 34096, 32054, 31785, 31887, 41652, 41625, 41512, 1895, 1897, 2051, 1881, 1978, 1867, - 26703, 26615, 26450, 28032, 28147, 28227, 26703, 26450, 26524, 9502, 9743, 9788, 30267, - 30144, 30142, 30622, 30399, 30501, 30622, 30701, 30808, 29943, 29817, 29688, 30048, 30128, - 29936, 2783, 2910, 2963, 2455, 2898, 2272, 3126, 3012, 3070, 3141, 3253, 3275, - 3188, 3275, 3312, 3012, 2825, 2783, 3445, 3555, 3504, 4079, 4013, 4089, 17784, - 17851, 17456, 16685, 16926, 16900, 23199, 23083, 23326, 23199, 23040, 23083, 24337, 24228, - 24316, 24504, 25209, 24586, 30808, 30845, 30861, 30371, 30591, 30342, 39182, 39289, 38893, - 39425, 39250, 39366, 41749, 41523, 41656, 41928, 41810, 41676, 1689, 1625, 1053, 1175, - 1138, 1289, 1146, 1138, 1175, 1146, 1175, 1234, 1146, 1234, 1177, 1146, 1177, - 1085, 2937, 2997, 2982, 3329, 3445, 3398, 2937, 2984, 2854, 30412, 30144, 30267, - 1085, 1177, 1217, 1184, 1260, 1269, 22815, 22858, 22775, 22750, 22858, 22815, 37534, - 37390, 37558, 38017, 38202, 38320, 2910, 3013, 2963, 3162, 3304, 3144, 28284, 28363, - 28423, 27922, 27825, 27654, 31011, 30808, 30861, 30745, 30799, 30636, 39764, 39481, 39468, - 39764, 39468, 39378, 39378, 39341, 39548, 40905, 40794, 40766, 40659, 40776, 40486, 41596, - 41479, 41250, 40855, 40776, 40659, 38320, 38202, 38374, 3012, 3045, 3070, 2854, 2902, - 2772, 11992, 12146, 12074, 11156, 11594, 11293, 30144, 29984, 29902, 28554, 28687, 28719, - 29688, 29817, 29452, 18043, 17851, 17784, 35790, 35663, 35772, 35790, 35986, 35663, 38522, - 38491, 38239, 35663, 35615, 35772, 41937, 41928, 41676, 42100, 41928, 41937, 41913, 41763, - 41915, 42059, 42056, 41885, 1857, 2160, 1976, 14999, 14986, 15170, 26524, 26450, 26308, - 35772, 35615, 35843, 5520, 5354, 5536, 4045, 4081, 4106, 7659, 7496, 7672, 7801, - 7995, 7929, 20130, 19979, 20100, 42175, 42070, 42053, 5848, 5754, 5867, 5716, 5629, - 5711, 5893, 5808, 5848, 6170, 5927, 6192, 6145, 6156, 6536, 6587, 6536, 6589, - 6587, 6589, 6660, 6675, 6722, 6660, 5277, 5348, 5254, 7020, 7049, 7154, 6851, - 6835, 6722, 35450, 35470, 35405, 36224, 36255, 36050, 31194, 31076, 31337, 2710, 2798, - 2694, 6722, 6835, 6755, 11691, 11736, 11773, 41749, 41656, 41771, 41474, 41127, 41208, - 41596, 41250, 41384, 25877, 26040, 25628, 1413, 1452, 1506, 1338, 1701, 1742, 1355, - 1452, 1413, 38515, 38487, 38374, 38691, 38555, 38546, 38691, 38546, 38690, 41815, 41654, - 41630, 41750, 41580, 41564, 41750, 41564, 41715, 4106, 4081, 4118, 4677, 4247, 4662, - 3959, 4013, 4079, 6755, 6835, 6769, 36255, 36409, 36308, 42070, 42087, 42044, 12772, - 12755, 12836, 12903, 12927, 13074, 31208, 31194, 31337, 31887, 31785, 31722, 32152, 32085, - 32395, 28326, 28363, 28284, 29269, 29444, 29439, 31208, 31337, 31440, 8094, 8186, 8043, - 9704, 9921, 9743, 2685, 2710, 2694, 6638, 6755, 6769, 17784, 17456, 17574, 15296, - 15282, 15583, 24586, 25209, 25047, 23326, 23443, 23539, 24059, 24300, 23778, 26308, 26231, - 26040, 24059, 23778, 23920, 41704, 41652, 41512, 41815, 41630, 41712, 37128, 37264, 37315, - 15314, 15184, 15372, 16600, 16623, 16864, 42059, 41782, 41893, 41915, 41678, 41793, 1160, - 1217, 1182, 19509, 19359, 19349, 17829, 17645, 17799, 18801, 18746, 18811, 32232, 32234, - 32249, 32347, 32234, 32232, 32357, 32347, 32445, 8174, 7929, 8077, 8658, 8795, 8689, - 38025, 37927, 37896, 37315, 37264, 37534, 38025, 37896, 38081, 5927, 5808, 5893, 28687, - 28800, 28955, 35228, 34947, 35222, 35314, 35426, 35228, 2011, 1895, 2051, 1897, 1857, - 1976, 2030, 2126, 2189, 14081, 14042, 14162, 13901, 14042, 14081, 14162, 14418, 14081, - 23567, 23929, 23539, 22624, 22503, 22434, 38636, 38515, 38555, 39519, 39474, 39366, 39498, - 39474, 39519, 39689, 39588, 39699, 39689, 39699, 39836, 2249, 2447, 2481, 11871, 12074, - 11896, 19359, 19272, 19296, 18801, 18491, 18746, 29279, 29444, 29269, 35124, 34889, 34999, - 33876, 34000, 33983, 40442, 40365, 39969, 40538, 40664, 40397, 5808, 5754, 5848, 27997, - 27922, 27964, 27964, 27922, 27654, 28147, 28326, 28227, 34947, 34889, 35124, 36537, 36425, - 35988, 36639, 36664, 36537, 36816, 36664, 36639, 37105, 36639, 36956, 5184, 5277, 5254, - 5184, 5254, 5176, 7875, 8094, 8043, 7085, 7701, 7712, 7081, 7195, 7154, 1452, - 1404, 1492, 1355, 1404, 1452, 41771, 41656, 41739, 41785, 41700, 41810, 41839, 41815, - 41712, 41715, 41564, 41625, 13024, 12903, 13074, 1740, 1857, 1897, 1858, 1772, 1924, - 1394, 1539, 1420, 1927, 2079, 1871, 1696, 1881, 1867, 1663, 1867, 1800, 1311, - 1562, 1285, 1236, 1160, 1182, 42059, 41893, 42036, 41931, 41915, 41793, 41931, 41793, - 41935, 1394, 1350, 1539, 1633, 1805, 1758, 1278, 1565, 1352, 41882, 41785, 41810, - 41839, 41712, 41741, 5754, 5704, 5725, 6937, 7049, 7020, 34889, 34885, 34999, 1631, - 1633, 1758, 1620, 1414, 1500, 26323, 26130, 26228, 25955, 26044, 25863, 25364, 25209, - 25337, 26403, 26130, 26323, 41536, 41349, 41381, 41536, 41381, 41549, 1110, 1184, 1269, - 22571, 22503, 22624, 23966, 24316, 24228, 22858, 23213, 23116, 22874, 23213, 22858, 31785, - 31484, 31496, 13786, 13951, 13986, 13075, 13429, 13245, 13075, 13245, 12811, 3102, 3188, - 3356, 4045, 4136, 4055, 12566, 12430, 12613, 12566, 12613, 12755, 12336, 12414, 12221, - 40365, 40477, 40304, 37558, 37779, 37829, 38118, 38025, 38081, 38636, 38487, 38515, 39247, - 39182, 39250, 38239, 38491, 38359, 37951, 37893, 37745, 4977, 5184, 5176, 3473, 4052, - 3670, 4081, 4045, 3974, 5704, 5629, 5716, 7049, 7081, 7154, 19272, 19064, 19296, - 34841, 34639, 34665, 2997, 3059, 3144, 2774, 3445, 3329, 3570, 3473, 3670, 3084, - 3059, 2990, 3059, 2997, 2990, 2997, 2937, 2925, 2937, 2758, 2793, 5138, 5871, - 6036, 5160, 5184, 5081, 29984, 29915, 29818, 30144, 30034, 29984, 30429, 30412, 30267, - 30622, 30507, 30399, 30723, 30507, 30622, 30723, 30622, 30808, 30723, 30808, 30997, 30808, - 31011, 31068, 34708, 34382, 34421, 34385, 34382, 34708, 2825, 3012, 3126, 2910, 2794, - 2974, 3188, 3312, 3356, 30048, 30301, 30128, 30579, 30745, 30591, 30591, 30745, 30636, - 30799, 31180, 31052, 30048, 29936, 29943, 34122, 33991, 34096, 37862, 37789, 37056, 3059, - 3162, 3144, 10891, 11364, 11001, 26308, 26319, 26231, 26955, 27194, 27028, 26600, 26524, - 26521, 31245, 31011, 31194, 30579, 30591, 30371, 30069, 30034, 30248, 30159, 30048, 29943, - 643, 1455, 645, 1273, 1218, 1352, 23213, 23262, 23376, 23131, 23262, 23213, 38434, - 38320, 38374, 38111, 38253, 37893, 41893, 41908, 42036, 4062, 4061, 3824, 10891, 10701, - 10827, 8351, 8409, 8399, 24063, 23966, 24228, 24063, 24228, 24534, 39699, 39742, 39963, - 39742, 40113, 39963, 40428, 40442, 39969, 40365, 40489, 40477, 39548, 39341, 39391, 39322, - 39247, 39250, 39425, 39366, 39474, 1404, 1450, 1492, 1355, 1450, 1404, 2725, 2794, - 2910, 2030, 2011, 2126, 3824, 4061, 4081, 5629, 5520, 5633, 11736, 11871, 11896, - 12146, 12336, 12221, 11594, 11691, 11773, 11306, 11691, 11594, 10527, 10917, 10516, 16864, - 16623, 17045, 17305, 17405, 17373, 22539, 22406, 22616, 29917, 29915, 29984, 32165, 32153, - 32395, 31785, 31930, 31484, 34509, 34420, 34584, 40894, 40664, 40538, 41756, 41596, 41384, - 42134, 42158, 41901, 1285, 1562, 1459, 1321, 1394, 1198, 10734, 10701, 10891, 12772, - 12566, 12755, 12772, 12836, 12903, 40489, 40485, 40477, 40477, 40485, 40304, 10701, 10566, - 10616, 1857, 1772, 1858, 2011, 2157, 2121, 2011, 2121, 2126, 2752, 2249, 2481, - 2204, 2092, 2044, 14042, 13901, 13902, 14081, 14418, 14082, 13536, 13951, 13786, 40896, - 40905, 40766, 40946, 40528, 40757, 40578, 40339, 40378, 41138, 41034, 41141, 34385, 34273, - 34382, 34382, 34273, 34293, 11691, 11871, 11736, 18746, 18491, 18485, 18043, 17908, 17851, - 22624, 22699, 22672, 22900, 22906, 22672, 20665, 20670, 20855, 20828, 20670, 20684, 20684, - 20670, 20549, 20549, 20278, 20424, 19509, 19371, 19359, 19359, 19371, 19272, 19272, 19371, - 19064, 20950, 20828, 20917, 20950, 20917, 21133, 20950, 21133, 21129, 1219, 1187, 1273, - 1302, 1355, 1413, 1131, 1187, 1219, 23262, 23391, 23376, 23318, 23391, 23262, 42123, - 41827, 41880, 42036, 41908, 41913, 42036, 41913, 41915, 20259, 20446, 20240, 21712, 22004, - 20787, 20361, 20446, 20259, 19895, 20000, 19787, 19895, 19787, 19745, 19895, 19745, 19955, - 19776, 19745, 19787, 27922, 27997, 28032, 29431, 29450, 29444, 27194, 27231, 27028, 33876, - 33423, 34000, 34028, 34231, 34043, 37789, 37816, 37745, 37963, 38024, 38111, 41014, 40905, - 40896, 41474, 41208, 41599, 42113, 42325, 41974, 42127, 42165, 42025, 42090, 42175, 42051, - 42070, 42179, 42087, 42072, 42245, 42113, 42256, 42245, 42072, 21216, 21133, 21240, 31245, - 31208, 31537, 31537, 31208, 31440, 39391, 39341, 39153, 1285, 1459, 1291, 1326, 1245, - 1333, 18780, 18699, 18782, 20403, 20278, 20549, 23692, 23778, 23577, 26124, 25877, 25862, - 41935, 41679, 41809, 41935, 41809, 41940, 42390, 41960, 41926, 4136, 4045, 4106, 4936, - 4672, 4908, 29444, 29450, 29452, 29279, 28589, 29020, 2631, 2898, 2833, 19064, 18846, - 18836, 18780, 18846, 18688, 20278, 20130, 20100, 21244, 21216, 21240, 21402, 21240, 21483, - 22672, 22906, 22731, 42279, 42165, 42127, 37315, 37200, 37128, 37779, 37839, 37829, 41785, - 41771, 41739, 41642, 41536, 41549, 41909, 41771, 41785, 41882, 41810, 42060, 42199, 42044, - 42087, 41849, 41839, 41741, 41832, 41715, 41625, 41832, 41625, 41652, 41704, 41512, 41479, - 2455, 2236, 2532, 13607, 13761, 13774, 21216, 21244, 21289, 26524, 26600, 26703, 25877, - 25628, 25862, 28211, 28326, 28147, 32234, 32357, 32249, 32061, 31961, 31934, 34076, 34231, - 34028, 40664, 40855, 40659, 40776, 40855, 40908, 3071, 3329, 3205, 38434, 38374, 38487, - 39498, 39425, 39474, 39153, 38659, 38925, 17456, 17510, 17574, 36255, 36416, 36409, 36409, - 36418, 36308, 35986, 36139, 36050, 35790, 35948, 35986, 35772, 35948, 35790, 35994, 35948, - 35772, 35450, 35405, 35426, 35450, 35426, 35417, 35426, 35314, 35417, 35314, 35222, 35417, - 35948, 36139, 35986, 5808, 5766, 5754, 5754, 5628, 5704, 5704, 5628, 5629, 5629, - 5368, 5520, 6156, 6029, 6170, 6217, 6145, 6536, 6217, 6536, 6587, 6555, 6587, - 6660, 6555, 6660, 6638, 36139, 36224, 36050, 2685, 2652, 2710, 2418, 2307, 2086, - 6145, 6029, 6156, 6638, 6660, 6722, 6638, 6722, 6755, 12135, 12336, 12146, 12581, - 12833, 12811, 13429, 13536, 13786, 28727, 28589, 28579, 18846, 18780, 18782, 18518, 18780, - 18594, 19655, 19537, 19776, 18485, 18491, 18376, 23124, 23040, 23199, 21586, 21751, 21483, - 42123, 41880, 42172, 42158, 42283, 41669, 20120, 19955, 20204, 37816, 37951, 37745, 37963, - 37951, 38024, 1244, 1245, 1326, 1291, 1459, 1299, 1459, 1350, 1299, 1163, 1278, - 1352, 7162, 7395, 7293, 6769, 6835, 6997, 17524, 17368, 17373, 17201, 17368, 17250, - 41940, 41809, 41815, 42194, 42036, 41915, 42076, 41880, 42056, 25993, 25877, 26124, 35417, - 35222, 35159, 34584, 34420, 34506, 37829, 37839, 38087, 41599, 41208, 41313, 41608, 41432, - 41811, 38025, 38118, 37927, 38320, 38179, 38081, 38269, 38179, 38320, 38690, 38893, 38749, - 41823, 41523, 41749, 2174, 2365, 2282, 1740, 1772, 1857, 6029, 5927, 6170, 14859, - 14874, 14986, 13370, 13244, 13364, 14859, 14986, 14977, 26597, 26779, 26839, 28955, 28800, - 28952, 36664, 36425, 36537, 36677, 36425, 36664, 37105, 36956, 37186, 36416, 36418, 36409, - 13244, 13024, 13102, 11606, 11901, 11677, 13244, 13394, 13364, 25993, 26308, 26040, 40946, - 40757, 40794, 30034, 29917, 29984, 29434, 28952, 29210, 30507, 30412, 30429, 30386, 30412, - 30507, 30248, 30412, 30386, 1244, 1326, 1311, 1022, 1138, 984, 3162, 3185, 3205, - 3059, 3084, 3162, 2925, 2937, 2793, 23966, 23539, 23929, 23581, 23539, 24020, 30486, - 30371, 30301, 30486, 30579, 30371, 30987, 31180, 30799, 30486, 30301, 30444, 29688, 29452, - 29450, 34273, 34122, 34096, 32395, 32085, 32864, 34223, 34122, 34273, 1138, 1088, 1205, - 1022, 1088, 1138, 1160, 1236, 1156, 1156, 1236, 1184, 2652, 2854, 2710, 16566, - 15841, 15992, 17456, 17446, 17510, 22674, 22750, 22714, 23391, 23692, 23577, 22539, 22714, - 22402, 35222, 35124, 35159, 41849, 41741, 41750, 42211, 42217, 42158, 42076, 42056, 42059, - 2725, 2736, 2794, 2794, 2736, 2889, 3188, 3141, 3275, 3102, 3141, 3188, 3084, - 3185, 3162, 39689, 39670, 39519, 40302, 39980, 40150, 30069, 29917, 30034, 35159, 35124, - 35119, 34506, 34420, 34304, 38749, 38893, 39096, 42419, 42175, 42090, 35124, 34999, 35119, - 39906, 39670, 39689, 2236, 2174, 2282, 2145, 2174, 2236, 38610, 38434, 38487, 1194, - 1244, 1311, 1299, 1350, 1321, 1278, 1330, 1443, 1193, 1330, 1278, 17368, 17305, - 17373, 17201, 17305, 17368, 41816, 41642, 41608, 42060, 41810, 41928, 2631, 2736, 2619, - 2188, 2145, 2236, 1824, 1897, 1895, 1321, 1350, 1394, 8280, 8156, 8331, 8893, - 8795, 9602, 9743, 9921, 10154, 10014, 9921, 9704, 22750, 22874, 22858, 22774, 22874, - 22750, 1187, 1218, 1273, 1130, 1218, 1187, 10566, 10411, 10446, 10538, 10411, 10566, - 10538, 10566, 10701, 12307, 12430, 12486, 23338, 23692, 23391, 24532, 24454, 24412, 30883, - 30799, 30745, 42194, 41915, 42207, 41915, 41931, 42207, 7967, 8094, 7921, 9704, 9743, - 9562, 7691, 7703, 7701, 34415, 34506, 34304, 33876, 34076, 33866, 33983, 34076, 33876, - 42175, 42179, 42070, 38160, 38118, 38081, 38335, 38269, 38320, 5184, 5160, 5277, 4853, - 5134, 3991, 7595, 7691, 7701, 12860, 12772, 12903, 12860, 12903, 13024, 24532, 24412, - 24059, 25877, 25993, 26040, 29434, 29364, 29915, 34415, 34304, 34301, 34957, 34841, 34779, - 41608, 41642, 41549, 41141, 41133, 41301, 41823, 41749, 41961, 2541, 2652, 2685, 2541, - 2685, 2550, 12336, 12258, 12414, 11871, 11992, 12074, 11878, 11992, 11871, 11878, 11871, - 11691, 40817, 40378, 40553, 13105, 13244, 12993, 1302, 1413, 1391, 1620, 1663, 1701, - 7081, 7085, 7195, 7049, 7054, 7081, 6937, 7054, 7049, 6937, 7020, 6519, 34841, - 34665, 34779, 41942, 41940, 41815, 41967, 41849, 41970, 41955, 41849, 41967, 18780, 18516, - 18699, 18518, 18516, 18780, 18097, 18485, 18376, 20259, 20120, 20204, 18097, 18376, 18043, - 39425, 39322, 39250, 39758, 39498, 39519, 42179, 42162, 42087, 1655, 1639, 1924, 1701, - 1663, 1800, 1871, 2042, 1899, 1701, 1414, 1620, 26130, 26044, 25955, 26901, 26839, - 27332, 1194, 1311, 1285, 1321, 990, 1180, 41942, 41815, 41839, 1802, 1824, 1895, - 1772, 1655, 1924, 2058, 2030, 2189, 7293, 7477, 7496, 7054, 7085, 7081, 17446, - 17413, 17510, 27533, 27428, 27332, 27763, 27480, 28063, 11992, 12135, 12146, 29279, 29431, - 29444, 29573, 29431, 29404, 19848, 19371, 19509, 1802, 1895, 2011, 32395, 32864, 33137, - 34708, 34421, 34817, 34779, 34665, 34697, 34301, 34304, 34231, 8223, 8491, 8440, 38160, - 38081, 38179, 38434, 38335, 38320, 38405, 38160, 38179, 38691, 38636, 38555, 39360, 39182, - 39247, 8280, 8331, 8454, 38087, 37839, 37927, 1017, 1085, 988, 1110, 1156, 1184, - 1110, 1269, 1056, 21751, 21538, 21483, 23125, 23124, 23199, 38491, 38548, 38429, 38522, - 38548, 38491, 38522, 38239, 38433, 28955, 28719, 28687, 28561, 28719, 28740, 34665, 34584, - 34697, 37186, 36956, 37200, 37186, 37200, 37270, 14999, 15170, 15184, 13607, 13774, 13901, - 15826, 16367, 16104, 38466, 38335, 38434, 2086, 2307, 2204, 2086, 2204, 2019, 16104, - 16367, 16600, 40710, 40489, 40607, 40485, 40697, 40538, 40626, 40489, 40710, 39737, 39764, - 39548, 41134, 40474, 40776, 28561, 28208, 28515, 1194, 1285, 1186, 23692, 23920, 23778, - 23510, 23920, 23692, 1533, 1812, 1633, 1186, 1285, 1291, 3084, 2969, 3185, 3309, - 3473, 3445, 2925, 2990, 2997, 2901, 2990, 2830, 2937, 2854, 2758, 17305, 17177, - 17045, 17201, 17177, 17305, 24716, 24532, 24359, 30579, 30727, 30745, 30576, 30486, 30573, - 41882, 41894, 41785, 42047, 41894, 41882, 41940, 42207, 41935, 41955, 41942, 41839, 41955, - 41839, 41849, 1025, 1085, 1017, 12206, 12262, 11851, 30576, 30727, 30579, 42162, 42199, - 42087, 7929, 7995, 8077, 21538, 21376, 21483, 23470, 23125, 23326, 23470, 23326, 23539, - 22874, 23131, 23213, 22917, 23131, 22874, 34602, 34584, 34506, 34300, 34301, 34231, 34553, - 34301, 34624, 3445, 3473, 3570, 4865, 4624, 4723, 3071, 3205, 3185, 7295, 7496, - 7412, 9921, 10014, 10209, 9296, 9168, 8984, 32153, 32165, 31887, 29939, 30069, 30170, - 34223, 33991, 34122, 37122, 37186, 37270, 39448, 39322, 39425, 41596, 41704, 41479, 2758, - 2854, 2652, 29917, 29939, 29915, 30248, 30034, 30144, 31245, 31194, 31208, 31180, 31201, - 31052, 30727, 30883, 30745, 1639, 1631, 1758, 1669, 1655, 1772, 1663, 1696, 1867, - 1620, 1696, 1663, 7978, 7929, 8174, 8351, 8280, 8454, 8351, 8454, 8409, 26639, - 26521, 26479, 26308, 26521, 26524, 26955, 27028, 26703, 27997, 28211, 28147, 29465, 29450, - 29431, 26595, 26521, 26639, 2618, 2758, 2652, 12307, 12262, 12430, 38226, 38160, 38403, - 38118, 38087, 37927, 10312, 10377, 10241, 11992, 11957, 12135, 12486, 12430, 12566, 13244, - 13105, 13024, 13607, 13901, 13773, 6447, 6587, 6555, 6338, 6217, 6587, 6145, 6093, - 6029, 6029, 6001, 5927, 5927, 5832, 5808, 6447, 6555, 6467, 6447, 6467, 6372, - 6217, 6157, 6145, 34602, 34506, 34553, 1625, 860, 999, 1163, 1193, 1278, 1212, - 1302, 1391, 6157, 6093, 6145, 6769, 6997, 6863, 17820, 18097, 18043, 17446, 17297, - 17413, 23131, 23318, 23262, 23255, 23318, 23131, 42479, 42136, 41592, 42065, 42076, 42059, - 42211, 42158, 42134, 42065, 42059, 42036, 27648, 27428, 27533, 27648, 27533, 27664, 2736, - 2631, 2833, 2174, 2058, 2189, 2725, 2910, 2783, 11632, 11878, 11691, 12135, 12258, - 12336, 29465, 29688, 29450, 29465, 29431, 29573, 27873, 27763, 28063, 38749, 38636, 38691, - 38405, 38179, 38269, 38610, 38636, 38770, 41141, 41034, 41133, 41034, 41085, 40896, 40905, - 41014, 40794, 40457, 40302, 40339, 41593, 41464, 41536, 41018, 41134, 40776, 41018, 40776, - 40908, 6093, 6001, 6029, 5162, 4774, 5118, 7847, 7929, 7818, 7241, 7181, 7293, - 8906, 9296, 8984, 25364, 25337, 25612, 26955, 26703, 26600, 31284, 31245, 31537, 31166, - 31201, 31180, 34385, 34223, 34273, 34965, 34223, 34385, 41894, 41909, 41785, 42003, 41909, - 41894, 42211, 42134, 42205, 6001, 5928, 5927, 38610, 38466, 38434, 2079, 2042, 1871, - 14082, 13901, 14081, 41085, 41014, 40896, 40908, 40855, 40664, 3800, 3665, 3972, 2783, - 2963, 3012, 3761, 3824, 4081, 5278, 4774, 5162, 32165, 32090, 31887, 33137, 32864, - 33991, 1824, 1740, 1897, 1802, 1740, 1824, 26595, 26955, 26600, 41195, 41340, 40571, - 1623, 1631, 1639, 1533, 1631, 1559, 5928, 5832, 5927, 35478, 35583, 35450, 35450, - 35583, 35470, 35948, 35994, 36139, 36198, 36416, 36224, 36224, 36416, 36255, 35478, 35450, - 35417, 35478, 35417, 35589, 35417, 35159, 35261, 2465, 2550, 2481, 2465, 2541, 2550, - 16346, 16104, 16600, 14944, 14999, 15440, 28589, 28363, 28579, 34936, 34708, 34817, 1625, - 1711, 860, 20687, 20787, 20638, 42205, 42134, 42176, 7978, 8174, 8156, 9583, 8893, - 9602, 19895, 19955, 20120, 17763, 18043, 17784, 20446, 20651, 20638, 20572, 20651, 20446, - 20240, 20120, 20259, 20651, 20687, 20638, 23318, 23338, 23391, 24716, 24914, 24532, 23255, - 23338, 23318, 31201, 31435, 31286, 34000, 33423, 33768, 37951, 37963, 37893, 37951, 37816, - 38024, 42176, 42134, 42123, 42178, 42065, 42194, 42245, 42325, 42113, 42595, 42285, 42175, - 42175, 42285, 42179, 42179, 42391, 42162, 42162, 42303, 42199, 42270, 42325, 42245, 42270, - 42245, 42256, 42270, 42256, 42539, 12993, 12860, 13024, 12749, 12860, 12767, 20278, 20145, - 20130, 20130, 19969, 19979, 20670, 20403, 20549, 20665, 20403, 20670, 20670, 20828, 20855, - 21129, 21133, 21216, 21129, 21216, 21289, 42325, 42314, 41958, 6863, 6997, 6979, 6997, - 7162, 6979, 19545, 19369, 19537, 20687, 20930, 20787, 35119, 34999, 34957, 42314, 42300, - 41912, 42283, 42158, 42310, 1186, 1291, 1203, 1244, 1173, 1245, 984, 1146, 1025, - 1291, 1299, 1203, 17413, 17297, 17245, 17693, 17763, 17784, 16926, 17234, 16900, 24534, - 24228, 24337, 9583, 9083, 8893, 19537, 19369, 19258, 42300, 42279, 42127, 2127, 2145, - 2098, 1709, 1802, 2011, 41014, 40946, 40794, 41029, 40908, 40664, 20235, 20145, 20278, - 19102, 19537, 19258, 22571, 22676, 22503, 14183, 14082, 14418, 14977, 14999, 14944, 26211, - 26044, 26130, 26788, 26597, 26839, 26521, 26595, 26600, 26124, 26308, 25993, 3659, 3665, - 3800, 6979, 7162, 6964, 15841, 15296, 15583, 32185, 32090, 32165, 31606, 32061, 31934, - 39103, 38804, 38712, 39391, 39562, 39548, 39103, 38712, 38882, 42176, 42123, 42269, 42310, - 42158, 42217, 41961, 41749, 41990, 41685, 41593, 41536, 2447, 2465, 2481, 12486, 12566, - 12772, 7691, 7621, 7875, 8094, 8148, 8440, 7085, 7595, 7701, 34553, 34506, 34415, - 35026, 35119, 34957, 34553, 34415, 34301, 20145, 20009, 20130, 18350, 17829, 18516, 1131, - 1130, 1187, 1106, 1130, 1131, 23581, 23470, 23539, 22571, 22672, 22676, 7181, 7162, - 7293, 7085, 7040, 7595, 7054, 7063, 7085, 6185, 6715, 6159, 20009, 19969, 20130, - 18925, 19033, 19258, 23040, 22906, 22900, 3824, 3659, 3800, 5278, 5354, 5086, 2990, - 2969, 3084, 2901, 2969, 2990, 2743, 2925, 2793, 3071, 2969, 2841, 2730, 2758, - 2666, 10901, 10734, 10891, 9732, 9194, 9083, 11204, 11001, 11606, 10892, 10908, 10842, - 30831, 30987, 30883, 30883, 30987, 30799, 31543, 31488, 31435, 30486, 30576, 30579, 30159, - 30301, 30048, 30159, 29943, 30163, 39616, 39425, 39498, 39448, 39360, 39322, 39836, 39906, - 39689, 40113, 39742, 39980, 40113, 39980, 40203, 22539, 22674, 22714, 22603, 22674, 22539, - 42310, 42217, 42211, 42172, 41880, 42076, 1165, 1173, 1244, 1203, 1299, 1180, 1163, - 1352, 1218, 1355, 1213, 1450, 2249, 2752, 2418, 1871, 1899, 1604, 14418, 14577, - 14298, 13607, 13567, 13761, 17693, 17784, 17574, 17400, 17413, 17245, 19969, 19885, 19979, - 23040, 23124, 22906, 30265, 30159, 30223, 38636, 38610, 38487, 38405, 38269, 38335, 38577, - 38610, 38667, 38433, 38239, 38253, 41134, 41195, 40474, 41550, 41195, 41134, 41136, 41134, - 41018, 42100, 42060, 41928, 41989, 41811, 41823, 7241, 7293, 7295, 7978, 8156, 7950, - 8689, 8399, 8658, 1686, 1899, 1881, 15296, 15203, 15282, 1927, 2044, 2092, 14082, - 13773, 13901, 26901, 26788, 26839, 27763, 27648, 27664, 28208, 27873, 28063, 27747, 27873, - 27804, 27873, 27956, 27804, 11204, 11606, 11677, 12749, 12486, 12772, 12749, 12772, 12860, - 40489, 40626, 40485, 40697, 40626, 40816, 2022, 2188, 2455, 3126, 2942, 2825, 7595, - 7621, 7691, 8667, 8984, 8817, 7849, 7621, 7494, 30069, 29939, 29917, 30248, 30144, - 30412, 30717, 30883, 30727, 31435, 31488, 31432, 35026, 34957, 34779, 34300, 34231, 34076, - 39322, 39360, 39247, 39448, 39425, 39609, 22906, 23124, 23187, 24020, 23539, 23966, 1241, - 1391, 1330, 1696, 1686, 1881, 41942, 42019, 41940, 41849, 41750, 41970, 41832, 41652, - 41704, 41832, 41704, 41787, 18925, 18928, 19033, 39565, 39562, 39391, 38882, 38712, 38899, - 23124, 23125, 23187, 22674, 22774, 22750, 22793, 22774, 22674, 2127, 2102, 2174, 2127, - 2174, 2145, 13709, 13567, 13607, 2725, 2619, 2736, 30987, 31166, 31180, 41787, 41704, - 41596, 7659, 7801, 7719, 35026, 34779, 34891, 1165, 1244, 1139, 1180, 1299, 1321, - 1193, 1241, 1330, 1136, 1241, 1193, 1198, 1394, 1420, 1740, 1669, 1772, 1594, - 1669, 1740, 14999, 14977, 14986, 14727, 14977, 14944, 27444, 27332, 27428, 26444, 26130, - 26403, 42060, 42047, 41882, 42251, 42047, 42060, 11839, 11957, 11878, 10014, 10312, 10241, - 10288, 10312, 10014, 11878, 11957, 11992, 13951, 14126, 14310, 12110, 11957, 11839, 39565, - 39391, 39600, 860, 1711, 1455, 984, 1138, 1146, 1146, 1085, 1025, 12504, 12749, - 12596, 11851, 12262, 12307, 42419, 42090, 42165, 42199, 42362, 41515, 42373, 42100, 41937, - 1053, 1100, 1689, 1130, 1163, 1218, 939, 1100, 1053, 21376, 21402, 21483, 23187, - 23125, 23275, 22774, 22917, 22874, 24532, 24059, 24359, 22793, 22917, 22774, 7847, 7801, - 7929, 18516, 17829, 18039, 17177, 17056, 17045, 18780, 18688, 18594, 34697, 34584, 34602, - 37186, 37122, 37105, 37169, 36816, 36639, 36269, 35023, 35099, 37270, 37200, 37315, 37270, - 37315, 37353, 38226, 38118, 38160, 38476, 38335, 38466, 8031, 8148, 8094, 32445, 32364, - 32357, 34624, 34697, 34602, 32099, 32054, 32090, 32090, 32054, 31887, 30386, 30507, 30463, - 32185, 32165, 32395, 26444, 26403, 26597, 24586, 24534, 24337, 24063, 24020, 23966, 41685, - 41536, 41642, 41811, 41432, 41823, 25770, 25612, 25863, 4055, 3974, 4045, 3884, 3974, - 3841, 18925, 18863, 18928, 24532, 24914, 24454, 23510, 23692, 23338, 41970, 41750, 41715, - 42008, 42019, 41942, 42211, 42205, 42318, 29895, 29434, 29915, 31225, 31435, 31201, 1338, - 1570, 1225, 26644, 26444, 26597, 32347, 32357, 32234, 32347, 32232, 32061, 18846, 19087, - 18688, 1217, 988, 1085, 8229, 8216, 8399, 8156, 8038, 7950, 10279, 10446, 10411, - 27194, 27361, 27231, 27339, 27361, 27194, 27088, 27194, 26955, 26806, 26955, 26595, 27747, - 27648, 27763, 26788, 26644, 26597, 27747, 27763, 27873, 37534, 37558, 37595, 38577, 38466, - 38610, 38577, 38476, 38466, 38475, 38433, 38253, 38899, 38712, 38548, 41138, 41085, 41034, - 41014, 41130, 40946, 41317, 41133, 41229, 41749, 41771, 41990, 8280, 8351, 8216, 1244, - 1194, 1139, 1533, 1633, 1631, 17250, 17368, 17524, 14690, 14727, 14760, 1194, 1186, - 1139, 1108, 1163, 986, 2102, 2058, 2174, 1936, 2058, 2102, 1920, 2019, 2044, - 2044, 2019, 2204, 1920, 2044, 1927, 1920, 1927, 1852, 5871, 6185, 6159, 6447, - 6338, 6587, 6217, 6141, 6157, 6003, 5962, 6093, 6093, 5962, 6001, 6001, 5933, - 5928, 5928, 5854, 5832, 6372, 6338, 6447, 6555, 6638, 6467, 6390, 6388, 6467, - 6390, 6467, 6638, 6449, 6638, 6769, 12767, 12860, 12770, 13773, 13709, 13607, 13680, - 13709, 13773, 14052, 13773, 14082, 17693, 17574, 17559, 18925, 18746, 18863, 17574, 17510, - 17559, 17510, 17400, 17559, 27750, 27964, 27654, 30265, 30301, 30159, 35843, 35615, 35620, - 35843, 35994, 35772, 37939, 37816, 37789, 35470, 35583, 35620, 35583, 35630, 35620, 40302, - 40150, 40339, 41203, 41085, 41138, 6863, 6979, 6964, 1217, 1160, 988, 5368, 5354, - 5520, 6035, 6093, 6157, 6964, 7162, 7016, 35583, 35478, 35630, 36198, 36224, 36139, - 38596, 38561, 38433, 5766, 5808, 5832, 8148, 8223, 8440, 8167, 8223, 8148, 3665, - 3543, 3748, 3634, 3659, 3824, 32099, 32185, 32216, 31068, 31011, 31245, 40553, 40749, - 40817, 39963, 39906, 39836, 2465, 2523, 2541, 1987, 2418, 2086, 38770, 38636, 38749, - 39616, 39498, 39758, 11001, 10892, 10901, 11851, 12052, 11880, 30576, 30717, 30727, 31243, - 31225, 31166, 31166, 31225, 31201, 30573, 30717, 30576, 30265, 30223, 30444, 3126, 3152, - 2942, 2725, 2636, 2619, 2188, 2236, 2455, 31068, 31245, 31284, 29939, 29895, 29915, - 30159, 30163, 30223, 1610, 1686, 1696, 2898, 2631, 2272, 27975, 28211, 27997, 2969, - 3071, 3185, 2730, 2793, 2758, 10892, 10734, 10901, 40097, 39906, 39963, 42391, 42303, - 42162, 42310, 42211, 42318, 42172, 42076, 42178, 5933, 5854, 5928, 5138, 5348, 5277, - 35261, 35159, 35119, 2618, 2652, 2594, 42008, 41942, 41955, 41832, 41970, 41715, 42022, - 41970, 41832, 25840, 25770, 25863, 24577, 24534, 24586, 25840, 25863, 26044, 1623, 1639, - 1655, 1623, 1655, 1669, 5160, 5138, 5277, 4977, 4853, 4865, 4977, 4865, 5047, - 25862, 25628, 25584, 867, 1160, 1156, 1139, 1186, 1147, 5854, 5766, 5832, 10734, - 10538, 10701, 18746, 18550, 18863, 17510, 17413, 17400, 25364, 25612, 25661, 23275, 23125, - 23470, 31930, 31785, 32054, 42008, 41955, 41999, 42248, 42388, 42278, 41996, 41771, 41909, - 2523, 2652, 2541, 40817, 40749, 40984, 1269, 1245, 1056, 25679, 25364, 25661, 41927, - 41787, 41914, 41787, 41596, 41914, 42303, 42307, 42199, 21289, 21402, 21376, 23275, 23470, - 23362, 38722, 38548, 38522, 39737, 39565, 39755, 42178, 42076, 42065, 5081, 5138, 5160, - 35348, 35261, 35374, 34624, 34602, 34553, 8795, 8644, 8689, 9298, 9979, 9596, 8667, - 8817, 8499, 9296, 9262, 9502, 39289, 39182, 39360, 38438, 38405, 38335, 37595, 37558, - 37829, 38111, 37893, 37963, 38433, 38561, 38522, 1523, 1623, 1669, 1620, 1610, 1696, - 1500, 1610, 1620, 2597, 2631, 2619, 32099, 31930, 32054, 40626, 40697, 40485, 40908, - 41136, 41018, 39633, 40414, 39685, 31537, 31440, 31484, 31243, 31166, 30987, 32437, 32347, - 32061, 12378, 12307, 12486, 11546, 11851, 11761, 39633, 39729, 40414, 4672, 4573, 4908, - 4004, 4573, 4120, 37862, 37536, 37970, 34060, 34000, 34095, 31606, 31742, 31488, 42318, - 42205, 42176, 5766, 5628, 5754, 14690, 14874, 14859, 12504, 12486, 12749, 27648, 27444, - 27428, 25874, 25840, 26044, 27686, 27444, 27648, 28561, 28515, 28719, 27964, 27975, 27997, - 27361, 27750, 27654, 27835, 27750, 27630, 8216, 8351, 8399, 7016, 7181, 7135, 8446, - 8667, 8499, 7921, 8094, 7875, 7921, 7875, 7849, 7063, 7054, 6937, 38035, 37862, - 37970, 1756, 2011, 2030, 1971, 2030, 2058, 1971, 2058, 1936, 38438, 38335, 38476, - 41141, 41203, 41138, 41474, 41317, 41229, 1147, 1186, 1203, 1056, 1245, 1103, 1147, - 1203, 1180, 18485, 18550, 18746, 17400, 17245, 17289, 24288, 24020, 24063, 1245, 1173, - 1103, 1100, 1106, 1131, 1021, 1106, 939, 16292, 16583, 16566, 23362, 23470, 23581, - 22197, 21751, 22434, 22967, 23255, 23131, 22967, 23131, 22917, 41811, 41816, 41608, 41599, - 41313, 41754, 42003, 41894, 42133, 4977, 5081, 5184, 5138, 5028, 5871, 38087, 38118, - 38226, 38620, 38476, 38577, 39758, 39519, 39670, 39562, 39737, 39548, 39391, 39153, 39600, - 17201, 17056, 17177, 14977, 14727, 14859, 17172, 17056, 17201, 16933, 17056, 17060, 42133, - 41894, 42047, 42194, 42065, 42036, 41999, 41955, 41967, 41999, 41967, 42159, 2446, 2523, - 2465, 2446, 2465, 2447, 11957, 12110, 12135, 16416, 16685, 16583, 11156, 11293, 11020, - 28579, 28363, 28326, 27835, 27975, 27964, 860, 1455, 643, 7016, 7162, 7181, 7181, - 7241, 7135, 18300, 18550, 18485, 35261, 35119, 35148, 25770, 25679, 25661, 26211, 26130, - 26444, 25820, 25862, 25725, 26479, 26521, 26308, 25305, 24741, 24914, 15314, 15440, 14999, - 27277, 26901, 27332, 1623, 1559, 1631, 885, 1147, 1180, 1444, 1559, 1398, 3659, - 3543, 3665, 3443, 3543, 3659, 3884, 4081, 3974, 12530, 12811, 12414, 26337, 26211, - 26444, 28579, 28326, 28455, 40984, 40749, 40946, 41130, 41014, 41085, 41899, 41816, 42043, - 7135, 7241, 7122, 6931, 7063, 6937, 831, 988, 1160, 18097, 18300, 18485, 31543, - 31606, 31488, 13123, 13383, 13429, 42269, 42318, 42176, 41931, 41935, 42207, 20855, 20828, - 20950, 20403, 20235, 20278, 20145, 20087, 20009, 20009, 19993, 19969, 19969, 19991, 19885, - 19885, 19848, 19509, 20855, 20950, 21129, 20855, 21129, 21113, 21244, 21402, 21289, 4573, - 4526, 4677, 4328, 4526, 4004, 20404, 20361, 20369, 20404, 20446, 20361, 20404, 20572, - 20446, 20651, 20666, 20687, 20687, 20957, 20930, 20930, 21712, 20787, 20361, 20259, 20369, - 20259, 20225, 20369, 20204, 20225, 20259, 19955, 20062, 20204, 19956, 20062, 19955, 12110, - 12258, 12135, 19745, 19956, 19955, 22731, 22676, 22672, 39600, 39813, 39828, 38561, 38722, - 38522, 38638, 38722, 38561, 42100, 42071, 42060, 42248, 42071, 42100, 7967, 8031, 8094, - 7865, 8031, 7967, 19976, 20041, 19956, 20918, 20957, 20687, 37862, 37939, 37789, 38111, - 38475, 38253, 37966, 37939, 38035, 20260, 20235, 20403, 20957, 21075, 20930, 26854, 26644, - 26788, 26282, 26308, 26124, 5047, 4927, 5058, 2830, 2990, 2925, 2830, 2925, 2743, - 2793, 2730, 2743, 20235, 20205, 20145, 30717, 30831, 30883, 31225, 31543, 31435, 30444, - 30573, 30486, 30444, 30301, 30265, 1302, 1213, 1355, 1136, 1212, 1391, 1136, 1391, - 1241, 1213, 1212, 1014, 2666, 2758, 2618, 5628, 5368, 5629, 7719, 7801, 7847, - 11020, 11293, 10922, 12110, 12199, 12258, 17056, 16933, 17045, 16864, 16933, 16905, 30248, - 30170, 30069, 29039, 28719, 28955, 30463, 30507, 30723, 30997, 30808, 31068, 29943, 29965, - 30163, 34708, 34946, 34385, 34408, 33137, 33991, 36430, 35576, 36425, 36677, 36664, 36816, - 37353, 37122, 37270, 42003, 41996, 41909, 41961, 41989, 41823, 42141, 41996, 42003, 42207, - 41940, 42019, 42159, 41967, 41970, 19757, 19976, 19956, 18043, 17763, 17820, 22616, 22603, - 22539, 42269, 42123, 42172, 20205, 20087, 20145, 38405, 38403, 38160, 38620, 38438, 38476, - 39390, 39360, 39448, 38596, 38475, 38570, 42279, 42419, 42165, 42285, 42391, 42179, 42303, - 42375, 42307, 42455, 42419, 42279, 42488, 42279, 42300, 42488, 42300, 42314, 42488, 42314, - 42325, 42488, 42325, 42560, 42390, 41926, 42496, 41926, 42283, 42496, 3023, 3102, 3356, - 2783, 2636, 2725, 20087, 19993, 20009, 19258, 19033, 19102, 22731, 22780, 22676, 31101, - 30997, 31068, 31127, 31068, 31284, 1103, 1173, 1165, 857, 922, 988, 23255, 23510, - 23338, 23144, 23510, 23255, 39674, 39390, 39448, 12833, 13075, 12811, 13007, 13075, 12884, - 29039, 28955, 29434, 28696, 28579, 28584, 28727, 29020, 28589, 2563, 2636, 2513, 2594, - 2666, 2618, 11851, 11546, 11677, 10456, 10538, 10537, 10456, 10279, 10538, 13105, 12993, - 13024, 13536, 13429, 13383, 13656, 14126, 13951, 40302, 40332, 39980, 39705, 39758, 39953, - 39884, 39758, 39670, 39616, 39609, 39425, 40464, 40332, 40302, 41317, 41301, 41133, 41239, - 41301, 41378, 4853, 4977, 5127, 5081, 5085, 5138, 5047, 5058, 5081, 7818, 7719, - 7847, 7818, 7929, 7978, 13364, 13567, 13417, 12258, 12530, 12414, 12581, 12530, 12371, - 19993, 19991, 19969, 19102, 19033, 18989, 22676, 22780, 22677, 25748, 25679, 25770, 25229, - 25047, 25209, 24534, 24288, 24063, 26152, 25874, 26044, 26152, 26044, 26211, 41834, 41685, - 41642, 41834, 41642, 41816, 1936, 2102, 1915, 1398, 1559, 1389, 2098, 2145, 2188, - 2019, 1987, 2086, 2397, 2594, 2652, 1852, 1927, 1773, 1927, 1871, 1763, 26929, - 26854, 26901, 26901, 26854, 26788, 27747, 27686, 27648, 27956, 27873, 28208, 41239, 41203, - 41141, 17393, 17400, 17289, 17727, 17763, 17693, 22731, 22906, 22780, 23134, 23187, 23275, - 31461, 31127, 31284, 42401, 42283, 42310, 26668, 26337, 26444, 26310, 26337, 26668, 26253, - 26282, 26124, 8031, 8167, 8148, 8085, 8167, 8031, 33983, 34135, 34076, 34697, 34891, - 34779, 34106, 34000, 34060, 37939, 38024, 37816, 37966, 38024, 37939, 40578, 40457, 40339, - 14727, 14690, 14859, 13417, 13567, 13709, 15951, 15826, 16104, 1909, 1987, 2019, 13361, - 13536, 13383, 21522, 21538, 21651, 41374, 41130, 41085, 40522, 40464, 40457, 41178, 41136, - 40908, 41830, 41384, 41766, 40778, 40538, 40697, 16933, 16864, 17045, 17250, 17524, 17407, - 6141, 6338, 6247, 6034, 6141, 6247, 6338, 6141, 6217, 5962, 5933, 6001, 5854, - 5587, 5766, 5766, 5587, 5628, 5227, 5086, 5368, 6338, 6372, 6247, 6372, 6467, - 6388, 7000, 6964, 7016, 10538, 10279, 10411, 10842, 10734, 10892, 38035, 37939, 37862, - 35994, 36198, 36139, 36159, 36198, 35994, 36159, 35994, 35843, 36033, 35843, 35620, 40097, - 39963, 40113, 39565, 39737, 39562, 39153, 39103, 39298, 6141, 6035, 6157, 7412, 7496, - 7659, 7135, 7000, 7016, 35143, 34936, 34817, 35589, 35630, 35478, 34944, 34891, 34894, - 37475, 37353, 37315, 37475, 37315, 37504, 16864, 16346, 16600, 22603, 22793, 22674, 22679, - 22793, 22603, 38859, 38770, 38749, 3841, 3974, 4055, 2942, 3141, 3102, 6035, 6003, - 6093, 8906, 9262, 9296, 10922, 10917, 10527, 9289, 9040, 9212, 6003, 5933, 5962, - 14052, 14082, 14183, 12504, 12378, 12486, 40816, 40778, 40697, 40489, 40365, 40607, 14808, - 14944, 15440, 4201, 4247, 4677, 8893, 8828, 8795, 8871, 8828, 8893, 1001, 1103, - 1165, 1554, 1812, 1140, 2022, 2098, 2188, 6185, 6519, 6715, 7849, 7875, 7621, - 6937, 6481, 6782, 6519, 6481, 6937, 41130, 40984, 40946, 38728, 38610, 38770, 39705, - 39609, 39616, 39755, 39828, 39941, 7719, 7412, 7659, 7122, 7000, 7135, 7310, 7412, - 7276, 18846, 19064, 19087, 18518, 18350, 18516, 18989, 19033, 18928, 17727, 17693, 17721, - 22793, 22886, 22917, 22818, 22886, 22793, 35589, 35417, 35348, 36639, 37105, 37169, 35147, - 34946, 34936, 42369, 42401, 42310, 42412, 42269, 42172, 42287, 42172, 42178, 922, 1017, - 988, 1001, 1165, 1139, 8229, 8399, 8238, 15282, 15203, 14933, 17721, 17559, 17532, - 42126, 42019, 42008, 2326, 2446, 2447, 25748, 25770, 25840, 25748, 25840, 25847, 35348, - 35417, 35261, 38438, 38403, 38405, 38620, 38403, 38438, 1140, 1812, 1533, 1212, 1213, - 1302, 1136, 1193, 1107, 41996, 41990, 41771, 42239, 41990, 41996, 42595, 42391, 42285, - 42307, 42370, 42199, 42251, 42133, 42047, 1987, 2249, 2418, 1920, 1931, 2019, 1763, - 1871, 1677, 1407, 1686, 1610, 27861, 27686, 27747, 27861, 27747, 27804, 1414, 1701, - 1365, 1677, 1871, 1604, 14355, 14577, 14690, 14355, 14298, 14577, 26282, 26479, 26308, - 26946, 27088, 26955, 28455, 28211, 28478, 28455, 28326, 28211, 26253, 26479, 26282, 26253, - 26124, 26142, 4672, 4774, 4120, 4781, 4774, 5278, 4526, 4201, 4677, 8150, 8499, - 8223, 7040, 7085, 7063, 25001, 25305, 24914, 24059, 23920, 24359, 1658, 1931, 1920, - 18594, 18497, 18518, 18688, 18497, 18594, 22886, 22967, 22917, 22994, 22967, 22886, 28095, - 27956, 28208, 28455, 28478, 28584, 28579, 28696, 28727, 37169, 37105, 37122, 40778, 40894, - 40538, 40903, 40894, 40778, 959, 935, 1025, 1025, 935, 984, 984, 935, 1022, - 1455, 1205, 645, 959, 1025, 1017, 959, 1017, 922, 2942, 3152, 3141, 2636, - 2597, 2619, 2942, 2604, 2825, 10922, 10527, 10814, 11156, 11290, 11594, 26806, 26595, - 26639, 40370, 40203, 39980, 39758, 39705, 39616, 40370, 39980, 40332, 1073, 1193, 1163, - 1163, 1130, 986, 3023, 3356, 3543, 10814, 10527, 10714, 17094, 17250, 17407, 16864, - 16674, 16346, 40190, 40097, 40113, 3715, 5134, 4013, 2830, 2760, 2901, 2634, 2743, - 2730, 2634, 2730, 2566, 11099, 11290, 11156, 30684, 30831, 30573, 30573, 30831, 30717, - 29573, 29688, 29465, 12596, 12378, 12504, 12596, 12749, 12767, 17721, 17693, 17559, 16685, - 16900, 16583, 35148, 35119, 35026, 3884, 3761, 4081, 3775, 3761, 3884, 13680, 13417, - 13709, 34408, 33991, 34646, 32185, 32099, 32090, 31930, 31851, 31484, 38728, 38667, 38610, - 39289, 39360, 39390, 26929, 26901, 27100, 25847, 25840, 25874, 26799, 26806, 26639, 41313, - 41464, 41754, 41301, 41239, 41141, 41203, 41374, 41085, 41130, 41128, 40984, 41464, 41877, - 41754, 2563, 2597, 2636, 2397, 2652, 2523, 11306, 11632, 11691, 12530, 12581, 12811, - 13075, 13123, 13429, 40457, 40464, 40302, 40578, 40378, 41027, 40414, 40499, 40621, 40414, - 40621, 40544, 8038, 8156, 8280, 8038, 8280, 8216, 34000, 34135, 33983, 35200, 35148, - 35026, 34106, 34135, 34000, 4977, 5047, 5081, 3715, 4013, 3959, 6890, 6931, 6782, - 16292, 16566, 15992, 25229, 25209, 25364, 23658, 23362, 23581, 25679, 25374, 25364, 26152, - 26211, 26310, 34522, 34624, 34301, 37209, 37169, 37122, 37653, 37595, 38132, 41899, 41834, - 41816, 1156, 1110, 1023, 1559, 1444, 1533, 1594, 1740, 1618, 26060, 26152, 26218, - 42391, 42375, 42303, 42369, 42310, 42318, 3761, 3634, 3824, 8828, 8644, 8795, 8597, - 8644, 8677, 8150, 8223, 8167, 17250, 17172, 17201, 17094, 17172, 17250, 42251, 42060, - 42071, 41990, 41980, 41961, 1021, 1130, 1106, 2446, 2409, 2523, 1891, 2249, 1987, - 12770, 12596, 12767, 12371, 12530, 12258, 18300, 18646, 18550, 17393, 17559, 17400, 29251, - 29039, 29434, 28561, 28468, 28208, 28937, 29020, 28727, 28937, 28727, 28696, 13007, 13123, - 13075, 14422, 14441, 14126, 14126, 14441, 14310, 28486, 28468, 28537, 28211, 28442, 28478, - 12052, 11851, 12307, 11546, 11204, 11677, 12052, 12307, 12224, 11778, 11839, 11878, 25607, - 25374, 25679, 40522, 40578, 40640, 41787, 41927, 41832, 41999, 42126, 42008, 41756, 41384, - 41830, 1023, 1110, 1056, 7122, 7241, 7295, 7122, 7295, 7211, 35258, 35148, 35200, - 18497, 18350, 18518, 18170, 18350, 18497, 39609, 39674, 39448, 40033, 39670, 39906, 39600, - 39755, 39565, 39298, 39103, 38882, 41378, 41301, 41425, 40471, 40472, 40501, 9562, 9743, - 9502, 9562, 9289, 9421, 32273, 32185, 32395, 39623, 39289, 39390, 2333, 2409, 2446, - 12224, 12307, 12378, 13656, 13951, 13536, 18989, 18928, 18806, 18928, 18863, 18806, 42375, - 42370, 42307, 42483, 42318, 42269, 42548, 42369, 42580, 7310, 7295, 7412, 8229, 8038, - 8216, 7865, 8085, 8031, 7865, 7967, 7921, 38024, 38072, 38111, 38963, 38899, 38994, - 38722, 38899, 38548, 37056, 37536, 37862, 7310, 7276, 7211, 1629, 1618, 1802, 1915, - 2102, 2127, 1998, 2127, 2098, 1931, 1909, 2019, 1823, 1909, 1931, 1734, 1920, - 1852, 1773, 1927, 1763, 3761, 3577, 3634, 4247, 3841, 4055, 3830, 3841, 3720, - 38596, 38433, 38475, 38667, 38620, 38577, 38426, 38087, 38226, 38859, 38728, 38770, 42069, - 41980, 41990, 41988, 42022, 41832, 1136, 1099, 1212, 1108, 1073, 1163, 982, 1073, - 1108, 969, 1023, 1056, 969, 1056, 1103, 969, 1103, 924, 939, 1106, 1100, - 939, 1053, 999, 17172, 17060, 17056, 14808, 14760, 14944, 17094, 17060, 17172, 24774, - 24586, 25047, 24774, 24577, 24586, 29039, 28740, 28719, 40894, 41029, 40664, 41995, 41832, - 42018, 40938, 40903, 40778, 42133, 42141, 42003, 42251, 42141, 42133, 42159, 42126, 41999, - 42194, 42287, 42178, 15583, 15753, 15841, 15603, 15753, 15583, 25748, 25607, 25679, 25055, - 24774, 25047, 25921, 25847, 25874, 25921, 25874, 26060, 41834, 41779, 41685, 41954, 41779, - 41834, 1618, 1740, 1802, 14944, 14760, 14727, 13286, 13370, 13398, 14609, 14760, 14665, - 26310, 26211, 26337, 27277, 27332, 27444, 27551, 27444, 27686, 27551, 27686, 27713, 27804, - 27956, 27861, 27835, 27964, 27750, 26806, 26946, 26955, 26799, 26946, 26806, 26419, 26639, - 26479, 18646, 18863, 18550, 1444, 1140, 1533, 1389, 1559, 1623, 4328, 4201, 4526, - 25881, 26124, 25862, 38623, 38620, 38667, 38648, 38596, 38570, 2022, 1998, 2098, 13417, - 13370, 13364, 12168, 12224, 12378, 14052, 14183, 14194, 13211, 13361, 13383, 13211, 13383, - 13123, 2283, 2326, 2447, 2283, 2447, 2249, 12168, 12378, 12254, 40607, 40365, 40442, - 40203, 40190, 40113, 40097, 40078, 39906, 40239, 40190, 40203, 40472, 40332, 40464, 11761, - 11880, 11753, 11761, 11851, 11880, 11074, 11204, 11049, 5933, 5587, 5854, 6003, 5810, - 5933, 6035, 6034, 6003, 6141, 6034, 6035, 6247, 6372, 6231, 6449, 6390, 6638, - 6388, 6390, 6316, 10908, 10892, 11001, 8985, 9083, 9194, 11298, 11306, 11290, 11290, - 11306, 11594, 11632, 11778, 11878, 10922, 10994, 11020, 10714, 10527, 10288, 30684, 30573, - 30541, 31606, 31831, 32061, 30573, 30444, 30541, 36198, 36378, 36416, 36140, 36159, 35843, - 36166, 36159, 36140, 35722, 35630, 35589, 35603, 35589, 35348, 40240, 40078, 40097, 9692, - 10288, 10014, 9684, 9655, 9692, 23658, 23581, 24020, 21435, 21376, 21538, 32380, 32273, - 32395, 42393, 42287, 42194, 42370, 42362, 42199, 31976, 31851, 31930, 30463, 30723, 30997, - 30463, 30170, 30386, 30386, 30170, 30248, 29039, 28958, 28740, 31976, 31930, 32099, 11298, - 11290, 11099, 12722, 12833, 12581, 12884, 13075, 12833, 31101, 31068, 31127, 20572, 20666, - 20651, 20957, 20970, 21075, 21075, 21712, 20930, 20399, 20666, 20572, 20399, 20572, 20404, - 20399, 20404, 20369, 20225, 20204, 20222, 20204, 20062, 20222, 20062, 20041, 20222, 1073, - 1107, 1193, 1338, 1742, 1570, 982, 1107, 1073, 6372, 6388, 6316, 38426, 38226, - 38403, 37966, 38072, 38024, 38114, 38072, 37966, 40078, 40033, 39906, 39705, 39674, 39609, - 42248, 42100, 42388, 20666, 20918, 20687, 42419, 42595, 42175, 42647, 42493, 42375, 42375, - 42493, 42370, 42370, 42542, 42362, 42560, 42325, 42603, 42325, 42270, 42603, 42496, 42283, - 42401, 7818, 7978, 7950, 6449, 6374, 6390, 37504, 37315, 37534, 37504, 37534, 37615, - 20205, 20083, 20087, 20087, 20083, 19993, 19993, 20083, 19991, 19991, 19919, 19885, 20235, - 20260, 20205, 20327, 20260, 20403, 20518, 20403, 20665, 20518, 20665, 20717, 21113, 21129, - 21289, 21113, 21289, 21351, 21289, 21376, 21435, 20062, 19956, 20041, 2597, 2530, 2631, - 2678, 2636, 2783, 2530, 2563, 2513, 2783, 2825, 2678, 41128, 40817, 40984, 40522, - 40472, 40464, 39729, 39764, 40050, 40428, 40565, 40442, 41980, 41989, 41961, 42069, 41989, - 41980, 42069, 41990, 42234, 42022, 42159, 41970, 41995, 41988, 41832, 41340, 41776, 41837, - 23794, 23658, 24020, 25229, 25364, 25374, 10537, 10538, 10734, 40033, 39884, 39670, 13370, - 12993, 13244, 11993, 12110, 11839, 19745, 19757, 19956, 22677, 22503, 22676, 20970, 21138, - 21075, 28455, 28584, 28579, 29404, 29431, 29279, 27750, 27361, 27630, 40903, 41029, 40894, - 41194, 41029, 40903, 42488, 42455, 42279, 2187, 2283, 2077, 22406, 22539, 22402, 22967, - 23144, 23255, 40938, 40816, 40967, 40710, 40816, 40626, 1909, 1935, 1987, 1677, 1773, - 1763, 7898, 7818, 7950, 7898, 7950, 8038, 8085, 8150, 8167, 7494, 7621, 7595, - 20260, 20083, 20205, 27861, 27956, 27884, 35258, 35261, 35148, 34135, 34300, 34076, 34347, - 34300, 34135, 34095, 34115, 34060, 14609, 14355, 14690, 12788, 12827, 12993, 28095, 28208, - 28420, 27477, 27361, 27339, 38774, 38623, 38667, 38620, 38623, 38403, 38869, 38859, 38749, - 1001, 1139, 1147, 890, 857, 988, 1001, 1147, 885, 11880, 12052, 12069, 11610, - 11753, 11543, 11670, 11778, 11632, 19745, 19537, 19757, 40544, 40565, 40428, 2832, 2942, - 3102, 3841, 3775, 3884, 3830, 3775, 3841, 25320, 25229, 25374, 26060, 25874, 26152, - 26644, 26854, 26853, 25820, 25881, 25862, 27270, 27108, 27281, 26142, 25881, 26136, 41302, - 41134, 41136, 31851, 31537, 31484, 32228, 31976, 32099, 5058, 5085, 5081, 3445, 2774, - 3309, 19757, 19703, 19762, 37615, 37534, 37595, 38648, 38638, 38596, 38596, 38638, 38561, - 41464, 41593, 41877, 41374, 41203, 41239, 42043, 41816, 42112, 1500, 1407, 1610, 1570, - 1450, 1225, 14933, 15203, 14842, 17289, 17245, 16926, 17820, 17763, 17727, 17532, 17393, - 17364, 15886, 15992, 15753, 42126, 42207, 42019, 42551, 42207, 42126, 1823, 1935, 1909, - 14760, 14609, 14690, 15314, 15826, 15557, 22780, 22906, 23114, 22616, 22679, 22603, 22818, - 22679, 22616, 28420, 28208, 28468, 36816, 36869, 36677, 35147, 34936, 35143, 36931, 36869, - 36816, 37122, 37353, 37209, 20083, 19919, 19991, 21522, 21435, 21538, 8597, 8689, 8644, - 8597, 8399, 8689, 2634, 2760, 2743, 2409, 2397, 2523, 2333, 2397, 2409, 2333, - 2446, 2326, 11735, 11993, 11839, 29404, 29279, 29252, 40565, 40607, 40442, 19919, 19848, - 19885, 21580, 21522, 21651, 31924, 31537, 31851, 31243, 31543, 31225, 17060, 16905, 16933, - 16942, 16905, 17060, 12827, 12770, 12860, 12827, 12860, 12993, 12621, 12722, 12581, 28537, - 28468, 28561, 28964, 28958, 29039, 28697, 28937, 28696, 29057, 28937, 28975, 1021, 986, - 1130, 945, 986, 1021, 8677, 8644, 8828, 25607, 25748, 25786, 42150, 42159, 42022, - 42018, 41832, 41927, 19087, 19064, 19371, 17407, 17524, 17829, 17820, 17727, 17721, 19864, - 19757, 19762, 21580, 21510, 21522, 23114, 22906, 23187, 23114, 23187, 23134, 1503, 1523, - 1669, 1398, 1360, 1444, 1503, 1669, 1594, 2030, 1971, 1756, 2851, 2969, 2901, - 12830, 13211, 13007, 13007, 13211, 13123, 13361, 13328, 13536, 14725, 14933, 14842, 14725, - 14842, 14441, 19079, 19102, 18989, 37209, 37353, 37470, 37653, 37615, 37595, 41282, 41128, - 41130, 41646, 41317, 41474, 41883, 41685, 41779, 35258, 35374, 35261, 35026, 34891, 35200, - 9562, 9684, 9704, 9684, 9562, 9421, 8793, 8906, 8634, 32273, 32216, 32185, 31976, - 31967, 31851, 32239, 32216, 32273, 2180, 2333, 2326, 2187, 2326, 2283, 12080, 12199, - 12110, 29252, 29279, 29020, 793, 1088, 1022, 793, 1022, 935, 793, 935, 839, - 21386, 21712, 21075, 42248, 42251, 42071, 42012, 41954, 41899, 42278, 42251, 42248, 1225, - 1450, 1213, 1685, 1734, 1773, 1099, 1136, 1026, 25965, 25748, 25847, 26853, 26854, - 26929, 15680, 15886, 15753, 15320, 15583, 15282, 42528, 42496, 42557, 42448, 42401, 42369, - 17843, 17820, 17721, 18182, 17820, 17843, 23610, 23658, 23794, 23431, 23658, 23610, 35200, - 34891, 34944, 37353, 37475, 37470, 1935, 1891, 1987, 1773, 1734, 1852, 1899, 1686, - 1604, 2743, 2760, 2830, 2730, 2666, 2566, 2666, 2594, 2566, 2711, 2851, 2901, - 10842, 10537, 10734, 11204, 10908, 11001, 11074, 10908, 11204, 14194, 14183, 14298, 14194, - 14298, 14355, 29931, 29895, 29939, 31058, 30463, 30997, 31152, 31243, 30987, 30541, 30444, - 30506, 29680, 29688, 29573, 1407, 1500, 1361, 2566, 2594, 2350, 10756, 10994, 10922, - 11520, 11670, 11632, 11778, 11735, 11839, 11993, 12080, 12110, 10288, 10527, 10312, 11099, - 11156, 11020, 12830, 12884, 12722, 12722, 12884, 12833, 34891, 34697, 34894, 32364, 32445, - 32772, 38570, 38475, 38111, 37970, 37536, 38123, 14052, 13680, 13773, 12247, 12371, 12258, - 12247, 12258, 12199, 29070, 29252, 29020, 29563, 29680, 29573, 29057, 29020, 28937, 1756, - 1971, 1782, 15886, 16292, 15992, 26946, 27108, 27088, 28697, 28696, 28584, 26305, 26479, - 26253, 42150, 42022, 41988, 42236, 42018, 41927, 2634, 2566, 2585, 10605, 10537, 10842, - 8961, 9083, 8985, 31233, 31101, 31127, 31461, 31284, 31537, 40472, 40471, 40332, 40190, - 40240, 40097, 40078, 40052, 40033, 40033, 40061, 39884, 40522, 40457, 40578, 6931, 7040, - 7063, 6942, 7040, 6931, 6931, 6937, 6782, 5028, 5138, 5085, 34522, 34301, 34300, - 37470, 37475, 37504, 775, 939, 477, 22852, 22994, 22886, 22818, 22793, 22679, 42408, - 42412, 42172, 42408, 42172, 42407, 32228, 31967, 31976, 32405, 32380, 32395, 1998, 1915, - 2127, 1952, 1915, 1998, 1823, 1891, 1935, 41272, 41178, 40908, 41302, 41178, 41304, - 40938, 40778, 40816, 2563, 2530, 2597, 2678, 2825, 2604, 11761, 11610, 11546, 12069, - 12052, 12224, 11520, 11632, 11416, 30161, 29939, 30170, 31152, 30987, 30831, 32772, 32445, - 32347, 40640, 40889, 40729, 1389, 1360, 1398, 1442, 1503, 1594, 5058, 5025, 5085, - 3481, 4052, 3473, 14368, 14194, 14355, 15951, 16104, 16346, 27100, 26853, 26929, 27277, - 27444, 27551, 27713, 27686, 27861, 34625, 34522, 34300, 21538, 22197, 21651, 23134, 23275, - 23362, 42540, 42448, 42369, 42407, 42172, 42287, 42407, 42287, 42477, 32772, 32437, 32917, - 34760, 34743, 34682, 38035, 38114, 37966, 38133, 38114, 38035, 41899, 41954, 41834, 41816, - 41811, 42112, 1389, 1623, 1390, 12444, 12621, 12371, 12371, 12621, 12581, 25881, 26142, - 26124, 25862, 25584, 25725, 29514, 29573, 29404, 28211, 27975, 28112, 29514, 29404, 29318, - 40834, 40816, 40710, 41756, 41914, 41596, 41766, 41189, 41340, 25229, 25055, 25047, 23431, - 23134, 23362, 24954, 25055, 25024, 42239, 41996, 42141, 42150, 41988, 41995, 42150, 41995, - 42236, 1888, 2022, 1818, 27884, 27713, 27861, 28732, 28561, 28740, 28732, 28740, 28958, - 28602, 28478, 28442, 42483, 42269, 42432, 3775, 3694, 3761, 3720, 3841, 4247, 3694, - 3830, 3720, 31633, 31606, 31543, 38829, 38899, 38722, 38899, 38963, 38882, 38779, 38722, - 38638, 36159, 36166, 36198, 36140, 36085, 36200, 35843, 36085, 36140, 35348, 35374, 35603, - 6316, 6231, 6372, 6247, 6134, 6034, 6034, 5810, 6003, 7037, 7000, 7122, 7310, - 7211, 7295, 7479, 7412, 7719, 7479, 7719, 7463, 35603, 35374, 35449, 34894, 34697, - 34624, 35374, 35258, 35449, 37618, 37470, 37504, 37618, 37504, 37615, 6501, 6449, 6769, - 6621, 6501, 6769, 12168, 12069, 12224, 12378, 12596, 12508, 11735, 12080, 11993, 14052, - 13913, 13680, 13286, 12993, 13370, 14368, 14355, 14609, 18182, 18300, 18097, 18803, 18806, - 18863, 18182, 18097, 17820, 22503, 22197, 22434, 23431, 23362, 23658, 22994, 23144, 22967, - 23099, 23144, 22994, 27339, 27194, 27088, 27630, 27477, 27473, 29318, 29404, 29252, 31627, - 31633, 31543, 38774, 38667, 38728, 37653, 37618, 37615, 38860, 38728, 38859, 38869, 38749, - 39096, 38312, 38111, 38072, 42393, 42194, 42387, 42432, 42269, 42412, 42373, 41937, 42136, - 42542, 42493, 42748, 1856, 1936, 1915, 1782, 1971, 1936, 1393, 1458, 1503, 27884, - 27956, 28021, 41465, 41301, 41491, 40640, 40501, 40522, 41646, 41474, 41599, 1501, 1629, - 1802, 1458, 1623, 1523, 13370, 13417, 13398, 28964, 28732, 28958, 28486, 28420, 28468, - 35270, 35258, 35200, 34743, 34894, 34624, 34743, 34624, 34522, 7956, 8150, 8085, 7865, - 7921, 7849, 922, 839, 959, 867, 1156, 1023, 920, 904, 876, 969, 906, - 1023, 912, 982, 1108, 912, 1108, 986, 4004, 4526, 4573, 5086, 5354, 5368, - 14933, 15059, 15282, 16033, 16416, 16292, 14422, 14725, 14441, 13328, 13361, 13211, 13328, - 13079, 13209, 41754, 41646, 41599, 924, 906, 969, 18803, 18863, 18646, 17532, 17559, - 17393, 983, 1136, 1107, 2835, 3329, 3071, 2760, 2711, 2901, 2642, 2711, 2760, - 2642, 2760, 2634, 2642, 2634, 2585, 2841, 2969, 2851, 10756, 10922, 10814, 11298, - 11262, 11306, 12131, 12285, 12080, 10756, 10814, 10714, 12080, 12247, 12199, 13572, 13328, - 13387, 12285, 12247, 12080, 18170, 17829, 18350, 15948, 15951, 16225, 25725, 25584, 25305, - 27339, 27088, 27108, 31100, 31152, 30831, 31627, 31676, 31633, 30506, 30444, 30223, 29943, - 29688, 29965, 40379, 40239, 40203, 39953, 39674, 39705, 40370, 40332, 40471, 40607, 40834, - 40710, 41213, 41194, 40903, 40912, 40834, 40607, 40721, 40607, 40565, 40544, 40428, 40414, - 39764, 39737, 39941, 41954, 41883, 41779, 42147, 41883, 41954, 42035, 41914, 41756, 42035, - 41756, 41830, 2711, 2841, 2851, 10658, 10756, 10714, 2022, 1952, 1998, 1888, 1952, - 2022, 3443, 3659, 3634, 1855, 1856, 1952, 13656, 13328, 13572, 40501, 40472, 40522, - 40534, 40370, 40471, 1338, 1365, 1701, 1309, 1365, 1338, 755, 890, 988, 40240, - 40052, 40078, 30255, 30161, 30170, 29251, 28964, 29039, 30255, 30170, 30463, 29965, 29688, - 29785, 1011, 1225, 1213, 35270, 35200, 35096, 37169, 36931, 36816, 36869, 36726, 36677, - 37230, 36931, 37169, 37217, 37169, 37209, 37411, 37217, 37209, 37595, 37829, 38132, 30874, - 30831, 30684, 39096, 38893, 39270, 30161, 29931, 29939, 29785, 29688, 29680, 40507, 40501, - 40642, 39941, 39737, 39755, 3830, 3694, 3775, 3637, 3694, 3720, 1361, 1500, 1414, - 1677, 1685, 1773, 1747, 1823, 1931, 14951, 15059, 14933, 38860, 38774, 38728, 38132, - 37829, 38087, 38751, 38779, 38648, 38648, 38779, 38638, 17289, 16926, 16830, 16416, 16583, - 16292, 28655, 28537, 28561, 28655, 28561, 28732, 28478, 28602, 28584, 29057, 29070, 29020, - 29827, 29785, 29680, 28112, 27975, 27835, 8004, 7898, 8038, 8597, 8238, 8399, 8302, - 8238, 8597, 20918, 20970, 20957, 21138, 21386, 21075, 22778, 22818, 22616, 20666, 20689, - 20918, 20535, 20689, 20666, 20399, 20369, 20225, 20399, 20389, 20423, 20225, 20222, 20284, - 20222, 20041, 20080, 20041, 20038, 20080, 28975, 29070, 29057, 32228, 32099, 32216, 30401, - 30255, 30463, 38114, 38312, 38072, 38290, 38312, 38114, 40834, 40967, 40816, 41070, 40967, - 41149, 20260, 20232, 20083, 20083, 19881, 19919, 19919, 19881, 19848, 19384, 19304, 19371, - 20717, 20665, 20855, 20717, 20855, 20817, 21510, 21289, 21435, 21510, 21435, 21522, 20689, - 20796, 20918, 42539, 42256, 42390, 42488, 42512, 42455, 42455, 42595, 42419, 42539, 42390, - 42737, 9692, 10014, 9704, 9692, 9704, 9684, 20041, 19976, 20038, 39600, 39153, 39813, - 39828, 39755, 39600, 42560, 42541, 42488, 20518, 20327, 20403, 20796, 20970, 20918, 42486, - 42387, 42495, 42226, 42150, 42236, 42541, 42512, 42488, 29865, 29785, 29867, 17094, 16942, - 17060, 16731, 16942, 16719, 24359, 23920, 23804, 1756, 1709, 2011, 1458, 1523, 1503, - 1687, 1709, 1756, 1614, 1685, 1677, 2077, 2283, 2249, 2585, 2422, 2486, 41378, - 41374, 41239, 41491, 41301, 41317, 7831, 7865, 7849, 20327, 20232, 20260, 36506, 36418, - 37183, 4865, 4927, 5047, 4917, 4927, 4882, 6327, 6316, 6390, 7447, 7479, 7448, - 7358, 7494, 7595, 34347, 34135, 34106, 35096, 35200, 34944, 37411, 37209, 37470, 38426, - 38403, 38793, 7040, 7358, 7595, 6519, 6185, 5875, 1540, 1604, 1686, 13092, 13286, - 13199, 14524, 14368, 14609, 14665, 14760, 14808, 13988, 14422, 14126, 14951, 15211, 15059, - 20970, 21093, 21138, 25965, 25921, 26060, 25965, 25847, 25921, 27279, 27277, 27579, 27224, - 27277, 27279, 42652, 42390, 42496, 18803, 18646, 18791, 18803, 18791, 18821, 20038, 19976, - 19867, 21093, 21167, 21138, 24534, 24524, 24288, 22677, 22780, 22808, 39298, 38882, 38963, - 42432, 42412, 42436, 42557, 42496, 42401, 42387, 42194, 42551, 2450, 2631, 2530, 1952, - 1856, 1915, 1658, 1920, 1734, 27630, 27361, 27477, 28067, 28112, 27835, 41178, 41302, - 41136, 41272, 40908, 41029, 19867, 19976, 19757, 21167, 21297, 21138, 16674, 16864, 16905, - 26444, 26644, 26668, 24534, 24577, 24524, 41877, 41593, 41685, 42140, 41811, 41989, 1594, - 1618, 1442, 965, 990, 1198, 14472, 14665, 14618, 15211, 15320, 15282, 15211, 15282, - 15059, 26218, 26346, 26193, 41837, 41766, 41340, 42236, 41995, 42018, 6890, 6942, 6931, - 35096, 34944, 35056, 37411, 37470, 37497, 982, 983, 1107, 1099, 1014, 1212, 932, - 983, 982, 21297, 21386, 21138, 42479, 41592, 42362, 42251, 42239, 42141, 42069, 42140, - 41989, 3408, 3443, 3634, 19864, 19867, 19757, 18646, 18332, 18791, 29251, 29434, 29516, - 28505, 28420, 28486, 30401, 30463, 30830, 32239, 32228, 32216, 32239, 32273, 32380, 32239, - 32380, 32386, 42547, 42481, 42362, 42542, 42370, 42493, 42412, 42408, 42436, 20113, 19881, - 20083, 16731, 16905, 16942, 19537, 19703, 19757, 22780, 22987, 22808, 38431, 38658, 38453, - 12508, 12596, 12770, 13417, 13680, 13671, 28505, 28486, 28537, 7865, 7956, 8085, 8317, - 8446, 8499, 7942, 7956, 7865, 10167, 10279, 9596, 31633, 31676, 31606, 31627, 31543, - 31243, 38287, 38132, 38087, 37970, 38133, 38035, 38796, 38829, 38779, 38123, 38133, 37970, - 40017, 39758, 39884, 42616, 42239, 42251, 9083, 8871, 8893, 16033, 16292, 15886, 19537, - 19199, 19703, 22780, 23114, 22987, 37497, 37470, 37618, 37646, 37618, 37653, 38774, 38920, - 38623, 38869, 38860, 38859, 38900, 38860, 38869, 38779, 38829, 38722, 38570, 38111, 38312, - 42229, 42140, 42069, 920, 924, 1103, 906, 867, 1023, 920, 1103, 1001, 775, - 945, 1021, 868, 945, 664, 1442, 1618, 1629, 22987, 23114, 23025, 24577, 24774, - 24524, 42620, 42373, 42136, 42436, 42408, 42553, 42226, 42126, 42159, 11753, 11610, 11761, - 11049, 11204, 11270, 10908, 10829, 10842, 12508, 12770, 12711, 23114, 23134, 23025, 23573, - 23920, 23510, 22778, 22616, 22406, 42481, 42479, 42362, 42568, 42479, 42481, 19537, 19102, - 19079, 22197, 22503, 22261, 8871, 8677, 8828, 7447, 7412, 7479, 40379, 40203, 40370, - 40379, 40240, 40239, 40239, 40240, 40190, 40061, 40017, 39884, 2711, 2555, 2841, 3078, - 3315, 2923, 2594, 2397, 2332, 11543, 11546, 11610, 10537, 10158, 10456, 10930, 11099, - 10994, 10994, 11099, 11020, 11207, 11099, 11168, 30541, 30793, 30684, 31684, 31831, 31676, - 30315, 30506, 30223, 30315, 30223, 30163, 30315, 30163, 30147, 40535, 40379, 40370, 2678, - 2513, 2636, 2908, 2832, 3102, 24954, 24774, 25055, 2001, 2397, 2333, 11099, 11262, - 11298, 19079, 18989, 18806, 30161, 30166, 29931, 29931, 30010, 29895, 31924, 31851, 31967, - 30110, 29965, 29969, 30110, 30163, 29965, 35056, 34944, 34894, 15524, 15603, 15583, 15524, - 15583, 15320, 27339, 27108, 27270, 32001, 31924, 31967, 39674, 39623, 39390, 39767, 39623, - 39674, 39941, 40050, 39764, 39951, 40050, 39941, 41465, 41425, 41301, 40501, 40507, 40471, - 41644, 41425, 41465, 41491, 41317, 41597, 42043, 42012, 41899, 42147, 42012, 42166, 28526, - 28655, 28522, 28964, 28655, 28732, 28654, 28697, 28602, 28602, 28697, 28584, 29865, 29965, - 29785, 28442, 28211, 28112, 39388, 39538, 39652, 39911, 39951, 39941, 26241, 26253, 26142, - 41597, 41317, 41646, 2404, 2513, 2678, 22818, 22852, 22886, 22778, 22852, 22818, 29573, - 29514, 29563, 40578, 40889, 40640, 42557, 42401, 42448, 42408, 42407, 42553, 17738, 17843, - 17721, 17738, 17721, 17716, 1393, 1390, 1458, 1856, 1782, 1936, 1662, 1782, 1856, - 2077, 2249, 2033, 6231, 6134, 6247, 6316, 6134, 6231, 6327, 6134, 6316, 7037, - 7122, 7211, 28021, 28095, 28185, 28021, 27956, 28095, 27277, 27100, 26901, 41399, 41374, - 41378, 14951, 14933, 14725, 25024, 25055, 25112, 42140, 42121, 41811, 42239, 42234, 41990, - 42321, 42234, 42636, 42229, 42234, 42321, 40061, 40033, 40052, 5694, 5810, 6034, 8153, - 8499, 8150, 13913, 14052, 14143, 14665, 14524, 14609, 14472, 14524, 14665, 27224, 27100, - 27277, 839, 935, 959, 839, 922, 784, 922, 857, 784, 2513, 2450, 2530, - 5227, 5368, 5628, 7447, 7276, 7412, 7719, 7818, 7689, 25607, 25320, 25374, 25467, - 25320, 25607, 25112, 25025, 25024, 29318, 29252, 29070, 34936, 34946, 34708, 36726, 36425, - 36677, 41300, 40817, 41128, 42212, 42121, 42140, 42557, 42448, 42540, 6863, 6621, 6769, - 1823, 1841, 1891, 1747, 1841, 1823, 1658, 1734, 1685, 983, 1026, 1136, 932, - 1026, 983, 6863, 6964, 6621, 16830, 16926, 16685, 22261, 22503, 22677, 23025, 23134, - 23319, 23134, 23431, 23319, 23477, 23510, 23144, 25647, 25725, 25305, 36831, 36726, 36869, - 36831, 36869, 36931, 36831, 37197, 36950, 42540, 42369, 42548, 42477, 42287, 42393, 31590, - 31461, 31537, 38431, 38287, 38426, 39270, 38893, 39435, 42318, 42580, 42369, 9562, 9502, - 9289, 10677, 10994, 10756, 1407, 1479, 1686, 1603, 1658, 1685, 1361, 1479, 1407, - 1361, 1414, 1309, 1414, 1365, 1309, 851, 867, 906, 990, 1321, 1198, 945, - 912, 986, 868, 912, 945, 23946, 23794, 24020, 23946, 24020, 24057, 5670, 5587, - 5933, 6621, 6707, 6667, 40732, 40721, 40565, 41070, 40903, 40938, 40732, 40565, 40544, - 2187, 2180, 2326, 2033, 2249, 1891, 28697, 28975, 28937, 29154, 28975, 29053, 4917, - 5025, 5058, 4917, 5058, 4927, 7482, 7831, 7849, 7956, 8153, 8150, 6868, 7358, - 7040, 1818, 2022, 2455, 3694, 3577, 3761, 3337, 3023, 3543, 3637, 3577, 3694, - 3609, 3649, 3720, 13286, 13092, 12993, 14052, 14194, 14143, 28526, 28505, 28537, 28526, - 28537, 28655, 28480, 28442, 28112, 6621, 6964, 6707, 15453, 15524, 15320, 15829, 16033, - 15886, 17271, 17364, 17289, 25977, 26136, 25881, 25855, 25725, 25713, 25977, 25881, 25820, - 39388, 39813, 39153, 851, 906, 901, 7880, 8153, 7956, 22261, 22677, 22365, 23533, - 23431, 23610, 38426, 38287, 38087, 37754, 37646, 37653, 38920, 38774, 38860, 16731, 16674, - 16905, 14367, 14368, 14524, 18170, 18497, 18688, 24906, 24524, 24774, 25112, 25055, 25229, - 42234, 42229, 42069, 42321, 42728, 42508, 2450, 2272, 2631, 784, 857, 748, 19384, - 19371, 19848, 22677, 22808, 22741, 38695, 38570, 38763, 39388, 39298, 39538, 42318, 42483, - 42580, 1140, 1444, 1360, 1458, 1390, 1623, 1442, 1629, 1433, 1309, 1338, 1063, - 7804, 7831, 7709, 24906, 24774, 24954, 34743, 34760, 34894, 34296, 34347, 34106, 34115, - 34106, 34060, 33423, 32827, 33411, 41877, 41685, 41883, 42121, 42112, 41811, 42212, 42112, - 42121, 1782, 1687, 1756, 1662, 1687, 1782, 1540, 1686, 1479, 1614, 1677, 1604, - 2003, 2187, 2077, 14143, 14194, 14316, 27630, 27813, 27835, 27339, 27473, 27477, 27270, - 27473, 27339, 41425, 41399, 41378, 41374, 41282, 41130, 41498, 41399, 41644, 41658, 41465, - 41491, 4920, 4917, 4882, 7090, 7037, 7211, 8038, 8229, 8004, 32405, 32395, 33137, - 32228, 32192, 31967, 31590, 31233, 31461, 34682, 34743, 34522, 37393, 37230, 37217, 37754, - 37653, 38188, 748, 857, 890, 901, 906, 924, 1551, 1540, 1454, 13865, 13671, - 13680, 13328, 13656, 13536, 14457, 14951, 14725, 15206, 15453, 15320, 12444, 12722, 12621, - 12285, 12371, 12247, 26668, 26644, 26853, 27277, 27551, 27680, 27551, 27713, 27680, 28185, - 28095, 28420, 31676, 31831, 31606, 31627, 31243, 31427, 39132, 39085, 39096, 39947, 39767, - 39674, 831, 1160, 867, 6942, 6900, 7040, 6890, 6770, 6942, 5875, 6185, 5871, - 5875, 5871, 5500, 22741, 22808, 22915, 35407, 35258, 35270, 35407, 35449, 35258, 36200, - 36166, 36140, 36390, 36378, 36166, 37036, 36418, 36829, 35407, 35270, 35477, 30506, 30549, - 30541, 30510, 30549, 30506, 30510, 30506, 30315, 30510, 30315, 30343, 29969, 29965, 29865, - 11074, 10829, 10908, 11049, 10829, 11074, 11880, 12069, 11753, 30255, 30166, 30161, 31058, - 30997, 31101, 2003, 2180, 2187, 2033, 1891, 1868, 11735, 11778, 11670, 29154, 29318, - 29070, 29154, 29070, 28975, 39096, 38985, 38869, 39085, 38985, 39096, 10829, 10605, 10842, - 3337, 3543, 3443, 4247, 3609, 3720, 13671, 13398, 13417, 11753, 12069, 12168, 19304, - 19087, 19371, 18821, 19079, 18806, 18821, 18806, 18803, 25320, 25112, 25229, 25024, 24906, - 24954, 26218, 26152, 26310, 30271, 30166, 30255, 35477, 35270, 35096, 40273, 40061, 40052, - 39773, 39659, 39947, 40379, 40436, 40240, 40507, 40534, 40471, 40642, 40534, 40507, 40642, - 40501, 40640, 41503, 41282, 41374, 42150, 42226, 42159, 42486, 42477, 42393, 42236, 41927, - 41914, 24057, 24288, 24186, 24057, 24020, 24288, 23711, 23533, 23610, 25725, 25855, 25820, - 26136, 26241, 26142, 25647, 25305, 25550, 35062, 35056, 34894, 34625, 34682, 34522, 40436, - 40052, 40240, 42373, 42388, 42100, 42441, 42388, 42954, 7783, 7898, 8004, 7831, 7942, - 7865, 7804, 7942, 7831, 7849, 7494, 7482, 38133, 38290, 38114, 36378, 36198, 36166, - 1026, 1024, 1099, 954, 1024, 1026, 782, 831, 867, 873, 901, 924, 18644, - 18170, 18688, 26668, 26853, 26815, 26161, 26241, 26136, 41766, 41868, 41830, 42111, 41868, - 41766, 42486, 42393, 42387, 42580, 42483, 42619, 3309, 3315, 3473, 2835, 3071, 2841, - 12770, 12827, 12711, 11416, 11632, 11306, 11207, 11306, 11262, 11207, 11262, 11099, 29867, - 29969, 29865, 40729, 40642, 40640, 10658, 10714, 10288, 9289, 9502, 9262, 9262, 8906, - 8878, 8317, 8499, 8153, 32239, 32192, 32228, 32370, 32570, 32336, 42647, 42375, 42391, - 42479, 42571, 42136, 42483, 42432, 42514, 3337, 3443, 3408, 2832, 2604, 2942, 2513, - 2404, 2450, 2450, 2216, 2272, 3562, 3720, 3649, 5587, 5227, 5628, 40499, 40414, - 39729, 39911, 39941, 39828, 39911, 39828, 39813, 12711, 12827, 12736, 12285, 12444, 12371, - 12131, 12444, 12285, 29318, 29563, 29514, 29053, 28975, 28697, 29053, 28697, 28777, 26815, - 26853, 27008, 28361, 28185, 28420, 29036, 28655, 28964, 41070, 40938, 40967, 41776, 41340, - 41195, 41877, 41883, 42238, 11548, 11753, 11540, 11692, 11735, 11670, 34524, 34625, 34300, - 34905, 34894, 34760, 34524, 34300, 34347, 42542, 42547, 42362, 42514, 42432, 42436, 863, - 932, 982, 868, 982, 912, 23711, 23610, 23794, 22915, 22808, 22987, 24519, 24288, - 24524, 39895, 39911, 39813, 39388, 39153, 39298, 1551, 1614, 1604, 1658, 1747, 1931, - 1551, 1604, 1540, 7090, 7276, 7307, 7090, 7211, 7276, 14316, 14194, 14368, 13913, - 13865, 13680, 13371, 13199, 13398, 14367, 14524, 14472, 34946, 34965, 34385, 35360, 35147, - 35143, 12463, 12711, 12556, 13730, 13865, 13770, 27593, 27813, 27630, 28067, 27813, 27811, - 42560, 42643, 42541, 42541, 42643, 42512, 42512, 42681, 42455, 42895, 42607, 42547, 42539, - 42603, 42270, 42790, 42905, 42897, 42652, 42496, 42711, 42496, 42528, 42676, 42528, 42557, - 42676, 42557, 42760, 42676, 16674, 16502, 16346, 16526, 16502, 16674, 20399, 20535, 20666, - 20689, 20771, 20796, 20796, 20890, 20970, 20970, 21140, 21093, 21093, 21140, 21167, 21167, - 21190, 21297, 21297, 21293, 21386, 22379, 22406, 21712, 20423, 20535, 20399, 20399, 20225, - 20389, 20225, 20284, 20389, 20153, 20284, 20222, 20153, 20222, 20080, 20153, 20080, 20069, - 20080, 20038, 20069, 20535, 20771, 20689, 8187, 8317, 8153, 20069, 20038, 20066, 20771, - 20890, 20796, 33002, 32827, 32772, 42603, 42643, 42560, 1024, 1014, 1099, 910, 1014, - 1024, 1454, 1540, 1479, 15557, 15826, 15951, 27008, 26853, 27100, 27680, 27713, 27773, - 27713, 27884, 27773, 27281, 27108, 27242, 41399, 41420, 41374, 41825, 41597, 41646, 3408, - 3634, 3577, 20232, 20113, 20083, 19677, 19384, 19848, 19304, 19207, 19087, 20327, 20390, - 20232, 20518, 20390, 20327, 20482, 20390, 20518, 21351, 21289, 21510, 21351, 21510, 21500, - 21510, 21580, 21500, 21580, 21654, 21500, 20066, 20038, 19930, 32370, 32192, 32239, 30010, - 30076, 29938, 42643, 42681, 42512, 20390, 20302, 20232, 19930, 20038, 19867, 29591, 29563, - 29318, 1661, 1747, 1293, 3401, 3408, 3577, 4941, 5278, 5086, 3481, 3715, 3959, - 39017, 38900, 38869, 39564, 39289, 39623, 39017, 38869, 38985, 19866, 19930, 19867, 21072, - 21140, 20970, 25786, 25965, 25935, 26218, 25965, 26060, 18646, 18300, 18332, 19864, 19866, - 19867, 18300, 18182, 18332, 1501, 1802, 1709, 1216, 1360, 1389, 20302, 20113, 20232, - 19831, 19866, 19864, 21140, 21190, 21167, 35843, 36033, 36085, 35630, 36033, 35620, 7307, - 7276, 7447, 35147, 35094, 34946, 35630, 35722, 36033, 34905, 34760, 34682, 37647, 37497, - 37618, 37647, 37618, 37646, 38308, 38132, 38287, 1380, 1454, 1312, 1215, 1309, 1063, - 1868, 1891, 1841, 5054, 5085, 5025, 12508, 12711, 12463, 12508, 12254, 12378, 26241, - 26305, 26253, 26364, 26305, 26241, 35603, 35722, 35589, 42147, 41954, 42012, 41710, 41658, - 41791, 42553, 42514, 42436, 42495, 42387, 42551, 8906, 8667, 8588, 10658, 10493, 10665, - 35603, 35687, 35722, 7783, 7689, 7818, 19762, 19831, 19864, 38570, 38751, 38648, 38695, - 38751, 38570, 6449, 6327, 6374, 6374, 6327, 6390, 5694, 5670, 5810, 5810, 5670, - 5933, 5587, 5147, 5227, 6454, 6327, 6449, 6454, 6449, 6501, 6454, 6501, 6525, - 6501, 6621, 6525, 17289, 17364, 17393, 16830, 16685, 16756, 35603, 35449, 35687, 1888, - 1855, 1952, 1471, 1501, 1408, 1818, 1855, 1888, 1787, 1868, 1841, 19762, 19670, - 19831, 21580, 21651, 21654, 41194, 41272, 41029, 41304, 41272, 41309, 19762, 19703, 19670, - 18332, 18182, 18081, 19703, 19199, 19670, 21654, 21692, 21525, 21654, 21651, 22197, 2529, - 2604, 2832, 1768, 1818, 2455, 2908, 3102, 3023, 1255, 1389, 1390, 876, 873, - 924, 11270, 11204, 11546, 10829, 10769, 10605, 11270, 11546, 11543, 11270, 11543, 11373, - 15149, 14951, 15157, 16756, 16685, 16513, 15453, 15603, 15524, 30793, 30874, 30684, 30147, - 30163, 30110, 30084, 30110, 29969, 4920, 5054, 5025, 4920, 5025, 4917, 30793, 30541, - 30549, 2529, 2373, 2284, 3401, 3577, 3417, 32405, 32386, 32380, 31233, 31127, 31461, - 32370, 32386, 32405, 38994, 38899, 38829, 6525, 6621, 6667, 5875, 6481, 6519, 7482, - 7494, 7358, 36726, 36430, 36425, 35147, 35360, 35094, 37230, 37169, 37217, 39767, 39659, - 39623, 39953, 39758, 40017, 876, 924, 920, 782, 867, 851, 11373, 11543, 11474, - 11520, 11692, 11670, 12029, 12131, 12004, 10288, 9692, 9655, 19670, 19780, 19831, 23711, - 23794, 23901, 40622, 40535, 40534, 40534, 40535, 40370, 40273, 39953, 40017, 40729, 40534, - 40642, 42553, 42407, 42477, 42552, 42495, 42901, 42557, 42540, 42632, 2344, 2835, 2841, - 2555, 2711, 2642, 2555, 2642, 2486, 2332, 2397, 2001, 30874, 31100, 30831, 6964, - 7000, 6707, 22915, 22987, 22966, 22852, 23099, 22994, 22406, 22402, 21712, 35687, 35449, - 35564, 42607, 42481, 42547, 42607, 42568, 42481, 42553, 42610, 42622, 42632, 42540, 42665, - 21654, 21707, 21692, 42913, 42595, 42455, 2222, 2404, 2302, 11207, 11416, 11306, 30166, - 30076, 29931, 30271, 30076, 30166, 31537, 31723, 31590, 30042, 30084, 29969, 3134, 3023, - 3337, 32001, 31967, 32114, 1747, 1787, 1841, 1614, 1603, 1685, 1477, 1603, 1614, - 1439, 1614, 1551, 28022, 27884, 28021, 26346, 26310, 26668, 26193, 25965, 26218, 15948, - 15557, 15951, 25855, 25977, 25820, 27571, 27473, 27270, 25822, 25977, 25855, 24914, 24716, - 25001, 29802, 29434, 29895, 28517, 28420, 28505, 1408, 1709, 1687, 14367, 14316, 14368, - 13984, 13865, 13913, 12827, 12788, 12736, 14393, 14316, 14367, 41597, 41658, 41491, 41465, - 41658, 41710, 6707, 7000, 6848, 35564, 35449, 35407, 1699, 1662, 1856, 4951, 4941, - 5086, 4951, 5086, 5227, 5054, 5028, 5085, 4925, 4920, 4882, 6667, 6707, 6537, - 7448, 7307, 7447, 19639, 19782, 19780, 25713, 25647, 25741, 32917, 33002, 32772, 32772, - 32347, 32437, 38793, 38403, 38623, 39085, 39017, 38985, 38966, 39145, 39043, 41282, 41300, - 41128, 41498, 41420, 41399, 2350, 2080, 2237, 11438, 11692, 11520, 29827, 29867, 29785, - 29827, 29680, 29563, 29291, 29318, 29154, 1393, 1503, 1442, 1254, 1255, 1390, 33002, - 33300, 32827, 38751, 38796, 38779, 38943, 38796, 38751, 782, 851, 901, 904, 920, - 1001, 21525, 21500, 21654, 22884, 22915, 22966, 22778, 22879, 22852, 22918, 22879, 22778, - 23337, 23319, 23431, 23901, 23794, 23946, 23901, 23946, 23950, 24906, 25024, 25025, 39715, - 39564, 39623, 39715, 39623, 39659, 40273, 40017, 40061, 42568, 42571, 42479, 42601, 42571, - 42568, 7000, 7037, 6848, 16225, 15951, 16346, 16719, 16942, 17094, 25025, 25112, 25026, - 28517, 28505, 28526, 38920, 38860, 38900, 4925, 5054, 4920, 3315, 3481, 3473, 3280, - 3481, 3315, 42330, 42212, 42140, 42184, 42012, 42043, 42321, 42140, 42229, 42251, 42278, - 42616, 42551, 42194, 42207, 42249, 42236, 41914, 860, 744, 999, 684, 767, 860, - 1205, 1088, 645, 585, 793, 839, 42595, 42647, 42391, 42540, 42548, 42665, 7463, - 7448, 7479, 7898, 7783, 7818, 8004, 8229, 8238, 8486, 8597, 8677, 8486, 8677, - 8490, 7942, 7880, 7956, 8588, 8667, 8446, 6770, 6890, 6782, 34922, 34905, 34682, - 35570, 35564, 35407, 34115, 34296, 34106, 34320, 34296, 34115, 4941, 4863, 5278, 4867, - 4863, 4941, 6558, 6667, 6537, 7463, 7719, 7689, 8790, 8677, 8871, 8790, 8871, - 8961, 8871, 9083, 8961, 37457, 37217, 37411, 37740, 37754, 37830, 38442, 38570, 38312, - 6481, 6770, 6782, 31427, 31243, 31152, 37457, 37411, 37497, 39911, 40006, 39951, 40499, - 39729, 40050, 41149, 40967, 40834, 40034, 39895, 39813, 17716, 17721, 17532, 16830, 17271, - 17289, 16940, 17271, 16830, 29251, 29036, 28964, 28856, 29036, 29106, 28777, 28697, 28654, - 40912, 40607, 40721, 782, 901, 835, 784, 691, 839, 1331, 1393, 1442, 41550, - 41134, 41302, 41868, 42035, 41830, 41304, 41178, 41272, 767, 744, 860, 28522, 28517, - 28526, 41517, 41300, 41282, 17716, 17532, 17364, 6770, 6900, 6942, 25996, 26161, 25977, - 25977, 26161, 26136, 42111, 42035, 41868, 1216, 1389, 1255, 1216, 1140, 1360, 25965, - 25786, 25748, 26218, 26310, 26346, 25647, 25713, 25725, 25001, 24716, 24935, 42184, 42043, - 42112, 41499, 41498, 41570, 19087, 19008, 18688, 16679, 16526, 16731, 19852, 19848, 19881, - 1014, 1011, 1213, 736, 1011, 1014, 954, 1026, 932, 24763, 24519, 24524, 25026, - 25112, 25350, 24650, 24716, 24359, 22879, 23099, 22852, 22939, 23099, 22879, 42665, 42548, - 42629, 42552, 42477, 42486, 42552, 42486, 42495, 4863, 4781, 5278, 4837, 4781, 4863, - 7037, 6972, 6848, 7567, 7463, 7689, 7337, 7482, 7358, 34320, 34524, 34296, 33002, - 33156, 33300, 32437, 32061, 31831, 1393, 1254, 1390, 7804, 7880, 7942, 7803, 7880, - 7804, 9979, 9194, 9732, 8588, 8446, 8528, 38796, 38915, 38829, 40032, 40006, 39895, - 38943, 38915, 38796, 751, 954, 932, 3078, 3280, 3315, 2486, 2642, 2585, 19384, - 19243, 19304, 24373, 24519, 24508, 30874, 30996, 31100, 31509, 31684, 31627, 30772, 30793, - 30549, 30772, 30549, 30510, 30147, 30110, 30084, 37596, 37457, 37497, 39435, 38893, 39289, - 39017, 38966, 38900, 42548, 42580, 42629, 29219, 29291, 29154, 30042, 30147, 30084, 28654, - 28602, 28442, 28067, 27835, 27813, 27630, 27473, 27593, 835, 901, 821, 785, 904, - 1001, 797, 904, 810, 775, 1021, 939, 18081, 18182, 17843, 19537, 19079, 19199, - 17756, 17716, 17696, 23950, 23946, 24057, 23337, 23431, 23533, 26346, 26700, 26335, 28185, - 28022, 28021, 28246, 28022, 28185, 27593, 27473, 27571, 2422, 2585, 2566, 9655, 9421, - 9431, 9655, 9684, 9421, 11207, 11395, 11416, 11416, 11438, 11520, 30891, 30996, 30874, - 1215, 1479, 1361, 1661, 1787, 1747, 1476, 1454, 1380, 14027, 13984, 14143, 14346, - 14472, 14618, 8528, 8446, 8317, 12463, 12254, 12508, 13092, 12788, 12993, 29219, 29154, - 29053, 11168, 11395, 11207, 12830, 12722, 12444, 30042, 29969, 29867, 40286, 40050, 39951, - 755, 748, 890, 901, 873, 821, 702, 939, 999, 18081, 17843, 17738, 19243, - 19207, 19304, 32114, 31967, 32192, 32370, 32239, 32386, 39576, 39435, 39289, 39773, 39715, - 39659, 3408, 3352, 3337, 3562, 3577, 3637, 3352, 3401, 3277, 39576, 39289, 39564, - 2350, 2332, 2080, 2332, 2350, 2594, 1864, 1933, 2033, 1741, 1787, 1661, 41238, - 41272, 41194, 41238, 41194, 41249, 4781, 4690, 4774, 4738, 4690, 4781, 7090, 6972, - 7037, 7674, 7567, 7689, 7674, 7689, 7783, 8004, 8238, 7940, 2404, 2342, 2450, - 1576, 1585, 1662, 2222, 2342, 2404, 2404, 2678, 2302, 2003, 2077, 2033, 30076, - 30010, 29931, 30271, 30255, 30401, 31058, 31101, 31233, 41027, 40378, 41120, 40535, 40717, - 40379, 39620, 39576, 39686, 40621, 40732, 40544, 1042, 965, 1198, 16731, 16526, 16674, - 14346, 14393, 14472, 16415, 16526, 16447, 42212, 42184, 42112, 42441, 42278, 42388, 26419, - 26479, 26305, 25713, 25822, 25855, 25741, 25822, 25713, 36200, 36390, 36166, 36378, 36486, - 36416, 38123, 38290, 38133, 36461, 36390, 36440, 36390, 36350, 36440, 36200, 36350, 36390, - 35981, 36033, 35722, 36390, 36486, 36378, 42629, 42580, 42619, 8302, 8597, 8486, 15206, - 15320, 15211, 15206, 15211, 15149, 13988, 14126, 13656, 13007, 12884, 12830, 27212, 27008, - 27100, 25350, 25112, 25320, 38542, 38290, 38668, 39002, 38994, 38915, 751, 863, 700, - 868, 863, 982, 751, 910, 954, 954, 910, 1024, 25001, 25550, 25305, 24723, - 24650, 24359, 755, 988, 831, 821, 873, 809, 23337, 23533, 23572, 22197, 21707, - 21654, 23099, 23288, 23144, 23197, 23288, 23099, 1933, 2003, 2033, 13286, 13398, 13199, - 4925, 5028, 5054, 4927, 4865, 4882, 15680, 15753, 15603, 17756, 17738, 17716, 30010, - 29802, 29895, 28856, 28522, 28655, 28517, 28361, 28420, 29729, 29827, 29563, 39895, 40006, - 39911, 40032, 39895, 40034, 40732, 40873, 40721, 1760, 1818, 1715, 1662, 1585, 1687, - 1501, 1433, 1629, 993, 1216, 1254, 5694, 6034, 6134, 5694, 6134, 5596, 6298, - 6327, 6454, 6444, 6454, 6525, 6444, 6525, 6558, 28856, 28655, 29036, 41249, 41194, - 41213, 755, 673, 748, 9257, 9421, 9289, 19207, 19008, 19087, 21398, 21712, 21386, - 42619, 42483, 42628, 8793, 8878, 8906, 8839, 8878, 8793, 33077, 33156, 33002, 33077, - 33002, 32917, 39132, 39096, 39270, 39132, 39017, 39085, 38915, 38994, 38829, 38943, 38751, - 38941, 39348, 39132, 39270, 34296, 34524, 34347, 35687, 35749, 35722, 33411, 32827, 33300, - 8588, 8634, 8906, 8528, 8634, 8588, 33449, 33411, 33300, 1760, 1856, 1855, 6558, - 6525, 6667, 7131, 6972, 7090, 41644, 41399, 41425, 41420, 41503, 41374, 40717, 40622, - 40858, 41465, 41710, 41644, 41468, 41550, 41302, 42258, 42062, 42035, 41468, 41302, 41304, - 755, 695, 673, 809, 873, 797, 873, 876, 797, 22261, 22365, 22197, 23572, - 23533, 23711, 23572, 23711, 23706, 29802, 29605, 29434, 29410, 29318, 29291, 29410, 29591, - 29318, 31627, 31684, 31676, 31427, 31152, 31324, 40873, 40912, 40721, 42954, 42388, 42373, - 42615, 42136, 42571, 831, 650, 667, 1471, 1433, 1501, 1454, 1476, 1551, 1439, - 1476, 1380, 1361, 1309, 1215, 4867, 4951, 4818, 4882, 4865, 4723, 14472, 14393, - 14367, 14206, 14393, 14337, 37754, 37647, 37646, 37740, 37647, 37754, 37754, 38188, 37830, - 885, 1180, 990, 1140, 1042, 1198, 923, 1042, 1140, 1216, 1255, 1254, 12080, - 12004, 12131, 41471, 41468, 41304, 7307, 7249, 7090, 21113, 21351, 21202, 20817, 21113, - 21044, 20817, 20855, 21113, 20390, 20318, 20302, 20302, 20170, 20113, 20113, 20053, 19881, - 19384, 19206, 19243, 19243, 19206, 19207, 19207, 19065, 19008, 21351, 21411, 21202, 33768, - 34095, 34000, 36829, 36418, 36416, 20589, 20563, 20618, 20563, 20515, 20414, 20389, 20515, - 20423, 20423, 20515, 20535, 20535, 20515, 20771, 20771, 20830, 20890, 20890, 21072, 20970, - 21140, 21223, 21190, 21190, 21293, 21297, 20515, 20563, 20589, 20414, 20515, 20389, 20258, - 20069, 20066, 19794, 20066, 19930, 19800, 19930, 19866, 19800, 19866, 19831, 19800, 19831, - 19780, 21351, 21500, 21411, 20515, 20830, 20771, 20717, 20482, 20518, 42681, 42722, 42455, - 42848, 42493, 42647, 42643, 42742, 42681, 42603, 42742, 42643, 42795, 42742, 42603, 42737, - 42390, 42652, 42737, 42652, 42798, 42652, 42711, 42699, 42676, 42711, 42496, 1864, 2033, - 1868, 2413, 2422, 2349, 1864, 1868, 1741, 13398, 13671, 13371, 28777, 28914, 29053, - 28751, 28914, 28777, 42742, 42722, 42681, 42748, 42547, 42542, 15453, 15680, 15603, 15532, - 15680, 15453, 26041, 25935, 25965, 24278, 24288, 24373, 26041, 25965, 26193, 20482, 20318, - 20390, 20830, 21072, 20890, 645, 793, 406, 645, 1088, 793, 427, 702, 744, - 744, 702, 999, 993, 1254, 1393, 3401, 3352, 3408, 2302, 2678, 2604, 3562, - 3637, 3720, 7880, 7842, 8153, 7482, 7709, 7831, 7803, 7709, 7635, 20318, 20170, - 20302, 27224, 27212, 27100, 32370, 32405, 32570, 31212, 31058, 31233, 37036, 37183, 36418, - 42628, 42483, 42514, 42676, 42760, 42711, 42628, 42697, 42718, 16225, 16346, 16502, 26419, - 26305, 26364, 25741, 25550, 25662, 42252, 42078, 41877, 42293, 42184, 42212, 42330, 42140, - 42321, 12080, 11735, 12004, 29219, 29410, 29291, 797, 876, 904, 725, 782, 835, - 1818, 1760, 1855, 1718, 1760, 1682, 13730, 13671, 13865, 19079, 18823, 19199, 17756, - 18081, 17738, 17716, 17604, 17696, 22741, 22365, 22677, 21072, 21223, 21140, 23288, 23477, - 23144, 23357, 23477, 23288, 28521, 28361, 28517, 27579, 27277, 27680, 28268, 28361, 28521, - 30793, 30891, 30874, 31324, 31152, 31100, 30642, 30772, 30510, 30642, 30510, 30343, 30042, - 29867, 30008, 29867, 29827, 30008, 42611, 42552, 42901, 42632, 42760, 42557, 4925, 4882, - 4884, 10658, 10677, 10756, 11395, 11438, 11416, 10665, 10677, 10658, 30884, 30891, 30793, - 34922, 34682, 34625, 35062, 34905, 35092, 691, 784, 748, 20170, 20053, 20113, 21223, - 21293, 21190, 24278, 24186, 24288, 24288, 24519, 24373, 31537, 31924, 31723, 30010, 29894, - 29802, 29802, 29819, 29605, 2350, 2422, 2566, 2486, 2413, 2555, 2774, 3329, 2835, - 1941, 2180, 2003, 30427, 30271, 30401, 35570, 35407, 35477, 40729, 40622, 40534, 40378, - 40817, 41120, 20053, 19978, 19881, 21293, 21398, 21386, 8790, 8490, 8677, 9979, 9298, - 9194, 42748, 42493, 42848, 42813, 42826, 42760, 42622, 42514, 42553, 4247, 4201, 3609, - 643, 684, 860, 11238, 11438, 11395, 16526, 16415, 16502, 16719, 17094, 17407, 29729, - 29563, 29591, 38991, 38920, 38900, 38991, 38900, 38966, 40034, 39813, 39388, 38962, 38943, - 38941, 42340, 42330, 42321, 38290, 38442, 38312, 38619, 38442, 38542, 37197, 36831, 36931, - 36831, 36950, 36726, 37454, 37393, 37217, 37454, 37217, 37457, 1933, 1941, 2003, 1741, - 1868, 1787, 22741, 22915, 22884, 23706, 23711, 23901, 23477, 23573, 23510, 25741, 25647, - 25550, 23448, 23573, 23477, 28600, 28654, 28442, 29163, 29219, 29053, 28480, 28112, 28184, - 41238, 41309, 41272, 41213, 40903, 41070, 4690, 4519, 4774, 4773, 4837, 4863, 4867, - 4941, 4951, 18821, 18823, 19079, 23025, 22966, 22987, 29555, 29729, 29591, 29163, 29053, - 28914, 32300, 32114, 32192, 42851, 42813, 42632, 7709, 7803, 7804, 7842, 7803, 7635, - 34104, 34115, 34095, 34275, 34320, 34115, 31324, 31100, 31135, 31959, 32437, 31831, 25996, - 25977, 25822, 42607, 42601, 42568, 42768, 42601, 42607, 29605, 29516, 29434, 29938, 29894, - 30010, 1433, 1331, 1442, 1408, 1501, 1709, 1408, 1687, 1522, 1476, 1439, 1551, - 1338, 1225, 1063, 8464, 8490, 8591, 7448, 7290, 7249, 8634, 8839, 8793, 9040, - 9289, 9262, 8279, 8528, 8317, 13984, 13913, 14143, 41498, 41499, 41420, 41597, 41825, - 41658, 18821, 18791, 18823, 23025, 23319, 22966, 25467, 25607, 25786, 26107, 26041, 26193, - 26335, 26193, 26346, 26008, 25996, 25822, 42035, 42062, 41914, 42611, 42477, 42552, 42111, - 41766, 42143, 24119, 23950, 24057, 24519, 24763, 24508, 7463, 7290, 7448, 7307, 7448, - 7249, 6900, 6898, 7040, 6797, 6898, 6900, 6797, 6900, 6770, 6797, 6770, 6686, - 6770, 6481, 6686, 5500, 5871, 5028, 4948, 5028, 4925, 37520, 37454, 37596, 37725, - 37497, 37647, 42184, 42166, 42012, 42293, 42166, 42184, 15149, 15211, 14951, 26364, 26241, - 26161, 1760, 1699, 1856, 1718, 1699, 1760, 41903, 41776, 41195, 41867, 41776, 41903, - 41645, 41550, 41587, 31995, 31924, 32001, 40006, 40286, 39951, 40887, 40873, 40732, 40887, - 40912, 40873, 41222, 40834, 40912, 39183, 38963, 38994, 725, 835, 821, 921, 990, - 965, 29555, 29591, 29410, 22966, 23319, 23249, 22760, 22918, 22778, 22760, 22778, 22406, - 882, 921, 965, 894, 921, 882, 4837, 4738, 4781, 4735, 4738, 4837, 17407, - 17829, 17671, 16513, 16685, 16416, 16513, 16416, 16033, 16513, 16033, 16075, 42665, 42629, - 42743, 7674, 7783, 7721, 12736, 12556, 12711, 12463, 12306, 12254, 11474, 11543, 11753, - 11270, 11012, 11049, 12788, 12556, 12736, 12788, 13092, 13014, 14206, 14316, 14393, 16415, - 16225, 16502, 16387, 16225, 16415, 32114, 31995, 32001, 32370, 32300, 32192, 32336, 32300, - 32370, 39435, 39284, 39270, 39043, 38991, 38966, 39782, 39576, 39564, 39564, 39715, 39773, - 41387, 41309, 41238, 41149, 41174, 41070, 41149, 40834, 41222, 1864, 1822, 1933, 1747, - 1658, 1293, 3562, 3417, 3577, 3580, 3649, 3609, 27773, 27884, 28022, 28654, 28751, - 28777, 29163, 29555, 29410, 28600, 28534, 28658, 41387, 41238, 41249, 8829, 8839, 8715, - 38308, 38287, 38453, 38950, 38991, 39043, 38943, 39002, 38915, 38962, 39002, 38943, 24119, - 24057, 24186, 23249, 23319, 23337, 25026, 24906, 25025, 22734, 22365, 22741, 23249, 23337, - 23310, 22918, 22939, 22879, 22760, 22939, 22918, 42601, 42606, 42571, 42365, 42212, 42330, - 42773, 42606, 42601, 29471, 29516, 29605, 29163, 29410, 29219, 41120, 40817, 41418, 39526, - 39284, 39435, 17716, 17364, 17604, 18823, 18791, 18579, 36486, 36829, 36416, 37036, 37195, - 37183, 36390, 36461, 36486, 36200, 36085, 36350, 42743, 42629, 42619, 25996, 26144, 26161, - 27281, 27571, 27270, 26008, 26144, 25996, 25550, 25549, 25662, 25822, 25741, 25883, 31103, - 31100, 30996, 30772, 30884, 30793, 30343, 30315, 30147, 30343, 30147, 30266, 30147, 30042, - 30192, 10930, 11168, 11099, 10493, 10658, 10288, 10493, 10175, 10571, 12004, 11659, 11856, - 10930, 10994, 10677, 16719, 16679, 16731, 16559, 16679, 16719, 25467, 25786, 25964, 30192, - 30042, 30105, 14206, 14143, 14316, 13014, 13092, 13199, 15314, 15557, 15440, 27805, 27773, - 27927, 28268, 28185, 28361, 41499, 41503, 41420, 42135, 41950, 41825, 15440, 15557, 15834, - 1063, 1225, 1034, 1769, 1822, 1864, 13626, 13671, 13730, 12406, 12830, 12444, 15157, - 15063, 15150, 12406, 12444, 12131, 13579, 13656, 13572, 15206, 15193, 15453, 32100, 31995, - 32114, 31822, 31831, 31684, 33156, 33449, 33300, 34049, 34104, 34095, 31509, 31627, 31427, - 38625, 38619, 38670, 36751, 36829, 36486, 41174, 41213, 41070, 41388, 41213, 41174, 42606, - 42615, 42571, 42769, 42615, 42606, 42763, 42743, 42619, 42610, 42553, 42477, 42610, 42477, - 42611, 1699, 1576, 1662, 1537, 1576, 1699, 13770, 13626, 13730, 33768, 33423, 33411, - 34922, 34625, 34685, 34905, 35062, 34894, 41570, 41503, 41499, 11049, 10769, 10829, 12306, - 12168, 12254, 12306, 12463, 12389, 30008, 29827, 29745, 4884, 4948, 4925, 4884, 4882, - 4723, 12389, 12463, 12556, 35640, 35749, 35687, 34625, 34524, 34685, 41116, 41280, 41142, - 894, 885, 990, 8490, 8302, 8486, 8464, 8302, 8490, 24763, 24524, 24906, 24119, - 24186, 24239, 37197, 36931, 37274, 36915, 36950, 37197, 725, 821, 732, 785, 810, - 904, 18086, 18332, 18081, 17604, 17364, 17363, 31103, 30996, 30891, 1682, 1760, 1715, - 1741, 1769, 1864, 1293, 1658, 1603, 1477, 1614, 1439, 13209, 13387, 13328, 28521, - 28517, 28522, 29819, 29471, 29605, 29106, 29036, 29246, 30256, 29938, 30076, 30256, 30076, - 30271, 30427, 30401, 30627, 31445, 31233, 31590, 30105, 30008, 30215, 41309, 41471, 41304, - 41753, 41471, 41691, 7721, 7783, 8004, 22939, 23197, 23099, 23573, 23804, 23920, 23059, - 23197, 22939, 42615, 42620, 42136, 42755, 42620, 42615, 42126, 42642, 42551, 42763, 42619, - 42628, 19008, 18644, 18688, 19342, 19206, 19384, 17802, 18081, 17756, 31482, 31509, 31427, - 3609, 4201, 3630, 4744, 4867, 4818, 4948, 4884, 4896, 6606, 6707, 6786, 6606, - 6537, 6707, 6558, 6537, 6444, 6039, 6134, 6327, 4744, 4773, 4867, 6707, 6848, - 6786, 7290, 7463, 7461, 35640, 35687, 35564, 36931, 37230, 37274, 37653, 38132, 38188, - 17363, 17364, 17271, 15829, 15886, 15680, 1845, 1933, 1822, 1845, 1941, 1933, 15834, - 15557, 15948, 16062, 15948, 16225, 41354, 41387, 41249, 40887, 40732, 40895, 673, 691, - 748, 821, 809, 732, 484, 744, 767, 664, 863, 868, 736, 1014, 910, - 3517, 3417, 3562, 3352, 3277, 3337, 3580, 3562, 3649, 19206, 19065, 19207, 22259, - 22365, 22734, 23048, 22884, 22966, 21902, 22379, 21712, 28480, 28600, 28442, 30105, 30042, - 30008, 28184, 28112, 28067, 27811, 27813, 27593, 41354, 41249, 41213, 42848, 42647, 42877, - 732, 809, 797, 885, 785, 1001, 17696, 17802, 17756, 17363, 17271, 17327, 24119, - 24239, 24069, 6786, 6848, 6799, 35570, 35640, 35564, 732, 797, 750, 23310, 23337, - 23332, 25964, 25786, 25935, 24278, 24239, 24186, 23999, 24119, 24069, 25964, 25935, 26041, - 31995, 31723, 31924, 40032, 40065, 40006, 39694, 40034, 39388, 7461, 7463, 7567, 7711, - 7721, 8004, 4867, 4773, 4863, 4735, 4773, 4744, 6701, 6786, 6799, 7461, 7567, - 7540, 34720, 34524, 34320, 35477, 35096, 35399, 37230, 37393, 37274, 38431, 38426, 38658, - 35096, 35056, 35399, 42763, 42628, 42718, 1471, 1331, 1433, 874, 965, 1042, 921, - 894, 990, 1522, 1687, 1585, 1522, 1585, 1576, 1271, 1477, 1439, 13984, 13770, - 13865, 12450, 12556, 12788, 14206, 14138, 14143, 14209, 14138, 14206, 27773, 27579, 27680, - 26700, 26346, 26668, 27549, 27579, 27733, 27108, 26946, 27242, 41644, 41570, 41498, 41035, - 41027, 41116, 42135, 42015, 41950, 1537, 1522, 1576, 13857, 13770, 13984, 27775, 27811, - 27593, 41561, 41468, 41484, 41561, 41550, 41468, 41776, 41896, 41837, 3204, 3277, 3401, - 2547, 2835, 2344, 3481, 3411, 3715, 32570, 32405, 33137, 32300, 32100, 32114, 31789, - 31659, 31723, 39576, 39620, 39435, 38966, 39017, 39145, 39659, 39767, 39947, 1312, 1454, - 1479, 14618, 14665, 14808, 26799, 26639, 26419, 42078, 41754, 41877, 13387, 13579, 13572, - 13288, 13579, 13387, 41484, 41468, 41471, 695, 755, 831, 750, 797, 810, 23197, - 23357, 23288, 23323, 23357, 23197, 42628, 42514, 42697, 42126, 42226, 42642, 23950, 23706, - 23901, 24763, 24906, 25026, 29413, 29251, 29516, 28268, 28246, 28185, 7131, 7090, 7249, - 6898, 6868, 7040, 6721, 6657, 6724, 5500, 5028, 4986, 16679, 16447, 16526, 16559, - 16447, 16679, 35570, 35477, 35623, 695, 831, 682, 923, 801, 874, 763, 810, - 785, 652, 725, 580, 24639, 24763, 24969, 30825, 30884, 30772, 31714, 31822, 31509, - 30825, 30772, 30642, 30825, 30642, 30658, 30266, 30147, 30192, 40717, 40436, 40379, 40717, - 40535, 40622, 40889, 40578, 41035, 8961, 8798, 8790, 7540, 7674, 7592, 10167, 9596, - 9979, 32984, 33077, 32917, 33156, 33077, 33280, 2422, 2413, 2486, 2349, 2422, 2350, - 20717, 20594, 20482, 20482, 20233, 20318, 20318, 20233, 20170, 20170, 20219, 20053, 19949, - 19874, 19978, 19978, 19874, 19881, 19206, 19195, 19065, 20817, 20594, 20717, 20904, 20594, - 20817, 21044, 21113, 21202, 21044, 21202, 21102, 21202, 21109, 21102, 20830, 21000, 21072, - 21072, 21178, 21223, 21223, 21178, 21293, 21293, 21286, 21398, 21398, 21342, 21712, 20515, - 20589, 20830, 20284, 20153, 20414, 19794, 19930, 19800, 19794, 19800, 19780, 20589, 20757, - 20830, 42790, 42795, 42603, 42742, 42967, 42722, 42913, 42647, 42595, 42603, 42903, 42905, - 42539, 42737, 42833, 42737, 42866, 42833, 42699, 42798, 42652, 42699, 42780, 42798, 20594, - 20498, 20482, 27212, 27224, 27279, 29471, 29413, 29516, 38442, 38619, 38570, 39002, 39066, - 38994, 37536, 37056, 37183, 41867, 41896, 41776, 42062, 42249, 41914, 10665, 10639, 10677, - 13079, 13211, 12830, 10639, 10571, 10630, 31509, 31822, 31684, 30884, 31103, 30891, 38991, - 38950, 38920, 39348, 39270, 39284, 38941, 38751, 38695, 1543, 1537, 1699, 1768, 2455, - 2272, 1768, 1544, 1578, 7803, 7842, 7880, 8715, 8839, 8634, 7635, 7709, 7372, - 10279, 9626, 9596, 9040, 9262, 8878, 8829, 8878, 8839, 11238, 11395, 11168, 13079, - 13328, 13211, 34338, 34275, 34104, 34104, 34275, 34115, 38453, 38287, 38431, 39398, 39348, - 39284, 26752, 26668, 26815, 26144, 26364, 26161, 26264, 26364, 26144, 26008, 25822, 25883, - 41991, 41766, 41837, 2237, 2349, 2350, 11373, 11237, 11270, 11474, 11237, 11373, 11182, - 11238, 11168, 29827, 29729, 29745, 30105, 30266, 30192, 20498, 20233, 20482, 21500, 21525, - 21411, 42166, 42265, 42147, 42365, 42293, 42212, 42340, 42321, 42508, 6797, 6868, 6898, - 40436, 40273, 40052, 42514, 42622, 42697, 42699, 42785, 42780, 20233, 20219, 20170, 21411, - 21525, 21551, 42711, 42785, 42699, 23357, 23448, 23477, 23329, 23448, 23357, 21087, 21178, - 21072, 32183, 32100, 32300, 39947, 39674, 39953, 39398, 39255, 39348, 12389, 12556, 12450, - 11753, 12168, 11540, 11548, 11474, 11753, 29745, 29729, 29555, 17671, 17829, 18170, 16940, - 16830, 16756, 17637, 17802, 17696, 42521, 42226, 42236, 21178, 21286, 21293, 2547, 2774, - 2835, 26996, 26752, 26815, 41983, 41991, 41837, 643, 633, 684, 684, 450, 767, - 462, 633, 643, 529, 643, 474, 585, 839, 691, 7093, 7131, 7249, 7540, - 7567, 7674, 7674, 7721, 7592, 34720, 34685, 34524, 35655, 35570, 35623, 42711, 42910, - 42785, 471, 585, 691, 682, 831, 667, 2216, 2450, 2342, 1721, 1769, 1741, - 2001, 2333, 2180, 1712, 1741, 1661, 12317, 12389, 12342, 12315, 12406, 12131, 28812, - 28681, 28856, 28856, 28681, 28522, 28862, 29163, 28914, 28751, 28654, 28600, 41388, 41354, - 41213, 41753, 41484, 41471, 41388, 41174, 41314, 42711, 42760, 42831, 42697, 42622, 42706, - 42622, 42610, 42706, 923, 833, 801, 16447, 16387, 16415, 16348, 16387, 16447, 42234, - 42239, 42636, 41035, 40578, 41027, 41517, 41282, 41503, 40895, 40732, 40939, 20015, 19978, - 20053, 21551, 21525, 21692, 14031, 14027, 14138, 14138, 14027, 14143, 13371, 13671, 13626, - 14337, 14393, 14346, 14337, 14346, 14209, 36461, 36751, 36486, 36829, 36971, 37036, 36350, - 36085, 36311, 36085, 36033, 36311, 35722, 35749, 35821, 35749, 35769, 35821, 35749, 35640, - 35769, 40034, 40065, 40032, 40205, 40065, 40179, 41925, 41570, 41644, 41925, 41644, 41710, - 14206, 14337, 14209, 19874, 19852, 19881, 18729, 18644, 19008, 19782, 19794, 19780, 19780, - 19670, 19639, 21707, 22197, 21823, 21707, 21551, 21692, 42760, 42826, 42831, 25550, 25419, - 25549, 27679, 27571, 27567, 42258, 42249, 42062, 42258, 42035, 42111, 588, 691, 673, - 831, 652, 650, 782, 652, 831, 18992, 19008, 19065, 22678, 22760, 22406, 22490, - 22406, 22379, 42895, 42768, 42607, 42837, 42616, 42441, 42895, 42547, 42748, 42632, 42813, - 42760, 42706, 42610, 42710, 3204, 3134, 3277, 4519, 4690, 4738, 8897, 8798, 8961, - 8897, 8961, 8985, 8715, 8634, 8436, 8829, 9040, 8878, 10175, 10288, 9824, 19639, - 19670, 19199, 24935, 24716, 24650, 28260, 28246, 28268, 27549, 27212, 27279, 26793, 26700, - 26752, 27811, 28184, 28067, 28061, 28184, 27811, 27775, 27593, 27571, 27775, 27571, 27679, - 38970, 38623, 38920, 39255, 39017, 39132, 39255, 39132, 39348, 38962, 39066, 39002, 39183, - 39066, 39164, 39606, 39435, 39620, 41116, 41027, 41120, 41480, 41309, 41387, 41561, 41587, - 41550, 42010, 41983, 41896, 41896, 41983, 41837, 42293, 42265, 42166, 41825, 41791, 41658, - 42429, 42265, 42293, 42851, 42632, 42665, 15149, 15193, 15206, 17556, 17604, 17363, 15157, - 15193, 15149, 1600, 1712, 1661, 1271, 1368, 1477, 1185, 1312, 1153, 1312, 1479, - 1153, 7711, 8004, 7940, 6973, 7131, 7064, 36950, 36915, 36726, 37725, 37647, 37740, - 36949, 36971, 36829, 31482, 31427, 31324, 1793, 1845, 1822, 1793, 1822, 1769, 19852, - 19677, 19848, 22259, 22197, 22365, 23249, 23048, 22966, 23999, 23706, 23950, 23999, 23950, - 24119, 23448, 23651, 23573, 23655, 23651, 23448, 763, 785, 697, 874, 882, 965, - 24723, 24935, 24650, 782, 725, 652, 588, 673, 525, 4986, 5028, 4948, 6797, - 6721, 6868, 42768, 42773, 42601, 42804, 42773, 42768, 1721, 1712, 1600, 13082, 13079, - 13066, 13209, 13288, 13387, 15157, 14911, 15063, 16387, 16217, 16225, 16348, 16217, 16387, - 25467, 25350, 25320, 24439, 24373, 24508, 25331, 25350, 25467, 26107, 26193, 26335, 28681, - 28521, 28522, 28543, 28521, 28681, 6972, 7131, 6973, 19607, 19639, 19544, 37849, 37725, - 37740, 37712, 37725, 37849, 12406, 12360, 12830, 11735, 11692, 11475, 29106, 28886, 28856, - 29819, 29802, 29894, 29819, 29894, 29996, 30463, 31058, 30830, 41418, 40817, 41300, 38970, - 38920, 38950, 37849, 37740, 37830, 42280, 42258, 42111, 41195, 41550, 41903, 35769, 35640, - 35655, 35640, 35570, 35655, 37274, 37393, 37426, 36971, 37195, 37036, 30537, 30642, 30343, - 31067, 31135, 31103, 31103, 31135, 31100, 30537, 30343, 30461, 30343, 30266, 30442, 40309, - 40499, 40050, 10769, 11012, 10970, 11237, 11012, 11270, 11086, 11237, 11201, 30442, 30266, - 30215, 33449, 33768, 33411, 34720, 34827, 34685, 33449, 33156, 33280, 38619, 38763, 38570, - 38625, 38763, 38619, 39686, 39606, 39620, 39782, 39564, 39773, 42792, 42851, 42665, 10493, - 10639, 10665, 11475, 11692, 11438, 9431, 9421, 9257, 673, 695, 605, 750, 810, - 763, 8436, 8634, 8528, 7372, 7709, 7482, 11073, 11182, 11168, 31659, 31590, 31723, - 30461, 30442, 30635, 40729, 40889, 40893, 40858, 40729, 40893, 40858, 40622, 40729, 40380, - 40210, 40273, 39864, 39782, 39773, 42773, 42769, 42606, 42804, 42769, 42773, 31067, 31103, - 30884, 35056, 35062, 35399, 37426, 37393, 37454, 785, 683, 697, 15385, 15532, 15453, - 15385, 15453, 15193, 17637, 17696, 17604, 17637, 17604, 17556, 23651, 23804, 23573, 23655, - 23804, 23651, 26740, 26107, 26335, 26700, 26668, 26752, 42743, 42792, 42665, 15729, 15829, - 15680, 1671, 1793, 1769, 2001, 1731, 1950, 2202, 2222, 2181, 2349, 2303, 2413, - 2344, 2841, 2555, 2303, 2237, 1984, 27571, 27281, 27567, 28886, 28812, 28856, 28658, - 28751, 28600, 29561, 29745, 29555, 28862, 28751, 28846, 41040, 40889, 41035, 41354, 41480, - 41387, 41314, 41174, 41149, 41222, 40912, 41235, 31135, 31297, 31324, 40205, 40286, 40006, - 40309, 40286, 40351, 41588, 41517, 41503, 41950, 41791, 41825, 12389, 12317, 12306, 13371, - 13468, 13281, 12029, 12315, 12131, 12299, 12315, 12029, 7940, 8238, 8058, 8925, 8897, - 8985, 8783, 8897, 8925, 24935, 25065, 25001, 25094, 25065, 24935, 35399, 35062, 35252, - 39025, 38970, 38950, 39255, 39145, 39017, 39188, 39145, 39406, 41484, 41587, 41561, 41723, - 41587, 41484, 14725, 14422, 14457, 42238, 41883, 42147, 695, 682, 605, 3580, 3517, - 3562, 2529, 2832, 2908, 3407, 3517, 3428, 605, 682, 599, 578, 652, 580, - 23310, 23048, 23249, 22760, 23059, 22939, 22783, 23059, 22760, 42769, 42755, 42615, 42804, - 42755, 42769, 42743, 42801, 42792, 42710, 42610, 42611, 28260, 28268, 28394, 27579, 27773, - 27733, 27549, 27279, 27579, 41903, 41550, 41645, 2202, 2216, 2342, 11540, 12168, 12306, - 40939, 40732, 40621, 42340, 42365, 42330, 42429, 42238, 42147, 42497, 42365, 42340, 39947, - 39953, 40158, 39526, 39398, 39284, 31297, 31482, 31324, 33280, 33077, 33242, 13857, 13626, - 13770, 13857, 13984, 14027, 13285, 13288, 13209, 13285, 13209, 13079, 28394, 28268, 28521, - 41588, 41503, 41570, 6786, 6701, 6606, 6563, 6298, 6537, 6298, 6454, 6444, 6799, - 6848, 6972, 6788, 7337, 7358, 6721, 6551, 6657, 37520, 37426, 37454, 4773, 4735, - 4837, 5147, 5587, 5139, 7346, 7337, 7121, 7093, 7290, 7137, 6846, 6799, 6972, - 8490, 8790, 8649, 17826, 17671, 18170, 16755, 16559, 16719, 18441, 18791, 18332, 17556, - 17720, 17656, 42913, 42455, 42988, 42763, 42801, 42743, 32130, 31982, 32100, 31789, 31723, - 31982, 32588, 32570, 33130, 34965, 34946, 35094, 8649, 8790, 8798, 29996, 29894, 29938, - 29449, 29251, 29413, 30215, 29745, 30059, 41113, 41040, 41035, 41113, 41035, 41167, 12458, - 12450, 12788, 11719, 11540, 12306, 31723, 31995, 31982, 6846, 6972, 6901, 22734, 22741, - 22884, 37596, 37454, 37457, 37596, 37497, 37712, 37402, 37536, 37183, 42763, 42718, 42801, - 1768, 1715, 1818, 1543, 1699, 1718, 1346, 1372, 1408, 1408, 1372, 1471, 1578, - 1715, 1768, 2180, 1731, 2001, 1712, 1721, 1741, 1671, 1721, 1600, 13371, 13014, - 13199, 15829, 15872, 16033, 15532, 15729, 15680, 15625, 15729, 15532, 1034, 827, 926, - 1368, 1603, 1477, 751, 932, 863, 15249, 15385, 15193, 15150, 15193, 15157, 16340, - 16559, 16755, 16217, 16189, 16225, 41825, 41646, 42135, 42252, 42238, 42624, 42555, 42521, - 42236, 42143, 41766, 41991, 42143, 41991, 42146, 39782, 39686, 39576, 39844, 39686, 39782, - 7337, 7372, 7482, 8187, 8153, 7906, 7346, 7372, 7337, 34685, 34827, 34922, 34720, - 34320, 34621, 590, 650, 578, 761, 885, 756, 18086, 18081, 17906, 17556, 17363, - 17327, 24639, 24508, 24763, 23332, 23337, 23572, 24969, 24763, 25026, 25095, 25026, 25350, - 13082, 13285, 13079, 11475, 11438, 11336, 42848, 42836, 42748, 42801, 42718, 42943, 6799, - 6846, 6780, 36269, 35360, 35143, 35092, 34905, 34922, 37712, 37497, 37725, 38763, 38941, - 38695, 38542, 38442, 38290, 23176, 23310, 23332, 23048, 23063, 22884, 24710, 24723, 24359, - 23059, 23323, 23197, 23042, 23323, 23059, 26996, 26815, 27008, 25984, 25964, 26041, 34295, - 34338, 34104, 40210, 39953, 40273, 42146, 41991, 41983, 42916, 42710, 42901, 42943, 42718, - 42697, 42706, 42710, 42806, 1346, 1408, 1522, 923, 874, 1042, 9257, 9289, 9212, - 8729, 8911, 9040, 7676, 7842, 7635, 27773, 28022, 27927, 27212, 26996, 27008, 28113, - 28022, 28246, 39560, 39435, 39606, 38297, 38308, 38576, 682, 667, 599, 667, 590, - 599, 1372, 1331, 1471, 1615, 1718, 1682, 10790, 10930, 10677, 11336, 11438, 11238, - 10790, 10677, 10639, 28394, 28521, 28543, 28249, 28246, 28260, 28249, 28113, 28246, 31053, - 31067, 30884, 31135, 31223, 31297, 31490, 31714, 31482, 30537, 30658, 30642, 30635, 30658, - 30537, 30461, 30343, 30442, 41687, 41418, 41300, 41957, 41588, 42220, 41925, 41710, 41791, - 41646, 41754, 42135, 29449, 29413, 29471, 28751, 28862, 28914, 28600, 28480, 28534, 10930, - 11073, 11168, 30537, 30461, 30635, 30635, 30442, 30570, 31053, 30884, 30825, 40499, 40759, - 40621, 41111, 40912, 40887, 40604, 40759, 40499, 38862, 38941, 38763, 40205, 40006, 40065, - 4896, 4986, 4948, 4896, 4884, 4834, 36530, 36430, 36619, 36430, 36726, 36619, 36726, - 36818, 36619, 37076, 37197, 37303, 37553, 37274, 37426, 37546, 37426, 37520, 29598, 29449, - 29471, 882, 794, 894, 923, 1140, 833, 2237, 2303, 2349, 1780, 1845, 1793, - 6606, 6701, 6563, 6537, 6606, 6563, 6298, 6444, 6537, 23323, 23329, 23357, 23552, - 23329, 23503, 23176, 23048, 23310, 24239, 24278, 24373, 29819, 29598, 29471, 30427, 30256, - 30271, 30417, 30256, 30427, 31445, 31212, 31233, 31145, 31223, 31135, 31959, 31831, 31822, - 35981, 35722, 35821, 35981, 36311, 36033, 36350, 36655, 36440, 36655, 36751, 36461, 36971, - 37035, 37195, 37195, 37402, 37183, 35981, 35821, 35974, 35821, 35769, 35974, 36849, 36751, - 36844, 40286, 40309, 40050, 39298, 38963, 39538, 1621, 1615, 1682, 1621, 1682, 1715, - 14457, 14422, 13988, 12360, 12406, 12315, 22400, 22490, 22379, 27137, 26996, 27212, 28543, - 28681, 28817, 39756, 39560, 39606, 39581, 39560, 39756, 39183, 38994, 39066, 42781, 42697, - 42706, 25702, 25883, 25662, 25662, 25883, 25741, 24710, 24359, 24027, 25984, 26041, 26107, - 25984, 26107, 26740, 26008, 26001, 26144, 25550, 25001, 25419, 20757, 20725, 20830, 21178, - 21230, 21286, 21286, 21342, 21398, 20589, 20618, 20757, 20389, 20284, 20414, 20258, 20337, - 20414, 20337, 20472, 20414, 20618, 20725, 20757, 42795, 42927, 42742, 42848, 43120, 42836, - 42790, 42927, 42795, 42952, 42927, 42790, 42952, 42790, 42897, 42603, 42905, 42790, 42903, - 42603, 42539, 42903, 42539, 42833, 42903, 42833, 42888, 42833, 42866, 42888, 42798, 42866, - 42737, 43053, 42866, 42798, 42935, 42798, 42780, 42999, 42935, 42780, 1544, 1768, 2272, - 2222, 2202, 2342, 2908, 2373, 2529, 6901, 6972, 6973, 8058, 8238, 8302, 11193, - 11238, 11182, 12299, 12360, 12315, 20066, 19794, 19835, 30256, 30068, 29938, 40380, 40273, - 40650, 39581, 39526, 39560, 41012, 40436, 40717, 40851, 40717, 40858, 41113, 40893, 40889, - 41113, 40889, 41040, 42785, 42999, 42780, 19835, 19782, 19740, 19835, 19794, 19782, 20594, - 20560, 20498, 20498, 20292, 20233, 20233, 20292, 20219, 20219, 20015, 20053, 19874, 19913, - 19852, 19852, 19770, 19677, 21044, 20904, 20817, 20936, 20904, 21044, 20936, 21044, 21109, - 21044, 21102, 21109, 21202, 21292, 21109, 21411, 21292, 21202, 42711, 42831, 42910, 4865, - 3991, 4624, 8464, 8248, 8302, 8208, 8248, 8464, 21411, 21551, 21490, 20725, 21000, - 20830, 25419, 25001, 25065, 37568, 37546, 37520, 38188, 38132, 38308, 38188, 38308, 38297, - 42910, 42831, 43033, 474, 643, 645, 633, 450, 684, 474, 645, 455, 6683, - 6701, 6799, 20368, 20292, 20498, 19677, 19598, 19384, 18158, 17826, 18170, 37079, 37035, - 36971, 18081, 17802, 17906, 20292, 20138, 20219, 21490, 21551, 21611, 21000, 21087, 21072, - 43033, 42831, 42826, 17906, 17802, 17876, 12458, 12342, 12450, 12450, 12342, 12389, 1721, - 1671, 1769, 1439, 1380, 1271, 28534, 28480, 28184, 29561, 29555, 29163, 28534, 28184, - 28611, 38950, 39043, 39025, 40179, 40065, 40034, 42154, 42146, 41983, 42143, 42241, 42111, - 42010, 41896, 41867, 42813, 42936, 42826, 35834, 35769, 35655, 3630, 4201, 3658, 3134, - 3337, 3277, 8897, 8783, 8798, 8925, 8985, 9194, 39054, 39066, 38962, 20138, 20015, - 20219, 16559, 16348, 16447, 14131, 14031, 14138, 16340, 16348, 16559, 35601, 35623, 35477, - 35120, 35092, 34922, 35252, 35092, 35120, 37553, 37546, 37568, 37897, 37849, 37830, 42365, - 42475, 42293, 42616, 42278, 42441, 588, 573, 691, 667, 650, 590, 814, 794, - 882, 650, 652, 578, 745, 814, 874, 1372, 1242, 1331, 1378, 1346, 1522, - 1378, 1522, 1366, 1185, 1380, 1312, 14209, 14346, 14618, 12668, 12788, 13014, 12458, - 12329, 12342, 20015, 19949, 19978, 21275, 21342, 21286, 22490, 22678, 22406, 22726, 22678, - 22661, 26799, 26419, 26609, 31714, 31509, 31482, 33768, 34049, 34095, 34338, 34456, 34275, - 39025, 39043, 39188, 39043, 39145, 39188, 27549, 27273, 27212, 27805, 27733, 27773, 28113, - 27927, 28022, 27994, 27927, 28113, 39560, 39526, 39435, 39864, 39773, 39947, 40147, 40179, - 40034, 39240, 39538, 38963, 19949, 19913, 19874, 21611, 21551, 21707, 21611, 21707, 21717, - 42813, 42858, 42936, 1780, 1941, 1845, 31659, 31725, 31590, 31982, 31995, 32100, 38941, - 39054, 38962, 38743, 38862, 38763, 38769, 38542, 38668, 38290, 38123, 38668, 17876, 17802, - 17656, 18086, 18189, 18332, 17802, 17637, 17656, 1615, 1543, 1718, 1446, 1543, 1615, - 25319, 25331, 25414, 24439, 24239, 24373, 26740, 26335, 26700, 25883, 26001, 26008, 25917, - 26001, 25883, 28394, 28249, 28260, 28096, 28249, 28224, 28113, 28249, 28096, 37210, 37402, - 37195, 19740, 19782, 19639, 21717, 21707, 21823, 42988, 42455, 42722, 525, 573, 588, - 732, 580, 725, 1153, 1479, 1215, 15806, 15872, 15829, 15806, 15829, 15729, 15625, - 15532, 15553, 22678, 22783, 22760, 23552, 23655, 23448, 22961, 22783, 22919, 25600, 25702, - 25549, 25549, 25702, 25662, 38743, 38763, 38625, 41723, 41645, 41587, 42082, 42010, 41867, - 1641, 1780, 1793, 1641, 1793, 1671, 7372, 7676, 7635, 7597, 7676, 7372, 37897, - 37870, 37849, 38576, 38308, 38453, 42238, 42252, 41877, 42429, 42147, 42265, 23572, 23706, - 23332, 21823, 22197, 22259, 24439, 24508, 24639, 42842, 42373, 42620, 42854, 42620, 42755, - 42804, 42768, 43015, 4735, 4664, 4738, 4818, 4951, 5227, 4865, 4853, 3991, 19913, - 19770, 19852, 19607, 19740, 19639, 9257, 9212, 9197, 9212, 8911, 9197, 35601, 35477, - 35399, 1578, 1621, 1715, 32183, 32300, 32334, 11012, 10769, 11049, 10970, 11012, 11237, - 10970, 11237, 11086, 10930, 10968, 11073, 11073, 11193, 11182, 10630, 10790, 10639, 21904, - 21668, 21717, 31182, 30830, 31058, 30256, 30153, 30068, 31182, 31058, 31212, 31182, 31212, - 31445, 3407, 3417, 3517, 10571, 10639, 10493, 756, 885, 894, 874, 814, 882, - 1140, 858, 833, 11502, 11474, 11548, 10837, 10968, 10930, 11659, 12004, 11735, 30830, - 30627, 30401, 30068, 29996, 29938, 17034, 16719, 17407, 18158, 18170, 18644, 18149, 18189, - 18086, 17656, 17637, 17556, 23552, 23448, 23329, 25782, 25917, 25702, 732, 403, 580, - 525, 673, 605, 25331, 25467, 25414, 42508, 42497, 42340, 42582, 42497, 42508, 1018, - 1153, 1215, 26609, 26419, 26364, 31725, 31659, 31789, 31421, 31482, 31297, 31067, 31145, - 31135, 31053, 31145, 31067, 31053, 30825, 30735, 30825, 30658, 30735, 42010, 42154, 41983, - 42146, 42241, 42143, 42806, 42916, 42951, 1288, 2272, 2216, 2529, 2302, 2604, 11097, - 11193, 11073, 30627, 30417, 30427, 28681, 28812, 28817, 41017, 40851, 40858, 41017, 40858, - 40893, 6780, 6683, 6799, 7592, 7721, 7711, 6686, 6721, 6797, 6686, 6551, 6721, - 6481, 5875, 5676, 4812, 5500, 4986, 4903, 4986, 4896, 35610, 35601, 35557, 37682, - 37596, 37712, 37870, 37712, 37849, 8707, 8649, 8798, 8696, 8925, 9077, 19770, 19598, - 19677, 23063, 23048, 23176, 42813, 42851, 42858, 7833, 7770, 7940, 8707, 8798, 8783, - 33829, 34049, 33768, 35834, 35623, 35610, 38793, 38658, 38426, 38542, 38670, 38619, 38743, - 38670, 38769, 38970, 38793, 38623, 39145, 39255, 39406, 39183, 39240, 38963, 39050, 39054, - 38941, 39050, 38941, 39005, 3428, 3517, 3580, 3524, 3580, 3609, 4744, 4664, 4735, - 4554, 4664, 4744, 6788, 7358, 6868, 11193, 11336, 11238, 30351, 30153, 30256, 664, - 945, 775, 1063, 1018, 1215, 664, 270, 502, 7940, 7770, 7711, 7833, 7940, - 7780, 7676, 7759, 7842, 7906, 7759, 7738, 23706, 23478, 23332, 24621, 24439, 24639, - 525, 605, 539, 732, 750, 607, 3280, 3030, 3481, 2923, 3315, 3309, 2923, - 3309, 2774, 12342, 12329, 12317, 12458, 12788, 12668, 31948, 31725, 31789, 32334, 32300, - 32336, 32334, 32336, 32550, 40100, 39864, 39947, 39200, 39188, 39219, 40158, 39953, 40210, - 41855, 41723, 41484, 41111, 40887, 40895, 42891, 42748, 42836, 42806, 42781, 42706, 42858, - 42851, 42792, 42806, 42951, 42781, 1460, 1522, 1537, 1346, 1242, 1372, 1460, 1537, - 1543, 6721, 6759, 6868, 27824, 27733, 27805, 26996, 26793, 26752, 27824, 27805, 27927, - 13281, 13014, 13371, 14618, 14808, 15440, 23655, 23800, 23804, 23772, 23800, 23655, 41950, - 41925, 41791, 41588, 41670, 41517, 42024, 41925, 41950, 10279, 10456, 10158, 29036, 29251, - 29246, 28096, 27994, 28113, 39756, 39606, 39686, 41480, 41354, 41388, 42281, 42241, 42292, - 2456, 2923, 2774, 2001, 2080, 2332, 1929, 2080, 2001, 11580, 11540, 11719, 30127, - 29996, 30068, 13656, 13579, 13988, 13304, 13579, 13288, 26936, 27242, 26946, 28703, 28534, - 28700, 41860, 41670, 41957, 7131, 7093, 7064, 16348, 16189, 16217, 16340, 16189, 16348, - 19598, 19342, 19384, 42497, 42475, 42365, 42582, 42475, 42497, 42913, 42877, 42647, 42858, - 42792, 43038, 605, 599, 539, 607, 750, 587, 23548, 23478, 23690, 31948, 31789, - 31982, 31421, 31297, 31223, 40380, 40158, 40210, 40205, 40351, 40286, 40309, 40604, 40499, - 40759, 40939, 40621, 39694, 39388, 39652, 39694, 39652, 39538, 43038, 42792, 43140, 42415, - 42249, 42258, 41142, 41035, 41116, 756, 894, 794, 7249, 7290, 7093, 8058, 8302, - 8248, 7906, 8153, 7842, 38670, 38743, 38625, 38928, 38743, 39018, 36430, 36269, 35099, - 36619, 36818, 36799, 3204, 3401, 3417, 3078, 3155, 3280, 3030, 3155, 2927, 13857, - 14027, 14031, 11371, 11502, 11504, 17980, 18086, 17906, 19544, 19639, 19331, 16940, 16756, - 16488, 29246, 29251, 29449, 32183, 32130, 32100, 32550, 32336, 32570, 37076, 36915, 37197, - 41222, 41314, 41149, 41443, 41314, 41555, 26264, 26144, 26001, 26778, 26936, 26799, 26799, - 26936, 26946, 36588, 36269, 36430, 36751, 36849, 36829, 37035, 37203, 37195, 37402, 37416, - 37536, 36655, 36461, 36440, 36655, 36350, 36693, 36691, 36311, 36309, 35974, 35769, 35834, - 1731, 2180, 1941, 1115, 1600, 1661, 1293, 1603, 1368, 1271, 1380, 1232, 3658, - 3735, 3661, 3245, 3204, 3417, 8791, 8707, 8783, 8114, 8208, 8170, 8791, 8783, - 8925, 28817, 28812, 28886, 28658, 28846, 28751, 28061, 27775, 27679, 33765, 33829, 33768, - 33242, 33077, 33090, 38996, 38793, 38970, 39255, 39398, 39542, 39054, 39164, 39066, 39210, - 39164, 39054, 4834, 4903, 4896, 4834, 4884, 4723, 7461, 7540, 7438, 2555, 2413, - 2344, 21717, 21823, 21904, 23999, 24069, 24223, 36849, 36949, 36829, 1034, 1225, 827, - 1319, 1271, 1176, 4664, 4519, 4738, 4396, 4519, 4664, 19342, 19195, 19206, 29721, - 29598, 29819, 41280, 41116, 41120, 42943, 42697, 42955, 25331, 25095, 25350, 24223, 24069, - 24239, 24969, 25095, 25058, 37303, 37197, 37274, 36949, 37079, 36971, 683, 785, 885, - 677, 756, 794, 677, 794, 814, 10790, 10837, 10930, 10968, 11097, 11073, 11213, - 11309, 11336, 10630, 10725, 10790, 10595, 10725, 10630, 37079, 37203, 37035, 40541, 40604, - 40309, 477, 939, 702, 694, 736, 910, 16189, 16062, 16225, 16101, 16062, 16189, - 42154, 42241, 42146, 42292, 42154, 42367, 13880, 13857, 14031, 14131, 14138, 14209, 27906, - 27824, 27927, 27733, 27518, 27549, 25319, 25095, 25331, 27906, 27927, 27994, 1380, 1185, - 1232, 5147, 4818, 5227, 4624, 4834, 4723, 7592, 7711, 7770, 10175, 10493, 10288, - 13959, 14131, 13971, 27508, 27518, 27733, 27491, 27567, 27281, 27491, 27281, 27242, 30266, - 30105, 30215, 31333, 31421, 31223, 37897, 37830, 38341, 37458, 37303, 37274, 37830, 38188, - 38341, 41932, 41903, 41645, 41932, 41645, 41820, 7759, 7906, 7842, 7915, 7906, 7815, - 7759, 7651, 7738, 11201, 11237, 11474, 10970, 10812, 10769, 10769, 10158, 10605, 11502, - 11548, 11540, 10878, 11097, 10968, 11856, 12029, 12004, 13285, 13082, 13288, 17980, 17906, - 17876, 42886, 42854, 42755, 42616, 42636, 42239, 42886, 42755, 42804, 1575, 1641, 1671, - 1575, 1671, 1600, 2128, 2013, 2034, 3332, 3417, 3407, 32588, 32550, 32570, 32344, - 32130, 32183, 39558, 39398, 39526, 39792, 39756, 39686, 39844, 39782, 39864, 39905, 39694, - 39538, 32344, 32183, 32334, 993, 1393, 1331, 1357, 1460, 1543, 1446, 1615, 1621, - 2344, 2413, 2303, 35834, 35655, 35623, 35623, 35601, 35610, 37553, 37426, 37546, 8591, - 8490, 8649, 7385, 7592, 7427, 8187, 8279, 8317, 8095, 8279, 8187, 27424, 27273, - 27549, 35446, 35399, 35252, 33765, 33768, 33449, 38658, 38576, 38453, 39200, 38970, 39025, - 42135, 41754, 42297, 41925, 42510, 41570, 42024, 42015, 42107, 2302, 2181, 2222, 2128, - 2181, 2302, 2090, 2181, 2128, 29472, 29408, 29449, 29106, 29055, 28886, 40990, 40939, - 40759, 599, 532, 539, 590, 532, 599, 7780, 7770, 7833, 19195, 18992, 19065, - 21902, 22400, 22379, 23389, 23329, 23323, 43120, 42891, 42836, 9824, 10288, 9741, 9516, - 9655, 9431, 31725, 31445, 31590, 30218, 30351, 30925, 30925, 30351, 30627, 30351, 30256, - 30417, 30127, 30068, 30153, 30036, 29906, 29996, 29996, 29906, 29819, 29598, 29472, 29449, - 31674, 31445, 31725, 31333, 31223, 31145, 33273, 33242, 33267, 40263, 40351, 40205, 40263, - 40205, 40179, 35601, 35399, 35557, 13468, 13371, 13626, 7137, 7290, 7222, 11719, 12329, - 11867, 11294, 11502, 11371, 15219, 14618, 15440, 683, 885, 761, 3630, 3524, 3609, - 3590, 3524, 3630, 8707, 8591, 8649, 8618, 8791, 8696, 18532, 18158, 18644, 16101, - 16027, 16062, 24223, 24239, 24439, 21567, 21717, 21668, 33280, 33437, 33449, 31780, 31822, - 31714, 39164, 39240, 39183, 39210, 39240, 39164, 15276, 15532, 15385, 16488, 16756, 16513, - 15249, 15193, 15150, 25702, 25917, 25883, 27322, 27491, 27242, 24710, 24935, 24723, 16075, - 16033, 15872, 17823, 17980, 17876, 24027, 24359, 23804, 23896, 23804, 23800, 5139, 5587, - 5670, 5139, 5670, 5431, 6039, 6327, 6298, 6563, 6701, 6683, 6563, 6683, 6273, - 6846, 6901, 6780, 6901, 6902, 6780, 6901, 6973, 6902, 42891, 42895, 42748, 8618, - 8591, 8707, 33273, 33437, 33280, 39005, 38941, 38862, 40100, 39844, 39864, 16062, 16027, - 15948, 16719, 17034, 16755, 30351, 30417, 30627, 40998, 41111, 40895, 42927, 42967, 42742, - 42913, 43007, 42877, 42877, 43007, 42848, 42891, 43015, 42895, 42952, 42968, 42927, 42986, - 42968, 42952, 42986, 42952, 42897, 42986, 42897, 42991, 42897, 42905, 42991, 42905, 43003, - 42991, 42903, 43003, 42905, 43018, 43003, 42903, 43018, 42903, 42888, 43018, 42888, 43020, - 43020, 42888, 42866, 529, 462, 643, 455, 645, 442, 11735, 11475, 11659, 20138, - 20316, 20015, 19795, 19824, 19949, 19949, 19824, 19913, 19913, 19824, 19770, 19770, 19733, - 19598, 19598, 19549, 19342, 19342, 19320, 19195, 19195, 19320, 18992, 20292, 20368, 20138, - 20788, 20560, 20594, 20788, 20594, 20904, 20788, 20904, 20936, 20788, 20936, 21079, 20936, - 21109, 21079, 21411, 21490, 21292, 21490, 21567, 21292, 21611, 21567, 21490, 21611, 21717, - 21567, 21000, 21069, 21087, 21087, 21230, 21178, 21342, 21902, 21712, 20725, 20838, 21000, - 20618, 20838, 20725, 20509, 20838, 20618, 20509, 20618, 20563, 20509, 20563, 20414, 20509, - 20414, 20472, 19702, 19835, 19740, 29308, 29246, 29408, 29408, 29246, 29449, 28488, 28249, - 28394, 42968, 42967, 42927, 43053, 43020, 42866, 20838, 20854, 21000, 42935, 43053, 42798, - 2090, 2216, 2202, 9212, 9040, 8911, 41496, 41480, 41388, 41443, 41388, 41314, 20560, - 20368, 20498, 35557, 35399, 35446, 37568, 37520, 37596, 520, 793, 585, 42935, 43118, - 43053, 3991, 5134, 3715, 499, 520, 585, 590, 578, 532, 31865, 31780, 31714, - 40194, 40147, 40034, 42854, 42842, 42620, 42857, 42842, 42854, 42785, 42910, 42999, 440, - 462, 529, 21069, 21230, 21087, 24621, 24223, 24439, 41903, 42054, 41867, 41820, 41645, - 41723, 1731, 1941, 1780, 2026, 2344, 2303, 11309, 11475, 11336, 29754, 29721, 29819, - 41142, 41167, 41035, 41098, 41017, 40893, 40399, 40380, 40650, 40158, 40234, 39947, 41311, - 41167, 41142, 41300, 41517, 41687, 41855, 41820, 41723, 22884, 23063, 22734, 21230, 21275, - 21286, 42999, 42910, 43102, 6759, 6788, 6868, 6721, 6724, 6759, 6788, 6724, 6657, - 4780, 4986, 4903, 4800, 4903, 4834, 16061, 16340, 16149, 34456, 34338, 34295, 37682, - 37568, 37596, 37682, 37712, 37747, 694, 910, 751, 42015, 42024, 41950, 41754, 42078, - 42297, 42075, 42054, 41903, 42808, 42636, 42616, 42297, 42078, 42252, 499, 585, 471, - 532, 578, 483, 18992, 18729, 19008, 18532, 18729, 18693, 39558, 39526, 39581, 39188, - 39200, 39025, 39844, 39792, 39686, 39860, 39792, 39844, 43309, 42988, 42722, 29125, 29055, - 29106, 28880, 29055, 29125, 41687, 41517, 41670, 41496, 41443, 41555, 41758, 41855, 41484, - 25917, 26067, 26001, 25836, 26067, 25917, 19094, 19199, 18823, 17720, 17876, 17656, 22961, - 23059, 22783, 4120, 4573, 4672, 4120, 4774, 4519, 8061, 8058, 8208, 8208, 8058, - 8248, 6902, 7064, 6998, 27186, 27137, 27212, 27186, 27212, 27273, 27424, 27549, 27518, - 27424, 27518, 27508, 42429, 42293, 42475, 1984, 2237, 2080, 2927, 3078, 2923, 7064, - 7093, 6998, 6902, 6973, 7064, 11103, 10812, 11086, 11086, 10812, 10970, 8170, 8591, - 8465, 17435, 17341, 17420, 15063, 15249, 15150, 15157, 14951, 14911, 34295, 34104, 34049, - 34295, 34049, 34424, 35252, 35062, 35092, 37747, 37712, 37870, 42241, 42280, 42111, 42281, - 42280, 42241, 376, 450, 633, 3735, 4201, 4328, 3395, 3332, 3407, 19795, 19949, - 20015, 22734, 23063, 23081, 39558, 39581, 39812, 38677, 38576, 38658, 29595, 29472, 29598, - 30215, 30008, 29745, 31406, 31333, 31145, 31421, 31490, 31482, 41540, 41280, 41120, 691, - 489, 471, 483, 578, 403, 23081, 23063, 23176, 23300, 23176, 23332, 42955, 42697, - 42781, 43033, 42826, 42936, 42955, 42781, 42951, 664, 700, 863, 622, 700, 540, - 3428, 3580, 3524, 2908, 3023, 2340, 13281, 13081, 13014, 11294, 11201, 11474, 13006, - 13081, 13145, 13468, 13626, 13857, 13880, 14031, 13959, 13066, 13079, 12830, 13066, 12830, - 12706, 16940, 17327, 17271, 15806, 15729, 15743, 11294, 11474, 11502, 19824, 19733, 19770, - 30627, 30830, 30925, 29906, 29754, 29819, 29721, 29595, 29598, 43033, 42936, 43062, 31449, - 31333, 31437, 8279, 8436, 8528, 8247, 8436, 8279, 7998, 8187, 7906, 38928, 39005, - 38862, 39050, 39210, 39054, 40270, 40147, 40255, 40270, 40263, 40147, 38928, 38862, 38743, - 25095, 24969, 25026, 25467, 25480, 25414, 7438, 7540, 7592, 27137, 26793, 26996, 1279, - 1346, 1378, 593, 683, 761, 2181, 2090, 2202, 3154, 3134, 3204, 11213, 11336, - 11193, 12044, 12299, 12029, 11213, 11193, 11097, 10703, 10790, 10725, 10703, 10725, 10595, - 25467, 25964, 25480, 30218, 30127, 30153, 29420, 29163, 28862, 36530, 36588, 36430, 34856, - 34965, 35112, 33388, 32570, 33137, 36686, 36588, 36530, 36686, 36530, 36619, 36686, 36619, - 36799, 36915, 36818, 36726, 37076, 36818, 36915, 37275, 36818, 37076, 37303, 37157, 37076, - 36949, 37041, 37079, 37241, 37210, 37203, 37203, 37210, 37195, 36849, 37041, 36949, 36693, - 36350, 36311, 36693, 36691, 36807, 36309, 35974, 36189, 35652, 35834, 35610, 35652, 35610, - 35557, 40939, 40998, 40895, 41409, 41314, 41222, 40990, 40998, 40939, 41111, 40998, 41117, - 40541, 40309, 40351, 42555, 42236, 42249, 7311, 7438, 7446, 32550, 32588, 32334, 32130, - 31948, 31982, 31188, 30830, 31182, 34965, 35094, 35360, 37303, 37306, 37157, 43062, 42936, - 42858, 42806, 42710, 42916, 37274, 37553, 37458, 36655, 36844, 36751, 31449, 31490, 31421, - 33090, 33077, 32984, 40893, 41113, 41098, 41012, 40717, 40851, 18441, 18332, 18189, 1714, - 1731, 1780, 1525, 1575, 1441, 5619, 5406, 5555, 5817, 6039, 5940, 6134, 6039, - 5619, 28880, 28886, 29055, 28880, 28817, 28886, 28534, 28846, 28658, 28703, 28846, 28534, - 27580, 27679, 27567, 11914, 12029, 11856, 8058, 7780, 7940, 35120, 34922, 34827, 33959, - 34049, 33829, 38677, 38658, 38924, 587, 750, 763, 593, 761, 756, 1303, 1279, - 1378, 1366, 1522, 1460, 1271, 1319, 1368, 1232, 1185, 1080, 42414, 42415, 42258, - 42414, 42258, 42280, 450, 484, 767, 967, 1185, 1153, 1018, 1063, 1034, 1563, - 1621, 1578, 1357, 1366, 1460, 4725, 4800, 4834, 4780, 4800, 4725, 27137, 27077, - 26793, 27906, 27733, 27824, 27192, 27242, 26936, 35446, 35652, 35557, 34320, 34275, 34621, - 43062, 42858, 43038, 40147, 40263, 40179, 40270, 40336, 40347, 15743, 15729, 15625, 42582, - 42429, 42475, 22726, 22783, 22678, 22678, 22490, 22661, 37458, 37553, 37530, 42792, 42801, - 43140, 42710, 42611, 42901, 587, 763, 697, 23552, 23772, 23655, 25420, 25419, 25306, - 23542, 23772, 23552, 926, 1018, 1034, 42292, 42241, 42154, 9440, 9516, 9431, 10595, - 10630, 10571, 9440, 9431, 9257, 3658, 3590, 3630, 3556, 3590, 3658, 33437, 33765, - 33449, 33242, 33273, 33280, 32917, 32437, 32984, 34621, 34275, 34456, 573, 489, 691, - 501, 489, 573, 3245, 3154, 3204, 3520, 3428, 3524, 27336, 27186, 27273, 27124, - 27192, 26936, 42135, 42153, 42015, 42024, 42107, 41925, 42222, 42153, 42135, 37241, 37203, - 37079, 648, 745, 874, 1950, 1929, 2001, 1771, 1929, 1950, 30036, 29754, 29906, - 29472, 29531, 29408, 25319, 25219, 25095, 25480, 25964, 25487, 25480, 25487, 25439, 25477, - 25619, 25600, 26067, 26264, 26001, 42728, 42582, 42508, 42728, 42321, 42636, 42901, 42495, - 42960, 42672, 42555, 42249, 4818, 4715, 4744, 4554, 4715, 4578, 4715, 4818, 4578, - 6902, 6585, 6780, 7137, 6998, 7093, 7290, 7461, 7222, 32344, 31948, 32130, 37530, - 37553, 37561, 37879, 37897, 38007, 500, 501, 573, 43265, 43007, 43458, 43146, 42886, - 42804, 42801, 42943, 42984, 18371, 18441, 18189, 18149, 18086, 18012, 700, 694, 751, - 696, 1225, 1011, 622, 694, 700, 1544, 1563, 1578, 4004, 3897, 4328, 4034, - 4120, 3913, 7759, 7676, 7597, 12706, 12830, 12360, 13082, 13163, 13288, 500, 539, - 483, 617, 587, 697, 617, 697, 683, 17435, 17720, 17556, 17435, 17556, 17327, - 23772, 23896, 23800, 23828, 23896, 23772, 29754, 29595, 29721, 37553, 37568, 37561, 525, - 500, 573, 3988, 3897, 4004, 39234, 39210, 39050, 38769, 38670, 38542, 34890, 35120, - 34827, 34491, 34621, 34456, 34491, 34456, 34424, 3245, 3417, 3332, 10595, 10571, 10438, - 11309, 11500, 11475, 30635, 30735, 30658, 31333, 31449, 31421, 30570, 30735, 30635, 30570, - 30442, 30215, 905, 926, 827, 1132, 1176, 1080, 26342, 26264, 26067, 6998, 6945, - 6902, 7222, 7461, 7438, 15930, 16075, 15872, 15553, 15743, 15625, 15276, 15385, 15249, - 34890, 34827, 34720, 35774, 35652, 35446, 42954, 42837, 42441, 43015, 42768, 42895, 42495, - 42551, 42960, 42984, 42943, 42965, 37561, 37568, 37682, 42943, 42955, 42965, 13959, 14031, - 14131, 12887, 12668, 13014, 13959, 13971, 13811, 1188, 1242, 1279, 1279, 1242, 1346, - 1303, 1378, 1366, 27472, 27580, 27491, 27491, 27580, 27567, 27322, 27242, 27192, 13006, - 13014, 13081, 14911, 14951, 14849, 26486, 26609, 26364, 28488, 28394, 28543, 29125, 29106, - 29246, 28846, 28854, 28862, 28822, 28854, 28846, 41443, 41496, 41388, 41820, 42020, 41932, - 42082, 41867, 42054, 42338, 42154, 42010, 41235, 40912, 41111, 42415, 42653, 42249, 42281, - 42414, 42280, 42082, 42054, 42075, 2090, 1972, 2216, 1972, 2128, 2034, 11201, 11103, - 11086, 8464, 8591, 8170, 11502, 11540, 11504, 10878, 11213, 11097, 13127, 13163, 12953, - 29796, 29531, 29595, 30127, 30036, 29996, 30351, 30218, 30153, 30036, 30218, 30594, 41098, - 41113, 41228, 41113, 41167, 41220, 801, 648, 874, 519, 617, 472, 858, 1140, - 1216, 15690, 15219, 15440, 16340, 16101, 16189, 16061, 16101, 16340, 15967, 16101, 16061, - 15930, 15872, 15806, 25221, 25219, 25319, 25414, 25480, 25439, 25419, 25477, 25549, 25600, - 25619, 25692, 3428, 3395, 3407, 3590, 3520, 3524, 3452, 3520, 3590, 23896, 24027, - 23804, 23927, 24027, 23896, 28488, 28543, 28725, 27290, 27077, 27186, 31974, 31959, 31780, - 31499, 31449, 31437, 41471, 41309, 41691, 525, 539, 500, 18853, 19094, 18823, 35354, - 35446, 35252, 37747, 37561, 37682, 3339, 3395, 3428, 27124, 27322, 27192, 42075, 41903, - 42108, 3735, 3658, 4201, 4120, 4034, 4004, 3897, 3735, 4328, 3943, 4034, 3913, - 7915, 7998, 7906, 9197, 9440, 9257, 7852, 7998, 7915, 21645, 21292, 21567, 23302, - 23300, 23478, 23176, 23300, 23157, 24728, 24639, 24969, 7137, 6945, 6998, 7311, 7222, - 7438, 36593, 35360, 36269, 11315, 11500, 11309, 34424, 34456, 34295, 34907, 34890, 34720, - 1563, 1446, 1621, 1461, 1446, 1563, 41691, 41309, 41480, 539, 532, 483, 3307, - 3245, 3332, 2128, 2302, 2013, 33568, 33765, 33437, 33568, 33437, 33273, 39036, 38996, - 38970, 37879, 37870, 37897, 39036, 38970, 39200, 25221, 25319, 25439, 11500, 11659, 11475, - 41181, 41199, 41111, 40990, 40759, 40604, 677, 814, 745, 578, 580, 403, 18441, - 18579, 18791, 18012, 18086, 17980, 18012, 17980, 17986, 23042, 23389, 23323, 23042, 23059, - 22961, 42886, 42857, 42854, 43025, 42857, 42886, 15264, 15276, 15249, 15828, 15930, 15806, - 42485, 42414, 42281, 42415, 42414, 42464, 40380, 40234, 40158, 39792, 39779, 39756, 40399, - 40234, 40380, 40263, 40458, 40351, 39437, 39538, 39240, 732, 607, 403, 30711, 31053, - 30735, 28822, 28703, 28700, 41578, 41660, 41496, 41496, 41660, 41480, 43120, 43015, 42891, - 7009, 6945, 7137, 7446, 7438, 7592, 34907, 34720, 34621, 35435, 35354, 35252, 6724, - 6788, 6759, 5676, 5875, 5500, 16101, 15967, 16027, 15931, 15967, 15991, 25477, 25600, - 25549, 26787, 26778, 26609, 25477, 25419, 25420, 37879, 37747, 37870, 38188, 38297, 38443, - 9980, 10238, 10175, 8829, 8729, 9040, 20788, 20612, 20560, 20560, 20434, 20368, 20316, - 19795, 20015, 19824, 19795, 19733, 19733, 19705, 19598, 20726, 20612, 20788, 20726, 20779, - 20708, 21109, 21292, 21079, 21079, 21024, 20923, 40122, 39860, 39844, 455, 384, 474, - 474, 440, 529, 462, 376, 633, 450, 287, 484, 76, 384, 455, 442, - 645, 406, 793, 520, 406, 520, 388, 406, 499, 388, 520, 393, 388, - 499, 20153, 20258, 20414, 20838, 20995, 20854, 20854, 20995, 21000, 21230, 21212, 21275, - 22661, 22490, 22400, 20069, 20258, 20153, 42967, 43309, 42722, 43265, 43120, 43007, 43007, - 43120, 42848, 42968, 43078, 42967, 43153, 43078, 42968, 43153, 42968, 42986, 43153, 42986, - 43189, 43126, 42991, 43003, 43126, 43003, 43018, 43126, 43018, 43166, 43018, 43020, 43166, - 43020, 43053, 43166, 42935, 42999, 43118, 42999, 43102, 43118, 953, 993, 1331, 4034, - 3988, 4004, 3943, 3988, 4034, 7998, 8095, 8187, 7597, 7372, 7240, 8058, 7768, - 7780, 7385, 7446, 7592, 8114, 8061, 8208, 8208, 8464, 8170, 8925, 8696, 8791, - 7980, 8095, 7998, 15063, 15264, 15249, 14849, 14951, 14652, 20612, 20434, 20560, 20066, - 19835, 20258, 26609, 26778, 26799, 26486, 26364, 26264, 11659, 11914, 11856, 20258, 19835, - 19959, 20928, 20995, 20838, 41199, 41235, 41111, 42910, 43033, 43102, 36588, 36680, 36269, - 36686, 36609, 36588, 36774, 36609, 36686, 36774, 36686, 36799, 36774, 36799, 36917, 36799, - 36818, 36917, 36818, 37254, 36917, 37303, 37324, 37306, 37458, 37324, 37303, 36844, 37041, - 36849, 36655, 36730, 36844, 36807, 36955, 37000, 243, 440, 474, 5433, 5676, 5500, - 19702, 19740, 19607, 21823, 21913, 21904, 20995, 21069, 21000, 37458, 37503, 37324, 36693, - 36730, 36655, 427, 477, 702, 427, 744, 484, 3395, 3307, 3332, 3520, 3440, - 3428, 3372, 3440, 3394, 3556, 3658, 3661, 31959, 31822, 31780, 1232, 1176, 1271, - 1319, 1293, 1368, 1525, 1780, 1641, 967, 1153, 1018, 31865, 31714, 31490, 40234, - 40200, 39947, 1145, 1303, 1366, 1242, 1126, 1331, 1132, 1293, 1319, 3569, 3556, - 3661, 18533, 18579, 18441, 17986, 17980, 17823, 23389, 23503, 23329, 25692, 25782, 25600, - 23625, 23503, 23398, 28096, 27906, 27994, 26740, 26700, 26793, 27951, 27906, 27979, 39234, - 39050, 39154, 42965, 42955, 42977, 42642, 42226, 42521, 17496, 17435, 17420, 42954, 42373, - 42842, 4800, 4780, 4903, 4725, 4834, 4624, 36823, 36807, 37000, 35188, 35252, 35120, - 42153, 42107, 42015, 41311, 41142, 41280, 42222, 42107, 42153, 42297, 42252, 42673, 42082, - 42202, 42010, 42108, 41903, 41932, 42020, 41820, 42007, 41758, 41484, 41753, 39779, 39581, - 39756, 1145, 1357, 1154, 1446, 1357, 1543, 41780, 41758, 41753, 25439, 25319, 25414, - 25058, 24918, 24969, 27077, 27137, 27186, 42684, 42642, 42521, 42684, 42521, 42555, 471, - 393, 499, 648, 677, 745, 756, 677, 615, 3684, 3735, 3897, 7281, 7446, - 7385, 7311, 7158, 7222, 10703, 10837, 10790, 11213, 11315, 11309, 11500, 11325, 11659, - 12046, 12044, 11948, 10438, 10571, 10238, 10595, 10837, 10703, 38677, 38443, 38576, 39219, - 39036, 39200, 42955, 42951, 42977, 43102, 43033, 43173, 1913, 1984, 2080, 1771, 1731, - 1704, 15504, 15553, 15532, 16333, 16488, 16513, 15504, 15532, 15276, 29595, 29531, 29472, - 28725, 28543, 28817, 29796, 29595, 29754, 41235, 41330, 41222, 41660, 41691, 41480, 27336, - 27273, 27424, 27322, 27348, 27491, 28700, 28534, 28611, 27048, 27124, 26936, 41180, 40990, - 40604, 41199, 41306, 41235, 41442, 41453, 41330, 341, 376, 462, 13066, 13163, 13082, - 12280, 12360, 12299, 15834, 15948, 16027, 15089, 15063, 14911, 15089, 15264, 15063, 18371, - 18189, 18220, 17823, 17876, 17720, 23503, 23542, 23552, 23625, 23542, 23503, 28725, 28817, - 28880, 37458, 37530, 37503, 40200, 40100, 39947, 39860, 39779, 39792, 41817, 41691, 41836, - 42857, 42950, 42842, 43034, 42950, 42857, 39812, 39779, 39913, 4745, 4725, 4633, 4780, - 4777, 4986, 15967, 15931, 16027, 15834, 15931, 15798, 15828, 15806, 15743, 37503, 37530, - 37602, 38443, 38297, 38576, 7738, 7815, 7906, 7637, 7815, 7738, 20316, 20138, 20368, - 18729, 18532, 18644, 43033, 43193, 43173, 7592, 7770, 7647, 10537, 10605, 10158, 33956, - 33959, 33765, 33765, 33959, 33829, 34491, 34617, 34621, 471, 489, 393, 478, 607, - 587, 411, 483, 196, 2128, 1972, 2090, 2302, 2000, 2013, 1913, 2080, 1929, - 2927, 2923, 2425, 2927, 3155, 3078, 11294, 11103, 11201, 11504, 11540, 11580, 11325, - 11315, 11213, 13127, 13304, 13163, 22661, 22400, 22542, 31449, 31499, 31490, 31437, 31333, - 31406, 31145, 31053, 31406, 37687, 37561, 37747, 40347, 40458, 40263, 40347, 40263, 40270, - 41311, 41280, 41540, 40650, 40273, 40436, 40221, 40178, 40200, 40200, 40178, 40100, 40990, - 41117, 40998, 43193, 43062, 43256, 42977, 42951, 42978, 19795, 19714, 19733, 21823, 22259, - 21913, 905, 967, 1018, 905, 1018, 926, 14652, 14951, 14457, 42624, 42429, 42709, - 42313, 42297, 42368, 5431, 5670, 5694, 3913, 4120, 3958, 5596, 6134, 5619, 25058, - 25095, 25219, 29531, 29308, 29408, 41453, 41222, 41330, 41453, 41409, 41222, 1262, 1544, - 2272, 1775, 1913, 1929, 17593, 17823, 17720, 18189, 18149, 18220, 17593, 17720, 17435, - 19714, 19705, 19733, 19544, 19702, 19607, 19639, 19199, 19331, 33090, 33267, 33242, 33396, - 33267, 33248, 39210, 39302, 39240, 39402, 39302, 39210, 39050, 39005, 39154, 40255, 40147, - 40194, 43140, 42801, 43116, 3245, 3108, 3154, 3440, 3339, 3428, 3372, 3339, 3440, - 3440, 3520, 3394, 33030, 32984, 32437, 33090, 32984, 33248, 18149, 18012, 18220, 22726, - 22919, 22783, 22745, 22919, 22726, 43116, 42801, 42984, 42978, 42951, 42916, 1091, 1188, - 1074, 1303, 1188, 1279, 1188, 1303, 1074, 3735, 3668, 3661, 3569, 3668, 3591, - 13145, 13081, 13281, 12306, 12317, 11719, 14131, 14209, 13971, 13766, 13988, 13579, 33396, - 33568, 33273, 41969, 41855, 41758, 41969, 41820, 41855, 42464, 42414, 42583, 19705, 19572, - 19598, 22071, 22046, 21939, 1143, 1126, 1242, 10438, 10837, 10595, 8829, 8715, 8729, - 8247, 8279, 8095, 15553, 15665, 15743, 15413, 15504, 15276, 15413, 15276, 15264, 38668, - 38123, 37536, 38668, 39150, 39186, 42464, 42458, 42415, 42281, 42292, 42485, 15931, 15834, - 16027, 17671, 17594, 17407, 25600, 25782, 25702, 26778, 27048, 26936, 24124, 24710, 24027, - 40333, 40255, 40194, 489, 421, 393, 19572, 19549, 19598, 19331, 19199, 19094, 23081, - 23176, 23157, 21846, 21913, 21939, 13163, 13304, 13288, 12165, 12299, 12044, 41817, 41780, - 41753, 41817, 41753, 41691, 688, 1011, 736, 7971, 8247, 8095, 7121, 7372, 7346, - 26574, 26486, 26264, 38658, 38793, 38924, 18987, 18729, 18992, 43116, 42984, 43068, 42979, - 42978, 42916, 42979, 42916, 42901, 14975, 15089, 14911, 14390, 14477, 14457, 42313, 42222, - 42135, 41540, 41120, 41418, 7980, 7998, 7852, 23542, 23828, 23772, 23625, 23828, 23542, - 42875, 42728, 42636, 42950, 42954, 42842, 43046, 42954, 42950, 29308, 29125, 29246, 41409, - 41555, 41314, 41623, 41555, 41629, 23157, 23300, 23302, 25136, 25058, 25219, 25136, 25219, - 25205, 489, 501, 421, 19549, 19425, 19342, 3155, 3030, 3280, 2774, 2547, 2456, - 42902, 42960, 42551, 42672, 42684, 42555, 1544, 1461, 1563, 1453, 1461, 1544, 6551, - 6686, 6481, 6788, 7121, 7337, 13691, 13857, 13880, 40100, 40122, 39844, 40221, 40200, - 40234, 41687, 41670, 41860, 19401, 19331, 19189, 23332, 23478, 23300, 22919, 23042, 22961, - 22876, 23042, 22919, 27077, 26964, 26793, 27064, 26964, 27077, 27508, 27733, 27951, 27733, - 27906, 27951, 615, 593, 756, 648, 801, 704, 694, 622, 736, 540, 700, - 664, 12044, 12029, 11914, 10837, 10878, 10968, 10804, 10878, 10837, 10571, 10175, 10238, - 3183, 3411, 3481, 39542, 39398, 39586, 39542, 39406, 39255, 38924, 38793, 38996, 39812, - 39581, 39779, 3988, 3771, 3897, 4120, 3939, 3958, 3451, 3991, 3715, 7971, 7980, - 7852, 11314, 11103, 11294, 11314, 11294, 11371, 39465, 39219, 39188, 40333, 40336, 40255, - 39028, 39005, 38928, 7597, 7651, 7759, 7551, 7651, 7597, 501, 500, 401, 421, - 501, 401, 251, 427, 484, 456, 540, 664, 3339, 3307, 3395, 3290, 3307, - 3339, 3520, 3379, 3394, 19425, 19320, 19342, 31865, 31974, 31780, 30570, 30215, 30059, - 42653, 42672, 42249, 42202, 42082, 42075, 25782, 25836, 25917, 25773, 25836, 25782, 1323, - 1453, 1262, 2890, 3134, 3154, 1984, 2026, 2303, 1951, 2026, 1984, 1951, 1984, - 1913, 18220, 18012, 18253, 18771, 18853, 18823, 18012, 18022, 18253, 21745, 21904, 21846, - 24621, 24639, 24728, 41555, 41578, 41496, 41623, 41578, 41555, 43185, 42979, 42901, 42984, - 42965, 43068, 704, 801, 833, 858, 1216, 993, 550, 688, 476, 42808, 42616, - 42928, 42311, 42203, 42222, 1126, 953, 1331, 1188, 1143, 1242, 1091, 1143, 1188, - 10158, 10769, 10812, 11914, 11659, 11763, 27906, 28096, 27979, 33728, 33737, 33568, 33568, - 33737, 33765, 34357, 34424, 34049, 34890, 35188, 35120, 33396, 33273, 33267, 40170, 40122, - 40100, 41442, 41330, 41235, 43146, 43025, 42886, 43007, 42913, 43458, 15006, 15089, 14975, - 41911, 41969, 41758, 42193, 42202, 42075, 41911, 41758, 41780, 3036, 3108, 3245, 39913, - 39779, 39860, 41012, 41017, 41143, 41012, 40851, 41017, 40178, 40170, 40100, 40458, 40541, - 40351, 41254, 41181, 41287, 41117, 41181, 41111, 40347, 40448, 40458, 40577, 40448, 40347, - 40336, 40270, 40255, 4745, 4777, 4780, 4745, 4780, 4725, 12317, 12329, 11719, 15834, - 15690, 15440, 13811, 13691, 13959, 17407, 17594, 17252, 15930, 16081, 16075, 15870, 16081, - 15930, 15665, 15553, 15504, 30218, 30036, 30127, 29359, 29125, 29308, 29359, 29045, 29125, - 31188, 31182, 31445, 37879, 37831, 37747, 38007, 37831, 37879, 41181, 41117, 41287, 42902, - 42551, 42642, 42653, 42415, 42458, 7446, 7281, 7311, 7770, 7780, 7647, 24728, 24969, - 24918, 24728, 24918, 24870, 42928, 42616, 42837, 13988, 14390, 14457, 14477, 14652, 14457, - 14642, 14390, 14312, 36979, 37041, 36844, 36693, 36807, 36730, 36311, 36691, 36693, 42108, - 41932, 42020, 6273, 6683, 6780, 17496, 17593, 17435, 401, 500, 411, 5596, 5508, - 5694, 3894, 3988, 3943, 18771, 18823, 18579, 18012, 17986, 18022, 21904, 21913, 21846, - 23706, 23690, 23478, 36979, 36844, 36730, 43146, 42804, 43172, 42954, 43094, 42837, 34537, - 34424, 34357, 35354, 35435, 35446, 38443, 38341, 38188, 39171, 38996, 39036, 37416, 37402, - 37210, 39018, 39028, 38928, 40399, 40367, 40234, 39437, 39240, 39302, 5508, 5431, 5694, - 41311, 41220, 41167, 41228, 41220, 41346, 14642, 14652, 14477, 27198, 27064, 27077, 26813, - 26740, 26793, 27124, 27348, 27322, 26787, 27048, 26778, 26787, 26609, 26486, 4747, 4745, - 4633, 411, 500, 483, 42965, 42977, 43068, 37041, 37241, 37079, 688, 668, 1011, - 584, 668, 569, 3036, 3086, 3108, 3569, 3661, 3668, 8729, 8436, 8188, 8729, - 8715, 8436, 9655, 9741, 10288, 34357, 34049, 33959, 33248, 33267, 33090, 33030, 32913, - 33015, 39219, 39171, 39036, 39406, 39465, 39188, 39586, 39398, 39558, 13006, 12887, 13014, - 13145, 12887, 13006, 15743, 15665, 15727, 15413, 15665, 15504, 29045, 28725, 28880, 29045, - 28880, 29125, 42203, 41925, 42107, 752, 858, 993, 7647, 7780, 7768, 7009, 7137, - 7222, 8170, 8061, 8114, 17758, 17986, 17823, 17435, 17327, 17341, 23927, 24124, 24027, - 23927, 23896, 23828, 628, 615, 677, 478, 587, 480, 628, 677, 648, 23706, - 23999, 23690, 25136, 24918, 25058, 40383, 40221, 40234, 40084, 39913, 39860, 39513, 39406, - 39542, 43025, 43031, 42857, 43162, 43031, 43025, 33563, 33728, 33568, 39241, 39171, 39219, - 1731, 1771, 1950, 1525, 1641, 1575, 564, 683, 593, 16061, 15991, 15967, 13959, - 13691, 13880, 15894, 15991, 16061, 43068, 42977, 43079, 7009, 7222, 7158, 26813, 26793, - 26964, 26596, 26787, 26486, 37382, 37416, 37210, 42688, 42684, 42672, 42338, 42367, 42154, - 13634, 13691, 13692, 20612, 20532, 20434, 20434, 20323, 20368, 19795, 19736, 19714, 19714, - 19736, 19705, 19705, 19659, 19572, 19572, 19628, 19549, 19483, 19353, 19425, 19425, 19353, - 19320, 20726, 20708, 20612, 20779, 20726, 20788, 20779, 20788, 20923, 20788, 21079, 20923, - 21292, 21024, 21079, 21354, 21024, 21292, 28224, 28249, 28258, 27479, 27336, 27424, 27012, - 26813, 26964, 42128, 42108, 42020, 42341, 42338, 42010, 42007, 41820, 41969, 43078, 43309, - 42967, 43189, 42986, 42991, 43189, 42991, 43126, 43189, 43345, 43313, 43053, 43167, 43166, - 43118, 43167, 43053, 43282, 43337, 43167, 20708, 20532, 20612, 21668, 21645, 21567, 20338, - 20461, 20337, 20337, 20461, 20472, 20472, 20461, 20509, 20768, 20928, 20838, 20995, 21076, - 21069, 21069, 21076, 21230, 20338, 20337, 20258, 20338, 20258, 20330, 19835, 19702, 19753, - 20532, 20323, 20434, 19753, 19702, 19708, 21668, 21745, 21645, 31674, 31188, 31445, 31674, - 31725, 31948, 29561, 29163, 29420, 28822, 28846, 28703, 41143, 41017, 41098, 40399, 40426, - 40367, 40367, 40383, 40234, 1441, 1575, 1600, 1441, 1600, 1115, 1661, 1293, 1115, - 1319, 1176, 1132, 3036, 3245, 3307, 3108, 3086, 3154, 3755, 3771, 3988, 4744, - 4715, 4554, 8618, 8707, 8791, 13634, 13468, 13857, 18771, 18579, 18666, 19708, 19702, - 19544, 18579, 18553, 18666, 20323, 20316, 20368, 21668, 21904, 21745, 20928, 21076, 20995, - 27479, 27424, 27508, 28258, 28249, 28488, 29359, 29308, 29531, 28056, 27979, 28224, 37355, - 37275, 37306, 37275, 37076, 37157, 36774, 36723, 36609, 37602, 37530, 37561, 37602, 37561, - 37687, 42222, 42203, 42107, 42313, 42135, 42297, 42187, 42193, 42075, 24587, 24223, 24621, - 21908, 21939, 22046, 43031, 43034, 42857, 43135, 43034, 43031, 40265, 40178, 40221, 40265, - 40170, 40178, 18253, 18371, 18220, 17341, 17327, 16940, 17341, 16940, 17052, 42902, 43249, - 43101, 43079, 42977, 42978, 43118, 43102, 43282, 1515, 1714, 1780, 12953, 13163, 13066, - 13304, 13766, 13579, 11325, 11500, 11315, 41836, 41691, 41660, 41629, 41555, 41409, 41306, - 41442, 41235, 1453, 1544, 1262, 2000, 2302, 1993, 5619, 6039, 5817, 7158, 7311, - 7279, 7311, 7281, 7279, 35123, 35188, 34890, 376, 363, 450, 440, 341, 462, - 299, 341, 440, 277, 474, 384, 277, 384, 113, 297, 442, 291, 345, - 406, 388, 345, 388, 350, 388, 393, 350, 393, 351, 350, 37687, 37747, - 37737, 31437, 31493, 31499, 31406, 31493, 31437, 40448, 40541, 40458, 41254, 41306, 41199, - 40577, 40541, 40448, 40577, 40347, 40336, 13468, 13145, 13281, 11580, 11314, 11504, 12280, - 12299, 12165, 14911, 14849, 14975, 41836, 41660, 41578, 42368, 42297, 42438, 19708, 19544, - 19550, 18579, 18533, 18553, 21463, 21342, 21275, 23398, 23503, 23389, 2134, 2547, 2344, - 1775, 1951, 1913, 1775, 1929, 1771, 11504, 11314, 11371, 9195, 9330, 9173, 11931, - 11867, 12329, 10911, 11325, 11213, 10804, 11213, 10878, 41228, 41158, 41098, 41228, 41113, - 41220, 43033, 43062, 43193, 9516, 9741, 9655, 8188, 8436, 8247, 7971, 8095, 7980, - 39513, 39465, 39406, 39586, 39558, 39683, 39402, 39437, 39302, 39402, 39210, 39234, 26342, - 26574, 26264, 25419, 25065, 25094, 33081, 33030, 33015, 33396, 33563, 33568, 39683, 39558, - 39812, 43034, 43044, 42950, 43135, 43044, 43034, 341, 363, 376, 3640, 3668, 3735, - 3372, 3290, 3339, 33469, 33563, 33396, 34537, 34491, 34424, 34537, 34617, 34491, 39276, - 39241, 39219, 38896, 38534, 38677, 6657, 6655, 6788, 6266, 6551, 6481, 6562, 6551, - 6438, 4812, 4986, 4777, 32344, 32334, 32588, 31958, 31674, 31948, 37672, 37687, 37737, - 40559, 40426, 40399, 4818, 4574, 4578, 3771, 3684, 3897, 550, 668, 688, 502, - 270, 422, 775, 270, 664, 16513, 16075, 16333, 17823, 17593, 17758, 43079, 42978, - 42979, 42720, 42642, 42684, 6298, 5940, 6039, 7279, 7281, 7361, 6736, 7121, 6788, - 7754, 7852, 7815, 7240, 7551, 7597, 11931, 11776, 11867, 12169, 12280, 12165, 12169, - 12165, 12044, 19544, 19331, 19550, 18441, 18371, 18533, 33765, 33737, 33956, 41246, 41228, - 41382, 41694, 41540, 41418, 41736, 41418, 41687, 43079, 42979, 43694, 43062, 43038, 43256, - 1461, 1252, 1446, 1912, 1972, 2034, 1349, 1704, 1714, 1176, 1232, 1080, 25487, - 25964, 25649, 27012, 26964, 27064, 28878, 28822, 28741, 27775, 28061, 27811, 3755, 3684, - 3771, 20010, 19736, 19795, 19320, 19100, 18992, 19331, 19401, 19550, 21913, 22071, 21939, - 39018, 38743, 38769, 39154, 39028, 39267, 17671, 17826, 17594, 17826, 17962, 17594, 301, - 704, 305, 6551, 6655, 6657, 42688, 42720, 42684, 42565, 42458, 42464, 40426, 40383, - 40367, 39933, 39683, 39812, 1080, 1185, 976, 1185, 967, 899, 23398, 23389, 23042, - 25619, 25773, 25692, 43044, 43046, 42950, 42808, 42875, 42636, 43121, 43046, 43044, 19736, - 19659, 19705, 19094, 18853, 18932, 23081, 23157, 23179, 14209, 14618, 13971, 13691, 13634, - 13857, 13468, 13237, 13145, 28224, 27979, 28096, 27628, 27479, 27508, 27336, 27290, 27186, - 28258, 28488, 28761, 42108, 42187, 42075, 42045, 42007, 41969, 18932, 18853, 18810, 18533, - 18371, 18299, 43038, 43140, 43158, 43091, 42901, 42960, 12668, 12887, 12828, 12458, 11931, - 12329, 27628, 27508, 27701, 41254, 41199, 41181, 41943, 41911, 41817, 41817, 41911, 41780, - 42185, 42187, 42108, 42341, 42010, 42202, 42604, 42565, 42464, 595, 827, 1225, 696, - 1011, 668, 6563, 6273, 6298, 7361, 7281, 7385, 42485, 42292, 42367, 23179, 23157, - 23302, 43140, 43183, 43158, 28761, 28488, 28725, 41409, 41453, 41629, 6655, 6736, 6788, - 17120, 17252, 17318, 15991, 15798, 15931, 15894, 15798, 15991, 15727, 15828, 15743, 15413, - 15264, 15117, 25692, 25773, 25782, 24935, 24710, 25094, 3913, 3894, 3943, 3958, 3894, - 3913, 7852, 7915, 7815, 26938, 27090, 27048, 26049, 26067, 25836, 41629, 41453, 41711, - 7768, 8058, 8061, 33710, 33737, 33728, 34909, 34907, 34621, 40453, 40265, 40221, 393, - 313, 351, 421, 313, 393, 3487, 3556, 3569, 3452, 3590, 3556, 3487, 3569, - 3521, 18853, 18771, 18810, 33563, 33710, 33728, 33081, 33248, 32984, 33081, 32984, 33030, - 3640, 3735, 3684, 8925, 9194, 9077, 7902, 7768, 8061, 18643, 18771, 18666, 17593, - 17496, 17502, 33491, 33469, 33396, 23625, 23792, 23828, 23699, 23792, 23625, 43046, 43048, - 42954, 42624, 42238, 42429, 43235, 43048, 43046, 5431, 5192, 5139, 5508, 5420, 5431, - 5596, 5529, 5508, 6585, 6273, 6780, 37282, 37382, 37241, 37241, 37382, 37210, 36807, - 36823, 36730, 36189, 35834, 35652, 1714, 1704, 1731, 1515, 1780, 1525, 5619, 5529, - 5596, 29420, 28862, 28854, 37275, 37355, 37254, 37306, 37324, 37355, 37275, 37157, 37306, - 36609, 36723, 36588, 36823, 36979, 36730, 30570, 30711, 30735, 30638, 30711, 30570, 39860, - 40122, 40157, 39614, 39513, 39542, 39444, 39276, 39219, 41957, 41670, 41588, 42510, 41925, - 42203, 41721, 41836, 41578, 4745, 4747, 4777, 4633, 4725, 4518, 35434, 35435, 35252, - 35434, 35252, 35188, 43140, 43116, 43183, 584, 696, 668, 25487, 25649, 25488, 24728, - 24587, 24621, 25094, 24710, 24893, 43249, 42902, 42642, 42787, 42688, 42672, 2013, 1912, - 2034, 1993, 2302, 2529, 3626, 3640, 3684, 39028, 39154, 39005, 39018, 39053, 39074, - 7320, 7361, 7385, 6945, 7009, 7011, 34909, 34621, 34617, 38534, 38341, 38443, 38534, - 38443, 38677, 42312, 42202, 42193, 31865, 31490, 31499, 31399, 31406, 31053, 40841, 40650, - 40436, 40426, 40559, 40383, 40153, 40157, 40278, 40841, 40436, 41012, 41143, 41098, 41158, - 565, 564, 593, 565, 593, 615, 17252, 17120, 17407, 15894, 15690, 15798, 17826, - 18158, 17962, 37672, 37503, 37602, 37672, 37602, 37687, 43224, 42928, 42837, 421, 401, - 313, 19497, 19425, 19549, 1928, 1912, 2013, 40157, 40122, 40170, 39707, 39905, 39538, - 40040, 39905, 40186, 41303, 41143, 41158, 41246, 41158, 41228, 41220, 41311, 41346, 480, - 587, 617, 23792, 23927, 23828, 23699, 23927, 23792, 37416, 37608, 37536, 37282, 37241, - 37041, 7427, 7320, 7385, 7902, 8061, 8170, 28822, 28878, 28854, 27679, 27580, 28061, - 38136, 38007, 37897, 41876, 41736, 41687, 12046, 12169, 12044, 12706, 12953, 13066, 15006, - 15264, 15089, 14849, 14652, 14642, 29045, 28899, 28725, 29796, 29359, 29531, 28899, 29359, - 29375, 29561, 30059, 29745, 28878, 29420, 28854, 313, 401, 304, 3766, 3755, 3894, - 3894, 3755, 3988, 13971, 14618, 14762, 13634, 13538, 13468, 15798, 15690, 15834, 15894, - 16149, 15843, 16333, 16075, 16081, 15587, 15727, 15665, 19353, 19289, 19320, 25773, 25831, - 25836, 25902, 25831, 25773, 1132, 1171, 1293, 1377, 1775, 1704, 976, 1185, 899, - 29809, 30059, 29561, 41346, 41311, 41440, 41818, 41711, 41941, 41180, 41117, 40990, 42294, - 42312, 42193, 42174, 42185, 42108, 42128, 42020, 42007, 42128, 42007, 42131, 5299, 5192, - 5431, 13534, 13538, 13634, 704, 628, 648, 615, 628, 402, 25205, 25219, 25221, - 24340, 24710, 24124, 25420, 25619, 25477, 478, 403, 607, 43172, 42804, 43015, 43048, - 43096, 42954, 43172, 43015, 43326, 14390, 13988, 14159, 14642, 14477, 14390, 26574, 26596, - 26486, 26473, 26596, 26574, 42565, 42653, 42458, 42530, 42485, 42367, 42570, 42485, 42637, - 283, 313, 304, 27377, 27290, 27336, 25384, 25487, 25488, 27198, 27290, 27289, 27290, - 27377, 27289, 42294, 42193, 42187, 3591, 3668, 3640, 3521, 3452, 3487, 3487, 3452, - 3556, 3394, 3290, 3372, 1969, 1928, 2000, 3411, 3451, 3715, 4706, 4812, 4747, - 3225, 3451, 3411, 3025, 3481, 3030, 8618, 8465, 8591, 9099, 9194, 9298, 9099, - 9298, 9330, 25345, 25205, 25221, 25984, 25649, 25964, 2456, 2547, 2134, 3265, 3290, - 3394, 32156, 32437, 31959, 33248, 33491, 33396, 33698, 33710, 33563, 519, 480, 617, - 402, 565, 615, 17120, 17034, 17407, 17112, 17034, 17120, 24870, 24587, 24728, 23478, - 23373, 23302, 4818, 4577, 4574, 478, 14, 403, 617, 683, 472, 154, 477, - 427, 688, 736, 476, 18214, 18158, 18532, 41440, 41311, 41559, 3549, 3591, 3640, - 8320, 8465, 8401, 33698, 33563, 33469, 35423, 35188, 35251, 9330, 9298, 9596, 43183, - 43116, 43208, 43116, 43068, 43208, 41623, 41721, 41578, 42045, 41969, 41911, 41699, 41629, - 41818, 18207, 18214, 18446, 17502, 17496, 17420, 18643, 18666, 18553, 17502, 17420, 17381, - 31569, 31499, 31493, 40194, 40034, 39694, 41534, 41180, 40604, 4198, 4120, 4519, 3549, - 3521, 3591, 7637, 7738, 7651, 7971, 8042, 8247, 7637, 7651, 7551, 7637, 7551, - 7564, 13766, 13304, 13425, 27198, 27012, 27064, 42334, 42311, 42222, 41876, 41789, 41736, - 42429, 42582, 42934, 1453, 1359, 1461, 1143, 1091, 1126, 858, 639, 833, 1252, - 1359, 1323, 12706, 12360, 12280, 28878, 29047, 29420, 27348, 27124, 27164, 4262, 4198, - 4519, 33710, 33956, 33737, 11719, 11488, 11580, 11580, 11488, 11314, 10158, 10812, 10752, - 12828, 12887, 13145, 16333, 16081, 16298, 25345, 25221, 25439, 25136, 24870, 24918, 37737, - 37747, 37831, 41559, 41311, 41540, 42641, 42653, 42565, 43208, 43280, 43308, 27090, 27124, - 27048, 26049, 26342, 26067, 26473, 26342, 26298, 502, 456, 664, 422, 456, 502, - 10812, 11103, 10776, 17381, 17420, 17341, 23548, 23373, 23478, 23993, 24177, 24124, 23072, - 23398, 23042, 22745, 22726, 22661, 9440, 9383, 9516, 11763, 12044, 11914, 32131, 32156, - 31959, 25538, 25619, 25420, 25306, 25419, 25094, 14642, 14975, 14849, 15006, 15117, 15264, - 15820, 15828, 15727, 15870, 15930, 15828, 1114, 1171, 1132, 1114, 1132, 1080, 6655, - 6598, 6736, 6736, 6993, 7121, 6551, 6562, 6655, 6438, 6551, 6266, 9440, 9233, - 9383, 13811, 13692, 13691, 13012, 12828, 13145, 13971, 13692, 13811, 13227, 13304, 13127, - 15073, 15006, 14975, 18643, 18553, 18533, 37914, 37737, 37831, 37914, 37831, 38007, 42185, - 42294, 42187, 42045, 41911, 42081, 43208, 43386, 43280, 1074, 1303, 1145, 42128, 42174, - 42108, 42312, 42341, 42202, 42604, 42641, 42565, 41699, 41721, 41623, 41699, 41623, 41629, - 2890, 3154, 3086, 3452, 3379, 3520, 3265, 3379, 3452, 3521, 3569, 3591, 39252, - 38996, 39171, 39614, 39542, 39586, 39754, 39586, 39683, 41943, 41817, 41836, 1323, 1359, - 1453, 2000, 1928, 2013, 3036, 3307, 3133, 41534, 40604, 41490, 41254, 41363, 41306, - 27048, 26787, 26884, 42334, 42222, 42313, 12065, 12706, 12280, 11763, 11659, 11600, 43153, - 43329, 43078, 43189, 43313, 43153, 43345, 43189, 43126, 43345, 43126, 43310, 43126, 43166, - 43310, 43166, 43327, 43310, 43167, 43327, 43166, 43337, 43327, 43167, 43167, 43118, 43282, - 113, 384, 76, 177, 287, 363, 363, 287, 450, 442, 406, 291, 406, - 288, 291, 345, 288, 406, 19445, 19628, 19652, 19736, 19628, 19659, 19659, 19628, - 19572, 19353, 19357, 19289, 20323, 20432, 20316, 20532, 20494, 20323, 20708, 20494, 20532, - 20605, 20494, 20708, 20605, 20708, 20802, 20708, 20779, 20802, 20779, 20873, 20802, 20923, - 21024, 20873, 21908, 21645, 21745, 21939, 21745, 21846, 43313, 43329, 43153, 3626, 3684, - 3755, 277, 243, 474, 33511, 33491, 33248, 33710, 34027, 33956, 32913, 33030, 32437, - 39808, 39754, 39683, 39933, 39812, 39913, 40157, 40170, 40322, 3638, 3626, 3755, 4198, - 4174, 4120, 4155, 4174, 4198, 20768, 20838, 20509, 21076, 21212, 21230, 20338, 20330, - 20461, 20322, 20330, 20258, 19959, 19835, 19753, 19959, 19753, 19694, 19753, 19708, 19576, - 20503, 20509, 20461, 43329, 43309, 43078, 43282, 43102, 43173, 43162, 43135, 43031, 43162, - 43025, 43146, 243, 299, 440, 4747, 4812, 4777, 4725, 4624, 4518, 43335, 43282, - 43173, 472, 683, 564, 480, 443, 478, 472, 564, 481, 17694, 17758, 17593, - 18580, 18643, 18533, 17303, 17381, 17341, 23993, 24124, 23927, 41180, 41287, 41117, 736, - 622, 476, 696, 595, 1225, 976, 1114, 1080, 16488, 16779, 16940, 15870, 15828, - 15820, 40453, 40221, 40383, 42220, 41588, 41570, 41736, 41694, 41418, 42013, 41943, 41836, - 43193, 43335, 43173, 40650, 40559, 40399, 40587, 40559, 40822, 41294, 41012, 41143, 41303, - 41158, 41246, 41382, 41228, 41346, 40391, 40577, 40336, 40391, 40336, 40333, 23690, 23999, - 24223, 25054, 24870, 25136, 26884, 26787, 26596, 42354, 42341, 42312, 3766, 3894, 3958, - 20928, 21212, 21076, 3133, 3307, 3290, 39997, 39933, 39913, 42918, 42787, 42915, 43185, - 43091, 43207, 43101, 43091, 42960, 42583, 42414, 42485, 21212, 21239, 21275, 26342, 26473, - 26574, 25902, 25836, 25831, 42570, 42583, 42485, 38136, 37897, 38341, 38104, 37914, 38007, - 2134, 2344, 1567, 1704, 1775, 1771, 1515, 1525, 1447, 4554, 4396, 4664, 4449, - 4396, 4554, 14762, 14618, 15219, 16149, 16340, 16755, 15448, 15665, 15413, 19576, 19708, - 19550, 41545, 41382, 41346, 41545, 41346, 41440, 43193, 43256, 43335, 1447, 1525, 1204, - 36926, 36723, 36774, 36926, 36774, 36917, 36926, 36917, 37050, 36818, 37275, 37254, 37631, - 37355, 37324, 4818, 5147, 4577, 5529, 5420, 5508, 5619, 5555, 5529, 7009, 7158, - 7011, 9440, 9197, 9233, 9197, 9109, 9233, 22924, 22734, 23081, 23690, 23813, 23676, - 37503, 37631, 37324, 40415, 40391, 40333, 43135, 43121, 43044, 43162, 43121, 43135, 13534, - 13468, 13538, 28700, 28741, 28822, 29420, 29678, 29561, 28701, 28741, 28700, 345, 272, - 288, 350, 272, 345, 216, 272, 350, 7011, 7158, 7279, 519, 443, 480, - 481, 564, 565, 5555, 5420, 5529, 4798, 5433, 5500, 7852, 7814, 7971, 7240, - 7372, 7121, 26618, 26884, 26596, 3713, 3766, 3958, 3939, 4120, 4174, 39280, 39402, - 39234, 39905, 40040, 39694, 39087, 39018, 39074, 43038, 43158, 43256, 2856, 2890, 3086, - 9197, 8911, 8938, 18299, 18371, 18253, 19448, 19576, 19550, 22542, 22745, 22661, 23398, - 23699, 23625, 40153, 40084, 40157, 40157, 40084, 39860, 37503, 37672, 37631, 4812, 4798, - 5500, 4706, 4633, 4622, 35684, 35774, 35446, 35423, 35434, 35188, 34909, 34617, 34992, - 12904, 13030, 12953, 12953, 13030, 13127, 11600, 11659, 11325, 967, 905, 799, 1171, - 1115, 1293, 13692, 13534, 13634, 15470, 15219, 15690, 16472, 16779, 16488, 15912, 16298, - 16081, 16472, 16488, 16333, 25205, 25168, 25136, 25384, 25345, 25439, 25384, 25439, 25487, - 25832, 25902, 25773, 25333, 25306, 25094, 39276, 39171, 39241, 39754, 39614, 39586, 39837, - 39614, 39754, 39808, 39683, 39933, 42928, 42875, 42808, 42368, 42334, 42313, 43365, 42875, - 42928, 351, 283, 350, 177, 363, 341, 27712, 28061, 27580, 27472, 27491, 27348, - 27472, 27348, 27371, 33241, 33248, 33081, 34992, 34617, 34537, 39280, 39234, 39154, 42174, - 42294, 42185, 42128, 42167, 42174, 42045, 42131, 42007, 42167, 42131, 42164, 9383, 9741, - 9516, 32958, 32913, 32892, 33015, 33182, 33081, 31974, 32131, 31959, 32074, 32131, 31974, - 31569, 31493, 31406, 31399, 31053, 31442, 37738, 37672, 37737, 27164, 27124, 27090, 42531, - 42294, 42174, 42530, 42367, 42338, 4396, 4262, 4519, 4220, 4262, 4202, 7361, 7320, - 7279, 7427, 7592, 7519, 7592, 7647, 7519, 23179, 23302, 23294, 23690, 24223, 23813, - 23548, 23690, 23676, 23501, 23699, 23398, 24177, 24340, 24124, 34357, 33959, 33956, 42787, - 42720, 42688, 43256, 43158, 43412, 8401, 8465, 8618, 8465, 8320, 8170, 9099, 9077, - 9194, 9024, 9077, 9099, 9195, 9099, 9330, 32982, 32913, 32958, 39945, 39808, 39933, - 351, 313, 283, 3626, 3549, 3640, 3237, 3265, 3452, 3379, 3265, 3394, 3036, - 2856, 3086, 3529, 3549, 3626, 8401, 8618, 8476, 22745, 22876, 22919, 23072, 22876, - 23148, 41789, 41694, 41736, 41959, 42013, 41836, 42081, 42131, 42045, 41453, 41442, 41711, - 943, 953, 1126, 435, 481, 402, 879, 953, 884, 27140, 26740, 26813, 27290, - 27198, 27077, 27336, 27479, 27377, 27951, 28056, 27701, 27133, 27164, 27090, 42220, 42142, - 41957, 41773, 41540, 41694, 42438, 42334, 42368, 42378, 42354, 42312, 287, 251, 484, - 2031, 1993, 2529, 2272, 1288, 1262, 2373, 2908, 2340, 5147, 4606, 4577, 20010, - 19795, 20316, 19289, 19193, 19320, 19331, 19094, 19189, 21463, 21902, 21342, 24314, 24340, - 24177, 37914, 37838, 37737, 38441, 38136, 38341, 43158, 43183, 43308, 15073, 15117, 15006, - 16350, 16333, 16298, 15073, 14975, 14898, 42591, 42604, 42464, 42504, 42338, 42341, 11763, - 11948, 12044, 41579, 41559, 41540, 3638, 3529, 3626, 4031, 3939, 4174, 7637, 7754, - 7815, 7591, 7754, 7637, 34646, 33991, 34223, 34646, 34223, 34965, 12280, 12169, 12053, - 13766, 14159, 13988, 28741, 28951, 28878, 28061, 28611, 28184, 2340, 3023, 2346, 31530, - 31399, 31442, 31053, 31412, 31442, 9980, 9824, 9798, 8938, 8911, 8713, 40084, 39997, - 39913, 40069, 39997, 40084, 39707, 39538, 39437, 401, 411, 304, 19628, 19497, 19549, - 23302, 23373, 23294, 7878, 8042, 7971, 43426, 43015, 43120, 43235, 43096, 43048, 17694, - 17593, 17502, 17694, 17598, 17633, 6585, 6902, 6945, 7035, 7011, 7279, 7519, 7647, - 7554, 39219, 39465, 39444, 584, 627, 696, 543, 627, 584, 25238, 25168, 25205, - 27140, 26813, 27012, 25306, 25436, 25420, 27014, 26938, 26884, 26884, 26938, 27048, 25333, - 25436, 25306, 31530, 31569, 31406, 26474, 26596, 26473, 19497, 19483, 19425, 355, 443, - 519, 481, 565, 402, 12053, 12169, 12046, 29359, 28899, 29045, 28761, 28899, 29375, - 29754, 30036, 29796, 28772, 28951, 28741, 34196, 33388, 33137, 22876, 23072, 23042, 23699, - 23993, 23927, 23232, 23072, 23148, 19189, 19094, 18932, 19189, 18932, 19085, 31569, 31865, - 31499, 32982, 33015, 32913, 32982, 33182, 33015, 33491, 33698, 33469, 32437, 32892, 32913, - 41457, 41362, 41382, 41382, 41362, 41246, 41287, 41363, 41254, 41610, 41363, 41287, 41610, - 41287, 41180, 40791, 40541, 40577, 43308, 43183, 43208, 40453, 40383, 40559, 40322, 40170, - 40265, 40040, 40194, 39694, 40391, 40647, 40577, 33528, 33698, 33491, 39294, 39276, 39444, - 39465, 39627, 39444, 39837, 39754, 39808, 39945, 39933, 39948, 39402, 39547, 39437, 40828, - 40637, 40801, 39267, 39280, 39154, 15117, 15448, 15413, 15476, 15448, 15445, 18180, 18299, - 18253, 17806, 17694, 17633, 42709, 42429, 42934, 42591, 42464, 42583, 42949, 42787, 42918, - 42591, 42583, 42589, 43235, 43046, 43121, 1114, 1052, 1171, 799, 905, 827, 13611, - 13534, 13692, 13611, 13692, 13971, 14216, 14159, 13987, 13425, 13304, 13227, 7754, 7814, - 7852, 7778, 7814, 7754, 39252, 38924, 38996, 304, 411, 83, 39948, 39933, 39997, - 43366, 42913, 42988, 7035, 7279, 7320, 6654, 6993, 6736, 6598, 6655, 6562, 274, - 799, 827, 3486, 3521, 3549, 4108, 4155, 4198, 4220, 4198, 4262, 7427, 7332, - 7320, 7554, 7647, 7768, 14898, 14975, 14876, 34856, 34646, 34965, 34408, 34196, 33137, - 415, 622, 540, 627, 595, 696, 415, 540, 456, 27198, 27140, 27012, 27508, - 27951, 27701, 40587, 40453, 40559, 40194, 40415, 40333, 18180, 18253, 18022, 23294, 23373, - 23349, 23373, 23436, 23349, 43172, 43159, 43146, 43330, 43159, 43172, 8320, 8154, 8170, - 8017, 8154, 8178, 25436, 25538, 25420, 25404, 25538, 25436, 42739, 42653, 42641, 196, - 483, 403, 19269, 19193, 19289, 18214, 17962, 18158, 18810, 18771, 18709, 35684, 35446, - 35435, 36823, 37000, 36979, 36979, 37103, 37041, 35684, 35435, 35434, 37965, 37838, 37914, - 38104, 38007, 38136, 355, 519, 329, 323, 422, 192, 24664, 24893, 24710, 23940, - 23993, 23699, 43096, 43094, 42954, 42934, 42582, 42983, 43204, 43094, 43096, 40153, 40069, - 40084, 40278, 40069, 40153, 953, 879, 993, 1006, 1126, 1091, 799, 899, 967, - 1359, 1252, 1461, 1873, 1912, 1928, 12799, 12904, 12953, 12799, 12953, 12706, 28611, - 28701, 28700, 31442, 31412, 31480, 28772, 28701, 28775, 28772, 28930, 28977, 27712, 27580, - 27472, 27371, 27348, 27164, 41773, 41789, 41890, 42673, 42438, 42297, 42489, 42504, 42341, - 42489, 42341, 42354, 42378, 42312, 42294, 6993, 7168, 7121, 7146, 7168, 6988, 19193, - 19100, 19320, 17594, 17318, 17252, 15608, 15630, 15843, 18446, 18214, 18532, 18709, 18771, - 18643, 18022, 17986, 17758, 21913, 22259, 22071, 23975, 23870, 23813, 40453, 40322, 40265, - 4633, 4706, 4747, 4622, 4633, 4518, 6583, 6598, 6562, 34890, 34907, 35123, 35682, - 35684, 35434, 8017, 7902, 8170, 8713, 8911, 8729, 7814, 7878, 7971, 7778, 7878, - 7814, 10438, 10804, 10837, 12065, 12053, 11984, 11948, 12053, 12046, 10911, 10804, 10836, - 10232, 10438, 10238, 9980, 10175, 9824, 3230, 3265, 3237, 2595, 3023, 3134, 3755, - 3766, 3638, 4155, 4031, 4174, 4021, 4031, 4155, 7300, 7332, 7427, 7679, 7554, - 7768, 7493, 7564, 7551, 34646, 34631, 34408, 34824, 34631, 34646, 15894, 15630, 15690, - 16898, 16755, 17034, 25832, 25773, 25619, 26049, 26298, 26342, 27307, 27371, 27164, 41255, - 40841, 41012, 40318, 40157, 40322, 42604, 42739, 42641, 42589, 42583, 42570, 42582, 42728, - 42983, 42533, 42466, 42438, 550, 569, 668, 398, 569, 550, 1993, 1969, 2000, - 1853, 1969, 1993, 2031, 2529, 2284, 17694, 17502, 17598, 17806, 18022, 17758, 16350, - 16472, 16333, 16350, 16298, 16307, 25238, 25205, 25345, 25238, 25345, 25384, 3127, 3133, - 3290, 33182, 33241, 33081, 32437, 32156, 32316, 19100, 18987, 18992, 43280, 43386, 43398, - 36723, 36680, 36588, 36926, 36828, 36723, 37022, 36828, 36926, 37050, 36917, 37163, 36917, - 37254, 37163, 35981, 35974, 36309, 36311, 35981, 36309, 37382, 37474, 37416, 422, 436, - 456, 323, 436, 422, 2373, 2200, 2284, 2595, 3134, 2890, 10776, 11103, 11024, - 11488, 11719, 11566, 32284, 32156, 32131, 31569, 31678, 31865, 31399, 31530, 31406, 29678, - 29420, 29686, 36890, 36680, 36723, 35974, 35834, 36189, 37163, 37422, 37192, 37000, 37103, - 36979, 1145, 1366, 1357, 911, 1052, 1114, 1171, 1052, 975, 41303, 41294, 41143, - 41303, 41246, 41362, 41545, 41440, 41559, 42131, 42167, 42128, 42081, 41911, 41943, 42081, - 41943, 42145, 996, 1006, 1091, 3713, 3958, 3780, 14876, 14975, 14642, 15107, 15448, - 15117, 16307, 16298, 16186, 27951, 27979, 28056, 27305, 27140, 27198, 37163, 37254, 37437, - 39513, 39627, 39465, 39294, 39171, 39276, 39294, 39252, 39171, 39156, 39267, 39028, 39505, - 39547, 39402, 39087, 39028, 39018, 43159, 43162, 43146, 43332, 43162, 43159, 11812, 11948, - 11763, 32812, 32344, 32588, 31674, 31764, 31188, 1154, 1357, 1446, 7146, 7240, 7168, - 7168, 7240, 7121, 13227, 13127, 13030, 14802, 14876, 14784, 13227, 13030, 12973, 38534, - 38441, 38341, 38660, 38441, 38534, 38660, 38534, 38896, 42164, 42081, 42531, 5420, 5299, - 5431, 3947, 3966, 4031, 5555, 5299, 5420, 5406, 5299, 5555, 5406, 5619, 5817, - 6273, 5940, 6298, 6182, 5940, 6273, 37103, 37282, 37041, 2919, 3025, 3030, 3451, - 3333, 3991, 2919, 3030, 2927, 9454, 9330, 9596, 8178, 8154, 8320, 8154, 8017, - 8170, 43185, 42901, 43091, 43412, 43280, 43398, 2134, 1567, 1882, 9966, 9980, 9893, - 9980, 9798, 9893, 27465, 27377, 27479, 27014, 27090, 26938, 31530, 31678, 31569, 42777, - 42604, 42591, 42531, 42378, 42294, 20779, 20923, 20873, 20494, 20432, 20323, 19445, 19483, - 19497, 19445, 19357, 19483, 19483, 19357, 19353, 19193, 19155, 19100, 18980, 18899, 18987, - 4031, 3966, 3939, 4484, 4554, 4578, 20330, 20503, 20461, 20928, 21221, 21212, 21212, - 21221, 21239, 21239, 21463, 21275, 20466, 20503, 20330, 20322, 20258, 20172, 20258, 19959, - 20172, 20221, 20226, 20172, 21037, 20966, 20873, 20873, 20966, 20912, 20503, 20768, 20509, - 23232, 23398, 23072, 34631, 34552, 34408, 34610, 34552, 34631, 299, 177, 341, 287, - 220, 251, 251, 221, 427, 243, 187, 299, 277, 187, 243, 113, 187, - 277, 142, 442, 297, 186, 297, 291, 186, 291, 117, 291, 288, 198, - 288, 272, 198, 20605, 20432, 20494, 21908, 21745, 21939, 36189, 35652, 35774, 37282, - 37474, 37382, 43400, 43345, 43310, 43400, 43389, 43345, 43345, 43389, 43313, 43313, 43496, - 43329, 43329, 43496, 43309, 43309, 43366, 42988, 43400, 43310, 43327, 43400, 43327, 43440, - 43327, 43337, 43394, 43337, 43453, 43394, 43282, 43453, 43337, 43335, 43409, 43282, 4493, - 4574, 4577, 37738, 37631, 37672, 38171, 38104, 38136, 39018, 38769, 39053, 43335, 43256, - 43409, 18709, 18643, 18580, 17806, 17758, 17694, 23232, 23501, 23398, 23993, 24191, 24177, - 22876, 23032, 23148, 18533, 18299, 18290, 19753, 19576, 19583, 23940, 24191, 23993, 25885, - 26049, 25902, 569, 574, 584, 799, 796, 899, 451, 574, 380, 402, 353, - 319, 849, 884, 953, 17502, 17381, 17598, 15587, 15665, 15448, 19576, 19448, 19583, - 23813, 23870, 23747, 25488, 25238, 25384, 27305, 27198, 27289, 11588, 11600, 11460, 19550, - 19401, 19448, 36386, 36189, 36282, 15476, 15587, 15448, 26298, 26474, 26473, 25902, 26049, - 25836, 25832, 25619, 25538, 42777, 42739, 42604, 42589, 42570, 42599, 1515, 1349, 1714, - 2344, 2026, 1567, 1204, 1525, 1441, 4202, 4262, 4396, 7300, 7427, 7519, 7011, - 6585, 6945, 7517, 7519, 7554, 21225, 21221, 21023, 26618, 26474, 26544, 42530, 42338, - 42504, 39449, 39280, 39293, 39449, 39402, 39280, 40724, 40511, 40415, 3133, 2985, 3036, - 3265, 3251, 3290, 3230, 3251, 3265, 33144, 33241, 33182, 35123, 34907, 34909, 33144, - 33182, 32982, 39563, 39707, 39437, 12904, 12873, 12973, 12873, 12697, 12818, 28701, 28772, - 28741, 29047, 28772, 28977, 43409, 43892, 43891, 552, 595, 627, 19448, 19315, 19435, - 18290, 18299, 18180, 37738, 37737, 37838, 4574, 4484, 4578, 4493, 4484, 4574, 35684, - 35682, 35774, 34357, 33956, 34236, 136, 177, 299, 39837, 39808, 39922, 39252, 39205, - 38924, 43474, 43366, 43309, 43332, 43121, 43162, 32316, 32156, 32284, 43101, 42960, 42902, - 42642, 43182, 43249, 15107, 15117, 15073, 14898, 14876, 14952, 42651, 42530, 42685, 41579, - 41545, 41559, 41687, 41860, 41876, 198, 272, 208, 21370, 21463, 21239, 436, 415, - 456, 323, 415, 436, 17342, 17318, 17448, 17962, 18214, 18207, 24191, 24314, 24177, - 24151, 24314, 24191, 42949, 42720, 42787, 34027, 33710, 33698, 27628, 27465, 27479, 27377, - 27305, 27289, 28056, 28224, 28258, 13534, 13237, 13468, 11566, 11719, 11867, 13673, 13611, - 13971, 42167, 42531, 42174, 42378, 42489, 42354, 42081, 42164, 42131, 41818, 41721, 41699, - 451, 543, 574, 574, 543, 584, 16940, 16779, 17052, 15912, 16081, 15870, 25152, - 25333, 25094, 249, 476, 622, 1006, 943, 1126, 933, 943, 1006, 996, 1091, - 1074, 2200, 2031, 2284, 1969, 1873, 1928, 7902, 7817, 7768, 8618, 8696, 8476, - 24664, 24710, 24340, 27639, 27465, 27628, 39087, 39156, 39028, 39128, 39156, 39087, 3780, - 3958, 3939, 3054, 3127, 3251, 4220, 4108, 4198, 4073, 4108, 4167, 34824, 34856, - 34935, 2149, 2373, 2340, 2149, 2200, 2373, 177, 202, 287, 2653, 2919, 2927, - 3025, 3183, 3481, 4484, 4449, 4554, 4404, 4449, 4484, 42466, 42311, 42334, 41818, - 41629, 41711, 37777, 37738, 37837, 9626, 9558, 9596, 8476, 8696, 8487, 24587, 24870, - 24881, 22259, 22477, 22071, 43208, 43068, 43386, 43101, 43207, 43091, 32284, 32131, 32074, - 31530, 31480, 31678, 30638, 30570, 30059, 15630, 15470, 15690, 15608, 15470, 15630, 15748, - 15820, 15727, 15107, 15073, 15035, 41759, 41579, 41540, 208, 272, 216, 350, 283, - 216, 202, 220, 287, 1853, 1873, 1969, 1252, 1154, 1446, 872, 849, 953, - 628, 353, 402, 42438, 42466, 42334, 42673, 42252, 42624, 42685, 42850, 42744, 15035, - 15073, 14898, 42637, 42599, 42570, 42589, 42777, 42591, 42787, 42672, 42915, 42589, 42599, - 42767, 15748, 15727, 15635, 6266, 6481, 5501, 6598, 6654, 6736, 6481, 5676, 5501, - 24314, 24343, 24340, 24444, 24343, 24314, 220, 221, 251, 19401, 19315, 19448, 43412, - 43158, 43308, 43412, 43308, 43280, 41457, 41303, 41362, 41294, 41319, 41012, 41457, 41382, - 41524, 3251, 3127, 3290, 3452, 3521, 3237, 2773, 3183, 3025, 8188, 8247, 8042, - 9550, 9741, 9383, 40278, 40157, 40318, 39948, 39997, 40152, 39922, 39808, 39945, 8696, - 9077, 8966, 39627, 39513, 39614, 39294, 39325, 39252, 39547, 39563, 39437, 39293, 39280, - 39267, 7708, 7817, 7749, 7912, 7817, 7902, 7591, 7637, 7564, 7591, 7778, 7754, - 7878, 7885, 8042, 7493, 7551, 7240, 34552, 34290, 34408, 33388, 33130, 32570, 34610, - 34290, 34552, 4449, 4331, 4396, 4283, 4331, 4317, 216, 283, 80, 4108, 4021, - 4155, 4073, 4021, 4108, 7495, 7517, 7554, 7332, 7035, 7320, 7178, 7493, 7240, - 22734, 22477, 22259, 9558, 9454, 9596, 16779, 16878, 17052, 18100, 18290, 18180, 19085, - 18932, 18977, 22734, 22924, 22477, 25054, 25136, 25106, 40509, 40322, 40453, 40559, 40650, - 40822, 40618, 40587, 40700, 43242, 43235, 43121, 43094, 43149, 42837, 43326, 43426, 43347, - 43326, 43015, 43426, 476, 482, 550, 398, 482, 335, 25106, 25136, 25168, 25106, - 25168, 25262, 25984, 25772, 25649, 15246, 14762, 15219, 6438, 6583, 6562, 25333, 25404, - 25436, 27133, 27014, 27069, 25289, 25404, 25333, 25152, 25094, 24893, 11326, 11488, 11352, - 10158, 9626, 10279, 9558, 9549, 9454, 2216, 1972, 1288, 892, 996, 1074, 40132, - 39997, 40069, 8135, 8178, 8320, 7900, 8188, 8042, 80, 283, 304, 18932, 18810, - 18977, 23179, 23294, 23349, 481, 435, 472, 443, 14, 478, 993, 879, 752, - 1116, 1074, 1145, 943, 872, 953, 24343, 24483, 24340, 24444, 24483, 24343, 40587, - 40545, 40453, 40415, 40511, 40391, 41941, 41959, 41818, 40647, 40511, 40637, 40511, 40724, - 40637, 18693, 18446, 18532, 18881, 18729, 18987, 43326, 43330, 43172, 43347, 43330, 43326, - 812, 933, 1006, 4706, 4607, 4812, 4518, 4624, 4272, 6583, 6654, 6598, 6988, - 7168, 6993, 19445, 19497, 19628, 23373, 23548, 23436, 34992, 35123, 34909, 35423, 35682, - 35434, 35787, 35682, 35724, 16186, 16397, 16307, 16779, 16472, 16878, 15635, 15727, 15587, - 15635, 15587, 15612, 18000, 18180, 18022, 16472, 16350, 16397, 34935, 34856, 35112, 36828, - 36890, 36723, 37022, 36890, 36828, 37022, 36926, 37050, 37022, 37050, 37192, 37437, 37355, - 37664, 37588, 37608, 37474, 37103, 37352, 37282, 37000, 37014, 37103, 36691, 36955, 36807, - 36850, 36955, 36691, 36850, 36691, 36804, 36850, 36976, 36969, 36955, 37014, 37000, 39053, - 38769, 38668, 13335, 13237, 13534, 13493, 13534, 13611, 13719, 14159, 13766, 14952, 15035, - 14898, 12973, 13030, 12904, 12904, 12799, 12873, 15107, 15250, 15448, 14952, 14876, 14802, - 4021, 3947, 4031, 3984, 3947, 4021, 7778, 7885, 7878, 7493, 7591, 7564, 7473, - 7591, 7493, 828, 872, 943, 752, 879, 739, 3869, 3939, 3966, 7855, 7885, - 7778, 27362, 27305, 27377, 27362, 27377, 27465, 34290, 34196, 34408, 34386, 34196, 34290, - 39347, 39293, 39267, 37608, 37416, 37474, 19357, 19269, 19289, 23747, 23676, 23813, 25262, - 25168, 25238, 41662, 41382, 41545, 41789, 41773, 41694, 41876, 41860, 42142, 9549, 9626, - 9504, 8966, 9077, 9024, 3127, 2985, 3133, 3486, 3549, 3529, 3183, 3225, 3411, - 3333, 3225, 3258, 9362, 9383, 9253, 8538, 8713, 8729, 8938, 8713, 8767, 18000, - 18022, 17992, 3225, 3333, 3451, 9099, 9195, 9024, 8401, 8293, 8320, 33511, 33528, - 33491, 35201, 35251, 35123, 33511, 33248, 33241, 33511, 33241, 33539, 39449, 39505, 39402, - 39575, 39505, 39589, 543, 552, 627, 116, 796, 799, 899, 796, 976, 451, - 552, 543, 25984, 26740, 25772, 42830, 42653, 42739, 43468, 43305, 43207, 329, 519, - 472, 879, 884, 739, 1181, 1233, 1252, 1181, 1252, 1323, 9024, 9195, 9173, - 17318, 17112, 17120, 17217, 17112, 17318, 16397, 16350, 16307, 24483, 24664, 24340, 24564, - 24664, 24483, 39948, 39922, 39945, 39701, 39627, 39614, 40120, 39922, 39948, 40132, 40069, - 40278, 41959, 41836, 41721, 42530, 42504, 42685, 41959, 41721, 41818, 29047, 28878, 28951, - 11024, 11103, 11314, 3638, 3486, 3529, 17992, 18022, 17806, 17303, 17598, 17381, 23737, - 23940, 23699, 23527, 23699, 23501, 26993, 27014, 26884, 28701, 28611, 28775, 28772, 29047, - 28951, 27133, 27069, 27179, 39344, 39325, 39469, 39514, 39325, 39294, 38441, 38171, 38136, - 38060, 37965, 37914, 39347, 39267, 39156, 43235, 43204, 43096, 42825, 42673, 42624, 43242, - 43204, 43235, 31442, 31480, 31530, 31412, 31053, 31192, 18977, 18810, 18891, 22876, 22745, - 22591, 3984, 3869, 3947, 5147, 5139, 4728, 4487, 4518, 4272, 38687, 38171, 38441, - 37738, 37704, 37631, 31974, 31865, 32074, 40478, 40318, 40322, 3713, 3638, 3766, 3947, - 3869, 3966, 4108, 4220, 4167, 7817, 7679, 7768, 7517, 7300, 7519, 7708, 7679, - 7817, 7902, 8017, 7970, 37352, 37474, 37282, 42767, 42777, 42589, 42637, 42485, 42530, - 42637, 42530, 42651, 15912, 15870, 15820, 15612, 15587, 15476, 42899, 42830, 42739, 25191, - 25152, 24893, 26596, 26474, 26618, 9980, 9966, 10238, 11118, 11600, 11325, 9109, 9197, - 9051, 1707, 1972, 1912, 3192, 3638, 3713, 27685, 27472, 27371, 41674, 41545, 41579, - 42142, 41860, 41957, 41442, 41306, 41711, 18891, 18810, 18709, 43068, 43483, 43386, 15035, - 14952, 14802, 15035, 15250, 15107, 37777, 37704, 37738, 42867, 42624, 42709, 42510, 42203, - 42311, 42504, 42489, 42685, 329, 472, 435, 270, 775, 477, 335, 482, 476, - 380, 574, 569, 17112, 16951, 17034, 17078, 16951, 17112, 43204, 43149, 43094, 43295, - 43149, 43204, 11566, 11867, 11776, 11488, 11326, 11314, 41303, 41319, 41294, 40618, 40509, - 40545, 40545, 40509, 40453, 41759, 41540, 41773, 42983, 42728, 43108, 42915, 42672, 42653, - 42949, 43182, 42720, 43068, 43079, 43483, 23436, 23548, 23557, 23548, 23676, 23557, 43330, - 43332, 43159, 43408, 43332, 43330, 25388, 25238, 25488, 27511, 27362, 27465, 27639, 27628, - 27701, 40511, 40647, 40391, 40194, 40040, 40186, 34044, 34027, 33698, 33144, 32982, 32958, - 39824, 39614, 39837, 39824, 39837, 40018, 39505, 39563, 39547, 39575, 39563, 39505, 828, - 943, 933, 786, 849, 872, 1233, 1154, 1252, 930, 1154, 1233, 6583, 6461, - 6654, 6484, 6988, 6993, 6438, 6461, 6583, 5343, 5676, 5433, 4607, 4706, 4622, - 18980, 18987, 19100, 16990, 16898, 16951, 22924, 23081, 23179, 37837, 37738, 37838, 40018, - 39837, 39922, 42979, 43185, 43305, 8352, 8293, 8401, 8352, 8401, 8476, 12458, 12124, - 11931, 11600, 11588, 11763, 11575, 11588, 11460, 187, 136, 299, 177, 10, 202, - 202, 48, 220, 94, 427, 221, 142, 455, 442, 142, 297, 186, 142, - 186, 111, 186, 107, 111, 516, 827, 595, 975, 1115, 1171, 3869, 3780, - 3939, 3499, 3780, 3869, 7576, 7495, 7554, 7970, 8017, 8178, 27014, 27133, 27090, - 25832, 25538, 25517, 42667, 42533, 42438, 3054, 2985, 3127, 3054, 3251, 3230, 3036, - 2985, 2892, 3230, 3002, 3054, 9173, 9330, 9454, 8581, 8487, 8696, 19652, 19628, - 19736, 19357, 19445, 19269, 19269, 19155, 19193, 20605, 20504, 20432, 20652, 20504, 20605, - 20652, 20605, 20802, 20912, 20802, 20873, 21024, 21037, 20873, 21645, 21908, 21974, 21908, - 22046, 21974, 43464, 43496, 43313, 43366, 43458, 42913, 43464, 43313, 43389, 43464, 43389, - 43440, 43389, 43400, 43440, 43327, 43549, 43440, 43394, 43549, 43327, 43282, 43484, 43453, - 20326, 20330, 20322, 20326, 20466, 20330, 20503, 20736, 20768, 21023, 21221, 20928, 21221, - 21370, 21239, 21463, 21621, 21902, 20326, 20322, 20226, 20322, 20172, 20226, 19959, 20221, - 20172, 20177, 20221, 20046, 21974, 22046, 21976, 41892, 41759, 41773, 41890, 41789, 41876, - 65, 270, 477, 154, 427, 94, 15912, 15820, 15768, 17806, 17633, 17952, 18506, - 18580, 18533, 17992, 17806, 17952, 17303, 17341, 17277, 23008, 22924, 23179, 23557, 23676, - 23747, 25152, 25289, 25333, 25191, 25289, 25152, 24691, 24893, 24664, 37965, 37837, 37838, - 40354, 40132, 40278, 40618, 40545, 40587, 19583, 19694, 19753, 23940, 24151, 24191, 24232, - 24151, 24327, 43496, 43493, 43309, 43282, 43409, 43484, 18948, 18881, 18899, 18899, 18881, - 18987, 43484, 43409, 43507, 43305, 43185, 43207, 77, 136, 187, 4283, 4396, 4331, - 15470, 15246, 15219, 13488, 13673, 14054, 15843, 15630, 15894, 19583, 19568, 19694, 34856, - 34824, 34646, 36593, 36269, 36680, 35123, 35251, 35188, 36691, 36309, 36572, 34992, 34537, - 34357, 1162, 1181, 1323, 1162, 1323, 1262, 16951, 16898, 17034, 17962, 18207, 18282, - 16413, 16878, 16472, 15238, 15250, 15035, 15768, 15820, 15748, 19583, 19556, 19568, 33671, - 33698, 33528, 20867, 20928, 20768, 43493, 43474, 43309, 12458, 12668, 12124, 29678, 29809, - 29561, 29686, 29809, 29678, 15768, 15748, 15687, 42918, 43028, 42949, 42830, 42915, 42653, - 42908, 42915, 42830, 42908, 42830, 43045, 186, 117, 107, 135, 117, 291, 2892, - 2856, 3036, 40152, 40132, 40235, 786, 884, 849, 786, 872, 828, 42759, 42767, - 42599, 42881, 42850, 42887, 42145, 41943, 42013, 198, 135, 291, 2031, 1919, 1993, - 1873, 1730, 1912, 2200, 1919, 2031, 1496, 1919, 1665, 21225, 21370, 21221, 32998, - 33144, 32958, 32074, 31865, 31890, 40509, 40478, 40322, 43474, 43470, 43366, 43409, 43891, - 43507, 2026, 1951, 1567, 2456, 2425, 2923, 2690, 3225, 3183, 17636, 17962, 17995, - 18506, 18533, 18290, 18100, 17952, 18134, 22822, 22924, 23008, 24881, 24870, 25054, 23232, - 23527, 23501, 23345, 23527, 23232, 43468, 43207, 43101, 12124, 12668, 12828, 13493, 13673, - 13488, 28717, 28056, 28258, 28761, 28725, 28899, 1919, 1853, 1993, 198, 153, 135, - 319, 329, 435, 198, 208, 153, 319, 435, 402, 4317, 4331, 4449, 7343, - 7473, 7493, 7713, 7855, 7778, 6986, 6988, 6484, 17448, 17318, 17594, 17277, 17341, - 17052, 21370, 21461, 21463, 43149, 43224, 42837, 43257, 43224, 43149, 43470, 43458, 43366, - 41470, 41303, 41457, 42094, 41890, 41876, 42067, 42145, 42013, 41711, 41306, 41610, 1154, - 1116, 1145, 938, 1116, 930, 911, 1114, 976, 1447, 1349, 1515, 13479, 13335, - 13534, 4487, 4607, 4622, 4615, 4607, 4466, 38060, 37914, 38104, 38060, 38104, 38171, - 39589, 39505, 39449, 39074, 39128, 39087, 39186, 39053, 38668, 4073, 3984, 4021, 3521, - 3486, 3237, 4009, 3984, 4073, 7576, 7554, 7679, 7576, 7679, 7692, 7178, 7240, - 7146, 8538, 8729, 8188, 18881, 18693, 18729, 18713, 18693, 18881, 208, 216, 153, - 552, 491, 595, 398, 550, 482, 476, 249, 335, 1752, 1730, 1873, 33526, - 33671, 33528, 33526, 33528, 33511, 41470, 41319, 41303, 40509, 40492, 40478, 41737, 41579, - 41759, 43108, 42728, 42875, 42724, 42667, 42791, 42673, 42667, 42438, 13012, 13145, 13237, - 25146, 24881, 25054, 25146, 25054, 25106, 25262, 25238, 25388, 41949, 41737, 41759, 41610, - 41306, 41363, 33795, 33130, 33388, 29796, 30036, 30355, 34079, 33388, 34196, 32892, 32437, - 32778, 196, 403, 51, 43565, 43412, 43398, 15608, 15511, 15470, 15559, 15511, 15608, - 828, 933, 812, 13719, 13766, 13425, 15333, 15448, 15250, 12799, 12697, 12873, 23527, - 23724, 23699, 24151, 24444, 24314, 23708, 23724, 23527, 27133, 27179, 27164, 26474, 26298, - 26433, 37413, 37352, 37103, 36955, 37033, 37014, 36309, 36386, 36572, 36890, 36738, 36680, - 37192, 37050, 37163, 37254, 37355, 37437, 37192, 37212, 37022, 37704, 37664, 37631, 36969, - 37033, 36955, 42067, 42013, 41959, 41524, 41470, 41457, 8293, 8135, 8320, 8093, 8135, - 8271, 36852, 36738, 36890, 37884, 37777, 37837, 39325, 39344, 39252, 39514, 39294, 39444, - 39630, 39444, 39627, 39630, 39627, 39701, 42759, 42599, 42637, 42759, 42637, 42751, 4808, - 5139, 5192, 4404, 4317, 4449, 4423, 4577, 4517, 5406, 5317, 5337, 37965, 37884, - 37837, 38113, 38060, 38169, 4798, 5343, 5433, 19583, 19448, 19556, 19448, 19435, 19556, - 227, 443, 355, 9051, 9197, 8938, 8767, 8713, 8538, 16149, 15894, 16061, 16782, - 16755, 16898, 15912, 16186, 16298, 16984, 17052, 16878, 16984, 17277, 17052, 15687, 15748, - 15635, 18506, 18290, 18420, 23179, 23221, 23008, 21976, 22046, 22071, 32778, 32437, 32316, - 4283, 4202, 4396, 4317, 4202, 4283, 6988, 7178, 7146, 6986, 7178, 6988, 17342, - 17217, 17318, 17236, 17217, 17342, 16984, 16878, 16844, 18242, 18100, 18134, 18420, 18290, - 18331, 24232, 24444, 24151, 37201, 37103, 37014, 39258, 39128, 39186, 80, 153, 216, - 19189, 19315, 19401, 1882, 2425, 2456, 40822, 40650, 40841, 40354, 40278, 40318, 40647, - 40651, 40577, 40186, 39905, 39707, 7418, 7300, 7517, 7692, 7679, 7708, 34822, 34610, - 34631, 34822, 34631, 34824, 42094, 41892, 41890, 42867, 42709, 42934, 42881, 42863, 42850, - 23221, 23349, 23436, 23751, 23747, 23870, 23724, 23737, 23699, 23708, 23737, 23724, 39053, - 39128, 39074, 39563, 39753, 39707, 39156, 39128, 39258, 43397, 43242, 43121, 43365, 43108, - 42875, 43397, 43121, 43332, 19189, 19161, 19315, 18180, 18000, 18100, 19085, 19161, 19189, - 21976, 22071, 22111, 43426, 43120, 43265, 16250, 16208, 16218, 2856, 2763, 2890, 2638, - 2763, 2856, 3486, 3201, 3237, 487, 911, 976, 908, 911, 861, 1204, 1349, - 1447, 908, 975, 1052, 8581, 8696, 8966, 7749, 7692, 7708, 8825, 8767, 8684, - 13335, 13235, 13237, 13673, 13493, 13611, 13479, 13493, 13488, 20286, 20316, 20432, 19085, - 18977, 19161, 22111, 22071, 22190, 34044, 34126, 34027, 34645, 34992, 34357, 33662, 33526, - 33539, 33526, 33511, 33539, 39701, 39614, 39824, 40152, 39997, 40132, 39589, 39449, 39605, - 4202, 4167, 4220, 3486, 3178, 3201, 4009, 4167, 4202, 11612, 11604, 11776, 11776, - 11604, 11566, 11566, 11352, 11488, 11024, 10752, 10776, 9549, 9558, 9626, 11944, 11776, - 11931, 36309, 36189, 36386, 34126, 33956, 34027, 39091, 38677, 38924, 39091, 38924, 39205, - 41674, 41579, 41737, 41674, 41662, 41545, 329, 271, 355, 353, 156, 138, 15511, - 15411, 15470, 15496, 15411, 15511, 15333, 15445, 15448, 15986, 16186, 15912, 15333, 15250, - 15238, 18100, 18000, 17952, 19161, 18891, 19291, 43347, 43408, 43330, 43428, 43408, 43347, - 13178, 13235, 13335, 32892, 32998, 32958, 33067, 32998, 32892, 25517, 25538, 25404, 25885, - 25832, 25893, 42915, 43028, 42918, 42899, 42739, 42777, 42794, 42777, 42767, 22003, 22111, - 22190, 26433, 26298, 26049, 41890, 41892, 41773, 42311, 42466, 42510, 42751, 42637, 42651, - 27179, 27307, 27164, 29047, 29150, 29420, 27253, 27307, 27179, 7418, 7517, 7495, 7970, - 8178, 8093, 380, 398, 286, 413, 491, 552, 42983, 42969, 42934, 43365, 42928, - 43224, 18709, 18580, 18560, 41939, 41674, 41737, 14216, 14390, 14159, 12065, 12280, 12053, - 42510, 42466, 42752, 8093, 8178, 8135, 9024, 9008, 8966, 9417, 9173, 9454, 9549, - 9504, 9441, 32706, 32778, 32316, 34044, 33698, 33671, 40354, 40318, 40582, 1853, 1752, - 1873, 1730, 1707, 1912, 1181, 1162, 1233, 1690, 1752, 1853, 1690, 1496, 1502, - 2346, 2149, 2340, 2763, 2595, 2890, 10752, 10812, 10776, 22542, 22400, 22171, 32284, - 32368, 32316, 32400, 32368, 32284, 31865, 31678, 31890, 7418, 7495, 7576, 35112, 34965, - 35646, 34610, 34546, 34290, 244, 271, 329, 353, 20, 156, 17217, 17078, 17112, - 15843, 15559, 15608, 17162, 17078, 17217, 17448, 17594, 17668, 24444, 24564, 24483, 24451, - 24564, 24444, 24691, 24564, 24642, 19445, 19155, 19269, 18693, 18459, 18446, 18560, 18580, - 18506, 1690, 1707, 1730, 40948, 40822, 40979, 40788, 40492, 40509, 40822, 40841, 41087, - 41518, 41319, 41470, 41524, 41382, 41624, 43242, 43295, 43204, 43378, 43295, 43446, 39648, - 39514, 39444, 39682, 39701, 39877, 39575, 39753, 39563, 39724, 39753, 39575, 28775, 28611, - 28449, 31626, 31678, 31480, 1204, 1441, 1058, 12501, 12124, 12828, 11812, 12053, 11948, - 11575, 11763, 11588, 15612, 15687, 15635, 15238, 15035, 14809, 43522, 43426, 43265, 43378, - 43339, 43295, 3499, 3869, 3984, 2763, 2638, 2595, 8767, 8825, 8938, 9798, 9824, - 9741, 7900, 8042, 7885, 15612, 15476, 15533, 16413, 16472, 16397, 25832, 25885, 25902, - 25251, 25404, 25289, 975, 1015, 1115, 911, 908, 1052, 861, 911, 487, 2595, - 2346, 3023, 11612, 11352, 11604, 11604, 11352, 11566, 39648, 39444, 39630, 40822, 40700, - 40587, 40637, 40651, 40647, 40791, 40651, 40828, 41624, 41382, 41662, 398, 380, 569, - 395, 380, 96, 9441, 9454, 9549, 9441, 9417, 9454, 25175, 25191, 25145, 40492, - 40318, 40478, 40152, 40120, 39948, 25649, 25772, 25555, 27695, 27639, 27701, 27511, 27639, - 27695, 27559, 27685, 27371, 27712, 27685, 27626, 27069, 27014, 26993, 42649, 42466, 42533, - 4167, 4009, 4073, 4404, 4484, 4493, 11905, 11944, 12124, 13493, 13479, 13534, 13673, - 13971, 14054, 7579, 7418, 7576, 7300, 7035, 7332, 7579, 7576, 7692, 34935, 34822, - 34824, 34958, 34822, 34935, 42802, 42794, 42767, 42744, 42751, 42651, 42744, 42651, 42685, - 48, 221, 220, 622, 415, 249, 3054, 2892, 2985, 2595, 1725, 2346, 8825, - 9051, 8938, 10911, 11213, 10804, 19155, 18980, 19100, 40287, 40120, 40152, 413, 552, - 451, 17992, 17952, 18000, 16250, 16397, 16186, 24564, 24691, 24664, 24151, 23940, 24084, - 43318, 42969, 42983, 42667, 42649, 42533, 43230, 42983, 43108, 43137, 43028, 42915, 43037, - 42915, 42908, 43295, 43339, 43149, 43404, 43332, 43408, 812, 1006, 996, 786, 739, - 884, 752, 639, 858, 812, 996, 826, 4607, 4615, 4812, 4487, 4622, 4518, - 6266, 6461, 6438, 6439, 6461, 6426, 7547, 7579, 7692, 8271, 8135, 8293, 7970, - 8093, 7958, 8293, 8352, 8271, 34110, 34044, 34279, 34126, 34236, 33956, 34126, 34044, - 34110, 33671, 33986, 34044, 39258, 39347, 39156, 39128, 39053, 39186, 42001, 41949, 42093, - 41524, 41624, 41745, 41826, 41624, 41662, 42510, 42220, 41570, 18524, 18560, 18506, 18290, - 18100, 18242, 43428, 43404, 43408, 10804, 10438, 10348, 32923, 32892, 32778, 31053, 30711, - 31192, 41949, 41759, 41892, 18980, 18948, 18899, 728, 739, 786, 7274, 7035, 7300, - 7178, 7047, 7493, 7713, 7778, 7693, 6524, 6993, 6654, 26715, 26884, 26618, 42724, - 42649, 42667, 6570, 6585, 7011, 4577, 4423, 4493, 6461, 6524, 6654, 38060, 38113, - 37965, 38149, 38113, 38169, 38060, 38171, 38169, 40287, 40235, 40449, 40354, 40235, 40132, - 30830, 31188, 30925, 31517, 31412, 31378, 28449, 28611, 28061, 42145, 42233, 42081, 42276, - 42067, 41959, 42186, 42067, 42276, 41959, 41941, 42276, 37352, 37528, 37474, 37033, 37201, - 37014, 36850, 36969, 36955, 35774, 35682, 35787, 36738, 36593, 36680, 37022, 37070, 36890, - 37212, 37070, 37022, 37355, 37631, 37664, 36960, 36852, 36890, 37112, 37201, 37033, 20825, - 20652, 20802, 20504, 20445, 20432, 19254, 19068, 19155, 19155, 19068, 18980, 18980, 19068, - 18948, 20825, 20802, 20912, 20825, 20912, 20966, 21354, 21037, 21024, 20466, 20736, 20503, - 21225, 21251, 21370, 21251, 21621, 21461, 21461, 21621, 21463, 20426, 20736, 20466, 20426, - 20466, 20326, 20177, 20326, 20226, 20177, 20226, 20221, 20221, 19959, 20046, 19959, 19694, - 20046, 19694, 19568, 19675, 19568, 19556, 19675, 19556, 19435, 19389, 27140, 27305, 27569, - 23751, 23656, 23747, 25175, 25251, 25191, 25191, 25251, 25289, 2, 142, 111, 2, - 455, 142, 2, 76, 455, 113, 77, 187, 136, 10, 177, 2, 111, - 107, 2, 107, 54, 107, 117, 54, 21645, 21354, 21292, 20736, 20795, 20768, - 43496, 43563, 43493, 43493, 43554, 43474, 43474, 43546, 43470, 43470, 43543, 43458, 43630, - 43522, 43265, 43464, 43563, 43496, 43609, 43563, 43464, 43573, 43464, 43440, 43573, 43440, - 43549, 244, 329, 319, 54, 135, 153, 54, 117, 135, 244, 319, 353, - 7778, 7591, 7693, 11575, 11812, 11763, 13016, 12984, 12818, 15706, 15559, 15843, 15411, - 15246, 15470, 15842, 15912, 15768, 15533, 15476, 15445, 15533, 15445, 15399, 17668, 17594, - 17962, 16990, 16782, 16898, 20652, 20445, 20504, 20795, 20867, 20768, 25885, 26011, 26049, - 25893, 26011, 25885, 31958, 31948, 32344, 40696, 40509, 40618, 42969, 42867, 42934, 43339, - 43257, 43149, 43378, 43257, 43339, 43404, 43397, 43332, 43532, 43397, 43404, 43549, 43394, - 43453, 43549, 43453, 43524, 625, 639, 752, 15420, 15246, 15411, 14876, 14559, 14784, - 26011, 26433, 26049, 42867, 42825, 42624, 42802, 42767, 42759, 42802, 42759, 42889, 76, - 77, 113, 21645, 21974, 21354, 20867, 20956, 20928, 43563, 43554, 43493, 21354, 21974, - 21801, 20956, 21023, 20928, 11024, 11314, 11326, 39534, 39469, 39325, 39682, 39648, 39630, - 39682, 39630, 39701, 39701, 39824, 39877, 40381, 40186, 39707, 39528, 39449, 39293, 19389, - 19435, 19315, 21023, 21134, 21225, 43565, 43398, 43386, 43524, 43453, 43518, 29150, 29047, - 28977, 35682, 35423, 35724, 37714, 37704, 37777, 491, 514, 595, 389, 514, 491, - 4272, 4624, 3991, 27511, 27305, 27362, 10232, 10238, 9966, 11575, 11651, 11812, 54, - 153, 80, 43554, 43546, 43474, 13425, 13227, 13204, 42489, 42887, 42685, 27685, 27712, - 27472, 27559, 27371, 27307, 39534, 39325, 39514, 18948, 18713, 18881, 18818, 18713, 18948, - 31517, 31626, 31480, 43611, 43483, 43694, 43386, 43483, 43575, 11516, 11024, 11352, 11352, - 11024, 11326, 10911, 11083, 11325, 28930, 29150, 28977, 28930, 28772, 28775, 77, 10, - 136, 861, 1015, 975, 1058, 1015, 887, 22822, 22477, 22924, 22003, 21976, 22111, - 22003, 21974, 21976, 43546, 43543, 43470, 43514, 43428, 43347, 43518, 43453, 43484, 9417, - 9259, 9173, 9418, 9441, 9504, 12124, 11944, 11931, 13012, 13237, 13235, 11941, 11984, - 11812, 11812, 11984, 12053, 12984, 13227, 12973, 12984, 12973, 12873, 23872, 23940, 23737, - 25145, 25191, 24893, 40463, 40186, 40431, 43257, 43266, 43224, 43039, 42825, 42867, 43462, - 43266, 43257, 43543, 43542, 43458, 43507, 43518, 43484, 9383, 9233, 9253, 4239, 4009, - 4202, 4808, 5192, 4912, 163, 236, 249, 380, 395, 451, 7418, 7274, 7300, - 7912, 7902, 7970, 15842, 15768, 15713, 18524, 18420, 18413, 192, 422, 270, 16990, - 16951, 17078, 23656, 23436, 23557, 23656, 23557, 23747, 13124, 13012, 13235, 13178, 13335, - 13479, 12083, 12706, 12065, 42067, 42233, 42145, 42186, 42233, 42067, 7958, 7912, 7970, - 8476, 8487, 8352, 34110, 34236, 34126, 35724, 35423, 35773, 33148, 33144, 32998, 39407, - 39528, 39293, 39186, 39150, 39261, 27069, 27253, 27179, 27267, 27253, 27069, 14495, 13971, - 14762, 15559, 15496, 15511, 15327, 15496, 15559, 15399, 15445, 15333, 15713, 15768, 15687, - 15399, 15333, 15277, 42922, 42777, 42794, 42922, 42899, 42777, 80, 304, 83, 21251, - 21461, 21370, 23474, 23708, 23527, 43892, 43256, 43412, 4239, 4202, 4317, 24082, 23975, - 23813, 23345, 23232, 23148, 26433, 26544, 26474, 26547, 26544, 26433, 26715, 26544, 26547, - 32233, 31958, 32344, 32812, 32588, 33130, 40700, 40696, 40618, 40404, 40235, 40354, 40797, - 40696, 40700, 40797, 40700, 40948, 41518, 41470, 41524, 42889, 42759, 42751, 42794, 42802, - 43050, 6250, 6182, 6273, 6250, 6273, 6585, 6250, 6131, 6116, 389, 522, 514, - 514, 522, 595, 11118, 11460, 11600, 15713, 15687, 15612, 2762, 2856, 2892, 2762, - 2638, 2856, 2762, 2892, 2713, 4394, 4404, 4423, 4423, 4404, 4493, 9253, 9233, - 9109, 9253, 9109, 9051, 8845, 9051, 8825, 18524, 18506, 18420, 19291, 19389, 19315, - 18420, 18331, 18413, 21621, 21709, 21902, 39648, 39534, 39514, 40018, 39922, 40120, 40287, - 40152, 40235, 42094, 41876, 42142, 41620, 41518, 41524, 83, 411, 196, 180, 244, - 353, 17272, 17236, 17448, 17448, 17236, 17342, 1164, 1162, 1262, 625, 701, 610, - 30638, 30059, 30209, 28843, 28930, 28775, 4912, 5192, 4897, 6116, 6131, 6066, 9008, - 9024, 9173, 39781, 39534, 39648, 39205, 39252, 39344, 39589, 39724, 39575, 39407, 39293, - 39347, 10, 48, 202, 150, 192, 270, 15041, 15277, 15238, 14559, 14876, 14642, - 8862, 9008, 8941, 32923, 33067, 32892, 32706, 32316, 32368, 32706, 32710, 32771, 34724, - 34546, 34610, 34724, 34610, 34822, 39205, 39344, 39368, 11534, 11651, 11575, 11984, 12083, - 12065, 16452, 16149, 16782, 16782, 16149, 16755, 24223, 24082, 23813, 25555, 25388, 25488, - 25555, 25488, 25649, 3, 477, 154, 23221, 23179, 23349, 24587, 24082, 24223, 19291, - 19315, 19161, 18290, 18242, 18331, 23221, 23436, 23716, 22190, 22071, 22477, 4808, 4728, - 5139, 13483, 13488, 13295, 38149, 37965, 38113, 38149, 37884, 37965, 7897, 7958, 8008, - 7912, 7749, 7817, 27639, 27511, 27465, 27695, 27701, 28056, 27540, 27559, 27307, 28175, - 28449, 28061, 27626, 27559, 27540, 34236, 34432, 34357, 33662, 33671, 33526, 13312, 13178, - 13479, 13012, 12821, 12828, 22190, 22477, 22256, 15496, 15420, 15411, 15286, 15420, 15496, - 15767, 15713, 15612, 15277, 15333, 15238, 43050, 42922, 42794, 43045, 43037, 42908, 43028, - 43064, 42949, 43061, 42922, 43050, 9893, 10232, 9966, 11014, 11118, 11083, 11083, 11118, - 11325, 11534, 11678, 11651, 10348, 9890, 10447, 17236, 17162, 17217, 17272, 17162, 17236, - 24232, 24451, 24444, 25251, 25344, 25404, 24327, 24451, 24232, 40404, 40354, 40582, 9362, - 9550, 9383, 428, 516, 522, 522, 516, 595, 413, 451, 395, 4728, 4606, - 5147, 16149, 15706, 15843, 16218, 16413, 16250, 15852, 15713, 15767, 43045, 42830, 42899, - 19161, 18977, 18891, 17952, 17633, 17509, 17633, 17598, 17509, 31626, 31686, 31678, 31412, - 31517, 31480, 30638, 30749, 30714, 1349, 1377, 1704, 2134, 1882, 2456, 1204, 1377, - 1349, 227, 355, 271, 19675, 19389, 19291, 1127, 1164, 1262, 1752, 1690, 1730, - 1613, 1690, 1502, 1601, 1690, 1613, 1496, 1690, 1853, 17636, 17668, 17962, 23716, - 23436, 23656, 25146, 25106, 25262, 23708, 23872, 23737, 23912, 23872, 23708, 30059, 29809, - 30209, 42220, 42230, 42142, 42291, 42230, 42446, 42230, 42220, 42446, 8631, 8581, 8966, - 8008, 7958, 8093, 8016, 8538, 8188, 9362, 9457, 9550, 25245, 25146, 25262, 31589, - 31686, 31626, 7786, 7912, 7843, 7786, 7749, 7912, 7480, 7274, 7418, 7855, 7900, - 7885, 7693, 7591, 7609, 7047, 7178, 6986, 34546, 34386, 34290, 34538, 34386, 34546, - 34276, 34432, 34236, 39399, 39407, 39347, 38668, 38651, 39033, 8381, 8352, 8487, 39528, - 39605, 39449, 39638, 39605, 39528, 286, 398, 335, 339, 413, 395, 4606, 4593, - 4577, 4404, 4326, 4317, 6461, 6439, 6524, 6883, 7047, 6986, 6426, 6461, 6266, - 6426, 6259, 6356, 4798, 4812, 4615, 10915, 11083, 10911, 22629, 22477, 22822, 35423, - 35251, 35773, 38169, 38171, 38687, 40183, 40018, 40120, 39510, 39469, 39644, 41620, 41524, - 41745, 41662, 41674, 41939, 43137, 43064, 43028, 43630, 43265, 43458, 43446, 43295, 43242, - 739, 701, 752, 207, 271, 244, 728, 786, 828, 17277, 17509, 17303, 18709, - 18560, 18891, 23008, 22828, 22822, 23716, 23656, 23751, 42649, 42752, 42466, 42791, 42667, - 42673, 42791, 42673, 42825, 42791, 42825, 42909, 43514, 43347, 43588, 9008, 8862, 8966, - 9441, 9418, 9417, 9504, 9626, 9832, 24451, 24642, 24564, 24509, 24642, 24451, 31686, - 31890, 31678, 40651, 40791, 40577, 40828, 40651, 40637, 40415, 40194, 40724, 43182, 42642, - 42720, 48, 94, 221, 3333, 3467, 3991, 3258, 3467, 3333, 2773, 3025, 2919, - 39399, 39347, 39258, 11941, 11812, 11678, 11941, 12083, 11984, 37201, 37285, 37103, 36969, - 37112, 37033, 37167, 37112, 36969, 36804, 36691, 36572, 892, 1074, 1116, 1127, 1262, - 1288, 2653, 2773, 2919, 2653, 2927, 2425, 5863, 5940, 6182, 5406, 5817, 5317, - 4808, 4717, 4728, 4728, 4571, 4606, 4606, 4497, 4593, 24082, 24587, 24506, 23865, - 23716, 23751, 36852, 36871, 36738, 37070, 36960, 36890, 37141, 36960, 37070, 37212, 37192, - 37422, 37163, 37437, 37422, 42230, 42094, 42142, 36960, 36871, 36852, 37422, 37437, 37554, - 37280, 37285, 37201, 4497, 4517, 4593, 4593, 4517, 4577, 4487, 4466, 4607, 4403, - 4466, 4487, 36624, 36804, 36572, 35201, 35123, 34992, 37664, 37704, 37714, 38687, 38441, - 38660, 36624, 36572, 36663, 37285, 37413, 37103, 6484, 6993, 6524, 15767, 15612, 15533, - 14809, 15035, 14802, 35408, 35201, 35237, 43133, 43137, 42915, 43061, 43045, 42899, 43061, - 42899, 42922, 892, 1116, 938, 13488, 13483, 13479, 13178, 13124, 13235, 13312, 13295, - 13257, 18560, 18524, 18424, 17277, 16984, 17021, 27559, 27626, 27685, 27789, 27626, 27658, - 36189, 36074, 36282, 37777, 37866, 37714, 19254, 19155, 19445, 18713, 18795, 18693, 24799, - 24893, 24691, 26544, 26715, 26618, 43579, 43230, 43108, 43369, 43224, 43266, 26547, 26433, - 26351, 37413, 37528, 37352, 42909, 42825, 43039, 812, 728, 828, 7843, 7912, 7958, - 7480, 7418, 7579, 13257, 13124, 13178, 11944, 11612, 11776, 14784, 14809, 14802, 14216, - 14312, 14390, 14079, 14312, 14216, 13016, 13227, 12984, 28930, 28896, 29150, 28146, 28061, - 27712, 34432, 34527, 34357, 34204, 34276, 34236, 34204, 34236, 34110, 39091, 38896, 38677, - 39368, 39344, 39469, 39368, 39469, 39410, 8867, 9253, 9051, 9888, 10232, 9893, 25347, - 25245, 25262, 24506, 24587, 24637, 25582, 25555, 25772, 32706, 32368, 32710, 33539, 33241, - 33556, 17162, 16990, 17078, 15327, 15559, 15362, 17117, 16990, 17162, 37528, 37588, 37474, - 207, 227, 271, 207, 244, 180, 23865, 23751, 23870, 24587, 24881, 24637, 43446, - 43242, 43532, 1058, 1441, 1115, 1058, 1115, 1015, 40016, 39877, 39824, 40016, 39824, - 40018, 33148, 32998, 33067, 39605, 39724, 39589, 39704, 39724, 39605, 18524, 18413, 18424, - 16413, 16397, 16250, 24828, 24799, 24642, 23032, 23345, 23148, 36189, 35774, 36074, 37777, - 37884, 37866, 35646, 34965, 35360, 8581, 8516, 8487, 8352, 8256, 8271, 9057, 9008, - 9173, 13051, 12821, 13012, 14312, 14559, 14642, 28449, 28843, 28775, 33052, 33148, 33067, - 42531, 42167, 42164, 42276, 41941, 42342, 42724, 42731, 42649, 41949, 41892, 42093, 42843, - 42731, 42724, 51, 83, 196, 10232, 10348, 10438, 9798, 9741, 9550, 22171, 22400, - 21902, 43575, 43565, 43386, 43575, 43483, 43611, 4897, 5192, 4995, 36074, 35774, 35787, - 38044, 37884, 38149, 4264, 4394, 4517, 4517, 4394, 4423, 2713, 2892, 2853, 11678, - 11812, 11651, 10836, 10915, 10911, 16250, 16186, 16208, 15912, 15842, 15852, 25347, 25262, - 25388, 30638, 30714, 30711, 31517, 31589, 31626, 31686, 31986, 31890, 29686, 29420, 29150, - 43064, 43182, 42949, 43168, 43182, 43064, 180, 353, 138, 14, 51, 403, 20707, - 20652, 20825, 20707, 20636, 20652, 20652, 20636, 20445, 20445, 20286, 20432, 20707, 20825, - 20872, 20825, 20966, 20872, 20966, 21080, 20872, 21037, 21080, 20966, 22035, 21974, 22003, - 32710, 32368, 32560, 31561, 31589, 31517, 43563, 43632, 43554, 43554, 43650, 43546, 43546, - 43645, 43543, 43543, 43645, 43542, 43542, 43630, 43458, 43573, 43609, 43464, 43743, 43609, - 43573, 43743, 43573, 43728, 43647, 43549, 43524, 43647, 43524, 43610, 43524, 43725, 43610, - 23345, 23474, 23527, 24642, 24799, 24691, 23722, 23474, 23538, 20177, 20426, 20326, 20736, - 20911, 20795, 20795, 20911, 20867, 20867, 20911, 20956, 20956, 20911, 21023, 21023, 20911, - 21134, 21134, 21251, 21225, 21621, 21737, 21709, 21709, 22171, 21902, 20046, 20426, 20177, - 20426, 20911, 20736, 43696, 43632, 43563, 145, 415, 323, 128, 323, 192, 16646, - 16844, 16878, 25175, 25344, 25251, 24327, 24151, 24084, 2638, 2506, 2595, 3178, 3157, - 3201, 4912, 4829, 4808, 4634, 4798, 4615, 6250, 6116, 6182, 6570, 7011, 7035, - 19068, 18818, 18948, 17483, 17272, 17448, 18883, 18818, 19068, 43524, 43518, 43725, 43611, - 43694, 43697, 43385, 43101, 43249, 43632, 43650, 43554, 1690, 1601, 1707, 1613, 1502, - 1507, 7713, 7900, 7855, 9325, 9457, 9253, 7631, 7900, 7713, 20483, 20286, 20445, - 34454, 34527, 34432, 34381, 34204, 34440, 39263, 38896, 39091, 39410, 39469, 39510, 516, - 416, 827, 413, 389, 491, 339, 389, 413, 43133, 42915, 43037, 43133, 43037, - 43123, 1116, 1154, 930, 653, 739, 728, 930, 1233, 1036, 1288, 1972, 1707, - 7480, 7579, 7547, 14559, 14809, 14784, 15852, 15842, 15713, 35112, 34958, 34935, 34991, - 34958, 35077, 28029, 27695, 28056, 25772, 26740, 26440, 28029, 28056, 28451, 27626, 27789, - 27712, 29030, 28896, 28938, 27540, 27307, 27267, 11575, 11460, 11534, 12818, 12984, 12873, - 4394, 4326, 4404, 4264, 4326, 4394, 43518, 43507, 43725, 1060, 1162, 1164, 13124, - 13051, 13012, 13483, 13312, 13479, 13257, 13233, 13078, 4829, 4717, 4808, 36082, 36074, - 36010, 35860, 35787, 35724, 94, 3, 154, 18818, 18795, 18713, 18883, 18795, 18818, - 19675, 20046, 19694, 19675, 19556, 19389, 20911, 21251, 21134, 40948, 40700, 40822, 41939, - 41737, 41949, 41746, 41610, 41180, 43647, 43610, 43725, 65, 150, 270, 18413, 18331, - 18338, 17509, 17598, 17303, 8518, 8516, 8581, 7547, 7692, 7749, 33662, 33770, 33671, - 33556, 33241, 33144, 43667, 43645, 43546, 43514, 43404, 43428, 9887, 9530, 9888, 40788, - 40603, 40492, 40183, 40016, 40018, 41668, 41319, 41518, 40791, 40956, 40541, 40724, 40194, - 40753, 23982, 23940, 23872, 12799, 12523, 12697, 14312, 14440, 14559, 14559, 14440, 14809, - 39469, 39534, 39644, 40183, 40120, 40287, 40603, 40318, 40492, 4552, 4634, 4615, 4552, - 4615, 4466, 8381, 8256, 8352, 16413, 16646, 16878, 15533, 15399, 15767, 25392, 25347, - 25388, 25081, 24881, 25146, 25582, 25388, 25555, 25277, 25344, 25175, 25385, 25344, 25431, - 38174, 38044, 38149, 38174, 38149, 38169, 40801, 40724, 40860, 39610, 39638, 39528, 39610, - 39528, 39407, 39399, 39258, 39285, 7451, 7591, 7473, 34454, 34432, 34276, 35773, 35860, - 35724, 34454, 34276, 34381, 22872, 22828, 23008, 22100, 22035, 22003, 22629, 22828, 22872, - 4326, 4239, 4317, 4103, 4239, 4326, 42889, 42751, 42744, 43645, 43630, 43542, 40305, - 40183, 40287, 39251, 39091, 39205, 26715, 26993, 26884, 26351, 26433, 26011, 39977, 39753, - 39724, 23865, 23870, 23975, 23865, 23975, 24110, 389, 428, 522, 333, 428, 389, - 15767, 15399, 15143, 39285, 39258, 39186, 43123, 43037, 43045, 43338, 43168, 43064, 861, - 975, 908, 4509, 4552, 4466, 6439, 6492, 6524, 7343, 7451, 7473, 5501, 5676, - 5343, 28843, 28896, 28930, 28627, 28843, 28449, 18331, 18242, 18338, 21251, 21737, 21621, - 23722, 23708, 23474, 14, 443, 227, 144, 180, 138, 15270, 15286, 15327, 17483, - 17448, 17668, 43465, 43369, 43266, 43039, 42867, 43277, 43462, 43257, 43378, 43242, 43397, - 43532, 43387, 43385, 43249, 43387, 43249, 43448, 11905, 11612, 11944, 9832, 9956, 9949, - 9832, 9626, 10158, 11905, 12124, 12291, 12799, 12706, 12523, 11534, 11460, 11451, 26751, - 26993, 26715, 42531, 42081, 42233, 32846, 32812, 33130, 31958, 31764, 31674, 34079, 34196, - 34386, 33556, 33654, 33539, 32706, 32771, 32778, 32851, 32771, 32745, 6426, 6492, 6439, - 30986, 31192, 30711, 31589, 31561, 31686, 30986, 30711, 30714, 35773, 35251, 35537, 723, - 861, 487, 9956, 10002, 9949, 9259, 9057, 9173, 8518, 8381, 8516, 28068, 28146, - 27712, 28175, 28146, 28202, 40788, 40509, 40696, 40449, 40305, 40287, 249, 286, 335, - 236, 286, 249, 16686, 16646, 16423, 18424, 18338, 17967, 15986, 16208, 16186, 25344, - 25385, 25404, 25145, 24893, 24799, 43186, 43064, 43137, 5387, 5501, 5343, 6426, 6356, - 6492, 5387, 5343, 5039, 4641, 4798, 4634, 35646, 35077, 35112, 36960, 36933, 36871, - 37212, 37141, 37070, 37288, 37141, 37212, 37288, 37212, 37342, 37554, 37437, 37664, 37774, - 37664, 37714, 3467, 3585, 3991, 3173, 3585, 3467, 10915, 11014, 11083, 10447, 10836, - 10804, 10846, 10836, 10447, 27267, 27307, 27253, 35860, 35773, 35857, 34489, 34454, 34528, - 37141, 36933, 36960, 37413, 37469, 37528, 37528, 37604, 37588, 39261, 39285, 39186, 37285, - 37348, 37413, 37112, 37280, 37201, 37167, 37280, 37112, 37167, 36969, 36976, 36821, 36804, - 36624, 36663, 36572, 36470, 36572, 36386, 36470, 36386, 36507, 36470, 133, 227, 207, - 7343, 7493, 7047, 13312, 13257, 13178, 14943, 14762, 15246, 37280, 37348, 37285, 3638, - 3178, 3486, 39638, 39704, 39605, 39675, 39704, 39638, 1601, 1507, 1707, 1919, 1496, - 1853, 10846, 11014, 10915, 12501, 12828, 12821, 29668, 29686, 29385, 42001, 41939, 41949, - 41892, 42094, 42093, 31765, 31764, 31958, 29796, 29654, 29359, 22100, 22003, 22190, 25081, - 25146, 25245, 24327, 24509, 24451, 24665, 24509, 24274, 23912, 23708, 23722, 36386, 36282, - 36507, 34645, 34357, 34527, 36282, 36074, 36247, 26997, 27267, 27069, 15852, 15986, 15912, - 15023, 15399, 15277, 42791, 42843, 42724, 42731, 42752, 42649, 42867, 42969, 43165, 7900, - 8016, 8188, 9457, 9798, 9550, 7994, 8016, 7900, 7631, 7713, 7693, 42186, 42328, - 42233, 42276, 42328, 42186, 41620, 41668, 41518, 40797, 40788, 40696, 41675, 41668, 41620, - 9798, 9887, 9893, 9457, 9362, 9253, 18282, 18207, 18446, 22629, 22822, 22828, 22256, - 22100, 22190, 24110, 23975, 24082, 22591, 22745, 22542, 40979, 40822, 41087, 40936, 40956, - 40828, 40828, 40956, 40791, 40801, 40637, 40724, 43347, 43426, 43600, 9259, 9417, 9418, - 8093, 8271, 8008, 22256, 22477, 22532, 32851, 32923, 32778, 33539, 33654, 33662, 32851, - 32778, 32771, 25185, 25081, 25245, 25392, 25245, 25347, 24929, 25145, 24799, 36247, 36074, - 36082, 428, 416, 516, 96, 339, 395, 25385, 25517, 25404, 26981, 26997, 26993, - 26993, 26997, 27069, 25431, 25517, 25385, 701, 625, 752, 610, 701, 739, 735, - 728, 812, 826, 996, 892, 6131, 6250, 6150, 7626, 7749, 7786, 7843, 7958, - 7897, 26751, 26715, 26547, 34785, 34724, 34822, 34991, 34822, 34958, 42957, 42843, 42791, - 18338, 18242, 18134, 21737, 22171, 21709, 29686, 30209, 29809, 41826, 41745, 41624, 41939, - 41826, 41662, 42093, 42094, 42315, 4995, 5192, 5299, 4912, 4765, 4829, 4829, 4692, - 4717, 4571, 4497, 4606, 5168, 5299, 5406, 8381, 8487, 8516, 37866, 37774, 37714, - 37866, 37884, 37900, 39399, 39610, 39407, 37536, 38651, 38668, 1127, 1060, 1164, 800, - 826, 892, 1105, 1060, 1127, 3, 65, 477, 98, 128, 192, 17967, 18338, - 18134, 17509, 17277, 17030, 40925, 40788, 40797, 40449, 40235, 40404, 40860, 40724, 40753, - 43601, 43426, 43522, 24506, 24110, 24082, 24946, 24637, 24881, 43472, 43365, 43369, 43369, - 43365, 43224, 43405, 43249, 43182, 43385, 43468, 43101, 895, 892, 938, 9361, 9259, - 9418, 13449, 13719, 13425, 16208, 16283, 16218, 13204, 13227, 13016, 22532, 22477, 22629, - 23912, 23982, 23872, 25148, 25156, 25145, 24067, 23982, 23912, 43637, 43468, 43385, 4897, - 4765, 4912, 6116, 6066, 6182, 6250, 6585, 6150, 37874, 37866, 37900, 818, 895, - 938, 8631, 8862, 8682, 8631, 8966, 8862, 28146, 28175, 28061, 28896, 29030, 29150, - 28068, 27712, 27789, 27658, 27626, 27540, 27658, 27540, 27576, 33556, 33144, 33435, 8941, - 9008, 9057, 15420, 15286, 15246, 15327, 15286, 15496, 15706, 16149, 15876, 16782, 16990, - 16693, 25893, 26351, 26011, 42909, 42946, 42791, 43318, 42983, 43230, 826, 735, 812, - 27874, 27658, 27760, 333, 416, 428, 3585, 4272, 3991, 4533, 4641, 4634, 11678, - 11902, 11941, 11451, 11460, 11368, 43133, 43186, 43137, 43168, 43321, 43182, 43061, 43123, - 43045, 43376, 43123, 43061, 32503, 32233, 32344, 39704, 39827, 39724, 39695, 39610, 39617, - 27066, 27373, 27267, 26859, 26751, 26830, 28371, 28518, 28449, 29686, 30328, 30209, 43051, - 42946, 42909, 42850, 42889, 42744, 42863, 42889, 42850, 4765, 4692, 4829, 6570, 7035, - 6596, 8862, 8941, 8757, 25145, 25156, 25175, 25517, 25893, 25832, 25277, 25156, 25210, - 36074, 35787, 36010, 735, 653, 728, 42822, 42752, 42731, 42822, 42731, 42948, 42039, - 41826, 41939, 42291, 42094, 42230, 6783, 7035, 7274, 7626, 7547, 7749, 7626, 7786, - 7748, 7451, 7609, 7591, 7415, 7609, 7451, 15622, 15986, 15852, 16646, 16413, 16423, - 15041, 15238, 14809, 25772, 25963, 25752, 25081, 24946, 24881, 17636, 17483, 17668, 17495, - 17483, 17636, 17021, 16984, 16844, 24089, 24110, 24156, 23008, 23221, 22872, 24089, 24156, - 24134, 23982, 24084, 23940, 24274, 24084, 24067, 4533, 4634, 4552, 30961, 30925, 31188, - 30961, 31188, 31213, 31192, 31378, 31412, 31315, 31378, 31192, 36010, 35787, 35963, 35787, - 35860, 35963, 43767, 43601, 43872, 35077, 34958, 35112, 8008, 8271, 8256, 39368, 39379, - 39205, 38814, 38687, 38660, 39648, 39682, 39781, 39682, 39890, 39781, 40249, 40016, 40183, - 12706, 12083, 12523, 33435, 33144, 33148, 32284, 32074, 32400, 40582, 40318, 40603, 144, - 207, 180, 653, 610, 739, 8845, 8825, 8684, 40690, 40582, 40603, 31378, 31561, - 31517, 23221, 23716, 23689, 43601, 43600, 43426, 35963, 35860, 35857, 1613, 1507, 1601, - 2200, 2149, 1665, 9504, 9361, 9418, 10158, 10002, 9956, 10752, 10109, 10002, 32021, - 31765, 31958, 40948, 40925, 40797, 40690, 40615, 40582, 41087, 40841, 41255, 41012, 41319, - 41255, 15286, 15270, 15246, 17117, 17162, 17272, 43049, 43050, 42802, 25156, 25277, 25175, - 24828, 24642, 24729, 7962, 8008, 8256, 8606, 8518, 8581, 8606, 8581, 8631, 34632, - 34489, 34528, 34454, 34489, 34527, 33052, 33067, 32923, 144, 133, 207, 704, 301, - 628, 7, 192, 150, 286, 200, 380, 339, 333, 389, 43446, 43462, 43378, - 43606, 43318, 43230, 43561, 43462, 43815, 43532, 43404, 43514, 1036, 1233, 1162, 960, - 1105, 1127, 12393, 12501, 12510, 11516, 11352, 11612, 13078, 13124, 13257, 58, 14, - 227, 38814, 38660, 38896, 163, 249, 415, 24665, 24642, 24509, 826, 729, 735, - 535, 528, 653, 653, 528, 610, 895, 800, 892, 729, 800, 818, 2853, - 2892, 3054, 2762, 2583, 2638, 3638, 3192, 3178, 3758, 4009, 3910, 2690, 3258, - 3225, 4348, 4403, 4255, 2690, 3183, 2773, 7748, 7786, 7843, 6783, 7274, 6834, - 7748, 7843, 7856, 28497, 28627, 28518, 27874, 28068, 27789, 27874, 27789, 27658, 34724, - 34538, 34546, 32718, 32503, 32344, 34770, 34538, 34724, 33770, 33662, 33654, 39610, 39675, - 39638, 39695, 39675, 39610, 42345, 42531, 42233, 42889, 43049, 42802, 43609, 43696, 43563, - 43632, 43794, 43650, 43650, 43668, 43546, 43645, 43698, 43630, 43630, 43698, 43522, 43601, - 43767, 43600, 43743, 43696, 43609, 43573, 43549, 43728, 43549, 43647, 43728, 43647, 43873, - 43728, 43891, 43893, 43725, 20636, 20483, 20445, 18830, 18883, 19068, 18795, 18687, 18693, - 20707, 20483, 20636, 21080, 21037, 21354, 21080, 21354, 21263, 21354, 21801, 21263, 22035, - 22100, 22226, 43412, 43565, 43770, 13719, 13987, 14159, 13816, 13987, 13719, 20010, 20316, - 20286, 18424, 18891, 18560, 18424, 18413, 18338, 22226, 22100, 22256, 23689, 23716, 23824, - 22171, 22591, 22542, 6883, 7343, 7047, 32094, 31958, 32233, 32094, 32021, 31958, 41072, - 40925, 40948, 40801, 40936, 40828, 41490, 40604, 40541, 41031, 40936, 40801, 42946, 42957, - 42791, 43051, 42957, 42946, 42900, 42957, 43047, 43340, 43186, 43133, 43338, 43186, 43340, - 4571, 4728, 4717, 4403, 4487, 4272, 4348, 4509, 4466, 6259, 6426, 6266, 6492, - 6484, 6524, 35857, 35773, 35881, 38285, 38174, 38169, 9259, 9129, 9057, 8682, 8606, - 8631, 9265, 9361, 9364, 40615, 40493, 40582, 40582, 40493, 40404, 22226, 22256, 22430, - 43804, 43668, 43650, 43668, 43667, 43546, 3002, 3230, 3237, 32851, 33052, 32923, 33089, - 33052, 33189, 40305, 40249, 40183, 40569, 40249, 40305, 7962, 8256, 8051, 38852, 38814, - 38907, 39682, 39877, 39890, 1036, 1162, 1060, 28518, 28627, 28449, 28371, 28449, 28175, - 37348, 37469, 37413, 37389, 37469, 37348, 36976, 36850, 36804, 36976, 36804, 36821, 36624, - 36663, 36821, 36663, 36835, 36821, 36470, 36594, 36663, 36507, 36594, 36470, 4897, 4828, - 4765, 4765, 4630, 4692, 4692, 4571, 4717, 5317, 5449, 5285, 5863, 6182, 6066, - 20054, 20010, 20286, 36593, 36738, 36871, 37141, 37262, 36933, 37554, 37212, 37422, 37554, - 37826, 37569, 37664, 37826, 37554, 11754, 11902, 11678, 11368, 11460, 11118, 11368, 11118, - 10857, 10846, 10915, 10836, 10804, 10348, 10447, 36367, 36507, 36282, 40463, 40194, 40186, - 41745, 41675, 41620, 42039, 41939, 42115, 43736, 43532, 43514, 6356, 6484, 6492, 36276, - 36367, 36282, 35408, 35251, 35201, 133, 58, 227, 833, 305, 704, 128, 145, - 323, 98, 145, 128, 5337, 5168, 5406, 36276, 36282, 36247, 37389, 37348, 37280, - 43462, 43465, 43266, 43561, 43465, 43462, 43719, 43565, 43575, 14816, 14495, 14762, 14303, - 14440, 14312, 43323, 43321, 43168, 43387, 43536, 43385, 37874, 37774, 37866, 25185, 24946, - 25081, 23824, 23716, 23865, 24828, 24929, 24799, 24833, 24929, 24828, 25040, 24929, 25008, - 2643, 2583, 2762, 18883, 18687, 18795, 18548, 18687, 18830, 40539, 40404, 40493, 40539, - 40449, 40404, 43722, 43611, 43697, 43719, 43611, 43722, 973, 1036, 1060, 973, 1060, - 1105, 7343, 7415, 7451, 8222, 8385, 8016, 8016, 8385, 8538, 7574, 7415, 7511, - 11978, 12083, 11941, 13633, 13816, 13719, 34898, 34785, 35009, 34991, 34785, 34822, 42625, - 42220, 42510, 42149, 41939, 42001, 42725, 42510, 42752, 42328, 42345, 42233, 42342, 41941, - 42465, 42000, 41711, 41610, 7856, 7843, 7897, 7590, 7480, 7547, 245, 333, 211, - 416, 274, 827, 200, 286, 236, 1507, 1288, 1707, 4403, 4199, 4255, 7590, - 7547, 7626, 5977, 5863, 6066, 25582, 25392, 25388, 26740, 27140, 27385, 5011, 4995, - 5299, 6059, 6066, 6131, 36181, 36276, 36247, 65, 7, 150, 2468, 2506, 2583, - 3085, 3002, 3237, 8051, 8256, 8159, 7826, 7856, 7897, 8682, 8862, 8757, 23824, - 23865, 23934, 23538, 23474, 23345, 33756, 33770, 33654, 33756, 33654, 33556, 39890, 40016, - 39975, 39890, 39877, 40016, 39675, 39827, 39704, 39695, 39827, 39675, 39610, 39399, 39617, - 43843, 43698, 43645, 43600, 43588, 43347, 1567, 1951, 1775, 1567, 1775, 1377, 903, - 1377, 1204, 30925, 30594, 30218, 31213, 31188, 31647, 31188, 31764, 31647, 30749, 30986, - 30714, 31378, 31579, 31561, 32154, 32074, 31890, 30523, 30638, 30209, 26751, 26981, 26993, - 26859, 26981, 26751, 26751, 26547, 26830, 25893, 25517, 25562, 42957, 42900, 42843, 43051, - 42909, 43099, 43338, 43064, 43186, 43338, 43323, 43168, 42850, 42685, 42887, 38120, 38044, - 38174, 39379, 39368, 39410, 39379, 39410, 39510, 4995, 4876, 4897, 17483, 17242, 17272, - 17495, 17242, 17483, 18687, 18632, 18693, 18548, 18632, 18687, 23097, 22872, 23221, 22430, - 22256, 22532, 36082, 36181, 36247, 43736, 43588, 43906, 10348, 10232, 9888, 13987, 14079, - 14216, 13204, 13016, 13072, 28320, 28371, 28175, 27576, 27540, 27267, 34162, 34079, 34405, - 34405, 34079, 34386, 39816, 39644, 39534, 40979, 41072, 40948, 40690, 40603, 40782, 41255, - 41319, 41930, 1058, 1047, 1204, 871, 1047, 1058, 887, 1015, 723, 134, 200, - 236, 163, 415, 145, 4393, 4517, 4497, 4393, 4264, 4517, 3201, 3157, 3237, - 4876, 4828, 4897, 12777, 13016, 12818, 13940, 14079, 13987, 16916, 16693, 16990, 16747, - 16646, 16686, 17967, 18134, 17952, 16844, 16646, 16747, 24929, 25040, 25145, 24509, 24327, - 24274, 25372, 25392, 25505, 27373, 27576, 27267, 28202, 28146, 28068, 28938, 28896, 28843, - 30557, 30594, 30675, 36082, 36010, 36181, 37900, 37884, 37969, 37884, 38044, 37969, 43477, - 43108, 43365, 43411, 43405, 43182, 43340, 43123, 43552, 11754, 11678, 11534, 13434, 13449, - 13204, 11754, 11534, 11429, 32718, 32344, 32812, 32047, 31827, 31765, 40603, 40788, 40782, - 39921, 39890, 39975, 23560, 23097, 23221, 24089, 23865, 24110, 24089, 24134, 23934, 2680, - 2653, 2416, 18632, 18459, 18693, 18548, 18459, 18632, 9956, 9832, 10158, 8757, 8941, - 8843, 11516, 11612, 11905, 6150, 6059, 6131, 36181, 36010, 36248, 37969, 38044, 38120, - 7650, 7590, 7626, 7826, 7897, 8008, 39585, 39379, 39510, 41977, 41675, 41745, 41977, - 41745, 41826, 42276, 42345, 42328, 42887, 42489, 43084, 42499, 42345, 42276, 42948, 42731, - 42843, 36980, 36871, 36933, 34551, 34386, 34538, 43125, 43049, 42889, 43024, 42889, 42863, - 144, 58, 133, 833, 639, 305, 17242, 17117, 17272, 17099, 17117, 17242, 43350, - 43165, 42969, 42948, 42835, 42822, 43465, 43472, 43369, 43561, 43472, 43465, 43477, 43472, - 43569, 6130, 6150, 6585, 32315, 32094, 32233, 38285, 38169, 38380, 17967, 17952, 17509, - 22591, 23032, 22876, 24274, 24327, 24084, 11384, 11368, 11248, 7574, 7693, 7609, 39781, - 39816, 39534, 39317, 39313, 39428, 40557, 40305, 40449, 2583, 2506, 2638, 2643, 2762, - 2713, 8256, 8381, 8159, 9265, 9259, 9361, 9364, 9361, 9504, 32503, 32549, 32233, - 32846, 32718, 32812, 31986, 31686, 31796, 33052, 33089, 33148, 40615, 40539, 40493, 40557, - 40539, 40964, 16693, 16590, 16782, 14192, 14054, 14495, 16675, 16590, 16693, 43411, 43182, - 43321, 43411, 43321, 43414, 1036, 934, 930, 818, 800, 895, 1002, 973, 1105, - 28938, 28843, 28627, 42887, 43084, 43112, 40161, 39707, 39753, 39617, 39399, 39285, 43340, - 43133, 43123, 4630, 4571, 4692, 4509, 4533, 4552, 4641, 4569, 4798, 5862, 6259, - 6266, 6356, 6260, 6484, 4528, 4533, 4509, 7650, 7626, 7748, 6043, 6059, 6150, - 7650, 7748, 7856, 7415, 7574, 7609, 7631, 7574, 7511, 34489, 34632, 34527, 35857, - 36061, 35963, 34528, 34454, 34381, 39313, 39205, 39379, 39313, 39251, 39205, 38233, 38285, - 38380, 37536, 37608, 38651, 33189, 33052, 32992, 34381, 34276, 34204, 22430, 22532, 22653, - 22532, 22629, 22653, 18459, 18282, 18446, 18288, 18282, 18459, 98, 163, 145, 245, - 338, 333, 818, 938, 815, 800, 729, 826, 305, 639, 158, 24729, 24580, - 24949, 25431, 25344, 25277, 11747, 11516, 11905, 12291, 12124, 12501, 815, 938, 930, - 13204, 13449, 13425, 14309, 14303, 14114, 12777, 12818, 12697, 28371, 28497, 28518, 28104, - 28202, 28068, 28104, 28068, 28018, 14495, 14054, 13971, 15040, 15246, 15270, 42835, 42725, - 42752, 42835, 42752, 42822, 56, 58, 144, 15362, 15559, 15706, 5862, 6266, 5501, - 6484, 6427, 6986, 333, 338, 416, 333, 339, 71, 25431, 25277, 25210, 27066, - 27267, 26997, 27576, 27760, 27658, 13295, 13312, 13483, 28357, 28497, 28371, 30557, 30488, - 30594, 31647, 31764, 31650, 12132, 12291, 12234, 32884, 32846, 33069, 31765, 32021, 32047, - 39977, 39724, 39827, 43099, 42909, 43152, 27066, 26997, 26981, 40683, 40690, 40782, 41930, - 41319, 41668, 42948, 42843, 43032, 16590, 16452, 16782, 16507, 16452, 16590, 16916, 16990, - 17117, 41077, 40979, 41087, 39921, 39781, 39890, 41126, 40541, 40956, 41031, 41126, 40936, - 40745, 40753, 40194, 43414, 43321, 43323, 43443, 43448, 43249, 31650, 31764, 31765, 31650, - 31765, 31827, 31612, 31579, 31378, 31315, 31192, 31332, 12800, 12777, 12697, 11429, 11534, - 11451, 35237, 35201, 34992, 41065, 41072, 41267, 42149, 42001, 42093, 42149, 42093, 42171, - 639, 625, 405, 138, 56, 144, 38852, 38687, 38814, 1507, 1419, 1288, 960, - 1002, 1105, 1919, 2200, 1665, 11978, 11941, 11902, 20, 353, 628, 7826, 7650, - 7856, 6205, 6585, 6570, 7574, 7631, 7693, 7640, 7631, 7511, 16733, 16916, 17099, - 16747, 17021, 16844, 16218, 16423, 16413, 16283, 16423, 16218, 24665, 24729, 24642, 24833, - 24729, 24949, 35199, 35237, 34992, 34204, 34279, 34440, 39334, 38814, 38896, 39585, 39510, - 39644, 43472, 43477, 43365, 43350, 43277, 43165, 43099, 43047, 43051, 43462, 43446, 43815, - 5977, 6066, 6059, 5225, 5317, 5216, 5317, 5817, 5449, 5337, 5257, 5168, 5168, - 5011, 5299, 4995, 4861, 4876, 4876, 4685, 4828, 4828, 4630, 4765, 4569, 5343, - 4798, 38651, 37608, 37953, 37167, 37389, 37280, 36976, 37140, 37167, 37069, 37140, 36976, - 37069, 36976, 37012, 36976, 36821, 37012, 36663, 36729, 36835, 36594, 36613, 36663, 36692, - 36613, 36594, 5317, 5257, 5337, 9412, 9364, 9504, 10002, 10158, 10752, 17534, 17495, - 17636, 24506, 24156, 24110, 23824, 23560, 23689, 36692, 36729, 36613, 37117, 36980, 36933, - 37554, 37342, 37212, 37590, 37342, 37554, 37664, 37774, 37826, 37911, 37874, 37900, 38018, - 37900, 37969, 37140, 37389, 37167, 41427, 41077, 41087, 3758, 3984, 4009, 3002, 2853, - 3054, 39921, 39816, 39781, 40557, 40449, 40539, 2785, 2853, 3002, 8437, 8518, 8606, - 8876, 8941, 9057, 8695, 8757, 8843, 22222, 22430, 22653, 26934, 27066, 26981, 37262, - 37141, 37288, 42881, 43024, 42863, 43376, 43061, 43050, 43413, 43414, 43323, 42881, 42887, - 43013, 1429, 1419, 1507, 30594, 30488, 30036, 25505, 25582, 25772, 30594, 30925, 30866, - 36507, 36692, 36594, 4533, 4569, 4641, 4403, 4348, 4466, 4403, 4272, 4199, 9412, - 9570, 9309, 35537, 35881, 35773, 5051, 5011, 5168, 8564, 8606, 8682, 7776, 7994, - 7900, 31738, 31686, 31561, 32710, 32745, 32771, 39768, 39585, 39644, 973, 934, 1036, - 934, 1002, 960, 2853, 2643, 2713, 1482, 1429, 1502, 11802, 11978, 11902, 11978, - 12523, 12083, 29030, 29077, 29150, 29050, 29077, 29030, 35408, 35537, 35251, 34645, 34527, - 34632, 39263, 39091, 39251, 42315, 42094, 42291, 41930, 41668, 41675, 29668, 30328, 29686, - 36507, 36552, 36690, 16452, 16380, 16149, 16507, 16380, 16452, 27516, 27760, 27576, 28202, - 28320, 28175, 28743, 28938, 28627, 27516, 27576, 27373, 29, 134, 236, 7, 98, - 192, 13078, 13051, 13124, 13381, 13295, 13475, 28241, 28320, 28202, 4857, 4861, 4995, - 24729, 24833, 24828, 24067, 23912, 23722, 43443, 43405, 43441, 43443, 43249, 43405, 27396, - 27516, 27373, 26830, 26547, 26351, 26934, 26859, 26830, 43051, 43047, 42957, 43042, 43047, - 43111, 31986, 32154, 31890, 20, 56, 156, 488, 625, 610, 43206, 43050, 43049, - 20896, 20483, 20707, 20010, 19652, 19736, 20896, 20707, 20872, 20896, 20872, 21080, 20896, - 21080, 21263, 21974, 22035, 21801, 43611, 43719, 43575, 43079, 43694, 43483, 43667, 43818, - 43645, 43698, 43787, 43522, 43668, 43804, 43667, 43696, 43794, 43632, 43844, 43794, 43696, - 43844, 43696, 43743, 43844, 43743, 43873, 43743, 43728, 43873, 34592, 34645, 34632, 33986, - 33671, 33770, 43794, 43804, 43650, 11384, 11248, 11402, 11384, 11429, 11368, 11368, 11429, - 11451, 11754, 11802, 11902, 13108, 13051, 13078, 12777, 13072, 13016, 14303, 14312, 14079, - 12800, 13072, 12777, 32734, 32745, 32710, 33400, 33435, 33148, 40683, 40539, 40615, 40683, - 40615, 40690, 3157, 3085, 3237, 2853, 2740, 2643, 3050, 3085, 3157, 8695, 8564, - 8682, 8695, 8682, 8757, 33400, 33148, 33089, 33628, 33756, 33556, 6043, 5977, 6059, - 6043, 6150, 6130, 20483, 20054, 20286, 21801, 22035, 22222, 32154, 32400, 32074, 17493, - 17967, 17509, 23032, 23538, 23345, 42880, 42817, 42725, 42411, 42315, 42291, 43032, 42843, - 42900, 24067, 24084, 23982, 36593, 35646, 35360, 34898, 34724, 34785, 43413, 43323, 43338, - 2680, 2690, 2773, 3258, 3216, 3467, 2680, 2773, 2653, 3137, 3216, 3258, 8159, - 8381, 8190, 7962, 7826, 8008, 8684, 8767, 8538, 9888, 9893, 9887, 8684, 8538, - 8385, 29385, 29686, 29150, 29050, 28938, 29044, 39816, 39768, 39644, 39317, 39251, 39313, - 39317, 39263, 39251, 39888, 39768, 39816, 29, 236, 163, 9887, 9798, 9530, 17030, - 17493, 17509, 15986, 16091, 16283, 14809, 14949, 15041, 30020, 29866, 29796, 31213, 31149, - 30961, 30488, 30355, 30036, 31128, 31149, 31213, 31570, 31213, 31647, 42979, 43305, 43694, - 43441, 43405, 43520, 31332, 31192, 30986, 31579, 31738, 31561, 32163, 32260, 32154, 32154, - 32260, 32400, 4685, 4630, 4828, 4571, 4496, 4497, 3910, 4009, 4239, 7480, 6834, - 7274, 6130, 6585, 6205, 15327, 15139, 15270, 13228, 13233, 13295, 15362, 15139, 15327, - 38120, 38018, 37969, 38120, 38174, 38233, 41126, 40956, 40936, 34592, 34632, 34528, 34592, - 34528, 34502, 39313, 39379, 39428, 38233, 38174, 38285, 43536, 43387, 43629, 43719, 43770, - 43565, 9997, 10002, 10109, 9673, 9504, 9832, 32549, 32503, 32589, 31612, 31738, 31579, - 7925, 7826, 7962, 8434, 8684, 8385, 7631, 7776, 7900, 7640, 7776, 7631, 8876, - 9057, 9129, 9877, 9832, 9949, 32589, 32503, 32718, 32589, 32718, 32763, 40782, 40788, - 40918, 39975, 40609, 40083, 40753, 40950, 40860, 40599, 40745, 40194, 40599, 40194, 40463, - 4103, 4326, 4264, 7480, 6975, 6834, 26859, 26934, 26981, 26830, 26351, 26832, 36061, - 36010, 35963, 36061, 35857, 35881, 35537, 35408, 35441, 38169, 38687, 38380, 43047, 43042, - 42900, 43032, 43042, 43111, 43013, 43024, 42881, 43340, 43413, 43338, 43013, 42887, 43112, - 35441, 35408, 35237, 1419, 1168, 1288, 1502, 1429, 1507, 2149, 1591, 1665, 28743, - 28627, 28705, 27882, 28068, 27874, 27882, 27874, 27760, 30866, 30925, 30961, 41977, 41826, - 42104, 42446, 42220, 42625, 43619, 43561, 43848, 43505, 43350, 43318, 43569, 43561, 43619, - 43528, 43387, 43448, 9929, 9877, 9949, 18830, 18687, 18883, 18282, 18256, 17962, 41077, - 41072, 40979, 41267, 41072, 41427, 42115, 41939, 42149, 41031, 40801, 40860, 43858, 43770, - 43719, 43694, 43305, 43842, 13295, 13233, 13257, 12030, 11905, 12291, 12030, 11747, 11905, - 13228, 13295, 13381, 29866, 29654, 29796, 29870, 29654, 29866, 29385, 29150, 29077, 31645, - 31612, 31315, 42171, 42115, 42149, 20054, 19652, 20010, 22222, 22035, 22226, 22222, 22226, - 22430, 27180, 27373, 27066, 4630, 4496, 4571, 4416, 4528, 4509, 4416, 4509, 4348, - 25392, 25372, 25245, 25505, 25392, 25582, 25505, 25772, 25752, 25148, 25145, 25040, 25008, - 24929, 24833, 43520, 43405, 43411, 43691, 43637, 43536, 43418, 43509, 43513, 15043, 15040, - 15139, 16916, 16675, 16693, 16715, 16675, 16916, 16507, 16675, 16715, 14809, 14433, 14949, - 17030, 17277, 17021, 24949, 25008, 24833, 30496, 30355, 30488, 41746, 41824, 41610, 42345, - 42774, 42531, 43418, 43411, 43414, 40031, 39977, 39827, 39784, 39827, 39695, 43843, 43787, - 43698, 2643, 2468, 2583, 2627, 2785, 2705, 2740, 2785, 2627, 8437, 8381, 8518, - 8051, 7925, 7962, 9259, 9265, 9129, 9530, 9798, 9457, 8222, 8016, 7994, 33435, - 33576, 33556, 33862, 33986, 33770, 33189, 33400, 33089, 33576, 33607, 33628, 42625, 42510, - 42814, 42510, 42725, 42817, 4302, 4416, 4348, 2690, 3137, 3258, 8437, 8606, 8564, - 33862, 33770, 33756, 535, 653, 735, 535, 735, 557, 581, 729, 818, 7061, - 7590, 7650, 34645, 35199, 34992, 34502, 34528, 34381, 39263, 39337, 38896, 39428, 39379, - 39531, 40531, 40599, 40463, 40804, 40950, 40753, 43858, 43719, 43722, 43669, 43305, 43468, - 37604, 37528, 37469, 39654, 39617, 39285, 15139, 15040, 15270, 15362, 15706, 15876, 13434, - 13719, 13449, 4272, 4157, 4199, 6259, 6260, 6356, 6243, 6260, 6110, 36015, 36061, - 35881, 38380, 38911, 38506, 338, 253, 416, 211, 333, 71, 11429, 11409, 11754, - 12947, 12800, 12699, 12978, 13204, 13072, 11118, 11014, 10857, 156, 56, 138, 105, - 628, 301, 2690, 2489, 3137, 2587, 2680, 2416, 8843, 8876, 8747, 43561, 43569, - 43472, 43736, 43514, 43588, 39654, 39285, 39521, 32400, 32560, 32368, 32163, 32154, 31986, - 40804, 40753, 40745, 1002, 934, 973, 960, 1127, 902, 28938, 29050, 29030, 28627, - 28497, 28705, 42446, 42411, 42291, 42275, 42171, 42093, 42465, 41941, 42363, 36980, 36593, - 36871, 37342, 37262, 37288, 37360, 37262, 37342, 37774, 37874, 37911, 37900, 38018, 37911, - 4861, 4685, 4876, 4630, 4557, 4496, 5011, 4946, 4995, 5257, 5116, 5168, 5317, - 5225, 5257, 5216, 5317, 5279, 5480, 5863, 5594, 5992, 5977, 6043, 43042, 43032, - 42900, 43277, 42867, 43165, 16675, 16507, 16590, 17449, 17242, 17495, 25008, 25148, 25040, - 25027, 25148, 25008, 25210, 25148, 25127, 37262, 37117, 36933, 37389, 37531, 37469, 37140, - 37308, 37389, 37069, 37308, 37140, 36835, 37012, 36821, 37023, 37012, 36835, 36729, 36663, - 36613, 36507, 36690, 36692, 6260, 6418, 6484, 37911, 38018, 38144, 38363, 38380, 38506, - 24506, 24565, 24156, 27569, 27511, 27695, 25431, 25469, 25517, 25443, 25469, 25431, 5117, - 5116, 5257, 37506, 37531, 37389, 2394, 2468, 2537, 40947, 40804, 40745, 40488, 40531, - 40463, 5116, 5051, 5168, 28357, 28371, 28320, 27891, 27882, 27760, 28018, 27882, 27891, - 38018, 38120, 38139, 12978, 13434, 13204, 12800, 12697, 12699, 19652, 19254, 19445, 22653, - 22629, 22872, 23934, 23865, 24089, 39033, 39150, 38668, 39330, 39150, 39357, 40683, 40964, - 40539, 40918, 40788, 41065, 40739, 40745, 40599, 8022, 8222, 7994, 7511, 7415, 7284, - 34592, 34711, 34645, 36326, 36181, 36248, 34440, 34502, 34381, 38362, 38363, 38506, 39531, - 39379, 39585, 39714, 39585, 39768, 31149, 31073, 30961, 30557, 30496, 30488, 31128, 31073, - 31149, 31570, 31647, 31650, 5051, 4946, 5011, 18394, 18288, 18459, 18394, 18459, 18548, - 36367, 36276, 36365, 43767, 43588, 43600, 686, 815, 930, 34279, 34204, 34110, 33607, - 33576, 33435, 33052, 32851, 32992, 1429, 1341, 1419, 1725, 2595, 2506, 15040, 14943, - 15246, 15876, 16149, 16311, 31073, 30866, 30961, 30355, 30020, 29796, 3178, 3050, 3157, - 2394, 2433, 2468, 4272, 3585, 4157, 7644, 7994, 7776, 31847, 31570, 31650, 31738, - 31796, 31686, 31315, 31612, 31378, 30749, 30638, 30523, 33846, 33862, 33756, 40016, 40609, - 39975, 4946, 4857, 4995, 25185, 25245, 25372, 36365, 36276, 36326, 43350, 42969, 43318, - 13940, 13987, 13816, 15043, 14943, 15040, 16283, 16208, 15986, 14433, 14809, 14440, 43152, - 42909, 43039, 43024, 43125, 42889, 43147, 43125, 43024, 1496, 1482, 1502, 9997, 9929, - 10002, 12291, 12501, 12393, 30866, 30675, 30594, 30523, 30209, 30328, 30523, 30328, 30633, - 10002, 9929, 9949, 9877, 9791, 9832, 8843, 8941, 8876, 10752, 11024, 10134, 11402, - 11409, 11384, 8867, 9051, 8845, 8867, 8845, 8690, 32047, 32021, 32094, 31675, 31796, - 31738, 34079, 33795, 33388, 32066, 32047, 32094, 34785, 34991, 35009, 39790, 39714, 39768, - 17030, 17021, 16747, 15023, 15277, 15041, 25190, 25185, 25249, 25148, 25210, 25156, 24729, - 24665, 24580, 267, 1567, 1377, 723, 1015, 861, 12697, 12583, 12699, 29090, 29385, - 29077, 28357, 28320, 28272, 42342, 42499, 42276, 42472, 42499, 42342, 18288, 18256, 18282, - 18394, 18256, 18288, 32763, 32718, 32846, 40723, 40739, 40599, 305, 184, 301, 158, - 184, 305, 25469, 25562, 25517, 27891, 27760, 27866, 25508, 25562, 25469, 30749, 30523, - 30882, 43579, 43108, 43477, 4157, 3585, 4001, 4857, 4685, 4861, 4159, 4103, 4264, - 32543, 32233, 32549, 31796, 32032, 31986, 32452, 32560, 32400, 38139, 38120, 38197, 98, - 29, 163, 96, 380, 200, 43569, 43574, 43477, 43619, 43574, 43569, 528, 488, - 610, 405, 488, 432, 42489, 42378, 43084, 17030, 16747, 16578, 24506, 24637, 24565, - 23097, 22653, 22872, 23538, 24067, 23722, 34502, 34711, 34592, 34279, 34044, 34167, 39647, - 39531, 39585, 39312, 39263, 39317, 43892, 43770, 43858, 43722, 43697, 43858, 6058, 5992, - 6043, 6058, 6043, 6130, 36010, 36061, 36248, 36326, 36276, 36181, 42275, 42093, 42315, - 42104, 41826, 42039, 42835, 42864, 42725, 42454, 42411, 42446, 42454, 42385, 42411, 42411, - 42385, 42315, 32032, 32163, 31986, 40914, 40950, 40804, 41025, 41031, 40950, 40950, 41031, - 40860, 41126, 41490, 40541, 41534, 41746, 41180, 245, 253, 338, 211, 253, 245, - 4393, 4497, 4496, 3192, 3713, 3780, 6783, 6596, 7035, 6552, 6596, 6783, 7699, - 7650, 7826, 28717, 28258, 28761, 29375, 29359, 29654, 27882, 28018, 28068, 27180, 27066, - 27013, 2468, 2433, 2506, 2740, 2853, 2785, 32589, 32543, 32549, 32884, 32763, 32846, - 40531, 40586, 40599, 40954, 40914, 40804, 40488, 40586, 40531, 40161, 39753, 39977, 184, - 105, 301, 6205, 6058, 6130, 36248, 36061, 36223, 38363, 38233, 38380, 38197, 38120, - 38263, 39921, 39888, 39816, 39647, 39423, 39531, 40016, 40249, 40569, 42835, 42948, 43019, - 43019, 42948, 43032, 43413, 43418, 43414, 43528, 43448, 43443, 43536, 43637, 43385, 43418, - 43413, 43509, 43872, 43601, 43522, 43599, 43579, 43574, 8695, 8552, 8564, 8159, 8001, - 8051, 8747, 8552, 8695, 9265, 9364, 9278, 40101, 40161, 39977, 39784, 39695, 39617, - 14957, 14816, 14943, 14943, 14816, 14762, 15043, 15139, 15362, 26086, 26351, 25893, 43099, - 43111, 43047, 43232, 43111, 43099, 43152, 43372, 43342, 11384, 11409, 11429, 11014, 10846, - 10857, 30285, 30020, 30355, 2785, 3002, 2705, 3499, 3984, 3758, 17534, 17449, 17495, - 16311, 16149, 16380, 23221, 23689, 23560, 24973, 24637, 24946, 39865, 39784, 39851, 43528, - 43443, 43525, 43525, 43443, 43441, 16311, 16380, 16507, 40954, 40804, 40947, 9278, 9364, - 9412, 32992, 32851, 32745, 33576, 33628, 33556, 34167, 34044, 33986, 40161, 40381, 39707, - 7284, 7415, 7343, 7640, 7644, 7776, 34809, 34711, 34502, 34478, 34502, 34440, 36015, - 35881, 36043, 43873, 43647, 43893, 43794, 43844, 43804, 43804, 43818, 43667, 43787, 43872, - 43522, 19254, 18830, 19068, 18256, 17995, 17962, 23824, 23934, 23560, 12501, 12821, 12510, - 11747, 11690, 11516, 12821, 13051, 12510, 29572, 29375, 29654, 29090, 29077, 29050, 29044, - 28938, 28743, 43893, 43647, 43725, 1591, 1431, 1483, 1371, 1341, 1482, 30778, 30496, - 30675, 30675, 30496, 30557, 31073, 30985, 30866, 31198, 31128, 31213, 31541, 31213, 31570, - 31541, 31570, 31847, 34025, 33986, 33862, 41490, 41126, 41682, 41586, 41682, 41803, 41824, - 42000, 41610, 2416, 2653, 2425, 903, 1204, 1047, 27013, 27066, 26934, 43136, 43019, - 43160, 11965, 11690, 11747, 29924, 29870, 30020, 30020, 29870, 29866, 43844, 43818, 43804, - 4416, 4419, 4528, 4528, 4569, 4533, 6243, 6288, 6260, 6260, 6288, 6418, 4302, - 4419, 4416, 4302, 4348, 4255, 40431, 40488, 40463, 40947, 40745, 40739, 17958, 17995, - 18256, 32525, 32543, 32640, 32047, 32116, 31827, 32452, 32400, 32260, 9929, 9839, 9877, - 10109, 10752, 10134, 16521, 16311, 16507, 41586, 41746, 41534, 253, 250, 416, 229, - 250, 253, 43160, 43019, 43032, 43205, 43152, 43342, 43891, 43725, 43507, 25210, 25443, - 25431, 26945, 26917, 26830, 24580, 24665, 24274, 43574, 43579, 43477, 43232, 43205, 43251, - 43446, 43532, 43815, 43618, 43629, 43387, 43520, 43525, 43441, 1436, 1482, 1496, 1482, - 1341, 1429, 686, 737, 815, 9940, 9839, 9929, 35471, 35441, 35237, 4375, 4393, - 4496, 4103, 3957, 4239, 6418, 6370, 6484, 5862, 5501, 5485, 8517, 8564, 8552, - 8517, 8437, 8564, 33607, 33435, 33400, 33846, 33628, 33655, 35641, 35881, 35537, 39423, - 39317, 39428, 40574, 40431, 40409, 40381, 40431, 40186, 40031, 40101, 39977, 39531, 39423, - 39428, 39647, 39585, 39714, 902, 1127, 1288, 815, 737, 818, 8263, 8190, 8381, - 12132, 12030, 12291, 13108, 13078, 13233, 26830, 26917, 26934, 26086, 25893, 25903, 33846, - 34025, 33862, 40083, 39888, 39921, 39790, 39888, 39893, 43125, 43206, 43049, 43513, 43520, - 43411, 43013, 43147, 43024, 43179, 43147, 43013, 3002, 3085, 2705, 5940, 5449, 5817, - 5279, 5317, 5285, 5225, 5177, 5257, 5116, 5005, 5051, 5051, 4967, 4946, 4946, - 4890, 4857, 4857, 4694, 4685, 4685, 4557, 4630, 37531, 37604, 37469, 37012, 37308, - 37069, 37193, 37308, 37012, 37023, 36835, 36921, 36835, 36729, 36921, 36729, 36973, 36921, - 36692, 36810, 36729, 36690, 36810, 36692, 37464, 37360, 37342, 37262, 37130, 37117, 37117, - 37078, 36980, 37464, 37342, 37590, 37554, 37569, 37590, 37569, 37947, 37590, 5216, 5177, - 5225, 37360, 37130, 37262, 37774, 37911, 37826, 686, 930, 934, 487, 976, 796, - 887, 871, 1058, 13295, 13488, 13475, 28241, 28202, 28104, 28241, 28104, 28018, 27760, - 27516, 27638, 5177, 5117, 5257, 37130, 37078, 37117, 35009, 34991, 35077, 36552, 36507, - 36367, 37513, 37506, 37389, 32164, 32066, 32094, 9281, 9278, 9412, 8456, 8517, 8552, - 43818, 43843, 43645, 581, 735, 729, 488, 405, 625, 37, 20, 105, 43124, - 42864, 42835, 42817, 42814, 42510, 42880, 42864, 43005, 5117, 5005, 5116, 36485, 36552, - 36367, 37826, 37911, 37934, 37506, 37604, 37531, 8001, 7925, 8051, 4210, 4255, 4199, - 4210, 4302, 4255, 6288, 6370, 6418, 8690, 8845, 8684, 8198, 8385, 8222, 40292, - 40381, 40161, 40723, 40599, 40586, 5005, 4967, 5051, 12800, 12947, 13072, 14309, 14433, - 14303, 12434, 12523, 12116, 25343, 25443, 25210, 28769, 28761, 29375, 28769, 28717, 28761, - 28357, 28705, 28497, 42515, 42532, 42679, 42613, 42532, 42446, 42386, 42275, 42315, 105, - 20, 628, 37, 105, 184, 6427, 6883, 6986, 16521, 16715, 16733, 16733, 16715, - 16916, 24949, 25027, 25008, 25101, 25027, 24949, 4967, 4890, 4946, 36365, 36485, 36367, - 11427, 11802, 11754, 10857, 10846, 10764, 32426, 32315, 32233, 32951, 32992, 32745, 32163, - 32306, 32260, 32067, 32306, 32163, 32067, 32163, 32032, 32067, 32032, 31796, 31675, 31738, - 31612, 31332, 30986, 31280, 42104, 42115, 42266, 42104, 42039, 42115, 41065, 40788, 40925, - 42079, 42000, 41824, 14303, 14433, 14440, 14949, 15023, 15041, 13633, 13719, 13434, 43892, - 43409, 43256, 43892, 43412, 43770, 250, 274, 416, 204, 274, 250, 12195, 12030, - 12132, 9933, 9940, 9997, 12234, 12291, 12393, 13185, 13108, 13228, 14957, 15043, 15074, - 14957, 15074, 14846, 16073, 15876, 16311, 15143, 15023, 14733, 36365, 36326, 36485, 38144, - 38018, 38139, 42487, 42315, 42385, 43152, 43205, 43099, 43039, 43372, 43152, 7230, 7284, - 7343, 7511, 7505, 7640, 35009, 35077, 35174, 33069, 32846, 33130, 32763, 32698, 32589, - 32543, 32426, 32233, 96, 200, 134, 34672, 34551, 34538, 1591, 1560, 1431, 2537, - 2468, 2643, 9278, 9129, 9265, 9281, 9129, 9278, 29052, 29044, 28743, 30955, 30749, - 30882, 32854, 32884, 33069, 42515, 42454, 42446, 42499, 42774, 42345, 42465, 42472, 42342, - 43670, 43669, 43468, 43618, 43387, 43528, 43618, 43528, 43615, 4569, 4528, 4419, 5485, - 5501, 5387, 6288, 6270, 6370, 37078, 36593, 36980, 36485, 36326, 36267, 1051, 1168, - 1419, 8437, 8263, 8381, 8190, 8001, 8159, 8747, 8695, 8843, 32525, 32426, 32543, - 32306, 32452, 32260, 40782, 40907, 40683, 41065, 40925, 41072, 41123, 41099, 41031, 40723, - 40586, 40488, 42266, 42115, 42171, 33628, 33846, 33756, 34025, 34167, 33986, 34279, 34478, - 34440, 34711, 35199, 34645, 33607, 33400, 33488, 40174, 40292, 40161, 39784, 40031, 39827, - 39865, 40031, 39784, 26917, 27013, 26934, 26945, 27013, 26917, 18830, 18394, 18548, 17099, - 17242, 17449, 24053, 23934, 24134, 43670, 43468, 43637, 16715, 16521, 16507, 17534, 17636, - 17995, 25027, 25127, 25148, 25443, 25508, 25469, 25101, 25127, 25027, 36267, 36248, 36223, - 36267, 36326, 36248, 41746, 41898, 41824, 41490, 41586, 41534, 41099, 41126, 41031, 43513, - 43411, 43418, 25478, 25508, 25443, 581, 464, 392, 557, 392, 458, 464, 581, - 818, 7993, 8001, 8190, 7925, 7838, 7826, 28357, 28660, 28705, 29052, 29090, 29044, - 27396, 27373, 27180, 34053, 34167, 34025, 39821, 39790, 39893, 39888, 39790, 39768, 3173, - 3467, 3216, 4302, 4192, 4419, 28019, 28241, 28018, 43843, 43872, 43787, 43767, 43906, - 43588, 1341, 1051, 1419, 1485, 1436, 1496, 1371, 1328, 1286, 42864, 42880, 42725, - 42532, 42515, 42446, 43136, 42835, 43019, 9776, 9940, 9872, 12510, 12234, 12393, 13228, - 13108, 13233, 14192, 14495, 14437, 4444, 4557, 4685, 3885, 3957, 4103, 9997, 9940, - 9929, 9839, 9791, 9877, 11965, 11747, 12030, 39312, 39317, 39423, 38120, 38233, 38263, - 38197, 38144, 38139, 10425, 10846, 10447, 10425, 10447, 9890, 34878, 34770, 34898, 34898, - 34770, 34724, 39337, 39312, 39424, 39150, 39330, 39261, 39357, 39150, 39033, 16578, 16747, - 16686, 16578, 16686, 16423, 24067, 24580, 24274, 43498, 43277, 43350, 43857, 43532, 43736, - 11427, 11754, 11409, 11427, 11409, 11402, 1485, 1496, 1665, 2539, 2537, 2643, 2544, - 2643, 2740, 32734, 32710, 32656, 34574, 34405, 34551, 34551, 34405, 34386, 39821, 39647, - 39714, 39521, 39285, 39261, 27287, 27396, 27180, 9776, 9791, 9839, 15043, 14957, 14943, - 15043, 15362, 15074, 36223, 36061, 36015, 35262, 35199, 35276, 43205, 43232, 43099, 43039, - 43277, 43372, 43147, 43206, 43125, 43333, 43206, 43147, 43803, 43670, 43637, 43858, 43697, - 43694, 43691, 43536, 43629, 28717, 28451, 28056, 25249, 25372, 25505, 29401, 28769, 29375, - 35641, 35537, 35507, 38263, 38233, 38362, 42613, 42446, 42625, 42454, 42487, 42385, 42242, - 42124, 42104, 30778, 30675, 30866, 29674, 29572, 29654, 30985, 31073, 31128, 32116, 32047, - 32066, 32164, 32094, 32315, 35507, 35537, 35441, 42242, 41930, 41977, 41977, 41930, 41675, - 42124, 41977, 42104, 43858, 43694, 43842, 29, 96, 134, 25185, 25190, 24946, 24156, - 24053, 24134, 25249, 25185, 25372, 25249, 25505, 25646, 43509, 43413, 43879, 43615, 43528, - 43525, 32393, 32164, 32315, 32507, 32315, 32426, 40918, 40907, 40782, 41072, 41077, 41427, - 41025, 40950, 40914, 41025, 40914, 40954, 40723, 40488, 40623, 36043, 36223, 36015, 38362, - 38233, 38363, 432, 528, 378, 432, 488, 528, 11146, 11248, 11368, 30496, 30285, - 30355, 40174, 40161, 40101, 40174, 40101, 40054, 29674, 29654, 29806, 32656, 32710, 32560, - 40875, 40723, 40861, 43615, 43525, 43608, 39708, 39784, 39617, 12234, 12195, 12132, 12493, - 12510, 12701, 28841, 28743, 28705, 29044, 29090, 29050, 30959, 30986, 30749, 42563, 42487, - 42454, 42363, 41941, 41711, 42472, 42579, 42499, 42472, 42465, 42574, 7303, 7511, 7284, - 7303, 7505, 7511, 7230, 7343, 7027, 17958, 17534, 17995, 24100, 24053, 24156, 34770, - 34672, 34538, 34784, 34672, 34770, 4159, 4264, 4393, 2705, 3085, 2767, 36005, 36043, - 35881, 35471, 35507, 35441, 32992, 33234, 33189, 34346, 34279, 34167, 33279, 33234, 33118, - 5594, 5977, 5706, 6596, 6205, 6570, 5964, 6205, 6148, 13666, 13633, 13498, 14433, - 14575, 14949, 13633, 13434, 13498, 28241, 28272, 28320, 27891, 28019, 28018, 28081, 28019, - 27891, 38380, 38687, 38911, 40989, 41025, 40954, 42959, 42814, 42817, 42515, 42563, 42454, - 42840, 42814, 42894, 12701, 12510, 13051, 13475, 13488, 14054, 28332, 28272, 28241, 42840, - 42757, 42625, 274, 116, 799, 211, 229, 253, 165, 229, 211, 581, 557, - 735, 845, 934, 960, 8001, 7838, 7925, 7993, 7838, 8001, 12583, 12697, 12523, - 11385, 11427, 11402, 39654, 39708, 39617, 39766, 39708, 39654, 42406, 42171, 42275, 25190, - 24973, 24946, 27305, 27511, 27569, 43608, 43525, 43520, 43894, 43509, 43879, 43872, 43884, - 43767, 42757, 42613, 42625, 5216, 5143, 5177, 5177, 5143, 5117, 4940, 4916, 5005, - 5005, 4916, 4967, 4967, 4809, 4890, 4890, 4694, 4857, 5940, 5863, 5449, 14596, - 14495, 14816, 5279, 5143, 5216, 5449, 5863, 5444, 37078, 37168, 36593, 37130, 37154, - 37078, 37360, 37300, 37130, 37464, 37421, 37360, 37678, 37421, 37464, 37452, 37421, 37488, - 37947, 37569, 37826, 37934, 37911, 37964, 37911, 38144, 37964, 38144, 38207, 37964, 6370, - 6427, 6484, 6243, 6270, 6288, 12076, 12195, 12234, 11965, 12195, 12076, 17534, 17395, - 17449, 17529, 17395, 17534, 29572, 29401, 29375, 29625, 29401, 29572, 30959, 30749, 30955, - 32552, 32510, 32452, 32452, 32510, 32560, 32893, 32745, 32734, 32893, 32951, 32745, 36005, - 35881, 35801, 37300, 37154, 37130, 35174, 35077, 35296, 37953, 37608, 37588, 37506, 37560, - 37604, 37308, 37513, 37389, 37023, 37193, 37012, 37039, 37193, 37023, 37039, 37023, 36921, - 37039, 36921, 36973, 36729, 36834, 36973, 36810, 36834, 36729, 36737, 36834, 36810, 36737, - 36810, 36690, 36737, 36690, 36618, 37580, 37513, 37308, 38144, 38197, 38317, 38907, 38687, - 38852, 42487, 42386, 42315, 42522, 42386, 42487, 43788, 43691, 43629, 43608, 43520, 43894, - 3957, 3910, 4239, 3750, 3910, 3885, 4413, 4496, 4557, 10857, 11146, 11368, 11248, - 11385, 11402, 9890, 10348, 9888, 35801, 35881, 35641, 35424, 35471, 35237, 35424, 35237, - 35199, 39334, 38907, 38814, 39337, 39263, 39312, 31847, 31650, 31827, 30151, 30020, 30285, - 5444, 5863, 5480, 36618, 36690, 36552, 37513, 37560, 37506, 32698, 32543, 32589, 32164, - 32116, 32066, 32698, 32763, 32854, 32552, 32452, 32306, 41023, 40907, 40918, 40875, 40739, - 40723, 40875, 40947, 40739, 31198, 30985, 31128, 29806, 29654, 29870, 30328, 29668, 29927, - 4940, 5005, 5117, 36485, 36618, 36552, 31645, 31675, 31612, 7027, 7343, 6883, 7557, - 7549, 7413, 7505, 7549, 7640, 36531, 35646, 36593, 39330, 39521, 39261, 39530, 39521, - 39330, 12523, 11978, 12116, 42574, 42579, 42472, 42574, 42465, 42621, 1436, 1371, 1482, - 902, 845, 960, 2506, 2433, 1725, 10674, 10764, 10846, 30985, 30778, 30866, 40574, - 40488, 40431, 40054, 40101, 40031, 40026, 40031, 39865, 40026, 39865, 39961, 36485, 36267, - 36569, 78, 37, 184, 458, 528, 535, 42945, 42378, 42531, 43206, 43376, 43050, - 39851, 39784, 39708, 4157, 4210, 4199, 4001, 4210, 4157, 6270, 6427, 6370, 36301, - 36267, 36223, 43305, 43669, 43817, 43842, 43305, 43817, 16521, 16244, 16311, 14205, 14075, - 14192, 16426, 16244, 16521, 16091, 15986, 15622, 16578, 16283, 16091, 18394, 17958, 18256, - 24100, 23560, 23934, 24100, 23934, 24053, 25903, 25893, 25562, 27013, 27287, 27180, 25127, - 25343, 25210, 25101, 25343, 25127, 25903, 25562, 25781, 27396, 27638, 27516, 35801, 35641, - 35627, 35262, 35424, 35199, 34478, 34279, 34346, 39424, 39312, 39423, 39790, 39821, 39714, - 40083, 39921, 39975, 43160, 43032, 43111, 43505, 43318, 43606, 8117, 8263, 8118, 8337, - 8263, 8437, 9309, 9281, 9412, 32126, 32116, 32248, 32854, 32763, 32884, 33130, 33260, - 33069, 34722, 34551, 34672, 32629, 32656, 32560, 32629, 32560, 32510, 40431, 40381, 40409, - 17099, 16916, 17117, 16426, 16515, 16314, 25142, 24973, 25190, 38197, 38263, 38317, 43730, - 43599, 43574, 43730, 43574, 43619, 43711, 43629, 43618, 43864, 43608, 43894, 43711, 43864, - 43788, 32507, 32426, 32525, 31817, 32067, 31796, 788, 845, 781, 778, 871, 730, - 903, 871, 778, 11844, 11978, 11802, 11844, 11752, 11885, 40409, 40381, 40292, 11433, - 11802, 11427, 29924, 30020, 30064, 11028, 11146, 10857, 42956, 42945, 42531, 26832, 26945, - 26830, 37953, 37588, 37604, 37168, 36531, 36593, 38385, 38263, 38362, 13381, 13185, 13228, - 13363, 13185, 13381, 7230, 7303, 7284, 7092, 7303, 7230, 35009, 34878, 34898, 34784, - 34878, 35042, 39424, 39423, 39494, 557, 458, 535, 378, 458, 342, 7549, 7644, - 7640, 7557, 7644, 7549, 14192, 14075, 14054, 14846, 14816, 14957, 34053, 34025, 33846, - 33400, 33189, 33279, 33234, 32992, 33118, 39521, 39592, 39654, 39551, 39592, 39521, 41137, - 41025, 40989, 41137, 41123, 41025, 41025, 41123, 41031, 41682, 41586, 41490, 4332, 4569, - 4419, 6110, 6260, 6259, 6270, 6301, 6427, 28769, 28662, 28717, 28894, 28662, 28769, - 28894, 28769, 29401, 29090, 29324, 29385, 28532, 28660, 28357, 28841, 28660, 28532, 28357, - 28272, 28447, 43711, 43618, 43615, 11254, 11385, 11248, 31988, 31827, 32116, 33069, 33260, - 33026, 32726, 32893, 32734, 32726, 32734, 32656, 639, 405, 352, 158, 639, 9, - 8747, 8876, 8902, 7838, 7699, 7826, 40569, 40305, 40557, 39669, 39423, 39647, 40513, - 40409, 40292, 40026, 40054, 40031, 40267, 40054, 40026, 33279, 33189, 33234, 27321, 27287, - 27013, 43255, 43111, 43232, 42713, 42613, 42832, 42679, 42532, 42613, 11885, 12116, 11844, - 11844, 12116, 11978, 229, 204, 250, 152, 204, 229, 26086, 26266, 26351, 27220, - 27321, 27013, 26077, 26266, 26086, 40964, 40569, 40557, 41065, 41023, 40918, 41060, 41023, - 41065, 41087, 41255, 41427, 8054, 7993, 8190, 39965, 39893, 39888, 39799, 39851, 39708, - 2680, 2587, 2690, 3137, 3173, 3216, 1211, 2425, 1882, 8902, 8876, 9129, 12743, - 12583, 12546, 12434, 12583, 12523, 12978, 13072, 12947, 28865, 29052, 28743, 33022, 32992, - 32951, 40574, 40623, 40488, 40875, 40989, 40947, 40513, 40292, 40546, 42648, 42563, 42515, - 42386, 42406, 42275, 42840, 42625, 42814, 352, 405, 432, 43884, 43906, 43767, 28647, - 28451, 28662, 30064, 30020, 30151, 30985, 31039, 30778, 30151, 30285, 30585, 31541, 31198, - 31213, 31197, 31198, 31578, 31332, 31645, 31315, 31675, 31817, 31796, 30959, 31280, 30986, - 30955, 31280, 30959, 39669, 39647, 39821, 39055, 38911, 38907, 38413, 38385, 38486, 38486, - 38385, 38362, 1485, 1483, 1336, 902, 1288, 1168, 4424, 4413, 4557, 36333, 36301, - 36223, 36333, 36223, 36183, 32552, 32629, 32510, 31597, 31645, 31332, 7413, 7549, 7505, - 6952, 7027, 6805, 10860, 11028, 10857, 11146, 11254, 11248, 10425, 10674, 10846, 10764, - 10674, 10759, 43200, 43179, 43013, 43200, 43013, 43112, 40051, 39669, 39821, 39592, 39766, - 39654, 39698, 39766, 39592, 31988, 31847, 31827, 32640, 32543, 32698, 31653, 31817, 31675, - 34518, 34162, 34405, 32626, 32640, 32698, 33118, 33022, 32898, 32893, 33022, 32951, 40699, - 40623, 40689, 8964, 8902, 9129, 9570, 9412, 9504, 9673, 9832, 9791, 9776, 9839, - 9940, 8867, 9325, 9253, 9395, 9325, 9221, 32507, 32640, 32626, 32552, 32306, 32554, - 13185, 13207, 13108, 13423, 13475, 13651, 42959, 42817, 42880, 43005, 42959, 42880, 16283, - 16578, 16423, 15852, 15767, 15622, 24580, 25101, 24949, 25606, 25562, 25508, 4413, 4375, - 4496, 38911, 38687, 38907, 41803, 41898, 41746, 41803, 41746, 41586, 43606, 43230, 43579, - 43279, 43124, 43136, 43606, 43579, 43679, 27447, 27638, 27396, 28660, 28841, 28705, 27447, - 27396, 27287, 28662, 28451, 28717, 29625, 29572, 29674, 43114, 43005, 42864, 43124, 42835, - 43136, 11024, 11516, 10134, 29924, 29806, 29870, 29886, 29806, 29924, 10860, 10857, 10764, - 11385, 11433, 11427, 39334, 38896, 39337, 3085, 3050, 2767, 2537, 2286, 2394, 3750, - 3758, 3910, 4375, 4253, 4393, 6427, 6689, 6883, 6110, 6259, 5862, 14114, 14303, - 14079, 13940, 13816, 13852, 29713, 29668, 29385, 28532, 28357, 28447, 33370, 33488, 33279, - 33279, 33488, 33400, 34129, 34053, 34094, 34784, 34722, 34672, 34784, 34770, 34878, 39622, - 39530, 39330, 42444, 42406, 42386, 42713, 42679, 42613, 43251, 43205, 43342, 42945, 43084, - 42378, 43216, 43357, 43301, 7993, 7699, 7838, 8117, 8054, 8190, 8117, 8190, 8263, - 33655, 33628, 33607, 35507, 35471, 35627, 39893, 40039, 39821, 40083, 39965, 39888, 40039, - 39965, 40059, 43817, 43669, 43670, 71, 165, 211, 871, 887, 730, 9776, 9673, - 9791, 26663, 26832, 26351, 25606, 25508, 25478, 43384, 43251, 43342, 32742, 32726, 32656, - 33544, 33655, 33488, 32898, 32726, 32742, 41682, 41126, 41526, 40699, 40861, 40723, 5313, - 5203, 5285, 5285, 5203, 5279, 5279, 5199, 5143, 5076, 4940, 5117, 4916, 4809, - 4967, 4413, 4424, 4375, 3999, 4159, 4253, 5313, 5285, 5449, 5338, 5313, 5449, - 37154, 37168, 37078, 37452, 37300, 37360, 37211, 37300, 37408, 37360, 37421, 37452, 38033, - 37934, 38088, 11098, 11254, 11146, 12743, 12699, 12583, 40964, 40683, 40907, 3039, 3173, - 2951, 15074, 15362, 15201, 16733, 16426, 16521, 17099, 17449, 17395, 39780, 39799, 39766, - 39766, 39799, 39708, 39851, 39961, 39865, 40546, 40292, 40174, 40409, 40513, 40574, 40623, - 40699, 40723, 5076, 5117, 5143, 5313, 5338, 5249, 5385, 5444, 5480, 36974, 36973, - 36834, 36974, 37030, 36973, 36973, 37030, 37039, 37039, 37030, 37193, 37193, 37580, 37308, - 37513, 37580, 37560, 39232, 39033, 39118, 36974, 36834, 36737, 29806, 29625, 29674, 29886, - 29625, 29806, 42522, 42487, 42563, 42124, 42242, 41977, 6243, 6301, 6270, 36720, 36974, - 36737, 35641, 35507, 35627, 35471, 35732, 35627, 96, 71, 339, 25478, 25443, 25343, - 40989, 40954, 40947, 302, 352, 432, 378, 528, 458, 845, 788, 934, 902, - 678, 829, 36618, 36485, 36569, 42579, 42590, 42499, 42363, 41711, 42000, 43255, 43160, - 43111, 43216, 43200, 43112, 43473, 43376, 43206, 3885, 3910, 3957, 4842, 4809, 4916, - 43608, 43711, 43615, 43801, 43803, 43637, 43711, 43608, 43864, 11376, 11433, 11385, 17958, - 17529, 17534, 24565, 24100, 24156, 30285, 30496, 30585, 42266, 42242, 42104, 12978, 12947, - 12868, 12947, 12699, 12743, 42696, 42648, 42679, 42959, 42911, 42814, 42987, 42911, 42959, - 42894, 42911, 42985, 43119, 42864, 43124, 3563, 3499, 3758, 39462, 39424, 39494, 39462, - 39337, 39424, 39462, 39334, 39337, 39268, 39357, 39033, 39530, 39551, 39521, 4809, 4694, - 4890, 13475, 13363, 13381, 10134, 11516, 10013, 13423, 13363, 13475, 13207, 13363, 13309, - 7644, 8022, 7994, 7413, 7505, 7303, 7413, 7303, 7313, 34722, 34574, 34551, 34721, - 34574, 34722, 39698, 39551, 39660, 13852, 13816, 13633, 43251, 43255, 43232, 43466, 43372, - 43277, 43333, 43147, 43179, 32640, 32507, 32525, 32626, 32698, 32821, 33026, 32854, 33069, - 33370, 33279, 33118, 32554, 32306, 32067, 40861, 40989, 40875, 41335, 40989, 40861, 1591, - 1485, 1665, 2286, 2433, 2394, 25903, 26071, 26086, 25961, 26071, 25903, 9997, 10109, - 9973, 9668, 9570, 9673, 2627, 2544, 2740, 2767, 3050, 2823, 12583, 12434, 12546, - 29198, 29090, 29052, 28081, 28241, 28019, 32992, 33022, 33118, 33488, 33655, 33607, 36569, - 36267, 36535, 8118, 8263, 8337, 5469, 5594, 5522, 8437, 8517, 8456, 1286, 1341, - 1371, 871, 903, 1047, 1567, 1423, 1882, 487, 796, 320, 16202, 16311, 16244, - 26663, 26351, 26266, 27866, 28081, 27891, 31597, 31653, 31645, 31645, 31653, 31675, 31817, - 31944, 32067, 28865, 28743, 28841, 42214, 42363, 42000, 41126, 41099, 41526, 41099, 41123, - 41526, 43401, 43255, 43251, 43219, 43119, 43279, 31597, 31332, 31298, 818, 737, 464, - 392, 557, 581, 27349, 27447, 27287, 43114, 43119, 43219, 2512, 2544, 2627, 33022, - 32893, 32898, 42648, 42515, 42679, 42348, 42171, 42406, 42348, 42266, 42171, 1328, 1371, - 1436, 36535, 36267, 36458, 39799, 39848, 39851, 39954, 39848, 39799, 43784, 43730, 43619, - 43556, 43384, 43372, 43801, 43637, 43691, 4210, 4192, 4302, 2750, 4001, 3585, 36535, - 36720, 36569, 35199, 34711, 35276, 34502, 34684, 34809, 12021, 12434, 12116, 29026, 28894, - 29401, 28451, 28386, 28029, 28829, 28894, 29026, 29035, 28865, 28841, 42613, 42757, 42832, - 42594, 42590, 42579, 43084, 43216, 43112, 42594, 42579, 42574, 43906, 43857, 43736, 8964, - 9129, 9123, 9129, 9281, 9123, 9570, 9504, 9673, 32898, 32893, 32726, 39460, 39462, - 39494, 39334, 39478, 38907, 43311, 43333, 43179, 43355, 43084, 43315, 41427, 41483, 41414, - 41427, 41731, 41581, 41023, 41057, 40907, 34502, 34478, 34684, 165, 152, 229, 75, - 152, 165, 3837, 3885, 4103, 4444, 4424, 4557, 11752, 11844, 11802, 26071, 26077, - 26086, 26168, 26077, 26071, 38413, 38317, 38263, 38413, 38263, 38385, 38362, 38506, 38486, - 42079, 41824, 41898, 43109, 43114, 43219, 43372, 43384, 43342, 43498, 43350, 43505, 43749, - 43579, 43599, 902, 781, 845, 829, 781, 902, 730, 887, 654, 29058, 29198, - 29052, 42308, 42079, 41898, 43822, 43817, 43670, 43788, 43801, 43691, 43788, 43629, 43711, - 9668, 9673, 9776, 13666, 13852, 13633, 13369, 13498, 13434, 13369, 13434, 13191, 27866, - 27760, 27638, 29035, 29058, 28865, 28865, 29058, 29052, 42911, 42894, 42814, 42987, 42959, - 43005, 43114, 42864, 43119, 116, 274, 204, 13828, 13852, 13695, 13940, 14114, 14079, - 15143, 15399, 15023, 27823, 27866, 27638, 27514, 27638, 27447, 27514, 27447, 27523, 13363, - 13207, 13185, 13475, 14054, 13651, 28482, 28386, 28451, 25142, 24565, 24973, 24973, 24565, - 24637, 27569, 27695, 27904, 25606, 25781, 25562, 25478, 25781, 25606, 32742, 32656, 32629, - 32742, 32629, 32552, 43520, 43513, 43894, 43311, 43179, 43200, 43905, 43498, 43505, 38486, - 38506, 39040, 39965, 40039, 39893, 40059, 39965, 40083, 40059, 40280, 40066, 39954, 39961, - 39848, 39848, 39961, 39851, 39698, 39592, 39551, 13917, 14114, 13940, 27904, 27695, 28029, - 27013, 26945, 27053, 43124, 43279, 43119, 11433, 11583, 11802, 11254, 11376, 11385, 11151, - 11376, 11254, 11098, 11146, 11028, 10860, 10764, 10759, 30064, 29886, 29924, 28829, 28647, - 28662, 30585, 30496, 30778, 31039, 30985, 31198, 31039, 31198, 31197, 7092, 7230, 7027, - 7857, 8022, 7644, 28829, 28662, 28894, 33795, 34079, 34162, 35061, 34878, 35009, 35077, - 35425, 35296, 34684, 34586, 34849, 42627, 42522, 42563, 42904, 42757, 42840, 42590, 42774, - 42499, 43301, 43311, 43200, 42766, 42774, 42590, 2512, 2539, 2544, 2544, 2539, 2643, - 2336, 2539, 2281, 40267, 40174, 40054, 41252, 41060, 41065, 3750, 3563, 3758, 2336, - 2537, 2539, 4159, 4393, 4253, 35725, 35627, 35732, 36267, 36301, 36458, 35934, 36133, - 36095, 43822, 43670, 43803, 35077, 35540, 35425, 39594, 39622, 39330, 39232, 39268, 39033, - 37668, 37604, 37560, 11885, 12021, 12116, 12743, 12868, 12947, 11738, 12021, 11885, 6081, - 6110, 5961, 6243, 6222, 6301, 6301, 6226, 6427, 5485, 5387, 5039, 38413, 38486, - 38505, 16299, 16202, 16244, 16314, 16244, 16426, 27053, 26945, 26832, 267, 1377, 903, - 1211, 1423, 55, 43730, 43749, 43599, 43606, 43905, 43505, 43784, 43749, 43730, 12246, - 12546, 12434, 28562, 28841, 28532, 29198, 29324, 29090, 42598, 42594, 42574, 11376, 11583, - 11433, 31198, 31541, 31741, 31653, 31835, 31817, 31715, 31597, 31712, 31332, 31280, 31298, - 8902, 8818, 8747, 9123, 9281, 9309, 32930, 33026, 33293, 32126, 31988, 32116, 40689, - 40623, 40574, 42308, 41898, 42188, 13309, 13423, 13460, 15298, 15362, 15876, 32930, 32698, - 32854, 5249, 5203, 5313, 5249, 5199, 5203, 5203, 5199, 5279, 4940, 4842, 4916, - 4809, 4710, 4694, 4694, 4444, 4685, 5449, 5385, 5338, 1286, 1247, 1341, 1300, - 1328, 1436, 1300, 1436, 1485, 5199, 5076, 5143, 5449, 5444, 5385, 9973, 9933, - 9997, 9570, 9545, 9309, 11965, 12030, 12195, 31715, 31835, 31653, 41163, 41057, 41060, - 42558, 41930, 42650, 4113, 4192, 4210, 4113, 4210, 4001, 6110, 6222, 6243, 158, - 78, 184, 9, 78, 158, 9, 639, 92, 5977, 5594, 5863, 37300, 37211, - 37154, 37421, 37678, 37488, 38207, 38144, 38317, 38207, 38360, 38210, 37735, 37580, 37524, - 37524, 37193, 37030, 37043, 37030, 36974, 37043, 36974, 36720, 5992, 5706, 5977, 37211, - 37168, 37154, 37580, 37668, 37560, 35276, 35337, 35262, 34346, 34167, 34237, 34167, 34053, - 34237, 34053, 34129, 34237, 34094, 34053, 33846, 1248, 1247, 1286, 5992, 5666, 5706, - 5039, 5343, 4569, 6081, 6226, 6222, 6952, 7092, 7027, 10644, 10674, 10554, 11587, - 11614, 11583, 27097, 27053, 26988, 27220, 27053, 27097, 32116, 32164, 32248, 34518, 34405, - 34574, 35174, 35061, 35009, 35184, 35061, 35174, 36720, 36737, 36618, 36720, 36618, 36569, - 39268, 39307, 39357, 39283, 39307, 39268, 43333, 43473, 43206, 43301, 43200, 43216, 7400, - 7557, 7413, 8198, 8022, 7857, 9395, 9530, 9457, 13423, 13651, 13460, 12493, 12234, - 12510, 42894, 42883, 42840, 42980, 42883, 42894, 42774, 42956, 42531, 43043, 42956, 42865, - 28299, 27904, 28029, 25963, 25646, 25752, 28299, 28029, 28386, 43109, 43005, 43114, 43109, - 42987, 43005, 12021, 12246, 12434, 12183, 12246, 12021, 29165, 29324, 29198, 42627, 42563, - 42754, 42266, 42420, 42242, 42696, 42679, 42713, 4553, 4842, 4940, 4019, 4159, 3999, - 11614, 11752, 11802, 11614, 11802, 11583, 42468, 42348, 42406, 28665, 28482, 28647, 28647, - 28482, 28451, 28332, 28447, 28272, 29314, 29423, 29324, 28332, 28241, 28081, 28332, 28183, - 28389, 27523, 27638, 27514, 27349, 27287, 27321, 4253, 4375, 4111, 4192, 4332, 4419, - 4163, 4113, 4070, 43401, 43160, 43255, 16202, 16073, 16311, 16067, 16073, 16202, 15023, - 14949, 14575, 25961, 26168, 26071, 25101, 25478, 25343, 4842, 4710, 4809, 7699, 7993, - 7872, 9737, 9668, 9776, 10860, 11098, 11028, 37758, 37953, 37604, 41057, 40964, 40907, - 41057, 41023, 41060, 33655, 34094, 33846, 8814, 8818, 8902, 8814, 8902, 8964, 12917, - 12868, 12632, 12546, 12868, 12743, 13695, 13852, 13666, 13852, 13828, 13940, 29026, 29401, - 29568, 35934, 36005, 35801, 42793, 42696, 42713, 13260, 13309, 13460, 15441, 15298, 15876, - 43746, 43466, 43277, 43449, 43401, 43251, 43372, 43466, 43556, 27262, 27349, 27321, 17529, - 17099, 17395, 25142, 25190, 25249, 43552, 43123, 43376, 43801, 43822, 43803, 9395, 9457, - 9325, 35899, 35934, 35801, 35801, 35627, 35899, 42079, 42214, 42000, 42621, 42598, 42574, - 42308, 42214, 42079, 41123, 41137, 41526, 7092, 7252, 7303, 7313, 7252, 7151, 35061, - 35042, 34878, 35050, 35042, 35061, 39462, 39460, 39334, 39494, 39423, 39669, 13051, 13108, - 12701, 39622, 39551, 39530, 39961, 40267, 40026, 40513, 40689, 40574, 42537, 42444, 42386, - 41414, 41267, 41427, 42537, 42386, 42522, 43857, 43815, 43532, 778, 834, 903, 654, - 887, 526, 12701, 13108, 13207, 42594, 42766, 42590, 42621, 42465, 42363, 2336, 2286, - 2537, 2627, 2705, 2674, 32248, 32164, 32393, 33026, 32930, 32854, 34518, 34574, 34601, - 36458, 36301, 36333, 38207, 38317, 38360, 37964, 38210, 38088, 43359, 43301, 43480, 43311, - 43359, 43333, 16073, 15980, 15876, 16067, 15980, 16073, 8117, 8091, 8054, 8456, 8552, - 8577, 8577, 8552, 8747, 9221, 9325, 8867, 41252, 41065, 41267, 36223, 36043, 36183, - 9933, 9872, 9940, 10013, 11516, 11331, 34586, 34684, 34478, 36095, 36005, 35934, 33655, - 33926, 34094, 40109, 39954, 39799, 42883, 42904, 42840, 42987, 42985, 42911, 43081, 42985, - 42987, 43240, 42987, 43109, 13423, 13309, 13363, 14816, 14846, 14663, 13191, 13434, 12978, - 14282, 14433, 14309, 28463, 28299, 28386, 27385, 27140, 27569, 28463, 28386, 28482, 28447, - 28562, 28532, 27937, 28081, 27866, 42980, 42904, 42883, 42627, 42537, 42522, 10134, 9973, - 10109, 9668, 9577, 9570, 31597, 31715, 31653, 31835, 31944, 31817, 33488, 33370, 33544, - 31849, 31715, 31712, 378, 302, 432, 686, 934, 788, 10860, 10858, 11098, 11738, - 11885, 11752, 10554, 10674, 10425, 9865, 9888, 9519, 7252, 7313, 7303, 7362, 7313, - 7151, 15298, 15201, 15362, 15283, 15201, 15298, 40185, 39494, 39669, 38317, 38413, 38360, - 40066, 39821, 40039, 40280, 40127, 40066, 28575, 28562, 28447, 42937, 42832, 42757, 671, - 686, 788, 722, 829, 678, 730, 834, 778, 12246, 12318, 12546, 12917, 13191, - 12978, 11962, 12183, 12021, 11583, 11376, 11587, 29324, 29423, 29385, 29165, 29198, 29058, - 42420, 42266, 42348, 42563, 42648, 42754, 71, 75, 165, 40, 116, 204, 526, - 887, 723, 9910, 9872, 9933, 9890, 9865, 9859, 31849, 31944, 31835, 36183, 36043, - 36005, 10754, 10759, 10674, 8777, 9221, 8867, 9519, 9888, 9530, 11587, 11376, 11274, - 30232, 29886, 30064, 28829, 28828, 28647, 30232, 30064, 30151, 35077, 35646, 35540, 34721, - 34722, 34784, 39594, 39330, 39357, 39698, 39780, 39766, 39310, 39232, 39118, 1248, 1286, - 1328, 3050, 3178, 2823, 3885, 3773, 3750, 4019, 3837, 4103, 4019, 4103, 4159, - 7872, 7993, 8054, 34721, 34784, 34786, 39811, 39780, 39698, 40699, 40802, 40861, 40783, - 40689, 40881, 16515, 16426, 16733, 15980, 15924, 15876, 43749, 43679, 43579, 43776, 43679, - 43749, 753, 788, 781, 13260, 12701, 13207, 12493, 12076, 12234, 31741, 31541, 31847, - 30933, 30585, 30778, 32315, 32507, 32393, 16067, 15924, 15980, 25752, 25646, 25505, 27385, - 27569, 27552, 30933, 30778, 31039, 43848, 43784, 43619, 43788, 43822, 43801, 43864, 43822, - 43788, 27053, 27220, 27013, 27349, 27523, 27447, 27262, 27220, 27317, 3192, 3780, 3499, - 9737, 9577, 9668, 8463, 8337, 8456, 40016, 40569, 40609, 41358, 41252, 41267, 42468, - 42406, 42444, 3837, 3773, 3885, 3828, 3773, 3837, 1247, 1051, 1341, 1048, 1051, - 1247, 1300, 1485, 1336, 34237, 34242, 34346, 33370, 33409, 33544, 40569, 40964, 41253, - 7313, 7400, 7413, 9401, 9395, 9221, 7362, 7400, 7313, 9148, 9123, 9309, 29464, - 29713, 29385, 29464, 29385, 29423, 39431, 39357, 39307, 42544, 42468, 42444, 42659, 42444, - 42537, 29035, 29165, 29058, 36095, 36183, 36005, 35627, 35725, 35899, 42704, 42917, 42939, - 42598, 42766, 42594, 43357, 43216, 43084, 35296, 35184, 35174, 35322, 35184, 35296, 39232, - 39283, 39268, 39532, 39283, 39426, 40, 204, 152, 14068, 14309, 14114, 16314, 16299, - 16244, 16515, 16299, 16314, 37211, 37216, 37168, 37168, 36938, 36531, 37464, 37590, 37678, - 38033, 37826, 37934, 431, 464, 737, 5355, 5385, 5480, 5258, 5338, 5385, 5258, - 5262, 5338, 5338, 5262, 5249, 5249, 5179, 5199, 5199, 5179, 5076, 4553, 4620, - 4842, 4842, 4620, 4710, 4710, 4620, 4694, 5355, 5480, 5469, 37452, 37408, 37300, - 3173, 3039, 3585, 2951, 3173, 3137, 2951, 3137, 2941, 13309, 13260, 13207, 14770, - 14846, 15074, 13695, 13666, 13498, 12917, 12978, 12868, 13695, 13498, 13566, 37408, 37216, - 37211, 37668, 37758, 37604, 39088, 39118, 38651, 37580, 37693, 37668, 37735, 37693, 37580, - 37785, 37693, 37735, 37524, 37043, 36720, 36513, 36720, 36535, 36513, 36535, 36458, 36513, - 36458, 36450, 5469, 5480, 5594, 37693, 37758, 37668, 15014, 14770, 15074, 15014, 15074, - 15201, 15014, 15201, 15231, 43449, 43251, 43384, 43449, 43384, 43551, 4113, 4163, 4192, - 4070, 4113, 4001, 6222, 6226, 6301, 6202, 6226, 6179, 36450, 36458, 36333, 35424, - 35262, 35337, 5522, 5594, 5516, 392, 342, 458, 22, 342, 392, 12318, 12246, - 12183, 12525, 12868, 12546, 13917, 14068, 14114, 27445, 27523, 27349, 28747, 28841, 28562, - 28747, 29035, 28841, 42832, 42793, 42713, 42937, 42793, 42832, 42937, 42757, 42904, 42980, - 42894, 42985, 43279, 43136, 43160, 5992, 5756, 5666, 10013, 9984, 10134, 12033, 12076, - 12493, 12033, 12493, 12248, 29748, 29927, 29668, 29386, 29464, 29423, 29606, 29464, 29638, - 40689, 40802, 40699, 40783, 40802, 40689, 40267, 39961, 40223, 39961, 39954, 40109, 31741, - 31847, 32056, 39283, 39431, 39307, 39622, 39660, 39551, 39532, 39431, 39283, 1485, 1591, - 1483, 2956, 3192, 3499, 11151, 11254, 11098, 10644, 10754, 10674, 10467, 10554, 10425, - 33913, 33795, 34162, 34913, 34784, 35042, 39832, 39660, 39622, 4553, 4940, 5076, 38088, - 37934, 37964, 37964, 38207, 38210, 3773, 3563, 3750, 4111, 4375, 4424, 3918, 4070, - 4001, 11614, 11738, 11752, 10858, 10860, 10759, 29748, 29668, 29713, 42566, 42420, 42348, - 42566, 42348, 42468, 342, 302, 378, 730, 642, 834, 55, 1423, 1567, 526, - 248, 407, 9865, 9890, 9888, 9519, 9530, 9401, 26168, 26266, 26077, 27220, 27262, - 27321, 29568, 29401, 29625, 28829, 29026, 28871, 29568, 29886, 29813, 28389, 28447, 28332, - 32801, 32742, 32552, 31715, 31849, 31835, 31298, 31280, 30955, 42704, 42766, 42598, 42704, - 42598, 42621, 2767, 2674, 2705, 2658, 2674, 2767, 8118, 8091, 8117, 8456, 8337, - 8437, 8577, 8747, 8818, 34469, 34162, 34518, 32930, 32821, 32698, 1300, 1248, 1328, - 2893, 2823, 3178, 8134, 8091, 8118, 10498, 10754, 10644, 30948, 30933, 31214, 34849, - 34809, 34684, 33079, 33118, 32898, 5588, 5706, 5666, 7480, 7061, 6975, 38413, 38505, - 38360, 8725, 8577, 8818, 25961, 25903, 25781, 41483, 41427, 41581, 41310, 41163, 41060, - 14711, 15014, 14940, 14770, 14663, 14846, 26399, 26663, 26266, 43254, 43227, 43219, 43556, - 43466, 43636, 4069, 4163, 4070, 2489, 2690, 2587, 10852, 10858, 10759, 38486, 39040, - 38505, 32554, 32067, 32413, 36393, 36333, 36183, 34711, 34809, 35276, 41414, 41358, 41267, - 686, 512, 737, 829, 753, 781, 722, 753, 829, 902, 1168, 678, 8865, - 8814, 8964, 9013, 8964, 9123, 12337, 12318, 12183, 14711, 14663, 14770, 42811, 42648, - 42696, 43301, 43359, 43311, 43071, 42945, 42956, 13651, 14054, 14075, 12520, 12493, 12701, - 43081, 42980, 42985, 42793, 42811, 42696, 43227, 43109, 43219, 11645, 11738, 11614, 11645, - 11614, 11587, 29927, 30230, 30328, 29646, 29748, 29713, 29606, 29713, 29464, 13828, 13917, - 13940, 14068, 14282, 14309, 13389, 13498, 13369, 13389, 13369, 13191, 13389, 13191, 13175, - 27823, 27937, 27866, 27823, 27638, 27523, 43815, 43848, 43561, 43867, 43776, 43749, 43907, - 43746, 43498, 36393, 36183, 36303, 42974, 42937, 42904, 5, 320, 796, 34721, 34601, - 34574, 34786, 34601, 34721, 43240, 43227, 43254, 6818, 6834, 6812, 9577, 9545, 9570, - 9619, 9545, 9577, 9737, 9776, 9872, 9910, 9933, 9973, 9984, 9973, 10134, 9401, - 9530, 9395, 8434, 8385, 8198, 15330, 15441, 15662, 17099, 16515, 16733, 25481, 25142, - 25249, 34971, 34913, 35042, 35540, 35646, 35665, 34242, 34237, 34129, 43867, 43749, 43784, - 28871, 28828, 28829, 27800, 27569, 27904, 25646, 25481, 25249, 29568, 29625, 29886, 43088, - 42811, 42793, 4119, 4332, 4192, 6081, 6222, 6110, 4119, 4192, 4163, 38506, 38911, - 39110, 30055, 30230, 29927, 9148, 9013, 9123, 14232, 14282, 14068, 28001, 27904, 28299, - 92, 639, 352, 8091, 7872, 8054, 8337, 8134, 8118, 8224, 8134, 8337, 8463, - 8456, 8577, 8463, 8425, 8323, 40109, 39799, 40009, 43797, 43552, 43376, 8725, 8818, - 8814, 8198, 8222, 8022, 30232, 30151, 30356, 29909, 30055, 29927, 29314, 29324, 29165, - 29314, 29165, 29228, 15143, 15622, 15767, 15262, 15622, 15143, 26024, 25963, 26440, 26168, - 26399, 26266, 25478, 25961, 25781, 2603, 2658, 2767, 2981, 2893, 3178, 2824, 2893, - 2811, 8045, 7872, 8091, 34233, 34242, 34129, 34233, 34129, 34094, 40059, 40066, 40039, - 39536, 39334, 39460, 40609, 40569, 41253, 36303, 36183, 36227, 36183, 36095, 36227, 39536, - 39460, 39494, 978, 2416, 2425, 8434, 8690, 8684, 12318, 12525, 12546, 12337, 12525, - 12318, 41171, 40964, 41057, 42811, 42754, 42648, 42627, 42646, 42537, 7151, 7252, 7092, - 8101, 8198, 7857, 35050, 35061, 35184, 39660, 39811, 39698, 39431, 39594, 39357, 39532, - 39594, 39431, 3789, 3828, 3837, 3789, 3837, 4019, 6818, 6552, 6783, 35732, 35471, - 35424, 30262, 30055, 30213, 2100, 2433, 2286, 1159, 1172, 1248, 671, 722, 678, - 2100, 2286, 2005, 6805, 7027, 6883, 14663, 14596, 14816, 14645, 14596, 14663, 14437, - 14596, 14475, 14282, 14575, 14433, 26988, 27053, 26832, 27262, 27445, 27349, 26988, 26832, - 26663, 43776, 43766, 43679, 43867, 43766, 43776, 11969, 11690, 11965, 34692, 34469, 34601, - 34601, 34469, 34518, 36227, 36095, 36133, 13460, 13408, 13260, 13678, 13651, 13801, 28137, - 28001, 28299, 9013, 8865, 8964, 8975, 8865, 9013, 9148, 9201, 9152, 13175, 13191, - 12917, 13712, 13917, 13828, 14282, 14522, 14575, 40802, 41218, 40861, 40881, 40689, 40957, - 42980, 42974, 42904, 42937, 42981, 42793, 42861, 42732, 42754, 43163, 42974, 42980, 42865, - 42956, 42774, 10467, 10498, 10554, 10716, 10852, 10754, 10754, 10852, 10759, 9771, 9859, - 9865, 9771, 9865, 9519, 41310, 41060, 41252, 41414, 41509, 41358, 41427, 41255, 41731, - 13712, 13828, 13695, 26440, 25963, 25772, 27966, 27800, 27904, 43227, 43240, 43109, 43279, - 43160, 43432, 43894, 43513, 43509, 570, 631, 686, 213, 302, 342, 213, 183, - 302, 1172, 1247, 1248, 1159, 1248, 1300, 10916, 11151, 11098, 11962, 12337, 12183, - 10498, 10644, 10554, 42732, 42627, 42754, 42702, 42646, 42627, 41731, 41255, 41918, 42827, - 42865, 42774, 42827, 42774, 42766, 36938, 36515, 36531, 37408, 37406, 37216, 37452, 37517, - 37408, 37488, 37517, 37452, 37678, 37517, 37488, 37678, 37590, 37731, 37590, 37947, 37731, - 38033, 37947, 37826, 38027, 37947, 38033, 5262, 5179, 5249, 3666, 3773, 3828, 5258, - 5179, 5262, 5258, 5385, 5355, 5351, 5355, 5469, 5351, 5469, 5515, 5469, 5522, - 5515, 9705, 9737, 9872, 11507, 11645, 11587, 26465, 26399, 26168, 43449, 43438, 43401, - 43636, 43466, 43746, 3918, 4001, 2750, 4069, 4119, 4163, 36133, 35934, 35899, 37517, - 37406, 37408, 38088, 38027, 38033, 2674, 2512, 2627, 2729, 2767, 2823, 8134, 8045, - 8091, 8323, 8224, 8337, 8323, 8337, 8463, 33795, 33260, 33130, 32056, 31847, 31988, - 34132, 33913, 34162, 38088, 38105, 38027, 37758, 37821, 37953, 37693, 37785, 37758, 37580, - 37193, 37524, 37524, 36720, 37294, 36450, 36333, 36393, 36450, 36393, 36338, 27345, 27445, - 27262, 28183, 28332, 28081, 27317, 27220, 27097, 34287, 34132, 34162, 34913, 34786, 34784, - 34971, 34786, 34913, 34586, 34478, 34346, 35732, 35838, 35725, 43430, 43160, 43401, 30345, - 30633, 30328, 30345, 30328, 30230, 2893, 2824, 2823, 2729, 2824, 2625, 671, 788, - 753, 302, 183, 352, 2551, 2512, 2674, 5516, 5594, 5588, 28828, 28665, 28647, - 28890, 28871, 29153, 33660, 33544, 33409, 34523, 34586, 34346, 37785, 37821, 37758, 2194, - 2286, 2336, 8865, 8725, 8814, 9029, 9148, 9152, 38088, 38303, 38105, 6226, 6202, - 6427, 5561, 5862, 5485, 5588, 5594, 5706, 4985, 5561, 5485, 5039, 4569, 4344, - 8660, 8725, 8865, 33391, 33260, 33795, 37947, 38027, 38105, 10916, 11098, 10858, 30533, - 30345, 30426, 30262, 30345, 30230, 7058, 7151, 7092, 6204, 6689, 6427, 14596, 14437, - 14495, 14711, 14770, 15014, 35322, 35050, 35184, 35665, 35646, 36111, 42659, 42544, 42444, - 42659, 42537, 42646, 42896, 42754, 42811, 42779, 42704, 42939, 42704, 42621, 42917, 5992, - 6058, 5756, 3936, 3918, 3862, 4298, 4569, 4332, 7058, 7092, 6952, 8301, 8559, - 8434, 34579, 34287, 34469, 35322, 35296, 35425, 39572, 39536, 39735, 37841, 37947, 38028, - 39310, 39283, 39232, 39832, 39811, 39660, 13651, 13504, 13460, 13678, 13504, 13651, 42974, - 42981, 42937, 43286, 43081, 42987, 43286, 42987, 43240, 43043, 43071, 42956, 43359, 43473, - 43333, 43154, 43071, 43043, 43315, 43071, 43354, 116, 5, 796, 75, 40, 152, - 5756, 6058, 5830, 26399, 26572, 26663, 26465, 26572, 26399, 43556, 43551, 43384, 43279, - 43254, 43219, 43676, 43551, 43556, 39832, 39622, 39594, 40267, 40546, 40174, 13566, 13712, - 13695, 13277, 13175, 13039, 12632, 12868, 12525, 28183, 28081, 27937, 30533, 30633, 30345, - 27663, 27823, 27523, 27663, 27523, 27445, 15441, 15876, 15924, 13615, 13678, 13801, 26926, - 26988, 26663, 41171, 41163, 41270, 43529, 43438, 43449, 43572, 43473, 43359, 43879, 43413, - 43340, 526, 723, 248, 654, 642, 730, 583, 526, 523, 2512, 2427, 2539, - 2658, 2551, 2674, 2579, 2551, 2658, 3602, 3563, 3773, 2824, 2729, 2823, 4444, - 4694, 4620, 4312, 4444, 4380, 6834, 6818, 6783, 5638, 5588, 5666, 7480, 7590, - 7061, 7650, 7699, 7061, 6689, 6805, 6883, 6680, 6805, 6689, 8224, 8275, 8134, - 8425, 8463, 8577, 28890, 28665, 28828, 27801, 27552, 27800, 28551, 28665, 28544, 35540, - 35457, 35425, 35559, 35457, 35540, 2811, 2893, 2795, 1044, 1159, 1300, 1591, 2149, - 1560, 41526, 41137, 41698, 27800, 27552, 27569, 27966, 27904, 28001, 12076, 11969, 11965, - 11969, 12033, 12248, 41509, 41414, 41483, 42702, 42659, 42646, 42702, 42627, 42732, 10852, - 10916, 10858, 10467, 10425, 10253, 30882, 30523, 30743, 30882, 31061, 30955, 32413, 32067, - 31944, 33782, 33655, 33544, 9984, 9910, 9973, 9148, 9309, 9201, 10013, 9910, 9984, - 8690, 8777, 8867, 8434, 8559, 8690, 7374, 7857, 7644, 2951, 2883, 3039, 2487, - 2941, 3137, 40009, 39799, 39780, 30743, 30523, 30633, 526, 583, 654, 2382, 2452, - 2143, 10253, 10425, 9890, 9342, 9771, 9519, 42779, 42827, 42766, 42779, 42766, 42704, - 255, 392, 464, 35050, 34971, 35042, 35390, 34971, 35050, 43355, 43357, 43084, 10716, - 10916, 10852, 11151, 11274, 11376, 11728, 12021, 11738, 30619, 30743, 30633, 29927, 29748, - 29909, 36338, 36393, 36303, 36338, 36303, 36298, 35838, 35899, 35725, 35732, 35424, 35337, - 34305, 34346, 34242, 39811, 39883, 39780, 40020, 39883, 40037, 40020, 40009, 39883, 39118, - 39033, 38651, 3794, 3789, 4019, 16067, 16202, 16299, 35732, 35723, 35877, 43746, 43277, - 43498, 43848, 43867, 43784, 512, 431, 737, 722, 671, 753, 918, 1168, 1051, - 1048, 1247, 1172, 12374, 12337, 12293, 29127, 29165, 29035, 30262, 30230, 30055, 512, - 686, 631, 28575, 28747, 28562, 28052, 28183, 27937, 28516, 28183, 28342, 36298, 36303, - 36227, 14232, 14522, 14282, 14575, 14733, 15023, 13566, 13498, 13389, 13917, 13712, 13821, - 14711, 14645, 14663, 14871, 14645, 14711, 28024, 27966, 28001, 2551, 2527, 2512, 2729, - 2603, 2767, 2625, 2603, 2729, 7270, 7400, 7362, 28551, 28463, 28482, 28551, 28482, - 28665, 33782, 33926, 33655, 32834, 32898, 32742, 43074, 42981, 42974, 43074, 42974, 43163, - 2508, 2527, 2551, 1560, 2149, 2346, 8323, 8275, 8224, 8505, 8425, 8577, 8505, - 8577, 8725, 9029, 9013, 9148, 9619, 9577, 9737, 2981, 3178, 3192, 2981, 3192, - 2956, 33926, 34233, 34094, 43432, 43254, 43279, 36099, 36133, 35899, 35276, 34809, 35128, - 39478, 39055, 38907, 11039, 11274, 11151, 28575, 28447, 28389, 29646, 29713, 29606, 6202, - 6204, 6427, 5961, 6110, 5862, 5638, 5666, 5646, 7061, 7699, 7077, 35421, 35322, - 35425, 35498, 35425, 35457, 34809, 34849, 35128, 35383, 35276, 35307, 32909, 32821, 33010, - 33637, 33391, 33795, 33637, 33795, 33908, 34162, 34469, 34287, 16515, 16067, 16299, 25916, - 25481, 25646, 25916, 25646, 25963, 26740, 27385, 26440, 8777, 8690, 8559, 9334, 9401, - 9221, 31917, 31944, 31849, 5561, 5961, 5862, 4298, 4332, 4215, 39883, 40009, 39780, - 40572, 40546, 40267, 39883, 39811, 39902, 183, 92, 352, 22, 213, 342, 12033, - 11969, 12076, 12248, 12493, 12520, 29509, 29638, 29464, 29386, 29423, 29314, 43357, 43480, - 43301, 43879, 43340, 43828, 43315, 43084, 42945, 43357, 43355, 43487, 4380, 4444, 4620, - 5351, 5258, 5355, 5287, 5258, 5351, 5515, 5522, 5516, 5515, 5516, 5588, 5515, - 5588, 5638, 15441, 15283, 15298, 15330, 15283, 15441, 35645, 35665, 35715, 37517, 37802, - 37406, 37678, 37705, 37517, 37731, 37705, 37678, 37841, 37705, 37731, 37841, 37731, 37947, - 37841, 38028, 37814, 37821, 37945, 37953, 37785, 37793, 37821, 37917, 37999, 38040, 36483, - 36513, 36450, 43606, 43679, 43905, 43529, 43430, 43438, 43438, 43430, 43401, 15231, 14940, - 15014, 38210, 38303, 38088, 37735, 37793, 37785, 583, 642, 654, 562, 642, 583, - 562, 583, 523, 28942, 29127, 29035, 42827, 43027, 42865, 42578, 42363, 42214, 3936, - 4069, 4070, 3936, 4070, 3918, 6081, 6179, 6226, 6089, 6179, 6081, 31061, 31298, - 30955, 31121, 31298, 31061, 31005, 31061, 30882, 31005, 30882, 31030, 30882, 30743, 30856, - 35646, 36531, 36399, 39310, 39426, 39283, 39088, 38651, 39106, 11304, 11328, 11274, 10498, - 10518, 10754, 9856, 9890, 9859, 9856, 9859, 9771, 32056, 31988, 32126, 31197, 31214, - 31039, 30933, 30885, 30585, 28544, 28665, 28890, 31298, 31712, 31597, 37793, 37945, 37821, - 41163, 41171, 41057, 40127, 40051, 40066, 40066, 40051, 39821, 41402, 41252, 41358, 42242, - 42650, 41930, 1206, 1300, 1336, 1206, 1336, 1258, 6205, 5830, 6058, 9538, 9856, - 9771, 30856, 30743, 30822, 42566, 42468, 42544, 6205, 5900, 5830, 7077, 7699, 7280, - 7151, 7185, 7362, 6728, 7058, 6952, 6728, 6952, 6805, 13972, 14068, 13917, 26988, - 27155, 27097, 26926, 27155, 26988, 43529, 43449, 43639, 2527, 2427, 2512, 2603, 2579, - 2658, 2508, 2579, 2603, 8349, 8275, 8323, 8349, 8323, 8425, 43797, 43376, 43473, - 3026, 3585, 3039, 4215, 4332, 4171, 6179, 6204, 6202, 6178, 6204, 6179, 36338, - 36483, 36450, 36099, 35899, 36024, 35852, 35838, 35732, 1159, 1048, 1172, 9910, 9705, - 9872, 9619, 9705, 9812, 13504, 13408, 13460, 14392, 14192, 14437, 14475, 14596, 14645, - 30619, 30633, 30533, 30619, 30533, 30631, 34093, 34168, 34026, 41581, 41509, 41483, 2459, - 2427, 2527, 2416, 2452, 2587, 2883, 3026, 3039, 2489, 2452, 2382, 8975, 9013, - 9029, 8660, 8505, 8725, 29286, 29386, 29314, 29780, 29909, 29748, 42600, 42566, 42544, - 42800, 42702, 42732, 13821, 13972, 13917, 13566, 13389, 13277, 28024, 27801, 27966, 28828, - 28871, 28890, 28516, 28575, 28389, 28747, 28942, 29035, 29127, 29228, 29165, 28516, 28389, - 28183, 6552, 6343, 6254, 29646, 29606, 29638, 42600, 42544, 42659, 6661, 6680, 6689, - 35322, 35421, 35050, 35665, 35559, 35540, 35645, 35559, 35665, 40059, 40083, 40280, 39224, - 39110, 39055, 9201, 9309, 9545, 32821, 32930, 33010, 33026, 33260, 33293, 32801, 32834, - 32742, 32801, 32552, 32554, 30426, 30345, 30262, 32393, 32507, 32553, 42188, 41898, 41803, - 14733, 15262, 15143, 26572, 26926, 26663, 25961, 26465, 26168, 2427, 2281, 2539, 570, - 555, 631, 431, 255, 464, 570, 686, 671, 27588, 27385, 27552, 27801, 27800, - 27966, 29054, 28942, 28747, 57, 92, 183, 57, 183, 213, 14940, 14871, 14711, - 14843, 14871, 14940, 15231, 15201, 15283, 7018, 7185, 7058, 7058, 7185, 7151, 1048, - 918, 1051, 6812, 6834, 6860, 30213, 30426, 30262, 29909, 30213, 30055, 29509, 29646, - 29638, 29509, 29464, 29386, 6860, 6834, 6975, 6860, 6975, 6885, 35559, 35498, 35457, - 35554, 35498, 35559, 12337, 12374, 12525, 11696, 11738, 11645, 11328, 11587, 11274, 14508, - 14475, 14645, 29286, 29228, 29261, 43487, 43480, 43357, 43315, 42945, 43071, 9152, 8975, - 9029, 8884, 8975, 9152, 5900, 6205, 5964, 34132, 34093, 33913, 34601, 34786, 34692, - 2452, 2489, 2587, 6955, 7077, 6936, 8435, 8349, 8425, 8435, 8425, 8505, 8198, - 8301, 8434, 8101, 8301, 8198, 40223, 39961, 40109, 40783, 40881, 40802, 42299, 42188, - 41803, 10872, 11151, 10916, 30164, 30213, 29909, 14289, 14733, 14522, 14522, 14733, 14575, - 13277, 13389, 13175, 34692, 34786, 34815, 34233, 34305, 34242, 36298, 36227, 36205, 34431, - 34305, 34233, 34374, 34305, 34431, 40280, 40083, 40617, 39478, 39334, 39536, 43163, 42980, - 43081, 43014, 42896, 42811, 43286, 43240, 43374, 13566, 13821, 13712, 28024, 28001, 28137, - 36498, 36483, 36338, 35852, 35900, 36012, 43154, 43043, 42865, 43639, 43449, 43551, 43374, - 43240, 43254, 43905, 43679, 43766, 1560, 2346, 1725, 1159, 1046, 1048, 1048, 1040, - 918, 31712, 31861, 31849, 31671, 31861, 31712, 31671, 31712, 31298, 31671, 31624, 31816, - 31061, 31005, 31121, 30882, 30856, 31030, 30856, 30892, 31030, 10467, 10518, 10498, 10465, - 10518, 10467, 555, 512, 631, 479, 512, 555, 35383, 35337, 35276, 39055, 39110, - 38911, 39478, 39536, 39572, 918, 678, 1168, 5769, 5756, 5830, 6885, 6975, 7061, - 29424, 29509, 29386, 29646, 29780, 29748, 35498, 35421, 35425, 35554, 35421, 35498, 35128, - 34849, 34928, 39456, 39426, 39310, 40009, 40171, 40109, 39456, 39310, 39292, 43639, 43551, - 43665, 27801, 27588, 27552, 1725, 2433, 2100, 2625, 2508, 2603, 2184, 2281, 2427, - 2103, 2194, 2113, 2956, 3499, 3014, 2883, 2951, 2941, 32248, 32056, 32126, 31578, - 31312, 31197, 32069, 32056, 32262, 39832, 39594, 39532, 10610, 10716, 10754, 42413, 42188, - 42405, 42308, 42426, 42214, 2281, 2194, 2336, 2508, 2551, 2579, 8605, 8777, 8559, - 10562, 10031, 10561, 9856, 10253, 9890, 8668, 8660, 8865, 9187, 9201, 9545, 33409, - 33370, 33118, 32641, 32801, 32554, 40957, 40689, 40513, 4312, 4111, 4424, 3789, 3666, - 3828, 4312, 4424, 4444, 6089, 5973, 6041, 6204, 6661, 6689, 6605, 7018, 7058, - 43088, 42793, 42981, 42729, 42600, 42659, 9705, 9619, 9737, 9812, 9705, 9910, 41698, - 41137, 40989, 10774, 10872, 10916, 14475, 14392, 14437, 14508, 14392, 14475, 14843, 14645, - 14871, 27155, 27317, 27097, 28575, 28926, 28747, 29261, 29228, 29127, 29780, 29646, 29795, - 27370, 27317, 27346, 4111, 3999, 4253, 36205, 36227, 36133, 39923, 39832, 39532, 32553, - 32626, 32788, 32553, 32507, 32626, 33908, 33795, 33913, 33908, 33913, 33929, 33079, 32898, - 32834, 40617, 40083, 40609, 41509, 41402, 41358, 41613, 41402, 41509, 41655, 41509, 41581, - 37705, 37929, 37517, 37841, 37814, 37705, 38210, 38379, 38303, 39536, 39494, 39735, 41210, - 40964, 41171, 40546, 40957, 40513, 40171, 40223, 40109, 40171, 40009, 40020, 39572, 39735, - 39550, 43867, 43905, 43766, 43746, 43726, 43636, 43802, 43726, 43838, 30003, 29780, 29795, - 30743, 30619, 30822, 29852, 29780, 30003, 41918, 41255, 42558, 42729, 42659, 42786, 678, - 634, 671, 570, 634, 546, 9756, 10013, 9707, 12520, 12701, 12672, 13408, 13504, - 13678, 42861, 42800, 42732, 4981, 5076, 5179, 4111, 3961, 3999, 5515, 5434, 5351, - 5549, 5434, 5515, 5287, 5434, 5549, 5646, 5666, 5756, 5646, 5756, 5769, 13559, - 13408, 13678, 43580, 43572, 43480, 43675, 43154, 42865, 43027, 42827, 42779, 8556, 8660, - 8668, 7699, 7582, 7280, 4119, 4069, 4020, 2751, 2883, 2469, 6089, 6178, 6179, - 34305, 34523, 34346, 34374, 34523, 34305, 35899, 35838, 36024, 36099, 36205, 36133, 43074, - 43088, 42981, 42896, 42861, 42754, 43432, 43160, 43430, 43432, 43430, 43590, 27932, 27937, - 27823, 40, 5, 116, 43480, 43572, 43359, 43487, 43355, 43512, 1949, 1725, 2100, - 41402, 41310, 41252, 38210, 38360, 38379, 7185, 7184, 7362, 6189, 6661, 6204, 34815, - 34786, 34971, 36399, 36531, 36515, 27430, 27663, 27445, 512, 361, 431, 445, 479, - 555, 6552, 6818, 6343, 8134, 8275, 8045, 6728, 6805, 6680, 39478, 39553, 39055, - 38321, 38303, 38379, 39669, 40051, 40185, 36024, 36076, 36174, 36024, 35838, 35852, 39832, - 39902, 39811, 40024, 39902, 39832, 1258, 1336, 1483, 596, 634, 678, 1258, 1483, - 1335, 1483, 1431, 1335, 10716, 10774, 10916, 10518, 10610, 10754, 9334, 9519, 9401, - 31578, 31741, 31791, 31578, 31198, 31741, 38360, 38853, 38379, 9869, 10013, 9803, 9120, - 9152, 9201, 8668, 8865, 8723, 27370, 27345, 27317, 27317, 27345, 27262, 30533, 30426, - 30631, 31861, 31917, 31849, 41310, 41270, 41163, 43590, 43430, 43529, 43540, 43487, 43512, - 10253, 10465, 10467, 642, 461, 834, 2382, 2487, 2489, 523, 526, 407, 12248, - 12289, 11969, 12672, 12701, 13260, 2625, 2824, 2811, 2194, 2005, 2286, 2489, 2487, - 3137, 2452, 2416, 2143, 11328, 11507, 11587, 12764, 13175, 12917, 11304, 11507, 11328, - 11304, 11274, 11039, 15662, 15441, 15924, 34026, 33913, 34093, 33445, 33293, 33391, 34093, - 34132, 34259, 2719, 2625, 2811, 2795, 2893, 2981, 31816, 31917, 31861, 41672, 41731, - 41918, 41449, 41270, 41310, 41395, 41219, 41270, 6661, 6728, 6680, 6515, 6728, 6661, - 35645, 35554, 35559, 35657, 35554, 35645, 43676, 43556, 43636, 43676, 43636, 43726, 1044, - 1046, 1159, 6811, 6812, 6860, 10560, 10610, 10518, 31214, 30933, 31039, 30631, 30426, - 30651, 16067, 15662, 15924, 26024, 25916, 25963, 26440, 25916, 26024, 41672, 41655, 41581, - 2731, 2795, 2843, 34928, 34849, 34586, 34431, 34233, 34313, 35852, 35732, 35900, 10719, - 10774, 10716, 2731, 2719, 2795, 4981, 5179, 5020, 4332, 4119, 4171, 5039, 4957, - 5485, 5961, 6089, 6081, 4119, 4020, 4171, 41219, 41171, 41270, 41219, 41210, 41171, - 419, 361, 512, 43316, 43163, 43081, 43316, 43081, 43286, 6989, 7184, 7018, 7018, - 7184, 7185, 8301, 8231, 8559, 12682, 12672, 12936, 13801, 13651, 14075, 13801, 14075, - 13916, 28137, 28299, 28464, 27563, 27440, 27588, 27588, 27440, 27385, 28544, 28463, 28551, - 34928, 34586, 34801, 40881, 41049, 40802, 41049, 40957, 40977, 40957, 41170, 40977, 11507, - 11696, 11645, 11704, 11696, 11507, 29780, 29852, 29909, 29286, 29314, 29228, 43811, 43340, - 43552, 43811, 43552, 43832, 28871, 29026, 29153, 43181, 43088, 43074, 42786, 42659, 42702, - 30164, 30426, 30213, 42413, 42379, 42308, 42426, 42379, 42457, 27753, 27778, 27663, 27663, - 27778, 27823, 30044, 29909, 29852, 34815, 35390, 34763, 39902, 40037, 39883, 40024, 40037, - 39902, 4069, 3952, 4020, 6885, 6811, 6860, 6885, 7061, 6955, 39426, 39587, 39532, - 39292, 39310, 39118, 39106, 38651, 37953, 31917, 32413, 31944, 32956, 33079, 32834, 33660, - 33782, 33544, 723, 487, 248, 12672, 13260, 12936, 12520, 12382, 12248, 29153, 29026, - 29173, 15330, 15231, 15283, 15254, 15231, 15330, 43802, 43676, 43726, 43639, 43634, 43529, - 27563, 27588, 27620, 27345, 27430, 27445, 27370, 27430, 27345, 4069, 3936, 3952, 6205, - 6596, 6148, 36329, 36298, 36205, 36329, 36498, 36298, 36298, 36498, 36338, 36483, 37294, - 36513, 37735, 37917, 37793, 37793, 37917, 37945, 37945, 38062, 37953, 36329, 36205, 36190, - 7644, 7557, 7374, 10562, 10465, 10031, 14812, 14843, 14940, 33908, 33752, 33637, 34259, - 34132, 34287, 43665, 43634, 43639, 43456, 43374, 43254, 2103, 2005, 2194, 1335, 1431, - 1395, 32956, 32834, 32801, 2508, 2459, 2527, 2316, 2459, 2372, 2459, 2508, 2372, - 33842, 33752, 33908, 33800, 33782, 33660, 2795, 2719, 2811, 3666, 3789, 3677, 7374, - 7557, 7400, 7184, 7270, 7362, 7073, 7270, 7184, 3794, 4019, 3999, 32413, 32641, - 32554, 634, 570, 671, 479, 419, 512, 596, 678, 469, 8660, 8556, 8505, - 9187, 9545, 9280, 12644, 12382, 12520, 43014, 42861, 42896, 41255, 41930, 42558, 6148, - 6596, 6552, 6955, 7061, 7077, 3952, 3936, 3862, 5900, 5964, 5881, 37168, 37216, - 36938, 14569, 14508, 14645, 43487, 43580, 43480, 43540, 43580, 43487, 10941, 11151, 10872, - 30044, 30164, 29909, 29127, 28942, 29261, 42520, 42578, 42214, 43154, 43354, 43071, 34692, - 34579, 34469, 34741, 34579, 34692, 35733, 35421, 35554, 1072, 1044, 1300, 1046, 1040, - 1048, 1431, 1560, 1395, 31312, 31214, 31197, 31791, 31741, 32056, 31791, 32056, 32069, - 4180, 4215, 4177, 4180, 4298, 4215, 4344, 4569, 4298, 4610, 4957, 5039, 31531, - 31214, 31312, 30948, 30885, 30933, 1395, 1560, 1290, 32056, 32248, 32262, 32669, 32801, - 32641, 32459, 32514, 32413, 31671, 31816, 31861, 31624, 31671, 31298, 31121, 31005, 31030, - 30892, 30856, 30822, 300, 431, 361, 300, 255, 431, 13615, 13559, 13678, 12672, - 12644, 12520, 13675, 13559, 13615, 27620, 27588, 27801, 28464, 28299, 28463, 28464, 28463, - 28544, 12632, 12374, 12457, 12632, 12525, 12374, 13566, 13751, 13821, 14232, 14068, 13972, - 1072, 1300, 1206, 10774, 10941, 10872, 10719, 10806, 10774, 10465, 10560, 10518, 10562, - 10560, 10465, 9334, 9221, 8899, 1257, 1395, 1290, 2184, 2194, 2281, 40957, 41049, - 40881, 42413, 42308, 42188, 40572, 40267, 40394, 37993, 37917, 38040, 1949, 2100, 2005, - 4177, 4215, 4171, 3862, 3918, 3803, 6178, 6155, 6204, 6913, 6989, 7018, 6041, - 5973, 6085, 9120, 9187, 9185, 9869, 9812, 9910, 9869, 9910, 10013, 13916, 14075, - 14127, 37524, 37030, 37043, 36190, 36205, 36099, 36190, 36099, 36174, 40290, 40127, 40280, - 41563, 41310, 41402, 41613, 41563, 41402, 41731, 41672, 41581, 42729, 42566, 42600, 43222, - 43014, 43088, 43088, 43014, 42811, 43456, 43254, 43432, 3666, 3602, 3773, 3551, 3602, - 3666, 36111, 35715, 35665, 445, 419, 479, 248, 487, 127, 5434, 5287, 5351, - 5549, 5515, 5638, 5549, 5638, 5569, 5638, 5646, 5569, 486, 445, 555, 546, - 469, 495, 43797, 43473, 43572, 962, 1040, 1046, 30924, 30885, 30963, 31007, 30892, - 30867, 14232, 13972, 13839, 26465, 26926, 26572, 6148, 6552, 6207, 8045, 8275, 8349, - 26969, 26440, 27385, 27620, 27801, 27704, 35128, 35307, 35276, 34627, 34586, 34523, 34497, - 34523, 34374, 35331, 35307, 35465, 39572, 39550, 39478, 40185, 40051, 40127, 40185, 40127, - 40290, 39520, 39587, 39426, 40394, 40267, 40223, 39520, 39426, 39456, 34026, 33929, 33913, - 33293, 33260, 33391, 34168, 33929, 34026, 40171, 40020, 40037, 34433, 34259, 34287, 8556, - 8435, 8505, 8284, 8435, 8502, 10806, 10941, 10774, 11728, 11696, 11704, 11728, 11738, - 11696, 42786, 42702, 42953, 43181, 43074, 43163, 3952, 3862, 3803, 3990, 4171, 4020, - 6089, 6155, 6178, 6041, 6155, 6089, 36720, 36513, 37294, 36174, 36099, 36024, 1911, - 1949, 2005, 33391, 33637, 33726, 32944, 32956, 32801, 33079, 33409, 33118, 32944, 32801, - 32750, 5569, 5646, 5710, 38303, 38321, 38105, 38112, 38028, 37947, 37814, 37929, 37705, - 38360, 38505, 38853, 34431, 34497, 34374, 33906, 33926, 33782, 35715, 35657, 35645, 34579, - 34433, 34287, 35737, 35657, 35715, 39202, 39118, 39088, 39202, 39292, 39118, 40617, 40609, - 41217, 22, 57, 213, 2316, 2184, 2427, 2103, 2012, 2005, 2113, 2184, 2076, - 8723, 8865, 8975, 33252, 33409, 33079, 10941, 11039, 11151, 42379, 42426, 42308, 42917, - 42621, 42363, 42188, 42417, 42405, 11704, 11507, 11300, 42702, 42800, 42953, 5769, 5830, - 5865, 5830, 5900, 5865, 38343, 38379, 38853, 3677, 3455, 3429, 3961, 3794, 3999, - 12162, 12293, 12337, 29424, 29286, 29261, 31007, 31030, 30892, 27932, 27823, 27778, 27932, - 27778, 27753, 36399, 36111, 35646, 36260, 36111, 36399, 42917, 42363, 42771, 32788, 32626, - 32821, 7073, 6989, 6913, 7270, 7374, 7400, 39550, 39553, 39478, 40271, 39735, 39494, - 43535, 43456, 43432, 43676, 43665, 43551, 43805, 43665, 43676, 118, 300, 361, 255, - 231, 392, 266, 361, 419, 43482, 43316, 43286, 43482, 43286, 43374, 2719, 2602, - 2625, 3348, 3499, 3563, 3448, 3563, 3602, 8070, 8231, 8101, 7254, 7374, 7270, - 34815, 34971, 35390, 39731, 39532, 39587, 39923, 40024, 39832, 13801, 13708, 13615, 12936, - 13260, 13408, 13875, 13708, 13801, 27753, 27663, 27566, 27704, 27801, 27808, 28645, 28464, - 28544, 28645, 28544, 28814, 43307, 43181, 43163, 42953, 42800, 42861, 43904, 43354, 43854, - 43580, 43602, 43572, 30641, 30151, 30585, 2113, 2012, 2103, 1258, 1335, 1183, 43905, - 43907, 43498, 39292, 39472, 39456, 39508, 39472, 39292, 486, 555, 570, 8101, 8231, - 8301, 8070, 8101, 7857, 26969, 27385, 27440, 27801, 28024, 27808, 33929, 33842, 33908, - 33965, 33842, 33929, 34168, 34093, 34259, 33800, 33906, 33782, 34286, 34168, 34259, 41253, - 40964, 41210, 3940, 4020, 3952, 5865, 5900, 5881, 11728, 11962, 12021, 11808, 11962, - 11728, 41613, 41655, 41708, 42953, 42861, 43127, 1044, 962, 1046, 1040, 791, 918, - 410, 486, 570, 1089, 1072, 1206, 1169, 1206, 1258, 1169, 1258, 1237, 1258, - 1183, 1237, 2843, 2795, 2981, 2184, 2113, 2194, 31007, 31121, 31030, 31816, 31873, - 31917, 30822, 30631, 30685, 34525, 34433, 34579, 34497, 34627, 34523, 35465, 35307, 35474, - 34313, 34233, 33926, 40369, 40290, 40459, 39820, 39710, 39735, 9444, 9545, 9619, 9187, - 9120, 9201, 9753, 9869, 9803, 31999, 31873, 31816, 30003, 30044, 29852, 546, 634, - 596, 1043, 962, 1044, 6807, 6811, 6885, 12632, 12764, 12917, 13751, 13972, 13821, - 12351, 12457, 12374, 12351, 12374, 12293, 27346, 27317, 27155, 30822, 30619, 30631, 43055, - 43027, 42779, 43055, 42779, 42939, 43512, 43355, 43315, 31791, 31903, 31578, 30963, 30948, - 31313, 30924, 30641, 30885, 30885, 30641, 30585, 32262, 32248, 32393, 6804, 6807, 6885, - 6804, 6885, 6955, 39472, 39520, 39456, 39508, 39520, 39472, 9598, 9619, 9812, 1335, - 1257, 1183, 2316, 2427, 2459, 33726, 33637, 33752, 32909, 32788, 32821, 32389, 32262, - 32393, 34815, 34741, 34692, 34763, 34741, 34815, 41049, 41052, 40802, 41082, 40977, 41170, - 41052, 40977, 41082, 10941, 10713, 11039, 11300, 11507, 11304, 10719, 10716, 10610, 10562, - 10610, 10560, 30651, 30426, 30452, 42592, 42363, 42578, 41859, 41682, 41526, 9753, 9598, - 9812, 32389, 32393, 32561, 5945, 5881, 5964, 546, 596, 469, 11962, 12162, 12337, - 12115, 12162, 11962, 14205, 14192, 14392, 14843, 14569, 14645, 14602, 14569, 14843, 14812, - 14940, 15231, 29286, 29424, 29386, 28624, 28575, 28516, 42520, 42214, 42426, 43627, 43602, - 43580, 11300, 11304, 11281, 28151, 28342, 28183, 28052, 27937, 27932, 27908, 28052, 27932, - 30885, 30948, 30963, 30232, 30132, 29886, 30631, 30651, 30685, 30452, 30426, 30164, 9598, - 9444, 9619, 41219, 41395, 41210, 41613, 41509, 41655, 41655, 41672, 41708, 8899, 9221, - 8777, 8141, 8070, 7941, 28342, 28624, 28516, 3677, 3551, 3666, 2956, 2843, 2981, - 3677, 3789, 3794, 39286, 39202, 39374, 2372, 2508, 2265, 2469, 2883, 2941, 3990, - 3940, 3843, 1211, 1882, 1423, 903, 834, 267, 642, 562, 461, 3918, 2750, - 3803, 3803, 3940, 3952, 5020, 5179, 5258, 5020, 5258, 5287, 4866, 4840, 4982, - 5372, 5549, 5569, 5710, 5646, 5769, 5710, 5769, 5865, 8435, 8284, 8349, 8502, - 8435, 8556, 8607, 8556, 8668, 34261, 34313, 33926, 33409, 33800, 33660, 33917, 33800, - 33836, 33117, 33079, 32956, 12936, 13408, 12972, 14205, 14392, 14278, 27633, 27440, 27563, - 27808, 28024, 28074, 27566, 27663, 27430, 43590, 43529, 43634, 43307, 43222, 43181, 43143, - 42861, 43014, 7582, 7699, 7872, 7374, 7312, 7857, 7073, 7254, 7270, 7073, 7184, - 6989, 33150, 33010, 32930, 35307, 35331, 35383, 35307, 35128, 35474, 34627, 34497, 34431, - 39710, 39553, 39550, 39710, 39550, 39735, 13675, 13615, 13708, 12382, 12289, 12248, 12457, - 12764, 12632, 12425, 12764, 12457, 30641, 30356, 30151, 28074, 28024, 28137, 38112, 37947, - 38105, 38112, 38105, 38181, 38105, 38248, 38181, 37917, 37993, 37945, 36345, 36498, 36329, - 42660, 42520, 42633, 8571, 8607, 8668, 8884, 9152, 9120, 8899, 8777, 8605, 15662, - 15254, 15330, 27633, 27563, 27620, 41489, 41449, 41310, 43838, 43726, 43746, 43845, 43590, - 43634, 5, 68, 320, 14278, 14392, 14508, 14127, 14205, 14241, 14289, 14232, 13839, - 2265, 2508, 2625, 2781, 2843, 2956, 34744, 34627, 34431, 40024, 40171, 40037, 40073, - 40171, 40024, 39731, 39587, 39676, 4753, 4553, 5076, 38105, 38321, 38248, 37993, 38062, - 37945, 6155, 6189, 6204, 6089, 5901, 5973, 15254, 14812, 15231, 43811, 43828, 43340, - 43832, 43828, 43811, 38248, 38321, 38343, 12162, 12351, 12293, 12115, 12351, 12162, 30273, - 30164, 30044, 29054, 29261, 28942, 43027, 43263, 42865, 43354, 43512, 43315, 43540, 43627, - 43580, 42994, 43055, 42939, 42994, 42939, 42917, 1725, 1949, 1879, 1072, 1043, 1044, - 469, 678, 918, 1911, 2005, 2012, 370, 562, 523, 31121, 31405, 31298, 32514, - 32641, 32413, 31398, 31405, 31121, 31069, 31121, 31007, 30867, 30892, 30822, 31405, 31624, - 31298, 11704, 11808, 11728, 11281, 11304, 11039, 30356, 30132, 30232, 42520, 42592, 42578, - 38343, 38321, 38379, 40977, 41052, 41049, 40957, 40546, 40795, 1169, 1089, 1206, 6679, - 6812, 6811, 7280, 6936, 7077, 6804, 6936, 6889, 32836, 32788, 32909, 38331, 38343, - 38471, 40271, 39494, 40185, 39676, 39587, 39520, 41449, 41395, 41270, 43845, 43634, 43665, - 6679, 6811, 6807, 5853, 5710, 5865, 6041, 6189, 6155, 36190, 36345, 36329, 36076, - 36024, 36012, 1038, 1043, 1072, 11272, 11281, 11122, 10635, 10562, 10561, 41854, 41859, - 41526, 42413, 42457, 42379, 42520, 42660, 42592, 4319, 4298, 4248, 4319, 4344, 4298, - 6089, 5961, 5901, 6041, 6085, 6189, 39166, 39110, 39224, 33989, 33965, 34171, 34168, - 33965, 33929, 33753, 33726, 33752, 33293, 33150, 32930, 33010, 32836, 32909, 34462, 34259, - 34433, 118, 231, 300, 300, 231, 255, 325, 419, 445, 325, 445, 263, - 28926, 29054, 28747, 28342, 28400, 28624, 28052, 28151, 28183, 28006, 28151, 28052, 40326, - 40394, 40223, 40326, 40223, 40171, 10562, 10719, 10610, 30356, 30279, 30132, 30433, 30279, - 30356, 31531, 31312, 31578, 31903, 31791, 32069, 32194, 32069, 32262, 30685, 30867, 30822, - 30685, 30651, 30659, 32282, 32194, 32262, 42299, 41803, 41682, 33881, 33752, 33842, 13916, - 13875, 13801, 13854, 13875, 13916, 14127, 14075, 14205, 42786, 42898, 42729, 43222, 43088, - 43181, 263, 445, 486, 495, 570, 546, 12682, 12644, 12672, 12972, 13408, 13559, - 43307, 43163, 43349, 43163, 43316, 43349, 43802, 43805, 43676, 43838, 43805, 43802, 35144, - 34863, 34830, 34691, 34579, 34741, 34593, 34525, 34579, 40290, 40241, 40185, 40369, 40241, - 40290, 40271, 40241, 40369, 37294, 36483, 36498, 36012, 36024, 35852, 32413, 31917, 32459, - 30452, 30164, 30273, 32561, 32393, 32553, 42420, 42566, 43029, 41563, 41489, 41310, 41449, - 41481, 41395, 42422, 42457, 42413, 14278, 14508, 14569, 28103, 28191, 28151, 27370, 27566, - 27430, 27346, 27566, 27370, 43640, 43512, 43737, 43851, 43797, 43572, 2032, 2076, 2184, - 2113, 1911, 2012, 2032, 2184, 2316, 5853, 5865, 5881, 407, 370, 523, 273, - 370, 407, 12705, 12644, 12682, 29646, 29509, 29795, 29074, 29054, 29027, 6913, 7018, - 6605, 7254, 7259, 7374, 35737, 35554, 35657, 6804, 6679, 6807, 5945, 5853, 5881, - 6804, 6955, 6936, 29280, 29424, 29261, 32645, 32561, 32553, 32671, 32553, 32788, 32688, - 32514, 32487, 39731, 39923, 39532, 39635, 39508, 39292, 39286, 39292, 39202, 41647, 41489, - 41563, 41395, 41253, 41210, 3915, 4177, 4171, 3990, 4020, 3940, 3551, 3509, 3602, - 3961, 4111, 4312, 35900, 35732, 35877, 36345, 36190, 36174, 35337, 35723, 35732, 43640, - 43627, 43540, 11662, 11704, 11470, 11662, 11808, 11704, 30132, 29813, 29886, 29373, 29813, - 29629, 43055, 43090, 43027, 43128, 42994, 42917, 42771, 42363, 42592, 1844, 1911, 2113, - 8607, 8502, 8556, 8284, 8045, 8349, 8881, 8884, 9120, 8241, 8559, 8231, 10635, - 10719, 10562, 8141, 8231, 8070, 33312, 33150, 33293, 1796, 1879, 1911, 2602, 2719, - 2731, 2602, 2731, 2843, 33726, 33445, 33391, 33965, 33881, 33842, 33989, 33881, 33965, - 34462, 34433, 34525, 5945, 5964, 5960, 36039, 35737, 35715, 36938, 37216, 37406, 43832, - 43797, 43851, 2768, 2602, 2843, 9444, 9280, 9545, 9186, 9280, 9258, 9537, 9444, - 9598, 9753, 9812, 9869, 28151, 28191, 28342, 27908, 27932, 27753, 32724, 32671, 32788, - 32514, 32669, 32641, 34476, 34462, 34525, 82, 487, 320, 43482, 43374, 43544, 43198, - 43143, 43014, 8571, 8502, 8607, 27838, 27908, 27753, 39903, 39923, 39731, 36345, 36174, - 36259, 35337, 35383, 35723, 1089, 1038, 1072, 917, 1038, 1089, 1237, 1057, 1169, - 1257, 1335, 1395, 14748, 14602, 14812, 14812, 14602, 14843, 3585, 3026, 2750, 5960, - 5964, 6148, 32189, 32069, 32194, 32189, 31903, 32069, 32189, 32194, 32282, 32522, 32389, - 32561, 43029, 42566, 42729, 41613, 41647, 41563, 946, 1040, 962, 1057, 1089, 1169, - 42405, 42422, 42413, 42633, 42520, 42426, 42117, 42299, 41682, 34763, 34691, 34741, 34830, - 34691, 34763, 9636, 9753, 9621, 8884, 8723, 8975, 8815, 8723, 8884, 30924, 30939, - 30641, 31313, 30948, 31214, 31069, 31018, 31062, 31062, 31018, 30867, 30867, 31018, 31007, - 31405, 31568, 31624, 31900, 31999, 31816, 32688, 32750, 32669, 41052, 41218, 40802, 42339, - 42374, 42299, 40795, 40546, 40572, 40795, 40572, 40655, 42299, 42417, 42188, 4981, 4753, - 5076, 3420, 3509, 3677, 5020, 4866, 4982, 4981, 5020, 4982, 5610, 5710, 5853, - 32671, 32645, 32553, 32953, 32836, 33010, 32724, 32836, 32874, 37993, 38225, 38062, 39527, - 39286, 39436, 36174, 36076, 36249, 38028, 37929, 37814, 38093, 37929, 38028, 38213, 38028, - 38112, 38213, 38112, 38181, 38213, 38181, 38282, 29373, 29026, 29568, 29373, 29568, 29813, - 29054, 29074, 29261, 31069, 31007, 31018, 28926, 28575, 28624, 43198, 43014, 43222, 42953, - 42898, 42786, 37999, 37917, 37735, 6037, 5960, 6148, 5945, 5805, 5853, 36249, 36076, - 36012, 3677, 3509, 3551, 3448, 3509, 3420, 8469, 8571, 8549, 9753, 9590, 9598, - 14292, 14278, 14569, 13713, 13675, 13875, 13875, 13675, 13708, 12936, 12705, 12682, 14232, - 14289, 14522, 13751, 13566, 13301, 13039, 13175, 12764, 13039, 12764, 12801, 27838, 28006, - 27908, 26926, 27346, 27155, 36096, 36249, 36012, 35723, 35383, 35331, 39508, 39676, 39520, - 38404, 37953, 38062, 41948, 41708, 41672, 41360, 41253, 41508, 43851, 43572, 43602, 43512, - 43640, 43540, 43709, 43640, 43737, 8444, 8045, 8284, 8469, 8284, 8502, 7073, 7259, - 7254, 6924, 7259, 7073, 43907, 43838, 43746, 43707, 43432, 43590, 43544, 43374, 43456, - 39710, 39762, 39553, 38282, 38181, 38248, 39820, 39762, 39710, 39635, 39676, 39508, 39923, - 40073, 40024, 38282, 38248, 38331, 34462, 34286, 34259, 33881, 33753, 33752, 34390, 34286, - 34462, 35465, 35723, 35331, 33917, 33926, 33906, 33917, 33906, 33800, 33252, 33079, 33117, - 33861, 33753, 33881, 1911, 1879, 1949, 2032, 2113, 2076, 2751, 3026, 2883, 5878, - 5805, 5945, 6207, 6037, 6148, 6362, 6515, 6661, 5961, 5723, 5901, 11808, 11892, - 11962, 11756, 11662, 11565, 36547, 36260, 36399, 36217, 36260, 36364, 38331, 38248, 38343, - 41481, 41449, 41489, 39820, 39687, 39762, 41333, 41218, 41052, 946, 962, 1043, 325, - 266, 419, 29292, 29373, 29556, 7535, 7582, 7872, 6254, 6207, 6552, 13854, 13916, - 13923, 27838, 27753, 27566, 27908, 28006, 28052, 28680, 28926, 28624, 34804, 34593, 34691, - 34691, 34593, 34579, 43307, 43258, 43222, 43535, 43707, 43633, 8723, 8571, 8668, 8815, - 8884, 8881, 33867, 33445, 33726, 3509, 3448, 3602, 3961, 4312, 3838, 6121, 6661, - 6189, 36013, 35715, 36111, 36096, 36012, 35900, 34801, 34586, 34627, 174, 266, 325, - 231, 22, 392, 12236, 12457, 12351, 39040, 38506, 39110, 32652, 32645, 32671, 32724, - 32788, 32836, 31, 22, 231, 43544, 43535, 43633, 42633, 42426, 42457, 4344, 4610, - 5039, 4248, 4298, 4180, 4248, 4180, 4177, 4248, 4177, 4095, 37739, 36938, 37406, - 6085, 6121, 6189, 6090, 6121, 6085, 9803, 10013, 9756, 12776, 12705, 12936, 30659, - 30651, 30452, 28400, 28342, 28191, 37768, 37867, 37524, 35903, 35900, 35877, 6605, 7058, - 6728, 7259, 7359, 7374, 7257, 7359, 7259, 39988, 40073, 39923, 41433, 41335, 41403, - 9185, 9187, 9280, 11756, 11892, 11808, 33117, 32956, 32944, 32750, 32801, 32669, 42993, - 42898, 42953, 42993, 42953, 43127, 3915, 4171, 3990, 31398, 31568, 31405, 991, 1057, - 1237, 1038, 946, 1043, 994, 1057, 991, 31255, 31121, 31069, 31255, 31398, 31121, - 9186, 9185, 9280, 32652, 32724, 32894, 32688, 32669, 32514, 3448, 3348, 3563, 3285, - 3348, 3448, 6514, 6605, 6515, 6515, 6605, 6728, 495, 410, 570, 371, 410, - 495, 7645, 8070, 7857, 29373, 29173, 29026, 28619, 28137, 28464, 27704, 27633, 27620, - 29292, 29173, 29373, 30867, 30685, 30659, 32652, 32671, 32724, 33452, 33293, 33445, 34193, - 33965, 34168, 34193, 34168, 34286, 33836, 33800, 33409, 34744, 34801, 34627, 42994, 43090, - 43055, 43128, 43090, 42994, 34390, 34193, 34286, 42660, 42771, 42592, 1290, 1560, 1725, - 5878, 5945, 5960, 6818, 6812, 6343, 39224, 39055, 39603, 917, 946, 1038, 29509, - 29424, 29795, 42417, 42422, 42405, 42660, 42698, 42771, 42299, 42374, 42417, 42117, 41682, - 41859, 34593, 34476, 34525, 34529, 34476, 34593, 9753, 9636, 9590, 9590, 9537, 9598, - 12289, 12382, 12644, 30946, 30939, 30963, 32282, 32262, 32389, 32522, 32561, 32645, 30963, - 30939, 30924, 31531, 31672, 31635, 42503, 42422, 42417, 28006, 28103, 28151, 27838, 28103, - 28006, 28240, 28400, 28191, 43494, 43349, 43316, 43494, 43316, 43482, 43544, 43456, 43535, - 43548, 43494, 43482, 41218, 41335, 40861, 41335, 41218, 41333, 370, 461, 562, 32, - 461, 370, 11966, 12115, 11962, 9535, 9537, 9590, 41708, 41727, 41613, 41862, 41727, - 41963, 41948, 41672, 41918, 5878, 5960, 5999, 6343, 6812, 6679, 29795, 29424, 29430, - 29027, 29054, 28926, 35390, 35050, 35421, 36217, 36013, 36111, 36217, 36111, 36260, 38384, - 38282, 38331, 39603, 39055, 39553, 248, 273, 407, 233, 273, 248, 2265, 2258, - 2372, 2372, 2258, 2316, 2778, 2781, 2956, 12648, 12609, 12705, 14034, 13916, 14127, - 13713, 13854, 13780, 29104, 28890, 29153, 34804, 34830, 34863, 34744, 34431, 34569, 43370, - 43258, 43307, 43548, 43544, 43658, 30643, 30659, 30452, 43797, 43832, 43552, 43709, 43602, - 43627, 43709, 43627, 43640, 4380, 4620, 4553, 3843, 3940, 3803, 3843, 3915, 3990, - 5960, 6037, 5999, 12705, 12609, 12644, 12972, 13253, 13009, 29130, 29027, 28926, 43258, - 43198, 43222, 32836, 32953, 32874, 32635, 32522, 32645, 41727, 41647, 41613, 15254, 14748, - 14812, 14292, 14241, 14278, 27386, 26969, 27440, 42529, 42633, 42457, 43175, 43128, 42917, - 2265, 2285, 2175, 1161, 1290, 1725, 8141, 8241, 8231, 10253, 10031, 10465, 8360, - 8241, 7941, 8621, 8571, 8723, 8571, 8469, 8502, 8045, 7535, 7872, 9000, 8881, - 9120, 8838, 8881, 8875, 33763, 33836, 33409, 33043, 33117, 32944, 33043, 32944, 32750, - 34261, 34569, 34313, 33343, 33409, 33252, 6121, 6362, 6661, 6924, 7073, 6913, 7124, - 7257, 7259, 6002, 6362, 6121, 35916, 35903, 35877, 38086, 37999, 38006, 35916, 35877, - 35723, 34476, 34390, 34462, 34193, 34171, 33965, 33312, 33293, 33383, 34529, 34390, 34476, - 3832, 3843, 3803, 5773, 5878, 5815, 40073, 40245, 40171, 39903, 39988, 39923, 39804, - 39731, 39676, 4982, 4862, 4981, 5287, 5549, 5372, 5569, 5710, 5610, 5610, 5853, - 5773, 11892, 11966, 11962, 11662, 11756, 11808, 11470, 11704, 11300, 10941, 10806, 10713, - 10806, 10719, 10635, 30207, 30273, 30044, 29280, 29261, 29074, 6889, 6936, 7280, 5773, - 5805, 5878, 6343, 6410, 6342, 35474, 35419, 35482, 39762, 39687, 39553, 40271, 40185, - 40241, 40280, 40459, 40290, 8727, 8723, 8815, 12609, 12289, 12644, 29173, 29104, 29153, - 29556, 29373, 29629, 33445, 33602, 33452, 32459, 31917, 32124, 38040, 38225, 37993, 40222, - 40080, 40243, 38006, 37999, 37735, 36259, 36174, 36249, 41647, 41481, 41489, 43737, 43904, - 43760, 2781, 2768, 2843, 2742, 2768, 2781, 34569, 34431, 34313, 35548, 35474, 35482, - 40369, 40459, 40334, 40222, 40245, 40073, 9945, 10031, 10253, 30207, 30044, 30003, 38086, - 38225, 38040, 31996, 31903, 32189, 31531, 31578, 31672, 30433, 30356, 30462, 32282, 32389, - 32355, 5961, 5467, 5723, 42151, 42117, 41859, 42374, 42503, 42417, 42422, 42529, 42457, - 28400, 28547, 28624, 28103, 28240, 28191, 28325, 28240, 28103, 31531, 31313, 31214, 32124, - 31917, 31873, 31398, 31642, 31568, 31255, 31338, 31398, 31278, 31338, 31255, 31278, 31255, - 31069, 31278, 31069, 31062, 38384, 38241, 38282, 38282, 38241, 38213, 38213, 38324, 38028, - 37929, 37802, 37517, 38384, 38331, 38471, 68, 82, 320, 13854, 13713, 13875, 12609, - 12521, 12289, 14034, 14127, 14091, 13301, 13566, 13277, 13839, 13751, 13301, 12104, 12351, - 12115, 377, 469, 331, 994, 917, 1089, 994, 1089, 1057, 8838, 8727, 8815, - 8838, 8815, 8881, 33726, 33753, 33861, 32472, 32389, 32522, 32953, 33010, 33019, 41727, - 41862, 41647, 41508, 41395, 41481, 42654, 41948, 41918, 337, 263, 486, 266, 118, - 361, 852, 1040, 946, 4333, 4380, 4553, 11756, 11966, 11892, 12104, 11966, 11988, - 39040, 39110, 39166, 38225, 38404, 38062, 42898, 43029, 42729, 43127, 42861, 43143, 9519, - 9334, 9342, 31151, 30946, 30963, 42425, 42503, 42374, 7359, 7312, 7374, 6924, 6913, - 6829, 14241, 14205, 14278, 27808, 27633, 27704, 27741, 27633, 27808, 39988, 40080, 40073, - 39635, 39292, 39527, 6362, 6514, 6515, 5973, 6090, 6085, 36096, 36259, 36249, 36096, - 35900, 35903, 39304, 39040, 39166, 39304, 39166, 39224, 11281, 11470, 11300, 11272, 11470, - 11281, 32472, 32522, 32602, 29292, 29104, 29173, 29068, 29104, 29292, 42519, 42529, 42422, - 43175, 42917, 43180, 6541, 6514, 6443, 32635, 32645, 32652, 31816, 31624, 31900, 32798, - 33043, 32750, 39820, 39684, 39687, 41217, 40609, 41253, 40441, 40326, 40245, 40245, 40326, - 40171, 32798, 32750, 32688, 34152, 33917, 33836, 36547, 36399, 36515, 36013, 36039, 35715, - 34861, 34529, 34593, 36547, 36515, 36783, 2210, 2032, 2316, 1109, 1237, 1183, 2210, - 2316, 2258, 33019, 33010, 33150, 32802, 32635, 32652, 33861, 33881, 33989, 30455, 30643, - 30452, 30455, 30452, 30273, 29795, 29840, 30003, 29993, 29840, 29795, 30011, 29840, 29993, - 4144, 4610, 4344, 5973, 5879, 6090, 4248, 4152, 4319, 4083, 4095, 4177, 4152, - 4095, 4083, 5773, 5853, 5805, 6037, 6207, 5999, 469, 371, 495, 377, 371, - 469, 6541, 6913, 6605, 42993, 43086, 42898, 43184, 43127, 43143, 43184, 43143, 43198, - 43393, 43198, 43258, 43370, 43307, 43349, 43454, 43349, 43494, 42698, 42660, 42633, 43737, - 43512, 43904, 32894, 32724, 32874, 7257, 7312, 7359, 7207, 7312, 7257, 159, 118, - 266, 43544, 43548, 43482, 43535, 43432, 43707, 273, 234, 370, 127, 233, 248, - 12972, 13559, 13253, 13559, 13675, 13253, 28498, 28547, 28400, 39527, 39292, 39286, 40080, - 40222, 40073, 43488, 43370, 43349, 36217, 36077, 36013, 36172, 36077, 36217, 42746, 42698, - 42633, 8727, 8621, 8723, 7617, 7535, 8045, 9000, 9120, 9185, 14034, 13923, 13916, - 14091, 13923, 14034, 43845, 43665, 43805, 337, 486, 410, 2265, 2625, 2285, 40655, - 40572, 40394, 42343, 42299, 42117, 9258, 9280, 9444, 9258, 9444, 9351, 9535, 9590, - 9636, 32767, 32798, 32688, 31526, 31642, 31398, 32459, 32487, 32514, 31526, 31398, 31338, - 1170, 1183, 1257, 917, 852, 946, 5999, 6207, 6118, 31313, 31151, 30963, 30279, - 29813, 30132, 31531, 31396, 31313, 31635, 31396, 31531, 31996, 32189, 32182, 32189, 32282, - 32182, 39040, 38853, 38505, 38519, 38724, 38532, 39684, 39553, 39687, 34390, 34529, 34193, - 34804, 34691, 34830, 31062, 30867, 30863, 42503, 42519, 42422, 42617, 42746, 42633, 42343, - 42339, 42299, 41698, 40989, 41335, 11516, 11690, 11331, 32182, 32282, 32355, 31900, 31624, - 31568, 14292, 14569, 14602, 43709, 43778, 43602, 43263, 43027, 43090, 30011, 30207, 30003, - 30776, 30867, 30659, 30011, 30003, 29840, 36077, 36039, 36013, 36093, 36039, 36077, 371, - 337, 410, 282, 337, 371, 43297, 43184, 43198, 43127, 43086, 42993, 897, 852, - 917, 11122, 11281, 11039, 9238, 9334, 8886, 30776, 30659, 30643, 39820, 39735, 40028, - 42339, 42425, 42374, 43838, 43845, 43805, 1653, 1725, 1879, 32355, 32389, 32472, 36968, - 36515, 36938, 2335, 2941, 2487, 3843, 3912, 3915, 2335, 2487, 2287, 35733, 35554, - 35737, 32602, 32355, 32472, 33318, 33150, 33312, 33383, 33293, 33452, 41170, 41052, 41082, - 8714, 8621, 8727, 8714, 8727, 8838, 33476, 33383, 33452, 40795, 41170, 40957, 4862, - 4844, 4981, 4840, 4844, 4862, 4840, 4862, 4982, 5372, 5569, 5535, 8820, 8714, - 8838, 9585, 9535, 9636, 32602, 32522, 32635, 37881, 37802, 37929, 38324, 38213, 38241, - 38324, 38241, 38337, 41698, 41854, 41526, 4844, 4753, 4981, 233, 234, 273, 82, - 127, 487, 29280, 29074, 29227, 28240, 28375, 28400, 28325, 28375, 28240, 43297, 43155, - 43184, 43564, 43454, 43494, 43488, 43454, 43614, 43494, 43643, 43564, 3746, 3539, 3648, - 6443, 6514, 6362, 6923, 7124, 6924, 4985, 5485, 4957, 11966, 12104, 12115, 11988, - 11966, 11756, 11988, 11756, 11683, 28814, 28544, 28890, 30565, 30462, 30356, 37999, 38086, - 38040, 38225, 38304, 38404, 39374, 39202, 39088, 38006, 37735, 37867, 3014, 2778, 2956, - 2175, 2210, 2265, 3342, 3420, 3429, 3420, 3677, 3429, 4330, 4312, 4380, 6410, - 6343, 6679, 6889, 7280, 7582, 35825, 35916, 35723, 37867, 37735, 37524, 35825, 35723, - 35706, 30441, 30455, 30273, 28680, 28624, 28547, 217, 174, 325, 217, 325, 263, - 2287, 2487, 2382, 28814, 28890, 28893, 28669, 28680, 28547, 34529, 34171, 34193, 34018, - 34171, 34021, 13923, 13780, 13854, 13829, 13780, 13923, 13751, 13839, 13972, 13301, 13277, - 13039, 27346, 27838, 27566, 41433, 41698, 41335, 7312, 7544, 7857, 6924, 7124, 7259, - 7207, 7124, 7097, 963, 1220, 1161, 2265, 2210, 2258, 2659, 2602, 2768, 1986, - 2211, 2335, 738, 2143, 2416, 34018, 33861, 33989, 35596, 35474, 35548, 34941, 34801, - 34744, 33926, 33917, 34261, 33917, 34152, 34261, 39684, 39603, 39553, 40306, 39735, 40271, - 39635, 39804, 39676, 40658, 40655, 40394, 39672, 39804, 39635, 38337, 38241, 38384, 41508, - 41253, 41395, 40369, 40334, 40271, 41765, 41481, 41647, 41350, 41333, 41052, 41433, 41792, - 41698, 6118, 6207, 6254, 5535, 5569, 5610, 36547, 36364, 36260, 36039, 35793, 35737, - 36172, 36694, 36229, 14241, 14091, 14127, 14292, 14091, 14241, 30441, 30273, 30207, 42617, - 42633, 42529, 43175, 43195, 43128, 40459, 40280, 40963, 9351, 9444, 9537, 8886, 9334, - 8899, 8605, 8559, 8241, 35960, 35793, 36039, 35916, 36096, 35903, 35706, 35723, 35465, - 39374, 39088, 39106, 4333, 4330, 4380, 5535, 5610, 5454, 38337, 38471, 38509, 38853, - 38471, 38343, 12104, 12236, 12351, 12010, 12236, 12104, 29130, 29074, 29027, 30819, 30643, - 30678, 43184, 43155, 43127, 43393, 43258, 43370, 43128, 43195, 43090, 42917, 42771, 43180, - 31830, 31900, 31568, 31999, 32124, 31873, 31368, 31526, 31338, 31368, 31338, 31278, 31368, - 31278, 31311, 43737, 43778, 43709, 43760, 43778, 43737, 8444, 8284, 8469, 9000, 9185, - 9186, 11122, 11039, 10713, 30641, 30565, 30356, 33476, 33318, 33383, 33383, 33318, 33312, - 32953, 32894, 32874, 41360, 41217, 41253, 808, 791, 852, 1167, 1170, 1257, 1220, - 1257, 1290, 3014, 3499, 3348, 7124, 7207, 7257, 6541, 6605, 6514, 31830, 31568, - 31642, 42425, 42519, 42503, 42339, 42482, 42425, 42482, 42343, 42451, 42151, 41859, 41854, - 33042, 32894, 32953, 1930, 2113, 2032, 4095, 4152, 4248, 4083, 4177, 3915, 5454, - 5610, 5773, 32143, 32120, 32182, 32182, 32120, 31996, 31672, 31578, 31878, 30641, 30682, - 30565, 31996, 32120, 32143, 32009, 32124, 31999, 159, 31, 118, 118, 31, 231, - 2143, 2287, 2382, 2335, 2469, 2941, 3323, 3285, 3448, 3342, 3448, 3420, 6002, - 6121, 6090, 29063, 29130, 28926, 28375, 28498, 28400, 28325, 28498, 28375, 35793, 35733, - 35737, 34140, 34171, 34214, 35864, 35733, 35793, 36040, 36096, 35916, 35596, 35706, 35465, - 39777, 39603, 39684, 39802, 39684, 39820, 39527, 39590, 39635, 40243, 40080, 40260, 39718, - 39590, 39664, 43454, 43488, 43349, 43658, 43544, 43633, 43798, 43658, 43633, 852, 791, - 1040, 219, 217, 263, 174, 159, 266, 928, 917, 994, 5999, 5898, 5878, - 6137, 6118, 6254, 6342, 6254, 6343, 9011, 9000, 9186, 9535, 9351, 9537, 9621, - 9585, 9636, 9621, 9753, 9803, 9621, 9803, 9756, 36093, 36172, 36229, 36364, 36172, - 36217, 42612, 42519, 42425, 43298, 43263, 43195, 219, 263, 282, 112, 234, 233, - 141, 978, 1211, 331, 469, 284, 11454, 11662, 11470, 12972, 12776, 12936, 13009, - 12776, 12972, 12648, 12776, 12569, 12425, 12457, 12236, 12624, 12801, 12764, 28619, 28074, - 28137, 28893, 28890, 29104, 29068, 29292, 29422, 29648, 29629, 29813, 43150, 43086, 43127, - 43150, 43127, 43155, 43581, 43393, 43370, 3912, 4083, 3915, 3912, 3843, 3832, 8549, - 8571, 8621, 33252, 33117, 33336, 35474, 35596, 35465, 33117, 33043, 33336, 39887, 39802, - 39820, 40963, 40280, 40617, 11272, 11454, 11470, 43778, 43851, 43602, 43888, 43707, 43590, - 8624, 8549, 8621, 8875, 9000, 9011, 32143, 32182, 32355, 33100, 33019, 33150, 41698, - 41786, 41854, 41333, 41403, 41335, 41350, 41403, 41333, 41350, 41052, 41170, 41377, 41170, - 41245, 30819, 30776, 30643, 30441, 30207, 30290, 41963, 41727, 41708, 41551, 41444, 41217, - 41963, 41708, 41948, 41888, 41786, 41792, 42682, 42617, 42529, 6829, 6923, 6924, 1917, - 1930, 2032, 1844, 1930, 1814, 8624, 8621, 8714, 8360, 8605, 8241, 7544, 7312, - 7142, 33318, 33100, 33150, 33602, 33476, 33452, 33867, 33726, 33861, 34018, 33989, 34171, - 12648, 12521, 12609, 29422, 29292, 29556, 29280, 29430, 29424, 29227, 29130, 29088, 2778, - 2742, 2781, 2704, 2742, 2778, 39903, 39731, 39804, 39590, 39672, 39635, 39718, 39672, - 39590, 36040, 35916, 35825, 39106, 37953, 38404, 13829, 13713, 13780, 14748, 14292, 14602, - 27741, 27386, 27633, 27633, 27386, 27440, 9405, 9351, 9535, 9238, 9342, 9334, 10713, - 10806, 10635, 11272, 11263, 11454, 9241, 9342, 9238, 3903, 3912, 3746, 29467, 29556, - 29629, 29467, 29422, 29556, 29227, 29430, 29280, 1844, 1796, 1911, 8605, 8832, 8899, - 33336, 33043, 33333, 40562, 40394, 40326, 41377, 41350, 41170, 41792, 41786, 41698, 34861, - 34593, 34804, 43488, 43581, 43370, 43423, 43297, 43198, 43643, 43494, 43548, 43643, 43548, - 43658, 6005, 5898, 5999, 6410, 6679, 6361, 6923, 6994, 7124, 6962, 6994, 6923, - 90, 159, 174, 90, 174, 217, 127, 112, 233, 49, 112, 127, 10496, - 10635, 10561, 12010, 12104, 11988, 28619, 28464, 28645, 28787, 28645, 28814, 28893, 29104, - 29068, 31374, 31313, 31396, 29782, 29648, 29813, 30214, 30207, 30011, 35706, 35888, 35825, - 35128, 35419, 35474, 34668, 34744, 34569, 37175, 36968, 37988, 37978, 37881, 37929, 37978, - 37929, 38093, 38028, 38324, 38093, 38509, 38471, 38519, 40306, 40271, 40334, 4169, 4152, - 4023, 4169, 4319, 4152, 4144, 4344, 4319, 38337, 38384, 38471, 38086, 38186, 38225, - 36498, 36982, 37294, 9945, 10253, 9856, 31578, 31903, 31878, 31903, 31996, 31878, 1170, - 1109, 1183, 1167, 1109, 1170, 1167, 1257, 1220, 9829, 9945, 9856, 31744, 31830, - 31642, 31900, 32009, 31999, 32124, 32487, 32459, 31744, 31642, 31526, 31278, 31210, 31311, - 991, 928, 994, 331, 322, 377, 31635, 31374, 31396, 30863, 30867, 30776, 282, - 371, 322, 282, 263, 337, 12776, 12648, 12705, 9756, 9707, 9666, 13675, 13380, - 13253, 28074, 27741, 27808, 29011, 28893, 29068, 2742, 2659, 2768, 1930, 1844, 2113, - 2601, 2659, 2742, 34863, 34861, 34804, 40527, 40306, 40334, 40424, 40306, 40527, 963, - 1167, 1220, 31830, 32009, 31900, 38006, 38186, 38086, 928, 897, 917, 42519, 42682, - 42529, 42343, 42482, 42339, 42451, 42343, 42117, 29782, 29813, 29911, 29258, 29011, 29068, - 38186, 38304, 38225, 6005, 5999, 6118, 5901, 5879, 5973, 6541, 6829, 6913, 5784, - 5879, 5901, 39810, 39804, 39672, 38709, 39106, 38404, 9585, 9548, 9474, 9474, 9405, - 9535, 1796, 1653, 1879, 1917, 2032, 2210, 8820, 8624, 8714, 8549, 8444, 8469, - 8875, 8881, 9000, 9186, 9258, 9112, 10072, 10496, 10561, 30094, 30214, 30011, 30819, - 30863, 30776, 41611, 41508, 41481, 40527, 40334, 40459, 2754, 2704, 2778, 3677, 3794, - 3455, 6083, 6005, 6118, 6304, 6410, 6361, 35144, 34830, 34763, 36093, 35960, 36039, - 36093, 36077, 36172, 322, 371, 377, 3392, 3429, 3455, 4357, 4333, 4553, 4357, - 4553, 4753, 4686, 4753, 4844, 5020, 5008, 4866, 5400, 5372, 5535, 12954, 13301, - 13039, 12251, 12425, 12236, 11565, 11662, 11454, 29942, 29993, 29795, 29130, 29227, 29074, - 29063, 28926, 28680, 39304, 39224, 39603, 43341, 43297, 43382, 42816, 41963, 41948, 43195, - 43263, 43090, 43778, 43895, 43851, 42771, 42698, 42944, 42944, 42746, 42829, 43895, 43760, - 43904, 41973, 42409, 42041, 41862, 41794, 41647, 10646, 10713, 10635, 11414, 11565, 11454, - 30643, 30455, 30678, 39810, 39903, 39804, 40222, 40441, 40245, 39590, 39527, 39574, 42929, - 42682, 42519, 5270, 5251, 5130, 6083, 6118, 6137, 34018, 33867, 33861, 33322, 33100, - 33318, 33019, 33042, 32953, 34021, 33867, 34018, 5815, 5878, 5898, 32586, 32487, 32124, - 41973, 41794, 41862, 469, 918, 284, 1607, 1653, 1796, 8820, 8875, 8859, 11263, - 11272, 11122, 29634, 29467, 29629, 29634, 29629, 29648, 30214, 30290, 30207, 30094, 29993, - 29942, 33322, 33318, 33476, 43294, 43150, 43155, 42944, 42698, 42746, 3342, 3323, 3448, - 3239, 3323, 3342, 5911, 6443, 6362, 35960, 35864, 35793, 35844, 35864, 35914, 36498, - 36345, 36982, 35765, 35888, 35706, 35765, 35706, 35596, 82, 49, 127, 34882, 34668, - 34475, 34475, 34569, 34261, 40548, 40441, 40222, 41245, 41170, 40795, 43294, 43341, 43382, - 43297, 43341, 43155, 43671, 43643, 43658, 43671, 43658, 43798, 4023, 4152, 4083, 1884, - 1917, 1778, 1844, 1748, 1796, 28498, 28669, 28547, 30094, 30011, 29993, 28762, 28669, - 28498, 33675, 33602, 33445, 5794, 5815, 5898, 6137, 6254, 6342, 9538, 9829, 9856, - 8886, 9241, 9238, 6421, 6829, 6541, 7097, 7312, 7207, 8721, 8886, 8832, 9553, - 9538, 9460, 3903, 4023, 4083, 3903, 4083, 3912, 3912, 3832, 3746, 12425, 12624, - 12764, 12420, 12624, 12425, 29356, 29068, 29422, 28893, 28787, 28814, 28074, 27812, 27741, - 29911, 29813, 30057, 30864, 30939, 30946, 2285, 2625, 2602, 3014, 3348, 3027, 40123, - 40080, 39988, 1814, 1748, 1844, 963, 1109, 1167, 29813, 30279, 30057, 29467, 29356, - 29422, 31878, 31996, 32143, 33613, 33322, 33476, 32866, 33043, 32798, 36345, 36259, 36982, - 35679, 35765, 35596, 39903, 40123, 39988, 39436, 39286, 39374, 41350, 41667, 41403, 41786, - 41888, 41854, 41245, 41410, 41554, 6221, 6137, 6342, 5794, 5898, 6005, 6304, 6342, - 6410, 825, 808, 897, 897, 808, 852, 1109, 991, 1237, 963, 991, 1109, - 1161, 1725, 1396, 31374, 31348, 31313, 31635, 31638, 31374, 32635, 32802, 32602, 32076, - 32108, 32009, 32009, 32108, 32124, 31470, 31744, 31526, 31470, 31526, 31368, 31278, 31062, - 31173, 31311, 31470, 31368, 41765, 41611, 41481, 41508, 41529, 41360, 1917, 1814, 1930, - 2078, 2175, 2182, 10584, 10646, 10496, 10496, 10646, 10635, 9945, 9924, 10031, 9538, - 9771, 9342, 33042, 33019, 33100, 43198, 43393, 43423, 43029, 42898, 43086, 43904, 43512, - 43354, 43175, 43298, 43195, 43319, 43298, 43175, 31439, 31348, 31374, 31173, 31062, 31024, - 11141, 11263, 11122, 11715, 12010, 11988, 11141, 11122, 11035, 30235, 30290, 30214, 29795, - 29430, 29942, 32487, 32767, 32688, 31793, 32009, 31830, 7097, 7124, 6994, 40441, 40562, - 40326, 40658, 40562, 40865, 825, 897, 928, 31348, 31151, 31313, 31024, 31062, 30863, - 43845, 43888, 43590, 3746, 3648, 3705, 2557, 2601, 2704, 3838, 4312, 4330, 10584, - 10496, 10545, 30964, 31024, 30863, 35390, 35421, 35733, 36611, 36364, 36547, 39574, 39788, - 39815, 39106, 39436, 39374, 36040, 35825, 35888, 35548, 35679, 35596, 39802, 39777, 39684, - 39887, 39777, 39802, 39664, 39810, 39718, 39718, 39810, 39672, 40243, 40548, 40222, 33105, - 33042, 33100, 41730, 41529, 41508, 40028, 39887, 39820, 1748, 1607, 1796, 1884, 1814, - 1917, 2704, 2601, 2742, 3348, 3285, 3184, 11683, 11756, 11565, 29649, 29634, 29648, - 29649, 29648, 29782, 30279, 30433, 30282, 34758, 34863, 35010, 34861, 34758, 34529, 33867, - 33675, 33445, 33342, 33188, 33322, 33322, 33188, 33100, 41792, 41433, 41667, 40926, 40795, - 40655, 3762, 3746, 3705, 28934, 28893, 29011, 28934, 28787, 28893, 41963, 41973, 41862, - 41794, 41765, 41647, 41611, 41730, 41508, 43029, 43086, 43765, 41433, 41403, 41667, 42829, - 42617, 42682, 30678, 30455, 30478, 30214, 30094, 30235, 43459, 43029, 43591, 30455, 30441, - 30478, 5020, 5287, 5008, 4333, 4293, 4330, 5287, 5109, 5008, 38264, 38401, 38304, - 38304, 38401, 38404, 38264, 38304, 38186, 36040, 35888, 35921, 5008, 5109, 5046, 37739, - 37406, 37802, 37978, 38093, 37881, 38388, 38093, 38324, 38388, 38324, 38337, 32802, 32652, - 32894, 41667, 41350, 41677, 5971, 6005, 6083, 6094, 5971, 6083, 6361, 6679, 6429, - 6361, 6429, 6271, 35921, 35888, 35765, 4866, 5008, 4938, 34020, 34021, 34090, 8624, - 8444, 8549, 8875, 8820, 8838, 9112, 9258, 9182, 30864, 30641, 30939, 32964, 32802, - 32894, 33613, 33476, 33602, 40279, 40123, 40281, 7544, 7645, 7857, 7764, 7645, 7349, - 35128, 34928, 35419, 35679, 35707, 35765, 38519, 38471, 38724, 40422, 39735, 40306, 11513, - 11565, 11414, 11513, 11683, 11565, 30282, 30433, 30414, 29502, 29356, 29467, 4372, 4357, - 4753, 38117, 38186, 38006, 8076, 8444, 8221, 29502, 29467, 29634, 33865, 33675, 33867, - 43341, 43294, 43155, 43614, 43454, 43564, 43614, 43564, 43643, 32964, 32894, 33042, 32866, - 32767, 32792, 5879, 5904, 6090, 6962, 6923, 6829, 7059, 7097, 6994, 5784, 5904, - 5879, 4357, 4293, 4333, 34863, 34758, 34861, 35844, 35733, 35864, 38853, 39040, 39363, - 6304, 6361, 6271, 6094, 6083, 6137, 11035, 11122, 10713, 40279, 40260, 40123, 39436, - 39574, 39527, 39664, 39936, 39955, 42829, 42746, 42617, 42612, 42425, 42482, 12801, 12712, - 12834, 12954, 12801, 12834, 12954, 13039, 12801, 28669, 29063, 28680, 27838, 28325, 28103, - 4293, 4208, 4330, 31348, 31249, 31151, 31064, 30864, 30946, 31672, 31638, 31635, 31669, - 31638, 31672, 31769, 31672, 31878, 31769, 31910, 31792, 39304, 39603, 39774, 9829, 9924, - 9945, 10646, 10584, 10713, 9825, 9924, 9829, 31669, 31769, 31792, 31744, 31793, 31830, - 32620, 32767, 32487, 31673, 31793, 31744, 31637, 31744, 31470, 31637, 31470, 31311, 31210, - 31278, 31173, 31210, 31173, 31171, 12648, 12569, 12521, 13675, 13713, 13380, 42564, 42451, - 42669, 42151, 41854, 42125, 43798, 43633, 43707, 33333, 33343, 33336, 33336, 33343, 33252, - 35419, 34928, 35272, 598, 918, 791, 726, 825, 928, 808, 825, 708, 31439, - 31249, 31348, 31171, 31024, 30964, 31171, 31173, 31024, 4786, 4866, 4938, 6094, 6137, - 6033, 5904, 6002, 6090, 3184, 3285, 3323, 3184, 3323, 3166, 28997, 28934, 29011, - 28787, 28686, 28645, 32143, 32355, 32197, 33027, 32964, 33042, 33105, 33100, 33188, 35548, - 35707, 35679, 34928, 34801, 35104, 42125, 41854, 41888, 6962, 6829, 6793, 40123, 40260, - 40080, 41446, 41377, 41245, 40123, 40125, 40281, 43831, 43798, 43707, 240, 195, 282, - 282, 195, 219, 219, 90, 217, 766, 791, 808, 29864, 29649, 29782, 29356, - 29258, 29068, 29864, 29782, 29911, 30433, 30462, 30414, 708, 766, 808, 34065, 34152, - 33836, 3929, 4023, 3880, 3929, 4007, 4023, 4023, 4007, 4169, 4169, 4144, 4319, - 5312, 5961, 5561, 5904, 5842, 6002, 9460, 9538, 9342, 8886, 8899, 8832, 35914, - 35864, 35960, 35914, 35960, 36093, 39574, 39664, 39590, 39810, 39664, 39955, 240, 282, - 322, 159, 90, 31, 29278, 29258, 29356, 33330, 33105, 33188, 34021, 33865, 33867, - 34020, 33865, 34021, 31169, 30946, 31151, 43760, 43895, 43778, 43675, 42865, 43263, 43478, - 43263, 43298, 5008, 5046, 4938, 6221, 6342, 6304, 39291, 39304, 39459, 2256, 2469, - 2335, 3746, 3762, 3903, 2256, 2335, 2211, 978, 2425, 1211, 834, 461, 267, - 370, 234, 1, 37739, 37802, 38026, 8574, 8832, 8605, 9474, 9535, 9585, 8820, - 8610, 8624, 11969, 11331, 11690, 32070, 32049, 31968, 33613, 33602, 33675, 1854, 1917, - 2210, 1814, 1767, 1748, 2078, 2210, 2175, 2602, 2356, 2285, 33764, 33613, 33675, - 35844, 35390, 35733, 33930, 33792, 33865, 35482, 35581, 35548, 34941, 34744, 34668, 30864, - 30682, 30641, 30478, 30441, 30290, 30478, 30290, 30366, 43180, 43319, 43175, 42929, 42829, - 42682, 29794, 29502, 29649, 29649, 29502, 29634, 43180, 42771, 42944, 35104, 34941, 34997, - 2602, 2659, 2356, 3392, 3342, 3429, 13829, 13923, 14091, 9688, 9756, 9666, 40963, - 40617, 41444, 41917, 41765, 41794, 41917, 41794, 41973, 43721, 43614, 43643, 43808, 43643, - 43671, 35844, 35984, 35390, 36694, 36172, 36364, 148, 90, 219, 12251, 12236, 12010, - 11715, 11988, 11683, 29183, 29011, 29258, 28619, 28686, 28739, 28739, 28686, 28787, 27741, - 27812, 27386, 43614, 43581, 43488, 14292, 13829, 14091, 28338, 27812, 28074, 29415, 29430, - 29227, 32866, 33333, 33043, 33901, 34065, 33836, 32866, 32798, 32767, 2750, 3026, 2751, - 4647, 4957, 4610, 7059, 6962, 6793, 36968, 36783, 36515, 97, 148, 195, 195, - 148, 219, 2754, 2778, 3014, 28762, 29063, 28669, 33763, 33409, 33343, 34152, 34262, - 34261, 43566, 43423, 43393, 43459, 43269, 43029, 9182, 9258, 9351, 32620, 32487, 32586, - 31249, 31169, 31151, 30864, 30811, 30682, 31492, 31439, 31374, 31769, 31669, 31672, 32049, - 31910, 31968, 11513, 11715, 11683, 11863, 11715, 11671, 1, 234, 112, 3731, 3794, - 3961, 5400, 5270, 5372, 6271, 6221, 6304, 6679, 6804, 6429, 5911, 6362, 6002, - 7097, 7153, 7312, 7941, 8241, 8141, 7941, 8070, 7764, 10072, 10561, 10031, 9697, - 9825, 9829, 9896, 9825, 9818, 33865, 33792, 33675, 33613, 33342, 33322, 34020, 34090, - 33930, 33901, 33763, 33844, 3838, 3731, 3961, 5723, 5784, 5901, 36783, 36611, 36547, - 42650, 42242, 42846, 42242, 42420, 42846, 3184, 3027, 3348, 2950, 3027, 3083, 12289, - 12521, 12303, 9405, 9337, 9351, 32937, 32802, 32964, 31878, 32143, 31968, 4840, 4686, - 4844, 4357, 4279, 4293, 4293, 4279, 4208, 4208, 3982, 4330, 4786, 4686, 4840, - 4786, 4840, 4866, 5270, 5400, 5251, 4507, 4647, 4610, 5723, 5737, 5784, 4763, - 4647, 4507, 5815, 5764, 5773, 11863, 12251, 12010, 29502, 29278, 29356, 29183, 29278, - 29525, 43423, 43382, 43297, 30608, 30462, 30565, 30608, 30565, 30682, 38026, 37802, 37881, - 37175, 36746, 36783, 36783, 36746, 36611, 38026, 37881, 38093, 38388, 38337, 38468, 37867, - 38117, 38006, 38401, 38460, 38404, 38079, 38117, 37867, 5815, 5794, 5764, 31331, 31169, - 31249, 30964, 30819, 30678, 30964, 30863, 30819, 31425, 31637, 31311, 32586, 32124, 32108, - 40617, 41217, 41444, 39887, 39857, 39777, 42602, 42650, 42719, 42431, 42451, 42117, 42451, - 42564, 42482, 42327, 42125, 41888, 41920, 41888, 41792, 38117, 38264, 38186, 6429, 6489, - 6414, 9112, 9011, 9186, 9061, 9011, 9112, 41446, 41350, 41377, 40658, 40394, 40562, - 38468, 38337, 38509, 38468, 38509, 38532, 9896, 10031, 9924, 30546, 30964, 30678, 5959, - 5971, 6094, 7617, 8045, 7705, 9548, 9585, 9621, 4372, 4279, 4357, 38532, 38509, - 38519, 38472, 38460, 38401, 331, 254, 322, 294, 254, 331, 30282, 30057, 30279, - 30169, 30057, 30282, 2879, 2754, 3014, 6962, 7059, 6994, 7153, 7059, 7056, 7764, - 8070, 7645, 12954, 12831, 13301, 12712, 12801, 12624, 34029, 34262, 34065, 34065, 34262, - 34152, 35556, 35482, 35419, 35556, 35581, 35482, 36163, 36259, 36096, 35104, 34801, 34941, - 40422, 40028, 39735, 38724, 38471, 38853, 40479, 40548, 40243, 40123, 39903, 40125, 39903, - 39955, 40125, 41217, 41360, 41551, 30972, 30811, 30864, 5959, 6094, 6033, 38724, 38975, - 38787, 7705, 8045, 7728, 40548, 40562, 40441, 9390, 9337, 9405, 31886, 32009, 31793, - 33494, 33343, 33333, 33844, 33763, 33681, 33763, 33901, 33836, 33617, 33342, 33613, 34021, - 34140, 34090, 41838, 41730, 41611, 42041, 41917, 41973, 36163, 36096, 36040, 39291, 39040, - 39304, 29063, 29088, 29130, 30478, 30546, 30678, 29185, 29088, 29063, 6889, 7582, 7535, - 6033, 6137, 6221, 36066, 35914, 36088, 35390, 35144, 34763, 35914, 36093, 36088, 40424, - 40390, 40306, 40963, 40527, 40459, 30784, 30608, 30682, 9337, 9182, 9351, 9011, 8859, - 8875, 32620, 32792, 32767, 5794, 5959, 5855, 30057, 29864, 29911, 30152, 29864, 30057, - 39774, 39603, 39777, 254, 240, 322, 148, 97, 90, 226, 240, 254, 2934, - 2879, 3014, 2950, 3014, 3027, 3027, 3184, 3083, 7059, 7153, 7097, 7142, 7153, - 7056, 35065, 35144, 35390, 34997, 34941, 34668, 9825, 9896, 9924, 9697, 9829, 9538, - 9342, 9248, 9460, 9976, 10072, 10031, 31425, 31311, 31210, 32620, 32679, 32792, 31673, - 31637, 31696, 31492, 31374, 31638, 31169, 31064, 30946, 30811, 30784, 30682, 31968, 31769, - 31878, 33027, 33042, 33105, 33617, 33613, 33733, 41426, 41446, 41245, 41667, 41920, 41792, - 30534, 30414, 30608, 30608, 30414, 30462, 31691, 31638, 31669, 32937, 32602, 32802, 42558, - 42562, 41918, 42602, 42562, 42558, 42602, 42558, 42650, 42302, 42117, 42151, 43070, 43180, - 42944, 42302, 42151, 42263, 9130, 9061, 9112, 39857, 39774, 39777, 39857, 39887, 40028, - 41838, 41611, 41765, 41910, 41765, 41917, 2557, 2704, 2580, 2522, 2659, 2601, 1778, - 1767, 1884, 9342, 9241, 9248, 8397, 8574, 8360, 7349, 7645, 7544, 9756, 9688, - 9621, 9474, 9390, 9405, 9160, 9130, 9182, 9182, 9130, 9112, 12569, 12776, 12841, - 28686, 28619, 28645, 28739, 28787, 28934, 29183, 29258, 29278, 43621, 43566, 43581, 43581, - 43566, 43393, 43423, 43654, 43382, 43798, 43808, 43671, 43831, 43808, 43798, 33962, 33901, - 33844, 34882, 34997, 34668, 49, 1, 112, 12834, 12831, 12954, 12552, 12712, 12624, - 12420, 12425, 12251, 11863, 12010, 11715, 42846, 42420, 43029, 43596, 43581, 43614, 284, - 294, 331, 766, 679, 791, 708, 679, 766, 726, 928, 731, 1767, 1814, - 1884, 9560, 9548, 9621, 8574, 8605, 8360, 11454, 11397, 11414, 11263, 11141, 11189, - 31162, 31064, 31169, 43888, 43831, 43707, 29525, 29278, 29502, 30272, 30169, 30282, 30272, - 30282, 30414, 8916, 9011, 9061, 8916, 8859, 9011, 1778, 1917, 1854, 12300, 12420, - 12251, 29794, 29649, 29864, 33342, 33330, 33188, 33764, 33675, 33792, 33764, 33792, 33871, - 35612, 35548, 35581, 35612, 35707, 35548, 39774, 39881, 39304, 39846, 39857, 39966, 2580, - 2704, 2754, 35144, 35010, 34863, 35065, 35010, 35144, 35104, 35272, 34928, 34668, 34569, - 34475, 40519, 40390, 40424, 40422, 40390, 40519, 40424, 40527, 40519, 36611, 36694, 36364, - 35098, 35065, 35293, 36694, 36746, 36897, 41551, 41360, 41529, 42041, 41910, 41917, 42031, - 41920, 41994, 12325, 12552, 12420, 11035, 10713, 10584, 29415, 29942, 29430, 31821, 31673, - 31696, 37988, 36968, 36938, 38066, 38026, 38093, 38066, 38093, 38437, 38469, 38388, 38468, - 38469, 38468, 38694, 38468, 38532, 38694, 43319, 43415, 43298, 43070, 42944, 42829, 4647, - 4763, 4957, 4144, 4169, 4007, 43424, 43415, 43319, 2070, 2182, 2124, 2285, 2182, - 2175, 38264, 38393, 38401, 38117, 38393, 38264, 37603, 37768, 37524, 37603, 37524, 37294, - 40658, 40926, 40655, 41446, 41677, 41350, 40870, 40926, 40658, 1667, 1607, 1748, 1534, - 1416, 1396, 33349, 33330, 33342, 5794, 6005, 5971, 5794, 5971, 5959, 5784, 5737, - 5904, 5519, 5737, 5723, 33901, 34029, 34065, 33962, 34029, 33901, 4763, 4985, 4957, - 2362, 2356, 2659, 43835, 43721, 43643, 43723, 43721, 43835, 35216, 35272, 35104, 35216, - 35104, 35134, 40479, 40243, 40260, 39903, 39810, 39955, 2879, 2826, 2754, 2557, 2522, - 2601, 3239, 3342, 3392, 3239, 3392, 3193, 4686, 4596, 4753, 4545, 4596, 4686, - 4545, 4686, 4786, 5109, 5287, 5372, 5109, 5372, 5270, 35556, 35612, 35581, 35873, - 35921, 35765, 38460, 38709, 38404, 38518, 38393, 38539, 43723, 43596, 43614, 43566, 43560, - 43423, 9049, 9130, 9160, 11189, 11035, 11082, 41910, 41838, 41765, 33617, 33517, 33342, - 33930, 33865, 34020, 5130, 5109, 5270, 38694, 38532, 38724, 38694, 38724, 38787, 38393, - 38472, 38401, 2525, 2522, 2557, 10432, 10545, 10496, 9896, 9976, 10031, 9951, 9976, - 9896, 12841, 12776, 13009, 12841, 13009, 13018, 12420, 12552, 12624, 12712, 12831, 12834, - 12300, 12251, 12150, 29183, 28997, 29011, 28954, 28997, 29299, 31439, 31331, 31249, 30152, - 30057, 30169, 31792, 31691, 31669, 31804, 31691, 31792, 31910, 31769, 31968, 31637, 31673, - 31744, 33763, 33343, 33624, 31210, 31171, 31425, 34475, 34261, 34262, 40479, 40260, 40279, - 43621, 43560, 43566, 4931, 5046, 5109, 6033, 6221, 6124, 6221, 6271, 6124, 5737, - 5842, 5904, 5812, 5842, 5682, 9697, 9818, 9825, 31968, 32143, 32070, 31821, 31886, - 31793, 31691, 31492, 31638, 1161, 1220, 1290, 9693, 9697, 9553, 9553, 9697, 9538, - 31886, 32076, 32009, 42263, 42151, 42125, 42564, 42612, 42482, 140, 164, 240, 240, - 164, 195, 21, 284, 918, 598, 791, 679, 29928, 29794, 29864, 30972, 30864, - 31064, 731, 928, 991, 31466, 31331, 31439, 42562, 42654, 41918, 41910, 41895, 41838, - 42674, 42602, 42819, 42762, 42612, 42564, 3455, 3794, 3731, 3166, 3239, 3172, 3929, - 4144, 4007, 4023, 3903, 3880, 7893, 8360, 7941, 33733, 33517, 33617, 33129, 33027, - 33105, 41554, 41426, 41245, 41920, 42031, 41888, 9688, 9560, 9621, 9160, 9182, 9337, - 9666, 9560, 9688, 30178, 30235, 30094, 33221, 33105, 33330, 31234, 31162, 31169, 226, - 254, 294, 12150, 12251, 12040, 11671, 11715, 11513, 43434, 43298, 43415, 43434, 43478, - 43298, 2950, 2934, 3014, 2946, 2934, 2950, 5842, 5911, 6002, 5812, 5911, 5842, - 4985, 5312, 5561, 35651, 35873, 35612, 35134, 35104, 34997, 1396, 1725, 1653, 9248, - 9241, 8796, 31162, 30972, 31064, 2469, 2390, 2751, 2335, 2287, 1986, 41554, 41532, - 41426, 40865, 40870, 40658, 34021, 34171, 34140, 33764, 33733, 33613, 34029, 34315, 34262, - 34950, 35134, 34997, 33343, 33494, 33624, 3705, 3903, 3762, 3239, 3166, 3323, 3455, - 3731, 3400, 35873, 35707, 35612, 35873, 35765, 35707, 199, 226, 294, 140, 226, - 108, 43596, 43621, 43581, 43721, 43723, 43614, 43744, 43723, 43870, 1607, 1534, 1653, - 1667, 1748, 1767, 2318, 2390, 2469, 11397, 11454, 11263, 11189, 11141, 11035, 29942, - 30052, 30094, 31425, 31171, 31417, 30337, 30052, 30125, 32049, 31804, 31910, 33349, 33221, - 33330, 33349, 33342, 33517, 30872, 30784, 30811, 3982, 4208, 3914, 11331, 11969, 12289, - 13018, 13009, 13253, 12552, 12831, 12712, 12325, 12831, 12552, 12325, 12420, 12300, 28619, - 28338, 28074, 28954, 28739, 28934, 28954, 28934, 28997, 28325, 28762, 28498, 29088, 29415, - 29227, 42719, 42650, 42846, 43744, 43621, 43596, 1854, 2210, 2078, 1973, 2078, 2182, - 1973, 2182, 2070, 5312, 5467, 5961, 33871, 33733, 33764, 43854, 43354, 43154, 2934, - 2826, 2879, 2522, 2362, 2659, 2775, 2826, 2934, 40662, 40865, 40562, 40281, 40328, - 40279, 39664, 39574, 39815, 2648, 2580, 2754, 7153, 7142, 7312, 7764, 7789, 7941, - 7056, 7059, 6793, 34171, 34529, 34873, 35984, 35844, 35914, 35387, 35419, 35272, 34950, - 34997, 34882, 40390, 40422, 40306, 39857, 39846, 39774, 40519, 40748, 40627, 5467, 5557, - 5723, 3101, 3083, 3166, 3166, 3083, 3184, 36038, 36163, 36040, 35387, 35272, 35239, - 39966, 39857, 40028, 5400, 5535, 5251, 6124, 6271, 6218, 11568, 11671, 11513, 11568, - 11513, 11414, 32937, 32964, 33027, 33505, 33349, 33517, 7700, 7705, 7728, 6794, 6889, - 6880, 8045, 8444, 7728, 2138, 2285, 2356, 10432, 10496, 10329, 9818, 9951, 9896, - 9948, 9951, 9801, 9693, 9818, 9697, 31331, 31234, 31169, 31162, 31035, 30972, 30972, - 30872, 30811, 31382, 31234, 31331, 31691, 31734, 31492, 31910, 31804, 31792, 32937, 33027, - 33039, 31886, 31981, 32076, 32586, 32679, 32620, 31673, 31821, 31793, 31425, 31417, 31501, - 3746, 3464, 3539, 9130, 9049, 9061, 9390, 9474, 9548, 29185, 29415, 29088, 33129, - 33105, 33221, 43478, 43675, 43263, 43424, 43434, 43415, 43424, 43319, 43180, 32070, 32143, - 32197, 31821, 31981, 31886, 30366, 30290, 30235, 42602, 42674, 42562, 42975, 42941, 42846, - 10978, 11035, 10584, 30337, 30366, 30235, 30178, 30094, 30052, 43098, 43070, 42829, 2462, - 2362, 2522, 1904, 1854, 2078, 1778, 1667, 1767, 9461, 9390, 9548, 11331, 12289, - 11816, 33733, 33505, 33517, 33930, 33871, 33792, 34014, 33871, 33930, 34155, 34315, 34029, - 33333, 33603, 33494, 726, 708, 825, 612, 708, 616, 731, 991, 661, 2390, - 2750, 2751, 7545, 7535, 7617, 31466, 31439, 31492, 35239, 35272, 35216, 35239, 35216, - 35233, 43294, 43382, 43911, 5535, 5454, 5251, 6218, 6271, 6429, 36038, 36040, 35921, - 36038, 35921, 35939, 39363, 39040, 39291, 40762, 39966, 40028, 39574, 39436, 39788, 40215, - 40328, 40281, 13829, 13380, 13713, 28742, 28338, 28619, 12841, 12752, 12569, 13380, 13018, - 13253, 43723, 43744, 43596, 43654, 43423, 43560, 43835, 43643, 43808, 38026, 37989, 37739, - 38066, 37989, 38026, 38093, 38388, 38470, 4805, 4786, 4938, 4975, 4938, 5046, 4975, - 5046, 4931, 38470, 38388, 38469, 608, 598, 679, 10496, 10072, 10329, 43654, 43560, - 43621, 4144, 4507, 4610, 5034, 5211, 4985, 4985, 5211, 5312, 5312, 5301, 5467, - 5467, 5458, 5557, 4002, 4507, 4144, 3979, 4144, 3929, 40422, 40498, 40028, 40558, - 40519, 40627, 32075, 31804, 32049, 33116, 33129, 33221, 33359, 33221, 33349, 1534, 1396, - 1653, 1577, 1667, 1778, 32840, 32866, 32792, 41551, 41681, 41571, 41895, 41730, 41838, - 12798, 12752, 12841, 28739, 28742, 28619, 28742, 28954, 29299, 29804, 29502, 29794, 30721, - 30608, 30784, 9461, 9548, 9560, 12303, 12521, 12569, 11189, 11397, 11263, 12040, 12251, - 11863, 11100, 11397, 11189, 31501, 31637, 31425, 30337, 30178, 30052, 4596, 4372, 4753, - 5764, 5794, 5657, 31035, 30872, 30972, 37522, 37603, 37294, 37768, 38079, 37867, 38393, - 38518, 38472, 3227, 3193, 3392, 2600, 2648, 2826, 2826, 2648, 2754, 2525, 2462, - 2522, 3227, 3392, 3455, 5855, 5959, 6033, 6278, 6218, 6429, 140, 97, 164, - 164, 97, 195, 140, 240, 226, 30125, 30052, 29942, 28762, 29185, 29063, 1577, - 1566, 1667, 1973, 1904, 2078, 2138, 2182, 2285, 2138, 2356, 2290, 7774, 7789, - 7680, 8796, 9241, 8886, 9460, 9693, 9553, 8721, 8832, 8574, 32586, 32108, 32076, - 33970, 33962, 33844, 34155, 34029, 33962, 42409, 41973, 41963, 41994, 41920, 41667, 42302, - 42431, 42117, 42612, 42762, 42519, 41532, 41446, 41426, 2946, 2950, 2917, 35939, 35921, - 35873, 35378, 35239, 35233, 40215, 40281, 40125, 41554, 41410, 41602, 2775, 2946, 2917, - 6889, 6595, 6804, 6489, 6595, 6507, 1953, 1904, 1973, 33708, 33505, 33733, 34529, - 34758, 34988, 7700, 7545, 7617, 7700, 7617, 7705, 5855, 5741, 5657, 8397, 8721, - 8574, 39868, 39774, 39846, 30842, 30721, 30784, 5855, 6033, 5741, 5797, 6421, 6443, - 5682, 5842, 5737, 5519, 5723, 5557, 139, 267, 461, 199, 294, 284, 5454, - 5773, 5764, 5128, 5211, 5034, 2525, 2557, 2580, 8822, 8820, 8859, 9126, 9160, - 9337, 42041, 41895, 41910, 6414, 6278, 6429, 6053, 6013, 6124, 36088, 36093, 36229, - 34037, 34014, 34090, 36694, 36611, 36746, 37040, 36982, 36903, 35556, 35419, 35387, 40491, - 40479, 40573, 39788, 39436, 39927, 39936, 39815, 39858, 3914, 4208, 4279, 5211, 5301, - 5312, 11717, 11863, 11671, 10978, 11082, 11035, 30592, 30534, 30608, 31804, 31734, 31691, - 31234, 31035, 31162, 30872, 30842, 30784, 30721, 30592, 30608, 32195, 31734, 31804, 32355, - 32653, 32197, 32672, 32586, 32329, 31821, 31823, 31981, 31501, 31696, 31637, 31171, 31217, - 31417, 42738, 42431, 42302, 657, 731, 661, 708, 608, 679, 149, 199, 284, - 991, 663, 661, 31734, 31466, 31492, 30546, 30478, 30366, 35433, 35556, 35387, 35378, - 35387, 35239, 9948, 10072, 9976, 10593, 10978, 10584, 9200, 9693, 9460, 32355, 32602, - 32653, 34102, 33733, 33871, 32075, 32197, 32224, 34075, 33970, 33844, 32960, 33333, 32866, - 40498, 40558, 40627, 41551, 41529, 41681, 41595, 41532, 41631, 7680, 7789, 7764, 6421, - 6541, 6443, 40328, 40479, 40279, 40215, 40125, 40293, 3982, 3838, 4330, 3705, 3880, - 3903, 3787, 3880, 3705, 5301, 5408, 5467, 42669, 42762, 42564, 42327, 41888, 42031, - 42327, 42263, 42125, 149, 284, 21, 6489, 6429, 6804, 6278, 6140, 6218, 6489, - 6804, 6595, 5797, 6443, 5911, 5797, 5911, 5812, 36066, 35984, 35914, 35990, 35984, - 36066, 36982, 36259, 36903, 35931, 35939, 35873, 39984, 39868, 39846, 39881, 39868, 39984, - 39815, 39936, 39664, 39955, 39936, 40064, 2070, 1988, 1973, 1716, 1524, 1854, 2021, - 1988, 2070, 612, 608, 708, 9948, 9976, 9951, 2290, 2356, 2362, 2390, 2101, - 2750, 2256, 2318, 2469, 1986, 2287, 1937, 2287, 2143, 1937, 8822, 8859, 8916, - 6546, 6648, 6604, 34315, 34475, 34262, 34355, 34475, 34315, 30446, 30272, 30414, 30446, - 30414, 30534, 5592, 5764, 5657, 5592, 5454, 5764, 5408, 5458, 5467, 9601, 9560, - 9666, 9531, 9461, 9560, 9126, 9036, 9160, 34090, 34014, 33930, 34758, 35010, 34988, - 33681, 33763, 33624, 2211, 2318, 2256, 3539, 3464, 3522, 31478, 31035, 31234, 43500, - 43424, 43547, 42762, 42929, 42519, 1416, 1534, 1607, 1566, 1607, 1667, 9036, 9049, - 9160, 8916, 9061, 9049, 41595, 41677, 41446, 33603, 33615, 33494, 32586, 32076, 32329, - 5458, 5519, 5557, 36089, 36163, 36038, 6421, 6793, 6829, 40118, 40125, 39955, 33615, - 33681, 33624, 33615, 33624, 33494, 6414, 6290, 6278, 6507, 6595, 6648, 31035, 30842, - 30872, 2462, 2290, 2362, 2648, 2525, 2580, 2440, 2525, 2531, 2775, 2934, 2946, - 40519, 40558, 40422, 41706, 40963, 41444, 43273, 43180, 43070, 43434, 43521, 43478, 43660, - 43654, 43621, 43831, 43835, 43808, 41784, 41994, 41667, 3705, 3648, 3623, 41532, 41595, - 41446, 41677, 41784, 41667, 41108, 40926, 40870, 40562, 40548, 40662, 1988, 1953, 1973, - 2138, 2124, 2182, 2021, 2124, 2138, 6648, 6595, 6889, 8076, 7728, 8444, 11082, - 11100, 11189, 10514, 10584, 10545, 30744, 30592, 30721, 30272, 30152, 30169, 30339, 30546, - 30366, 30337, 30235, 30178, 4582, 4545, 4786, 4596, 4506, 4372, 4372, 4305, 4279, - 3982, 3914, 3838, 4805, 4938, 4905, 4938, 4975, 4905, 4975, 4931, 4905, 2021, - 1953, 1988, 4545, 4506, 4596, 34014, 34118, 33871, 34037, 34140, 34214, 34260, 34155, - 34105, 33970, 34155, 33962, 35233, 35216, 35134, 43660, 43621, 43870, 5109, 5053, 4931, - 3193, 3172, 3239, 3112, 3227, 3236, 3172, 3227, 3112, 2324, 2290, 2462, 5519, - 5682, 5737, 6623, 6815, 6793, 40662, 40548, 40665, 5109, 5106, 5053, 9126, 9337, - 9205, 7436, 7685, 7728, 35556, 35651, 35612, 35939, 36089, 36038, 34950, 34882, 34945, - 6257, 6290, 6414, 6889, 6731, 6712, 40064, 40118, 39955, 40491, 40548, 40479, 39788, - 39927, 39858, 9801, 9951, 9818, 10432, 10514, 10545, 9801, 9818, 9693, 9801, 9686, - 9837, 31696, 31823, 31821, 31750, 31823, 31696, 31516, 31696, 31501, 4448, 4305, 4372, - 5109, 5130, 5106, 38543, 38470, 38469, 38066, 38208, 37989, 37175, 36783, 36968, 38543, - 38469, 38654, 43192, 43098, 42929, 42431, 42669, 42451, 42623, 42669, 42431, 42623, 42431, - 42716, 9801, 9693, 9686, 31466, 31382, 31331, 31478, 30744, 30842, 30842, 30744, 30721, - 31860, 31382, 31466, 31860, 31466, 31734, 32075, 32049, 32070, 31217, 31171, 30964, 32602, - 32937, 32653, 33027, 33129, 33039, 1, 32, 370, 5106, 5119, 5060, 5106, 5130, - 5119, 11568, 11414, 11353, 38654, 38469, 38694, 43424, 43521, 43434, 43603, 43521, 43595, - 43273, 43070, 43433, 34945, 34882, 34917, 30459, 30534, 30592, 30459, 30446, 30534, 36938, - 37739, 37988, 39459, 39363, 39291, 39459, 39304, 40045, 21, 918, 598, 616, 708, - 726, 657, 726, 731, 10093, 10329, 10072, 31228, 31217, 30964, 5130, 5251, 5119, - 38787, 38654, 38694, 3227, 3172, 3193, 2525, 2440, 2462, 3101, 3172, 3112, 32840, - 32679, 32672, 32840, 32792, 32679, 33985, 34075, 33844, 35293, 35065, 35695, 36272, 36088, - 36229, 38709, 38460, 38472, 41551, 41548, 41444, 41571, 41548, 41551, 41595, 41714, 41677, - 41627, 41554, 41602, 8990, 8916, 9049, 5519, 5606, 5682, 5458, 5513, 5519, 5408, - 5383, 5458, 5301, 5218, 5408, 5211, 5218, 5301, 5034, 4985, 4973, 4748, 4911, - 4973, 3979, 3929, 3848, 10470, 10514, 10432, 11353, 11414, 11397, 2917, 2950, 3083, - 6257, 6414, 6489, 7608, 7545, 7700, 35433, 35651, 35556, 35433, 35387, 35378, 199, - 108, 226, 140, 35, 97, 149, 108, 199, 35286, 35233, 35134, 38940, 38787, - 38975, 39881, 39774, 39868, 3848, 3929, 3880, 5128, 5218, 5211, 30446, 30152, 30272, - 28954, 28742, 28739, 30140, 30152, 30446, 38654, 38787, 38866, 43742, 43675, 43478, 7685, - 7608, 7700, 7685, 7700, 7728, 34140, 34037, 34090, 34988, 35010, 35065, 3172, 3101, - 3166, 3083, 3101, 3005, 6459, 6489, 6507, 36088, 35990, 36066, 36127, 35990, 36088, - 39984, 39846, 39966, 41631, 41714, 41595, 42716, 42431, 42738, 3787, 3848, 3880, 3787, - 3705, 3623, 40328, 40215, 40417, 40479, 40328, 40417, 41627, 41631, 41554, 41554, 41631, - 41532, 30848, 30744, 31250, 3623, 3648, 3539, 5218, 5383, 5408, 5682, 5717, 5812, - 9036, 8990, 9049, 7587, 7436, 7329, 9321, 9337, 9390, 9321, 9390, 9461, 32960, - 32840, 32921, 11100, 11082, 10978, 30152, 29928, 29864, 30018, 29928, 30152, 11899, 12040, - 11863, 12150, 12325, 12300, 40293, 40125, 40118, 5383, 5513, 5458, 40045, 39486, 39459, - 40067, 39984, 40167, 40498, 40422, 40558, 661, 663, 638, 1577, 1778, 1854, 1577, - 1558, 1528, 1524, 1558, 1577, 40519, 40527, 40748, 41681, 41529, 41807, 41529, 41730, - 41807, 41730, 42042, 41807, 42654, 42562, 42674, 42654, 42674, 42694, 40795, 41410, 41245, - 41714, 41784, 41677, 11003, 11100, 10978, 30744, 30459, 30592, 42694, 42674, 42819, 42602, - 42719, 42819, 1388, 1161, 1396, 497, 598, 608, 11029, 9707, 10013, 32672, 32679, - 32586, 31417, 31516, 31501, 31450, 31516, 31417, 31450, 31417, 31217, 32197, 32075, 32070, - 29987, 30060, 30092, 30092, 30060, 30140, 33039, 33129, 33116, 42819, 42719, 42846, 43675, - 43854, 43154, 9019, 8990, 9036, 9019, 9036, 9126, 33116, 33221, 33359, 6604, 6648, - 6889, 8624, 8610, 8444, 7789, 7893, 7941, 8721, 8796, 8886, 7774, 7893, 7789, - 7544, 7142, 7349, 7142, 7056, 7349, 34105, 34155, 33970, 34155, 34260, 34315, 35372, - 35378, 35233, 33700, 33681, 33615, 657, 616, 726, 9707, 9601, 9666, 42941, 42819, - 42846, 3832, 3464, 3746, 11644, 11717, 11671, 11644, 11671, 11568, 29898, 29794, 29928, - 29898, 29804, 29794, 35372, 35433, 35378, 37410, 37294, 36982, 35372, 35233, 35286, 30125, - 29942, 29812, 31228, 31450, 31217, 43098, 42829, 42929, 43521, 43603, 43478, 43675, 43825, - 43854, 2531, 2525, 2648, 2021, 2070, 2124, 3005, 2917, 3083, 3227, 3455, 3236, - 6546, 6459, 6507, 5657, 5794, 5855, 6546, 6507, 6648, 40030, 40064, 39936, 39858, - 39815, 39788, 3623, 3539, 3578, 6033, 5857, 5741, 5513, 5606, 5519, 42034, 41784, - 41714, 12752, 12303, 12569, 9380, 9531, 9521, 12259, 12303, 12752, 12798, 12841, 13018, - 11765, 12325, 12040, 12040, 12325, 12150, 29185, 29277, 29415, 28762, 29277, 29185, 43500, - 43521, 43424, 1566, 1416, 1607, 2021, 2138, 1992, 2600, 2826, 2775, 7883, 8397, - 8360, 33603, 33700, 33615, 4805, 4905, 4836, 4650, 4648, 4544, 4650, 4786, 4805, - 4650, 4582, 4786, 4545, 4513, 4506, 4506, 4448, 4372, 3920, 3914, 4279, 4514, - 4445, 4492, 4931, 4836, 4905, 9385, 9321, 9461, 38013, 38079, 37768, 38013, 37768, - 38004, 37522, 37294, 37410, 4582, 4513, 4545, 4931, 4820, 4836, 4513, 4448, 4506, - 38680, 38543, 38654, 38602, 38470, 38543, 38602, 38437, 38470, 38470, 38437, 38093, 38680, - 38846, 38750, 38853, 38975, 38724, 4931, 4870, 4820, 6033, 6124, 6013, 5606, 5717, - 5682, 9321, 9205, 9337, 8820, 8822, 8610, 38539, 38393, 38117, 43017, 42929, 42762, - 42824, 42762, 42669, 3506, 3731, 3838, 30060, 30018, 30152, 30060, 30152, 30140, 1992, - 2138, 2290, 1937, 2143, 1672, 2211, 2037, 2318, 2671, 3803, 2750, 34499, 34355, - 34333, 34260, 34355, 34315, 43547, 43424, 43180, 43521, 43500, 43595, 3823, 3787, 3698, - 3823, 3848, 3787, 3752, 3979, 3848, 3965, 4144, 3979, 4985, 4748, 4973, 5128, - 5182, 5218, 5218, 5132, 5383, 5383, 5410, 5513, 5513, 5410, 5606, 5606, 5639, - 5717, 38853, 39363, 38975, 38518, 38709, 38472, 34075, 34105, 33970, 1362, 1416, 1566, - 1388, 1416, 1259, 36089, 35939, 35931, 35286, 35134, 35160, 40662, 40826, 40865, 41631, - 41831, 41714, 40491, 40665, 40548, 40293, 40417, 40215, 40527, 41104, 40748, 41730, 41895, - 42042, 6124, 6218, 6053, 6604, 6889, 6712, 13380, 12798, 13018, 29525, 29502, 29804, - 29299, 28997, 29183, 5034, 5105, 5128, 35442, 35651, 35433, 5547, 5454, 5592, 6257, - 6489, 6392, 11229, 11353, 11397, 11717, 11899, 11863, 10593, 11003, 10978, 10593, 10584, - 10514, 10470, 10432, 10329, 10242, 10329, 10093, 9837, 9948, 9801, 32840, 32960, 32866, - 34333, 34260, 34105, 32076, 31981, 32113, 2440, 2324, 2462, 2241, 2324, 2440, 2600, - 2775, 2747, 35098, 34988, 35065, 33177, 33116, 33359, 35011, 34945, 34917, 40644, 40665, - 40491, 3920, 4279, 4305, 5105, 5182, 5128, 43654, 43911, 43382, 43870, 43621, 43744, - 36000, 35390, 35984, 36218, 36127, 36088, 36272, 36229, 36575, 40189, 40293, 40118, 39927, - 39436, 39106, 42327, 42031, 42183, 551, 548, 616, 548, 608, 612, 991, 963, - 663, 108, 35, 140, 548, 612, 616, 32, 139, 461, 267, 55, 1567, - 11501, 11644, 11568, 30060, 29898, 29928, 30060, 29928, 30018, 38975, 39295, 39076, 5639, - 5797, 5717, 5717, 5797, 5812, 40795, 40926, 41410, 42073, 42031, 41994, 9601, 9531, - 9560, 9116, 9100, 9205, 9521, 9531, 9601, 9385, 9531, 9380, 6392, 6489, 6459, - 6889, 6794, 6731, 30337, 30339, 30366, 30125, 30339, 30337, 33039, 32985, 32937, 34118, - 34014, 34037, 40189, 40118, 40064, 40417, 40573, 40479, 35372, 35442, 35433, 35160, 35134, - 34950, 40963, 41104, 40527, 39486, 39363, 39459, 40588, 40573, 40417, 3698, 3787, 3623, - 3698, 3623, 3651, 40019, 39881, 39984, 3832, 3803, 3464, 1672, 2143, 738, 7893, - 7883, 8360, 7349, 7056, 6873, 42073, 41994, 41784, 7685, 7587, 7608, 8610, 8916, - 8827, 34945, 35160, 34950, 34499, 34565, 34475, 34499, 34475, 34355, 34355, 34260, 34333, - 3112, 3005, 3101, 3073, 3005, 3112, 6392, 6459, 6474, 40067, 40019, 39984, 39949, - 40030, 39858, 39858, 40030, 39936, 3651, 3623, 3578, 5137, 5410, 5383, 38208, 37739, - 37989, 6815, 7056, 6793, 149, 35, 108, 21, 35, 149, 11740, 11899, 11717, - 11740, 11717, 11644, 32113, 31981, 31823, 33844, 33681, 33985, 32113, 31823, 31977, 1416, - 1388, 1396, 1528, 1566, 1577, 11229, 11397, 11100, 41796, 41807, 41889, 41797, 41548, - 41571, 2747, 2775, 2917, 6474, 6459, 6546, 7535, 6880, 6889, 3240, 3361, 3464, - 35343, 35442, 35372, 35164, 35160, 34945, 40067, 40045, 40019, 41797, 41571, 41681, 40573, - 40644, 40491, 40665, 40826, 40662, 40588, 40644, 40573, 40588, 40675, 40670, 5635, 5592, - 5657, 6053, 6218, 6140, 6278, 6290, 6140, 6474, 6546, 6581, 9205, 9100, 9126, - 9019, 9100, 9116, 42183, 42073, 42103, 43603, 43742, 43478, 43720, 43742, 43603, 43595, - 43500, 43735, 34917, 34882, 34475, 33603, 33333, 32960, 34873, 34214, 34171, 29743, 29525, - 29804, 29987, 29804, 29898, 43547, 43649, 43646, 43547, 43180, 43273, 9200, 9460, 9248, - 11150, 11229, 11100, 8796, 8721, 8457, 33116, 32985, 33039, 31478, 31234, 31382, 33177, - 32985, 33116, 4544, 4492, 4582, 4582, 4492, 4513, 4513, 4445, 4448, 3714, 3920, - 4305, 5635, 5657, 5653, 38437, 38208, 38066, 38529, 38208, 38437, 38602, 38543, 38673, - 38543, 38680, 38673, 42816, 42409, 41963, 42694, 42721, 42654, 42778, 42721, 42694, 42958, - 42694, 42819, 38079, 38539, 38117, 38518, 38674, 38709, 40225, 40189, 40030, 38004, 37768, - 37603, 37692, 37603, 37522, 31750, 31696, 31516, 5653, 5657, 5741, 6140, 6290, 6257, - 36000, 35984, 35990, 34330, 34219, 34214, 36575, 36229, 36694, 2600, 2593, 2648, 1716, - 1953, 2021, 1577, 1854, 1524, 2549, 2593, 2600, 3449, 3506, 3477, 2777, 2747, - 2917, 3506, 3838, 3477, 3803, 3240, 3464, 5653, 5741, 5707, 6623, 6793, 6421, - 35343, 35372, 35286, 35343, 35286, 35325, 5060, 5053, 5106, 6095, 6140, 6257, 6581, - 6546, 6604, 6581, 6604, 6611, 40030, 40189, 40064, 39927, 39106, 39983, 551, 616, - 657, 638, 657, 661, 42975, 42846, 43269, 38673, 38680, 38750, 38787, 38940, 38866, - 43835, 43870, 43723, 42964, 42958, 42941, 36000, 35990, 36127, 40644, 40667, 40665, 40670, - 40667, 40644, 5034, 5066, 5105, 5105, 5092, 5182, 5182, 5132, 5218, 4985, 4763, - 4748, 3965, 3979, 3752, 3848, 3823, 3752, 3823, 3698, 3752, 38866, 38940, 39076, - 10242, 10470, 10329, 8357, 8721, 8397, 43768, 43786, 43742, 43742, 43786, 43675, 663, - 963, 602, 1904, 1716, 1854, 3506, 3400, 3731, 3299, 3400, 3297, 3573, 3698, - 3651, 2750, 2101, 2671, 5119, 5251, 5454, 5635, 5653, 5566, 11899, 11765, 12040, - 11765, 11740, 11644, 11765, 11644, 11501, 41627, 41831, 41631, 41108, 40870, 40865, 5119, - 5454, 5029, 11150, 11100, 11003, 6328, 6257, 6392, 5857, 6033, 6013, 36272, 36218, - 36088, 36091, 36218, 36192, 10470, 10593, 10514, 3942, 4305, 4448, 3578, 3539, 3507, - 5547, 5592, 5635, 5066, 5092, 5105, 5410, 5639, 5606, 6702, 6873, 6815, 2593, - 2531, 2648, 2777, 2917, 3005, 6474, 6328, 6392, 6611, 6604, 6712, 2458, 2531, - 2593, 7349, 7680, 7764, 7774, 7883, 7893, 6815, 6873, 7056, 6623, 6421, 6346, - 35931, 35873, 35651, 35325, 35286, 35160, 40045, 39304, 39881, 40045, 39881, 40019, 5092, - 5132, 5182, 39076, 38940, 38975, 41807, 41796, 41681, 42042, 42215, 42088, 32195, 31804, - 32075, 35931, 35651, 35908, 39984, 39966, 40167, 34917, 34475, 34565, 37221, 37410, 36982, - 40667, 40826, 40665, 40962, 40826, 40667, 9100, 9019, 9126, 9245, 9205, 9321, 9385, - 9461, 9531, 32672, 32921, 32840, 34796, 34917, 34565, 32823, 32921, 32672, 36897, 36575, - 36694, 36897, 36746, 37175, 6581, 6523, 6474, 6731, 6611, 6712, 7136, 6880, 7535, - 6309, 6421, 5797, 963, 706, 602, 548, 497, 608, 40588, 40417, 40675, 42816, - 41948, 42654, 42958, 42778, 42694, 42958, 42819, 42941, 42815, 42824, 42669, 42815, 42669, - 42623, 42302, 42263, 42738, 42183, 42031, 42073, 32243, 32224, 32197, 33263, 33603, 32960, - 43774, 43768, 43742, 43786, 43825, 43675, 43720, 43603, 43595, 638, 551, 657, 32784, - 32823, 32672, 31228, 30964, 30546, 40045, 40074, 39486, 40628, 40028, 40498, 40628, 40498, - 40627, 42846, 43029, 43269, 32985, 32653, 32937, 33086, 33177, 33359, 139, 87, 267, - 32, 60, 139, 43381, 43070, 43098, 3299, 3236, 3455, 3299, 3455, 3400, 34217, - 34333, 34105, 41003, 40865, 40826, 41003, 41108, 40865, 42964, 42975, 43066, 11501, 11568, - 11353, 10899, 11150, 11003, 8610, 8822, 8916, 8827, 8916, 8990, 11029, 10013, 11331, - 33985, 33681, 33700, 43774, 43720, 43595, 34969, 35020, 35142, 35060, 35164, 34945, 35343, - 35325, 35442, 3507, 3539, 3522, 3507, 3522, 3422, 6611, 6523, 6581, 5857, 6013, - 5873, 7545, 7136, 7535, 9385, 9245, 9321, 33074, 32653, 32985, 1904, 1953, 1716, - 1528, 1421, 1566, 1412, 1421, 1558, 2747, 2549, 2600, 2790, 2777, 3005, 3422, - 3522, 3464, 5566, 5547, 5635, 6013, 6053, 5873, 35060, 34945, 35011, 41104, 40963, - 41516, 30339, 30495, 30546, 29812, 29942, 29415, 43435, 43192, 42929, 3106, 3073, 3236, - 4492, 4445, 4513, 4544, 4582, 4650, 4650, 4805, 4648, 4805, 4688, 4648, 4836, - 4688, 4805, 4836, 4820, 4688, 5053, 4870, 4931, 5053, 4956, 4870, 43869, 43825, - 43768, 43768, 43825, 43786, 9245, 9116, 9205, 42319, 42183, 42371, 41719, 41627, 41602, - 5053, 5060, 4956, 36575, 36897, 36753, 38602, 38529, 38437, 38727, 38529, 38602, 38727, - 38602, 38673, 38727, 38673, 38750, 38654, 38846, 38680, 38366, 38539, 38079, 40480, 40417, - 40293, 38766, 38844, 38848, 36091, 36127, 36218, 34214, 34873, 34330, 36897, 37175, 37226, - 3236, 3073, 3112, 3400, 3269, 3297, 38805, 39106, 38709, 4956, 5060, 4997, 7431, - 7680, 7349, 7779, 7698, 7781, 38654, 38866, 38846, 38539, 38674, 38518, 8968, 8990, - 9019, 7779, 7883, 7774, 34709, 34565, 34499, 34969, 35060, 35011, 34153, 34217, 34105, - 34153, 34105, 34075, 7545, 7608, 7136, 6620, 6523, 6611, 4997, 5060, 5119, 38846, - 38976, 38932, 38674, 38745, 38709, 33177, 33074, 32985, 33086, 33074, 33177, 34118, 34037, - 34214, 30060, 29987, 29898, 29525, 29299, 29183, 30446, 30459, 30140, 33893, 33985, 33700, - 33893, 33700, 33739, 504, 497, 551, 1231, 1161, 1388, 5132, 5137, 5383, 5092, - 5066, 5132, 4973, 5066, 5034, 4952, 5066, 4973, 4763, 4507, 4398, 3752, 3698, - 3573, 38750, 38846, 38932, 42824, 42884, 42762, 42439, 42263, 42327, 31450, 31750, 31516, - 34263, 34153, 34202, 31940, 31750, 31753, 42976, 42778, 42958, 42976, 42828, 42778, 42778, - 42828, 42721, 42852, 42815, 42623, 2390, 2318, 2101, 3573, 3651, 3578, 34969, 35011, - 34917, 35306, 35325, 35160, 32224, 32195, 32075, 32653, 32243, 32197, 32195, 32243, 32276, - 11188, 11029, 11331, 11816, 12289, 12303, 30125, 30495, 30339, 39927, 39949, 39858, 40588, - 40670, 40644, 40130, 39949, 40091, 551, 497, 548, 504, 551, 638, 11153, 11217, - 11150, 10470, 10375, 10593, 10093, 10072, 9948, 10093, 9948, 9837, 9200, 9248, 9062, - 42975, 42964, 42941, 42972, 42964, 43066, 42505, 42439, 42327, 1558, 1421, 1528, 2290, - 2324, 2118, 41813, 41719, 41602, 42183, 42384, 42327, 42042, 41895, 42215, 41726, 41444, - 41548, 3573, 3578, 3507, 5066, 5137, 5132, 3400, 3506, 3449, 2037, 2211, 1986, - 6620, 6611, 6731, 6688, 6620, 6731, 7136, 7608, 7587, 6794, 6880, 6684, 35306, - 35160, 35164, 36903, 36259, 36163, 40750, 40628, 40627, 40067, 40046, 40045, 40750, 40627, - 40748, 42505, 42384, 42445, 11740, 11765, 11899, 11217, 11353, 11229, 11217, 11229, 11150, - 29277, 29812, 29415, 30469, 30626, 30495, 10899, 11003, 10778, 41797, 41681, 41796, 34219, - 34118, 34214, 36000, 36127, 36091, 34709, 34499, 34669, 35198, 35306, 35164, 34157, 34153, - 34075, 33700, 33603, 33739, 40167, 40046, 40067, 9062, 9248, 8796, 3422, 3573, 3507, - 2671, 3240, 3803, 5381, 5029, 5454, 5873, 6053, 5980, 42042, 41889, 41807, 42066, - 41889, 42042, 34263, 34333, 34217, 12798, 12259, 12752, 29743, 29299, 29525, 2118, 2324, - 2117, 1421, 1362, 1566, 33739, 33603, 33870, 2667, 2549, 2747, 2689, 2747, 2777, - 2790, 3005, 2855, 6523, 6328, 6474, 6688, 6731, 6794, 3422, 3464, 3361, 11211, - 11501, 11217, 11217, 11501, 11353, 35908, 35651, 35442, 35198, 35164, 35060, 40762, 40167, - 39966, 40811, 40750, 40748, 40225, 40293, 40189, 41952, 41831, 41813, 2855, 3005, 2914, - 6579, 6328, 6523, 6623, 6702, 6815, 6253, 6309, 6160, 36218, 36528, 36192, 38975, - 39363, 39295, 40762, 40028, 40628, 3143, 3106, 3236, 3143, 3236, 3299, 5707, 5566, - 5653, 5980, 6053, 6140, 1316, 1362, 1421, 41889, 41797, 41796, 41934, 41797, 42085, - 41719, 41831, 41627, 41256, 40926, 41108, 30469, 30495, 30125, 30495, 30626, 30546, 31885, - 31977, 31823, 31885, 31823, 31750, 36903, 36163, 36670, 37410, 37692, 37522, 42655, 42738, - 42439, 42439, 42738, 42263, 42716, 42852, 42623, 42815, 42884, 42824, 42505, 42327, 42384, - 42834, 42852, 42716, 10778, 11003, 10593, 9686, 10093, 9837, 32243, 32195, 32224, 32276, - 32243, 32326, 33126, 32653, 33074, 42852, 42884, 42815, 43649, 43547, 43273, 43547, 43646, - 43500, 43720, 43774, 43742, 7883, 7884, 8397, 7680, 7779, 7774, 7431, 7349, 7152, - 33359, 33349, 33505, 42409, 41895, 42041, 42964, 42972, 42958, 43150, 43765, 43086, 2241, - 2440, 2360, 1524, 1412, 1558, 40962, 41003, 40826, 4711, 4820, 4870, 4711, 4688, - 4820, 4663, 4648, 4688, 4663, 4514, 4648, 4648, 4514, 4544, 4544, 4514, 4492, - 3608, 3610, 3920, 4711, 4870, 4847, 3106, 3081, 3073, 3097, 3081, 3106, 5707, - 5741, 5857, 6095, 5980, 6140, 6328, 6095, 6257, 6620, 6579, 6523, 6684, 6688, - 6794, 7136, 7587, 7160, 6545, 6702, 6623, 43649, 43273, 43555, 3233, 3361, 3240, - 3327, 3422, 3361, 5707, 5857, 5738, 9116, 8968, 9019, 9245, 9142, 9116, 9385, - 9273, 9245, 9521, 9601, 9707, 31288, 31228, 30546, 42319, 42384, 42183, 2360, 2440, - 2531, 2790, 2689, 2777, 2855, 2689, 2790, 6309, 6346, 6421, 6623, 6346, 6380, - 35908, 35442, 35735, 40130, 40225, 40030, 40670, 40962, 40667, 40130, 40030, 39949, 4860, - 4870, 4956, 38490, 38246, 38208, 38727, 38708, 38529, 38840, 38708, 38727, 38729, 38708, - 38840, 40074, 40045, 40046, 2458, 2593, 2483, 43735, 43774, 43595, 1362, 1259, 1416, - 1440, 1412, 1524, 34202, 34153, 34157, 34153, 34263, 34217, 34969, 35198, 35060, 33870, - 33603, 33788, 41797, 41726, 41548, 41104, 40811, 40748, 41706, 41726, 41934, 3965, 3625, - 4002, 4144, 3965, 4002, 4398, 4507, 4002, 5066, 4950, 5137, 4843, 5639, 5410, - 9380, 9273, 9385, 6864, 7136, 6927, 38745, 38805, 38709, 38674, 38766, 38745, 38539, - 38766, 38674, 38366, 38079, 38013, 5029, 4997, 5119, 4911, 4952, 4973, 37796, 37692, - 37410, 38766, 38805, 38745, 5876, 6095, 5874, 5738, 5857, 5873, 9273, 9142, 9245, - 32784, 32672, 32329, 42103, 42073, 41784, 43890, 43654, 43660, 5381, 5454, 5547, 46, - 21, 598, 30626, 31288, 30546, 29812, 30187, 30125, 41145, 41256, 41108, 42034, 42103, - 41784, 41145, 41108, 41003, 2483, 2593, 2549, 43646, 43735, 43500, 43800, 43735, 43646, - 1801, 1716, 2021, 1992, 2290, 2118, 1992, 2118, 1990, 1937, 1672, 1986, 738, - 2416, 978, 34118, 34102, 33871, 35195, 34988, 35098, 34075, 33985, 34157, 36406, 36089, - 35931, 2117, 2324, 2241, 1230, 1259, 1316, 1231, 1259, 1230, 2914, 3005, 3073, - 2325, 2360, 2458, 3838, 3914, 3610, 5497, 5381, 5547, 5738, 5873, 5795, 8221, - 8444, 8610, 6513, 6579, 6620, 9041, 8968, 9116, 10264, 10470, 10242, 40220, 40074, - 40046, 40220, 40046, 40167, 40933, 40962, 40670, 39295, 39363, 39486, 43870, 43890, 43660, - 31977, 32140, 32113, 31940, 31885, 31750, 31468, 31450, 31228, 43381, 43098, 43192, 42852, - 43017, 42884, 42738, 42834, 42716, 42885, 42834, 42873, 42852, 42834, 42885, 3129, 3233, - 3240, 3625, 3752, 3573, 3129, 3240, 2671, 5876, 5873, 5980, 5497, 5547, 5566, - 5876, 5980, 6095, 31990, 32140, 31977, 43381, 43192, 43360, 30140, 30848, 30334, 29987, - 29976, 29804, 32326, 32243, 32653, 32326, 32653, 32457, 497, 383, 598, 507, 504, - 638, 400, 504, 414, 42972, 42976, 42958, 43077, 42976, 42972, 6513, 6620, 6688, - 40225, 40480, 40293, 40470, 40480, 40225, 2458, 2360, 2531, 2483, 2549, 2520, 7136, - 6864, 6880, 40676, 40675, 40417, 30274, 30469, 30125, 42654, 42721, 42816, 42834, 42738, - 42873, 42034, 41714, 41831, 400, 383, 497, 10178, 10264, 10242, 10178, 10242, 10093, - 43077, 43314, 43170, 43269, 43066, 42975, 2970, 3073, 3081, 35695, 35065, 35390, 36218, - 36272, 36528, 36272, 36575, 36528, 39983, 39949, 39927, 37040, 37221, 36982, 36903, 37221, - 37040, 3327, 3573, 3422, 3233, 3129, 3170, 34669, 34499, 34333, 41952, 42034, 41831, - 41288, 41145, 41003, 41081, 41003, 40962, 34219, 34102, 34118, 34354, 34102, 34219, 1791, - 1801, 2021, 2150, 2117, 2241, 5497, 5492, 5356, 39700, 39295, 39486, 33263, 32960, - 32921, 34669, 34333, 34618, 34669, 34796, 34709, 32329, 32076, 32113, 42816, 42721, 42828, - 1259, 1231, 1388, 1316, 1421, 1412, 1440, 1524, 1519, 30187, 30274, 30125, 30469, - 30649, 30626, 30298, 30274, 30187, 33708, 33359, 33505, 42355, 42384, 42319, 41831, 41719, - 41813, 2053, 1990, 2117, 2667, 2747, 2689, 1519, 1524, 1716, 3143, 3097, 3106, - 2855, 2667, 2689, 3143, 3299, 3297, 35695, 35390, 36000, 40750, 40758, 40628, 40789, - 40811, 40921, 41706, 41444, 41726, 3610, 3914, 3920, 5566, 5492, 5497, 5304, 5497, - 5356, 9142, 9041, 9116, 8968, 8909, 8990, 9046, 9041, 9142, 9046, 9142, 9273, - 8968, 9041, 8943, 9200, 9686, 9693, 8586, 9062, 8796, 3327, 3361, 3324, 4911, - 4868, 4952, 10899, 11018, 11150, 11501, 11211, 11765, 10735, 10778, 10593, 43017, 42762, - 42884, 3714, 4305, 3942, 4711, 4663, 4688, 4683, 4663, 4711, 4860, 4956, 4997, - 4860, 4997, 5029, 4860, 4924, 4847, 37692, 38004, 37603, 38766, 38848, 38805, 38311, - 38376, 38599, 31860, 31734, 32195, 41410, 40926, 41256, 42355, 42319, 42371, 3324, 3361, - 3255, 34102, 33708, 33733, 34873, 34529, 34988, 38311, 38013, 38004, 36337, 36163, 36089, - 36337, 36089, 36406, 41352, 41410, 41256, 41352, 41256, 41145, 3097, 2970, 3081, 2828, - 2970, 3097, 35735, 35325, 35306, 40320, 40470, 40225, 40597, 40676, 40417, 39727, 39983, - 39106, 38972, 39106, 38805, 3625, 3965, 3752, 2117, 1990, 2118, 2150, 2241, 2186, - 8943, 8909, 8968, 42088, 42066, 42042, 42409, 42215, 41895, 6726, 6684, 6864, 6864, - 6684, 6880, 6579, 6406, 6328, 6513, 6684, 6726, 42869, 42816, 42828, 42382, 42204, - 42215, 42869, 42828, 42989, 32269, 31860, 32195, 32285, 32195, 32276, 2186, 2241, 2360, - 2576, 2667, 2855, 4847, 4924, 4683, 4748, 4868, 4911, 4952, 4950, 5066, 10947, - 11018, 10899, 30445, 30649, 30469, 38844, 38766, 38539, 43911, 43150, 43294, 43066, 43077, - 42972, 42885, 43017, 42852, 42183, 42103, 42196, 33249, 33074, 33086, 31990, 31977, 31885, - 32267, 32329, 32140, 32140, 32329, 32113, 504, 400, 497, 383, 362, 598, 362, - 400, 346, 10264, 10375, 10470, 10778, 10947, 10899, 10191, 10178, 10093, 42976, 43077, - 43170, 4868, 4950, 4952, 38976, 38846, 38866, 37226, 37175, 38152, 38976, 38866, 39058, - 2385, 2458, 2483, 3367, 3269, 3449, 3449, 3269, 3400, 3255, 3361, 3233, 3327, - 3263, 3573, 3255, 3233, 3170, 35293, 35195, 35098, 35368, 35195, 35293, 35142, 35198, - 34969, 34796, 34565, 34709, 2637, 2914, 2661, 2970, 2914, 3073, 39983, 40091, 39949, - 40675, 40780, 40670, 40366, 40437, 40410, 10319, 10375, 10264, 31231, 31288, 30626, 39058, - 38866, 39076, 42196, 42103, 42099, 41774, 41813, 41602, 42204, 42088, 42215, 42204, 42066, - 42088, 60, 87, 139, 11067, 11150, 11018, 11067, 11153, 11150, 31567, 31468, 31736, - 30274, 30445, 30469, 30298, 30445, 30274, 39700, 39486, 40151, 39139, 39076, 39295, 39139, - 39058, 39076, 3324, 3291, 3327, 3076, 3129, 2671, 40228, 40225, 40130, 40811, 40758, - 40750, 40789, 40758, 40811, 40597, 40417, 40480, 43774, 43869, 43768, 43735, 43869, 43774, - 43800, 43869, 43735, 43800, 43646, 43649, 1316, 1259, 1362, 1791, 2021, 1992, 1791, - 1992, 1874, 41410, 41774, 41602, 41475, 41352, 41145, 7779, 7884, 7883, 7152, 7349, - 6866, 7349, 6873, 6866, 6873, 6702, 6676, 33893, 34081, 33985, 33985, 34081, 34157, - 4448, 4445, 3942, 7781, 7884, 7779, 33893, 33739, 33870, 42103, 42034, 42099, 36091, - 36152, 36000, 36637, 36575, 36753, 430, 507, 663, 1316, 1412, 1343, 10637, 10735, - 10593, 43381, 43433, 43070, 43435, 43360, 43192, 6545, 6623, 6380, 35020, 34969, 34917, - 35735, 35442, 35325, 3269, 3143, 3297, 3243, 3143, 3269, 30092, 29976, 29987, 30140, - 30459, 30848, 37739, 38208, 38246, 36337, 36670, 36163, 38004, 37692, 37796, 36776, 36670, - 36805, 41934, 41726, 41797, 2667, 2520, 2549, 2150, 2053, 2117, 2533, 2520, 2667, - 2385, 2520, 2421, 6684, 6513, 6688, 6874, 6864, 6927, 6253, 6346, 6309, 43479, - 43433, 43381, 3610, 3477, 3838, 38208, 38529, 38490, 6927, 7136, 6980, 40676, 40780, - 40675, 40767, 40780, 40676, 31567, 31750, 31450, 32921, 32823, 33263, 31468, 31228, 31288, - 42816, 43006, 42409, 42989, 42828, 43082, 42906, 42869, 42989, 43435, 43479, 43360, 43635, - 43531, 43613, 42655, 42439, 42505, 36243, 36152, 36192, 36192, 36152, 36091, 40762, 40220, - 40167, 40470, 40597, 40480, 40091, 40228, 40130, 40366, 40228, 40437, 3255, 3291, 3324, - 3095, 3076, 3018, 36637, 36528, 36575, 36684, 36528, 36637, 507, 638, 663, 1343, - 1412, 1440, 34255, 33708, 34102, 32269, 32285, 32324, 34354, 34219, 34330, 32326, 32285, - 32276, 30334, 30088, 30140, 33249, 33086, 33359, 8909, 8827, 8990, 8943, 8827, 8909, - 9046, 9273, 9222, 31468, 31288, 31424, 33319, 33249, 33359, 42084, 41797, 41889, 42195, - 42204, 42382, 42639, 42655, 42505, 42099, 42034, 41952, 42099, 42101, 42237, 30088, 29976, - 30092, 30088, 30092, 30140, 42445, 42384, 42355, 400, 362, 383, 1161, 706, 963, - 10375, 10405, 10593, 10178, 10319, 10264, 10191, 10319, 10178, 10947, 11067, 11018, 11153, - 11211, 11217, 10947, 10778, 10802, 43531, 43555, 43433, 43433, 43555, 43273, 1564, 1519, - 1716, 1582, 1716, 1801, 34927, 34938, 34796, 34796, 35020, 34917, 33424, 33512, 33263, - 35208, 35306, 35198, 34938, 35020, 34796, 2520, 2385, 2483, 2325, 2385, 2421, 6545, - 6618, 6702, 6503, 6618, 6545, 36129, 35695, 36000, 34428, 34354, 34330, 38490, 38529, - 38713, 38529, 38708, 38713, 38708, 38729, 38713, 38311, 38366, 38013, 40366, 40320, 40228, - 37075, 37221, 36903, 40677, 40597, 40470, 5795, 5876, 5874, 5144, 5029, 5381, 38750, - 38840, 38727, 3477, 3367, 3449, 2533, 2667, 2576, 10285, 10405, 10375, 5639, 6309, - 5797, 40228, 40320, 40225, 38881, 38805, 38848, 38246, 37988, 37739, 38932, 38910, 38840, - 38750, 38932, 38840, 42421, 42445, 42355, 42049, 41952, 41813, 42421, 42355, 42371, 1161, - 705, 706, 1462, 1343, 1440, 2227, 2186, 2360, 6874, 6726, 6864, 5874, 6095, - 5943, 7164, 7587, 7329, 8300, 8221, 8610, 33512, 33547, 33521, 41039, 40933, 40780, - 40780, 40933, 40670, 41845, 41774, 41410, 4868, 4909, 4950, 4950, 4881, 5137, 4398, - 4748, 4763, 4269, 4748, 4398, 4269, 4398, 4002, 38932, 39162, 38910, 12259, 11816, - 12303, 8943, 8736, 8728, 30088, 29743, 29976, 29976, 29743, 29804, 43695, 43800, 43649, - 11067, 11211, 11153, 10815, 11211, 11067, 30445, 30836, 30649, 29812, 30298, 30187, 4663, - 4282, 4514, 3351, 3367, 3477, 3198, 3243, 3367, 4860, 4847, 4870, 5304, 5381, - 5497, 10405, 10637, 10593, 39139, 38976, 39058, 38838, 38844, 38539, 3170, 3291, 3255, - 8827, 8619, 8610, 9521, 9707, 9551, 4748, 4909, 4868, 38844, 38881, 38848, 1519, - 1462, 1440, 1874, 1992, 1990, 1651, 1582, 1801, 2385, 2325, 2458, 1876, 1874, - 1990, 2855, 2637, 2576, 6710, 6726, 6874, 7698, 7680, 7509, 7698, 7779, 7680, - 6618, 6676, 6702, 6734, 6676, 6503, 7680, 7431, 7509, 7884, 8357, 8397, 8970, - 9686, 9200, 33319, 33126, 33249, 34873, 34988, 35195, 6253, 6380, 6346, 6160, 6380, - 6253, 35208, 35198, 35142, 35197, 34873, 35195, 35136, 35208, 35142, 34333, 34263, 34438, - 34263, 34202, 34438, 40151, 39486, 40074, 8221, 8030, 8076, 6927, 6892, 6874, 8300, - 8030, 8221, 34010, 34081, 33893, 34010, 33893, 33870, 30459, 30744, 30848, 43687, 43695, - 43555, 43555, 43695, 43649, 31940, 31990, 31885, 32036, 31990, 31940, 31567, 31450, 31468, - 35136, 35142, 35020, 41075, 40985, 40933, 40933, 40985, 40962, 41081, 40985, 41075, 42869, - 42906, 42816, 42828, 42976, 43082, 705, 609, 706, 1221, 1230, 1316, 8879, 9200, - 9062, 10319, 10285, 10375, 10405, 10558, 10637, 40220, 40175, 40074, 40169, 40175, 40268, - 40762, 40628, 40758, 42655, 42788, 42738, 43479, 43381, 43360, 42873, 42788, 43002, 507, - 414, 504, 31753, 31567, 31736, 39229, 39139, 39295, 42929, 43017, 43435, 3095, 3170, - 3129, 3732, 4269, 4002, 3095, 3129, 3076, 36929, 36753, 36897, 36377, 36243, 36192, - 36129, 35880, 35695, 37107, 36897, 37226, 36670, 36776, 36903, 37075, 36776, 36805, 414, - 346, 400, 362, 46, 598, 10102, 10191, 10093, 10802, 10778, 10735, 40921, 40811, - 41397, 42084, 41889, 42066, 42195, 42066, 42204, 2325, 2227, 2360, 2855, 2914, 2637, - 33208, 32784, 33114, 42192, 42195, 42382, 2312, 2227, 2325, 6676, 6748, 6873, 6734, - 6748, 6676, 41516, 40963, 41706, 7794, 8357, 7884, 7125, 7431, 7152, 36550, 36192, - 36528, 35695, 35368, 35293, 2053, 2150, 2122, 1438, 1564, 1582, 11816, 11188, 11331, - 2987, 3263, 3291, 3018, 3076, 2671, 36786, 36684, 36753, 36753, 36684, 36637, 1651, - 1801, 1791, 1582, 1564, 1716, 1343, 1221, 1316, 34354, 34255, 34102, 34428, 34255, - 34354, 10495, 10558, 10461, 2122, 2150, 2186, 7164, 7160, 7587, 6899, 7125, 7152, - 35101, 35136, 35020, 35208, 35735, 35306, 35101, 35020, 34938, 40985, 41081, 40962, 40767, - 40676, 40597, 42445, 42639, 42505, 42371, 42183, 42196, 42371, 42502, 42490, 42192, 42084, - 42066, 42192, 42066, 42195, 5492, 5707, 5380, 5795, 5873, 5876, 6328, 5943, 6095, - 34438, 34202, 34157, 34103, 34010, 33949, 41845, 41410, 41778, 2219, 2122, 2186, 2533, - 2421, 2520, 2439, 2421, 2533, 43531, 43635, 43555, 43117, 43017, 42885, 3095, 2964, - 3170, 2895, 3018, 2671, 5874, 5943, 5793, 40320, 40410, 40470, 40228, 40091, 40437, - 42237, 42196, 42099, 6980, 6892, 6927, 6748, 6866, 6873, 6714, 6866, 6748, 35647, - 35368, 35695, 34873, 34428, 34330, 5492, 5566, 5707, 43890, 43911, 43654, 43082, 42976, - 43170, 38833, 38490, 38713, 38439, 38425, 38490, 38490, 38425, 38246, 38246, 38399, 37988, - 37046, 37107, 37267, 38773, 38713, 38729, 38773, 38729, 38851, 38838, 38880, 38844, 38844, - 38880, 38881, 38881, 38972, 38805, 37796, 37410, 37221, 1049, 1221, 1343, 67, 46, - 362, 10654, 10735, 10637, 1720, 1732, 1681, 1874, 1732, 1791, 1564, 1462, 1519, - 1903, 1990, 2053, 7794, 7884, 7781, 7433, 7509, 7431, 7698, 7509, 7457, 34438, - 34157, 34215, 42788, 42873, 42738, 42783, 42788, 42655, 42783, 42655, 42856, 42190, 42192, - 42382, 43066, 43314, 43077, 41848, 41516, 41706, 41848, 41706, 41934, 32219, 32267, 32140, - 31567, 31753, 31750, 31736, 31468, 31629, 32219, 32140, 31990, 34215, 34081, 34103, 38910, - 39162, 39010, 38851, 38729, 38840, 42639, 42445, 42421, 43748, 43269, 43459, 5380, 5707, - 5442, 5795, 5785, 5738, 6406, 6513, 6389, 37107, 37226, 37267, 36377, 36203, 36243, - 4847, 4683, 4711, 4924, 4860, 5029, 5144, 5381, 5304, 5144, 5304, 5259, 1161, - 1231, 705, 602, 536, 663, 507, 446, 414, 292, 259, 346, 346, 259, - 362, 40770, 40762, 40758, 40175, 40169, 40074, 40770, 40758, 40789, 1438, 1462, 1564, - 2219, 2186, 2227, 2914, 2970, 2828, 3243, 3269, 3367, 38851, 38944, 38820, 38976, - 39139, 39229, 38838, 38539, 38855, 10191, 10285, 10319, 10558, 10654, 10637, 10276, 10285, - 10102, 42747, 42639, 42421, 2312, 2325, 2421, 6779, 6710, 6874, 7014, 6980, 7136, - 7014, 7136, 7160, 11188, 11102, 11029, 11190, 11102, 11188, 35368, 35274, 35195, 35586, - 35274, 35368, 35197, 35274, 35416, 43733, 43591, 43029, 38880, 38972, 38881, 3542, 3477, - 3610, 37107, 36929, 36897, 37046, 36929, 37107, 42084, 42085, 41797, 43006, 42816, 42906, - 42371, 42490, 42421, 42101, 42099, 41952, 40268, 40175, 40220, 4282, 4445, 4514, 3714, - 3608, 3920, 4821, 5410, 5137, 6503, 6676, 6618, 36929, 36884, 36753, 37051, 36884, - 36929, 2339, 2312, 2421, 6779, 6874, 6892, 6866, 6899, 7152, 6503, 6545, 6380, - 40313, 40268, 40220, 40921, 40770, 40789, 41081, 41288, 41003, 41774, 42049, 41813, 40677, - 40767, 40597, 1903, 2053, 2122, 1720, 1651, 1732, 1732, 1651, 1791, 10495, 10654, - 10558, 42190, 42085, 42084, 42077, 42085, 42190, 3608, 3542, 3610, 39229, 39295, 39621, - 40288, 40268, 40313, 1792, 2037, 1986, 1792, 1986, 1672, 6872, 6779, 6892, 7164, - 7014, 7160, 35274, 35197, 35195, 36203, 36152, 36243, 41039, 41075, 40933, 41966, 41848, - 41934, 41397, 40811, 41104, 9046, 8943, 9041, 7587, 7685, 7436, 9222, 9273, 9380, - 10722, 10802, 10735, 10947, 10815, 11067, 33249, 33126, 33074, 32285, 32269, 32195, 33319, - 33359, 33367, 33359, 33708, 33367, 36884, 36786, 36753, 36893, 36786, 36884, 42989, 42998, - 42906, 43234, 42998, 42989, 43210, 42989, 43082, 534, 536, 602, 534, 602, 706, - 2312, 2219, 2227, 2444, 2439, 2533, 2444, 2533, 2576, 32081, 32219, 31990, 33521, - 33263, 33512, 430, 446, 507, 42995, 42873, 43002, 42995, 42885, 42873, 43130, 43117, - 42885, 43314, 43066, 43792, 43911, 43765, 43150, 9981, 9707, 11029, 1981, 2219, 2312, - 6872, 6892, 6980, 5943, 6328, 6028, 40288, 40169, 40268, 41423, 41104, 41516, 43586, - 43459, 43591, 7695, 7781, 7698, 10276, 10405, 10285, 7695, 7698, 7457, 42077, 41982, - 42085, 42085, 41982, 41934, 42130, 42049, 41774, 42502, 42371, 42196, 43002, 42788, 42783, - 2568, 2637, 2476, 2828, 3097, 2820, 5639, 6160, 6309, 36673, 36528, 36684, 8784, - 8768, 8827, 8784, 8827, 8943, 33367, 33436, 33403, 43751, 43586, 43591, 43613, 43531, - 43433, 43695, 43823, 43800, 43568, 43433, 43479, 36786, 36673, 36684, 36773, 36673, 36786, - 292, 346, 414, 7457, 7509, 7433, 6899, 6866, 6741, 1719, 1553, 1561, 7014, - 6872, 6980, 7031, 7164, 7098, 35014, 35101, 34938, 35136, 35101, 35208, 36805, 36670, - 36337, 35014, 34938, 34927, 34157, 34081, 34215, 6529, 6503, 6456, 36123, 35735, 35917, - 38855, 38366, 38742, 40410, 40320, 40366, 40593, 40677, 40470, 40767, 40884, 40780, 43908, - 43823, 43695, 43800, 43823, 43869, 3018, 2944, 3095, 2814, 2895, 2671, 5259, 5304, - 5356, 5874, 5793, 5795, 6579, 6513, 6406, 4456, 4282, 4663, 3714, 3639, 3608, - 3608, 3525, 3542, 4456, 4663, 4683, 4748, 4846, 4909, 4909, 4881, 4950, 3263, - 3327, 3291, 11102, 10702, 11029, 11228, 11190, 11188, 38425, 38399, 38246, 38833, 38439, - 38490, 38820, 38713, 38773, 38851, 38840, 38910, 43765, 43733, 43029, 43314, 43201, 43170, - 2637, 2568, 2576, 2439, 2339, 2421, 1726, 1876, 1903, 3097, 3143, 2820, 10654, - 10722, 10735, 10461, 10558, 10405, 10285, 10191, 10102, 40437, 40091, 39983, 43635, 43687, - 43555, 43612, 43435, 43017, 2037, 2101, 2318, 1792, 2101, 2037, 6513, 6726, 6389, - 7031, 6872, 7014, 6714, 6748, 6734, 40151, 40074, 40169, 38855, 38539, 38366, 38880, - 38978, 38972, 38972, 39727, 39106, 38855, 38937, 38871, 42502, 42196, 42237, 87, 55, - 267, 10495, 10722, 10654, 10802, 10815, 10947, 43435, 43568, 43479, 37267, 37226, 37323, - 36291, 36211, 36203, 5259, 5356, 5293, 6726, 6446, 6389, 40288, 40151, 40169, 40288, - 40313, 40272, 4678, 4846, 4748, 6060, 6380, 6160, 38954, 38978, 38880, 1651, 1624, - 1582, 1462, 1246, 1343, 609, 534, 706, 1799, 1732, 1874, 1876, 1990, 1903, - 8509, 8457, 8354, 7139, 7431, 7125, 8357, 8457, 8721, 7794, 7781, 7695, 41982, - 41966, 41934, 41848, 41814, 41516, 42190, 42084, 42192, 42049, 42101, 41952, 42180, 42101, - 42130, 41288, 41081, 41075, 34081, 34010, 34103, 1799, 1876, 1726, 35917, 35735, 35208, - 34927, 34796, 34669, 41383, 41288, 41075, 4846, 4881, 4909, 8768, 8619, 8827, 8728, - 8784, 8943, 43612, 43534, 43435, 43435, 43534, 43568, 42747, 42655, 42639, 42995, 43130, - 42885, 280, 292, 414, 536, 430, 663, 386, 549, 705, 32457, 32653, 33036, - 32457, 32285, 32326, 43624, 43613, 43568, 43568, 43613, 43433, 34772, 34618, 34656, 31753, - 32036, 31940, 30836, 30626, 30649, 42382, 42215, 42409, 43170, 43201, 43082, 43210, 43201, - 43314, 3542, 3351, 3477, 3644, 3639, 3714, 1231, 386, 705, 32324, 32457, 32416, - 259, 67, 362, 280, 414, 290, 39717, 39295, 39700, 40220, 40945, 40313, 567, - 705, 549, 42890, 42747, 42421, 42655, 42747, 42879, 3639, 3525, 3608, 39717, 39700, - 39852, 10344, 10276, 10215, 10495, 10324, 10722, 8728, 8619, 8768, 33319, 33311, 33126, - 34335, 33708, 34255, 37051, 36893, 36884, 36129, 36000, 36152, 37051, 36929, 37046, 11190, - 11084, 11102, 11228, 11084, 11190, 43733, 43751, 43591, 43779, 43751, 43733, 43717, 43635, - 43613, 43717, 43687, 43635, 2568, 2444, 2576, 2476, 2444, 2568, 6749, 6710, 6779, - 6899, 6985, 7125, 6610, 6714, 6734, 6529, 6734, 6503, 6741, 6714, 6725, 40677, - 40884, 40767, 41050, 40884, 40677, 10344, 10461, 10405, 1720, 1624, 1651, 1599, 1624, - 1720, 1799, 1874, 1876, 32281, 32267, 32219, 34438, 34618, 34333, 1726, 1553, 1719, - 34857, 34927, 34669, 35014, 35246, 35101, 1493, 1438, 1582, 7522, 7794, 7695, 7471, - 7695, 7457, 5356, 5492, 5293, 5795, 5793, 5785, 36893, 36773, 36786, 37118, 36773, - 36893, 42068, 41966, 41982, 43006, 42906, 42998, 6872, 6749, 6779, 7164, 7031, 7014, - 7728, 8076, 7436, 6741, 6985, 6899, 11816, 11228, 11188, 30088, 30334, 29743, 30842, - 31035, 31478, 42068, 41982, 42077, 40911, 40762, 40770, 3458, 3351, 3542, 5785, 5793, - 5833, 2444, 2339, 2439, 2361, 2339, 2444, 36211, 36152, 36203, 34434, 34428, 34547, - 2895, 2944, 3018, 2814, 2944, 2895, 5833, 5793, 5943, 6977, 6749, 6872, 5730, - 5833, 5943, 6714, 6741, 6866, 6503, 6396, 6456, 40884, 41039, 40780, 41475, 41410, - 41352, 41058, 41039, 41050, 40593, 40470, 40410, 36377, 36192, 36550, 10324, 10815, 10722, - 10722, 10815, 10802, 30298, 30836, 30445, 496, 430, 536, 496, 536, 534, 496, - 534, 498, 5380, 5293, 5492, 31736, 32036, 31753, 32081, 32036, 32109, 498, 609, - 567, 498, 534, 609, 42856, 43002, 42783, 42995, 43105, 43130, 43344, 43017, 43117, - 42856, 42655, 42879, 8619, 8300, 8610, 43201, 43210, 43082, 43066, 43269, 43855, 32457, - 32324, 32285, 32269, 32150, 31860, 32416, 32639, 32551, 42859, 42747, 43011, 38439, 38399, - 38425, 38698, 38399, 38439, 38820, 38773, 38851, 292, 197, 259, 290, 414, 446, - 1799, 1681, 1732, 1624, 1493, 1582, 1643, 1681, 1799, 7139, 7125, 6985, 7367, - 7433, 7431, 34618, 34857, 34669, 34927, 35246, 35014, 34772, 34857, 34618, 41606, 41423, - 41516, 43748, 43459, 43586, 387, 498, 437, 1508, 1493, 1624, 7367, 7139, 6914, - 38932, 38976, 39162, 39010, 38851, 38910, 38838, 38895, 38880, 40635, 40437, 40692, 37075, - 36903, 36776, 3007, 3143, 3243, 2987, 3291, 3170, 2294, 2814, 2671, 5267, 5259, - 5293, 6028, 6328, 6406, 31231, 31424, 31288, 2964, 3095, 2868, 34010, 33870, 33949, - 39852, 39700, 40311, 40272, 40151, 40288, 42101, 42261, 42237, 41475, 41145, 41288, 5950, - 6160, 5639, 6637, 6914, 6985, 38855, 38895, 38838, 36323, 36129, 36211, 36211, 36129, - 36152, 4269, 4678, 4748, 4846, 4795, 4881, 4881, 4807, 5137, 4719, 4678, 4653, - 39162, 38976, 39229, 38895, 38954, 38880, 10461, 10324, 10495, 10276, 10344, 10405, 10102, - 10093, 9611, 30836, 31231, 30626, 42180, 42261, 42101, 4678, 4795, 4846, 36406, 35931, - 35908, 36406, 36222, 36509, 38092, 37796, 37979, 40911, 40770, 40921, 43344, 43117, 43130, - 3942, 3644, 3714, 3639, 3587, 3525, 3525, 3458, 3542, 2545, 2661, 2828, 3942, - 4445, 4282, 4924, 5029, 5144, 4924, 5144, 5121, 39338, 39162, 39229, 1367, 1462, - 1438, 1681, 1599, 1720, 1643, 1599, 1681, 7433, 7471, 7457, 8354, 8457, 8357, - 10006, 10102, 9611, 7367, 7471, 7433, 7367, 7431, 7139, 40514, 40593, 40410, 41615, - 41475, 41288, 41058, 41075, 41039, 42130, 42101, 42049, 6529, 6610, 6734, 6456, 6610, - 6529, 35880, 35647, 35695, 35854, 35647, 35880, 41022, 40911, 41135, 3644, 3587, 3639, - 5122, 5144, 5259, 5122, 5259, 5267, 35178, 34873, 35197, 32416, 32457, 32639, 1903, - 2122, 1981, 1643, 1726, 1719, 42130, 41774, 41845, 42261, 42502, 42237, 10791, 10702, - 11102, 9521, 9304, 9380, 8784, 8728, 8768, 8619, 8563, 8300, 10791, 11102, 11084, - 43534, 43624, 43568, 43687, 43908, 43695, 2828, 2661, 2914, 3007, 3243, 2991, 35702, - 35586, 35647, 36550, 36528, 36673, 36550, 36673, 36732, 36406, 35908, 36222, 39621, 39295, - 39717, 38988, 39010, 39020, 40945, 40220, 40762, 34473, 34618, 34438, 36509, 36605, 36406, - 33521, 33603, 33263, 42546, 42502, 42261, 43779, 43748, 43586, 43765, 43874, 43733, 43911, - 43874, 43765, 32036, 32081, 31990, 32190, 32081, 32109, 32036, 31736, 31772, 260, 290, - 446, 496, 387, 430, 1367, 1438, 1399, 3266, 3367, 3351, 2868, 3095, 2944, - 4758, 4719, 4653, 2868, 2944, 2814, 43063, 42998, 43234, 43063, 43006, 42998, 42989, - 43210, 43234, 280, 197, 292, 260, 446, 430, 32298, 32150, 32269, 33311, 33319, - 33367, 43002, 43105, 42995, 43777, 43717, 43624, 43141, 43105, 43002, 42859, 42879, 42747, - 43687, 43717, 43777, 43624, 43717, 43613, 6446, 6726, 6710, 5707, 5738, 5442, 6292, - 6389, 6332, 6977, 6872, 7031, 169, 197, 280, 10344, 10324, 10461, 8509, 8796, - 8457, 41966, 41814, 41848, 41022, 40913, 40911, 42228, 42068, 42077, 42228, 42077, 42190, - 42180, 42394, 42261, 42213, 42130, 42332, 9315, 9304, 9521, 6610, 6725, 6714, 6641, - 6725, 6610, 35647, 35586, 35368, 35854, 35880, 36056, 43246, 42382, 42409, 5738, 5553, - 5442, 36377, 36291, 36203, 36323, 36291, 36480, 41050, 41039, 40884, 40583, 40437, 40635, - 55, 141, 1211, 3625, 3573, 3177, 2964, 2868, 2873, 36605, 36805, 36337, 38376, - 38004, 38306, 1726, 1643, 1799, 1399, 1438, 1493, 2122, 2219, 1981, 7436, 8076, - 7488, 7436, 7488, 7440, 8354, 8357, 8234, 7193, 7367, 6914, 1399, 1493, 1508, - 34428, 34335, 34255, 34434, 34335, 34428, 42027, 41814, 41966, 3325, 3266, 3351, 197, - 67, 259, 8357, 7933, 8234, 32784, 32329, 33114, 35586, 35416, 35274, 36056, 35880, - 36129, 2534, 2476, 2637, 3007, 2820, 3143, 2876, 2820, 3007, 36406, 36605, 36337, - 38376, 38478, 38520, 34772, 34927, 34857, 2552, 2637, 2661, 40437, 40514, 40410, 40680, - 40514, 40583, 3266, 3198, 3367, 37323, 37226, 37761, 40679, 40677, 40593, 41475, 41615, - 41410, 3644, 3544, 3587, 3587, 3458, 3525, 3248, 3165, 3198, 4046, 3942, 4282, - 4456, 4683, 4924, 8586, 8879, 9062, 38152, 37175, 37988, 38820, 38833, 38713, 38988, - 38944, 38851, 38988, 38851, 39010, 39010, 39162, 39020, 38855, 38871, 38895, 38895, 39000, - 38954, 39207, 38972, 38978, 38599, 38366, 38311, 38311, 38004, 38376, 39020, 39162, 39272, - 38871, 39000, 38895, 5267, 5380, 5296, 5122, 5121, 5144, 8509, 8586, 8796, 8357, - 7794, 7933, 33521, 33788, 33603, 34473, 34438, 34413, 33805, 33788, 33521, 42068, 42027, - 41966, 42372, 42228, 42190, 42372, 42190, 42382, 7329, 7098, 7164, 7316, 7436, 7440, - 34438, 34215, 34413, 35830, 35747, 35854, 36548, 36550, 36732, 43779, 43586, 43751, 567, - 609, 705, 1508, 1624, 1599, 1508, 1599, 1643, 34413, 34215, 34359, 498, 387, - 496, 290, 169, 280, 197, 89, 67, 1230, 386, 1231, 4795, 4762, 4881, - 4678, 4719, 4795, 2987, 3170, 2964, 32081, 32190, 32219, 31772, 31736, 31629, 39338, - 39229, 39621, 43006, 43275, 42409, 43234, 43210, 43272, 43141, 43002, 42856, 43141, 42856, - 43057, 42747, 42890, 43011, 43272, 43210, 43314, 9078, 8943, 9046, 33403, 33311, 33367, - 7212, 7098, 7329, 6389, 6292, 6406, 9304, 9222, 9380, 9719, 9551, 9707, 31629, - 31424, 31420, 31629, 31468, 31424, 35854, 35747, 35647, 36056, 36129, 36104, 40911, 40913, - 40762, 39621, 39717, 39889, 40911, 40921, 41135, 4719, 4762, 4795, 1230, 1221, 386, - 31420, 31424, 31231, 43057, 42859, 43011, 37267, 37051, 37046, 36893, 37051, 37118, 35545, - 35416, 35586, 3456, 3544, 3644, 9315, 9222, 9304, 10102, 10215, 10276, 10006, 10215, - 10102, 31447, 31420, 31231, 43874, 43779, 43733, 43748, 43747, 43269, 8728, 8563, 8619, - 8620, 8563, 8728, 8316, 8586, 8509, 10006, 10324, 10215, 40151, 40311, 39700, 2873, - 2987, 2964, 3001, 2987, 2873, 6446, 6710, 6463, 35702, 35545, 35586, 36323, 36211, - 36291, 36291, 36377, 36480, 40680, 40679, 40593, 40680, 40593, 40514, 41801, 41615, 41288, - 41048, 41050, 40677, 3544, 3458, 3587, 2538, 2552, 2482, 1246, 1462, 1367, 1598, - 1508, 1643, 41299, 41075, 41058, 42130, 42213, 42180, 1981, 2312, 2339, 7316, 7212, - 7329, 7078, 6977, 7031, 7316, 7329, 7436, 43777, 43908, 43687, 43777, 43624, 43750, - 33436, 33367, 33821, 34547, 34428, 34984, 34473, 34656, 34618, 34555, 34413, 34359, 41615, - 41778, 41410, 2545, 2552, 2661, 2476, 2461, 2444, 2876, 3007, 2991, 6060, 5950, - 5994, 6725, 6641, 6741, 3165, 3243, 3198, 5087, 5121, 5122, 5267, 5293, 5380, - 7078, 7031, 7098, 41814, 41606, 41516, 42223, 42027, 42068, 42223, 42068, 42228, 43781, - 43747, 43748, 40151, 40272, 40384, 387, 358, 430, 324, 358, 387, 437, 498, - 420, 32411, 32269, 32324, 32411, 32324, 32416, 32172, 32109, 32175, 31772, 32109, 32036, - 32190, 32281, 32219, 33788, 33949, 33870, 32109, 31772, 31775, 324, 437, 420, 32172, - 32281, 32190, 43063, 43113, 43006, 43261, 43113, 43063, 43241, 43063, 43234, 43221, 43344, - 43130, 43057, 42856, 42879, 43057, 42879, 42859, 35702, 35647, 35747, 34984, 34428, 34873, - 43379, 43272, 43314, 43221, 43130, 43105, 2538, 2534, 2552, 2552, 2534, 2637, 36548, - 36377, 36550, 35902, 35830, 35854, 32551, 32411, 32416, 32457, 33036, 32639, 42546, 42490, - 42502, 8354, 8353, 8509, 8642, 8970, 8879, 7522, 7695, 7471, 8353, 8234, 8316, - 42332, 42130, 41845, 5730, 5785, 5833, 34183, 33708, 34335, 43750, 43624, 43534, 1276, - 1367, 1399, 8661, 8620, 8728, 9551, 9315, 9521, 9222, 9315, 9165, 141, 160, - 978, 91, 160, 141, 7150, 7078, 7098, 8076, 8030, 7488, 38871, 38937, 39000, - 40583, 40514, 40437, 38510, 38478, 38376, 38599, 38706, 38366, 36975, 37075, 36805, 38706, - 38742, 38366, 5087, 4924, 5121, 4485, 4456, 4924, 3353, 3458, 3544, 3353, 3349, - 3458, 38931, 38833, 38820, 38931, 38820, 38944, 38931, 38944, 39098, 38931, 39098, 38903, - 38988, 39098, 38944, 38742, 38785, 38855, 2101, 2275, 2671, 1660, 1792, 1573, 6463, - 6710, 6749, 7150, 7098, 7212, 55, 91, 141, 6000, 5730, 5943, 6028, 6406, - 6292, 38833, 38931, 38903, 38785, 38937, 38855, 3248, 3198, 3266, 2442, 2461, 2534, - 3349, 3351, 3458, 6411, 6446, 6463, 6396, 6503, 6380, 36034, 35854, 36056, 2534, - 2461, 2476, 2361, 2461, 2298, 33263, 32823, 33424, 35702, 35501, 35545, 35545, 35501, - 35416, 38988, 39020, 39098, 40384, 40272, 40313, 3177, 3573, 3263, 4719, 4758, 4762, - 4762, 4807, 4881, 6471, 6610, 6456, 4741, 4758, 4653, 36323, 36104, 36129, 36732, - 36673, 36773, 36732, 36773, 37118, 40389, 40384, 40313, 40945, 40762, 40913, 45, 738, - 978, 43865, 43750, 43534, 7221, 7150, 7212, 6463, 6749, 6415, 7488, 7656, 7460, - 8030, 7656, 7488, 41998, 41606, 41814, 2461, 2361, 2444, 2538, 2482, 2442, 8234, - 8353, 8354, 7522, 7471, 7193, 33727, 33805, 33521, 33727, 33521, 33547, 35497, 35365, - 35501, 36328, 36104, 36323, 41043, 41048, 40677, 41271, 41299, 41058, 38978, 38954, 39207, - 41397, 41104, 41423, 40769, 40677, 40679, 42394, 42500, 42443, 42332, 42309, 42213, 41845, - 42366, 42332, 42213, 42309, 42180, 34434, 34417, 34335, 35365, 35197, 35416, 34413, 34555, - 34473, 36705, 36509, 36579, 34359, 34215, 34278, 7221, 7212, 7316, 41541, 41397, 41423, - 3165, 2991, 3243, 3031, 2991, 3165, 2987, 3001, 3263, 2873, 2868, 2791, 5553, - 5738, 5785, 5267, 5087, 5122, 5553, 5785, 5572, 42608, 42546, 42261, 33424, 32823, - 33208, 32109, 32172, 32190, 31657, 31772, 31629, 43865, 43839, 43750, 43141, 43221, 43105, - 43289, 43221, 43213, 43221, 43141, 43213, 324, 260, 358, 358, 260, 430, 324, - 387, 437, 9981, 9719, 9707, 11228, 10791, 11084, 31478, 31382, 31860, 35501, 35365, - 35416, 35702, 35747, 35791, 36605, 36975, 36805, 35246, 34927, 34772, 115, 169, 290, - 31447, 31643, 31420, 31420, 31643, 31629, 3001, 3177, 3263, 2791, 2868, 2814, 5280, - 5087, 5267, 5572, 5785, 5730, 3353, 3544, 3456, 33988, 33949, 33805, 33805, 33949, - 33788, 2099, 2275, 1851, 6411, 6332, 6389, 6411, 6389, 6446, 31204, 31447, 31231, - 33424, 33208, 33363, 36104, 36034, 36056, 36175, 36034, 36104, 40680, 40769, 40679, 40772, - 40769, 40680, 2154, 1981, 2339, 1719, 1598, 1643, 1348, 1276, 1399, 6568, 6641, - 6610, 6396, 6380, 6060, 35791, 35747, 35830, 3349, 3325, 3351, 5296, 5380, 5409, - 2361, 2154, 2339, 2828, 2820, 2545, 2820, 2715, 2545, 7199, 7221, 7316, 7066, - 6977, 7078, 8433, 8300, 8563, 34567, 34473, 34555, 34567, 34656, 34473, 10215, 10324, - 10344, 8970, 9200, 8879, 30836, 31204, 31231, 1561, 1598, 1719, 2803, 3177, 3001, - 2746, 2791, 2814, 5409, 5380, 5442, 5692, 5572, 5730, 7157, 7221, 7199, 41606, - 41541, 41423, 41135, 41007, 41022, 41537, 41541, 41591, 42014, 41814, 42027, 1348, 1399, - 1508, 420, 498, 567, 34547, 34417, 34434, 34544, 34417, 34547, 35178, 35197, 35365, - 34278, 34215, 34103, 3325, 3248, 3266, 33677, 33727, 33547, 34492, 34555, 34359, 33677, - 33547, 33512, 42498, 42372, 42382, 42890, 42421, 42490, 42309, 42394, 42180, 41845, 41778, - 42366, 41058, 41050, 41053, 6074, 6028, 6292, 7066, 7078, 7150, 6373, 6396, 6265, - 35497, 35178, 35365, 36034, 35902, 35854, 36175, 35902, 36034, 41007, 40945, 40913, 40317, - 39889, 39852, 41007, 40913, 41022, 36548, 36480, 36377, 37323, 37051, 37267, 6074, 6292, - 6332, 41053, 41050, 41048, 39207, 38954, 39000, 38937, 39274, 39000, 38785, 38946, 38937, - 38742, 38839, 38785, 38706, 38732, 38742, 38599, 38635, 38706, 38376, 38520, 38599, 38478, - 38510, 38585, 38520, 38635, 38599, 38520, 38478, 38585, 2907, 3001, 2873, 38152, 37988, - 38399, 38833, 38817, 38439, 38903, 38817, 38833, 39162, 39327, 39272, 38732, 38839, 38742, - 39162, 39338, 39327, 38839, 38946, 38785, 43747, 43855, 43269, 43272, 43241, 43234, 42498, - 42400, 42372, 43866, 43781, 43748, 43866, 43748, 43779, 38581, 38152, 38399, 43383, 43241, - 43272, 260, 115, 290, 420, 567, 372, 32172, 32293, 32281, 32175, 32293, 32172, - 31657, 31629, 31643, 31657, 31643, 31587, 43792, 43379, 43314, 372, 567, 549, 1276, - 1246, 1367, 1356, 1348, 1508, 1356, 1508, 1445, 5409, 5442, 5445, 5442, 5553, - 5445, 34278, 34103, 34349, 34492, 34567, 34555, 34656, 34844, 34772, 39852, 39889, 39717, - 40311, 40151, 40384, 9087, 9046, 9222, 9087, 9222, 9165, 34384, 34278, 34349, 32823, - 32784, 33208, 169, 89, 197, 47, 115, 260, 160, 147, 978, 64, 147, - 160, 31775, 31657, 31693, 40389, 40311, 40384, 43129, 43011, 43177, 43221, 43289, 43344, - 7157, 7066, 7150, 7157, 7150, 7221, 7316, 7440, 7199, 35497, 35501, 35525, 6752, - 6749, 6977, 6411, 6311, 6332, 7193, 7471, 7367, 6396, 6471, 6456, 6373, 6471, - 6396, 35902, 35791, 35830, 36018, 35791, 35902, 40857, 40389, 40313, 41135, 40921, 41528, - 1196, 1246, 1276, 34103, 33949, 34349, 42089, 42014, 42027, 41528, 40921, 41397, 43702, - 43383, 43379, 43874, 43866, 43779, 32150, 31478, 31860, 31965, 31478, 32150, 32298, 32269, - 32411, 33126, 33036, 32653, 4758, 4741, 4762, 4653, 4678, 3892, 3892, 4516, 4603, - 39327, 39338, 39393, 39301, 39207, 39274, 5553, 5572, 5499, 5445, 5553, 5499, 41053, - 41048, 41056, 4741, 4807, 4762, 8620, 8484, 8563, 39393, 39338, 39621, 39207, 39349, - 38972, 42400, 42228, 42372, 42400, 42223, 42228, 40311, 40434, 39852, 40461, 40389, 40525, - 39327, 39288, 39272, 39866, 39393, 39621, 2791, 2907, 2873, 3732, 4002, 3625, 2746, - 2907, 2791, 6000, 5943, 6028, 40685, 40772, 40680, 40685, 40680, 40583, 6471, 6568, - 6610, 6373, 6568, 6471, 40996, 40313, 40945, 41537, 41397, 41541, 41043, 40677, 40769, - 34690, 34844, 34567, 34567, 34844, 34656, 3325, 3246, 3248, 2820, 2876, 2715, 3349, - 3246, 3325, 3456, 3644, 3942, 3456, 3209, 3354, 4046, 4456, 4043, 5280, 5267, - 5296, 5280, 5296, 5409, 7453, 7440, 7488, 6163, 6219, 6233, 41591, 41541, 41606, - 41591, 41606, 42260, 33821, 33367, 33708, 34600, 34544, 34547, 34384, 34492, 34359, 34384, - 34359, 34278, 36780, 36480, 36548, 36455, 36480, 36780, 41271, 41383, 41299, 41299, 41383, - 41075, 42223, 42089, 42027, 42189, 42089, 42223, 43213, 43141, 43057, 43213, 43057, 43202, - 43275, 43006, 43113, 43379, 43383, 43272, 43855, 43747, 43781, 43129, 43057, 43011, 6315, - 6311, 6411, 6219, 6311, 6233, 41053, 41271, 41058, 40772, 40886, 40769, 40899, 40886, - 40772, 31657, 31775, 31772, 33363, 33512, 33424, 31587, 31643, 31447, 47, 89, 115, - 420, 95, 324, 95, 372, 36, 33436, 33311, 33403, 42443, 42261, 42394, 42890, - 42490, 42876, 115, 89, 169, 47, 260, 324, 31693, 31587, 31447, 41801, 41778, - 41615, 1548, 1508, 1598, 2538, 2442, 2534, 3031, 3165, 3248, 6074, 6000, 6028, - 36480, 36347, 36323, 35525, 35501, 35702, 35178, 34984, 34873, 36455, 36347, 36480, 40691, - 40635, 40692, 3732, 3625, 3419, 2415, 2746, 2814, 33490, 33436, 33821, 1246, 1049, - 1343, 1348, 1196, 1276, 1548, 1598, 1561, 6311, 6315, 6233, 7656, 7716, 7681, - 7139, 6985, 6914, 8561, 8879, 8586, 1726, 1903, 1553, 7288, 7199, 7440, 6985, - 6741, 6637, 41187, 41132, 41135, 41998, 41814, 42014, 8417, 8433, 8484, 8484, 8433, - 8563, 9326, 9315, 9551, 38817, 38698, 38439, 37196, 37174, 37637, 36455, 36328, 36347, - 38768, 38698, 38815, 38698, 38817, 38815, 39098, 39020, 39264, 39020, 39272, 39264, 39301, - 39349, 39207, 39301, 39400, 39349, 38839, 38969, 38946, 38635, 38732, 38706, 38520, 38718, - 38635, 38585, 38718, 38520, 38376, 38306, 38510, 1250, 1196, 1348, 34492, 34690, 34567, - 33677, 33805, 33727, 33677, 33512, 33518, 38698, 38581, 38399, 38004, 37796, 38306, 38718, - 38732, 38635, 42089, 41998, 42014, 42189, 41998, 42089, 6637, 6741, 6641, 38306, 38275, - 38373, 5379, 5280, 5409, 5762, 5692, 5730, 6265, 6396, 6060, 6568, 6637, 6641, - 40899, 41043, 40886, 40886, 41043, 40769, 38306, 37796, 38092, 3063, 3031, 3248, 5379, - 5409, 5445, 8587, 8484, 8620, 33114, 33190, 33208, 42500, 42394, 42309, 5620, 5572, - 5692, 6219, 6074, 6332, 6219, 6332, 6311, 36347, 36328, 36323, 36175, 36328, 36471, - 40635, 40685, 40583, 40688, 40685, 40635, 39727, 38972, 39349, 39264, 39272, 39288, 39264, - 39296, 39112, 41155, 41271, 41053, 41383, 41801, 41288, 42668, 42608, 42443, 4807, 4821, - 5137, 4741, 4716, 4807, 3625, 3177, 3419, 39327, 39451, 39288, 2821, 2876, 2991, - 2298, 2154, 2361, 36509, 36705, 36605, 36123, 35908, 35735, 35208, 35101, 35246, 40389, - 40461, 40311, 40973, 40945, 41007, 41132, 41007, 41135, 4653, 4716, 4741, 43261, 43063, - 43241, 43750, 43839, 43777, 43777, 43839, 43908, 43612, 43017, 43344, 41528, 41397, 41537, - 41043, 41056, 41048, 41166, 41056, 41043, 2275, 2294, 2671, 2099, 2294, 2275, 2415, - 2294, 2248, 36328, 36175, 36104, 37174, 37051, 37323, 41666, 41528, 41537, 41666, 41537, - 41591, 41666, 42260, 41788, 9981, 11029, 10702, 32456, 32298, 32411, 32456, 32411, 32551, - 43383, 43261, 43241, 43402, 43261, 43425, 8736, 8661, 8728, 7439, 7453, 7460, 9078, - 9046, 9087, 34047, 34349, 33949, 32267, 33114, 32329, 3031, 2880, 2991, 5499, 5379, - 5445, 5499, 5572, 5531, 32484, 32456, 32551, 38209, 37226, 38152, 43129, 43202, 43057, - 43213, 43288, 43289, 43604, 43612, 43344, 43285, 43202, 43129, 3031, 2881, 2880, 3353, - 3246, 3349, 3456, 3441, 3209, 4282, 4456, 4046, 4716, 4821, 4807, 38969, 38937, - 38946, 34384, 34543, 34492, 33988, 33805, 33677, 9333, 9326, 9551, 10379, 9981, 10702, - 33281, 33126, 33311, 35525, 35702, 35656, 33490, 33281, 33436, 2337, 2482, 2407, 2545, - 2482, 2552, 9220, 9165, 9315, 2880, 2821, 2991, 2715, 2821, 2645, 4924, 5087, - 4485, 5531, 5572, 5620, 37174, 37118, 37051, 37196, 37118, 37174, 2298, 2461, 2442, - 5620, 5692, 5714, 6977, 7066, 6752, 9012, 9078, 9087, 35246, 34772, 34844, 40774, - 40899, 40772, 40774, 40772, 40685, 42876, 42490, 42862, 41056, 41155, 41053, 41933, 41801, - 42132, 41166, 41155, 41056, 7017, 7066, 7157, 7460, 7453, 7488, 8030, 7716, 7656, - 41379, 41383, 41271, 42443, 42608, 42261, 36780, 36548, 36732, 35656, 35702, 36018, 1548, - 1445, 1508, 1142, 1049, 1196, 1553, 1903, 1981, 3105, 3246, 3353, 41562, 41187, - 41135, 41594, 41666, 41788, 2337, 2298, 2442, 2821, 2715, 2876, 2640, 2715, 2645, - 5087, 5280, 5151, 5730, 6000, 5762, 8336, 8433, 8417, 8336, 8300, 8433, 34423, - 34543, 34384, 34423, 34384, 34349, 8587, 8620, 8661, 42360, 42189, 42223, 42657, 42498, - 42730, 3246, 3139, 3248, 7491, 7933, 7522, 7522, 7933, 7794, 7144, 7522, 7193, - 7144, 7193, 6933, 42380, 42223, 42400, 6373, 6483, 6568, 6060, 6160, 5950, 41132, - 40973, 41007, 41125, 40973, 41132, 33436, 33281, 33311, 34061, 33827, 33821, 5280, 5379, - 5151, 5966, 6000, 6074, 41281, 41227, 41155, 40691, 40688, 40635, 41155, 41227, 41271, - 41166, 41043, 41407, 39015, 38969, 38839, 38718, 38653, 38732, 38585, 38653, 38718, 38526, - 38653, 38585, 38526, 38585, 38510, 38526, 38510, 38373, 38581, 38595, 38152, 38698, 38684, - 38581, 38815, 38817, 38998, 38817, 38903, 38998, 38903, 39104, 38998, 3139, 3063, 3248, - 38373, 38510, 38306, 38903, 39098, 39104, 43285, 43288, 43202, 43202, 43288, 43213, 32639, - 32484, 32551, 32456, 32275, 32298, 31708, 31250, 31478, 31478, 31250, 30744, 32526, 32484, - 32623, 34047, 33988, 33984, 37796, 37952, 37979, 39098, 39264, 39112, 39104, 39098, 39112, - 39015, 38839, 38732, 40781, 40774, 40688, 42423, 42380, 42400, 42423, 42400, 42498, 91, - 64, 160, 147, 45, 978, 1660, 2101, 1792, 2837, 3001, 2907, 4603, 4703, - 4716, 4716, 4703, 4821, 2837, 2907, 2746, 8632, 8587, 8661, 7681, 7563, 7656, - 32623, 32484, 32639, 34471, 34417, 34544, 39451, 39296, 39288, 42500, 42309, 42332, 43325, - 43285, 43129, 1561, 1445, 1548, 1196, 1049, 1246, 1426, 1445, 1561, 9012, 8999, - 9078, 9078, 8736, 8943, 9326, 9220, 9315, 9333, 9220, 9326, 9333, 9551, 9613, - 35291, 34984, 35178, 35291, 35178, 35497, 40466, 40311, 40461, 35702, 35791, 36018, 37118, - 36780, 36732, 37196, 36780, 37118, 40525, 40466, 40461, 35111, 35246, 34844, 34690, 34492, - 34543, 34468, 34423, 34349, 36975, 36605, 36705, 37796, 37221, 37952, 1846, 1553, 1981, - 2337, 2442, 2482, 2482, 2545, 2407, 40688, 40774, 40685, 39727, 39349, 39400, 39327, - 39393, 39451, 39274, 39207, 39000, 8215, 8417, 8342, 8587, 8417, 8484, 35497, 35525, - 35563, 8316, 8509, 8353, 42862, 42490, 42546, 10791, 10379, 10702, 9799, 9696, 9719, - 32275, 32150, 32298, 5994, 5950, 5929, 4603, 4716, 4653, 33988, 34047, 33949, 33750, - 33988, 33677, 33308, 33208, 33190, 32175, 32109, 31775, 2640, 2545, 2715, 3139, 3058, - 3063, 3105, 3058, 3139, 3456, 3354, 3353, 5379, 5499, 5151, 2664, 2837, 2746, - 6219, 6163, 6074, 7017, 7157, 7199, 36123, 36222, 35908, 36290, 36222, 36123, 7453, - 7288, 7440, 7439, 7288, 7453, 7563, 7460, 7656, 41227, 41379, 41271, 42511, 42500, - 42332, 41274, 41166, 41407, 7681, 7716, 7633, 34984, 34600, 34547, 34471, 34600, 34615, - 1250, 1348, 1356, 1846, 1981, 2154, 7256, 7017, 7199, 41666, 41594, 41528, 40731, - 40525, 40389, 42156, 41606, 41998, 42156, 41998, 42305, 42366, 41778, 42474, 42838, 42862, - 42546, 1792, 1672, 1422, 2294, 2415, 2814, 33490, 33408, 33281, 33555, 33408, 33490, - 1250, 1356, 1243, 1422, 1672, 579, 6822, 6752, 7066, 32526, 32275, 32456, 32526, - 32456, 32484, 8999, 8736, 9078, 9799, 9719, 9981, 43177, 42890, 43229, 43177, 43011, - 42890, 43674, 43612, 43604, 39651, 39727, 39400, 9613, 9551, 9719, 9611, 10093, 9686, - 31587, 31693, 31657, 31204, 31693, 31447, 1851, 2275, 2101, 6163, 5966, 6074, 6315, - 6411, 6463, 34577, 34690, 34543, 33750, 33677, 33813, 42500, 42668, 42443, 41933, 41778, - 41801, 41166, 41281, 41155, 41274, 41281, 41166, 40922, 40899, 40774, 42695, 42668, 42782, - 2298, 2177, 2154, 2821, 2880, 2728, 40692, 40437, 40695, 3016, 3031, 3063, 2415, - 2664, 2746, 2708, 3419, 3177, 2700, 2683, 2769, 36908, 36975, 36705, 7288, 7256, - 7199, 7017, 6822, 7066, 7563, 7439, 7460, 7435, 7439, 7563, 41657, 41801, 41383, - 1553, 1426, 1561, 1401, 1426, 1553, 3105, 3139, 3246, 8300, 8336, 8193, 7569, - 7681, 7633, 34600, 34471, 34544, 34615, 34600, 34657, 5551, 5499, 5531, 3118, 3105, - 3353, 5551, 5531, 5620, 38768, 38684, 38698, 38890, 38684, 38768, 39067, 38768, 38815, - 38961, 38815, 38998, 39174, 38998, 39104, 39174, 39104, 39112, 38969, 39274, 38937, 39301, - 39651, 39400, 38918, 39008, 38732, 38526, 38725, 38653, 38618, 38725, 38526, 38618, 38526, - 38373, 38275, 38306, 38092, 42838, 42546, 42608, 7933, 8316, 8234, 8970, 9494, 9686, - 8325, 8316, 8133, 32155, 31965, 32275, 34446, 34335, 34417, 33518, 33512, 33363, 33308, - 33363, 33208, 39008, 39015, 38732, 5993, 5966, 6163, 6415, 6315, 6463, 6415, 6749, - 6752, 41187, 41125, 41132, 40466, 40434, 40311, 40525, 40434, 40466, 39333, 39174, 39112, - 43866, 43855, 43781, 42657, 42423, 42498, 2959, 3016, 3058, 3058, 3016, 3063, 2130, - 2248, 2294, 2130, 2294, 2099, 5993, 6163, 6050, 40691, 40781, 40688, 40922, 40781, - 40691, 38383, 38235, 38152, 38199, 38275, 38092, 39296, 39264, 39288, 6483, 6637, 6568, - 6483, 6373, 6360, 41281, 41379, 41227, 41327, 41379, 41281, 9087, 9165, 9012, 32267, - 32281, 33114, 42695, 42838, 42608, 42695, 42608, 42668, 38235, 38209, 38152, 38203, 38199, - 38092, 40695, 40437, 39983, 39130, 39274, 38969, 3016, 2881, 3031, 2147, 2298, 2337, - 2728, 2881, 2753, 39451, 39866, 39490, 40000, 39621, 39889, 40996, 40945, 40973, 42380, - 42360, 42223, 41562, 41135, 41528, 43275, 43113, 43402, 42366, 42511, 42332, 42474, 42511, - 42366, 9611, 9494, 9294, 7282, 7256, 7288, 7282, 7288, 7439, 7569, 7563, 7681, - 9846, 9799, 9981, 9696, 9613, 9719, 9012, 9165, 9133, 32275, 31965, 32150, 33126, - 33281, 33036, 1294, 1445, 1426, 1294, 1356, 1445, 34577, 34543, 34423, 35851, 35917, - 35208, 34468, 34349, 34047, 33036, 33281, 33120, 4654, 4843, 4703, 2803, 3001, 2837, - 8316, 8561, 8586, 8642, 8561, 8325, 34474, 34599, 34678, 33308, 33518, 33363, 37952, - 37720, 37949, 40000, 39889, 40166, 6582, 6415, 6752, 6050, 6163, 6233, 35499, 35291, - 35497, 35902, 36175, 36018, 36222, 36579, 36509, 36002, 35917, 35851, 41125, 41124, 40973, - 41125, 41187, 41165, 43447, 43289, 43288, 43447, 43288, 43285, 42890, 42876, 42990, 2147, - 2177, 2298, 2407, 2545, 2374, 4843, 5410, 4821, 34471, 34446, 34417, 34484, 34446, - 34471, 34468, 34599, 34474, 2700, 2803, 2837, 2700, 2837, 2664, 37957, 37952, 37949, - 2374, 2545, 2640, 5752, 6000, 5966, 5752, 5762, 6000, 4703, 4843, 4821, 4678, - 4269, 3854, 34312, 34183, 34335, 33120, 33281, 33265, 42423, 42360, 42380, 42305, 42360, - 42494, 8215, 8336, 8417, 9165, 9220, 9133, 33555, 33490, 33821, 2803, 2738, 3177, - 2769, 2683, 2748, 37637, 37174, 37323, 36947, 36471, 36455, 2065, 1846, 2154, 2082, - 2154, 2177, 6933, 7193, 6914, 6360, 6373, 6265, 41379, 41507, 41383, 42527, 42500, - 42511, 41326, 41274, 41434, 1370, 1294, 1426, 33114, 32281, 32293, 33308, 33593, 33518, - 34474, 34423, 34468, 1660, 1728, 2101, 2248, 2288, 2415, 579, 1672, 738, 1158, - 1142, 1250, 1250, 1142, 1196, 95, 420, 372, 95, 47, 324, 6582, 6822, - 6668, 8417, 8587, 8512, 35001, 34600, 34984, 34446, 34312, 34335, 34474, 34577, 34423, - 34690, 34818, 34844, 34690, 34577, 34761, 41434, 41274, 41407, 40695, 39983, 39727, 42305, - 41998, 42189, 2223, 2337, 2407, 3118, 3353, 3354, 8632, 8661, 8736, 34061, 33708, - 34183, 34061, 33821, 33708, 1422, 1573, 1792, 6050, 6233, 6172, 6822, 7017, 6668, - 34363, 34312, 34446, 8732, 8632, 8736, 8561, 8642, 8879, 8325, 8561, 8316, 41165, - 41124, 41125, 41165, 41187, 41607, 9669, 9613, 9696, 8999, 8732, 8736, 9465, 9613, - 9541, 9494, 9611, 9686, 9660, 9611, 9294, 31965, 31708, 31478, 32415, 32241, 32275, - 32499, 32275, 32526, 386, 1221, 1049, 10008, 9846, 9981, 1573, 1728, 1660, 41274, - 41327, 41281, 41326, 41327, 41274, 32774, 32623, 32639, 32774, 32639, 32948, 34112, 34061, - 34183, 32948, 32639, 33036, 40317, 39852, 40434, 40317, 40434, 40502, 31880, 31708, 31965, - 33555, 33821, 33808, 38684, 38595, 38581, 38235, 38274, 38209, 38209, 38180, 37226, 38789, - 38595, 38684, 38961, 38998, 39090, 38998, 39174, 39090, 39112, 39296, 39333, 39333, 39296, - 39463, 39015, 39109, 38969, 39641, 39651, 39301, 38918, 38732, 38653, 38918, 38653, 38725, - 38414, 38373, 38275, 38414, 38275, 38254, 38275, 38199, 38254, 42990, 42876, 42862, 42990, - 42862, 42838, 8533, 8587, 8632, 8533, 8512, 8587, 7282, 7435, 7331, 33808, 33821, - 33827, 42782, 42668, 42500, 42474, 41778, 41933, 39008, 39109, 39015, 1142, 1039, 1049, - 1294, 1243, 1356, 1152, 1243, 1294, 6695, 6914, 6637, 7569, 7435, 7563, 8030, - 8300, 7716, 34761, 34818, 34690, 33988, 33750, 33984, 38595, 38383, 38152, 38203, 38092, - 38097, 38092, 37979, 38097, 37979, 37962, 38097, 43855, 43792, 43066, 9133, 9220, 9167, - 33120, 32948, 33036, 8193, 8336, 8215, 33813, 33677, 33518, 1152, 1158, 1243, 2223, - 2147, 2337, 2728, 2880, 2881, 5762, 5714, 5692, 6233, 6315, 6172, 6315, 6415, - 6172, 6302, 6360, 6213, 6500, 6662, 6637, 5929, 5950, 5345, 38274, 38180, 38209, - 37979, 37952, 37962, 39463, 39296, 39451, 43912, 43865, 43612, 43612, 43865, 43534, 33265, - 33281, 33408, 43233, 42990, 43134, 8375, 8342, 8417, 8375, 8417, 8512, 33480, 33265, - 33408, 34003, 33808, 33827, 33593, 33813, 33518, 6500, 6637, 6483, 36471, 36328, 36455, - 34484, 34471, 34615, 34484, 34363, 34446, 34199, 34112, 34183, 34061, 34003, 33827, 4843, - 4768, 5639, 3854, 4269, 3732, 37962, 37952, 37957, 39490, 39463, 39451, 4603, 4654, - 4703, 37221, 37720, 37952, 5752, 5714, 5762, 8930, 8732, 8999, 33606, 33408, 33555, - 35111, 34995, 34963, 34818, 34995, 34844, 36002, 36290, 36123, 34995, 34818, 34761, 2147, - 2082, 2177, 2065, 2082, 2123, 2047, 2130, 2099, 5935, 5752, 5966, 6172, 5936, - 5897, 36002, 36123, 35917, 41124, 40996, 40973, 41184, 40996, 41124, 2099, 1851, 1923, - 1923, 1851, 1759, 1728, 1851, 2101, 2885, 2881, 3016, 2700, 2769, 2803, 3672, - 3854, 3732, 2311, 2664, 2415, 6075, 6265, 6060, 8173, 8193, 8215, 8173, 8215, - 8342, 1243, 1158, 1250, 1401, 1553, 1846, 1392, 1401, 1306, 6695, 6637, 6662, - 6695, 6933, 6914, 8133, 8316, 7947, 32241, 32155, 32275, 32265, 32155, 32241, 32499, - 32526, 32623, 32499, 32623, 32613, 32623, 32696, 32613, 32774, 32948, 32861, 8608, 8533, - 8632, 4756, 4768, 4843, 32071, 32048, 31965, 32861, 32948, 32965, 7890, 7716, 8300, - 7470, 7435, 7569, 6012, 6172, 5897, 35001, 34984, 35068, 33627, 33606, 33555, 42360, - 42305, 42189, 41184, 41165, 41224, 42567, 42360, 42423, 5935, 5966, 5993, 5714, 5551, - 5620, 40857, 40731, 40389, 39490, 39417, 39463, 40692, 40922, 40691, 40929, 40695, 40994, - 6500, 6695, 6662, 35656, 35563, 35525, 35660, 35563, 35656, 41441, 41507, 41379, 41441, - 41379, 41327, 43402, 43113, 43261, 43177, 43325, 43129, 43390, 43325, 43177, 2728, 2645, - 2821, 40502, 40434, 40525, 3105, 2959, 3058, 2728, 2641, 2645, 3092, 3118, 3090, - 3118, 3354, 3209, 35660, 35499, 35563, 38180, 37761, 37226, 9167, 9220, 9333, 9012, - 8930, 8999, 8732, 8608, 8632, 9167, 9333, 9465, 32774, 32861, 32696, 33206, 32948, - 33120, 34343, 34183, 34312, 42575, 42474, 42775, 42695, 42782, 42838, 43390, 43285, 43325, - 7282, 7439, 7435, 6012, 5935, 5993, 8342, 8375, 8261, 8533, 8375, 8512, 7682, - 7633, 7716, 40922, 40774, 40781, 1392, 1370, 1401, 2179, 2223, 2136, 2199, 2288, - 2248, 2089, 2248, 2130, 36290, 36579, 36222, 37159, 37166, 37297, 40590, 40502, 40525, - 40996, 40857, 40313, 40997, 40857, 40996, 7593, 7633, 7682, 7593, 7569, 7633, 1401, - 1370, 1426, 2065, 2154, 2082, 7682, 7716, 7761, 3092, 2959, 3105, 2374, 2223, - 2407, 35563, 35499, 35497, 34363, 34343, 34312, 36455, 36780, 36997, 42730, 42498, 42382, - 3672, 3732, 3279, 4636, 4756, 4654, 4654, 4756, 4843, 39109, 39130, 38969, 39008, - 39135, 39109, 38797, 38918, 38725, 38618, 38373, 38446, 38373, 38414, 38446, 38414, 38354, - 38446, 38918, 38990, 39008, 34430, 34343, 34363, 33627, 33555, 33808, 41666, 41591, 42260, - 38199, 38203, 38254, 38203, 38222, 38254, 38408, 38274, 38383, 38383, 38274, 38235, 38180, - 38266, 37761, 38961, 39067, 38815, 39119, 39090, 39174, 39119, 39174, 39231, 39417, 39333, - 39463, 5585, 5714, 5712, 5585, 5551, 5714, 36579, 36908, 36705, 40590, 40525, 40726, - 40317, 40166, 39889, 40525, 40731, 40726, 2959, 2885, 3016, 6012, 5993, 6050, 6012, - 6050, 6172, 5994, 5968, 6060, 6386, 6500, 6483, 5232, 5950, 5639, 36997, 36780, - 37196, 38203, 38097, 38222, 39135, 39130, 39109, 40929, 40922, 40692, 40929, 40692, 40695, - 6386, 6483, 6360, 6798, 7006, 6933, 41326, 41441, 41327, 42575, 42527, 42474, 41455, - 41441, 41326, 64, 45, 147, 32155, 32071, 31965, 32499, 32415, 32275, 32621, 32415, - 32499, 32623, 32774, 32696, 38464, 38383, 38595, 37087, 36997, 37335, 38222, 38097, 37962, - 43481, 43447, 43285, 43390, 43177, 43290, 32265, 32071, 32155, 32048, 31880, 31965, 42305, - 42316, 42156, 42657, 42567, 42423, 42518, 42567, 42644, 42474, 42527, 42511, 41657, 41383, - 41507, 33206, 33120, 33265, 43275, 43246, 42409, 43425, 43261, 43501, 2885, 2792, 2881, - 5551, 5151, 5499, 32071, 31880, 32048, 31708, 31689, 31250, 40376, 40166, 40317, 43604, - 43344, 43289, 39451, 39393, 39866, 34995, 35111, 34844, 34761, 34577, 34678, 5551, 5416, - 5151, 5712, 5714, 5752, 34003, 34061, 34169, 34678, 34577, 34474, 33299, 33593, 33308, - 33299, 33308, 33190, 40468, 40376, 40317, 40726, 40731, 40877, 33885, 33750, 33813, 9133, - 9065, 9012, 9465, 9333, 9613, 43396, 43246, 43275, 9726, 9696, 9799, 10379, 10008, - 9981, 31880, 31689, 31708, 35851, 35208, 35246, 37347, 37286, 37295, 39624, 39490, 39866, - 2047, 2089, 2130, 2683, 2700, 2664, 2769, 2748, 2803, 2047, 2099, 1923, 1728, - 1645, 1851, 5757, 5712, 5752, 6172, 6415, 6135, 5929, 5968, 5994, 6075, 5968, - 5816, 41184, 41124, 41165, 41190, 40997, 40996, 7282, 7039, 7256, 7593, 7470, 7569, - 7890, 8300, 8193, 7890, 8193, 8020, 34343, 34199, 34183, 34657, 34484, 34615, 42494, - 42316, 42305, 9167, 9065, 9133, 2792, 2753, 2881, 2683, 2664, 2498, 37221, 37075, - 37720, 39641, 39301, 39274, 43486, 42730, 42382, 42567, 42518, 42360, 5757, 5752, 5935, - 5585, 5416, 5551, 9065, 8930, 9012, 32643, 33114, 32293, 40877, 40731, 40857, 40468, - 40317, 40502, 8173, 8342, 8261, 34430, 34199, 34343, 4768, 4835, 5639, 4516, 4654, - 4603, 37286, 37075, 36975, 2748, 2738, 2803, 2311, 2415, 2288, 39624, 39417, 39490, - 40468, 40502, 40645, 2123, 2082, 2147, 2179, 2147, 2223, 2199, 2311, 2288, 1728, - 1549, 1645, 4756, 4835, 4768, 33593, 33636, 33813, 33114, 33299, 33190, 35068, 34984, - 35248, 34484, 34430, 34363, 34918, 35001, 34978, 1207, 1152, 1294, 1158, 1039, 1142, - 1287, 1392, 1306, 7531, 7470, 7593, 7531, 7593, 7682, 34918, 34657, 34600, 7890, - 7761, 7716, 8608, 8375, 8533, 33606, 33480, 33408, 34169, 34061, 34112, 34169, 34112, - 34199, 2199, 2248, 2089, 5835, 5757, 5935, 5712, 5416, 5585, 5835, 5935, 5897, - 40645, 40502, 40590, 40906, 40877, 40857, 40906, 40857, 40997, 2681, 2641, 2753, 2374, - 2640, 2502, 2885, 2787, 2792, 2959, 2929, 2885, 3118, 3092, 3105, 3456, 3942, - 3441, 39445, 39417, 39624, 40645, 40590, 40719, 41441, 41657, 41507, 41478, 41657, 41441, - 7628, 7761, 7710, 8674, 8608, 8732, 33543, 33480, 33606, 34534, 34430, 34484, 9611, - 9660, 10006, 9294, 9494, 8970, 8653, 8970, 8642, 7522, 7149, 7491, 31693, 32175, - 31775, 33582, 33593, 33299, 43545, 43604, 43447, 43447, 43604, 43289, 42789, 42689, 42730, - 43402, 43396, 43275, 43702, 43261, 43383, 32613, 32621, 32499, 32384, 32265, 32241, 32071, - 32177, 31880, 31880, 32177, 31689, 32965, 32696, 32861, 43425, 43396, 43402, 43229, 42890, - 42990, 2183, 2199, 2029, 1728, 1573, 1549, 41562, 41528, 41788, 1759, 1645, 1451, - 37286, 36908, 37295, 37962, 37957, 38108, 35516, 35851, 35246, 35516, 35246, 35111, 41043, - 40899, 41407, 41434, 41455, 41326, 1207, 1287, 1190, 2640, 2645, 2502, 2199, 2089, - 1996, 2607, 2748, 2683, 5757, 5729, 5712, 5897, 5935, 6012, 34200, 34169, 34199, - 33880, 33627, 33808, 40719, 40590, 40726, 40999, 40906, 40997, 42845, 42782, 42500, 42428, - 42474, 41933, 33338, 33206, 33265, 33880, 33808, 34003, 33582, 33636, 33593, 34761, 34963, - 34995, 33749, 33636, 33738, 42661, 42500, 42527, 43792, 43702, 43379, 43855, 43834, 43792, - 2912, 2929, 2959, 39641, 39759, 39651, 38990, 39135, 39008, 38918, 38949, 38990, 38753, - 38797, 38725, 38753, 38725, 38618, 38753, 38618, 38632, 38618, 38558, 38632, 38446, 38558, - 38618, 38414, 38254, 38354, 38354, 38254, 38222, 39090, 39075, 38961, 39119, 39075, 39090, - 39174, 39333, 39231, 39333, 39445, 39231, 1287, 1294, 1370, 1287, 1370, 1392, 7377, - 7331, 7435, 7377, 7435, 7470, 35001, 34918, 34600, 34657, 34534, 34484, 34430, 34200, - 34199, 34984, 35291, 35248, 43233, 43229, 42990, 1401, 1568, 1306, 39333, 39417, 39445, - 1061, 1039, 1158, 8020, 8193, 8173, 7628, 7682, 7761, 7628, 7531, 7682, 38274, - 38266, 38180, 38692, 38464, 38595, 40000, 40166, 40140, 35248, 35291, 35371, 37637, 37323, - 37761, 40719, 40726, 40871, 40295, 40166, 40376, 38464, 38408, 38383, 38222, 37962, 38108, - 37957, 37961, 38108, 33338, 33265, 33480, 8203, 8261, 8144, 33543, 33338, 33480, 33996, - 33880, 34003, 33996, 34003, 34169, 33749, 33885, 33813, 33749, 33813, 33636, 2179, 2123, - 2147, 2136, 2123, 2179, 40871, 40726, 40877, 41190, 40999, 40997, 40295, 40376, 40396, - 41032, 40906, 40999, 41788, 41528, 41594, 41606, 42156, 42260, 4756, 4636, 4835, 4835, - 5232, 5639, 3892, 4603, 4653, 3892, 4678, 3854, 37957, 37949, 37961, 2607, 2738, - 2748, 2498, 2664, 2311, 40401, 40376, 40468, 8144, 8261, 8375, 8930, 8674, 8732, - 8880, 8674, 8930, 8880, 8930, 9065, 8880, 9065, 8953, 33543, 33606, 33627, 2641, - 2728, 2753, 40506, 40401, 40468, 40871, 40877, 40880, 4516, 4598, 4654, 37961, 37949, - 37968, 8203, 8020, 8173, 7861, 8020, 7957, 42575, 42661, 42527, 43248, 43290, 43229, - 42596, 42661, 42575, 42132, 41801, 41657, 34855, 34534, 34657, 36018, 36175, 36471, 32621, - 32613, 32696, 32384, 32241, 32415, 32621, 32696, 32760, 9726, 9799, 9846, 43481, 43285, - 43390, 43481, 43545, 43447, 43481, 43390, 43578, 1152, 1061, 1158, 980, 1061, 966, - 1207, 1294, 1287, 7508, 7377, 7470, 6582, 6752, 6822, 7508, 7470, 7531, 2681, - 2753, 2792, 3092, 2912, 2959, 3089, 3209, 3029, 4598, 4636, 4654, 6500, 6412, - 6695, 6213, 6360, 6265, 6075, 6060, 5968, 10008, 9726, 9846, 36539, 36018, 36471, - 37286, 36975, 36908, 39651, 39759, 39727, 39641, 39274, 39515, 43834, 43702, 43792, 43425, - 43501, 43396, 2787, 2885, 2929, 4793, 5232, 4835, 32965, 32948, 33166, 42260, 42156, - 42430, 43290, 43177, 43229, 33166, 32948, 33206, 33711, 33543, 33627, 33711, 33627, 33880, - 844, 919, 1039, 1039, 919, 1049, 7710, 7761, 7890, 34855, 34657, 34918, 35729, - 35660, 35656, 40880, 40877, 40906, 40506, 40468, 40645, 40880, 40906, 41032, 40999, 41115, - 41032, 33166, 33206, 33376, 42990, 42838, 43134, 2641, 2564, 2645, 2521, 2564, 2641, - 37311, 37331, 37297, 39185, 39231, 39230, 40716, 40645, 40719, 3209, 3090, 3118, 4636, - 4793, 4835, 7522, 7144, 7149, 34599, 34468, 34392, 33268, 33299, 33114, 34571, 34200, - 34430, 42689, 42567, 42657, 42689, 42657, 42730, 42382, 43246, 43486, 8203, 8173, 8261, - 8953, 9065, 9167, 43134, 42838, 42782, 5816, 5968, 5929, 6302, 6386, 6360, 6326, - 6386, 6302, 41455, 41478, 41441, 41066, 40899, 40922, 37667, 37720, 37075, 2199, 2183, - 2311, 1996, 2089, 2047, 1996, 2047, 1956, 40853, 40716, 40719, 40996, 41184, 41190, - 40003, 40695, 39727, 42320, 42132, 41657, 2564, 2502, 2645, 2168, 2136, 2223, 1401, - 1846, 1568, 2521, 2502, 2564, 3279, 3732, 3419, 2183, 2498, 2311, 35371, 35291, - 35499, 35068, 34978, 35001, 34571, 34205, 34200, 33207, 33268, 33114, 42845, 42500, 42661, - 43161, 43134, 42782, 7006, 7144, 6933, 33984, 33750, 33885, 35851, 36119, 36002, 33543, - 33736, 33338, 34205, 33996, 34169, 34205, 34169, 34200, 33749, 33984, 33885, 33738, 33984, - 33749, 43377, 43246, 43396, 2909, 2912, 3092, 35636, 35546, 35660, 35660, 35546, 35499, - 35680, 35516, 35777, 38063, 37637, 37761, 35628, 35729, 35972, 36018, 35729, 35656, 37494, - 37667, 37075, 7861, 7710, 7890, 7628, 7546, 7531, 7017, 7039, 6668, 7861, 7890, - 8020, 42545, 42494, 42518, 42518, 42494, 42360, 38797, 38949, 38918, 38753, 38802, 38797, - 38759, 38802, 38753, 38759, 38753, 38632, 38759, 38632, 38676, 38446, 38354, 38558, 38354, - 38676, 38558, 38222, 38214, 38354, 38108, 38214, 38222, 38929, 38949, 38797, 38108, 38116, - 38214, 39185, 39075, 39119, 39185, 39067, 39075, 39075, 39067, 38961, 38464, 38666, 38408, - 38408, 38266, 38274, 39185, 39119, 39231, 39185, 39230, 39192, 38949, 39101, 38990, 2723, - 3177, 2738, 4501, 4564, 4598, 4598, 4564, 4636, 4636, 4564, 4793, 39621, 40000, - 39866, 39101, 39135, 38990, 41066, 41008, 40994, 40853, 40719, 40871, 41224, 41165, 41380, - 41618, 41562, 41788, 40929, 41008, 40922, 41008, 40929, 40994, 2912, 2787, 2929, 9107, - 8953, 9167, 9669, 9541, 9613, 32265, 32177, 32071, 32621, 32384, 32415, 32177, 32384, - 32609, 32870, 32696, 32965, 9726, 9669, 9696, 9649, 9669, 9726, 35516, 35845, 35851, - 38108, 37961, 38116, 41434, 41478, 41455, 41605, 41478, 41434, 36, 372, 549, 43702, - 43501, 43261, 42518, 42644, 42745, 42689, 42644, 42567, 42775, 42596, 42575, 43785, 43912, - 43674, 43674, 43912, 43612, 43785, 43674, 43604, 43656, 43604, 43545, 43656, 43545, 43616, - 43545, 43481, 43578, 43390, 43422, 43578, 33918, 33711, 33880, 33736, 33711, 33918, 43444, - 43377, 43396, 1846, 2065, 1568, 1061, 980, 1039, 541, 386, 1049, 6798, 6933, - 6695, 35248, 35192, 35068, 35395, 35192, 35248, 2607, 2723, 2738, 2607, 2683, 2590, - 40853, 40871, 40880, 39866, 40000, 40140, 8880, 8515, 8674, 9107, 9167, 9465, 7605, - 7546, 7628, 7508, 7546, 7605, 34678, 34832, 34761, 35516, 35680, 35845, 34392, 34468, - 34047, 1939, 2454, 2498, 1645, 1759, 1851, 1549, 1573, 1422, 6386, 6412, 6500, - 6075, 6213, 6265, 6183, 6213, 6075, 6326, 6183, 6287, 1956, 2047, 1923, 5835, - 5729, 5757, 3441, 3942, 4046, 7256, 7039, 7017, 37968, 37949, 37933, 40396, 40376, - 40401, 39404, 39274, 39130, 2723, 2607, 2650, 2723, 2708, 3177, 33268, 33351, 33299, - 34748, 34678, 34599, 32997, 33207, 33114, 1451, 1549, 1174, 7282, 7331, 7127, 35546, - 35371, 35499, 35636, 35729, 35628, 42430, 42316, 42494, 41607, 41618, 42200, 41046, 40853, - 40880, 8375, 8608, 8400, 40506, 40396, 40401, 41046, 40880, 41032, 37494, 37075, 37286, - 37933, 37720, 37855, 37933, 37949, 37720, 33422, 33351, 33268, 37295, 36908, 37159, 40506, - 40645, 40713, 41224, 41190, 41184, 6213, 6326, 6302, 6412, 6326, 6287, 7006, 7149, - 7144, 8133, 8653, 8325, 6798, 7149, 7006, 2912, 2812, 2787, 2681, 2521, 2641, - 3090, 3010, 3092, 3209, 3089, 3090, 3441, 4046, 3425, 37855, 37720, 37716, 40140, - 40166, 40312, 1050, 1061, 1152, 34978, 35068, 35129, 34978, 34855, 34918, 34748, 34832, - 34678, 34748, 34599, 34583, 42596, 42740, 42661, 43390, 43290, 43399, 42775, 42740, 42596, - 42845, 42810, 42874, 1207, 1050, 1152, 1568, 2065, 1513, 2304, 2374, 2502, 35565, - 35371, 35546, 43290, 43248, 43399, 43656, 43701, 43604, 33351, 33582, 33299, 3089, 3010, - 3090, 37716, 37720, 37667, 43229, 43233, 43248, 2733, 2792, 2787, 5936, 5729, 5897, - 7250, 7331, 7377, 7508, 7531, 7546, 35729, 35636, 35660, 35565, 35636, 35628, 35376, - 35516, 35111, 37159, 36908, 37166, 37166, 36908, 37042, 37711, 37716, 37667, 40312, 40166, - 40295, 40713, 40645, 40716, 40713, 40716, 40849, 43501, 43444, 43396, 42789, 42745, 42689, - 43471, 43444, 43562, 43715, 43501, 43896, 3010, 2909, 3092, 37494, 37286, 37347, 41380, - 41165, 41607, 41115, 41046, 41032, 43248, 43233, 43194, 34571, 34430, 34534, 33376, 33206, - 33338, 33657, 33738, 33636, 42845, 42914, 42782, 2054, 2065, 2123, 6326, 6412, 6386, - 5816, 5929, 5396, 2168, 2223, 2374, 5897, 5729, 5835, 6135, 6415, 6582, 37473, - 37494, 37347, 36964, 37042, 36579, 41115, 40999, 41151, 33736, 33543, 33711, 43194, 43233, - 43134, 980, 844, 1039, 1151, 1050, 1207, 1190, 1287, 1306, 35175, 35192, 35275, - 35175, 35068, 35192, 34855, 34662, 34534, 34900, 34761, 34832, 34900, 34963, 34761, 39042, - 38890, 39067, 39067, 38890, 38768, 39192, 39067, 39185, 39192, 39230, 39152, 39135, 39364, - 39130, 39326, 39364, 39135, 38949, 39137, 39101, 38802, 38929, 38797, 38818, 38929, 38802, - 38818, 38802, 38759, 38818, 38759, 38676, 38632, 38558, 38676, 38354, 38214, 38676, 38364, - 39072, 38676, 37968, 38116, 37961, 1151, 1190, 1306, 38890, 38789, 38684, 37968, 37974, - 38116, 39067, 39192, 39152, 7605, 7628, 7710, 7769, 7710, 7861, 34757, 34748, 34940, - 38789, 38692, 38595, 37968, 37933, 37974, 35636, 35565, 35546, 36947, 36455, 36997, 36997, - 37196, 37335, 43161, 43194, 43134, 39137, 39135, 39101, 40003, 39727, 39759, 8515, 8608, - 8674, 42914, 42996, 42782, 42740, 42845, 42661, 42775, 42474, 42428, 37335, 37196, 37637, - 40849, 40716, 40853, 40497, 40295, 40396, 39382, 39583, 39492, 2812, 2733, 2787, 2055, - 2054, 2136, 2650, 2708, 2723, 2590, 2683, 2498, 4485, 5087, 4594, 3089, 2977, - 3010, 3010, 2812, 2909, 2909, 2812, 2912, 39364, 39404, 39130, 7834, 7769, 7861, - 42745, 42545, 42518, 41357, 41190, 41224, 42745, 42644, 42689, 2136, 2054, 2123, 2304, - 2502, 2137, 1996, 2029, 2199, 1956, 2029, 1996, 1956, 1923, 1722, 5345, 5950, - 5232, 40919, 40849, 40853, 41151, 40999, 41190, 41151, 41190, 41357, 41008, 41066, 40922, - 41478, 41605, 41657, 39732, 39759, 39641, 39404, 39515, 39274, 41733, 41605, 41434, 34757, - 34832, 34748, 33582, 33657, 33636, 33351, 33504, 33582, 33422, 33504, 33351, 33422, 33268, - 33207, 4501, 4598, 4516, 4793, 4579, 5232, 2708, 3279, 3419, 38508, 38266, 38408, - 2733, 2681, 2792, 2553, 2681, 2733, 37974, 37933, 37855, 37473, 37347, 37295, 43701, - 43785, 43604, 43656, 43661, 43701, 43686, 43661, 43656, 43616, 43545, 43578, 43616, 43578, - 43659, 43390, 43399, 43422, 43422, 43489, 43510, 2168, 2304, 2094, 10008, 9649, 9726, - 9669, 9649, 9541, 9282, 9107, 9465, 8953, 8994, 8880, 32384, 32177, 32265, 32662, - 32384, 32621, 37087, 36947, 36997, 36788, 36947, 36846, 40919, 40853, 41046, 40497, 40396, - 40506, 43758, 43785, 43701, 4594, 5087, 5151, 8203, 7957, 8020, 7935, 7957, 7983, - 39515, 39732, 39641, 42789, 42730, 43731, 45, 15, 738, 35395, 35248, 35371, 34978, - 34774, 34855, 35490, 35371, 35565, 1050, 966, 1061, 1000, 966, 1050, 1000, 1050, - 1151, 1207, 1190, 1151, 34757, 34900, 34832, 34963, 35088, 35111, 34047, 34250, 34392, - 33918, 33880, 33996, 32957, 32870, 32965, 33918, 33996, 34247, 33573, 33657, 33582, 2573, - 2590, 2454, 1938, 1956, 1722, 1923, 1759, 1722, 9392, 9465, 9541, 32957, 32965, - 33166, 35628, 35490, 35565, 40844, 40713, 40849, 41187, 41562, 41607, 43296, 43248, 43194, - 43422, 43399, 43489, 3441, 3180, 3209, 3892, 3854, 3663, 37974, 37855, 37861, 2607, - 2590, 2573, 2708, 2565, 3279, 9107, 8994, 8953, 3180, 3029, 3209, 37861, 37855, - 37716, 2136, 2168, 1982, 2304, 2168, 2374, 2054, 1893, 2065, 2168, 2024, 1982, - 7957, 7834, 7861, 7769, 7605, 7710, 7352, 7250, 7377, 7935, 7834, 7957, 37367, - 37335, 37727, 39904, 40003, 39759, 6391, 6798, 6695, 6183, 6326, 6213, 6183, 6075, - 5868, 8325, 8653, 8642, 7614, 7933, 7491, 7442, 7491, 7149, 33736, 33376, 33338, - 33725, 33376, 33736, 33504, 33573, 33582, 35210, 35088, 34900, 33278, 33422, 33207, 35175, - 35129, 35068, 35275, 35129, 35175, 34900, 35088, 34963, 36290, 36002, 36672, 37159, 37297, - 37295, 33984, 34250, 34047, 42430, 42156, 42316, 42430, 42494, 42545, 37711, 37861, 37716, - 37711, 37667, 37655, 35490, 35395, 35371, 35767, 35395, 35490, 35729, 36018, 36028, 41066, - 41407, 40899, 40308, 40994, 40695, 7101, 7442, 7149, 33984, 34238, 34250, 37295, 37297, - 37331, 42745, 42841, 42545, 43486, 43246, 43377, 36681, 36471, 36947, 2977, 2812, 3010, - 37655, 37667, 37494, 40711, 40713, 40844, 40711, 40506, 40713, 541, 1049, 919, 8443, - 8515, 8880, 43661, 43758, 43701, 43616, 43686, 43656, 43714, 43686, 43616, 43659, 43578, - 43422, 43686, 43758, 43661, 43785, 43900, 43912, 8949, 9294, 8970, 32175, 32643, 32293, - 41357, 41380, 41857, 41107, 41046, 41115, 3663, 3854, 3672, 3663, 3672, 3484, 38789, - 38821, 38692, 38692, 38666, 38464, 38266, 38063, 37761, 38913, 38821, 38789, 39152, 39042, - 39067, 39231, 39457, 39230, 43834, 43849, 43702, 43444, 43471, 43377, 3484, 3672, 3279, - 38913, 38789, 38890, 39231, 39445, 39457, 39364, 39546, 39404, 39404, 39546, 39515, 39515, - 39752, 39732, 39732, 39904, 39759, 39167, 39137, 38949, 38960, 38949, 38929, 38960, 38929, - 38818, 38960, 38818, 39072, 38119, 38214, 38116, 38119, 38116, 37974, 38119, 37974, 38128, - 41107, 41115, 41197, 32870, 32760, 32696, 32957, 32760, 32870, 4101, 4043, 4456, 2904, - 2977, 3180, 3180, 2977, 3029, 3029, 2977, 3089, 38821, 38736, 38692, 39209, 39230, - 39382, 1982, 2055, 2136, 1893, 2055, 1889, 36788, 36681, 36947, 41197, 41115, 41151, - 38128, 37974, 37861, 37622, 37655, 37494, 4286, 4101, 4485, 4485, 4101, 4456, 38736, - 38666, 38692, 7352, 7377, 7508, 6023, 6135, 6133, 7983, 7957, 8203, 42428, 41933, - 42132, 42874, 42996, 42914, 42810, 43059, 43041, 9107, 9063, 8994, 8307, 8400, 8515, - 8980, 9063, 9107, 43628, 43444, 43501, 42874, 42914, 42845, 950, 844, 980, 1151, - 1306, 1068, 1068, 1306, 1076, 7763, 7769, 7834, 35411, 35275, 35395, 35395, 35275, - 35192, 34774, 34662, 34855, 35767, 35490, 35628, 38666, 38508, 38408, 36657, 36539, 36681, - 2573, 2650, 2607, 1850, 2183, 2029, 37871, 37861, 37711, 37476, 37622, 37494, 40919, - 40844, 40849, 40707, 40497, 40506, 950, 980, 966, 34774, 34978, 34916, 38508, 38410, - 38266, 6104, 6135, 6023, 5498, 5416, 5712, 6391, 6695, 6412, 5868, 6075, 5816, - 41320, 41407, 41066, 2055, 1893, 2054, 1834, 1893, 1889, 1956, 1938, 2029, 1451, - 1645, 1549, 36681, 36539, 36471, 36788, 36846, 36735, 41097, 40919, 41046, 41237, 41197, - 41151, 41357, 41224, 41380, 32997, 33278, 33207, 33422, 33448, 33504, 43161, 43296, 43194, - 7808, 7763, 7834, 8299, 8144, 8375, 8400, 8608, 8515, 32957, 32662, 32760, 34247, - 33996, 34205, 43171, 43161, 42782, 42810, 42845, 42740, 2577, 2573, 2454, 3301, 3484, - 2954, 7808, 7834, 7935, 35193, 35210, 34900, 33682, 33738, 33657, 4564, 4602, 4793, - 4379, 4501, 4516, 41097, 41046, 41107, 40707, 40506, 40711, 33358, 33448, 33422, 43171, - 42782, 42996, 4501, 4602, 4564, 37871, 37711, 37877, 37877, 37711, 37655, 37331, 37473, - 37295, 35777, 35845, 35680, 39209, 39152, 39230, 40707, 40711, 40840, 6010, 5936, 6172, - 6010, 6172, 6135, 8067, 7983, 8203, 8067, 8203, 8144, 42789, 42841, 42745, 41607, - 41562, 41618, 43840, 42841, 42789, 42775, 42810, 42740, 43097, 43171, 42996, 42320, 41657, - 41905, 1000, 950, 966, 844, 804, 919, 937, 950, 1000, 937, 1000, 891, - 7250, 7127, 7331, 7605, 7352, 7508, 7605, 7769, 7611, 6237, 6412, 6287, 7614, - 8316, 7933, 8299, 8400, 8307, 9649, 9392, 9541, 2502, 2521, 2137, 3232, 3180, - 3441, 4602, 4629, 4793, 32760, 32662, 32621, 32957, 33166, 33180, 43471, 43486, 43377, - 43715, 43628, 43501, 43399, 43248, 43489, 43510, 43659, 43422, 43686, 43900, 43758, 8515, - 8443, 8307, 816, 804, 844, 7611, 7769, 7763, 34662, 34571, 34534, 34771, 34571, - 34662, 43489, 43248, 43375, 35376, 35777, 35516, 35242, 35111, 35088, 36908, 36579, 37042, - 37877, 37655, 37641, 43375, 43296, 43407, 43375, 43248, 43296, 5498, 5712, 5729, 6104, - 6010, 6135, 7795, 7808, 7935, 7795, 7935, 7983, 41618, 41788, 42200, 40830, 40840, - 40991, 40840, 40711, 40844, 37476, 37494, 37473, 43407, 43296, 43245, 42200, 41788, 42260, - 36947, 37367, 36846, 36122, 36028, 36018, 34771, 34774, 34916, 40994, 41069, 41066, 41755, - 41657, 41605, 41241, 41069, 40994, 41241, 40994, 41665, 4575, 5345, 5232, 6183, 6237, - 6287, 39445, 39624, 39457, 40840, 40844, 40919, 7128, 7127, 7250, 7039, 7127, 7128, - 7128, 7352, 7141, 41488, 41434, 41407, 39137, 39326, 39135, 39125, 39072, 39265, 38364, - 38214, 38119, 39220, 39042, 39152, 39220, 39032, 39042, 39042, 39032, 38890, 38821, 38913, - 38736, 38736, 38762, 38666, 38666, 38536, 38508, 38508, 38448, 38410, 38325, 38063, 38266, - 39583, 39457, 39785, 33278, 33358, 33422, 33448, 33573, 33504, 33438, 33358, 33278, 33845, - 33751, 33918, 33918, 33751, 33736, 34978, 35129, 34916, 39032, 38913, 38890, 38960, 39167, - 38949, 39866, 40142, 39624, 3663, 3617, 3892, 4379, 4468, 4501, 4501, 4468, 4602, - 4602, 4556, 4629, 2565, 2708, 2650, 7808, 7611, 7763, 8165, 8067, 8144, 8299, - 8375, 8400, 38913, 38762, 38736, 39167, 39326, 39137, 40312, 40295, 40497, 5498, 5729, - 5809, 6135, 6582, 6133, 5809, 5936, 6010, 7795, 7611, 7808, 37471, 37476, 37473, - 36579, 36840, 36964, 41182, 41107, 41197, 40342, 40312, 41186, 40830, 40497, 40707, 38762, - 38536, 38666, 33492, 33573, 33448, 34940, 34900, 34757, 36788, 36657, 36681, 36735, 36657, - 36788, 41237, 41151, 41305, 41237, 41182, 41197, 41069, 41154, 41066, 41320, 41347, 41459, - 43097, 42996, 43023, 42996, 42874, 43023, 1339, 1451, 1174, 2454, 2590, 2498, 38536, - 38448, 38508, 43659, 43510, 43657, 43714, 43659, 43810, 43714, 43616, 43659, 43819, 43900, - 43686, 43758, 43900, 43785, 43510, 43489, 43657, 43628, 43562, 43444, 43896, 43501, 43702, - 43577, 43489, 43375, 2573, 2577, 2650, 2498, 2183, 1939, 34238, 33984, 33738, 37471, - 37473, 37331, 36119, 35851, 35845, 8273, 8299, 8307, 8067, 7981, 7983, 33725, 33751, - 33848, 43245, 43296, 43161, 43023, 42874, 43041, 386, 36, 549, 69, 36, 386, - 33180, 33166, 33376, 43663, 43562, 43628, 804, 541, 919, 950, 816, 844, 1041, - 1000, 1151, 41505, 41488, 41407, 1893, 1834, 2065, 2521, 2193, 2137, 5452, 5868, - 5816, 41097, 40840, 40919, 41305, 41151, 41357, 43562, 43486, 43471, 4629, 4579, 4793, - 6195, 6132, 6188, 4379, 4516, 3892, 38022, 38128, 37861, 37311, 37297, 37166, 8299, - 8165, 8144, 7101, 7149, 6798, 7614, 7491, 7442, 8653, 8949, 8970, 38325, 38266, - 38410, 38022, 37861, 37871, 43245, 43161, 43171, 43041, 42874, 42810, 43245, 43171, 43328, - 1850, 2029, 1938, 2577, 2528, 2650, 41097, 41107, 41182, 40840, 40830, 40707, 41424, - 41305, 41357, 41369, 41305, 41424, 33573, 33682, 33657, 33358, 33492, 33448, 33438, 33492, - 33358, 43178, 43171, 43097, 6132, 6237, 6183, 35777, 36119, 35845, 36512, 36119, 36434, - 7127, 7039, 7282, 7128, 7250, 7352, 7352, 7605, 7141, 34940, 34748, 34859, 34599, - 34392, 34583, 34583, 34392, 34588, 42907, 43174, 43083, 42469, 42733, 42638, 42320, 42428, - 42132, 42593, 42428, 42320, 8065, 7981, 8067, 2521, 2273, 2193, 1076, 1306, 1054, - 33751, 33725, 33736, 33845, 33918, 33979, 33492, 33682, 33573, 43225, 43178, 43097, 43144, - 43097, 43023, 34401, 34392, 34250, 9392, 9282, 9465, 8299, 8273, 8165, 8165, 8065, - 8067, 9312, 9282, 9392, 37641, 37655, 37622, 37641, 37622, 37634, 37311, 37166, 37188, - 39326, 39387, 39364, 39167, 39396, 39326, 38960, 39165, 39167, 39125, 39165, 38960, 38960, - 39072, 39125, 37188, 37166, 37042, 39354, 39220, 39209, 39209, 39220, 39152, 39032, 39023, - 38913, 38786, 38536, 38762, 38622, 38621, 38536, 38536, 38621, 38448, 38514, 38325, 38410, - 39238, 39220, 39354, 41257, 41182, 41237, 39354, 39209, 39382, 36122, 36018, 36213, 34247, - 34205, 34619, 36608, 36539, 36657, 41488, 41733, 41434, 41634, 41733, 41488, 41755, 41733, - 41799, 1982, 1889, 2055, 2024, 1889, 1982, 36947, 37087, 37367, 7820, 7795, 7981, - 7981, 7795, 7983, 8880, 8994, 8443, 34771, 34662, 34774, 39396, 39387, 39326, 39387, - 39546, 39364, 6379, 6582, 6668, 7038, 7128, 7141, 6803, 7101, 6798, 1786, 2065, - 1834, 798, 816, 950, 42469, 42200, 42260, 3425, 3310, 3441, 2647, 2733, 2812, - 3425, 4046, 4043, 3781, 4043, 4101, 38786, 38762, 38913, 36771, 36608, 36735, 869, - 950, 937, 34916, 35129, 35411, 37877, 38022, 37871, 37634, 37622, 37476, 2647, 2812, - 2846, 3310, 3232, 3441, 39546, 39752, 39515, 6104, 6006, 6010, 6379, 6487, 6378, - 7141, 7605, 6925, 8142, 8065, 8165, 7981, 8065, 7926, 42924, 42810, 42775, 37087, - 37335, 37367, 36735, 36608, 36657, 4468, 4556, 4602, 4402, 4379, 4307, 4451, 4379, - 4402, 41733, 41755, 41605, 43292, 43144, 43041, 41320, 41066, 41154, 38216, 38022, 37877, - 37487, 37634, 37476, 43352, 43328, 43262, 43178, 43328, 43171, 43245, 43439, 43407, 43577, - 43657, 43489, 43714, 43819, 43686, 39752, 39904, 39732, 2137, 2094, 2304, 1797, 1786, - 1834, 2119, 2094, 2137, 5809, 5729, 5936, 4895, 4594, 5151, 8443, 8994, 8420, - 9649, 9312, 9392, 33585, 33376, 33725, 32983, 32662, 32957, 32983, 32609, 32662, 32662, - 32609, 32384, 33845, 33848, 33751, 34619, 34205, 34571, 33682, 34238, 33738, 35193, 34900, - 34940, 35193, 35242, 35210, 35210, 35242, 35088, 36840, 36579, 36290, 37322, 37471, 37331, - 35193, 34940, 35031, 43486, 43537, 42730, 42430, 42469, 42260, 43562, 43557, 43486, 43715, - 43663, 43628, 43795, 43663, 43715, 816, 741, 804, 891, 869, 937, 1041, 1151, - 1068, 1811, 1834, 1889, 6006, 5809, 6010, 6006, 6104, 6023, 41305, 41369, 41237, - 41364, 41369, 41424, 41320, 41154, 41347, 6237, 6391, 6412, 6018, 6132, 6015, 6183, - 6015, 6132, 41585, 41634, 41488, 43577, 43375, 43439, 4895, 5151, 5416, 4451, 4556, - 4468, 2094, 2024, 2168, 2119, 2024, 2094, 36840, 36290, 36672, 41257, 41097, 41182, - 39230, 39457, 39382, 15, 53, 738, 43648, 43557, 43780, 43439, 43375, 43407, 37322, - 37331, 37311, 37851, 37877, 37641, 37640, 37641, 37634, 34247, 33979, 33918, 43352, 43439, - 43245, 43041, 43144, 43023, 42924, 42775, 42428, 34238, 34401, 34250, 43352, 43245, 43328, - 1339, 1722, 1759, 1339, 1759, 1451, 36213, 36018, 36494, 36028, 35972, 35729, 34660, - 34619, 34571, 34066, 33848, 33979, 41755, 41905, 41657, 41634, 41683, 41733, 41585, 41683, - 41634, 37335, 37637, 37727, 36494, 36018, 36539, 36964, 36840, 37027, 37317, 37322, 37311, - 37188, 37042, 37032, 37625, 37640, 37634, 7128, 7038, 7039, 7729, 7611, 7795, 35242, - 35376, 35111, 34859, 34748, 34583, 1054, 1306, 1568, 869, 798, 950, 780, 798, - 869, 35411, 35129, 35275, 2846, 2812, 2977, 39387, 39396, 39546, 39546, 39738, 39752, - 40042, 40111, 39904, 39297, 39396, 39167, 38818, 38676, 39072, 39220, 39238, 39032, 38600, - 38410, 38448, 40140, 40251, 39866, 40140, 40342, 40251, 39023, 38786, 38913, 40140, 40312, - 40342, 39297, 39167, 39165, 41459, 41505, 41320, 34778, 34571, 34771, 34401, 34588, 34392, - 4418, 4286, 4594, 5009, 5416, 5498, 6133, 6006, 6023, 41585, 41505, 41609, 41320, - 41505, 41407, 2024, 1811, 1889, 1786, 1644, 2065, 2273, 2521, 2681, 2647, 2553, - 2733, 43849, 43896, 43702, 43663, 43780, 43562, 1764, 1811, 2024, 38786, 38622, 38536, - 40312, 40497, 41186, 41364, 41257, 41237, 41364, 41237, 41369, 43896, 43795, 43715, 43775, - 43659, 43657, 43775, 43810, 43659, 43775, 43657, 43753, 36122, 36044, 36028, 36125, 36044, - 36122, 7926, 7820, 7981, 8142, 8165, 8273, 41905, 41755, 41799, 43059, 42924, 43052, - 43144, 43225, 43097, 43439, 43523, 43577, 8656, 8653, 8550, 8656, 8949, 8653, 32643, - 32997, 33114, 33492, 33438, 33682, 34449, 34361, 34238, 34238, 34361, 34401, 34401, 34361, - 34588, 33801, 33848, 34066, 33979, 33848, 33845, 43292, 43225, 43144, 2454, 2528, 2577, - 2408, 2528, 2454, 39318, 39297, 39125, 37487, 37476, 37471, 37487, 37471, 37322, 1076, - 1041, 1068, 936, 1041, 1076, 35362, 35376, 35242, 35362, 35242, 35193, 798, 741, - 816, 1041, 891, 1000, 6379, 6668, 6487, 7584, 7605, 7611, 37032, 37042, 36964, - 37032, 36964, 37027, 780, 741, 798, 34066, 33979, 34211, 34916, 34778, 34771, 34883, - 34778, 34916, 34588, 34859, 34583, 34719, 34859, 34588, 41505, 41585, 41488, 40111, 40003, - 39904, 1811, 1797, 1834, 1647, 1797, 1764, 40497, 40830, 40991, 41424, 41357, 41857, - 4379, 4451, 4468, 5161, 5396, 5345, 4556, 4451, 4402, 38600, 38448, 38621, 6274, - 6379, 6283, 6195, 6391, 6237, 7246, 7614, 7442, 6195, 6237, 6132, 36044, 35972, - 36028, 36125, 35972, 36044, 41799, 41733, 41683, 7947, 7614, 7562, 37317, 37487, 37322, - 36672, 36002, 36119, 2647, 2467, 2553, 2254, 2273, 2681, 1647, 1644, 1797, 2899, - 2904, 3180, 2899, 3180, 3232, 2899, 3232, 2807, 40042, 39904, 39752, 38214, 38364, - 38676, 37317, 37311, 37299, 43262, 43328, 43178, 43262, 43178, 43225, 2904, 2846, 2977, - 1797, 1644, 1786, 2119, 2137, 2193, 40840, 41097, 40991, 41412, 41424, 41543, 41373, - 41412, 41371, 41241, 41154, 41069, 41585, 41799, 41683, 36615, 36539, 36608, 36771, 36735, - 36846, 7614, 7947, 8316, 42924, 43059, 42810, 43052, 42924, 42428, 891, 780, 869, - 777, 780, 891, 777, 891, 843, 34859, 35031, 34940, 37299, 37188, 37032, 35054, - 35031, 35217, 1332, 1054, 1568, 41097, 41257, 41371, 8994, 9063, 8980, 6939, 6940, - 7141, 33848, 33801, 33725, 34211, 34247, 34723, 43467, 43262, 43225, 43557, 43537, 43486, - 43795, 43812, 43663, 43896, 43812, 43795, 43810, 43819, 43714, 43753, 43657, 43577, 43523, - 43439, 43352, 2254, 2681, 2371, 34778, 34660, 34571, 34883, 34660, 34778, 35783, 35628, - 35972, 36162, 35783, 35972, 41373, 41257, 41364, 33585, 33180, 33376, 41525, 41511, 41459, - 41459, 41511, 41505, 34449, 34238, 34181, 8235, 8142, 8273, 7176, 7246, 7021, 7992, - 8133, 7947, 5396, 5929, 5345, 39409, 39238, 39354, 39226, 39023, 39238, 39238, 39023, - 39032, 38786, 38799, 38622, 38622, 38600, 38621, 39409, 39354, 39382, 40142, 39866, 40251, - 41770, 41799, 41585, 43093, 43052, 43209, 37727, 37637, 38021, 37637, 38063, 38021, 37299, - 37311, 37188, 37851, 37641, 37640, 37299, 37032, 37027, 39396, 39738, 39546, 39125, 39297, - 39165, 37625, 37634, 37487, 40308, 40695, 40003, 43648, 43537, 43557, 43753, 43523, 43871, - 39297, 39466, 39396, 2528, 2565, 2650, 2411, 2565, 2528, 35031, 35163, 35193, 35054, - 35163, 35031, 35783, 35767, 35628, 36059, 35767, 35783, 36125, 36122, 36213, 38021, 38063, - 38325, 2273, 2119, 2193, 843, 1041, 936, 2254, 2119, 2273, 37657, 37625, 37487, - 35886, 35777, 35376, 41511, 41609, 41505, 41684, 41609, 41511, 37110, 36771, 36846, 36615, - 36771, 36944, 41424, 41373, 41364, 41857, 42264, 42092, 41241, 41347, 41154, 41365, 41347, - 41241, 4594, 4286, 4485, 2904, 2810, 2846, 4895, 5416, 5009, 5498, 5809, 5617, - 6379, 6274, 6582, 6940, 7039, 7038, 6133, 6274, 6283, 8307, 8235, 8273, 8142, - 7926, 8065, 8980, 9107, 9282, 2201, 2408, 2454, 41398, 41365, 41241, 39919, 40042, - 39752, 43753, 43819, 43775, 43775, 43819, 43810, 4579, 4629, 4556, 35767, 35411, 35395, - 33585, 33725, 33801, 35817, 35411, 35767, 35163, 35362, 35193, 35297, 35362, 35163, 2519, - 2467, 2647, 2807, 3232, 3088, 780, 718, 741, 6, 69, 386, 843, 891, - 1041, 1513, 2065, 1644, 8443, 8235, 8307, 35046, 35031, 34859, 1764, 1797, 1811, - 6195, 6167, 6391, 6015, 6183, 5868, 36745, 36672, 36679, 37780, 37625, 37657, 37757, - 37625, 37780, 2899, 2810, 2904, 1700, 1764, 2024, 40335, 40142, 40251, 40335, 40251, - 40423, 42469, 42907, 42733, 43780, 43557, 43562, 37006, 37027, 36840, 2371, 2681, 2553, - 541, 804, 636, 4443, 4579, 4556, 4379, 3892, 3816, 3663, 3484, 3301, 8653, - 8133, 8129, 8550, 8653, 8129, 636, 804, 741, 2201, 2411, 2408, 1174, 1549, - 1422, 6274, 6133, 6582, 6940, 7038, 7141, 6018, 6188, 6132, 6078, 6188, 6018, - 777, 718, 780, 936, 1076, 1054, 7729, 7795, 7820, 43731, 42730, 43537, 7881, - 7926, 8142, 579, 1174, 1422, 39725, 39738, 39396, 39297, 39443, 39466, 38119, 38128, - 38364, 38364, 38128, 38022, 39265, 39318, 39125, 34361, 34719, 34588, 35054, 35297, 35163, - 34700, 34719, 34361, 3421, 3425, 4043, 2899, 2807, 2810, 4286, 3781, 4101, 3738, - 3781, 4286, 39041, 38891, 38786, 39492, 39409, 39382, 39318, 39443, 39297, 39041, 38786, - 39023, 39583, 39382, 39457, 1647, 1513, 1644, 1579, 1513, 1647, 38891, 38799, 38786, - 41089, 40991, 41097, 39238, 39409, 39476, 41371, 41257, 41373, 2677, 2647, 2846, 1678, - 1764, 1700, 2687, 2846, 2810, 37757, 37851, 37640, 37757, 37640, 37625, 2024, 2119, - 1700, 37487, 37317, 37657, 36672, 36863, 36840, 36745, 36863, 36672, 36672, 36119, 36679, - 41347, 41525, 41459, 42061, 42046, 41799, 42083, 42320, 41905, 40308, 40003, 40111, 40308, - 40111, 40042, 1513, 1332, 1568, 36246, 36125, 36213, 36615, 36608, 36771, 39725, 39396, - 39466, 7813, 7729, 7820, 34181, 34238, 33682, 43059, 43292, 43041, 43871, 43523, 43909, - 43523, 43753, 43577, 42046, 41905, 41799, 39738, 39834, 39752, 957, 936, 1054, 724, - 718, 777, 2408, 2411, 2528, 1606, 1938, 1722, 4625, 4895, 5009, 39359, 39237, - 39254, 37332, 37299, 37027, 38767, 38600, 38622, 37110, 36846, 37367, 43648, 43631, 43537, - 43662, 43631, 43648, 38600, 38514, 38410, 7992, 7947, 7562, 5452, 6015, 5868, 5452, - 5816, 5396, 36679, 36119, 36512, 36963, 37006, 36840, 2467, 2371, 2553, 2428, 2371, - 2467, 5161, 5452, 5396, 3617, 3663, 3301, 42061, 41799, 42038, 2488, 2807, 2351, - 1425, 1606, 1722, 1425, 1722, 1339, 37643, 37367, 37727, 36963, 36840, 36863, 36765, - 36679, 36798, 41428, 41525, 41347, 41428, 41347, 41365, 2807, 2687, 2810, 7926, 7813, - 7820, 6925, 6939, 7141, 7881, 7813, 7926, 7881, 8142, 7960, 43052, 43076, 43059, - 43093, 43076, 43052, 724, 843, 823, 724, 777, 843, 151, 6, 386, 1781, - 1850, 1938, 4575, 5232, 4579, 9312, 8980, 9282, 8177, 8142, 8235, 33180, 32983, - 32957, 33453, 32983, 33180, 34723, 34619, 34660, 34883, 34916, 35039, 36963, 36863, 36867, - 43812, 43780, 43663, 43631, 43731, 43537, 43846, 43780, 43812, 43467, 43352, 43262, 600, - 636, 741, 34719, 34788, 34859, 34700, 34788, 34719, 39956, 40308, 40042, 43780, 43662, - 43648, 38514, 38021, 38325, 36125, 36162, 35972, 36494, 36246, 36213, 39340, 39238, 39476, - 39340, 39226, 39238, 38891, 38933, 38799, 38799, 38767, 38622, 38600, 38643, 38514, 38514, - 39100, 38021, 39409, 39492, 39476, 39443, 39725, 39466, 39738, 39919, 39834, 39834, 39919, - 39752, 39318, 39419, 39443, 39265, 39237, 39318, 39072, 39237, 39265, 38364, 38022, 38277, - 1606, 1781, 1938, 2436, 2565, 2411, 2504, 3279, 2565, 37332, 37317, 37299, 37757, - 37780, 37851, 36867, 36863, 36745, 36867, 36745, 36765, 39476, 39492, 39583, 39785, 39624, - 40142, 41412, 41373, 41424, 3088, 3232, 3310, 2626, 2677, 2687, 3781, 3421, 4043, - 3738, 3421, 3781, 39226, 39041, 39023, 39457, 39624, 39785, 39237, 39419, 39318, 39041, - 38980, 38891, 2436, 2504, 2565, 2436, 2411, 2353, 6378, 6283, 6379, 4625, 4594, - 4895, 6844, 6939, 6826, 35217, 35297, 35054, 870, 957, 866, 718, 600, 741, - 1070, 1054, 1332, 1189, 1332, 1308, 1678, 1647, 1764, 38980, 38933, 38891, 39785, - 39830, 39761, 53, 52, 738, 7584, 7611, 7729, 8177, 8235, 8443, 38933, 38767, - 38799, 40423, 40342, 41186, 2677, 2846, 2687, 2519, 2428, 2467, 1700, 1486, 1517, - 2504, 2471, 3279, 1939, 2183, 1850, 41286, 41089, 41097, 36615, 36494, 36539, 36812, - 36494, 36615, 35046, 35217, 35031, 34642, 34700, 34361, 34642, 34361, 34449, 38767, 38643, - 38600, 39956, 39919, 39738, 2250, 2254, 2371, 37332, 37027, 37281, 36765, 36745, 36679, - 41371, 41286, 41097, 41543, 41424, 41857, 41770, 41585, 41609, 41398, 41428, 41365, 41525, - 41428, 41567, 42046, 42083, 41905, 41770, 41609, 41684, 2428, 2369, 2371, 2250, 2369, - 2320, 37027, 37006, 37281, 43759, 43705, 43662, 43662, 43705, 43631, 43896, 43846, 43812, - 4402, 4395, 4556, 3893, 4307, 4379, 43076, 43157, 43059, 42844, 43052, 42428, 1765, - 1939, 1850, 8341, 8177, 8443, 7772, 7729, 7813, 35046, 34859, 34788, 36119, 35777, - 36359, 4307, 4395, 4402, 41583, 41511, 41525, 1678, 1579, 1647, 1545, 1579, 1678, - 35376, 35362, 35538, 37281, 37006, 37265, 43759, 43662, 43898, 41543, 41422, 41412, 710, - 600, 718, 19, 73, 541, 843, 936, 823, 35039, 35411, 35130, 35039, 34916, - 35411, 4625, 4418, 4594, 5809, 6006, 5617, 4395, 4443, 4556, 6668, 7039, 6487, - 6844, 6940, 6939, 42091, 42083, 42061, 42061, 42083, 42046, 8656, 8550, 8949, 7442, - 7101, 7246, 32997, 33438, 33278, 34700, 34803, 34788, 41450, 41286, 41371, 39830, 39785, - 39935, 8036, 7960, 8142, 6078, 6195, 6188, 34644, 34642, 34449, 2626, 2687, 2807, - 1657, 2119, 1738, 4443, 4502, 4579, 41567, 41583, 41525, 41770, 41870, 41799, 41684, - 41850, 41798, 8177, 8036, 8142, 8598, 8420, 8994, 6015, 6078, 6018, 5983, 6078, - 6015, 5983, 6015, 5902, 41891, 41870, 41770, 7772, 7813, 7881, 1781, 1765, 1850, - 2353, 2430, 2436, 1676, 1765, 1781, 1676, 1781, 1606, 1425, 1339, 1267, 43093, - 43157, 43076, 43336, 43157, 43270, 6283, 5783, 6133, 6705, 7039, 6940, 2677, 2519, - 2647, 34644, 34803, 34700, 35538, 35362, 35472, 34788, 34803, 34986, 1267, 1339, 1005, - 37006, 36963, 37265, 35238, 35297, 35217, 38767, 38756, 38643, 38643, 38756, 38514, 37643, - 37110, 37367, 38933, 38957, 38767, 38980, 39013, 38933, 39131, 39013, 38980, 39131, 38980, - 39041, 39343, 39041, 39226, 39343, 39226, 39340, 39343, 39340, 39403, 39483, 39476, 39583, - 41398, 41665, 41542, 41583, 41684, 41511, 39785, 39761, 39583, 39785, 40044, 39935, 39419, - 39725, 39443, 39919, 39956, 40042, 39598, 39725, 39419, 39359, 39419, 39237, 1308, 1332, - 1513, 2250, 2371, 2369, 2436, 2430, 2504, 2201, 2454, 1939, 40251, 40342, 40423, - 41412, 41422, 41371, 41380, 41607, 41857, 41567, 41398, 41619, 1308, 1513, 1253, 42028, - 42038, 41870, 41870, 42038, 41799, 42083, 42593, 42320, 7960, 7934, 7881, 8121, 8036, - 8177, 34211, 33979, 34247, 41221, 41089, 41286, 38957, 38756, 38767, 823, 936, 957, - 35046, 35238, 35217, 42756, 42593, 42926, 6844, 6705, 6940, 6753, 6705, 6844, 35472, - 35362, 35297, 81, 579, 738, 6200, 6798, 6391, 7992, 8129, 8133, 34723, 34247, - 34619, 36162, 36125, 36246, 37281, 37265, 37336, 38277, 38022, 38216, 6378, 6334, 6283, - 6705, 6487, 7039, 35538, 35886, 35376, 33640, 33585, 33801, 7936, 7934, 7960, 43157, - 43292, 43059, 43336, 43292, 43157, 41386, 41221, 41286, 41450, 41543, 41477, 2320, 2369, - 2428, 4502, 4474, 4579, 4443, 4389, 4502, 4395, 4391, 4443, 4307, 4267, 4395, - 3893, 4267, 4307, 4277, 4267, 4189, 8420, 8341, 8443, 7936, 7797, 7934, 8598, - 8341, 8420, 37877, 37851, 38216, 36963, 37148, 37265, 36867, 36765, 36882, 41450, 41371, - 41422, 4267, 4391, 4395, 37657, 37317, 37609, 2213, 1785, 2057, 2430, 2438, 2504, - 1676, 1939, 1765, 7797, 7881, 7934, 7797, 7772, 7881, 37800, 37657, 37833, 817, - 823, 957, 36798, 36679, 36512, 35538, 35671, 35886, 35358, 35472, 35297, 35358, 35297, - 35238, 618, 710, 724, 724, 710, 718, 151, 386, 541, 1410, 1513, 1579, - 1189, 1070, 1332, 1545, 1678, 1700, 1292, 1676, 1606, 1005, 1339, 1174, 6078, - 6026, 6195, 6007, 5983, 5902, 42038, 42091, 42061, 41916, 41891, 41770, 41798, 41770, - 41684, 2519, 2320, 2428, 2677, 2488, 2519, 2488, 2626, 2807, 3310, 3425, 3088, - 38216, 37851, 37882, 41010, 40773, 40682, 34066, 34008, 33801, 34078, 34008, 34066, 43753, - 43871, 43819, 43909, 43523, 43352, 4457, 4474, 4502, 37800, 37851, 37780, 40518, 41010, - 40682, 1093, 1070, 1189, 7772, 7584, 7729, 6350, 6357, 6487, 7599, 7584, 7772, - 4474, 4575, 4579, 5983, 6026, 6078, 6007, 6026, 5983, 41891, 42028, 41870, 42011, - 42028, 41891, 1292, 1606, 1425, 36812, 37643, 36631, 36363, 36162, 36246, 41221, 41386, - 41089, 41543, 41450, 41422, 41607, 42200, 42677, 39483, 39340, 39476, 39013, 39077, 38933, - 36812, 36944, 37643, 39483, 39583, 39734, 39483, 39591, 39512, 39761, 39830, 39931, 41567, - 41428, 41398, 41725, 41684, 41583, 39254, 39237, 39072, 39254, 39072, 38564, 39072, 38364, - 38564, 38391, 38364, 38277, 6925, 6826, 6939, 34008, 33640, 33801, 33585, 33453, 33180, - 33854, 33640, 34008, 35472, 35671, 35538, 35300, 35358, 35238, 35046, 34788, 34986, 39343, - 39131, 39041, 39785, 40142, 40044, 866, 957, 1054, 823, 747, 724, 35469, 35671, - 35472, 2353, 2438, 2430, 2353, 2411, 2213, 34986, 34803, 34854, 42593, 42844, 42428, - 43292, 43467, 43225, 42756, 42844, 42593, 6925, 6753, 6826, 7936, 7960, 8036, 43209, - 43157, 43093, 6487, 6357, 6378, 6564, 6487, 6705, 40044, 40142, 40335, 618, 600, - 710, 151, 541, 73, 2277, 2320, 2519, 1517, 1545, 1700, 2213, 2411, 2201, - 41732, 41843, 41717, 42028, 42091, 42038, 41916, 41798, 41971, 37110, 36944, 36771, 39011, - 38514, 38756, 39935, 40044, 39962, 40277, 40070, 39962, 6026, 6167, 6195, 5982, 6167, - 6026, 36363, 36246, 36494, 34723, 34660, 34883, 42011, 42091, 42028, 42844, 43209, 43052, - 43388, 43467, 43292, 38216, 38391, 38277, 37657, 37800, 37780, 37609, 37317, 37332, 37336, - 37332, 37281, 43388, 43292, 43336, 36882, 36765, 36798, 870, 817, 957, 768, 817, - 870, 866, 1054, 1070, 1093, 1189, 1075, 42397, 42593, 42083, 43392, 43270, 43209, - 43705, 43759, 43631, 43898, 43662, 43780, 42091, 42173, 42083, 41798, 41916, 41770, 41241, - 41665, 41398, 35515, 35469, 35358, 35358, 35469, 35472, 34644, 34700, 34642, 1700, 1657, - 1486, 5982, 6200, 6167, 4474, 4457, 4575, 4391, 4389, 4443, 4267, 4277, 4391, - 4311, 4277, 4189, 3484, 2840, 2954, 36798, 36512, 36700, 36512, 36434, 36700, 41665, - 41800, 41572, 1785, 2201, 1939, 2353, 2331, 2438, 43759, 43731, 43631, 34723, 34883, - 34867, 1075, 1189, 1308, 4277, 4389, 4391, 6167, 6200, 6391, 6015, 5347, 5902, - 35130, 34883, 35039, 34780, 34644, 34449, 41450, 41386, 41286, 41406, 41386, 41450, 4389, - 4457, 4502, 37250, 37265, 37148, 36119, 36359, 36434, 41567, 41725, 41583, 41916, 42011, - 41891, 41697, 41725, 41567, 5161, 5345, 4885, 36162, 36059, 35783, 36592, 36363, 36494, - 41971, 42011, 41916, 6826, 6753, 6844, 6925, 7605, 7104, 35515, 35358, 35591, 35110, - 35046, 34986, 43209, 43270, 43157, 43388, 43270, 43392, 747, 823, 817, 582, 618, - 724, 689, 866, 690, 8341, 8121, 8177, 7620, 7599, 7772, 8161, 8121, 8341, - 37439, 37609, 37332, 37800, 37882, 37851, 37439, 37332, 37336, 6357, 6334, 6378, 6350, - 6334, 6357, 36023, 36059, 36164, 39131, 39169, 39013, 39343, 39236, 39131, 39512, 39403, - 39340, 39512, 39340, 39483, 39483, 39734, 39591, 39830, 39935, 39931, 39403, 39236, 39343, - 39931, 39935, 39962, 39236, 39169, 39131, 36963, 36867, 37148, 35926, 35886, 35671, 41971, - 41850, 41725, 41725, 41850, 41684, 541, 636, 19, 7620, 7772, 7797, 39956, 39738, - 39725, 2279, 2331, 2353, 2279, 2353, 2171, 5009, 5498, 5617, 3531, 3738, 3950, - 2277, 2178, 2320, 7755, 7620, 7797, 8980, 8598, 8994, 33963, 33453, 33640, 33640, - 33453, 33585, 33854, 34008, 34078, 39962, 40070, 39971, 6753, 6644, 6705, 6564, 6644, - 6534, 39931, 39962, 39971, 39897, 39956, 39725, 39598, 39419, 39359, 39598, 39359, 39803, - 7246, 7562, 7614, 7021, 7246, 7101, 7021, 7101, 6803, 34078, 34066, 34151, 35285, - 35130, 35481, 37833, 37882, 37800, 37833, 37657, 37845, 5617, 6006, 5783, 6564, 6350, - 6487, 35788, 35926, 35671, 35515, 35671, 35469, 4885, 5345, 4575, 43270, 43388, 43336, - 43467, 43909, 43352, 43392, 43209, 43442, 43209, 42844, 43016, 42173, 42091, 42011, 1545, - 1410, 1579, 582, 747, 699, 2178, 2254, 2250, 41542, 41619, 41398, 42277, 42173, - 42011, 41572, 41619, 41542, 34644, 34854, 34803, 34780, 34854, 34644, 34066, 34211, 34151, - 41971, 41798, 41850, 2320, 2178, 2250, 2488, 2677, 2626, 38300, 38391, 38216, 37845, - 37657, 37609, 4457, 4382, 4575, 4389, 4384, 4457, 4277, 4311, 4389, 3816, 3892, - 3617, 7104, 7605, 7584, 8029, 8036, 8121, 19, 636, 600, 768, 747, 817, - 870, 866, 768, 52, 81, 738, 579, 1005, 1174, 1267, 1123, 1425, 8161, - 8029, 8121, 34151, 34211, 34268, 6644, 6564, 6705, 7476, 7584, 7599, 1517, 1410, - 1545, 1473, 1410, 1517, 41386, 41494, 41089, 41857, 41732, 41543, 41732, 41857, 41843, - 6007, 5982, 6026, 5834, 5902, 5347, 36959, 36882, 36798, 36359, 35777, 35886, 36059, - 35817, 35767, 35130, 34867, 34883, 36023, 35817, 36059, 4311, 4384, 4389, 38300, 38216, - 37882, 43759, 43898, 43731, 41843, 41857, 41964, 43846, 43898, 43780, 36809, 36798, 36700, - 37833, 37845, 37882, 41477, 41406, 41450, 340, 1005, 579, 2274, 2279, 2171, 7620, - 7476, 7599, 8029, 7936, 8036, 36582, 36164, 36162, 36944, 36812, 36615, 37643, 38154, - 37811, 36685, 36809, 36700, 5902, 5982, 6007, 5884, 5982, 5902, 36434, 36685, 36700, - 36271, 36359, 35886, 36434, 36359, 36439, 41717, 41477, 41543, 39908, 39931, 39971, 6534, - 6644, 6613, 6006, 6133, 5783, 6644, 6753, 6613, 2323, 2504, 2438, 4311, 4295, - 4384, 7888, 8129, 7992, 6405, 6798, 6200, 39169, 39077, 39013, 39236, 39273, 39169, - 39549, 39273, 39236, 39524, 39236, 39403, 39524, 39403, 39512, 39583, 39761, 39734, 39761, - 39908, 39734, 39761, 39931, 39908, 39803, 39359, 39254, 41697, 41567, 41619, 7844, 7755, - 7797, 43388, 43455, 43467, 43455, 43392, 43442, 40335, 40277, 40044, 3738, 4286, 3950, - 39273, 39077, 39169, 7562, 7246, 7148, 33438, 33968, 33682, 34854, 35110, 34986, 3281, - 3816, 3617, 35036, 34867, 35130, 39077, 38957, 38933, 40335, 40423, 40518, 1410, 1253, - 1513, 1364, 1253, 1410, 36812, 36626, 36494, 35047, 35036, 35130, 36631, 36626, 36812, - 36534, 36685, 36434, 37357, 37336, 37265, 43016, 42844, 42756, 41697, 41971, 41725, 41542, - 41665, 41572, 3816, 3893, 4379, 40991, 41186, 40497, 41697, 41572, 41800, 7148, 7246, - 7176, 34078, 33963, 33854, 33854, 33963, 33640, 34268, 34211, 34339, 33968, 34181, 33682, - 37357, 37439, 37336, 36959, 36798, 36826, 34780, 35110, 34854, 36439, 36534, 36434, 36626, - 36592, 36494, 36631, 36592, 36626, 36826, 36798, 36809, 36439, 36359, 36383, 1486, 1473, - 1517, 36826, 36809, 36685, 41494, 41386, 41406, 41732, 41717, 41543, 42200, 42469, 42638, - 41572, 41697, 41619, 40994, 40308, 41665, 3893, 4189, 4267, 4384, 4382, 4457, 5884, - 6234, 5982, 38391, 38564, 38364, 37918, 37845, 37609, 7936, 7844, 7797, 7755, 7634, - 7620, 8012, 7844, 7936, 8012, 7936, 8029, 43392, 43455, 43388, 42397, 42083, 42173, - 42397, 42173, 42277, 4189, 4295, 4311, 37439, 37918, 37609, 37250, 37357, 37265, 2400, - 2488, 2247, 1657, 1700, 2119, 4295, 4382, 4384, 41494, 41406, 41477, 1473, 1364, - 1410, 768, 689, 676, 1373, 1364, 1473, 37148, 36867, 36882, 36948, 36826, 36685, - 36648, 36685, 36534, 41717, 41582, 41477, 42430, 42907, 42469, 7844, 7634, 7755, 35300, - 35238, 35046, 36383, 36359, 36271, 35110, 35300, 35046, 35599, 35300, 35110, 38686, 38300, - 37882, 38564, 38592, 38702, 37357, 37371, 37439, 37148, 36882, 36959, 34713, 34211, 34723, - 35047, 35130, 35285, 5982, 6234, 6200, 7760, 7888, 7562, 6405, 6289, 6441, 42277, - 42011, 42282, 39134, 39092, 39077, 39077, 39092, 38957, 38957, 39011, 38756, 39591, 39524, - 39512, 39549, 39524, 39612, 39524, 39591, 39612, 39876, 39734, 39908, 39876, 39908, 39960, - 7562, 7888, 7992, 7148, 7176, 7021, 34117, 33963, 34078, 34713, 34723, 34901, 7533, - 7476, 7620, 34901, 34723, 34867, 43841, 43909, 43467, 3950, 4286, 4418, 5783, 6334, - 6255, 6255, 6350, 6564, 37108, 37148, 36959, 36992, 36959, 36826, 36271, 35886, 35926, - 2119, 2254, 1738, 37250, 37371, 37357, 37108, 36959, 36992, 41673, 41582, 41717, 39134, - 39077, 39273, 39960, 39908, 39971, 39598, 39897, 39725, 40138, 39897, 39598, 2400, 2277, - 2519, 2331, 2279, 2438, 2353, 2213, 2171, 3893, 3765, 4189, 4189, 4224, 4295, - 4295, 4258, 4382, 3816, 3769, 3893, 3281, 3769, 3816, 3765, 3769, 3424, 40070, - 39960, 39971, 747, 582, 724, 768, 676, 713, 689, 768, 866, 6405, 6803, - 6798, 699, 768, 713, 6613, 6753, 6729, 35515, 35776, 35671, 35614, 35776, 35515, - 43174, 42907, 42430, 41841, 41673, 41717, 42926, 43016, 42756, 43455, 43841, 43467, 36164, - 36059, 36162, 35036, 34901, 34867, 36631, 36363, 36592, 35055, 34901, 35036, 34117, 34151, - 34268, 8598, 8161, 8341, 7550, 7533, 7634, 7634, 7533, 7620, 37148, 37371, 37250, - 36545, 36534, 36439, 41841, 41717, 41843, 41582, 41494, 41477, 39692, 39876, 39929, 36447, - 36545, 36439, 36208, 36271, 35926, 42397, 42480, 42593, 42282, 42011, 41971, 42480, 42277, - 42404, 1738, 2254, 2178, 1280, 1253, 1364, 6729, 6753, 6925, 7550, 7634, 7844, - 8161, 8012, 8029, 4382, 4367, 4575, 4090, 4224, 4189, 38592, 38564, 38391, 38391, - 38300, 38592, 768, 699, 747, 1424, 1473, 1486, 5783, 6283, 6334, 7104, 7584, - 7386, 41964, 41841, 41843, 42545, 43174, 42430, 1005, 1123, 1267, 1150, 802, 1097, - 36447, 36439, 36383, 36948, 36992, 36826, 37233, 37371, 37148, 41612, 41494, 41582, 41964, - 41857, 42092, 6234, 6405, 6200, 6803, 7148, 7021, 5884, 5902, 5834, 7386, 7584, - 7476, 34117, 34268, 34339, 35130, 35411, 35481, 4224, 4258, 4295, 36075, 36208, 35926, - 36387, 36447, 36383, 37126, 37148, 37108, 41743, 41582, 41673, 151, 73, 6, 19, - 600, 261, 473, 618, 582, 1816, 1738, 2178, 2488, 2400, 2519, 3088, 3425, - 3421, 7533, 7386, 7476, 7550, 7386, 7533, 35300, 35591, 35358, 35776, 35788, 35671, - 34400, 34780, 34449, 34400, 34449, 34181, 6334, 6350, 6255, 42677, 42200, 42638, 41906, - 41743, 41673, 2279, 2323, 2438, 2274, 2323, 2279, 6015, 5452, 5347, 36992, 37126, - 37108, 36545, 36648, 36534, 36387, 36383, 36271, 6255, 6564, 6534, 6861, 6729, 6925, - 7048, 6925, 7104, 36306, 36387, 36271, 35614, 35591, 35599, 35884, 35788, 35776, 42735, - 42677, 42638, 42735, 42638, 42733, 43436, 43442, 43209, 43436, 43209, 43429, 39612, 39591, - 39692, 39524, 39549, 39236, 39092, 39099, 38957, 39591, 39734, 39692, 39734, 39876, 39692, - 39876, 39960, 39992, 39992, 39960, 40070, 2171, 2213, 2057, 35967, 36075, 35926, 42277, - 42480, 42397, 42282, 42376, 42404, 39567, 39134, 39273, 39134, 39099, 39092, 39962, 40044, - 40277, 1509, 1424, 1486, 2166, 2178, 2277, 3769, 3765, 3893, 4224, 4090, 4258, - 3281, 3617, 3301, 3484, 3279, 2840, 40277, 40335, 40495, 2120, 2166, 2277, 2274, - 2225, 2323, 1512, 1939, 1676, 1509, 1486, 1657, 40495, 40335, 40518, 41906, 41673, - 41841, 42002, 41841, 41964, 36447, 36648, 36545, 36449, 36387, 36477, 41902, 41971, 41697, - 40991, 41089, 41186, 2166, 2110, 2178, 42264, 41857, 41607, 43840, 42789, 43731, 43211, - 42926, 42480, 42480, 42926, 42593, 699, 606, 582, 1075, 1308, 1253, 43026, 42735, - 42733, 6255, 6534, 6613, 7115, 7048, 7104, 7287, 7104, 7386, 1123, 1150, 1425, - 1097, 802, 997, 6255, 6613, 6286, 4268, 4625, 4426, 36582, 36631, 37152, 35481, - 35411, 35795, 36449, 36648, 36447, 42106, 42092, 42301, 1424, 1373, 1473, 1344, 1373, - 1424, 1280, 1373, 1324, 2110, 1989, 2178, 7666, 7550, 7844, 8161, 7961, 8012, - 8598, 8113, 8161, 34117, 34078, 34151, 34211, 34554, 34339, 34713, 34653, 34211, 7666, - 7844, 8012, 43442, 43533, 43455, 43429, 43209, 43016, 713, 606, 699, 594, 606, - 713, 1373, 1280, 1364, 1509, 1657, 1498, 1150, 1292, 1425, 36306, 36271, 36208, - 36387, 36449, 36447, 35788, 35967, 35926, 35591, 35614, 35515, 35599, 35591, 35300, 36848, - 36685, 36648, 36848, 36948, 36685, 38686, 37882, 37845, 977, 1075, 1253, 7048, 6861, - 6925, 6778, 6861, 6842, 8113, 7961, 8161, 34713, 34903, 34653, 35884, 35967, 35788, - 171, 340, 579, 1078, 1512, 1292, 6441, 6803, 6405, 6850, 7148, 6460, 1569, - 1657, 1738, 1292, 1512, 1676, 41693, 41612, 41582, 41693, 41582, 41743, 36582, 36162, - 36363, 35055, 35036, 35047, 2163, 2225, 2274, 2163, 2274, 2171, 81, 171, 579, - 42092, 41979, 41964, 42106, 41979, 42092, 36306, 36208, 36075, 40071, 40086, 40296, 41906, - 41693, 41743, 2840, 3279, 2471, 2471, 2504, 2323, 2057, 2163, 2171, 43898, 43840, - 43731, 606, 556, 582, 547, 556, 606, 866, 1070, 690, 6289, 6234, 6070, - 6289, 6405, 6234, 35967, 36148, 36075, 35614, 35884, 35776, 35760, 35884, 35614, 40450, - 40086, 40070, 40070, 40086, 39992, 39929, 39842, 39692, 39673, 39639, 39612, 39612, 39639, - 39549, 39120, 39099, 39134, 39108, 39011, 39099, 41089, 41494, 41186, 35411, 35817, 35795, - 81, 8, 171, 43436, 43533, 43442, 43519, 43533, 43436, 2471, 2323, 2297, 39099, - 39011, 38957, 39554, 39273, 39549, 36250, 36148, 36081, 41979, 42002, 41964, 42264, 41607, - 42677, 41979, 42106, 42137, 42526, 42418, 42264, 1075, 1037, 1093, 1280, 1209, 1253, - 1481, 1344, 1424, 1481, 1424, 1509, 37061, 37126, 36948, 36948, 37126, 36992, 36848, - 36648, 36932, 41665, 40308, 42577, 42282, 42404, 42277, 43519, 43429, 43752, 42376, 42282, - 42352, 1785, 2213, 2201, 2297, 2323, 2225, 34987, 34713, 34901, 43429, 43016, 43252, - 1652, 1569, 1738, 556, 473, 582, 453, 473, 556, 594, 713, 676, 6861, - 6778, 6729, 6842, 6861, 7048, 7287, 7386, 7550, 35182, 35055, 35047, 35795, 35817, - 36124, 2297, 2225, 2141, 4258, 4367, 4382, 3765, 4090, 4189, 4193, 4090, 4164, - 38564, 39438, 39254, 40533, 40308, 39956, 38592, 38300, 38686, 5970, 6234, 5884, 7348, - 7309, 6850, 41800, 41902, 41697, 42026, 41902, 41800, 1989, 1816, 2178, 1960, 1963, - 1989, 1960, 1989, 2110, 1983, 2110, 2166, 1750, 1963, 1670, 3088, 3421, 3738, - 38686, 37845, 38503, 7888, 7760, 8129, 7309, 7760, 7562, 7309, 7562, 7148, 33968, - 34400, 34181, 35643, 35599, 35110, 36148, 36306, 36075, 36250, 36306, 36148, 36477, 36306, - 36488, 1456, 1498, 1547, 1569, 1498, 1657, 1324, 1209, 1280, 41829, 42119, 42005, - 7523, 7287, 7550, 41821, 41612, 41693, 41186, 41494, 41546, 1963, 1816, 1989, 1324, - 1373, 1344, 42137, 42002, 41979, 42526, 42461, 42418, 977, 1037, 1075, 5347, 5452, - 5161, 42997, 42733, 42907, 2141, 2225, 2163, 4193, 4367, 4258, 6778, 6528, 6729, - 6849, 6842, 7048, 690, 1070, 1093, 1456, 1481, 1498, 1498, 1481, 1509, 1816, - 1788, 1738, 4367, 4885, 4575, 39612, 39842, 39673, 39554, 39639, 39673, 35182, 35047, - 35285, 1785, 1939, 1512, 2115, 2163, 2057, 2115, 2141, 2163, 42404, 42573, 42480, - 42463, 42573, 42404, 42282, 41971, 42352, 3151, 3088, 3738, 1963, 1750, 1816, 1816, - 1750, 1788, 4418, 4625, 3950, 2954, 3033, 3301, 4090, 4193, 4258, 3150, 3033, - 2509, 3150, 2509, 2900, 2093, 2840, 2471, 2253, 2471, 2297, 37643, 37727, 38626, - 36124, 36023, 36164, 39277, 39120, 39134, 36477, 36648, 36449, 37126, 37233, 37148, 34339, - 34329, 34117, 34117, 34383, 33963, 34554, 34329, 34339, 34554, 34211, 34653, 39120, 39108, - 39099, 37061, 37233, 37126, 36148, 35967, 36081, 36306, 36477, 36387, 42463, 42376, 42501, - 35398, 35110, 34780, 43083, 42997, 42907, 689, 594, 676, 626, 594, 689, 36124, - 35817, 36023, 35131, 34987, 35055, 36124, 36164, 36228, 36228, 36164, 36582, 6849, 6740, - 6842, 7758, 7666, 8012, 7555, 7666, 7758, 34987, 34901, 35055, 34727, 34554, 34653, - 531, 547, 594, 977, 889, 1037, 1305, 1324, 1344, 1383, 1344, 1481, 42002, - 41906, 41841, 42116, 41906, 42002, 42137, 42106, 42227, 35429, 35285, 35481, 40682, 40495, - 40518, 40678, 40495, 40682, 41764, 41494, 41612, 43833, 43455, 43533, 43833, 43841, 43455, - 43519, 43436, 43429, 5834, 5970, 5884, 6289, 6268, 6441, 5814, 5970, 5834, 43104, - 43016, 42926, 42376, 42463, 42404, 42536, 42463, 42513, 7555, 7523, 7550, 34783, 34727, - 34653, 43104, 42926, 43211, 261, 600, 618, 594, 547, 606, 690, 1093, 889, - 35599, 35760, 35614, 35808, 35760, 35643, 4587, 4811, 4885, 5390, 5814, 5834, 4047, - 4090, 3765, 6842, 6740, 6778, 3950, 4625, 4268, 6849, 7048, 7062, 34987, 34903, - 34713, 35797, 35429, 35481, 35797, 35481, 35795, 42849, 42677, 42735, 43174, 42545, 42841, - 36958, 36948, 36848, 36958, 37061, 36948, 37918, 37439, 37371, 36958, 36848, 36932, 626, - 690, 604, 6528, 6613, 6729, 35287, 35182, 35285, 1547, 1498, 1569, 1324, 1122, - 1209, 1652, 1738, 1788, 4193, 4281, 4367, 41010, 40518, 40423, 42463, 42536, 42573, - 42501, 42376, 42352, 2120, 2277, 2400, 1529, 1785, 1512, 2212, 2253, 2297, 1097, - 1292, 1150, 35127, 34903, 34987, 37061, 37045, 37233, 36932, 36648, 36643, 42227, 42106, - 42301, 41875, 41821, 41693, 41186, 41010, 40423, 39639, 39554, 39549, 39120, 39133, 39108, - 39612, 39692, 39842, 40071, 39929, 39876, 39992, 40071, 39876, 39992, 40086, 40071, 5970, - 6070, 6234, 5347, 5161, 4893, 42849, 42735, 43026, 40070, 40277, 40450, 1750, 1652, - 1788, 1571, 1652, 1588, 1318, 1383, 1456, 1456, 1383, 1481, 41665, 41829, 41800, - 42005, 42119, 42139, 2247, 2120, 2400, 5009, 4426, 4625, 2351, 2247, 2488, 40450, - 40277, 40495, 40773, 40678, 40682, 41162, 41010, 41186, 690, 626, 689, 889, 1093, - 1037, 43026, 42733, 42997, 6740, 6528, 6778, 7115, 7104, 7287, 43151, 43026, 42997, - 43320, 43174, 42841, 7205, 7115, 7287, 7666, 7555, 7550, 7758, 8012, 7961, 34554, - 34383, 34329, 34727, 34573, 34554, 34714, 34573, 34727, 43519, 43623, 43533, 43607, 43623, - 43519, 37727, 38021, 38626, 39277, 39133, 39120, 36179, 35951, 35795, 35287, 35131, 35182, - 35182, 35131, 35055, 34903, 34783, 34653, 36582, 36363, 36631, 36081, 35967, 36019, 7407, - 7287, 7523, 35287, 35285, 35429, 2120, 1983, 2166, 1965, 1983, 1946, 1150, 1123, - 802, 802, 1005, 86, 41, 340, 171, 42137, 42116, 42002, 42301, 42092, 42264, - 42301, 42264, 42395, 1383, 1305, 1344, 1208, 1305, 1383, 1547, 1569, 1652, 977, - 1253, 1209, 36376, 36488, 36306, 43211, 42480, 42573, 42352, 41971, 42206, 453, 556, - 547, 261, 618, 473, 7381, 7407, 7523, 35127, 34783, 34903, 1983, 1960, 2110, - 1965, 1960, 1983, 1571, 1547, 1652, 626, 531, 594, 604, 531, 626, 36265, - 36376, 36306, 35760, 35808, 35884, 35971, 35808, 35993, 42640, 42573, 42536, 4114, 4336, - 4367, 4193, 4230, 4281, 4012, 4047, 3962, 4047, 3424, 3962, 35131, 35127, 34987, - 35438, 35287, 35429, 36019, 35967, 35884, 1016, 977, 1209, 524, 453, 531, 1208, - 1324, 1305, 42219, 42116, 42137, 42395, 42264, 42418, 41829, 42026, 41800, 42005, 42026, - 41829, 4047, 4164, 4090, 40672, 40678, 41054, 40678, 40773, 41054, 7314, 7205, 7287, - 6870, 6742, 6849, 6849, 6742, 6740, 36265, 36306, 36250, 36643, 36648, 36477, 42501, - 42513, 42463, 42708, 42513, 42634, 2221, 2247, 2017, 1588, 1652, 1750, 2115, 2297, - 2141, 2115, 2057, 1975, 4164, 4230, 4193, 42219, 42137, 42227, 42322, 42219, 42227, - 42461, 42395, 42418, 42820, 42677, 42849, 42206, 41971, 41902, 43623, 43708, 43533, 43752, - 43607, 43519, 604, 690, 740, 531, 453, 547, 43199, 42997, 43083, 359, 343, - 473, 7062, 7048, 7115, 5009, 5617, 4991, 43174, 43199, 43083, 43320, 43199, 43174, - 524, 396, 447, 36184, 36265, 36250, 35971, 36019, 35884, 35971, 35884, 35808, 43073, - 42820, 42849, 41875, 41693, 41906, 6987, 7062, 7115, 5859, 6070, 5970, 5859, 5970, - 5814, 36184, 36250, 36081, 36643, 36477, 36488, 39554, 39567, 39273, 37643, 36944, 37110, - 39769, 39567, 39554, 39769, 39554, 39673, 39769, 39673, 39842, 39979, 39842, 39929, 39979, - 39929, 40071, 42703, 42640, 42708, 42513, 42640, 42536, 43783, 43708, 43752, 2297, 2115, - 2112, 40098, 39979, 40071, 39567, 39277, 39134, 6987, 6928, 7062, 7407, 7314, 7287, - 7381, 7314, 7407, 8113, 7758, 7961, 34573, 34383, 34554, 34329, 34383, 34117, 34714, - 34383, 34573, 34714, 34727, 34783, 36491, 36488, 36376, 36958, 37045, 37061, 42322, 42227, - 42301, 42116, 41875, 41906, 42322, 42301, 42450, 7381, 7523, 7555, 6268, 6803, 6441, - 1547, 1417, 1456, 740, 690, 889, 1588, 1750, 1605, 39011, 39108, 39100, 35438, - 35127, 35287, 35287, 35127, 35131, 42526, 42264, 42677, 42169, 41875, 42116, 41341, 41162, - 41186, 36502, 36491, 36376, 36019, 36072, 36081, 35999, 35971, 35993, 252, 261, 343, - 343, 261, 473, 359, 473, 453, 7062, 6870, 6849, 6742, 6720, 6740, 6928, - 6870, 7062, 43903, 43320, 42841, 43199, 43253, 42997, 42803, 42678, 42820, 42678, 42526, - 42677, 40672, 40450, 40495, 40672, 40495, 40678, 1946, 1983, 2120, 41764, 41612, 41821, - 43607, 43708, 43623, 43252, 43016, 43104, 1571, 1556, 1547, 1538, 1556, 1571, 41879, - 41821, 41875, 42329, 42322, 42344, 42322, 42450, 42344, 35795, 36124, 36179, 1318, 1208, - 1383, 604, 524, 531, 4893, 5161, 4885, 5617, 5228, 4991, 2351, 2807, 3088, - 2247, 2221, 2120, 36502, 36376, 36265, 42678, 42677, 42820, 1556, 1417, 1547, 1538, - 1417, 1556, 4230, 4099, 4281, 4164, 4121, 4230, 4047, 4012, 4164, 3150, 3301, - 3033, 2093, 2471, 2253, 43840, 43852, 42841, 740, 889, 977, 444, 359, 453, - 43211, 43237, 43104, 1208, 1122, 1324, 1135, 1122, 1208, 4012, 4121, 4164, 35999, - 36072, 36019, 6870, 6720, 6742, 6987, 7115, 7205, 6987, 7205, 7175, 41879, 41764, - 41821, 42208, 42116, 42219, 42208, 42219, 42329, 1670, 1963, 1960, 2771, 3088, 3151, - 2112, 2212, 2297, 2112, 2115, 1975, 42329, 42219, 42322, 43073, 42849, 43026, 8, - 41, 171, 1975, 2057, 1693, 997, 1292, 1097, 36857, 37045, 36932, 36932, 37045, - 36958, 36643, 36488, 36491, 42395, 42450, 42301, 3218, 3150, 2900, 3033, 2954, 2509, - 4078, 4099, 4121, 39567, 39446, 39277, 39277, 39316, 39133, 39987, 39769, 39842, 39925, - 39769, 39987, 40098, 40071, 40296, 3150, 3281, 3301, 447, 444, 524, 524, 444, - 453, 1201, 1135, 1208, 1820, 1960, 1965, 41546, 41341, 41186, 40296, 40086, 40450, - 42004, 41879, 41875, 39559, 39446, 39567, 40296, 40450, 40387, 6070, 6268, 6289, 6127, - 6268, 6070, 34789, 34783, 35127, 34789, 34714, 34783, 36072, 36184, 36081, 35971, 35999, - 36019, 35643, 35760, 35599, 43237, 43252, 43104, 43380, 43252, 43237, 42703, 42573, 42640, - 40773, 41010, 41054, 42708, 42640, 42513, 42513, 42501, 42634, 7175, 7205, 7314, 6671, - 6720, 6870, 802, 1123, 1005, 1825, 1946, 2120, 42169, 42004, 41875, 42395, 42516, - 42450, 1588, 1538, 1571, 1122, 1016, 1209, 1484, 1538, 1588, 42026, 42206, 41902, - 40338, 39956, 39897, 39803, 39254, 39438, 38564, 38702, 39438, 7309, 7348, 7760, 6850, - 7309, 7148, 34400, 34887, 34780, 1946, 1820, 1965, 36128, 36184, 36072, 35398, 35643, - 35110, 36179, 36124, 36228, 36179, 36228, 36525, 39100, 39108, 39133, 252, 343, 359, - 212, 215, 261, 261, 215, 19, 252, 359, 444, 36525, 36228, 36582, 36128, - 36072, 35999, 41054, 41010, 41162, 1318, 1456, 1417, 1318, 1417, 1256, 42005, 42152, - 42026, 43708, 43833, 43533, 43752, 43708, 43607, 754, 740, 977, 36412, 36502, 36265, - 1820, 1670, 1960, 3962, 4121, 4012, 4121, 4099, 4230, 5681, 5859, 5814, 7758, - 7381, 7555, 34714, 34869, 34383, 34869, 34789, 35127, 43756, 43752, 43897, 43252, 43752, - 43429, 42152, 42206, 42026, 42703, 42799, 42573, 396, 524, 604, 35951, 35797, 35795, - 35805, 35797, 36257, 228, 252, 444, 6982, 6928, 6987, 6982, 6870, 6928, 43320, - 43253, 43199, 42516, 42461, 42666, 43457, 43253, 43320, 36184, 36412, 36265, 35993, 36128, - 35999, 35993, 35808, 36048, 1256, 1417, 1277, 1135, 1016, 1122, 7053, 6982, 6987, - 1670, 1605, 1750, 36220, 36412, 36184, 36502, 36643, 36491, 42550, 42501, 42352, 39925, - 39778, 39769, 39769, 39778, 39567, 39446, 39316, 39277, 39840, 39778, 39925, 39979, 40098, - 40072, 37371, 37878, 37918, 38686, 38702, 38592, 42005, 42139, 42152, 42152, 42168, 42206, - 3424, 4047, 3765, 3150, 3218, 3281, 2087, 2253, 2212, 39778, 39749, 39567, 2112, - 2087, 2212, 1693, 2057, 1785, 3151, 3738, 3531, 1724, 1820, 1946, 1717, 1670, - 1820, 1717, 1581, 1670, 1670, 1581, 1605, 5617, 5783, 5228, 39749, 39559, 39567, - 39559, 39516, 39446, 43756, 43783, 43752, 43756, 43833, 43783, 43783, 43833, 43708, 39487, - 39316, 39446, 1428, 1529, 1340, 4587, 4885, 4434, 36500, 36643, 36502, 42437, 42550, - 42352, 6720, 6528, 6740, 6669, 6528, 6720, 43253, 43151, 42997, 43457, 43151, 43253, - 36412, 36500, 36502, 36128, 36220, 36184, 36048, 35808, 35643, 40610, 40387, 40450, 40610, - 40450, 40672, 130, 212, 122, 252, 212, 261, 215, 38, 19, 228, 444, - 447, 35797, 35438, 35429, 42942, 42803, 42820, 42329, 42344, 42208, 41546, 41494, 41744, - 42847, 42799, 42708, 42708, 42799, 42703, 4811, 4893, 4885, 4898, 4893, 4813, 42395, - 42461, 42516, 42206, 42437, 42352, 42550, 42634, 42501, 42119, 41829, 41665, 42663, 42634, - 42550, 41546, 41744, 41601, 7381, 7328, 7314, 6982, 6671, 6870, 7308, 7328, 7381, - 5228, 5783, 5634, 4336, 4885, 4367, 3424, 3769, 3281, 429, 396, 604, 429, - 604, 373, 43151, 43073, 43026, 42741, 42526, 42678, 43239, 43073, 43343, 35993, 36220, - 36128, 36048, 36220, 35993, 42139, 42168, 42152, 42177, 42168, 42139, 42004, 41764, 41879, - 42741, 42678, 42803, 42359, 42437, 42206, 43073, 42942, 42820, 3962, 4078, 4121, 1318, - 1201, 1208, 1277, 1417, 1538, 1484, 1588, 1605, 36581, 36500, 36412, 37371, 37233, - 37878, 42882, 42741, 42803, 1975, 2087, 2112, 2027, 2087, 1975, 7328, 7175, 7314, - 36857, 36932, 36643, 1724, 1946, 1825, 40098, 40296, 40274, 42116, 42208, 42169, 1004, - 1016, 1135, 1340, 1529, 1512, 1693, 1918, 1975, 16, 1005, 340, 42169, 42208, - 42344, 42666, 42461, 42526, 39657, 39487, 39516, 39516, 39487, 39446, 39316, 39100, 39133, - 39749, 39840, 39559, 39778, 39840, 39749, 39842, 39979, 39987, 39979, 40072, 39987, 40098, - 40162, 40072, 40098, 40274, 40162, 43211, 42799, 42962, 43211, 42573, 42799, 43897, 43752, - 43252, 1222, 1201, 1256, 1256, 1201, 1318, 6528, 6286, 6613, 6687, 6671, 6982, - 40296, 40451, 40274, 42658, 42344, 42450, 39657, 39516, 39559, 40274, 40310, 40297, 39803, - 40138, 39598, 40063, 40138, 39803, 3151, 3531, 3314, 3218, 3424, 3281, 3928, 4099, - 4078, 3222, 3424, 3218, 40610, 40672, 41015, 130, 38, 215, 130, 215, 212, - 212, 252, 228, 40138, 40338, 39897, 1340, 1512, 1078, 42561, 42523, 42437, 42847, - 42708, 42634, 42254, 42119, 41665, 42516, 42680, 42450, 42741, 42666, 42526, 42680, 42666, - 42715, 42923, 42803, 42942, 41054, 41162, 41404, 1484, 1277, 1538, 1825, 2120, 2221, - 6485, 6286, 6528, 36791, 36857, 36643, 36581, 36791, 36500, 36149, 36048, 35643, 2771, - 2351, 3088, 228, 447, 223, 1918, 2027, 1975, 1351, 1340, 1317, 4893, 4898, - 5347, 6460, 7148, 6803, 4681, 4893, 4811, 4281, 4114, 4367, 42971, 42923, 42942, - 42882, 42923, 42971, 1016, 909, 977, 1201, 1113, 1135, 989, 1113, 1201, 42119, - 42177, 42139, 42201, 42177, 42119, 1724, 1717, 1820, 1697, 1717, 1724, 7175, 7053, - 6987, 6671, 6669, 6720, 7308, 7053, 7175, 5390, 5834, 5347, 1484, 1605, 1581, - 4801, 5291, 5347, 4281, 4099, 4114, 7328, 7308, 7175, 7758, 7308, 7381, 35414, - 34869, 35127, 34789, 34869, 34714, 35414, 35127, 35438, 35605, 35438, 35805, 36257, 35951, - 36454, 42523, 42550, 42437, 1113, 1004, 1135, 916, 1004, 1113, 5390, 5291, 5318, - 349, 447, 396, 6687, 6982, 6896, 6687, 6669, 6671, 36791, 36643, 36500, 42359, - 42206, 42168, 5859, 6127, 6070, 6111, 6127, 5942, 2087, 2093, 2253, 2093, 2027, - 2006, 41067, 41054, 41421, 41601, 41341, 41546, 41494, 41764, 41744, 42680, 42516, 42666, - 41744, 41764, 41767, 42750, 42847, 42634, 40259, 40072, 40162, 39998, 39987, 40181, 39998, - 39925, 39987, 39998, 39914, 39925, 39925, 39914, 39840, 39840, 39657, 39559, 39487, 39415, - 39316, 40297, 40162, 40274, 40296, 40387, 40451, 1004, 909, 1016, 916, 909, 1004, - 5291, 5390, 5347, 5318, 5291, 5238, 42523, 42663, 42550, 42288, 42359, 42168, 42288, - 42168, 42177, 40451, 40387, 40653, 37493, 37762, 37045, 36581, 36412, 36590, 39657, 39415, - 39487, 37643, 37152, 36631, 39246, 39438, 38702, 40419, 40533, 40338, 39246, 38702, 38686, - 42715, 42666, 42741, 42614, 42663, 42523, 1277, 1222, 1256, 1717, 1484, 1581, 1310, - 1484, 1717, 4587, 4681, 4811, 4576, 4681, 4587, 41767, 41764, 42004, 41404, 41162, - 41341, 1959, 1825, 2221, 40310, 40542, 40400, 373, 604, 740, 228, 122, 212, - 130, 122, 38, 103, 122, 228, 6669, 6560, 6528, 5634, 5783, 6255, 6659, - 6687, 6652, 42923, 42882, 42803, 43655, 43457, 43320, 43852, 43903, 42841, 40338, 40533, - 39956, 40419, 40338, 40138, 42971, 42942, 43069, 42872, 42932, 42847, 42847, 42932, 42799, - 3878, 4078, 3962, 4707, 4813, 4681, 4681, 4813, 4893, 39100, 38514, 39011, 41404, - 41341, 41601, 40310, 40274, 40451, 42080, 41767, 42004, 42663, 42750, 42634, 42359, 42507, - 42437, 42554, 42507, 42359, 39415, 39100, 39316, 42692, 42450, 42680, 42353, 42169, 42476, - 42254, 42201, 42119, 42797, 42715, 42741, 42784, 42750, 42717, 4336, 4434, 4885, 429, - 349, 396, 356, 349, 429, 6659, 6560, 6669, 6659, 6669, 6687, 43211, 43380, - 43237, 43541, 43380, 43653, 42962, 42799, 42932, 3424, 3878, 3962, 4361, 4430, 4434, - 3928, 3878, 3835, 41, 79, 340, 1078, 1292, 997, 43069, 42942, 43073, 42882, - 42797, 42741, 4430, 4461, 4434, 4434, 4461, 4587, 42784, 42872, 42847, 42507, 42561, - 42437, 42614, 42561, 42686, 42201, 42288, 42177, 42416, 42288, 42201, 2027, 2093, 2087, - 1785, 1529, 1693, 1529, 1428, 1351, 3878, 3928, 4078, 36590, 36412, 36453, 36791, - 36860, 36857, 42818, 42797, 43012, 42715, 42692, 42680, 1484, 1222, 1277, 909, 881, - 977, 1148, 1222, 1112, 4461, 4576, 4587, 4801, 5347, 4898, 4491, 4576, 4461, - 862, 916, 1113, 5390, 5681, 5814, 4801, 4898, 4813, 1351, 1428, 1340, 3928, - 4114, 4099, 36743, 36860, 36791, 6560, 6485, 6528, 6556, 6659, 6652, 349, 247, - 447, 369, 373, 518, 39438, 39924, 39803, 40063, 39924, 40092, 39914, 39657, 39840, - 38995, 38885, 39100, 40181, 39987, 40072, 40181, 40072, 40259, 40387, 40610, 40653, 43012, - 42797, 42882, 43239, 43069, 43073, 43073, 43151, 43343, 3314, 3531, 3632, 1932, 2017, - 2002, 1762, 1697, 1825, 3531, 3950, 3632, 3950, 4268, 3981, 39924, 40063, 39803, - 42577, 42254, 41665, 4576, 4674, 4681, 4491, 4674, 4576, 40093, 39657, 39914, 40063, - 40131, 40138, 4426, 5009, 4991, 6460, 6803, 6268, 6460, 6268, 6111, 34887, 35398, - 34780, 36453, 36412, 36220, 36581, 36743, 36791, 41067, 40672, 41054, 42784, 42847, 42750, - 42962, 42872, 43089, 916, 881, 909, 862, 881, 916, 1386, 1351, 1317, 4674, - 4707, 4681, 4665, 4707, 4674, 42288, 42399, 42359, 42399, 42416, 42442, 5505, 5681, - 5390, 5859, 5681, 5841, 42818, 42692, 42715, 42095, 41744, 41767, 42818, 42715, 42797, - 6556, 6485, 6560, 373, 356, 429, 369, 356, 373, 43012, 42882, 42971, 43343, - 43452, 43364, 1222, 1148, 1201, 1825, 1697, 1724, 2017, 2247, 2351, 42750, 42663, - 42717, 42872, 42962, 42932, 4713, 4426, 4991, 4707, 4801, 4813, 4314, 4434, 4336, - 42259, 42004, 42169, 41404, 41601, 41924, 43075, 42971, 43069, 42614, 42523, 42561, 43756, - 43897, 43833, 43862, 43897, 43252, 43541, 43252, 43380, 4430, 4491, 4461, 356, 247, - 349, 242, 247, 356, 2017, 2351, 2002, 1890, 2006, 2027, 2093, 2059, 2840, - 3835, 4067, 3928, 3928, 4067, 4114, 4114, 4229, 4336, 4430, 4361, 4491, 1890, - 2027, 1918, 41775, 41651, 41421, 43239, 43075, 43069, 43343, 43151, 43452, 122, 27, - 38, 223, 103, 228, 5634, 6255, 6057, 6659, 6556, 6560, 6896, 6982, 7053, - 6255, 6286, 6057, 42416, 42399, 42288, 42416, 42675, 42471, 42554, 42561, 42507, 43243, - 43075, 43239, 43903, 43655, 43320, 2017, 1959, 2221, 1118, 1148, 1112, 1837, 1890, - 1918, 3835, 3878, 3274, 1222, 1484, 1112, 238, 223, 247, 37152, 36525, 36582, - 36453, 36220, 36382, 37878, 37233, 37875, 4067, 4098, 4114, 38885, 38021, 39100, 38885, - 38626, 38021, 37834, 37152, 37643, 38995, 39100, 39999, 39998, 40093, 39914, 40259, 40162, - 40297, 40259, 40297, 40310, 40131, 40230, 40138, 40063, 40124, 40131, 40092, 40124, 40063, - 40092, 39924, 40119, 40257, 40259, 40345, 40124, 40230, 40131, 6313, 6286, 6485, 42614, - 42717, 42663, 43138, 43089, 42872, 43653, 43380, 43211, 42770, 42717, 42614, 1351, 1386, - 1529, 1078, 997, 878, 4637, 4665, 4551, 4491, 4665, 4674, 40230, 40419, 40138, - 878, 997, 805, 373, 740, 518, 247, 223, 447, 4098, 4229, 4114, 242, - 369, 238, 37233, 37045, 37875, 36382, 36220, 36048, 42080, 42004, 42259, 43092, 43012, - 42971, 43092, 42971, 43075, 43243, 43239, 43343, 1386, 1693, 1529, 4229, 4314, 4336, - 40807, 40653, 40610, 41015, 40672, 41067, 42169, 42353, 42259, 1144, 1646, 1693, 1078, - 1317, 1340, 4426, 4339, 4268, 5228, 4713, 4991, 4088, 3621, 3475, 36743, 36581, - 36590, 42442, 42359, 42399, 42534, 42554, 42359, 36742, 36743, 36590, 4713, 4339, 4426, - 4314, 4361, 4434, 6127, 5859, 5942, 6111, 6268, 6127, 369, 242, 356, 754, - 977, 881, 4665, 4801, 4707, 4760, 4801, 4637, 36453, 36437, 36590, 35789, 36149, - 35643, 40119, 39924, 39438, 37880, 37878, 37875, 43364, 43243, 43343, 41028, 41015, 41177, - 36168, 36382, 36048, 43218, 43092, 43075, 42344, 42658, 42169, 42554, 42686, 42561, 42717, - 42871, 42784, 42534, 42686, 42554, 1954, 2006, 1890, 1954, 2041, 2006, 2006, 2041, - 2093, 4161, 4229, 4098, 4161, 4314, 4229, 4243, 4263, 4314, 4314, 4263, 4361, - 1954, 1890, 1837, 38626, 38154, 37643, 39862, 39415, 39657, 43317, 42818, 43012, 40652, - 40653, 40807, 1959, 1762, 1825, 2017, 1932, 1959, 2243, 2351, 2771, 2243, 2771, - 2289, 2771, 2317, 2289, 1837, 1918, 1646, 4088, 3981, 4268, 886, 862, 1113, - 1118, 1201, 1148, 42416, 42201, 42254, 43092, 43218, 43012, 43243, 43218, 43075, 43452, - 43151, 43457, 42686, 42770, 42614, 43036, 42770, 42686, 1646, 1918, 1693, 223, 27, - 103, 103, 27, 122, 104, 27, 223, 238, 247, 242, 43089, 43211, 42962, - 1112, 951, 1009, 40181, 40093, 39998, 40244, 40093, 40181, 40257, 40181, 40259, 40259, - 40310, 40345, 40230, 40413, 40419, 40419, 40554, 40533, 40124, 40232, 40230, 38503, 37845, - 37918, 40345, 40310, 40400, 40310, 40451, 40542, 1729, 1762, 1959, 40542, 40451, 40643, - 40521, 40413, 40230, 40643, 40451, 40653, 40643, 40653, 40652, 40413, 40554, 40419, 820, - 787, 862, 862, 787, 881, 42871, 42872, 42784, 42442, 42534, 42359, 42569, 42534, - 42442, 41421, 41054, 41404, 41924, 41601, 41744, 1118, 989, 1201, 1009, 989, 1118, - 40807, 40610, 40949, 43351, 43218, 43243, 43550, 43452, 43457, 43550, 43457, 43734, 5942, - 5859, 5841, 36149, 36168, 36048, 36382, 36437, 36453, 37875, 37045, 37762, 36300, 36168, - 36149, 2464, 2474, 2460, 1932, 1729, 1959, 40949, 40610, 41015, 35571, 35605, 35622, - 35805, 35438, 35797, 4361, 4263, 4491, 5238, 5390, 5318, 3956, 4098, 4067, 38205, - 38503, 37918, 37880, 37918, 37878, 5238, 5291, 4789, 36168, 36437, 36382, 42871, 42717, - 42770, 37875, 37930, 38003, 2243, 2140, 2351, 3981, 3632, 3950, 3475, 3632, 3981, - 4088, 4268, 4339, 41028, 40949, 41015, 7308, 6896, 7053, 6556, 6313, 6485, 35571, - 35414, 35438, 820, 754, 787, 787, 754, 881, 42471, 42675, 42630, 43021, 42871, - 43036, 41177, 41015, 41067, 42871, 42770, 43036, 37880, 38049, 37918, 37883, 37875, 38003, - 120, 238, 369, 3252, 3878, 3424, 2954, 2840, 2509, 2093, 2041, 2059, 754, - 518, 740, 989, 886, 1113, 819, 886, 776, 1064, 951, 1112, 1078, 1086, - 1317, 1144, 1693, 1386, 805, 997, 802, 43351, 43243, 43364, 42080, 42095, 41767, - 35605, 35571, 35438, 35622, 35605, 35805, 3835, 3956, 4067, 4789, 5291, 4801, 1619, - 1697, 1762, 42169, 42658, 42476, 41129, 40949, 41028, 38603, 38154, 38626, 38995, 38626, - 38885, 43903, 43856, 43655, 43452, 43485, 43364, 2059, 2041, 1892, 3835, 3851, 3956, - 1821, 1729, 1932, 38503, 38780, 38686, 38720, 38780, 38503, 40413, 40521, 40554, 42577, - 40308, 40533, 40092, 40232, 40124, 40145, 40232, 40092, 886, 820, 862, 819, 820, - 886, 4665, 4491, 4551, 3024, 3222, 3218, 120, 104, 238, 238, 104, 223, - 6422, 6313, 6556, 5634, 5236, 5228, 3895, 4088, 4339, 40093, 40202, 39657, 40244, - 40202, 40093, 40244, 40181, 40257, 40400, 40516, 40345, 40542, 40516, 40400, 40643, 40516, - 40542, 40687, 40516, 40643, 40787, 40643, 40652, 40787, 40652, 40807, 40787, 40807, 40949, - 40787, 40949, 40916, 6313, 6057, 6286, 1892, 2041, 1849, 1086, 1386, 1317, 4011, - 4161, 4098, 3973, 4098, 3956, 5942, 5932, 6111, 5505, 5841, 5681, 4161, 4243, - 4314, 4011, 4243, 4161, 2243, 2197, 2140, 2140, 2002, 2351, 2464, 2771, 2474, - 41177, 41067, 41243, 37883, 38049, 37880, 37883, 37880, 37875, 41193, 41177, 41243, 42450, - 42692, 42658, 39138, 39246, 38686, 39138, 38686, 39081, 2197, 2072, 2140, 1009, 1118, - 1112, 79, 16, 340, 43218, 43317, 43012, 43734, 43457, 43655, 43485, 43351, 43364, - 38049, 38205, 37918, 38049, 37883, 38003, 6313, 6203, 6057, 6896, 6652, 6687, 35571, - 35622, 35414, 35797, 35951, 36257, 2072, 2002, 2140, 2041, 1954, 1849, 5841, 5932, - 5942, 6065, 6457, 6460, 5861, 5932, 5841, 37834, 37643, 37811, 42416, 42471, 42442, - 42871, 43021, 42872, 42586, 42471, 42630, 42095, 42080, 42259, 418, 518, 754, 733, - 754, 820, 886, 989, 948, 42707, 42686, 42534, 43666, 43653, 43211, 3418, 3851, - 3835, 5187, 5505, 5238, 1484, 1129, 1064, 878, 773, 1078, 1849, 1954, 1837, - 59, 805, 802, 42471, 42569, 42442, 42586, 42569, 42471, 43570, 43485, 43452, 43351, - 43264, 43218, 43570, 43452, 43550, 6065, 6460, 6111, 6460, 6457, 6850, 36454, 36179, - 36525, 35398, 35789, 35643, 36661, 36742, 36437, 38182, 38147, 38131, 43371, 43211, 43089, - 43541, 43862, 43252, 5932, 5997, 6111, 5238, 5505, 5390, 4801, 4665, 4637, 3851, - 3973, 3956, 43353, 43264, 43351, 1691, 1762, 1729, 40232, 40521, 40230, 40041, 40119, - 39438, 40244, 40257, 40350, 40257, 40345, 40350, 40345, 40632, 40350, 40119, 40145, 40092, - 38147, 38205, 38049, 40340, 40298, 40119, 38147, 38049, 38003, 3222, 3252, 3424, 3851, - 3418, 3973, 2900, 3024, 3218, 2886, 3024, 2900, 40504, 40444, 40364, 40345, 40516, - 40632, 43021, 43138, 42872, 43188, 43138, 43197, 1744, 1691, 1729, 2771, 2543, 2474, - 4673, 4713, 5228, 3603, 4011, 3973, 3973, 4011, 4098, 2289, 2197, 2243, 1916, - 1877, 2002, 2002, 1821, 1932, 3151, 2543, 2771, 40421, 40521, 40232, 2464, 2317, - 2771, 38627, 38720, 38503, 37493, 37045, 36857, 38456, 38503, 38205, 1009, 948, 989, - 93, 369, 518, 913, 948, 1009, 43504, 43353, 43351, 43617, 43570, 43550, 43504, - 43351, 43485, 42658, 42692, 42700, 43771, 43734, 43655, 2317, 2197, 2289, 5779, 5861, - 5841, 5800, 5861, 5779, 43138, 43223, 43089, 43188, 43223, 43138, 42462, 42095, 42259, - 41177, 41193, 41028, 42476, 42259, 42353, 43820, 43862, 43653, 43653, 43862, 43541, 42692, - 42921, 42700, 2059, 2509, 2840, 1849, 1837, 1713, 41243, 41067, 41513, 877, 1086, - 1078, 773, 878, 805, 4491, 4263, 4551, 93, 120, 369, 104, 100, 27, - 733, 820, 819, 6057, 5708, 5634, 6652, 6422, 6556, 948, 776, 886, 853, - 776, 948, 743, 773, 805, 951, 913, 1009, 1877, 1821, 2002, 1713, 1837, - 1646, 41513, 41067, 41421, 42569, 42605, 42534, 40868, 40533, 40554, 4760, 4789, 4801, - 4708, 4789, 4760, 42095, 41924, 41744, 41404, 41900, 41775, 1467, 1713, 1646, 3024, - 2968, 3222, 4551, 4263, 4243, 2701, 2886, 2900, 2509, 2232, 2343, 2059, 1892, - 1859, 776, 733, 819, 769, 733, 776, 4789, 5187, 5238, 42692, 43106, 42921, - 42476, 42462, 42259, 42707, 42605, 42630, 42586, 42605, 42569, 40350, 40364, 40244, 40244, - 40314, 40202, 39862, 39100, 39415, 40916, 40643, 40787, 40916, 40949, 41129, 37152, 37093, - 36525, 37147, 37093, 37152, 36925, 37093, 37199, 6422, 6203, 6313, 43353, 43317, 43264, - 43570, 43558, 43485, 43617, 43558, 43570, 1859, 1892, 1849, 43734, 43704, 43550, 43771, - 43704, 43734, 1619, 1762, 1691, 5800, 5997, 5932, 5800, 5932, 5861, 38147, 38182, - 38205, 38720, 38870, 38780, 38003, 38189, 38131, 1916, 2002, 2072, 2061, 1916, 2197, - 2464, 2460, 2317, 3151, 3314, 3042, 1608, 1619, 1691, 1744, 1729, 1821, 41651, - 41513, 41421, 41129, 41028, 41193, 36824, 36689, 36525, 43197, 43138, 43021, 43223, 43267, - 43089, 40521, 40868, 40554, 40736, 40868, 40521, 40298, 40232, 40145, 40298, 40145, 40119, - 41129, 41193, 41265, 913, 853, 948, 475, 418, 754, 888, 853, 913, 37093, - 36925, 36525, 36824, 36925, 36991, 42707, 43036, 42686, 43704, 43617, 43550, 43558, 43504, - 43485, 41265, 41193, 41243, 43856, 43771, 43655, 43677, 43642, 43617, 4708, 4637, 4551, - 4789, 4970, 5187, 5779, 5841, 5430, 38496, 38456, 38205, 36860, 37493, 36857, 5841, - 5505, 5430, 43283, 43267, 43188, 43188, 43267, 43223, 38496, 38205, 38392, 656, 754, - 733, 1064, 1112, 1484, 1916, 2072, 2197, 36925, 36824, 36525, 36454, 35951, 36179, - 37147, 37152, 37320, 4637, 4708, 4760, 4712, 4708, 4619, 1877, 1744, 1821, 1713, - 1770, 1849, 1703, 1770, 1713, 968, 1386, 1086, 41651, 41775, 41686, 41419, 41366, - 41556, 41513, 41366, 41243, 93, 100, 120, 120, 100, 104, 36454, 36525, 36689, - 35805, 35811, 35622, 43642, 43558, 43617, 43642, 43504, 43558, 43371, 43666, 43211, 771, - 769, 776, 771, 776, 853, 36583, 36454, 36689, 37834, 37811, 38154, 36709, 36689, - 36824, 38872, 38870, 38720, 1717, 1697, 1310, 2886, 2968, 3024, 2556, 2701, 2900, - 2806, 2701, 2757, 40455, 40298, 40340, 5733, 5708, 6057, 36876, 36709, 36824, 2903, - 2968, 2886, 40298, 40421, 40232, 42630, 42605, 42586, 2061, 2197, 1977, 1877, 1761, - 1744, 3175, 3314, 3632, 2993, 2921, 3042, 3175, 2993, 3042, 39976, 39657, 40202, - 40687, 40632, 40516, 40687, 40643, 40953, 40687, 40779, 40705, 769, 656, 733, 418, - 93, 518, 624, 656, 769, 3140, 3252, 3222, 40643, 40916, 40953, 42658, 42700, - 42476, 43317, 43218, 43264, 43197, 43283, 43188, 43267, 43371, 43089, 42605, 42707, 42534, - 42416, 42254, 42675, 830, 888, 951, 951, 888, 913, 41603, 41651, 41686, 41366, - 41265, 41243, 6203, 6103, 6057, 6422, 6252, 6203, 6236, 6252, 6422, 6490, 6422, - 6652, 43700, 43317, 43353, 43790, 43617, 43704, 6896, 6490, 6652, 36556, 36257, 36454, - 36279, 35811, 36257, 36257, 35811, 35805, 35622, 35811, 35414, 43876, 43790, 43771, 43771, - 43790, 43704, 5800, 5925, 5997, 5997, 6065, 6111, 5430, 5505, 5103, 43416, 43317, - 43508, 43122, 43021, 43036, 39081, 38686, 38780, 38456, 38627, 38503, 38496, 38627, 38456, - 1310, 1697, 1619, 38003, 38131, 38147, 36860, 37425, 37493, 37199, 36991, 36925, 36814, - 36583, 36689, 36876, 36991, 37077, 43191, 43122, 43036, 1744, 1608, 1691, 2334, 2317, - 2460, 877, 968, 1086, 743, 1078, 773, 1770, 1859, 1849, 1703, 1859, 1770, - 39081, 38780, 38870, 41417, 41265, 41366, 43856, 43876, 43771, 43790, 43677, 43617, 43642, - 43677, 43504, 36556, 36583, 36814, 43406, 43371, 43283, 43283, 43371, 43267, 39019, 39081, - 38870, 38392, 38205, 38182, 888, 771, 853, 656, 586, 754, 830, 771, 888, - 42675, 42254, 42577, 43191, 43228, 43122, 43122, 43197, 43021, 1848, 1761, 1877, 624, - 769, 771, 38872, 38720, 38826, 43228, 43197, 43122, 4708, 4712, 4789, 4551, 4460, - 4601, 40314, 40244, 40364, 41556, 41366, 41513, 41556, 41513, 41603, 38313, 38392, 38182, - 38826, 38720, 38627, 38826, 38627, 38783, 41603, 41513, 41651, 3252, 3274, 3878, 2968, - 3140, 3222, 2701, 2806, 2886, 2556, 2900, 2509, 40444, 40314, 40364, 40364, 40350, - 40504, 40350, 40632, 40504, 40632, 40581, 40504, 40705, 40581, 40632, 2474, 2334, 2460, - 1916, 1848, 1877, 2695, 2543, 3151, 2559, 2556, 2536, 2806, 2903, 2886, 40687, - 40705, 40632, 6236, 6108, 6252, 6252, 6108, 6203, 2800, 2921, 2703, 40953, 40779, - 40687, 3175, 3042, 3314, 5236, 5634, 5708, 41038, 40953, 40916, 38603, 37834, 38154, - 36814, 36689, 36709, 38392, 38597, 38496, 38131, 38313, 38182, 38342, 38313, 38372, 2379, - 2334, 2474, 2903, 3140, 2968, 41129, 41038, 40916, 40738, 40736, 40521, 40738, 40521, - 40421, 40455, 40421, 40298, 39871, 40023, 40041, 39871, 40041, 39438, 41129, 41200, 41038, - 41421, 41404, 41775, 41265, 41200, 41129, 41265, 41318, 41200, 624, 586, 656, 925, - 951, 1064, 41366, 41419, 41417, 41404, 41924, 41900, 41924, 42267, 41900, 41419, 41556, - 41417, 36860, 36743, 37425, 1977, 2197, 2317, 1275, 1310, 1619, 6108, 6103, 6203, - 6490, 6236, 6422, 43763, 43677, 43790, 43190, 42692, 42818, 16, 86, 1005, 41417, - 41556, 41501, 41900, 42357, 41945, 41556, 41603, 41720, 4551, 4412, 4460, 4712, 4970, - 4789, 43190, 42818, 43317, 1945, 1848, 1916, 613, 743, 397, 1467, 1703, 1713, - 42630, 42749, 42707, 42807, 42675, 42577, 1608, 1744, 1761, 41720, 41603, 41686, 41924, - 42095, 42267, 43197, 43331, 43283, 43850, 43820, 43666, 43191, 43036, 42707, 1033, 925, - 1064, 4551, 4619, 4708, 4601, 4619, 4551, 2536, 2556, 2509, 1010, 1386, 968, - 41720, 41686, 41945, 6055, 6103, 6108, 5925, 5800, 5779, 5925, 6065, 5997, 35789, - 36300, 36149, 42675, 42749, 42630, 42807, 42749, 42675, 36583, 36556, 36454, 36876, 36824, - 36991, 1583, 1608, 1761, 1310, 1129, 1484, 743, 877, 1078, 968, 877, 806, - 37762, 37930, 37875, 38313, 38342, 38392, 37790, 37930, 37762, 1223, 1129, 1310, 37199, - 37093, 37147, 38189, 38313, 38131, 40041, 40023, 40047, 43228, 43331, 43197, 43299, 43331, - 43228, 2800, 2695, 3151, 2315, 2291, 2334, 2334, 2291, 2317, 2061, 1945, 1916, - 1684, 1583, 1761, 2800, 3151, 3042, 3140, 3274, 3252, 2903, 2801, 3140, 2806, - 2801, 2903, 2617, 2757, 2701, 2559, 2701, 2556, 2536, 2509, 2410, 2695, 2800, - 2703, 2757, 2801, 2806, 40567, 40504, 40581, 40567, 40444, 40504, 40567, 40456, 40444, - 40444, 40456, 40314, 40314, 39976, 40202, 40567, 40581, 40722, 40581, 40705, 40722, 40705, - 40823, 40722, 40779, 40823, 40705, 41021, 40823, 40779, 40736, 40859, 40868, 39138, 39081, - 39197, 2410, 2509, 2343, 40953, 41021, 40779, 40455, 40560, 40421, 2509, 2091, 2232, - 40456, 39976, 40314, 37219, 37320, 37404, 39019, 38870, 38872, 1608, 1511, 1619, 1526, - 1511, 1608, 1883, 2059, 1859, 39976, 39862, 39657, 40953, 41038, 41021, 40560, 40738, - 40421, 586, 475, 754, 674, 624, 771, 830, 951, 925, 36742, 36590, 36437, - 42947, 42796, 42749, 42749, 42796, 42707, 2457, 2474, 2543, 41139, 41038, 41200, 40738, - 40859, 40736, 5103, 5505, 5187, 37320, 37199, 37147, 37320, 37152, 37834, 1129, 1045, - 1064, 1095, 1045, 1129, 803, 830, 925, 38597, 38627, 38496, 41945, 41686, 41775, - 41233, 41139, 41200, 41945, 41775, 41900, 43850, 43666, 43371, 43666, 43820, 43653, 5662, - 5925, 5779, 2960, 3274, 3140, 36876, 36814, 36709, 36866, 36814, 36876, 36661, 36437, - 36168, 43331, 43406, 43283, 43431, 43406, 43331, 2291, 1977, 2317, 41318, 41265, 41417, - 1045, 1033, 1064, 1029, 1033, 1045, 1275, 1619, 1295, 38501, 38597, 38392, 38228, - 38189, 38003, 38372, 38189, 38229, 1977, 1945, 2061, 42462, 42476, 43030, 43300, 43190, - 43317, 1794, 1883, 1859, 1794, 1859, 1703, 1295, 1619, 1511, 43677, 43881, 43504, - 43876, 43763, 43790, 1650, 1794, 1703, 41501, 41318, 41417, 36300, 36661, 36168, 36742, - 37031, 36743, 38372, 38313, 38189, 37199, 37139, 36991, 37139, 37320, 37219, 1275, 1223, - 1310, 1228, 1223, 1275, 38965, 39019, 38872, 38501, 38392, 38342, 38501, 38342, 38372, - 830, 674, 771, 624, 475, 586, 670, 674, 830, 670, 830, 803, 4530, - 4970, 4712, 5430, 5453, 5779, 4601, 4712, 4619, 1526, 1583, 1435, 38965, 38872, - 38826, 38003, 37930, 38228, 39029, 38965, 38826, 6103, 5733, 6057, 6236, 6055, 6108, - 6049, 6055, 6236, 38645, 38627, 38597, 2695, 2669, 2543, 2291, 1974, 1977, 1977, - 1967, 1945, 1945, 1819, 1848, 2703, 2669, 2695, 2800, 3042, 2921, 2759, 2960, - 3140, 2757, 2617, 2801, 2559, 2617, 2701, 2477, 2617, 2559, 2477, 2559, 2536, - 2477, 2536, 2424, 2536, 2410, 2424, 2410, 2343, 2354, 40738, 40847, 40859, 43212, - 43191, 42796, 40560, 40592, 40738, 40455, 40552, 40560, 40191, 40340, 40119, 40191, 40119, - 40041, 40191, 40041, 40047, 43190, 43106, 42692, 41233, 41200, 41376, 43300, 43106, 43190, - 2509, 2059, 2091, 39805, 39871, 39438, 40500, 40552, 40455, 2395, 2457, 2543, 39246, - 39805, 39438, 2457, 2379, 2474, 39197, 39081, 39019, 1087, 1095, 1129, 1087, 1129, - 1223, 38547, 38645, 38597, 37790, 37762, 37658, 2379, 2315, 2334, 2091, 2059, 1883, - 40722, 40616, 40567, 40567, 40616, 40456, 40456, 40654, 39976, 39976, 39999, 39862, 40823, - 40864, 40722, 41036, 40864, 40823, 41021, 41038, 41071, 41071, 41038, 41139, 41071, 41139, - 41233, 4970, 5103, 5187, 5055, 5103, 4970, 783, 1010, 968, 1794, 1803, 1883, - 806, 877, 712, 41501, 41556, 41713, 37320, 37139, 37199, 37077, 37139, 37219, 42796, - 43191, 42707, 43406, 43699, 43371, 43299, 43358, 43463, 37658, 37762, 37493, 1974, 1967, - 1977, 1376, 1295, 1511, 1526, 1608, 1583, 42476, 42700, 43030, 36661, 36759, 36742, - 36806, 36759, 36661, 38001, 38228, 37930, 38547, 38597, 38501, 460, 475, 624, 530, - 624, 674, 925, 841, 803, 925, 1033, 841, 38965, 39197, 39019, 38547, 38501, - 38608, 37139, 37077, 36991, 36645, 36279, 36556, 36556, 36279, 36257, 38603, 38626, 38995, - 37063, 37031, 36742, 37790, 38001, 37930, 43176, 42700, 42921, 43416, 43300, 43317, 43191, - 43299, 43228, 40533, 42246, 42577, 1491, 1650, 1703, 4243, 3603, 4551, 4551, 3603, - 4412, 43176, 42921, 43106, 39432, 38603, 38995, 39999, 39100, 39862, 38608, 38501, 38372, - 39257, 39197, 38965, 38229, 38189, 38228, 38783, 38627, 38645, 41852, 41720, 41945, 41852, - 41556, 41720, 173, 93, 418, 5315, 5236, 5708, 1684, 1761, 1848, 1029, 1045, - 1095, 1087, 1223, 1098, 412, 423, 475, 330, 173, 418, 1144, 1467, 1646, - 712, 877, 743, 38083, 38001, 38075, 423, 418, 475, 1228, 1275, 1295, 2669, - 2497, 2543, 2107, 2185, 2379, 2379, 2185, 2315, 2315, 2185, 2291, 1967, 1819, - 1945, 3175, 3069, 2993, 40552, 40592, 40560, 40340, 40500, 40455, 40469, 40500, 40340, - 40469, 40340, 40191, 40213, 40191, 40047, 40055, 40047, 40023, 2354, 2424, 2410, 2477, - 2424, 2617, 3121, 3418, 3274, 2354, 2343, 2232, 40869, 40616, 40722, 40869, 40722, - 40864, 40869, 40864, 41036, 40823, 41021, 41036, 40500, 40592, 40552, 2083, 2354, 2232, - 1144, 1386, 1102, 2091, 1894, 2010, 2779, 2921, 2882, 39871, 40055, 40023, 41036, - 41021, 41088, 40592, 40847, 40738, 2370, 2379, 2457, 39805, 39246, 39709, 5811, 5733, - 6103, 6490, 6049, 6236, 36866, 36556, 36814, 1087, 1029, 1095, 949, 1029, 1087, - 42462, 42267, 42095, 41945, 42357, 41981, 1803, 1794, 1710, 39709, 39246, 39138, 1526, - 1376, 1511, 1354, 1376, 1526, 41804, 41852, 41968, 41376, 41200, 41318, 37052, 36866, - 37077, 37077, 36866, 36876, 43463, 43431, 43331, 43463, 43331, 43299, 38220, 38229, 38228, - 38700, 38783, 38645, 39855, 39856, 39805, 38220, 38228, 38001, 1831, 1819, 1967, 41376, - 41318, 41533, 613, 712, 743, 1102, 1386, 1010, 5453, 5386, 5295, 5037, 5386, - 5430, 5925, 5720, 6065, 1710, 1794, 1650, 1710, 1650, 1491, 41533, 41318, 41501, - 1304, 1228, 1376, 1376, 1228, 1295, 38700, 38645, 38547, 43763, 43881, 43677, 43300, - 43176, 43106, 43876, 43881, 43763, 4601, 4530, 4712, 3418, 3835, 3274, 38608, 38700, - 38547, 38083, 38220, 38001, 1819, 1684, 1848, 1640, 1710, 1491, 5453, 5662, 5779, - 841, 1033, 1029, 530, 670, 511, 530, 674, 670, 173, 66, 93, 37031, - 37425, 36743, 37272, 37425, 37031, 42912, 42807, 42966, 1228, 1121, 1223, 1019, 1121, - 1031, 1102, 1010, 1032, 40055, 39871, 40164, 38371, 38372, 38229, 5386, 5453, 5430, - 5493, 5453, 5295, 38220, 38371, 38229, 38075, 38001, 38019, 1121, 1098, 1223, 949, - 1098, 1019, 1491, 1703, 1467, 783, 968, 806, 511, 670, 568, 37680, 37658, - 37493, 42807, 42947, 42749, 42912, 42947, 42807, 41852, 41713, 41556, 41804, 41713, 41852, - 2675, 2703, 2599, 5811, 6103, 6055, 36866, 36645, 36556, 36772, 36645, 36866, 41521, - 40868, 40859, 40592, 40740, 40847, 40641, 40740, 40592, 40213, 40469, 40191, 40213, 40047, - 40176, 40047, 40055, 40176, 40055, 40164, 40176, 2675, 2497, 2669, 2185, 2129, 2291, - 1819, 1789, 1684, 2675, 2669, 2703, 2703, 2921, 2779, 3103, 3069, 3175, 2497, - 2395, 2543, 39871, 39805, 39856, 2395, 2370, 2457, 3981, 4088, 3475, 39138, 39467, - 39709, 40869, 40764, 40616, 40654, 39999, 39976, 40768, 40764, 40869, 41021, 41071, 41088, - 41071, 41201, 41088, 40641, 40592, 40500, 43508, 43317, 43700, 41968, 41852, 41945, 43699, - 43850, 43371, 43358, 43299, 43191, 4339, 4291, 3895, 40654, 40456, 40616, 41071, 41233, - 41201, 41968, 41945, 41981, 2107, 2129, 2185, 1435, 1354, 1526, 3140, 2801, 2759, - 2354, 2083, 2424, 2091, 2104, 2232, 2010, 2104, 2091, 2091, 1883, 1894, 1883, - 1803, 1894, 39138, 39197, 39467, 41233, 41259, 41201, 2129, 1974, 2291, 1894, 1803, - 1751, 41233, 41355, 41259, 530, 460, 624, 423, 330, 418, 434, 460, 449, - 43004, 43010, 42947, 42947, 43010, 42796, 38177, 38371, 38220, 38784, 38826, 38783, 38177, - 38220, 38083, 41533, 41501, 41705, 41938, 41968, 41981, 37404, 37910, 37783, 37052, 37219, - 37404, 38019, 38001, 37790, 37572, 37680, 37493, 37063, 37272, 37031, 1640, 1803, 1710, - 38784, 38783, 38771, 41533, 41573, 41544, 6049, 5811, 6055, 5022, 4673, 5236, 1974, - 1831, 1967, 38771, 38783, 38700, 86, 59, 802, 712, 687, 806, 949, 841, - 1029, 949, 1087, 1098, 460, 412, 475, 434, 412, 460, 397, 743, 805, - 1101, 1467, 1144, 1081, 1144, 1102, 2485, 2617, 2424, 39257, 39467, 39197, 4673, - 5228, 5236, 41808, 41713, 41804, 687, 783, 806, 4460, 4503, 4601, 4412, 4503, - 4460, 1032, 1081, 1102, 1472, 1491, 1268, 39029, 39257, 38965, 5493, 5720, 5662, - 5662, 5720, 5925, 5493, 5662, 5453, 36759, 37063, 36742, 37272, 37432, 37425, 36300, - 36806, 36661, 412, 330, 423, 434, 330, 412, 37544, 37432, 37435, 38480, 38608, - 38372, 38922, 39029, 38826, 40928, 40859, 40847, 43010, 43212, 42796, 43115, 43212, 43010, - 4503, 4530, 4601, 4524, 4530, 4503, 5055, 5430, 5103, 37320, 37910, 37404, 37219, - 37052, 37077, 36806, 37063, 36759, 38019, 37790, 37936, 38480, 38372, 38371, 40740, 40928, - 40847, 40469, 40641, 40500, 40537, 40641, 40469, 40537, 40469, 40213, 40264, 40213, 40176, - 40264, 40176, 40164, 39871, 39974, 40164, 39856, 39974, 39871, 39856, 39855, 39974, 1435, - 1583, 1684, 449, 460, 530, 39805, 39709, 39855, 38922, 38826, 38784, 39709, 39870, - 39855, 40764, 40935, 40616, 40969, 40768, 40869, 40969, 40869, 41036, 40969, 41036, 41102, - 41036, 41088, 41102, 37572, 37493, 37425, 37572, 37425, 37544, 43115, 43004, 43085, 42912, - 43004, 42947, 2993, 2882, 2921, 2779, 2599, 2703, 2675, 2434, 2497, 2107, 2370, - 2062, 1966, 2107, 2062, 2370, 2107, 2379, 2129, 2043, 1974, 1974, 1964, 1831, - 1831, 1789, 1819, 2858, 2882, 2993, 41102, 41088, 41172, 40931, 40928, 40740, 37231, - 37404, 37694, 43431, 43463, 43638, 43699, 43431, 43638, 43699, 43406, 43431, 2434, 2395, - 2497, 39709, 39467, 39495, 1019, 1098, 1121, 38771, 38922, 38784, 38533, 38480, 38371, - 38177, 38083, 38075, 43358, 43191, 43212, 613, 687, 712, 1032, 1101, 1081, 397, - 687, 613, 37936, 37790, 37658, 1354, 1304, 1376, 1240, 1304, 1354, 2107, 2043, - 2129, 2104, 2083, 2232, 2010, 1980, 2104, 1862, 1980, 2010, 1862, 2010, 1894, - 1751, 1803, 1640, 3103, 3175, 3632, 39495, 39467, 39506, 41172, 41088, 41201, 41968, - 41938, 41804, 41408, 41233, 41376, 41981, 42114, 42052, 2043, 1964, 1974, 3221, 3103, - 3632, 43416, 43508, 43300, 43700, 43353, 43504, 3475, 3221, 3632, 3300, 3221, 3475, - 41408, 41376, 41544, 39506, 39467, 39257, 38771, 38700, 38608, 41544, 41376, 41533, 41981, - 42335, 42114, 790, 803, 841, 4750, 5055, 4970, 37876, 37936, 37658, 37544, 37425, - 37432, 38776, 38771, 38608, 38071, 38177, 38075, 37981, 37936, 38008, 1964, 1789, 1831, - 1727, 1751, 1695, 1751, 1640, 1695, 1101, 1144, 1081, 43302, 43358, 43212, 39506, - 39257, 39455, 41501, 41713, 41808, 949, 790, 841, 765, 790, 949, 1121, 1228, - 1111, 4979, 5037, 5055, 3603, 4243, 4011, 43699, 43883, 43850, 43598, 43638, 43463, - 41808, 41804, 41938, 37981, 38019, 37936, 37435, 37432, 37272, 37435, 37272, 37330, 43461, - 43176, 43300, 1032, 1010, 783, 38922, 39006, 39029, 38557, 38608, 38480, 38075, 38019, - 38071, 4412, 4524, 4503, 4432, 4524, 4412, 38071, 38019, 37981, 1261, 1435, 1684, - 1111, 1228, 1304, 1695, 1640, 1596, 998, 1032, 563, 37658, 37680, 37876, 37330, - 37272, 37312, 43729, 43684, 43638, 43322, 43302, 43212, 43115, 43010, 43004, 43816, 43700, - 43504, 43142, 43148, 43156, 41847, 41808, 41884, 41705, 41808, 41847, 42246, 40533, 40868, - 40641, 40839, 40740, 40264, 40537, 40213, 40418, 40537, 40264, 40300, 40264, 40164, 40300, - 40164, 40254, 40164, 39974, 40102, 2799, 2599, 2882, 2882, 2599, 2779, 2107, 1966, - 2043, 2043, 1966, 1964, 1964, 1634, 1789, 1789, 1634, 1684, 2858, 2993, 3069, - 2858, 3069, 2998, 38533, 38557, 38480, 37680, 37572, 37730, 40102, 40246, 40254, 40102, - 39974, 39855, 40742, 40839, 40641, 38776, 38557, 38842, 39049, 39006, 38955, 40839, 40931, - 40740, 39870, 39709, 39739, 42966, 43004, 42912, 41355, 41233, 41456, 41268, 41172, 41259, - 41259, 41172, 41201, 41102, 41285, 40969, 40969, 40935, 40768, 40768, 40935, 40764, 39999, - 39432, 38995, 41233, 41408, 41456, 37571, 37572, 37544, 37312, 37272, 37063, 38791, 38922, - 38771, 5315, 5708, 5733, 3087, 3069, 3103, 39049, 39146, 39006, 38071, 38096, 38177, - 37571, 37544, 37435, 1980, 2083, 2104, 4979, 4572, 4879, 1751, 1727, 1894, 1640, - 1491, 1596, 41456, 41408, 41566, 4291, 4339, 4713, 1596, 1472, 1612, 3318, 3300, - 3475, 41566, 41408, 41544, 41521, 40859, 40928, 4750, 4970, 4530, 5055, 5037, 5430, - 5493, 5435, 5720, 37700, 37671, 37776, 4486, 4750, 4530, 3603, 3973, 3418, 1491, - 1467, 1268, 39146, 39257, 39029, 5037, 5295, 5386, 37496, 37571, 37435, 37204, 37312, - 37063, 1019, 931, 949, 568, 670, 803, 1020, 1111, 929, 1111, 1304, 1117, - 41705, 41501, 41808, 41705, 41573, 41533, 1111, 1031, 1121, 1020, 1031, 1111, 1032, - 998, 1101, 470, 1032, 783, 621, 783, 687, 43638, 43684, 43699, 43503, 43463, - 43358, 43469, 43358, 43302, 43322, 43212, 43115, 41808, 41938, 41884, 43276, 43322, 43115, - 182, 66, 330, 330, 66, 173, 707, 803, 790, 37730, 37572, 37700, 37730, - 37876, 37680, 37981, 38096, 38071, 39006, 39146, 39029, 43087, 42966, 42807, 315, 330, - 434, 5295, 5435, 5493, 5202, 5435, 5295, 5202, 5295, 5037, 37700, 37572, 37571, - 36806, 37204, 37063, 43469, 43503, 43358, 41884, 41938, 42052, 765, 707, 790, 43203, - 43087, 43217, 41260, 41258, 40931, 40537, 40742, 40641, 40596, 40742, 40537, 40418, 40264, - 40300, 40254, 40164, 40102, 3568, 3621, 3895, 3895, 3621, 4088, 38791, 38771, 38776, - 39981, 40102, 39855, 42267, 42357, 41900, 42052, 41938, 41981, 41355, 41345, 41268, 41268, - 41345, 41212, 41268, 41259, 41355, 41212, 41102, 41172, 41026, 40935, 41061, 41544, 41573, - 41566, 41573, 41747, 41566, 511, 449, 530, 318, 449, 511, 38008, 38096, 37981, - 37435, 37330, 37496, 43276, 43085, 43324, 42966, 43085, 43004, 43738, 43598, 43503, 1942, - 2083, 1980, 1862, 1894, 1779, 1894, 1727, 1779, 1727, 1635, 1779, 5811, 5654, - 5733, 4673, 4291, 4713, 6049, 5654, 5811, 37052, 36772, 36866, 36645, 36772, 36279, - 37231, 36772, 37052, 37231, 37052, 37404, 2062, 2370, 2009, 3087, 3103, 3221, 3087, - 3221, 3122, 38008, 37936, 37876, 41573, 41705, 41747, 42267, 42664, 42357, 2434, 2675, - 2599, 43469, 43302, 43419, 43503, 43598, 43463, 1727, 1695, 1635, 3122, 3221, 3190, - 41705, 41907, 41747, 1635, 1695, 1612, 3190, 3221, 3300, 449, 315, 434, 308, - 315, 262, 38134, 38008, 37942, 37328, 37330, 37312, 41747, 41907, 41722, 43030, 42700, - 43176, 3650, 4291, 3888, 3318, 3190, 3300, 765, 949, 727, 465, 568, 707, - 707, 568, 803, 38776, 38608, 38557, 38008, 37876, 37942, 43516, 43469, 43419, 1749, - 1634, 1964, 1612, 1695, 1596, 3318, 3191, 3261, 43700, 43875, 43508, 43881, 43816, - 43504, 1472, 1596, 1491, 3190, 3318, 3214, 931, 1019, 1031, 43738, 43729, 43598, - 43598, 43729, 43638, 43684, 43764, 43699, 41847, 41907, 41705, 5315, 5022, 5236, 43148, - 43030, 43176, 1240, 1354, 1435, 39323, 39455, 39257, 38557, 38533, 38842, 40620, 39432, - 39999, 39323, 39257, 39146, 41884, 42032, 41847, 41566, 41747, 41722, 39311, 39323, 39146, - 1020, 931, 1031, 727, 931, 789, 38533, 38177, 38096, 38955, 39006, 38922, 42691, - 42267, 42462, 33, 397, 805, 1268, 1467, 1071, 43761, 43764, 43729, 43729, 43764, - 43684, 2322, 2434, 2599, 1966, 1749, 1964, 1227, 1240, 1435, 2799, 2882, 2858, - 2998, 3069, 3087, 2998, 3087, 3122, 2998, 3122, 2808, 397, 621, 687, 39495, - 39506, 39739, 39709, 39495, 39739, 43087, 42807, 42577, 3206, 3603, 3418, 4750, 4979, - 5055, 3214, 3318, 3261, 3214, 3122, 3190, 2485, 2801, 2617, 2485, 2424, 2262, - 1942, 1980, 1862, 1692, 1862, 1779, 1692, 1779, 1635, 41355, 41456, 41506, 41345, - 41355, 41506, 41268, 41212, 41172, 40935, 41026, 40616, 41456, 41598, 41506, 39739, 39506, - 39601, 38955, 38922, 38791, 38939, 38955, 38791, 38008, 38134, 38096, 37942, 37876, 37730, - 37942, 37730, 37805, 1843, 1749, 1966, 39506, 39455, 39601, 41456, 41566, 41598, 43740, - 43738, 43503, 43516, 43503, 43469, 43276, 43115, 43085, 43085, 42966, 43324, 39601, 39455, - 39535, 38939, 38791, 38828, 3409, 3475, 3621, 3568, 3895, 3565, 39455, 39323, 39418, - 41598, 41566, 41722, 318, 315, 449, 315, 308, 330, 318, 511, 391, 651, - 707, 765, 4432, 4530, 4524, 43403, 43276, 43348, 59, 33, 805, 979, 998, - 779, 5435, 5284, 5720, 4979, 5202, 5037, 37204, 37328, 37312, 37261, 37328, 37204, - 43419, 43302, 43322, 39418, 39323, 39311, 42160, 42052, 42114, 39121, 39146, 39049, 38828, - 38791, 38776, 1557, 1692, 1635, 1467, 979, 1071, 672, 651, 765, 727, 949, - 931, 43054, 42691, 42462, 42357, 42335, 41981, 43054, 42462, 43030, 43764, 43883, 43699, - 43738, 43761, 43729, 43901, 43761, 43738, 39121, 39049, 39163, 38842, 38828, 38776, 38898, - 38828, 38842, 42584, 42335, 42357, 308, 182, 330, 188, 182, 308, 43516, 43740, - 43503, 43276, 43403, 43322, 40931, 40839, 41260, 37805, 37730, 37700, 43148, 43278, 43156, - 39049, 38955, 39163, 5202, 5284, 5435, 4987, 5284, 5202, 37776, 37805, 37700, 36806, - 37261, 37204, 4979, 4987, 5202, 4346, 4432, 4412, 4486, 4432, 4442, 1472, 1334, - 1437, 1467, 1101, 979, 40254, 40418, 40300, 40408, 40418, 40254, 39981, 39855, 39870, - 39981, 39870, 39886, 39870, 39739, 39886, 1261, 1684, 1634, 3409, 3568, 3497, 262, - 258, 188, 465, 511, 568, 37496, 37330, 37328, 38371, 38177, 38533, 41212, 41345, - 41390, 41285, 41212, 41390, 41285, 41102, 41212, 41061, 40935, 41192, 41345, 41413, 41390, - 37482, 37496, 37328, 43403, 43419, 43322, 43576, 43419, 43403, 1749, 1698, 1634, 2009, - 2370, 2395, 2009, 2395, 1999, 2799, 2858, 2894, 2858, 2998, 2894, 43761, 43883, - 43764, 43901, 43883, 43761, 2894, 2998, 2796, 4432, 4486, 4530, 4346, 4412, 4329, - 39706, 39739, 39601, 39069, 38955, 38939, 38898, 38939, 38828, 2062, 1843, 1966, 3114, - 3122, 3214, 41390, 41413, 41332, 39706, 39601, 39631, 41722, 41506, 41598, 318, 262, - 315, 465, 707, 490, 38096, 38134, 38533, 37671, 37700, 37571, 1843, 1698, 1749, - 1557, 1612, 1437, 1557, 1635, 1612, 929, 931, 1020, 672, 727, 709, 490, - 707, 651, 43142, 43054, 43030, 42377, 42306, 42335, 42335, 42306, 42114, 43142, 43030, - 43148, 1698, 1574, 1634, 2960, 3121, 3274, 2490, 3121, 2960, 42664, 42267, 42691, - 3191, 3318, 3475, 3121, 3206, 3418, 39535, 39455, 39418, 727, 672, 765, 929, - 1111, 1117, 37496, 37671, 37571, 38134, 37942, 37913, 37650, 37671, 37496, 41907, 41847, - 42032, 42618, 42664, 42764, 43148, 43176, 43278, 1117, 1304, 1240, 39414, 39535, 39418, - 37942, 37805, 37913, 39311, 39146, 39121, 4365, 4979, 4750, 4329, 4412, 3603, 42032, - 41884, 42160, 41884, 42052, 42160, 37913, 37805, 37813, 39414, 39311, 39367, 37813, 37805, - 37776, 42664, 42892, 42764, 43278, 43176, 43461, 39311, 39121, 39367, 42160, 42114, 42231, - 40418, 40596, 40537, 40408, 40596, 40418, 40408, 40254, 40246, 40102, 39981, 40246, 39981, - 40425, 40246, 4346, 4442, 4432, 4378, 4442, 4346, 2262, 2424, 2083, 3121, 2936, - 3206, 39631, 39601, 39535, 1698, 1504, 1574, 1079, 1117, 1240, 1843, 1777, 1698, - 2062, 1828, 1843, 1999, 2395, 2434, 2322, 2599, 2586, 2819, 2799, 2894, 41026, - 40654, 40616, 41192, 40935, 40969, 41192, 40969, 41285, 41192, 41285, 41277, 41285, 41332, - 41277, 41390, 41332, 41285, 41640, 41413, 41345, 42231, 42114, 42273, 1592, 1942, 1862, - 1592, 1862, 1692, 2485, 2759, 2801, 4378, 4329, 4273, 41337, 41277, 41332, 1880, - 1828, 2062, 2796, 2819, 2894, 41722, 41835, 41640, 43461, 43300, 43582, 42691, 43080, - 42892, 37671, 37813, 37776, 37261, 37482, 37328, 41986, 41907, 42032, 42584, 42664, 42618, - 465, 391, 511, 492, 490, 651, 592, 651, 672, 709, 727, 601, 1261, - 1634, 1574, 789, 931, 929, 39414, 39418, 39311, 38672, 38533, 38521, 38533, 38134, - 38521, 258, 262, 318, 262, 188, 308, 182, 30, 66, 391, 465, 490, - 1437, 1612, 1472, 1472, 1268, 1334, 3261, 3114, 3214, 3191, 3114, 3261, 3191, - 3475, 3409, 390, 391, 490, 41258, 40928, 40931, 43681, 43740, 43516, 1101, 998, - 979, 3409, 3621, 3568, 42160, 42097, 42032, 42424, 42377, 42335, 42584, 42357, 42664, - 709, 592, 672, 492, 592, 494, 4442, 4378, 4486, 4329, 4184, 4273, 39414, - 39631, 39535, 38955, 39069, 39163, 37633, 37650, 37496, 43054, 43142, 43215, 43582, 43300, - 43508, 1117, 974, 929, 1385, 1261, 1574, 43681, 43516, 43419, 1261, 1227, 1435, - 3565, 3895, 3650, 38939, 38898, 39069, 42231, 42097, 42160, 43142, 43156, 43215, 2242, - 2322, 2586, 2009, 1947, 2062, 1828, 1777, 1843, 1141, 1066, 1227, 2217, 2322, - 2242, 2796, 2998, 2808, 3122, 3114, 2808, 391, 258, 318, 354, 258, 391, - 390, 490, 492, 43087, 43324, 42966, 43203, 43324, 43087, 42114, 42306, 42273, 137, - 30, 188, 188, 30, 182, 37482, 37633, 37496, 37746, 37813, 37671, 39069, 38898, - 38989, 37656, 37633, 37482, 2035, 1999, 2434, 1999, 1947, 2009, 42273, 42306, 42398, - 43215, 43156, 43303, 1947, 1880, 2062, 39886, 39706, 39818, 39886, 39739, 39706, 40754, - 40813, 40596, 41260, 40839, 40742, 41337, 41247, 41277, 41277, 41247, 41192, 41192, 41276, - 41061, 41061, 41276, 41026, 41337, 41332, 41413, 40813, 40742, 40596, 1066, 1079, 1240, - 1066, 1240, 1227, 783, 621, 470, 3497, 3565, 3510, 3111, 3114, 3191, 4291, - 4673, 4473, 5654, 5315, 5733, 38292, 38135, 37910, 37320, 37834, 37910, 41345, 41506, - 41640, 42306, 42377, 42398, 1880, 1777, 1828, 3111, 3191, 3389, 41506, 41722, 41640, - 41722, 41907, 41956, 37746, 37671, 37650, 43495, 43348, 43324, 43324, 43348, 43276, 1079, - 974, 1117, 927, 974, 1079, 470, 621, 397, 39818, 39706, 39631, 38898, 38842, - 38989, 41956, 41907, 41986, 42398, 42377, 42424, 258, 137, 188, 492, 651, 592, - 42032, 42097, 41986, 40755, 40408, 40633, 38989, 38842, 38841, 41986, 42221, 41992, 42424, - 42335, 42584, 3389, 3191, 3409, 43461, 43421, 43278, 42631, 42424, 42584, 43816, 43875, - 43700, 38841, 38842, 38533, 37656, 37746, 37650, 43582, 43421, 43461, 1557, 1334, 1475, - 964, 1334, 1268, 1437, 1334, 1557, 1550, 1592, 1692, 2262, 2496, 2485, 2485, - 2496, 2759, 390, 354, 391, 365, 354, 390, 43303, 43156, 43278, 43217, 43087, - 43009, 974, 893, 929, 813, 893, 855, 39367, 39121, 39163, 38841, 38533, 38672, - 42631, 42584, 42618, 42097, 42289, 41986, 42231, 42273, 42289, 3497, 3568, 3565, 3427, - 3389, 3409, 42440, 42273, 42398, 893, 789, 929, 813, 789, 893, 354, 298, - 258, 185, 298, 354, 42892, 42664, 42691, 43361, 43303, 43278, 43361, 43278, 43421, - 43789, 43582, 43508, 601, 592, 709, 394, 470, 24, 1550, 1557, 1475, 4329, - 4378, 4346, 4273, 4184, 4323, 2490, 2960, 2759, 40754, 40596, 40408, 41258, 41521, - 40928, 40754, 40408, 40755, 39367, 39163, 39199, 38134, 37913, 38521, 39199, 39163, 39069, - 2262, 2083, 1942, 1179, 1227, 1261, 1880, 1675, 1777, 1947, 1955, 1880, 1999, - 1955, 1947, 2035, 1955, 1999, 2035, 2434, 2322, 2035, 2322, 2217, 2586, 2599, - 2799, 1627, 1698, 1777, 789, 601, 727, 2808, 3114, 2906, 3650, 3895, 4291, - 39199, 39069, 38989, 43530, 43361, 43421, 42691, 43054, 43080, 41400, 41413, 41661, 41400, - 41337, 41413, 41400, 41370, 41337, 41337, 41370, 41247, 41247, 41276, 41192, 41413, 41640, - 41751, 41260, 41356, 41258, 41835, 41722, 41956, 43054, 43215, 43214, 41992, 41956, 41986, - 41992, 41835, 41956, 1586, 1627, 1777, 1550, 1692, 1557, 1550, 1546, 1592, 41356, - 41521, 41258, 1627, 1504, 1698, 1550, 1475, 1546, 4473, 4673, 5022, 2975, 3111, - 3389, 39818, 39631, 39794, 39227, 39199, 38989, 126, 137, 258, 185, 258, 298, - 185, 235, 167, 692, 601, 789, 893, 974, 927, 39631, 39414, 39491, 4548, - 4473, 5022, 43203, 43284, 43324, 43622, 43681, 43419, 42870, 43087, 42577, 43576, 43403, - 43348, 43740, 43901, 43738, 1504, 1385, 1574, 39491, 39414, 39380, 42440, 42398, 42424, - 42683, 42440, 42424, 42631, 42618, 42764, 43250, 43215, 43303, 42246, 42870, 42577, 1385, - 1251, 1261, 33, 13, 397, 1325, 1465, 1475, 4365, 4750, 4486, 43284, 43203, - 43217, 43495, 43576, 43348, 43530, 43421, 43582, 43410, 43250, 43361, 43361, 43250, 43303, - 43271, 43284, 43217, 365, 390, 492, 927, 1079, 1066, 1251, 1179, 1261, 42289, - 42097, 42231, 4378, 4388, 4486, 4329, 3616, 4184, 1179, 1141, 1227, 39380, 39414, - 39367, 42524, 42289, 42273, 42839, 42631, 42764, 42812, 42764, 42892, 126, 185, 167, - 40813, 41260, 40742, 41356, 41575, 41521, 40754, 40952, 40813, 40398, 40408, 40246, 40398, - 40246, 40425, 39981, 40196, 40425, 4879, 4987, 4979, 4572, 4987, 4879, 37746, 38137, - 37813, 39227, 39367, 39199, 39416, 39380, 39367, 37633, 37656, 37650, 37261, 37656, 37482, - 43789, 43589, 43582, 42860, 42812, 42892, 43576, 43622, 43419, 43597, 43622, 43576, 1379, - 1266, 1385, 1385, 1266, 1251, 1251, 1229, 1179, 1179, 1166, 1141, 1379, 1385, - 1504, 1955, 1675, 1880, 3427, 3409, 3497, 3510, 3427, 3497, 3510, 3565, 3541, - 39894, 39886, 39818, 39227, 38989, 39083, 41521, 42246, 40868, 42257, 42246, 41521, 39894, - 39818, 39794, 41751, 41640, 41835, 41661, 41370, 41400, 41661, 41276, 41370, 41370, 41276, - 41247, 40952, 41260, 40813, 4273, 4388, 4378, 4323, 4388, 4273, 43690, 43901, 43681, - 43681, 43901, 43740, 3541, 3565, 3650, 2906, 3114, 3111, 1546, 1584, 1592, 1592, - 1584, 1942, 4184, 4110, 4234, 964, 1475, 1334, 3377, 3389, 3427, 185, 126, - 258, 137, 11, 30, 494, 592, 601, 1096, 1066, 1141, 952, 927, 1066, - 537, 494, 601, 3510, 3377, 3427, 3628, 3541, 3650, 43214, 43215, 43250, 42631, - 42683, 42424, 41929, 41751, 41835, 1475, 1465, 1546, 43622, 43690, 43681, 43597, 43690, - 43622, 43597, 43576, 43620, 43271, 43217, 43391, 43410, 43214, 43250, 563, 1032, 470, - 41929, 41835, 41992, 39794, 39631, 39491, 38521, 37913, 38554, 39593, 39794, 39491, 42690, - 42683, 42631, 42992, 42860, 42892, 43589, 43530, 43582, 43214, 43080, 43054, 1489, 1504, - 1627, 43009, 43087, 42870, 1266, 1229, 1251, 759, 813, 795, 759, 789, 813, - 43420, 43009, 43417, 855, 893, 927, 1229, 1166, 1179, 42920, 42812, 42860, 42690, - 42631, 42839, 43690, 43863, 43901, 43495, 43324, 43284, 43495, 43284, 43271, 3955, 3888, - 4291, 4964, 4548, 5022, 1166, 1096, 1141, 3350, 3510, 3541, 3350, 3377, 3510, - 375, 404, 494, 494, 404, 492, 24, 470, 397, 4388, 4365, 4486, 2490, - 2759, 2496, 43187, 43080, 43312, 2819, 2796, 2586, 2799, 2819, 2586, 1680, 1675, - 1955, 1266, 1214, 1229, 1229, 1214, 1166, 1166, 1067, 1096, 40796, 40952, 40754, - 41260, 41431, 41356, 43420, 43395, 43009, 40796, 40754, 40755, 40796, 40755, 40633, 2586, - 2796, 2686, 2097, 2262, 1942, 1527, 1942, 1584, 1536, 1584, 1546, 40633, 40408, - 40398, 40510, 40633, 40398, 40425, 40510, 40398, 1067, 1028, 1096, 1096, 1028, 1066, - 334, 365, 404, 42524, 42273, 42440, 42221, 42289, 42272, 2686, 2796, 2808, 126, - 11, 137, 365, 185, 354, 43620, 43495, 43682, 1847, 1955, 2035, 2635, 2686, - 2808, 537, 601, 692, 404, 365, 492, 1675, 1586, 1777, 1028, 952, 1066, - 875, 952, 1028, 1586, 1489, 1627, 1465, 1536, 1546, 1535, 1536, 1465, 1489, - 1409, 1504, 2975, 2906, 3111, 952, 855, 927, 875, 855, 952, 39083, 38989, - 38841, 39894, 40005, 39886, 39083, 38841, 38876, 692, 789, 759, 42992, 42920, 42860, - 42992, 42892, 43080, 1409, 1379, 1504, 2922, 2975, 3389, 2938, 2975, 2834, 43001, - 42992, 43095, 43589, 43688, 43530, 43875, 43789, 43508, 41751, 41661, 41413, 42221, 41929, - 41992, 42221, 41986, 42289, 42524, 42440, 42683, 43410, 43361, 43594, 1274, 1214, 1266, - 39593, 39491, 39380, 43597, 43863, 43690, 43495, 43620, 43576, 43863, 43620, 43682, 43594, - 43361, 43530, 39646, 39593, 39380, 38876, 38841, 38672, 537, 375, 494, 4, 11, - 167, 367, 375, 332, 692, 759, 698, 4323, 4365, 4388, 2936, 3603, 3206, - 38137, 37913, 37813, 1214, 1067, 1166, 39743, 39593, 39646, 42764, 42812, 42839, 795, - 813, 855, 42812, 42920, 42933, 42839, 42812, 42933, 2173, 2242, 2398, 2173, 2217, - 2242, 2173, 2067, 2217, 2217, 2067, 2035, 1675, 1555, 1586, 1555, 1464, 1489, - 1489, 1464, 1409, 1409, 1369, 1379, 1379, 1274, 1266, 1214, 1239, 1067, 2591, - 2586, 2686, 2591, 2686, 2635, 37834, 38292, 37910, 40654, 41026, 41276, 40784, 40930, - 40796, 40796, 40930, 40952, 41469, 41431, 41260, 43538, 43495, 43271, 40760, 40796, 40633, - 40760, 40633, 40510, 40005, 39894, 39794, 43789, 43688, 43589, 42933, 42920, 43001, 41692, - 40654, 41276, 41661, 41751, 41707, 41707, 41751, 42058, 42337, 42272, 42484, 1838, 1847, - 2035, 367, 334, 375, 375, 334, 404, 3955, 4291, 4473, 2635, 2808, 2770, - 38744, 38876, 38672, 39646, 39380, 39416, 42662, 42524, 42683, 42920, 42992, 43001, 1847, - 1680, 1955, 2808, 2906, 2770, 41469, 41260, 40952, 2938, 2906, 2975, 1536, 1535, - 1584, 4287, 4323, 4184, 1268, 1071, 964, 41751, 41929, 42105, 41431, 41575, 41356, - 235, 185, 365, 167, 11, 126, 5315, 4964, 5022, 3844, 3777, 3888, 37783, - 37694, 37404, 38101, 37694, 37783, 42992, 43080, 43095, 42576, 42524, 42662, 742, 875, - 1028, 692, 603, 537, 792, 875, 742, 1555, 1489, 1586, 779, 1071, 979, - 4287, 4365, 4323, 2490, 2496, 2066, 2834, 2975, 2922, 334, 235, 365, 875, - 795, 855, 792, 795, 875, 563, 779, 998, 42105, 41929, 42262, 42683, 42772, - 42662, 1369, 1274, 1379, 39938, 40005, 39794, 39743, 39794, 39593, 42683, 42690, 42772, - 43367, 43214, 43410, 37834, 38593, 38292, 43688, 43594, 43530, 43497, 43367, 43410, 43875, - 43853, 43789, 43789, 43773, 43688, 43688, 43773, 43594, 43187, 43095, 43080, 43008, 42839, - 42933, 795, 698, 759, 760, 698, 795, 39367, 39227, 39416, 39416, 39227, 39300, - 463, 375, 537, 505, 563, 470, 24, 317, 394, 43312, 43080, 43214, 43008, - 42933, 43001, 43312, 43214, 43367, 43312, 43363, 43291, 1521, 2097, 1942, 1527, 1584, - 1535, 1527, 1535, 1397, 2398, 2586, 2591, 2398, 2242, 2586, 1838, 1755, 1847, - 1617, 1555, 1680, 1680, 1555, 1675, 1464, 1369, 1409, 2571, 2591, 2635, 698, - 603, 692, 611, 603, 698, 3888, 3777, 3650, 2660, 2571, 2635, 3955, 4160, - 3963, 40930, 41131, 40952, 41985, 41521, 41575, 40556, 40760, 40510, 39981, 39886, 40196, - 39886, 40005, 40196, 43853, 43773, 43789, 2770, 2906, 2938, 40196, 40005, 40193, 1397, - 1535, 1465, 505, 470, 394, 4365, 4572, 4979, 4234, 4287, 4184, 43008, 43001, - 43095, 43312, 43367, 43497, 1755, 1680, 1847, 742, 1028, 1067, 1397, 1465, 1342, - 39938, 39794, 39743, 39300, 39227, 39083, 39300, 39650, 39608, 1527, 1397, 1427, 2660, - 2770, 2696, 41661, 41692, 41276, 42337, 42221, 42272, 42576, 42289, 42524, 1434, 1369, - 1464, 39938, 39743, 39822, 1239, 1214, 1274, 603, 463, 537, 39667, 39743, 39646, - 39479, 39300, 39608, 43008, 43095, 43274, 538, 463, 603, 1427, 1397, 1342, 317, - 505, 394, 43260, 43095, 43187, 1296, 1239, 1274, 742, 760, 792, 792, 760, - 795, 42484, 42272, 42289, 42772, 42690, 42853, 39667, 39646, 39733, 3777, 3628, 3650, - 3528, 3628, 3777, 42484, 42289, 42576, 42853, 42690, 42839, 41648, 41575, 41431, 41985, - 42257, 41521, 39489, 39646, 39416, 760, 611, 698, 693, 611, 760, 42484, 42576, - 42588, 43008, 42853, 42839, 42931, 42853, 43056, 43291, 43187, 43312, 13, 24, 397, - 317, 347, 505, 42576, 42662, 42712, 40760, 40784, 40796, 40556, 40784, 40760, 40556, - 40510, 40425, 40556, 40425, 40227, 40425, 40196, 40227, 1369, 1296, 1274, 510, 538, - 611, 1555, 1434, 1464, 1838, 2035, 2067, 1838, 2067, 1827, 2398, 2591, 2571, - 332, 375, 463, 332, 246, 367, 367, 246, 334, 43652, 43410, 43594, 2448, - 2398, 2571, 2660, 2635, 2770, 611, 538, 603, 742, 669, 646, 1755, 1617, - 1680, 40227, 40196, 40193, 3469, 3350, 3541, 40193, 40005, 40085, 39479, 39489, 39416, - 39615, 39489, 39479, 42712, 42662, 42772, 42712, 42772, 42931, 1427, 1521, 1527, 1527, - 1521, 1942, 4276, 4365, 4287, 1071, 734, 964, 779, 734, 1071, 4276, 4572, - 4365, 2496, 2262, 2066, 37910, 38101, 37783, 37834, 38603, 38593, 38603, 38652, 38593, - 37656, 38137, 37746, 38521, 38744, 38672, 1617, 1434, 1555, 559, 563, 222, 2696, - 2770, 2938, 43620, 43863, 43597, 43391, 43217, 43009, 2834, 2696, 2938, 3628, 3469, - 3541, 3528, 3469, 3628, 205, 235, 246, 246, 235, 334, 43395, 43391, 43009, - 2655, 2696, 2834, 40005, 39938, 40085, 1434, 1296, 1369, 40085, 39938, 40117, 39822, - 39743, 39667, 3844, 3955, 3963, 43773, 43741, 43594, 43291, 43260, 43187, 43718, 43741, - 43902, 43651, 43682, 43495, 43652, 43497, 43410, 348, 332, 463, 348, 463, 409, - 70, 347, 317, 38554, 38744, 38521, 39733, 39822, 39667, 559, 779, 563, 39733, - 39646, 39615, 38603, 39065, 38652, 43391, 43538, 43271, 43451, 43538, 43391, 39615, 39646, - 39489, 43363, 43260, 43291, 43363, 43312, 43491, 40784, 41131, 40930, 43644, 43651, 43538, - 41728, 41131, 41497, 40993, 40784, 40556, 40356, 40556, 40227, 40229, 40227, 40193, 40229, - 40193, 40085, 40229, 40085, 40356, 1434, 947, 1296, 1617, 1495, 1434, 1755, 1705, - 1617, 2004, 2067, 2173, 2004, 2173, 2052, 2567, 2571, 2660, 1838, 1745, 1755, - 742, 1067, 669, 41131, 41469, 40952, 40117, 39938, 39822, 39479, 39416, 39300, 43741, - 43652, 43594, 43538, 43651, 43495, 43682, 43821, 43863, 42821, 43417, 43009, 1347, 2097, - 1521, 2066, 2262, 2097, 1463, 1521, 1427, 41469, 41648, 41431, 4110, 3736, 4053, - 38603, 39432, 39653, 43491, 43312, 43497, 42609, 42337, 42484, 42870, 42821, 43009, 1342, - 1463, 1427, 39880, 39822, 39733, 39300, 39083, 39650, 1325, 1342, 1465, 2696, 2655, - 2660, 3389, 2978, 2922, 3377, 2978, 3389, 41648, 41783, 41575, 39690, 39733, 39615, - 43741, 43718, 43652, 43567, 43491, 43497, 43673, 43718, 43769, 693, 742, 646, 3955, - 3844, 3888, 3955, 4473, 4160, 4234, 4276, 4287, 4235, 4276, 4234, 43567, 43497, - 43652, 42772, 42853, 42931, 43395, 43451, 43391, 43644, 43451, 43712, 3377, 3250, 2978, - 41783, 41985, 41575, 3377, 3350, 3250, 2735, 2936, 3121, 41707, 41692, 41661, 42262, - 41929, 42221, 42262, 42221, 42381, 43008, 43056, 42853, 623, 693, 620, 742, 693, - 760, 43095, 43260, 43274, 257, 348, 409, 332, 205, 246, 3724, 3528, 3777, - 4160, 4473, 4205, 43476, 43260, 43363, 43626, 43567, 43652, 3724, 3777, 3844, 222, - 563, 505, 964, 1325, 1475, 222, 505, 347, 42712, 42588, 42576, 43476, 43363, - 43491, 38292, 38245, 38135, 38135, 38101, 37910, 38419, 38245, 38292, 38551, 38292, 38593, - 43451, 43644, 43538, 43651, 43672, 43682, 43680, 43644, 43712, 2567, 2655, 2517, 2567, - 2660, 2655, 1962, 2004, 2052, 1746, 1705, 1745, 1745, 1705, 1755, 39763, 39690, - 39615, 39763, 39615, 39479, 1746, 1745, 1838, 257, 332, 348, 203, 205, 332, - 235, 4, 167, 4125, 4160, 4205, 3818, 3724, 3844, 4053, 3744, 3953, 40620, - 39999, 40654, 3818, 3844, 3857, 2741, 2834, 2922, 1705, 1495, 1617, 203, 4, - 205, 43718, 43673, 43652, 43553, 43476, 43491, 43902, 43741, 43773, 43644, 43672, 43651, - 43680, 43672, 43644, 2741, 2655, 2834, 3350, 3469, 3250, 43420, 43451, 43395, 41783, - 41976, 41985, 41648, 41790, 41783, 41922, 41790, 41648, 41604, 41648, 41469, 41500, 41469, - 41131, 41500, 41728, 41757, 3250, 3469, 3308, 3857, 3844, 3963, 559, 734, 779, - 4110, 4235, 4234, 4276, 4238, 4572, 4053, 4235, 4110, 38652, 38551, 38593, 38634, - 38551, 38652, 39608, 39763, 39479, 38137, 38554, 37913, 42776, 42588, 42712, 43100, 42712, - 42931, 43553, 43491, 43567, 1342, 1282, 1463, 1817, 2066, 2097, 2490, 2735, 3121, - 1282, 1325, 1238, 4110, 4184, 3736, 2622, 2735, 2490, 42105, 42058, 41751, 42138, - 42058, 42105, 42182, 42138, 42105, 3469, 3528, 3308, 3971, 3857, 3963, 4160, 3971, - 3963, 4964, 4595, 4548, 38245, 38101, 38135, 38419, 38101, 38245, 623, 611, 693, - 205, 4, 235, 43527, 43274, 43260, 43626, 43553, 43567, 39880, 40117, 39822, 39880, - 39733, 39690, 1067, 762, 669, 3528, 3724, 3605, 42381, 42337, 42609, 42381, 42221, - 42337, 409, 463, 538, 4015, 3971, 4160, 3605, 3724, 3818, 43334, 43274, 43527, - 43739, 43626, 43652, 43238, 43164, 43334, 43853, 43902, 43773, 38634, 38419, 38551, 38551, - 38419, 38292, 43739, 43652, 43673, 39841, 39880, 39690, 42467, 42381, 42609, 225, 203, - 257, 257, 203, 332, 4125, 4015, 4160, 3807, 3818, 3857, 623, 510, 611, - 448, 510, 623, 43164, 43056, 43008, 43164, 43008, 43274, 2004, 1827, 2067, 1705, - 1178, 1495, 1067, 1239, 762, 2052, 2173, 2203, 2173, 2398, 2203, 1962, 1827, - 2004, 2203, 2398, 2245, 1827, 1746, 1838, 1358, 1521, 1463, 2245, 2398, 2448, - 2448, 2571, 2567, 40356, 40227, 40229, 42198, 42257, 41985, 40356, 40085, 40285, 43260, - 43476, 43527, 43769, 43739, 43673, 41976, 41783, 41790, 43672, 43821, 43682, 2329, 2448, - 2321, 3807, 3857, 3971, 40285, 40085, 40117, 39083, 38876, 39650, 41500, 41604, 41469, - 2741, 2922, 2845, 42182, 42105, 42271, 42182, 42058, 42138, 42096, 41707, 42058, 40976, - 40620, 41202, 3682, 3807, 3971, 4205, 4473, 4548, 510, 409, 538, 309, 409, - 510, 40285, 40117, 40058, 39697, 39608, 39650, 1325, 1282, 1342, 1238, 1325, 964, - 43902, 43769, 43718, 43476, 43553, 43683, 2735, 2720, 2936, 2218, 2622, 2490, 39841, - 39690, 39763, 42030, 41976, 41790, 669, 762, 635, 43100, 42776, 42712, 42271, 42105, - 42262, 43100, 42931, 43056, 4050, 3971, 4015, 43782, 43626, 43739, 4125, 4050, 4015, - 4259, 4205, 4548, 2845, 2922, 2978, 2845, 2978, 2888, 640, 620, 646, 646, - 620, 693, 2888, 2978, 3000, 42271, 42262, 42467, 42467, 42262, 42381, 4595, 4259, - 4548, 4100, 4050, 4125, 309, 257, 409, 102, 225, 257, 203, 34, 4, - 2096, 2203, 2153, 2096, 2025, 2203, 2203, 2025, 2052, 2052, 1934, 1962, 1962, - 1934, 1827, 1827, 1327, 1746, 635, 468, 560, 2203, 2245, 2153, 2245, 2144, - 2153, 734, 774, 964, 577, 774, 734, 577, 734, 357, 39697, 39841, 39763, - 39697, 39763, 39608, 2245, 2448, 2329, 2448, 2429, 2321, 4100, 4125, 4205, 3807, - 3605, 3818, 4235, 4238, 4276, 4085, 4053, 3953, 42870, 42246, 42821, 3598, 3605, - 3633, 2448, 2567, 2429, 2517, 2741, 2500, 39650, 38876, 39079, 1263, 1358, 1463, - 2066, 2218, 2490, 1263, 1463, 1282, 43164, 43238, 43056, 42609, 42484, 42588, 43769, - 43782, 43739, 43902, 43782, 43769, 1238, 1263, 1282, 43334, 43164, 43274, 24, 70, - 317, 4053, 4116, 4235, 4085, 4116, 4053, 38865, 38634, 38652, 38419, 38598, 38101, - 1434, 1495, 947, 620, 561, 623, 3598, 3308, 3528, 39861, 39653, 39432, 757, - 1238, 964, 40620, 40430, 39432, 40341, 40430, 40639, 42096, 42058, 42182, 41976, 42064, - 41985, 41922, 42030, 41790, 41922, 41648, 41604, 41922, 41604, 41757, 41500, 41131, 41728, - 40117, 39880, 40058, 42030, 42064, 41976, 669, 640, 646, 635, 640, 669, 43793, - 43821, 43680, 43680, 43821, 43672, 43527, 43476, 43683, 42609, 42588, 42776, 40058, 39880, - 40104, 4116, 4238, 4235, 4085, 4238, 4116, 39012, 39079, 38744, 40154, 40058, 40104, - 38137, 38601, 38554, 3000, 2978, 3250, 39787, 39841, 39697, 43724, 43712, 43451, 43517, - 43451, 43420, 3057, 3060, 3017, 3057, 3250, 3060, 3057, 3000, 3250, 42295, 42096, - 42182, 42609, 42776, 42693, 42821, 42246, 42257, 3598, 3528, 3605, 3633, 3605, 3807, - 2025, 1934, 2052, 2023, 1934, 2025, 2023, 2025, 2096, 2023, 2096, 2153, 2088, - 2153, 2144, 2567, 2517, 2429, 2741, 2517, 2655, 43772, 43793, 43712, 43712, 43793, - 43680, 43100, 43056, 43238, 1313, 1358, 1263, 1313, 1347, 1358, 1358, 1347, 1521, - 4329, 3603, 3616, 1313, 1263, 1191, 1263, 1238, 1191, 2592, 2500, 2741, 3603, - 3378, 3616, 43417, 43517, 43420, 43724, 43517, 43882, 3060, 3250, 3308, 3682, 3633, - 3807, 3533, 3633, 3472, 2845, 2592, 2741, 42456, 42821, 42257, 42155, 42198, 42064, - 41757, 41604, 41500, 40784, 41497, 41131, 2915, 2888, 3000, 3017, 3000, 3057, 42295, - 42182, 42271, 42295, 42271, 42492, 640, 561, 620, 560, 468, 521, 40744, 40356, - 40285, 39079, 38876, 38744, 42198, 41985, 42064, 4259, 4100, 4205, 4250, 4100, 4259, - 42155, 42064, 42030, 635, 561, 640, 560, 561, 635, 42492, 42271, 42467, 70, - 222, 347, 4217, 4250, 4259, 3682, 3971, 4050, 43517, 43724, 43451, 43772, 43724, - 43882, 38634, 38598, 38419, 39065, 38865, 38652, 39065, 38603, 39381, 3308, 3077, 2966, - 3060, 2955, 3021, 42758, 42492, 42467, 43678, 43100, 43238, 43515, 43238, 43334, 3533, - 3598, 3633, 40094, 39861, 39432, 40094, 39432, 40430, 1239, 947, 762, 2088, 2023, - 2153, 2245, 2329, 2144, 2329, 2321, 2144, 2321, 2229, 2144, 2429, 2229, 2321, - 4085, 3953, 4238, 3603, 2936, 3378, 43683, 43553, 43626, 2429, 2348, 2229, 4074, - 4050, 4100, 2915, 3000, 3017, 41922, 42155, 42030, 42198, 42456, 42257, 40154, 40285, - 40058, 39650, 39787, 39697, 39879, 39787, 39807, 1488, 1817, 2097, 1191, 1238, 1155, - 1226, 1191, 1155, 306, 309, 510, 225, 34, 203, 506, 623, 561, 3378, - 2936, 3260, 4250, 4074, 4100, 42157, 42155, 41922, 43882, 43517, 43887, 1296, 947, - 1239, 3616, 3736, 4184, 3527, 3736, 3616, 39381, 38603, 39653, 39012, 38744, 38554, - 43809, 43683, 43626, 43527, 43515, 43334, 43809, 43626, 43782, 521, 506, 560, 560, - 506, 561, 201, 102, 309, 309, 102, 257, 3657, 3744, 3736, 3736, 3744, - 4053, 40104, 39880, 39841, 39879, 39841, 39787, 40341, 40094, 40430, 42295, 42346, 42096, - 42693, 42467, 42609, 42693, 42776, 43000, 4250, 4217, 4074, 3689, 3682, 3812, 3021, - 3017, 3060, 4595, 4217, 4259, 38760, 38634, 38865, 38760, 38598, 38634, 42758, 42693, - 42940, 43829, 43809, 43782, 43724, 43772, 43712, 43793, 43882, 43821, 43517, 43417, 43887, - 506, 448, 623, 433, 448, 506, 39795, 39381, 39653, 38951, 38760, 38865, 39795, - 39653, 39861, 3021, 2915, 3017, 3060, 3308, 2955, 40430, 40959, 40639, 26, 34, - 102, 102, 34, 225, 3744, 3839, 3953, 3953, 3788, 4238, 3691, 3839, 3744, - 2916, 3021, 2955, 43515, 43527, 43889, 43902, 43829, 43782, 41760, 41728, 41734, 42157, - 42191, 42155, 42155, 42191, 42198, 40744, 40556, 40356, 39807, 39787, 39650, 43527, 43683, - 43889, 1495, 985, 947, 2088, 1649, 2023, 2144, 2220, 2088, 2348, 2429, 2517, - 2348, 2517, 2377, 448, 306, 510, 310, 306, 448, 1281, 2097, 1347, 1191, - 1226, 1313, 1155, 1238, 758, 2845, 2888, 2592, 39944, 39795, 39861, 38951, 38865, - 39065, 39879, 40104, 39841, 39678, 39807, 39650, 757, 964, 774, 2592, 2888, 2629, - 42006, 41922, 41757, 40007, 40104, 39879, 39203, 39678, 39650, 39331, 39065, 39381, 2784, - 2888, 2915, 2784, 2915, 2916, 1746, 1178, 1705, 40430, 40620, 40959, 40116, 39944, - 39861, 42346, 42295, 42492, 42435, 42346, 42549, 42758, 42467, 42693, 3682, 4050, 3812, - 521, 433, 506, 306, 201, 309, 374, 433, 521, 2720, 2735, 2622, 2916, - 2915, 3021, 43889, 43683, 43809, 1746, 1327, 1178, 2955, 3308, 2966, 40007, 39879, - 39891, 3472, 3598, 3533, 39891, 39879, 39807, 39891, 39807, 39907, 1202, 1347, 1313, - 1202, 1313, 1226, 327, 310, 448, 327, 448, 433, 3378, 3479, 3616, 3527, - 3479, 3438, 41728, 41760, 41757, 42191, 42392, 42198, 40327, 40285, 40154, 40327, 40154, - 40291, 2229, 2220, 2144, 2264, 2220, 2229, 2264, 2229, 2348, 2377, 2517, 2445, - 2517, 2500, 2445, 2500, 2518, 2445, 2592, 2518, 2500, 41760, 41887, 41757, 357, - 734, 559, 1157, 1202, 1226, 39795, 39640, 39381, 40144, 39861, 40094, 40291, 40154, - 40198, 40038, 39891, 39907, 1157, 1226, 1155, 41887, 42006, 41757, 2592, 2484, 2518, - 42006, 42157, 41922, 310, 201, 306, 170, 201, 310, 3479, 3527, 3616, 3536, - 3527, 3438, 2518, 2484, 2426, 2592, 2629, 2484, 762, 468, 635, 374, 468, - 279, 222, 121, 559, 72, 121, 222, 3527, 3657, 3736, 3536, 3657, 3527, - 1827, 1934, 1327, 42232, 42392, 42191, 40154, 40104, 40198, 42392, 42456, 42198, 632, - 757, 577, 70, 72, 222, 3600, 3472, 3633, 2426, 2445, 2518, 3812, 4050, - 4074, 3657, 3691, 3744, 3839, 3788, 3953, 3536, 3691, 3657, 2514, 2720, 2622, - 40198, 40104, 40007, 43772, 43882, 43793, 43887, 43417, 43827, 374, 521, 468, 360, - 327, 433, 39640, 39331, 39381, 40341, 40144, 40094, 40348, 40144, 40341, 40038, 40198, - 40007, 3859, 3812, 4074, 3600, 3633, 3682, 3691, 3788, 3839, 3460, 3788, 3691, - 39853, 39907, 39678, 39891, 40038, 40007, 38601, 39012, 38554, 43000, 42776, 43100, 41692, - 41707, 42096, 39907, 39807, 39678, 1202, 1281, 1347, 1817, 2218, 2066, 1224, 1281, - 1202, 1157, 1155, 1065, 4217, 3859, 4074, 3600, 3682, 3673, 2314, 2218, 2046, - 3682, 3689, 3673, 39640, 39795, 39994, 39203, 39650, 39079, 757, 774, 577, 1327, - 1934, 1649, 2377, 2264, 2348, 2445, 2264, 2377, 2426, 2264, 2445, 2784, 2629, - 2888, 40576, 40744, 40285, 42102, 42006, 41887, 42244, 42232, 42006, 42006, 42232, 42157, - 42157, 42232, 42191, 42392, 42572, 42456, 40576, 40285, 40327, 40315, 40327, 40291, 40315, - 40291, 40226, 40291, 40198, 40226, 43827, 43417, 42821, 42023, 41887, 41760, 2784, 2764, - 2629, 2784, 2916, 2764, 3673, 3689, 3812, 3292, 3479, 3378, 3260, 2936, 2983, - 39012, 39203, 39079, 42435, 42096, 42346, 39994, 39795, 39944, 42549, 42346, 42492, 43678, - 43000, 43100, 2916, 2761, 2764, 327, 170, 310, 591, 468, 762, 662, 762, - 947, 3164, 3260, 2983, 40639, 40407, 40341, 42549, 42492, 42726, 2764, 2761, 2656, - 3774, 3673, 3812, 2764, 2656, 2629, 40226, 40198, 40307, 40198, 40038, 40095, 42726, - 42492, 42758, 374, 360, 433, 170, 360, 232, 3260, 3292, 3378, 3156, 3292, - 3260, 40116, 39861, 40144, 357, 559, 123, 2802, 2761, 2916, 40015, 40038, 39907, - 40173, 40116, 40144, 41485, 41497, 40784, 41734, 41497, 41696, 40576, 40327, 40473, 42240, - 42096, 42435, 42240, 41692, 42096, 40639, 40520, 40407, 40407, 40348, 40341, 3292, 3438, - 3479, 3536, 3460, 3691, 3294, 3438, 3292, 1224, 1297, 1281, 1281, 1488, 2097, - 2218, 2314, 2622, 1224, 1202, 1157, 1200, 1224, 1077, 41202, 40620, 40654, 40473, - 40327, 40315, 39853, 40015, 39907, 43000, 42940, 42693, 42938, 42626, 42435, 43287, 42940, - 43000, 43678, 43238, 43515, 40976, 40959, 40620, 1735, 2218, 1817, 40473, 40315, 40416, - 39915, 39853, 39678, 2582, 2484, 2629, 2582, 2401, 2484, 2484, 2401, 2426, 2426, - 2401, 2264, 591, 662, 381, 2582, 2629, 2656, 2817, 2936, 2720, 40714, 40520, - 40639, 40473, 40416, 40543, 2955, 2802, 2916, 40095, 40038, 40015, 123, 559, 121, - 1200, 1297, 1224, 2955, 2966, 2802, 40116, 40068, 39944, 40520, 40348, 40407, 3156, - 3294, 3292, 3438, 3460, 3536, 3156, 3260, 3164, 2023, 1649, 1934, 3598, 3077, - 3308, 40348, 40237, 40144, 42940, 42726, 42758, 3489, 3472, 3600, 2609, 2817, 2720, - 40237, 40173, 40144, 360, 170, 327, 201, 26, 102, 232, 360, 275, 3294, - 3363, 3438, 3460, 3363, 3093, 2314, 2514, 2622, 1297, 1488, 1281, 1320, 1488, - 1297, 1320, 1297, 1200, 41497, 41734, 41728, 42232, 42410, 42392, 41485, 40784, 40993, - 40835, 40744, 40735, 40173, 40068, 40116, 39389, 38951, 39331, 39950, 40095, 40015, 40735, - 40744, 40576, 39950, 40015, 39853, 1224, 1157, 1065, 40520, 40619, 40348, 40348, 40208, - 40237, 40237, 40208, 40173, 40173, 40208, 40068, 40959, 40819, 40639, 40976, 40981, 40959, - 41316, 41202, 40654, 41316, 40654, 41692, 2558, 2656, 2657, 2558, 2582, 2656, 2558, - 2401, 2582, 1327, 971, 1210, 2088, 2220, 1649, 1065, 1155, 758, 3859, 3774, - 3812, 3673, 3489, 3600, 4217, 3774, 3859, 39331, 38951, 39065, 38760, 38951, 38598, - 39493, 39331, 39640, 2860, 2983, 2817, 2817, 2983, 2936, 40068, 39994, 39944, 40208, - 39994, 40068, 40735, 40576, 40543, 39915, 39950, 39853, 40095, 39950, 40371, 758, 1238, - 757, 40981, 40819, 40959, 40576, 40473, 40543, 170, 26, 201, 124, 26, 170, - 360, 374, 275, 3514, 3489, 3673, 43829, 43889, 43809, 42940, 43287, 42726, 2983, - 3156, 3164, 2863, 3156, 2983, 2437, 2514, 2314, 632, 758, 757, 2657, 2656, - 2761, 2657, 2761, 2722, 2722, 2761, 2802, 2514, 2609, 2720, 591, 762, 662, - 381, 662, 515, 41734, 42023, 41760, 40993, 40556, 40744, 41565, 41485, 41589, 41569, - 41316, 41692, 41248, 40981, 40976, 40819, 40714, 40639, 357, 632, 577, 99, 123, - 121, 42016, 42023, 41734, 2721, 2860, 2817, 42023, 42102, 41887, 41051, 40981, 41086, - 42543, 42240, 42626, 41984, 42074, 42055, 42102, 42244, 42006, 3489, 3437, 3472, 3514, - 3437, 3489, 1178, 985, 1495, 907, 985, 1178, 1679, 1649, 2220, 3287, 3598, - 3472, 2657, 2195, 2558, 42244, 42410, 42232, 40937, 40714, 40819, 39597, 39493, 39716, - 40315, 40226, 40416, 2609, 2670, 2817, 2514, 2575, 2609, 2412, 2437, 2364, 1735, - 1817, 1488, 1272, 1488, 1320, 1272, 1320, 1125, 1320, 1200, 1120, 40416, 40226, - 40307, 232, 124, 170, 279, 275, 374, 279, 468, 591, 2412, 2575, 2514, - 40307, 40198, 40095, 40307, 40095, 40371, 1077, 1224, 1065, 43, 632, 357, 2575, - 2670, 2609, 39915, 39678, 39203, 2827, 2802, 2966, 2827, 2722, 2802, 2670, 2721, - 2817, 2860, 2863, 2983, 3093, 3363, 3294, 40619, 40208, 40348, 3437, 3287, 3472, - 3242, 3287, 3437, 42023, 42016, 42102, 42102, 42298, 42244, 42433, 42572, 42410, 41485, - 41565, 41497, 40993, 40744, 40835, 40993, 40835, 41016, 40993, 41016, 41121, 40735, 40543, - 40842, 41565, 41696, 41497, 41696, 41805, 41734, 1120, 1200, 1077, 2437, 2412, 2514, - 2526, 2684, 2670, 2670, 2684, 2721, 1597, 1735, 1449, 2924, 2827, 2966, 41805, - 42016, 41734, 1077, 1065, 970, 42572, 42392, 42410, 42973, 42821, 42456, 123, 43, - 357, 72, 99, 121, 39493, 39640, 39873, 970, 942, 1003, 970, 1065, 680, - 2957, 2924, 2966, 2684, 2863, 2721, 2721, 2863, 2860, 1077, 970, 1003, 40714, - 40619, 40520, 40981, 41051, 40819, 41086, 40981, 41248, 40976, 41202, 41248, 40550, 40543, - 40416, 41051, 40937, 40819, 39873, 39640, 39994, 3093, 3294, 3156, 3363, 3460, 3438, - 39012, 39439, 39203, 40307, 40550, 40416, 3077, 2957, 2966, 275, 124, 232, 218, - 279, 125, 3130, 3077, 3598, 39439, 39915, 39203, 2364, 2437, 2081, 2863, 2867, - 3156, 3287, 3130, 3598, 3774, 3514, 3673, 43889, 43678, 43515, 41772, 41569, 41692, - 40371, 40550, 40307, 3061, 3130, 3062, 157, 124, 275, 2526, 2670, 2575, 40483, - 40371, 39950, 41772, 41692, 41984, 41051, 41095, 40937, 114, 218, 125, 279, 218, - 275, 1808, 1679, 2220, 1808, 2220, 2264, 2699, 2722, 2827, 2782, 2827, 2924, - 2932, 2924, 2957, 2932, 2957, 2971, 42433, 42410, 42244, 41805, 41946, 42016, 41904, - 41946, 41805, 41904, 41805, 41696, 41828, 41696, 41565, 41121, 41485, 40993, 40835, 40910, - 41016, 1013, 1120, 1077, 1013, 1125, 1120, 1120, 1125, 1320, 1449, 1735, 1488, - 1735, 2046, 2218, 2412, 2319, 2575, 970, 680, 942, 1013, 1003, 942, 2081, - 2046, 1908, 41445, 41202, 41316, 41006, 40619, 40714, 40835, 40735, 40910, 40910, 40735, - 40842, 2971, 2957, 3077, 2971, 3077, 3061, 2816, 2867, 2684, 2684, 2867, 2863, - 40602, 40543, 40550, 42298, 42102, 42016, 3061, 3077, 3130, 2401, 1808, 2264, 2081, - 2437, 2314, 41006, 40714, 40937, 279, 161, 125, 3242, 3130, 3287, 2657, 2722, - 2195, 218, 157, 275, 124, 12, 26, 114, 157, 218, 42878, 42973, 42456, - 3247, 3242, 3437, 2924, 2932, 2782, 42210, 42298, 42016, 42572, 42878, 42456, 41121, - 41589, 41485, 41828, 41589, 41781, 41109, 41121, 41016, 41636, 41445, 41316, 41086, 41095, - 41051, 41984, 41692, 42240, 1327, 1210, 1178, 2932, 2878, 2782, 2932, 2971, 2878, - 41636, 41316, 41569, 41984, 42240, 42224, 41445, 41248, 41202, 39493, 39389, 39331, 39873, - 39994, 40049, 39994, 40128, 40049, 1125, 1083, 1272, 2046, 2081, 2314, 1003, 1013, - 1077, 1083, 1013, 958, 41248, 41164, 41086, 42122, 42016, 41946, 2878, 2971, 2962, - 41164, 41095, 41086, 2364, 2319, 2412, 1870, 2046, 1735, 41095, 41006, 40937, 42298, - 42433, 42244, 2962, 2971, 3061, 1808, 2401, 1878, 2198, 2319, 2364, 3062, 2962, - 3061, 3514, 3439, 3437, 3774, 3439, 3514, 39597, 39389, 39493, 39716, 39389, 39597, - 40371, 40602, 40550, 40910, 41109, 41016, 40483, 40602, 40371, 40483, 39950, 39915, 157, - 12, 124, 279, 178, 161, 39994, 40344, 40128, 39439, 39934, 39915, 2319, 2526, - 2575, 2816, 3093, 3156, 43847, 43287, 43000, 43889, 43880, 43678, 114, 12, 157, - 125, 12, 114, 40649, 40483, 40362, 41589, 41828, 41565, 42298, 42336, 42433, 41781, - 41589, 41553, 40842, 40543, 40602, 41445, 41359, 41248, 41248, 41344, 41164, 41164, 41242, - 41095, 41095, 41242, 41006, 39775, 39716, 39873, 41846, 41636, 41569, 41846, 41569, 41772, - 41846, 41772, 41965, 41828, 41904, 41696, 41904, 42029, 41946, 42736, 42878, 42572, 3439, - 3247, 3437, 2699, 2827, 2782, 40208, 40344, 39994, 39873, 39716, 39493, 971, 898, - 1210, 662, 947, 515, 2699, 2782, 2878, 42029, 42122, 41946, 1013, 1083, 1125, - 2081, 2198, 2364, 2319, 2133, 2526, 1065, 758, 680, 41584, 41359, 41445, 2935, - 2699, 2878, 1597, 1870, 1735, 680, 758, 597, 2105, 2198, 2081, 40625, 40619, - 40955, 597, 758, 632, 40706, 40842, 40602, 40706, 40602, 40608, 40608, 40602, 40483, - 907, 1178, 1210, 3062, 3130, 3242, 1878, 2401, 2060, 40484, 40608, 40483, 42736, - 42572, 42433, 43859, 43827, 42821, 3138, 3062, 3242, 2401, 2558, 2195, 3138, 3242, - 3247, 40674, 40484, 40649, 3195, 3138, 3247, 2935, 2878, 2962, 39716, 39850, 39389, - 39993, 39775, 39873, 40089, 39873, 40049, 41584, 41344, 41359, 41359, 41344, 41248, 42055, - 41772, 41984, 42224, 42240, 42543, 1870, 1810, 2046, 1449, 1488, 1353, 1062, 1272, - 1083, 1062, 1083, 1035, 958, 1013, 942, 42240, 42435, 42626, 42122, 42210, 42016, - 42029, 42210, 42122, 42323, 42210, 42284, 42210, 42029, 42086, 42029, 41904, 42086, 41109, - 40910, 40927, 40910, 40842, 40927, 40842, 40706, 40927, 41584, 41445, 41636, 3439, 3195, - 3247, 2935, 2962, 3062, 840, 958, 942, 746, 907, 811, 2935, 3062, 3034, - 1638, 1810, 1870, 41344, 41242, 41164, 43847, 43000, 43678, 1810, 1908, 2046, 2198, - 2133, 2319, 1908, 2040, 2081, 40927, 40786, 41005, 40344, 40208, 40625, 2040, 2105, - 2081, 2816, 3156, 2867, 40927, 40706, 40786, 42805, 42736, 42433, 3169, 3062, 3138, - 40128, 40089, 40049, 40180, 40089, 40128, 43060, 42973, 42878, 43859, 42821, 42973, 680, - 840, 942, 265, 597, 632, 99, 43, 123, 2816, 2684, 2526, 40786, 40706, - 40608, 40649, 40484, 40483, 39439, 39912, 39934, 41846, 41689, 41636, 41447, 41196, 41242, - 40625, 40208, 40619, 42055, 41965, 41772, 42074, 41965, 42055, 42074, 41984, 42224, 1908, - 1739, 2040, 2040, 1739, 2105, 2676, 2816, 2526, 1810, 1739, 1908, 1597, 1638, - 1870, 1353, 1488, 1128, 1094, 1272, 1062, 1094, 1062, 1035, 41965, 41689, 41846, - 3195, 3169, 3138, 2195, 2722, 2699, 3034, 3169, 3195, 41689, 41584, 41636, 42181, - 42074, 42224, 1035, 1083, 941, 1083, 958, 941, 941, 958, 840, 42210, 42323, - 42298, 42736, 43060, 42878, 42086, 41904, 41828, 41589, 41121, 41553, 40619, 41006, 40992, - 666, 907, 746, 558, 459, 515, 1035, 941, 914, 42323, 42336, 42298, 42435, - 42549, 42938, 40344, 40224, 40128, 40089, 39993, 39873, 40250, 40224, 40467, 42938, 42549, - 42726, 40927, 41005, 41109, 40786, 40608, 40674, 178, 279, 591, 125, 85, 12, - 2133, 2198, 2105, 40224, 40180, 40128, 40250, 40180, 40224, 40180, 39993, 40089, 39775, - 39850, 39716, 40160, 39993, 40180, 515, 947, 985, 40992, 41006, 41196, 1449, 1400, - 1597, 1128, 1488, 1272, 1128, 1272, 1094, 1027, 1094, 1035, 1027, 1035, 914, - 42323, 42491, 42336, 41215, 41121, 41109, 42118, 42086, 41828, 42805, 43060, 42736, 41196, - 41006, 41242, 41689, 41897, 41584, 41965, 42040, 41689, 42074, 42040, 41965, 42364, 42181, - 42224, 42535, 42224, 42543, 381, 307, 591, 914, 941, 840, 840, 680, 597, - 1541, 1638, 1597, 914, 840, 900, 307, 178, 591, 41211, 41215, 41109, 41394, - 41215, 41214, 42645, 42535, 42543, 42645, 42543, 42626, 178, 166, 161, 161, 85, - 125, 40467, 40224, 40344, 40763, 40344, 40625, 42855, 42938, 42961, 42961, 42938, 43236, - 40674, 40608, 40484, 40483, 39915, 40362, 178, 168, 166, 307, 175, 178, 381, - 316, 307, 366, 316, 381, 1069, 1137, 1092, 40362, 39915, 39934, 42253, 42040, - 42074, 42253, 42074, 42181, 42364, 42224, 42460, 1192, 1082, 1235, 915, 1094, 1027, - 972, 1128, 1094, 1353, 1400, 1449, 41997, 42118, 41828, 42086, 42284, 42210, 41997, - 41828, 41781, 41394, 41121, 41215, 41109, 41005, 41211, 41005, 41152, 41211, 3169, 3034, - 3062, 3439, 3034, 3195, 40160, 39850, 39993, 39993, 39850, 39775, 40353, 40180, 40250, - 1307, 1400, 1353, 1638, 1739, 1810, 1400, 1541, 1597, 42460, 42224, 42535, 176, - 175, 307, 42645, 42460, 42535, 40775, 40786, 40674, 43880, 43847, 43678, 42734, 42645, - 42626, 2195, 2699, 2306, 316, 176, 307, 42809, 42626, 42938, 42855, 42809, 42938, - 168, 178, 175, 168, 85, 166, 166, 85, 161, 41242, 41344, 41633, 42938, - 42726, 43236, 515, 985, 558, 2306, 2699, 2295, 40992, 40955, 40619, 43236, 42726, - 43287, 42805, 42433, 42336, 40671, 40775, 40674, 40671, 40674, 40649, 515, 366, 381, - 40955, 40763, 40625, 40968, 40671, 40862, 1400, 1008, 1541, 1626, 1739, 1638, 1128, - 1192, 1353, 915, 1027, 914, 915, 914, 900, 42118, 42243, 42086, 41947, 41997, - 41781, 41947, 41781, 41632, 41121, 41394, 41553, 1192, 1307, 1353, 41553, 41539, 41632, - 41997, 42243, 42118, 42243, 42284, 42086, 900, 840, 836, 42284, 42383, 42323, 880, - 900, 836, 41005, 40786, 41047, 42383, 42491, 42323, 176, 168, 175, 43, 146, - 632, 40523, 40467, 40344, 1626, 1638, 1541, 42919, 42809, 42855, 42919, 42734, 42809, - 42809, 42734, 42626, 42645, 42734, 42460, 42331, 42253, 42333, 42364, 42253, 42181, 41768, - 41344, 41584, 40992, 41292, 40955, 40836, 40709, 40763, 40763, 40523, 40344, 42919, 42855, - 42982, 40523, 40353, 40467, 40467, 40353, 40250, 41897, 41689, 42040, 40885, 40786, 40775, - 2195, 2060, 2401, 666, 985, 907, 515, 426, 366, 366, 241, 316, 1906, - 2060, 2195, 42982, 42855, 42961, 1210, 811, 907, 1739, 2133, 2105, 2816, 2676, - 3093, 459, 426, 515, 40785, 40775, 40671, 40785, 40885, 40775, 40353, 40160, 40180, - 40454, 40160, 40353, 40968, 40785, 40671, 43244, 43236, 43287, 426, 241, 366, 241, - 176, 316, 1739, 1865, 2133, 1307, 1235, 1400, 1192, 1235, 1307, 1082, 1192, - 1128, 1082, 1128, 972, 1094, 915, 972, 42383, 42470, 42491, 43910, 42973, 43060, - 42284, 42470, 42383, 42243, 42268, 42284, 41997, 42225, 42243, 41947, 41975, 41997, 41951, - 41975, 41947, 41632, 41781, 41553, 41553, 41394, 41539, 41394, 41519, 41539, 43910, 43859, - 42973, 42805, 42336, 42491, 972, 915, 856, 42925, 42734, 43022, 42364, 42460, 42671, - 42253, 42364, 42671, 880, 915, 900, 42225, 42268, 42243, 836, 840, 268, 41215, - 41211, 41214, 41231, 40992, 41196, 40631, 40523, 40709, 268, 840, 597, 1008, 1626, - 1541, 41214, 41211, 41152, 1210, 898, 811, 459, 408, 426, 426, 344, 241, - 241, 194, 176, 146, 265, 632, 43, 17, 146, 41152, 41005, 41047, 666, - 558, 985, 41047, 40786, 40885, 2224, 2676, 2526, 2116, 2526, 2133, 40968, 41047, - 40885, 39912, 40362, 39934, 43132, 42982, 42961, 43132, 42961, 43236, 466, 408, 459, - 41055, 41047, 41063, 43244, 43132, 43236, 230, 265, 39, 43587, 43244, 43287, 42009, - 41897, 42040, 42009, 42040, 42331, 42040, 42253, 42331, 42734, 42671, 42460, 41897, 41768, - 41584, 42517, 42470, 42268, 42268, 42470, 42284, 42225, 41997, 41975, 41951, 41947, 41632, - 41653, 41632, 41539, 41653, 41539, 41519, 41394, 41438, 41519, 836, 807, 880, 880, - 856, 915, 972, 854, 1082, 1082, 1008, 1235, 1008, 1628, 1626, 1626, 1628, - 1739, 715, 807, 836, 41768, 41633, 41344, 41394, 41214, 41438, 558, 466, 459, - 666, 589, 558, 971, 865, 898, 41633, 41487, 41242, 41438, 41214, 41393, 41214, - 41307, 41393, 746, 665, 666, 41487, 41447, 41242, 41214, 41152, 41307, 665, 589, - 666, 41055, 41152, 41047, 589, 571, 558, 408, 344, 426, 41447, 41231, 41196, - 571, 466, 558, 40968, 40885, 40785, 379, 344, 408, 40862, 40671, 40649, 1649, - 971, 1327, 2633, 2699, 2935, 42470, 42581, 42491, 41951, 42225, 41975, 41709, 41632, - 41653, 41709, 41653, 41649, 41653, 41519, 41649, 41519, 41438, 41649, 41438, 41735, 41649, - 41886, 41641, 41633, 41633, 41641, 41487, 41487, 41641, 41447, 41493, 41292, 41231, 41897, - 42050, 41768, 42734, 42925, 42671, 807, 856, 880, 854, 856, 832, 571, 517, - 466, 466, 379, 408, 589, 576, 571, 665, 576, 589, 746, 655, 665, - 1069, 971, 1649, 41438, 41393, 41473, 42517, 42581, 42470, 40523, 40631, 40353, 40709, - 40523, 40763, 40763, 41041, 40836, 41886, 41633, 41768, 41307, 41152, 41289, 660, 655, - 746, 1008, 1400, 1235, 655, 576, 665, 42581, 42805, 42491, 41289, 41152, 41055, - 576, 517, 571, 41283, 41289, 41055, 40631, 40454, 40353, 40160, 40382, 39850, 40681, - 40454, 40631, 43814, 43703, 43287, 42919, 42982, 43022, 517, 379, 466, 3034, 2633, - 2935, 2306, 1906, 2195, 40454, 40382, 40160, 40666, 40382, 40454, 40995, 41047, 40968, - 40995, 41063, 41047, 1865, 2116, 2133, 41037, 40995, 40968, 43847, 43814, 43287, 42919, - 43022, 42734, 162, 194, 344, 344, 194, 241, 176, 44, 168, 168, 44, - 85, 265, 268, 597, 39, 265, 146, 2633, 2295, 2699, 42009, 42050, 41897, - 40763, 40955, 41041, 43226, 43022, 42982, 42331, 42050, 42009, 194, 44, 176, 40955, - 41183, 41041, 517, 399, 379, 379, 162, 344, 194, 162, 44, 424, 399, - 517, 655, 637, 576, 811, 714, 746, 1679, 1069, 1649, 856, 854, 972, - 1628, 1865, 1739, 832, 856, 807, 42581, 42517, 42805, 42225, 42517, 42268, 41709, - 41951, 41632, 41735, 41951, 41709, 41735, 41709, 41649, 41735, 41438, 41473, 41393, 41307, - 41473, 41283, 41055, 41063, 715, 832, 807, 42349, 42517, 42225, 764, 714, 811, - 681, 715, 836, 43587, 43287, 43703, 714, 660, 746, 43689, 43587, 43703, 42982, - 43132, 43226, 43368, 43132, 43244, 424, 517, 576, 230, 268, 265, 40995, 41068, - 41063, 41037, 41068, 40995, 40862, 41037, 40968, 43559, 43368, 43244, 40709, 40681, 40631, - 40992, 41231, 41292, 40362, 40862, 40649, 42050, 42017, 41768, 42235, 42129, 42050, 42509, - 42333, 42253, 42509, 42253, 42671, 42509, 42671, 42635, 42930, 42925, 42970, 660, 637, - 655, 714, 675, 660, 898, 837, 811, 1137, 1069, 1679, 42129, 42017, 42050, - 865, 837, 898, 837, 764, 811, 715, 721, 832, 832, 720, 854, 854, - 1008, 1082, 681, 721, 715, 40836, 40681, 40709, 40666, 40681, 40824, 629, 681, - 836, 41473, 41307, 41466, 41951, 42349, 42225, 41307, 41289, 41466, 41289, 41462, 41466, - 675, 637, 660, 399, 162, 379, 41063, 41068, 41283, 41283, 41068, 41198, 2116, - 2224, 2526, 1832, 1865, 1593, 41090, 41068, 41037, 43293, 43226, 43132, 43293, 43132, - 43368, 43293, 43693, 43445, 43899, 42805, 43813, 43826, 43060, 43899, 43826, 43910, 43060, - 43559, 43244, 43587, 554, 629, 836, 230, 209, 268, 129, 209, 230, 41110, - 41090, 41037, 39, 129, 230, 41851, 41447, 41641, 17, 39, 146, 40862, 40888, - 41037, 40827, 40888, 40862, 43689, 43559, 43587, 1329, 1137, 1679, 865, 772, 837, - 837, 772, 764, 764, 675, 714, 1808, 1329, 1679, 971, 846, 865, 42017, - 41886, 41768, 42235, 42050, 42331, 42635, 42671, 42705, 42970, 43022, 43356, 43259, 43226, - 43293, 2007, 2224, 2116, 40362, 40827, 40862, 846, 772, 865, 42, 162, 399, - 721, 720, 832, 1865, 2007, 2116, 647, 720, 721, 647, 721, 681, 647, - 681, 629, 268, 554, 836, 42129, 41886, 42017, 772, 675, 764, 629, 641, - 647, 629, 554, 641, 40904, 40681, 40836, 40681, 40666, 40454, 40904, 40836, 41041, - 43445, 43259, 43293, 43796, 43689, 43703, 41735, 41812, 41951, 41473, 41812, 41735, 41466, - 41462, 41473, 41283, 41462, 41289, 41458, 41462, 41283, 41198, 41068, 41090, 41198, 41090, - 41110, 41493, 41231, 41447, 43293, 43368, 43693, 41292, 41183, 40955, 41110, 41037, 41044, - 424, 576, 637, 41183, 41103, 41041, 41044, 41037, 40888, 40827, 41044, 40888, 41093, - 40904, 41041, 971, 944, 846, 846, 838, 772, 772, 717, 675, 675, 544, - 637, 987, 944, 971, 987, 971, 1069, 987, 1069, 1092, 1878, 1329, 1808, - 944, 896, 846, 1384, 1270, 1329, 896, 838, 846, 1329, 1270, 1195, 42235, - 42331, 42333, 41886, 41851, 41641, 41262, 41103, 41183, 41262, 41093, 41103, 41103, 41093, - 41041, 42235, 42333, 42434, 42705, 42671, 42930, 641, 711, 647, 647, 711, 720, - 649, 1008, 854, 268, 63, 554, 1906, 2306, 2295, 40825, 40824, 40904, 40904, - 40824, 40681, 40666, 40825, 40382, 554, 438, 572, 41871, 41851, 41886, 41690, 41473, - 41462, 41690, 41812, 41473, 41458, 41283, 41312, 41458, 41574, 41476, 513, 544, 675, - 614, 554, 572, 43689, 43796, 43559, 42930, 42671, 42925, 43836, 43796, 43703, 41283, - 41198, 41296, 1832, 2007, 1865, 41368, 41183, 41292, 1007, 1092, 1090, 1007, 987, - 1092, 1007, 956, 987, 987, 956, 944, 944, 859, 896, 896, 822, 838, - 838, 717, 772, 956, 859, 944, 544, 424, 637, 1090, 1092, 1137, 649, - 854, 720, 685, 720, 711, 685, 711, 614, 859, 822, 896, 1030, 1090, - 1059, 1059, 1090, 1137, 42129, 42063, 41886, 41851, 41493, 41447, 42434, 42333, 42509, - 42727, 42509, 42635, 822, 717, 838, 42235, 42063, 42129, 614, 711, 641, 614, - 641, 554, 42925, 43022, 42970, 268, 209, 63, 42063, 41871, 41886, 43022, 43226, - 43356, 2633, 2251, 2295, 41173, 40825, 40904, 40824, 40825, 40666, 41173, 40904, 41093, - 41476, 41690, 41462, 41812, 42048, 41951, 41476, 41462, 41458, 43356, 43226, 43259, 513, - 424, 544, 43837, 43693, 43559, 43814, 43836, 43703, 41856, 41493, 41851, 41296, 41198, - 41110, 41493, 41472, 41292, 41472, 41368, 41292, 41368, 41262, 41183, 41179, 41110, 41044, - 41179, 41296, 41110, 162, 42, 44, 84, 42, 399, 2251, 1906, 2295, 41240, - 41179, 41044, 1030, 842, 1007, 1007, 842, 956, 956, 842, 859, 859, 824, - 822, 822, 824, 717, 717, 644, 675, 424, 84, 399, 1030, 1007, 1090, - 842, 824, 859, 1059, 1137, 1119, 1119, 1137, 1329, 824, 644, 717, 572, - 649, 685, 685, 649, 720, 1593, 1865, 1628, 572, 685, 614, 1195, 1119, - 1329, 42063, 42247, 41871, 41639, 41472, 41493, 41547, 41368, 41472, 41435, 41348, 41368, - 41368, 41348, 41262, 42235, 42247, 42063, 42705, 42727, 42635, 42963, 42727, 42705, 42963, - 42705, 42930, 42963, 42930, 42970, 1329, 1878, 1384, 41923, 41690, 41769, 41923, 41812, - 41690, 41923, 42048, 41812, 41690, 41476, 41769, 1384, 1878, 1411, 41312, 41283, 41296, - 533, 513, 675, 1411, 1878, 2060, 1406, 1411, 1514, 41856, 41851, 41871, 41262, - 41173, 41093, 41261, 41312, 41296, 41179, 41261, 41296, 41240, 41261, 41179, 41372, 41173, - 41262, 42324, 42048, 41923, 42324, 42349, 42048, 42048, 42349, 41951, 41769, 41476, 41748, - 1195, 1270, 1133, 1134, 1195, 1133, 1134, 1119, 1195, 995, 1059, 1119, 995, - 992, 1059, 1059, 992, 1030, 1030, 992, 842, 842, 864, 824, 527, 533, - 644, 644, 533, 675, 42286, 42247, 42235, 41348, 41372, 41262, 42434, 42597, 42525, - 1264, 1270, 1384, 1264, 1384, 1301, 527, 644, 454, 513, 368, 424, 649, - 658, 1008, 63, 209, 129, 1301, 1384, 1411, 43899, 43060, 42805, 41972, 41856, - 41871, 1514, 1411, 2060, 1301, 1406, 1298, 41856, 41716, 41493, 41716, 41639, 41493, - 41639, 41547, 41472, 41547, 41435, 41368, 43693, 43368, 43559, 39, 63, 129, 41435, - 41372, 41348, 41261, 41353, 41312, 41240, 41353, 41261, 2007, 1832, 2224, 1593, 1628, - 1480, 40827, 41240, 41044, 42247, 42120, 41871, 41856, 41842, 41716, 41716, 41842, 41639, - 41639, 41650, 41547, 41547, 41527, 41435, 41435, 41527, 41372, 42434, 42509, 42597, 42434, - 42402, 42235, 1012, 995, 1134, 1134, 995, 1119, 992, 864, 842, 1133, 1270, - 1249, 42402, 42286, 42235, 575, 630, 649, 575, 649, 572, 533, 485, 513, - 454, 644, 824, 385, 575, 572, 1249, 1270, 1264, 42286, 42120, 42247, 527, - 485, 533, 1301, 1411, 1406, 1301, 1249, 1264, 43067, 42963, 42970, 63, 438, - 554, 1514, 2060, 1906, 42120, 41972, 41871, 41972, 41842, 41856, 41748, 41476, 41574, - 43813, 42805, 43732, 41458, 41522, 41574, 41458, 41312, 41522, 1478, 1514, 1531, 41842, - 41650, 41639, 41522, 41312, 41430, 43445, 43356, 43259, 43539, 43356, 43445, 41650, 41527, - 41547, 41430, 41312, 41353, 41240, 41430, 41353, 43837, 43559, 43796, 42597, 42509, 42727, - 42434, 42449, 42402, 42402, 42358, 42286, 42250, 42161, 42120, 42120, 42161, 41972, 41972, - 41978, 41842, 41842, 41680, 41650, 41650, 41680, 41527, 42597, 42727, 42765, 42727, 42963, - 43040, 42525, 42449, 42434, 43040, 42963, 43067, 1012, 1133, 981, 940, 1012, 981, - 1133, 1012, 1134, 995, 940, 992, 454, 417, 485, 1124, 1249, 1301, 385, - 566, 575, 575, 566, 630, 658, 850, 1008, 545, 566, 452, 42358, 42120, - 42286, 43067, 43268, 43169, 454, 485, 527, 485, 417, 513, 42161, 41978, 41972, - 43067, 42970, 43268, 417, 368, 513, 1315, 1298, 1406, 41663, 41574, 41522, 41853, - 41748, 41574, 41853, 41769, 41748, 41853, 41921, 41769, 41769, 41921, 41923, 1514, 1478, - 1406, 1531, 1514, 1632, 41430, 41663, 41522, 850, 1628, 1008, 43693, 43539, 43445, - 2251, 1872, 1906, 41173, 41284, 40825, 41372, 41284, 41173, 41718, 41284, 41372, 41718, - 41372, 41527, 43836, 43837, 43796, 43791, 43706, 43539, 658, 649, 630, 42893, 42765, - 42727, 42597, 42765, 42525, 42525, 42556, 42449, 42449, 42358, 42402, 42161, 42109, 41978, - 41936, 41680, 41842, 42893, 42727, 43040, 43103, 43040, 43067, 42970, 43356, 43268, 981, - 1133, 1084, 1012, 940, 995, 417, 269, 368, 1133, 1249, 1124, 1301, 1298, - 1124, 42478, 42358, 42449, 566, 545, 630, 385, 572, 438, 1315, 1406, 1381, - 864, 454, 824, 42358, 42250, 42120, 88, 385, 438, 43268, 43356, 43492, 1381, - 1406, 1478, 43169, 43247, 43103, 1387, 1381, 1478, 41663, 41853, 41574, 41921, 42324, - 41923, 42109, 41842, 41978, 155, 84, 368, 368, 84, 424, 1632, 1514, 1906, - 1872, 1632, 1906, 1055, 1480, 1628, 553, 658, 630, 553, 630, 545, 42358, - 42350, 42250, 42250, 42109, 42161, 42687, 42556, 42525, 42687, 42525, 42765, 42893, 43040, - 43103, 961, 940, 981, 961, 864, 940, 940, 864, 992, 328, 269, 417, - 1124, 1298, 1199, 1298, 1315, 1199, 1315, 1381, 1199, 42556, 42478, 42449, 452, - 553, 545, 42478, 42350, 42358, 43103, 43196, 43107, 43103, 43067, 43169, 385, 452, - 566, 457, 452, 312, 42296, 42324, 41921, 43103, 43247, 43196, 1199, 1381, 1387, - 42170, 42109, 42250, 41680, 41833, 41527, 328, 417, 454, 1387, 1478, 1448, 42109, - 41936, 41842, 41853, 41869, 41921, 41806, 41869, 41853, 41806, 41853, 41663, 41806, 41663, - 41752, 1448, 1478, 1531, 41936, 41802, 41680, 41752, 41663, 41430, 1494, 1448, 1531, - 1494, 1531, 1632, 41740, 41752, 41430, 1518, 1494, 1632, 42805, 43641, 43732, 42350, - 42326, 42250, 42109, 42148, 41936, 41936, 41944, 41802, 42478, 42453, 42350, 42556, 42687, - 42478, 42823, 42687, 42765, 42823, 42765, 42893, 43035, 42823, 42893, 42761, 43058, 42714, - 42324, 42506, 42349, 42351, 42506, 42324, 42351, 42324, 42296, 41921, 42110, 42296, 452, - 457, 553, 553, 509, 658, 1055, 1628, 850, 312, 452, 385, 1084, 1133, - 1124, 1084, 961, 981, 278, 328, 285, 1084, 1124, 1199, 1084, 1199, 1197, - 1199, 1387, 1314, 42110, 41869, 41993, 42453, 42326, 42350, 269, 155, 368, 328, - 454, 285, 1314, 1387, 1448, 42326, 42170, 42250, 42170, 42148, 42109, 42148, 42021, - 41936, 41802, 41833, 41680, 50, 155, 269, 42021, 41944, 41936, 63, 88, 438, - 41944, 41833, 41802, 1494, 1405, 1448, 1518, 1405, 1494, 1593, 1480, 1832, 542, - 850, 658, 41752, 41740, 41806, 41240, 41740, 41430, 1872, 1518, 1632, 42687, 42714, - 42478, 42347, 42216, 42170, 42170, 42216, 42148, 42148, 42197, 42021, 42021, 42098, 41944, - 41944, 41962, 41833, 42823, 42761, 42687, 43107, 42893, 43103, 457, 509, 553, 321, - 509, 457, 955, 847, 961, 961, 847, 864, 328, 278, 269, 955, 961, - 1084, 1314, 1448, 1405, 43169, 43346, 43247, 25, 312, 385, 42110, 41921, 41869, - 42351, 42427, 42506, 42805, 42517, 43641, 43169, 43268, 43346, 42347, 42170, 42326, 43346, - 43268, 43492, 41993, 41869, 41806, 43492, 43356, 43706, 41740, 41993, 41806, 43706, 43356, - 43539, 1418, 1314, 1405, 1518, 1418, 1405, 1474, 1418, 1518, 42761, 42714, 42687, - 43058, 42761, 42823, 43035, 42893, 43139, 42893, 43107, 43139, 43107, 43231, 43139, 43196, - 43231, 43107, 503, 509, 425, 503, 542, 509, 509, 542, 658, 493, 503, - 425, 43196, 43362, 43231, 42216, 42197, 42148, 42714, 42453, 42478, 43196, 43247, 43362, - 770, 454, 864, 1149, 955, 1084, 1197, 1199, 1314, 43362, 43247, 43346, 770, - 864, 847, 42304, 42197, 42216, 42144, 42110, 41993, 42144, 42255, 42110, 42110, 42255, - 42296, 42296, 42396, 42351, 42218, 42144, 41993, 43492, 43437, 43346, 43592, 43437, 43492, - 1149, 1197, 1314, 41987, 41962, 41944, 41833, 41718, 41527, 43791, 43539, 43824, 1418, - 1149, 1314, 1872, 1474, 1518, 41962, 41718, 41833, 43824, 43539, 43693, 43837, 43824, - 43693, 425, 509, 321, 503, 493, 542, 749, 1055, 850, 848, 770, 847, - 848, 847, 955, 848, 955, 883, 43131, 43035, 43139, 43131, 43058, 43035, 43035, - 43058, 42823, 42452, 42347, 42453, 42453, 42347, 42326, 42197, 42098, 42021, 41962, 42057, - 41718, 43131, 43139, 43304, 43139, 43231, 43304, 43346, 43437, 43362, 43437, 43584, 43362, - 321, 457, 312, 43492, 43706, 43592, 295, 321, 191, 1149, 1084, 1197, 278, - 206, 269, 770, 285, 454, 42452, 42453, 42701, 42427, 42396, 42459, 42255, 42396, - 42296, 285, 206, 278, 155, 50, 84, 42347, 42304, 42216, 43592, 43706, 43710, - 206, 50, 269, 42317, 42098, 42197, 42098, 41987, 41944, 43710, 43706, 43791, 43692, - 43710, 43754, 295, 425, 321, 295, 382, 425, 425, 382, 493, 336, 850, - 542, 42290, 42396, 42255, 42396, 42427, 42351, 42452, 42304, 42347, 42361, 42317, 42304, - 42304, 42317, 42197, 42098, 42057, 41987, 43131, 43281, 43058, 43362, 43304, 43231, 43475, - 43304, 43716, 43584, 43437, 43592, 206, 239, 50, 285, 239, 206, 109, 239, - 285, 467, 285, 770, 42453, 42714, 42701, 42144, 42290, 42255, 42218, 42290, 42144, - 42209, 42218, 41993, 43585, 43584, 43592, 1474, 1149, 1418, 848, 703, 770, 42274, - 42057, 42098, 41987, 42057, 41962, 42517, 42349, 43641, 619, 703, 848, 191, 321, - 312, 336, 542, 493, 42317, 42403, 42098, 42701, 42714, 43145, 42714, 43058, 43145, - 43641, 42349, 43605, 42389, 42459, 42396, 42389, 42396, 42290, 42452, 42361, 42304, 42218, - 42389, 42290, 88, 25, 385, 326, 493, 382, 42218, 42209, 42389, 41740, 42209, - 41993, 43716, 43304, 43362, 43692, 43585, 43592, 43692, 43592, 43710, 43754, 43710, 43791, - 42349, 42506, 43605, 43824, 43754, 43791, 256, 326, 382, 256, 382, 295, 43762, - 43585, 43692, 43281, 43304, 43475, 43281, 43131, 43304, 42538, 42403, 42361, 191, 256, - 295, 25, 191, 312, 43605, 42506, 43713, 42389, 42473, 42459, 42209, 42473, 42389, - 42538, 42361, 42452, 42361, 42403, 42317, 43732, 43877, 43813, 42506, 42427, 42753, 43754, - 43762, 43692, 43886, 43762, 43754, 42701, 42538, 42452, 43362, 43584, 43716, 61, 224, - 191, 191, 224, 256, 256, 264, 326, 326, 336, 493, 42585, 42538, 42868, - 42447, 42356, 42403, 42403, 42356, 42098, 42057, 42163, 41718, 43641, 43727, 43732, 42753, - 42427, 42459, 42356, 42274, 42098, 1149, 883, 955, 703, 467, 770, 1474, 1104, - 1149, 42274, 42163, 42057, 43860, 43716, 43585, 43824, 43886, 43754, 619, 467, 703, - 239, 74, 50, 264, 336, 326, 190, 264, 256, 659, 619, 848, 224, - 190, 256, 61, 190, 224, 42587, 42753, 42459, 42587, 42459, 42473, 281, 109, - 285, 42723, 42587, 42656, 109, 74, 239, 42274, 42559, 42163, 42356, 42447, 42274, - 42538, 42585, 42403, 42868, 42538, 42701, 43145, 43058, 43306, 1104, 883, 1149, 42585, - 42447, 42403, 43605, 43727, 43641, 43755, 43727, 43605, 43306, 43058, 43281, 42585, 42559, - 42447, 214, 293, 264, 264, 293, 336, 508, 749, 850, 43475, 43306, 43281, - 190, 214, 264, 61, 214, 190, 883, 659, 848, 314, 281, 467, 467, - 281, 285, 109, 131, 74, 43716, 43584, 43585, 43727, 43877, 43732, 43755, 43877, - 43727, 43755, 43605, 43713, 314, 467, 619, 25, 61, 191, 210, 276, 293, - 42587, 42723, 42753, 42656, 42587, 42473, 289, 314, 364, 883, 719, 659, 716, - 719, 883, 276, 336, 293, 508, 850, 336, 42209, 42656, 42473, 43220, 43145, - 43306, 43072, 42701, 43145, 42670, 42559, 42868, 42447, 42559, 42274, 43860, 43585, 43762, - 43373, 43220, 43306, 43713, 42506, 42753, 311, 314, 289, 281, 131, 109, 43373, - 43306, 43490, 110, 293, 214, 43490, 43306, 43475, 189, 131, 281, 61, 110, - 214, 43511, 43490, 43475, 43716, 43511, 43475, 43713, 42753, 43807, 43799, 43713, 43807, - 314, 311, 281, 289, 364, 296, 276, 303, 336, 210, 303, 276, 311, - 189, 281, 132, 210, 293, 43427, 43373, 43490, 43427, 43220, 43373, 43460, 43072, - 43220, 43220, 43072, 43145, 110, 132, 293, 61, 132, 110, 303, 508, 336, - 43511, 43526, 43490, 43625, 43526, 43511, 1104, 716, 883, 364, 619, 659, 42559, - 42670, 42163, 42868, 42559, 42585, 43745, 43625, 43511, 43886, 43860, 43762, 289, 172, - 311, 311, 172, 189, 189, 18, 131, 303, 193, 508, 210, 181, 303, - 23, 181, 210, 43072, 42868, 42701, 43526, 43427, 43490, 43499, 43427, 43526, 172, - 18, 189, 131, 18, 74, 43065, 42868, 43072, 43745, 43511, 43716, 43860, 43745, - 43716, 181, 237, 303, 119, 237, 181, 172, 62, 18, 314, 619, 364, - 43499, 43526, 43625, 43499, 43460, 43427, 43427, 43460, 43220, 43571, 43499, 43806, 43110, - 42753, 42723, 43713, 43861, 43755, 43755, 43861, 43877, 43799, 43861, 43713, 296, 179, - 289, 289, 179, 172, 237, 193, 303, 508, 439, 749, 119, 193, 237, - 119, 181, 23, 23, 210, 132, 364, 659, 441, 61, 23, 132, 441, - 659, 719, 193, 439, 508, 43799, 43807, 43861, 42656, 43110, 42723, 43110, 43807, - 42753, 193, 101, 439, 119, 143, 193, 23, 143, 119, 43757, 43499, 43625, - 43499, 43571, 43460, 43460, 43571, 43072, 42868, 43065, 42670, 43757, 43625, 43745, 716, - 441, 719, 106, 62, 296, 296, 62, 179, 43450, 43065, 43072, 43571, 43506, - 43072, 43830, 43757, 43745, 43860, 43830, 43745, 106, 296, 364, 179, 62, 172, - 143, 101, 193, 0, 101, 143, 43830, 43806, 43757, 43757, 43806, 43499, 43583, - 43885, 43807, 43807, 43885, 43861, 101, 0, 439, 23, 0, 143, 43593, 43506, - 43685, 43110, 43583, 43807, 441, 106, 364, 43506, 43450, 43072, 43506, 43502, 43450, - 43685, 43506, 43571, 43685, 43571, 43806, 43878, 43685, 43806, 441, 28, 106, 106, - 28, 62, 43664, 43502, 43593, 43593, 43502, 43506, 43450, 43502, 43065, 43685, 43664, - 43593, 43830, 43878, 43806, 43878, 43664, 43685, 43583, 43868, 43885, 43878, 43913, 43664, - 43664, 43913, 43502 - }; - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/triangle_indices.h b/unittests/tntn/triangle_indices.h deleted file mode 100644 index 71c693a..0000000 --- a/unittests/tntn/triangle_indices.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -namespace tntn { -namespace unittests { - void init_triangle_list(std::vector& data); -} -} // namespace tntn diff --git a/unittests/tntn/triangle_indices_data.cpp b/unittests/tntn/triangle_indices_data.cpp deleted file mode 100644 index ea54245..0000000 --- a/unittests/tntn/triangle_indices_data.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "triangle_indices.h" - -namespace tntn { -namespace unittests { - - void init_triangle_list(std::vector& data) - { - - data = { 1, 43913, 43664 }; - /* - data = {20719,20633,20715,20633,20575,20715,20719,20422,20633,20633,20422,20575,20719,20816,20422,20715,20816,20719,20715,20952,20816,20575,20903,20715,20715,21270,20952,20816,20659,20422,20952,20659,20816,20903,21270,20715,20903,21261,21270,20903,21222,21261,21270,21401,20952,20952,21189,20659,21395,21401,21270,20659,20525,20422,20419,20525,20803,21343,21395,21270,21261,21343,21270,21375,21343,21261,20575,20169,20903,20903,21317,21222,20039,20129,20575,20039,20575,20422,21222,21375,21261,19960,20039,19912,20129,20169,20575,21401,21458,20952,21454,21446,21401,21454,21401,21395,21454,21395,21343,21456,21454,21343,21446,21458,21401,20129,20106,20169,20051,20106,20129,19912,20039,19845,20039,20051,20129,21458,21473,20952,21375,21456,21343,21478,21456,21375,19845,20039,20422,21222,21478,21375,21446,21590,21458,21458,21570,21473,21454,21590,21446,21545,21590,21454,21545,21454,21456,21605,21545,21456,19960,20051,20039,19970,20051,19960,21065,21317,20903,21222,21507,21478,20106,20099,20169,20824,21065,20903,20051,20099,20106,19799,19845,20422,20525,19799,20422,20962,20525,20659,21317,21507,21222,21478,21605,21456,21685,21570,21458,21501,21189,20952,21695,21605,21478,19925,19970,19960,20051,20040,20099,19925,19960,19912,19845,19842,19912,19842,19925,19912,20099,20071,20169,20040,20071,20099,21501,20952,21473,21590,21698,21458,21545,21698,21590,21887,21698,21545,21698,21685,21458,21633,21501,21473,19980,19799,20525,21189,20962,20659,21685,21661,21570,19970,20040,20051,19958,20040,19970,21633,21473,21570,19845,19766,19842,19842,19735,19925,19722,19958,19970,19645,19766,19845,21189,21001,20962,21086,21001,21189,20824,20903,20169,21652,21695,21507,20824,20169,20287,21661,21633,21570,20287,20169,20071,19570,19673,19845,20419,19980,20525,19722,19970,19925,20040,20017,20071,21418,21086,21189,21507,21695,21478,21605,21767,21545,21652,21507,21317,21698,21799,21685,21685,21799,21661,21661,21839,21633,21887,21799,21698,19958,20017,20040,19673,19645,19845,19766,19735,19842,19684,19735,19766,21633,21671,21501,21501,21418,21189,21736,21671,21633,21769,21652,21750,21695,21767,21605,19645,19684,19766,20132,20287,20071,21001,21029,20962,20962,20803,20525,20013,19732,19980,21086,21029,21001,21096,21029,21086,21761,21767,21695,19958,19946,20017,20017,20132,20071,19892,19946,19958,19496,19570,19845,19673,19606,19645,19645,19634,19684,21029,20803,20962,21839,21736,21633,19570,19606,19673,19735,19722,19925,19585,19722,19735,19585,19735,19684,19606,19634,19645,20011,20132,20017,21736,21782,21671,21671,21775,21501,21652,21761,21695,21769,21761,21652,19634,19585,19684,21799,21839,21661,21736,21845,21782,22068,21839,21799,21887,21545,21767,21893,21887,21767,19799,19496,19845,19570,19525,19606,19606,19525,19634,19634,19493,19585,19372,19496,19246,19946,20011,20017,19966,20011,19946,20287,20512,20824,20824,20811,21065,20358,20512,20287,20358,20287,20201,21782,21775,21671,21896,21775,21782,21750,21652,21317,21761,21893,21767,21839,21845,21736,21852,21893,21761,19431,19525,19570,19525,19493,19634,19585,19115,19722,19722,19892,19958,19882,19892,19758,20073,20287,20132,20011,20073,20132,19957,20073,20011,21769,21852,21761,19892,19966,19946,21065,21750,21317,21769,21889,21852,21862,21750,21970,21845,21896,21782,21330,21096,21086,21750,21889,21769,20073,20201,20287,20146,20201,20073,20803,20631,20419,20971,20631,20803,21096,20803,21029,20512,20625,20824,20568,20625,20512,20568,20512,20358,21706,21501,21775,19496,19431,19570,19525,19486,19493,20377,20568,20358,19892,19882,19966,19966,19957,20011,19758,19892,19722,21896,21706,21775,19431,19486,19525,19493,19486,19585,20201,20377,20358,21845,21921,21896,21896,21809,21706,21839,21921,21845,22068,21921,21839,22068,21799,22545,22062,21887,21893,22062,21893,21852,19882,19957,19966,20201,20146,20377,21750,21862,21889,21889,21938,21852,21938,21862,21970,19957,20146,20073,19496,19372,19431,19431,19416,19486,19202,19496,19799,20625,20811,20824,20568,20587,20625,20620,20587,20417,20587,20568,20417,21706,21418,21501,21907,21809,21896,21706,21812,21418,19372,19416,19431,19115,19758,19722,21330,21210,21096,21096,20971,20803,21418,21330,21086,21921,21907,21896,21862,21938,21889,21970,21860,22027,21103,20971,21096,19980,19732,19799,20013,19980,20419,19115,19585,19486,19882,19828,19957,19957,19877,20146,21330,21269,21210,21210,21103,21096,22027,21860,22088,21163,21103,21210,22545,21799,21887,21921,22051,21907,22062,21852,21938,19372,19246,19416,19202,19246,19496,20587,20811,20625,20417,20568,20377,20620,20811,20587,20146,20417,20377,20454,20417,20146,22068,22051,21921,21907,21926,21809,21809,21926,21706,21477,21372,21330,21330,21372,21269,22174,22062,21938,19416,19235,19486,19159,19235,19416,19758,19828,19882,19797,19828,19746,22033,21926,21907,21103,21054,20971,20971,21050,20631,20013,19669,19732,21163,21054,21103,19828,19877,19957,22051,22033,21907,22150,22033,22051,20620,20588,20811,20417,20588,20620,20745,20523,20718,21477,21330,21418,21269,21163,21210,19246,19159,19416,19746,19828,19758,19143,19159,19246,21372,21163,21269,19828,19797,19877,19877,19798,20146,19115,19486,19235,21970,21750,21860,21970,22027,21938,19159,19204,19235,21054,21050,20971,21163,21050,21054,21679,21477,21418,21372,21407,21163,21163,21199,21050,21679,21418,21812,22033,22150,21926,22068,22150,22051,20013,20419,20631,19732,19202,19799,21812,21706,21926,21477,21407,21372,21391,21407,21477,22027,22174,21938,22062,22545,21887,22343,22170,22150,20588,20745,20811,20811,21156,21065,20745,20588,20523,20745,20772,20811,22027,22078,22174,22088,22078,22027,19669,19202,19732,21288,21199,21163,18999,19143,19246,19159,19143,19204,19204,19069,19235,21993,21812,21926,21391,21288,21407,22150,21993,21926,22078,22173,22174,21106,20013,20631,21407,21288,21163,21391,21477,21679,19143,19069,19204,19656,19746,19758,19797,19798,19877,19069,19129,19235,21943,21391,21679,19746,19798,19797,22150,22170,21993,22343,22150,22068,19202,18999,19246,19143,19054,19069,19069,19054,19129,20745,20718,20772,20772,20941,20811,20523,20588,20417,21993,21929,21812,21812,21848,21679,22104,21929,21993,19129,19115,19235,18930,19115,19129,20454,20523,20417,21929,21848,21812,20718,20859,20772,22170,22104,21993,21860,21750,21065,22078,22221,22173,20859,20941,20772,21288,21284,21199,21199,21172,21050,21050,21106,20631,21391,21284,21288,21249,21284,21391,19746,19779,19798,19798,19844,20146,19656,19779,19746,22088,22221,22078,18809,19054,19143,20941,21003,20811,19779,19844,19798,22221,22277,22173,22173,22322,22174,22174,22322,22062,22277,22322,22173,19316,19656,19076,19779,19750,19844,20718,20808,20859,20859,20963,20941,20941,21038,21003,20523,20751,20718,20492,20751,20523,21284,21172,21199,21249,21172,21284,21003,21156,20811,21094,21156,21003,22170,22217,22104,22119,21989,21929,21929,21943,21848,22258,22217,22170,22597,22545,22062,20454,20492,20523,20751,20808,20718,19844,20454,20146,22388,22343,22068,19656,19750,19779,19889,20373,20454,22343,22258,22170,19115,18983,19758,18930,18983,19115,21941,21249,21391,21943,21679,21848,20963,21038,20941,21989,21943,21929,21929,22104,22119,19054,18930,19129,18809,18930,19054,21172,21106,21050,21249,21106,21172,21038,21094,21003,22280,22285,22088,22499,22388,22068,22343,22374,22258,19656,19667,19750,19750,19658,19844,19592,19667,19656,22088,22285,22221,22221,22285,22277,22277,22439,22322,21860,21065,21156,22564,22597,22062,22545,22499,22068,22564,22062,22322,22502,22439,22277,18999,18809,19143,18333,18809,18999,21943,22047,21391,22119,22104,22217,22374,22217,22258,22420,22374,22343,20808,20963,20859,21038,20963,21094,20827,20963,20808,20827,20808,20751,20827,20751,20492,22578,22499,22723,22388,22420,22343,21604,21860,21156,21226,21156,21094,22479,22420,22388,22346,22119,22217,18983,18940,19758,18820,18929,18983,18820,18983,18930,22499,22546,22388,22578,22546,22499,22439,22564,22322,22455,22217,22374,21989,22047,21943,21249,21720,21106,18733,18820,18930,20963,21226,21094,18929,18940,18983,18769,18940,18929,22546,22479,22388,22420,22455,22374,22578,22479,22546,19667,19658,19750,19520,19592,19340,21226,21258,21156,22435,22502,22277,22439,22632,22564,22435,22277,22285,19592,19658,19667,21285,21217,21033,22598,22455,22420,22513,22435,22528,22723,22499,22758,22479,22598,22420,18809,18733,18930,18820,18790,18929,22119,22047,21989,22081,22047,22119,18733,18712,18820,20963,21217,21226,21226,21217,21258,21258,21604,21156,20373,20492,20454,22435,22471,22502,22502,22632,22439,22578,22598,22479,18712,18790,18820,19520,19658,19592,21217,21248,21258,22758,22499,22545,22578,22728,22598,22758,22545,22850,19889,20454,19844,21217,21285,21248,22346,22081,22119,22047,21941,21391,22471,22632,22502,22850,22545,23049,19658,19651,19844,19520,19651,19658,19592,19656,19340,22435,22508,22471,22471,22590,22632,22513,22508,22435,22435,22285,22528,18790,18769,18929,21248,21333,21258,21285,21333,21248,18733,18695,18712,18712,18546,18790,18790,18546,18769,18620,18695,18733,18620,18733,18809,19656,19758,19076,18769,18898,18940,22508,22590,22471,22850,23049,22998,22597,23049,22545,22723,22728,22578,22280,22088,21860,22508,22554,22590,19076,19758,18940,22393,22280,21860,18898,19076,18940,19316,19340,19656,21033,21217,20963,21333,21604,21258,19340,19466,19520,19520,19623,19651,21434,21604,21333,22513,22554,22508,22798,22564,22632,22528,22554,22513,18433,18620,18809,18695,18546,18712,18769,18748,18898,21285,21397,21333,22280,22528,22285,22758,22728,22723,22598,22881,22455,22455,22346,22217,19202,18567,18999,18293,18567,19202,19211,19202,19669,22798,22632,22590,22758,22834,22728,18822,18936,19076,18694,18748,18769,19412,19211,19669,19412,19669,20013,19316,19301,19340,19301,19484,19466,19076,19157,19316,19074,19157,19076,22411,22346,22582,19484,19623,19520,19651,19889,19844,19484,19520,19466,21397,21434,21333,21604,21655,21860,18620,18546,18695,19301,19466,19340,20373,20827,20492,21285,21455,21397,21397,21455,21434,20735,20827,20373,22850,22834,22758,22728,22881,22598,18748,18717,18898,18694,18717,18748,21434,21565,21604,21455,21565,21434,22346,22249,22081,22081,22228,22047,22411,22249,22346,22834,22898,22728,19157,19301,19316,19074,19301,19157,22249,22228,22081,18620,18503,18546,18538,18694,18769,18433,18503,18620,18538,18769,18546,18822,19076,18898,22554,22798,22590,22739,22798,22554,22850,22979,22834,22834,22979,22898,23053,22597,22564,18822,18898,18717,19465,19412,20013,19623,19889,19651,19666,19889,19623,19474,19623,19484,21449,21455,21285,21565,21655,21604,22898,22881,22728,23069,22881,22898,18503,18538,18546,22998,22979,22850,18787,18822,18717,19299,19474,19484,20032,20735,20373,20827,21033,20963,22799,22739,22554,23128,23053,22564,22799,22554,22528,22799,22528,22764,19889,20032,20373,18906,19074,19076,19301,19299,19484,18906,19076,18936,21455,21572,21565,21449,21572,21455,22582,22346,22455,22363,22210,22228,18333,18433,18809,18503,18308,18538,18763,18906,18936,19074,19299,19301,22228,22210,22047,22363,22228,22249,22871,22564,22798,22998,23023,22979,20735,21033,20827,23233,23049,22597,22979,23122,22898,21572,21655,21565,21541,21655,21572,22764,22528,22786,22739,22871,22798,22832,22871,22739,23049,23023,22998,18682,18787,18717,18822,18763,18936,18682,18717,18583,21334,21449,21285,23023,23122,22979,22494,22363,22411,18906,19050,19074,19074,19050,19299,18912,19050,18906,22411,22363,22249,22378,22363,22494,18763,18912,18906,22799,22832,22739,22871,23128,22564,18583,18717,18694,18787,18763,18822,18583,18694,18538,22210,21941,22047,21106,20994,20013,22275,21941,22210,22786,22528,22566,22799,22844,22832,21449,21541,21572,22870,22786,22944,21497,21541,21449,18567,18333,18999,18143,18333,18567,18433,18308,18503,18201,18286,18433,18286,18308,18433,17867,18583,18538,18669,18763,18787,22764,22844,22799,23141,23128,22871,23049,23192,23023,23023,23137,23122,23233,23192,23049,22393,21860,21655,22764,22870,22844,22363,22378,22210,22582,22455,23006,21334,21497,21449,21541,21646,21655,23122,23069,22898,23132,23069,23122,23006,22455,22881,23192,23137,23023,23005,22871,22832,23053,23233,22597,18669,18787,18682,18684,18897,19050,21497,21585,21541,18293,18364,18567,18293,19202,19211,18472,18669,18682,18333,18201,18433,18286,18178,18308,18308,18222,18538,18583,18472,18682,18030,18201,18333,23413,23233,23053,23192,23276,23137,18201,18178,18286,22582,22494,22411,22378,22275,22210,22543,22494,22649,21033,21334,21285,21497,21334,21585,21278,21334,21033,22844,23005,22832,22936,23005,22844,23137,23132,23122,23069,23186,22881,23475,23132,23137,21585,21646,21541,21554,21646,21585,18178,18190,18308,22786,22870,22764,22566,22528,22280,22350,22275,22378,18190,18222,18308,23386,23276,23192,17867,18472,18583,19474,19666,19623,19889,19666,20032,20522,20967,20735,21174,21278,21033,19230,19666,19474,19230,19474,19145,19474,19299,19049,22870,22936,22844,23005,23141,22871,23132,23186,23069,23317,23186,23132,22494,22543,22378,22649,22494,22582,20967,21033,20735,21334,21439,21585,21646,22393,21655,23030,23055,22936,22659,22649,22582,22393,22566,22280,22543,22350,22378,22287,22041,21941,18364,18143,18567,18201,17998,18178,18178,18027,18190,18190,18027,18222,23435,23413,23635,23233,23386,23192,23475,23317,23132,20522,20735,20032,21720,20994,21106,22287,21941,22275,23413,23386,23233,22936,23055,23005,23576,23435,23635,23030,22936,22870,23186,23170,22881,23317,23170,23186,20967,21174,21033,21278,21392,21334,22533,22608,22393,23006,22659,22582,22649,22644,22543,22644,22326,22350,18472,18527,18669,18669,18527,18763,19049,19299,19050,17867,18527,18472,23170,23006,22881,22350,22326,22275,22644,22350,22543,23475,23137,23276,21174,21294,21278,22326,22287,22275,18143,18030,18333,18222,17867,18538,23055,23141,23005,23208,23141,23055,22041,21720,21941,22115,21994,22041,22944,23030,22870,18030,17998,18201,23413,23435,23386,23386,23453,23276,23413,23053,23635,21294,21392,21278,17998,18027,18178,21720,21249,21941,22668,22644,22649,22385,22252,22287,22668,22649,22659,23435,23453,23386,22771,22668,22861,21392,21439,21334,21994,21720,22041,22287,22115,22041,21994,21969,21720,22252,22115,22287,21439,21554,21585,22385,22287,22326,22115,22057,21994,22063,22057,22115,23030,23208,23055,23635,23053,23649,23215,23208,23030,22944,22786,22566,18143,17901,18030,18030,17960,17998,17998,17993,18027,17982,17901,18143,17901,17960,18030,18027,17760,18222,17985,17982,18143,17960,17993,17998,23435,23524,23453,23453,23475,23276,23880,23128,23141,23730,23475,23453,23458,23006,23170,23120,22659,23006,22861,22668,22659,18364,17985,18143,17830,17985,17800,23576,23524,23435,22057,21969,21994,21720,21445,20994,22120,21969,22057,23208,23260,23141,21439,21438,21554,23016,22566,22393,21392,21438,21439,21294,21438,21392,21448,21438,21294,21448,21294,21174,22195,22063,22115,22544,22385,22326,22648,22326,22644,23016,22944,22566,23208,23245,23260,21793,21646,21554,18277,18293,19211,18277,19211,18673,22195,22115,22252,21829,21721,21720,21438,21600,21554,22668,22771,22644,22861,22659,23120,20994,19465,20013,23215,23245,23208,23649,23053,23128,21969,21829,21720,21721,21445,21720,21838,21829,21930,23120,23006,23327,19049,19050,18897,19666,19631,20032,21424,21448,21400,22338,22195,22252,22063,22120,22057,22338,22252,22385,17901,17873,17960,17960,17873,17993,17993,17760,18027,17794,17873,17901,17837,17901,17982,19050,18912,18633,23387,23141,23260,23576,23730,23524,23524,23730,23453,17985,17837,17982,17830,17837,17985,17800,17985,18364,23635,23730,23576,19049,19145,19474,23245,23387,23260,23333,23387,23245,19230,19419,19666,19310,19419,19230,22195,22120,22063,22099,22120,22290,23880,23649,23128,21591,21445,21721,20994,20159,19465,21728,21721,21829,21438,21448,21600,23428,23215,23571,21573,21448,21424,21838,21728,21829,22771,22820,22644,22943,22820,22771,18673,19211,19412,18293,18079,18364,19145,19222,19230,22944,23215,23030,21676,21554,21600,22820,22648,22644,22648,22544,22326,21728,21591,21721,21448,21550,21600,19419,19449,19666,19310,19449,19419,19449,19631,19666,21930,21829,21969,21728,21641,21591,21930,21969,22026,23327,23006,23401,22861,22943,22771,23006,23458,23401,21742,21641,21728,21550,21676,21600,17837,17794,17901,17873,17785,17993,17653,17794,17837,17794,17785,17873,22544,22338,22385,23635,23823,23730,23730,23822,23475,23931,23823,23635,18842,18673,19412,18107,18079,18293,17830,17800,17837,18107,18293,18277,22099,21969,22120,21838,21742,21728,22290,22120,22195,22648,22663,22544,22525,22325,22338,22820,22663,22648,22770,22663,22820,23215,23333,23245,23387,23498,23141,23513,23498,23387,23823,23822,23730,18633,18912,18763,19049,18954,19145,19145,19003,19222,19222,19310,19230,18633,18763,18457,23120,22943,22861,17712,17800,18364,21851,21742,21838,21676,21793,21554,22338,22290,22195,22182,22290,22283,18897,18954,19049,17619,17760,17993,17760,17768,18222,18954,19003,19145,19449,19489,19631,21591,21575,21445,21425,20809,20994,21641,21575,21591,21667,21575,21641,21550,21573,21676,21676,21658,21793,21448,21573,21550,21448,21174,21400,21930,21851,21838,21742,21667,21641,22099,22026,21969,22182,22026,22099,23333,23513,23387,24009,23888,24103,18104,18107,18277,19096,19310,19222,21992,21851,21930,18457,18763,18527,18897,18807,18954,18954,18807,19003,18633,18684,19050,19003,19096,19222,18985,19096,19003,22916,22770,22820,22663,22752,22544,23170,23875,23458,23120,23160,22943,22943,22999,22820,21573,21658,21676,23428,23333,23215,23020,22999,22943,17794,17653,17785,17785,17619,17993,17760,17615,17768,17583,17653,17837,23888,23931,23635,23823,23857,23822,23822,24045,23475,23888,23635,23649,23880,23141,23498,19465,18842,19412,18010,18104,18277,18804,18807,18897,20315,20522,20032,21573,21674,21658,20315,20032,19631,21425,20994,21445,19465,18756,18842,19310,19373,19449,19245,19373,19310,23333,23466,23513,23768,23880,23498,23428,23466,23333,22393,21646,22533,17690,17712,18364,17800,17641,17837,17956,17911,18079,23931,23857,23823,23170,23317,23875,23327,23160,23120,23857,23887,23822,23251,23160,23327,17768,17867,18222,21658,21752,21793,21674,21752,21658,17712,17641,17800,21400,21174,20967,18807,18985,19003,19096,19245,19310,17690,18364,18079,18107,17956,18079,17855,17956,17987,19373,19489,19449,19356,19489,19373,18970,19245,19096,22290,22182,22099,21992,21882,21851,21851,21882,21742,22325,22290,22338,23875,23317,23475,23411,23251,23327,22770,22752,22663,22990,22916,22820,22990,22820,22999,18633,18604,18684,18684,18804,18897,18807,18804,18985,18449,18457,18165,22916,22752,22770,23020,22990,22999,23020,22943,23160,21992,21930,22026,21575,21425,21445,18604,18804,18684,23217,23020,23160,18052,18104,18010,22525,22338,22544,21882,21667,21742,21424,21674,21573,23612,23428,23665,21532,21674,21424,17690,18079,17911,19489,19502,19631,19356,19502,19489,20522,21400,20967,22694,22525,22544,23411,23327,23401,23768,23498,23513,23888,24009,23931,23931,23983,23857,23857,24055,23887,24037,24009,24103,17571,17583,17837,17653,17619,17785,17768,17617,17867,17571,17837,17641,22116,21992,22026,21882,21792,21667,22325,22283,22290,22257,22283,22342,23428,23571,23665,23466,23595,23513,24009,23983,23931,24045,23875,23475,17618,17571,17641,17497,17619,17653,17462,17618,17517,18985,18970,19096,19245,19356,19373,18804,18970,18985,21667,21425,21575,21686,21425,21667,23589,23411,23401,18457,18604,18633,18804,18574,18970,18481,18604,18457,19502,20315,19631,21304,21332,21400,22752,22825,22544,22841,22825,22752,22931,22752,22916,22931,22916,22990,23046,22990,23020,23217,23160,23251,17619,17615,17760,17956,17855,17911,17987,17956,18107,22116,22026,22182,23428,23595,23466,22825,22694,22544,22257,22182,22283,22257,22116,22182,23450,23217,23251,17787,17690,17911,17513,17517,17641,17855,17787,17911,17615,17586,17768,18449,18481,18457,19266,19356,19245,20003,20268,20315,21992,21916,21882,22283,22325,22422,18104,17987,18107,17658,17635,17787,18052,17987,18104,22422,22325,22525,23428,23612,23595,23595,23639,23513,21646,21793,22533,22044,21916,21992,17584,17590,17712,17584,17712,17690,18604,18487,18804,18970,19266,19245,18457,18527,18165,21400,21332,21424,21387,21332,21304,23046,22931,22990,22825,22841,22694,22686,22422,22525,17583,17497,17653,17619,17503,17615,17615,17528,17586,17376,17497,17583,17515,17583,17571,17515,17571,17618,18165,18527,18060,22931,22841,22752,23217,23046,23020,23253,23046,23217,24009,24037,23983,23983,24055,23857,24103,23888,23649,24037,24097,23983,23458,23589,23401,17462,17515,17618,18010,18277,18673,22686,22525,22694,17787,17635,17690,17658,17787,17855,21916,21792,21882,24045,23822,23887,23411,23450,23251,17517,17618,17641,24097,24055,23983,17582,17584,17690,17513,17641,17712,17586,17617,17768,17461,17617,17586,19097,18756,19465,18842,18756,18673,17382,17503,17619,23880,24103,23649,24302,24103,24537,19200,19266,18970,19356,19352,19502,23875,23645,23458,23612,23639,23595,21916,21949,21792,22116,22044,21992,22155,22044,22116,22155,22116,22257,17513,17712,17590,22422,22342,22283,22472,22342,22422,22533,21793,22092,23612,23665,23639,21793,21752,22092,23713,23589,23458,17613,17582,17690,17458,17513,17590,17458,17590,17370,17503,17528,17615,17662,18010,18673,18052,17935,17987,17351,17613,17280,17635,17613,17690,22092,21752,21995,18481,18487,18604,18340,18487,18481,18340,18481,18449,17356,17458,17370,22381,22155,22257,21693,21686,21788,21995,21752,21674,23639,23768,23513,23879,23768,23639,24055,24045,23887,17809,17855,17987,17356,17385,17458,21792,21686,21667,20877,20691,20809,21985,21916,22044,23645,23713,23458,23531,23450,23411,23748,23713,23645,23748,23645,23930,18060,18527,17628,18010,17935,18052,21332,21442,21424,21304,21400,20522,20809,20159,20994,20877,20809,21425,23010,22686,22694,22106,21985,22155,23010,22694,22841,23010,22841,22931,23183,22931,23046,24037,24221,24097,24097,24174,24055,24055,24242,24045,24302,24221,24037,17515,17376,17583,17240,17382,17619,17503,17358,17528,17462,17376,17515,17430,17376,17462,17430,17462,17517,17430,17517,17406,24221,24174,24097,21514,20877,21425,17617,17454,17867,17528,17461,17586,17443,17461,17528,21387,21442,21332,23531,23411,23589,22155,21985,22044,22106,22155,22262,17406,17517,17513,17406,17513,17385,17240,17619,17497,23571,23215,22944,17385,17513,17458,17382,17358,17503,20372,20159,20809,18165,18340,18449,19152,19200,19030,18247,18340,18165,21442,21532,21424,17935,17809,17987,18010,17977,17935,17662,17977,18010,22686,22472,22422,23748,23531,23589,23748,23589,23713,23525,23571,22944,23697,23571,23839,23450,23253,23217,22686,22646,22472,23271,23253,23374,17590,17584,17370,17977,17809,17935,17370,17584,17423,19266,19352,19356,18574,18804,18487,19238,19352,19266,22381,22257,22342,21788,21686,21792,21686,21693,21425,23930,23645,23875,24017,23930,23875,17584,17582,17423,17461,17454,17617,17380,17454,17461,21177,21304,20522,21387,21373,21442,21442,21471,21532,20268,20522,20315,21949,21916,21985,22127,21949,21985,23665,23879,23639,23571,23697,23665,17628,18527,17867,17423,17582,17613,24221,24245,24174,24407,24242,24055,24074,24017,23875,24302,24245,24221,24302,24037,24103,24302,24364,24402,21949,21788,21792,21693,21514,21425,22486,22381,22342,22821,22646,22686,24560,23880,23768,17809,17658,17855,17280,17658,17032,20003,20315,19965,19200,19238,19266,19152,19238,19200,23760,23879,23665,18340,18414,18487,18324,18414,18340,22486,22342,22472,22106,22127,21985,21949,21951,21788,17328,17423,17351,17312,17443,17528,20691,20372,20809,20734,20372,20691,20734,20691,20877,21516,21514,21693,21471,21995,21532,21532,21995,21674,22092,22992,22533,23183,23010,22931,24074,24291,24150,23930,23980,23748,20315,19896,19965,22646,22486,22472,22596,22486,22646,17406,17326,17430,17061,17254,17376,17240,17299,17382,17382,17299,17358,17358,17312,17528,17385,17326,17406,17309,17326,17385,17309,17385,17356,17309,17356,17283,17254,17497,17376,17443,17380,17461,17454,17386,17867,17333,17380,17443,21703,21516,21693,20840,20734,20877,21703,21693,21788,23010,22821,22686,17283,17356,17370,17299,17312,17358,19030,19200,18970,19238,19325,19352,20159,19907,19465,20310,20133,20159,21195,21177,21117,21304,21373,21387,22381,22262,22155,22297,22262,22320,24407,24055,24174,22180,22127,22106,24017,23945,23930,23748,23951,23531,23271,23046,23253,23271,23183,23046,24128,23945,24017,23697,23760,23665,23839,23760,23697,23016,22393,22608,17380,17442,17454,17333,17442,17380,21177,21262,21304,22008,21951,21949,24254,23875,24045,18414,18574,18487,18247,18324,18340,23253,23450,23374,23010,22938,22821,23183,23102,23010,22992,23016,22608,23624,23016,23216,23374,23558,23437,22622,22320,22381,22821,22596,22646,22908,22596,22821,21262,21373,21304,23102,22938,23010,23374,23450,23558,24242,24240,24045,17442,17386,17454,17762,18247,18165,17333,17386,17442,19152,19325,19238,19150,19325,19152,22262,22180,22106,22127,22008,21949,22297,22180,22262,23945,23980,23930,24128,23980,23945,17061,17376,17430,17299,17220,17312,17270,17430,17326,20840,20877,20853,20372,20310,20159,24245,24437,24174,24242,24429,24240,24402,24437,24245,24402,24245,24302,24364,24302,24537,17254,17208,17497,17312,17288,17443,18305,18574,18414,24391,24103,23880,17208,17240,17497,21951,21864,21788,22180,22008,22127,17423,17328,17370,17309,17270,17326,17351,17423,17613,21373,21471,21442,24240,24254,24045,24074,24128,24017,24552,24254,24240,23525,23839,23571,23760,23985,23879,24560,24391,23880,20642,20310,20372,21945,21864,21951,21516,21475,21514,17283,17270,17309,17240,17220,17299,17285,17351,17280,17328,17283,17370,24437,24407,24174,19030,19150,19152,20315,19502,19896,23878,23985,23760,24155,24128,24074,23980,23951,23748,17296,17628,17867,18680,19030,18970,23839,23878,23760,23843,23878,23839,17220,17288,17312,18110,18247,17762,18324,18305,18414,19007,19122,19030,18247,18305,18324,21177,21195,21262,21262,21271,21373,21373,21271,21471,21117,21177,20522,23271,23307,23183,23183,23311,23102,23102,23071,22938,22938,22908,22821,23437,23307,23271,23311,23307,23437,24407,24429,24242,24291,24074,23875,23311,23071,23102,17147,17333,17443,17386,17296,17867,21864,21703,21788,21864,21705,21703,22008,21945,21951,21958,21945,21982,22297,22008,22180,22262,22381,22320,24155,24150,24322,20133,19907,20159,20202,20025,20133,19502,19561,19896,20924,21117,20522,21195,21271,21262,24560,23768,24567,23016,23525,22944,17156,17283,17328,20025,19947,20133,19502,19352,19561,24107,23951,23980,24132,23980,24128,23878,23952,23985,23985,24079,23879,23995,23952,23878,24155,24132,24128,17333,17308,17386,17258,17308,17333,17254,17185,17208,17208,17144,17240,17240,17144,17220,17220,17141,17288,17086,17185,17254,17086,17254,17061,20734,20642,20372,20310,20202,20133,20025,20035,19947,20840,20642,20734,23914,23843,23839,24150,24155,24074,24291,23875,24254,20853,20877,21074,17185,17144,17208,17288,17147,17443,21074,20877,21514,24391,24537,24103,24364,24537,24402,24402,24698,24437,24437,24464,24407,24407,24464,24429,19947,19907,20133,19929,19907,19947,19561,19352,19325,21612,21475,21516,21612,21516,21703,23307,23311,23183,22320,22622,22416,23437,23271,23374,21475,21074,21514,24372,24291,24495,22908,22938,23071,21705,21612,21703,23558,23450,23701,24132,24107,23980,23701,23450,23787,24322,24107,24132,24094,24107,24146,23952,24079,23985,24210,24079,23952,21958,21864,21945,21042,20981,21074,17144,17141,17220,20277,20202,20310,21126,21117,20924,21195,21170,21271,20089,20268,20003,20089,20003,19982,23843,23995,23878,24201,23995,24147,24994,24464,24437,24429,24489,24240,23450,23531,23787,17141,17133,17288,19982,20003,19965,21117,21170,21195,21271,21254,21471,22198,22589,21995,19106,19561,19325,19896,19914,19965,19122,19325,19150,21982,21945,22008,17351,17156,17328,17283,17119,17270,17280,17613,17635,17280,17635,17658,23303,22908,23071,23787,23531,24042,20202,20035,20025,24464,24489,24429,19030,19122,19150,18680,18970,18574,22381,22486,22622,22128,21982,22008,24107,24094,23951,24322,24132,24155,18185,18680,18574,18275,18574,18305,24042,23531,23951,17156,17119,17283,20035,19929,19947,19907,19701,19465,24489,24552,24240,24291,24322,24150,17108,17280,17101,17285,17156,17351,21870,21705,21864,21042,21074,21115,21870,21864,21958,17308,17296,17386,17762,18165,18060,17258,17296,17308,18247,18110,18305,18105,18110,17990,22293,22008,22297,24372,24322,24291,18110,18275,18305,23016,23485,23525,23525,23914,23839,23624,23485,23016,22608,22533,22992,20642,20277,20310,20202,20090,20035,20035,20047,19929,20840,20640,20642,20821,20640,20840,20821,20840,20853,20821,20853,20981,17061,17430,17270,17185,16953,17144,17144,16925,17141,17141,16962,17133,20981,20853,21074,17096,17156,17285,16956,17061,17270,19825,19914,19896,23437,23335,23311,23311,23335,23071,23558,23609,23437,23683,23609,23558,23683,23558,23701,24552,24460,24254,24537,24590,24402,24703,24552,24489,24703,24460,24552,24760,24601,24460,24670,24590,24537,24670,24537,24391,16956,17270,17119,24787,24670,24841,17147,17258,17333,21982,21870,21958,21074,21475,21115,24495,24291,24254,22320,22293,22297,21982,22225,21870,22416,22293,22320,23781,23683,23701,23781,23701,23787,18680,19007,19030,19122,19106,19325,19561,19825,19896,20640,20277,20642,17133,17147,17288,16954,17147,17133,19929,19860,19907,17402,17190,17977,19924,19860,19929,19870,19825,19839,22293,22128,22008,24460,24469,24254,24601,24469,24460,21117,21126,21170,21170,21254,21271,20924,20522,20268,20224,20268,20089,20128,20089,19982,24026,23781,23787,20277,20090,20202,19982,19965,19914,17258,17197,17296,17296,17216,17628,17129,17197,17258,19860,19764,19907,19809,19764,19860,24469,24495,24254,24601,24495,24469,23684,23335,23437,22203,22184,22293,23684,23437,23609,23618,23609,23683,24008,23914,23525,23995,24210,23952,19007,19106,19122,19072,19106,19052,19106,19007,19052,20090,20047,20035,21126,21254,21170,24567,23768,23879,24201,24210,23995,22293,22184,22128,22128,22203,21982,22486,22596,22622,24094,24042,23951,24146,24042,24094,24352,24107,24322,24352,24322,24372,19764,19701,19907,19653,19701,19764,20047,19936,19929,19870,19982,19914,19870,19914,19825,23770,23618,23683,23770,23683,23781,17197,17209,17296,17182,17209,17197,24518,24352,24372,24026,23770,23781,17086,16953,17185,17147,17129,17258,16910,16953,17086,16910,17086,16786,24590,24698,24402,24787,24698,24590,24787,24590,24670,19936,19924,19929,19839,19825,19738,22622,22596,22908,24283,24146,24107,24042,24200,23787,24147,23995,23843,24841,24670,24391,17046,17129,17147,21296,21108,21115,20821,20672,20640,20272,20139,20277,20277,20139,20090,20090,20127,20047,20047,20127,19936,19936,19809,19924,21612,21296,21475,20502,20924,20268,21126,21214,21254,20224,20089,20128,20224,20128,20217,23879,24079,24567,16953,16925,17144,17209,17216,17296,17118,17216,17209,20217,20128,20043,21612,21705,21883,22805,22622,22932,17108,17096,17285,17156,17096,17119,17108,17285,17280,16925,16962,17141,18110,18105,18275,18275,18185,18574,17762,18060,17711,20457,20277,20640,20043,20128,19982,21883,21705,21870,20924,21142,21126,18105,18232,18275,17129,17182,17197,16876,17182,17129,24654,24518,24372,24352,24283,24107,24654,24372,24495,16962,16954,17133,20139,20127,20090,21142,21214,21126,23021,22992,22589,23618,23684,23609,23335,23303,23071,23754,23684,23618,23754,23618,23770,17101,17280,17065,17096,16956,17119,16954,17046,17147,24703,24489,24464,24567,24079,24455,19106,19072,19561,19052,19007,18831,22622,22514,22416,22442,22203,22293,22184,22203,22128,22583,22514,22622,24146,24184,24042,24283,24184,24146,24201,24303,24210,23914,24147,23843,17711,18060,17628,22442,22293,22416,24026,23754,23770,16945,16956,17096,19870,20043,19982,19839,20043,19870,25118,24703,24464,17108,16945,17096,17065,17280,17032,16971,16992,17032,17182,17118,17209,17592,17711,17298,17081,17118,17182,17176,17628,17216,19701,19097,19465,19724,19653,19764,19809,19860,19924,24518,24492,24352,24747,24492,24518,24601,24654,24495,24760,24654,24601,16786,17086,17061,16730,16836,16925,16925,16836,16962,16962,16836,16954,19035,19052,18947,19738,19825,19561,20981,20672,20821,20139,20110,20127,20865,20672,20981,20865,20981,21067,22514,22442,22416,22583,22442,22514,24492,24283,24352,24184,24200,24042,24147,24303,24201,20427,20502,20268,20924,21016,21142,21142,21194,21214,20427,20268,20224,20427,20224,20357,17762,17990,18110,18126,18185,18232,18232,18185,18275,17664,17990,17762,20672,20457,20640,20110,19809,19936,20357,20224,20143,20502,20905,20924,24787,24810,24698,24698,24994,24437,24841,24810,24787,24356,24200,24184,18036,18232,18105,20457,20371,20277,20143,20224,20217,23528,23303,23335,23528,23335,23684,20371,20272,20277,20905,21016,20924,24885,24841,24391,16957,16945,17108,16744,16786,17061,20110,19936,20127,19135,19561,19072,20043,20143,20217,23754,23743,23684,23987,23743,23754,16769,16925,16953,16954,16818,17046,17081,17216,17118,20176,20143,20043,17658,17190,17032,17101,16957,17108,24455,24079,24210,24890,24885,24391,19153,19097,19701,19153,19701,19510,19052,19135,19072,19035,19135,19052,16836,16818,16954,20272,20110,20139,24147,24279,24303,24510,24455,24210,24321,24279,24147,24321,24147,23914,16945,16808,16956,16972,16957,17101,19809,19724,19764,19581,19724,19590,19657,19738,19619,19839,19807,20043,24703,24760,24460,24654,24739,24518,24492,24356,24283,24850,24760,24908,24363,24210,24303,24176,24026,23787,17658,17809,17190,16986,16972,17101,24455,24674,24567,25017,24921,24841,16986,17101,17065,16828,16808,16945,17990,18036,18105,18947,19052,18831,17927,18036,17676,23743,23528,23684,23811,23528,23974,16828,16945,16957,18036,18126,18232,22992,22092,21995,23485,24008,23525,22198,22584,22589,19097,18986,18756,19083,18986,19097,19007,18680,18831,19723,19807,19738,24279,24363,24303,24455,24566,24674,24405,24363,24279,17081,17176,17216,17711,17664,17762,17081,17182,16876,19510,19701,19653,22225,21883,21870,20489,20520,20672,22442,22243,22203,22373,22243,22442,22583,22622,22805,22622,22908,22932,20502,20630,20905,20905,20993,21016,20467,20630,20502,20467,20502,20427,20467,20427,20357,20467,20357,20176,16910,16791,16953,16836,16691,16818,16499,16791,16910,17592,17664,17711,20672,20520,20457,20457,20469,20371,20371,20263,20272,20272,20199,20110,20981,21042,21067,16927,16986,17065,16851,16828,16957,22225,21982,22203,24760,24739,24654,24325,24176,24200,24200,24176,23787,24855,24739,24760,16744,17061,16956,20176,20357,20143,21067,21042,21115,20630,20901,20905,21016,21194,21142,24810,24921,24698,24841,24921,24810,24391,24560,24890,16876,17129,17046,24762,24560,24567,24645,24566,24455,16687,16744,16956,16791,16769,16953,16540,16876,17046,20901,20993,20905,22932,22908,23044,24356,24184,24283,24026,23987,23754,17284,17711,17628,24207,23987,24026,23624,24008,23485,16769,16730,16925,16851,16957,16972,16644,16687,16956,19738,19807,19839,19723,19738,19657,20345,20263,20371,20110,20105,19809,21108,21067,21115,20993,21013,21016,20263,20199,20272,19188,19083,19153,20098,20176,20005,21296,21115,21475,24762,24567,24674,17032,16927,17065,16831,16851,16972,16992,16927,17032,19153,19083,19097,19510,19653,19581,19581,19653,19724,22522,22373,22442,22243,22225,22203,22522,22442,22583,22633,22522,22583,24975,24356,24492,24442,24405,24279,24363,24510,24210,24540,24510,24363,24739,24747,24518,24855,24747,24739,24778,24762,24674,24778,24674,24566,23044,22908,23303,22805,22732,22583,21194,21254,21214,16644,16956,16808,16831,16972,16986,19738,19561,19619,20005,20176,20043,20199,20105,20110,21013,21194,21016,22234,22225,22243,24387,24325,24200,24176,24247,24026,24061,24321,23914,24661,24645,24455,24908,24760,24703,24762,24805,24560,21883,21296,21612,21053,21296,21359,16813,16831,16986,16644,16808,16639,19619,19561,19135,19723,19754,19807,24850,24855,24760,24494,24387,24356,24933,24855,24850,24805,24890,24560,24356,24387,24200,24325,24284,24176,24345,24387,24494,24405,24540,24363,24510,24661,24455,24321,24442,24279,24589,24442,24432,19231,19188,19153,22373,22234,22243,22225,22248,21883,22352,22234,22373,22633,22373,22522,24645,24778,24566,24762,24807,24805,24805,24905,24890,24634,24661,24510,22932,22732,22805,24345,24284,24325,16927,16813,16986,16808,16828,16639,16838,16813,16927,19590,19724,19809,19510,19231,19153,19657,19754,19723,18995,19619,19135,20630,20737,20901,20901,20852,20993,20993,21028,21013,21013,21028,21194,20513,20737,20630,20513,20630,20467,20513,20467,20478,22932,23026,22732,23267,23044,23303,23383,23303,23580,23303,23528,23580,24008,24061,23914,23624,24061,24008,24432,24061,24408,24921,24994,24698,25017,24994,24921,25017,24841,24885,17190,17809,17977,20520,20469,20457,20263,20252,20199,20199,20190,20105,20105,19590,19809,20762,20489,20672,20762,20672,20865,20762,20865,20886,20865,21067,20886,20478,20467,20176,20886,21067,21053,20737,20786,20901,24720,24778,24645,20489,20469,20520,20291,20478,20176,20786,20852,20901,20469,20345,20371,24980,25017,24885,25073,24908,24703,24494,24356,24975,20345,20252,20263,20852,21028,20993,23021,23216,22992,17662,18673,18756,18778,18756,18986,19067,18986,19083,19035,18995,19135,18831,18680,18437,24442,24540,24405,24661,24720,24645,24589,24540,24442,17176,17284,17628,17026,17093,17176,17026,17176,17081,19188,19067,19083,19059,19067,19188,24540,24634,24510,16828,16851,16639,16911,16838,16927,16911,16927,16992,16540,17046,16818,23528,23743,23974,24778,24807,24762,24890,24980,24885,24866,24807,24778,16851,16831,16639,16744,16568,16786,16786,16499,16910,16557,16730,16769,16557,16691,16730,16730,16691,16836,16557,16769,16495,20252,20190,20199,24387,24345,24325,24284,24247,24176,24933,24747,24855,25141,24980,25132,16876,17026,17081,19440,19231,19510,24695,24720,24661,19709,19754,19657,19709,19657,19619,23383,23267,23303,23044,23026,22932,24944,24905,24805,24385,24247,24284,16639,16831,16575,23267,23196,23044,22992,23216,23016,23021,22589,23189,16781,16911,16992,16575,16831,16813,19581,19440,19510,19535,19440,19581,18947,18995,19035,18935,18995,18947,20599,20626,20580,19564,19709,19619,24908,24933,24850,25023,24933,24908,24807,24944,24805,25132,24980,24890,24948,24944,24807,19067,18827,18986,18814,18827,19067,19059,19188,19231,18307,18680,18185,22732,22633,22583,21053,21108,21296,22636,22860,22670,17190,16971,17032,24720,24866,24778,24634,24695,24661,24727,24695,24634,25118,25073,24703,23196,23026,23044,22992,21995,22589,24247,24207,24026,17093,17284,17176,17676,17990,17664,17676,18036,17990,18036,17927,18126,18126,18008,18185,17027,17284,17093,24345,24385,24284,24247,24353,24207,24494,24385,24345,17676,17664,17417,23811,23580,23528,23383,23446,23267,23267,23214,23196,23196,23214,23026,18278,17662,18756,16725,16781,16971,17927,18008,18126,19440,19409,19231,19450,19409,19440,20175,19590,20105,23580,23502,23383,24823,24866,24720,20762,20596,20489,20489,20505,20469,20469,20442,20345,20345,20311,20252,20252,20311,20190,20190,20175,20105,20698,20596,20762,20513,20626,20737,20737,20711,20786,20786,20898,20852,20852,20898,21028,20478,20626,20513,20043,19807,20005,20596,20505,20489,17284,17298,17711,21053,21067,21108,22352,22225,22234,20711,20898,20786,21028,21020,21194,18831,18935,18947,19433,19564,19619,18952,18935,18831,24540,24589,24634,24695,24823,24720,24432,24442,24321,16575,16813,16838,16781,16838,16911,17026,16949,17093,17284,17168,17298,16856,16949,17026,16856,17026,16876,19057,19059,19231,22633,22352,22373,22496,22352,22633,24701,24727,24634,18827,18778,18986,18814,18778,18827,24975,24492,24747,24385,24428,24247,16687,16568,16744,16336,16568,16687,16390,16568,16336,16495,16769,16791,16691,16540,16818,20442,20311,20345,20898,21020,21028,24980,25141,25017,25017,25309,24994,24994,25118,24464,25029,24890,24905,19590,19535,19581,19295,19057,19231,19377,19535,19332,16557,16598,16691,16754,16856,16612,20311,20175,20190,24494,24428,24385,23974,23743,23987,17662,17402,17977,22636,22633,22860,23446,23214,23267,25100,25023,24908,24933,25036,24747,25100,24908,25073,24944,25029,24905,25037,25029,24944,24948,24807,24866,20005,19807,19754,25259,25387,25341,25119,25132,24890,19535,19450,19440,19377,19450,19535,25018,24948,24866,16949,17027,17093,16899,17027,16949,18966,18814,19067,18778,18619,18756,18966,19067,19059,19057,18966,19059,19847,20005,19754,19564,19754,19709,23974,23987,24263,23580,23446,23502,23502,23446,23383,24727,24823,24695,24589,24701,24634,25427,24701,24589,17417,17664,17592,17934,18056,18008,25023,25036,24933,25111,25036,25023,24948,25037,24944,25029,25119,24890,24701,24823,24727,18008,18056,18185,17827,18008,17927,16598,16540,16691,16971,16781,16992,16725,16971,16621,24061,24432,24321,24408,24061,23624,24408,23624,23884,25115,25119,25029,20886,20698,20762,20596,20556,20505,20505,20442,20469,20311,20251,20175,20977,20698,20886,20626,20711,20737,20898,20937,21020,20599,20711,20626,20291,20176,20098,16568,16499,16786,16557,16482,16598,16598,16352,16540,16315,16499,16326,16687,16317,16336,18935,18952,18995,18858,18952,18831,20698,20556,20596,19910,19332,19590,16499,16495,16791,18814,18797,18778,18939,18797,18814,18939,18814,18966,20556,20442,20505,20711,20870,20898,21318,21254,21194,16856,16899,16949,16938,17113,17284,17298,17417,17592,16754,16899,16856,19295,19231,19409,20870,20937,20898,25194,25100,25073,24602,24493,24494,25203,25115,25029,25203,25029,25037,25018,25037,24948,16495,16482,16557,18797,18619,18778,20442,20251,20311,19450,19295,19409,20056,20291,20098,20056,20098,20005,21359,21296,21883,23021,23189,23216,21154,21194,21020,19377,19295,19450,17676,17827,17927,18056,18307,18185,17934,17827,17875,25132,25155,25141,25141,25309,25017,25118,25182,25073,25206,25155,25132,25206,25132,25119,17827,17934,18008,24263,23987,24207,23757,23446,23580,25100,25111,25023,25192,25111,25100,21125,21154,21020,24428,24353,24247,24493,24353,24428,24493,24428,24494,23757,23580,23811,22636,22496,22633,16899,16846,17027,16754,16846,16899,19057,18962,18966,18797,18672,18619,18960,18962,19057,24823,25018,24866,25233,25018,25427,25018,24823,25427,16938,17284,17027,21154,21318,21194,25149,25206,25119,25149,25119,25188,16621,16971,17190,16781,16695,16838,17662,17444,17402,16894,16621,17190,17588,17444,17662,17113,17168,17284,21531,21359,21883,24975,24747,25036,24353,24263,24207,25259,25182,25118,25188,25119,25115,24310,24263,24452,16658,16695,16781,19187,19332,19154,19295,19223,19057,16695,16575,16838,19433,19619,19105,18962,18939,18966,18960,18939,18962,22732,22860,22633,22352,22405,22225,25182,25194,25073,25311,24975,25406,25257,25188,25115,16846,16938,17027,17073,17151,17168,16499,16315,16495,16495,16352,16482,16326,16499,16390,20580,20626,20478,20711,20655,20870,21055,21125,20937,20937,21125,21020,21154,21291,21318,20580,20478,20291,16390,16499,16568,18619,18278,18756,18171,18278,18339,18089,18307,18056,19105,19619,18995,20556,20583,20442,20442,20385,20251,20251,19910,20175,20698,20583,20556,20554,20583,20698,20977,20886,21053,20449,20580,20291,16687,16644,16317,18437,18592,18831,20583,20409,20442,17934,17926,18056,17875,17926,17934,17875,17652,17791,20409,20385,20442,21207,20977,21053,25194,25192,25100,16725,16658,16781,16695,16490,16575,16621,16658,16725,19377,19228,19295,19223,19228,19187,24975,25036,25406,16482,16352,16598,16612,16856,16876,16296,16352,16495,17151,17417,17298,17151,17298,17168,17926,18089,18056,17073,17168,17113,18307,18437,18680,18380,18437,18266,16359,16644,16382,21055,20937,20870,21995,21471,22198,25155,25275,25141,25182,25259,25194,25194,25248,25192,25240,25275,25155,25240,25155,25206,25240,25206,25231,16575,16468,16639,16391,16468,16575,18677,18858,18831,18677,18831,18592,22732,23026,22860,21531,21280,21359,21471,21254,21557,16846,16848,16938,16991,17073,17113,16612,15917,16125,19223,18960,19057,18517,18278,18619,24263,24310,23974,24081,23757,23811,24471,24263,24353,24471,24353,24493,16359,16317,16644,18467,18677,18592,25231,25206,25149,19105,18995,18952,19847,20056,20005,19228,19223,19295,19060,19223,19187,16382,16644,16639,19601,19754,19564,21359,21280,21053,22405,22352,22496,21125,21291,21154,25266,25149,25188,25266,25231,25149,17151,17088,17417,16991,17113,16938,24708,24602,24494,25018,25203,25037,25233,25203,25018,18278,18171,17662,18672,18797,18939,25415,25118,24994,25192,25248,25111,25257,25266,25188,17875,17827,17652,17926,17903,18089,18089,18133,18307,16754,16848,16846,18921,19105,18952,18677,18731,18858,18648,18731,18677,18380,18592,18437,19433,19601,19564,19458,19601,19433,24652,24471,24493,17875,17903,17926,16468,16382,16639,16137,16382,16468,16894,17190,17402,16514,16490,16695,16801,16991,16938,17073,17097,17151,18921,18952,18858,20599,20655,20711,21125,21209,21291,20580,20655,20599,20449,20655,20580,16326,16301,16315,16315,16296,16495,16390,16301,16326,16167,16301,16390,16167,16390,16097,16146,16336,16317,16270,16317,16359,20583,20554,20409,20409,20401,20385,20385,20333,20251,20539,20554,20698,20539,20698,20730,25357,25309,25141,25357,25141,25275,25357,25275,25300,25275,25307,25300,16153,16296,16103,16352,16219,16540,20554,20401,20409,20438,20449,20291,20655,20449,20581,25259,25248,25194,25353,25248,25259,25203,25257,25115,25275,25240,25307,16514,16695,16658,16543,16514,16658,16797,17097,17073,17652,17827,17676,18266,18437,18307,24602,24652,24493,24708,24652,24602,24615,24652,24708,25240,25231,25307,16296,16219,16352,17903,18133,18089,25307,25231,25266,21557,21254,21318,22589,22584,23189,16848,16801,16938,16991,16797,17073,16751,16801,16848,16751,16848,16754,18878,18672,18939,18965,18939,18960,19223,18965,18960,19060,18965,19223,22549,22405,22496,22549,22496,22636,18171,17588,17662,16966,16894,17402,17560,17588,17731,18133,18266,18307,19302,19458,19433,19601,19847,19754,21280,21207,21053,21220,21207,21246,21055,21209,21125,21291,21419,21318,24471,24452,24263,24310,24341,23974,22860,23026,23130,24615,24452,24471,25918,25307,25266,16324,16391,16490,16621,16543,16658,16473,16543,16621,19105,19178,19433,19138,19178,19105,18921,18858,18872,18858,18731,18872,16264,16270,16359,16264,16359,16382,16264,16137,16174,24708,24494,25495,24652,24615,24471,16391,16575,16490,16710,16751,16754,16801,16817,16991,22860,23130,22968,25387,25259,25118,25406,25036,25111,18378,18592,18380,22670,22549,22636,21738,21531,21883,16966,17402,17444,16793,16817,16801,17652,17676,17417,18672,18565,18619,18561,18565,18672,23365,23214,23687,16456,16490,16514,19501,19620,19601,19501,19601,19458,19302,19433,19178,19187,19228,19377,18965,18914,18939,19021,19138,19105,21320,21419,21291,25341,25353,25259,18219,18378,18380,24748,24708,24788,20655,20623,20870,21209,21320,21291,20581,20623,20655,20581,20449,20438,24452,24486,24310,24758,24486,24452,24758,24452,24615,25309,25415,24994,25341,25396,25353,25435,25449,25309,25435,25309,25363,25309,25357,25363,16301,16167,16315,16296,16171,16219,16146,16390,16336,16146,16317,16270,20519,20539,20608,20554,20539,20401,20401,20333,20385,20438,20291,20238,25449,25415,25309,25363,25357,25422,16103,16296,16315,15917,16876,16540,16543,16456,16514,16473,16456,16543,19171,19302,19178,20539,20479,20401,20455,20438,20394,25422,25357,25300,16137,16264,16382,16393,16324,16490,19380,19501,19458,19695,19847,19601,19695,19601,19620,21521,21531,21738,21207,21097,20977,21419,21557,21318,21443,21557,21419,25427,24823,24701,25203,25233,25257,25637,25422,25307,25307,25422,25300,16153,16171,16296,20479,20333,20401,18921,19021,19105,19138,19171,19178,18766,18872,18731,16751,16793,16801,16967,17151,17097,16710,16793,16751,18467,18648,18677,17875,17791,17903,17903,17849,18133,18133,18053,18266,18266,18219,18380,16967,17097,16797,20623,21055,20870,25637,25307,25918,16116,16540,16219,19060,18968,18965,19077,18968,19060,18872,19021,18921,16174,16146,16270,16174,16270,16264,17791,17849,17903,18565,18517,18619,18561,18517,18565,18378,18467,18592,18479,18467,18378,21220,21097,21207,25415,25362,25118,16456,16393,16490,16137,16468,16180,19187,19377,19332,19302,19380,19458,19091,19171,19138,21246,21207,21280,25362,25387,25118,24485,24341,24310,24485,24310,24486,16797,16991,16817,24708,24748,24615,24758,24748,24788,19637,19695,19620,20455,20507,20438,19637,19620,19501,21531,21246,21280,21055,21320,21209,25387,25417,25341,25353,25369,25248,16612,16710,16754,16696,16797,16817,17849,18053,18133,18648,18766,18731,18872,18766,19021,19021,19091,19138,18479,18766,18648,18479,18648,18467,24758,24485,24486,18968,18914,18965,19077,18914,18968,18752,18561,18672,18517,18339,18278,16456,16394,16393,16297,16391,16324,16361,16394,16456,19234,19380,19302,19234,19302,19171,16297,16324,16393,25417,25396,25341,16894,16473,16621,18867,19091,19021,16967,17088,17151,16696,16817,16793,16978,17088,16967,18053,18108,18266,17791,17728,17849,17849,17848,18053,18053,18063,18108,16977,17652,17417,21320,21443,21419,21557,22198,21471,25396,25369,25353,17652,17728,17791,24081,23811,23974,24421,23974,24341,16167,16103,16315,16153,16088,16171,16171,16116,16219,15994,16103,16167,16097,16390,16089,19220,19234,19171,19380,19429,19501,25449,25485,25415,25415,25666,25362,25548,25417,25387,25596,25490,25417,25417,25490,25396,25396,25490,25369,25544,25485,25449,25544,25449,25435,25544,25435,25463,25463,25435,25363,25463,25363,25500,20539,20519,20479,20479,20407,20333,19332,19535,19590,20608,20539,20730,20698,20977,20730,20998,21097,21185,20623,20501,21055,21430,21443,21320,21430,21546,21443,20581,20507,20623,20438,20507,20581,19868,20056,19847,25500,25363,25422,16259,16297,16393,16259,16393,16394,16089,16390,16146,16103,16088,16153,16180,16468,16391,15949,16089,16146,16710,16696,16793,16463,16696,16710,16463,16710,16612,17728,17848,17849,18108,18219,18266,18063,18219,18108,18914,18878,18939,18874,18878,18914,19695,19785,19847,19707,19785,19695,20519,20407,20479,20394,20438,20238,21531,21521,21246,21246,21352,21220,22248,22225,22405,22549,22493,22405,22670,22614,22549,22875,22614,22670,22875,22670,22860,24545,24421,24341,24545,24341,24485,23884,23624,23216,24432,25427,24589,23884,23216,23189,25602,25500,25637,15957,16146,16174,18561,18525,18517,18657,18525,18561,18219,18479,18378,19268,19220,18867,19091,19220,19171,23130,23026,23214,17848,17932,18053,21443,21640,21557,21546,21640,21443,16242,16259,16394,16297,16180,16391,19268,19429,19380,19268,19380,19234,16473,16361,16456,16267,16361,16473,16797,16799,16967,17575,17725,17652,16460,16799,16797,18443,18339,18517,19187,19077,19060,19590,20175,19910,19344,19441,19420,22493,22248,22405,23365,23130,23214,18236,18002,18171,17588,16966,17444,17932,18063,18053,17747,18274,18479,16032,16180,16048,16137,16078,16174,18878,18752,18672,18525,18443,18517,18874,18752,18878,19637,19707,19695,19785,19868,19847,22248,21738,21883,21521,21352,21246,22968,22875,22860,22614,22493,22549,22976,22875,22968,17731,17588,18171,16195,16267,16039,22626,22493,22614,17652,17725,17728,17728,17651,17848,17848,17674,17932,17932,17703,18063,16977,17417,17088,16048,16180,16297,16361,16242,16394,16641,16966,17588,16799,16978,16967,19910,20251,20333,19154,19077,19187,23687,23214,23446,23130,22976,22968,24748,24758,24615,24788,24708,25349,18339,18236,18171,18271,18443,18525,15970,16116,16171,21523,21352,21521,25594,25387,25362,25406,25111,25492,18002,17731,18171,17432,17731,17399,19158,19077,19154,19560,19637,19501,19814,19868,19785,19560,19501,19429,23757,23687,23446,23897,23687,23757,24081,23974,24421,24598,24545,24485,16032,16078,16137,16032,16137,16180,19953,19868,19814,18259,18236,18339,23365,23315,23130,23339,23315,23365,25495,24494,24975,24764,24598,24485,18752,18657,18561,18443,18259,18339,18742,18657,18752,19332,19328,19154,19077,18874,18914,19158,19328,19277,19220,19268,19234,19268,19344,19420,21640,22198,21557,23321,23884,23189,18742,18874,18815,22853,22626,22614,22493,22527,22248,21691,21521,21738,22853,22614,22875,15981,15994,16167,16103,15961,16088,16088,15970,16171,15981,16167,16097,15981,16097,15969,15994,15961,16103,19507,19560,19429,19814,19785,19726,20730,20977,20916,20519,20545,20407,20407,19910,20333,20680,20730,20826,24764,24485,24758,24408,24616,24432,24686,24616,24408,15969,16097,16089,20507,20501,20623,20455,20501,20507,20398,20501,20455,23285,22976,23130,25485,25559,25415,25544,25559,25485,25602,25559,25544,25602,25544,25463,25500,25602,25463,25637,25500,25422,21430,21320,21055,21640,21856,22198,15949,15969,16089,15961,15970,16088,20394,20398,20455,15957,15949,16146,20238,20291,20056,20004,20238,20056,16978,17007,17088,16886,17007,16978,16886,16978,16799,24788,24764,24758,24339,24081,24421,24649,24421,24545,24569,24545,24598,16361,16267,16242,16048,16297,16049,16267,16194,16039,25111,25248,25492,24788,24872,24764,25666,25594,25362,25492,25248,25369,17725,17651,17728,18063,17463,18219,17575,17651,17725,24180,23884,24153,16078,15957,16174,15977,15957,16078,16086,16463,16612,16696,16460,16797,18874,18742,18752,18271,18259,18443,18815,18874,19077,25594,25548,25387,16966,16891,16894,16431,16891,16641,16535,16886,16799,17007,16977,17088,23315,23285,23130,23467,23339,23365,23563,23365,23687,16297,16259,16049,21546,21722,21640,21726,21722,21546,19868,20004,20056,19953,20004,19868,25548,25596,25417,25492,25369,25843,23777,23715,23687,24872,24569,24598,24872,24598,24764,19507,19707,19637,16032,15977,16078,16184,16259,16242,21722,21856,21640,21726,21856,21722,18236,18259,18002,18271,18525,18367,23339,23285,23315,22976,22853,22875,23442,23285,23339,16825,16977,17007,16825,17007,16886,23715,23563,23687,16017,15977,16032,20545,19910,20407,18973,18815,19077,20876,21430,21055,18973,19077,19084,18367,18525,18657,16267,16184,16242,16195,16184,16267,16184,16049,16259,16048,16017,16032,19560,19507,19637,19420,19507,19429,19420,19429,19268,18867,19344,19268,25843,25369,25490,19158,19154,19328,20608,20545,20519,20730,20680,20608,20826,20730,20916,15961,15879,15970,15970,15588,16116,16379,16458,16463,15994,15879,15961,15877,15879,15994,15877,15994,15981,15877,15981,15969,15877,15969,15949,15877,15949,15890,16787,16825,16886,17651,17674,17848,16741,17575,17652,17674,17575,17468,19726,19785,19707,20680,20545,20608,20916,20977,21097,20916,21097,20998,23563,23467,23365,24081,24019,23757,23715,23660,23563,23660,23442,23467,24040,24019,24081,18708,18657,18742,15890,15949,15957,20398,20421,20501,20501,20876,21055,20394,20421,20398,20391,20421,20394,20391,20394,20238,20391,20238,20198,20238,20004,20198,20845,20916,20998,25559,25666,25415,25594,25650,25548,25548,25711,25596,25596,25843,25490,25788,25645,25559,17575,17674,17651,20198,20004,20034,24019,23897,23757,25645,25666,25559,15864,15890,15957,25666,25644,25594,25918,25266,25257,25602,25788,25559,25918,25257,25233,16024,16010,16049,16267,16473,16194,19358,19328,19332,20034,20004,19953,19507,19726,19707,23897,23777,23687,15933,15957,15977,15933,15864,15957,20034,19953,19986,25644,25650,25594,16463,16458,16696,16379,16463,16183,18815,18708,18742,18737,18708,18815,18926,18815,18973,23052,22853,22976,22626,22713,22493,21691,21523,21521,23052,22976,23285,15772,15933,15836,18975,18926,18973,23229,23052,23285,23229,23285,23442,25650,25711,25548,16010,16017,16048,16010,16048,16049,21430,21726,21546,21856,22036,22198,22989,23321,22584,21832,21726,21746,19986,19953,19900,19910,19358,19332,19158,19084,19077,25406,25484,25311,24895,24872,24788,25492,25484,25406,25972,25484,25492,18271,18265,18259,18259,18059,18002,17731,17432,17560,17560,17432,17588,18367,18265,18271,19277,19084,19158,23442,23339,23467,24804,24872,24895,24181,24040,24081,19900,19953,19814,16035,16049,16184,15836,15933,15977,21726,21837,21856,21832,21837,21726,24019,24023,23897,23897,23907,23777,23660,23467,23563,24649,24545,24569,22853,22809,22626,22757,22809,22867,23103,22853,23052,24040,24023,24019,19726,19900,19814,19981,19900,19584,16195,16035,16184,16039,16035,16195,19358,19277,19328,19367,19277,19358,23660,23715,23777,23229,23185,23052,17674,17703,17932,17468,17703,17674,16908,17652,16977,24770,24649,24569,23159,23185,23336,16035,16024,16049,15836,15977,15793,19084,18975,18973,18926,18737,18815,18708,18650,18657,18911,18975,19084,20680,20619,20545,20545,20462,19910,19434,19367,19358,20814,20619,20680,20814,20680,20826,20814,20826,20916,21691,21738,21820,20845,20814,20916,24804,24770,24569,21097,21220,21185,25645,25788,25666,25666,25775,25644,25644,25775,25650,25650,25779,25711,25711,25776,25596,26186,25788,25602,21185,21220,21352,16612,16876,15917,16458,16460,16696,16825,16908,16977,20198,20295,20391,20391,20295,20421,20876,21806,21430,20072,20295,20198,20072,20198,20034,20072,20034,19981,25788,25775,25666,16787,16908,16825,18882,18737,18926,19091,18867,19220,19507,19584,19726,19981,20034,19986,22527,21738,22248,21327,21185,21352,21837,22036,21856,21933,22036,21837,23907,23660,23777,23336,23185,23229,24872,24804,24569,24895,25162,25033,16379,16460,16458,15864,15772,15890,15890,15772,15877,15418,15588,15879,15933,15772,15864,15977,16017,15793,25775,25779,25650,23884,24315,24408,24180,24315,23884,17399,17731,17490,16194,16473,16894,19981,19986,19900,21327,21352,21523,24339,24421,24550,24339,24181,24081,24040,24166,24023,24023,23907,23897,24421,24649,24550,24550,24649,24656,16535,16787,16886,24895,24788,25162,24656,24649,24702,16741,17468,17575,19021,18766,18867,16741,17652,16908,24649,24770,24702,19434,19358,19910,19277,19256,19084,18745,18650,18737,22036,22065,22198,22103,22065,22036,15891,16017,16010,16194,16894,16123,15853,15891,16024,16024,15891,16010,25779,25776,25711,24702,24770,24947,18737,18650,18708,18265,18113,18259,18882,18926,18975,22809,22757,22626,22867,22809,22853,23159,23052,23185,16028,16024,16035,19584,19900,19726,21592,21327,21523,21592,21523,21691,21746,21726,21430,23988,23907,24023,23336,23229,23442,15783,16194,15615,18911,18882,18975,18476,18367,18657,23336,23442,23667,16039,16028,16035,16021,16028,16039,19367,19256,19277,19405,19256,19367,15891,15793,16017,15917,16540,16116,16252,16535,16460,15917,16116,15358,21832,21933,21837,21746,21933,21832,16460,16535,16799,16787,16716,16908,16057,16460,16379,18367,18113,18265,23667,23442,23660,16647,16716,16787,20619,20462,20545,20814,20683,20619,20781,20683,20814,20781,20814,20845,20781,20845,20998,20781,20998,21010,21010,20998,21185,18650,18606,18657,18160,18059,18113,18653,18606,18650,18745,18737,18882,23103,22867,22853,22757,22713,22626,23103,23052,23159,24181,24166,24040,23807,23667,23660,24339,24292,24181,24525,24292,24339,24503,24339,24550,16086,16183,16463,18860,18745,18882,22867,22713,22757,24292,24166,24181,24656,24503,24550,24702,24503,24656,25376,25427,24432,25013,24432,24616,23084,23103,23155,15588,15970,15879,16125,16086,16612,19405,19434,19456,19198,18911,19084,19420,19441,19507,17589,18063,17703,20295,20296,20421,20137,20296,20295,20137,20295,20072,20137,20072,20179,20964,21010,21059,24166,24054,24023,15770,16086,16125,16535,16647,16787,16777,16647,16637,19198,19084,19256,22713,22527,22493,20690,20782,20871,24686,25013,24616,20179,20072,19981,25779,25869,25776,25776,25843,25596,25775,25833,25779,25889,25833,25775,25889,25775,25988,25775,25788,25988,17468,17589,17703,17494,17589,17468,16777,16908,16716,24054,23988,24023,24880,24770,24804,24315,24686,24408,15836,15736,15772,15772,15661,15877,15695,15736,15836,15695,15836,15793,15695,15573,15647,25833,25869,25779,21806,21746,21430,16194,16021,16039,16028,15853,16024,22065,22286,22198,21933,22103,22036,22013,22103,21933,15639,15793,15891,18113,18059,18259,18167,18113,18367,18606,18476,18657,18563,18476,18606,18653,18650,18745,18770,18653,18745,16647,16777,16716,16741,16777,16637,24895,24880,24804,25033,24880,24895,24975,25311,25495,18476,18269,18367,19441,19584,19507,25954,25843,25776,25495,25311,25484,23321,23189,22584,24315,24867,24686,19441,19528,19584,19859,20179,19981,19344,19528,19441,18867,18766,18274,17426,17494,17339,17955,17921,18059,18476,18391,18269,18400,18391,18476,20683,20681,20619,20781,20681,20683,20782,20681,20781,20782,20781,21010,21059,21185,21496,26195,25495,25484,16021,15938,16028,15783,15938,16021,15783,16021,16194,15917,15916,16125,15952,16057,16183,16637,16647,16604,15770,15916,15715,18059,17921,18002,18167,18367,18269,19284,19198,19256,18911,18860,18882,18400,18345,18391,19405,19367,19434,15938,15853,16028,18345,18167,18269,21746,22013,21933,22103,22176,22065,22015,22013,21746,16777,16741,16908,16057,16379,16183,24651,24525,24503,24503,24525,24339,24292,24520,24166,24166,24178,24054,24178,23956,23988,24880,24947,24770,25031,24947,24880,24884,24947,25031,15736,15661,15772,15647,15661,15736,15647,15736,15695,20137,20179,20296,20876,20501,20421,19514,19981,19584,25833,25889,25869,25869,25954,25776,25988,25788,26186,15573,15695,15793,25889,25920,25869,25843,25957,25492,19527,19434,19910,18563,18606,18653,17463,18063,17589,19528,19514,19584,22013,22082,22103,22015,22082,22013,18391,18345,18269,18167,18160,18113,18860,18911,19198,24651,24503,24702,23956,23660,23907,23155,23103,23159,24709,24651,24702,18674,18860,18800,17490,17731,18002,16641,16891,16966,17490,18002,17921,23956,23907,23988,23103,23084,22867,22867,22933,22713,22713,22777,22527,25920,25954,25869,18208,18160,18167,17494,17488,17589,17426,17488,17494,19405,19284,19256,19248,19284,19405,22082,22176,22103,22138,22176,22082,25954,25882,25843,15853,15708,15891,15669,15708,15853,19626,19527,19910,19344,19514,19528,24178,23988,24054,24947,24884,24702,25031,24880,25033,15952,16183,16086,18770,18563,18653,18345,18208,18167,18770,18745,18860,18003,17955,18059,18003,18059,18160,18522,18400,18476,23471,23159,23336,21820,21592,21691,25349,25162,24788,15934,15952,16086,18570,18770,18674,21820,21738,22527,25882,25957,25843,18349,18208,18345,22989,22584,22198,16604,16647,16484,17339,17494,17468,20681,20462,20619,20782,20690,20681,20964,20782,21010,22176,22286,22065,22218,22286,22176,25144,25031,25033,19527,19456,19434,18570,18563,18770,19513,19456,19527,21806,22015,21746,15418,15879,15877,15916,15770,16125,15592,15877,15661,21059,21010,21185,15708,15639,15891,15545,15592,15661,25884,25918,25233,15545,15661,15647,18121,18003,18160,17955,17850,17921,21496,21185,21327,23667,23471,23336,23566,23471,23667,26186,25602,25637,25889,26020,25920,25920,26059,25954,25954,26012,25882,25882,26003,25957,23956,23807,23660,25162,25144,25033,15481,15545,15647,24821,24709,24702,24651,24633,24525,24365,24178,24166,23956,24123,23807,24821,24702,24917,24702,24884,24917,25988,26020,25889,18400,18349,18345,17942,17994,18003,18563,18522,18476,18534,18522,18563,18534,18563,18570,23084,22933,22867,23041,22933,23084,22414,22989,22198,17488,17463,17589,16939,17468,16741,20876,20421,20296,22933,22777,22713,24520,24292,24525,24917,24884,24982,18522,18349,18400,22015,22138,22082,22286,22414,22198,22142,22138,22015,23409,23155,23159,26020,26059,25920,17994,17850,17955,17994,17955,18003,17850,17490,17921,16123,16894,16891,17426,17463,17488,19344,19475,19514,18274,18766,18479,22777,22585,22527,24982,24884,25031,23471,23409,23159,23423,23409,23471,25495,25349,24708,25162,25213,25144,25139,24982,25031,25222,25349,25424,19671,19626,19910,19456,19248,19405,25947,25884,25233,26186,26127,25988,25947,25233,25427,15639,15573,15793,16637,16660,16741,16604,16660,16637,25139,25031,25144,26059,26012,25954,25957,25972,25492,18867,19278,19344,19514,19859,19981,22138,22218,22176,22142,22218,22138,17588,17432,16641,15938,15759,15853,15708,15669,15639,15380,15482,15573,15715,15916,15917,15952,15985,16057,16057,16252,16460,17850,17576,17490,18121,18160,18208,23807,23566,23667,23886,23566,23807,25349,25222,25162,15887,15985,15952,21592,21496,21327,21820,21496,21592,22933,22896,22777,22777,22804,22585,23041,22896,22933,23041,23084,23155,23322,23155,23409,15593,15669,15853,16252,16647,16535,19626,19513,19527,19609,19513,19626,15792,15934,16086,18349,18233,18208,18342,18233,18349,18534,18349,18522,25013,25376,24432,25412,25376,25013,25288,25013,24686,24633,24651,24709,24633,24520,24525,24178,24123,23956,24633,24709,24852,24709,24821,24852,25051,24821,24917,24520,24365,24166,26012,26003,25882,15783,15759,15938,16939,17339,17468,17426,17414,17463,17747,18479,18219,16939,16741,16660,15770,15792,16086,15715,15792,15770,23566,23423,23471,23452,23423,23566,25222,25213,25162,24982,25051,24917,19278,19475,19344,19242,19475,19278,20690,20462,20681,20836,20462,20690,20871,20782,20964,20871,20964,20944,20836,20871,20944,19248,19198,19284,25376,25617,25427,24379,24123,24178,25139,25051,24982,15545,15516,15592,15592,15418,15877,15481,15516,15545,15481,15647,15573,16484,16554,16604,15934,15887,15952,15855,15887,15934,22896,22804,22777,22585,21820,22527,22859,22804,22896,26020,26127,26059,26059,26109,26012,26012,26148,26003,25988,26127,26020,26186,25637,26500,24867,25288,24686,25688,25622,25617,24867,24315,24180,19888,19671,19910,19473,19248,19456,22218,22188,22286,22020,22142,22015,26003,25972,25957,26148,25972,26003,25884,26033,25918,26125,26033,25884,15482,15481,15573,18233,18121,18208,16943,17399,17090,18090,18121,18233,25288,25412,25013,16604,16554,16660,16252,16057,15985,25213,25139,25144,26127,26109,26059,19671,19609,19626,19697,19609,19671,21535,21597,21451,20944,20964,21059,15754,16252,15985,15380,15573,15639,15380,15639,15294,15208,15715,15917,15716,15855,15934,16946,17432,17399,15783,15638,15759,16252,16484,16647,19473,19456,19513,18867,19242,19278,19375,19179,19347,22142,22188,22218,22188,22414,22286,24123,23886,23807,23198,23041,23155,16943,16946,17399,16943,17090,17002,23322,23409,23452,21451,21597,21428,18090,17942,18121,18674,18770,18860,23041,22859,22896,24633,24619,24520,24520,24619,24365,24379,24086,24123,24123,24086,23886,25104,24852,24821,25104,24821,25051,24606,24867,24180,25617,25648,25427,25622,25648,25617,23452,23409,23423,20462,19888,19910,16946,16641,17432,17339,17414,17426,17315,17414,17339,16493,16660,16554,23886,23452,23566,23669,24153,23884,23669,23884,23321,23669,23321,24007,26109,26148,26012,25706,25349,25495,19609,19473,19513,18800,18860,19198,19578,19473,19609,20871,20836,20690,19818,19698,19888,20944,21059,21009,21806,22020,22015,22142,22075,22188,22188,22085,22414,21910,22020,21806,21910,21813,21935,19859,19514,19475,24379,24178,24365,24262,23806,23452,15516,15418,15592,15588,15358,16116,15421,15418,15516,15421,15516,15481,26456,25637,25918,26127,26190,26109,26109,26190,26148,20889,20944,21009,22930,23321,22989,25222,25336,25213,25213,25163,25139,25139,25104,25051,25424,25336,25222,25706,26250,25944,26087,25484,25972,25556,25617,25376,25648,25947,25427,25536,25376,25412,23041,23198,22859,23322,23198,23155,23806,23198,23322,15887,15855,15985,15716,15934,15792,18800,19198,19191,18090,18233,18072,25272,25163,25213,15673,15638,15783,15759,15593,15853,16143,16123,16891,16143,16891,16431,25441,25536,25412,25441,25412,25288,25753,25947,25648,15433,15421,15481,15433,15481,15482,19242,19375,19475,19375,19242,19179,22020,22075,22142,22414,22930,22989,19888,19697,19671,19698,19697,19888,15715,15716,15792,15632,15716,15460,16946,16840,16641,17804,17850,17994,24942,24619,24633,24879,24633,24852,15380,15433,15482,16943,16840,16946,16409,16143,16431,16409,16431,16323,18121,17942,18003,18349,18534,18342,25336,25272,25213,25522,25424,25349,16615,16431,16641,25265,25272,25423,25163,25104,25139,26329,26190,26127,26205,26087,25972,16840,16682,16641,19697,19578,19609,19191,19198,19248,19698,19578,19697,26223,25972,26148,15638,15593,15759,15615,15673,15783,15581,15593,15638,25947,26025,25884,26394,26456,25918,26063,26025,25947,25622,25753,25648,25787,25753,25622,16123,16003,16194,16029,16003,16123,25536,25556,25376,25733,25556,25642,16682,16615,16641,25265,25104,25163,17942,17804,17994,19191,19248,19276,18342,18534,18386,17795,17631,17804,16143,16036,16123,16050,16036,16143,16192,16143,16409,18534,18570,18386,15288,15639,15669,21910,21806,21813,22020,22017,22075,22075,22085,22188,26150,26125,25884,16484,16493,16554,16320,16493,16484,16504,16493,16320,19368,19248,19473,25411,25441,25288,15593,15464,15669,15381,15464,15593,21910,22017,22020,26699,26329,26186,26025,26150,25884,26167,26150,26025,15936,15789,16194,15673,15581,15638,15936,16194,16003,15844,15936,15821,16615,16323,16431,16036,16029,16123,17804,17576,17850,17631,17576,17804,18386,18570,18493,17895,17804,17942,25272,25265,25163,25423,25272,25336,25556,25688,25617,25753,26063,25947,25733,25688,25556,17090,17399,17087,16943,16822,16840,16840,16743,16682,16682,16563,16615,16615,16462,16323,16841,16939,16625,17087,17399,17490,15418,15297,15588,15359,15297,15418,15359,15418,15421,15359,15421,15328,20944,20889,20836,20836,20538,20462,21009,21059,21496,16746,16743,16840,25102,24879,24852,24619,24379,24365,24942,24879,25044,26374,26223,26148,26087,26195,25484,15328,15421,15433,15328,15433,15380,15515,15581,15673,16743,16655,16682,21068,21009,21099,24860,24379,24619,24086,24262,23886,23452,23806,23322,16323,16235,16409,16310,16235,16323,16983,17002,17090,17895,17942,18090,16113,16050,16143,19578,19368,19473,18595,18674,18800,18595,18570,18674,19571,19368,19578,19375,19347,19475,19179,19242,18867,22017,22085,22075,25424,25423,25336,25581,25522,25349,25701,25349,25706,26186,26329,26127,26190,26370,26148,26376,26033,26125,17747,18219,17463,17282,17315,17339,19818,19888,20208,26223,26205,25972,26341,26205,26223,15243,15328,15110,16481,16462,16615,16493,16504,16660,16432,16504,16320,15936,15811,15789,15789,15615,16194,15844,15811,15936,18595,18800,18681,18122,18072,18233,25688,25787,25622,25733,25787,25688,25723,25701,25706,15855,15752,15985,15716,15752,15855,15632,15752,15716,16235,16192,16409,16050,16029,16036,16069,16192,16235,18789,18800,19191,19698,19571,19578,19730,19571,19698,25522,25423,25424,25102,24852,25104,25470,25423,25522,25496,25411,25288,25441,25541,25536,25496,25288,24867,26076,26063,25753,19368,19276,19248,19388,19276,19368,16002,16029,16050,18122,18233,18342,25701,25581,25349,26329,26370,26190,16462,16369,16323,15654,15615,15789,19066,18789,19191,21910,21935,22017,22017,22018,22085,20876,20296,20179,26205,26271,26087,26341,26271,26205,14730,15358,15588,16743,16567,16655,16655,16563,16682,16462,16341,16369,17002,16822,16943,16983,16822,17002,16983,17090,17087,16625,16939,16660,16939,17282,17339,17087,17049,16922,16822,16746,16840,16981,17087,16988,17648,17576,17631,24153,24606,24180,24406,24606,24153,24879,24942,24633,25102,25104,25247,16192,16113,16143,15963,16113,16069,17920,17895,18090,25411,25541,25441,25496,25541,25411,16369,16310,16323,16179,16310,16369,18798,19179,18867,20760,20876,20179,15288,15294,15639,15288,15669,15360,15669,15464,15360,15811,15700,15789,15821,15936,16003,15821,16003,15847,18386,18352,18342,18072,17920,18090,18415,18352,18386,18493,18570,18595,17747,17463,17520,26370,26374,26148,15738,15700,15811,18614,18493,18595,16567,16563,16655,17315,17302,17414,16895,17282,16939,24399,24406,24153,24578,24406,24557,25247,25104,25265,18352,18122,18342,22768,22930,22414,21935,22018,22017,25701,25675,25581,25591,25470,25522,25423,25529,25265,25723,25675,25701,26150,26167,26125,26324,26167,26025,18789,18681,18800,18627,18681,18789,16563,16481,16615,16504,16432,16660,16320,16484,15907,17282,17302,17315,19385,19475,19347,21935,21813,22018,16113,16002,16050,15963,16002,16113,15895,16002,15963,17895,17795,17804,18046,17920,18072,21009,20954,20889,20889,20902,20836,21068,20954,21009,21009,21496,21099,21496,21535,21099,19276,19066,19191,19259,19066,19276,21496,21820,21535,15615,15595,15673,15580,15595,15615,16228,16320,16070,19571,19388,19368,19479,19388,19571,19179,19385,19347,19219,19385,19179,15328,15225,15359,15359,15064,15297,15297,14730,15588,15243,15225,15328,21597,21535,21855,15381,15593,15428,15110,15328,15380,26374,26341,26223,25842,25723,25944,17781,17795,17895,25591,25522,25581,15253,15380,15294,15844,15738,15811,15700,15654,15789,15760,15738,15844,15752,15754,15985,15629,15754,15752,15895,16003,16029,25664,25591,25581,26195,26087,26271,25642,25556,25536,25787,25904,25753,26449,26376,26389,15685,15654,15700,15497,15716,15715,18681,18614,18595,18212,18135,18352,18135,18046,18122,18122,18046,18072,17655,17648,17795,18627,18614,18681,15595,15515,15673,15509,15515,15595,24942,24860,24619,24379,24911,24086,25044,24860,24942,25044,24879,25102,16002,15895,16029,16113,16192,16069,16983,16784,16822,16822,16784,16746,16746,16567,16743,16563,16567,16481,17087,16981,16983,16988,17087,16922,18135,18122,18352,24606,24749,24867,24608,24749,24606,25541,25642,25536,25791,25642,25541,15329,15360,15464,15251,15253,15294,21779,21813,21806,26167,26376,26125,26376,26167,26389,15428,15593,15581,19388,19259,19276,18627,18415,18614,19479,19259,19388,26292,26195,26271,16841,16895,16939,17282,17267,17302,16602,16625,16660,16602,16660,16432,24406,24608,24606,24750,24608,24578,25247,25044,25102,16694,16567,16746,16069,16235,16310,16402,16602,16432,26394,25918,26033,26685,26374,26370,26685,26441,26374,26374,26441,26341,16341,16462,16481,25470,25529,25423,25750,25581,25675,15515,15428,15581,15381,15329,15464,15342,15428,15515,15738,15685,15700,15654,15580,15615,15821,15760,15844,15699,15760,15821,15847,16003,15895,15645,15685,15738,15632,15629,15752,16228,16408,16320,15460,15629,15632,22136,22414,22085,22136,22085,22018,15762,15847,15895,16567,16341,16481,16320,16408,16432,16402,16408,16228,17655,17795,17781,18212,18352,18325,25723,25759,25675,25842,25759,25723,15251,15294,15288,15251,15288,15215,16179,16069,16310,15762,15699,15847,17795,17648,17631,17895,17920,17781,19811,19818,19875,21252,21535,21360,25591,25529,25470,25664,25529,25591,26376,26394,26033,15574,15580,15654,19490,19479,19571,18627,18789,18615,15215,15288,15360,19818,19730,19698,20954,20902,20889,19648,19552,19730,20997,20902,20954,20997,20954,21068,20997,21068,21035,26413,26292,26271,26685,26370,26329,21035,21068,21099,15580,15509,15595,15275,15329,15381,15208,15497,15715,16865,16784,16983,16271,16291,16341,16865,16983,16981,16638,16773,16841,16638,16841,16625,16638,16625,16546,16988,16865,16981,16773,16895,16841,17520,17463,17414,24749,24937,24867,24750,24789,24749,24750,24749,24608,24789,24937,24749,17520,17414,17302,18274,18544,18867,21130,21035,21099,15275,15381,15428,16784,16694,16746,16546,16625,16602,17087,17490,17049,21813,22136,22018,21964,22136,21813,24578,24608,24406,25944,25723,25706,26481,26271,26341,16175,16179,16369,15762,15895,15935,16291,16369,16341,15266,15215,15360,15358,15208,15917,14658,15208,15358,15685,15574,15654,15580,15408,15509,15760,15645,15738,15699,15645,15760,15699,15821,15847,15895,15963,15935,16485,16546,16602,18415,18386,18493,17949,17920,18046,18415,18493,18614,18789,19066,19042,21508,21779,21806,24399,24153,24307,25750,25664,25581,25706,25495,26250,26277,25495,26195,25733,25904,25787,26376,26449,26394,26116,25904,25733,25791,25733,25642,26441,26427,26341,26239,26025,26063,15591,15574,15685,17747,18035,18274,19042,19066,19120,26456,26500,25637,26685,26495,26427,26785,26500,26456,26584,26456,26394,19120,19066,19259,19485,19259,19479,26076,26239,26063,15236,15266,15360,15329,15236,15360,15342,15275,15428,15236,15275,15134,24937,25496,24867,26292,26352,26195,26472,26352,26292,26306,26324,26025,16408,16402,16432,16484,16252,15907,17091,17267,17282,24307,24153,23669,25529,25247,25265,25351,24943,24860,25351,25247,25767,17747,17815,18035,17801,17815,17747,25750,25675,25759,26131,26076,25753,15253,15110,15380,15034,15064,15225,15225,15064,15359,15160,15110,15253,15160,15253,15126,15253,15251,15126,16271,16341,16567,15982,15963,16069,16234,16228,16070,24073,24307,23669,19730,19490,19571,19552,19490,19730,26427,26481,26341,26495,26481,26427,18415,18325,18352,17949,18046,18135,18297,18325,18415,18193,18325,18297,18103,18323,18274,18103,18274,18035,25944,25958,25842,25844,25750,25759,25997,25958,25944,15126,15251,15146,15699,15591,15645,15645,15591,15685,15982,16069,16025,16025,16069,16179,17049,17490,17576,17949,18135,18157,18132,18103,18029,19073,19219,19179,19385,19859,19475,26352,26277,26195,26416,26277,26352,26239,26306,26025,26593,26584,26449,26523,26306,26545,16291,16175,16369,18157,18135,18212,25664,25767,25529,25844,25759,25842,25496,25791,25541,25904,26131,25753,15497,15460,15716,16279,16234,16070,14446,15460,15497,15146,15251,15215,15146,15215,15266,16865,16789,16784,16784,16589,16694,16694,16589,16567,16291,16166,16175,16988,16811,16865,16922,16811,16988,19362,19859,19385,20876,21508,21806,26449,26584,26394,26389,26167,26324,15275,15236,15329,15342,15515,15509,19490,19485,19479,19042,18615,18789,19552,19485,19490,26481,26413,26271,26495,26413,26481,26488,26389,26324,16699,16589,16784,16638,16668,16773,16773,16668,16895,17038,17306,17267,16546,16511,16638,16485,16511,16546,16485,16602,16342,17049,17576,17085,16342,16602,16402,17572,17576,17648,24578,24557,24750,24913,25074,24789,24789,25074,24937,24937,25264,25496,24399,24557,24406,24555,24557,24399,15982,15935,15963,16025,15935,15982,17949,17781,17920,17655,17572,17648,20660,20760,20179,26500,26699,26186,26634,26699,26500,15344,15342,15509,15463,15580,15574,17306,17520,17302,18029,18103,18035,17306,17302,17267,19374,19120,19259,20760,20765,20876,16234,16342,16402,16234,16402,16228,21035,20927,20997,20997,20927,20902,20208,19888,20462,21130,20927,21035,18325,18193,18212,17672,17669,17781,18469,18415,18627,25958,25926,25842,25997,25926,25958,15762,15591,15699,15287,15111,15216,26413,26472,26292,26250,25997,25944,26641,26472,26413,15034,15243,15110,15034,15225,15243,15034,14904,14976,25926,25844,25842,26103,25767,25664,15029,15146,15266,14904,15110,15160,15067,15146,15029,14928,15160,15126,15591,15463,15574,16321,16271,16567,16095,16025,16179,16252,15578,15907,18589,18615,19042,18323,18544,18274,18539,18544,18323,18273,18323,18264,21228,21130,21252,26785,26634,26500,16095,16179,16175,15344,15438,15287,17669,17572,17655,17669,17655,17781,17520,17551,17747,17392,17551,17520,19120,19009,19042,18849,19009,18844,15438,15408,15580,15342,15247,15275,17091,17282,16895,26472,26416,26352,26555,26416,26472,21779,21898,21813,23209,23509,22930,21741,21898,21779,17015,16922,17049,17824,17781,17949,16579,16668,16638,16579,16638,16511,16579,16511,16485,16579,16485,16339,16811,16789,16865,16589,16446,16567,16913,16789,16811,16913,16811,16922,16913,16922,17015,16668,16739,16895,18469,18297,18415,18193,18157,18212,18469,18627,18615,18132,18323,18103,25926,25929,25844,26250,25495,26277,16339,16485,16342,17015,17049,16918,18181,18157,18193,17897,18035,17815,16166,16095,16175,15463,15111,15287,16166,16291,16271,18589,18469,18615,18933,19073,19179,18273,18539,18323,19485,19374,19259,19811,19730,19818,21898,21964,21813,21847,21964,21898,26116,26131,25904,26545,26306,26239,26488,26449,26389,26685,26427,26441,16363,16446,16589,16918,17049,17085,21319,21508,20876,16446,16321,16567,16279,16339,16342,16279,16342,16234,16739,17091,16895,15463,15438,15580,15344,15247,15342,15287,15438,15463,14917,15038,15591,24007,24073,23669,24307,24555,24399,24202,24073,24159,17640,17801,17747,17640,17747,17551,17897,17801,17640,20208,20462,20538,21508,21582,21779,26699,26685,26329,26584,26593,26456,26657,26593,26449,26488,26324,26523,16252,15754,15578,24496,24555,24307,24913,24789,24750,26523,26324,26306,15344,15509,15408,19219,19362,19385,18798,18867,18544,26416,26442,26277,26555,26442,26416,26555,26472,26620,20760,20744,20765,20765,20858,20876,21508,21494,21582,19859,20660,20179,20744,20660,20648,15146,15067,15126,15029,15266,15236,16308,16166,16271,15762,15935,15731,17672,17599,17669,18297,18181,18193,18417,18181,18297,18132,18264,18323,18273,18436,18539,18510,18798,18544,18029,18264,18132,18264,18436,18273,20761,20858,20765,17975,18029,18035,25844,25929,25750,25979,25929,25926,25979,25926,25997,15578,15754,15629,17669,17599,17572,17824,17949,18157,19552,19374,19485,18849,18589,19042,18469,18498,18297,19285,19374,19421,15064,14724,15297,15034,14908,15064,14976,14908,15034,18498,18589,18547,18023,17824,18157,17801,17897,17815,17640,17551,17526,15054,15029,15236,14904,15034,15110,15907,16070,16320,19811,19648,19730,21659,21741,21582,21582,21741,21779,21964,22168,22136,24073,24312,24307,14904,15160,14928,20538,20836,20902,19811,19760,19648,20538,20902,20927,16789,16699,16784,16363,16308,16321,16321,16308,16271,16913,16699,16789,16861,16699,16913,16861,16913,17015,16739,16688,17091,17392,17520,17306,16668,16684,16739,16596,16684,16668,16596,16668,16579,16596,16173,16489,16596,16489,16555,24913,24750,24557,26357,26116,25791,25791,26116,25733,24913,24840,24977,24913,24557,24840,16918,16861,17015,21252,21130,21099,21130,21052,20927,21252,21099,21535,15438,15344,15408,15247,15134,15275,15935,16025,15731,18510,18544,18539,26641,26413,26495,26154,25979,25997,17771,17672,17781,17085,17576,17572,17392,17306,17313,17486,17572,17599,21741,21847,21898,21890,21847,21741,26488,26657,26449,26673,26657,26488,17313,17306,17122,24073,24202,24312,24312,24496,24307,24007,23321,23509,21535,21820,21855,21360,21535,21451,21031,21319,20876,26250,26277,26442,25929,26048,25750,16022,16025,16095,16363,16321,16446,14928,15126,15067,18111,18336,18264,18336,18510,18436,18436,18510,18539,17897,17975,18035,17749,17975,17897,18589,18498,18469,17753,17771,17824,17824,17771,17781,18849,19042,19009,18336,18436,18264,21855,21820,22529,21319,21349,21508,26268,26250,26300,26593,26785,26456,26634,26810,26699,26699,27676,26685,26765,26785,26593,18798,18933,19179,19073,19082,19219,18856,18933,18798,15049,15134,15247,14924,14928,15067,24435,24496,24312,26545,26239,26076,17672,17486,17599,17411,17486,17672,17392,17526,17551,17640,17608,17897,17325,17526,17392,20208,19875,19818,19421,19374,19552,21855,21560,21597,21349,21494,21508,26785,26765,26967,26967,26765,26593,15344,15230,15247,16022,16095,16166,18023,18157,18181,14924,15067,15029,19875,19857,19811,19104,19009,19120,21494,21574,21582,26685,26641,26495,26537,26250,26442,26754,26641,27213,26357,25791,25496,26131,26545,26076,18724,18849,18844,18875,18856,18741,18974,19082,19073,18974,19073,18933,24319,24007,24243,24202,24290,24312,17940,18023,18067,18417,18297,18498,25979,26048,25929,26154,26048,25979,26250,26268,25997,26546,26442,26599,16579,16173,16596,16684,16705,16739,16596,16705,16684,25074,25264,24937,24913,25046,25074,24977,25046,24913,14962,14924,15029,16040,16022,16166,17038,17267,17091,17526,17408,17640,19857,19760,19811,20660,20744,20760,20858,21031,20876,21319,21301,21349,21349,21378,21494,21494,21432,21574,20648,20660,20570,21631,21659,21574,21574,21659,21582,21847,21890,21964,24159,24290,24202,24977,25109,25046,24860,24943,24379,25351,24860,25044,25351,25044,25247,21052,21130,21139,21052,20538,20927,20208,19883,19875,19875,19883,19857,19857,19804,19760,21130,21228,21139,21228,21213,21139,20744,20761,20765,20761,20863,20858,16440,16363,16589,16308,16142,16166,16440,16589,16699,16558,16699,16861,16918,16890,16861,17085,16890,16918,15134,15054,15236,15092,15054,15134,18724,18547,18589,19265,19362,19219,26641,26620,26472,26754,26620,26641,26523,26673,26488,26545,26673,26523,20863,20945,20858,26867,26810,26634,26867,26634,26833,26634,26785,26833,21228,21252,21213,20945,21031,20858,15054,14962,15029,14976,14799,14908,14908,14724,15064,14851,14799,14976,14851,14976,14904,14851,14904,14878,14904,14928,14878,15837,15731,16025,18875,18974,18933,19082,19265,19219,21213,21252,21259,24290,24435,24312,24007,24159,24073,26701,26442,26555,26833,26785,26967,15287,15230,15344,15216,15230,15287,16164,16142,16308,16022,15837,16025,17486,17085,17572,17331,17085,17486,17699,17672,17771,16688,17038,17091,18849,18724,18589,19285,19120,19374,14878,14928,14775,21259,21252,21360,15049,15092,15134,15054,14819,14962,19421,19552,19648,19362,19478,19859,19213,19265,19082,26620,26687,26555,26754,26687,26620,26260,26154,25997,25767,25247,25529,26260,25997,26268,21659,21890,21741,21723,21890,21659,16142,16040,16166,21428,21360,21451,21428,21259,21360,21031,21301,21319,26920,26833,26967,26537,26300,26250,15781,15837,16022,21301,21378,21349,26546,26576,26442,26623,26576,26546,26726,26545,26131,26967,26593,27022,18023,17753,17824,17699,17753,17739,18417,18498,18547,15092,14918,15054,15057,15049,15247,24319,24435,24290,26687,26701,26555,26754,26701,26687,15230,15057,15247,15111,15463,15591,15111,15591,15038,14775,14928,14924,14775,14924,14962,16627,16558,16861,16363,16164,16308,16142,16038,16040,16750,16861,16890,16705,16688,16739,16596,16555,16705,16579,16339,16173,16339,16090,16173,19922,19883,20028,19777,19421,19648,22804,22859,22947,21378,21432,21494,25046,25109,25074,24557,24555,24840,16558,16440,16699,16555,16688,16705,24840,24555,24496,16440,16353,16363,15837,15714,15731,15613,15714,15837,15781,16022,15900,17313,17325,17392,18741,18798,18450,18741,18856,18798,18856,18875,18933,17276,17325,17313,17122,17306,17038,19777,19648,19760,19041,18844,19009,19253,19478,19362,19253,19362,19265,24699,24840,24496,26154,26173,26048,26284,26260,26268,26284,26268,26300,19883,19804,19857,23419,22859,23198,18501,18417,18547,18584,18547,18724,19104,19120,19285,18798,18510,18450,18974,18991,19082,26461,26284,26300,26576,26537,26442,26647,26537,26576,26701,26599,26442,26796,26599,26701,15285,15578,15629,15907,15804,16070,15527,15578,15285,14705,15497,15208,19804,19777,19760,21432,21631,21574,23509,23321,22930,20744,20648,20761,20761,20958,20863,20863,20958,20945,20945,20958,21031,21031,21082,21301,21301,21355,21378,21378,21355,21432,21432,21584,21631,20624,20648,20570,15900,16022,16040,16164,16038,16142,17325,17408,17526,17330,17408,17325,26810,26986,26699,27056,26986,26810,27056,26810,26867,17753,17699,17771,16386,16440,16558,17940,17753,18023,14799,14724,14908,14679,14724,14799,14679,14799,14669,20624,20958,20761,21631,21723,21659,21584,21723,21631,18875,18991,18974,26599,26623,26546,26507,26461,26300,26767,26623,26599,15216,15140,15230,15049,14918,15092,15111,15140,15216,15057,15140,14929,16698,17122,17038,18875,19039,18991,18336,18111,18174,14525,14730,15297,20958,21082,21031,26260,26173,26154,26291,26173,26260,26291,26260,26284,18283,18336,18174,14932,14918,15049,14669,14799,14851,18067,18023,18181,26796,26754,26957,21259,21162,21213,21213,21162,21139,21139,21162,21052,21052,20344,20538,20028,19883,20208,19883,19922,19804,19804,19739,19777,21302,21162,21259,21302,21259,21428,26833,26920,26867,26593,26657,27022,19478,19574,19859,19548,19574,19478,16476,16489,16119,16555,16476,16688,16688,16606,17038,26507,26300,26537,15875,15900,16040,15762,15731,15376,18283,18450,18336,17122,17276,17313,17330,17276,17163,16353,16164,16363,16038,16007,16040,16440,16388,16353,16386,16388,16440,16750,16890,17085,17940,17739,17753,16627,16750,16788,21311,21302,21406,17331,17486,17411,24840,24941,24977,25225,25264,25109,24957,24941,24840,25664,25750,26103,26623,26647,26576,26767,26647,26623,14658,14856,15208,14704,14775,14962,15057,14932,15049,16154,16164,16353,19241,19180,19285,18092,18181,18417,18092,18067,18181,19241,19285,19421,18991,19213,19082,19039,19213,18991,20570,20660,19859,19423,19548,19478,17411,17672,17699,24159,24319,24290,24620,24699,24496,24007,24319,24159,22930,22768,23209,26103,25750,26048,20028,20208,20344,19777,19739,19421,27022,26657,26673,24620,24496,24435,18584,18724,18753,17940,17864,17739,17371,17411,17699,22168,21964,21890,26173,26103,26048,26470,26291,26284,26470,26284,26461,17924,17864,17940,18336,18450,18510,18854,19039,18875,18062,18111,18264,15140,15057,15230,15731,15714,15543,15950,16007,16038,15613,15837,15781,24522,24620,24435,19180,19104,19285,19214,19104,19180,17708,17699,17739,16788,16750,17085,15613,15781,15658,17864,17708,17739,18753,18724,18844,26746,26507,26537,14819,15054,14918,14819,14918,14745,19922,19739,19804,16007,15875,16040,20648,20624,20761,20958,21110,21082,21082,21198,21301,20570,19859,20430,14756,14819,14745,19649,19859,19574,16489,16476,16555,16090,16279,16070,16476,16606,16688,25225,25109,24977,25109,25264,25074,25225,24977,24941,24957,24840,24699,19104,19041,19009,19040,19041,19104,18696,18875,18741,19213,19253,19265,26796,26767,26599,26647,26756,26537,26796,26701,26754,14669,14851,14634,14724,14525,15297,16750,16627,16861,16388,16154,16353,16164,15950,16038,15878,15791,15875,16788,16758,16683,18422,18092,18417,18067,17924,17940,17568,17525,17708,19041,18753,18844,18584,18501,18547,26920,27056,26867,26957,26754,27213,27156,27056,26920,18069,17924,18067,18450,18696,18741,17452,17640,17408,26494,26470,26461,26291,26643,26173,26494,26461,26507,15563,15804,15907,24319,24380,24435,24800,24957,24699,24243,24380,24319,14634,14851,14878,16285,16154,16388,16090,16339,16279,17167,17085,17331,21122,21110,20958,24943,24911,24379,25381,24911,24943,24800,24699,24620,19417,19241,19421,19039,19253,19213,19548,19567,19574,21723,22168,21890,21822,22168,21723,24262,23452,23886,21311,21203,21302,18629,18501,18584,21162,21203,21052,19922,19878,19739,21302,21203,21162,21302,21428,21406,21110,21198,21082,15804,16090,16070,14756,14704,14962,14620,14634,14878,19423,19567,19548,14620,14878,14775,20344,20208,20538,19417,19214,19241,21406,21428,21560,17276,17330,17325,17163,17276,17122,24380,24522,24435,24052,24243,24007,26767,26753,26647,26908,26753,26767,18387,18696,18450,19239,19423,19253,19241,19214,19180,19041,18893,18753,18629,18422,18501,19417,19421,19739,20028,19977,19922,21560,21428,21597,21198,21355,21301,18264,18029,18062,18283,18387,18450,14573,14620,14775,15791,15781,15900,15791,15900,15875,17411,17218,17331,17525,17371,17699,17525,17699,17708,18501,18422,18417,17894,17864,17924,17568,17708,17864,18629,18584,18753,18353,18387,18283,26660,26494,26507,26470,26643,26291,14819,14756,14962,14704,14573,14775,14745,14918,14932,14929,14932,15057,14867,14929,15140,14867,15140,14869,19253,19423,19478,20430,20600,20570,19239,19253,19039,26753,26756,26647,26844,26756,26916,15578,15563,15907,15640,15786,16090,15285,15629,15460,15878,15875,16007,16427,16558,16627,16427,16386,16558,16154,15950,16164,16427,16627,16599,16599,16627,16582,21820,22585,22529,24466,24522,24380,26631,26357,26517,25332,25225,24941,25332,24941,24957,26641,26685,27213,16386,16285,16388,16582,16627,16788,14730,14658,15358,14856,14705,15208,14327,14658,14186,14662,14705,14856,15613,15543,15714,15477,15543,15613,15527,15563,15578,17371,17218,17411,17568,17864,17761,17330,17452,17408,17337,17452,17330,19330,19417,19467,19214,19040,19104,14597,14525,14724,14597,14724,14679,14597,14679,14479,14679,14669,14479,20624,20600,20958,21110,21122,21198,21198,21324,21355,20570,20600,20624,19649,19574,19567,17167,17218,17159,14479,14669,14482,18174,18353,18283,17859,18029,17975,16019,15950,16154,15791,15658,15781,19144,19040,19214,21187,21052,21203,21187,20344,21052,20028,20052,19977,19977,19878,19922,21187,21203,21311,21187,21311,21265,24688,24800,24620,18600,18667,18696,18696,18667,18875,18093,18353,18174,19662,19649,19616,19649,19567,19616,17608,17749,17897,20600,21122,20958,21355,21584,21432,14929,14745,14932,14756,14636,14704,14452,14482,14634,15376,15591,15762,14702,14692,14745,15950,15878,16007,24522,24688,24620,26494,26643,26470,26706,26660,26507,26746,26537,26756,15601,15658,15791,15543,15376,15731,15527,15492,15563,15563,15537,15804,15405,15492,15527,18069,18067,18092,17159,17218,17238,17452,17608,17640,17563,17608,17434,21265,21311,21406,26967,27156,26920,27213,26685,27676,27160,27156,26967,14658,14662,14856,14565,14662,14402,22947,22585,22804,21358,21265,21406,27666,27022,26673,27666,26673,26545,26726,26131,26116,20344,20052,20028,21358,21406,21560,21122,21324,21198,18600,18696,18387,26844,26746,26756,18123,18069,18092,18123,18092,18422,17859,18062,18029,18111,18093,18174,18341,18600,18387,17859,17975,17749,23806,23419,23198,23636,23419,23806,16427,16422,16386,16386,16251,16285,16285,16158,16154,15950,15812,15878,16421,16422,16427,16421,16427,16599,16422,16251,16386,20052,19972,19977,21324,21338,21355,15232,15285,15460,17916,17894,17924,17732,17859,17749,23509,23704,24007,24466,24584,24522,24522,24584,24688,23631,23704,23509,22414,22136,22768,26357,25496,26517,16251,16158,16285,16683,16582,16788,17167,17331,17218,17036,17167,17159,17371,17238,17218,16906,17163,17122,17608,17702,17749,16698,17038,16606,16420,16606,16476,16420,16476,16119,26660,26616,26494,26741,26616,26660,16158,16047,16154,15878,15794,15791,16758,16788,17085,15523,15376,15543,15523,15543,15477,15400,15537,15563,15285,15405,15527,17563,17702,17608,19972,19878,19977,18900,18893,19040,19040,18893,19041,19144,19214,19417,18667,18854,18875,18726,18854,18667,14745,14636,14756,14692,14636,14745,16047,16019,16154,19330,19144,19417,26796,26908,26767,26746,26706,26507,27877,26986,27056,18658,18629,18753,18341,18387,18353,21338,21584,21355,26978,26706,26746,15477,15613,15658,17163,17244,17330,23779,24052,24007,14538,14573,14704,18069,17916,17924,17894,17761,17864,17941,17916,18069,18062,18093,18111,17859,17909,18062,17890,17909,17859,17732,17749,17702,18355,18123,18422,18054,18093,18062,21855,21681,21560,21576,21681,21581,14597,14436,14525,14525,14502,14730,14350,14436,14597,15285,15350,15405,15400,15563,15492,15232,15350,15285,15812,15794,15878,17780,17761,17894,17719,17732,17702,18629,18355,18422,18093,18341,18353,22768,22136,22168,23704,23779,24007,23789,23779,23704,26616,26643,26494,26774,26643,26616,14869,15140,15111,14945,15111,15038,18893,18755,18753,18629,18326,18355,18889,18755,18893,18624,18726,18667,19616,19567,19522,18624,18667,18600,26916,26756,26753,26706,26741,26660,20382,20430,19859,20524,21165,21122,21122,21165,21324,21324,21165,21338,21338,21423,21584,20382,19859,19649,26957,26908,26796,27035,26908,27213,14482,14669,14634,14436,14502,14525,15357,15492,15405,16241,16420,16119,17244,17337,17330,24911,24262,24086,19239,19039,18808,14917,14945,15038,14917,15591,14841,17434,17608,17452,23419,22947,22859,23301,22947,23419,26980,26741,26706,14702,14745,14929,14636,14538,14704,17167,17036,17085,17371,17350,17238,19264,19239,19217,25359,25365,24800,24800,25332,24957,24466,24380,24243,24466,24243,24052,16158,16006,16047,16047,16006,16019,16019,15812,15950,16251,16237,16158,16422,16237,16251,16421,16237,16422,16421,16599,16582,16524,16582,16683,16401,16420,16241,17163,17131,17244,17244,17227,17337,16420,16436,16606,14452,14634,14620,14452,14620,14573,16758,16524,16683,19522,19567,19423,20382,20582,20430,20582,21122,20600,27156,27160,27056,27022,27160,26967,19144,18900,19040,18755,18658,18753,18805,18900,19144,22790,22529,22585,26908,26916,26753,26980,26774,26741,27035,26916,26908,14945,14869,15111,14420,14591,14692,15523,15131,15376,15601,15477,15658,17337,17434,17452,17403,17434,17345,18728,18658,18755,22947,22790,22585,22865,22768,22168,21715,21723,21584,26643,26103,26173,25767,26120,25351,25381,25009,24911,24911,24462,24262,15868,16006,16158,15558,15601,15791,15350,15357,15405,15133,15232,15460,15133,15460,14938,17371,17525,17350,17036,16758,17085,16906,17131,17163,23846,23636,23806,22947,23037,22790,24160,24466,24052,14591,14538,14636,14591,14636,14692,16847,16758,17036,20382,19649,19662,19239,19522,19423,17732,17890,17859,17909,18054,18062,18464,18600,18341,17563,17719,17702,17403,17719,17563,19467,19417,19739,19972,19933,19878,20052,19933,19972,20014,19933,20052,20136,20052,20344,20136,20344,20271,21358,21187,21265,21576,21358,21560,21576,21560,21681,24131,23846,23806,14945,14848,14869,14801,14917,14751,26741,26774,26616,26586,26120,26819,26978,26746,26844,14342,14452,14573,21165,21423,21338,15467,15601,15558,14751,14917,14779,17482,17525,17568,16994,16847,17036,18900,18889,18893,18728,18889,18900,17761,17482,17568,17686,17482,17761,17780,17894,17916,17941,18069,18123,17941,18123,18028,18123,18355,18194,14662,14565,14705,14402,14662,14658,14702,14929,14867,14801,14848,14945,18464,18624,18600,18726,18639,18854,19612,19616,19522,18464,18341,18327,21581,21681,21880,21423,21553,21584,18326,18629,18389,26357,26653,26116,27847,27877,27160,26631,26653,26357,15232,15191,15350,15133,15191,15232,16994,17036,17159,17429,17350,17525,17429,17525,17482,14702,14867,14869,14538,14455,14573,16429,16421,16582,16237,16165,16158,16006,15812,16019,16429,16582,16524,16429,16524,16365,16420,16401,16436,16436,16698,16606,16489,16173,16119,16173,15786,16119,18194,18326,18204,26653,26726,26116,14848,14702,14869,16421,16429,16365,26916,26976,26844,27035,26976,26916,15191,15357,15350,20430,20582,20600,21165,21499,21423,21423,21499,21553,20382,19662,19642,23779,24003,24052,23789,24003,23779,23789,23704,23631,14479,14350,14597,14436,14267,14502,14327,14402,14658,14352,14350,14479,14352,14479,14412,14412,14479,14482,14412,14482,14375,18624,18639,18726,18221,18341,18093,19642,19662,19616,19612,19642,19616,19264,19522,19239,16335,16698,16436,17227,17434,17337,17434,17403,17563,25381,24943,25351,24262,24131,23806,19721,19739,19878,18389,18629,18559,14375,14482,14452,15357,15400,15492,17543,17429,17482,16365,16524,16450,17227,17244,17131,17931,18054,17909,25009,24462,24911,15868,15812,16006,14451,14455,14538,14451,14538,14591,18194,18028,18123,17780,17686,17761,18194,18355,18326,17890,17732,17688,23636,23516,23419,22501,22236,22529,23561,23516,23636,23561,23636,23814,15100,15214,15357,15308,15429,15400,14446,15497,14705,17688,17732,17719,20271,20344,20329,19933,19975,19878,21344,21187,21358,18616,18639,18624,18616,18624,18464,26976,26978,26844,26774,26980,26643,27035,26978,26976,18629,18658,18559,18054,18221,18093,23516,23301,23419,22529,22236,21855,17780,17916,17941,20136,20014,20052,16698,16906,17122,22651,22529,22790,14917,14801,14945,14848,14766,14702,14420,14451,14591,15398,15523,15477,15467,15477,15601,18559,18658,18728,23301,23037,22947,15558,15791,15794,17187,17227,17131,17811,17931,17890,24462,24346,24262,24502,24346,24462,14307,14375,14452,20014,19975,19933,21503,21344,21358,21503,21358,21576,24264,24131,24262,22927,22651,22790,27213,26908,26957,16220,16165,16237,16220,16237,16421,16220,16421,16365,17159,17107,16994,16401,16335,16436,16537,16897,16906,16173,16090,15786,21581,21503,21576,21608,21499,21165,21553,21704,21584,25365,25332,24800,25225,25657,25264,24800,24688,25359,25365,25359,25498,16090,15804,15640,18728,18755,18889,14420,14692,14322,14455,14342,14573,17890,17931,17909,18054,17931,18221,18221,18327,18341,17688,17719,17403,15467,15398,15477,15388,15398,15467,15558,15794,15618,17227,17345,17434,17187,17345,17227,23516,23346,23301,23301,23244,23037,23037,23027,22790,23561,23346,23516,24346,24264,24262,23407,23244,23346,24415,24264,24346,17792,17780,17941,17686,17543,17482,17673,17780,17792,17941,17833,17792,18028,18194,18204,21569,21581,21880,21499,21549,21553,23631,23509,23209,24003,24160,24052,23631,23209,23427,16012,15868,16158,15618,15794,15812,17811,18327,18221,17673,17543,17686,17159,17238,17107,15640,15804,15537,18805,18728,18900,18204,18326,18389,18805,19144,19330,19975,19721,19878,21549,21704,21553,14335,14267,14436,14335,14436,14350,14335,14350,14300,14350,14352,14300,14300,14352,14412,14801,14766,14848,14751,14766,14801,26978,26980,26706,27035,26980,26978,16897,17187,17131,17214,17688,17403,16897,17131,16906,20382,20443,20582,20582,20524,21122,21608,21731,21549,21549,21731,21704,20375,20443,20382,24696,24502,24462,23636,24002,23814,14229,14300,14412,14307,14412,14375,14306,14342,14455,14306,14455,14451,21731,21715,21704,21704,21715,21584,19217,19239,18808,20294,20375,20382,19039,18854,18808,21369,21187,21344,20329,20344,20637,20136,20064,20014,20014,20064,19975,19975,19790,19721,21369,21344,21503,24111,24160,24003,23427,23209,22865,15558,15494,15467,15704,15618,15812,15414,15640,15537,15429,15537,15400,17238,17350,17107,16537,16906,16698,20271,20180,20136,17107,17350,17429,17780,17673,17686,18204,18389,18444,17811,17688,17581,18448,18473,18327,18444,18389,18559,23346,23244,23301,24077,24131,24264,14658,14730,14186,14565,14512,14705,19515,19612,19522,21715,21822,21723,21731,21822,21715,15308,15400,15214,24502,24415,24346,16165,16094,16158,15868,15704,15812,16054,16094,16165,16054,16165,16220,14398,14512,14565,15214,15400,15357,16094,16012,16158,16450,16524,16758,16241,16335,16401,16178,16335,16241,16044,16241,16119,16044,16119,15932,18311,18444,18559,18808,18854,18639,19472,19515,19522,20180,20064,20136,23244,23027,23037,22651,22501,22529,21470,21503,21581,27676,26699,26986,28182,27470,26980,15618,15602,15558,14841,15591,15376,15561,15602,15618,17107,17429,17011,16847,16450,16758,24502,24623,24415,25009,24696,24462,24876,24696,25110,16012,15923,15868,19472,19522,19264,20375,20524,20443,14171,14307,14452,21470,21369,21503,21470,21581,21569,16335,16537,16698,18616,18808,18639,18616,18464,18473,15357,15191,15072,15429,15414,15537,18473,18464,18327,23027,22927,22790,15602,15494,15558,15491,15494,15602,16994,16826,16847,17480,17429,17543,21681,21855,22102,24077,23846,24131,23244,23191,23027,23027,22929,22927,26103,26120,25767,26586,26819,26786,17833,17941,18028,17673,17602,17543,17833,18028,17819,19721,19467,19739,18101,18204,18444,19355,19467,19617,20382,20002,20294,19462,19472,19264,19462,19264,19354,23561,23407,23346,15923,15704,15868,17654,17602,17673,20064,19790,19975,22102,21855,22236,14994,15376,15131,14322,14692,14246,15494,15388,15467,15345,15388,15407,22927,22691,22651,22849,22691,22927,14627,14702,14766,14177,14247,14307,22334,22102,22236,14186,14730,14502,14402,14398,14565,15308,15352,15429,15072,15191,15133,24111,24003,23789,14751,14627,14766,17811,18221,17931,18616,18575,18808,19354,19264,19255,23191,22929,23027,14267,14208,14502,14098,14208,14267,14098,14267,14335,14176,14335,14300,15704,15561,15618,16950,16826,16994,16950,16994,17107,20443,20524,20582,19566,19612,19515,14229,14176,14300,14229,14412,14247,16012,15971,15923,15923,15671,15704,15597,15491,15561,16094,15971,16012,16203,16054,16220,16203,16220,16261,15932,16119,15775,16335,16221,16537,16119,15786,15775,16261,16220,16365,16044,16178,16241,25678,25381,25351,14548,14938,15460,16054,15971,16094,16383,16261,16365,17792,17654,17673,17011,16950,17107,17819,18028,18031,21822,21961,22168,21875,21731,21628,14247,14412,14307,23686,23427,23698,23631,23801,23789,14512,14446,14705,14190,14398,14402,15131,15523,15398,14751,14680,14627,14938,15072,15133,17642,17654,17792,15180,15352,15308,15180,15308,15214,14424,14446,14512,16520,16450,16847,17480,17543,17602,16347,16383,16450,22691,22501,22651,22587,22501,22691,15072,15100,15357,17654,17480,17602,21731,21900,21822,21875,21900,21731,24530,24077,24264,23561,23593,23407,23407,23410,23244,24501,24264,24415,24623,24502,24696,20180,20085,20064,20064,19833,19790,19617,19467,19721,20171,20085,20180,20320,20180,20271,20344,21187,20637,21486,21369,21470,14177,14307,14171,14208,14186,14502,14181,14424,14398,14420,14306,14451,14240,14306,14420,15352,15414,15429,15168,15180,15214,15195,15414,15352,24876,24623,24696,14171,14452,14342,14994,14841,15376,23814,23593,23561,22929,22849,22927,17688,17811,17890,17581,17688,17214,17403,17345,17214,17345,17187,17000,17187,16897,16727,18473,18575,18616,18448,18575,18473,23003,22849,22929,24002,23636,23846,24002,23846,24077,23427,23801,23631,23593,23410,23407,15072,15078,15100,15168,15194,15180,14905,15078,15072,14905,15072,14938,21569,21486,21470,21528,21486,21569,21528,21569,21653,22501,22334,22236,22429,22334,22501,24075,24002,24077,19472,19462,19515,19557,19462,19354,14779,14680,14751,14627,14476,14702,15388,15345,15398,14994,14857,14841,15407,15388,15494,15491,15602,15561,23410,23191,23244,24623,24501,24415,24530,24501,24623,14248,14171,14342,21880,21681,22102,15118,15131,15398,16178,16152,16335,15954,16152,16178,15954,16178,16044,15671,15561,15704,15775,15786,15705,16152,16221,16335,22202,22145,22102,15598,15786,15640,15988,15920,16203,16203,15920,16054,15803,15923,15971,15652,15671,15923,16450,16383,16365,16771,16847,16826,14398,14424,14512,14548,14815,14938,14190,14402,14327,14571,14558,14627,22587,22429,22501,22334,22202,22102,22587,22691,22849,23191,23003,22929,17833,17642,17792,17654,17642,17480,17480,17011,17429,16950,16771,16826,18031,18028,18204,18031,18204,18101,15180,15194,15352,15510,15598,15640,15168,15214,15100,14841,14779,14917,14680,14571,14627,14717,14779,14841,18311,18559,18397,14176,14098,14335,14208,13982,14186,14102,14098,14176,14102,14176,14229,14102,14229,14029,14229,14000,14029,14988,14987,14994,15016,15168,15100,14815,14905,14938,17810,17642,17833,15053,14988,15131,15131,14988,14994,15491,15407,15494,15323,15407,15491,16829,17011,16677,14083,14247,14177,14363,14692,14702,14306,14248,14342,15597,15671,15569,20637,21187,20882,19833,19617,19790,21505,21369,21486,20294,20002,20196,21608,21549,21499,21578,21505,21528,22230,22202,22334,15204,15398,15345,23936,24111,23789,24572,24584,24466,26517,25496,25264,26653,27039,26726,26726,27344,26545,14558,14476,14627,14487,14476,14558,20329,20320,20271,18070,17963,18031,19566,19642,19612,20320,20171,20180,14240,14248,14306,14145,14083,14177,15510,15640,15303,19557,19566,19515,19557,19515,19462,21900,21961,21822,23817,23936,23801,23801,23936,23789,21608,21165,21479,14562,14571,14680,18302,18448,18327,19264,19217,19255,15303,15640,15414,15016,15100,15078,25928,26517,25264,25657,25225,25332,14145,14177,14171,16829,16771,16950,16829,16950,17011,14092,14190,14327,14120,14327,14186,14791,14717,14841,14779,14683,14680,14857,14994,14987,14731,14857,14864,16770,16829,16677,17819,17810,17833,17886,17810,17819,18031,17963,17819,18805,19330,19283,18558,18808,18575,20256,20359,20294,21875,21961,21900,21834,21961,21875,16152,16008,16221,17000,17187,16727,15906,15954,16044,15906,16044,15932,15906,15932,15750,19283,19330,19467,22985,22587,22849,22429,22230,22334,25381,25378,25009,25678,25531,25381,14476,14363,14702,14470,14487,14558,14470,14558,14571,18529,18558,18575,14155,14145,14171,15750,15932,15775,18311,18101,18444,24572,24466,24160,23686,23801,23427,25657,25365,25670,25804,25678,25351,26631,27039,26653,26900,27039,26631,15261,15204,15345,14988,14985,14987,15261,15345,15407,24501,24530,24264,24002,23959,23814,23814,23799,23593,23582,23334,23410,23410,23334,23191,23191,23156,23003,23003,22985,22849,24856,24530,24623,26120,25804,25351,17011,16595,16677,21528,21505,21486,21578,21528,21653,21569,21880,21653,25110,24696,25009,14322,14240,14420,14248,14155,14171,14089,14240,14322,15086,15053,15131,14946,15016,15078,15195,15352,15194,14838,15078,14905,15624,15705,15786,15624,15786,15598,15604,15624,15598,14108,14155,14248,22102,22145,21880,21479,21165,20778,14296,14363,14476,14275,14363,14296,15204,15118,15398,15151,15118,15204,19255,19217,19061,18448,18529,18575,18429,18529,18448,19617,19721,19790,19217,18808,19061,20256,20294,20196,14717,14683,14779,14857,14791,14841,14731,14791,14857,14985,14988,15053,15671,15597,15561,15920,15971,16054,16203,16261,15988,16261,16383,15988,22865,23209,22768,13799,14120,13560,14548,15460,14446,21880,22145,22199,21608,21628,21731,22289,22865,22168,14641,14683,14717,17963,17886,17819,16677,16470,16434,18101,18070,18031,18083,18070,18101,14936,14985,15053,24393,24075,24077,23959,24197,23973,14098,14019,14208,14102,14010,14098,13927,14010,14102,14229,14247,14000,14247,14083,14000,14010,14019,14098,14683,14562,14680,21186,21369,21396,21186,21187,21369,20329,20243,20320,20320,20243,20171,19086,19283,19121,21369,21505,21396,15195,15194,14995,15194,15168,14995,14120,14092,14327,14101,14181,14398,14270,14548,14446,13799,14092,14120,19355,19283,19467,18397,18559,18728,20064,20085,19833,19642,20002,20382,19061,18808,18894,15323,15261,15407,15118,15086,15131,14995,15168,15016,20375,20359,20524,21588,21730,21628,20294,20359,20375,19566,20002,19642,14000,14083,14050,14914,15086,15118,14946,14995,15016,19566,19406,20002,26517,26608,26631,26780,26608,26517,15954,16008,16152,15906,16008,15954,15750,16008,15906,15750,15775,15705,15689,15705,15624,14562,14470,14571,16347,16450,16520,25769,25663,25678,25678,25663,25531,25378,25110,25009,14050,14083,14145,16829,16770,16771,17724,17642,17810,19566,19557,19386,14240,14108,14248,14045,14050,14145,14089,14108,14240,14334,14692,14363,15920,15803,15971,15167,15151,15261,19833,20085,20210,22199,22145,22202,21396,21505,21433,21628,21834,21875,21730,21834,21628,14045,14145,14155,21505,21578,21433,14101,14398,14190,22370,22230,22429,22561,22429,22587,14791,14641,14717,14683,14549,14562,14387,14399,14470,14864,14857,14987,14864,14987,14985,23959,23799,23814,23686,23817,23801,24572,24160,24145,23698,23817,23686,14936,14864,14985,14815,14838,14905,14204,14838,14815,15261,15151,15204,15086,14936,15053,15323,15491,15368,24075,23959,24002,24393,24077,24530,16520,16847,16771,19386,19557,19354,14092,14137,14190,13799,14137,14092,14514,14549,14683,23582,23410,23593,14275,14334,14363,14476,14487,14296,15517,15491,15597,15195,15303,15414,15510,15604,15598,15313,15303,15161,14922,15195,14995,22289,22168,21961,14914,14936,15086,14838,14946,15078,21433,21578,21552,15652,15569,15671,15526,15604,15510,14214,14246,14692,18188,18311,18362,18070,17886,17963,18894,18808,18757,19255,19287,19354,23292,23156,23191,13992,14045,14155,13992,14155,14108,14084,14089,14322,21552,21578,21653,21552,21653,21636,28136,27676,26986,26103,27470,26931,27877,27056,27160,15569,15517,15597,16770,16520,16771,16571,16520,16770,25378,25381,25531,24581,24393,24530,24581,24530,24856,14334,14214,14692,14386,14487,14470,20210,20085,20171,19121,19283,19323,18397,18728,18805,21636,21653,21880,14399,14386,14470,14731,14641,14791,14387,14470,14562,14563,14641,14731,14718,14731,14864,17902,17886,18070,23156,22985,23003,22865,23698,23427,24160,24111,24145,13961,13998,13955,14245,14214,14334,14064,14446,14424,14838,14980,14946,18188,18083,18101,16205,15988,16383,15920,15849,15803,15803,15652,15923,15569,15459,15517,16231,16383,16347,25365,25657,25332,24111,23936,24145,15822,15849,15920,25663,25659,25531,25804,25769,25678,25991,25769,25804,25991,25804,26120,25991,26230,26141,15323,15167,15261,15151,14914,15118,14936,14718,14864,15042,15167,15323,24145,23936,23817,18311,18188,18101,18397,18805,18542,23181,22937,22985,23334,23292,23191,23518,23292,23334,23582,23593,23799,23582,23799,23659,15689,15750,15705,15689,15624,15575,25615,25378,25531,14946,14980,14995,15303,15313,15510,14922,14980,14115,15517,15368,15491,15402,15368,15517,14922,15303,15195,14029,13927,14102,14010,13802,14019,14019,13982,14208,13769,13927,14029,13979,14029,14000,13979,14000,14050,13802,13982,14019,14137,14101,14190,14181,14064,14424,13815,14101,14137,14301,14296,14487,14130,14245,14334,14301,14487,14386,15684,15652,15803,15575,15624,15604,16438,16231,16347,19186,19287,19255,19186,19255,19061,21588,21628,21608,21834,22289,21961,22230,22199,22202,22370,22199,22230,21186,20882,21187,20465,20243,20329,21063,20882,21186,21063,21186,21091,21512,21396,21433,14084,14322,14246,14130,14334,14275,14387,14562,14549,19086,18805,19283,18302,18429,18448,18529,18511,18558,18302,18327,17811,16374,16640,16897,15526,15575,15604,20465,20329,20637,20256,20227,20359,20778,21165,20524,20196,20227,20256,20242,20227,20207,20227,20196,20207,13905,13979,14050,13905,14050,14045,13905,14045,13872,20243,20210,20171,23698,23819,23817,23849,23819,23698,16677,16571,16770,18083,17902,18070,17959,17902,18083,17896,17902,17959,23659,23799,23788,14914,14718,14936,14641,14563,14683,16537,16374,16897,15605,15459,15569,15313,15526,15510,19287,19386,19354,19175,19186,19022,13998,14108,14089,23819,24145,23817,26608,26872,26631,26780,26872,26608,14296,14226,14275,14294,14301,14386,14294,14386,14399,18757,18808,18558,22722,22561,22587,22722,22587,22985,22722,22985,22937,14084,14246,14214,14084,14214,14005,15459,15402,15517,15066,15151,15167,15066,14914,15151,16520,16438,16347,16595,16470,16677,16537,16221,16374,18511,18757,18558,17581,18302,17811,14005,14214,14245,15066,15167,15042,17000,17214,17345,19283,19355,19323,18922,19086,19006,22510,22370,22429,21843,21636,21880,21552,21512,21433,26784,26780,26517,25769,25659,25663,25378,25371,25110,25657,25762,25264,25498,25670,25365,15849,15744,15803,15652,15605,15569,15459,15446,15402,15988,15822,15920,15856,15822,15988,16205,16383,16231,20559,20524,20359,21730,22289,21834,25659,25615,25531,24856,24623,24876,25670,25762,25657,16312,16205,16231,17724,17810,17886,16374,16221,16008,15822,15744,15849,25615,25515,25378,25359,24688,24584,25359,24584,25158,14511,14563,14731,14514,14563,14511,17902,17896,17886,18138,18083,18188,18138,18188,18362,23261,23181,23292,23925,23799,23959,23925,23959,23973,24197,24075,24430,18511,18529,18429,19175,19232,19186,22985,23156,23181,22561,22510,22429,15744,15684,15803,16438,16520,16571,18385,18511,18429,23181,23156,23292,25498,25359,25519,21479,21588,21608,14380,14514,14359,15182,15323,15368,15182,15368,15402,24856,24876,25069,15684,15605,15652,19232,19386,19287,19232,19287,19186,26069,25991,26141,25769,25853,25659,16640,16727,16897,17000,17134,17214,14380,14387,14549,14301,14226,14296,27039,27344,26726,27338,27275,27039,26900,26631,26872,13998,13992,14108,13961,13992,13998,21843,21880,22199,15526,15505,15575,15575,15499,15689,15689,15499,15750,16260,16374,15677,16640,16632,16727,15424,15505,15526,15161,15526,15313,16454,16374,16260,14294,14226,14301,13955,13998,14089,13927,13802,14010,13982,13809,14186,13769,13802,13927,13826,14029,13979,13826,13979,13905,19175,19022,19139,20242,20559,20227,13802,13809,13982,20227,20559,20359,21558,21666,21588,20196,20081,20207,14101,14064,14181,13815,14064,14101,14387,14294,14399,16550,16438,16571,16550,16571,16677,16727,16879,17000,16732,16879,16727,17214,17221,17581,18365,18385,18302,18302,18385,18429,16958,17134,17000,18511,18768,18757,18757,18768,18894,18365,18302,18192,19086,18922,18805,19355,19617,19323,20699,20465,20637,20243,20266,20210,20210,19887,19833,20699,20637,20882,22612,22510,22561,21877,21843,22233,22612,22561,22722,25082,24876,25110,23973,23788,23925,27275,27344,27039,20465,20339,20243,23518,23334,23582,22937,22829,22722,23925,23788,23799,24594,24393,24581,14563,14514,14683,14387,14053,14294,14731,14718,14511,20196,20002,20081,21512,21186,21396,21756,21843,21877,21636,21512,21552,13872,13826,13905,20081,20002,20093,27847,27160,28034,16434,16550,16677,26956,26900,26872,27275,27408,27344,26956,26872,26780,18362,18311,18397,17401,17480,17642,21879,22289,21730,23054,23849,23698,13701,13872,14045,19406,19566,19386,27738,27160,27022,16205,15856,15988,15822,15757,15744,15541,15579,15684,15684,15579,15605,15757,15856,15666,15856,16205,15666,25670,25746,25762,25928,26784,26517,25498,25685,25670,25583,25685,25498,25583,25498,25519,25685,25746,25670,14064,14262,14446,14548,14204,14815,16879,16958,17000,16814,16958,16879,25519,25359,25528,25911,25853,25769,25659,25789,25615,25694,25371,25515,25515,25371,25378,14078,14130,14275,13992,13701,14045,14078,14275,14226,13955,14089,13918,25564,25519,25528,15528,15459,15605,15284,15182,15402,14511,14254,14321,16523,16632,16640,18542,18362,18397,18192,18302,17581,18610,18768,18511,17221,17214,17134,23518,23582,23726,15676,15684,15744,25694,25515,25615,19323,19617,19370,18922,18751,18805,15579,15528,15605,13961,13823,13992,13918,14089,14084,16958,17109,17134,16806,17109,16958,21648,21512,21636,24856,24594,24581,24689,24594,24856,25928,25264,25762,14023,14005,14245,13658,14078,14226,13658,14226,14294,16632,16732,16727,18610,18511,18316,19232,19406,19386,14514,14380,14549,14718,14254,14511,23726,23582,23659,23726,23659,23788,15528,15446,15459,27338,27408,27275,26864,26956,26780,14023,14245,14130,19121,19006,19086,19194,19006,19121,27596,27666,26545,27596,26545,27344,19175,19406,19232,27666,27738,27022,14262,14270,14446,14980,14922,14995,23091,22829,22937,23518,23261,23292,27338,27039,26900,16374,16454,16640,16632,16626,16732,15614,16008,15750,21756,21648,21636,21756,21636,21843,21947,21831,21877,21588,21666,21730,21417,21588,21479,16626,16814,16732,16732,16814,16879,26784,26864,26780,26845,26864,26784,23091,22937,23181,14262,14167,14270,14067,14167,14262,19370,19617,19833,23316,23091,23181,14434,14914,15066,13944,14023,14078,25746,25928,25762,25685,25808,25746,25660,25808,25685,25660,25685,25583,13560,14120,14186,14064,14067,14262,13796,13961,13955,14078,14023,14130,14244,14387,14380,15856,15757,15822,15579,15458,15528,15528,15340,15446,16312,16231,16438,16454,16523,16640,20784,20699,20882,20465,20365,20339,20339,20266,20243,20784,20882,21063,21091,21186,21512,21495,21091,21512,22199,22370,22233,24197,23959,24075,23518,23550,23261,23207,22974,23091,25540,25082,25110,24430,24075,24393,25564,25583,25519,25564,25660,25583,27666,27900,27738,27662,27596,27344,13826,13769,14029,13802,13587,13809,13809,13560,14186,13594,13769,13661,13769,13826,13661,14394,14359,14514,15757,15676,15744,18138,17959,18083,18016,17959,18138,18153,18138,18362,25693,25564,25560,25813,25789,25659,25371,25540,25110,25991,25911,25769,26069,25911,25991,25809,25928,25746,20471,20365,20465,24430,24393,24594,15676,15541,15684,14115,14980,14838,15505,15499,15575,20365,20266,20339,20207,20248,20242,20242,20248,20559,21323,21417,21479,20197,20248,20207,20197,20207,20081,14270,14286,14548,14239,14286,14270,18896,18922,19006,18245,18153,18362,13796,13823,13961,13918,14084,13938,22491,22370,22510,21495,21512,21556,15541,15458,15579,15021,15042,15182,15182,15042,15323,15424,15499,15505,16414,16545,16523,20093,20197,20081,21512,21648,21556,13938,14084,14005,14922,15161,15303,16545,16626,16523,16523,16626,16632,19186,19061,19022,19865,20093,20002,25082,25069,24876,25215,25069,25082,17110,17134,17109,17173,17221,17134,17110,17109,16955,24689,24430,24594,13999,14067,13952,14167,14236,14270,19865,20002,19406,18617,18744,18634,22829,22612,22722,22796,22612,22829,15365,15424,15526,14153,14236,14167,27408,27490,27344,27520,27490,27408,27338,26900,27417,16806,16958,16814,15284,15402,15446,13918,13796,13955,13944,13938,14005,13944,14005,14023,15340,15284,15446,14359,14317,14380,14511,14394,14514,14321,14394,14511,23776,23726,23788,22974,22796,22829,23776,23788,23973,23776,23973,24022,13771,13796,13918,13620,13701,13992,13799,13815,14137,13571,13815,13799,18153,18016,18138,17724,17886,17896,18245,18016,18153,13620,13992,13823,18751,18542,18805,18896,18751,18922,18477,18751,18617,21556,21648,21687,21648,21756,21687,21498,21417,21323,21666,21879,21730,16550,16434,16438,16406,16434,16470,16626,16806,16814,16545,16806,16626,14286,14178,14548,14236,14239,14270,14090,14239,14236,14153,14167,14067,18431,18245,18362,18365,18192,18385,19139,19216,19175,18130,18192,17527,17237,17581,17221,17173,17134,17110,21687,21756,21803,21417,21558,21588,25813,25659,25853,25808,25809,25746,26818,26845,26784,25660,25747,25808,25693,25747,25660,25693,25660,25564,25911,25813,25853,25747,25809,25808,15499,15614,15750,15426,15614,15499,25789,25694,25615,25528,25359,25158,16955,17173,17110,25911,26058,25813,26457,26315,26230,15284,15162,15182,14321,14317,14394,16414,16523,16454,21803,21756,21877,25694,25473,25371,25991,26457,26230,22974,22829,23091,22612,22491,22510,27665,27662,27344,27596,27881,27666,23726,23550,23518,24171,23973,24197,13999,14153,14067,18542,18431,18362,18425,18431,18542,14394,14317,14359,14902,15066,15042,23776,23550,23726,24430,24171,24197,24360,24171,24430,24689,24856,25069,25991,26586,26457,27201,26900,26956,27490,27665,27344,13789,13944,14078,13938,13771,13918,16806,16955,17109,17080,16955,16663,22703,22491,22612,25215,24689,25069,26864,26950,26956,26818,26784,25928,21831,21803,21877,13594,13587,13802,13594,13802,13769,13661,13826,13513,15162,15021,15182,20699,20541,20465,20365,20335,20266,20266,19887,20210,18401,18542,18477,20784,20541,20699,20784,21063,21091,20784,20692,20590,21091,21495,21464,21495,21556,21662,21662,21556,21687,20541,20471,20465,20248,20416,20559,21417,21498,21558,20328,20416,20248,20167,20248,20197,20167,20197,20093,13513,13826,13872,15424,15426,15499,15161,15365,15526,15239,15365,15161,16406,16312,16438,15389,15541,15502,15389,15458,15541,15340,15528,15458,15340,15244,15284,15284,15244,15162,14880,14960,15021,16406,16438,16434,15677,16374,16008,16545,16663,16806,17173,17237,17221,17150,17237,17173,20471,20335,20365,22233,21843,22199,21803,21662,21687,13785,13771,13938,13796,13704,13823,13433,13513,13455,19175,19216,19406,19061,18894,19022,22438,22233,22370,19865,20167,20093,15541,15676,15502,17724,17896,17959,16260,16414,16454,27662,27772,27596,27738,28034,27160,27864,27772,27662,15021,14902,15042,14960,14902,15021,14153,14090,14236,14239,14178,14286,15326,15426,15365,14040,14090,14153,26845,26950,26864,27094,26950,27002,13599,13704,13650,18016,17724,17959,18150,17724,18016,18255,18016,18245,23054,23698,22865,23819,23849,24145,24585,25158,24572,23054,22865,22892,16377,16595,16316,13650,13704,13796,13944,13785,13938,13789,13785,13944,19022,18894,18768,20447,20328,20167,25809,25870,25928,25858,25870,25809,25858,25809,25747,25858,25747,25693,25473,25540,25371,25694,25673,25473,25758,25673,25694,25856,25694,25789,25856,25789,25813,25959,25813,26058,26078,26069,26141,25870,25986,25928,14094,14178,14239,13952,14067,14064,14090,14094,14239,23316,23181,23261,22796,22703,22612,22491,22438,22370,25673,25608,25473,26349,26078,26141,22942,22703,22796,21558,21519,21666,20778,20524,20559,28212,28034,28180,27847,28333,27877,27877,28136,26986,17527,18192,17581,16955,17150,17173,17180,17150,17080,15551,15676,15757,15055,15021,15162,15666,16205,15874,16229,16312,16406,15365,15426,15424,16212,16215,16260,16260,16215,16414,15239,15161,14942,25608,25540,25473,25158,24584,24572,14040,14094,14090,18431,18255,18245,18303,18255,18431,18425,18542,18401,23550,23316,23261,23207,23316,23464,23316,23550,23623,19182,19406,19216,18610,19022,18768,18511,18385,18316,22390,22438,22491,21947,21662,21831,27772,27881,27596,27907,27881,27903,21498,21519,21558,15389,15340,15458,25991,26120,26586,26230,26349,26141,14317,14244,14380,14251,14321,14254,13704,13620,13823,13599,13620,13704,13835,13952,14064,13999,14040,14153,13835,14064,13815,14254,14718,14434,15136,15162,15244,21831,21662,21803,21947,21877,22233,13981,14040,13999,14942,15161,14922,16354,16229,16406,16354,16406,16470,16414,16364,16545,16212,16260,15677,18303,18425,18401,22892,22865,22289,26931,26819,26120,27637,27665,27490,27520,27408,27338,14207,14244,14317,13699,13789,14078,13650,13796,13771,13587,13565,13809,13594,13565,13587,13556,13565,13594,13556,13594,13661,17527,17581,17237,20510,20742,20559,21498,21484,21519,20510,20559,20416,20510,20416,20328,27625,27520,27338,28333,28136,27877,26518,26586,26603,13411,13556,13661,15128,15136,15244,16377,16354,16470,20541,20555,20471,20471,20362,20335,20335,20362,20266,20784,20555,20541,20451,20555,20542,20328,20248,20167,20742,20778,20559,26518,26603,26528,20555,20362,20471,19182,19216,19139,16210,16312,16229,15874,16205,16312,15389,15305,15340,15340,15128,15244,26069,26121,26058,25911,26069,26058,25959,25856,25813,25673,25793,25608,25608,25552,25540,26078,26121,26069,25792,25858,25693,25870,26034,25986,27027,27002,26845,26078,26279,26121,13469,13513,13433,15666,15551,15757,18316,18385,18192,22792,22892,22289,25856,25758,25694,26230,26315,26349,25974,26034,25870,19132,19182,19139,19132,19139,19022,27881,27900,27666,27907,27900,27881,15551,15502,15676,26349,26315,26528,15136,15055,15162,14251,14207,14321,14941,15055,15136,18425,18303,18431,18255,18150,18016,18262,18303,18215,18130,18316,18192,22974,22942,22796,22557,22390,22491,23316,23207,23091,23759,23550,23776,24585,24572,24145,25528,25560,25564,17180,17527,17237,18130,18156,18316,17180,17237,17150,25793,25552,25608,25317,25215,25082,25609,25560,25528,13699,13745,13789,14321,14207,14317,14914,14434,14718,13650,13771,13541,13620,13550,13701,21927,21947,22000,20542,20555,20784,22390,22233,22438,27094,27201,26956,27094,26956,26950,20778,21323,21479,22794,22792,22693,15289,15305,15389,15426,15335,15614,15239,15326,15365,15361,15326,15233,26528,26315,26457,14178,14204,14548,14094,14148,14178,13922,14148,13830,13924,14094,14040,20195,20447,20167,19011,19132,19022,27900,28030,27738,27903,27881,27772,27864,27662,27665,15055,14880,15021,14909,14880,15055,14586,14942,14922,13395,13560,13809,17080,17150,16955,21323,21341,21498,27002,26950,26845,13952,13981,13999,13788,13981,13952,16272,16210,16229,16272,16229,16354,16272,16354,16377,15677,16008,15614,16215,16286,16414,13499,13550,13620,13662,13771,13785,18303,18262,18255,19194,19121,19323,20078,19887,20266,21341,21484,21498,27520,27637,27490,27625,27637,27520,13789,13745,13785,14053,14387,14244,15271,15128,15340,16470,16595,16377,16212,16286,16215,22557,22491,22703,26586,26518,26457,26931,26120,26103,14207,14087,14244,14254,14017,14071,14148,14204,14178,14117,14204,13922,19887,19370,19833,13571,13835,13815,13981,13924,14040,14125,14087,14207,22892,23200,23054,23054,23200,23849,23849,24585,24145,21879,21666,21519,27923,27864,27665,13825,13924,13981,18477,18542,18751,16286,16364,16414,24171,24022,23973,24625,24360,24430,24625,24430,24689,13499,13620,13599,13499,13599,13520,25758,25793,25673,25317,25082,25540,25856,25910,25758,25959,25910,25856,26062,25910,25959,26062,25959,26058,26062,26058,26138,26279,26078,26349,25910,25793,25758,25560,25792,25693,25858,25974,25870,26818,25928,25986,25609,25792,25560,13406,13699,13296,13520,13599,13650,15305,15271,15340,15502,15417,15389,15551,15417,15502,15315,15417,15551,15315,15551,15666,15874,16312,16210,15995,15874,16210,18262,18150,18255,18215,18150,18262,18019,18156,17970,18316,18199,18610,18917,19011,18877,18199,18156,18019,17180,17203,17527,16663,16955,16806,13556,13407,13565,13565,13395,13809,13411,13407,13556,13411,13661,13513,13407,13445,13565,15066,14902,14434,14941,14909,15055,14941,15136,15128,20742,20705,20778,20778,20895,21323,21323,21367,21341,21341,21367,21484,20510,20705,20742,20649,20705,20510,20649,20510,20447,25636,25540,25552,15417,15289,15389,15326,15361,15426,16212,16262,16286,16286,16262,16364,15137,15326,15239,25158,25609,25528,26480,26279,26349,28136,28248,27676,28256,28248,28136,28236,27847,28034,20362,20247,20266,20555,20451,20362,21464,21495,21662,20705,20895,20778,13469,13411,13513,20451,20356,20362,19430,19194,19370,13835,13788,13952,13924,13784,14094,13726,13788,13835,13513,13872,13455,13662,13785,13745,13455,13872,13701,14902,14552,14434,14251,14125,14207,14087,14053,14244,15289,15271,15305,20356,20247,20362,21489,21879,21519,21489,21519,21484,27907,28030,27900,28038,28030,27907,22877,23200,22892,22794,22892,22792,27864,27903,27772,27923,27903,27864,13455,13701,13424,14071,14125,14251,26155,25986,26034,27094,27227,27201,27661,27625,27338,13424,13701,13550,14942,15137,15239,15138,15137,14830,20247,20078,20266,26518,26528,26457,26603,26586,26786,13560,13571,13799,13052,13571,13560,21947,21927,21662,22000,21947,22233,14125,14053,14087,27173,27227,27094,27899,27923,27665,27417,26900,27201,13500,13662,13745,13541,13662,13500,27903,28038,27907,28212,28236,28034,13788,13825,13981,13726,13825,13788,18617,18751,18896,18401,18215,18303,23207,22942,22974,22390,22000,22233,23163,22942,23207,16553,16663,16545,16150,16262,16212,27470,26103,26643,21393,21367,21323,28034,27738,28180,13541,13520,13650,13379,13424,13550,21701,21464,21662,22049,22000,22122,18156,18199,18316,18156,18130,17970,25910,26062,25793,25793,25636,25552,26138,26058,26121,26138,26121,26172,26121,26304,26172,25982,25974,25858,25982,25858,25906,13472,13550,13499,21701,21662,21794,21367,21489,21484,26480,26349,26528,25974,26155,26034,24270,24022,24171,23883,24022,24060,27398,27417,27201,14902,14960,14666,14961,14941,15128,16272,16065,16210,16257,16377,16316,18990,19011,18917,19132,19103,19182,24022,23759,23776,26980,27470,26643,26695,26480,26528,15361,15335,15426,15233,15335,15361,25802,25636,25793,28180,27738,28030,27818,27665,27637,27903,28033,28038,27794,27661,27338,13825,13859,13924,13726,13859,13825,22693,22792,22289,22693,22289,22507,15138,15233,15137,15137,15233,15326,26735,26528,26603,21794,21662,21927,25215,25160,24689,25273,25160,25215,26786,26783,26603,27035,28182,26980,28298,28180,28413,24248,24585,23849,25671,25689,25609,25906,25858,25792,23252,23849,23200,16187,16065,16272,15199,15315,15666,15198,15271,15289,15104,15070,15271,15271,15070,15128,13367,13472,13291,13472,13499,13291,21942,21794,21927,21942,21927,22000,13407,13393,13445,13445,13395,13565,13411,13393,13407,13172,13393,13206,13206,13411,13469,13316,13469,13433,13316,13433,13455,13316,13455,13388,13393,13289,13445,20705,20837,20895,20895,21064,21323,21367,21393,21489,20447,20510,20328,13289,13395,13445,20590,20542,20784,20451,20484,20356,20356,20484,20247,20247,20213,20078,20784,20790,20692,20590,20692,20657,20649,20837,20705,28248,28566,27676,28642,28256,28136,28333,27847,28236,28333,28236,28298,14125,14026,14053,13500,13745,13699,14254,14071,14251,14960,14880,14666,24022,23883,23759,23759,23623,23550,24270,24171,24360,15315,15289,15417,14860,14880,14909,18399,18215,18401,17011,16619,16595,18744,18896,19006,19194,19323,19370,19370,19887,19849,20542,20484,20451,19865,19406,19182,27035,28493,28182,26819,26783,26786,27702,27637,27625,28413,28180,28030,24625,24270,24360,13859,13784,13924,14204,14117,14838,13703,13784,13859,20837,20976,20895,13662,13541,13771,13500,13699,13561,20058,19887,20078,23755,23623,23759,20976,21064,20895,22942,22557,22703,22956,22557,22942,27923,28033,27903,27227,27285,27201,27771,27702,27661,27173,27285,27227,27173,27094,27002,13388,13455,13424,20484,20213,20247,15070,14961,15128,16377,16257,16272,17642,17724,17401,25563,25317,25540,25160,24997,24689,26897,26783,26819,25974,26175,26155,26155,26204,25986,25906,25792,25936,27661,27702,27625,27771,27661,27794,15316,15614,15335,15316,15677,15614,25689,25792,25609,21861,21942,22049,21743,21464,21701,26138,26172,26062,26062,25802,25793,25636,25632,25540,26304,26121,26279,26304,26279,26401,26175,26204,26155,16553,16545,16364,17080,17084,17180,16150,16364,16262,25125,24997,25160,19011,19103,19132,18990,19103,19011,13326,13388,13424,13326,13424,13307,14860,14909,14941,15683,15666,15874,15070,14882,14961,15995,16210,16065,16663,17020,17080,20213,20058,20078,25796,25802,25838,26401,26279,26480,27286,27173,27412,28298,28236,28212,28298,28212,28180,13347,13726,13835,14961,14860,14941,14763,14860,14961,17401,17724,18150,16187,15995,16065,23211,23252,23200,22507,22289,21879,21414,21879,21489,25317,25273,25215,25432,25273,25317,15315,15198,15289,18399,18401,18477,18399,18477,18617,22877,22892,22794,25802,25632,25636,25735,25689,25671,26695,26401,26480,27702,27818,27637,27923,28120,28033,13307,13424,13379,21205,21393,21323,13922,14204,14148,14148,14094,13830,17905,17401,18150,24270,24140,24022,23883,23755,23759,24194,24140,24411,14071,14026,14125,14017,14026,14071,23464,23163,23207,23877,23755,23883,15198,15104,15271,15233,15120,15335,15120,15138,14830,16187,16272,16257,25632,25563,25540,13379,13550,13472,27285,27398,27201,27887,27946,27818,27452,27398,27285,13561,13699,13406,13367,13379,13472,19011,19022,18877,20558,20649,20447,19022,18610,18877,24997,24894,24689,25020,24894,24997,13830,14094,13784,26931,26897,26819,26783,26735,26603,27136,26897,26931,27794,27338,27512,13499,13520,13291,20058,19849,19887,28205,28030,28038,17020,17084,17080,17076,17084,16839,18215,17905,18150,18458,18399,18617,18617,18896,18744,24894,24625,24689,27818,27899,27665,28033,28205,28038,28057,27899,28003,13698,13830,13784,13699,14078,13658,13291,13520,13541,15104,14882,15070,14860,14666,14880,16295,16187,16257,16295,16257,16316,16117,16150,16212,16689,16839,17020,20558,20402,20577,18877,18610,18569,22551,22507,22526,22693,22877,22794,26843,26735,26783,14687,14666,14860,14434,14017,14254,16619,17011,17480,16381,16553,16364,24894,24730,24625,25273,25125,25160,25166,25125,25273,24140,24060,24022,24194,24060,24140,24060,23877,23883,23464,23316,23623,13291,13382,13278,25982,26175,25974,27292,27173,27002,25906,26056,25982,25936,26056,25906,28586,27213,27676,25735,25936,25792,18458,18555,18372,18399,18177,18215,22766,22877,22693,13393,13172,13289,13289,13282,13395,13395,12987,13560,13603,13703,13726,13206,13393,13411,13206,13469,13226,13469,13316,13226,13316,13256,13226,13388,13256,13316,13174,13256,13388,13172,13282,13289,16254,16295,16316,21743,21701,21794,20542,20493,20484,20484,20487,20213,20213,20077,20058,20058,19891,19849,20649,20639,20837,20837,20907,20976,20976,20972,21064,21064,21205,21323,20558,20639,20649,19182,19103,19101,13726,13703,13859,13698,13703,13603,20590,20493,20542,19101,19103,18990,23629,23623,23755,21853,21861,22049,23744,23629,23755,27887,27818,27702,27512,27338,27417,20493,20487,20484,20743,20907,20837,22662,22551,22586,13326,13174,13388,18988,19101,18990,18228,18610,18199,22507,22551,22693,21414,21489,21393,25802,25796,25632,25632,25698,25563,25563,25476,25317,25721,25796,25838,25802,26356,25838,26899,26172,26304,26598,26304,26401,25689,25735,25792,25671,25609,25158,21942,21861,21794,21743,21861,21853,13326,13243,13174,14666,14552,14902,14520,14552,14666,16595,16459,16316,17401,16619,17480,13922,13868,14117,13830,13861,13922,13688,13861,13830,17970,18130,17527,23629,23464,23623,13326,13307,13243,21058,21088,21064,25796,25698,25632,25672,25671,25158,24411,24140,24270,24956,24730,24894,24956,24894,25020,27173,27286,27285,27543,27512,27417,26818,25986,26552,16150,16381,16364,17076,17203,17084,21088,21205,21064,13476,13541,13500,13243,13307,13263,18634,18458,18617,18744,19006,19194,18988,18990,18917,26757,26695,26528,26757,26528,26735,26757,26735,26843,27899,28057,27923,27946,27899,27818,13307,13379,13263,21205,21255,21393,28661,28642,28136,28298,28384,28333,28511,28384,28298,13703,13698,13784,13688,13698,13603,13967,14017,14434,13406,13476,13561,18019,18228,18199,18903,18988,18917,18972,18744,19194,24060,23971,23877,23677,23564,23629,23629,23564,23464,24411,24270,24625,27452,27417,27398,27887,27702,27771,28003,27946,28127,28116,28120,27923,25020,24997,25125,24666,24411,24625,17084,17203,17180,18019,18025,18228,17084,17020,16839,24666,24625,24730,27286,27452,27285,13263,13379,13188,13967,13896,14017,14689,14687,14860,16569,16459,16595,16150,16193,16381,15953,16117,16212,15953,16212,15677,19849,19430,19370,19751,19430,19849,25668,25476,25563,26843,26783,26897,13188,13379,13367,13561,13476,13500,13093,13188,13367,13772,14053,14026,13861,13868,13922,15234,15335,15120,13688,13868,13861,16534,16553,16381,16534,16663,16553,17203,17970,17527,18903,18917,18877,19101,19865,19182,23677,23629,23744,23090,23092,23293,23163,23092,22942,24862,24666,24730,28244,28205,28033,16295,16161,16187,16187,16161,15995,15995,15854,15874,14882,15104,14883,14763,14882,14729,14673,14763,14729,14882,14763,14961,16254,16161,16295,16117,16193,16150,25476,25432,25317,27060,26843,26897,26552,25986,26204,27657,27543,27594,23366,23163,23464,22551,22766,22693,22877,23211,23200,23252,24248,23849,22662,22766,22551,13278,13367,13291,19307,19865,19101,26056,26175,25982,25936,26038,26056,25970,26038,25936,25970,25936,25735,26111,26175,26056,16619,16569,16595,16378,16254,16316,16512,16569,16619,16443,16569,16512,16505,16534,16319,27405,27136,26931,15234,15316,15335,16117,16074,16193,15233,15138,15120,25848,25970,25735,13698,13688,13830,13603,13726,13347,16689,17020,16663,24956,24834,24730,24992,24834,24956,15120,15045,15129,25756,25735,25671,25756,25848,25735,14883,15198,15315,14448,14434,14552,16378,16316,16459,26818,26922,26845,27027,26922,27102,23246,24248,23252,26022,26145,26192,27452,27543,27417,27512,27709,27794,27448,27452,27286,14017,13896,14026,14520,14666,14687,15137,14942,14830,16161,15854,15995,15683,15854,15623,25698,25668,25563,25476,25535,25432,25796,25721,25698,25764,25721,25838,26598,26401,26695,26598,26695,26757,24680,25158,24585,21861,21743,21794,21942,22000,22049,23564,23537,23464,23744,23755,23877,24203,24060,24194,24203,24194,24293,24194,24411,24293,28609,28413,28519,25721,25668,25698,25113,25020,25125,26918,26598,26757,26918,26757,26843,28057,28116,27923,28120,28244,28033,28443,28437,28413,28149,28116,28057,28003,27899,27946,13347,13835,13203,16534,16689,16663,16707,16689,16505,23051,23211,22877,25166,25273,25268,24570,24411,24666,27887,27771,27794,20590,20657,20493,20493,20567,20487,20487,20077,20213,20784,21091,20790,20639,20743,20837,20907,20972,20976,21088,21104,21205,21205,21160,21255,20558,20607,20639,20577,20607,20558,20607,20743,20639,13282,13142,13395,13067,13142,13282,13067,13282,13172,13067,13172,13034,13172,13206,13034,13034,12933,12934,12983,13256,13174,13150,13174,13243,13150,13243,13263,14763,14689,14860,14673,14689,14763,15623,15854,15650,16443,16378,16459,20402,20558,20447,26922,27027,26845,27114,27027,27166,20195,20402,20447,13658,14294,14053,13382,13291,13541,24468,24680,24585,28345,28244,28120,16009,15953,15910,16193,16051,16381,20743,20972,20907,22526,22507,22440,17970,18025,18019,18884,18903,18877,17965,18025,17970,17965,17970,17893,17965,17939,18041,17893,17939,17965,20692,20567,20657,22000,22390,22122,27969,27887,27794,20972,21058,21064,21058,21104,21088,15953,16074,16117,25629,25535,25476,13382,13541,13476,13077,13150,13263,14689,14520,14687,14509,14520,14689,16253,16161,16254,16569,16443,16459,16512,16619,16649,20486,20077,20487,23092,22956,22942,23090,22956,23092,24570,24666,24776,23677,23537,23564,25438,25273,25432,24862,24730,24834,27027,27114,27002,27202,27114,27166,24098,23971,24060,13181,13382,13164,13772,13658,14053,13164,13382,13476,18370,18177,18399,18372,18399,18458,18458,18634,18555,18972,19194,19430,23211,23246,23252,23051,23246,23211,23051,22877,22766,21414,21393,21255,23971,23744,23877,26038,26111,26056,26398,26552,26204,25995,26111,26038,25995,26038,25970,25995,25970,26022,26022,25848,25756,26022,25970,25848,24862,24834,24992,25535,25438,25432,13077,13263,13188,15316,15058,15677,15953,16009,16074,15234,15177,15316,15129,15177,15234,15129,15234,15120,15854,15683,15874,16253,16254,16378,22122,22390,22484,21091,21464,20790,18569,18610,18228,17893,17910,17939,23710,23537,23677,14115,14838,14117,26398,26204,26175,14520,14448,14552,14509,14448,14520,16649,16619,17401,16384,16253,16378,19167,18972,19430,25166,25113,25125,25241,25113,25166,27114,27184,27002,27202,27184,27114,12996,13077,13188,20077,19891,20058,21314,21414,21255,28437,28511,28298,28722,28610,28256,28437,28298,28413,18555,18634,18744,22956,22769,22557,23293,23092,23163,23058,23051,22766,24992,24956,25020,27470,27405,26931,27087,27060,26897,27347,27405,27517,27292,27412,27173,27700,27709,27512,28003,28149,28057,28116,28238,28120,28443,28413,28609,28242,28149,28003,28127,27946,27887,25668,25629,25476,25527,25409,25438,25721,25764,25668,25838,26356,25969,14883,15104,15198,16384,16378,16443,22941,22769,22956,27087,26897,27136,25802,26062,26356,23484,23366,23464,13807,13967,13847,13896,13772,14026,23933,23734,23744,23744,23710,23677,23537,23484,23464,24203,24098,24060,24293,24098,24203,24293,24411,24382,27657,27512,27543,14853,14883,15315,24453,24411,24570,25764,25629,25668,25131,24992,25113,27594,27543,27452,13967,13772,13896,27709,27841,27794,18972,18923,18744,18576,18923,18686,18988,18903,19101,20475,20540,20402,18569,18228,18270,22440,22507,21879,22983,23058,22766,13397,14115,14117,13497,14117,13868,13497,13868,13688,19891,19751,19849,24776,24453,24570,24248,24468,24585,26267,26022,26192,24902,24468,24248,24902,24248,24576,28030,28205,28519,16451,16384,16443,16594,16649,16659,16649,16767,16659,25113,24992,25020,24862,24776,24666,25268,25273,25438,27405,27303,27136,27184,27292,27002,27631,27594,27452,27296,27292,27184,15650,15854,16161,16451,16443,16512,25409,25268,25438,27264,27087,27136,27033,26918,26843,14883,14813,14882,14586,14830,14942,23734,23710,23744,18372,18370,18399,18314,18370,18372,18576,18555,18744,18041,18228,18025,28149,28238,28116,28345,28397,28368,25062,24776,24862,13278,13093,13367,12996,13093,12995,28265,28205,28244,13142,12987,13395,13034,13206,12933,13226,12933,13206,13174,13150,12983,12983,13150,13077,14673,14509,14689,14813,14729,14882,17965,18041,18025,17203,17076,16935,20526,20475,20388,18655,18884,18877,20657,20567,20493,20077,19749,19891,19749,19538,19751,21895,21743,21853,20577,20540,20607,20607,20540,20743,20743,20495,20972,20972,21160,21058,21058,21160,21104,21104,21160,21205,20402,20540,20577,20475,20402,20388,22526,22586,22551,22556,22586,22526,23710,23484,23537,23013,22941,23090,23090,22941,22956,27033,26843,27060,28345,28265,28244,13067,12987,13142,20567,20486,20487,18825,19101,18903,21914,21895,21853,21914,21853,22049,26961,26922,26818,27292,27380,27412,27303,27278,27136,27086,27033,27060,27405,27347,27303,27517,27405,27667,27296,27380,27292,26111,26398,26175,26870,26961,26818,26485,26398,26111,26222,26111,25995,27709,27858,27841,27841,27969,27794,27657,27700,27512,27774,27700,27657,15129,15165,15177,15177,14997,15316,15045,15165,15129,24293,24382,24098,23933,23744,23971,23710,23449,23484,24453,24382,24411,24476,24382,24453,27448,27286,27412,28256,28610,28248,28136,28333,28661,28612,28384,28511,28612,28511,28437,23293,23163,23366,21988,21914,22049,25613,25438,25535,25241,25131,25113,24992,25062,24862,24776,24476,24453,27086,27060,27087,19751,19553,19430,18314,18372,18555,19538,19553,19751,21988,22049,22122,21627,21464,21743,23359,23293,23366,23359,23366,23484,13382,13181,13278,13164,13476,13264,13390,13406,13296,14830,15045,15120,20495,21160,20972,22449,22440,22291,23933,23971,24098,25969,26072,25932,26062,26172,26356,25764,25797,25629,25629,25613,25535,27929,27969,27841,28610,28566,28248,13296,13699,13658,21160,21314,21255,16649,16594,16512,16098,15968,16253,18075,18215,18177,25241,25166,25268,27499,27278,27303,27380,27448,27412,27202,27296,27184,27263,27296,27202,25838,25797,25764,18484,18655,18569,18569,18655,18877,16935,17076,16839,27969,28035,27887,28422,28205,28265,14115,14586,14922,14830,14972,15045,21627,21743,21895,22390,22557,22640,27033,27158,26918,27233,27086,27087,12996,12983,13077,12996,13188,13093,27437,27448,27380,13264,13476,13406,12995,13093,13278,22440,21879,22291,22983,22766,22662,28422,28426,28205,28345,28120,28238,23051,23058,23246,23165,23058,22983,28566,28586,27676,28790,28612,28437,28609,28437,28443,18163,18228,18041,18884,18869,18903,28397,28238,28149,18370,18102,18177,18249,18102,18370,18314,18555,18513,17910,18163,18041,23226,23013,23090,22640,22557,22769,23449,23359,23484,13967,13807,13772,13772,13459,13658,13847,13967,14434,13847,14434,13721,22640,22769,22755,21997,21895,21914,27700,27858,27709,27969,28073,28035,27594,27774,27657,27743,27774,27594,27820,27858,27700,16074,16051,16193,16689,16707,16839,15910,15953,15348,16594,16451,16512,16767,16649,17401,16505,16689,16534,25131,25062,24992,25455,25062,25131,25241,25268,25403,25732,25613,25629,26870,26818,26552,14583,14509,14673,25403,25268,25409,25067,24476,24776,24382,23933,24098,23559,23449,23710,27670,27631,27452,27898,27929,27841,28035,28127,27887,12995,13278,12886,13390,13264,13406,13179,13264,13390,28519,28413,28030,28491,28422,28265,13278,13181,12780,16776,16935,16839,17939,17910,18041,28072,28073,27969,14729,14615,14673,14747,14615,14729,14747,14729,14813,14747,14813,14883,16009,16051,16074,25613,25527,25438,18249,18314,18112,18163,18270,18228,18095,18270,18163,26445,26536,26530,26762,26712,26552,13327,13296,13658,16613,16451,16594,15683,15199,15666,16707,16776,16839,16319,16534,16381,27278,27264,27136,27086,27158,27033,27409,27264,27278,27409,27278,27499,13160,13181,13164,15968,16161,16253,18075,18177,18102,16855,16767,17401,16659,16613,16594,16642,16776,16707,18112,18075,18102,23486,23449,23559,23226,23090,23293,27296,27437,27380,27448,27670,27452,27357,27437,27296,28153,28127,28035,28570,28519,28422,18739,18869,18884,18739,18884,18655,23013,22769,22941,13034,12928,13067,13067,12914,12987,13203,13835,13571,12934,12928,13034,13226,13256,12933,13256,12845,12933,12928,12914,13067,14615,14583,14673,14173,14434,14448,14572,14583,14615,21997,21914,21988,20567,20553,20486,20486,20412,20077,25241,25455,25131,25527,25403,25409,26829,26712,26790,26961,27102,26922,27233,27158,27086,27058,27102,26961,28661,28333,28384,28610,28637,28566,28566,28711,28586,12933,12846,12797,20692,20553,20567,20540,20526,20743,21160,21624,21314,20475,20526,20540,20388,20402,20195,20553,20412,20486,27858,27898,27841,27929,28072,27969,28073,28153,28035,27774,27820,27700,27849,27820,27774,27743,27594,27631,28642,28722,28256,27768,27743,27631,28519,28205,28426,28664,28661,28384,12883,12983,12996,20195,20167,19865,24108,23933,24382,28037,27898,27858,25797,25732,25629,25613,25864,25527,25527,25864,25403,25969,25732,25797,25969,25797,25838,26712,26870,26552,27545,27670,27448,13052,13560,12447,13603,13497,13688,23364,23293,23359,27992,28072,27929,18314,18249,18370,18576,18744,18923,20324,20195,20246,28127,28242,28003,28188,28242,28127,28722,28637,28610,28664,28384,28612,27327,27233,27087,26304,26598,26899,27102,27166,27027,27437,27545,27448,27226,27166,27102,28422,28519,28426,28368,28265,28345,13296,13179,13390,13264,13160,13164,13099,13179,13157,18652,18739,18655,18869,18825,18903,28637,28711,28566,14773,14747,14883,16767,16613,16659,16947,16855,17401,17905,18215,18075,16776,16845,16935,17893,17970,17203,16760,16845,16776,27667,27405,27470,27264,27327,27087,27667,27470,27766,27585,27545,27437,13347,13497,13603,14761,14830,14281,17978,17905,18075,17893,17203,17140,18270,18409,18569,28140,28153,28073,12653,13560,12987,22122,21997,21988,22137,21997,22122,22137,22122,22399,16191,16319,16381,16611,16642,16707,16009,15999,16051,15910,15999,16009,15953,15677,15348,27043,27058,26961,28790,28664,28612,28661,28664,28784,13099,13160,13264,22440,22556,22526,22497,22449,22327,22556,22449,22497,16191,16381,16051,18241,18409,18270,27409,27327,27264,26598,26918,26899,27166,27263,27202,27271,27263,27166,16433,16707,16505,13807,13702,13772,14173,14448,14509,26022,26222,25995,26712,26829,26870,26870,26932,26961,26445,26222,26281,28037,28025,27898,27898,27992,27929,28072,28140,28073,27743,27849,27774,27768,27849,27743,27768,27631,27670,13722,13702,13807,15623,15535,15683,15486,15535,15623,16253,16384,16098,18077,18095,18163,18739,18825,18869,18484,18652,18655,22920,22755,22769,22920,22769,23013,23364,23359,23449,23486,23364,23449,28315,28188,28153,28153,28188,28127,28397,28345,28238,28397,28149,28390,28025,27992,27898,21774,21627,21895,22484,22390,22640,14583,14411,14509,14603,14572,14615,14603,14615,14747,27058,27098,27102,27157,27098,27058,17025,16947,17105,16711,16613,16767,27499,27303,27347,27766,27470,28220,15045,14972,15165,14761,14972,14830,14997,14981,15022,26918,27158,26899,25732,25806,25613,17910,18077,18163,17888,17893,17140,17907,17893,17888,22607,22484,22640,27992,28140,28072,16319,16433,16505,16642,16760,16776,16411,16433,16319,27521,27158,27233,27528,27347,27517,27263,27357,27296,27545,27768,27670,27487,27357,27263,12995,12883,12996,12886,12883,12995,21986,21895,21997,26693,26552,26398,23058,23165,23246,22983,22662,22831,27667,27528,27517,13347,12739,13497,13052,13203,13571,15942,16191,16051,15942,16051,15999,19167,18923,18972,18112,17978,18075,18513,18435,18279,22755,22607,22640,23065,22920,23013,17907,18077,17910,18363,18484,18409,18711,18739,18652,23559,23710,23680,23364,23226,23293,25811,25806,25732,25403,25455,25241,23680,23933,23732,23680,23734,23933,23680,23710,23734,26829,26932,26870,27098,27226,27102,12803,12886,13278,13847,13722,13807,13702,13652,13772,13667,13722,13847,13179,13099,13264,12780,12803,13278,13157,13179,13296,18711,18825,18739,18484,18569,18409,22097,21986,22137,22137,21986,21997,22813,22607,22755,22449,22556,22440,21879,21414,21624,13555,13652,13702,27992,28181,28140,28037,27858,27820,28037,27820,27849,12914,12865,12987,12928,12857,12914,12934,12857,12928,12797,12857,12934,12797,12934,12933,12933,12845,12846,20692,20650,20553,20553,20552,20412,19749,19751,19891,20790,20650,20692,28642,28818,28722,28722,28759,28637,28637,28753,28711,28833,28805,28642,28833,28642,28661,16711,16767,16855,16433,16611,16707,16411,16611,16433,20650,20552,20553,20526,20495,20743,20388,20495,20526,20383,20495,20388,20383,20388,20195,21179,20790,21464,27542,27499,27347,27483,27233,27327,27787,27768,27545,28805,28818,28642,13256,12983,12845,12857,12865,12914,14773,14603,14747,14411,14173,14509,14997,15177,15165,16313,16411,16319,26932,27043,26961,28818,28734,28722,28766,28833,28661,12845,12983,12693,20460,20383,20324,28734,28759,28722,28711,28778,28586,18576,18513,18555,17105,16947,17401,19167,19430,19553,18241,18270,18095,22831,22662,22586,28273,28149,28242,28533,28570,28422,28784,28664,28851,28273,28242,28188,28273,28188,28315,13339,13327,13658,18077,18241,18095,23486,23226,23364,22920,22813,22755,28315,28153,28181,28759,28754,28637,28784,28766,28661,28802,28609,28519,12853,12983,12883,28491,28265,28368,16098,16384,16080,15910,15942,15999,20324,20383,20195,18630,18711,18652,26222,26485,26111,26829,26951,26932,27004,27157,27043,28558,28491,28368,18112,18102,18249,16761,16711,16855,18077,18218,18241,17893,17907,17910,17203,16935,16884,23486,23559,23226,23933,24108,23732,28754,28753,28637,28790,28437,28609,14972,14997,15165,16015,16055,15942,14997,14972,14981,15535,15199,15683,15531,15486,15623,26485,26693,26398,16760,16935,16845,16313,16319,16191,16761,16855,16947,16080,16384,16451,26693,26762,26552,27483,27327,27409,27528,27542,27347,27650,27542,27528,28753,28778,28711,22399,22122,22484,20844,20773,20790,16080,16131,16085,15968,15650,16161,27157,27058,27043,27157,27226,27098,27357,27487,27437,28377,28181,27992,28164,28037,27849,23226,23065,23013,22535,22399,22484,23166,23065,23226,25806,25864,25613,25969,25932,25732,27483,27409,27499,26762,26790,26712,28273,28390,28149,28558,28533,28491,28315,28390,28273,28778,28821,28586,27667,27766,27528,22535,22484,22607,18279,18112,18314,28181,28153,28140,12803,12883,12886,12990,13157,13296,13652,13562,13772,13327,13140,13296,13555,13562,13652,13459,13562,13431,22833,22813,22920,17105,17401,17248,17401,17905,17685,27035,27213,28493,12816,12853,12883,12816,12883,12803,28821,28771,28586,25932,25811,25732,14411,14583,14572,21920,21774,21895,22399,22097,22137,27271,27487,27263,28369,28377,28037,14401,14411,14572,14478,14572,14603,18218,18363,18241,18241,18363,18409,18484,18630,18652,16760,16642,16522,23892,23166,23226,24382,24476,24108,27226,27271,27166,27568,27271,27226,28493,27213,28586,28377,27992,28025,12803,12677,12774,16711,16538,16613,16869,16761,16947,16522,16642,16611,22555,22535,22607,22185,22148,22097,22556,22831,22586,21624,21414,21314,18218,18077,17907,23065,22833,22920,22813,22555,22607,23732,23226,23559,21850,21624,20974,28867,28790,28609,18460,18630,18484,20324,20246,20347,23094,22833,23065,22743,22831,22556,22983,23093,23165,23707,24248,23246,13318,13339,13658,27004,27043,26932,16055,16313,16191,16411,16522,16611,16055,16191,15942,16586,16538,16711,16305,16522,16411,27542,27554,27499,27650,27554,27542,27487,27585,27437,27683,27585,27487,27683,27487,27271,12931,13160,13099,15486,15199,15535,15003,15199,15259,17025,16869,16947,16761,16586,16711,16941,17105,17033,21920,21895,21986,21920,21986,22148,26222,26445,26485,26485,26627,26693,26693,26627,26762,26762,26797,26790,26790,26951,26829,26222,26022,26267,26215,26192,26145,26445,26512,26485,22148,21986,22097,22717,22555,22813,28491,28533,28422,28570,28802,28519,28466,28368,28397,28466,28397,28390,28466,28390,28765,14997,15022,15316,14981,14972,14862,26512,26627,26485,21624,22291,21879,22975,23093,22831,14830,14586,14281,13562,13459,13772,13555,13702,13722,14462,14478,14603,14411,14113,14173,16098,15983,15968,16080,15983,16098,16941,16869,17025,20650,20747,20552,19749,20077,19903,20790,20747,20650,20773,20747,20790,28805,28908,28818,28818,28879,28734,28734,28947,28759,28759,28947,28754,28754,28944,28753,28753,28946,28778,28778,28994,28821,28821,28932,28771,28833,28908,28805,28868,28908,28833,28868,28833,28766,28868,28766,29038,12857,12683,12865,12865,12653,12987,13052,12710,13203,12589,12683,12857,12679,12857,12797,12679,12797,12846,12679,12846,12657,12846,12845,12657,12845,12587,12657,20844,20790,21179,28908,28879,28818,12983,12853,12693,20495,20527,21160,20383,20460,20495,20192,20246,20195,29038,28766,29037,18038,18218,17907,18442,18460,18484,18442,18484,18363,19813,20192,20195,28558,28765,28749,12683,12653,12865,19715,20195,19865,26627,26797,26762,28879,28947,28734,12693,12853,12647,27554,27483,27499,28947,28944,28754,13339,13262,13327,13459,13318,13658,14172,14586,14021,15799,15650,15968,22291,22327,22449,22311,22327,22291,27521,26899,27158,25932,26072,25811,26797,26951,26790,27568,27683,27271,27554,27917,27483,27766,27650,27528,27872,27650,27766,20077,20412,19903,17869,17978,17989,20844,20703,20773,22097,22274,22185,14478,14401,14572,13653,13667,13847,14406,14401,14478,16368,16451,16613,15337,15531,15306,16368,16613,16538,16313,16305,16411,15897,15942,15910,28944,28946,28753,29180,28493,28586,13721,14434,13953,13459,13168,13318,13653,13669,13511,26951,27004,26932,13667,13555,13722,18825,19307,19101,18218,18442,18363,23166,23094,23065,22553,22518,22555,22518,22399,22535,23087,23094,23166,22831,23093,22983,22743,22556,22719,16703,16586,16761,17105,16941,17025,17685,17905,17978,13318,13262,13339,13157,12931,13099,13114,13262,13318,13414,13431,13562,17869,17685,17978,17978,18112,18004,28533,28653,28570,28695,28653,28533,12647,12853,12816,12774,12816,12803,28790,28851,28664,28900,28851,28790,22719,22556,22497,28466,28558,28368,28811,28558,28749,28994,28932,28821,18279,18314,18513,22518,22535,22555,21464,21627,21179,28810,28802,28570,26445,26530,26512,26512,26638,26627,26627,26862,26797,26797,26924,26951,26951,26924,27004,26267,26192,26281,13953,14434,14173,14646,14462,14603,15483,15897,15910,16055,16305,16313,15022,15058,15316,14955,15058,15022,14955,15022,14981,26530,26638,26512,22901,22813,22833,28840,28810,28570,28811,28695,28533,14862,14955,14981,26145,26022,25756,13262,13140,13327,13037,13140,12929,16015,16305,16055,16428,16884,16760,16760,16884,16935,17888,18038,17907,18218,18038,18442,18686,18513,18576,16835,16761,16869,13037,12990,13296,13667,13501,13555,13555,13414,13562,13273,13168,13459,13721,13653,13847,14295,14411,14401,23094,22901,22833,15199,14853,15315,15007,14853,15199,14761,14862,14972,14866,14862,14761,15650,15531,15623,15799,15968,15983,15987,15983,16080,28867,28900,28790,28840,28570,28653,12677,12803,12453,18166,18004,18112,28867,28609,28802,13356,13414,13555,14462,14406,14478,14195,14406,14238,16085,15987,16080,15897,16015,15942,15554,16015,15897,14853,14773,14883,25811,25864,25806,26356,26072,25969,26975,26924,26797,27568,27226,27574,16941,16835,16869,17028,16835,16941,17248,17401,17685,17743,17685,17869,16428,16760,16522,28020,27872,27766,27650,27748,27554,27117,26923,26899,12780,13181,13160,12875,12931,13157,22717,22553,22555,22518,22534,22399,17805,17743,17869,23680,23732,23559,22675,22717,22901,24108,24476,25067,19538,19167,19553,19322,19167,19538,28949,28840,28653,28974,28867,28802,16586,16368,16538,16263,16368,16332,18004,17989,17978,18279,18166,18112,18179,18166,18279,20747,20703,20552,20773,20703,20747,20844,20850,20812,29031,28586,28771,28020,27831,27872,12683,12589,12653,12139,12710,13052,12449,12589,12857,12449,12857,12679,12641,12679,12611,12679,12657,12611,12401,12359,12611,14406,14295,14401,14113,14295,14195,15987,15799,15983,16131,16080,16451,22743,22975,22831,24902,24680,24468,22894,22975,22743,29170,29140,28879,29108,28944,28947,29108,29059,28944,28944,29059,28946,28946,28994,28778,28868,28989,28908,29038,28989,28868,28766,28784,29037,27872,27748,27650,12845,12693,12587,21983,21774,21920,12587,12693,12647,20324,20347,20460,20460,20527,20495,22391,22497,22327,18976,19307,18825,25898,25864,25811,29037,28784,29010,17966,17989,18004,18711,18976,18825,22553,22534,22518,22901,22717,22813,22581,22717,22675,22391,22719,22497,22311,22291,22042,22424,22311,22042,13653,13501,13667,13114,13140,13262,13511,13501,13653,18711,18630,18315,29140,28947,28879,28932,29031,28771,29010,28784,28851,29010,28851,29147,28882,28802,28810,16305,16428,16522,15554,16428,16305,28996,28851,28900,16085,15972,15987,16368,16131,16451,16263,16131,16368,26530,26678,26638,26638,26862,26627,26281,26536,26445,12990,12875,13157,13140,13037,13296,13114,13318,13168,15003,15007,15199,14853,14738,14773,14773,14646,14603,15199,15486,15259,17595,17709,17634,17743,17709,17685,13459,13431,13273,15058,15348,15677,14955,14919,15058,14866,14919,14955,14866,14955,14862,26816,26356,26172,26072,25898,25811,26128,26129,26018,26267,26281,26222,25158,24680,25252,12931,12780,13160,12862,12780,12931,22311,22391,22327,22424,22391,22311,27748,27958,27554,27872,27831,27748,27822,27831,28054,12647,12816,12774,12647,12774,12615,12877,12875,12990,15007,14872,14853,14742,14866,14761,19167,18686,18923,17966,17805,17989,17805,17709,17743,22709,22724,22719,22719,22724,22743,25252,24680,24902,29139,28994,28946,13356,13431,13414,14872,14738,14853,16486,16368,16586,16131,15972,16085,16486,16586,16703,29109,28996,28900,13894,13953,14173,14113,14411,14295,14738,14646,14773,12813,12862,12931,12615,12774,12677,16201,15972,16131,22581,22534,22553,22148,21983,21920,22581,22553,22717,12615,12677,12453,13471,13356,13555,13669,13653,13721,17369,17248,17685,28994,29031,28932,13953,13669,13721,17248,17033,17105,12875,12813,12931,13037,12877,12990,12929,12877,13037,12875,12877,12796,23246,23165,23707,22724,22894,22743,22803,22894,22724,26128,25898,26072,25864,25950,25403,13471,13555,13501,12929,13140,13114,18315,18630,18460,22274,22097,22399,28840,28882,28810,28867,29022,28900,28949,28882,28840,28949,28653,28695,19569,19715,19865,23165,23093,23707,27585,27787,27545,28037,28377,28025,28558,28466,28765,28558,28811,28533,27246,27157,27004,27246,27004,26924,14021,14586,13995,14586,14115,13995,22675,22901,22725,22355,22274,22399,12453,12803,12780,27831,27822,27748,28020,27766,28220,12447,13560,12653,13203,12718,13347,20812,20703,20844,22355,22399,22534,12343,12449,12428,12641,12449,12679,12589,12394,12653,12449,12641,12428,12401,12657,12587,12490,12587,12647,12449,12522,12589,20703,20732,20552,20812,20732,20703,21627,21774,21179,15259,15486,15531,15007,14965,14872,14872,14757,14738,14738,14700,14646,15972,15799,15987,15733,15799,15839,16201,16131,16263,19546,19569,19865,21179,21774,21983,26536,26678,26530,26281,26557,26536,26482,26557,26281,26482,26281,26354,26557,26678,26536,15003,14965,15007,15096,15259,15147,26354,26281,26192,26678,26710,26638,29170,28879,28908,29059,29139,28946,28994,29093,29031,29170,28908,28989,29250,28989,29038,29078,29038,29037,29078,29037,29224,13511,13471,13501,13159,13114,13168,13167,13471,13511,13494,13511,13669,14406,14462,14269,14195,14295,14406,13953,13790,13669,16703,16761,16835,17248,17154,17033,17206,17154,17248,17083,17154,17024,20347,20349,20460,20246,20349,20347,20309,20349,20246,20309,20246,20192,20309,20192,20155,14113,13894,14173,17028,16941,17033,26215,26354,26192,26710,26862,26638,27683,27787,27585,27719,27787,27683,12796,12813,12875,12862,12654,12780,13273,13431,13356,22391,22709,22719,23707,23093,23497,22424,22709,22391,28390,28904,28765,20155,20192,20044,29140,29108,28947,29224,29037,29010,29147,28851,28996,17083,17028,17033,21983,22148,22093,22404,22355,22534,25067,24776,25062,22725,22901,23087,29018,28949,28695,28974,29022,28867,25945,25756,25671,26862,26975,26797,19813,20195,19715,19307,19546,19865,19813,19715,19737,28974,28802,28990,25252,25672,25158,13217,13273,13356,22148,22185,22093,25898,25950,25864,26356,26128,26072,26406,26259,26129,25945,26145,25756,12301,12929,13114,18686,18435,18513,18379,18435,18686,18379,18686,18794,29200,29139,29059,29031,29180,28586,22093,22185,22215,29109,29147,28996,28990,28802,28882,12686,12654,12862,12686,12862,12813,22495,22424,22042,12649,12796,12877,28811,28885,28695,29086,28990,28882,28603,28315,28181,12384,12490,12647,12498,12647,12615,13894,13790,13953,13879,13790,13894,29139,29128,28994,29109,28900,29079,14269,14462,14646,13798,13879,13894,26018,25950,25898,26975,27246,26924,29128,29093,28994,21007,21026,21179,22107,22093,22215,29086,28882,28949,29079,28900,29022,13576,13494,13669,13094,13217,13356,17154,17083,17033,16293,16332,16356,17595,17685,17709,12416,12447,12653,16884,17140,17203,19470,19546,19307,16428,16857,16884,17140,16857,16867,15554,16305,16015,19641,19715,19569,28220,27470,28182,27822,27958,27748,29079,29022,29152,16486,16332,16368,16703,16835,17028,28164,27849,27768,27568,27719,27683,13273,13159,13168,13094,13356,13471,17805,17869,17989,28164,27768,28088,15259,14998,15003,15003,14974,14965,14965,14757,14872,15096,14998,15259,15259,15531,15337,26678,26622,26710,26710,26915,26862,26862,26915,26975,26975,27005,27246,26557,26622,26678,26482,26622,26557,26418,26622,26482,26418,26482,26354,26418,26354,26331,12474,12498,12615,14998,14974,15003,15531,15650,15584,19903,20412,20397,16904,16703,17028,26331,26354,26215,26331,26215,26233,17966,18004,18166,14049,13894,14113,14497,14269,14646,14172,14281,14586,14742,14823,14919,14230,14281,14172,12649,12686,12813,12453,12474,12615,12649,12813,12796,12654,12686,12554,14865,14757,14965,15584,15650,15799,26233,26215,26145,12453,12780,12654,13995,14115,13732,14757,14700,14738,16303,16201,16263,16303,16263,16332,18435,18179,18279,18379,18179,18435,26119,26233,26145,14049,14113,14195,13576,13384,13494,28904,28390,28315,28749,28885,28811,16857,17140,16884,19495,19641,19546,14700,14517,14646,25945,26119,26145,12449,12343,12522,12522,12394,12589,12428,12641,12345,12641,12611,12345,12611,12359,12345,12343,12385,12522,14269,14238,14406,14036,14238,14100,19546,19641,19569,19495,19546,19470,29152,29022,28974,29152,28974,28990,29250,29170,28989,29140,29204,29108,29108,29200,29059,29139,29226,29128,29128,29211,29093,29250,29038,29078,29250,29078,29393,29010,29263,29224,12657,12401,12611,29010,29147,29263,12587,12490,12401,12385,12394,12522,20812,20677,20732,20732,20397,20552,21026,20850,20844,21026,20844,21179,29170,29204,29140,12401,12490,12441,12394,12344,12653,12710,12694,13203,12564,12694,12505,22581,22573,22534,22355,22404,22274,23892,23226,23732,28948,28885,28749,22840,22975,22894,26029,25945,25907,25672,25945,25671,28020,28054,27831,28220,28054,28020,12344,12416,12653,12631,12674,12694,15733,15584,15799,20349,20527,20460,20309,20254,20349,20155,20254,20309,20091,20254,20155,20044,20192,19931,21148,21357,21310,22107,21983,22093,26128,26018,25898,25950,25455,25403,26128,26406,26129,13217,13159,13273,13094,13159,13217,13094,13471,13167,17595,17369,17685,17083,16904,17028,17805,17634,17709,17844,17634,17805,19931,20192,19813,18315,18460,18442,24108,23892,23732,24071,23892,24108,13732,14115,13570,14001,14230,14172,15839,15799,15972,16293,16303,16332,16332,16486,16356,29274,29200,29108,29263,29147,29295,18179,17966,18166,18819,18686,19167,27574,27226,27157,28088,27768,27787,27574,27157,27246,12441,12490,12384,29266,29147,29109,25945,25672,25907,27986,27958,27822,12384,12647,12498,19931,19813,19879,29200,29226,29139,29093,29232,29031,29176,28220,28182,12554,12617,12654,12273,12384,12498,12649,12877,12929,22573,22404,22534,28981,29018,28695,29086,29152,28990,29233,29266,29109,12686,12649,12349,22709,22803,22724,22664,22803,22709,22495,22709,22424,23497,23093,22975,28885,28981,28695,28765,28948,28749,28980,28948,28765,19737,19715,19641,29226,29211,29128,15839,15972,15778,28750,28182,28493,28054,27986,27822,28369,28164,28311,28377,28603,28181,15096,15095,14998,14998,14887,14974,14974,14865,14965,14757,14592,14700,14700,14592,14517,15147,15095,15096,15147,15259,15185,15259,15337,15185,14887,14865,14974,14036,14195,14238,14919,14823,15058,14742,14919,14866,14742,14761,14193,15185,15337,15306,17531,17369,17595,17531,17595,17634,14036,14049,14195,13167,13511,13384,14497,14646,14517,17024,16904,17083,12245,12384,12273,14193,14761,14281,15306,15531,15584,22215,22185,22274,26808,26915,26710,26808,26710,26622,26808,26622,26863,26327,26418,26331,26327,26331,26233,26327,26233,26181,12524,12554,12686,12617,12453,12654,22634,22495,22042,29062,28981,28885,29018,29086,28949,15274,15306,15351,14823,15348,15058,16867,17005,17140,17521,18038,17888,26181,26233,26119,26915,27005,26975,12694,12674,13203,12694,12710,12451,14001,14172,14021,15490,15391,15584,15778,15972,16201,16082,16201,16303,22803,22840,22894,22664,22840,22803,28111,27986,28054,26816,26172,26899,29211,29232,29093,29233,29109,29079,29233,29079,29181,14506,14592,14757,26091,26181,26119,19749,19322,19538,19257,19322,19749,22404,22215,22274,20892,20850,21026,28682,28603,28377,28948,29062,28885,19521,19737,19641,19470,19641,19495,29181,29079,29152,14592,14497,14517,15348,15483,15910,26018,26043,25950,27917,27554,27958,26029,26091,25945,25945,26091,26119,22675,22573,22581,22404,22270,22215,22725,22573,22675,22495,22652,22709,22634,22652,22495,29232,29180,29031,29202,29086,29018,29144,29018,28981,17139,17024,17154,16356,16486,16703,25907,25672,25888,17984,17966,18179,17369,17206,17248,17844,17966,17984,13511,13494,13384,13159,12896,13114,12524,12617,12554,17622,17531,17634,29186,29181,29152,12428,12240,12343,12343,12240,12385,12385,12282,12394,12394,12252,12344,12344,12312,12416,12416,12022,12447,12231,12240,12428,12231,12428,12345,12231,12345,12292,12345,12359,12292,12359,12330,12292,12240,12282,12385,16356,16703,16273,20850,20677,20812,20892,20677,20850,20892,21026,21007,12359,12401,12330,12330,12401,12156,12282,12252,12394,12451,12710,12419,13851,14021,13995,14049,13798,13894,14100,14238,14269,13980,14001,14021,14671,14765,14742,12718,13203,12674,21007,21032,20942,22652,22664,22709,24175,24287,23707,22634,22664,22652,26002,25907,25888,12276,12401,12441,12252,12312,12344,12524,12453,12617,12245,12276,12441,12524,12686,12352,12312,12319,12416,20254,20276,20349,20091,20276,20254,20091,20155,20044,20091,20044,20030,21007,21148,21032,27986,28069,27958,28111,28069,27986,29200,29328,29226,29226,29316,29211,29211,29282,29232,29232,29409,29180,29204,29274,29108,29354,29274,29204,29368,29204,29170,29433,29170,29250,29323,29078,29224,29323,29224,29263,29323,29263,29295,29147,29313,29295,15028,14887,15095,15095,14887,14998,14865,14715,14757,14427,14376,14497,15028,15095,15147,15028,15147,15185,15028,15185,15274,15721,15733,15839,15274,15185,15306,26923,26816,26899,29285,28750,28493,27978,27958,28069,29274,29328,29200,29147,29266,29313,12445,12718,12674,14887,14715,14865,14264,14100,14269,14823,14795,15348,15348,15004,15483,14742,14765,14823,14193,14281,14230,27521,27233,27483,28982,28904,28315,14103,14193,14230,15778,15721,15839,15351,15306,15434,20030,20044,19931,17966,17844,17805,17984,18179,18094,12419,12710,12263,12564,12631,12694,12410,12631,12564,22573,22620,22404,22215,22270,22107,23087,22901,23094,28980,29062,28948,29086,29186,29152,12245,12441,12384,13669,13790,13576,13576,13790,13879,13397,14117,13497,14001,14103,14230,15434,15306,15584,16136,16356,16273,16293,16082,16303,17388,17206,17369,16136,16275,16356,17388,17369,17531,19438,19470,19336,19737,19879,19813,29407,29186,29086,29313,29266,29233,29328,29316,29226,29313,29233,29507,17498,17388,17531,12273,12498,12474,14265,14269,14497,13608,13576,13879,14671,14783,14765,14056,14103,14001,15310,15434,15391,27656,27574,27246,28131,28009,28076,13094,12982,13159,12896,12982,13094,13798,14049,14036,17844,17622,17634,11906,12273,11537,20397,20412,20552,19521,19879,19737,29316,29282,29211,29180,29285,28493,29303,29233,29181,12391,12524,12352,11983,12185,11906,14506,14497,14592,29062,29144,28981,13732,13851,13995,14671,14742,14193,13980,14056,14001,14376,14265,14497,26129,26043,26018,26102,26043,26129,25907,26002,26029,26029,26135,26091,26091,26387,26181,26181,26650,26327,26863,26622,26418,26915,27235,27005,27005,27235,27246,25888,25672,25252,12829,12896,13094,13384,13251,13167,13153,13251,13097,17206,17139,17154,17287,17139,17206,17104,17139,17181,28164,28369,28037,29265,28980,28904,28088,27787,28009,12451,12505,12694,12445,12563,12718,12410,12505,12332,22665,22620,22573,22665,22573,22725,22042,22291,21624,22664,22634,22840,12789,13397,13497,13632,13980,13851,12739,13347,12718,14265,14264,14269,13963,13798,14036,14887,14958,14715,14715,14506,14757,14376,14427,14265,14112,14028,14264,15028,14958,14887,15274,14958,15028,15228,14958,15274,15228,15274,15351,16356,16275,16293,15347,15351,15434,16273,16904,16868,18094,18179,18379,17844,17831,17622,17287,17206,17388,17831,17984,17881,26863,26418,26650,27978,27917,27958,28111,28054,28220,29062,29199,29144,28904,28980,28765,28982,28315,28603,12263,12710,12139,13851,13980,14021,14671,14408,14581,13899,13980,13591,22431,22270,22404,14765,14783,14823,14193,14103,14135,14135,14103,14056,15347,15228,15351,15347,15434,15310,27340,27117,26899,26923,27165,26816,26406,26128,26356,28082,28310,28193,28009,27787,27719,29186,29303,29181,29388,29303,29186,29202,29018,29144,12231,12189,12240,12240,12189,12282,12282,12167,12252,12252,12182,12312,12312,12137,12319,12319,12022,12416,12292,12189,12231,11971,12189,12292,12156,12292,12330,12156,12401,12276,12156,12276,12081,12189,12167,12282,13899,14135,14056,22767,22665,22725,22498,22431,22404,27917,27521,27483,29393,29433,29250,29274,29486,29328,29328,29416,29316,29316,29499,29282,29393,29078,29323,29393,29323,29443,29323,29295,29443,20677,20529,20732,20653,20529,20677,20856,20677,20892,20856,20892,21007,20276,20527,20349,20191,20527,20276,20191,20276,20091,29433,29368,29170,12167,12182,12252,20529,20397,20732,20942,20856,21007,14347,14188,14260,15644,15733,15721,29199,29202,29144,29368,29354,29204,12185,12276,12245,12185,12245,12273,12182,12137,12312,13963,14100,14006,13963,14036,14100,13097,13251,13384,16275,16082,16293,16136,16082,16275,26043,25455,25950,23892,23087,23166,29443,29295,29523,24018,23087,23892,27917,28172,27521,28111,27978,28069,28076,27719,27568,27739,27568,27574,14506,14427,14497,20030,20191,20091,20030,19931,19954,26406,26356,26816,26043,26244,25455,17139,17104,17024,17498,17531,17622,17984,17831,17844,18094,18379,18456,16082,15778,16201,29486,29416,29328,29282,29409,29232,29523,29295,29635,28088,28311,28164,28369,28682,28377,28431,28311,28088,22498,22404,22620,22882,22767,22725,22498,22620,22698,22270,22238,22107,19470,19438,19641,19336,19470,19307,21850,22042,21624,26259,26102,26129,26002,26135,26029,25888,26135,26002,19954,19931,19879,25455,25067,25062,24902,24999,25252,24576,24999,24902,24287,24248,23707,12310,12474,12453,12982,12896,13159,12986,13094,13167,13153,13167,13251,19830,19954,19879,13097,13040,13002,14006,14100,14264,13980,13899,14056,14651,14783,14671,13632,13851,13732,18038,18315,18442,18015,18315,18038,17521,17888,17140,19438,19521,19641,18976,19336,19307,13397,13570,14115,12524,12391,12453,12352,12686,12349,22380,22238,22270,22698,22620,22665,29407,29388,29186,29303,29388,29233,29370,29199,29062,29265,29062,28980,23087,22882,22725,22767,22698,22665,22980,22882,23087,27219,27235,26915,26979,26863,26650,14651,14795,14783,14783,14795,14823,14651,14671,14581,15766,15644,15721,15766,15721,15778,25976,25888,25987,26135,26387,26091,12419,12229,12451,12445,12674,12631,12139,13052,12447,13608,13879,13798,13664,13608,13798,29499,29409,29282,15228,14768,14958,14331,14347,14260,14506,14347,14427,15347,15235,15228,15310,15235,15347,26621,26406,26816,26259,26355,26102,26102,26252,26043,27219,26915,26808,12349,12649,12328,12047,12276,12185,12445,12631,12410,13397,13311,13570,17831,17498,17622,24673,24071,24108,28756,28682,28369,12410,12564,12505,14028,14006,14264,13689,13664,13798,14331,14265,14427,15925,15766,15778,15391,15434,15584,15925,15778,16082,16703,16904,16273,14506,14188,14347,15584,15733,15490,12263,12229,12419,12197,12229,12263,22380,22270,22431,22380,22431,22417,29409,29392,29180,12739,12809,13497,15490,15733,15644,28682,28837,28603,12026,12276,12047,12268,12349,12328,12332,12505,12149,22922,22698,22767,22922,22767,22882,29407,29086,29202,20856,20653,20677,20529,20551,20397,20397,20184,19903,18819,19167,19322,20942,20653,20856,28111,28082,27978,27978,28091,27917,27504,27340,26899,28091,28082,28193,29433,29469,29368,29368,29547,29354,29354,29486,29274,29416,29540,29316,29409,29550,29392,29621,29469,29433,29621,29433,29393,29474,29393,29443,20653,20551,20529,27656,27739,27574,28009,28131,28088,28311,28431,28369,29469,29503,29368,12182,12058,12137,12067,12139,12447,12167,12058,12182,11938,12058,12167,11971,12167,12189,11971,12292,12156,20551,20456,20397,21007,21179,21148,22417,22431,22498,29503,29547,29368,18819,18934,18857,17246,17344,17320,15455,15490,15644,21357,21148,21179,13153,12986,13167,12268,12352,12349,13056,13097,13002,17498,17287,17388,17181,17287,17196,22292,22107,22238,29523,29474,29443,12097,12319,12137,12332,12423,12410,13043,13201,13397,13914,14048,13899,19468,19521,19438,19468,19438,19336,29392,29405,29180,28082,28111,28310,29550,29405,29392,12563,12739,12718,12809,12789,13497,12723,12739,12605,12739,12563,12623,12026,12081,12276,12453,12391,12310,12058,12097,12137,29597,29486,29354,13201,13311,13397,12310,12391,12233,13608,13545,13576,13813,13798,13963,16904,17024,16868,15766,15657,15644,20191,20123,20527,20974,21624,21160,20030,20123,20191,19954,20123,20030,19830,20123,19954,29486,29458,29416,29635,29295,29614,12233,12391,12352,16023,15925,16082,18628,18976,18711,12139,12158,12263,11972,12158,12139,14795,15009,15348,16867,16857,16742,14671,14193,14408,14193,14135,14048,19521,19830,19879,19270,19468,19336,11983,12047,12185,29458,29540,29416,12689,12789,12809,14048,14135,13899,14637,15009,14795,12097,12022,12319,27583,27656,27246,26979,27219,26808,26979,26808,26863,29540,29499,29316,14006,13813,13963,14112,14264,14265,13632,13732,13489,28076,28009,27719,27583,27246,27235,29453,29407,29202,29388,29507,29233,29545,29407,29453,12013,12026,12047,12268,12233,12352,12649,12929,12328,12739,12723,12809,12519,12563,12445,16136,16023,16082,15925,15657,15766,15898,16023,15984,13664,13545,13608,13481,13545,13664,28082,28091,27978,26385,26355,26458,28115,28091,28193,28076,27568,27739,28979,28982,28837,13097,12986,13153,13056,12986,13097,17287,17181,17139,17196,17287,17498,14347,14331,14427,14768,14715,14958,15171,15228,15235,15171,15235,15310,15171,15310,15183,26406,26355,26259,25189,24955,25067,26621,26816,27165,26164,26387,26135,26164,26135,25888,27504,26899,27521,12022,12103,12447,23497,22975,22840,25976,26164,25888,23497,22840,22634,12423,12519,12445,12423,12445,12410,18819,19322,18934,17344,17196,17498,24071,24018,23892,24673,24046,24071,24018,24046,24190,25888,25252,25987,27833,27504,27521,29479,29507,29388,12519,12623,12563,28837,28982,28603,28979,28837,28682,12203,12451,12229,12197,12263,12055,23340,22980,23087,22417,22292,22380,29231,29265,28904,13489,13732,13570,12055,12263,12158,22380,22292,22238,22417,22498,22698,12103,12067,12447,14028,13813,14006,13689,13813,13824,29569,29550,29409,29405,29285,29180,14331,14112,14265,12789,13043,13397,13280,13570,13311,13280,13489,13570,12723,12689,12809,12605,12689,12723,12328,12929,12301,12013,12047,11983,12149,12505,12451,18819,18794,18686,18857,18794,18819,26650,26181,26387,26650,26418,26327,28076,27739,28004,29545,29479,29388,29545,29388,29407,14651,14637,14795,14458,14637,14651,14458,14651,14581,14408,14193,13921,12986,12829,13094,13097,13384,13040,13481,13576,13545,24287,24576,24248,11783,11971,12156,12058,11926,12097,12097,11986,12022,12022,11995,12103,12103,11995,12067,11922,12156,12081,11922,12081,12026,11922,12026,12013,11971,11938,12167,29503,29664,29547,29547,29597,29354,29486,29623,29458,29458,29623,29540,29540,29623,29499,29499,29569,29409,29469,29566,29503,29725,29566,29469,29621,29393,29474,29621,29474,29577,29474,29601,29577,12197,12203,12229,12014,12203,12197,16868,17024,17104,17146,17196,17142,26159,25976,26217,26540,26650,26387,20456,20384,20397,20551,20408,20456,20653,20408,20551,20497,20408,20653,20951,20653,20942,20951,20942,21032,29474,29523,29601,26336,26387,26164,12623,12605,12739,12454,12605,12623,12454,12623,12519,12454,12519,12347,13849,13914,13899,13096,13311,13201,16023,15898,15925,15183,15310,15391,16072,16023,16136,20408,20384,20456,28091,28115,27917,29230,28182,28750,29664,29597,29547,29601,29523,29635,12652,12829,12986,15183,15391,15363,14331,14260,14112,12273,11906,12185,11898,11926,12058,20384,20184,20397,21145,21148,21310,29295,29313,29614,12474,11537,12273,12301,13114,12896,13591,13980,13632,15815,15657,15925,12310,12233,12161,11926,11986,12097,11924,12055,12158,15363,15391,15490,21164,21145,21310,22801,22417,22698,29597,29623,29486,12689,12659,12789,12643,12659,12689,24046,24018,24071,22980,22922,22882,24955,24108,25067,29584,29559,29405,29584,29405,29550,29453,29202,29538,29614,29313,29507,12161,12233,12268,29614,29507,29571,13489,13591,13632,13630,13591,13528,23752,23497,23648,24287,24410,24576,29294,29126,28750,15455,15363,15490,26355,26385,26102,26621,26355,26406,26923,27117,27165,13011,13481,13664,13689,13798,13813,17116,17104,17181,15898,15815,15925,28115,28156,27917,28310,28111,28674,29571,29507,29479,13921,14193,14048,13630,13849,13899,13056,12900,12986,13040,13384,13576,12651,13043,12789,15554,15897,15483,19244,19270,19109,15397,15483,15367,17196,17146,17181,17498,17831,17881,22843,22922,22980,13027,13096,13201,15396,15644,15657,15396,15455,15644,15367,15483,15004,26385,26252,26102,25976,26210,26164,26159,26210,25976,28410,28431,28088,28410,28088,28131,17142,17246,17031,28830,28756,28369,29496,29370,29265,13118,13280,13311,11782,11995,12022,29849,29569,29499,11972,12139,12067,12203,12149,12451,12482,12689,12605,16273,16072,16136,15984,16072,15880,18976,19270,19336,19468,19376,19521,18628,18711,18315,28204,28076,28004,27583,27235,27219,29538,29202,29199,29820,29571,29811,29370,29062,29265,12829,12740,12896,12602,12740,12829,12659,12707,12789,12643,12707,12659,12519,12423,12283,17264,17521,17140,26166,26159,26217,13824,13813,14028,14041,14028,14112,15984,15815,15898,12225,12423,12332,12028,12161,12268,12109,12161,12028,12093,12149,12203,14906,14768,15228,14906,15228,15171,15012,15171,15183,15224,15183,15363,18934,19322,19123,18794,18456,18379,29661,29571,29820,12082,12225,12332,29426,29285,29405,29426,29405,29559,29089,28979,28682,13969,14048,13914,15004,15348,15009,27165,27117,27340,26385,26299,26252,13863,13969,13914,13863,13914,13849,13630,13899,13591,15397,15554,15483,15501,15554,15397,13002,12900,13056,12848,12900,13002,13040,13576,13481,17146,17116,17181,17142,17116,17146,17142,17196,17344,17005,17054,17140,16928,17054,17005,13002,13040,12848,13043,13027,13201,13096,13118,13311,13663,13630,13528,12899,13027,13043,13591,13313,13528,17116,16868,17104,16742,16857,16676,18857,18772,18794,18799,18772,18857,28076,28169,28131,28204,28169,28076,17054,17264,17140,25987,25252,25514,24175,24410,24287,12871,13118,13096,20974,21160,20527,22042,22072,22634,20664,20527,20123,29705,29584,29550,14188,14506,14715,15455,15224,15363,15396,15224,15455,22417,22368,22292,22427,22368,22417,11971,11833,11938,11938,11874,12058,11926,11825,11986,11986,11825,12022,11722,11833,11971,11722,11971,11783,11904,11922,12013,11904,12013,11766,11833,11873,11938,12225,12283,12423,12082,12283,12225,12454,12482,12605,12824,12899,13043,12347,12482,12454,14373,14581,14408,13747,13863,13849,29735,29469,29621,29735,29725,29469,29566,29664,29503,29597,29723,29623,29623,29665,29499,29569,29705,29550,29735,29621,29692,29621,29577,29692,29577,29601,29692,29601,29832,29692,17521,17546,18038,17264,17404,17521,29601,29635,29657,11873,11874,11938,29773,29664,29566,21018,20951,21032,20352,20261,20384,20384,20261,20184,21018,21032,21148,29664,29723,29597,29657,29635,29798,11806,11972,12067,12014,12093,12203,12149,12114,12332,11900,11972,11806,11874,11898,12058,15004,15009,14844,20352,20384,20408,20184,19945,19903,21145,21018,21148,26458,26299,26385,26252,26244,26043,26210,26336,26164,27138,27318,26979,27318,27583,27219,26166,26336,26210,26166,26210,26159,27852,27583,27919,11766,12013,11983,12482,12643,12689,16072,15984,16023,15572,15396,15657,15880,16072,16273,17378,17546,17521,20261,20189,20184,22922,22801,22698,22843,22801,22922,29231,28904,28982,29661,29614,29571,12014,12197,12055,21983,21357,21179,22540,22427,22417,11898,11825,11926,13630,13747,13849,14373,14408,14311,13711,13747,13663,29723,29665,29623,29823,29657,29798,29479,29811,29571,28674,28111,28220,28193,28194,28115,26454,26619,26561,11972,11924,12158,11900,11924,11972,14260,14041,14112,12848,13040,12664,15572,15657,15667,21850,22038,22042,24936,24999,24576,29584,29562,29559,29666,29562,29584,17776,18015,18038,28979,29231,28982,13027,12871,13096,13663,13747,13630,12651,12789,12707,16867,16928,17005,17054,17184,17264,17378,17521,17404,17580,17678,17546,16909,16928,16867,17116,16961,16868,16868,16565,16273,17881,17984,18094,16676,16083,16592,16676,16857,16428,17546,17776,18038,17678,17776,17546,24825,24936,24576,11608,12474,12310,12466,12651,12707,14373,14458,14581,14048,13969,13921,15419,15501,15397,15292,15397,15367,18015,18628,18315,19257,19749,19903,18772,18456,18794,19270,19376,19468,19244,19376,19270,22038,22072,22042,22801,22540,22417,22986,22843,22980,29285,29294,28750,28674,28261,28310,29518,29426,29671,28261,28194,28193,28169,28348,28131,29119,29089,28756,28756,29089,28682,28979,29089,29231,27970,27739,27656,13711,13969,13863,15012,14906,15171,14768,14188,14715,14260,14080,14041,15012,15183,15124,12740,12602,12896,12652,12602,12829,12652,12986,12900,15124,15183,15224,14707,15009,14637,29479,29545,29811,19346,19257,19903,19109,19270,18976,29436,29294,29285,12327,12347,12519,12482,12443,12643,12643,12443,12707,12363,12347,12327,15069,15124,15224,15667,15657,15815,14104,14188,14768,15069,15224,15396,12161,12109,12310,12028,12268,12328,12093,12114,12149,11843,12114,11714,29370,29538,29199,29496,29538,29370,18799,18456,18772,18799,18857,18934,29771,29705,29569,29518,29436,29426,17580,17546,17378,17776,17839,18015,18015,17979,18628,23497,23932,23707,24558,24825,24576,24030,23932,24024,14041,13824,14028,14188,14080,14260,15004,15192,15367,26299,26314,26252,26621,26458,26355,27165,27954,27601,26336,26430,26387,26276,26430,26336,26276,26336,26166,28194,28156,28115,28310,28261,28193,29230,28750,29126,28204,28348,28169,28425,28348,28204,12899,12871,13027,12651,12824,13043,12781,12824,12568,16928,16996,17054,16742,16909,16867,16875,16909,16735,24936,25064,24999,24558,24576,24410,13747,13711,13863,13489,13313,13591,15682,15667,15815,15069,15012,15124,15880,15815,15984,12762,12652,12900,13011,13664,13689,24825,25064,24936,15192,15292,15367,15475,16428,15554,18833,18799,18934,26458,26314,26299,26217,26276,26166,24018,23340,23087,23725,23340,24018,23932,24175,23707,12347,12363,12482,12411,12363,12287,18260,17881,18094,18260,18094,18456,17774,17839,17776,17774,17776,17678,29366,29230,29126,29426,29436,29285,29294,29366,29126,29426,29559,29671,11642,12014,12055,12327,12519,12043,11900,12055,11924,19257,19123,19322,19070,19123,19257,18628,19109,18976,19227,19109,19224,28314,28156,28194,11873,11768,11874,11613,11758,11898,11898,11758,11825,11825,11713,12022,11833,11768,11873,11722,11768,11833,12156,11803,11783,12156,11922,11803,21119,20497,20951,20951,20497,20653,20261,20352,20189,19166,19070,19257,21145,20951,21018,29725,29773,29566,29664,29901,29723,29723,29747,29665,29904,29771,29569,29772,29773,29725,29772,29725,29735,29772,29735,29822,29735,29692,29822,29822,29692,29832,11803,11922,11904,11803,11904,11731,13117,13280,12908,13622,13921,13969,13622,13969,13711,15292,15419,15397,26314,26244,26252,25987,26217,25976,29832,29601,29757,11731,11904,11766,20497,20352,20408,12411,12443,12482,14458,14521,14637,15004,15046,15192,15192,15218,15292,15292,15349,15419,14442,14521,14365,14313,14458,14373,17316,17404,17264,28348,28410,28131,28434,28410,28348,28830,28369,28431,29504,29496,29265,29705,29666,29584,29771,29666,29705,14521,14707,14637,27885,27340,27504,26458,26454,26314,26314,26454,26244,29757,29601,29657,11766,11983,11906,12301,12028,12328,12301,12896,12602,14707,14844,15009,11766,11906,11684,11613,11898,11533,22295,22292,22368,29901,29747,29723,29635,29614,29798,29823,29757,29657,19123,19037,18934,18799,18514,18456,19070,19037,19123,13935,13824,14041,13921,14311,14408,14906,14541,14768,13884,13935,14080,14080,13935,14041,15012,14979,14906,15069,14979,15012,15462,15396,15572,14844,14973,15004,15487,15462,15572,15487,15572,15667,28172,27833,27521,11758,11805,11825,12824,12781,12899,12727,12824,12651,17142,16961,17116,17031,16961,17142,16909,16996,16928,16875,16996,16909,29798,29614,29661,11806,12067,11995,12781,12871,12899,25189,25067,25448,12539,12727,12651,16996,17184,17054,13663,13486,13711,13313,13117,13254,11982,12310,12109,11805,11713,11825,12363,12411,12482,12480,12539,12651,12082,12332,12114,14973,15046,15004,17839,17979,18015,17681,17774,17678,17681,17678,17580,28156,28172,27917,28261,28314,28194,28387,28314,28261,17184,17316,17264,29820,29798,29661,11843,12082,12114,12114,12093,11748,29436,29366,29294,29659,29559,29562,29504,29265,29231,29811,29545,29825,11981,11982,12109,15046,15142,15192,22536,22540,22635,22427,22398,22368,22986,22801,22843,26526,26540,26430,26430,26540,26387,26526,26430,26276,19244,19383,19376,19376,19383,19521,21850,21981,22038,22038,21981,22072,19227,19383,19244,19227,19244,19109,27852,27970,27656,27852,27656,27583,11713,11782,12022,15142,15218,15192,16676,16909,16742,12091,12301,12602,11990,11981,12109,12134,12327,12105,12411,12426,12443,16115,15880,16273,17748,17979,17839,17748,17839,17774,28337,28172,28156,29545,29453,29825,19224,19109,19112,29830,29659,29562,29830,29562,29666,11990,12109,12028,11684,11628,11766,15880,15682,15815,15390,15069,15396,19037,18833,18934,19055,18833,19037,27970,28004,27739,28336,28004,27970,12211,12426,12411,17705,17681,17580,18704,18514,18799,17031,16800,16961,23340,22986,22980,23082,22986,23158,14104,14080,14188,12664,13040,12585,12762,12848,12664,12652,12511,12602,16961,16800,16868,17142,17344,17246,15554,15501,15443,16996,17127,17184,17127,17378,17316,17316,17378,17404,28763,28830,28431,28691,28431,28410,17246,17320,17261,24955,24673,24108,29849,29499,29665,16735,16676,16592,17106,17246,17143,14707,14759,14844,14844,14829,14973,14973,14970,15046,15046,15033,15142,15142,15144,15218,14521,14608,14707,14442,14608,14521,25448,25067,25455,24955,24938,24673,27318,27219,26979,13313,13489,13117,13528,13505,13663,14313,14373,14311,14365,14521,14458,28314,28337,28156,28190,27885,27833,28387,28337,28314,11684,11906,11537,12018,11990,12028,12464,12511,12652,13473,13505,13528,17127,17316,17184,24473,24190,24046,29526,29366,29436,29021,28674,28220,29526,29436,29518,12327,12287,12363,12134,12287,12327,14759,14829,14844,29565,29526,29644,14829,14970,14973,15443,15501,15419,19994,20184,20189,18833,18704,18799,19830,19521,19383,20474,20664,20123,11722,11710,11768,11533,11898,11874,11758,11613,11805,11805,11648,11713,11713,11654,11782,11783,11710,11722,11669,11710,11783,11669,11783,11803,11669,11803,11628,11803,11731,11628,29773,29901,29664,29747,29849,29665,29772,29913,29773,30004,29913,29772,29882,29772,29822,29882,29822,29855,29822,29832,29855,29832,29757,29855,29757,30097,29855,11628,11731,11766,29757,29823,29872,14541,14104,14768,15390,15396,15462,14800,14541,14906,20664,20974,20527,29913,29901,29773,29872,29823,29798,11782,11806,11995,11642,11748,12014,12171,12211,12287,11656,11806,11782,29771,29759,29666,29659,29671,29559,30002,29759,29771,29658,29453,29538,29948,29872,29798,12310,11982,11804,11845,12018,12028,11883,12018,11845,18514,18445,18456,18812,18704,18833,12848,12762,12900,12664,12514,12633,12781,12778,12871,12871,12751,13118,12724,12778,12781,12568,12824,12727,12707,12443,12466,16875,17127,16996,16676,16735,16909,15349,15292,15218,25063,24938,24955,24673,24473,24046,11982,11981,11883,11528,11874,11768,12466,12443,12400,15033,15144,15142,16709,17127,16875,19070,19055,19037,19140,19055,19070,22540,22398,22427,22536,22398,22540,24672,24473,24673,27138,26979,26650,26468,26526,26276,26468,26276,26217,29903,29671,29659,29838,29658,29538,29838,29538,29496,29176,28182,29230,11613,11648,11805,21145,21119,20951,20027,19994,20111,20352,19994,20189,21983,22107,21357,12287,12211,12411,12519,12283,12043,19112,19109,19005,17681,17748,17774,17705,17748,17681,17705,17580,17378,21854,21981,21850,22072,22269,22634,24614,24558,24175,29759,29830,29666,29843,29830,29926,12400,12443,12426,11883,11981,11990,11648,11654,11713,19994,20352,20111,21357,22107,22011,26454,26458,26619,25962,25674,25455,25189,25063,24955,26513,26468,26217,29948,29798,29820,18704,18552,18514,18637,18552,18704,19994,19945,20184,22011,22107,22292,22635,22540,22801,22398,22295,22368,22635,22801,22909,22801,22986,22909,29946,29849,29747,13313,13355,13528,13505,13486,13663,13254,13355,13313,26070,25455,26244,28337,28327,28172,27833,27885,27504,26455,26244,26454,28387,28327,28337,12260,12400,12426,19945,19346,19903,19055,18812,18833,13473,13486,13505,15268,15349,15218,11654,11656,11782,25674,25448,25455,29849,29904,29569,12043,12283,12002,12211,12260,12426,12002,12283,12082,14608,14759,14707,14829,14759,14970,14970,15033,15046,15144,15268,15218,14365,14458,14313,14800,14906,14979,29461,29504,29231,29461,29231,29613,14313,14311,14160,26654,26540,26526,26654,26650,26540,13117,13489,13280,12568,12724,12781,12568,12727,12539,12568,12539,12480,14160,14311,13765,14661,14759,14608,19346,19309,19257,19140,19309,19395,19427,19830,19383,19224,19383,19227,29658,29825,29453,29952,29948,29820,30006,29825,29658,12480,12651,12466,17031,17106,16800,16800,16653,16868,17246,17106,17031,17344,17498,17320,17757,17705,17695,18061,18628,17979,24473,24470,24190,24677,24672,24673,24677,24673,24938,24175,24558,24410,24825,24930,25064,25987,26513,26217,24780,24558,24802,18941,18812,19055,22310,22295,22398,23725,24018,24001,25186,25063,25189,15487,15390,15462,15069,14800,14979,15487,15667,15682,15487,15682,15538,15349,15443,15419,15272,15443,15349,28190,27833,28172,14927,14800,15069,12762,12464,12652,12511,12091,12602,12429,12466,12400,12429,12480,12466,17320,17498,17881,13355,13473,13528,13280,13118,12908,13486,13622,13711,13200,13473,13355,25256,25186,25189,28327,28316,28172,28674,28387,28261,28004,28425,28204,29613,29231,29089,28477,28425,28514,28434,28425,28477,19309,19166,19257,19140,19166,19309,17846,17979,17748,22310,22398,22536,29542,29176,29230,28500,28372,28530,29557,29230,29366,29557,29366,29615,20974,21796,21850,24030,24175,23932,13435,13622,13486,14629,15033,14970,15538,15682,15880,15390,14927,15069,15443,15475,15554,15442,15475,15443,25464,25313,25448,25448,25313,25189,26513,26654,26526,26513,26526,26468,28434,28556,28410,29667,29714,29496,29119,28756,28830,12018,11883,11990,11845,12028,12301,11748,12093,12014,12055,11900,11642,12134,12171,12287,11942,12171,12134,12105,12327,12043,17705,17846,17748,24001,24018,24190,18552,18445,18514,18478,18445,18552,18280,18445,18408,23158,22986,23340,22563,22310,22536,13430,13510,13824,12762,12415,12464,14104,13884,14080,13973,13884,14104,21796,21854,21850,11657,11804,11982,19005,19109,18628,19224,19427,19383,22563,22536,22635,21173,21310,21299,28372,28316,28327,28372,28327,28387,12193,12260,12211,13254,13200,13355,13473,13435,13486,12751,12871,12778,25674,25464,25448,25626,25464,25674,28425,28434,28348,28477,28514,28545,11710,11592,11768,11613,11585,11648,11648,11556,11654,11654,11556,11656,11425,11592,11710,11425,11710,11669,11425,11669,11472,11517,11628,11684,29913,29974,29901,29901,29935,29747,29849,30009,29904,29930,30004,29772,29930,29772,29882,29930,29882,30098,29930,30098,30103,29882,29855,30097,11592,11528,11768,13510,13689,13824,12724,12775,12778,12588,12775,12724,12751,12775,12588,12724,12478,12588,13779,13824,13935,24672,24470,24473,24945,24677,24938,24945,24938,25063,24945,25063,25077,25063,25181,25077,24558,24780,24825,23932,23752,24024,25256,25189,25313,26236,26070,26244,29176,29021,28220,11528,11533,11874,30004,29974,29913,13884,13779,13935,15033,15268,15144,16735,16692,16875,17695,17705,17601,17705,17757,17846,16083,16676,16428,16665,16653,16800,17261,17143,17246,17132,17143,17261,21854,21924,21981,24579,24470,24672,28691,28763,28431,28691,28410,28556,28978,29119,28830,12171,12193,12211,11933,12105,12043,11642,11900,11806,11903,12002,12082,11547,11806,11490,19112,19125,19224,19010,19005,18955,11533,11585,11613,21164,21119,21145,19994,20027,19945,21173,21119,21164,21173,21164,21310,21310,21357,21299,29974,29935,29901,29926,29830,29759,11903,12082,11843,12464,12435,12511,12415,12435,12464,17291,17320,17508,18445,18280,18456,18637,18704,18812,22946,22909,22986,23384,23158,23340,23082,23158,23019,24470,24238,24190,25321,25256,25313,28826,28691,28556,11498,11517,11684,13126,13200,13254,13126,13254,13117,22011,22292,22132,22132,22292,22295,22132,22295,22213,25810,25626,25674,25482,25321,25313,26654,27138,26650,28425,28004,28514,28316,28372,28500,28316,28190,28172,29935,29946,29747,29830,29843,29659,13242,13435,13473,14268,14365,14313,14467,14661,14608,14759,14629,14970,15272,15349,15268,14467,14608,14442,14351,14442,14365,14351,14365,14268,26070,25962,25455,11585,11556,11648,19945,19395,19346,20111,20352,20262,21277,21299,21399,29946,30009,29849,11883,11755,11982,11800,11845,12301,11750,11903,11843,18915,18637,18812,18941,19055,19031,22946,22986,23082,22076,22072,21981,19140,19070,19166,22364,22295,22310,22011,21967,21357,21924,22076,21981,30002,29771,30087,29565,29366,29526,15272,15442,15443,16300,16322,16592,15387,15442,15369,26455,26236,26244,26070,25999,25962,26458,26835,26619,29526,29518,29644,29176,29663,29021,11556,11563,11656,12664,12542,12762,12633,12542,12664,14863,14927,14746,14800,14622,14541,13942,13973,14104,13884,13862,13779,18280,18260,18456,18196,18260,18280,24344,24225,24238,24677,24579,24672,24945,24858,24677,24839,24858,24974,28925,28978,28830,29667,29504,29461,28925,28830,28763,29805,29518,29671,29952,29820,29811,29952,29811,30174,12775,12751,12778,12429,12568,12480,16665,16800,16724,14863,14800,14927,16565,16653,16665,16592,16692,16735,16709,16692,16592,28884,28925,28763,25626,25603,25464,25077,24858,24945,25962,25810,25674,25871,25810,25962,12163,12429,12400,12062,12193,12171,11942,12134,12105,11933,12043,11855,25634,25603,25626,11804,11608,12310,11329,11608,11804,11599,11642,11806,11748,11714,12114,28884,28801,28912,28691,28801,28763,11688,11714,11748,11903,11894,12002,12151,12400,12260,13942,14104,14541,13779,13430,13824,22909,22563,22635,29863,29805,29671,18637,18478,18552,18310,18478,18637,22909,22601,22563,23019,22946,23082,23596,23340,23725,29805,29644,29518,29667,29496,29504,29667,29940,29848,26236,26075,26070,13973,13862,13884,12514,12664,12585,24238,24225,24190,24554,24238,24470,26458,26621,26835,26236,26384,26075,26654,26905,27138,25252,24999,25514,22076,22269,22072,29843,29903,29659,29960,29903,29843,29565,29615,29366,29557,29542,29230,29643,29615,29565,23848,23632,23725,29610,29542,29557,30174,29811,29825,11845,11755,11883,11666,11755,11689,26075,25999,26070,25810,25823,25626,26137,25999,26075,25514,24999,25064,28292,28190,28316,27000,26621,27165,28292,28316,28359,17291,17132,17320,18478,18408,18445,18310,18408,18478,26561,26455,26454,29714,29838,29496,29247,29089,29119,24225,24001,24190,24802,24930,24780,24780,24930,24825,24011,24024,23752,12381,12415,12762,12106,12091,12511,12533,12633,12514,12494,12724,12568,12967,13126,13117,24614,24175,24354,11608,11537,12474,11329,11537,11608,12478,12494,12361,12429,12494,12568,15212,15272,14889,14268,14313,14160,14351,14467,14442,18941,18915,18812,19395,19309,19346,19005,19125,19112,19010,19125,19005,22563,22364,22310,22029,21967,22011,22213,22364,22354,28978,29116,29119,29115,29116,28978,29115,28978,28925,30087,29771,29904,14311,13921,13765,16653,16565,16868,17132,17106,17143,17132,17261,17320,12533,12762,12542,17841,17881,18260,29116,29247,29119,30004,30103,29974,30137,30050,29935,29935,30050,29946,29946,30050,30009,30162,30087,29904,29930,30103,30004,30098,29882,30205,29757,29872,30097,30097,29872,30054,26455,26312,26236,11472,11669,11628,11592,11449,11528,11528,11449,11533,11533,11445,11585,11585,11495,11556,11556,11484,11563,11472,11628,11517,11387,11449,11592,11490,11806,11656,11714,11750,11843,11643,11750,11714,13551,13921,13622,14863,14758,14800,13973,13693,13862,14927,15256,14746,19830,20474,20123,20664,20474,20974,21764,21854,21796,21764,22009,21854,21854,22009,21924,21924,22009,22076,22076,22130,22269,20239,20474,19830,25154,25227,25064,11490,11656,11563,11642,11688,11748,13200,13242,13473,13435,13551,13622,12908,13118,12751,22029,22011,22132,28434,28568,28556,28801,28884,28763,28004,28336,28514,30002,29926,29759,30096,29926,30150,11449,11445,11533,11855,12043,12002,12193,12151,12260,27000,27165,27076,28359,28316,28500,11498,11472,11517,30054,29872,29948,11432,11688,11642,14758,14863,14746,19140,19031,19055,18915,19031,19004,19131,19427,19224,18955,19005,18628,11650,11894,11903,12477,12908,12751,13330,13551,13435,15442,15387,15475,15272,15268,14889,19131,19224,19125,21764,21796,21452,24011,24033,24024,11307,11498,11684,11310,11495,11585,20262,20352,20497,20027,19934,19945,20262,20497,20506,21184,21119,21173,21184,21173,21299,21277,21184,21299,26640,26704,26654,28545,28568,28477,26640,26654,26513,30134,29935,29974,12042,12151,12193,24225,24062,24001,23821,23596,23632,23632,23596,23725,22601,22364,22563,24154,24062,24225,24839,24677,24858,24024,24033,24030,23932,23497,23752,21399,21299,21357,11755,11657,11982,11307,11346,11498,11666,11657,11755,19010,19131,19125,18762,18955,18628,19010,18955,19018,26561,26514,26455,26455,26541,26312,27165,27356,27076,26617,26640,26513,12633,12533,12542,12415,12265,12435,13011,13689,13510,12588,12557,12751,12494,12478,12724,12492,12478,12361,25063,25186,25181,25186,25256,25181,24614,24802,24558,24930,25154,25064,11547,11599,11806,11479,11599,11547,12492,12557,12588,13242,13330,13435,12908,12967,13117,13076,12967,12902,16565,16115,16273,16724,16800,17106,16692,16709,16875,16714,16709,16525,20111,19934,20027,21577,21399,21357,22009,22130,22076,22227,22130,22084,25181,25256,25258,28477,28568,28434,27852,28162,27970,30139,30054,29948,30139,29948,29952,11933,11942,12105,11861,11942,11933,23848,23725,24001,24761,24579,24677,11894,11855,12002,11785,11855,11894,11650,11903,11750,11643,11714,11688,13299,13430,13779,13320,13430,13299,18408,18196,18280,16860,16724,17106,18310,18196,18408,25999,25871,25962,26384,26137,26075,26384,26236,26312,29615,29610,29557,29644,29643,29565,29826,29643,29644,29929,29644,29805,29863,29671,29992,25313,25464,25558,25227,25514,25064,25987,26617,26513,25207,25154,24930,28826,28801,28691,29116,29188,29247,11318,11484,11556,12007,12062,12171,12210,12494,12429,24013,23848,24001,23821,23848,24013,26619,26514,26561,12215,12265,12415,17508,17320,17881,22364,22213,22295,21967,21776,21357,22601,22909,22580,25558,25464,25603,28767,28826,28556,30096,29960,29843,30096,29843,29926,11657,11329,11804,11672,11755,11845,11405,11643,11688,11658,11800,11633,23019,22909,22946,30007,29671,29903,14467,14324,14661,14351,14400,14467,14268,14400,14351,14213,14400,14268,14213,14268,14160,15387,15423,15475,15268,15033,14889,30162,29904,30009,16031,16115,16565,25390,25514,25227,14758,14622,14800,14746,14622,14758,14530,14622,14589,18044,17841,18260,23596,23384,23340,23506,23384,23596,28507,27885,28190,26655,26541,26514,29542,29673,29176,28372,28387,28530,29799,29610,29615,29799,29615,29643,11672,11689,11755,11666,11511,11657,29851,29838,29714,29851,29714,29667,21881,21776,21967,21452,21796,20974,12557,12477,12751,12478,12492,12588,12210,12429,12163,16665,16549,16565,17071,17106,17132,16681,16724,16700,25077,24974,24858,24839,24761,24677,24579,24554,24470,25034,24974,25077,25034,25077,25181,29105,29115,28925,29620,29613,29089,28983,28925,28884,12106,12511,12435,11800,11672,11845,12062,12042,12193,11932,12042,12062,12007,12171,11942,15272,15369,15442,15322,15369,15212,23220,23019,23158,24354,24175,24030,23497,23263,23648,12533,12381,12762,12265,12164,12435,12437,12381,12533,24974,24761,24839,23554,23506,23596,29115,29188,29116,16681,16549,16665,29013,28983,28884,13908,13942,14541,27000,26835,26621,25973,25999,26137,12308,12215,12415,12163,12400,12151,24765,24554,24579,25973,25871,25999,25321,25258,25256,25823,25871,26053,28292,28359,28190,28387,28674,28530,19018,19131,19010,20022,20239,19830,18061,17979,17846,22601,22354,22364,22152,22029,22132,22580,22354,22601,25794,25634,25626,28568,28650,28556,28826,28912,28801,27583,27318,27919,29960,30007,29903,30032,29826,29644,30040,30007,29960,11401,11490,11563,11599,11432,11642,25482,25258,25321,25154,25283,25227,25207,25283,25154,25390,25283,25234,28873,28912,28826,11273,11307,11299,11658,11672,11800,12208,12164,12265,12032,12163,12151,15369,15423,15387,15322,15423,15369,23274,23220,23158,23821,23632,23848,30098,30205,30103,30103,30198,29974,30050,30212,30009,30097,30205,29882,30406,30205,30097,30434,30097,30054,11445,11310,11585,11495,11318,11556,11484,11401,11563,11449,11387,11445,11219,11387,11592,11219,11592,11180,11346,11425,11472,30309,30198,30103,11891,12007,11942,12042,12032,12151,11861,11933,11751,17705,17378,17601,24013,24001,24062,23497,22634,23263,24011,24048,24033,22227,22269,22130,18196,18044,18260,18915,18310,18637,18915,18941,19031,23111,22580,22909,23274,23158,23384,29929,29805,29863,19597,19830,19427,18862,19018,18955,30007,29992,29671,30024,29992,30007,29838,30006,29658,11498,11346,11472,11307,11684,11537,11387,11310,11445,13551,13765,13921,13300,13765,13551,20506,20497,21119,20111,19961,19934,19124,19031,19140,21182,21119,21184,21182,21184,21277,21182,21277,21326,26905,27268,27138,26640,26860,26704,27073,27120,27065,30198,30134,29974,30150,29926,30002,20262,20223,20111,25871,25823,25810,25634,25558,25603,25973,26137,26261,27356,27601,27538,28512,28500,28530,27268,27318,27138,28545,28650,28568,30134,30137,29935,11633,11800,12301,12164,12106,12435,17542,17508,17881,17542,17881,17841,23990,24048,24011,11490,11479,11547,11643,11650,11750,11321,11479,11490,22152,22132,22213,21326,21277,21399,22152,22213,22362,30150,30002,30087,11511,11666,11689,21326,21399,21513,25794,25558,25634,28688,28650,28545,30137,30181,30050,13430,13320,13510,13623,13779,13862,13076,13200,13126,13076,13126,12967,11405,11650,11643,12902,12967,12908,12210,12361,12494,12372,12361,12269,12585,13040,13481,12381,12308,12415,12215,12208,12265,12164,12066,12106,16724,16681,16665,16549,16031,16565,17071,17132,17291,16709,16714,17127,16525,16709,16592,29115,29184,29188,29188,29319,29247,28983,29105,28925,29013,29105,28983,29013,28884,28912,21513,21399,21577,30181,30212,30050,12266,12308,12381,12742,12585,13481,17292,17071,17291,19395,19945,19934,24354,24030,24033,28873,29013,28912,29381,29319,29361,29838,30053,30006,29992,29932,29863,30095,29932,29992,11932,12032,12042,12163,12060,12210,11751,11933,11855,23426,23274,23384,23821,23554,23596,23721,23554,23821,26905,26654,26704,19237,19395,19387,21577,21357,21776,22362,22213,22354,11287,11318,11495,11650,11785,11894,23111,22909,23019,23258,23274,23426,14622,14530,14541,15256,15390,15487,18489,18762,18628,17601,17378,17354,27000,27059,26835,25938,25794,25823,28450,28190,28359,29620,29089,29247,24554,24344,24238,24505,24344,24554,24765,24579,24761,25034,24761,24974,25034,25181,25258,24048,24354,24033,28921,28873,28826,13320,13011,13510,12372,12557,12492,16115,15813,15880,16030,15813,16115,25823,25794,25626,25558,25482,25313,26791,26619,26835,21577,21776,21656,21204,21452,20974,22084,22130,22009,21204,20974,20474,27076,27059,27000,30212,30162,30009,13330,13300,13551,13076,13242,13200,15813,15538,15880,26384,26312,26388,11910,12301,12091,11672,11511,11689,29848,29851,29667,21859,22009,21764,23111,23019,23220,29932,29978,29863,30095,29978,29932,30040,29960,30096,30143,30040,30249,15256,14927,15390,27059,26991,26835,26860,26905,26704,11318,11401,11484,12049,12066,12164,12106,11917,12091,11932,12062,12007,21656,21776,21881,24344,24154,24225,25771,25482,25558,28816,28767,28650,28650,28767,28556,30126,30139,29952,30126,29952,30174,15212,15369,15272,16322,16525,16592,26541,26455,26514,26768,26860,26640,26768,26640,26617,26617,27073,26768,11861,11891,11942,11597,11891,11861,21881,22029,21899,21881,21967,22029,23752,23990,24011,24048,24206,24354,23263,22634,22269,30174,29825,30182,11785,11751,11855,11597,11751,11785,29826,29799,29643,28906,28795,28684,29990,29799,29826,12514,12437,12533,12308,12208,12215,12333,12437,12514,12333,12514,12585,12361,12372,12492,12269,12361,12210,29105,29184,29115,29593,29620,29247,29480,29184,29105,29361,29184,29480,29239,29013,28873,16681,16528,16549,16700,16528,16681,17354,17378,17127,16592,16083,16300,28500,28512,28359,28530,28684,28622,12437,12266,12381,11505,11511,11672,11980,11917,12106,11658,11557,11672,11980,12106,12066,11821,11932,12007,12032,12045,12163,13942,13693,13973,13320,13246,13011,13649,13693,13942,17508,17292,17291,16860,16700,16724,17798,17542,17841,18044,18196,18146,16664,17127,16714,18061,17846,17757,17759,17757,17695,19183,19427,19131,24049,24013,24062,23258,23220,23274,23866,23990,23752,25850,25987,25514,27832,27919,27318,28864,28921,28767,29940,29667,29461,29381,29247,29319,11655,11633,12301,23258,23111,23220,23384,23506,23426,29851,29944,29838,29988,29848,29940,16428,15475,16083,12142,12208,12308,25973,26053,25871,25794,25771,25558,26384,26261,26137,26382,26261,26384,11355,11432,11599,11165,11597,11785,11355,11599,11479,13693,13623,13862,18146,18196,18310,19395,19124,19140,19237,19124,19395,30040,30024,30007,29978,29929,29863,30143,30024,30040,11401,11321,11490,21781,21881,21899,22408,22354,22580,21719,21859,21764,25283,25390,25227,25207,24930,24989,24930,24802,24892,24802,24614,24892,28767,28921,28826,28688,28545,28514,30312,30150,30087,11974,12045,12032,18146,18310,18051,30091,29929,29978,17547,17759,17695,18061,17759,17918,25635,25850,25514,28906,28684,28530,27356,27165,27601,11180,11592,11425,11387,11288,11310,11310,11258,11495,11318,11131,11401,11401,11111,11321,11253,11425,11346,11253,11346,11273,30205,30309,30103,30198,30281,30134,30134,30281,30137,30137,30219,30181,30181,30233,30212,30212,30320,30162,30162,30251,30087,30390,30309,30406,30311,30054,30139,11273,11346,11307,13215,13246,13320,13011,12742,13481,21859,21934,22009,23712,23746,23648,26727,26514,26619,28450,28359,28512,27076,27129,27059,26937,26791,26991,26991,26791,26835,27268,27463,27318,27471,27403,27268,27070,27268,26905,27018,26905,26860,27919,28150,27852,28162,28150,28659,30182,29825,30006,30126,30311,30139,27403,27463,27268,11432,11411,11688,11380,11411,11432,19124,19004,19031,19113,19004,19124,22446,22408,22580,11299,11307,11537,11175,11288,11387,11917,11910,12091,11936,11980,12066,18907,19131,19018,21719,22056,21859,21859,22056,21934,24013,23905,23821,24154,24049,24062,24036,24049,24154,24505,24154,24344,30368,30281,30198,14530,14266,14541,13649,13547,13623,14639,14589,14622,14639,14622,14746,16345,16031,16549,16860,17106,17071,16525,16664,16714,16435,16664,16525,25652,25034,25258,24718,24796,24617,11288,11258,11310,12468,12902,12908,12179,12269,12210,17004,16860,17071,17292,17508,17317,30281,30219,30137,16246,16424,16322,16322,16424,16525,24892,24614,24910,25390,25635,25514,14545,14639,14746,10828,11299,11537,12208,12049,12164,12266,12142,12308,12333,12142,12266,12333,12266,12437,15538,15256,15487,15122,15256,15538,15730,15538,15813,16083,15475,15976,14889,15033,14629,14759,14661,14629,26541,26388,26312,26224,26053,25973,26613,26388,26541,28150,28162,27852,28580,28786,29012,29361,29319,29188,29361,29188,29184,30219,30233,30181,29988,29944,29851,29988,29851,29848,29669,29613,29620,15278,15423,15322,11258,11287,11495,11399,11405,11411,11411,11405,11688,11355,11479,11123,13028,13110,13242,13110,13300,13330,12477,12557,12275,18044,17925,17841,18051,17925,18044,21513,21253,21326,21326,21253,21182,20312,20173,20262,20262,20173,20223,19387,19395,19629,21482,21253,21513,21482,21513,21577,21482,21577,21663,21577,21656,21663,26224,25973,26261,28622,28450,28512,28849,28688,28514,29480,29105,29013,30024,30095,29992,30224,30095,30024,30040,30096,30249,12142,12049,12208,12045,12060,12163,11859,12060,12045,11974,12032,11932,11821,12007,11891,11821,11567,11724,17317,17508,17523,11850,11910,11917,11850,11917,11980,11908,11821,11724,23426,23506,23554,22437,22446,22580,24036,23905,24013,24036,24013,24049,21934,22084,22009,22056,22084,21934,30233,30320,30212,26937,26991,27129,26768,26873,26860,27065,26873,26768,12783,12742,13011,13623,13299,13779,13246,13064,13011,13547,13299,13623,13110,13330,13242,14324,14467,14400,15212,15278,15322,16345,16549,16528,15976,15475,15423,28162,28336,27970,28580,28336,28786,21781,21656,21881,30320,30293,30162,11633,11557,11658,11511,11329,11657,11576,11557,11633,11908,11974,11932,23990,24206,24048,24109,24206,23990,24273,24206,24139,18762,18862,18955,18750,18862,18762,11123,11479,11321,19961,20111,20223,18051,18310,18957,30466,30182,30006,30258,30311,30126,14629,14661,14324,15212,15210,15278,26791,26727,26619,26388,26382,26384,27538,27350,27356,28530,28622,28512,29673,29542,29610,30293,30251,30162,30258,30126,30174,12269,12222,12372,12179,12222,12269,12078,12210,12060,24641,24614,24354,25456,25635,25390,25234,25283,25207,27065,26895,26873,28688,28816,28650,28864,28816,28849,11910,11767,12301,11744,11767,11910,23905,23721,23821,23840,23721,23905,29799,29781,29610,29990,29781,29799,30032,29644,29929,13299,13215,13320,13098,13215,13299,18957,18915,19004,17523,17508,17542,16860,16706,16700,16087,16030,16031,17051,17004,17071,17051,17071,17292,25034,24765,24761,24718,24765,25089,30251,30312,30087,12275,12557,12372,13649,13623,13693,25195,25234,25207,26727,26655,26514,11821,11908,11932,12009,12078,12060,11821,11891,11567,19237,19169,19124,19221,19169,19237,29781,29673,29610,29593,29669,29620,30277,30096,30150,30095,30091,29978,12101,12078,12009,24765,24505,24554,11323,11329,11511,11560,11576,11633,29940,29461,29844,29944,30053,29838,14370,14266,14530,14370,14530,14589,14370,14589,14465,27356,27258,27076,26791,26937,26727,26775,26613,26655,28507,28190,28450,14465,14589,14639,21899,22029,22229,22029,22152,22229,27350,27258,27356,30416,30258,30174,16030,15730,15813,14545,14465,14639,16030,16115,16031,12049,11936,12066,11950,11936,12049,11950,12049,12142,13215,13087,13246,13098,13087,13215,13028,13242,12920,14213,14160,13400,12784,13076,12902,17523,17542,17798,24206,24273,24354,23746,23752,23648,11355,11380,11432,10867,11165,11650,11186,11380,11355,22446,22354,22408,16345,16528,16700,16083,16211,16300,16246,16435,16424,16424,16435,16525,15611,15976,15423,17759,18061,17757,17918,17759,17878,17354,17127,16664,23721,23426,23554,23305,22580,23111,23840,23426,23721,11767,11655,12301,11647,11744,11636,23263,22269,23015,26895,27018,26860,27803,27832,27463,27463,27832,27318,26895,26860,26873,27803,27463,27749,30322,30091,30095,11253,11180,11425,11219,11175,11387,11288,11125,11258,11258,11197,11287,11287,11131,11318,11126,11180,11253,11126,11253,11163,11253,11273,11163,11180,11127,11219,30045,30053,29944,30416,30357,30258,29844,29461,29613,11163,11273,11056,11127,11171,11219,30309,30368,30198,30281,30432,30219,30219,30388,30233,30233,30388,30320,30320,30407,30293,30293,30407,30251,30251,30413,30312,30406,30309,30205,30406,30097,30434,30434,30054,30360,30394,30277,30150,30143,30224,30024,30394,30150,30312,11171,11175,11219,11936,11850,11980,12357,12333,12585,11936,11877,11850,12543,12585,12742,17838,17841,17925,24388,24036,24154,23866,24109,23990,24892,24989,24930,25234,25310,25390,24910,24989,24892,24400,24354,24273,27129,26991,27059,26126,25987,25850,30390,30368,30309,11505,11672,11557,11380,11399,11411,11186,11399,11380,12101,12179,12210,12275,12481,12477,12101,12210,12078,23296,23111,23258,29381,29593,29247,29480,29013,29726,11066,11163,11056,16246,16322,16300,24989,25195,25207,11175,11125,11288,13087,13064,13246,13031,13064,13087,30368,30432,30281,12117,12101,11994,12925,12783,13011,16810,17051,17115,17115,17051,17292,16467,16345,16700,29484,29505,29381,30114,29988,29940,13042,13098,12938,13908,13649,13942,20506,21119,21182,20506,20946,20644,21381,21253,21482,21381,21482,21474,30360,30054,30311,23015,22269,22227,21603,21764,21452,11370,11505,11557,11308,11505,11370,30045,29944,29988,11125,11197,11258,20693,21204,20474,26396,26382,26388,25938,25771,25794,26613,26541,26655,30432,30388,30219,11647,11655,11767,11647,11767,11744,18750,18907,18862,17878,17759,17680,11482,11950,11450,11443,11560,11655,24236,24400,24273,18862,18907,19018,21467,21603,21204,18750,18762,18489,12559,12543,12742,23746,23866,23752,24109,24139,24206,23928,23866,23746,23426,23296,23258,23330,23296,23426,22060,22227,22084,19629,19395,19934,18051,18044,18146,22056,22060,22084,21952,22060,22056,30277,30249,30096,30403,30249,30497,20173,19961,20223,21663,21656,21781,21663,21781,21899,30357,30360,30311,30357,30311,30258,24092,24139,24109,12771,12761,12783,12783,12761,12742,13219,13299,13547,26382,26224,26261,26295,26224,26382,28606,28507,28450,28606,28450,28622,11197,11131,11287,12925,13011,13064,26775,26655,26727,28816,28864,28767,28849,28816,28688,28849,28514,28580,30416,30174,30539,30114,30045,29988,30114,29940,30047,30492,30407,30320,27601,27954,27765,27350,27450,27258,27297,27129,27076,26877,26775,26727,16435,16577,16664,16517,16577,16457,24845,24910,24614,24989,25135,25195,24845,24614,24641,25099,25135,24989,25195,25243,25234,27105,27018,26895,27165,27340,27954,12101,12117,12179,12147,12372,12222,12477,12481,12908,12009,12060,11859,11724,11974,11908,14545,14746,14543,14370,14008,14266,13305,13515,13297,16706,16860,16810,15670,15577,15730,21204,21603,21452,24765,24718,24505,24505,24388,24154,24036,23840,23905,25652,25258,25482,25167,25243,25195,29505,29593,29381,29361,29484,29381,29480,29484,29361,30407,30413,30251,30416,30539,30456,17933,17838,17925,17115,17292,17149,16810,16860,17004,19113,19124,19169,18489,18628,18061,17547,17695,17601,23263,23712,23648,23866,23977,24109,11655,11560,11633,11744,11910,11636,15577,15538,15730,14543,14746,14682,27297,27076,27258,27018,27070,26905,27105,27070,27018,25825,25850,25635,28659,28150,28501,27471,27463,27403,11597,11861,11751,17457,17547,17354,26613,26491,26388,26775,26491,26613,11859,12045,11974,12147,12222,12179,16056,16211,16083,16056,16083,15976,15911,15976,15824,29484,29593,29505,21937,21663,21899,30413,30369,30312,12468,12784,12902,13110,13156,13300,19387,19221,19237,19288,19221,19387,25897,25825,25635,29239,28873,28921,28580,28514,28336,13098,13031,13087,13042,13031,13098,12920,13242,13076,27954,27340,27885,28684,28606,28622,11505,11323,11511,11066,11126,11163,11308,11323,11505,15113,15210,15212,13239,13765,13300,17957,18061,17918,19183,19597,19427,30091,30032,29929,29766,29663,29673,30327,30032,30091,30224,30143,30387,29844,29613,29669,30466,30006,30053,21603,21719,21764,24092,23977,24035,30369,30394,30312,30191,30053,30045,11950,11877,11936,11769,11877,11950,11759,11877,11769,12357,12585,12543,11724,11859,11974,12761,12559,12742,12590,12559,12761,29673,29663,29176,29766,29673,29781,14959,15212,14889,25938,25823,26053,26491,26396,26388,26564,26396,26679,19221,19113,19169,19201,19113,19221,22446,22362,22354,22437,22362,22446,11636,11910,11850,11370,11557,11576,17838,17798,17841,17871,17798,17838,18957,18310,18915,23763,23840,24106,22645,22437,22580,29923,29844,29669,30032,29990,29826,13649,13515,13547,13908,14541,14266,12071,12147,12179,12071,12179,12117,11994,12101,12009,13031,12925,13064,12815,12925,13031,13036,13156,13110,12784,12920,13076,12863,12920,12784,12863,12784,12745,15825,15730,16030,16810,17004,17051,16345,16276,16031,27634,27538,27601,28530,29352,28906,12147,12275,12372,17292,17317,17274,24910,25099,24989,25167,25310,25243,25243,25310,25234,24641,24354,24400,24641,24400,24592,12721,12771,12783,25938,26053,26035,30300,29766,29781,30114,30191,30045,29844,30047,29940,11171,11060,11175,11175,11037,11125,11125,11107,11197,11197,11107,11131,11127,11062,11171,11180,11062,11127,11066,11062,11180,11066,11180,11126,11273,11299,11056,11056,10828,10969,13036,13110,13028,16467,16276,16345,16211,16246,16300,17457,17680,17547,16056,16246,16211,20506,21182,20946,20173,20154,19961,19487,19365,19387,21182,21253,20946,25167,25195,25135,30406,30480,30390,30390,30681,30368,30625,30388,30681,30625,30492,30388,30388,30492,30320,30407,30512,30413,30413,30512,30369,30369,30512,30394,30434,30480,30406,30680,30480,30846,30618,30434,30360,30519,30360,30357,11062,11060,11171,11796,11994,12009,17274,17317,17523,23305,23111,23296,21571,21482,21663,24718,24573,24505,24617,24573,24718,24236,24273,24139,30403,30143,30249,30032,30227,29990,11056,11299,10828,11060,11037,11175,13515,13419,13547,14668,14959,14889,26877,26727,26937,26035,26053,26224,20506,20312,20262,16276,16087,16031,15423,15447,15611,15911,16056,15976,20312,20154,20173,11481,11576,11560,11323,11286,11329,13400,14160,13765,14668,14885,14959,17233,17274,17523,24573,24388,24505,27538,27450,27350,27129,27127,26937,27515,27450,27538,27885,28126,27954,27070,27471,27268,27236,27471,27070,11418,11597,11140,11675,11796,11859,11828,11960,11994,11785,11650,11165,14213,14324,14400,18051,17933,17925,17798,17643,17523,17783,17933,18051,17878,17957,17918,17793,17957,17878,17680,17759,17547,27450,27331,27258,11037,11107,11125,11048,11123,11321,12745,12784,12468,12941,13036,13028,16517,16664,16577,26035,26224,26295,25089,24765,25034,14008,13908,14266,13305,13324,13419,14407,14370,14465,14492,14407,14465,14492,14465,14545,27331,27297,27258,28528,28507,28606,27755,27749,27463,29121,28580,29012,14959,15091,15212,14885,15091,14959,11443,11481,11560,12925,12721,12783,12989,13098,13299,12941,13028,12920,13156,13239,13300,28795,28528,28606,28795,28606,28684,28892,28580,29121,29239,28921,28864,27297,27238,27129,30388,30432,30681,30497,30249,30277,16087,15913,16030,15258,15278,15210,11111,11401,11131,19629,19934,19961,17783,17871,17933,11877,11759,11850,11647,11593,11655,11769,11950,11609,12532,12543,12559,14746,15256,14682,14492,14543,14493,27238,27127,27129,27065,27105,26895,28126,28485,28218,16403,16577,16435,16403,16435,16246,16403,16256,16376,25006,25099,24910,25006,24910,24845,12147,12175,12275,12275,12102,12481,11928,12071,12117,11960,12117,11994,28855,28864,28849,29484,29670,29593,29593,29885,29669,11208,11286,11323,11358,11370,11576,15091,15113,15212,14923,15113,15091,18369,18489,18061,18750,18824,18907,30121,30191,30114,30121,30114,30047,30121,30550,30624,15978,16246,16056,21571,21474,21482,22229,22152,22362,11928,11960,11828,18793,18824,18750,26126,26617,25987,19365,19288,19387,19360,19288,19365,22208,22229,22357,22144,22229,22208,30481,30277,30394,30224,30322,30095,11636,11593,11647,11481,11358,11576,17933,17871,17838,18957,19004,19113,25825,26126,25850,26074,26126,25825,25456,25390,25310,12516,12532,12559,12673,12721,12925,28892,28855,28849,18018,18141,18061,18018,18061,17957,21758,21571,21663,23646,23330,23426,23646,23426,23840,30416,30519,30357,30456,30519,30416,11663,11636,11850,17274,17149,17292,16803,16704,16810,16506,16467,16706,15926,16087,15973,15926,15913,16087,15926,15825,15913,17233,17149,17274,23928,23977,23866,24965,25006,24845,23928,23746,23712,23015,22227,22060,15113,15258,15210,15115,15258,15113,12590,12761,12771,11759,11663,11850,30615,30512,30407,11123,11186,11355,11048,11186,11123,30403,30387,30143,30457,30387,30403,11208,11323,11308,11208,11308,11370,11209,11358,11481,18489,18793,18750,21747,21603,21467,18515,18793,18489,30313,30047,29844,30539,30174,30182,30604,30322,30224,29990,30300,29781,26892,26877,26937,26775,26817,26491,11609,11950,11482,24092,24236,24139,30512,30481,30394,30466,30053,30191,15324,15423,15278,15911,15909,16056,25938,25765,25771,26295,26382,26396,12721,12590,12771,12619,12590,12721,15913,15825,16030,16467,16700,16706,15681,15824,15976,17680,17793,17878,18141,18369,18061,17650,17793,17680,28855,29004,28864,29081,29004,28855,11593,11443,11655,11357,11443,11232,11391,11593,11636,12071,12039,12147,11991,12039,12071,11928,12117,11960,15258,15324,15278,15205,15324,15258,17835,18018,17957,24592,24845,24641,25099,25167,25135,26397,26295,26396,12035,12175,12147,16704,16706,16810,17354,17547,17601,16403,16457,16577,16376,16457,16403,25122,25167,25099,13419,13324,13547,12692,12673,12925,13305,13419,13515,14668,14889,14629,11796,12009,11859,27331,27372,27297,27297,27315,27238,27238,27315,27127,27127,26892,26937,27450,27476,27331,27634,27515,27538,27634,27601,27765,10800,11111,11131,19660,19629,19961,21719,21824,22056,21747,21824,21719,21747,21719,21603,21204,20693,21260,27515,27476,27450,27698,27634,27765,27840,27765,27954,11206,11208,11370,10969,11066,11056,11286,11208,11206,11609,11663,11759,17354,16664,16517,23977,24092,24109,24438,24592,24400,23928,23712,23818,27476,27372,27331,27749,27755,27803,28580,28892,28849,27471,27755,27463,27675,27755,27471,27236,27070,27105,18237,18369,18141,23763,23646,23840,24573,24617,24388,25652,25482,25771,24438,24400,24236,27890,27840,27954,25445,25456,25310,11066,10958,11062,11062,10945,11060,11060,10945,11037,11037,10613,11107,11107,10800,11131,10969,10958,11066,11537,11329,10751,21824,21952,22056,13324,13219,13547,14543,14492,14545,14166,14008,14370,13192,13219,13324,13104,12989,13219,14682,15256,14695,27120,27236,27105,27120,27105,27065,28128,27890,27954,11155,11329,11286,12815,13031,13042,12863,12745,12920,13036,12941,13156,12468,12908,12481,15825,15670,15730,15723,15670,15825,15611,15681,15976,15824,15909,15911,15576,15681,15611,29081,28892,29094,12745,12941,12920,15324,15447,15423,15371,15447,15324,11675,11859,11724,11567,11891,11597,24214,24438,24236,20312,20250,20154,19727,19660,19961,20506,20250,20312,20452,20250,20506,21253,21381,20946,11111,11048,11321,11418,11567,11597,10800,11048,11111,11405,10867,11650,12532,12357,12543,11769,11609,11759,12590,12516,12559,12405,12516,12590,12118,12468,12481,15973,16087,16079,15919,15909,15749,17871,17643,17798,16803,16810,17115,17783,17643,17871,19201,19221,19288,17549,17650,17680,17793,17835,17957,18152,18237,18141,17549,17680,17457,19629,19487,19387,19361,19487,19463,24092,24214,24236,23818,23712,23263,30481,30497,30277,30421,30327,30322,15506,15538,15577,14923,15115,15113,18369,18515,18489,18152,18141,18018,28126,27885,28485,11536,11675,11724,17340,17354,17111,12175,12077,12275,12039,12035,12147,11991,12035,12039,11991,12071,11928,11828,11994,11796,25167,25445,25310,25006,25122,25099,25075,25122,25006,24965,24845,24592,30492,30615,30407,30512,30630,30481,30481,30639,30497,30681,30432,30368,30680,30390,30480,30618,30360,30519,24924,24965,24592,29480,29640,29484,29726,29640,29480,29239,28864,29004,19487,19360,19365,19361,19360,19487,22229,22144,21899,21571,21413,21474,22229,22362,22357,15610,15506,15577,15610,15577,15670,15681,15656,15824,15447,15530,15611,15371,15530,15447,27073,27065,26768,25897,26074,25825,25897,25635,25710,28218,28128,28126,28530,28674,29352,28836,28795,28906,26877,26817,26775,27282,26892,27127,15742,15723,15825,30625,30615,30492,30708,30618,30519,30708,30519,30456,11627,11828,11796,18272,18515,18369,19131,18907,19047,25428,25445,25167,30322,30327,30091,30457,30224,30387,15115,15205,15258,11206,11155,11286,11206,11370,11209,11567,11536,11724,11405,11399,10867,17650,17835,17793,18571,18698,18515,17577,17835,17650,23840,24036,24106,22357,22362,22437,23369,23296,23330,22144,21937,21899,26892,26817,26877,25765,25938,26149,11443,11357,11481,11232,11443,11593,17354,17549,17457,23487,23369,23330,12516,12357,12532,12334,12357,12516,12619,12721,12673,16079,16087,16276,15926,15742,15825,16079,16276,16467,29229,29239,29004,27372,27315,27297,26892,26911,26817,27476,27492,27372,27515,27529,27476,27745,27529,27515,27745,27515,27634,27698,27765,27848,27765,27840,27848,14720,14695,15256,15723,15610,15670,15742,15610,15723,27529,27492,27476,27848,27840,27949,11601,11609,11482,11663,11530,11636,12746,13239,13156,13893,14540,14324,14324,14540,14629,15011,15159,15115,15115,15159,15205,13275,13239,12660,13156,12941,12746,19360,19201,19288,19240,19201,19360,28128,27954,28126,27949,27840,27890,29815,29885,29593,30327,30296,30032,28674,29021,29716,30352,30296,30327,30886,30466,30894,30783,30466,30886,30615,30630,30512,30647,30457,30403,12989,12938,13098,12989,13299,13219,14492,14379,14407,14493,14379,14492,14493,14543,14682,27492,27315,27372,12035,12077,12175,11792,11991,11928,11882,11991,11792,11571,11796,11675,16803,17115,17149,23889,23818,23444,21824,21844,21952,18840,18824,18793,17585,17783,17689,17070,16803,17149,23818,23263,23444,24035,24214,24092,24808,24924,24592,17233,17523,17643,29640,29670,29484,29726,29670,29640,22645,22357,22437,23646,23487,23330,23341,23487,23457,22091,21937,22144,23305,23296,23369,30647,30403,30497,11339,11536,11212,29885,29923,29669,30078,29923,29885,13819,14324,14213,27167,27120,27073,27236,27675,27471,27885,28507,28485,11209,11370,11358,10798,10940,10969,15816,15742,15926,15955,16079,16063,18515,18698,18793,18272,18369,18237,19047,18907,18824,21747,21844,21824,30611,30421,30322,30630,30639,30481,12692,12619,12673,12938,12815,13042,12850,12815,12938,15576,15656,15681,15909,15919,16056,16457,16376,16517,17354,17577,17549,15576,15611,15530,15371,15324,15205,26320,26617,26126,25710,25635,25456,28795,28836,28528,29021,29663,29716,11357,11209,11481,11232,11209,11357,18152,18272,18237,18152,18018,17835,14720,15256,14903,14540,14668,14629,28720,28507,28528,22177,22144,22208,30639,30653,30497,30466,30539,30182,10958,10945,11062,10969,10940,10958,11090,11329,11155,10940,10945,10958,13515,13649,13297,14923,15091,14885,15749,15909,15824,17222,17233,17643,25765,25652,25771,23341,23369,23487,26422,26035,26295,30846,30480,30434,30625,30769,30615,30615,30755,30630,30630,30688,30639,30639,30688,30653,30846,30434,30618,17783,17667,17643,17603,17667,17783,13297,13649,13644,30911,30681,30390,12815,12692,12925,12670,12692,12815,25897,26117,26074,28789,28720,28528,29716,29663,29769,16704,16506,16706,16734,16506,16704,16734,16704,16803,23341,23305,23369,24538,24388,24617,25652,25089,25034,11934,12077,12035,12468,12373,12745,12102,12077,11934,16256,16403,16246,11023,11090,11155,11023,11155,11206,11609,11530,11663,11601,11530,11609,12142,11450,11950,12333,12357,11820,15867,15926,15973,14903,15256,15122,15867,15973,16079,15919,15978,16056,15656,15749,15824,15634,15749,15656,24035,23977,23928,24965,25075,25006,25330,25428,25167,25445,25547,25456,25897,26005,26117,24808,24592,24732,26564,26397,26396,26396,26491,26828,28789,28528,28836,13305,13192,13324,12849,12850,12938,25330,25167,25122,19597,20022,19830,21747,21699,21844,30681,30769,30625,14166,14370,14407,13305,13258,13192,14166,14407,14379,19463,19487,19629,19201,18957,19113,27848,27745,27698,27698,27745,27634,27529,27730,27492,27730,27282,27315,26828,26491,26817,27949,27745,27848,27949,27890,28051,30653,30647,30497,30699,30352,30421,30726,30647,30653,14277,14166,14379,30421,30352,30327,30296,30227,30032,30553,30224,30457,30769,30755,30615,15697,15978,15919,25428,25547,25445,28051,28128,28119,28051,27890,28128,10988,11023,11206,10708,10798,10969,10988,11206,11019,18698,18840,18793,19597,19444,20022,18689,18840,18698,13258,13104,13192,13192,13104,13219,14668,14923,14885,15471,15576,15530,28720,28485,28507,15371,15205,15174,15749,15697,15919,17549,17577,17650,18272,18402,18515,17340,17577,17354,21260,21467,21204,23889,24035,23818,27205,27301,27236,29094,28892,29121,27205,27236,27120,28222,28128,28218,17889,18152,17835,19361,19240,19360,22357,22177,22208,22091,22177,22625,22625,22177,22357,23763,23487,23646,30437,30227,30296,12334,12516,12405,12961,12938,12989,15106,15205,15159,28906,28789,28836,28720,28672,28485,14695,14493,14682,14480,14493,14695,27167,27205,27120,25652,25641,25089,26149,25938,26035,11240,11232,11593,12509,12619,12692,11536,11571,11675,11453,11571,11339,11536,11567,11212,18238,18402,18272,14923,15011,15115,24924,25075,24965,25553,25710,25547,24808,25075,24924,29239,29726,29013,29670,29815,29593,30539,30708,30456,30664,30708,30539,30664,30539,30783,12077,12102,12275,11882,12035,11991,16376,16372,16517,15978,16256,16246,16372,16256,16169,25089,24796,24718,24962,24796,24985,24732,24592,24438,29726,29815,29670,12850,12670,12815,12734,12670,12850,15576,15634,15656,15371,15382,15530,15174,15382,15371,24538,24036,24388,15471,15634,15576,28892,29081,28855,29839,29755,29726,29094,29167,29162,11439,11636,11530,13644,13649,13908,13041,12961,12989,19727,19961,19863,19361,19463,19240,19961,20154,19863,21758,21663,21937,21867,21758,21937,22645,22580,23061,23763,23457,23487,28404,28305,28218,28404,28218,28485,23818,24035,23928,24638,24732,24438,22060,22039,23015,29923,30078,29844,30335,30078,29885,17233,17070,17149,15955,15867,16079,17195,17070,17233,30647,30652,30457,30352,30437,30296,30718,30652,30647,13041,12989,13104,15011,15106,15159,26397,26422,26295,26911,26892,27017,28956,28672,28720,21960,21937,22091,21960,21867,21937,30598,30437,30352,30227,30300,29990,31102,30688,30630,12405,12590,12619,25553,25547,25428,25547,25710,25456,26320,26126,26074,13297,13258,13305,15538,15506,15122,27282,27127,27315,28461,28404,28485,17487,17222,17643,17195,17222,17352,15382,15471,15530,15634,15697,15749,15437,15471,15382,19240,18957,19201,19341,18957,19240,18840,19047,18824,18689,19047,18840,30652,30553,30457,30690,30553,30652,22091,22144,22177,30790,30664,30783,10940,10798,10945,10393,10800,11107,10828,11537,10751,14008,13644,13908,13297,13089,13258,14166,14156,14008,14249,14156,14166,14277,14379,14383,21571,21758,21413,21381,21474,21413,20946,21381,21101,12432,12405,12619,12961,12849,12938,12687,12849,12961,15106,15174,15205,26564,26422,26397,26645,26422,26564,26911,26828,26817,28591,28461,28485,12509,12692,12591,15437,15697,15634,29081,29229,29004,29162,29229,29081,11792,11928,11828,21413,21758,21789,11847,11934,12035,12102,12118,12481,16256,16372,16376,16329,16372,16289,18507,18571,18515,18507,18515,18402,18238,18272,18152,11623,11792,11828,13526,13644,13758,14383,14379,14493,27730,27315,27492,26911,27024,26828,27949,28040,27745,28051,28070,27949,28119,28070,28051,28119,28128,28222,28218,28305,28222,31059,30846,30618,30680,30911,30390,30681,31025,30769,30769,31025,30755,31296,30786,30688,31059,30618,30708,10887,11399,11186,11515,11627,11796,10887,11186,10803,11601,11439,11530,11482,11439,11601,11929,12118,12102,17889,18238,18152,17475,17835,17577,19660,19463,19629,19635,19463,19660,30688,30726,30653,30786,30726,30688,14480,14383,14493,27730,27529,27745,28222,28305,28286,30553,30604,30224,30692,30604,30553,11515,11796,11571,17070,16998,16803,16969,16998,17070,24808,24818,25075,25651,25553,25428,24638,24438,24497,13258,13041,13104,12937,13041,12950,14582,14480,14695,15122,15506,15354,15506,15610,15354,25931,26005,25897,25717,25553,25625,12734,12850,12849,12591,12692,12670,14582,14695,14720,20693,20474,20239,21467,21699,21747,25714,25897,25710,26320,26074,26117,27205,27391,27301,27301,27675,27236,28286,28305,28376,28786,28336,28162,12687,12734,12849,22580,23305,23061,21789,21758,21867,26235,26320,26117,30726,30694,30647,30786,30694,30726,11453,11515,11571,17222,17195,17233,17603,17643,17667,18238,18507,18402,18956,19183,19047,24796,24538,24617,23583,23473,23457,24746,24538,24796,17539,17603,17585,14681,14582,14720,23473,23305,23341,23473,23341,23457,25717,25714,25710,26149,25727,25765,24985,24796,25089,26828,26679,26396,26868,26679,26828,30437,30353,30227,28956,28720,28789,28757,28591,28672,30500,30353,30556,21789,21867,21960,17111,17354,16517,18605,18571,18507,11934,11929,12102,11882,11847,12035,11685,11847,11882,11685,11882,11792,11623,11828,11627,13239,13275,13765,14686,14923,14668,14686,15011,14923,14686,15000,15011,15011,15000,15106,15106,15000,15174,12373,12941,12745,12373,12468,12090,27282,27017,26892,30263,29663,29766,10751,11329,11090,10988,11090,11023,29815,30012,29885,29726,29755,29815,29839,29726,29239,29312,29239,29229,11742,11929,11934,12734,12591,12670,12529,12591,12734,26005,26235,26117,27295,27205,27167,26318,26235,26283,12509,12432,12619,12405,12296,12334,11317,11482,11241,12320,12432,12509,25714,25931,25897,11019,11206,10881,11019,10881,10865,11532,11623,11627,16998,16872,16803,16768,16872,16969,16734,16872,16768,24732,24818,24808,25553,25717,25710,25714,25717,25931,24682,24818,24732,30604,30611,30322,30759,30611,30604,19047,19183,19131,20022,20693,20239,18689,18698,18571,30694,30718,30647,30828,30718,30694,10613,11037,10945,15354,15610,15596,14903,14749,14720,19863,20154,20086,19463,19341,19240,21677,21699,21467,14681,14749,14578,30500,30300,30227,30500,30227,30353,30078,30313,29844,30382,30313,30503,11165,11140,11597,11515,11532,11627,11092,11140,10667,23583,23457,23657,11453,11532,11515,24497,24214,24481,24497,24438,24214,27460,27675,27301,17603,17487,17643,17539,17487,17603,17340,17540,17577,24538,24106,24036,16079,16467,16063,22048,21789,21960,22048,21960,22091,14383,14249,14277,14277,14249,14166,13758,13644,14008,14150,14249,14383,14421,14383,14480,14421,14480,14582,30718,30690,30652,30844,30690,30718,10988,10889,11090,10889,11019,10865,18605,18689,18571,18605,18507,18541,26907,26868,26828,25727,25652,25765,28672,28591,28485,28461,28523,28404,28956,28789,28906,13644,13526,13297,13041,12937,12961,14009,14008,14156,27295,27391,27205,27295,27167,27366,19727,19635,19660,17539,17365,17487,29537,28956,28906,30664,30790,30708,30783,30539,30466,11820,12357,12334,11439,11391,11636,11339,11571,11536,12432,12296,12405,12320,12296,12432,29298,29312,29229,29162,29081,29094,27073,26617,26320,16372,16329,16517,17340,17394,17540,16169,16256,15978,16169,16053,16133,16133,16370,16289,30690,30692,30553,30598,30353,30437,30844,30692,30690,19635,19539,19463,22060,21952,22039,10798,10709,10945,10708,10709,10798,13089,13041,13258,12320,12181,12296,15978,15697,16053,16872,16734,16803,16872,16998,16969,20846,20693,20716,21336,21677,21467,26645,26564,26679,24332,24185,24106,26868,26720,26679,29755,29877,29815,29951,29877,29755,10328,10708,10969,20644,20452,20506,19727,19565,19635,19635,19565,19539,20822,20516,20644,20881,20644,20946,20881,20946,21078,13275,13400,13765,13241,13400,13275,28222,28323,28119,28323,28040,28070,28070,28040,27949,27464,27024,27017,27017,27024,26911,26868,26941,26720,28376,28305,28404,20516,20452,20644,21101,21381,21413,30960,30911,30967,30911,30680,30967,18956,19444,19183,18541,18507,18238,11482,11391,11439,17487,17365,17222,17352,17365,17398,17540,17475,17577,17360,17394,17300,15596,15610,15742,14817,14749,14903,15663,15596,15742,16063,16467,16506,24638,24682,24732,25330,25122,25075,24659,24682,24638,26235,26318,26320,26283,26235,26005,26529,26318,26579,12108,12468,12118,15816,15926,15867,28659,28786,28162,29312,29839,29239,22154,22048,22091,21457,21101,21413,22625,22357,22645,30624,30191,30121,30967,30680,30846,13121,13241,12735,21457,21413,21583,28523,28376,28404,28523,28461,28591,10803,11186,11048,30692,30759,30604,30806,30759,30692,15174,15437,15382,14686,14668,14540,26594,26645,26883,26720,26645,26679,28956,28757,28672,28820,28757,28903,12296,12181,12334,11482,11317,11391,12320,12509,12223,15955,15816,15867,24481,24214,24035,26149,26035,26422,25330,25075,25057,31102,30630,30755,13139,13089,13297,12223,12509,12591,14749,14681,14720,14817,14903,15122,22039,21952,21844,27123,27024,27199,23015,23400,23263,24301,24481,24035,28501,28150,27919,29162,29298,29229,29716,29352,28674,30263,29769,29663,11192,11567,11418,11453,11361,11532,11361,11685,11623,11866,11929,11742,11866,11952,11929,11929,11952,12118,11192,11418,11140,12814,12961,12937,14249,14009,14156,13526,13139,13297,14150,14009,14249,17300,17394,17340,16169,16289,16372,16289,16169,16133,17365,17352,17222,17603,17783,17585,21583,21413,21789,25057,25075,24818,24822,24818,24682,29288,29298,29162,30786,30828,30694,31032,30828,30786,12373,12746,12941,24962,24932,24796,25604,24985,25089,26645,26588,26422,26594,26588,26645,27024,26907,26828,11685,11792,11623,12485,12595,12746,29877,30012,29815,29951,30012,29877,20086,20154,20250,17783,17730,17689,21689,21583,21789,27366,27460,27391,27391,27460,27301,27832,28501,27919,27366,27391,27295,23378,23061,23305,21808,21689,21789,23378,23305,23473,23457,23763,23657,11019,10889,10988,10551,10643,10708,11206,11209,10881,30828,30844,30718,30699,30421,30611,31032,30844,30828,11952,12108,12118,25727,25641,25652,25894,25641,25727,25651,25625,25553,26283,26005,26234,11092,11192,11140,30313,30476,30047,30601,30382,30555,13089,12950,13041,12922,12950,13089,21699,21795,21844,21336,21467,21260,28757,28646,28591,28820,28646,28757,11361,11623,11532,11192,11212,11567,19341,19463,19539,17394,17475,17540,17360,17475,17394,23400,23444,23263,23740,23444,23602,26588,26149,26422,29463,29839,29312,29121,29167,29094,29206,29167,29121,30699,30611,30806,30300,30263,29766,15354,15265,15122,15178,15265,15354,15178,15354,15356,27803,28501,27832,14384,14421,14582,14578,14582,14681,21677,21795,21699,23740,23889,23444,29769,29352,29716,10889,10751,11090,10881,11209,10904,10887,10867,11399,10838,10867,10887,10803,11048,10515,11391,11240,11593,11241,11482,11450,11221,11317,11241,30550,30121,30047,30806,30611,30759,12950,12814,12937,12839,12814,12950,28903,28757,28956,27803,28307,28501,19706,19565,19727,11676,11685,11562,11979,12090,12108,11742,11934,11847,12997,12823,12820,16969,17070,17195,16734,16063,16506,15756,15663,15816,15816,15663,15742,16969,17195,17352,24985,24932,24962,24882,24932,24976,10688,10803,10404,23657,23763,24106,30382,30476,30313,30479,30476,30382,19565,19558,19539,11221,11240,11391,17539,17398,17365,17362,17398,17539,17475,17889,17835,17300,17340,17111,10708,10643,10709,10709,10613,10945,10551,10328,10428,10643,10648,10709,10648,10613,10709,10855,10881,10770,10690,10751,10889,12814,12687,12961,12575,12687,12814,17323,16969,17352,20881,20822,20644,20516,20646,20452,20086,19808,19863,19863,19713,19727,19565,19554,19558,20906,20822,20881,20906,20881,21078,20946,21101,21078,24932,24746,24796,26567,26113,26149,26883,26645,26720,21078,21101,21112,30911,31025,30681,30967,30846,31059,31022,30708,30790,30699,30598,30352,30500,30574,30300,28367,28323,28286,28323,28070,28119,27123,26941,26907,26907,26941,26868,28646,28523,28591,28774,28523,28646,12108,12090,12468,11979,12108,11952,21112,21101,21197,21795,22039,21844,10803,10838,10887,10909,11092,10667,10688,10838,10803,21197,21101,21257,21689,21457,21583,28323,28222,28286,24497,24659,24638,25330,25651,25428,24301,24035,23889,14119,14150,14383,12957,12997,12820,14119,14383,14259,29167,29288,29162,29012,29206,29121,29297,29206,29012,31049,31025,30911,27123,26907,27024,27803,27755,28307,28786,29043,29012,17485,17889,17475,18956,19047,18689,24185,23657,24106,23493,23378,23473,21808,21789,22048,26318,26529,26320,26005,25931,26234,28911,29043,28786,30476,30550,30047,30637,30479,30623,17398,17323,17352,17783,18051,17730,19558,19341,19539,19554,19341,19558,15756,15816,15955,14969,14817,15122,11685,11676,11847,11866,11840,11952,11361,11453,11045,29440,29312,29298,30012,30190,29885,11676,11742,11847,23493,23473,23583,30598,30556,30353,30748,30556,30598,30894,30466,30191,30783,31022,30790,30572,30550,30476,21192,21336,21260,21677,21614,21795,21795,22012,22039,21192,21260,20693,27460,27550,27675,27073,27366,27167,28367,28286,28489,29839,29951,29755,30699,30748,30598,30966,30806,30692,30915,30806,30966,10855,10831,10881,11317,11221,11391,11820,12334,12181,17362,17323,17398,17111,16517,16652,17360,17335,17475,11937,11820,12181,11937,12181,12320,11602,11840,11866,16768,16063,16734,15893,16063,16768,16863,16768,16969,14969,15122,15265,24726,24822,24682,25625,25830,25717,30046,30030,30012,12485,12746,12375,11823,11979,11952,25454,25651,25330,15498,15354,15596,15606,15498,15663,15663,15498,15596,29206,29288,29167,29350,29288,29206,20086,20250,20452,16652,16517,16329,24481,24659,24497,24591,24659,24481,11192,11110,11212,11212,11045,11339,11016,11092,10909,28839,28911,28786,29043,29157,29012,28614,28501,28474,10831,10889,10865,15163,14969,15265,14635,14578,14749,19808,19713,19863,22625,22645,23061,23654,22625,23061,23562,23493,23583,23562,23583,23657,28820,28774,28646,28523,28531,28376,29008,28903,28956,28839,28786,28659,30556,30581,30500,30733,30581,30556,30620,30572,30476,30738,30764,30624,30620,30476,30479,13139,12997,13089,12687,12529,12734,13758,14008,13812,14635,14749,14817,26669,27073,26320,28774,28531,28523,19713,19706,19727,30190,30335,29885,16289,16370,16329,16169,15978,16053,26234,25931,26032,26529,26669,26320,30738,30624,30550,10881,10831,10865,11209,11232,10904,15437,15634,15471,29288,29440,29298,29463,29440,29462,13812,14008,14009,13812,14009,13930,13930,14009,14150,12746,12660,13239,13121,13229,13400,13893,14686,14540,12746,12373,12375,26579,26669,26529,30030,30190,30012,29951,30046,30012,30022,30046,29951,30015,29951,29839,13925,13930,14150,28040,27730,27745,27926,27730,28040,28367,28040,28323,11840,11823,11952,11831,12373,12090,11626,11823,11840,11602,11866,11742,11620,11742,11676,12997,12922,13089,12957,12922,12997,13542,14213,13400,15132,15437,15174,28501,28651,28659,28911,29157,29043,17730,18051,17874,17585,17362,17539,17062,16863,16969,17730,17775,17639,23654,23061,23378,23641,23562,23657,30668,30738,30550,30637,30620,30479,14259,14383,14421,27489,27550,27460,28501,28614,28651,27489,27460,27366,30827,30191,30624,17453,17362,17585,24822,25057,24818,24659,24726,24682,24591,24726,24659,30247,30190,30030,30623,30479,30382,31047,31022,30783,10904,11232,10619,10831,10690,10889,14384,14259,14421,27550,27777,27799,27611,27489,27366,10643,10551,10648,10648,10519,10613,10613,10389,11107,10551,10708,10328,10551,10519,10648,20822,20646,20516,19808,19862,19713,19713,19763,19706,20910,20646,20822,20910,20822,20906,20910,20906,21078,20910,21078,21197,10619,11232,11240,12922,12839,12950,12731,12839,12922,28881,28774,28820,28489,28286,28376,28881,28820,28903,28796,28839,28651,28651,28839,28659,30869,30748,30699,30686,30263,30300,30764,30827,30624,30668,30550,30572,15132,15174,15000,21197,21078,21112,26283,26579,26318,25913,25931,25717,25913,25717,25830,12575,12529,12687,14523,14384,14578,14578,14384,14582,15178,15163,15265,15356,15163,15178,15356,15354,15498,26669,26625,27073,26275,26579,26283,11450,12142,12333,11221,11087,11240,13121,13400,13241,28489,28376,28531,31528,31059,30708,30967,31291,30960,30960,31049,30911,10838,10688,10867,10515,11048,10800,25830,25625,25651,31025,31102,30755,30806,30915,30699,31317,31049,30960,11092,11110,11192,11016,11110,11092,11562,11620,11676,12448,12660,12595,12735,13241,13275,14635,14817,14754,20188,20086,20452,21257,21101,21457,21257,21457,21350,21232,21192,21151,21336,21491,21677,19444,19597,19183,28499,28489,28608,30299,30015,30302,30270,30291,30190,30710,30668,30572,30623,30382,30601,12595,12660,12746,12090,11979,11895,26941,26883,26720,26789,26149,26588,26149,26113,25727,25641,25604,25089,27116,26883,26941,28774,28993,28531,29008,28881,28903,10700,10690,10831,10904,10770,10881,30812,30827,30764,30812,30764,30738,16573,16652,16370,16370,16652,16329,17111,17198,17300,17300,17335,17360,16177,16370,16133,24813,25057,24822,21350,21457,21689,24304,24301,23889,24726,24813,24822,23444,23400,23363,23400,23015,23291,30710,30572,30620,23638,23378,23493,28307,27755,28170,11045,11453,11339,17062,16969,17323,15831,15756,15955,26789,26588,26594,24332,24538,24667,24332,24106,24538,12839,12575,12814,12223,11937,12320,11191,11133,11241,12731,12575,12839,21192,21491,21336,26883,26789,26594,26820,26789,26883,28881,28920,28774,29537,29008,28956,29064,29008,29537,29537,30239,29791,31164,31102,31025,12223,12591,12529,12997,13139,12912,15831,15955,16063,24301,24591,24481,26263,26275,26234,26234,26275,26283,25930,25830,25651,27464,27017,27282,30574,30500,30581,30190,30291,30335,30270,30190,30247,17689,17612,17585,17362,17062,17323,18051,18957,17874,19706,19554,19565,20086,19862,19808,23291,23015,23117,24301,24624,24591,30733,30574,30581,30767,30710,30620,30503,30078,30335,10700,10831,10855,10751,10480,10828,30966,30692,30844,30748,30733,30556,30827,30894,30191,30886,31047,30783,30859,30894,30827,30812,30738,30810,12700,12820,12823,13812,13782,13758,13930,13782,13812,13925,13782,13930,13925,14150,14119,13925,14119,13970,13331,13400,13229,13331,13542,13400,13970,14119,14259,31326,31032,30786,30791,30733,30748,30767,30620,30637,15304,15356,15498,14754,14817,14969,26032,25931,25913,27550,27489,27595,19862,19763,19713,14754,14969,14732,13735,13970,14259,11620,11602,11742,11301,11562,11685,11895,11979,11823,13170,13259,13152,13259,13331,13229,29075,29157,28911,29440,29463,29312,29075,28911,29103,11241,11133,11221,10742,10855,10770,10742,10700,10855,11191,11241,11142,15756,15606,15663,17178,17198,17111,18541,18689,18605,25930,26032,25913,29350,29440,29288,30380,30338,30335,11459,11602,11620,16053,16177,16133,16652,16785,17111,13259,13229,13152,16444,16573,16370,28170,27755,27675,28614,28721,28651,27806,27675,27799,30810,30738,30668,10296,10480,10751,10742,10770,10695,16662,16785,16652,30915,30932,30699,30954,30932,30915,31159,31047,30886,30890,30859,30827,27730,27464,27282,28144,27464,27730,28527,28040,28367,29008,28920,28881,28489,28499,28367,29064,28920,29008,17730,17723,17689,17639,17723,17730,30503,30313,30078,30720,30767,30637,30710,30810,30668,11743,11895,11823,22154,21808,22048,28608,28489,28531,28307,28474,28501,16785,16985,17111,30291,30380,30335,30338,30503,30335,30247,30030,30046,30022,29951,30015,30720,30637,30623,24538,24746,24667,23562,23641,23493,30292,30022,30299,29355,29350,29206,30460,30503,30338,12735,13275,12660,12324,12375,12373,31032,30966,30844,31081,31220,31108,10656,10751,10690,19633,19554,19706,28993,28608,28531,30974,30886,30894,31022,31528,30708,30935,30890,30827,30935,30827,30812,23117,23015,22039,23740,24304,23889,26113,25894,25727,25886,25894,26004,10551,10428,10519,10519,10450,10613,10326,10428,10328,10428,10450,10519,11450,12333,11820,11133,11087,11221,18005,18238,17889,16985,17178,17111,30408,30380,30291,10376,10515,10800,11140,11165,10667,18541,18238,18005,30974,30894,31028,11247,11450,11820,16573,16662,16652,16902,17137,16985,16985,17137,17178,16181,16444,16370,27464,27199,27024,27123,27116,26941,26789,26567,26149,28677,28721,28614,29157,29297,29012,30022,30015,30299,30270,30408,30291,11602,11626,11840,12138,12324,12038,11459,11626,11602,11459,11620,11562,16177,16181,16370,15437,16053,15697,11110,11045,11212,11361,11301,11685,11165,10867,10667,12200,12223,12529,11005,11249,11450,12200,12529,12172,12735,12660,12571,11831,12090,11895,17723,17612,17689,17639,17612,17723,20646,20188,20452,20086,19817,19862,19862,19817,19763,19763,19643,19706,19897,20188,20074,20188,20301,20074,21147,20910,21197,21350,21197,21257,29322,29297,29157,29350,29462,29440,23802,23641,23657,22625,22154,22091,30767,30810,30710,30752,30720,30623,30752,30623,30601,30752,30601,30757,15520,15529,15606,15606,15529,15498,15356,15082,15163,15520,15606,15756,15831,16063,15893,29493,29462,29350,10695,10770,10904,10700,10656,10690,17335,17300,17198,21192,21232,21491,21491,21614,21677,20846,21192,20693,30932,30869,30699,30733,30832,30574,30956,30869,30932,30871,30935,30812,31028,30894,30859,11075,11087,11133,11075,11133,11191,17137,17335,17198,17137,17198,17178,24185,23802,23657,24667,24746,24882,24333,24304,23740,24591,24813,24726,25057,25370,25330,25830,25930,25913,29001,28911,28839,30588,30460,30338,30588,30338,30380,22371,22154,22625,21808,21350,21689,28340,27926,28040,27176,27116,27199,28527,28367,28499,23291,23363,23400,23298,23363,23291,24759,24813,24591,27199,27116,27123,27092,27116,27176,27799,27675,27550,28307,28360,28474,28474,28677,28614,27550,27595,27777,28721,28796,28651,28897,28796,28966,30250,30247,30046,30908,30791,30748,30574,30686,30300,30904,30810,30767,13838,13970,13735,13925,13733,13782,12820,12731,12957,12957,12731,12922,14523,14578,14635,26625,26669,26579,28235,28170,27675,31028,30859,30890,21147,21348,21135,31049,31164,31025,31102,31296,30688,31230,31164,31345,31291,30967,31358,11249,11142,11241,24882,24746,24932,24374,24624,24301,30448,30408,30270,13331,13170,13542,13542,13819,14213,12660,12448,12571,28427,28360,28307,13526,12974,12912,12595,12485,12448,15383,15304,15498,28897,28876,28796,28796,28876,28839,30292,30257,30022,29297,29355,29206,29380,29355,29297,29380,29297,29406,10592,10656,10700,10589,10695,10904,23641,23638,23493,24116,23802,24185,23638,23802,23837,26275,26625,26579,26543,26625,26275,26095,26234,26032,31021,30871,30810,30555,30382,30503,30555,30503,30554,17612,17453,17585,17639,17453,17612,17335,17485,17475,17259,17485,17335,30554,30503,30460,10592,10700,10742,19850,19817,19897,17874,18957,18024,21492,21614,21491,28360,28465,28474,30966,30954,30915,30869,30908,30748,31081,30954,30966,23363,23445,23444,24304,24374,24301,23352,23445,23363,16053,16181,16177,16738,16985,16785,16084,16181,16053,16084,16053,15444,25410,25370,25057,25454,25370,25410,10689,11301,11361,10374,10589,10904,11088,11075,11191,11016,11045,11110,24624,24759,24591,24333,24374,24304,25638,25604,25641,25886,25641,25894,13152,13229,13121,12448,12485,12281,14732,14969,14875,28876,29001,28839,28897,29001,28876,24976,24932,24985,24667,24499,24332,31002,30908,30869,30878,30832,30733,11626,11743,11823,12281,12485,12375,11726,11743,11693,15893,16768,16863,15529,15383,15498,19817,19643,19763,10656,10497,10751,10482,10592,10742,10589,10742,10695,15520,15383,15529,15304,15082,15356,29355,29493,29350,29492,29493,29355,30954,30956,30932,31081,30956,30954,31010,31028,30890,30974,31098,30886,31010,30890,30935,31010,30935,30953,11016,10717,11045,10667,10867,10220,18957,19341,18967,17047,17062,17362,30555,30757,30601,30904,30767,30720,30679,30757,30555,24786,24759,24624,30588,30554,30460,30247,30448,30270,30527,30448,30247,30250,30046,30022,13152,13121,12979,12281,12375,12324,23445,23602,23444,24374,24553,24624,23620,23602,23461,26999,26820,26883,27092,26883,27116,29001,29103,28911,29122,29103,29001,30484,30380,30408,19643,19633,19706,11726,11831,11895,26004,25894,26113,25454,25930,25651,13733,13758,13782,12731,12576,12575,31190,31098,30974,31358,30967,31059,31028,31078,30974,30871,30812,30810,10619,11240,11087,11142,11088,11191,11042,11088,11142,13838,13733,13925,13838,13925,13970,16662,16573,16601,17485,18005,17889,24596,24499,24667,24536,24553,24374,30904,30720,30752,12038,12324,12373,13735,13617,13614,13596,13819,13542,14686,15132,15000,13170,13331,13259,28170,28334,28307,28360,28427,28465,28781,28796,28721,27806,28235,27675,28048,28235,27806,27844,27806,27799,29212,29157,29075,30257,30250,30022,10428,10326,10450,10450,10349,10613,10328,10969,10828,10328,10828,10260,16181,16318,16444,15444,16053,15437,25370,25454,25330,25410,25057,25399,24786,24813,24759,31358,31059,31457,10326,10349,10450,13819,13893,14324,27595,27489,27611,28235,28334,28170,15172,15082,15304,15649,15520,15756,26046,26095,26032,27751,27595,27735,26046,26032,25930,10349,10389,10613,20103,20693,20022,21232,21312,21491,27176,27199,27291,28598,28474,28465,29103,29212,29075,29254,29212,29103,16601,16573,16444,24846,24596,24667,25282,24976,24985,25571,24985,25604,29463,29462,29881,30448,30484,30408,13121,12735,12702,21614,22012,21795,21690,22012,21614,25760,25638,25641,27595,27611,27735,28334,28427,28307,19247,19341,19554,17047,17362,17453,23802,23638,23641,24289,24185,24332,23602,23630,23740,23620,23630,23602,10260,10828,10480,20846,21151,21192,12538,12735,12571,24499,24289,24332,24527,24289,24499,24265,24333,24114,24553,24786,24624,30871,30953,30935,31071,31078,31028,11831,12038,12373,11743,11726,11895,11559,11743,11626,12402,12538,12571,12580,12538,12500,27092,26999,26883,26206,26004,26113,25886,25760,25641,11930,12038,11893,12143,12281,12324,21151,21312,21232,28608,28527,28499,27291,27199,27526,27092,27083,26999,28993,28527,28608,28993,28774,28920,28427,28598,28465,29380,29492,29355,29483,29492,29380,12143,12324,12138,15172,15304,15383,14754,14523,14635,29212,29322,29157,29290,29322,29212,29122,29001,28897,10995,11042,11142,10979,11087,11075,11249,11241,11450,17677,17453,17639,15831,15649,15756,24903,24667,24882,30575,30484,30448,30554,30679,30555,30757,30814,30752,31172,31071,30953,31164,31230,31102,31345,31164,31049,26206,26113,26340,26263,26543,26275,26118,26046,25930,19579,19247,19554,28598,28677,28474,10979,11075,11088,10592,10497,10656,14875,14969,15163,17874,17775,17730,17735,17775,17874,21312,21492,21491,22749,23117,22039,24116,23837,23802,23638,23654,23378,24116,24185,24169,28966,29122,28897,30878,30733,30791,29537,28906,29352,31014,30791,30908,24169,24185,24289,30665,30679,30554,11337,11459,11562,11337,11562,11301,11337,11301,11278,16223,16318,16181,16662,16738,16785,10482,10497,10592,11247,11820,11937,11687,11937,12223,11459,11559,11626,12036,12138,12038,16318,16601,16444,25638,25571,25604,24976,24903,24882,25680,25571,25638,30250,30391,30247,29609,29462,29493,31070,31002,30869,31081,30966,31220,31071,31028,31010,31098,31159,30886,31071,31010,30953,10389,10393,11107,10515,10404,10803,28677,28781,28721,17137,17259,17335,17130,17259,17137,30484,30588,30380,30741,30588,30766,10205,10404,10515,12500,12538,12402,12036,12143,12138,11700,11831,11726,14438,15132,14686,16084,16223,16181,26263,26234,26095,29322,29406,29297,29492,29609,29493,29500,29406,29322,26220,26263,26095,11559,11693,11743,16601,16738,16662,25116,24903,24976,24533,24169,24289,25852,25760,25886,15082,14875,15163,13530,13637,13645,14732,14875,14605,29122,29254,29103,29243,29254,29122,13735,13637,13733,13733,13637,13758,14523,14754,14732,13819,13718,13893,13893,13888,14686,13107,13596,13542,13107,13542,13170,27844,27799,27777,27844,28048,27806,28235,28355,28334,28334,28355,28427,28726,28677,28598,28902,28781,28677,28902,28923,28781,27844,27777,27751,12820,12704,12731,12700,12704,12820,26340,26113,26567,27199,27464,27526,28781,28966,28796,28923,28966,28781,31091,30869,30956,31165,31159,31098,31021,30953,30871,10393,10376,10800,15893,15649,15831,15520,15493,15383,19643,19674,19633,19633,19579,19554,19817,19674,19643,19748,19674,19817,19817,20086,19897,24571,24786,24553,25780,26118,25930,26046,26220,26095,24536,24374,24333,24536,24333,24420,27751,27777,27595,31165,31098,31190,17775,17677,17639,17735,17677,17775,30679,30814,30757,30909,30814,30679,23948,23654,23837,24527,24499,24596,27850,27751,27735,30832,30686,30574,30918,30686,30832,30741,30665,30588,30588,30665,30554,29406,29483,29380,29500,29483,29406,19674,19579,19633,19247,18967,19341,12704,12576,12731,12622,12576,12704,12538,12580,12735,13152,13069,13170,12402,12448,12281,14557,14523,14732,11042,10979,11088,10995,10979,11042,11377,11541,11559,11559,11541,11693,11278,11301,11085,15649,15493,15520,14605,14557,14732,16999,16902,16491,16318,16043,16601,16043,16223,16084,17665,18005,17485,16932,17130,17137,16902,16985,16738,19335,18967,19247,18541,18956,18689,19444,20103,20022,18662,18956,18541,24740,24527,24596,24333,23740,24114,31190,30974,31078,31310,31022,31047,10296,10260,10480,10565,10482,10742,10565,10742,10589,12702,12979,13121,23117,23298,23291,23248,23298,23117,23352,23298,23248,31050,31021,30810,31200,31190,31229,31081,31091,30956,30947,30878,30791,31108,31091,31081,11377,11559,11459,11693,11700,11726,15252,15172,15493,16728,15893,16863,16833,16863,17062,25760,25680,25638,25571,25282,24985,24903,24846,24667,25744,25680,25760,25744,25760,25852,30257,30391,30250,30404,30391,30257,30742,29769,30263,31232,31047,31159,31291,31317,30960,10349,10231,10389,10389,10226,10393,10393,10297,10376,10326,10231,10349,10096,10231,9962,10260,10326,10328,11541,11700,11693,12143,12170,12281,23837,23654,23638,20646,20910,20774,23948,23837,24116,24189,24116,24169,23461,23602,23445,31014,30908,31002,30814,30904,30752,30944,30904,30989,30781,30679,30665,31237,31232,31159,31165,31190,31227,16902,16738,16491,25042,24846,24903,24527,24533,24289,11893,12038,11831,12172,12529,12575,12036,12170,12143,23793,23740,23630,29483,29609,29492,29642,29609,29483,29290,29212,29254,30686,30729,30263,30913,30729,30686,10436,10565,10589,10464,10751,10497,31456,31317,31291,31230,31301,31102,10220,10867,10688,10909,10675,11016,23298,23352,23363,23461,23352,23248,31256,31014,31002,10464,10497,10423,19476,20103,19444,21169,21312,21151,21169,21385,21312,21312,21385,21492,28966,29243,29122,29192,29243,28966,16924,17047,17453,24536,24571,24553,25399,25057,25274,24420,24571,24536,31317,31345,31049,12912,13139,13526,12184,12172,12575,27176,27083,27092,27526,27464,28144,27730,27926,28144,28615,28598,28427,21492,21690,21614,21169,21151,20846,25049,24813,24786,25458,25282,25571,30015,29839,30302,30766,30588,30484,13637,13530,13758,13735,13733,13838,28048,28165,28235,28050,28152,28048,28050,28048,27844,27850,27844,27751,12402,12571,12448,12702,13069,12979,11930,12036,12038,11939,12036,11930,17677,17715,17453,17865,17735,17874,23620,23793,23630,24265,24420,24333,23526,23793,23620,23793,24114,23740,28152,28165,28048,31237,31159,31165,31091,31070,30869,31178,31070,31091,13735,14259,13617,13596,13718,13819,13284,13718,13596,25282,25116,24976,24846,24740,24596,30450,30404,30257,11787,11893,11831,27083,26820,26999,25680,25458,25571,26118,26220,26046,26263,26326,26543,27366,27073,27611,27073,27575,27611,28165,28355,28235,29243,29290,29254,29412,29290,29243,12700,12622,12704,12628,12622,12700,25852,25886,26097,23352,23461,23445,23248,23117,23080,24251,24420,24265,24571,24684,24786,30527,30247,30391,10423,10497,10482,30404,30527,30391,19897,20086,20188,19674,19687,19579,19579,19696,19247,27575,27931,27868,12979,13069,13152,12702,12735,12580,27865,27611,27868,10189,10297,10393,10376,10205,10515,10460,10506,10667,19850,19748,19817,17865,17715,17735,31345,31301,31230,12402,12281,12170,13617,14259,13958,14605,14875,14807,27239,27083,27176,11249,10995,11142,10979,10918,11087,10382,10423,10482,10903,10995,10893,17247,17485,17259,16902,16932,17137,16999,16932,16902,24713,24740,24793,24849,24684,24571,30729,30590,30263,30785,30590,30729,30918,30832,30878,30918,30878,31020,15493,15172,15383,15252,15493,15427,10464,10296,10751,10382,10482,10565,11721,11687,12223,12184,12575,12576,12974,13526,13758,12196,12184,12576,17735,17715,17677,17865,17874,18024,28340,28040,28396,27291,27239,27176,30947,30791,31014,31326,30966,31032,31086,30947,31116,31306,31310,31047,31227,31237,31165,31227,31190,31200,31078,31229,31190,19748,19687,19674,24420,24423,24571,24114,24188,24265,24309,24188,24141,24251,24188,24309,30741,30781,30665,31078,31294,31229,30931,30781,30741,31301,31296,31102,11700,11787,11831,11879,11939,11930,12235,12402,12170,11615,11787,11700,11362,11700,11541,26220,26326,26263,25780,25930,25454,31020,30947,31086,11337,11278,11459,11085,11301,10689,30292,30450,30257,30404,30548,30527,30739,30766,30484,30302,29839,29463,30302,29463,29881,12912,12823,12997,10903,10918,10979,12380,12702,12580,11939,12170,12036,14807,14875,15082,13614,13645,13735,24793,24740,24846,25282,25198,25116,25450,25198,25282,30411,30450,30292,30575,30448,30527,31050,30810,30904,31306,31047,31232,23080,22749,22955,23461,23526,23620,12823,12741,12700,12340,12580,12500,30297,29352,30524,29064,28993,28920,25605,25458,25680,26097,25886,26004,26203,26004,26206,31306,31232,31413,26567,26789,26820,26243,26326,26220,10503,10675,10909,10506,10909,10667,20103,20716,20693,30548,30575,30527,18024,18957,18967,16924,16833,17047,30947,31020,30878,30918,30887,30686,31139,31002,31070,30989,30904,30814,30909,30679,30781,30909,30781,30931,31358,31456,31291,31317,31459,31345,31345,31705,31301,31301,31740,31296,31670,31457,31059,24188,24251,24265,24423,24251,24309,31327,31232,31237,31078,31071,31294,10030,10296,10464,12741,12628,12700,29171,28993,29064,31327,31237,31227,31310,31433,31022,12966,12974,13758,12912,12858,12823,12823,12760,12741,12741,12601,12628,13735,13645,13637,13530,13645,13532,28152,28297,28165,28430,28520,28355,28355,28520,28427,27918,28050,27844,27918,27844,27850,27918,27850,27962,27918,27962,28002,31595,31456,31721,27850,27735,27962,31108,31178,31091,31254,31178,31108,10128,10225,10389,10096,10389,10231,10231,10326,9962,31456,31418,31317,13069,13107,13170,12297,13107,13069,28358,28355,28165,29529,29412,29243,10698,10619,11087,10995,10903,10979,10893,10995,11249,24740,24630,24527,24713,24630,24740,30671,30739,30484,10225,10226,10389,11879,11930,11893,12402,12340,12500,11879,11893,11746,20716,21169,20846,21385,21690,21492,26629,26567,26820,26340,26203,26206,26629,27144,26773,31418,31459,31317,31296,31326,30786,31472,31326,31602,25410,25653,25454,26118,26243,26220,25049,25057,24813,25049,24786,24684,30299,30411,30292,30731,30548,30404,30575,30671,30484,29881,29462,29609,27259,27239,27291,12966,13758,13138,28520,28615,28427,30402,30411,30299,31430,31327,31227,31172,30953,31021,11278,11377,11459,11394,11377,11085,11721,12223,12200,12461,12576,12622,13532,13645,13614,14884,14807,15082,29290,29412,29322,29529,29243,29192,26332,26203,26340,30973,30887,30918,30973,30918,31020,30797,30741,30766,31392,31172,31021,10698,11087,10918,10423,10308,10464,10362,10436,10589,23080,23117,22749,24188,24114,24141,31178,31139,31070,31209,31139,31178,31050,30904,30944,24251,24423,24420,23227,23461,23248,19850,19759,19748,19748,19759,19687,17880,18024,18007,19836,19897,19901,22337,21808,22154,30477,30404,30450,30739,30797,30766,17865,17845,17715,19696,19579,19687,29537,29171,29064,12876,12858,12912,12628,12461,12622,28615,28726,28598,31381,31220,30966,12235,12340,12402,11746,11893,11787,15010,14884,15082,15427,15493,15649,15427,15649,15379,16833,17062,17047,15010,15082,15172,14523,14391,14384,29412,29500,29322,29529,29500,29412,12858,12760,12823,24286,24189,24169,25042,24903,25116,25042,25116,25198,25042,25198,25138,28726,28902,28677,30774,30671,30575,10297,10189,10376,10132,10189,10393,11842,12200,12172,11584,11615,11362,19897,19759,19850,21361,21690,21385,26203,26097,26004,26293,26097,26203,26332,26340,26548,29859,29881,29609,31086,30973,31020,30909,30989,30814,31033,30989,30909,24533,24527,24630,22337,22371,23205,31220,31295,31108,31116,30947,31014,31349,31295,31220,31172,31294,31071,31430,31227,31200,31430,31294,31707,23797,22625,23654,30302,30402,30299,30411,30477,30450,30548,30774,30575,30606,30402,30302,31393,31327,31430,31401,31433,31310,10460,10667,10213,11085,11377,11278,12760,12601,12741,12184,11842,12172,18024,17961,17865,17880,17961,18024,30989,31050,30944,11377,11394,11541,10717,11016,10675,25399,25653,25410,25780,25653,25598,10903,10824,10918,10784,10824,10903,24653,24533,24630,30913,30785,30729,30590,30742,30263,30913,30686,30887,30857,30797,30739,30857,30739,30671,15252,15010,15172,14557,14391,14523,26629,26820,27144,13532,13426,13530,12974,12876,12912,12858,12737,12760,12760,12570,12601,14553,14391,14557,14605,14553,14557,28396,28040,28527,27379,27259,27495,28396,28527,28860,28520,28572,28615,28615,28744,28726,28726,29046,28902,28264,28297,28152,28094,28152,28050,28002,28050,27918,12380,12340,12235,12702,12407,13069,11618,11746,11787,11618,11787,11615,26548,26340,26567,14605,14807,14734,26099,25852,26097,25680,25744,25605,24653,24449,24533,24849,25049,24684,27962,27735,27865,28860,28527,29091,28297,28358,28165,31401,31310,31306,12479,12461,12601,12601,12461,12628,14734,14807,14884,23080,23227,23248,24423,24849,24571,23151,23227,23080,26773,26610,26629,27259,27291,27495,27865,27735,27611,27575,27868,27611,28358,28430,28355,31295,31254,31108,31349,31254,31295,13138,13758,13530,26428,26543,26326,10189,10205,10376,31413,31401,31306,10761,10893,10777,16924,17453,16936,15252,15071,15010,24189,23948,24116,24331,23948,24189,24533,24286,24169,25042,24793,24846,24369,24849,24423,30731,30774,30548,10506,10503,10909,10460,10503,10506,10824,10698,10918,10372,10382,10436,10594,10698,10824,10327,10717,10675,17961,17845,17865,17880,17845,17961,24449,24286,24533,24141,24114,23984,30958,30887,31090,30958,30913,30887,30797,30931,30741,31605,31392,31050,30965,30931,30797,12966,12876,12974,13718,13888,13893,15444,16043,16084,13284,13888,13718,12170,11492,12235,13107,13284,13596,26629,26548,26567,26293,26099,26097,26610,26548,26629,29500,29642,29483,29881,30393,30302,29784,29642,29750,10092,10096,9960,10225,10150,10226,10226,10151,10393,10189,10161,10205,18956,19476,19444,20103,20579,20716,18904,19476,18956,10096,10128,10389,28572,28744,28615,29192,28966,28923,10436,10382,10565,9962,10326,9916,10372,10436,10362,31254,31209,31178,31341,31209,31254,10893,10784,10903,11584,11618,11615,12170,11939,11492,15379,15649,15893,15010,15071,14884,26254,26243,26118,29784,29859,29609,30774,30857,30671,11687,11247,11937,10893,10761,10784,30402,30477,30411,31216,31107,30857,30606,30477,30402,31459,31471,31345,31341,31261,31209,31418,31505,31459,31456,31505,31418,31595,31505,31456,31456,31358,31721,31528,31022,31433,10128,10150,10225,12684,12737,12858,25653,25780,25454,25598,25653,25399,25274,25057,25049,31393,31413,31232,31510,31528,31433,31393,31232,31327,31505,31471,31459,31116,31014,31256,10150,10151,10226,10382,10308,10423,10362,10589,10374,12737,12570,12760,12461,12350,12576,11195,11138,11247,21169,21361,21385,23494,23526,23227,20579,21361,21169,20579,21169,20716,24309,24369,24423,25039,25274,25049,24141,24369,24309,26243,26428,26326,26322,26428,26243,31209,31261,31139,31349,31220,31381,16999,17259,17130,31256,31002,31139,31381,30966,31472,26293,26203,26332,24653,24713,24704,12570,12479,12601,15293,15379,15374,16936,17453,17416,10151,10132,10393,10220,10688,10404,19897,19836,19759,19759,19696,19687,21147,21197,21350,13426,13202,13530,12966,12840,12876,12876,12684,12858,12737,12541,12570,12570,12377,12479,13317,13202,13426,13317,13426,13532,13552,13532,13614,13617,13552,13614,28340,28144,27926,28596,28144,28340,27911,28144,28031,28002,28094,28050,28297,28399,28358,28358,28535,28430,28430,28572,28520,27973,28094,28002,27973,28002,27962,27973,27962,28028,28421,28399,28297,31430,31200,31229,31510,31433,31401,31430,31229,31294,13202,13138,13530,28028,27962,27865,10372,10308,10382,10374,10904,10619,10604,10619,10698,15444,15437,15132,16223,16043,16318,16932,16999,17130,25605,25744,26054,24331,24189,24286,23948,23853,23654,23924,23853,23948,24630,24713,24653,10594,10604,10698,10594,10824,10784,13138,13054,12966,15123,15071,15252,13958,14259,14384,15123,15252,15427,24791,25049,24849,23984,24114,23793,26548,26447,26332,26820,27083,27144,27083,27239,27310,28535,28572,28430,29192,28923,28902,31090,30887,30973,31041,31000,30785,31000,30742,30590,31090,30973,31110,30965,31033,30931,30931,31033,30909,31486,31294,31172,30965,30797,31107,31510,31401,31544,12377,12350,12479,12479,12350,12461,12340,12380,12580,11939,11879,11564,14935,14734,14884,29046,28726,28744,29642,29784,29609,10220,10404,9958,10503,10327,10675,23227,23526,23461,22039,22012,22749,27240,26625,26543,24713,24793,24704,10132,10161,10189,30477,30731,30404,31077,30731,30477,10161,10147,10205,26099,26068,25852,26265,26068,26099,31544,31401,31413,11564,11879,11746,12840,12684,12876,10870,10893,11249,15071,14935,14884,15187,15123,15427,29750,29642,29500,30269,30393,29881,23845,23984,23793,24791,24849,24369,24417,24331,24286,24417,24286,24449,31318,31050,30989,31107,30797,30857,17845,17880,17715,18155,18024,18967,11618,11561,11746,11362,11615,11700,11362,11541,11394,12684,12541,12737,16728,16863,16833,29041,29046,28744,29529,29750,29500,10689,11361,11045,10689,11045,10717,14734,14553,14605,14606,14553,14734,25458,25450,25282,25389,25450,25506,31392,31021,31050,31535,31544,31413,10327,10689,10717,25138,24793,25042,24148,24369,24141,26254,26322,26243,31535,31413,31393,10128,10092,10150,10150,10043,10151,10151,10043,10132,10132,10056,10161,10161,10038,10147,10096,10092,10128,10326,10260,9916,10314,10308,10372,10314,10372,10362,22749,22012,22705,24130,24078,23984,31349,31341,31254,31261,31256,31139,31244,31110,31086,31411,31341,31349,31351,31256,31261,31721,31358,31457,31505,31586,31471,31471,31705,31345,31628,31059,31528,31628,31528,31607,25304,25138,25198,31000,30590,30785,29717,29339,29171,30785,30913,31143,11721,11842,11795,11963,11842,12184,10652,10744,10761,21147,21350,21348,22337,22154,22371,26671,26447,26548,27310,27239,27259,31595,31586,31505,11174,11362,11394,26671,26548,26610,25605,25450,25458,28094,28264,28152,28399,28535,28358,29110,29041,28744,28203,28264,28094,28203,28094,28122,31607,31528,31588,31707,31535,31393,20301,20188,20646,19836,19696,19759,28122,28094,27973,28264,28421,28297,31586,31608,31471,10604,10488,10619,10476,10488,10420,23984,24078,24141,23845,23793,23526,31110,30973,31086,31472,30966,31326,16924,16728,16833,16854,16728,16924,12380,12399,12702,12235,12399,12380,12407,12399,12218,14273,14318,14391,20074,19995,19897,27635,27291,27526,24331,23924,23948,24539,24417,24449,24539,24449,24653,28439,28535,28399,10255,10314,10362,9886,10260,10296,22955,23088,23080,23007,23088,22955,9993,10043,10150,31528,31510,31588,23151,23494,23227,12684,12604,12541,12196,12576,12350,13054,12840,12966,12835,12840,13054,13058,13054,13138,13058,13138,13202,13317,13532,13552,19995,19901,19897,31381,31411,31349,31341,31351,31261,31550,31411,31381,31588,31510,31576,10761,10744,10784,11005,11450,11247,17416,17453,17715,16491,16738,16601,25123,24704,24793,11842,11721,12200,12377,12570,12541,30225,30269,29859,29981,29750,29966,27379,27310,27259,11002,11005,11247,10043,10056,10132,10147,10025,10205,11195,11247,11687,11584,11561,11618,11497,11561,11584,26447,26293,26332,26484,26293,26447,26265,26293,26469,26254,26118,25780,26428,26674,26543,28416,28264,28203,10488,10397,10619,10476,10397,10488,23853,23924,23654,24129,23924,24331,24539,24331,24417,25740,25598,25610,23831,23845,23526,10030,10464,10308,10230,10255,10362,11005,10870,11249,24006,24130,23845,23088,23151,23080,23098,23151,23088,31451,31351,31525,31244,31086,31116,31576,31510,31544,12637,12604,12684,22705,22323,22658,27699,27635,27526,27379,27353,27310,29110,28744,28572,29046,29192,28902,10346,10374,10619,10621,10594,10784,10621,10784,10744,12205,12196,12350,22423,22337,23205,10056,10038,10161,19768,19696,19836,26322,26515,26428,16936,16854,16924,15293,15187,15379,16820,16854,16936,31351,31334,31256,31451,31334,31351,10038,10025,10147,31909,31576,31544,31588,31576,31735,11553,11426,11687,11553,11687,11721,26293,26265,26099,25450,25304,25198,25123,24772,24704,26671,26610,26773,26522,26674,26515,25878,26254,25780,27310,27144,27083,27329,27144,27310,31602,31326,31296,31451,31322,31334,31244,31116,31303,31144,30913,30958,12604,12377,12541,11809,11795,11842,27635,27495,27291,29085,29192,29046,10397,10346,10619,10200,10230,10362,10392,10346,10397,13391,13317,13552,12840,12637,12684,12604,12313,12377,31303,31116,31256,25744,25852,26054,26054,25852,26068,25274,25598,25399,24148,24141,24078,29110,29085,29041,29041,29085,29046,28421,28439,28399,28416,28439,28421,28416,28421,28264,28122,27973,28028,13046,13058,13202,28028,27865,27868,10420,10488,10604,10652,10621,10744,11963,12184,12196,15123,14935,15071,14553,14273,14391,13958,14384,14391,14966,14935,15123,15187,15427,15379,13958,14391,14318,27931,28028,27868,11639,11553,11721,15379,15893,15374,10164,10308,10314,10092,10018,10150,10043,10001,10056,10056,9908,10038,10038,9908,10025,9962,9960,10096,9958,10404,9851,10316,10327,10503,10870,10777,10893,10712,10777,10696,10777,10870,10696,11002,11247,11138,11195,11687,11235,12059,11963,12196,14320,14273,14553,18076,18155,18223,17880,17416,17715,27495,27353,27379,29171,29339,28993,28144,27911,27526,29791,29171,29537,31334,31322,31256,31483,31341,31411,31595,31724,31586,31586,31728,31608,31608,31681,31471,31799,31721,31966,31670,31059,31628,31670,31628,31683,31628,31607,31683,9960,10018,10092,28596,28340,28396,27635,27547,27495,27495,27427,27353,27575,27073,27351,31721,31667,31595,31667,31724,31595,20774,20301,20646,19943,19901,19995,19943,19821,19901,19901,19821,19836,21348,21350,21778,31724,31728,31586,31683,31607,31807,10420,10604,10459,23845,24130,23984,24148,24130,24051,23845,23860,24006,29091,28527,28993,10346,10236,10374,10321,10392,10397,31472,31550,31381,31615,31550,31472,27352,27329,27353,27353,27329,27310,26675,26671,26909,9941,9993,10150,10153,10213,9709,11553,11456,11426,11795,11639,11721,11661,11639,11795,12526,12637,12840,12205,12059,12196,13946,13958,14318,26671,26773,26909,25573,25506,25605,26515,26674,26428,26522,26515,26322,26522,26322,26391,27911,27699,27526,31728,31681,31608,10220,10213,10667,10404,10205,9851,18155,18007,18024,18076,18007,18155,31322,31303,31256,31235,31090,31110,31504,31303,31322,31895,31602,31296,31681,31705,31471,31727,31607,31588,11359,11456,11313,24704,24772,24653,25123,24793,25138,25389,25304,25450,25605,25506,25450,26054,26068,26092,29161,29091,28993,29966,29750,29529,29110,28572,28535,22749,22839,22955,22705,22012,22323,25532,25304,25389,31550,31483,31411,31615,31483,31550,9993,10001,10043,12205,12350,12377,11963,11809,11842,11235,11687,11426,11316,11497,11584,12218,12399,12235,11085,11174,11394,11148,11174,10942,11174,11085,10801,30269,29881,29859,31216,30857,31266,29859,29784,30189,10325,10321,10397,10557,10604,10594,10557,10594,10621,17692,17416,17880,24130,24148,24078,23526,23494,23831,10265,10236,10346,10325,10397,10476,20018,19995,20074,18609,18155,18967,31705,31740,31301,12399,12407,12702,11564,11746,11561,27351,27073,26625,29339,29161,28993,29446,29161,29339,11836,11809,11963,11639,11552,11553,26092,26068,26265,30447,30269,30225,10347,10557,10621,10712,10761,10777,11497,11564,11561,24772,24539,24653,23205,22371,22625,24129,24539,25286,26682,26522,26708,26674,26730,26543,10265,10346,10392,10255,10230,10314,18007,17996,17880,18076,17996,18007,19821,19768,19836,31735,31727,31588,31735,31576,31909,31544,31535,31909,22705,22807,22749,13317,13250,13202,13058,12906,13054,13391,13250,13317,13391,13552,13334,28203,28122,28230,28302,28203,28230,28302,28416,28203,28439,28582,28535,28122,28028,28230,13250,13103,13202,13183,13391,13334,28230,28028,27990,13103,13046,13202,12313,12205,12377,27990,28028,27931,28416,28582,28439,12180,12218,12107,26659,26675,26721,27547,27427,27495,13046,12906,13058,31707,31393,31430,16854,16820,16728,16970,16820,16936,24783,24791,24369,25598,25878,25780,31144,31090,31235,31144,30958,31090,30742,30805,29769,12906,12835,13054,27911,27836,27699,27720,27547,27635,28432,28031,28144,27836,28031,28134,28396,28641,28596,27717,27990,27931,10200,10362,10374,31525,31351,31341,31235,31110,31300,10321,10265,10392,10236,10200,10374,10420,10325,10476,10315,10325,10420,24148,24783,24369,23831,23494,23626,22807,22839,22749,9944,10030,10308,10557,10459,10604,10367,10459,10557,10965,11002,11138,10965,11138,10980,11235,11426,11251,11809,11661,11795,11652,11661,11809,11836,11963,11853,25940,25573,25605,25506,25532,25389,25294,25123,25138,26682,26730,26674,26682,26674,26522,30393,30606,30302,31318,30989,31033,30580,30606,30393,31143,31144,31273,12313,12604,12228,11853,11963,12059,14740,14606,14734,13943,13946,14318,13605,13517,13617,14740,14734,14935,14740,14935,14839,12180,12249,12218,11148,11584,11362,31051,30805,30742,28031,27836,27911,26073,25878,25740,10843,10870,11005,25294,25138,25304,31656,31525,31341,31871,31615,31472,31871,31472,31602,10179,10200,10236,10230,10164,10314,9962,9902,9960,9960,9902,10018,10018,9941,10150,9993,9867,10001,9886,9916,10260,14198,14318,14273,22839,23007,22955,19841,20579,20103,22323,22012,21690,22705,22658,22807,22807,22763,22839,22839,22763,23007,19841,20103,19476,11359,11426,11456,26054,25940,25605,26469,26092,26265,26675,26447,26671,9916,9902,9962,31724,31870,31728,31728,31853,31681,31681,31812,31705,31705,31806,31740,31740,31895,31296,31667,31870,31724,31721,31799,31667,31966,31721,31457,31941,31457,31670,31837,31670,31683,31837,31683,31811,10712,10652,10761,27352,27144,27329,27352,27353,27427,26730,27240,26543,26708,26522,26632,10316,10503,10460,11836,11775,11809,11313,11456,11553,11781,11775,11836,14839,14935,14966,14606,14468,14553,20774,20910,21147,19821,19926,19768,24006,24051,24130,24122,24051,24006,30297,29537,29352,31799,31870,31667,10280,10265,10321,10280,10321,10325,10280,10325,10315,10153,10316,10460,10153,10460,10213,23380,23494,23151,29085,29175,29192,29110,29175,29085,31144,31143,30913,31000,31051,30742,31110,31244,31300,31870,31853,31728,31811,31683,31807,9854,9941,10018,10001,9908,10056,11552,11639,11661,15374,15280,15109,14576,14468,14606,13888,14438,14686,16043,15997,16601,14174,14438,13888,27249,27240,26730,28613,28324,27990,23007,23098,23088,23173,23098,23043,11002,10927,11005,10712,10596,10652,10885,10927,11002,11138,11195,11105,20301,20018,20074,18609,18967,19335,25573,25532,25506,25453,25532,25573,31853,31812,31681,11105,11195,11038,10200,10164,10230,10224,10179,10236,16820,16792,16728,17416,16970,16936,17003,16970,17416,19247,19696,19335,17996,17692,17880,24791,25039,25049,24700,24783,24148,31143,31041,30785,31267,31033,30965,10927,10843,11005,12526,12604,12637,11824,11853,12059,12407,12297,13069,12218,12249,12407,11465,11939,11564,25532,25294,25304,27720,27635,27699,11143,11195,11235,13391,13183,13250,13250,13032,13103,13103,12907,13046,13046,12907,12906,12906,12859,12835,12625,12526,12840,13334,13552,13451,28416,28714,28582,28582,29110,28535,28302,28401,28416,28278,28401,28302,28278,28302,28230,28278,28230,28324,30471,30504,30393,30857,30774,31266,30447,30393,30269,20018,19943,19995,31812,31806,31705,31807,31607,31802,31607,31727,31802,13451,13552,13617,28324,28230,27990,10843,10696,10870,10315,10420,10240,13032,12907,13103,13517,13451,13617,13617,13958,13605,14740,14576,14606,14966,15123,15187,11497,11485,11564,11316,11485,11497,11148,11362,11174,26675,26484,26447,26092,26133,26054,26659,26484,26675,31802,31727,31735,11202,11143,11235,10801,11085,10385,29981,29784,29750,13605,13958,13707,31252,31045,31041,31300,31244,31397,31244,31303,31436,10194,10224,10236,10420,10459,10240,11181,11251,11129,11359,11251,11426,12079,12059,12205,17750,17692,17996,24051,24122,24148,23831,23860,23845,23841,23860,23831,31436,31303,31504,14320,14198,14273,14320,14553,14468,9867,9908,10001,13707,13958,13846,19692,19841,19476,18662,18541,18005,23098,23142,23151,23173,23142,23098,31656,31341,31483,31504,31525,31656,31806,31782,31740,31925,31802,31909,30774,30731,31266,10145,10164,10200,10194,10236,10265,11552,11661,11555,14599,15444,15132,18076,17919,17996,18131,17919,18076,31504,31322,31451,13846,13958,13946,12313,12079,12205,11996,12079,12313,13943,13846,13946,14235,14320,14332,27485,27352,27427,27240,27351,26625,27411,27351,27240,11652,11809,11775,11652,11775,11781,14839,14825,14740,15293,14966,15187,16970,16802,16820,15293,15374,14966,17003,16802,16970,29966,29529,30014,31041,31045,31000,30524,29352,29769,31252,31041,31143,12625,12840,12835,13707,13846,13684,27836,27817,27699,27547,27536,27427,27982,27817,27836,28396,28860,28641,29428,29110,29425,30014,29529,29883,10927,10810,10843,10626,10596,10696,10965,10885,11002,10950,10885,10965,10980,11138,11105,10980,11105,10982,15444,15997,16043,16999,17247,17259,12180,12297,12249,11148,11316,11584,26484,26469,26293,26509,26469,26484,30158,30189,29784,10145,10200,10179,11038,11195,11143,30504,30580,30393,30568,30580,30504,30471,30393,30447,10146,10194,10265,10224,10145,10179,10367,10557,10347,10596,10712,10696,31235,31273,31144,31454,31273,31235,31454,31235,31300,31107,31267,30965,31318,31267,31342,19335,19696,19768,27817,27720,27699,11202,11235,11251,11109,11038,11143,30568,30471,30447,10146,10265,10280,12079,11987,12059,12008,11987,12079,23496,23626,23494,23860,24122,24006,31436,31397,31244,31491,31397,31436,10687,10696,10843,11181,11202,11251,26373,26133,26092,25532,25453,25294,12526,12228,12604,12249,12297,12407,11465,11564,11485,27720,27649,27547,27128,26773,27144,11781,11836,11853,11552,11313,11553,11350,11465,11485,27311,27144,27352,26469,26373,26092,31877,31707,31294,31486,31172,31392,31525,31504,31451,31656,31483,32040,31605,31486,31392,16802,16792,16820,16821,16792,16802,17003,17416,17415,31045,31051,31000,31141,31051,31045,10030,9904,10296,9733,9904,10030,11987,11824,12059,12008,11824,11987,13183,13032,13250,12907,12859,12906,12023,12085,12228,13334,13234,13183,13451,13234,13334,13467,13234,13451,13467,13451,13517,13467,13517,13605,13467,13605,13679,21135,20774,21147,20301,20164,20018,20018,20037,19943,21348,20774,21135,26953,27249,26730,27351,27433,27575,26838,26730,26682,28641,28957,28809,27817,27971,27720,27720,27971,27649,28860,29275,29213,9902,9854,10018,9941,9867,9993,9916,9848,9902,9759,9848,9916,31870,31954,31853,31853,31919,31812,31812,31919,31806,31806,31914,31782,31799,31954,31870,32043,31913,31799,31941,31670,31837,31941,31837,31943,31837,31811,31943,15374,15893,15280,14966,14825,14839,23841,24122,23860,29378,29091,29161,30524,29769,30603,29456,29446,29339,30189,30225,29859,30158,30225,30189,9848,9854,9902,12107,12218,12235,27649,27536,27547,27589,27536,27590,29717,29171,29791,31913,31954,31799,10469,10621,10652,10070,10145,10054,16624,17247,16999,12913,12859,12907,13679,13605,13707,13679,13707,13684,17919,17750,17996,17767,17750,17919,31943,31811,31929,31811,31925,31929,20299,20164,20301,19943,19926,19821,10885,10810,10927,10596,10490,10652,10757,10810,10885,10950,10965,10980,10950,10980,10818,10982,11105,11038,12859,12669,12835,25601,25453,25573,25294,25295,25123,25123,25270,24772,9854,9827,9941,9891,10213,10220,10741,10687,10843,11652,11555,11661,11109,10982,11038,10868,11555,11652,14703,14825,14966,13684,13846,13690,20164,20115,20018,25453,25295,25294,23797,23654,23924,26708,26838,26682,26322,26254,26391,24700,24791,24783,31811,31807,31925,17607,17416,17692,24342,24700,24148,12669,12625,12835,11641,11781,11824,14318,14198,13943,10069,10145,10224,10164,10026,10308,10197,10280,10315,27536,27485,27427,27358,27485,27469,27411,27433,27351,27411,27240,27300,11555,11313,11552,26659,26509,26484,26133,25940,26054,26533,26509,26721,29981,30158,29784,30242,30158,29981,9827,9867,9941,12008,12079,11996,11824,11781,11853,14632,14576,14740,31925,31807,31802,13943,14198,13933,32146,31919,31853,31782,31876,31740,22323,21975,22235,23827,23841,23626,23626,23841,23831,31267,31318,31033,31342,31267,31107,17750,17701,17692,17767,17701,17750,17247,17665,17485,19987,19926,19943,23380,23151,23142,24122,24342,24148,31919,31914,31806,31909,31802,31735,11129,11251,11359,24700,25039,24791,24961,25039,24700,11996,12313,12085,27300,27240,27249,18609,18361,18155,18263,18361,18328,23043,23098,23007,9904,9886,10296,9500,9886,9904,27387,27300,27249,26391,26254,25878,10205,10025,9851,10316,10037,10327,10385,11085,10689,17836,18662,18005,22658,22763,22807,23164,22763,22658,14235,14198,14320,17003,16821,16802,15109,14990,15374,16915,16821,17003,31914,31876,31782,10810,10741,10843,10687,10626,10696,10950,10757,10885,10818,10757,10950,32002,31871,31602,10757,10741,10810,27358,27311,27352,27358,27352,27485,26953,26730,26838,30526,29717,29791,29446,29378,29161,11109,11143,11202,19559,19692,19476,20088,20270,20579,22323,21690,21975,26112,25940,26133,25453,25504,25295,26373,26469,26533,31266,30731,31355,30471,30568,30504,30499,30568,30447,30350,30447,30225,31876,31895,31740,10622,10626,10687,10070,10026,10164,10070,10164,10145,10240,10459,10367,10256,10240,10367,12180,12159,12297,12297,12031,13107,12107,12159,12180,18361,18223,18155,18263,18223,18361,23173,23278,23142,23043,23278,23173,13234,13032,13183,12681,12629,12669,12669,12629,12625,12625,12440,12526,12913,13032,13155,13032,13234,13155,13155,13467,13322,13518,13679,13684,26800,26953,26838,26800,26838,26708,11181,11109,11202,11070,11109,11181,11129,11359,11178,11359,11313,11178,11129,11043,11070,30297,30239,29537,30603,29769,30805,10153,10152,10316,10037,10152,9523,11492,12107,12235,11316,11350,11485,11225,11350,11316,11225,11316,11113,21778,21350,21808,24129,24331,24539,23841,24127,24122,23496,23678,23626,27717,27575,27433,27717,27931,27575,28278,28607,28401,28401,28607,28416,27443,27433,27411,31273,31252,31143,31051,31141,30805,31373,31252,31273,31491,31300,31397,31491,31436,31563,30881,30606,30580,31563,31436,31504,31883,31909,31535,31883,31535,31707,10575,10490,10596,11492,11939,11465,29717,29456,29339,12681,12669,12859,28199,28134,28031,28432,28144,28596,28563,28596,28689,10868,10880,11043,26533,26469,26509,30158,30350,30225,30242,30350,30158,30499,30350,30529,9926,9944,10308,10069,10224,10194,10421,10469,10652,16821,16778,16792,16915,16778,16821,17607,17692,17701,18223,18131,18076,18263,18131,18223,23278,23380,23142,23424,23380,23278,31252,31141,31045,18662,18904,18956,19333,18904,18168,28134,27982,27836,10240,10197,10315,10221,10197,10240,23962,24127,23841,23827,23626,23678,31941,31966,31457,31913,31970,31954,31954,31970,31853,31919,32010,31914,31914,32010,31876,31876,32102,31895,32045,31966,31941,32045,31941,31975,31941,31943,31975,31943,31987,31975,10347,10256,10367,12008,11813,11824,12085,12313,12228,14332,14320,14468,13943,13690,13846,14332,14468,14405,14468,14576,14405,24127,24342,24122,27387,27443,27411,27387,27411,27300,31318,31605,31050,31877,31883,31707,31304,31342,31107,31304,31107,31216,31966,32043,31799,10757,10622,10741,10492,10575,10626,10626,10575,10596,10490,10421,10652,10982,10818,10980,10539,10818,10982,10873,10982,11109,10192,10689,10327,25295,25270,25123,25601,25504,25453,25391,25504,25601,10197,10146,10280,18131,17767,17919,23653,23827,23678,27311,27128,27144,27293,27128,27311,32043,31970,31913,31943,31929,31987,13845,13690,13943,30568,30719,30580,30705,30719,30568,26373,26196,26133,26721,26509,26659,9851,10025,9604,9827,9761,9867,9867,9757,9908,9854,9773,9827,9662,9773,9854,9730,9854,9848,31987,31929,32089,19338,19335,19768,25740,25878,25598,25598,25274,25610,30740,30603,31132,30483,30239,30297,29275,29378,29402,10622,10687,10741,10469,10347,10621,15997,16491,16601,17247,17058,17665,16624,16491,16593,22763,23043,23007,23380,23496,23494,23308,23043,23164,32040,31483,31615,31947,31615,31871,32148,31987,32089,10069,10054,10145,9926,10308,9889,23585,23496,23424,31532,31454,31300,31252,31299,31141,31656,31563,31504,14055,13933,14198,14405,14576,14507,14740,14825,14703,27589,27485,27536,9773,9761,9827,20115,20037,20018,19926,19869,19768,20164,20037,20115,20299,20037,20164,20299,20301,20774,11129,11070,11181,11178,10868,11043,26410,26196,26373,30350,30499,30447,29192,29175,29428,9604,10025,9908,14438,14599,15132,16593,16491,16176,14174,14599,14438,20037,19987,19943,21778,21808,22337,26909,26721,26675,26345,26112,26196,26909,26773,27128,29428,29175,29110,31532,31300,31491,10400,10421,10490,14055,14198,14074,29456,29378,29446,29378,29515,29402,29435,29110,29276,31386,31304,31453,31581,31605,31318,19987,19869,19926,11313,10868,11178,14703,14966,14990,14074,14198,14235,26089,26391,25878,27393,27387,27249,28689,28596,28809,28134,28114,27982,27703,27536,27649,28324,28607,28278,28638,28607,28704,13032,12913,12907,12212,12228,12526,13155,13234,13467,13467,13679,13322,13322,13679,13518,28563,28432,28596,28607,28714,28416,23496,23544,23678,23827,23962,23841,24127,24193,24342,23585,23544,23496,12440,12625,12629,10868,11652,10999,14074,14235,14200,13518,13684,13690,32002,31947,31871,32105,32010,31919,10294,10347,10469,10256,10221,10240,10048,10069,10146,9963,10070,10054,25819,25740,25610,26073,26089,25878,12913,12681,12859,13518,13690,13442,10022,10026,10070,9958,9891,10220,9709,9891,9958,10575,10400,10490,10294,10251,10347,10539,10622,10757,10539,10757,10818,10400,10218,10361,25504,25391,25295,25601,25573,25940,10801,10942,11174,11350,11492,11465,10502,10942,10292,30978,30477,30606,30809,30705,30568,30840,30705,30926,28432,28199,28031,14632,14703,14659,26570,26373,26533,27072,26909,27128,27072,27128,27222,29966,30090,29981,30332,30090,30195,10622,10492,10626,11113,11316,10953,26391,26632,26522,26894,27023,27101,30483,30297,30524,30129,30242,29981,10044,10221,10256,9963,10022,10070,13845,13943,13933,13871,13845,13933,14200,14235,14332,14200,14332,14263,26196,26112,26133,26570,26533,26591,25819,26089,26073,27971,27817,27982,28199,28114,28134,14632,14507,14576,17767,17607,17701,17415,17607,17506,18151,17767,18131,23895,23962,23827,25610,25274,25039,31598,31532,31491,31373,31299,31252,31598,31491,31661,10069,10194,10146,18416,18361,18609,22301,21778,22337,9889,10308,10026,9944,9876,10030,10116,10146,10197,31512,31318,31342,32035,31602,31895,31701,31491,31563,31877,31294,31486,32148,31975,31987,30740,30483,30524,30740,30524,30603,30603,30805,31132,32102,32025,31895,13738,13845,13871,14263,14332,14405,27589,27469,27485,27590,27469,27589,28114,27971,27982,26909,26821,26721,26898,26821,26909,26632,26800,26708,27443,27717,27433,26894,26800,27023,30809,30568,30499,30090,30129,29981,30332,30129,30090,30840,30580,30719,31479,31512,31342,27390,27311,27358,10022,9889,10026,9982,9963,10054,18263,18151,18131,18198,18151,18263,26732,26533,26721,10221,10116,10197,10069,9982,10054,10091,10116,9860,10251,10256,10347,25270,24539,24772,22423,22301,22337,23962,24112,24127,24031,24112,23962,13933,14055,13871,29428,29466,29192,29429,29425,29110,30705,30840,30719,30529,30350,30242,32025,32035,31895,9886,9759,9916,9641,9757,9761,9761,9757,9867,9670,9759,9432,10047,10048,10146,24129,23797,23924,27455,27390,27469,27469,27390,27358,27029,27249,26953,31701,31563,31856,31373,31273,31454,31966,32119,32043,32043,32077,31970,31970,32146,31853,32010,32102,31876,32025,32091,32035,32045,32119,31966,32062,32119,32045,32062,32045,31975,32062,31975,32148,9759,9730,9848,32119,32077,32043,31373,31454,31641,32077,32146,31970,31929,31925,32089,12159,12086,12297,12107,12086,12159,12019,12086,12107,20181,20299,20228,20037,20050,19987,19987,19932,19869,19869,19338,19768,18587,18519,18609,20299,20774,20517,27971,27703,27649,29425,29466,29428,10492,10400,10575,10136,10400,10492,11015,11109,11070,32167,31877,31486,32089,31925,32432,11159,11492,11350,11176,11350,11225,14703,14632,14740,14507,14333,14405,13871,14055,14060,14556,14632,14659,19324,19338,19869,26894,27029,26953,26894,26953,26800,28432,28308,28199,28199,28251,28114,28114,28237,27971,27971,28023,27703,28563,28689,28432,28809,28596,28641,28607,28638,28714,29435,29429,29110,29425,29451,29466,28704,28607,28324,31925,31909,32432,13155,12852,12913,12769,12598,12681,12681,12598,12629,13322,13149,13155,13247,13149,13322,13247,13322,13303,26898,26909,27006,26842,26732,26821,26821,26732,26721,28957,28641,29213,30129,30288,30242,30332,30288,30129,9795,9876,9944,9947,9889,10022,9947,10022,9857,18519,18416,18609,12977,13247,13023,28860,29091,29275,29213,28641,28860,27390,27293,27311,27375,27293,27390,12491,12598,12465,28459,28308,28432,16491,16624,16999,17665,17836,18005,16491,15997,15675,20299,20050,20037,32148,32381,32221,27703,27590,27536,27939,27590,27703,31386,31342,31304,31605,31749,31486,11178,11043,11129,11822,12008,11996,11822,11996,12085,26551,26410,26570,26570,26410,26373,26057,25601,25940,30545,30529,30242,9795,9944,9926,10116,10047,10146,10048,9982,10069,10091,10047,10116,23805,23895,23827,24517,24700,24342,23653,23678,23544,28308,28251,28199,31562,31454,31532,31479,31386,31476,31453,31304,31216,9641,9761,9773,9851,9780,9958,12398,12440,12629,25391,25433,25295,26258,25940,26112,29275,29091,29378,30840,30881,30580,31019,30881,30990,30881,30978,30606,9857,10022,9963,9889,9816,9926,18416,18328,18361,17506,17607,17767,18209,18328,18416,27006,26909,27072,26732,26591,26533,27393,27498,27387,26800,26904,27023,9604,9780,9851,10294,10469,10421,11890,11822,12085,22317,22301,22423,20517,20774,20611,23424,23496,23380,23424,23278,23308,25465,25433,25391,31598,31562,31532,31856,31563,31656,31856,31656,32118,31709,31749,31605,32035,32002,31602,32091,32002,32035,14632,14489,14507,13845,13738,13690,27293,27222,27128,27288,27222,27293,26410,26345,26196,26836,26591,26732,32146,32105,31919,12440,12212,12526,29378,29696,29515,25433,25270,25295,21660,21348,21778,22451,22317,22423,21690,21361,21975,10047,9982,10048,10047,10091,9860,10152,10037,10316,9523,10152,10153,9709,10213,9891,14065,14074,14200,29378,29456,29696,29456,29792,29696,31733,31562,31598,14333,14263,14405,13378,14174,13888,15586,15997,15444,27590,27455,27469,27486,27455,27655,27387,27498,27443,27393,27249,27214,10400,10361,10421,10251,10044,10256,10539,10492,10622,11043,11015,11070,10873,11015,10880,18328,18198,18263,18209,18198,18328,26423,26345,26410,32105,32102,32010,9826,9982,10047,24193,24127,24112,23585,23653,23544,23627,23653,23585,26898,26842,26821,26371,26184,26345,26989,26842,26898,27006,27072,27222,31701,31661,31491,31856,31661,31701,31749,31852,31486,31581,31709,31605,31581,31318,31512,14632,14556,14489,14358,14333,14507,14659,14703,14990,12212,12023,12228,11822,11813,12008,12086,12051,12297,12019,12051,12086,14060,14055,14074,29835,29529,29192,29429,29451,29425,10361,10294,10421,10953,11316,11148,11236,12019,12107,10953,11148,10942,14358,14507,14489,14263,14065,14200,27455,27375,27390,27486,27375,27455,27214,27249,27029,27498,27717,27443,25740,25819,26073,26800,26632,26904,27101,27214,27029,24031,23962,23895,25433,25407,25270,25601,25465,25391,25407,25465,25890,28907,28797,28809,28809,28797,28689,28594,28459,28432,28282,28237,28251,28251,28237,28114,28907,28809,28957,29168,28957,29213,29168,29213,29337,31133,31077,31156,30978,31077,30477,31762,31581,31512,31019,30978,30881,11956,12019,11834,27715,27717,27498,28594,28432,28689,23976,24031,23895,31479,31342,31386,31453,31216,31266,9885,9816,9889,9571,9670,9432,9885,9889,9947,12031,12297,12051,12005,13284,13107,26423,26410,26551,27288,27006,27222,12598,12491,12629,12440,12335,12212,12212,12057,12023,12769,12681,12913,12852,13155,12880,13155,13149,12880,13149,12977,12880,13284,13378,13888,23653,23805,23827,23627,23805,23653,31661,31716,31598,31552,31377,31373,31824,31716,31661,10037,10192,10327,11113,11176,11225,26345,26184,26112,26570,26591,26551,30813,30526,30239,31132,30805,31141,31426,31141,31299,31377,31299,31373,31677,31454,31562,31476,31453,31460,32196,32091,32025,31815,31733,31716,9730,9681,9854,9552,9604,9908,9759,9670,9730,9733,10030,9713,32077,32162,32146,32146,32332,32105,32105,32187,32102,32102,32187,32025,32119,32178,32077,32184,32178,32119,32184,32119,32202,32119,32062,32202,32202,32062,32221,32062,32148,32221,9670,9682,9730,32221,32381,32258,9682,9681,9730,14333,14065,14263,14556,14358,14489,29835,29192,29466,30545,30540,30529,30529,30540,30499,32178,32162,32077,12491,12398,12629,28282,28251,28308,29337,29213,29275,29337,29275,29402,9681,9662,9854,32258,32381,32375,20088,20579,19841,20088,19841,19692,23308,23278,23043,31864,31852,31749,32258,32202,32221,31864,31749,31709,9795,9779,9876,9785,9885,9947,11065,11159,11176,10861,10953,10795,20299,20181,20050,20050,19932,19987,18447,18209,18416,22024,21778,22301,26836,26732,26842,29515,29337,29402,30545,30242,30472,20181,20108,20050,19559,20088,19692,19559,19476,18904,17607,17415,17416,14990,14966,15374,14556,14498,14358,17506,17767,17777,24031,24193,24112,24091,24193,24031,23916,23895,23805,11720,11813,11822,12017,12085,12023,14060,14065,14124,13149,13247,12977,29761,29835,29466,9614,9641,9773,24193,24517,24342,27006,26989,26898,27026,26989,27006,27288,27293,27375,28237,28023,27971,28898,28582,28714,29451,29684,29466,28898,28714,28638,30195,30090,29966,30195,29966,30014,23733,23916,23805,31716,31733,31598,31615,31947,32040,27393,27459,27498,27101,27029,26894,30990,30881,30840,31077,31112,30731,9795,9926,9766,25173,25610,25039,26632,26824,26904,20108,19932,20050,31133,31112,31077,12075,12057,12212,11956,12031,12051,11956,12051,12019,29456,29717,29792,30663,30809,30499,30663,30499,30540,32132,31947,32002,32312,31883,31877,31844,31864,31709,31844,31709,31581,31844,31581,31767,27655,27455,27590,27261,27459,27393,28803,28704,28656,29835,29883,29529,30016,29883,29835,10192,10385,10689,9713,10030,9876,9766,9926,9816,11015,10873,11109,10361,10218,10294,10758,10873,10880,26184,26258,26112,26423,26371,26345,26476,26371,26423,30661,30663,30540,12057,12017,12023,11813,11641,11824,11338,12107,11492,11292,11338,11492,11159,11350,11176,26391,26824,26632,27214,27261,27393,30019,30195,30014,30472,30242,30288,11065,11176,11113,11065,11113,10861,13518,13303,13322,12294,12335,12398,12398,12335,12440,12057,11940,12017,13690,13738,13442,16624,17058,17247,15586,15444,15186,23916,23976,23895,24193,24441,24517,23733,23976,23916,28704,28324,28656,28704,28745,28638,31733,31758,31562,31783,31758,31733,9713,9876,9779,12852,12769,12913,13442,13738,13463,28395,28282,28308,28237,28161,28023,28845,28594,28689,28845,28689,28797,28907,28957,29129,28907,28853,28845,28957,29168,29270,28745,28898,28638,32180,32132,32002,32200,32002,32091,16593,17058,16624,23164,23043,22763,23424,23627,23585,29883,29957,30014,30073,29957,29883,30019,30278,30199,26836,26551,26591,26836,26842,26989,30472,30288,30332,11832,11890,12017,12017,11890,12085,17058,17836,17665,23454,23627,23424,31856,31824,31661,31901,31824,32308,32167,31486,31852,31762,31512,31730,31476,31386,31453,9706,9766,9816,9691,9713,9779,9706,9816,9885,9857,9963,9982,9857,9982,9826,28487,28308,28459,28023,27939,27703,10758,10539,10982,9826,10047,9860,24517,24961,24700,24878,24961,24517,31377,31426,31299,31552,31426,31377,31156,31077,30978,30926,30990,30840,30926,30705,30809,30926,30809,30905,31270,31132,31141,31460,31453,31266,31094,30978,31019,32271,32187,32529,30800,30809,30663,11236,11834,12019,11159,11292,11492,11277,11292,11132,12294,12398,12491,13303,13442,13463,14990,15109,14912,14256,14065,14333,14065,14060,14074,27722,27715,27459,26745,26847,26824,28282,28161,28237,11890,11720,11822,11637,11720,11709,14256,14333,14358,9411,9517,9706,10861,11113,10953,23308,23347,23424,23350,23347,23308,30535,30472,30332,30661,30800,30663,30317,30332,30195,17415,16915,17003,17862,17767,18151,18209,18151,18198,23976,24091,24031,24227,24091,23976,23733,23805,23627,27494,27288,27375,27494,27375,27486,29957,30019,30014,29552,29451,29429,19333,19559,18904,26371,26258,26184,26179,26258,26476,26258,26371,26476,30661,30540,30545,32187,32196,32025,12335,12148,12212,29276,29110,28582,32078,32040,31947,32078,31947,32132,9432,9759,9886,9691,9779,9728,9779,9795,9728,23664,23733,23627,31497,31270,31141,31577,31552,31373,31641,31454,31677,31355,30731,31112,31824,31815,31716,31901,31815,31824,24961,25173,25039,26391,26745,26824,25197,25173,24961,31287,31355,31112,22077,22024,22301,22077,22301,22220,32196,32215,32091,30667,30661,30545,12148,12075,12212,29435,29552,29429,9682,9564,9681,9681,9564,9662,9662,9614,9773,9670,9571,9682,9628,9904,9733,11720,11641,11813,11637,11641,11720,32178,32295,32162,32529,32187,32105,32187,32271,32196,32196,32271,32215,32184,32295,32178,32202,32295,32184,32258,32295,32202,31909,31883,32169,20611,20823,20695,20181,20194,20108,20108,20031,19932,9571,9564,9682,9552,9908,9757,32169,31883,32312,9728,9795,9717,9646,9628,9733,20517,20228,20299,19932,19324,19869,23347,23454,23424,23350,23454,23347,30019,30199,30195,30472,30552,30545,30307,30199,30278,31355,31460,31266,22024,21660,21778,22220,22301,22317,32271,32200,32215,32215,32200,32091,20228,20194,20181,28141,27939,28023,29552,29637,29451,31730,31512,31479,31730,31479,31949,14852,14990,14912,13386,13463,13368,30569,30552,30472,30990,31094,31019,31133,31287,31112,31465,31591,31460,31309,31094,30990,31191,31094,31202,30990,30926,30949,30926,30905,30949,9493,9614,9662,9780,9709,9958,31191,31156,30978,31677,31562,31758,31552,31507,31426,26948,26836,26989,27655,27494,27486,31815,31783,31733,31901,31783,31815,20194,20031,20108,25270,25286,24539,24129,23756,23797,22451,22220,22317,25465,25407,25433,25890,25465,25601,31269,31287,31133,9646,9733,9676,12977,12782,12880,12880,12782,12852,12852,12655,12769,12769,12597,12598,12335,12127,12148,12148,12127,12075,12655,12782,12757,22451,22423,22489,21802,21660,21965,28594,28487,28459,28282,28329,28161,28161,28155,28023,28907,28845,28797,29270,29168,29337,32200,32161,32002,32307,32161,32200,9676,9733,9713,9717,9795,9766,11956,11881,12031,12031,12005,13107,13284,13261,13378,11236,12107,11338,29414,29270,29337,30526,29791,30239,30239,30483,30813,29637,29684,29451,12565,12597,12769,17128,16915,17415,12597,12465,12598,28539,28487,28594,9857,9785,9947,10156,10251,10294,11292,11277,11338,11046,11292,11159,30199,30317,30195,30307,30317,30199,10873,10758,10982,10880,11015,11043,27026,27006,27169,26258,26147,25940,28487,28395,28308,9422,9564,9571,9676,9713,9659,32161,32180,32002,31874,31777,31783,32307,32180,32161,31936,31852,31864,31936,31864,31844,27459,27715,27498,27185,27214,27101,29684,29761,29466,9659,9713,9691,9706,9717,9766,12433,12294,12491,11709,11720,11890,13442,13303,13518,13463,13738,13581,13738,13871,13581,28395,28329,28282,27839,27655,27590,29414,29337,29515,10136,10218,10400,10156,10218,10136,31641,31577,31373,31777,31677,31758,31767,31730,31922,31767,31936,31844,31479,31476,31949,10868,11313,11555,10795,10953,10942,11065,11046,11159,31655,31577,31641,12294,12127,12335,10676,10854,10880,14498,14556,14659,22133,22024,22077,28329,28155,28161,29579,29414,29515,9659,9691,9627,9500,9904,9527,18609,19335,18587,17506,17128,17415,11940,12057,12075,27965,27590,27939,27169,27006,27288,31156,31269,31133,31465,31460,31355,31094,31191,30978,30809,30800,30905,31767,31581,31762,27404,27288,27494,26476,26423,26551,30317,30344,30332,30905,30800,30661,30367,30344,30317,28155,28141,28023,31754,31507,31552,14774,15444,14599,16593,16176,17058,15675,15586,15186,30667,30545,30552,31132,31270,30740,31497,31141,31426,31202,31269,31156,30577,30569,30472,23205,22625,23797,22220,22133,22077,10385,10290,10801,10192,10313,10385,10290,10313,9961,9806,10192,10037,26476,26551,26662,31015,30905,30661,12127,11940,12075,29696,29579,29515,29786,29579,29696,31677,31655,31641,31577,31754,31552,31826,31655,31677,31777,31758,31783,32118,31656,32040,23454,23575,23627,23733,24227,23976,24091,24227,24193,23283,23350,23308,23164,22658,22650,9539,9757,9641,10974,11046,11065,10502,10795,10942,26662,26551,26836,32332,32146,32162,32349,32078,32132,9482,9709,9780,18587,19335,19338,32287,32132,32180,9599,9628,9646,9627,9691,9728,9627,9728,9661,9860,10116,9784,9661,9728,9717,24484,23756,24129,11940,11832,12017,11834,11881,11956,11807,11881,11631,11236,11338,11277,27987,27965,27939,26896,26948,27104,10974,11065,10833,11132,11236,11277,14590,14498,14659,27026,26948,26989,27646,27494,27655,27023,27185,27101,26089,26525,26391,27147,27185,27023,30073,30019,29957,30344,30535,30332,30813,30483,30740,30569,30667,30552,30367,30535,30344,12782,12655,12852,12597,12565,12465,12465,12433,12491,11730,11762,12127,12127,11762,11940,11653,11709,11832,12757,12782,12977,13023,13247,13303,28745,29048,28898,28898,29276,28582,29435,29482,29552,29679,29833,29637,29637,29833,29684,29912,30016,29761,28704,28803,28745,28656,28324,28613,27990,28008,28613,28845,28643,28594,28487,28577,28395,28395,28269,28329,28329,28269,28155,28155,28330,28141,28141,28080,27939,29129,28853,28907,29129,28957,29270,29129,29270,29225,12655,12565,12769,28853,28643,28845,27990,27717,28008,13386,13303,13463,13065,13023,13095,20611,20774,20823,20517,20428,20228,20228,20186,20194,20194,20186,20031,19672,19324,19932,28643,28539,28594,28008,27717,27715,29558,29270,29414,32295,32362,32162,32258,32362,32295,32375,32362,32258,10218,10156,10294,10136,10492,10539,10295,10539,10259,14304,14256,14358,20611,20521,20517,26825,26662,26836,30099,30073,29883,30016,29835,29761,30687,30667,30569,20521,20428,20517,32381,32148,32089,9564,9493,9662,9614,9539,9641,9422,9493,9564,9599,9646,9597,9706,9885,9785,9597,9646,9676,12565,12433,12465,20428,20364,20228,27965,27839,27590,27987,27839,27965,29579,29558,29414,30116,29792,29717,32362,32332,32162,32432,32381,32089,9706,9785,9411,18209,17938,18151,18519,18447,18416,18411,18447,18519,22192,22133,22220,20823,20774,21066,22192,22220,22265,23664,24227,23733,25975,25819,25610,31730,31767,31762,31591,31476,31460,29132,29276,28898,20364,20186,20228,26182,26147,26179,26179,26147,26258,25407,25509,25270,26057,26147,26209,10313,10290,10385,9769,10313,10192,31928,31826,31677,32308,31824,31856,12005,11958,11807,11046,11132,11292,10974,11132,11046,27185,27261,27214,26904,27147,27023,30307,30367,30317,30535,30577,30472,30384,30367,30307,13581,13871,13832,28374,28269,28395,29276,29377,29435,10156,10044,10251,26182,26179,26380,26948,26825,26836,26896,26825,26948,25567,25610,25173,26904,27082,27147,30716,30577,30535,27839,27752,27655,27827,27752,27839,9597,9676,9485,9576,9676,9659,9625,9661,9717,13832,13871,14060,14498,14304,14358,19941,19932,20031,22265,22220,22451,20774,21348,21066,27539,27404,27494,32271,32307,32200,32322,32307,32271,9438,9539,9614,29641,29558,29579,23756,23205,23797,22650,22658,22323,23350,23575,23454,23520,23575,23350,10880,10854,10758,10156,10029,10044,11652,11781,11124,11574,11641,11637,31665,30813,30740,29786,29696,29792,9527,9904,9628,9576,9659,9627,21348,21660,21377,22376,22265,22451,32307,32287,32180,32038,31874,32310,32322,32287,32307,11525,11574,11637,11709,11890,11832,11881,11958,12031,13378,13261,14174,11958,11881,11807,14124,14065,14256,28330,28080,28141,30278,30384,30307,29833,29761,29684,9518,9576,9627,9706,9625,9717,9568,9625,9706,9539,9552,9757,9353,9482,9250,9784,10116,10221,9826,9783,9857,31901,31874,31783,31655,31826,31577,31507,31497,31426,32118,32040,32078,27324,27185,27147,27324,27261,27185,31191,31202,31156,31465,31355,31287,31309,31202,31094,31346,31202,31309,30990,30949,31309,31015,30661,30667,23164,23283,23308,23416,23283,23164,26147,26057,25940,26179,26476,26380,28080,27987,27939,27363,27169,27404,30577,30687,30569,30716,30687,30577,30621,30535,30367,32349,32118,32078,23575,23664,23627,23520,23664,23575,14304,14124,14256,26380,26476,26571,30016,30099,29883,30138,30099,30130,9527,9628,9554,19324,18587,19338,18447,18411,18209,32280,32167,31852,32169,32350,31909,32084,31852,31936,28803,28895,28745,29441,29482,29377,29679,29637,29552,28656,28895,28803,28844,28895,28656,28844,28656,28613,11762,11832,11940,12565,12636,12433,12655,12636,12565,12757,12636,12655,12757,12977,13023,13023,13303,13095,28895,29048,28745,29482,29435,29377,29048,29132,28898,10854,10728,10758,10640,10728,10676,13095,13303,13182,13303,13386,13182,24227,24441,24193,24258,24441,24227,27404,27169,27288,26825,26734,26662,27104,27169,27229,28269,28330,28155,28080,28100,27987,28539,28577,28487,28807,28577,28539,28807,28539,28643,29056,28643,28853,29056,28853,29304,29437,29225,29270,30278,30019,30073,31907,31677,31777,31270,31665,30740,31893,31777,31874,27104,26948,27026,32038,31893,31874,10058,10136,9989,9770,9783,9860,25293,25197,25143,31594,31497,31507,13182,13386,13368,11525,11709,11542,11124,11781,11641,14124,13832,14060,29833,29912,29761,30138,30278,30073,29889,29912,29833,9554,9628,9599,9554,9599,9447,9518,9627,9661,9676,9576,9555,13368,13463,13581,12939,13261,13284,23101,22489,22423,21660,21459,21377,10076,10029,10156,31465,31287,31366,32299,32312,32167,13287,13368,13581,27363,27404,27539,28374,28330,28269,29441,29377,29276,15586,15675,15997,18168,18662,17836,14774,14599,14633,9511,9599,9597,32515,32350,32169,25499,25567,25173,26824,26847,26904,14498,14279,14304,13989,13890,14124,13590,13502,13832,14990,14590,14659,14852,14590,14990,20611,20557,20521,20521,20557,20428,20428,20436,20364,20364,20293,20186,20186,20094,20031,21536,21459,21660,27169,27104,27026,26571,26476,26662,27655,27752,27646,9376,9432,9886,9493,9438,9614,9539,9451,9552,9376,9886,9319,9471,9500,9527,11709,11525,11637,11487,11525,11542,20695,20557,20611,21802,21536,21660,27591,27722,27459,27591,27459,27261,9432,9422,9571,20557,20436,20428,18440,18411,18587,11958,12005,12031,11881,11834,11631,18587,18411,18519,18209,18411,18139,23205,23101,22423,23622,23101,23205,22785,23101,22904,27646,27752,27827,29558,29437,29270,29786,29641,29579,29786,29792,29857,30851,30716,30535,30138,30073,30099,31893,31907,31777,31875,31754,31577,32038,31907,31893,26525,26089,25975,30621,30367,30384,30687,30820,30667,26182,26209,26147,26057,25890,25601,26571,26662,26646,9422,9438,9493,9552,9400,9604,9860,9783,9826,9770,9860,9784,31875,31577,31826,31591,31748,31476,31366,31287,31269,31591,31751,31748,31346,31269,31202,20141,20094,20186,30085,30099,30016,29482,29679,29552,27827,27839,28100,27722,28008,27715,27474,27591,27261,26734,26825,26902,25975,26089,25819,32167,32312,31877,32084,31936,32122,32287,32338,32132,32038,31928,31907,32450,32322,32271,32122,31936,31767,9438,9450,9539,10833,11065,10861,11132,11053,11236,10963,10974,10833,21965,21660,22024,27243,27324,27147,27082,26904,26847,28007,28008,27722,29857,29792,30116,10136,10076,10156,9784,10221,10044,10058,10076,10136,31497,31630,31270,31747,31594,31507,9450,9451,9539,22133,22187,21965,31907,31928,31677,31754,31747,31507,31874,31901,32308,9485,9511,9597,9554,9471,9527,9485,9676,9555,21975,21361,21734,23283,23416,23350,21361,21030,21734,20579,20270,20366,32322,32338,32287,26902,26825,26896,27041,26896,27104,27229,27169,27328,26525,26745,26391,30716,30820,30687,30851,30820,30716,9952,10044,10029,9517,9568,9706,27646,27539,27494,27776,27539,27646,30085,30016,29912,30278,30422,30384,31262,30949,30905,25567,25975,25610,26525,26651,26745,29132,29220,29276,29482,29719,29679,29222,29220,29132,29222,29132,29048,29222,29048,29201,22376,22451,22489,22376,22192,22265,32466,32432,31909,32579,32477,32375,32375,32477,32362,32362,32577,32332,32529,32450,32271,32322,32412,32338,32466,31909,32350,26330,26321,25975,25197,25499,25173,25293,25499,25197,26344,26209,26380,26380,26209,26182,26344,26380,26412,32004,31747,31754,31949,31922,31730,31697,31751,31591,31697,31591,31465,9525,9661,9625,9414,9471,9554,22358,22376,22482,29459,29437,29558,29304,28853,29129,28577,28374,28395,29459,29558,29641,29220,29441,29276,30049,30085,29912,10963,11053,11132,27328,27169,27363,10728,10640,10758,10676,10728,10854,11124,11641,11574,14633,14599,13996,9525,9568,9517,28692,28374,28577,28330,28341,28080,32673,32466,32680,32280,32299,32167,21965,22024,22133,32515,32169,32312,9447,9599,9511,9518,9555,9576,31949,31476,31748,32084,32280,31852,10076,9974,10029,10295,10136,10539,31594,31616,31497,31699,31616,31594,13368,13283,13182,12898,12915,13095,12915,12757,13065,13065,12757,13023,12127,12294,11730,13396,13287,13581,13502,13581,13832,28374,28341,28330,10868,10676,10880,26734,26646,26662,26755,26646,26734,26963,27082,26847,26580,26651,26525,23388,23416,23164,23664,24258,24227,24878,25197,24961,11525,11487,11574,12294,12433,11730,30138,30422,30278,29889,29833,29679,9447,9511,9425,10974,10963,11132,11050,11834,11236,10833,10861,10403,22187,22133,22192,27324,27337,27261,27756,28007,27722,26850,26847,26745,27256,27337,27324,30515,30422,30138,26209,26108,26057,26344,26108,26209,31346,31366,31269,32037,31949,31748,31458,31366,31346,31015,30667,30820,16728,15280,15893,13590,13832,13610,15785,15280,16728,26852,26850,26745,11999,12433,12636,11745,11807,11631,11869,12939,13284,13832,14124,13890,20366,20270,20088,23388,23520,23416,10292,10942,10801,10292,10801,10290,26412,26380,26571,18139,18047,18209,18440,18587,18486,23416,23520,23350,22443,22323,22235,17391,17128,17506,17492,17391,17506,20695,20753,20557,20557,20585,20436,20436,20378,20364,18611,18587,18847,20823,20753,20695,20878,20753,20823,20878,20823,21066,21348,21377,21066,21377,21340,21066,21459,21340,21377,30085,30130,30099,30154,30130,30085,32308,31856,32118,31992,31875,31826,31699,31630,31616,32577,32477,32579,32579,32375,32381,20753,20585,20557,9525,9518,9661,9425,9511,9485,9525,9625,9568,9319,9886,9500,9266,9295,9422,9422,9379,9438,9438,9382,9450,9450,9311,9451,19941,20031,20094,21459,21542,21340,32378,32280,32084,32299,32377,32312,20585,20378,20436,29304,29129,29225,28374,28495,28341,11762,11653,11832,13095,12975,12898,12915,13065,13095,11469,11542,11653,14124,14304,14059,13283,13368,13287,19559,19333,20088,18168,18904,18662,18168,17751,18073,20378,20293,20364,21459,21536,21542,21975,22110,22235,24878,24517,24441,26321,26580,25975,25975,26580,26525,26852,26963,26850,26777,26580,26711,29786,29758,29641,29349,29304,29225,30116,29717,30724,30116,30165,30089,31096,31015,30820,31616,31630,31497,31699,31594,31850,32338,32349,32132,32529,32807,32625,29056,28807,28643,28804,28844,28613,29220,29362,29441,29441,29548,29482,28858,28844,28804,29084,29048,28895,9295,9379,9422,9523,10153,9709,20293,20141,20186,27148,27041,27104,26690,26412,26571,27496,27328,27363,27496,27363,27539,27839,27987,28100,30422,30482,30384,30474,30482,30422,13996,14599,14174,14774,15186,15444,27148,27104,27229,13283,13287,13396,13261,13616,14174,11869,13284,12005,28807,28692,28577,9379,9382,9438,32399,32377,32299,9425,9485,9555,9408,9402,9500,22110,22157,22235,32450,32412,32322,32606,32412,32450,10058,9974,10076,9785,9338,9411,9989,9974,10058,10539,10758,10259,11499,11542,11469,11653,11542,11709,11487,11334,11574,10599,10533,10676,14279,14498,14590,16792,15785,16728,18047,17938,18209,17974,17938,18047,26902,26755,26734,31935,31697,31465,31922,32122,31767,29703,29459,29641,29362,29548,29441,10259,10758,10640,21763,21536,21802,26108,26036,26057,26221,26036,26108,26432,26108,26344,24233,24258,23664,31992,31826,31928,31843,31748,31751,13396,13581,13409,29548,29639,29482,25890,25509,25407,9455,9425,9555,9857,9783,9481,23101,22785,22489,21830,21763,21965,21965,21763,21802,23622,23205,23756,27082,27243,27147,27337,27474,27261,27223,27243,27082,26963,26847,26850,30482,30621,30384,30474,30621,30482,30756,30621,30818,28100,28080,28217,29857,30116,30089,29857,29758,29786,26690,26571,26646,27041,26902,26896,27134,26902,27041,27148,27229,27161,26852,26745,26651,30756,30851,30535,27606,27496,27539,27256,27474,27337,14633,15186,14774,15675,16176,16491,26690,26646,26755,11745,11909,12005,11745,12005,11807,13409,13502,13590,13409,13581,13502,29639,29719,29482,17938,17862,18151,17391,17286,17128,17974,17862,17938,24484,23622,23756,9455,9555,9518,9408,9500,9471,9408,9471,9414,11050,11236,11053,13293,13409,13590,18847,18587,19324,18440,18139,18411,22187,22192,22376,23622,22904,23101,26869,26690,26755,32377,32515,32312,32579,32808,32765,32280,32399,32299,32378,32399,32280,11320,11334,11487,10172,10259,10640,11499,11487,11542,14279,14315,14185,27827,27776,27646,27714,27776,27875,22187,22376,22358,31630,31665,31270,31850,31594,31747,9712,9784,10044,9434,9806,10037,9780,9604,9400,17375,17286,17391,16572,16778,16915,24258,24434,24441,24607,24434,24233,17777,17492,17506,9414,9554,9416,9446,9455,9518,22335,22443,22235,23520,23600,23664,27266,27229,27328,26902,26913,26755,27266,27328,27406,30474,30422,30515,30621,30756,30535,10934,11050,11053,10934,11053,10963,14258,14279,14185,30221,30138,30130,11466,11631,11834,18320,18139,18440,17862,17777,17767,23354,23388,23204,28217,28080,28341,29770,29889,29679,9554,9447,9416,10295,9989,10136,9974,9952,10029,10533,10640,10676,10170,10292,10290,10403,10861,10795,26036,25890,26057,26221,25890,26036,26432,26344,26412,31262,31309,30949,31366,31556,31465,31262,30905,31015,31096,30820,30851,31309,31458,31346,31697,31843,31751,27223,27256,27243,27243,27256,27324,26777,26852,26651,26777,26651,26580,17834,17777,17862,12757,12599,12636,12716,12599,12757,12716,12757,12915,12716,12915,12856,12915,12898,12856,28807,28888,28692,28692,28495,28374,29056,29016,28807,29304,29016,29056,29225,29437,29349,29102,29084,28895,29222,29362,29220,29655,29719,29639,29655,29770,29719,29719,29770,29679,29102,28895,28844,9680,9783,9770,9525,9446,9518,9400,9552,9318,18611,18486,18587,18585,18486,18611,31458,31556,31366,32675,32349,32338,32038,31992,31928,13182,12975,13095,29084,29201,29048,31953,31843,31935,31949,32000,31922,27776,27606,27539,27714,27606,27776,9318,9552,9451,13182,13086,12975,32529,32875,32807,32412,32568,32338,13218,13616,13261,14378,15370,15186,27756,27722,27591,27555,27591,27474,13182,13283,13086,13283,13396,13171,13086,13283,13171,9447,9425,9419,9416,9447,9419,10599,10676,10868,16572,16915,17128,14279,14590,14315,27134,26913,26902,27406,27328,27496,27052,27082,26963,32052,31850,31747,32141,31992,32038,32037,32000,31949,32529,32493,32450,17286,16572,17128,17492,17375,17391,17366,17375,17492,23388,23500,23520,23354,23500,23388,10705,10833,10403,27055,27052,26963,9928,9989,10295,18964,18847,19324,20753,20603,20585,20585,20603,20378,20305,20119,20293,20293,20119,20141,20141,20119,20094,20733,20603,20753,20733,20753,20810,20753,20878,20810,20878,20988,20810,20878,21066,20988,32451,32378,32478,32479,32515,32377,32477,32577,32362,32529,32625,32493,32381,32896,32808,20988,21066,21025,32673,32432,32466,13171,13396,13293,28718,28495,28692,28100,28098,27827,11320,11499,11283,10478,10599,10576,27544,27555,27474,29889,30049,29912,29941,30049,29889,9266,9422,9432,9379,9307,9382,9382,9311,9450,9266,9432,9376,9319,9500,9402,9319,9402,9322,19333,20366,20088,22087,22157,22110,22087,22276,22157,22157,22276,22235,21025,21066,21340,9419,9425,9455,9322,9402,9331,11124,11574,11334,26852,27055,26963,25975,26187,26330,25329,25499,25293,13101,13171,13274,13881,13832,13890,13029,13218,13261,13029,13261,12939,12842,12939,12396,11725,11909,11745,9240,9307,9379,9913,9952,9974,16425,16572,17286,20305,20293,20378,31699,31838,31630,31978,31754,31875,10403,10795,10502,9961,10170,10290,11499,11320,11487,11289,11320,11283,13989,13881,13890,14258,14304,14279,18139,17974,18047,17629,17366,17492,18032,17974,18139,18032,18139,18320,22376,22489,22482,21680,21542,21536,30049,30154,30085,30875,30818,30621,30246,30154,30049,9307,9311,9382,10833,10934,10963,11708,11745,11631,11050,10934,10928,11708,11725,11745,11708,11631,11437,27266,27161,27229,26532,26432,26412,27406,27161,27266,27532,27496,27606,27256,27544,27474,27052,27223,27082,27113,27223,27052,29920,29758,29857,29655,29639,29548,14315,14852,14697,32000,32122,31922,32186,32122,32000,31992,31972,31875,32141,31972,31992,9402,9336,9331,27134,27041,27148,9654,9680,9770,9654,9770,9784,26532,26412,26690,9402,9408,9336,9352,9419,9455,9446,9525,9517,23204,23388,23164,22087,22110,21975,28288,28217,28341,9408,9345,9336,9470,9446,9517,18847,18683,18611,18572,18683,18714,25143,25329,25293,25475,25329,25279,14059,13989,14124,13881,13610,13832,27936,27776,27827,27555,27756,27591,28858,29102,28844,27645,27756,27555,30154,30221,30130,30756,30818,30851,30246,30221,30154,9408,9414,9345,9311,9318,9451,9434,9523,9403,21680,21536,21763,9482,9523,9709,9523,9482,9403,15109,15080,14912,14989,15080,15109,17974,17834,17862,17375,17366,17286,18032,17834,17974,28217,28098,28100,29084,29174,29201,29201,29333,29222,28613,28008,28804,30089,29920,29857,30089,30165,30061,29962,29941,29889,29962,29889,29770,22276,22335,22235,22410,22335,22276,29102,29174,29084,27161,27206,27148,27441,27406,27496,30928,30818,30875,21830,21680,21763,29016,28888,28807,28495,28472,28341,28217,28209,28098,29101,28888,29016,29437,29459,29349,28804,28008,28347,29349,29459,29616,29174,29333,29201,9952,9712,10044,9989,9913,9974,9928,9913,9989,9928,9811,9881,10172,10640,10533,31850,31846,31699,31952,31846,31850,12698,12795,12975,12975,12795,12898,12898,12795,12856,12856,12558,12716,12558,12367,12599,11469,11653,11762,13101,12975,13086,13101,13086,13171,11869,12005,11909,28888,28850,28692,28347,28008,28007,29703,29641,29758,29333,29362,29222,18683,18585,18611,18572,18585,18683,9345,9414,9348,9411,9470,9517,9680,9654,9478,11289,11124,11334,11289,11334,11320,13750,13610,13881,14258,14059,14304,14073,14059,14258,31972,31978,31875,32144,31978,31972,31993,32037,31748,31953,31748,31843,13750,13881,13797,29788,29703,29758,30061,30165,30043,31458,31474,31556,31556,31625,31465,31309,31474,31458,31718,31474,31309,19480,18964,19324,32535,32377,32399,32422,32399,32378,32422,32378,32451,12842,13029,12939,13294,13996,13616,22650,22323,22443,23500,23600,23520,31619,31625,31556,21959,21830,21965,25475,25567,25499,27009,27055,26852,31935,31843,31697,9367,9470,9411,9072,9352,9455,9348,9414,9416,13293,13396,13409,28718,28472,28495,29897,29758,29991,29693,29655,29548,32378,32421,32478,15370,16176,15675,13568,13293,13590,13797,13881,13989,26432,26221,26108,25510,25286,25509,25509,25286,25270,26589,26532,26690,26935,26755,26913,26321,26582,26580,27534,27544,27256,26962,26852,26777,28098,27936,27827,27734,27532,27606,28060,27936,28098,30818,30858,30851,30928,30858,30818,32680,32466,32350,32654,32479,32377,9348,9416,9252,22489,22641,22482,21917,21959,22032,22187,21959,21965,32666,32625,32807,32493,32606,32450,32310,32141,32038,14059,13797,13989,14185,14073,14258,27734,27606,27714,27406,27206,27161,27756,28347,28007,27534,27256,27497,31978,32004,31754,32308,32118,32555,17629,17492,17777,17629,17777,17834,18320,18440,18486,18320,18486,18396,25971,25509,25890,22489,22785,22641,9352,9416,9419,9806,9762,10192,9586,9762,9806,10599,10478,10533,10576,10599,10868,26592,26711,26580,32136,32004,31978,31953,31993,31748,32037,32088,32000,31973,31993,31953,32612,32596,32479,32535,32451,32478,11466,11834,11223,11725,11791,11909,13568,13590,13610,22511,22650,22443,22511,22443,22335,28472,28288,28341,9218,9319,9322,9110,9376,9319,9110,9266,9376,9295,9240,9379,9307,9251,9311,9311,9267,9318,9218,9322,9331,9218,9331,9183,9331,9336,9228,10401,10439,10478,12367,12636,12599,17733,17629,17834,20603,20305,20378,20119,19941,20094,20733,20700,20603,20810,20700,20733,20841,20700,20810,20841,20810,20988,20841,20988,20868,21340,21487,21025,21542,21487,21340,27936,27875,27776,28016,27875,27936,30221,30341,30138,30175,30246,30049,30175,30049,29941,32555,32118,32349,21542,21524,21487,27441,27206,27406,27441,27496,27532,21841,22087,21975,32625,32606,32493,9266,9240,9295,9190,9224,9400,10928,10991,11050,10928,10934,10705,21542,21680,21524,27510,27441,27532,31625,31935,31465,26325,26221,26432,26325,26432,26520,28288,28209,28217,29970,29962,29770,32064,31973,31935,31474,31619,31556,31718,31619,31474,27134,26935,26913,9240,9251,9307,23354,23600,23500,23508,23600,23354,12558,12599,12716,12558,12856,12795,12558,12795,12634,18512,18486,18585,18032,17733,17834,23077,23204,23164,25329,25475,25499,26321,26443,26582,26582,26592,26580,24607,24441,24434,26330,26443,26321,28858,29123,29102,29102,29267,29174,29174,29267,29333,29578,29596,29362,29362,29596,29548,29655,29793,29770,29145,29123,28858,29267,29123,29309,32606,32568,32412,27945,27734,27875,27875,27734,27714,30246,30341,30221,30383,30341,30246,12634,12795,12698,9251,9267,9311,20305,20008,20119,18714,18683,18847,24233,24434,24258,32141,32144,31972,32369,32144,32141,11549,11469,11762,11223,11834,11050,13507,13568,13610,13293,13274,13171,13507,13610,13750,30089,30061,29920,29717,30526,30724,20008,19941,20119,28472,28460,28288,28288,28294,28209,28850,28791,28692,28945,28791,28850,28945,28850,28888,29101,29016,29427,29427,29304,29349,29616,29459,29703,9762,9769,10192,10705,10934,10833,9586,9769,9762,24607,24878,24441,32004,32052,31747,31846,31838,31699,32103,32052,32004,9913,9845,9952,9928,10295,9811,10478,10439,10533,10576,10868,10457,11652,11124,10999,26869,26589,26690,26605,26592,26582,27009,27113,27055,27055,27113,27052,31952,31838,31846,9072,9455,9446,9228,9336,9239,11375,11437,11466,10502,10309,10403,9336,9345,9239,10502,10292,10309,21524,21680,21595,26935,26869,26755,27206,27134,27148,27183,27134,27206,27183,27206,27383,27009,26852,26962,28791,28718,28692,29788,29616,29703,29490,29362,29333,30858,31036,30851,30875,30621,30877,18168,17836,17751,20697,20746,20366,23204,23235,23354,24831,24811,24607,23256,23235,23204,23077,23164,22650,27544,27645,27555,27534,27645,27544,30341,30515,30138,30383,30515,30341,30383,30246,30405,21595,21680,21635,28166,28060,28098,27734,27510,27532,28166,28098,28209,29596,29693,29548,9928,9845,9913,10999,11124,10986,26958,26869,26935,32051,31952,31850,22785,22904,22641,21635,21680,21733,32680,32350,32756,32579,32765,32577,32529,32105,32875,32625,32665,32606,32606,32665,32568,32350,32515,32713,11841,11730,12433,11527,11791,11708,11708,11791,11725,12932,13048,13029,28565,28460,28472,29897,29788,29758,9470,9367,9446,9785,9857,9300,9783,9680,9481,18714,18847,18964,17782,17733,18032,32144,32136,31978,32052,32051,31850,32209,32136,32144,32205,32088,31993,31993,32088,32037,31973,31953,31935,32308,32310,31874,32356,32310,32308,15785,16792,16778,14315,14590,14852,13443,13314,13568,15255,15280,15301,26221,25971,25890,26520,26432,26532,26520,26532,26589,26187,25975,26143,26443,26605,26582,26962,26777,26711,9239,9345,9246,9345,9348,9246,9769,9961,10313,32596,32515,32479,11730,11699,11762,10986,11124,11021,13314,13274,13293,13314,13293,13568,28460,28366,28288,29991,29758,29920,32535,32399,32422,32535,32422,32451,9523,9434,10037,9250,9780,9400,11343,11499,11469,27871,27510,27734,26719,26589,26869,28016,27936,28060,29145,28858,29002,27497,27256,27223,27497,27223,27196,26962,26711,26881,30928,31036,30858,31023,31036,30928,32072,32051,32052,32137,31973,32064,26686,26520,26589,26686,26589,26719,31096,31262,31015,31770,31935,31625,18234,18032,18320,17629,17471,17366,15295,15785,15542,9246,9348,9252,18572,18512,18585,18774,18512,18572,32378,32084,32421,11699,11549,11762,13797,14059,13895,28366,28294,28288,30043,29991,29920,30043,29920,30061,13895,14059,14073,22641,22904,22954,21917,21830,21959,22410,22511,22335,30877,30621,30474,30109,29941,29962,32783,32673,32680,32654,32612,32479,9252,9416,9352,32105,32332,32875,32592,32555,32349,11549,11457,11469,11466,11437,11631,11223,11050,11006,13507,13443,13568,24607,24811,24878,24878,25143,25197,26462,26435,26330,24233,23664,24105,28294,28166,28209,30724,30526,30813,29970,30109,29962,31036,31096,30851,30564,30474,30515,32209,32103,32136,32136,32103,32004,14852,14912,14697,27196,27223,27113,28347,27756,27834,31361,30724,31963,29612,29616,29724,29612,29349,29616,29427,29016,29304,28791,28730,28718,28718,28716,28472,28460,28565,28366,28380,28328,28294,28294,28328,28166,29616,29788,29878,29788,29897,29878,29123,29267,29102,29596,29578,29693,29693,29793,29655,27756,27645,27782,9190,9400,9318,11598,11705,11730,11730,11705,11699,11699,11417,11549,11379,11356,11457,12290,12145,12367,12698,12975,13101,12698,13101,12353,13101,13274,13255,32666,32665,32625,9360,9411,9338,9072,9252,9352,18512,18396,18486,18292,18396,18512,22891,23077,22650,23235,23390,23354,17733,17718,17629,17782,17718,17733,13255,13274,13314,21959,22187,22032,22954,22904,23622,22511,22567,22650,26212,25971,26221,26212,26221,26325,29073,28945,28888,29473,29490,29333,27009,27196,27113,26881,26711,26592,31083,31096,31036,13618,13507,13750,13957,13895,14073,13616,13996,14174,15186,15370,15675,13294,13616,13218,13048,13218,13029,20841,20780,20700,20700,20305,20603,20008,20012,19941,20868,20780,20841,20868,20988,21025,20868,21025,20926,21025,21012,20926,32808,32579,32381,32666,32738,32665,32381,32432,32896,21595,21487,21524,24998,25143,24878,29921,29897,29991,29490,29578,29362,31838,31665,31630,32235,31665,31838,32235,31838,31952,32072,31952,32051,11356,11343,11457,11457,11343,11469,13618,13750,13797,13443,13255,13314,30043,30029,29991,30724,30165,30116,30109,30175,29941,30383,30564,30515,30310,30175,30109,32753,32432,32673,15280,15255,15109,15785,16778,16572,26330,26435,26443,25975,25567,26143,20731,20305,20700,18855,18714,18964,11791,11869,11909,11625,11869,11791,28730,28716,28718,9093,9190,9318,9251,9188,9267,9240,9188,9251,8861,9188,9240,9058,9188,8861,9178,9319,9218,9178,9218,9118,9331,9228,9183,19816,19932,19941,14185,13957,14073,14868,14912,15080,24105,23664,23600,25199,25279,25143,32088,32186,32000,32205,32186,32088,32137,31993,31973,9353,9403,9482,9371,9586,9806,32735,32713,32885,32421,32084,32122,12932,13029,12842,15255,14989,15109,26520,26534,26325,26534,26686,26612,26435,26605,26443,28716,28565,28472,29578,29793,29693,9072,9446,9367,9183,9228,9171,11343,11283,11499,10337,10401,10576,11266,11283,11343,11006,11050,10991,11437,11527,11708,10847,10991,10928,13146,13255,13443,13601,13618,13797,13767,13797,13895,20305,20012,20008,28215,28060,28166,28215,28016,28060,26719,26869,26958,9845,9712,9952,9928,9881,9845,9811,10295,9912,10172,10533,10439,11021,11124,11289,10576,10401,10478,30823,30564,30383,30875,31023,30928,9228,9239,9171,11999,12636,12367,10391,10401,10337,10309,10292,9972,10705,10847,10928,14989,14868,15080,26962,27196,27009,26605,26881,26592,32783,32753,32673,32713,32515,32596,32713,32596,32810,11386,11527,11437,13529,13443,13507,18396,18234,18320,18292,18234,18396,23077,23256,23204,23284,23256,23077,32500,32421,32122,11283,11199,11289,11108,11199,11047,28016,27945,27875,28215,27945,28016,30175,30405,30246,30494,30405,30175,19894,19816,19941,22187,22358,22032,30837,30877,30474,31023,30877,30968,17471,17286,17366,15255,15108,14989,14989,14900,14868,15785,15301,15280,32654,32377,32535,32617,32535,32607,9171,9239,9246,14868,14697,14912,14151,13957,14185,14483,14697,14868,32796,32783,32680,9250,9482,9780,27782,27645,27534,27782,27534,27622,30201,30029,30043,30075,30029,30201,15155,15108,15255,26686,26534,26520,26935,27081,26958,32103,32072,32052,32220,32072,32103,32356,32141,32310,31770,31625,31619,32519,32500,32122,31718,31309,31776,31369,31262,31487,9146,9171,9246,11199,11021,11289,10391,10359,10401,11108,11021,11199,19816,19672,19932,18714,18774,18572,21030,21361,20579,22331,22410,22276,22511,22410,22567,23140,23284,23077,21841,21734,21739,32828,32796,32680,22331,22276,22087,23256,23390,23235,23284,23390,23256,29101,29073,28888,28945,28730,28791,28716,28730,28565,28380,28294,28366,29268,29073,29101,29427,29349,29581,29002,28858,28804,29267,29473,29333,29490,29715,29578,29578,29715,29793,29363,29427,29633,32675,32338,32568,12290,12367,12558,12698,12630,12634,12404,12630,12353,17854,17782,18032,17718,17471,17629,28815,29002,28804,29454,29473,29267,29793,29970,29770,11417,11457,11549,11417,11699,11705,11226,11466,11223,11226,11375,11466,10401,10359,10439,10868,10999,10607,26935,27134,27183,12145,11999,12367,21734,21841,21975,32875,32332,33008,32873,32675,32568,9411,9360,9367,9146,9183,9171,9481,9680,9478,10706,10847,10448,32607,32535,32478,27021,27196,26962,30877,31023,30875,31083,31023,31129,11999,11841,12433,28965,28730,28945,9881,9778,9845,9811,9778,9881,25143,25279,25329,26435,26602,26605,26605,26602,26881,26881,27021,26962,24998,24878,24811,24831,24607,24233,25286,24484,24129,25159,24484,25286,25510,25509,25971,32780,32568,32665,9224,9250,9400,9089,9318,9267,22032,22358,22271,22358,22482,22450,32807,32738,32666,14151,14185,14315,13618,13529,13507,12404,12456,12630,27558,27534,27497,32748,32356,32308,11139,11226,11223,13601,13529,13618,24877,24831,24928,32369,32209,32144,32137,32205,31993,32644,32607,32478,12976,13294,13218,12396,12932,12842,12396,12939,11869,11625,11791,11527,11625,11527,11581,27206,27441,27644,23390,23508,23354,23284,23508,23390,31369,31309,31262,32137,32225,32205,26366,26212,26325,26366,26325,26424,26612,26686,26719,26143,25567,25837,9508,9654,9784,17782,17663,17718,17812,17663,17782,17854,18032,18234,21733,21787,21619,32738,32780,32665,11386,11437,11375,29921,29878,29897,31771,31770,31619,32735,32756,32713,32713,32756,32350,32644,32478,32700,10257,10172,10439,26187,26462,26330,31339,31262,31096,9147,9250,9224,9778,9712,9845,9648,9712,9778,18861,18855,18937,14697,14339,14315,14215,14339,14276,12456,12634,12630,13767,13601,13797,13767,13895,13957,30075,29991,30029,30075,29921,29991,29899,29970,29793,30837,30474,30564,31023,31083,31036,30837,30564,30823,10399,10847,10705,9972,10292,10170,9972,10170,9752,10847,10864,10991,11006,10864,10875,20780,20731,20700,20006,19894,20012,20012,19894,19941,19816,19646,19672,20868,20926,20780,21012,21025,21487,21012,21487,21061,21487,21595,21061,26887,26612,26719,26506,26602,26435,32808,32819,32765,33008,32332,32577,32807,32822,32738,32738,32842,32780,32972,32819,32808,32896,32432,32753,32896,32753,32961,9158,9110,9319,9188,9089,9267,9158,9319,9178,9158,9178,9144,21680,21830,21733,9371,9806,9434,9769,9632,9961,9288,9434,9403,9358,9403,9353,9520,9508,9784,18855,18774,18714,18861,18774,18855,9146,9246,8770,9300,9338,9785,9279,9338,9284,9260,9358,9353,18430,18292,18512,32661,32592,32349,32448,32369,32582,32661,32349,32675,32596,32612,32810,32700,32478,32421,11047,11199,11283,11434,11417,11705,30201,30043,30165,32072,32235,31952,32209,32220,32103,32240,32220,32382,32369,32141,32356,32535,32617,32654,32961,32753,32783,10359,10257,10439,10607,10999,10835,10866,10986,11021,11266,11343,11356,13101,13255,13146,13752,13767,13957,9144,9178,9118,9218,9183,9118,32961,32783,32796,9118,9183,9146,9058,9089,9188,9190,9134,9224,10835,10999,10986,14339,14151,14315,13932,14151,13903,27196,27558,27497,27782,27834,27756,29244,29145,29002,27622,27558,27624,30823,30383,30405,11417,11379,11457,11187,11386,11375,11187,11375,11226,28380,28366,28492,27945,27871,27734,30062,30201,30449,30449,30201,30165,26212,26114,25971,26366,26114,26212,26408,26506,26462,26462,26506,26435,26185,26143,26151,29073,28998,28945,28730,28965,28565,29427,29268,29101,29363,29268,29427,29349,29612,29581,29612,29724,29581,29878,29724,29616,29244,29309,29123,29473,29715,29490,29244,29123,29145,29244,29002,29293,32756,32828,32680,32654,32617,32607,11999,11886,11841,11461,11434,11705,11417,11378,11379,12456,12558,12634,13443,13529,13146,25451,25159,25286,25837,25567,25475,25092,25199,25143,24998,24811,24831,28815,28804,28347,29777,29652,29724,31770,32064,31935,32205,32263,32186,13583,13529,13601,20006,20012,20305,19672,19480,19324,29309,29454,29267,15051,15370,14378,17751,17836,17545,15664,15051,15631,31770,32176,32064,31718,31771,31619,31776,31771,31718,18064,17854,18234,17663,17471,17718,9358,9288,9403,9268,9288,9358,18292,18173,18234,18064,18173,18037,23735,24105,23600,22891,22650,22567,22891,22567,22826,29235,28998,29073,29878,29921,30062,10864,11006,10991,10967,11006,10875,28192,27871,27945,26958,26887,26719,27622,27834,27782,9246,9252,8770,15108,14900,14989,15301,15155,15255,15017,15155,15301,15005,15155,15017,27449,27558,27196,26408,26462,26187,11734,11886,11999,28998,28965,28945,30062,29921,30075,29454,29715,29473,29970,30038,30109,11194,11266,11379,11379,11266,11356,11108,10866,11021,28328,28215,28166,28351,28215,28328,22069,22331,22087,9508,9478,9654,9404,9478,9508,17562,17471,17663,23735,23600,23508,9089,9086,9318,8905,9260,9353,21733,21830,21917,21733,21886,21787,22826,22567,22643,32733,32654,32607,32782,32654,32733,32920,32577,32765,32780,32842,32568,24877,24998,24831,26185,26191,26143,32064,32225,32137,32245,32225,32345,9912,10295,10259,9712,9520,9784,9725,9811,9698,10391,10257,10359,10271,10257,10391,15005,14900,15108,27644,27441,27510,26424,26325,26534,29715,29899,29793,9274,9367,9360,9086,9093,9318,19894,19646,19816,18774,18430,18512,22450,22482,22641,22954,22450,22641,10967,11139,11223,13543,13583,13601,13543,13601,13767,23803,23735,23508,23272,23508,23284,10851,10866,10955,10457,10337,10576,14151,13932,13957,13855,13932,13903,11625,11630,11869,11398,11581,11527,11398,11527,11386,10457,10868,10607,32875,32822,32807,9338,9274,9360,9279,9274,9338,22891,22958,23077,22826,22958,22891,32843,32661,32675,32736,32308,32555,32751,32555,32592,26143,26191,26187,27624,27558,27449,26353,26191,26185,32245,32263,32205,32245,32205,32225,32785,32810,32612,32878,32828,32756,10851,10835,10866,11598,11730,11841,30201,30062,30075,30449,30165,30724,29899,30038,29970,32878,32756,32735,26353,26408,26187,31083,31339,31096,31788,31776,31309,30837,30968,30877,31066,30968,31183,18168,18343,19333,17836,17211,17545,10866,10835,10986,11047,11283,11266,27834,28071,28347,27558,27622,27534,26881,26602,27021,10568,10457,10607,24998,25092,25143,25048,25092,24998,24831,24233,24928,27183,27081,26935,27159,27081,27162,9288,9209,9434,8905,9353,9250,32661,32683,32592,32981,32683,32661,9026,9134,9190,14215,14151,14339,15155,15005,15108,14971,15005,15017,19646,19480,19672,21841,22050,22087,22643,22567,22410,21909,22050,21841,20746,20579,20366,32822,32842,32738,11187,11398,11386,28492,28366,28565,28215,28192,27945,27871,27644,27510,18937,18855,18964,17812,17782,17854,17812,17562,17663,25887,25510,25971,25159,24912,24484,22552,22271,22450,25525,25510,25887,32890,32878,32735,32782,32785,32612,32782,32612,32654,11139,11187,11226,11006,10967,11223,10706,10864,10847,13855,13752,13957,12404,12290,12456,13855,13957,13932,20926,20731,20780,19604,19518,19646,19646,19518,19480,20969,20731,20926,20969,20926,21012,20969,21012,21061,19116,20366,19333,32819,32920,32765,33080,32934,32822,32822,32934,32842,32972,32920,32819,32972,32808,32896,12456,12290,12558,11772,11734,11999,11522,11598,11841,13146,13529,13583,29268,29343,29073,28998,29242,28965,28581,28492,28565,29457,29343,29268,29457,29268,29363,29633,29427,29581,29633,29581,29652,9134,9135,9224,11630,12396,11869,12976,13218,13048,11630,11625,11596,22050,22069,22087,21987,22069,22050,29343,29235,29073,10337,10271,10391,10257,10129,10172,10277,10271,10337,21061,21595,21431,29652,29581,29724,9811,9725,9778,9698,9811,9608,12976,13048,12932,21619,21595,21635,28380,28351,28328,28418,28351,28380,30038,30310,30109,10457,10277,10337,10517,10568,10607,10399,10705,10403,25048,24877,24928,25475,25620,25837,32264,32225,32064,33021,32700,32421,32700,32607,32644,32890,32735,32885,33107,32972,32896,9300,9857,9481,8992,8848,8864,9300,9481,9339,18073,18343,18168,22958,23140,23077,24144,24233,24105,23222,23140,22958,8861,9240,9266,9089,9010,9086,8937,9026,9093,9093,9026,9190,9134,9028,9135,9001,9266,9110,8987,9110,8989,9030,9158,9144,9030,9144,9018,17471,16425,17286,17812,17854,18064,32713,32810,32885,33153,32961,32796,30363,30389,30038,30389,30365,30310,29715,29765,29899,29454,29765,29715,29530,29765,29454,29530,29454,29309,29530,29309,29244,10910,11187,11139,10849,10875,10864,13752,13543,13767,14339,14697,14276,31891,31776,32005,32135,32176,31770,11596,11625,11581,10910,11139,10967,26424,26534,26649,27021,26602,27032,26191,26353,26187,25279,25452,25475,11596,11581,11462,9018,9144,9118,9018,9118,8918,22480,22410,22331,9028,9147,9135,9135,9147,9224,33062,32796,32828,32885,32810,32959,9404,9481,9478,9072,9367,9274,9260,9268,9358,8896,9268,9260,11734,11841,11886,11079,11047,11266,10835,10699,10607,11577,11596,11462,23140,23272,23284,23222,23272,23140,32327,32186,32263,32959,32810,32785,9499,9520,9712,14836,14868,14900,32345,32327,32263,32345,32263,32245,11378,11417,11434,13535,13543,13752,13535,13752,13519,15005,14971,14900,14836,14971,14963,30365,30494,30310,30310,30494,30175,33062,32828,32878,9377,9404,9508,10955,10866,11108,13885,13903,14151,32519,32122,32480,9147,9137,9250,9043,9137,9147,11598,11461,11705,33025,33062,32878,32959,32785,32782,9725,9648,9778,9912,10259,10172,24877,25048,24998,24144,24105,23944,25510,25451,25286,25525,25451,25510,32852,32733,32607,21733,21619,21635,21733,21917,21886,21030,21639,21734,22069,22200,22331,10129,9912,10172,10174,10277,10098,10277,10097,10098,11461,11378,11434,13543,13146,13583,28581,28565,28965,27796,27644,27871,18064,18234,18173,15017,15301,15785,17836,17058,16931,18073,18261,18343,21886,21917,22032,21639,21739,21734,11047,10955,11108,10985,10955,11047,32842,32873,32568,32963,32873,32842,9622,9648,9725,31884,31770,31771,26602,26792,27032,25279,25199,25296,30968,31066,31023,31183,30968,31054,10851,10699,10835,10678,10699,10851,10706,10746,10864,10875,10931,10967,11462,11581,11398,10632,10746,10706,25174,25199,25092,28192,28215,28411,26649,26534,26612,27622,27933,27834,26506,26792,26602,31776,31884,31771,31891,31884,31776,22271,22358,22450,22045,21886,22032,26134,25971,26114,27159,26958,27081,28492,28418,28380,23944,24105,23735,32500,32603,32421,32837,32852,32607,32480,32122,32186,32603,32519,32716,27162,27081,27183,29633,29457,29363,29343,29242,29235,29235,29242,28998,28492,28581,28418,29675,29457,29633,11772,11999,12145,11598,11493,11461,11461,11224,11378,12353,12630,12698,19032,18937,18964,18037,18173,18115,19032,18964,19480,29497,29242,29343,8986,9093,9086,19604,19646,19894,21739,21909,21841,29777,29724,29871,33080,32822,32875,9300,9284,9338,9279,9161,9274,9217,9284,9300,10849,10931,10875,18796,18774,18861,27886,27933,27622,9648,9592,9712,9520,9427,9508,9404,9339,9481,25048,25091,25092,24928,25091,25048,32220,32240,32072,30237,30374,30253,32382,32220,32209,32235,32240,32387,32209,32448,32382,12202,12145,12290,29871,29878,29980,29871,29724,29878,11378,11194,11379,10609,10678,10851,11007,11194,11008,24990,24912,25159,26134,26114,26171,30724,30813,32346,30389,30310,30038,30494,30628,30405,9117,9161,9279,14971,14836,14900,13752,13855,13625,17500,17471,17562,32934,32963,32842,29980,29878,30062,32873,32843,32675,32981,32843,33286,9994,10399,10403,10746,10849,10864,10448,10399,9994,31066,31129,31023,31281,31129,31183,9369,9427,9520,9648,9563,9592,9592,9499,9712,9698,9622,9725,9657,9622,9698,9586,9632,9769,9305,9632,9586,11596,11577,11630,11630,12271,12396,12965,12976,12932,11462,11398,11017,20731,20613,20305,20879,20613,20731,20879,20731,20969,20879,20969,20921,20969,21061,20921,21061,21034,20921,25174,25296,25199,28350,28815,28347,30156,30038,29899,30035,29980,30062,9110,9158,8989,8987,9001,9110,9058,8996,9089,9158,8992,8989,10632,10849,10746,11477,11462,11327,11194,11079,11266,10985,11079,11007,21800,21619,21787,9026,9028,9134,9137,9055,9250,9004,9028,9026,9158,9030,8992,17751,17930,18073,21539,21518,21688,17997,17930,17904,9428,9499,9592,24990,25159,25451,32264,32345,32225,32264,32064,32176,26367,26408,26353,28049,28071,27933,31350,31339,31083,8992,9030,8936,20746,21030,20579,21639,21757,21739,21739,21757,21909,18330,19333,18343,10129,10257,10271,10910,10967,10931,22952,23222,22958,23272,23230,23508,22897,22958,22826,26171,26114,26366,26171,26366,26383,26185,26367,26353,25837,26151,26143,25998,26151,25837,31788,31309,31369,31884,31979,31770,9317,9339,9404,9284,9117,9279,16931,17058,16720,26202,26367,26185,21987,22200,22069,21987,22050,21909,33244,33008,32577,32934,33014,32963,33244,32577,32920,33107,32920,32972,25296,25452,25279,25091,25174,25092,25196,25174,25091,32240,32235,32072,32209,32369,32448,32396,32264,32176,13004,12951,13146,12257,12202,12404,13519,13752,13625,14088,14151,14215,30365,30628,30494,30707,30628,30365,9030,9018,8936,12250,12932,12396,13294,12981,13996,27422,27449,27196,27933,28071,27834,10699,10517,10607,10174,10129,10271,10609,10851,10585,27383,27162,27183,27159,26887,26958,27869,27796,27889,27383,27206,27581,8883,8996,9058,10174,10271,10277,9028,9043,9147,8963,9043,9028,22954,23622,24090,21886,21800,21787,17930,18261,18073,18330,18261,18203,23222,23230,23272,25346,25296,25174,23195,23230,23222,9427,9377,9508,9399,9377,9427,9209,9371,9434,9209,9288,9268,16720,17058,16176,8996,9010,9089,9622,9563,9648,9369,9399,9427,9608,9657,9698,25358,25452,25296,10789,10910,10931,10789,10931,10849,27729,27622,27624,32751,32592,32683,32519,32603,32500,32480,32186,32327,32480,32327,32414,9010,8986,9086,10277,10457,10097,27112,26887,27159,12404,12202,12290,11734,11646,11841,12353,13101,13146,28652,28581,29487,27744,27673,27796,29457,29497,29343,29675,29497,29457,29675,29633,29652,29675,29652,29828,29652,29777,29828,29293,29530,29244,29293,29002,28815,11476,12271,11630,11503,11630,11577,30294,29293,29506,12257,12353,12092,29828,29777,29880,29777,29871,29880,30156,29899,30122,10399,10448,10847,9994,10403,10309,14483,14276,14697,27581,27206,27644,27162,27112,27159,10541,10632,10706,27581,27673,27598,27796,27673,27644,27449,27636,27624,27535,27636,27449,11884,11772,12145,11079,10985,11047,29975,29871,29980,32981,32751,32683,32736,32751,32945,9339,9217,9300,9037,9072,9274,9175,9217,9339,17812,17657,17562,18064,17788,17812,17950,17788,18064,26050,25998,25837,26151,26202,26185,26672,26506,26408,27422,27535,27449,26134,25887,25971,25525,25720,25451,26434,26366,26424,9752,10170,9961,11772,11646,11734,18937,18796,18861,19281,19032,19480,19398,19480,19518,21833,21800,21886,21664,21757,21639,22200,22480,22331,26649,26434,26424,27216,27112,27162,26725,26649,26612,31339,31487,31262,31129,31350,31083,31281,31350,31129,31129,31066,31183,31891,31979,31884,32005,31979,31891,33008,33080,32875,32963,33185,32873,10962,11398,11187,10733,10789,10849,9377,9317,9404,9428,9520,9499,32414,32327,32345,32414,32345,32443,32582,32369,32356,32443,32345,32264,11646,11522,11841,14250,14255,14276,14963,15017,14764,15370,15929,16176,15664,15929,15370,26725,26612,26887,32924,32959,32782,33025,32878,32890,32837,32607,32700,32837,32700,32976,9302,9317,9377,19491,19604,19588,22045,21833,21886,9037,9274,9161,8951,9055,9137,8951,9137,9043,19032,18949,18937,18961,18949,19032,22377,22480,22200,11522,11493,11598,11462,11477,11577,10962,11187,10874,30167,30035,30062,10733,10787,10789,10448,10541,10706,10522,10541,10305,14255,14088,14215,13004,13146,13543,14255,14215,14276,27383,27216,27162,27673,27581,27644,27744,27796,27869,27636,27729,27624,27422,27196,27021,18115,18173,18292,25452,25461,25475,25358,25461,25452,24928,24233,24837,31469,31487,31339,33080,33014,32934,33025,32890,32885,32961,33107,32896,30823,30405,30628,31350,31455,31339,11007,11079,11194,10678,10517,10699,17788,17657,17812,17853,17657,17788,12976,13001,13294,12671,12965,12932,30035,30167,30237,30449,30167,30062,30122,29899,29765,30707,30763,30628,32924,32975,33053,32924,32782,32733,8894,9004,9026,22083,22032,22271,22083,22045,22032,21757,21987,21909,33014,33000,32963,22480,22643,22410,22466,22643,22480,32924,32733,32852,9657,9563,9622,9608,9563,9657,9608,9811,9533,9811,9912,9782,26672,26408,26367,9399,9302,9377,9317,9235,9339,9108,9117,9284,9229,9302,9399,12965,13001,12976,28550,28581,28652,9462,9428,9592,16931,17211,17836,17997,18261,17930,16548,16720,16176,24883,24928,24837,23944,23735,23938,9001,8869,9266,8996,8883,9010,9010,8883,8986,8986,8922,9093,8939,8869,9001,8939,9001,8895,9001,8987,8895,8987,8989,8895,13625,13855,13903,30707,30365,30389,8895,8989,8892,26434,26383,26366,26177,25887,26134,26575,26383,26434,26575,26434,26649,27034,26887,27112,31760,31788,31369,32467,32443,32264,18066,17950,18037,18037,17950,18064,9004,9009,9028,8860,9009,9004,19437,19398,19518,18949,18796,18937,22059,22083,22552,8892,8989,8912,8869,8861,9266,14088,13885,14151,14483,14868,14836,20879,20722,20613,19491,19437,19604,19604,19437,19518,21034,21061,21431,21034,21218,21006,21619,21431,21595,21800,21833,21772,27726,27729,27636,27252,27422,27021,31281,31455,31350,31487,31760,31369,31054,30968,30837,32060,31760,31487,8912,8989,8992,14011,13885,14088,18261,18330,18343,17930,17751,17638,22059,21833,22045,28467,28351,28418,27182,27216,27383,28071,28350,28347,27726,27636,27535,18826,18796,18949,23938,23735,23803,8864,8912,8992,14533,14483,14836,24928,25196,25091,27641,27383,27581,28581,28467,28418,32235,32674,31665,32382,32387,32240,32442,32387,32382,32442,32382,32448,9009,8963,9028,8860,8963,9009,15017,14963,14971,14676,14963,14764,19398,19281,19480,19298,19281,19398,21987,22219,22200,27034,26725,26887,33055,33025,32885,8936,9018,8918,33168,33107,32961,33008,33093,33080,33080,33141,33014,33014,33164,33000,33168,32961,33153,11772,11649,11646,11646,11419,11522,11522,11319,11493,11034,11194,11378,12202,11884,12145,11870,11884,12202,12257,12404,12353,12176,12257,12092,25461,25620,25475,25998,26202,26151,25580,25620,25461,10789,10787,10910,10733,10849,10632,13588,13625,13903,12176,12202,12257,27886,28049,27933,30763,30823,30628,30952,30823,31009,11884,11817,11772,29828,29803,29675,29675,29803,29497,28548,28550,28652,28581,28550,28467,29880,29803,29828,29880,29871,29975,8896,9209,9268,9371,9305,9586,8890,9250,9055,17657,17500,17562,17950,17853,17788,17882,17853,17950,29975,29980,30086,8861,8883,9058,16960,17211,16931,9108,9284,9115,8918,9118,9146,25346,25358,25296,10609,10517,10678,9782,9912,9617,10851,10955,10766,14033,14011,14088,13686,13588,13903,14033,14088,14255,27744,27598,27673,27727,27598,27744,30086,29980,30035,30823,31054,30837,31183,31196,31281,8918,8770,8805,21030,21453,21639,21757,21957,21987,22253,22377,22219,21566,21453,21539,32497,32442,32448,32396,32176,32540,32694,32705,32480,32480,32716,32519,9229,9235,9317,9229,9317,9302,17624,17500,17657,8936,8918,8771,12250,12671,12932,12965,12768,13001,12250,12396,12271,30237,30086,30035,30112,30086,30124,10874,11187,10910,10522,10733,10632,10522,10632,10541,27729,27886,27622,28049,28078,28071,28121,27886,28043,8963,8951,9043,8940,8951,8963,11319,11461,11493,26050,26202,25998,27632,27519,27422,27422,27519,27535,26050,25837,25923,22643,22897,22826,22621,22897,22643,25923,25837,25620,31788,32005,31776,32112,32005,32181,32005,31788,32181,32975,32924,32852,32959,33055,32885,32976,32700,33021,32135,31770,31979,8883,8922,8986,21453,21664,21639,22928,22952,22897,32005,32135,31979,33153,32796,33062,33153,33062,33083,11419,11319,11522,30156,30304,30038,30314,30122,29765,30314,30294,30489,30314,30489,30528,18250,18115,18292,17853,17882,17657,18430,18774,18796,32751,32736,32555,32981,32661,32843,26429,26672,26367,19281,18961,19032,19298,18961,19281,33110,33055,32959,8922,8937,9093,9014,9305,9371,9484,9752,9961,33794,33093,33008,33000,33185,32963,33083,33062,33025,9428,9369,9520,9314,9369,9428,27252,27021,27032,31054,31179,31183,31130,31179,31054,31196,31179,31241,28411,28215,28351,28510,28351,28467,11319,11224,11461,30122,30304,30156,14483,14377,14276,14503,14377,14483,17211,17441,17545,17422,17441,17263,22897,22952,22958,22466,22480,22377,26672,26792,26506,32480,32414,32694,32705,32716,32480,10053,10129,10174,10766,10955,10985,10766,10985,10844,27889,27796,27871,27182,27112,27216,27182,27034,27112,33093,33141,33080,16720,16960,16931,15929,16548,16176,9563,9462,9592,10457,10104,10097,8951,9005,9055,8868,9005,8951,22377,22200,22219,9115,9284,9217,9117,9037,9161,9175,9339,9170,18115,18066,18037,18009,18066,18115,17638,17751,17545,18330,19116,19333,28965,29487,28581,30304,30363,30038,9170,9339,9235,17587,17638,17545,8937,8894,9026,10053,10098,10027,27641,27581,27598,26177,26171,26383,26792,26998,27032,33141,33164,33014,10844,10985,11007,28121,28078,28049,28121,28049,27886,8979,9037,9117,18568,18430,18796,22952,23045,23222,22928,23045,22952,12176,12056,12202,11884,11870,11817,11817,11649,11772,11160,11119,11224,12353,13146,12951,25358,25580,25461,25196,25346,25174,25278,25346,25196,25161,25196,24928,24233,24737,24837,12056,11870,12202,13543,13535,13352,13686,13903,13885,13625,13457,13519,14377,14250,14276,31179,31196,31183,31281,31196,31434,9617,9912,10129,28187,27889,27871,28550,28510,28467,18961,18826,18949,18944,18826,18961,19604,19894,19588,22083,22059,22045,22552,22083,22271,22466,22621,22643,22524,22621,22466,32748,32582,32356,33164,33162,33000,33133,33083,33025,26177,26134,26171,24090,23622,24484,26575,26649,26670,9191,9229,9399,9136,9229,9149,23938,24144,23944,32582,32497,32448,32442,32516,32387,30237,30167,30374,11870,11649,11817,11034,11008,11194,26750,26649,26725,31403,31455,31281,18203,18337,18330,17638,17904,17930,8869,8853,8861,8861,8648,8883,8883,8807,8922,8922,8807,8937,8937,8786,8894,8939,8853,8869,8738,8853,8939,8842,8939,8895,8842,8895,8849,8895,8892,8849,8892,8830,8849,8912,8830,8892,13803,13885,14011,8894,8860,9004,8850,8860,8894,8912,8808,8830,8864,8808,8912,27034,26750,26725,8864,8800,8808,9175,9115,9217,9006,8979,9117,9136,9170,9235,9486,9462,9563,9486,9563,9608,11119,11378,11224,10874,10910,10787,11477,11503,11577,17441,17587,17545,17638,17808,17904,17422,17587,17441,23803,23508,23230,24978,25161,24928,28510,28411,28351,32396,32467,32264,32540,32467,32396,32736,32748,32308,32945,32748,32736,18203,18261,17997,23045,23195,23222,23067,23195,23045,33165,33133,33025,32924,32986,32959,33053,32986,32924,8864,8848,8800,11327,11503,11477,21034,21006,20921,20921,20794,20879,21431,21619,21800,30086,30112,29975,29975,30112,29880,29880,30336,29803,28965,29242,29487,28550,28548,28510,28510,28457,28411,30449,30374,30167,33551,33244,33673,33093,33213,33141,33141,33213,33164,33164,33213,33162,33244,32920,33673,33233,33107,33168,33233,33168,33153,25397,25358,25346,25397,25580,25358,26050,26248,26202,26202,26429,26367,26672,26611,26792,27126,27252,26998,8992,8936,8848,8860,8919,8963,8850,8919,8860,10098,10053,10174,10457,10568,10104,10573,10517,10609,10585,10851,10766,19437,19298,19398,19418,19298,19437,33165,33025,33055,33247,33233,33153,8848,8936,8771,14250,14033,14255,27727,27641,27598,26585,26670,26604,27727,27744,27869,11017,11327,11462,10601,10874,10787,10962,11017,11398,10641,10787,10733,16795,16960,16720,28411,28313,28192,28458,28313,28411,9136,9115,9175,9503,9486,9608,10743,10585,10766,13457,13535,13519,13803,13686,13885,18066,17882,17950,14503,14533,14676,17816,17882,18066,18250,18292,18430,18250,18430,18359,25302,25397,25346,28187,27871,28192,8771,8918,8805,18359,18430,18520,18175,18203,18020,21539,21453,21030,18281,18203,18175,32674,32235,32387,8919,8940,8963,9005,8890,9055,9209,9014,9371,8776,8940,8919,24883,24978,24928,25161,25278,25196,25053,24978,24883,33247,33153,33083,33113,33165,33055,10252,10568,10517,14377,14330,14250,14122,13929,14033,14676,14533,14836,14503,14403,14369,8918,9146,8770,21772,21431,21800,26585,26177,26383,26585,26383,26575,26162,26248,26050,26162,26050,25923,32005,32112,32135,32135,32540,32176,32181,31788,32060,26301,26429,26202,10528,10573,10585,11215,11224,11319,13457,13625,13582,13582,13625,13588,28313,28187,28192,28454,28187,28313,8770,9072,8804,8770,9252,9072,21664,21670,21757,21453,21566,21664,19116,18330,18337,25923,25620,25834,25284,25278,25161,22253,22219,22183,22862,22928,22897,26750,26670,26649,26882,26750,27109,33419,32843,32873,32975,32852,32837,33110,33113,33055,32975,32837,32976,10585,10573,10609,10743,10766,10680,10305,10541,10448,9994,10309,9972,13686,13582,13588,13929,13803,14011,13929,14011,14033,8659,8807,8883,21566,21670,21664,31455,31469,31339,31434,31403,31281,31130,31054,30952,33247,33083,33305,11119,11034,11378,29242,29497,29685,32694,32414,32791,32414,32443,32791,24978,25284,25161,24737,24233,24144,12092,11976,12056,12056,11976,11870,11870,11801,11649,11649,11419,11646,11119,11160,11034,11848,11976,11819,11976,11837,11870,33211,33083,33133,33110,32959,32986,33211,33133,33165,10946,11007,11008,13415,13582,13686,13457,13352,13535,18020,17997,17904,17263,17441,17211,28078,28350,28071,27857,27886,27729,27726,27535,27519,27726,27519,27632,12671,12768,12965,15186,14633,14378,11846,12250,12271,11476,11630,11503,24990,24484,24912,21146,21218,21431,25720,25525,25887,23637,23803,23230,24582,24737,24144,22666,22897,22621,32497,32516,32442,32598,32516,32497,32598,32497,32582,33175,33110,32986,32421,32603,33021,10097,10027,10098,10053,9847,10129,9533,9503,9608,9995,10027,10097,10863,11017,10962,11327,11311,11503,10863,10962,10874,28548,28457,28510,8807,8786,8937,8940,8868,8951,8776,8868,8940,10573,10396,10517,10528,10396,10573,14122,14033,14250,13803,13777,13686,22377,22524,22466,22401,22524,22377,27570,27182,27383,27889,27727,27869,28247,27727,27889,28189,27889,28187,27252,27032,26998,30952,31054,30823,33175,32986,33053,33187,33211,33165,11589,11419,11649,19588,19894,20006,18783,18796,18826,33162,33195,33000,33310,33213,33093,25620,25580,25834,26248,26301,26202,27126,26998,26792,26207,26301,26248,10522,10641,10733,14533,14503,14483,15017,15295,14764,27570,27383,27641,26531,26672,26429,31009,30823,30763,31403,31469,31455,31494,31469,31403,11296,11311,11327,12981,13294,13001,16487,16541,16548,16548,16795,16720,16960,17012,17211,22928,23067,23045,22862,23067,22928,25590,25397,25533,25590,25580,25397,26510,26531,26429,30112,30185,29880,28548,28557,28457,30253,30124,30086,30253,30086,30237,32112,32168,32135,32292,32168,32112,10925,10946,11008,10743,10528,10585,10925,11008,11034,30363,30707,30389,30629,30707,30363,30436,30363,30304,30314,30304,30122,32791,32443,32769,32887,32603,32716,16541,16795,16548,32704,32598,32582,32704,32582,32781,22524,22638,22621,22468,22638,22524,8804,9072,8584,26006,25720,25887,26420,25887,26177,26585,26575,26670,11419,11215,11319,30374,30703,30487,30436,30314,30528,33139,32945,32751,33139,32751,32981,32516,32517,32387,32608,32517,32516,28274,28350,28121,27527,27632,27422,31130,31241,31179,31274,31241,31130,8842,8738,8939,8853,8737,8861,8807,8754,8786,8451,8738,8842,8451,8842,8849,8730,8849,8830,8730,8830,8808,8730,8808,8800,8730,8800,8848,8730,8848,8394,8848,8771,8733,8738,8737,8853,8786,8850,8894,8754,8850,8786,9170,9136,9175,9006,9117,9108,9229,9136,9235,9191,9399,9211,9399,9369,9211,9486,9443,9462,9533,9811,9782,10946,10844,11007,10783,10844,10946,13415,13457,13582,13415,13352,13457,12092,12056,12176,25302,25346,25278,28121,28350,28078,27857,27729,27726,33213,33195,33162,14369,14330,14377,13929,13777,13803,31241,31434,31196,32060,31788,31760,9006,9108,9003,11215,11160,11224,19212,18961,19298,18009,17816,18066,18203,18281,18337,18203,17997,18020,17638,17627,17808,30424,30374,30487,30314,30436,30304,32725,32716,32705,33095,33175,33053,8737,8722,8861,21006,20919,20921,21043,20919,21006,21043,21006,21218,8868,8890,9005,8780,8890,8868,22638,22666,22621,22823,22666,22638,33187,33165,33113,33095,33053,32975,21218,21034,21431,8733,8771,8805,33187,33113,33612,9503,9443,9486,21772,21833,22059,27953,27705,27786,27150,27126,26792,29685,29497,29803,28457,28458,28411,16862,17012,16960,16862,16960,16795,24582,24144,24475,24837,25053,24883,17012,17263,17211,32835,32725,32705,32835,32705,32694,10844,10680,10766,10396,10252,10517,10590,10680,10844,17882,17813,17657,18009,18115,18250,25471,24990,25451,9633,9752,9484,10522,10511,10641,9097,9632,9305,26245,26207,26162,26162,26207,26248,26301,26510,26429,26531,26611,26672,26343,26207,26245,17638,17587,17627,21688,21518,21804,8850,8776,8919,8708,8776,8850,10125,10252,10187,9617,9533,9782,11976,11848,11837,11837,11801,11870,11419,11396,11215,11215,11096,11160,12092,12353,12561,14330,14122,14250,19313,19212,19298,19451,19437,19491,22183,22219,21987,33195,33185,33000,33415,33612,33562,11848,11801,11837,11976,12092,11921,13904,13777,13929,27705,27857,27726,27705,27726,27632,28652,28557,28548,14330,14169,14122,14503,14369,14377,14676,14836,14963,25053,25284,24978,25590,25834,25580,11801,11589,11649,10883,10925,11034,8657,8733,8805,8657,8805,8693,9503,9424,9443,9424,9533,9394,19212,19062,18961,17741,17813,17816,19081,19062,19212,21670,21957,21757,21566,21539,21670,21488,21518,21539,8890,8905,9250,8851,8905,8890,11311,11476,11503,11276,11476,11311,11296,11327,11017,12250,12436,12671,12314,12436,12250,22666,22862,22897,23637,23230,23195,22823,22862,22666,33157,33095,32975,33415,33305,33187,33157,32975,32976,10883,11034,10896,10125,10104,10252,10808,10863,10874,10808,10874,10601,17816,17813,17882,18009,18250,18109,17627,17587,17422,23637,23195,23182,28557,28458,28457,26670,26750,26882,8734,8804,8584,9003,9108,9115,9314,9462,9443,9314,9428,9462,9136,9003,9115,11345,11396,11419,16885,16862,16795,17012,16979,17263,17646,17627,17422,24737,24816,24837,24745,24816,24737,30124,30185,30112,28712,28597,28557,28557,28597,28458,30284,30185,30124,30284,30124,30253,32598,32608,32516,32781,32582,32991,9633,9994,9972,14925,14490,14560,25302,25533,25397,25302,25278,25284,27527,27422,27252,27857,28043,27886,9072,9037,8584,22253,22401,22377,22339,22401,22253,9396,9314,9443,16487,16548,16288,32517,32618,32387,32691,32608,32598,32725,32887,32716,32872,32887,32725,10894,11296,11017,10601,10787,10641,10863,10894,11017,10452,10511,10522,27845,28043,27857,29765,30294,30314,8480,8754,8807,8776,8780,8868,20006,20305,20613,26207,26343,26301,27126,27170,27252,26245,26162,25923,18109,18250,18359,19116,18337,18281,17969,18020,17904,17969,17904,17808,8724,8780,8692,17813,17624,17657,17741,17624,17813,17646,17422,17249,19062,18944,18961,19019,18944,19062,25533,25574,25590,25413,25302,25284,26604,26670,26882,25471,25038,24990,27034,27182,27254,26343,26510,26301,21688,21957,21670,33195,33329,33185,33419,33286,32843,33213,33325,33195,33432,33310,33093,33432,33093,33794,33591,33107,33233,33447,33233,33247,33305,33083,33211,9191,9149,9229,9141,9211,9369,24475,24144,23938,24816,25053,24837,31117,31131,30952,30952,31131,31130,30436,30453,30363,30528,30453,30436,29028,28815,28350,28160,28274,28121,33187,33612,33415,33181,33157,32976,31599,31494,31434,31434,31494,31403,31009,30763,30707,10252,10104,10568,10528,10743,10680,31316,31434,31241,14139,14169,14210,14369,14169,14330,13351,13415,13342,14764,14925,14560,19588,19451,19491,33310,33325,33213,16862,16979,17012,16885,16979,16862,16288,16548,15929,9533,9424,9503,9092,9191,9211,9943,10053,10027,18040,18281,18175,17856,17969,17808,18040,17969,17947,25542,25574,25533,25676,25574,25554,30453,30629,30363,11921,11819,11976,11848,11611,11801,11801,11667,11589,11589,11345,11419,11921,11857,11799,12353,12951,12561,13004,13543,13352,8754,8708,8850,10856,10894,10863,10511,10601,10641,10569,10601,10511,11611,11667,11801,11096,11034,11160,13548,13415,13686,13904,13929,14122,19451,19418,19437,20794,20722,20879,19588,19530,19451,19451,19530,19418,20794,20921,20919,20794,20919,20864,20919,20949,20864,28454,28189,28187,28454,28313,28458,33325,33329,33195,33187,33305,33211,33194,33175,33095,20919,21043,20949,33232,33181,32976,33157,33194,33095,10104,9995,10097,26611,27150,26792,27705,27845,27857,28043,28160,28121,8737,8635,8722,8722,8648,8861,8754,8673,8708,8555,8635,8737,8555,8737,8738,8555,8738,8451,20949,21043,21060,8780,8851,8890,8905,8896,9260,8724,8851,8780,11667,11535,11589,18944,18783,18826,18848,18783,18944,8635,8662,8722,10925,10783,10946,11250,11215,11396,10856,10863,10808,13220,13004,13352,28712,28557,28652,32424,32540,32135,32564,32540,32670,8662,8648,8722,16885,16795,16587,24582,24745,24737,24612,24745,24582,27953,27845,27705,31131,31274,31130,31117,31274,31131,32704,32691,32598,32833,32781,32928,32793,32781,32833,32769,32443,32467,32887,33021,32603,19418,19313,19298,19519,19313,19418,21957,22183,21987,22468,22823,22638,22862,22846,23067,24744,24794,24745,26105,26245,25923,26466,26611,26510,26510,26611,26531,32042,31487,31469,9092,9149,9191,9271,9369,9314,32835,32872,32725,8648,8659,8883,9015,9271,9314,24794,25053,24816,32805,32691,32704,32608,32618,32517,8664,9003,8622,9006,8866,8979,26585,26471,26177,26471,26604,26568,26466,26510,26343,31494,31560,31469,31690,31560,31494,10481,10528,10680,9821,9943,9874,22468,22524,22401,8913,8866,9006,8834,8896,8905,25676,25834,25590,25676,25590,25574,10883,10783,10925,10768,10783,10883,10720,10856,10808,11345,11250,11396,12436,12513,12671,12314,12513,12436,12314,12250,11846,12271,11420,11846,11311,11296,11276,30336,29685,29803,30424,30284,30253,30424,30253,30374,22183,22282,22253,33329,33335,33185,32691,32618,32608,25542,25533,25302,30374,30449,30703,9995,9943,10027,9847,9943,9821,9994,10305,10448,10601,10720,10808,31274,31316,31241,31584,31316,31752,18783,18568,18796,17929,17741,17816,18730,18568,18783,22282,22339,22253,22823,22846,22862,22851,22846,22823,14561,14503,14676,10659,10720,10601,11041,11296,10907,15017,15785,15295,17929,17816,18009,32989,33021,32887,17249,17422,17263,16587,16795,16541,24745,24794,24816,25413,25542,25302,24043,23938,23803,32691,32815,32618,32781,32793,32704,32805,32793,32833,10305,10452,10522,11250,11096,11215,12513,12768,12671,18240,18109,18359,30703,31174,31056,29765,29530,30294,30453,30669,30629,30770,31009,30707,33047,32989,32887,32791,32835,32694,32829,32835,32791,9424,9396,9443,9394,9396,9424,25554,25542,25557,8693,8805,8770,8733,8616,8848,8734,8770,8804,21539,21688,21670,21957,22016,22183,22183,22172,22282,22282,22172,22339,18040,18175,18020,8683,9014,9209,27150,27170,27126,27382,27170,27150,8584,9037,8979,19081,19019,19062,19081,19212,19313,22339,22453,22401,22428,22453,22339,8539,8693,8492,9847,9617,10129,9752,9633,9972,10063,10275,10305,9484,9961,9632,22552,21772,22059,22552,22450,22954,8709,8834,8905,8896,8762,9209,8709,8905,8851,18568,18520,18430,18405,18520,18461,32181,32292,32112,32540,32648,32467,32288,32292,32181,33203,33194,33157,33203,33157,33181,10187,10252,10396,10750,10590,10844,10750,10844,10783,10767,10894,10856,10569,10659,10601,11799,11819,11921,13415,13351,13352,13220,13351,13342,30770,30707,30629,26245,26466,26343,27562,27426,27681,25834,25876,25923,25754,25876,25834,25754,25834,25676,32564,32648,32540,32042,32060,31487,31828,31469,31560,9003,8913,9006,8866,8785,8979,8823,8913,9003,17969,18040,18020,17646,17808,17627,17006,17263,16979,30295,30284,30420,30295,30185,30284,30336,29880,30185,22453,22468,22401,22696,22468,22604,11096,10896,11034,28779,28712,28652,28597,28592,28458,26420,26471,26568,31361,30449,30724,30420,30284,30424,30669,30770,30629,25730,25754,25676,25554,25574,25542,29685,29487,29242,9149,9032,9136,9141,9092,9211,9141,9369,9271,9014,9097,9305,9943,9847,10053,9939,9995,10104,32793,32805,32704,33139,32748,32945,11535,11486,11589,11004,10992,11096,11096,10992,10896,11667,11486,11535,11611,11486,11667,11611,11848,11819,11611,11819,11799,19611,19530,19588,33329,33347,33335,33362,33139,32981,33325,33374,33329,33310,33432,33325,33470,33432,33794,18520,18405,18359,18109,17929,18009,18321,18405,18461,18240,18405,18321,33113,33110,33612,33298,33203,33181,10590,10481,10680,10546,10481,10590,10767,10856,10684,10452,10569,10511,10542,10569,10433,28086,28160,28043,30294,29530,29293,27953,28043,27845,11486,11345,11589,12513,12582,12768,10856,10720,10684,25413,25284,25053,8652,8780,8776,8638,8776,8708,10896,10768,10883,10850,10768,10896,10684,10720,10512,12768,12981,13001,16587,16541,16487,12709,12981,12768,23375,22552,22954,28712,28592,28597,28595,28592,28779,8566,8673,8489,14764,14561,14676,13342,13415,13392,14560,14561,14764,21810,22016,21957,11041,11276,11296,18091,17929,18109,16572,15795,15785,18621,19116,18281,17856,17947,17969,30420,30424,30487,32873,33185,33419,10187,10396,10528,30613,30420,30487,22016,22135,22183,33432,33374,33325,33305,33415,33247,33524,33415,33562,20722,20647,20613,20794,20647,20722,20621,20647,20794,20866,20794,20864,25643,25413,25053,32424,32135,32168,32769,32829,32791,8635,8555,8662,8662,8589,8648,8648,8495,8659,8489,8673,8754,8511,8555,8295,8616,8733,8657,10099,10187,10528,10768,10750,10783,10633,10750,10768,10512,10720,10659,11041,11267,11276,26604,26471,26585,24990,24404,24484,28247,27889,28189,26288,26466,26245,26288,26245,26105,25923,25876,26105,25876,26042,26105,28592,28454,28458,28595,28454,28592,32333,32424,32168,32268,32288,32181,21060,21043,21218,21060,21218,21146,9349,9484,9632,10569,10452,10433,10512,10542,10433,16885,17006,16979,17646,17856,17808,16775,17006,16885,16587,16487,16288,32667,32467,32648,33047,32887,32872,33021,33232,32976,8555,8589,8662,20949,21060,20866,12253,12582,12513,9092,9032,9149,9076,9032,9092,8673,8638,8708,8566,8638,8673,33374,33347,33329,32333,32168,32292,17857,17856,17646,18082,18281,18040,23182,23195,23067,24794,24853,25053,23182,23067,22846,22851,22823,22738,8834,8762,8896,9014,8488,9097,8724,8709,8851,8639,8709,8724,8913,8785,8866,8539,8657,8693,8823,8785,8913,18405,18240,18359,18848,18944,19019,33407,33185,33335,10127,10187,10099,9939,9943,9995,11004,11096,11250,12582,12709,12768,13351,13220,13352,13415,13548,13392,20418,20006,20613,19099,19081,19313,23637,24043,23803,30703,30613,30487,30765,30613,30703,32650,32667,32648,32650,32648,32564,9045,9141,9015,9357,9394,9533,9366,9394,9357,10032,10104,10125,9847,9582,9617,9996,10032,10125,10992,10888,10896,10750,10546,10590,30770,31275,31009,31009,31117,30952,30528,30669,30453,30489,30669,30528,9270,9314,9396,8688,8823,8664,22696,22823,22468,32805,32815,32691,32618,32674,32387,32928,32781,32991,8638,8652,8776,8604,8652,8638,10032,9939,10104,19519,19418,19530,17857,18040,17947,11004,10762,10992,10992,10762,10888,11233,11004,11345,12561,12951,13004,24043,24475,23938,8539,8616,8657,8693,8770,8492,10633,10546,10750,10569,10542,10659,11296,10894,10907,10452,10305,10275,14139,14122,14169,12960,12561,13004,15631,15929,15664,17885,17857,17773,32667,32769,32467,32740,32769,32667,25876,25754,25730,27426,27252,27170,27786,27705,27632,10888,10850,10896,10762,10850,10888,33047,32872,32835,33047,32835,33054,33481,33447,33247,33432,33470,33374,33374,33470,33347,33481,33247,33415,33481,33569,33447,25730,25554,25557,25730,25676,25554,32776,32650,32564,32288,32333,32292,32341,32333,32288,32341,32288,32268,31599,31434,31316,27527,27252,27426,28764,28350,28274,8652,8692,8780,8601,8692,8652,33499,33407,33335,33499,33335,33347,15051,15664,15370,8504,8539,8492,11276,11267,11476,12460,12577,12582,12582,12577,12709,10894,10767,10794,15631,16288,15929,21688,21804,21957,22016,22034,22135,22135,22172,22183,21539,21030,21488,32611,32540,32424,33414,33194,33203,28266,28247,28189,28266,28189,28454,31275,31117,31009,8785,8584,8979,8622,9136,9032,25557,25542,25413,28779,28592,28712,33251,33232,33021,21804,21810,21957,33407,33419,33185,33046,32991,33106,33065,32820,32833,33460,33419,33407,9141,9076,9092,9045,9076,9141,24475,24612,24582,24593,24612,24475,24744,24612,24593,24475,24513,24593,16587,16775,16885,17006,16775,16912,32833,32820,32805,32582,32748,32991,9939,9874,9943,9695,9582,9847,9808,9874,9939,9931,9939,10032,10127,10125,10187,14210,14169,14369,17814,17624,17741,28385,28274,28160,30669,31275,30770,32853,32829,32769,33054,32835,32829,33275,33251,33021,9394,9366,9396,9357,9533,9617,25633,25557,25413,14403,14503,14561,27660,27681,27557,31584,31599,31316,32650,32740,32667,32853,32740,32888,27953,28086,28043,27980,28086,27953,8692,8639,8724,8709,8694,8834,8553,8639,8692,19081,18848,19019,18730,18848,18890,12960,13004,13220,13222,13220,13342,12253,12513,12314,12709,12690,12981,14014,14633,13996,21810,22034,22016,33551,33008,33244,14560,14403,14561,31690,31828,31560,9695,9847,9821,26471,26420,26177,26750,27034,27109,32518,32341,32605,32562,32528,32424,32815,32674,32618,14014,13996,13265,17900,17825,17929,17929,17825,17741,18461,18520,18568,27562,27681,27692,26105,26194,26288,25730,26042,25876,26194,26042,26156,30698,30498,30420,30347,30336,30295,30295,30336,30185,28773,28779,28931,28931,28779,28652,30936,30765,30703,8480,8807,8659,22034,22147,22135,10542,10512,10659,10305,9754,10063,13392,13222,13342,20647,20418,20613,18697,18730,18890,20866,20621,20794,20866,20864,20949,20866,21060,21146,28257,28385,28160,18848,18730,18783,19611,19588,19822,22851,23182,22846,22428,22468,22453,24612,24744,24745,24475,24043,24513,27109,27034,27254,32820,32815,32805,32991,33301,33214,20621,20418,20647,21146,21431,21772,10341,10528,10481,10449,10481,10546,14139,13904,14122,14038,13904,14139,25471,25451,25720,33050,32815,32820,8589,8495,8648,8555,8511,8589,8451,8849,8730,8451,8730,8347,32423,32424,32333,25038,24404,24990,10331,10275,10137,28086,28257,28160,27947,27980,27953,33621,32920,33107,33621,33107,33622,11857,11921,12092,11233,11345,11486,14403,14210,14369,27527,27786,27632,27681,27426,27557,31599,31690,31494,31828,32042,31469,31713,31690,31599,8566,8604,8638,8601,8604,8285,10850,10633,10768,11004,11250,11345,12561,11857,12092,11420,12271,11476,11420,11476,11267,18091,18109,18240,17856,17857,17947,16923,17263,17006,20804,21146,21472,20450,20425,20528,22147,22172,22135,29741,29487,29685,28663,28266,28454,32253,32042,31828,33259,33251,33275,33232,33298,33181,33622,33107,33591,11144,11420,11267,8382,8495,8589,33591,33447,33569,33591,33233,33447,9249,9349,9632,9463,9994,9633,9249,9632,9097,24404,24090,24484,33282,33298,33232,8639,8694,8709,8599,8694,8639,22696,22738,22823,22702,22738,22696,10907,10894,10794,10331,10433,10452,13548,13686,13777,13222,13154,13220,27570,27641,27928,28343,28266,28502,28373,28257,28346,29331,29293,28815,30347,30295,30498,33470,33499,33347,33362,32981,33286,33597,33499,33735,11846,12253,12314,13265,13996,12981,9015,9141,9271,9076,8981,9032,13904,13874,13777,14121,14038,14139,12460,12709,12577,31690,31842,31828,31752,31316,31274,31713,31584,31729,8978,8981,9076,33462,33286,33419,32928,33065,32833,25891,25471,25720,26822,26568,26604,26822,26604,26882,8604,8601,8652,8519,8601,8285,32740,32853,32769,33270,33232,33251,32888,32740,32650,8823,8760,8785,8688,8760,8823,8560,8762,8834,8560,8834,8694,32528,32611,32424,32341,32423,32333,32518,32423,32341,10767,10651,10794,21804,21872,21810,21810,21906,22034,22034,22070,22147,22070,22298,22172,20697,21030,20746,33569,33481,33546,10762,10633,10850,10415,10633,10424,32423,32562,32424,8539,8504,8616,8492,8770,8459,8450,8480,8659,33546,33481,33524,11446,11486,11611,8601,8553,8692,8519,8553,8601,22172,22428,22339,22298,22428,22172,33499,33460,33407,33597,33460,33499,18148,18091,18240,18730,18461,18568,18697,18461,18730,9366,9270,9396,9582,9357,9617,32707,32611,32528,8480,8489,8754,33524,33481,33415,13840,13874,13904,13169,13154,13222,11777,11799,11857,13169,13222,13392,27641,27727,27928,10767,10684,10651,17825,17814,17741,18148,18240,18321,33110,33718,33612,33270,33282,33232,33270,33251,33259,14210,14121,14139,13739,13624,13874,14077,14121,14210,14077,14210,14403,14490,14403,14560,27928,27727,28196,27426,27562,27527,28158,28257,28086,26560,26466,26288,31584,31713,31599,32518,32548,32423,31842,31713,31848,8981,8900,9032,8971,8978,9076,8971,9076,9045,13600,13548,13777,24744,24853,24794,25981,26042,25730,24513,24043,24419,23182,22851,22738,32376,30813,31665,30498,30295,30420,32991,33046,32928,32815,33050,32674,33106,32991,33214,32939,33054,32829,32939,32829,32853,8459,8770,8734,19822,19588,20006,21518,21872,21804,9357,9270,9366,9207,9463,9484,8841,9249,9097,32611,32670,32540,32970,32888,32650,10820,10794,10710,33493,33362,33286,14014,14378,14633,19611,19519,19530,21872,21906,21810,27570,27254,27182,33175,33718,33110,10633,10449,10546,10415,10449,10633,11799,11674,11611,11777,11674,11799,11777,11410,11605,13292,13169,13392,11605,11410,11430,28158,28086,27980,28257,28373,28385,11674,11590,11611,12960,13220,13154,32674,32376,31665,32363,32376,32486,26042,26194,26105,25981,25730,25861,8553,8599,8639,8519,8599,8553,22428,22604,22468,22409,22604,22428,33460,33462,33419,33565,33462,33460,18091,17900,17929,17937,17900,18091,33021,33328,33275,33414,33203,33298,25861,25730,25795,27562,27786,27527,27856,27786,27692,32562,32707,32528,32795,32776,32670,32423,32548,32562,32181,32060,32268,26006,25887,26420,26890,26822,26882,26890,26882,27109,28779,28773,28595,28266,28343,28247,28931,28652,29487,31056,30936,30703,13624,13600,13874,13874,13600,13777,13548,13292,13392,9996,9931,10032,9874,9695,9821,9094,9263,9357,9996,10125,10127,22845,23182,22738,31713,31842,31690,31729,31584,31752,8978,8900,8981,8917,8971,8942,16912,16923,17006,16912,16775,16718,16775,16508,16718,16587,16508,16775,16306,16508,16587,24593,24767,24744,24513,24767,24593,25633,25730,25557,9734,9695,9874,9357,9263,9270,11041,11144,11267,11420,11529,11846,11818,12460,12253,11077,11144,10971,10822,11041,10907,30420,30613,30698,30465,29741,29685,33414,33298,33282,8394,8616,8308,8394,8848,8616,8511,8382,8589,8495,8450,8659,8480,8447,8489,20621,20609,20418,20418,20355,20006,19611,19676,19519,20804,20609,20621,20804,20621,20866,20804,20866,21146,19116,20697,20366,21518,21618,21872,22019,22070,21906,20987,20913,21105,10433,10370,10512,10794,10820,10907,10275,10331,10452,10063,9754,10011,13422,13292,13548,12970,12960,13154,16923,17249,17263,17857,17885,18040,20804,20450,20528,28644,28454,28595,27189,27109,27254,33724,33673,33621,33621,33673,32920,33551,33794,33008,33724,33621,33635,33621,33622,33635,33622,33591,33635,33591,33629,33635,33569,33629,33591,12970,13154,12985,20528,20355,20418,28773,28644,28595,28758,28644,28773,30698,30613,30765,33912,33631,33551,33569,33798,33629,17900,17814,17825,17937,17814,17900,18148,18321,18257,17773,17857,17646,25643,25633,25413,33428,33414,33282,33184,32989,33047,8358,8382,8511,8489,8314,8566,9931,9808,9939,16572,16230,15795,13739,13874,13840,8382,8430,8495,28196,27727,28247,27110,26890,27109,27786,27947,27953,27856,27947,27786,33428,33282,33270,33569,33546,33798,8568,8584,8785,8568,8785,8760,9647,9734,9618,9971,9996,10127,19099,18848,19081,32253,32268,32042,31752,31274,31117,33462,33493,33286,33106,33065,33046,33545,33493,33462,8398,8616,8504,8398,8504,8492,11595,11605,11430,12985,13154,13169,13068,12985,13169,13432,13422,13548,13432,13548,13600,22070,22172,22147,22604,22702,22696,22070,22034,21906,28343,28196,28247,28291,28196,28343,28145,28158,27980,33652,33612,33834,33707,33546,33524,26487,26420,26568,25038,24683,24404,24404,23957,24090,32670,32776,32564,33125,33094,33054,33054,33094,33047,32795,32670,32611,8430,8450,8495,12253,12460,12582,14459,14794,14378,11818,12253,11846,17471,17500,16425,30923,30765,30936,30923,30698,30765,17210,17322,17249,17682,17773,17646,16288,15631,15881,24767,24853,24744,24719,24853,24767,33046,33065,32928,33050,33065,33098,27150,26611,27382,25981,26156,26042,26037,26156,25981,25934,25981,25861,8917,8900,8978,8917,8978,8971,24419,24043,24234,32939,32853,32888,8998,9015,9314,8998,9314,9270,32970,32939,32888,17682,17646,17322,17885,18082,18040,20987,21488,21030,33360,33428,33270,33184,33021,32989,18439,18321,18461,19519,19099,19313,18504,18439,18461,19025,19099,19147,22298,22319,22428,22333,22319,22298,25795,25934,25861,25795,25730,25633,27110,27109,27189,26822,26856,26568,33735,33499,33857,10651,10684,10416,20102,19822,20006,33707,33524,33761,10449,10341,10481,10424,10633,10442,10633,10582,10442,33199,33184,33047,28064,28145,27980,27692,27786,27562,28064,27980,27947,8303,8398,8492,8450,8447,8480,9459,9357,9582,9459,9582,9695,9808,9734,9874,9734,9808,9702,17500,17624,16671,16425,17500,16671,25643,25795,25633,27189,27254,27414,31729,31848,31713,31859,31848,31729,8285,8604,8566,8496,8560,8694,11777,11605,11674,11674,11595,11590,11590,11446,11611,12661,12561,12960,22319,22409,22428,23861,24043,23637,22333,22409,22319,12460,12690,12709,29751,28931,29487,28502,28291,28343,11595,11446,11590,17913,18082,17885,17322,17646,17249,33652,33683,33612,33360,33270,33259,33360,33259,33275,11446,11233,11486,17210,17249,16959,15734,15631,15479,28346,28257,28158,28764,28385,28373,28764,28274,28385,30489,30789,30669,33065,33050,32820,32748,33301,32991,10415,10341,10449,9702,9808,9931,10307,10341,10415,32748,33139,33301,33094,33199,33047,33514,33360,33275,33266,33125,33054,14490,14349,14403,14771,14349,14490,33683,33524,33562,33683,33562,33612,16671,17624,17814,33493,33519,33362,33597,33565,33460,33642,33565,33597,10416,10684,10512,16759,16923,16912,33327,33199,33316,32017,31752,31117,13904,14038,13840,13068,13169,13144,27856,28064,27947,28177,28346,28158,28107,28064,27856,8471,8694,8599,8762,8683,9209,18586,18461,18697,18148,17937,18091,32548,32573,32562,32933,32970,32650,33266,33257,33125,32268,32060,32042,31828,31842,31956,8254,8459,8734,26865,26856,26888,26890,26856,26822,31956,31842,31848,15295,15222,14764,15795,15542,15785,15393,15542,15465,26611,26466,26749,25934,26037,25981,25783,26037,25934,26560,26497,26691,32518,32573,32548,32026,31956,31848,30294,30617,30489,8664,8823,9003,8237,8303,8210,18087,17937,18148,19099,18890,18848,18665,18890,18871,28143,27934,27928,27414,27254,27570,27110,27054,26890,28663,28454,28644,28177,28158,28145,31174,30703,30449,31174,30449,31361,15031,15631,15051,32721,32707,32562,8622,9003,9136,8942,8971,9045,8942,9045,9015,24513,24648,24767,24853,25643,25053,23861,23637,23579,22019,21906,21872,22637,22702,22604,27934,27570,27928,33175,33194,33718,8519,8471,8599,8449,8471,8346,9463,9633,9484,10370,10416,10512,13432,13292,13422,12970,12785,12960,13840,14038,13974,22637,22604,22409,28143,27928,28196,33565,33545,33462,33717,33545,33565,9263,9198,9270,9094,9198,9263,15734,15881,15631,32814,32795,32611,10341,10099,10528,10633,10762,10582,10370,10433,10331,13432,13600,13549,20355,20140,20006,19822,19773,19611,20609,20528,20418,20804,20528,20609,22139,21772,22552,27728,27677,27570,31242,31174,31519,31752,31859,31729,31956,32253,31828,31905,31859,31752,32856,32650,32776,33327,33184,33199,8451,8295,8555,8382,8366,8430,8430,8297,8450,8450,8363,8447,8447,8314,8489,8266,8295,8451,8347,8730,8394,8347,8394,8359,10710,10822,10820,10820,10822,10907,11144,11077,11420,12600,13265,12690,10710,10794,10651,8295,8358,8511,13549,13600,13624,28291,28253,28196,28406,28253,28291,28863,28764,28731,28107,28177,28145,28107,28145,28064,8611,8568,8760,8542,8475,8526,33328,33021,33184,33806,33652,33762,33328,33184,33327,20346,20289,20355,33199,33094,33316,8359,8394,8308,8358,8366,8382,20289,20140,20355,33724,33909,33673,33673,33912,33551,33638,33519,33545,33635,33811,33724,33748,33811,33635,33748,33635,33907,33635,33868,33907,18439,18257,18321,16343,16230,16425,18312,18257,18439,27640,27414,27570,8366,8297,8430,8471,8481,8694,8449,8481,8471,9647,9459,9695,9647,9695,9734,10484,10710,10651,26624,26487,26568,26764,26568,26856,26764,26856,26865,30975,30923,30936,30584,30505,30498,30498,30505,30347,30465,29685,30336,30975,30936,31042,33798,33546,33754,15393,15339,15295,13974,14038,14121,15222,15339,15311,32845,32856,32776,26624,26764,26865,32376,32363,30813,32352,32363,32440,8308,8616,8330,10416,10580,10651,10234,10370,10331,11605,11595,11674,11446,11366,11233,10582,10762,11004,11777,11857,11410,32996,32743,33236,33106,33098,33065,33205,33098,33106,33194,33414,33718,33754,33546,33707,11351,11366,11446,30505,30336,30347,28319,28143,28253,8330,8398,8303,8330,8616,8398,13631,13549,13624,14077,14403,14196,16306,16587,16288,16718,16759,16912,33301,33446,33405,32707,32814,32611,32795,32845,32776,32573,32721,32562,32729,32721,32573,32584,32573,32518,10267,10099,10341,12879,12970,12985,13631,13624,13739,28253,28143,28196,27934,27728,27570,27677,27640,27570,28758,28773,28931,8297,8363,8450,14196,14403,14349,18665,18586,18697,18665,18697,18890,33545,33519,33493,33499,33470,33857,8611,8760,8688,8611,8688,8542,9702,9931,9723,22070,22333,22298,23579,23637,23182,33794,33551,33900,16425,16230,16572,17898,17814,17937,16140,16306,16288,33257,33316,33125,32856,32933,32650,32973,32933,32856,8303,8492,8459,30584,30498,30698,32729,32814,32707,10307,10267,10341,10307,10415,10424,13134,13265,12600,12690,13265,12981,14818,15031,15051,10352,10580,10416,12879,12785,12970,12879,12985,13068,29023,28758,28931,28764,28373,28731,8363,8328,8447,19834,19773,19822,21488,21618,21518,22070,22204,22333,21607,21618,21488,30732,30584,30698,33900,33551,33631,33754,33707,33761,9723,9931,9755,33735,33642,33597,33723,33642,34084,8249,8683,8762,8481,8496,8694,8449,8496,8481,18586,18504,18461,18257,18087,18148,18601,18504,18586,8998,8942,9015,8622,9032,8900,9198,9139,9270,9070,9139,9198,13635,13631,13739,13169,13292,13144,13635,13739,13840,16508,16759,16718,17885,17773,17891,16672,16759,16508,23579,23182,23422,24419,24487,24513,32838,32845,32795,14020,13974,14077,14077,13974,14121,27798,27728,28026,26856,26890,27054,27640,27728,27798,26288,26194,26560,29051,29028,28764,8303,8459,8210,19773,19676,19611,33761,33524,33769,8210,8459,8254,8542,8688,8664,18136,18087,18257,15339,15222,15295,15393,15295,15542,14794,15051,14378,16134,16140,16128,15881,16140,16288,26764,26624,26568,26487,26006,26420,27110,27237,27054,10582,11004,10624,12785,12661,12960,13292,13432,13144,28758,28663,28644,28835,28663,28758,15311,15393,15415,32904,32838,32814,32814,32838,32795,32605,32584,32518,32605,32341,32268,23861,24234,24043,33550,33139,33362,33214,33205,33106,33486,33514,33275,33769,33683,33806,33316,33094,33125,32939,32970,33161,8328,8314,8447,14619,14196,14349,27110,27189,27237,33642,33723,33565,33405,33306,33301,33799,33723,34084,26296,26006,26487,25471,25394,25038,16306,16419,16508,16140,15881,16128,25891,25394,25471,24090,23834,22954,27237,27189,27414,33683,33652,33806,33769,33524,33683,8622,8900,8629,8734,8258,8254,10484,10691,10710,10710,10691,10822,10971,11144,11041,18087,17898,17937,18136,17898,18087,23422,23182,22845,24605,24368,24561,8819,8900,8917,24683,23957,24404,12729,12661,12785,13144,13432,12991,22467,22637,22409,22467,22409,22333,30789,31275,30669,33723,33717,33565,33799,33717,33723,10099,9971,10127,9965,9971,10099,10108,10099,10267,9702,9618,9734,9647,9473,9459,9459,9094,9357,9616,9618,9594,21618,22019,21872,27728,27640,27677,27728,27934,28026,26560,26194,26156,28011,28107,27856,33414,33572,33583,8942,8819,8917,8782,8819,8942,33317,33205,33214,33098,33611,33050,16536,16671,17814,15465,15542,15473,10624,11004,10507,10442,10330,10424,24234,24368,24419,24487,24368,24605,29751,29023,28931,28663,28502,28266,28764,29028,28350,31017,30789,30617,30617,30789,30489,28306,28346,28177,30788,30732,30698,31042,30936,31056,31042,31056,31123,32845,32973,32856,32729,32707,32721,33550,33362,33705,33301,33306,33214,33071,32970,32933,33572,33428,33530,9139,8998,9270,8923,8998,9139,33717,33680,33545,33799,33680,33717,10370,10352,10416,10484,10740,10691,10137,10234,10331,13512,13432,13549,12618,12661,12729,13512,13549,13631,13635,13840,13619,28648,28502,28663,8295,8192,8358,8162,8204,8366,8366,8204,8297,8297,8204,8363,8363,8244,8328,8328,8244,8314,8139,8266,8451,8139,8451,8347,8269,8347,8359,8269,8359,8308,8269,8308,8253,20528,20425,20355,20289,20265,20140,20140,20102,20006,19773,19717,19676,20265,20425,20450,34011,33912,33673,33799,33638,33680,33909,33724,33887,33724,33811,33887,33811,33748,33887,33748,33907,33887,33868,33635,33629,33888,33868,33629,20425,20346,20355,20697,20987,21030,21618,21759,22019,20230,20697,19116,26497,26560,26156,25783,25934,25795,8376,8762,8560,9207,9484,8901,13848,14132,13737,15393,15311,15339,15542,15795,15473,8806,9349,9249,10063,10011,10275,10971,10822,10740,10971,11041,10822,26560,26749,26466,12729,12879,12790,31242,31056,31174,33798,33888,33629,33798,33980,33888,33414,33428,33572,32838,32973,32845,16188,15795,16230,27860,27856,27692,33275,33328,33486,15031,15065,15631,14459,13912,14413,26296,25891,26006,26865,26840,26624,27054,26888,26856,27237,26888,27054,32363,32352,30813,32486,32376,32610,8346,8471,8519,8496,8422,8560,10740,10822,10691,18312,18136,18257,18601,18665,18871,18890,19099,19025,33680,33638,33545,33898,33470,33794,33583,33718,33414,8253,8308,8330,8253,8330,8237,8162,8366,8358,8262,8285,8566,20187,20102,20140,14196,14132,14077,14925,14764,15222,26006,25891,25720,26296,26487,26840,32584,32729,32573,33109,33060,32973,32902,32729,32584,32026,31848,31859,33931,33900,33631,33754,33982,33798,8230,8566,8314,24368,24487,24419,24648,24487,24605,28502,28406,28291,28409,28406,28553,33882,33762,33652,33754,33761,33831,30584,30571,30505,29910,29751,29741,29741,29751,29487,30788,30698,30873,30698,30923,30873,28869,28835,28758,28972,28758,29023,33761,34009,33831,23957,23834,24090,23852,23834,23957,23852,23957,23854,33344,33328,33327,33060,33071,32933,33385,33344,33327,33060,32933,32973,8237,8330,8303,18423,18439,18504,16343,16479,16344,30873,30923,30975,31017,30617,30294,33669,33362,33519,33583,33877,33718,33530,33428,33360,33831,34009,33939,33385,33327,33316,9754,10305,9994,13619,13840,13764,13144,12991,13068,19984,19834,19822,20987,21607,21488,22255,22467,22333,27461,27237,27414,28171,27934,28143,27681,27725,27692,27660,27725,27681,32022,31905,31752,32026,32022,32098,10345,10330,10442,10234,10352,10370,10291,10352,10234,28835,28648,28663,28406,28319,28253,28869,28648,28835,31519,31174,31361,31029,30873,30975,10484,10651,10580,31187,30975,31042,9755,9931,9996,10169,10108,10267,28409,28319,28406,28107,28306,28177,28206,28306,28107,8584,8321,8258,8204,8244,8363,8998,8782,8942,8819,8629,8900,8475,8542,8664,8766,8782,8718,15311,15245,15222,15415,15245,15311,15415,15393,15465,33638,33669,33519,33743,33669,33638,9075,9094,9080,9755,9996,9971,9526,9754,9994,20450,20804,21472,23854,23957,24047,24487,24648,24513,24368,24234,24561,33514,33530,33360,33477,33486,33328,14794,14818,15051,14739,14818,14794,26749,26848,26611,26744,26848,26749,26744,26749,26560,16671,16479,16425,16343,16344,16277,17913,17885,17891,17773,17682,17891,17682,17322,17476,23579,23762,23861,22845,22738,22702,22802,22702,22637,10582,10463,10442,10924,11004,11233,11295,11233,11366,11351,11446,11595,10330,10307,10424,10261,10307,10330,33446,33301,33139,33392,33317,33214,33205,33317,33098,33392,33405,33466,33344,33477,33328,33402,33385,33316,12133,11857,12561,11430,11351,11595,22204,22070,22019,8526,8568,8611,33761,33769,34009,34005,33806,33762,33882,33652,33834,11351,11295,11366,16343,16188,16230,16140,16134,16306,16128,15881,15857,33266,33054,32939,32904,32973,32838,28319,28171,28143,28409,28171,28319,8449,8422,8496,8305,8422,8449,8346,8519,8285,16479,16536,16344,18480,18423,18504,18601,18586,18665,33669,33705,33362,33859,33705,33669,30584,30722,30571,30465,30505,30571,30465,30336,30505,10624,10513,10582,10463,10513,10395,10414,10484,10580,10414,10580,10352,14132,14020,14077,13848,14020,14132,27725,27860,27692,27382,27426,27170,28553,28406,28502,29149,28972,29023,28863,29051,28764,29028,29331,28815,31905,32026,31859,32026,31905,32022,9616,9647,9618,9594,9618,9702,14453,14459,14413,27461,27414,27876,26840,26487,26624,27414,27640,27876,8175,8230,8314,11077,11104,11420,10923,11104,11077,10923,11077,10971,10923,10971,10749,30584,30732,30722,34087,33898,33794,8542,8526,8611,8475,8664,8622,18082,18200,18281,17249,16923,16959,10307,10169,10267,10108,9965,10099,9581,9594,9702,10155,10169,10207,13344,13580,14014,12600,12690,12460,30722,30732,30849,30732,30788,30849,8488,8841,9097,8847,8841,8554,24648,24719,24767,24605,24719,24648,33392,33214,33306,33161,32970,33071,8258,8734,8584,25108,25643,24853,26987,27382,26611,10513,10463,10582,10363,10463,10395,10749,10971,10740,10258,10414,10352,28972,28869,28758,29024,28869,28972,29006,28863,28731,28731,28373,28702,31242,31123,31056,31268,31123,31242,16479,16343,16425,15707,15473,15795,16188,16343,16277,17329,17210,17064,18423,18312,18439,18480,18312,18423,30849,30788,30873,33060,33161,33071,33361,33402,33316,33625,33477,33344,9894,9965,9957,13635,13512,13631,12661,12133,12561,13619,13512,13635,27853,27860,27725,27853,27725,27660,32532,32605,32268,32729,32902,32814,33610,33595,33161,8267,8346,8285,26848,26987,26611,26691,26744,26560,32743,32376,32674,31912,31519,31361,33857,33642,33735,8230,8262,8566,12618,12133,12661,31029,30849,30873,8458,8475,8406,8321,8584,8568,17913,18078,18082,17552,17891,17682,33486,33530,33514,33572,33633,33583,33590,33530,33486,26849,26987,26848,32496,32440,32363,33909,34011,33673,33912,33931,33631,33900,34156,33794,33976,34011,33909,33976,33909,33887,33976,33887,33907,33976,33907,33943,33907,33868,33943,15245,15099,15222,15415,15473,15406,33646,32674,33050,8169,8139,8347,8266,8192,8295,8033,8175,7965,8244,8175,8314,8230,8127,8262,8169,8347,8269,8169,8269,8201,8269,8253,8201,8253,8037,8201,8096,8192,8266,8841,8997,9249,9463,9526,9994,10011,10137,10275,10202,10120,10186,10169,10155,10108,10463,10345,10442,10363,10345,10463,16959,16923,16759,15718,15881,15734,17431,17476,17322,27382,27557,27426,27438,27557,27382,28171,28233,27934,28553,28502,28648,32346,30813,32352,33601,33477,33625,8192,8162,8358,8253,8237,8160,20102,19984,19822,19099,19519,19147,20346,20265,20289,20425,20265,20346,23375,22954,23834,33943,33868,33980,22086,22204,22019,22467,22802,22637,29317,29028,29051,29317,29331,29028,33898,33857,33470,34042,33857,33898,8422,8376,8560,8344,8376,8422,32440,32346,32352,20265,20187,20140,32903,32902,33004,34099,33931,33912,8782,8766,8819,8718,8782,8701,22530,22802,22467,24561,24234,24418,33601,33590,33477,33257,33361,33316,33291,33266,32939,33257,33266,33381,8160,8237,8210,8643,8629,8819,33317,33371,33098,33405,33392,33306,33567,33139,33550,33567,33550,33878,13512,12991,13432,13764,13840,13974,13764,13974,14020,31187,31029,30975,31187,31042,31123,33980,33868,33888,33980,33798,33982,9581,9702,9723,9616,9473,9647,10202,10291,10234,10749,10740,10655,22204,22255,22333,32098,32253,31956,9094,9070,9198,9075,9070,9094,25643,25783,25795,25416,25783,25643,32919,32904,32814,33760,33550,33705,20026,19984,20102,17476,17552,17682,17210,17431,17322,17329,17431,17210,33567,33446,33139,19717,19773,19834,18216,17898,18136,22802,22845,22702,22747,22845,22802,33530,33633,33572,33732,33633,33530,33799,33743,33638,33838,33743,33799,33982,33754,33831,29751,29149,29023,28831,28553,28648,11430,11252,11351,11351,11154,11295,10395,10513,10624,11865,11410,11857,33834,33612,33718,11104,11529,11420,10960,11529,11104,27846,27853,27660,28373,28346,28702,27343,27438,27382,14916,15065,15031,14916,15031,14818,14916,14818,14739,26987,27131,27382,26744,26849,26848,26497,26156,26414,13544,12991,13512,11389,11252,11410,28409,28233,28171,29032,28648,28869,26691,26849,26744,32440,32434,32346,31205,31268,31416,32486,32496,32363,32610,32496,32486,8701,8782,8998,8766,8643,8819,15473,15415,15465,15998,15795,16188,8024,8160,8210,8131,8210,8254,8676,8643,8766,8458,8448,8475,19909,19717,19834,24801,24605,24561,24719,24801,24853,33381,33361,33257,33477,33590,33486,33291,32939,33161,11529,11818,11846,12729,12785,12879,11749,12600,12460,14739,14794,14685,13619,13544,13512,13760,13764,14020,18601,18480,18504,18482,18480,18601,19147,19519,19443,23852,23854,23834,23766,23854,23968,29149,29024,28972,28863,29006,29051,28206,28107,28011,30587,29910,29741,29164,29024,29149,29164,29032,29024,30571,30562,30465,30709,30562,30571,30709,30571,30722,30709,30722,30927,33939,33982,33831,33884,33834,33718,28473,28233,28409,28011,27856,27860,17884,18078,17913,17884,17913,17891,9817,9755,9971,9894,9971,9965,10740,10484,10655,21607,21759,21618,22204,22086,22255,22255,22530,22467,21506,21759,21607,21911,21759,21596,30683,30709,30927,32026,32098,31956,32022,31752,32017,33769,33806,34009,16672,16508,16547,17418,17552,17476,33446,33466,33405,33392,33371,33317,33578,33466,33446,33475,33466,33594,9387,9526,9463,9954,10137,10011,10137,10202,10234,8958,8923,9139,10207,10169,10307,10261,10330,10345,8321,8568,8448,8568,8526,8448,9070,8958,9139,9080,9094,9459,9080,8873,8969,15659,15718,15734,16419,16306,16134,22395,22530,22255,24234,23861,24418,32904,33109,32973,32902,32919,32814,32903,32919,32902,32902,32584,33004,32903,33004,32987,8175,8244,7965,8262,8116,8285,8251,8305,8449,10395,10624,10507,12618,12264,12133,12790,12879,13068,12790,13068,12885,30927,30722,30849,31416,31268,31242,31963,30724,32346,34009,33806,34005,8448,8526,8475,8251,8449,8346,8416,8488,8683,9559,9581,9723,10655,10484,10526,17418,17476,17431,33344,33385,33625,33877,33884,33718,8158,8131,8254,8525,8622,8629,10033,9965,10108,9466,9536,9581,13764,13544,13619,13760,13544,13764,16419,16134,16216,17481,17697,17552,33429,33291,33574,33625,33385,33402,16807,16959,16759,33475,33371,33392,32804,32610,32376,27941,27853,27846,27846,27557,27438,32471,31963,32346,32404,32268,32253,32217,32022,32204,19025,18871,18890,18920,18871,19025,10155,10033,10108,10363,10261,10345,10184,10261,10363,12729,12553,12618,12885,13068,12991,28346,28306,28593,28702,28346,28593,16216,16134,16128,10039,10033,10155,15415,15099,15245,15090,15099,15068,8179,8158,8254,8175,8127,8230,10258,10352,10291,10322,10484,10414,15099,14925,15222,15479,15659,15734,14794,14453,14685,21759,21996,22019,32604,32610,32686,32512,32434,32440,34005,33762,33882,34005,33882,33993,8305,8344,8422,8199,8344,8305,26840,26865,26888,25405,25260,25394,26840,26888,26983,33859,33760,33705,33466,33475,33392,33859,33669,33743,9207,9387,9463,14794,14459,14453,26849,26947,26987,27045,26947,26849,27045,26849,26982,8075,8267,8285,33877,34032,34033,8158,7964,8083,8258,8179,8254,8127,8116,8262,16277,16042,16188,18216,18136,18312,21996,22086,22019,26947,27131,26987,32512,32440,32496,18078,18200,18082,17697,17884,17891,17697,17891,17552,23766,23675,23834,23766,23834,23854,33590,33732,33530,33703,33732,33590,8383,8525,8629,8498,8629,8643,8676,8766,8718,33625,33402,33553,10261,10207,10307,10184,10207,10261,10291,10202,10186,10202,10137,10120,12773,12553,12729,12688,12885,12678,28344,28306,28206,34011,34050,33912,33931,34083,33900,33933,33838,34054,34034,34050,34011,34034,34011,33976,34034,33976,34141,33976,33943,34035,33943,34048,34035,34055,34048,33943,8139,8096,8266,8192,7846,8162,7965,8244,8204,8175,8033,8127,8127,8033,8116,8010,8096,8139,8062,8139,8169,8062,8169,8201,8062,8201,7963,8253,8080,8037,8160,8080,8253,33980,34055,33943,9075,8958,9070,8613,8676,8718,9536,9616,9594,15718,15857,15881,15479,15631,15065,32919,33040,32904,32404,32253,32435,27853,28011,27860,28042,28011,27853,18480,18216,18312,18482,18216,18480,18118,18200,18078,8160,8024,8080,8592,8676,8472,9581,9536,9594,9559,9723,9755,16959,17064,17210,16672,16807,16759,16737,16807,16672,16547,16508,16419,24605,24801,24719,27326,27247,27174,23762,23422,23488,28157,28344,28206,32383,32253,32098,33429,33381,33266,33429,33266,33291,16375,16547,16419,10924,11233,11295,22530,22747,22802,22595,22747,22530,31268,31187,31123,31205,31187,31268,33993,33882,33834,33977,33877,34033,33980,34108,34055,32686,32610,32804,33578,33446,33567,34099,34083,33931,33980,33982,34108,8969,8958,9075,10884,10923,10614,10884,11104,10923,10884,10960,11104,11529,11749,11818,10923,10749,10614,15655,15857,15718,8806,9484,9349,8841,8847,8997,8488,9014,8683,16479,16671,16536,15267,15099,15415,16151,16216,16128,19443,19519,19676,18549,18482,18601,19984,19909,19834,19717,19688,19676,20187,20026,20102,20450,20026,20187,20450,20187,20265,33993,33834,33884,34077,33982,33939,8406,8475,8622,8448,8283,8321,8083,7964,7972,8406,8622,8525,23675,23375,23834,24683,25038,25260,28344,28593,28306,9817,9894,9957,9817,9971,9894,9556,9559,9755,10933,10924,11295,11252,11430,11410,10631,10749,10655,30709,30683,30562,30587,29741,30465,30927,30849,30995,8210,8131,8024,20026,19944,19984,33690,33578,33567,33601,33703,33590,33940,33884,33877,33497,33402,33361,34077,33939,34009,12773,12729,12790,29024,29032,28869,28671,28473,28409,29389,29149,29751,21105,21607,20987,18049,18118,18078,18049,18078,17884,23418,23375,23675,8416,8683,8228,8267,8251,8346,7907,8251,8267,13848,13760,14020,15099,15090,14925,15998,16188,16042,14916,15076,15065,15659,15655,15718,14744,15076,14916,33760,33878,33550,33838,33799,34054,32610,32604,32496,32434,32541,32346,32376,32743,32804,8024,8131,8083,12688,12787,12885,12787,12773,12790,14132,14196,13737,19944,19909,19984,16102,15998,16042,28011,28157,28206,28344,28365,28593,28042,28157,28011,15660,15406,15473,14739,14698,14916,14378,13912,14459,32604,32512,32496,32404,32532,32268,33574,33291,33595,33381,33497,33361,10080,10039,10155,10080,10155,10207,16807,17064,16959,16737,17064,16807,17348,17064,17114,23762,23579,23422,26414,26037,25783,33531,33497,33381,10186,10258,10291,10137,9954,10120,12787,12790,12885,11389,11410,11865,8371,8283,8448,8415,8406,8525,9468,9473,9536,9536,9473,9616,9080,8969,9075,9468,9536,9466,14378,14014,13710,17348,17431,17329,27131,27247,27382,27174,27247,27131,26156,26037,26414,18347,18482,18453,16536,17814,17010,22369,22395,22255,23371,23422,22845,34052,34077,34009,33940,33993,33884,33817,33633,33732,10526,10631,10655,17866,18049,17884,18621,18281,18200,23522,23418,23745,22139,21146,21772,17064,17348,17329,8083,8131,8158,8179,7868,7964,19729,19688,19717,18549,18601,18871,32903,33040,32919,32987,33040,32903,27247,27343,27382,9957,9965,10033,9934,9957,10033,10262,10184,10363,10262,10363,10395,9631,9711,9954,10322,10526,10484,10631,10526,10500,11389,11619,11239,12750,12787,12688,29032,28831,28648,28233,28026,27934,29033,28831,29032,29331,29506,29293,32204,32022,32017,29006,29317,29051,29136,29317,29006,29136,29006,28731,29136,28731,28995,29136,28995,29215,13748,13737,13668,13760,13496,13544,34052,34009,34005,33838,33859,33743,33933,33859,33838,33697,33703,33601,33697,33601,33625,8371,8448,8458,33745,33817,33732,8676,8592,8643,8211,8371,8458,8701,8998,8645,25260,25038,25394,23745,23418,23675,8158,8179,7964,7965,8204,7846,8116,8056,8285,22086,22074,22255,21996,22074,22086,21759,21911,21996,18289,18200,18183,26414,25783,26392,27247,27326,27343,32604,32599,32512,32804,33034,32816,34156,34087,33794,12618,12553,12487,10611,10507,11004,12487,12553,12773,16277,16102,16042,15998,15780,15795,17814,17898,17010,11252,11154,11351,22395,22595,22530,22421,22595,22395,10322,10414,10258,10011,9754,9487,33578,33594,33466,33475,33608,33371,33690,33594,33578,15469,15479,15213,15076,15479,15065,15974,16151,16128,16737,16672,16547,14698,14739,14685,19688,19443,19676,30587,30465,30562,30683,30587,30562,30779,30587,30683,34087,34042,33898,34174,34052,34127,34052,34005,34127,18183,18200,18118,18183,18118,18145,17866,17884,17697,28412,28026,28233,28157,28365,28344,27941,28042,27853,16287,16102,16277,28731,28702,28995,31146,30995,31029,31416,31242,31519,31416,31519,31912,31361,31963,31912,9466,9581,9559,9934,10033,10039,22595,22697,22747,22623,22697,22595,33977,33940,33877,8218,8371,8211,8179,8258,7868,8645,8998,8923,9181,9080,9459,9556,9755,9458,9473,9181,9459,14453,14698,14685,13710,14014,13580,15479,15655,15659,17840,17866,17714,27343,27482,27438,27045,27131,26947,33040,33109,32904,32803,32584,32605,33703,33745,33732,33877,33583,34032,21911,22074,21996,24683,24047,23957,33689,33697,33625,33957,34015,33745,33553,33402,33497,33553,33497,33531,8096,7874,8192,8062,8010,8139,7963,8010,8062,7963,8201,8006,8201,8037,8006,8037,8080,8006,23236,22552,23375,20026,19939,19944,19944,19939,19909,19909,19823,19717,19688,19494,19443,34303,34308,34050,34050,34099,33912,34083,34156,33900,34087,34353,34042,34121,34141,33976,34121,33976,34160,33976,34035,34160,34035,34178,34160,34048,34178,34035,16344,16287,16277,18217,17898,18216,18482,18217,18216,18347,18217,18482,18289,18621,18200,18145,18118,18049,23406,23236,23375,23218,23236,23406,30995,30849,31029,34048,34114,34178,8033,8056,8116,7969,8056,8033,8006,8080,7948,34308,34099,34050,34048,34055,34114,27368,27482,27343,33174,33109,33040,8530,8498,8643,8530,8643,8592,33531,33381,33429,34127,34005,34143,33583,33633,34032,16163,16287,16410,34114,34055,34520,10631,10614,10749,10884,10902,10960,10960,10937,11529,11818,11749,12460,10500,10614,10631,10193,10258,10186,29317,29506,29331,29543,29506,29317,31146,31029,31187,34099,34177,34083,34108,33982,34077,13848,13748,13760,14771,14490,14925,28381,28365,28157,27846,27660,27557,15267,15068,15099,15090,14811,14925,15267,15415,15406,15267,15406,15290,22907,22845,22747,32697,32599,32604,33611,33098,33371,32532,32803,32605,32987,33174,33040,32941,32803,32867,32727,32532,32404,14910,14811,15090,26983,26888,27237,26013,25394,25891,15869,15998,16102,26724,26849,26691,27326,27368,27343,25035,24853,24801,24907,24801,24736,8383,8415,8525,10120,10193,10186,10212,10193,10113,12787,12750,12773,12555,12750,12688,17348,17418,17431,18210,18289,18183,17265,17418,17348,16737,16547,16643,32541,32434,32512,31205,31146,31187,33594,33608,33475,33804,33690,33855,33957,33745,33703,34166,33940,34248,33553,33689,33625,14385,14698,14453,15692,15857,15655,26724,26691,26497,32697,32604,32789,7948,8080,8024,7948,7917,7939,10611,11004,10924,9959,9934,10039,10339,10500,10526,20450,19939,20026,18468,18621,18289,18468,18289,18395,22697,22907,22747,22623,22907,22697,7972,8024,8083,19939,19916,19909,19443,19108,19147,34177,34156,34083,8056,8075,8285,8762,8376,8249,7952,8075,8056,22074,22369,22255,27984,28062,27941,27135,27174,27131,32599,32541,32512,16375,16419,16216,24736,24801,24561,33073,33004,32584,33574,33531,33429,8669,8923,8958,8498,8383,8629,8472,8530,8592,8376,8184,8249,8806,9249,8997,16737,17114,17064,33670,33608,33594,19916,19823,19909,27335,27368,27326,18621,18817,19116,17968,18049,17866,23236,22996,22552,23218,22996,23236,33859,33974,33760,34084,33642,34131,33974,33933,34146,11252,11158,11154,11154,11022,11295,11389,11239,11252,11865,11857,12133,15974,16128,15857,15974,15857,15692,19823,19729,19717,22369,22421,22395,32022,32217,32098,31017,31275,30789,34174,34108,34077,34174,34077,34052,8969,8932,8958,8907,8932,8969,9957,9831,9817,10080,10207,10184,11239,11158,11252,28381,28157,28262,29136,29215,29317,28062,28042,27941,8211,8458,8406,8453,8383,8498,8376,8344,8199,11158,11022,11154,10212,10322,10258,29389,29164,29149,28671,28409,28553,28995,28702,28834,10937,10902,10772,10772,10902,10884,14014,13265,13344,10532,10614,10466,9332,9181,9473,9420,9556,9458,10094,10080,10184,9332,9473,9468,8806,8997,8691,9299,9487,9526,14811,14771,14925,15068,14910,15090,15083,14910,15068,15083,15068,15267,16120,15869,16102,15780,15869,15827,27045,27135,27131,27174,27335,27326,26554,26724,26497,26554,26497,26414,7846,8204,8162,11365,11749,10912,26763,26554,26802,30855,30779,30865,30927,30779,30683,30587,30676,29910,29910,29389,29751,30779,31026,30865,33933,33974,33859,33690,33674,33594,33642,33857,34131,8701,8613,8718,8423,8453,8498,8350,8613,8387,8488,8554,8841,7959,8554,8488,14806,14771,14811,24907,25035,24801,24940,25035,24907,26840,26798,26296,26968,26983,27049,10507,10262,10395,10140,10262,10103,12555,12487,12773,12555,12773,12750,24047,23968,23854,24216,23968,24047,24216,24047,24683,29164,29146,29032,26968,26798,26983,29216,29146,29164,15412,15290,15406,24418,24736,24561,33553,33658,33689,33957,33703,33697,33649,33531,33644,17840,17968,17866,17866,17697,17714,33934,33878,33760,16151,16375,16216,17001,17265,17114,17114,17265,17348,16355,16375,16290,27846,27438,27672,12054,11865,12133,9934,9831,9957,9834,9831,9934,27368,27475,27482,27115,27135,27045,32305,31912,31963,31360,31146,31205,8082,8321,8283,8218,8283,8371,19582,19494,19688,34005,33993,34143,18706,18817,18621,18706,18621,18679,34131,33857,34042,8294,8406,8415,8423,8498,8530,16780,17114,16737,33802,33674,33690,33608,33611,33371,32217,32252,32098,32259,32252,32217,10839,10611,10924,30560,31017,30294,30560,30294,29506,32541,32557,32346,32578,32557,32541,32578,32541,32599,10080,9959,10039,9895,9959,10080,16247,16410,16837,15707,15780,15827,18549,18871,18792,23406,23375,23418,22462,22139,22552,10322,10339,10526,10193,10212,10258,10113,10193,10120,12487,12369,12618,12885,12991,12678,29146,29033,29032,29096,29033,29146,28834,28702,28593,29215,29367,29317,28834,28593,28604,8551,8645,8923,8873,8907,8969,33004,33174,32987,33160,33174,33004,33160,33004,33237,8294,8415,8383,8199,8305,8251,8416,8152,8488,8199,8251,7907,18581,18621,18468,17481,17552,17418,18679,18621,18581,17445,17481,17418,8082,8258,8321,9556,9466,9559,9420,9466,9556,22782,22552,22996,8513,8472,8676,8296,8294,8383,8513,8676,8613,25056,25108,25035,25035,25108,24853,33659,33611,33608,32789,32604,32686,13053,13134,12779,14413,14385,14453,32252,32383,32098,32017,31117,31921,8010,7874,8096,7877,7874,8010,7877,8010,7923,8010,7963,7923,7790,7811,7923,7790,7923,7963,15869,15780,15998,16102,16287,16163,10140,10094,10262,10262,10094,10184,12388,12369,12487,12678,12991,12756,13668,13760,13748,29535,29389,30072,31360,31205,31416,8006,7948,7939,8011,8267,8075,34141,34265,34034,34099,34256,34177,34177,34232,34156,34149,34054,34084,34121,34265,34141,34222,34265,34121,34222,34121,34160,34222,34160,34272,34160,34178,34272,34178,34212,34272,7948,8024,7917,8427,8423,8530,8788,8958,8932,9487,9754,9526,33802,33670,33674,33674,33670,33594,33649,33658,33553,34143,33993,34166,33649,33553,33531,34178,34114,34212,7924,7969,8033,7924,8033,7965,33993,33940,34166,34212,34114,34608,34055,34108,34192,13737,13748,13848,14910,14806,14811,14899,14806,14910,15083,15267,15105,18145,18049,17968,22914,22782,22996,26983,26798,26840,26983,27237,27461,34084,34054,33799,34031,33934,33760,33855,33690,33567,34353,34087,34156,9299,9526,9176,20230,19116,19218,20230,20987,20697,22254,22369,22074,22344,22445,22369,22369,22445,22421,18832,18817,18706,32447,32383,32252,34325,34256,34099,34192,34108,34174,32557,32544,32346,32816,32686,32804,10310,10339,10322,10310,10322,10212,34256,34228,34177,11239,11173,11158,11158,11059,11022,11022,10933,11295,11120,11173,11239,11059,11173,10914,7969,7952,8056,7924,7952,7969,8296,8383,8453,15692,15655,15469,17102,17445,17265,17265,17445,17418,15655,15479,15469,17481,17714,17697,17981,18145,17968,16780,16737,16643,23522,23406,23418,23218,23113,22996,24246,24216,24683,33855,33567,33923,32699,32578,32599,34228,34232,34177,28995,29112,29215,28604,28593,28365,17981,17968,17840,23675,23766,23745,22907,23371,22845,24958,24940,24736,24736,24940,24907,23095,23371,22907,23488,23371,23534,11010,10933,11022,10055,10140,10059,10902,10937,10960,10772,10884,10532,19108,19025,19147,16287,16344,16410,30855,30676,30587,30855,30587,30779,8907,8788,8932,9132,8873,9080,9132,9080,9181,33291,33161,33595,32941,32584,32803,8338,8296,8453,8472,8427,8530,8350,8513,8613,8472,8350,8339,9458,9755,9817,9844,9834,9934,9844,9934,9959,16643,16547,16588,24418,23861,24253,26886,26763,26802,28262,28157,28042,28262,28042,28062,10532,10884,10614,10144,10310,10212,12264,12369,12388,27935,27798,28026,29389,29216,29164,29096,29216,29240,9466,9393,9468,9323,9393,9466,10933,10839,10924,10614,10500,10466,27316,27335,27174,27316,27174,27135,26982,26849,26724,27672,27438,27482,31088,30927,30995,32720,32544,32557,7917,8024,7785,19308,19108,19443,33633,34015,34032,34189,34192,34174,8339,8427,8472,32996,32804,32743,33670,33659,33608,33774,33659,33670,33633,33817,34015,33060,33610,33161,7919,8024,7972,19729,19686,19688,19494,19543,19443,19823,19838,19729,19916,19838,19823,19939,19838,19916,19806,19838,19939,19685,19838,19806,8044,8082,8283,7905,7919,7972,8268,8211,8406,8268,8406,8294,8836,8788,8907,15780,15707,15795,16344,16536,16410,15479,15076,15087,16355,16547,16375,17535,17714,17481,17981,17714,17972,16536,16837,16410,8044,8283,8218,18549,18536,18482,18598,18536,18549,33817,33745,34015,8199,8184,8376,8249,8228,8683,8055,8184,8199,23745,23766,23968,23056,23113,23299,23371,23488,23422,22623,22595,22421,34031,33760,33974,33804,33802,33690,7952,8011,8075,7866,8011,7952,8338,8453,8423,9458,9817,9310,22254,22074,22098,32544,32471,32346,31354,31088,31146,32383,32435,32253,32447,32435,32383,33891,33802,33804,34451,34131,34042,34186,33923,33934,34189,34174,34127,9332,9468,9393,9034,9132,9181,8873,8836,8907,26554,26763,26724,25285,25643,25108,32830,32816,32938,32697,32699,32599,32580,32539,32544,32544,32539,32471,32867,32803,32532,13737,14196,14356,12388,12487,12555,19838,19686,19729,26013,25891,26296,27640,27798,27876,26763,26982,26724,28270,28262,28062,28381,28604,28365,31921,31117,31275,32204,32259,32217,32830,32789,32686,31146,31088,30995,31360,31375,31354,19108,18920,19025,18838,18920,19023,22782,22462,22552,19806,19939,20033,22602,22462,22782,26982,27115,27045,27335,27475,27368,28207,28270,28062,32779,32699,32697,34235,34189,34127,34116,33940,33977,16780,17001,17114,16375,16151,16290,24940,25056,25035,24958,25056,24940,33595,33610,33691,33634,33574,33744,18536,18453,18482,18490,18453,18536,18679,18676,18706,18210,18395,18289,18210,18183,18145,23113,23218,23299,34033,34116,33977,33697,34372,33957,33689,34163,33697,10094,10041,10080,10262,10507,10103,9987,10113,10120,10310,10282,10339,9987,10120,9954,12779,13134,12600,12779,12600,12141,13710,13912,14378,13727,13912,13710,16866,17001,16780,19686,19582,19688,28574,28604,28381,28834,29112,28995,33634,33644,33531,8211,8125,8218,8145,8268,8164,33923,33567,33878,15725,15660,15707,18421,18217,18347,16130,16151,15974,26013,26296,26400,24216,24138,23968,15993,16130,15974,15087,15076,14744,17714,17981,17840,18145,17981,18140,33689,33658,33779,9323,9332,9393,27115,27316,27135,7905,7972,7964,19582,19543,19494,24253,23861,23762,34235,34127,34143,19806,20033,19663,22730,22602,22782,22445,22623,22421,22593,22623,22445,15993,15974,15693,8773,8836,8873,8788,8669,8958,15707,15660,15473,14619,14349,14771,15827,15869,15914,10140,10041,10094,9718,9817,9831,9420,9323,9466,10055,10041,10140,27935,28026,28221,27394,27475,27335,32470,32305,31963,32720,32557,32578,7868,7905,7964,14619,14771,14806,12388,12555,12488,14111,14385,14413,13659,13727,13710,28553,28831,28792,32470,31963,32471,32270,32259,32204,33289,33073,32941,9895,9844,9959,28792,28831,29033,32017,32270,32204,32028,31921,32013,10103,10181,9900,10933,10779,10839,11173,11059,11158,11619,11389,11865,24246,24138,24216,23299,23218,23406,33855,33835,33804,33774,33646,33659,33592,33276,33236,33946,33835,33855,33923,33878,33934,34031,33974,34123,34195,34116,34032,33779,33658,33649,11059,11010,11022,34131,34149,34084,34190,34149,34131,10144,10282,10310,12369,12264,12618,12555,12688,12488,16643,16866,16780,17001,17102,17265,16355,16588,16547,16407,16588,16355,25056,25087,25108,25016,25087,25056,31360,31553,31375,15725,15827,15914,16654,16866,16643,9718,9831,9834,27475,27672,27482,29262,29112,29067,32614,32470,32471,15105,15267,15290,14899,15083,15075,32779,32711,32699,32699,32711,32578,32539,32614,32471,32816,32830,32686,33050,33611,33646,16130,16290,16151,16213,16290,16130,8164,8268,8294,8427,8338,8423,8339,8338,8427,8472,8513,8350,10113,10144,10212,9988,9987,9946,13344,13265,13134,12141,12600,11749,14722,14619,14806,18224,18210,18140,18581,18676,18679,18210,18145,18140,29096,29146,29216,29017,28792,29033,33646,33611,33659,32941,33073,32584,32867,32532,32727,33759,33779,33649,33759,33649,33644,33634,33531,33574,34146,33933,34054,34303,34050,34034,34256,34325,34228,34228,34307,34232,34232,34285,34156,34303,34034,34265,34303,34265,34331,34265,34322,34331,34222,34322,34265,34272,34322,34222,34272,34212,34322,34322,34212,34608,7923,7811,7877,7877,7718,7874,7874,7846,8192,7790,7963,7731,7963,8006,7731,8006,7939,7827,7939,7805,7827,7600,7846,7874,31026,30779,30927,30855,30795,30676,30676,30712,29910,31026,30927,31088,34331,34322,34435,7939,7917,7805,7859,7868,7771,7837,7868,7859,8125,8211,8145,7806,7924,7965,7800,8055,8199,34274,34235,34143,34435,34835,34514,34299,34143,34166,34116,34033,34032,18581,18468,18505,7917,7791,7805,13496,13760,13668,10755,11010,10792,18963,19116,18817,22098,22074,21911,32779,32697,32789,34445,34325,34099,13648,13496,13668,13648,13668,13737,13344,13134,13053,13727,13866,13912,28552,28412,28473,28473,28412,28233,15693,15974,15692,8145,8211,8268,23965,23745,23968,23113,22914,22996,30994,31026,31157,8152,8228,7949,8691,8997,8847,8055,8249,8184,13659,13866,13727,27935,27876,27798,27905,27876,27935,8646,8669,8788,8655,8773,8873,8655,8873,9132,9034,9181,9332,8691,8847,8426,9176,9526,9387,9988,10113,9987,21335,21607,21105,23534,23762,23488,24971,24736,24597,26400,26296,26798,27049,26798,26968,27049,26983,27461,34325,34307,34228,10466,10500,10358,10772,10848,10937,10937,10848,11529,10500,10339,10358,9930,9895,10080,9219,9323,9320,9930,10080,10041,28792,28671,28553,28629,28671,28783,10052,10144,10113,12054,12133,12264,12472,12488,12688,16247,16207,16410,18792,18598,18549,18792,18871,18920,18832,18963,18817,18505,18468,18395,23056,22914,23113,22426,22139,22462,26886,26921,26763,24971,24958,24736,23893,23762,23534,29240,29216,29271,29067,29112,28834,28270,28381,28262,33774,33670,33802,33109,33610,33060,34149,34146,34054,34190,34146,34149,34195,34032,34362,7917,7785,7791,21193,21335,21105,33109,33357,33610,8613,8701,8387,8164,8294,8296,33855,34045,33946,33891,33835,33946,33891,33804,33835,33891,33774,33802,33824,33759,33644,33779,34163,33689,34195,34248,34116,22254,22344,22369,22332,22344,22254,8024,7919,7785,10358,10339,10282,15827,15725,15707,16120,16102,16163,16207,16163,16410,21335,21506,21607,34307,34285,34232,18421,18347,18453,23534,23371,23459,13580,13659,13710,13306,13344,13119,27984,27941,27846,7785,7919,7837,12756,12991,13544,13627,13648,13737,13462,13659,13580,27943,27984,27846,32259,32374,32252,32171,32270,32017,34285,34316,34156,10181,10611,10839,15083,14899,14910,13685,13627,13737,15105,15290,15242,18598,18490,18536,18641,18490,18598,18832,18706,18784,18224,18505,18395,18224,18395,18210,23893,24253,23762,33855,33923,34089,7938,8267,8011,10233,10358,10282,14899,14722,14806,27115,27152,27316,27316,27394,27335,27740,27759,27672,27672,27759,27846,26982,27152,27115,26763,26921,26982,25285,25108,25087,32727,32404,32755,33691,33574,33595,15412,15406,15660,7773,7866,7952,7806,7952,7924,18706,18676,18784,26921,27152,26982,32711,32720,32578,32848,32779,32789,32848,32789,32830,8646,8788,8836,27878,27759,27740,19582,19613,19543,19023,18920,19108,19686,19685,19582,19838,19685,19686,22426,22462,22602,34316,34353,34156,24958,25016,25056,24971,25016,24958,14111,14413,13912,15562,15693,15692,14449,14385,14274,29262,29367,29215,32028,32017,31921,29262,29215,29112,31360,31354,31146,31360,31416,31553,32895,32720,32711,32470,32433,32305,32257,32214,31912,16290,16407,16355,16654,17102,16866,18140,17981,17972,16213,16407,16290,16213,16130,15993,25216,25285,25087,18490,18421,18453,18562,18421,18490,22914,22730,22782,23299,23406,23480,8125,8044,8218,8164,8296,7951,12243,12264,12388,12756,13544,13176,24138,23965,23968,23745,23662,23522,24246,23965,24138,24246,24683,24512,7837,7919,7905,7837,7905,7868,24066,24597,24253,22707,22907,22623,28412,28221,28026,27876,27790,27461,28168,28221,28339,28629,28473,28671,29067,28834,29025,27984,28207,28062,28398,28207,28287,11010,10779,10933,10755,10779,11010,12243,12388,12213,10682,10772,10662,10682,10848,10772,10441,10532,10466,30901,30795,30855,30901,30855,30865,30901,30865,30994,9320,9323,9420,8593,8646,8836,9718,9834,9844,9768,9844,9895,32714,32580,32544,8669,8551,8923,7951,8296,8338,8531,8551,8669,15422,15412,15660,16207,16120,16163,16076,16120,16207,28000,27905,27935,27878,27943,27846,27878,27846,27759,32270,32374,32259,32458,32374,32270,12213,12388,12488,30994,30865,31026,7866,7938,8011,7830,7938,7866,19447,19443,19543,18784,18676,18581,18963,19218,19116,22344,22593,22445,22332,22593,22344,34116,34248,33940,34055,34192,34520,34195,34362,34398,9992,9930,10041,9992,10041,10055,7868,8258,7771,19613,19447,19543,8052,8044,8125,8034,8164,7951,8600,8646,8593,8806,8901,9484,8426,8847,8554,9899,10103,9900,29096,29141,29033,29535,29216,29389,28834,28939,29025,34173,33934,34031,33891,33972,33774,33774,33951,33646,8052,8125,8145,23890,23662,23745,27525,27672,27475,26921,27190,27152,26392,26554,26414,33051,32938,32816,32747,32714,32720,32720,32714,32544,33034,32804,32996,14744,14916,14698,33051,33034,33123,33123,33034,32996,7938,7870,8267,7853,7870,7938,14722,14614,14619,14858,14614,14722,14858,14722,14899,14858,14899,14907,18838,18792,18920,18710,18792,18838,18832,18913,18963,18760,18784,18581,18887,18784,18760,27011,27049,27125,32938,32848,32830,34254,34123,33974,34451,34190,34131,8741,8901,8633,26566,26392,26421,17010,17898,17160,15648,15660,15725,9768,9718,9844,19447,19411,19443,21978,22098,21911,10358,10441,10466,10233,10441,10358,15914,15869,16120,17714,17535,17972,23480,23406,23522,22960,22730,22914,34254,33974,34146,28142,28207,27984,28834,28604,28939,27394,27316,27152,32374,32447,32252,32458,32447,32374,34331,34378,34303,34303,34378,34308,34308,34445,34099,34325,34620,34307,34307,34465,34285,34285,34388,34316,34316,34379,34353,34435,34378,34331,34192,34189,34447,7601,7718,7811,7811,7718,7877,7732,7806,7368,7715,7811,7790,7715,7790,7731,8006,7827,7731,7827,7743,7731,7734,7743,7827,34378,34364,34308,34274,34189,34235,9930,9768,9895,10103,10059,10140,10016,10059,10103,9988,10052,10113,10144,10111,10282,9954,10011,9631,12678,12472,12688,12186,12054,12264,12608,12472,12678,28783,28671,28792,28221,28000,27935,29240,29141,29096,29203,29141,29240,28604,28574,28939,34364,34445,34308,34559,34451,34042,7805,7734,7827,7725,7859,7771,19411,19308,19443,22098,22186,22254,27457,27394,27359,32747,32720,32895,32614,32485,32470,34299,34274,34143,34445,34444,34325,7870,7907,8267,7862,7907,7870,22960,22914,23056,8034,8052,8145,7771,8258,7618,7707,7734,7805,7791,7707,7805,21021,21193,21105,21465,21596,21506,21506,21596,21759,22098,22167,22186,21465,21193,21383,7732,7521,7610,19308,19170,19108,9176,9387,9207,27457,27525,27475,18887,18832,18784,17481,17445,17535,25016,25216,25087,26972,26802,26874,24597,24736,24418,25016,24971,25079,33759,34012,33779,33634,33744,33644,33691,33744,33574,33174,33357,33109,7791,7744,7707,10173,10233,10111,12186,12264,12243,13524,13833,13866,14657,14744,14698,13344,13306,13580,13119,13344,13053,13119,12958,12998,30072,29389,29910,29367,29543,29317,29353,29543,29367,29353,29367,29262,32028,32171,32017,31921,31275,32013,33174,33160,33324,10059,9992,10055,10016,9992,10059,10111,10233,10282,9946,9987,9810,29141,29017,29033,29209,29017,29141,29273,29353,29262,28381,28270,28398,14356,14196,14619,13648,13464,13496,27905,27790,27876,28168,28000,28221,28552,28473,28629,34297,34299,34166,34324,34195,34398,15562,15692,15469,16654,16643,16588,7791,7785,7744,34620,34465,34307,28670,28552,28629,32013,31275,31017,15922,16213,15993,26013,25405,25394,23965,23890,23745,25366,25405,25512,33237,33004,33073,7806,7773,7952,7732,7773,7806,22186,22332,22254,22707,23095,22907,22167,22332,22186,7744,7785,7837,32938,33078,32848,32747,32580,32714,33034,33051,32816,33123,32996,33253,34465,34388,34285,14845,14744,14640,15087,15213,15479,12213,12488,12472,12213,12186,12243,11977,12141,11749,23662,23480,23522,23152,22960,23056,24285,23890,23965,33946,33972,33891,34185,34089,33923,32614,32580,32747,32614,32539,32580,10779,10753,10839,10914,11010,11059,11619,11865,12054,8228,8152,8416,7949,8228,8249,8002,8249,8055,21972,21146,22139,19685,19613,19582,19447,19459,19411,19411,19394,19308,19308,19280,19170,21465,21506,21335,24512,24683,25021,34041,33972,33946,10848,10912,11529,10419,10772,10532,10419,10532,10441,22704,22426,22602,23152,23056,23299,23584,23480,23662,33289,33237,33073,33426,33535,33442,34123,34173,34031,34194,34173,34310,34254,34146,34277,34277,34146,34190,10004,10144,10052,9810,9987,9954,13176,13544,13496,28398,28270,28207,29025,29155,29067,27984,27943,28142,16000,15914,16120,16076,16207,16247,15693,15922,15993,15888,15922,15693,7773,7830,7866,7800,8002,8055,7732,7830,7773,8991,9176,8741,9631,10011,9512,19190,19023,19170,19170,19023,19108,18792,18641,18598,16000,16076,15810,22704,22602,22730,32755,32404,32435,32755,32435,32583,34297,34166,34248,34393,34447,34189,34388,34379,34316,31157,31026,31088,30901,30888,30795,30795,30898,30676,31157,31088,31364,13485,13464,13648,13485,13648,13627,13306,13462,13580,13375,13462,13306,28484,28221,28412,26286,26400,26628,28670,28484,28552,28552,28484,28412,29535,29271,29216,29307,29271,29535,33237,33324,33160,8387,8701,8645,8164,8034,8145,8387,8645,8551,9631,9512,9605,13128,13119,12998,28783,28792,28919,12001,11619,12054,32485,32433,32470,32504,32433,32485,34379,34380,34353,9323,9219,9332,9320,9420,9458,9320,9458,9310,27525,27740,27672,27394,27457,27475,27190,27394,27152,26972,26921,26886,7951,8338,8339,7771,7618,7619,18887,18913,18832,18096,18505,18224,34089,34045,33855,34148,34045,34089,34393,34189,34274,34324,34297,34248,22707,22623,22593,24597,24418,24253,7800,8199,7717,17102,17001,16866,18140,18120,18224,29003,28792,29017,34173,34186,33934,34194,34186,34173,7725,7744,7837,7725,7837,7859,10388,10419,10293,10173,10441,10233,15075,15083,15105,13343,13176,13464,15914,15648,15725,16000,15810,15769,15914,15653,15648,19806,19613,19685,31364,31088,31354,33324,33357,33174,29271,29203,29240,29307,29203,29271,9310,9817,9718,32711,32779,32895,34393,34274,34396,7830,7853,7938,7741,7853,7830,9711,9810,9954,9946,9830,9988,9620,9631,9605,13464,13176,13496,13485,13685,13343,15075,15105,15242,14744,14845,15087,14657,14698,14449,26392,26802,26554,25416,25643,25285,28142,27943,28059,14518,14619,14614,15242,15290,15412,14845,15056,15087,32895,32779,32848,32743,33592,33236,9090,9034,9219,9219,9034,9332,8646,8600,8669,14449,14698,14385,8655,8836,8773,9992,9880,9930,9899,10016,10103,15422,15242,15412,15056,15213,15087,19613,19459,19447,26628,26400,26798,28079,27905,28000,33253,33236,33276,34396,34274,34458,14111,13912,13977,26972,27190,26921,27653,27740,27525,8002,7977,8249,7800,7977,8002,9880,9768,9930,9700,9810,9711,28783,28670,28629,28484,28339,28221,28889,28670,28783,33744,33824,33644,34195,34324,34248,33851,33824,33744,33851,33744,33691,33851,33691,34007,34186,34185,33923,34194,34185,34186,32676,32504,32485,32214,31416,31912,32527,32504,32637,7889,7987,8034,8405,8387,8551,7853,7862,7870,7613,7862,7853,18908,18710,18838,18908,18838,19023,22720,22704,22848,22064,22053,22139,22559,22704,22720,22418,22707,22593,22418,22593,22332,34457,34324,34394,34458,34274,34299,15564,15422,15660,15564,15660,15648,27190,27359,27394,33078,32938,33051,32727,33009,32867,33426,33377,33324,33324,33377,33357,32583,32435,32447,32296,32270,32171,8082,7629,7704,19459,19394,19411,34458,34299,34453,31912,32305,32257,16076,16000,16120,17898,18217,17160,12756,12608,12678,12186,12072,12054,12592,12608,12756,29209,29003,29017,29209,29141,29203,34445,34504,34444,34444,34516,34325,34465,34515,34388,34388,34515,34379,34379,34512,34380,34364,34495,34445,34378,34501,34364,34514,34501,34378,34514,34378,34435,34435,34768,34835,34192,34535,34520,34192,34447,34535,10755,10753,10779,11120,10914,11173,10686,10914,10673,15653,15564,15648,33357,33706,33610,33426,33324,33237,34501,34495,34364,14123,14111,14015,13186,13375,13306,13128,13306,13119,28168,28079,28000,28605,28339,28484,28782,28484,28670,32304,32296,32171,32166,32171,32028,34495,34504,34445,10914,10792,11010,13372,13659,13462,18710,18641,18792,18764,18641,18710,19394,19280,19308,21978,22167,22098,34504,34516,34444,23890,23816,23662,23480,23348,23299,23868,23816,23890,23584,23816,23868,32468,32458,32270,9620,9700,9711,9810,9830,9946,9620,9711,9631,28939,29155,29025,28398,28574,28381,28590,28574,28398,10792,10753,10755,30998,30888,30901,30998,30901,30994,30998,30994,31044,33972,34059,33774,34045,34041,33946,34119,34041,34045,7715,7683,7811,7239,7965,7846,7731,7683,7715,7664,7683,7731,7664,7731,7743,7664,7743,7548,7743,7734,7548,7734,7707,7548,10682,10618,10848,10419,10662,10772,10618,10662,10534,30712,30072,29910,30991,30998,31044,25079,25216,25016,24253,23893,24066,23893,23534,24066,7548,7707,7327,7568,7683,7548,7987,8044,8052,19280,19190,19170,18913,19218,18963,18887,19218,18913,34536,34042,34353,34254,34294,34123,34536,34353,34380,34535,34447,34725,34453,34299,34387,17972,18120,18140,18084,18120,17972,23584,23348,23480,27653,27525,27457,7959,8426,8554,8633,8901,8408,9114,9299,9176,8130,8426,8007,9838,9880,9992,9768,9644,9718,9787,9880,9838,9809,9830,9810,15052,14907,15075,15075,14907,14899,14858,14518,14614,15240,15075,15242,15240,15242,15422,16654,16588,16407,16654,16407,16551,15888,16213,15922,23145,23371,23095,27190,27274,27359,27621,27653,27457,26802,26972,26886,26874,26802,26739,29003,28919,28792,28889,28919,29003,33096,33078,33051,33103,33051,33123,33253,32996,33236,33253,33103,33123,34578,34277,34190,34185,34148,34089,14601,14518,14858,14449,14527,14657,14657,14640,14744,15032,15145,15056,15056,15145,15213,14505,14527,14449,15567,15888,15693,15032,15056,14950,33276,33592,33416,12413,12213,12472,29289,29521,29390,34387,34299,34297,34447,34393,34725,34387,34297,34466,8034,7987,8052,8015,8339,8350,34249,34148,34185,21596,21978,21911,21193,21465,21335,20913,20987,20230,26400,26286,26013,24285,23965,24246,27011,26798,27049,27200,27274,27190,32747,32676,32614,32906,32895,32848,34620,34515,34465,9738,9644,9768,9320,9225,9219,9699,9809,9810,10011,9487,9512,14123,14197,14111,13119,13053,12958,13186,13128,13109,32257,32305,32481,32527,32433,32504,8600,8531,8669,8387,8245,8350,8593,8531,8600,15562,15469,15213,34041,34059,33972,34207,34059,34041,34393,34396,34480,32676,32485,32614,32458,32489,32447,32583,32489,32476,8602,8655,9132,14111,14197,14385,13323,13462,13375,15564,15472,15422,15456,15472,15564,7600,7874,7718,7862,7740,7907,10111,10144,10004,9699,9810,9700,22313,22418,22332,22925,23145,23095,22299,22332,22167,32079,32013,32246,32296,32361,32270,34480,34396,34458,34466,34297,34457,12470,12413,12472,12209,12072,12186,12470,12472,12608,12470,12608,12592,16058,16407,16213,33824,34012,33759,33952,33851,34007,34515,34512,34379,33920,34012,33824,34480,34458,34496,8655,8593,8836,9310,9225,9320,8602,8562,8655,15769,15653,15914,15456,15653,15568,27501,27457,27359,28059,27943,27878,8531,8405,8551,8298,8405,8324,15888,16058,16213,16018,16058,15888,7732,7741,7830,7613,7741,7610,19133,18908,19023,18641,18562,18490,22704,22537,22426,22559,22537,22704,34277,34294,34254,34422,34294,34277,34422,34277,34795,34496,34458,34453,34457,34297,34324,9620,9624,9700,9290,9487,9299,13128,13186,13306,13323,13186,13109,31553,31364,31375,32473,32257,32481,23816,23584,23662,22704,22730,22848,24683,25260,25021,34310,34173,34397,34148,34119,34045,10052,9915,10004,28339,28079,28168,28300,28079,28339,28059,27878,27740,31375,31364,31354,31553,31416,32272,12209,12186,12213,12592,12756,12794,12756,13176,12794,29092,29155,28939,30435,30560,29506,29158,29155,29092,26739,26802,26392,27374,27501,27274,27274,27501,27359,32013,32149,32028,32079,32149,32013,32906,32883,32895,32895,32883,32747,33103,33096,33051,33354,33096,33103,33258,33103,33253,14527,14640,14657,15480,15562,15213,14469,14640,14527,14950,15056,14845,9114,9290,9299,9114,9176,8991,14274,14385,14197,14345,14505,14449,18760,18581,18573,20929,20913,20805,23152,23299,23348,34496,34453,34490,34394,34324,34398,34596,34536,34380,14360,14356,14518,15332,15240,15422,15332,15422,15472,32743,33714,33592,9716,9830,9809,10052,9988,9915,12209,12213,12413,31364,31553,31498,23224,23152,23417,22925,23095,22707,8205,8245,8387,26728,26739,26566,25030,25079,24971,24904,24971,24597,7977,7949,8249,7901,7949,7977,14085,14274,14197,23459,24066,23534,32906,32848,33011,32481,32305,32433,34032,34015,34362,33952,33920,33824,33952,33824,33851,34244,34119,34148,33416,33258,33276,12794,13176,12894,12084,12209,12413,10662,10618,10682,10427,10662,10419,10427,10419,10388,21826,21978,21596,22618,22925,22707,30998,30991,30888,30888,30898,30795,31044,30994,31157,31044,31157,31124,33289,32941,32867,33377,33484,33357,33468,33426,33442,34194,34197,34185,34310,34197,34194,34536,34559,34042,9373,9512,9487,9605,9624,9620,13186,13323,13375,13053,12717,12958,28142,28287,28207,28085,28287,28142,32489,32583,32447,32304,32361,32296,18908,18764,18710,20913,20230,20805,18573,18581,18505,18096,18224,18120,18084,17972,17899,22848,22730,22960,34015,33957,34362,34453,34387,34490,30984,31044,31124,12084,12413,12470,24398,24512,24526,23017,22960,23152,29273,29262,29067,29273,29067,29158,9606,9624,9605,12421,12779,12141,32149,32166,32028,32079,32166,32149,9225,9214,9219,8655,8562,8593,9180,9214,9225,13977,13912,13866,15896,16018,15888,16200,16551,16407,27830,28059,27740,27830,27740,27653,19394,19404,19280,19280,19293,19190,19190,19133,19023,18908,19133,18764,19459,19404,19394,19613,19404,19459,19663,19404,19613,19663,19613,19806,22139,22426,22064,22426,22452,22064,8593,8324,8531,8405,8298,8387,8602,9132,8717,15154,15213,15145,33468,33484,33377,10419,10441,10293,7601,7600,7718,7601,7811,7568,7811,7683,7568,9880,9787,9768,9155,9180,9225,9838,9992,10016,28919,28889,28783,29196,28889,29003,29289,29203,29307,29289,29390,29341,7369,7744,7725,7613,7740,7862,7613,7853,7741,20230,20314,20805,21465,21630,21596,34387,34526,34490,34163,33779,34012,34504,34623,34516,34516,34620,34325,34515,34638,34512,34512,34596,34380,34536,34563,34559,34495,34623,34504,34501,34623,34495,34688,34623,34501,34688,34501,34835,34608,34114,34520,7771,7615,7725,7619,7615,7771,10293,10201,10318,10293,10441,10173,19404,19293,19280,34466,34526,34387,34813,34608,34520,34244,34249,34298,34464,34249,34197,34197,34249,34185,7548,7683,7664,20913,20931,21105,29307,29521,29289,29158,29067,29155,34623,34603,34516,13833,13977,13866,32949,32676,32747,20931,21021,21105,25416,25285,25216,24685,24904,24597,34111,34163,34012,34007,33691,33910,14594,14706,14640,14640,14706,14845,15032,15154,15145,14469,14527,14505,14345,14449,14274,14345,14283,14409,33096,33082,33078,32883,32926,32747,33230,33082,33096,14706,14950,14845,21021,21141,21193,27200,27190,26972,25416,25216,25250,10293,10173,10201,7717,8199,7907,13841,14015,13977,12998,13109,13128,12958,13109,12998,14996,15154,15032,25250,25216,25079,32166,32304,32171,32361,32468,32270,32340,32304,32166,32495,32468,32361,33276,33258,33253,32674,33714,32743,34603,34620,34516,7327,7707,7744,7618,8258,7704,22126,22299,22167,22126,22167,21978,34813,34520,34535,34466,34477,34526,14518,14356,14619,14601,14858,14785,14085,14197,14123,33011,32848,33078,7604,7725,7615,18244,18562,18764,18764,18562,18641,23017,22848,22960,22426,22537,22452,23017,23152,23224,22538,22707,22418,23145,23459,23371,34637,34393,34480,9884,9899,9900,15456,15332,15472,14785,14858,14907,15456,15564,15653,29289,29209,29203,29341,29209,29289,29092,28939,28574,9727,9738,9787,9787,9738,9768,9624,9699,9700,9606,9699,9624,12084,12072,12209,12894,13176,13026,28889,28782,28670,29196,28782,28889,32246,32013,32342,32676,32637,32504,31371,31364,31498,32762,32637,32676,32476,32489,32458,21141,21383,21193,7949,7702,8152,7800,7901,7977,33951,33774,34059,34249,34244,34148,34173,34123,34397,7704,8258,8082,7619,7604,7615,19293,19133,19190,22299,22313,22332,22328,22313,22299,27001,26972,26874,34466,34457,34477,34496,34637,34480,8015,7951,8339,7629,8082,8044,7863,7951,7765,24398,24285,24246,24398,24246,24512,15769,15914,16000,33484,33706,33357,33426,33468,33377,33009,32727,32755,17535,17445,17102,16673,17102,16654,23282,23459,23145,24887,25030,24904,7860,8044,7987,34578,34190,34451,34607,34451,34559,12072,12001,12054,10914,10686,10792,10181,10839,10753,9884,9823,9899,12084,12001,12072,12084,11925,11872,11365,11977,11749,34730,34638,34515,24904,25030,24971,24685,24597,24604,9214,9090,9219,9310,9718,9306,9899,9838,10016,9823,9838,9899,13977,14015,14111,13866,13659,13524,27501,27621,27457,28059,28085,28142,29238,29092,28574,26728,26851,26739,25030,25250,25079,34612,34637,34496,34477,34457,34550,34457,34394,34550,21383,21630,21465,28216,28085,28059,33191,33009,33196,32468,32476,32458,32566,32476,32585,32340,32361,32304,24848,24863,24887,30984,30898,30888,30984,30888,30991,30984,30991,31044,12794,12666,12592,13343,13464,13485,12717,13053,12779,13372,13462,13323,8324,8405,8531,8324,8593,8386,10618,10597,10848,10534,10597,10618,10534,10662,10427,10534,10427,10356,31124,31157,31222,29353,29491,29543,29554,29491,29353,29554,29353,29273,29554,29273,29158,21630,21718,21596,34638,34596,34512,7740,7717,7907,7800,7730,7901,7670,7717,7740,10369,10388,10318,10369,10427,10388,22537,22559,22452,23152,23348,23417,26739,26851,26874,27603,27784,27621,26739,26392,26566,13685,13485,13627,14785,14907,14931,15075,15240,15052,22313,22538,22418,22925,23282,23145,22618,22538,22328,27210,27049,27564,25366,25260,25405,27790,27905,28079,26939,27001,26874,34612,34496,34490,34550,34394,34541,13372,13323,13109,27784,27653,27621,27784,27830,27653,34360,34123,34294,14950,14996,15032,15154,15480,15213,16034,16058,16018,15025,14996,14954,14621,14950,14706,14469,14505,14345,14469,14345,14409,23417,23348,23521,25405,25846,25512,27011,26628,26798,14085,14123,14015,27001,27200,26972,32906,32926,32883,33112,33011,33078,33112,33078,33082,33132,32755,32583,21718,21826,21596,31222,31157,31371,31157,31364,31371,33230,33112,33082,33951,34059,34207,15810,16076,15838,15456,15449,15332,9915,9988,9855,9512,9442,9605,9855,9988,9830,9373,9435,9512,9373,9487,9290,10318,10388,10293,13685,13737,14356,13010,13372,13109,31553,32506,31498,34612,34490,34526,34541,34394,34398,13166,13026,13176,12792,12666,12794,16034,16407,16058,15567,15693,15562,28782,28605,28484,28683,28605,28782,34207,34041,34119,34210,34119,34244,8524,8602,8407,33535,33426,33237,33598,33706,33484,23348,23584,23521,22559,22469,22452,34422,34360,34294,34486,34360,34422,8243,8205,8387,8243,8387,8298,24685,24848,24904,25323,25325,25250,24848,24685,24863,25250,25325,25416,25483,25325,25323,7951,7889,8034,7863,7889,7951,17124,17535,17102,34318,34210,34244,34207,34210,34318,9180,9090,9214,9016,9090,9155,9572,9644,9738,9176,9207,8741,13954,14085,14015,13841,13977,13833,10201,10173,10107,22720,22746,22559,19404,19593,19293,19293,19593,19133,34693,34563,34536,9690,9727,9787,9690,9787,9838,12792,12794,12894,10107,10173,10111,9855,9830,9716,29209,29196,29003,29196,29341,29310,34111,34012,33920,34074,33920,33952,7610,7741,7732,15643,15568,15653,10107,10111,10034,31416,32214,32272,22720,22848,22746,21826,22126,21978,28300,27790,28079,27603,27621,27501,27830,28216,28059,29166,29092,29238,34360,34367,34123,34486,34367,34360,34372,34362,33957,32534,32340,32166,32476,32566,32583,32495,32340,32534,9716,9809,9699,9293,9373,9290,14601,14360,14518,15052,15240,15332,27577,27603,27501,27001,27071,27200,26851,26939,26874,26857,26939,26851,26392,25783,26421,7836,7860,7987,8015,8350,8245,10591,10753,10792,9606,9605,9442,10034,10111,9967,10111,10004,9967,12095,12421,12141,12958,13010,13109,12095,12141,11977,14469,14594,14640,15020,15480,15154,14425,14594,14469,27011,27030,26628,27210,27125,27049,27107,27071,27001,32449,32214,32257,33354,33103,33258,33202,32926,32906,33598,33484,33468,34210,34207,34119,34298,34249,34464,34362,34541,34398,34612,34526,34834,7596,7604,7619,7596,7619,7618,7596,7618,7586,34526,34477,34834,34623,34688,34603,34603,34710,34620,34620,34730,34515,34868,34693,34596,34596,34693,34536,34835,34501,34514,34435,34322,34768,33910,33691,33610,7600,7507,7846,7186,7507,7600,7239,7507,7042,7600,7601,7186,7601,7568,7106,12593,12470,12592,12895,12792,12894,12895,12894,13026,20931,20929,21021,21021,21019,21141,21141,21137,21383,21665,21755,21630,21630,21755,21718,21718,21755,21826,21826,21868,22126,20913,20929,20931,18718,19218,18887,34007,34074,33952,25731,25783,25416,33416,33369,33258,33456,33369,33416,14564,14360,14601,13343,13166,13176,14283,14274,14225,14283,14345,14274,20929,21019,21021,8149,8243,8298,8205,8103,8245,25405,26013,25846,25512,25565,25479,33850,33910,33610,21019,21137,21141,34765,34710,34603,18084,18096,18120,18760,18659,18887,18088,18096,18084,22746,22848,22977,23868,23890,24101,23890,24285,24101,30435,29506,30222,34367,34397,34123,34542,34397,34367,7604,7369,7725,7586,7618,7474,9967,10004,9953,10673,10914,11094,11741,11619,12001,34563,34607,34559,34712,34607,34563,34637,34725,34393,34587,34477,34550,34710,34730,34620,33202,32906,33011,32481,32433,32527,10686,10591,10792,18096,18573,18505,30898,30712,30676,30984,30993,30898,31097,30993,30984,31207,30984,31124,31207,31124,31222,31207,31222,31371,8500,8593,8562,28398,28287,28590,30222,29506,29543,10912,11749,11529,10534,10543,10597,10435,10543,10534,10356,10427,10369,10356,10369,10269,10369,10318,10269,10318,10201,10269,7836,7987,7889,7836,7889,7765,8602,8500,8562,8524,8500,8602,13055,13166,13343,15025,15154,14996,24101,24285,24229,32481,32527,32637,33706,33850,33610,33442,33598,33468,33535,33598,33442,34464,34197,34310,7466,7586,7474,7596,7466,7604,27784,27828,27830,27577,27501,27374,34607,34578,34451,34762,34578,34607,9685,9738,9727,9567,9572,9738,9442,9512,9435,9953,10004,9915,12593,12592,12666,13062,12895,13026,9306,9718,9644,8717,9132,9034,9378,9442,9435,9261,9293,9290,10269,10201,10057,9873,9915,9855,12593,12666,12792,32585,32476,32468,33009,33289,32867,18642,18659,18573,17899,18088,18084,17899,17972,17535,22848,23017,22977,23882,23521,23584,34397,34410,34310,34542,34410,34397,7537,7670,7740,7717,7677,7800,7537,7740,7613,25204,25021,25260,8149,8103,8205,8149,8205,8243,10201,10107,10079,15769,15643,15653,15088,15052,15332,15810,15643,15769,23017,23135,22977,9823,9690,9838,9796,9690,9823,9658,9716,9699,12791,12593,12792,17160,18217,18421,13755,13841,13833,13755,13833,13524,27767,27828,27784,15896,16034,16018,16551,16673,16654,25366,25315,25260,25366,25512,25479,25325,25483,25416,25323,25250,25030,10079,10107,10034,14594,14621,14706,14404,14621,14594,14425,14469,14409,26729,26857,26728,26728,26857,26851,26939,27107,27001,27374,27274,27200,27603,27767,27784,26729,26728,26566,33029,32949,32926,33304,33230,33096,33191,33289,33009,15449,15456,15568,14785,14564,14601,14954,14996,14950,15480,15567,15562,27125,27211,27011,27564,27049,27461,33369,33354,33258,33489,33354,33369,7474,7618,7704,7765,7889,7863,34298,34318,34244,34207,34787,33951,33592,33456,33416,34403,34318,34298,21972,22139,22053,20033,19939,20450,17179,18421,17464,16790,16837,16877,21972,22053,22014,21665,21630,21383,22328,22538,22313,22538,22618,22707,32473,32449,32257,32762,32481,32637,32949,32747,32926,9572,9495,9644,9483,9495,9572,13166,13062,13026,12895,12791,12792,12942,13062,13055,8741,9207,8901,9215,9261,9124,8806,8408,8901,14225,14274,14085,18635,18573,18455,18074,17899,17991,26262,26421,25783,32674,33646,33714,15508,15449,15568,15838,15965,15800,21755,21868,21826,32566,32712,32583,32737,32712,32566,34868,34596,34638,9690,9685,9727,10103,10507,10181,9674,9685,9690,12421,12717,12779,12663,12717,12640,8500,8386,8593,8137,8149,8298,9016,9034,9090,9155,9090,9180,9155,9225,9127,15508,15568,15643,27374,27200,27272,33198,33011,33112,33577,33592,33775,7521,7732,7368,22178,22299,22126,24863,24685,24604,24981,25323,25030,25479,25315,25366,24526,24285,24398,25232,25342,25235,26505,26642,26421,24887,24904,24848,17010,16837,16536,17160,18421,17179,22014,22053,22064,34074,34111,33920,34163,34372,33697,34180,34111,34074,34036,34074,34007,34036,34007,34154,34924,34725,34637,34834,34637,34612,7670,7677,7717,8806,8691,8408,7559,7677,7492,34795,34486,34422,34530,34464,34310,34795,34277,34874,24926,24512,25021,23868,23882,23584,23017,23224,23135,9127,9225,9310,15394,15567,15480,27577,27767,27603,28216,28287,28085,32949,32841,32676,10012,10079,10034,10012,10034,9967,12015,11897,12001,12015,12001,12084,12015,12084,11868,33925,33850,33706,33716,33706,33598,9658,9729,9716,9716,9772,9855,9378,9435,9373,9378,9373,9243,34693,34675,34563,9729,9772,9716,29341,29196,29209,27892,27564,27790,27790,27564,27461,29307,29535,29521,29092,29166,29158,28216,27830,27828,28289,28216,28105,31095,30712,30898,31097,30898,30993,10591,10555,10753,10686,10583,10591,10602,10673,11094,34541,34587,34550,34580,34587,34541,34580,34541,34749,9495,9306,9644,9685,9567,9738,9497,9567,9685,12942,12791,12895,12942,12895,13062,13685,14356,14360,8691,8426,8130,9243,9373,9293,14626,14564,14785,14931,14907,15052,33230,33217,33112,32949,32954,32841,33304,33217,33230,33304,33096,33354,33489,33369,33456,7730,7949,7901,10583,10555,10591,10543,10577,10597,10435,10577,10543,10435,10534,10356,10435,10356,10248,15088,14931,15052,15025,15020,15154,14621,14954,14950,14948,14954,14630,21868,22094,22126,27272,27200,27071,27577,27582,27767,26642,26729,26566,26642,26566,26421,34675,34712,34563,10248,10356,10269,9953,10012,9967,11897,11741,12001,11718,12015,11868,13954,14225,14085,14283,14425,14409,13524,13659,13372,32841,32762,32676,32876,32762,32841,14225,14425,14283,10248,10269,10057,33559,33489,33456,25315,25204,25260,25232,25204,25315,34154,34007,33910,34530,34310,34410,34318,34403,34207,33592,33577,33456,7610,7537,7613,7459,7537,7610,18573,18659,18760,18074,18096,18088,23224,23417,23135,22452,22209,22064,24991,24926,25021,24981,24887,24863,34587,34677,34477,34677,34580,34749,9873,9953,9915,9658,9699,9606,34768,34322,34608,34688,34765,34603,34710,34776,34730,34730,34776,34638,34693,34797,34675,34675,34934,34712,7586,7466,7596,7474,7417,7376,22205,22209,22383,22094,22178,22126,8103,8100,8245,8137,8298,8324,10912,10848,10597,13783,14015,13841,16034,16200,16407,15989,16200,16034,31247,31207,31328,30984,31207,31247,32449,32473,32494,33714,33646,33951,33289,33535,33237,34269,34180,34412,33696,33535,33653,34919,34765,34688,10181,10507,10611,9884,9796,9823,10057,10201,10079,9873,9855,9772,29166,29554,29158,29468,29554,29166,9290,9124,9261,9584,9658,9606,33196,33009,32755,32340,32495,32361,32246,32166,32079,9567,9483,9572,9497,9483,9567,34486,34542,34367,34570,34542,34486,34813,34768,34608,34813,34535,34725,9290,9114,9124,13755,13783,13841,13416,13524,13372,15567,15896,15888,15989,15896,15915,33029,32954,32949,21137,21171,21383,21755,21773,21868,21868,21894,22094,22212,22264,22178,21019,21171,21137,21022,21171,21019,20932,21019,20929,34872,34776,34710,8524,8386,8500,8407,8386,8524,8717,9034,9016,15093,15088,15332,15646,15508,15643,15646,15643,15810,33796,33714,33886,33696,33716,33598,21472,21146,21972,20935,20033,20450,17179,17232,17165,21171,21300,21383,10555,10181,10753,9775,9873,9772,9584,9606,9534,24101,23882,23868,24041,23882,24101,10057,10079,9746,9775,9772,9751,29083,28683,28782,29521,29535,29998,22264,22328,22178,22178,22328,22299,24597,24066,24604,9155,8973,9016,9184,9127,9310,13613,13783,13755,8149,8100,8103,8009,8100,7864,16385,16673,16551,17899,18074,18088,16385,16551,16200,24887,24981,25030,26760,26642,26684,24066,23459,23650,24926,24844,24512,24964,24844,24926,26013,26286,25846,34111,34203,34163,34036,34180,34074,33960,33910,33850,17569,17899,17535,15702,15646,15810,8973,8717,9016,13636,13685,14360,14931,14626,14785,14772,14626,14931,15332,15449,15093,23135,23417,23451,22642,22469,22559,33217,33198,33112,33510,33304,33354,33534,33354,33489,33559,33456,33577,9483,9429,9495,9301,9291,9286,12962,13010,12958,13990,13954,13817,12663,12958,12717,28289,28590,28287,28289,28287,28216,32722,32481,32762,32494,32473,32576,33386,33198,33217,33196,32755,33132,33535,33696,33598,9429,9306,9495,25846,26286,26527,28105,27828,27767,28105,28216,27828,32495,32585,32468,32746,32585,32806,33925,33960,33850,35033,34813,34725,14892,15088,15093,26992,26939,26857,26421,26477,26505,7629,8044,7860,7629,7860,7594,9863,9796,9884,9863,9884,9900,29390,29310,29341,29383,29310,29390,11718,11741,11897,11718,11897,12015,26992,26857,26729,12640,12717,12408,21444,21665,21383,7527,7730,7800,7559,7800,7677,33715,33559,33577,34464,34403,34298,33715,33534,33559,34635,34403,34464,15093,15449,15508,15838,16076,15965,28300,28339,28683,26846,26286,26628,27374,27582,27577,33202,33029,32926,33017,32876,32841,7668,7860,7836,21665,21773,21755,7368,7806,7227,7492,7677,7670,22642,22559,22746,22014,21928,21972,10555,10301,10181,9714,9674,9796,10673,10583,10686,10602,10583,10673,33716,33925,33706,33653,33535,33869,31168,31097,30984,29481,29521,29602,31095,31097,31168,21773,21894,21868,8100,8015,8245,8009,8015,8100,14212,14404,14425,14584,14954,14621,13783,13954,14015,13509,13755,13524,25218,25021,25204,25218,25204,25232,23282,22925,23169,25416,25483,25731,34269,34203,34111,34269,34111,34180,13348,13416,13372,13348,13372,13136,22014,22064,22209,22711,22642,22746,22912,22746,22977,23417,23521,23451,7426,7369,7604,7227,7806,7140,7426,7604,7466,22014,22209,22205,23693,23521,23882,34557,34372,34163,34868,34797,34693,34712,34754,34607,34581,34530,34410,7959,8488,8152,15896,15989,16034,15915,15896,15567,14948,15025,14954,34570,34410,34542,9746,10012,9638,10435,10057,10577,10577,10912,10597,16837,16790,16247,17075,17160,17179,17082,17124,17102,17082,17102,16974,24618,24526,24512,26760,26992,26729,27374,27431,27582,26760,26729,26642,26992,27107,26939,14499,14360,14564,12791,12586,12593,22209,22452,22383,33017,32841,32954,9796,9674,9690,9210,9310,9306,9863,9900,9858,15088,14892,14931,14626,14499,14564,15560,15508,15646,15020,14948,14982,25483,25586,25695,7521,7459,7610,7409,7459,7521,18659,18718,18887,18642,18718,18659,18642,18635,18640,27221,27272,27071,28093,28105,27767,34580,34677,34587,34749,34541,34746,9764,9863,9802,11852,12095,11977,12663,12962,12958,11852,11977,11441,29329,28782,29196,29535,30072,30180,15838,15702,15810,15800,15702,15838,27211,27125,27210,25235,25218,25232,25483,25323,25586,33559,33534,33489,33202,33011,33198,33261,33017,33029,33029,33017,32954,33775,33592,33714,7492,7670,7537,23169,22925,23106,22606,22618,22328,7330,7426,7466,7376,7466,7474,27400,27431,27374,7864,8100,8149,7632,7765,7951,8137,8324,8189,7642,7959,8152,7702,7949,7730,13055,13062,13166,12714,12962,12663,25232,25315,25342,24844,24618,24512,7668,7765,7632,7417,7474,7704,16995,16837,17010,24991,24964,24926,34203,34437,34163,34317,34180,34036,34154,33910,33960,8717,8407,8602,8362,8407,8260,33869,33535,33289,33995,33925,33716,9210,9184,9310,9048,8973,9155,9106,9184,9071,9534,9606,9449,9658,9671,9729,9873,9775,9953,9261,9243,9293,9124,9114,8962,9114,8991,8962,8716,8787,8962,20042,20230,19974,18642,18573,18635,32746,32737,32566,33651,33869,33289,32746,32566,32585,9048,9155,9127,33202,33198,33337,20230,19218,19974,21241,21444,21300,21300,21444,21383,21665,21696,21773,21773,21963,21894,22383,22403,22316,22383,22452,22469,34934,34754,34712,9606,9442,9449,9751,9772,9729,12408,12717,12421,29521,29383,29390,29481,29383,29521,32331,32272,32214,32331,32214,32449,32473,32481,32576,32320,32246,32342,34835,34919,34688,34765,34872,34710,34776,34868,34638,34797,34934,34675,35016,34919,34835,35016,34835,34953,17160,17075,17010,16995,17075,17053,17124,17275,17535,16974,17102,16804,24742,24618,24844,24526,24229,24285,25316,25323,24981,24643,24604,24066,8286,8324,8386,15378,15915,15567,16901,16804,16673,24835,24981,24863,7559,7527,7800,7503,7527,7559,8407,8286,8386,33775,33796,33914,33714,33951,33886,34985,34872,34765,22212,22178,22094,21963,22094,21894,34754,34762,34607,34904,34762,34754,9106,9048,9127,22951,22912,22977,22951,22977,23135,34677,34834,34477,34953,34835,34768,34746,34541,34362,11120,11239,11619,11868,11872,11810,11770,11868,11810,13003,13055,13343,32576,32481,32722,24547,24229,24526,9203,9243,9261,9301,9306,9429,9724,9714,9796,9764,9796,9863,9671,9751,9729,9746,10079,10012,9671,9658,9578,13136,13372,13010,13817,13954,13783,14404,14594,14425,13136,13010,12946,28683,28339,28605,14672,14499,14626,12867,12817,13055,14772,14931,14892,24865,24742,24844,24618,24547,24526,25147,24991,25021,25342,25315,25382,27462,27211,27210,27462,27210,27564,27272,27400,27374,27107,27221,27071,27294,27221,27107,27294,27107,27068,26723,26992,26760,26684,26642,26505,9449,9442,9308,10583,10443,10555,11120,11619,11741,12640,12714,12663,12502,12714,12640,22711,22469,22642,25147,25021,25218,32542,32331,32449,31168,30984,31247,34843,34834,34677,31097,31095,30898,31371,31328,31207,14964,15093,15508,14948,15020,15025,13990,14225,13954,26504,26684,26505,34530,34635,34464,34842,34570,34486,21241,21300,21171,27410,27400,27272,27431,27605,27582,28847,29238,28590,33337,33198,33386,32722,32762,33059,33510,33354,33534,9429,9483,9370,9184,9106,9127,8991,8374,8535,9215,9203,9261,7382,7492,7537,7382,7537,7459,10394,10443,10583,22912,22711,22746,23178,22951,23135,31247,31328,31224,34749,34843,34677,34680,34746,34362,34680,34362,34888,11711,11120,11741,12084,11872,11868,11382,11977,11365,12295,12408,12421,17075,16995,17010,15965,16076,16247,15702,15560,15646,16877,16995,17053,17157,17275,17124,16804,17102,16673,24865,24844,24964,24604,24754,24863,24643,24754,24604,8200,8408,8691,8200,8691,8130,21444,21555,21665,33775,33715,33577,11711,11741,11718,31371,31551,31328,7450,7704,7629,7239,7846,7507,9751,9679,9775,9578,9658,9584,12295,12421,12095,28668,28590,28289,28590,29238,28574,30222,29543,29491,32320,32319,32246,15965,16247,16591,25695,25731,25483,25658,25731,25695,33995,33716,33696,35041,34868,34776,9569,9685,9674,13474,13524,13416,12946,13010,12962,12837,12962,12714,17157,17124,17082,32722,33037,32693,32494,32624,32449,15179,15394,15480,16077,16200,15989,25731,26262,25783,33796,33775,33714,33886,34040,33998,7668,7594,7860,7668,7836,7765,12502,12837,12714,34570,34581,34410,34716,34581,34570,34649,34362,34372,34862,34843,34749,13474,13416,13348,9216,9210,9306,9308,9442,9378,9547,9578,9584,9102,9203,9215,9102,9215,9124,13357,13474,13348,21869,21928,21968,21869,21753,21928,21928,21753,21972,21928,22014,21968,33132,32583,32712,32806,32585,32495,7341,7417,7169,24991,25071,24964,25280,25147,25218,25078,25147,25280,25315,25479,25382,25565,25512,25846,25007,25316,24981,34267,34154,34282,34269,34350,34203,7369,7327,7744,7263,7327,7369,7330,7369,7426,7330,7466,7335,22014,22205,22113,21968,22014,22113,9650,9569,9674,9650,9674,9714,9671,9679,9751,9547,9584,9534,16995,16877,16837,17179,17009,17053,17039,17157,17082,16974,16804,16901,34412,34350,34269,15732,15560,15702,15732,15702,15800,34040,33951,34107,9932,9900,10181,29403,29196,29310,30229,30072,30361,29238,29468,29166,8137,8047,8149,7632,7951,7616,7974,8047,8137,16591,16247,16790,25497,25565,25631,25316,25586,25323,25731,25994,26262,28014,27892,27790,28014,27790,28300,7368,7409,7521,7354,7409,7368,7951,8015,7616,23106,22925,22618,23282,23650,23459,22347,22328,22264,33694,33510,33534,33202,33290,33029,33694,33534,33715,33858,33715,33775,22113,22205,22302,21696,21963,21773,34868,34911,34797,34762,34865,34578,14212,14425,14225,15020,15179,15480,23926,23693,23882,22712,22711,22816,24296,24101,24229,24547,24618,24627,23169,23650,23282,24754,24835,24863,26684,26723,26760,27221,27410,27272,26504,26723,26684,26477,26421,26262,33386,33217,33304,17053,17009,16762,17039,17082,16974,18573,18096,18455,24627,24618,24742,13136,13238,13348,12837,12946,12962,12955,12946,12837,13268,13238,13112,13474,13509,13524,13990,14024,14225,29403,29310,29383,32417,32534,32166,32417,32166,32246,32576,32624,32494,33049,32876,33017,27600,27462,27564,27211,27030,27011,32889,32712,32737,34317,34267,34282,32889,32737,32746,21963,21990,22094,34911,34934,34797,34834,34924,34637,35033,34924,35265,15830,15732,15800,9642,9724,9764,9764,9724,9796,22711,22912,22816,11770,11711,11718,11770,11718,11868,9490,9497,9569,9569,9497,9685,9286,9216,9306,13357,13509,13474,32013,31017,31717,32908,32889,32746,7273,7702,7730,7492,7503,7559,7430,7503,7492,8286,8189,8324,8407,8362,8286,8260,8407,8717,8802,8717,8973,8885,8973,9048,9068,9048,9106,13776,14024,13990,32889,33132,32712,7335,7466,7376,7335,7376,7341,22302,22205,22383,25497,25382,25479,25078,25071,25147,24422,24296,24547,25497,25479,25565,34581,34635,34530,34716,34635,34581,12817,12791,12942,10443,10301,10555,10602,10477,10583,10350,10477,10602,11094,10914,11120,11094,11120,10957,10821,10912,10550,10912,10577,10550,18642,18640,18718,18096,18309,18455,34862,34749,34746,34862,34746,34892,8962,8991,8716,9547,9679,9578,9724,9650,9714,9642,9650,9724,9578,9679,9671,9378,9193,9308,10477,10394,10583,11964,12295,12095,12408,12442,12640,11964,12095,11852,13742,13817,13783,17179,17053,17075,15819,15830,15965,15965,15830,15800,16877,17053,16762,18455,18309,18426,16901,17039,16974,16077,15989,15979,21990,22212,22094,24600,24643,24472,25611,25658,25586,25586,25658,25695,25763,25658,25639,33886,33914,33796,33998,33914,33886,34350,34437,34203,34539,34437,34350,34919,34985,34765,35057,35041,34776,34868,34955,34911,34911,34943,34934,34953,34768,35162,35016,34942,34919,35087,34768,34813,20805,20932,20929,21444,21696,21555,21555,21696,21665,21963,21966,21990,21990,22143,22212,20955,20932,20805,34942,34985,34919,9071,9068,9106,9286,9306,9301,9301,9429,9291,11538,11120,11711,13509,13613,13755,13238,13357,13348,13268,13357,13238,12955,13136,12946,9102,9243,9203,20932,21022,21019,32659,32806,32495,32319,32417,32246,32407,32417,32319,30222,29491,29554,22316,22302,22383,22223,22246,22212,22212,22246,22264,27369,27030,27211,35030,34904,34754,35030,34754,34934,7409,7382,7459,7354,7382,7409,17535,17275,17569,19974,19218,19771,33510,33386,33304,33337,33323,33202,33345,33386,33463,35265,34924,34834,34892,34746,34680,7799,8015,8009,7668,7539,7594,7341,7376,7417,7425,7730,7527,7959,8007,8426,7429,7527,7503,8274,8189,8286,7840,7799,8009,9071,9184,9210,8962,9054,9124,13558,13613,13509,24547,24296,24229,22403,22469,22711,22403,22383,22469,25071,24991,25147,27821,27600,27564,27462,27369,27211,27944,28014,27985,34437,34557,34163,27400,27410,27431,30306,30358,29468,27294,27410,27221,27107,26992,27068,30513,30222,29554,33345,33323,33337,7186,7601,7106,7133,7548,7187,19218,19263,19771,21022,21241,21171,12295,12442,12408,12284,12442,12295,25218,25235,25280,19218,18718,19093,7263,7210,7327,7417,7704,7450,7886,8007,7959,8716,8991,8685,15979,15989,15915,15378,15567,15394,23451,23521,23693,22246,22347,22264,23169,23104,23650,22223,22347,22246,25280,25235,25342,25631,25565,25798,34904,34865,34762,34968,34865,35075,11441,11964,11852,23700,23451,23693,14993,15179,15020,14584,14621,14404,14584,14404,14142,14035,14024,13776,26395,26477,26262,24643,24715,24754,24600,24715,24643,24835,24715,24752,9071,8974,9068,9370,9483,9497,21530,21472,21753,21753,21472,21972,17179,17165,17009,21530,21783,21564,21753,21869,21783,21869,21968,21918,21968,22113,21918,19093,18718,18982,17569,17275,17343,34874,34277,34578,9423,9370,9497,13055,12817,12942,12728,12817,12867,9054,9102,9124,15732,15728,15560,14964,14892,15093,14964,14772,14892,14499,13636,14360,16591,16790,16656,21918,22113,22054,25658,25763,25731,25611,25586,25316,8857,8885,9048,8362,8274,8286,8974,9048,9068,22164,22113,22302,22321,22436,22341,8138,8274,8362,15179,15378,15394,17343,17275,17157,17023,17157,17039,10012,9953,9638,9449,9547,9534,9453,9547,9449,31717,31017,30560,32659,32495,32534,21410,21696,21444,35057,34776,34872,32080,31717,31902,34040,33886,33951,35007,34716,34570,34795,34842,34486,35018,34842,34795,7450,7629,7594,7263,7369,7330,7864,8047,7787,7864,8149,8047,13613,13742,13783,13558,13742,13613,13558,13509,13357,16656,16790,16877,24909,24865,24964,25280,25342,25382,34865,34874,34578,34968,34874,34865,8088,8200,8130,7500,7886,7959,34154,34267,34036,34731,34372,34557,34282,34154,33960,33960,33925,34282,8088,8130,8007,8965,9066,9054,9054,9066,9102,33914,33858,33775,34207,34403,34787,14212,14225,14024,15179,15281,15378,16385,16901,16673,24909,24964,25071,24296,24041,24101,24715,24835,24754,24643,24066,24472,9370,9291,9429,9071,9210,9216,9264,9291,9275,9193,9378,9243,12826,12955,12837,12395,12640,12442,14964,15508,15430,32331,32506,32272,32693,32624,32576,32693,32576,32722,13045,13238,13136,16077,16385,16200,15873,15979,15784,25539,25611,25316,26395,26504,26477,32889,32994,33132,32559,32534,32417,7263,7174,7094,9937,9932,10181,9650,9490,9569,27732,27767,27582,27068,26992,26723,33323,33290,33202,33386,33345,33337,33399,33345,33463,35041,34955,34868,34924,35033,34725,35052,34834,34843,9603,9642,9764,14786,14964,15430,7632,7539,7668,7489,7539,7632,24161,24041,24296,23451,23178,23135,12817,12586,12791,11770,11538,11711,12728,12586,12817,32320,32407,32319,32559,32407,32320,7209,7354,7368,7285,7430,7492,14035,14212,14024,22347,22606,22328,22413,22606,22347,31095,30980,30712,31140,30980,31095,31224,31095,31168,31224,31168,31247,33399,33290,33323,7285,7492,7382,23377,23178,23451,13776,13990,13817,13187,13558,13357,22164,22302,22300,22302,22316,22300,21696,21966,21963,26477,26504,26505,26395,26262,26174,27605,27431,27410,30513,30654,30222,8081,8088,7653,15830,15728,15732,15819,15728,15830,34652,34403,34635,34024,33858,33914,9932,9858,9900,31328,31551,31357,13776,13817,13742,27821,27564,27892,27030,26846,26628,27821,27892,27944,27613,27605,27410,7263,7330,7174,10394,10301,10443,9932,9883,9858,10237,10301,10394,10350,10394,10477,21966,22006,21990,32506,31553,32272,34955,34943,34911,34024,33914,34057,12174,12284,12295,12174,12295,11964,7267,7450,7594,7341,7225,7335,7974,8137,8189,7686,7616,8015,13268,13187,13357,12955,13045,13136,12944,13045,12955,33059,32762,32876,32624,32542,32449,32813,32659,32534,24257,24161,24296,25078,24909,25071,25280,24909,25078,27764,27821,27944,27944,27892,28014,9740,9802,9858,9858,9802,9863,9642,9490,9650,24041,23926,23882,24627,24742,24687,12586,12497,12593,13003,13343,13685,22006,22143,21990,32593,32542,32708,34943,35030,34934,34874,34920,34795,30361,30072,30833,29481,29602,29383,25611,25639,25658,25577,25639,25611,7686,8015,7799,7539,7070,7594,24687,24742,24865,25526,25539,25316,24752,24600,24644,22300,22316,22321,22143,22223,22212,7568,7548,7133,7106,7568,7133,7165,7357,7354,9426,9490,9436,12284,12395,12442,12219,12395,12284,11257,11382,10895,10895,11365,10912,14772,14672,14626,14653,14672,14772,14653,14772,14786,14466,14630,14584,14584,14630,14954,15378,15784,15915,14142,14404,14212,30229,30180,30072,8885,8802,8973,9071,9216,9053,9216,9286,9053,14426,13636,14499,33210,33049,33017,34942,35102,34985,34985,35057,34872,35041,35053,34955,34955,35118,34943,34943,35049,35030,35016,35102,34942,35227,35102,35016,35227,35016,34953,7548,7327,7187,21022,21089,21241,21241,21410,21444,21696,21953,21966,21966,21953,22006,22006,21953,22143,22143,22211,22223,20932,20955,21022,20770,20955,20805,20750,20805,20314,27369,27462,27509,27298,26846,27030,25576,25280,25382,29998,29602,29521,33290,33261,33029,33345,33399,33323,33694,33386,33510,8200,8136,8408,8088,8081,8200,7561,8088,8007,14982,14993,15020,20955,21089,21022,35157,35057,34985,22321,22316,22403,7354,7357,7382,7315,7429,7503,7702,7642,8152,7806,7965,7140,11382,11441,11977,34990,34920,34874,34842,34933,34570,13045,13112,13238,13643,13776,13742,14861,14948,14630,12882,13112,13045,23899,23926,24041,22712,22403,22711,23899,24041,24205,24422,24257,24296,32659,32730,32806,32931,32908,32746,33614,33191,33620,33869,33696,33653,32901,32730,32659,33479,33261,33290,34716,34652,34635,34845,34652,34716,34853,34557,34437,34731,34649,34372,34862,34892,34843,7187,7327,7210,7864,7840,8009,7821,7840,7864,25576,25382,25497,24909,24687,24865,24627,24422,24547,34267,34317,34036,33289,33191,33614,16591,16037,15965,16762,16656,16877,18244,18421,18562,34317,34412,34180,16108,16037,16147,15728,15430,15560,26676,27068,26723,27613,27732,27605,25994,25731,25763,33614,33620,33651,9264,9286,9291,9102,9193,9243,9386,9453,9449,8965,9054,8962,32818,32746,32806,9490,9423,9497,9426,9423,9490,9386,9449,9313,9547,9453,9679,12540,12497,12586,10739,10350,10602,12540,12586,12728,12395,12502,12640,12417,12502,12395,7140,6963,7012,8857,8802,8885,8069,7974,8189,8857,9048,8974,11554,11538,11770,21472,21149,20450,21422,21403,21472,21422,21472,21530,21422,21530,21564,21753,21783,21530,21869,21903,21783,22912,23012,22816,27821,27764,27600,28014,28300,28276,27605,27732,27582,27613,27410,27556,7324,7503,7430,7653,8041,8081,24397,24647,24390,24600,24752,24715,24472,24066,23650,23106,22618,22606,34483,34539,34350,34996,34892,34972,6974,7187,6961,7190,7210,7263,8069,8189,8274,15892,15819,15965,21918,21903,21869,8081,8136,8200,21918,22054,21903,35033,35087,34813,35301,35087,35422,7227,7231,7368,7357,7285,7382,6992,7231,7227,34652,34666,34403,34845,34666,34652,35075,34865,34904,34983,34933,34842,35075,34904,35030,8852,8857,8974,28276,28300,28635,10057,10435,10248,11382,11372,11441,31357,31140,31224,31224,31140,31095,30833,30072,30712,30229,30361,30180,31357,31224,31328,24205,24041,24161,24397,24422,24627,9275,9291,9370,8710,8852,8974,12177,11569,12087,13112,13187,13268,12826,12944,12955,12826,12837,12614,29602,29403,29383,29608,29403,29602,13017,13187,13112,18597,18640,18635,20160,20314,20042,32730,32818,32806,33191,33196,33620,32901,32818,32730,32559,32417,32407,35057,35053,35041,17569,17991,17899,18455,18597,18635,18011,17991,17828,7202,7285,7357,9953,9775,9638,9313,9449,9308,12084,12470,11925,12867,12540,12728,18309,18096,18074,22970,23106,22606,26676,26723,26504,32521,32559,32320,32994,32889,32908,8138,8069,8274,25925,25994,25763,26395,26578,26504,25925,25763,25639,33858,33694,33715,33399,33479,33290,34024,33694,33858,33694,33463,33386,33321,33059,33049,7169,7225,7341,7105,7225,7169,7231,7209,7368,7165,7209,7231,34968,35025,34874,35059,35025,34968,12470,12593,11925,22113,22153,22054,14861,14982,14948,15013,15281,15179,14142,14212,14035,7528,7642,7506,8081,8041,8136,7425,7527,7429,34519,34483,34350,34853,34731,34557,34519,34350,34412,34519,34412,34562,8792,8965,8962,8946,9193,9102,28105,28419,28289,27819,28093,27767,27819,27767,27732,22113,22164,22153,30833,30712,30980,29682,29608,29602,35053,35118,34955,8119,8260,7944,8260,8717,8370,26379,26578,26395,12174,12219,12284,12417,12219,12323,11478,11964,11220,29403,29329,29196,29365,29329,29403,34649,34888,34362,34798,34731,35191,27397,27410,27294,7285,7304,7430,7271,7304,7285,18492,18597,18455,18011,18309,18074,35018,34795,34920,35025,34990,34874,35059,34990,35025,15819,15726,15728,15892,15726,15819,15892,15965,16037,24448,24472,24275,25801,25925,25639,34040,34136,33998,34253,34107,34348,7255,7425,7429,9775,9679,9638,7094,7190,7263,8945,9102,9066,22223,22211,22347,21729,21953,21696,8260,8138,8362,9386,8914,9453,9277,9313,9308,15013,15179,14993,16020,16385,16077,16901,17023,17039,34030,33914,33998,33869,33995,33696,33941,33995,33869,9164,9277,9193,8991,8535,8685,13643,13742,13558,27880,27819,27732,28635,28300,28683,32818,32931,32746,32910,32931,32818,11257,11372,11382,7174,7330,7091,22153,22164,22263,22164,22300,22263,7556,7686,7799,7467,7489,7632,7787,7821,7864,7787,8047,7974,7891,7974,8069,22912,22951,23012,22951,23178,23012,34391,34282,33925,7556,7799,7840,9603,9490,9642,9287,9275,9370,9264,9208,9286,9603,9764,9802,19133,18879,18244,16656,16510,16591,34853,34437,34539,34562,34412,34679,7304,7324,7430,7245,7324,7304,29998,29535,30180,29083,28785,28683,7467,7632,7616,34176,34030,33998,15975,15892,16037,25798,25565,25846,24390,24515,24396,23700,23899,23761,7091,7330,7335,7091,7335,7105,10015,9937,10181,10015,10181,10301,10957,11120,11255,22341,22300,22321,28077,27985,28014,27944,27708,27764,27509,27462,27600,25841,25798,25901,35158,35049,34943,14672,14526,14499,12805,12867,13055,14786,14772,14964,14526,14653,14786,14982,15013,14993,14901,14861,14847,22436,22321,22403,23899,23693,23926,27509,27600,27708,27068,27397,27294,27613,27880,27732,27502,27397,27546,34990,35044,34920,35085,35044,34990,9287,9370,9423,9313,8914,9386,9193,9277,9308,8957,9066,8965,12805,13055,13003,11573,11554,11810,12944,12882,13045,13187,13385,13558,12506,12837,12502,12506,12502,12417,29083,28782,29329,28276,28077,28014,32931,32994,32908,32813,32901,32659,21953,22211,22143,9937,9883,9932,11810,11554,11770,12528,12497,12540,20314,20230,20042,20955,21150,21089,21089,21287,21241,21953,22117,22211,30563,29998,30180,7186,7042,7507,6959,7042,7186,6959,7186,6912,7186,7106,6912,7106,6934,6912,7187,7210,6961,7075,7190,7094,9150,9208,9275,9607,9603,9802,13776,14142,14035,13907,14142,13776,14901,15013,14982,20750,20770,20805,26578,26676,26504,26702,26676,26578,26174,26262,25994,27708,27600,27764,27502,27556,27410,35102,35187,34985,35506,35352,35053,35053,35185,35118,35118,35158,34943,35249,35227,34953,7324,7315,7503,7506,7642,7410,7245,7315,7324,25316,25007,25526,34107,34136,34040,34253,34136,34107,12763,12528,12540,12417,12395,12219,29178,29083,29329,29365,29403,29619,35227,35187,35102,8772,8957,8965,33049,33059,32876,32708,32542,32624,31428,31357,31551,33210,33017,33292,33167,32994,33044,20160,20042,20118,20042,19974,20118,35187,35157,34985,15338,15378,15281,15873,16077,15979,18492,18426,18412,20118,19974,19876,21403,21149,21472,21235,21149,21403,21235,21403,21306,21403,21427,21306,21422,21427,21403,21564,21427,21422,21783,21643,21564,21015,21150,20955,7174,7075,7094,7105,7335,7225,7140,7965,6963,7165,7202,7357,8741,8633,8364,8787,8792,8962,10739,10602,11094,9937,9792,9883,18492,18455,18426,18011,18074,17991,24205,24161,24257,24257,24422,24295,27723,27708,27985,27985,27708,27944,31122,30833,30980,29756,29682,29900,31122,30980,31140,35024,34845,34716,34348,34107,34399,35007,34570,34933,34798,34850,34649,35271,35162,35301,34798,34649,34731,35049,35075,35030,35260,35075,35049,24960,24835,24752,19876,19974,19771,21783,21727,21643,35087,35162,34768,34996,34843,34892,10350,10237,10394,32506,32331,32542,21783,21903,21727,21150,21287,21089,10237,10182,10301,11255,11120,11538,16762,16510,16656,18764,19133,18244,16461,17023,16901,29619,29403,29608,31717,32342,32013,32559,32571,32534,32521,32342,32365,32342,31717,32365,17828,17991,17569,18982,18718,18640,22436,22403,22712,21922,21903,22054,22436,22712,22470,25631,25576,25497,25766,25798,25841,7042,6996,7239,8857,8852,8802,8260,8119,8138,8710,8974,8743,8744,8792,8787,9275,9208,9264,9287,9423,9426,12826,12882,12944,12851,12882,12826,26379,26174,26249,26249,26174,25994,28785,28635,28683,28927,28635,28785,28927,28785,29083,34057,33914,34030,33964,33694,34024,33479,33463,33588,33479,33399,33463,33292,33017,33261,34138,34057,34030,7165,7354,7209,18412,18426,18309,18868,18982,18640,23377,23012,23178,23106,23104,23169,22656,22970,22606,35044,35018,34920,35048,35018,35044,34972,34892,34680,9272,9287,9426,12506,12614,12837,12417,12614,12506,32708,32693,32847,32708,32624,32693,32521,32571,32559,32901,32910,32818,19793,19876,19771,21287,21410,21241,22893,23104,22970,34702,34539,34483,34850,34888,34649,7169,7417,7450,6947,7075,7174,7408,7467,7616,7267,7169,7450,7379,7467,7408,14653,14526,14672,15508,15560,15430,19725,19793,19771,18868,18640,18597,19263,19218,19093,21410,21601,21696,21922,22054,22153,22470,22712,22562,33614,33651,33289,34533,34391,34643,33366,33196,33132,15430,15728,15726,28255,28077,28469,34253,34176,34136,34136,34176,33998,16657,16510,16762,15892,15835,15726,27369,27298,27030,27509,27435,27369,27481,27435,27610,27342,27435,27481,27397,27502,27410,27697,27880,27613,27819,27983,28093,27546,27397,27323,27397,27068,27323,33588,33694,33964,33588,33463,33694,11478,12174,11964,10895,11382,11365,10771,10912,10821,21922,22153,22263,35089,34888,34850,7202,7271,7285,7323,7730,7425,7130,7271,6918,11925,12593,12497,11554,11431,11538,22970,23104,23106,25526,25577,25539,22260,22347,22211,29365,29178,29329,29998,29682,29602,29619,29682,29728,35018,34983,34842,35048,34983,35018,34996,35052,34843,35003,34972,34680,16108,15975,16037,25766,25576,25631,25766,25631,25798,25539,25577,25611,24644,24600,24472,17009,16812,16762,16657,16812,17009,6992,7165,7231,6992,7227,7140,8716,8744,8787,8364,8633,8157,33389,33366,33132,33167,33132,32994,35075,35059,34968,35212,35059,35311,21601,21729,21696,35352,35185,35053,8370,8717,8392,8138,8019,8069,7573,7556,7840,33651,33941,33869,32593,32506,32542,33037,32722,33059,8772,8945,8957,8957,8945,9066,8772,8965,8792,13017,13385,13187,13017,13112,12882,21729,21827,21953,8852,8750,8802,8710,8750,8852,27697,27613,27556,28093,28419,28105,33321,33149,33059,33444,33292,33261,11573,11431,11554,12063,11925,12497,12063,12497,12126,19404,19663,19593,24480,24448,24275,8119,8019,8138,8136,8041,8408,7561,8007,7886,12614,12851,12826,12323,12219,12174,15263,15338,15281,15263,15281,15013,15263,15013,14901,14982,14861,14901,26174,26379,26395,26249,25994,26084,29485,29178,29365,28469,28077,28276,32632,32506,32593,6947,7174,7091,7267,7594,7070,35059,35115,34990,35212,35115,35059,18011,18127,18309,19263,19093,19164,17578,17828,17569,23899,23700,23693,22330,22341,22436,24205,24257,24295,11573,11810,11607,22263,22341,22330,22263,22300,22341,34282,34391,34317,34519,34702,34483,34391,34751,34643,27880,27983,27819,6947,7091,6830,7642,7528,7959,7323,7425,7255,9883,9792,9858,9603,9436,9490,9938,9792,9937,10429,10550,10577,10429,10577,10057,9164,9313,9277,11790,11810,11872,35185,35158,35118,10550,10653,10821,29485,29619,29728,31279,31122,31140,31320,31140,31357,35115,35085,34990,35212,35085,35115,9101,9164,9193,12867,12763,12540,12763,12805,13003,12695,12851,12614,32571,32813,32534,32817,32813,32907,7271,7245,7304,7130,7245,7271,8157,8633,8408,9208,9053,9286,9150,9053,9208,9150,9275,9166,15784,15979,15915,17225,17343,17037,17948,18011,17828,19593,19663,20033,32817,32910,32901,34994,35003,34680,35064,35052,34996,34994,34680,34888,34994,35141,35067,24295,24422,24397,27435,27342,27369,27298,27342,27493,31428,31320,31357,33479,33444,33261,34138,34024,34057,7255,7429,7315,24000,23761,23899,22562,22816,22842,32708,32632,32593,31363,31140,31320,32757,32632,32708,8672,8744,8716,8946,9101,9193,8374,8991,8741,24448,24644,24472,24480,24644,24448,9792,9740,9858,33044,32994,32931,35064,34996,35072,8019,7891,8069,34787,34403,34666,34176,34138,34030,28065,28135,27983,27710,27697,27556,27546,27556,27502,6963,7965,7239,7118,7255,7245,19250,19263,19164,18412,18597,18492,7042,6670,6996,6996,6922,7239,7106,7133,6934,7070,7539,7489,6961,7190,7075,7379,7489,7467,17948,18127,18011,17343,17157,17023,35095,35007,34933,34845,34787,34666,35095,34933,34983,35072,34996,34972,34994,35089,35141,35227,35282,35187,35187,35282,35157,35506,35053,35057,35185,35309,35158,35316,35249,34953,35316,34953,35271,35271,34953,35162,6934,7133,6981,15338,15784,15378,14861,14630,14466,6981,7133,7187,21149,20935,20450,21036,20935,21149,21036,21149,21235,21036,21235,21048,21235,21128,21048,20770,20992,20955,21150,21272,21287,21287,21272,21410,21410,21429,21601,21601,21700,21729,21729,21871,21827,20991,20992,20770,20991,20770,20799,20297,20750,20314,20297,20314,20160,20297,20160,20131,20160,20118,20131,20118,19876,20131,35369,35282,35227,7408,7616,7388,9154,9101,9021,10444,10429,10270,11862,11790,11872,11862,11872,11925,15835,15430,15726,16147,16037,16591,16147,16591,16366,16591,16510,16366,16461,16901,16385,20131,19876,19873,21427,21564,21643,20992,21015,20955,24205,24072,23899,24397,24627,24687,26084,25994,25925,25007,24981,24835,34472,34412,34317,35220,34787,34845,10182,10015,10301,9792,9653,9740,9978,10015,10182,10100,10182,10237,10266,10237,10350,10266,10350,10739,11381,11538,11431,11381,11431,11444,35301,35162,35087,35072,34972,35003,8672,8716,8685,22712,22816,22562,21632,21427,21643,21871,21953,21827,22117,22260,22211,24480,24697,24644,35087,35033,35265,28356,28419,28093,28356,28093,28290,32910,33044,32931,33108,33044,32910,6841,6981,6884,19873,19876,19793,15835,15892,15975,14786,14450,14526,26084,25925,26017,26379,26702,26578,34226,34138,34176,7891,7787,7974,15873,16020,16077,15325,15784,15338,24644,24697,24752,24472,23650,24275,25682,24909,25280,25798,25846,25901,21121,21272,21150,35265,34834,35533,7245,7255,7315,7410,7642,7702,7010,7202,7165,12177,12627,12614,12177,12323,12174,12174,11569,12177,32342,32521,32320,32813,32817,32901,32365,31717,32309,30560,30435,30945,9653,9607,9740,9740,9607,9802,8364,8374,8741,8535,8532,8685,8282,8374,8364,27342,27298,27369,27435,27509,27610,27509,27708,27610,35167,35048,35044,35007,35024,34716,35167,35044,35085,11444,11431,11573,19725,19873,19793,21632,21643,21727,21272,21429,21410,27610,27708,27723,33366,33620,33196,34158,34046,33941,34533,34472,34391,33758,33620,33366,33389,33132,33167,17165,16657,17009,17464,17232,17179,24272,24072,24205,23377,23451,23441,24272,24390,24255,8041,8157,8408,8068,8157,7822,14466,14584,14142,15263,15325,15338,6932,6992,7140,6954,7140,7012,22260,22413,22347,22348,22413,22260,6961,7210,7190,6961,7075,6762,12805,12763,12867,11607,11444,11573,13003,13685,13636,13003,13636,13575,14426,14499,14526,12952,13017,12882,13385,13643,13558,12952,12882,12851,29178,28927,29083,29259,28927,29348,29619,29608,29682,34391,34472,34317,34046,33995,33941,7573,7840,7821,8384,8532,8535,8946,9102,8945,27723,27985,28047,33529,33444,33479,33321,33049,33210,33529,33479,33588,15899,16020,15873,15899,15873,15784,18127,18412,18309,17822,17948,17828,9607,9524,9603,9532,9524,9607,11607,11810,11790,29682,29756,29728,7005,7105,7169,6853,6922,6996,21727,21903,21835,21429,21700,21601,34179,34046,34209,18298,18412,18127,19263,19250,19771,35533,34834,35052,35067,35072,35003,35067,35003,34994,34702,34519,34562,33421,33210,33292,7410,7702,7273,7528,7500,7959,34775,34702,34562,8532,8672,8685,33444,33421,33292,7025,7005,7169,6992,7010,7165,6932,7010,6992,10653,10771,10821,10550,10444,10653,9154,9313,9164,21835,21903,21922,23679,23700,23761,31363,31279,31140,31122,31323,30833,31363,31320,31428,6922,6963,7239,21835,21922,22263,10739,10957,10402,10739,11094,10957,9445,9436,9524,11255,11538,11381,25901,25846,26527,25588,25280,25576,31371,31498,31551,34253,34226,34176,33685,33529,33588,34399,34107,33951,15189,15325,15263,24272,24205,24295,24272,24295,24397,26249,26350,26379,26169,26350,26249,10499,10771,10653,31551,31498,32797,7388,7616,7686,7379,7317,7489,6840,7025,7169,7273,7730,7323,22330,21835,22263,21700,21871,21729,24275,24183,24276,24697,24960,24752,26017,25925,25801,34702,34853,34539,8392,8717,8802,8119,7973,8019,8019,7910,7891,7891,7733,7787,8743,8974,9071,8854,9071,9053,9524,9436,9603,9653,9580,9588,12126,12497,12528,13404,13643,13385,29619,29485,29365,29476,29485,29600,10771,10895,10912,31409,31514,31400,23826,23679,23761,35140,35024,35007,34365,34284,34348,6830,7091,7105,6978,7025,6840,9166,9275,9287,9101,9154,9164,8946,8945,8908,18851,18868,18671,22842,22816,23012,22470,22330,22436,32684,31498,32506,33037,32847,32693,32794,32813,32571,33044,33108,33167,8772,8792,8744,33149,33037,33059,33218,33037,33149,9297,9272,9426,35203,35052,35064,15866,15835,15975,16366,16510,16494,34472,34679,34412,34702,34775,34853,34213,33925,33995,9938,9937,10015,11757,11607,11790,11374,11255,11381,8392,8802,8572,14474,14450,14786,14426,14450,14474,14435,14466,14203,15158,15189,15263,25639,25577,25801,34284,34226,34253,24873,24960,24697,10090,9978,10182,16020,16111,16385,17790,17822,17623,15941,15899,15740,14435,14847,14861,15740,15899,15784,6963,6950,7012,8765,8772,8744,22413,22656,22606,22685,22656,22413,27323,27068,27141,27697,27915,27880,27643,27546,27781,33444,33566,33421,33421,33321,33210,33964,34024,34463,35311,35059,35075,35154,35095,34983,35260,35049,35158,35352,35309,35185,7255,7103,7323,7002,7130,6918,7118,7130,7002,35154,34983,35048,34994,34888,35089,35072,35203,35064,24000,23826,23761,23441,23451,23700,24000,23899,24072,9978,9938,10015,27610,27687,27481,27481,27493,27342,26527,26286,26846,27694,27723,28047,27643,27710,27556,21871,22117,21953,25715,25576,25766,26527,26846,27384,34348,34284,34253,34463,34024,34138,34399,33951,34595,8946,9021,9101,9638,9679,9230,8931,9021,8946,13017,13015,13385,12695,12952,12851,12695,12614,12627,28419,28668,28289,28555,28668,28419,9272,9166,9287,8545,8750,8710,9172,9166,9272,9297,9426,9436,7954,7973,8119,7404,7518,7556,11374,11381,11444,34046,34179,33995,34213,34179,34209,8772,8908,8945,28135,28093,27983,33229,33108,32910,34158,33941,33651,6978,7105,7005,19164,19093,19001,35309,35260,35158,7130,7118,7245,7271,6882,6918,16657,16762,16812,15960,15975,16108,23441,23700,23679,35176,35203,35072,35089,34850,35191,35249,35369,35227,35282,35344,35157,35309,35406,35260,35437,35369,35249,35437,35249,35316,35336,35316,35271,35336,35271,35382,6912,6911,6959,6757,6853,6996,6922,6824,6963,6963,6831,6950,6934,6911,6912,6865,6911,6934,6865,6934,6981,6865,6981,6841,7187,6884,6981,7556,7518,7686,7408,7317,7379,7573,7821,7583,9255,9297,9381,9588,9607,9653,11268,11374,11444,12063,11862,11925,11829,11862,12063,12126,12528,12379,20948,20880,20935,20935,20701,20033,20948,20935,21036,20948,21036,21048,21183,21128,21235,21427,21412,21306,24960,25007,24835,24898,25007,24960,24873,24697,24480,32521,32646,32571,33303,33222,33229,30654,30435,30222,32365,32646,32521,35382,35271,35301,7322,7317,7408,7025,6978,7005,25715,25766,25841,23727,23441,23679,24275,23650,24183,21427,21593,21412,21015,21121,21150,21272,21242,21429,21429,21515,21700,21700,21786,21871,21871,21962,22117,20992,20991,21015,20741,20770,20750,20741,20750,20297,20162,20297,20131,20162,20131,20007,35369,35344,35282,11268,11444,11335,7187,6974,6884,21427,21632,21593,22516,22330,22470,21593,21632,21727,23231,22842,23012,35212,35167,35085,35312,35167,35212,6862,6954,7012,6862,7012,6950,19001,19093,18982,20007,20131,19873,19001,18982,18868,19001,18868,18851,15960,16108,16147,20007,19873,19962,20991,21121,21015,25966,25715,25841,25691,25715,25857,34284,34443,34226,34365,34399,34498,35422,35382,35301,28065,27983,27880,33474,33321,33421,33037,33031,32847,7443,7388,7686,7410,7399,7506,7437,7500,7528,7340,7399,7410,8493,8569,8532,8532,8569,8672,8672,8569,8744,8687,8931,8908,8068,8282,8364,8068,8364,8157,14450,14426,14526,12379,12528,12763,14474,14786,14464,6884,6974,6910,7118,7100,7255,7002,7100,7118,8572,8802,8750,7882,7954,8119,8572,8750,8545,9638,9230,9574,12952,13015,13017,12614,12417,12177,19962,19873,19725,21121,21242,21272,23377,23231,23012,23727,23679,23826,35176,35072,35067,35321,35487,35339,35366,35422,35087,35366,35087,35265,10429,10444,10550,10771,10634,10895,12639,12893,12695,10270,10429,10057,12893,13015,12952,14110,14466,14142,6954,6932,7140,6859,6932,6954,22516,22470,22562,22296,22348,22260,24276,24394,24275,22296,22260,22117,6910,6974,6762,27723,27687,27610,27694,27687,27723,27985,28077,28255,27915,28065,27880,27546,27643,27556,27736,27643,27781,35176,35067,35320,26169,26451,26350,25624,25577,25526,24167,24000,24072,24167,24072,24272,6762,6974,6961,10266,10100,10237,9978,9879,9938,9580,9653,9792,10133,10100,10266,10133,10266,10021,10133,10021,10046,21593,21727,21835,24275,24394,24480,23650,23955,24183,28135,28290,28093,28905,28847,28668,28214,28290,28135,33108,33222,33167,33222,33108,33229,7583,7821,7787,7197,7322,7219,9746,9708,10057,9708,9667,9694,7910,7954,7882,7627,7733,7891,8854,9053,8670,8384,8535,8374,19725,19771,19250,18868,18597,18671,27384,26846,27298,35260,35311,35075,35392,35311,35260,10100,10090,10182,14220,14474,14464,16124,15960,16147,25715,25588,25576,25691,25588,25715,6757,6996,6670,21362,21593,22207,21242,21515,21429,7100,7103,7255,7057,7103,7100,25707,25624,25526,24675,24873,24480,29485,29476,29178,29998,29900,29682,30513,29554,30358,28847,28590,28668,35533,35366,35265,35320,35067,35321,6853,6824,6922,7910,8019,7973,28905,28668,28806,34399,34365,34348,34443,34365,34498,27915,27697,27710,28290,28555,28356,6840,7169,7267,6947,6879,7075,9580,9792,9938,21279,21412,21408,22610,22516,22562,22733,22562,22842,9166,8915,9150,9255,9172,9272,9255,9272,9297,9746,9638,9667,8908,8931,8946,8765,8908,8772,35506,35057,35157,7116,7273,7323,18244,17464,18421,17155,16657,17165,16124,15866,15960,17357,17464,17470,7388,7322,7408,7317,7070,7489,7443,7686,7518,6824,6831,6963,7057,7173,7103,35384,35052,35203,7103,7173,7323,7202,6882,7271,15710,15430,15835,14426,14097,13636,14947,15263,14901,14466,14435,14861,14110,14142,13907,17948,17879,18127,17879,17822,17790,18050,18298,18127,35024,35220,34845,35269,35140,35007,35166,35007,35095,35154,35048,35256,35256,35048,35167,12379,12763,13003,11862,11757,11790,18528,18597,18412,19725,19250,19181,34463,34138,34589,33529,33566,33444,7437,7528,7506,7437,7506,7266,8641,8765,8744,34651,34679,34472,35321,35141,35089,35321,35067,35141,34651,34472,34698,9588,9532,9607,9452,9532,9588,11829,11757,11862,11061,10957,11255,8569,8641,8744,8292,8384,8236,8429,8384,8292,33964,33685,33588,6831,6869,6950,21786,21962,21871,22685,22893,22656,7350,7443,7518,7404,7556,7573,15960,15866,15975,16124,16147,16366,15899,15941,16020,15312,15784,15325,24873,24898,24960,24931,24898,24873,25326,25526,25007,26451,26379,26350,8429,8493,8532,27548,27493,27481,28276,28635,28819,27643,27736,27710,28065,28214,28135,26249,26084,26169,33685,33566,33529,33321,33218,33149,13249,13404,13385,12695,12893,12952,12417,12323,12177,11205,11964,11441,17464,17357,17232,17311,17357,17437,24255,24167,24272,23290,23231,23441,23441,23231,23377,23727,23826,23775,35154,35166,35095,35323,35166,35154,35312,35212,35380,7099,7340,7410,7099,7410,7273,8915,9053,9150,9532,9445,9524,8527,8743,8543,9384,9445,9532,11170,11255,11374,12016,11829,12063,30180,30361,30753,29348,28927,29178,33384,33218,33321,32757,32506,32632,8654,8545,8710,8572,8196,8392,7882,8119,7944,9381,9297,9436,27807,27915,27710,32646,32655,32571,32731,32655,32646,32731,32646,32365,33581,33474,33421,7954,7910,7973,7490,7583,7787,8260,8370,7944,14947,14901,14847,26169,26084,26017,34179,34213,33995,33825,33651,33620,6830,6879,6947,21962,22095,22117,24931,25000,24898,35542,35406,35309,22911,22733,22842,21306,21412,21279,31279,31323,31122,31363,31409,31279,31428,31409,31363,31514,31409,31428,32757,32708,32868,34679,34775,34562,34698,34472,34533,7469,7583,7513,15866,15710,15835,16114,16124,16366,15941,16111,16020,15937,16111,15941,6820,7010,6932,7173,7116,7323,6801,6862,6950,8743,8654,8710,8765,8687,8908,9667,9574,9656,8520,8641,8569,10090,9968,9978,10100,10085,10090,11635,11607,11757,33474,33365,33321,33222,33389,33167,33303,33389,33222,35406,35392,35260,17155,17165,17232,24898,25000,25007,24467,24480,24394,34814,34775,34679,7322,7215,7317,6978,6830,7105,7197,7215,7322,7322,7388,7219,9445,9381,9436,9384,9381,9445,20880,20701,20935,20813,20701,20880,20813,20880,20986,20880,20948,20986,20948,21048,20986,21306,21183,21235,20767,20741,20720,20569,20741,20297,20991,21051,21121,21121,21107,21242,21647,21786,21515,21515,21786,21700,21962,21946,22095,20216,20162,20007,23775,23826,24000,24390,24272,24397,22893,22970,22656,26216,26169,26017,25801,25577,25624,29728,29600,29485,29732,29600,29728,35369,35444,35344,35344,35506,35157,35352,35542,35309,35406,35466,35392,35336,35437,35316,35496,35437,35336,35496,35336,35382,35496,35382,35436,21306,21279,21183,20741,20799,20770,35437,35444,35369,6911,6791,6959,6853,6757,6824,6824,6758,6831,6831,6744,6869,6869,6801,6950,6865,6791,6911,6809,6791,6865,6809,6865,6841,6809,6841,6776,6841,6884,6776,10133,10085,10100,35436,35382,35432,25707,25801,25624,20799,20975,20991,27141,27068,26676,27736,27807,27710,26702,26379,26451,33921,33825,33875,6776,6884,6767,12126,12024,12063,12098,12006,11830,20975,21051,20991,21593,21408,21412,22973,22911,22842,22973,22842,23231,22685,22413,22348,27548,27481,27687,27384,27493,27451,32868,32708,32847,33031,33037,33226,32655,32794,32571,32731,32794,32655,35380,35212,35311,6674,6830,6978,6767,6884,6910,6862,6859,6954,6723,6859,6862,14435,14726,14847,14834,14726,14767,22095,22296,22117,22061,22296,22095,9544,9580,9938,21321,21408,21362,32080,32309,31717,35432,35382,35422,8546,8687,8641,8384,8429,8532,8384,8374,8236,22330,22389,21835,35853,35432,35422,8594,8743,8527,8743,8854,8543,8854,8743,9071,33875,33825,33620,33229,32910,33172,15189,15312,15325,14814,14947,14847,33921,34158,33651,34643,34698,34533,6767,6910,6762,22330,22516,22444,34365,34443,34284,34595,33951,34736,27781,27807,27736,27996,28214,28065,33566,33581,33421,33474,33596,33365,33365,33384,33321,33701,33581,33566,33701,33566,33685,33701,33685,33742,6762,7075,6879,18298,18528,18412,19250,19164,19181,18319,18528,18298,17879,17948,17822,19164,19134,19181,22444,22516,22610,30475,30513,30358,30654,30782,30435,34852,34698,34805,34651,34814,34679,7044,7116,7173,11829,11635,11757,11550,11635,11829,14947,15158,15263,23775,24000,23996,24390,24647,24515,7822,8157,8041,7266,7506,7399,7266,7399,7340,34736,33951,34871,22610,22562,22733,35392,35327,35311,35466,35327,35392,33172,32910,32817,33758,33366,33389,6670,6352,6488,11268,11170,11374,7002,7057,7100,6938,7057,7002,15196,15312,15189,17822,17828,17623,15312,15740,15784,33734,33701,33742,34575,34498,34399,35312,35256,35167,35166,35278,35007,34764,34736,34871,35412,35256,35312,6802,6762,6879,10932,11257,10895,12627,12639,12695,12964,13385,13015,18938,19001,18851,35639,35506,35344,27451,27548,27513,30753,30361,30833,9667,9708,9746,10444,10499,10653,8914,9021,8637,11335,11444,11607,18788,18938,18851,12866,13015,12893,27996,28065,27915,28847,28905,29238,7116,7108,7273,6946,7108,7116,6757,6758,6824,6938,7034,7057,21316,21515,21242,22296,22685,22348,27493,27384,27298,25966,25841,25901,25588,25682,25280,27548,27687,27694,7219,7388,7262,6816,6840,6772,7561,7886,7500,24276,24467,24394,25326,25707,25526,24358,24467,24276,13907,13776,13643,14726,14814,14847,14947,14834,15158,15158,15196,15189,29695,29476,29600,7057,7034,7173,7202,7010,6882,14834,14814,14726,16461,16385,16111,18528,18671,18597,24000,24167,23996,22574,22610,22716,32794,32907,32813,32880,32907,32794,6758,6744,6831,7387,7404,7573,7469,7573,7583,16657,16494,16510,16124,16114,15866,16330,16494,16327,16400,16461,16240,18050,18319,18298,20234,19593,20033,33758,33389,33648,32907,33172,32817,34852,34814,34651,34850,34798,35191,34852,34651,34698,34731,34853,35191,35176,35384,35203,35521,35436,35509,13676,13907,13643,22973,22733,22911,21183,21279,21181,28271,28283,28214,27323,27781,27546,27837,27781,27960,33581,33596,33474,34589,34226,34443,9381,9163,9255,9452,9384,9532,9452,9588,9580,9804,10270,10057,29756,29732,29728,29744,29732,29756,31400,31323,31279,31400,31279,31409,7291,7561,7500,7238,7500,7437,25966,25901,26015,26052,26216,26017,26569,26702,26451,25326,25007,25200,31514,31428,31551,16631,16722,17023,24675,24931,24873,8594,8545,8654,8506,8572,8545,7944,8370,7908,7910,7850,7891,26402,26451,26169,31559,31514,31685,34158,34209,34046,34345,34209,34291,33921,33651,33825,21786,21946,21962,10085,9968,10090,10133,10046,10085,10021,10266,10402,11061,11255,11170,33734,33596,33581,7108,7138,7273,7065,7138,7108,23955,23650,23104,25070,25061,24931,24317,24183,24268,7070,7317,7215,6830,6802,6879,7561,7653,8088,25857,25966,25951,35327,35380,35311,35866,35380,35327,6820,6932,6859,7065,7099,7138,10046,9968,10085,23603,23290,23441,30839,30782,30654,30839,30654,30768,7004,7070,7215,7262,7388,7443,7845,7850,7910,15299,15709,15740,16529,16631,16461,15229,15196,15158,26216,26402,26169,17623,17828,17578,17879,18050,18127,24277,24167,24255,23727,23603,23441,24277,24255,24390,31402,30753,30833,8743,8594,8654,9166,9172,8915,28555,28419,28356,28555,28290,28405,32757,32684,32506,33226,33037,33218,6677,6802,6830,6709,6801,6869,28283,28290,28214,16494,16330,16366,16268,16330,16327,17311,17232,17357,33031,32868,32847,35191,34853,35213,34391,33925,34751,7513,7583,7490,7404,7350,7518,16159,16114,16366,18377,18671,18528,19134,19164,19001,18788,18671,18685,34595,34575,34399,34498,34510,34443,35220,35024,35140,35278,35166,35323,34866,34643,34912,26052,26017,25801,6904,7350,7404,17578,17569,17343,16461,16631,17023,15777,15941,15740,24931,25061,25000,25707,25719,25801,24675,24480,24467,33389,33303,33420,26910,27141,26702,26702,27141,26676,27996,27915,27807,26569,26451,26402,35323,35154,35256,35509,35756,35691,34926,34775,34814,35539,35466,35406,35397,35269,35278,7138,7099,7273,7044,7173,7034,15709,15777,15740,17610,17464,18244,24396,24277,24390,24183,24317,24276,24358,24317,24268,25949,25719,25743,34701,34575,34595,8641,8687,8765,8520,8313,8388,8292,8493,8429,27837,27807,27781,33478,33384,33365,7129,7215,7197,7129,7197,7166,6984,7044,7034,8236,8374,8171,8374,8282,8171,11117,11061,11170,11117,11170,11268,11335,11607,11635,17790,17870,17879,17343,17023,17037,30358,29554,29468,35444,35639,35344,35506,35542,35352,35437,35526,35444,35577,35526,35437,35577,35437,35496,35577,35496,35566,35496,35521,35566,35496,35436,35521,12379,12024,12126,12016,12024,12098,20799,20767,20975,20975,21070,21051,21051,21107,21121,21786,21754,21946,20741,20767,20799,20216,20297,20162,20216,20007,19962,32900,32684,32757,35436,35432,35509,6791,6697,6959,6757,6673,6758,6758,6673,6744,6744,6700,6869,6718,6697,6791,6718,6791,6809,6718,6809,6612,6809,6776,6612,6776,6767,6612,6612,6767,6602,21120,21128,21183,21120,20986,21128,21128,20986,21048,20813,20739,20701,20701,20334,20033,21120,21183,21181,21279,21321,21181,29732,29695,29600,30563,29900,29998,35432,35719,35509,24826,24675,24467,20767,21070,20975,35384,35176,35413,19134,19001,18938,19999,20216,19962,27960,27781,27912,33596,33478,33365,33701,33734,33581,33742,33685,34328,19999,19962,19989,21279,21408,21321,21070,21107,21051,7850,7627,7891,9708,9694,10057,9667,9638,9574,26438,26569,26402,25953,26052,25801,31600,31717,30560,32844,32731,32365,34626,34510,34498,21408,21593,21362,35278,35269,35007,35412,35312,35380,7850,7478,7627,7882,7845,7910,7720,7845,7706,26438,26402,26216,34209,34319,34213,34345,34319,34209,21593,21835,22207,21107,21316,21242,6723,6862,6801,6691,6820,6859,6918,6938,7002,8594,8506,8545,8527,8506,8594,18816,19134,18938,20420,20569,20216,18788,18851,18671,25085,25000,25061,25085,25007,25000,25719,25953,25801,27837,27996,27807,34819,34805,34698,34852,34926,34814,34819,34698,34643,6820,6882,7010,23153,22973,23231,22389,22330,22444,23153,23231,23290,23603,23727,23775,29900,29744,29756,29775,29744,29900,35451,35412,35380,35413,35176,35320,7166,7197,7219,17037,17023,16722,23742,23603,23775,24397,24687,24647,25682,25588,25691,24317,24358,24276,25070,25085,25061,23955,23104,23393,7469,7387,7573,7350,7262,7443,7490,7787,7733,8914,9154,9021,16842,17037,16722,16400,16529,16461,17596,17610,17944,17311,17155,17232,17623,17870,17790,17225,17578,17343,22515,22444,22610,24121,23955,24217,21956,22095,21946,25200,25085,25117,33163,32731,33264,33464,33277,33172,33420,33303,33229,34736,34745,34595,34575,34626,34498,34764,34745,34736,35342,35220,35140,15777,15937,15941,15299,15740,15312,25966,25857,25715,25951,25966,26015,6946,7065,7108,6756,6938,6665,23996,24167,24277,33296,33226,33218,32905,32900,32868,32868,32900,32757,33719,33478,33596,10270,10499,10444,10634,10499,10387,9763,10057,9694,31514,31533,31400,31400,31380,31323,31323,31402,30833,31559,31533,31514,11550,11335,11635,30782,30945,30435,30977,30945,30782,35412,35353,35256,35269,35342,35140,35451,35353,35412,35659,35533,35052,35503,35413,35320,35339,35320,35321,12087,12639,12627,13898,14110,13907,12087,12627,12177,29744,29695,29732,29775,29695,29744,30563,30180,30753,6670,6673,6757,8520,8569,8313,8171,8282,8063,14110,14203,14466,14814,14834,14947,15196,15229,15312,13898,14076,14110,14203,14076,13898,21316,21647,21515,33296,33218,33384,22574,22515,22610,22610,22733,22716,17610,17470,17464,17596,17470,17610,23955,24121,24183,25070,24931,24950,24224,23955,23998,32905,32868,33031,31685,31514,31551,32731,32880,32794,32980,32880,33163,7908,8370,8392,7602,7733,7627,7356,7387,7360,14354,14726,14435,17059,17155,17204,16330,16159,16366,33420,33229,33277,34291,34209,34158,21647,21754,21786,9942,9955,9968,9968,9955,9978,10021,9968,10046,10266,10739,10402,30768,30513,30475,30768,30654,30513,7360,7387,7469,7490,7733,7602,16268,16159,16330,16114,16013,15866,28283,28405,28290,28555,28806,28668,30543,30768,30475,28444,28405,28283,33277,33229,33172,34931,34926,34852,34866,34819,34643,25949,25953,25719,25085,25200,25007,24931,24675,24950,34931,34852,34805,17579,17870,17623,18050,17870,17936,23440,23153,23290,35353,35323,35256,35459,35323,35353,7602,7627,7441,15782,15937,15777,16100,15937,15962,25742,25682,25691,34745,34701,34595,34589,34138,34226,34755,34701,34745,9955,9879,9978,9052,9172,9255,29468,30217,30306,34291,34158,34306,34751,33925,34213,6840,6774,6978,6455,6602,6477,6816,6774,6840,6840,7267,6772,22716,22733,22973,20869,21071,20939,6904,7262,7350,7129,7004,7215,6965,7266,7340,7561,7321,7653,8063,8282,8068,7087,7266,6857,12024,12016,12063,12098,12024,12379,11732,11814,11697,6673,6700,6744,6575,6665,6882,9544,9452,9580,9656,9763,9694,9656,9694,9667,11732,11550,11829,11335,11117,11268,21754,21956,21946,30834,30563,31055,35698,35542,35506,35466,35582,35327,7720,7850,7845,26015,25901,26527,25857,25742,25691,27067,26527,27384,26163,26438,26216,26163,25953,26007,34689,34626,34575,6990,7004,7129,6946,7116,7044,8687,8546,8931,8569,8493,8313,14953,15229,15158,17470,17437,17357,16327,16494,16657,17479,17437,17470,26569,26748,26702,27360,27781,27323,28118,28214,27996,28444,28630,28405,26163,26216,26052,35086,34853,34775,33226,33239,33031,33584,33296,33384,33158,33172,32907,33932,33875,33758,6674,6677,6830,6772,7267,6891,18377,18528,18319,20569,20297,20216,22389,22444,22515,22617,22716,22690,22657,22685,22312,7161,7166,7219,17379,17511,17578,16629,16722,16631,16629,16631,16529,6700,6709,6869,6906,6984,6756,6938,6984,7034,35542,35539,35406,6946,6984,6906,11205,11372,11257,32900,32728,32684,32905,32728,32900,14203,14354,14435,14834,14953,15158,14203,14110,14076,13907,13676,13898,16240,16461,16111,16100,16111,15937,7822,8041,7524,8388,8494,8520,12866,12893,12639,16197,16100,15962,27548,27451,27493,27854,27548,27694,34701,34689,34575,34871,33951,34787,8494,8546,8641,8494,8641,8520,28819,28635,28927,35659,35052,35751,9679,9453,9230,11184,11117,11335,29468,29790,30217,6891,7267,7070,6674,6978,6774,33758,33875,33620,33451,33389,33420,16607,16629,16529,24950,24675,24826,25200,25348,25326,25851,25742,25857,24647,24687,24676,25851,25857,25951,34806,34689,34701,6593,6891,7070,35323,35397,35278,35040,34871,35298,35459,35397,35323,35487,35321,35089,35413,35513,35384,24121,24268,24183,24217,24268,24121,6709,6723,6801,12747,12866,12639,28047,27854,27694,29065,28819,28927,28630,28806,28555,28630,28555,28405,32880,32980,32907,33170,32980,33163,33274,33239,33226,33734,33773,33596,33478,33600,33384,33296,33274,33226,33773,34221,33879,33685,33964,34328,7841,7822,7578,26771,26748,26569,26910,26748,26771,35006,34931,34819,34306,34158,33921,8914,9313,9154,20775,20739,20813,17479,17596,17944,20775,20813,20869,20813,20986,20869,20986,21071,20869,21120,21071,20986,21181,21071,21120,20767,20793,21070,21070,21166,21107,21107,21166,21316,21509,21637,21647,21647,21637,21754,21754,21817,21956,20569,20720,20741,19725,19181,19165,35566,35626,35577,35577,35626,35526,35526,35642,35444,35542,35667,35539,35631,35626,35566,35631,35566,35521,35631,35521,35691,7055,6990,7129,7004,6593,7070,7262,7161,7219,7003,7161,7262,7166,7161,7003,7404,7387,7356,11550,11491,11335,12016,11732,11829,14097,14426,14220,20739,20511,20701,19165,19181,19134,21181,21321,21071,20720,20793,20767,29348,29178,29476,29873,29775,29900,35626,35642,35526,35691,35521,35509,20511,20477,20701,21071,21321,20939,31533,31380,31400,31549,31380,31533,20477,20334,20701,25905,26015,26016,28255,28047,27985,28819,28469,28276,35642,35639,35444,35756,35509,35719,20334,20234,20033,22389,22515,22505,27925,28047,27995,6674,6774,6608,6723,6691,6859,19095,19165,19134,31685,31551,33066,31446,30945,31407,31446,30560,30945,31446,31600,30560,33170,33158,32980,30782,30839,30977,35616,35582,35466,35616,35466,35539,7706,7845,7882,7469,7513,7360,7706,7882,7944,10402,10957,10780,9955,9875,9879,9879,9544,9938,10499,10634,10771,10387,10499,10270,10932,10634,10638,9927,10273,10387,17870,18050,17879,18788,18816,18938,17936,17772,17973,17623,17578,17579,35397,35386,35269,35592,35386,35397,6602,6767,6762,6718,6543,6697,6559,6670,6488,6673,6522,6700,6530,6631,6709,6709,6631,6723,6723,6631,6691,21234,21166,21070,21956,22061,22095,16159,16013,16114,16170,16268,16274,16492,16607,16529,16749,16842,16722,16100,16240,16111,16197,16240,16100,34764,34755,34745,35040,35298,35045,34819,34931,34805,34926,35086,34775,34358,34319,34345,10021,9942,9968,16170,16013,16159,35038,34755,34764,34686,34510,34626,19989,19962,19791,7266,7234,7437,7087,7234,7266,7340,7099,6965,16492,16529,16400,25070,25117,25085,25953,26163,26052,25012,25117,25070,6499,6762,6802,6608,6774,6816,6719,6816,6772,7055,7129,7166,6984,6946,7044,6984,6938,6756,8506,8196,8572,8915,9172,9052,8637,9021,8474,8151,8292,8236,17059,17040,17155,17610,18244,17944,24403,23996,24277,23085,22973,23153,22505,22574,22617,24403,24277,24396,35523,35451,35380,9163,9381,9384,9163,9384,9269,19791,19962,19725,32980,33158,32907,33439,33451,33420,32880,32731,33163,12866,12964,13015,12861,12964,12866,16013,15710,15866,24687,24909,24676,25905,25851,25951,25905,25951,26015,27960,27996,27837,29371,29238,28905,33235,32905,33031,31582,31533,31559,6646,6802,6677,7042,6352,6670,11531,11491,11550,11106,10952,11061,16749,16722,16629,8171,8151,8236,8063,8151,8171,14220,14426,14474,26016,26015,26665,27684,27513,27548,27684,27548,27854,22505,22515,22574,22574,22716,22617,18227,18377,18319,17578,17225,17379,19781,19791,19725,14203,14430,14354,14354,14430,14726,13676,13643,13404,8670,8543,8854,12964,13249,13385,18227,18319,18050,19165,19781,19725,33417,33420,33277,34291,34358,34345,34419,34306,34452,34306,33921,34452,9269,9384,9452,25719,25707,25743,11106,11061,11117,19090,19781,19165,21509,21647,21316,17183,17225,17037,7003,7055,7166,6990,6929,7004,7513,7490,7434,11184,11106,11117,11732,11531,11550,11697,11531,11732,17043,17183,17037,20800,20869,20862,22716,22973,22905,24647,24676,24671,28047,27925,27854,27995,28047,28198,27360,27323,27141,26910,26702,26748,33742,33773,33734,33239,33235,33031,34686,34626,34689,7434,7490,7602,16268,16170,16159,16013,15565,15710,17040,16657,17155,16325,16492,16400,16560,16749,16629,17018,17043,17037,15782,15777,15709,15782,15709,15703,7234,7238,7437,7087,7238,7234,16325,16400,16240,34419,34358,34291,7360,7223,7278,12754,12747,12562,12919,13205,13249,12861,12754,12919,34755,34806,34701,34937,34806,34755,34820,34806,34937,11184,11335,11282,28540,28479,28469,28469,28479,28255,29348,29476,29737,35386,35342,35269,35592,35342,35386,35451,35459,35353,35720,35459,35451,8396,8373,8527,8527,8373,8506,8494,8431,8546,8313,8493,8292,16560,16629,16607,25743,25707,25326,24826,24467,24358,24378,24358,24268,27960,28118,27996,33741,33719,33596,33587,33648,33389,8698,8670,9053,8462,8396,8527,8576,8670,8698,33454,33417,33277,33451,33587,33389,35915,35698,35506,35674,35523,35380,18685,18816,18788,20869,20939,20862,22905,22973,23085,23228,23225,23085,25892,25905,26016,25826,25682,25742,26771,26569,26635,26007,25949,25922,34820,34686,34689,11282,11335,11491,11814,11732,12016,11835,12098,11830,11282,11491,11508,18017,18050,17936,18142,18227,18050,18377,18407,18671,17294,17379,17225,17294,17225,17183,24224,24217,23955,24299,24217,24224,17155,17311,17204,17018,17037,16842,24515,24403,24396,25826,25742,25851,33719,33600,33478,33571,33587,33451,14221,14430,14203,14221,14203,13898,18142,18050,18017,31380,31408,31323,29737,29695,29775,29124,29065,29241,31549,31408,31380,31549,31533,31582,30977,30839,30880,31600,31902,31717,35339,35503,35320,35575,35503,35339,35487,35089,35483,7625,8063,8068,8155,8313,8292,7841,8068,7822,12098,12379,12006,14464,14786,15430,31582,31559,31685,35698,35667,35542,10780,10952,10879,10780,11061,10952,10780,10957,11061,9922,9875,9942,31498,32684,32797,31446,31604,31600,10879,10952,11106,11508,11491,11531,26665,26527,27067,27843,27684,27854,27671,27684,27783,30880,30839,30768,30376,30306,30217,16170,16168,16013,14968,14464,15430,16544,16327,16657,16492,16560,16607,16907,17018,16842,16135,16325,16240,16135,16240,16197,29259,29065,28927,29476,29695,29737,33464,33454,33277,33417,33439,33420,32365,32309,32844,12747,12861,12866,13480,13676,13404,12747,12187,12562,32797,32684,32728,33431,33274,33296,32940,32797,32728,7524,8041,7653,9163,9052,9255,9177,9269,9234,9875,9955,9942,14631,14767,14726,26569,26438,26496,27960,28005,28118,7167,7291,7500,6966,7099,7065,15299,15312,15229,21817,22061,21956,30880,30768,30930,31710,31857,31600,34676,34443,34510,34806,34820,34689,35038,34764,34871,8934,9052,9163,29737,29775,29739,6617,6719,6772,6591,6646,6677,6608,6719,6640,7736,7706,7944,7720,7478,7850,14870,14953,14834,26496,26438,26163,28540,28469,28819,29120,28905,28806,28271,28444,28283,28617,28444,28585,33571,33439,33454,34676,34510,34686,33773,33741,33596,33780,33589,33600,6843,6966,7065,6832,7065,6946,9922,9942,10021,18227,18407,18377,18017,17936,17973,24217,24299,24268,24378,24299,24433,30543,30475,30358,31857,31902,31600,8053,8292,8151,8388,8431,8494,13205,13404,13249,28198,28047,28255,33879,33741,33773,33584,33431,33296,6591,6677,6674,6691,6549,6820,6530,6709,6453,6938,6918,6665,35667,35616,35539,35751,35052,35384,35719,35432,35853,7055,6929,6990,6949,7003,6875,7003,7262,6875,17035,17294,17183,17579,17578,17511,16907,16842,16749,25949,26007,25953,25348,25200,25117,25348,25117,25012,20511,20410,20477,20477,20410,20334,20334,20353,20234,20234,20149,19593,20739,20592,20511,20800,20592,20739,20800,20739,20775,20800,20775,20869,21835,22389,22207,20793,20894,21070,21166,21509,21316,21637,21711,21754,20720,20694,20793,20569,20628,20720,20420,20628,20569,20420,20152,20348,20420,20348,20406,19999,19989,19871,29873,29900,29964,32940,32728,32905,35631,35778,35626,35626,35778,35642,35642,35837,35639,35639,35915,35506,35698,35849,35667,35667,35803,35616,35812,35778,35631,35812,35631,35691,14953,15166,15229,22550,22389,22505,26758,26496,26163,20592,20410,20511,20628,20406,20714,19989,19791,19871,20839,20894,20793,23153,23228,23085,22617,22550,22505,35625,35327,35582,35459,35592,35397,6612,6543,6718,6670,6522,6673,6494,6543,6612,6521,6612,6602,20410,20353,20334,6482,6521,6602,6567,6591,6674,8372,8196,8506,8462,8527,8543,8576,8543,8670,8327,8431,8388,11512,11508,11531,10879,11106,11013,11512,11531,11697,35616,35625,35582,35803,35625,35616,35422,35366,35853,10634,10932,10895,10057,9763,9804,16327,16274,16268,16281,16274,16327,20353,20149,20234,25012,25070,24950,34871,34787,35298,35038,35040,35045,35853,36233,36080,17579,17511,17491,18187,18407,18227,33020,32940,32905,33589,33384,33600,7434,7360,7513,7360,7434,7223,7167,7500,7238,15782,15962,15937,16455,16560,16492,15845,15962,15782,35114,35086,34926,34751,34213,34319,16455,16492,16325,35114,34926,34931,15166,15299,15229,17035,17183,17043,17424,17294,17123,24671,24403,24515,24671,24515,24647,24299,24378,24268,23104,22893,23393,27232,27360,27141,27089,27141,26910,26879,26910,26771,30376,30543,30358,30376,30358,30306,17491,17511,17379,15299,15703,15709,25905,25826,25851,25892,25826,25905,6499,6802,6569,12919,13249,12964,13480,13205,13088,14767,14870,14834,14953,15061,15166,15166,15061,15299,14430,14631,14726,14708,14631,14644,14631,14430,14644,28479,28362,28255,28540,28362,28479,28540,28819,29118,28819,29065,29124,33780,33600,33719,34463,34289,33964,33663,33584,33589,34334,34572,34508,34823,34686,34820,8372,8506,8373,24378,24826,24358,6425,6959,6697,21234,21509,21166,7706,7638,7720,7908,7736,7944,14708,14870,14767,18162,18227,18142,17772,17936,17870,34306,34419,34291,34358,34493,34319,34134,33921,33875,34134,33875,34216,33758,33648,33832,35503,35513,35413,35483,35089,35191,27689,27912,27781,6559,6522,6670,21509,21616,21637,18162,18142,18017,19045,19095,19134,6966,6965,7099,7134,7321,7291,6906,6832,6946,6756,6832,6906,7657,7638,7706,17596,17479,17470,16281,16168,16274,18879,19133,19593,17579,17772,17870,17424,17491,17379,17424,17379,17294,26496,26635,26569,26879,26635,26758,26635,26496,26758,29120,28806,28887,34419,34493,34358,7003,6929,7055,6949,6929,7003,16274,16168,16170,16678,16657,17040,16129,16197,15962,16129,16135,16197,17035,17043,17018,29964,29900,30834,29737,29587,29348,35040,35038,34871,34787,35480,35298,8698,9053,8915,8396,8372,8373,29065,29259,29320,28444,28617,28630,28271,28214,28118,8335,8372,8396,31408,31402,31323,31524,31402,31408,31524,31408,31549,31524,31549,31687,31524,31618,31520,31446,31527,31604,31604,31710,31600,31857,31899,31902,31253,31407,30945,31527,31407,31610,31075,30977,30880,30930,30768,30807,22690,22550,22617,22690,22716,22905,31524,31687,31618,7291,7321,7561,7167,7238,6956,35038,34937,34755,9804,9763,9721,21616,21711,21637,22657,22893,22685,31527,31710,31604,32844,32309,32790,10402,9922,10021,9234,9269,9452,9765,9922,9861,10387,10479,10634,35700,35513,35503,24676,24909,25682,27671,27451,27513,34877,34823,34820,21711,21817,21754,6719,6608,6816,6569,6802,6646,6640,6719,6617,8322,8462,8543,19233,18879,19593,28223,28271,28118,10479,10638,10634,11205,11441,11372,9269,9177,9163,9052,8775,8915,9765,9879,9875,11106,11184,11013,12098,11814,12016,11835,11814,12098,29873,29739,29775,29892,29739,29873,8548,8775,8615,8257,8335,8462,29320,29259,29348,29249,29120,29264,28887,28806,28630,8196,7908,8392,7575,7720,7638,7722,7908,8196,8232,8196,8372,33832,33648,33860,34419,34548,34493,6832,6843,7065,6743,6843,6832,8775,8698,8915,17479,17361,17437,17281,17361,17479,17683,17772,17579,17973,18162,18017,17035,17018,16917,22685,22296,22312,24939,25012,24826,6569,6646,6464,8313,8327,8388,8063,8053,8151,8005,8053,8063,8005,8063,7667,9721,9763,9656,9721,9456,9542,27684,27671,27513,27843,27854,27925,27843,27925,27895,27925,27995,28046,30807,30768,30543,34289,34334,33964,34572,34289,34753,6838,6965,6966,17204,17311,17437,16690,16749,16560,22715,22690,22817,24676,25682,24797,7206,7524,7653,34823,34676,34686,34493,34751,34319,34866,35006,34819,34860,34751,34648,8053,8155,8292,9721,9656,9456,14870,15061,14953,15845,15782,15703,15943,16129,15962,14631,14708,14767,14221,13920,14199,17683,17579,17491,23775,23996,23742,20629,20592,20710,22312,22296,22061,28255,28362,28198,28046,27995,28198,34134,34452,33921,8122,8546,8431,11184,11080,11013,16518,16690,16560,15845,15703,15761,30666,30543,30730,30666,30807,30543,34970,35006,34866,35555,35483,35191,6464,6646,6591,33589,33584,33384,32952,32940,33020,33780,33719,33741,33439,33571,33451,33454,33439,33417,33172,33158,33464,15761,15703,15299,25472,25743,25326,25472,25326,25348,25012,24950,24826,17059,16678,17040,16280,16325,16135,24815,24826,24781,28198,28362,28424,27912,28005,27960,28585,28794,28617,28148,28005,27912,28110,28005,28219,33781,33648,33587,11184,11282,11185,30730,30543,30376,11205,11257,10932,6608,6567,6674,6617,6772,6891,18407,18685,18671,18543,18685,18540,6843,6867,6966,6743,6867,6843,6918,6882,6665,17746,18162,17973,22657,23393,22893,35720,35592,35459,35674,35451,35523,26061,26016,26665,25821,25682,25826,28417,28424,28546,29520,29320,29348,32483,32080,31902,6549,6691,6631,8462,8335,8396,8257,8462,8322,8209,8327,8313,11185,11282,11508,13205,13480,13404,12919,12964,12861,17707,17683,17491,17772,17754,17973,17754,17707,17746,17123,17294,17035,24224,24433,24299,23393,23881,23955,28424,28362,28540,28110,28223,28118,33879,33780,33741,33679,33781,33587,33679,33587,33571,34676,34589,34443,35213,34853,35086,35487,35575,35339,6540,6617,6520,6875,7262,6904,7278,7356,7360,16907,16917,17018,24531,23996,24403,25821,25826,25892,6453,6709,6700,19712,19233,19593,17281,17204,17361,33464,33158,33541,20628,20694,20720,20894,21234,21070,21509,21466,21616,21616,21534,21711,21711,21807,21817,20714,20694,20628,19871,19791,19781,35778,35872,35642,35866,35674,35380,35812,35872,35778,35812,35691,35756,35812,35756,35982,35756,35719,35982,20592,20490,20410,20410,20431,20353,20353,20253,20149,20149,19988,19593,20629,20490,20592,21321,21673,20939,20694,20839,20793,6792,7004,6929,6547,6567,6608,35866,35327,35625,6543,6448,6697,6559,6476,6522,6382,6453,6700,6494,6448,6543,6494,6612,6413,6494,6413,6393,11814,11512,11697,11545,11512,11814,11478,11569,12174,11421,11569,11478,20490,20431,20410,21321,21362,21673,29739,29587,29737,29892,29587,29739,30834,29900,30563,31942,31867,31685,33235,33274,33485,33632,33431,33584,35366,35533,36233,22207,22389,22550,35872,35837,35642,15097,15430,15710,16358,16281,16327,16129,16280,16135,16717,16907,16749,16096,16280,16129,34787,35220,35480,35038,35074,34937,34937,34877,34820,34823,34974,34676,34676,34759,34589,35006,35114,34931,35126,35114,35006,6530,6549,6631,6453,6549,6530,7223,7434,7602,7478,7720,7575,15862,15943,15962,15862,15962,15845,36087,35751,35384,35685,35384,35513,6482,6602,6455,20431,20253,20353,35837,35855,35639,7625,8068,7841,8053,8073,8155,8126,8209,8313,7657,7706,7736,29118,28819,29124,33684,33679,33571,35907,35575,35487,16678,16544,16657,16635,16544,16678,16635,16678,17059,16455,16518,16560,20253,20209,20149,35219,35213,35086,27671,27597,27451,27843,27783,27684,27913,27783,27843,27895,27925,28046,27895,28239,27913,6867,6838,6966,6956,7238,7087,7321,7206,7653,6813,6838,6867,17361,17204,17437,17944,18244,18879,24528,24433,24198,14199,14644,14430,14736,15061,14870,15628,15761,15237,20908,21234,20894,22090,22312,22061,26061,25821,25892,25860,25821,26061,34976,34877,34937,34751,34912,34643,34821,34912,34751,35909,35533,35659,31055,30563,30753,31524,31520,31402,31549,31582,31687,31407,31527,31446,31710,31803,31857,31253,30945,30977,31075,30880,30930,31075,31170,31113,23881,23998,23955,23922,23998,23881,11162,11185,11508,10954,11205,10932,19045,19134,18816,19045,18816,18767,22010,22061,21817,23385,23608,23393,23969,24065,23998,29320,29241,29065,29223,29241,29320,29120,29249,28905,28887,28630,28794,28794,28630,28617,27693,27815,27696,11569,11706,12087,11421,11706,11569,16717,16749,16690,16917,17123,17035,25012,25421,25348,24551,24826,24378,7908,7657,7736,7536,7449,7373,10707,10890,10932,10479,10536,10638,10387,10475,10479,10355,10475,10387,10355,10387,10273,31854,31803,31710,34452,34548,34419,34636,34548,34452,34636,34452,34566,33932,33758,33832,33860,33648,33781,6352,7042,6959,29587,29520,29348,29846,29520,29587,31075,30930,30979,30730,30807,30666,31803,31899,31857,7478,7441,7627,7383,7441,7478,34860,34821,34751,6602,6762,6477,6762,6499,6477,6488,6476,6559,18732,17944,18879,19090,19871,19781,21234,21466,21509,6547,6608,6475,8335,8232,8372,8257,8232,8335,8540,8576,8698,8637,8474,8612,8126,8313,8155,19095,19090,19165,18767,18816,18685,28354,28444,28271,28005,28110,28118,27689,27781,27360,28354,28415,28504,33780,33663,33589,33966,33879,34221,33897,33879,33966,33895,33860,33781,11044,11220,11205,11205,11220,11964,29790,29468,29238,7657,7575,7638,9922,9765,9875,9861,9922,10007,10354,10402,10780,10853,10780,10879,10853,10879,10876,14736,14870,14708,6477,6499,6424,6575,6882,6820,6756,6743,6832,21466,21534,21616,24531,24403,24671,22690,22715,22550,6857,7266,6965,7988,8053,8005,25052,25421,25012,25743,25812,25949,35045,35051,35038,35279,35051,35045,17057,17123,16917,17683,17754,17772,18162,18187,18227,23998,24065,24224,24433,24551,24378,23922,23881,23798,24613,24531,24671,24613,24671,24676,24559,24551,24528,24815,24939,24826,15774,15862,15845,15943,16096,16129,16280,16455,16325,16574,16717,16690,16907,17057,16917,15774,15845,15761,16544,16471,16327,16281,16248,16168,16496,16471,16544,16574,16455,16096,35313,34970,35304,34912,34970,34866,35114,35219,35086,35206,35219,35114,35213,35555,35191,35700,35503,35575,6540,6608,6640,6424,6499,6368,6540,6640,6617,11220,11333,11478,11134,11333,11220,6464,6591,6496,8548,8540,8698,8428,8540,8389,8775,8666,8615,10876,10879,11013,16574,16690,16518,21534,21807,21711,24781,24939,24815,28354,28271,28223,28887,29042,29120,29249,29371,28905,33454,33684,33571,33797,33895,33781,33729,33464,33541,33557,33464,33729,34877,34915,34823,34328,33964,34334,34960,34915,34877,8202,8431,8327,29264,29371,29249,14221,13898,13920,14644,14736,14708,35700,35685,35513,35700,35863,35833,27783,27597,27671,27693,27597,27783,27693,27783,27913,21807,21815,21817,10929,10876,11013,11080,11184,11185,10707,10932,10638,30632,30730,30376,30979,31048,31170,7988,8073,8053,8209,8202,8327,7578,7822,7524,33830,33663,33780,33557,33684,33454,6838,6775,6965,6732,6743,6756,11797,11835,11830,11162,11080,11185,32940,32952,32797,33235,33239,33274,15628,15774,15761,14648,14736,14644,6949,6858,6929,6875,6858,6949,7404,7356,6904,7441,7223,7602,7339,7383,7478,8967,9230,9453,10387,10270,9927,34821,35122,34912,34648,34751,34493,35915,35849,35698,8073,8126,8155,25421,25472,25348,25570,25472,25421,34001,33932,33860,33860,33932,33832,34548,34648,34493,34970,35126,35006,35168,35126,35313,9610,9544,9879,10890,10954,10932,16471,16358,16327,16496,16358,16471,16635,16903,16636,17754,17683,17707,17491,17555,17707,18251,18187,18162,24531,23742,23996,18743,18767,18685,19045,19090,19095,22817,22690,22905,22817,22905,22838,7391,7578,7524,7159,7223,7119,16096,16455,16280,16455,16574,16518,15094,15299,15061,28870,29042,28887,28870,28887,28794,35106,34976,34937,34328,34334,34508,21815,22010,21817,22312,22579,22657,33485,33274,33431,35849,35803,35667,16496,16635,16636,24939,25052,25012,24812,25052,24939,24781,24826,24551,12639,12187,12747,12754,12861,12747,13920,13898,13734,33302,33154,33235,33879,33897,33780,34463,34589,34759,33797,33781,33679,11162,11508,11297,10954,11112,11205,12639,12087,11912,11622,11545,11814,33154,33020,32905,31687,31582,31867,6382,6700,6522,6440,6575,6820,6496,6591,6567,6520,6617,6486,6743,6813,6867,6732,6813,6743,6732,6756,6650,20800,20862,20834,22838,22905,23011,31055,30753,31402,31582,31685,31867,31685,33066,31942,35748,35833,35836,36087,35909,35751,35379,35213,35219,10540,10354,10780,9765,9610,9879,10600,10780,10853,10823,10853,10876,10270,9804,9790,10475,10536,10479,10890,10944,10954,10954,10987,11112,24559,24781,24551,24551,24433,24528,32046,31899,31803,32046,32033,31899,31075,31253,30977,31113,31253,31075,31687,31867,31798,6496,6567,6394,10007,9922,10402,28415,28354,28223,26879,26771,26635,30979,30930,30807,33684,33797,33679,33815,33797,33684,10929,10823,10876,11297,11508,11324,34974,34823,34915,14968,15430,15097,14220,13791,14097,10440,10536,10475,31899,32033,31902,33464,33557,33454,32046,31803,31894,35168,35206,35114,35168,35114,35126,6448,6408,6697,6488,6366,6476,6227,6382,6522,6279,6408,6448,6393,6448,6494,6612,6521,6413,6521,6482,6413,6482,6364,6413,6486,6617,6436,6394,6567,6547,6440,6820,6549,7167,7134,7291,7068,7134,7167,8073,8027,8126,8126,8027,8209,7904,7988,8005,20490,20548,20431,20431,20376,20253,20253,20206,20209,20209,20029,20149,20710,20592,20800,20710,20800,20834,20862,20939,20834,20834,20939,20820,20839,20908,20894,21234,21416,21466,21466,21416,21534,21534,21675,21807,21807,21897,21815,21897,22090,22010,20694,20714,20839,20406,20628,20420,20216,20152,20420,22599,22550,22715,23011,22905,23085,26665,26015,26527,28239,28046,28198,28417,28198,28424,29241,29223,29124,29631,29223,29320,29631,29320,29520,29892,29873,29964,29042,29264,29120,29371,29790,29238,29072,29264,29042,29874,29892,29958,34976,34960,34877,35051,35074,35038,35279,35074,35051,6408,6425,6697,22599,22715,22681,20714,20819,20839,11421,11478,11333,14777,14648,14667,20601,20406,20348,20819,20908,20839,35872,35980,35837,35837,35932,35855,35855,35915,35639,36169,36022,35803,36055,35980,35872,36055,35872,35812,35982,35719,35853,35982,36137,36086,6425,6352,6959,14271,14648,14644,14736,14777,15061,13088,13205,12919,20453,20376,20431,19233,18732,18879,6482,6455,6364,6475,6608,6540,16717,16666,16907,16666,16574,16580,6455,6269,6364,30632,30376,30464,31012,30979,30807,32922,32797,32952,33235,33154,32905,33485,33431,33630,35980,35932,35837,25821,25860,25682,23290,23603,23440,26061,25892,26016,25745,25812,25743,25922,25812,25745,25743,25472,25570,6813,6754,6838,6682,6754,6813,11324,11508,11512,10929,11013,11080,35909,35659,35751,28354,28585,28444,7657,7536,7575,7575,7272,7478,7159,7089,7223,7536,7657,7449,26758,26163,26007,28354,28504,28585,6455,6240,6269,35932,35915,35855,10536,10707,10638,22681,22715,22817,23225,23011,23085,6858,6792,6929,6917,7356,7278,6789,6857,6965,18909,19090,19045,18909,19045,18767,33932,34216,33875,33895,34001,33860,34039,34001,33895,20082,20029,20209,11835,11797,11814,11545,11324,11512,12379,13003,12006,29583,29790,29371,6341,6366,6488,6264,6440,6549,20029,19988,20149,10929,11080,11069,31572,31402,31520,9324,9452,9544,9324,9234,9452,11069,11080,11162,11341,11324,11545,6499,6569,6368,21281,21416,21234,29223,29118,29124,29151,29118,29223,8232,8072,8196,8322,8543,8576,8428,8576,8540,33897,33830,33780,33966,33830,33897,35313,35126,34970,35206,35379,35219,33541,33170,33163,34092,34039,33895,7223,7089,7278,7223,7441,7226,7134,7189,7321,7068,7189,7134,35074,35106,34937,35223,35106,35074,11069,11162,11152,11393,11421,11333,10799,10944,10890,6754,6775,6838,7188,7321,7189,6682,6775,6754,16635,16496,16544,16358,16248,16281,16635,17059,16903,35807,35220,35342,35738,35342,35592,35720,35451,35674,21416,21675,21534,22359,22579,22312,6264,6549,6453,6650,6756,6473,11797,11622,11814,13791,13636,14097,20216,19999,20152,18876,18909,18767,18876,18767,18743,25812,25922,25949,25570,25421,25572,35223,34960,34976,11044,11205,11112,27265,27689,27360,12802,13088,12919,12676,12919,12754,28219,28223,28110,28808,28870,28794,29264,29527,29371,30464,30376,30217,7606,7625,7841,7606,7841,7578,26914,27089,26910,26914,26910,26879,14464,13791,14220,23228,23153,23440,22681,22817,22756,24632,23742,24531,35870,35720,35674,35866,35625,36022,7464,7606,7578,14648,14777,14736,16096,15943,15862,14667,14648,14271,26807,26914,26879,34566,34452,34622,34860,35122,34821,7991,8027,8073,7991,8073,7988,19999,19871,20152,18251,18407,18187,17746,17973,17754,22817,22838,22756,22090,22061,22010,31618,31572,31520,31698,31572,31618,31698,31618,31687,31698,31687,31798,6368,6569,6464,6368,6464,6267,11912,12087,11706,33048,32952,33020,33632,33584,33663,6956,7087,6766,6682,6732,6573,11152,11297,11324,11152,11162,11297,10987,11044,11112,30660,30464,30217,10355,10336,10475,10536,10649,10707,10707,10745,10890,10944,10987,10954,9790,9804,9542,6875,6792,6858,6823,6792,6875,24797,24613,24676,24781,24812,24939,24433,24224,24198,11421,11544,11706,11424,11544,11421,10273,10336,10355,7536,7468,7575,7373,7468,7536,25980,26758,26007,34636,34648,34548,6272,6522,6476,8548,8698,8775,8257,8128,8232,11694,11622,11797,12383,12006,13003,33746,33632,33663,8026,8128,8112,28148,28219,28005,33830,33902,33663,34221,33773,33742,33830,33966,33953,6353,6593,7004,6358,6475,6540,6738,6823,6875,7226,7441,7383,17491,17424,17555,9861,9767,9765,9745,9767,9861,10204,10402,10354,10600,10853,10823,10817,10823,10929,9542,9804,9721,10336,10440,10475,18116,18251,18162,22756,22838,22982,23440,23603,23742,32790,32309,32080,31854,31710,31527,31610,31407,31522,31407,31253,31522,31253,31113,31302,31012,30730,30816,35700,35748,35685,35748,35700,35833,6358,6540,6520,19114,18732,19233,17125,17059,17204,18543,18743,18685,20214,20264,20152,22838,23011,22982,20820,20710,20834,35976,35866,36014,11044,11134,11220,11025,11134,11044,16496,16248,16358,17281,17479,17858,6267,6464,6208,6382,6349,6453,9767,9750,9765,7188,7206,7321,6789,6965,6775,25860,24797,25682,27384,27451,27067,11694,11797,11830,28546,28424,28540,27693,27696,27597,28219,28415,28223,28808,28794,28585,29892,29874,29587,28393,28239,28417,30051,29892,29964,33953,33902,33830,10440,10649,10536,6732,6682,6813,6650,6473,6573,21897,22010,21815,22207,22550,22599,22982,23011,23225,6681,6789,6775,14199,14430,14221,12562,12676,12754,12626,12676,12562,28541,28585,28504,30914,30650,30981,12255,12626,12562,11134,11230,11333,11025,11230,11134,17555,17424,17319,17746,18116,18162,23798,23881,23393,23969,23922,23937,29321,29527,29264,7667,8063,7625,7667,7904,8005,27089,27232,27141,28578,28445,28379,28259,28445,28415,27241,27232,27089,27025,27089,26914,27913,27843,27895,34165,34216,33932,34636,34836,34648,34165,33932,34001,10649,10745,10707,7272,7339,7478,36087,35384,35685,6745,7087,6857,6935,7068,7167,7904,7991,7988,8764,8967,8914,8914,8967,9453,14777,15094,15061,13676,13734,13898,25572,25421,25355,27007,26807,26977,26959,27025,26914,24755,24781,24559,26807,26879,26758,28239,27895,28046,34622,34452,34134,35326,35206,35168,8340,8322,8428,8428,8322,8576,28445,28504,28415,28445,28541,28504,33557,33815,33684,33784,33815,33557,10998,10817,10929,10727,10817,10608,10745,10799,10890,6408,6279,6425,6425,6281,6352,6352,6341,6488,6366,6272,6476,6382,6319,6349,6284,6279,6448,6284,6448,6393,6284,6393,6413,6284,6413,6310,6413,6364,6310,20819,20806,20908,20908,20996,21234,21416,21625,21675,21675,21897,21807,20714,20740,20819,20406,20601,20714,19090,19029,19871,20601,20740,20714,35980,36236,35932,35932,36236,35915,36169,35803,36671,36053,36055,35812,36053,35812,36068,6279,6281,6425,7380,7464,7578,7606,7462,7625,7013,7188,7189,8202,8209,8086,9456,9656,9574,20629,20548,20490,20376,20206,20253,20029,19952,19988,19988,19712,19593,20710,20548,20629,20820,20548,20710,22754,22599,22681,20740,20806,20819,33138,33048,33020,33138,33020,33154,33508,33235,33485,33508,33485,33536,35326,35379,35206,34836,34860,34648,20548,20453,20431,36068,35812,35982,8026,8072,8128,8128,8072,8232,7229,7226,7339,11458,11341,11545,11230,11393,11333,11388,11393,11230,19090,18909,19029,20806,20996,20908,26959,26807,27007,36086,36068,35982,23574,23440,23742,23194,22982,23225,35720,35738,35592,35924,35738,35720,6310,6364,6269,17125,17281,16944,35379,35555,35213,20281,20206,20376,19029,18909,18841,20996,21144,21234,23922,23969,23998,23798,23608,23835,9002,9163,9177,9002,9177,9007,29029,29072,28870,28870,29072,29042,33630,33431,33632,6455,6477,6240,6792,6353,7004,6917,7278,7089,6917,7089,7007,7339,7226,7383,7119,7226,7030,16636,16474,16496,17125,16903,17059,20206,20082,20209,24803,24797,24968,23728,23574,23742,33496,33302,33235,34960,34974,34915,35081,34974,34960,35223,34976,35106,35279,35045,35298,6436,6617,6891,6359,6394,6547,6240,6477,6424,6436,6891,6395,22756,22754,22681,23313,23225,23228,35866,35870,35674,35976,35870,35866,14721,15094,14777,16574,16666,16717,22090,22359,22312,22509,22359,22232,27659,27451,27597,26061,25941,25860,35108,34759,34676,33953,33904,33902,6206,6341,6352,8548,8389,8540,8112,8128,8257,12676,12802,12919,12574,12802,12676,21144,21281,21234,28676,28808,28585,28676,28585,28541,33904,33663,33902,33746,33630,33632,11341,11152,11324,11622,11458,11545,11354,11458,11367,11458,11428,11367,11393,11424,11421,11388,11424,11393,30176,30051,29964,29874,29846,29587,30176,29964,30323,32790,32080,32483,10799,10987,10944,21281,21404,21416,30464,30650,30632,30829,30650,30914,29583,29371,29527,31942,31798,31867,33302,33138,33154,23355,23313,23228,23728,23809,23670,6956,6951,7167,7068,6968,7189,6825,6951,6956,31302,31113,31277,32483,31902,32033,35391,35279,35298,6296,6424,6368,6341,6272,6366,19952,19898,19988,6359,6547,6475,10303,10204,10354,9767,9749,9750,18841,18909,18876,18841,18876,18743,18841,18743,18723,31698,31666,31572,31564,31055,31402,31551,32797,32922,31610,31854,31527,13100,13480,13088,14667,14696,14777,16542,16474,16636,13640,13575,13791,6323,6359,6475,6486,6436,6430,10273,10250,10336,10336,10342,10440,10417,10625,10649,10649,10625,10745,10745,10625,10799,10799,10650,10987,10198,10250,10273,12802,13100,13088,17281,17125,17204,16903,16721,16636,16948,17125,16944,24198,24224,24065,27696,27659,27597,27754,27659,27696,27815,27693,27913,28415,28219,28259,31277,31113,31170,32922,32952,33048,31854,31894,31803,33953,33966,34073,35870,35794,35720,35976,35794,35870,6756,6402,6473,6682,6681,6775,6592,6745,6857,6176,6575,6440,6258,6453,6349,23969,24095,24065,23937,24095,23969,9327,9324,9544,9637,9765,9750,26031,25941,26061,28239,28198,28417,27870,27815,28013,31170,31075,30979,34661,34836,34636,34540,34622,34134,34461,34134,34216,29072,29321,29264,29372,29321,29358,29029,28870,28808,11912,11706,11544,12725,13059,13100,16816,16721,16903,19898,19712,19988,21563,21625,21416,30051,29958,29892,30131,29958,30051,33147,32922,33048,33630,33536,33485,33508,33496,33235,33334,33147,33138,33138,33147,33048,33520,33536,33686,9745,9749,9767,31048,30979,31012,23355,23228,23440,24632,24531,24613,7391,7143,7347,8086,8027,7894,7524,7206,7192,26807,26959,26914,27241,27265,27232,28259,28219,28148,25980,26007,25922,29372,29583,29527,9749,9637,9750,31564,31402,31572,31012,30807,30730,8288,8340,8389,8389,8340,8428,8288,8389,8270,28578,28676,28541,28578,28541,28445,33904,33746,33663,11354,11152,11341,10727,10600,10823,8112,8257,8322,8072,7722,8196,29151,28540,29118,34092,33895,33797,33853,33797,33815,6358,6520,6486,6267,6296,6368,20264,20348,20152,18723,18743,18543,7180,7206,7188,9637,9610,9765,10727,10823,10817,10342,10649,10440,11264,11388,11230,15565,16013,16168,21625,21897,21675,24095,24198,24065,24133,24198,24095,23798,23835,23900,30816,30632,30650,30816,30730,30632,34661,34636,34566,6584,6681,6682,7007,7089,7159,6951,6935,7167,6825,6935,6951,6917,6904,7356,6823,6703,6792,9159,9177,9234,9206,9234,9324,29958,29846,29874,29995,29846,29958,7119,7223,7226,7119,7007,7159,25570,25745,25743,25572,25745,25570,24755,24559,24528,35279,35223,35074,34974,35108,34676,6464,6496,6208,6227,6319,6382,9456,9574,9415,9790,9927,10270,10998,10929,11069,23937,23798,23900,9091,9206,9324,23355,23440,23601,22926,22754,22756,35748,35836,35685,35700,35575,35863,8213,8112,8322,8086,8209,8027,8086,7928,8049,33904,33954,33746,34221,33742,34328,16474,16248,16496,16721,16670,16636,16564,16670,16721,15628,15862,15774,18685,18407,18540,18116,17746,17914,20152,20104,20214,35875,35480,35220,35460,35230,35223,35505,35658,35549,32844,33264,32731,7229,7339,7272,7046,7180,7188,25655,24797,25860,26081,26031,26061,25919,26031,26081,33541,33158,33170,35223,35081,34960,34572,34334,34289,6291,6496,6394,6319,6258,6349,9415,9230,8921,9415,9574,9230,30919,30816,30829,34667,34461,34216,34622,34661,34566,7484,7667,7625,7462,7606,7464,34289,34463,34753,13177,13480,13100,13438,13676,13480,14271,14696,14667,27659,27067,27451,27815,27754,27696,27870,27754,27815,9002,8934,9163,8340,8213,8322,9007,8934,9002,6738,6703,6823,6430,6358,6486,9091,9159,9206,9206,9159,9234,11152,10998,11069,11458,11354,11341,11694,11830,11774,11424,11452,11544,11025,11044,10987,22926,22756,22982,24963,24755,24528,24401,24528,24198,29159,29321,29072,29321,29372,29527,28259,28148,28379,30323,29964,30834,34039,34165,34001,33784,33853,33815,34425,34221,34328,17706,17746,17707,23112,22926,22982,23601,23440,23574,23601,23574,23728,35836,35897,35685,35863,35575,35907,35487,35483,35731,7364,7462,7464,7380,7578,7391,15237,15761,15299,14721,14696,14693,34683,34661,34622,6935,6920,7068,6773,6920,6935,25355,25421,25052,27241,27025,27096,16360,16248,16474,35492,35391,35298,35190,35084,35081,34128,34165,34039,22268,22207,22599,6983,7013,7189,7347,7380,7391,29631,29151,29223,28013,27815,27913,29631,29520,29846,7192,7206,7180,9021,8931,8474,29029,28808,28861,30829,30816,30650,6592,6857,6789,16670,16542,16636,16564,16542,16670,31666,31564,31572,30131,30051,30176,31666,31698,31798,31666,31798,31834,31911,31798,31942,31522,31704,31610,31610,31704,31854,31854,32059,31894,31894,32059,32046,33777,33541,33264,31522,31253,31302,31522,31302,31404,31302,31277,31404,31277,31329,31404,31170,31048,31150,6430,6436,6395,6359,6291,6394,9593,9790,9542,9720,9927,9790,10250,10342,10336,22754,22787,22599,23194,23225,23313,31099,31048,31012,9397,9327,9544,11009,10998,11152,9927,10198,10273,11264,11452,11388,20806,20925,20996,20996,21132,21144,21144,21157,21281,21281,21290,21404,21404,21563,21416,21625,21672,21897,20740,20667,20806,20601,20667,20740,20348,20667,20601,20470,20667,20348,20264,20374,20470,31985,31911,31942,36055,36103,35980,36053,36103,36055,36206,36103,36215,36215,36053,36068,35982,35853,36137,11388,11452,11424,11025,10987,10681,20548,20395,20453,20453,20395,20376,20206,20124,20082,20082,19952,20029,19898,19908,19712,21176,20820,20939,6281,6216,6352,6341,6194,6272,6272,6227,6522,6319,6227,6258,6117,6216,6281,6117,6281,6279,6117,6279,6284,6235,6284,6310,6235,6310,6191,6310,6269,6191,8270,8389,8548,33729,33784,33557,33853,34092,33797,34080,33784,34101,8202,8122,8431,8027,7991,7894,27265,27360,27232,28693,28808,28676,35833,35897,35836,35731,35483,35555,11489,11912,11544,12626,12574,12676,20820,20395,20548,20395,20281,20376,18834,19029,18841,35081,35084,34974,35108,35084,35310,34836,35122,34860,35649,35731,35555,34959,35122,34836,36137,35853,36080,17319,17424,17123,23798,23937,23922,24133,23937,24016,35649,35555,35379,9749,9652,9637,9637,9609,9610,9610,9397,9544,10007,9745,9861,10007,10402,10204,10540,10780,10600,10540,10600,10525,10300,10342,10250,6191,6269,6240,20925,21132,20996,24797,24803,24613,25919,25860,25941,24755,24812,24781,25019,24812,24963,6146,6206,6352,10508,10799,10625,20281,20124,20206,19712,19506,19233,16816,16948,16944,16464,16360,16542,21132,21157,21144,23393,23608,23798,35853,35366,36233,35794,35924,35720,36022,35625,35803,9745,9652,9749,6240,6424,6125,6424,6296,6212,8049,8122,8202,21157,21290,21281,33953,33954,33904,33520,33508,33536,33520,33496,33508,34073,33954,33953,36137,36080,36160,34461,34540,34134,34661,34840,34836,34667,34540,34461,7816,7722,8072,7976,8072,8026,8025,8026,8112,8194,8213,8123,9159,9007,9177,8988,9007,9159,30037,29995,29958,30323,30921,30259,6904,6738,6875,6917,6837,6904,6817,6837,6760,6763,6917,7007,6948,7007,7119,6766,6825,6956,6920,6968,7068,6206,6194,6341,7013,7046,7188,6773,6968,6920,9652,9609,9637,9199,9091,9324,10525,10600,10727,20124,19952,20082,23670,23601,23728,23342,23194,23313,27241,27089,27025,25980,25922,25745,30919,31099,31012,30919,31012,30816,33536,33630,33767,32922,33066,31551,34616,34572,34753,34508,34425,34328,34221,34073,33966,35194,34970,34912,7272,7575,7468,27402,27067,27659,27724,27870,27851,12255,12574,12626,28693,28676,28578,6658,6789,6681,6627,6766,6745,6745,6766,7087,35190,35081,35223,35480,35505,35298,35807,35342,35738,6263,6291,6359,6154,6453,6258,6154,6264,6453,6650,6573,6732,8637,8764,8914,8612,8764,8637,19952,19908,19898,27724,27659,27754,34540,34683,34622,35746,35649,35379,6943,7046,7013,15237,15299,15094,16666,17057,16907,26031,25919,25941,26081,26061,26227,35122,35194,34912,35304,35194,35340,6323,6263,6359,6395,6891,6593,23937,24133,24095,22359,22090,22232,35976,35924,35794,36185,35924,35976,6212,6296,6267,21290,21563,21404,8288,8213,8340,8775,9052,8666,28813,28693,28578,28379,28445,28259,7449,7657,7908,14696,14721,14777,14271,14644,14199,14149,14199,13920,6241,6395,6128,6603,6738,6904,19908,19742,19712,21563,21672,21625,29790,29583,29779,30217,29790,30520,36438,35849,35915,11774,11830,12006,11354,11260,11152,10998,10608,10817,11774,12006,12099,33334,33138,33302,7051,7192,7180,35084,35108,34974,35223,35279,35460,30323,30834,30970,6323,6475,6358,6353,6792,6703,23342,23313,23355,22926,22787,22754,6957,6948,7119,7351,7306,7468,7143,7391,7524,7392,7484,7462,7462,7484,7625,7894,7991,7687,8086,8049,8202,14721,14926,15094,29029,29159,29072,29358,29159,29236,33840,33630,33746,33575,33334,33302,34100,34092,33853,34829,34683,35017,33264,33541,33163,33503,33264,32844,9368,9397,9610,9456,9415,9542,8921,9230,8967,29779,29583,29699,15928,16096,15862,16580,16059,16603,35313,35326,35168,35333,35326,35313,6756,6665,6402,8050,8025,8112,8474,8931,8421,7894,7661,7854,13059,13177,13100,33954,33840,33746,34072,34073,34170,6323,6358,6225,6184,6212,6267,16651,17057,16666,24722,24632,24613,23112,22982,23194,24722,24613,24803,36022,36067,35866,36120,36067,36169,6136,6227,6272,6968,6983,7189,7046,7051,7180,6787,6983,6968,6943,6983,6887,6935,6825,6773,16542,16360,16474,15036,15097,15565,16948,16903,17125,25572,25749,25745,25818,25749,25572,25849,25749,25818,35335,35304,35340,35194,35304,34970,35505,35492,35298,35549,35492,35505,7306,7272,7468,11428,11458,11622,15097,15710,15565,13640,13791,14464,30323,30131,30176,29995,29937,29846,30259,30131,30323,11694,11428,11622,13575,13636,13791,29586,29583,29372,9397,9329,9327,6208,6496,6251,13606,14149,13920,14721,14803,14926,16580,16651,16666,25849,25980,25745,34753,34463,34759,35230,35190,35223,35978,35897,35833,35978,35833,35863,35978,35863,35962,14149,14271,14199,34572,34616,34508,34753,34759,35211,27870,27724,27754,28084,27913,28239,28546,28540,29151,6251,6496,6291,6336,6358,6430,9828,10007,10204,9745,9591,9652,9652,9591,9609,9609,9514,9610,9397,9223,9329,10303,10354,10540,36067,36046,35866,36185,35807,35738,36120,36046,36067,31564,31679,31055,31666,31834,31564,31911,31834,31798,31679,31834,31889,31704,31841,31854,31522,31841,31704,32053,31841,31522,31277,31170,31329,31170,31246,31329,28483,28546,28529,7364,7464,7380,28148,27912,27689,27007,27025,26959,13438,13734,13676,10198,10229,10250,10342,10417,10649,9833,10229,10198,9833,10198,9927,31048,31099,31150,31841,32059,31854,6573,6584,6682,6445,6584,6573,10990,11009,11152,17555,17706,17707,18540,18407,18251,17260,17319,17123,17260,17123,17057,7373,7351,7468,7306,7043,7272,7504,7449,7908,7504,7908,7722,10229,10300,10250,14926,15030,15094,14534,14693,14696,27093,27007,26977,31150,31099,31134,34683,34840,34661,34829,34840,34683,34402,34216,34165,8666,9052,8934,7996,7976,8025,8666,8934,8700,8764,8745,8967,8931,8546,8421,12574,12573,12802,11912,12187,12639,11216,12187,11912,12321,12476,12512,11544,11452,11489,7472,7904,7667,8421,8546,8105,13640,14152,13466,28231,28084,28239,6584,6658,6681,16816,16832,16729,23670,23468,23601,24712,24722,24968,11367,11260,11354,11383,11428,11407,30131,30037,29958,30245,30037,30131,33147,33070,32922,33254,33070,33147,22830,22787,22926,22207,21673,21362,22830,22926,23112,36046,36014,35866,36120,36014,36046,36160,36080,36233,35962,35863,35907,17567,17706,17555,18723,18834,18841,22509,22579,22359,24963,24812,24755,36185,35738,35924,35335,35333,35313,36113,35746,36078,35907,35487,35731,35335,35313,35304,8460,8745,8764,7242,7351,7373,7347,7353,7380,7236,7353,7347,7143,7524,7192,33520,33686,33496,34067,33840,33954,34072,33954,34073,7030,7229,6971,7030,7226,7229,6666,6642,6738,9498,9591,9745,27093,27096,27007,25749,25849,25745,25019,25052,24812,31099,30919,31134,31246,31150,31134,35460,35279,35391,35177,34759,35108,8025,7976,8026,8050,8112,8213,32483,32033,32419,6251,6291,6165,16360,16371,16248,16816,16564,16721,16980,17145,17057,16096,16580,16574,16651,16580,16603,9591,9514,9609,9199,9324,9327,10608,10525,10727,18540,18251,18432,22488,22268,22599,23468,23355,23601,6971,7229,7272,6943,7051,7046,6943,7013,6983,26227,26061,26665,24983,24968,24797,26227,26460,26311,6047,6117,6284,6216,6146,6352,6206,6129,6194,6020,6136,6272,6047,6284,6235,6190,6235,6191,6190,6191,6240,6190,6017,6102,17145,17260,17057,17514,17567,17555,30037,29937,29995,30102,29937,30037,36103,36236,35980,36215,36103,36053,36215,36068,36086,36215,36086,36210,36086,36137,36210,23728,23742,23809,36210,36137,36160,35907,35731,35992,6117,6166,6216,20264,20470,20348,20843,20925,20806,21132,21233,21157,21157,21233,21290,21290,21245,21563,21563,21609,21672,20214,20104,20178,35909,36233,35533,6125,6424,6212,6244,6291,6263,8194,8050,8213,22488,22599,22787,34170,34073,34240,34124,34092,34100,34128,34092,34124,20752,20806,20667,36206,36236,36103,6402,6119,6280,6504,6592,6658,6445,6473,6416,8612,8460,8764,8421,8332,8468,12187,12255,12562,13177,13438,13480,11264,11230,11025,17514,17555,17319,18432,18251,18294,23900,24016,23937,23855,24016,23900,21825,21897,21672,6738,6642,6703,6241,6336,6430,6323,6244,6263,6817,6904,6837,16948,16816,16903,17858,17944,18732,6166,6146,6216,9199,9327,9329,35909,36280,36233,12512,12573,12574,33864,33767,33630,33864,33630,33840,8270,8213,8288,8874,8934,9007,20124,19998,19952,19952,19967,19908,19908,19786,19742,19742,19636,19712,20281,20212,20124,20245,20212,20281,20245,20281,20395,20245,20395,20820,20152,19871,20104,29953,29631,29846,6241,6430,6395,18543,18834,18723,18251,18116,18294,27724,27586,27659,28013,27851,27870,28013,27913,28084,28013,28084,28226,34735,34425,34508,34735,34508,34616,6146,6129,6206,6665,6119,6402,21046,21233,21132,35685,36193,36087,6760,6837,6917,6760,6917,6763,9514,9368,9610,32419,32033,32046,35492,35460,35391,35549,35460,35492,6969,7143,7192,36078,35379,35326,35340,35454,35489,6125,6212,6072,20212,19998,20124,21233,21245,21290,7854,7928,7894,7364,7392,7462,7364,7380,7353,27959,27689,27442,27007,27096,27025,26807,26758,26977,28231,28239,28267,35177,35108,35315,35253,35190,35230,34840,34910,34836,34910,35015,34959,8270,8548,8312,16564,16464,16542,16531,16464,16564,19998,19967,19952,36087,36193,36230,7030,6957,7119,6948,6957,6808,7026,7113,7143,6773,6825,6643,9091,9020,9159,8988,9020,8858,11383,11260,11367,10660,10608,10730,11383,11367,11428,11428,11694,11407,11279,11264,11183,30245,30259,30610,29937,29953,29846,35332,35253,35464,17349,17514,17319,16980,17057,16882,35685,35897,36193,7894,7928,8086,7472,7667,7484,13279,13438,13177,14323,14271,14149,14534,14696,14500,14778,14721,14693,18294,18116,18057,17349,17319,17260,28393,28417,28546,17746,17706,17914,18566,18834,18543,23342,23112,23194,22729,22488,22787,6658,6592,6789,6504,6658,6122,8546,8122,8105,8474,8460,8612,19967,19786,19908,21245,21609,21563,33767,33686,33536,33903,33686,33767,26081,26047,25919,26227,26665,26460,7113,7236,7347,7113,7347,7143,22729,22787,22830,22268,22067,22207,21825,22090,21897,28483,28393,28546,27689,27265,27442,29099,29159,29029,29159,29358,29321,34092,34128,34039,33853,34080,34100,8312,8548,8615,23809,23742,23858,23468,23342,23355,23742,24241,23858,34019,33840,34067,34019,33864,33840,36239,35897,35978,35746,35731,35649,9020,8988,9159,7918,7752,7848,8935,8988,8858,11147,10990,11152,11407,11694,11539,31841,32053,32059,32360,32419,32046,31404,31523,31522,31329,31523,31404,31441,31523,31329,31246,31170,31150,33575,33302,33496,33070,33066,32922,18566,18543,18540,17914,17706,17472,6184,6267,6208,6184,6208,6171,6763,7007,6948,6817,6672,6904,35727,35326,35333,35340,35194,35454,6473,6445,6573,6136,6258,6227,35489,35333,35335,6431,6672,6817,6225,6358,6336,16464,16371,16360,16531,16371,16464,35332,35190,35253,35658,35505,35744,6225,6244,6323,6225,6336,6139,18566,18540,18452,9223,9199,9329,11147,11152,11260,27930,27586,27724,27897,27724,27851,27897,27851,28013,28226,28084,28231,12725,13100,12802,12725,12802,12573,12512,12574,12255,6020,6272,6194,19699,19636,19742,21609,21825,21672,7996,8025,8050,7816,8072,7976,7292,7504,7722,7449,7242,7373,7351,7242,7306,7996,8050,8194,27586,27402,27659,9496,9593,9542,10177,10342,10300,11279,11452,11264,9496,9542,9415,9496,9415,9363,31134,30919,30957,26083,26047,26081,26083,26081,26227,27407,27265,27241,6603,6666,6738,8988,8874,9007,8935,8874,8988,11256,11147,11260,11539,11694,11774,11322,11489,11452,10417,10342,10177,23666,23342,23468,22948,22729,22830,24712,24632,24722,23393,22657,23385,24963,24528,24401,24198,24133,24401,25849,25818,25980,30245,30102,30037,28483,28267,28393,30245,30131,30259,29099,29029,28861,30957,30919,30829,12612,12512,12476,28813,28578,28832,28813,28808,28693,10177,10300,10229,19636,19506,19712,30957,30829,30914,27959,28148,27689,36014,36146,35976,35744,35505,35480,36169,36067,36022,7428,7472,7484,7258,7364,7353,7258,7353,7117,34829,34910,34840,34910,34829,35015,32790,32832,32844,32744,32832,32790,32744,32790,32483,10417,10508,10625,32600,32419,32546,8270,8123,8213,8580,8615,8666,28861,28813,28832,17477,17706,17567,17212,17349,17260,17212,17260,17145,16882,17057,16651,16580,16096,16059,24968,24722,24803,28393,28267,28239,28546,29095,28708,6635,6825,6766,6685,6969,7051,6627,6745,6592,14778,14803,14721,14696,14271,14500,14158,14165,14323,6171,6208,6251,6539,6703,6642,11369,11539,11463,11256,11260,11383,22948,22830,23112,22520,22067,22268,23666,23468,23670,23075,23342,23279,33334,33254,33147,33558,33254,33334,33575,33496,33686,36120,36146,36014,36187,36146,36120,6665,6575,6119,6504,6627,6592,10608,10998,10730,10525,10422,10540,9498,9514,9591,9335,9368,9514,9226,9223,9368,9368,9223,9397,10422,10608,10474,23835,23855,23900,23838,23855,23835,30650,30464,30981,6171,6251,6165,21818,22067,22520,6787,6887,6983,25623,25818,25572,27096,27260,27241,11256,11383,11407,6666,6539,6642,6672,6603,6904,6614,6603,6672,6616,6627,6531,8421,8468,8474,8032,8122,7955,15928,15862,15628,7918,7996,8194,28708,28991,28633,34128,34245,34165,34245,34124,34230,8700,8580,8666,7777,7871,7918,29358,29586,29372,29699,29586,29718,29236,29159,29099,6165,6291,6147,6030,6154,6258,29985,29790,29779,36230,36244,35909,36230,35909,36087,6969,7192,7051,14803,15030,14926,24983,24797,25655,26311,26083,26227,18452,18540,18432,20584,20470,20374,18452,18432,18294,17477,17567,17514,17186,17212,17145,16964,17145,16980,7428,7484,7392,7955,8122,8049,7428,7392,7344,20584,20752,20667,20925,21046,21132,21267,21368,21245,21245,21368,21609,21609,21526,21825,20584,20667,20470,20264,20214,20374,20374,20214,20178,36215,36307,36206,36206,36348,36236,36671,35803,35849,36315,36307,36215,36315,36215,36210,36315,36210,36352,36210,36160,36352,6550,6539,6666,10998,11009,10730,11200,11256,11407,11489,11269,11912,11183,11264,11025,16745,16882,16651,20752,20843,20806,30102,30028,29937,30970,30834,31055,33092,33066,33070,7423,7428,7344,8856,8935,8858,8874,8778,8934,9498,9745,9488,19871,20112,20104,20843,20980,20925,36263,36160,36233,7955,8049,7928,28529,28708,28633,14152,14464,14968,13575,12535,13003,13522,13640,13466,20897,20245,20820,20212,20001,19998,19998,20001,19967,19967,19973,19786,19786,19699,19742,19636,19596,19506,20980,21046,20925,6038,6047,6235,5892,6146,6166,5981,6129,6146,5981,6056,6129,6129,6056,6194,6136,6030,6258,6038,6235,6190,6038,6190,6102,6240,6017,6190,14803,14828,15030,13196,13734,13438,15030,15237,15094,15217,15237,15152,19871,19029,20112,26977,26758,26626,27959,28101,28148,31834,31679,31564,31889,31834,31985,31985,31834,31911,35310,35084,35190,34073,34221,34564,35310,35190,35332,6685,7051,6943,6773,6787,6968,6472,6787,6773,15518,15928,15628,16603,16745,16651,22729,22773,22488,23075,22948,23112,23075,23112,23342,32151,31985,32545,6240,6125,6106,20166,20104,20112,6147,6291,6177,6106,6125,6072,9593,9720,9790,10523,10650,10508,9496,9720,9593,19432,19114,19506,19506,19114,19233,16816,16729,16564,36001,35978,35962,36280,36263,36233,7687,7991,7904,13522,13478,13575,28280,28226,28267,28267,28226,28231,27354,27309,27402,26460,26665,26565,28280,28267,28483,6212,6019,6072,6363,6614,6672,6603,6550,6666,6363,6672,6431,6763,6948,6808,6627,6616,6766,6658,6584,6122,20245,20001,20212,29114,29236,29099,28861,28808,28813,33853,33784,34080,32682,32744,32483,33807,33575,33686,33254,33092,33070,33903,33767,33864,33954,34072,34170,36280,35909,36244,17477,17514,17349,24260,24133,24016,23599,23608,23385,23619,23608,23599,22232,22090,21825,35907,36001,35962,36121,36001,35907,7260,7242,7449,7260,7449,7228,14650,14778,14693,9020,9091,9023,11279,11322,11452,11183,11322,11279,5981,6146,5892,20001,19973,19967,21219,21245,21233,6402,6416,6473,6299,6416,6402,8021,8105,8032,8032,8105,8122,13059,13279,13177,12612,12725,12573,12612,12573,12512,17436,17477,17349,17226,17349,17212,28832,28578,28379,28832,28986,28866,34073,34564,34240,6212,6044,6019,6177,6291,6244,6177,6244,6062,7996,7871,7976,7816,7871,7777,13196,13279,13047,34124,34245,34128,33729,34101,33784,6056,6020,6194,18566,18593,18834,18383,18452,18268,21368,21481,21609,22910,22773,22729,23666,23670,23809,36342,36280,36578,6458,6504,6122,15237,15435,15628,15518,15435,15341,15565,16168,16248,17858,17479,17944,16798,16745,16794,16882,16964,16980,24838,24968,24972,23858,23666,23809,25019,25355,25052,23943,24016,23855,35253,35551,35464,9488,9745,10007,8856,8778,8935,8921,8967,8745,31134,31259,31246,31246,31441,31329,32360,32046,32059,32419,32600,32483,31153,31259,31134,31153,31134,30957,31441,31259,31248,21481,21526,21609,10608,10422,10525,11027,10990,11147,17945,17858,18732,23742,24632,24241,23608,23619,23835,22657,22579,23385,6076,6177,6062,6184,6044,6212,35744,35480,35875,36438,35915,36236,36336,36193,36335,36342,36263,36280,6064,6044,6184,22067,21673,22207,21735,21673,22067,7854,7955,7928,8935,8778,8874,7871,7996,7918,8700,8778,8706,28708,28529,28546,28546,29151,29095,30208,30028,30102,30208,30102,30245,34735,34616,34753,35211,34759,35177,33729,33541,34101,6128,6395,6593,6808,6957,7030,35340,35489,35335,35746,35992,35731,35454,35194,35122,7428,7423,7472,7502,7687,7904,7788,7913,7955,7344,7392,7364,7344,7364,7258,14323,14149,14158,14534,14650,14693,14778,14828,14803,27260,27407,27241,27442,27407,27420,6616,6635,6766,7353,7236,7117,6566,6635,6616,35549,35621,35460,36185,35976,36146,11200,11027,11147,11200,11147,11256,10905,10948,10773,19921,19699,19786,28861,29114,29099,29718,29586,29358,29586,29699,29583,28976,29114,28861,34019,33903,33864,34069,33903,34019,7502,7904,7472,28012,27897,28013,28012,28013,28252,29783,29699,29718,7236,7113,7117,14323,14500,14271,13478,13332,13575,13640,13522,13575,13332,13466,13132,34288,34165,34245,34288,34402,34165,34910,34959,34836,6171,6064,6184,6539,6353,6703,6450,6550,6603,6497,6550,6450,16729,16661,16564,16774,16661,16729,24963,25002,25019,27260,27096,27093,25176,25002,24963,10730,11009,10990,10508,10650,10799,10471,10508,10417,32053,31522,31523,33503,32844,33473,28832,28509,28986,34170,34067,33954,34230,34288,34245,32863,32832,32744,7043,6971,7272,7228,7449,7504,6943,6887,6685,14504,14650,14534,35015,34829,35017,30028,29953,29937,30093,29953,30028,6171,6082,6064,6176,6440,6264,5995,6030,6136,7871,7816,7976,8123,7752,7918,13522,13332,13478,28675,28280,28483,28279,28280,28675,34230,34124,34100,7043,7306,7242,6685,6887,6645,26665,27067,27188,24972,24968,24983,35310,35315,35108,35329,35315,35310,10905,10730,10990,32600,32682,32483,6282,6353,6539,7026,7117,7113,14607,14828,14778,6165,6076,6082,6171,6165,6082,8468,8460,8474,8110,8332,8421,8110,8421,8105,19596,19432,19506,19114,18919,18732,33903,33807,33686,33401,33092,33254,33833,33807,34004,16968,16944,17281,16798,16964,16882,17951,18057,17914,18383,18593,18452,16798,16882,16745,15996,16096,15928,15996,15928,15885,15518,15628,15435,25176,25355,25019,34311,34230,34100,12725,12650,13059,14158,14149,14043,12476,12321,12341,6458,6531,6504,6504,6531,6627,6176,6264,5908,23018,22948,23075,24583,24632,24712,36121,35992,36191,36001,36126,35978,22910,22729,22948,22910,22948,23018,31464,30970,31055,31889,31813,31679,31779,31813,31896,31813,31889,31962,36169,36187,36120,36595,36187,36169,31755,32053,31523,32600,32689,32682,6165,6147,6076,8575,8921,8745,32211,32151,32335,33558,33334,33575,8778,8700,8934,9091,9199,9023,6325,6445,6416,6635,6643,6825,16661,16531,16564,16618,16531,16661,35875,35220,35807,35551,35230,35460,7117,6958,7050,6969,7026,7143,15217,15435,15237,35621,35549,35658,35283,35177,35315,35280,34735,34753,34170,34264,34067,27407,27442,27265,27260,27093,27299,6076,6147,6177,9833,10177,10229,9833,9927,9720,29442,29151,29631,31259,31441,31246,31153,30957,31038,26758,25980,26626,5908,6264,6154,7687,7661,7894,8355,8468,8332,7534,7661,7687,7660,7661,7534,7472,7355,7421,7423,7355,7472,7344,7355,7423,11200,11407,11369,11027,10905,10990,17186,17226,17212,17186,17145,16964,18452,18593,18566,18057,18116,17914,21818,21735,22067,23279,23342,23382,27897,27930,27724,28252,28013,28226,28252,28226,28280,9828,9488,10007,9498,9477,9514,10303,10540,10422,10303,10422,10244,10608,10660,10474,10474,10660,10553,17472,17706,17477,32242,32360,32059,16944,16832,16816,16968,16832,16944,16794,16745,16603,24968,24838,24712,26200,26047,26083,8355,8460,8468,8021,8032,7932,33807,33713,33575,33833,33713,33807,33807,33903,34004,6280,6299,6402,6249,6299,6280,7260,7112,7242,7145,7228,7504,9023,9199,9119,30286,30208,30245,29700,29442,29631,20752,20783,20843,20843,20960,20980,20980,20960,21046,21046,21219,21233,21368,21409,21481,21481,21543,21526,20749,20783,20752,20593,20752,20584,20488,20584,20374,20488,20374,20325,20374,20178,20325,15152,15237,15030,20325,20178,20166,21814,22232,21825,21814,21825,21526,26311,26200,26083,27309,27067,27402,28279,28252,28280,36542,36348,36206,36448,36206,36307,36448,36307,36315,36352,36160,36263,20166,20178,20104,20783,20960,20843,36348,36361,36236,9488,9477,9498,32360,32430,32419,16328,16794,16603,15518,15885,15928,16059,15885,15801,6566,6643,6635,6566,6616,6531,29699,29783,29779,29718,29358,29455,29358,29236,29455,35815,35621,35658,9119,9199,9223,20112,19029,20063,36469,36352,36421,36342,36578,36451,7913,8032,7955,12612,12650,12725,12646,12650,12612,12255,12321,12512,28832,28866,28861,28509,28379,28148,25942,25980,25818,6763,6716,6760,6550,6497,6539,6971,6808,7030,6590,6808,6597,25946,25942,25818,35489,35727,35333,35841,35454,35878,5892,6166,6117,6056,5984,6020,6020,5984,6136,5615,5643,6154,5892,5528,5678,5802,6047,6038,5802,6038,6102,6017,6240,6106,6017,6106,5972,6106,6072,5972,6072,6019,5972,6019,5819,5972,7918,8194,8123,7060,6877,6847,10553,10660,10730,10177,10471,10417,10681,11183,11025,18736,19029,18834,20960,21219,21046,31248,31153,31038,32430,32546,32419,32682,32863,32744,35815,35761,35744,35744,35761,35658,23619,23838,23835,25623,25572,25355,23553,23599,23385,36121,36126,36001,36421,36342,36451,36121,35907,35992,21219,21267,21245,17192,17186,16964,17436,17472,17477,17192,16964,16982,30208,30093,30028,29972,30093,30196,19973,19921,19786,19699,19596,19636,20001,19928,19973,20245,19928,20001,19826,20107,19589,6299,6325,6416,6198,6325,6299,10471,10523,10508,17436,17349,17226,26360,26200,26311,26360,26311,26460,35332,35329,35310,35464,35329,35332,14828,14921,15030,15217,15173,15435,14753,14921,14828,14607,14778,14650,14504,14534,14500,14305,14500,14323,6062,6244,6225,6019,6044,5978,6139,6336,6241,6450,6603,6614,6128,6139,6241,16832,16774,16729,15565,16248,15814,16889,16774,16832,16059,16096,15996,24766,24583,24712,25860,25919,25655,35952,35875,35807,6128,6593,6045,18593,18738,18834,18268,18452,18294,18268,18294,18057,8483,8580,8700,8312,8615,8580,34732,34221,34425,6044,6064,5978,8102,8355,8332,8460,8377,8745,19928,19921,19973,29896,29631,29953,28675,28483,28529,36244,36578,36280,29783,29985,29779,29455,29236,29394,8021,8110,8105,8102,8110,8090,13047,13279,13059,11269,11489,11322,29442,29095,29151,5917,5984,6056,21409,21543,21481,31464,31055,31679,32546,32689,32600,34837,34667,35005,34402,34667,34216,34959,35876,35122,34667,34402,35005,28012,27930,27897,27989,27930,28012,27989,28012,28252,36126,36239,35978,36231,36121,36191,5978,6064,6082,5986,6062,6225,6808,6716,6763,6590,6716,6808,14921,15152,15030,35338,35283,35315,7117,7026,6941,6404,6566,6531,7661,7660,7854,7344,7147,7355,27952,28101,27959,27602,27959,27442,27420,27407,27260,30093,29972,29953,29933,29972,30196,29856,29985,29783,35017,34683,34540,8856,8706,8778,9023,8858,9020,8789,8858,8763,11369,11407,11539,10905,10737,10730,10681,10987,10650,18383,18268,18334,18651,18738,18593,36187,36185,36146,36595,36185,36187,24766,24712,24838,23382,23342,23556,10773,10737,10905,10523,10681,10650,17472,17951,17914,17192,17436,17226,17626,17436,17253,25942,26030,25980,25946,26030,25942,26115,26030,26122,5978,6082,5967,19921,19679,19699,19432,19303,19114,16889,16618,16774,7228,7112,7260,7145,7112,7228,7722,7816,7419,28675,28529,28633,31813,31779,31679,31962,31889,31985,32151,31962,31985,6122,6584,6445,16774,16618,16661,16968,17077,16976,26014,25919,26047,24923,24766,24838,35875,35856,35744,35761,35815,35658,35464,35338,35329,35329,35338,35315,35952,35856,35875,5984,5995,6136,19679,19596,19699,21543,21814,21526,23553,23838,23599,23599,23838,23619,23943,23838,23876,9131,9119,9223,32689,32863,32682,34080,34311,34100,26200,26232,26047,26407,26360,26460,35253,35230,35551,5986,5989,6062,5963,6128,5996,6176,6119,6575,6325,6186,6445,5705,6119,6176,23342,23666,23556,22910,22945,22773,7033,7043,7242,13158,12535,13575,13158,13575,13332,12476,12646,12612,12341,12646,12476,13132,13158,13332,13332,13522,13466,28866,28976,28861,29762,29856,29783,28986,28976,28866,35283,35211,35177,34264,34170,34240,35254,35211,35283,18651,18593,18471,29972,29896,29953,29607,28991,29095,29933,29896,29972,29762,29783,29718,31038,30957,30914,32995,32844,32832,34705,34402,34288,24445,24241,24632,24445,24632,24583,16889,16968,16976,24923,24838,24972,10474,10244,10422,10303,9828,10204,9398,9335,9477,9477,9335,9514,10335,10244,10474,35454,35512,35489,35727,35512,35745,6119,6249,6280,7344,7258,7086,7258,7050,7086,7788,7955,7684,8110,8102,8332,7932,7913,7788,23223,23018,23075,23556,23666,23729,7421,7502,7472,18471,18593,18383,20749,20593,20832,18471,18383,18334,7258,7117,7050,13196,13438,13279,15103,15173,15152,27364,27420,27260,29296,29114,29190,27299,27093,26977,31153,31248,31259,31441,31755,31523,32488,32430,32360,32488,32524,32430,32430,32524,32546,32546,32581,32689,32947,32962,32863,31038,30914,30981,32242,32059,32053,6497,6381,6539,6407,6450,6363,6381,6450,6407,8789,8706,8856,8789,8856,8858,11463,11539,11774,10563,10553,10737,10737,10553,10730,26030,26115,25980,25946,25818,25623,35363,35254,35283,35551,35460,35621,5967,6082,6076,5967,6076,5989,19503,19345,19432,7502,7534,7687,27314,27309,27354,28163,27989,28252,28163,28252,28279,28991,28708,29095,29394,29236,29296,27402,27586,27354,27364,27299,27376,35015,35103,34959,34837,35017,34540,34837,34540,34667,8090,8110,8021,8028,8377,8460,12535,12383,13003,12267,12383,12438,32863,32995,32832,32962,32995,32863,8419,8483,8700,9479,9477,9488,8959,8858,9023,30981,30464,30660,29888,29762,29718,5989,6076,6062,19345,19303,19432,7112,7033,7242,6597,6808,6971,7751,7816,7777,7026,6845,6941,24080,23989,23858,24546,24445,24583,35171,35103,35015,15152,15173,15217,15885,16059,15996,15103,15152,15085,16968,16889,16832,15036,14968,15097,16968,17255,17077,26360,26232,26200,24775,24583,24766,24775,24546,24583,26565,26407,26460,36231,36239,36126,36231,36126,36121,9335,9226,9368,10905,11027,10948,24080,23858,24241,23838,23943,23855,22314,22509,22232,30117,29985,29856,7767,7751,7777,7848,7777,7918,13047,13059,12732,20783,20884,20960,20960,21081,21219,21219,21409,21267,21267,21409,21368,21543,21610,21814,20488,20593,20584,20380,20593,20488,20832,20593,20682,20488,20325,20380,18736,18834,18738,20593,20749,20752,11369,11169,11200,12099,11463,11774,36499,36448,36315,36348,36501,36361,36361,36438,36236,36499,36315,36352,36499,36352,36469,21814,22279,22232,22314,22279,22214,7067,7033,7112,20749,20884,20783,36542,36501,36348,36501,36493,36361,26115,26269,25980,25176,25019,25002,35662,35551,35621,35355,35283,35338,5981,5917,6056,5984,5919,5995,5892,6117,5560,5804,5892,5782,5802,6017,5806,6017,5972,5806,36352,36263,36421,18651,18736,18738,18202,18268,18057,25263,25176,24792,35856,35815,35744,35964,35815,35856,36421,36263,36342,29455,29888,29718,29296,29236,29114,29114,28976,29190,34069,34019,34172,33713,33558,33575,32092,31896,31962,34019,34067,34172,7869,8123,8270,12732,12650,12646,12732,13059,12650,29896,29700,29631,29789,29700,29896,17626,17951,17472,18057,17951,18202,16964,16798,16982,23729,23666,23738,23223,23075,23279,20669,19928,20245,23385,22579,22509,8102,8018,8355,7975,8090,8021,7932,8032,7913,24923,24972,24983,24208,24080,24241,23738,23666,23858,26316,26232,26360,26316,26360,26407,26122,26269,26115,34264,34594,34340,35211,35243,34753,35355,35338,35504,5804,5917,5981,5615,6154,6030,36244,36230,36514,6249,6198,6299,6186,6198,6054,6198,6249,6097,24416,24241,24445,10210,9828,10303,9335,9231,9226,10210,10303,10244,9546,9833,9720,10177,10340,10471,10471,10340,10523,10523,10434,10681,9546,9720,9496,9546,9496,9363,31962,31896,31813,31779,31464,31679,30286,30093,30208,31942,33066,33216,6450,6381,6497,6817,6760,6431,8706,8705,8700,8959,9023,9119,11234,11169,11369,21083,21409,21219,25076,24923,24983,36105,35952,36165,33225,33066,33092,34369,34288,34230,35017,35171,35015,14165,14305,14323,14043,14149,13939,14149,13606,13939,27420,27573,27442,27434,27573,27420,27364,27260,27299,30286,30245,30423,6031,6225,6139,5967,5819,5978,6031,6139,6128,5963,6031,6128,23223,23279,23382,32019,31755,31932,32303,31755,32019,14175,14305,14165,27434,27364,27376,36565,36438,36361,36336,36230,36193,32174,32242,32053,32752,32863,32689,7955,7854,7671,34831,34425,34735,15801,15885,15518,27188,26565,26665,35504,35338,35464,5917,5887,5984,14305,14504,14500,15173,15341,15435,19921,19826,19679,19679,19621,19596,19596,19503,19432,19345,19261,19303,19928,19826,19921,21176,20939,21673,21409,21610,21543,27309,27188,27067,27314,27188,27309,36335,36193,35897,36191,36354,36305,10268,10210,10244,10948,11027,11200,33220,33473,32844,32581,32546,32524,5989,5938,5967,5894,5986,6225,36335,35897,36239,8483,8312,8580,8212,8312,8242,9828,9479,9488,8972,8959,9119,10335,10474,10553,33503,33777,33264,33688,33777,33503,5887,5919,5984,12383,12099,12006,11227,11234,11369,12438,12383,12535,19826,19734,19679,29394,29475,29455,30106,30117,29856,28832,28379,28509,33837,33558,33713,34069,34004,33903,33947,34004,34251,35551,35518,35464,35662,35518,35551,35662,35621,36157,6381,6282,6539,11057,10948,11200,11227,11369,11463,11183,11269,11322,11114,11269,11183,11114,11183,10681,30921,30323,30970,23180,23223,23358,22806,22488,22773,23018,23223,23074,7145,7067,7112,6810,6971,7043,7060,7067,7145,7145,7504,6877,7235,7326,7355,7355,7326,7421,7421,7338,7502,7671,7660,7456,7671,7854,7660,7026,6969,6845,6787,6472,6645,6643,6566,6469,14528,14607,14650,9479,9398,9477,32394,32488,32360,33837,33713,33833,5919,5883,5995,22945,22910,23018,29501,29095,29442,27354,27586,27607,29501,29442,29700,29501,29700,29656,28509,28148,28101,34264,34172,34067,26146,26047,26232,25103,25076,24983,24775,24416,24546,24546,24416,24445,35952,35964,35856,36105,35964,35952,7848,7767,7777,7694,7767,7752,12881,12499,12535,16371,15814,16248,28370,28509,28101,9131,9223,9226,8628,8705,8706,11057,11200,11169,10563,10335,10553,15103,15341,15173,26565,26316,26407,26178,26316,26378,10563,10737,10657,10110,10340,10177,19734,19621,19679,17017,16976,17077,32488,32581,32524,36191,35992,36354,36495,36335,36607,6469,6566,6404,35377,35240,35254,35254,35240,35211,34264,34239,34172,35363,35283,35355,8628,8706,8789,30286,30196,30093,30231,30196,30286,33558,33401,33254,19621,19503,19596,7975,8018,8090,7420,7534,7502,18649,18736,18651,18649,18651,18471,28991,28675,28633,34352,34311,34080,6810,7043,6615,6381,6300,6282,12267,12099,12383,12160,12099,12267,16889,16859,16618,19056,19114,19303,29789,29896,29933,28503,28279,28675,29546,29475,29394,29582,29475,29546,6404,6531,6458,7235,7355,7147,7071,7086,7050,14305,14344,14504,14504,14528,14650,14158,14175,14165,13920,13734,13606,27573,27602,27442,27587,27602,27573,27434,27420,27364,8090,8018,8102,7975,8021,7932,12321,12255,12187,13402,13734,13196,14044,14175,14158,14607,14753,14828,27376,27299,26977,29138,29190,28976,29138,28976,28986,16371,16282,15814,30115,29789,29933,35590,35363,35355,6645,6887,6787,10657,10737,10773,26178,26146,26232,26178,26232,26316,25946,26122,26030,26269,26626,25980,26219,26122,25946,32581,32752,32689,33220,32844,32995,23702,23876,23838,23943,24260,24016,26219,26189,26122,23702,23838,23553,23385,23241,23368,27586,27930,27902,27188,26677,26565,23499,23385,23368,6363,6450,6614,6122,6404,6458,18608,18649,18471,20325,20166,20380,12537,12732,12646,30106,29856,30017,31759,31706,31248,33220,32995,33152,34500,34369,34460,6919,7043,7033,7697,7816,7751,6958,7071,7050,6958,7117,6941,10726,10657,10773,11234,11057,11169,11227,11057,11234,11216,12321,12187,11011,11114,10645,14344,14528,14504,33295,33225,33092,8797,8763,8858,9174,9131,9226,10788,10773,10948,30520,29790,29985,7767,7697,7751,7694,7697,7767,7456,7660,7534,7753,7975,7932,6919,7033,7067,35524,35504,35464,35619,35464,35518,24080,24050,23989,24899,24766,24923,24899,24923,25076,19390,19261,19345,16976,16859,16889,17017,16859,16976,31063,30921,30970,32151,32092,31962,32211,32092,32151,36281,36239,36231,36665,36421,36451,6839,6958,6941,14675,14753,14607,23385,23499,23553,22314,22232,22279,32242,32394,32360,32758,32741,32581,32581,32741,32752,31755,32174,32053,32313,32174,32303,34266,34004,34069,34004,33947,33833,33295,33092,33401,33295,33216,33225,34266,34069,34172,29501,29607,29095,29789,29656,29700,29731,29656,29742,32020,31779,31896,30196,30177,29933,32752,32947,32863,32879,32947,32752,6472,6773,6643,6814,6845,6727,6472,6643,6469,34311,34369,34230,34101,33541,33777,36157,35621,35815,8264,8377,8028,7810,7932,7788,29546,29394,29296,30017,29856,29762,29272,29138,28917,29138,28986,28917,34191,34101,34411,36501,36542,36493,36493,36565,36361,36448,36542,36206,36695,36542,36448,36695,36448,36499,36597,36499,36469,36526,36469,36421,36526,36421,36665,30610,30423,30245,32174,32394,32242,20884,21081,20960,21409,21437,21610,22028,22279,21814,20749,20875,20884,20832,20875,20749,20166,20112,20165,6431,6760,6716,6407,6300,6381,5921,5986,5851,6544,6716,6590,20875,21081,20884,23074,22945,23018,23074,23223,23180,6839,6845,6814,21081,21083,21219,25010,24899,25076,26378,26316,26565,26122,26189,26269,25263,25355,25176,7326,7338,7421,7275,7338,7326,7344,7086,7147,7086,7071,7147,13606,13734,13402,14043,14044,14158,14550,14675,14528,14528,14675,14607,5921,5938,5989,5921,5989,5986,6128,5923,5996,21694,21814,21610,5892,5804,5981,5917,5780,5887,5887,5856,5919,5919,5856,5883,5883,5849,5995,5802,6102,6017,7147,6976,7022,9131,8972,9119,9398,9341,9335,8898,8903,8972,9479,9409,9398,9344,9409,9479,9805,9479,9828,9805,9828,10061,10268,10244,10335,10268,10335,10563,10190,10268,10159,10882,10788,10948,10882,10948,11057,21405,21176,21673,19826,19650,19734,19734,19650,19621,19621,19650,19503,19503,19461,19345,21405,21673,21735,27602,27952,27959,27434,27587,27573,27466,27587,27434,36305,36281,36231,36305,36231,36191,36578,36244,36610,7697,7419,7816,7338,7420,7502,7756,7810,7788,35132,34831,34735,35243,35211,35240,35243,35240,35377,7684,7955,7671,6806,7071,6958,27320,26677,27188,27320,27354,27607,24208,24050,24080,24208,24241,24416,23876,24076,23943,24025,24076,23876,6285,6300,6407,7420,7456,7534,26014,26047,26146,34831,34732,34425,8529,8419,8700,8312,8212,8270,8763,8628,8789,9409,9341,9398,10117,10563,10559,11149,11227,11463,30423,30231,30286,30359,30231,30423,5806,5972,5699,8242,8312,8483,7697,7532,7419,21818,21405,21735,36438,36671,35849,36165,35952,36284,36620,36565,36493,11216,11912,11269,12376,12537,12646,12943,13025,13047,22520,22268,22488,23358,23382,23556,5819,6019,5978,5894,6225,6031,35232,35171,35017,35878,35454,35876,35512,35727,35489,35113,35017,34837,15720,15801,15522,15085,15152,14921,15085,14921,14893,21502,21437,21409,36565,36544,36438,8460,8355,7945,8355,8018,7945,16059,16328,16603,18202,18334,18268,15336,15518,15341,33664,33688,33503,33548,33503,33473,35745,35512,35841,10961,10882,11057,10788,10726,10773,9341,9231,9335,23738,23858,23989,23499,23702,23553,23551,23702,23499,5819,5967,5796,12376,12646,12341,34340,34239,34264,33295,33401,33472,36514,36230,36336,16371,16531,16282,24792,25176,24963,26214,26014,26146,26214,26146,26178,7060,6919,7067,6597,6544,6590,6908,6919,6852,14202,14305,14175,35377,35254,35363,35377,35363,35439,7752,7767,7848,7810,7753,7932,7499,7684,7671,36580,36431,36336,36580,36336,36335,5780,5856,5887,9231,9174,9226,8797,8858,8959,10340,10434,10523,12242,12376,12321,10302,10434,10340,10110,10177,10064,32633,32581,32488,33152,32995,32962,6593,6353,6045,6198,6186,6325,6419,6472,6469,6097,6249,6119,18202,18231,18366,18649,18608,18736,23851,23738,23989,24320,24208,24416,8377,8575,8745,30231,30177,30196,30216,30177,30231,10920,10961,10984,10841,10726,10788,30921,30610,30259,30693,30610,30921,33225,33216,33066,33401,33558,33755,33032,32962,32947,15209,15336,15341,15209,15341,15103,25103,25010,25076,24854,24775,24766,26677,26378,26565,26189,26359,26269,26219,26359,26189,5856,5849,5883,19589,19650,19826,16968,17281,17255,6845,6839,6941,6845,6969,6727,35590,35355,35504,7869,7752,8123,7684,7756,7788,32741,32879,32752,23729,23640,23556,23851,23989,24050,33688,33820,33777,34101,34352,34080,33785,33820,33688,36607,36335,36239,36344,35992,35746,12499,12438,12535,11680,11149,11463,10949,10882,10961,12535,13158,12881,13640,14464,14152,13911,14044,13939,12321,12376,12341,11093,11269,11114,5763,5938,5921,6045,6353,5926,7420,7336,7456,7456,7499,7671,7566,7753,7756,7338,7237,7420,7235,7275,7326,7022,7275,7235,7237,7275,7045,7419,7292,7722,7123,7292,7419,7532,7697,7694,13939,14044,14043,13196,13047,13025,18382,18608,18471,18202,18129,18231,6628,6969,6685,6419,6469,6277,13047,12732,12943,14128,14202,14175,14893,14921,14753,6597,6971,6810,6363,6285,6407,36078,35746,35379,35799,35745,35841,8529,8700,8705,8903,8959,8972,11011,11093,11114,33837,33833,33947,32095,32020,32092,5643,5908,6154,10061,9828,10210,9344,9237,9341,9341,9237,9231,9231,9237,9174,10095,10210,10190,14893,14654,14797,16859,16834,16618,19210,19303,19261,24076,24260,23943,24192,24260,24076,24854,24766,24899,23909,23851,24050,27320,27188,27314,26359,26626,26269,30117,30234,29985,30017,29762,29888,32092,32020,31896,32151,32545,32335,32879,32936,32947,33664,33548,33656,33552,33548,33473,32092,32211,32170,14831,14968,15036,14325,14344,14305,27354,27320,27314,27902,27930,27989,28403,28163,28279,28503,28675,28621,29731,29501,29656,33944,33837,34150,34594,34264,34240,34369,34500,34288,34191,34352,34101,35662,35619,35518,35677,35619,35969,5796,5967,5938,5796,5938,5763,19650,19461,19503,6277,6469,6404,5957,6097,5906,5926,6353,6282,6330,6285,6363,23738,23640,23729,23738,23851,23812,24934,24854,24899,25655,25103,24983,25655,25919,26014,25655,26014,26358,14481,14550,14528,23379,23368,23241,24259,24401,24260,23551,23368,23439,34732,34564,34221,34594,34564,34811,34564,34732,35132,35280,34753,35243,10841,10788,10882,10841,10882,10949,32936,33032,32947,12438,12160,12267,12096,12160,12438,29742,29656,29789,29742,29789,30115,34266,34172,34239,10190,10210,10268,10064,10177,9833,11011,11157,11093,19461,19390,19345,11093,11157,11269,10645,10681,10434,30610,30359,30423,30216,30359,30502,15148,15209,15103,15720,15805,15801,15148,15103,15085,35619,35524,35464,35388,35280,35243,7612,7694,7752,8614,8705,8628,13019,13158,13132,30106,30234,30117,29582,29455,29475,29296,29448,29546,34411,34101,34120,33548,33664,33503,33656,33548,33552,34448,34266,34239,34448,34239,34340,33981,33777,33820,13466,13019,13132,12943,12732,12719,24260,24401,24133,24025,23876,23898,34460,34369,34311,34460,34311,34352,10042,10190,10159,10110,10183,10340,31872,31464,31779,32879,33023,32936,32936,33075,33032,32741,32897,32879,32394,32633,32488,32628,32633,32394,32313,32394,32174,32174,31755,32303,17017,16834,16859,16921,16834,17017,24431,24320,24416,24934,24899,25010,36078,35326,35727,26214,26178,26378,25059,24934,25010,25360,25623,25355,26359,26556,26626,25360,25355,25263,8993,8972,9131,8578,8614,8628,9143,9131,9174,10949,10961,10920,10042,10095,10190,33032,33152,32962,33134,33152,33032,18382,18471,18334,36607,36239,36281,36665,36451,36616,36394,36281,36305,6122,6445,6067,6628,6685,6645,25592,25360,25460,6239,6282,6300,23898,23876,23702,9344,9341,9409,10183,10302,10340,32633,32687,32581,5894,6031,5963,5894,5963,5799,6285,6239,6300,6431,6330,6363,6839,6806,6958,6628,6645,6451,8578,8628,8763,14956,14893,14797,19390,19210,19261,30171,30234,30106,34426,34460,34352,35590,35439,35363,14344,14481,14528,14893,14753,14654,14202,14325,14305,14044,14128,14175,13743,13911,13939,13743,13939,13606,20380,20166,20165,20875,20899,21081,21081,21092,21083,21083,21092,21409,21437,21694,21610,13749,13743,13628,20832,20899,20875,28010,27902,27989,28010,27989,28163,27623,27952,27602,27623,27602,27587,36597,36695,36499,36744,36620,36493,36565,36651,36544,36597,36469,36526,36597,36526,36715,6615,6597,6810,6201,6285,6330,6908,7043,6919,14018,14128,14044,26328,26214,26378,26328,26378,26633,26378,26677,26633,25805,26219,25946,27080,27376,26977,34705,34288,34500,35005,35113,34837,35841,35512,35454,20165,20117,20220,29296,29190,29448,30017,30171,30106,32687,32758,32581,5896,5963,5996,8903,8797,8959,8816,8797,8903,10268,10117,10159,11149,11057,11227,27952,28133,28101,12376,12403,12537,12188,12242,12321,14128,14325,14202,27466,27376,27453,20165,20063,20117,21002,21092,21081,29582,29888,29455,33837,33790,33558,33755,33790,33938,36451,36578,36616,23368,23551,23499,23694,23551,23439,19210,19056,19303,5804,5782,5917,5856,5726,5849,5849,5726,5995,5678,5782,5892,6117,6047,5560,5778,5802,5806,5778,5806,5699,13162,13402,13196,13063,13196,13025,24320,24050,24208,25059,25010,25103,6097,6054,6198,6004,6054,6097,9237,9143,9174,14423,14481,14344,32758,32897,32741,35388,35243,35377,36744,36493,36542,36544,36701,36438,15027,15148,15085,15801,15518,15522,15801,15805,16059,15027,15085,14893,35524,35590,35504,35453,35388,35377,35677,35590,35524,8614,8529,8705,7612,7752,7603,8521,8529,8614,36514,36336,36431,16282,16531,16618,15119,14831,15036,15518,15336,15522,18366,18382,18334,18608,18556,18736,18366,18334,18202,25623,25805,25946,25592,25805,25623,25592,25623,25360,6419,6384,6472,6306,6384,6419,15805,16045,16059,7612,7532,7694,6852,6919,7060,8270,8212,7869,19056,18958,19114,28621,28675,28639,36641,36514,36431,6852,7060,6847,35403,35388,35467,21092,21502,21409,36620,36651,36565,36610,36616,36578,16045,16328,16059,23812,23640,23738,23074,23089,22945,23812,23851,23909,24025,24192,24076,24401,24792,24963,23551,23694,23702,23385,22509,23241,36354,36394,36305,36495,36580,36335,5739,5972,5819,5713,5780,5917,6004,6107,6054,29801,29956,29888,29448,29190,29272,32020,31991,31779,32170,32095,32092,32170,32211,32335,32170,32261,32095,32095,31991,32020,31942,32545,31985,16052,15739,15814,17255,17281,17858,29100,28675,28991,30115,29933,30177,30115,30177,30216,5755,5739,5819,5790,5851,5986,18958,18919,19114,31706,31932,31755,32633,32660,32687,32687,32773,32758,32758,32849,32897,8242,8483,8419,13019,12881,13158,12256,12096,12438,11920,11463,12099,12968,12881,13019,12499,12881,12358,12459,12732,12537,6054,6107,6186,6097,6119,5906,24034,24192,24025,6588,6628,6451,9363,9415,8921,10110,10135,10183,10183,10112,10302,12242,12403,12376,12309,12403,12242,18202,17951,18129,18530,18556,18608,23358,23223,23382,26633,26677,27320,26214,26358,26014,25105,25059,25103,15119,15036,15565,21502,21694,21437,36651,36701,36544,36601,36610,36244,8287,8379,8529,9143,8993,9131,33552,33473,33459,33023,33075,32936,33023,32879,32897,6201,6239,6285,6431,6716,6544,25105,25103,25164,24416,24775,24431,30234,30520,29985,30372,30520,30234,30660,30520,30578,32313,32427,32394,8529,8379,8419,8578,8763,8675,30216,30231,30359,31343,30970,31464,33664,33785,33688,34191,34426,34352,33406,33220,33152,5780,5726,5856,7275,7237,7338,7022,7235,7147,6806,6839,6814,27466,27623,27587,28679,28370,28715,28133,28370,28101,27466,27434,27376,10042,10061,10095,10095,10061,10210,9513,9344,9479,9237,9169,9143,8877,8898,8993,10559,10726,10841,9986,10064,9703,10302,10274,10434,7224,7336,7420,7756,7753,7810,8377,8264,8575,27902,27607,27586,27998,28010,28210,23640,23358,23556,24775,24854,24952,26977,26626,27080,27453,27376,27413,7585,7756,7684,7737,9363,8921,34460,34487,34500,34585,34426,34654,6143,6431,6544,6143,6112,6100,8993,8898,8972,8824,8898,8877,13743,13749,13911,14018,14325,14128,14223,14423,14325,14325,14423,14344,13402,13428,13606,13482,13428,13194,22806,22773,22945,21405,21062,21176,19589,19469,19650,19650,19469,19461,19461,19469,19390,19390,19260,19210,19210,19117,19056,19056,19117,18958,18958,18870,18919,33075,33134,33032,33088,33134,33075,9242,9344,9138,10064,10135,10110,15814,15739,15565,16282,16618,16834,15522,15336,15436,15805,15832,16045,16045,16046,16328,5719,5763,5851,5923,5896,5996,5923,6128,6045,6628,6727,6969,15156,15336,15209,14956,15027,14893,14675,14654,14753,18530,18608,18382,17626,17472,17436,26667,26633,26954,14018,14044,13911,35263,35232,35017,35263,35017,35113,6451,6645,6120,6594,6717,6727,6242,6277,6168,6067,6445,6186,24952,24854,24934,24192,24259,24260,24261,24259,24192,8742,8763,8797,10949,10781,10841,10984,11149,11030,5755,5819,5796,5755,5796,5680,7422,7499,7456,15156,15209,15148,28503,28403,28279,28471,28403,28503,28186,28133,27952,29801,29888,29582,29272,29190,29138,32628,32660,32633,34694,34705,34500,36567,36580,36495,36621,36601,36244,36701,36671,36438,35964,36105,35815,7060,7145,6877,6622,6615,7043,7504,7292,6877,33790,33755,33558,33944,33790,33837,33837,33947,34150,33656,33785,33664,33771,33785,33656,8898,8816,8903,8824,8816,8898,25059,24952,24934,25032,25105,25164,25059,25105,25032,35952,35807,36284,35619,35677,35524,5763,5921,5851,6107,6067,6186,6004,5957,5922,10112,10274,10302,12241,12459,12403,12403,12459,12537,12943,13063,13025,12309,12242,12188,17192,17226,17186,21062,20820,21176,21694,22028,21814,23731,23358,23640,24218,23909,24050,23694,23898,23702,23939,23898,23694,31513,31343,31464,36344,36354,35992,36607,36567,36495,7499,7585,7684,12916,13063,12943,23180,23089,23074,23731,23640,23812,23241,22509,23100,28639,28675,28729,35672,35531,35439,35779,35677,35784,36621,36244,36514,36452,36281,36394,6717,6806,6814,6717,6814,6727,10274,10360,10434,8578,8521,8614,8246,8242,8419,8479,8521,8578,30115,30141,29742,28729,28675,29100,30693,30359,30610,33459,33473,33220,17945,18732,18531,17945,17255,17858,17077,16921,17017,8816,8742,8797,8824,8742,8816,10984,10961,11057,31063,30693,30921,30520,30660,30217,29956,30017,29888,36284,35807,36667,34426,34487,34460,34585,34487,34426,6277,6306,6419,6242,6306,6277,35745,35799,35727,36113,36344,35746,35122,35876,35454,19469,19260,19390,36621,36514,36652,18530,18382,18291,18382,18366,18291,5858,5923,5740,5790,5986,5894,23379,23439,23368,23404,23439,23379,5957,6004,6097,6168,6277,6404,5906,6119,5836,7336,7422,7456,7499,7444,7585,7237,7224,7420,7045,7224,7237,8246,8419,8379,13628,13743,13606,13628,13606,13482,34705,35005,34402,34799,35005,34705,7879,7869,8212,6877,7292,7123,12923,13162,13063,12241,12309,12188,28917,28986,28509,29801,29582,29708,6878,7147,7071,15027,15156,15148,14675,14550,14654,14550,14496,14654,5829,5926,6282,6109,6201,6330,6109,6330,6431,36151,36078,35727,35862,35103,35171,35427,35263,35113,36652,36514,36641,20832,20801,20899,20899,20999,21081,21092,21005,21502,21502,21762,21694,22108,22214,22028,20380,20682,20593,20614,20682,20380,20220,20380,20165,7253,7422,7336,8146,8107,8242,8742,8675,8763,8573,8675,8742,11149,10984,11057,10268,10563,10117,12096,12099,12160,10645,11114,10681,31263,31063,30970,33406,33459,33220,32914,33023,32897,34594,34448,34340,34594,34240,34564,35420,34735,35280,35403,35280,35388,20801,20999,20899,31991,31872,31779,31343,31263,30970,32095,32125,31991,32261,32125,32095,31942,33216,32545,20165,20112,20063,18291,18366,18231,32125,32012,31991,32427,32530,32394,32660,32773,32687,32313,32492,32427,31441,31706,31755,6622,7043,6908,7510,7532,7612,21620,21062,21405,19469,19391,19260,20999,21002,21081,35453,35377,35531,5969,6067,5886,16628,16798,16794,18164,18291,18231,16628,16794,16328,32012,31872,31991,32545,33216,32594,5782,5713,5917,5780,5668,5726,5615,6030,5995,5655,6047,5802,5655,5802,5651,5802,5778,5651,18747,18732,18919,18557,18736,18556,13063,13162,13196,12916,12943,12864,34663,34694,34500,5799,5963,5896,5651,5778,5700,6819,6908,6852,14956,15156,15027,15668,15832,15720,15720,15832,15805,15336,15156,15273,25032,24952,25059,23815,23812,23909,25103,25276,25164,36641,36580,36567,36641,36431,36580,25460,25360,25263,23898,24034,24025,23939,24034,23898,37091,36744,36542,36620,36830,36651,36651,36769,36701,36701,36797,36671,36822,36542,36695,36822,36695,36881,36715,36526,36665,36715,36665,36711,36665,36616,36711,36616,36610,36711,36610,36878,36711,33284,33216,33339,32492,32530,32427,12390,12438,12499,5778,5699,5700,8242,8107,8212,8287,8529,8521,15903,15832,15918,33023,33088,33075,33131,33088,33023,33560,33472,33401,34344,34004,34266,36610,36601,36764,35531,35377,35439,16011,16046,16045,10657,10559,10563,10805,11030,11349,23149,23089,23180,20851,20897,21062,23149,23180,23295,23731,23812,23815,33560,33401,33863,33647,33771,33656,33785,33981,33820,34879,34799,34694,33406,33152,33134,5972,5739,5699,10061,9843,9805,10949,10920,10781,10274,10206,10360,10360,10645,10434,10135,10112,10183,10064,10060,10135,9986,10060,10064,32530,32628,32394,35799,36011,35727,35402,35171,35232,12719,12732,12459,28621,28471,28503,27998,27902,28010,27998,27607,27902,29501,29731,29650,34448,34321,34266,35132,34732,34831,12358,12390,12499,12256,12390,12358,34344,34321,34395,16046,16404,16328,33647,33656,33552,5577,5713,5782,36764,36601,36734,5836,6119,5705,6004,5922,6107,9344,9242,9237,9138,9344,9439,10781,10920,10984,10060,10112,10135,23815,23997,23784,36354,36452,36394,36587,36452,36354,6976,7045,7022,6588,6727,6628,8877,8993,9143,8573,8479,8578,17255,17041,17077,16989,17041,17193,5699,5739,5603,36862,36769,36651,36667,36907,36896,36571,36344,36632,13749,13843,13911,13706,13843,13749,13606,13428,13482,7289,7444,7422,7022,7045,7275,6878,7071,6806,9242,9169,9237,13843,14018,13911,28010,28163,28210,26358,26214,26328,32628,32773,32660,5858,5799,5896,5858,5896,5923,13428,13402,13194,17803,17951,17626,18530,18557,18556,23295,23180,23358,23089,22806,22945,28210,28163,28303,12489,12719,12459,13133,13402,13162,12489,12459,12241,24925,24431,24775,26667,26328,26633,5713,5668,5780,8573,8578,8675,27623,27721,27952,29546,29448,29632,27466,27537,27623,27080,26626,27111,13133,13162,12923,28303,28163,28403,5680,5796,5763,5603,5739,5605,7603,7510,7612,7999,7879,8212,7999,8212,8107,32773,32849,32758,33826,33647,33459,36769,36797,36701,36734,36601,36775,10805,10781,10984,10559,10781,10805,33339,33216,33295,33339,33295,33472,6847,6819,6852,7510,7419,7532,6739,6878,6693,19117,18870,18958,19117,19210,19260,35263,35402,35232,35427,35402,35263,35427,35113,35602,36801,36641,36567,36775,36601,36621,5906,5891,5957,5822,5891,5906,17670,17803,17626,17861,17803,17670,23483,23295,23358,24218,24050,24320,26606,26667,26954,8287,8246,8379,16046,16064,16404,16404,16628,16328,15832,16011,16045,15903,16011,15832,26333,26556,26219,24463,24401,24259,29582,29546,29708,30171,30318,30325,34694,34799,34705,34663,34500,34487,20107,19826,19928,6645,6472,6120,6168,6404,6022,6404,6122,6022,18521,18557,18530,18129,18164,18231,20851,21062,21426,23483,23358,23731,23439,23425,23694,23100,22509,22314,23404,23241,23381,12719,12864,12943,12241,12403,12309,35876,34959,35862,36047,36011,35799,36623,36571,36704,17041,16921,17077,16989,16921,17041,17041,17255,17193,31063,31257,30693,30440,30275,30216,31513,31263,31343,32849,32914,32897,36731,36169,36671,36165,36253,36105,36105,36157,35815,35531,35467,35453,6704,6819,6847,24034,24261,24192,24135,24261,24034,26556,26359,26219,35403,35420,35280,35453,35467,35388,35439,35590,35672,7603,7752,7662,34585,34663,34487,18870,18747,18919,18885,18747,18870,30216,30275,30115,30502,30359,30693,33459,33647,33552,33945,33981,33785,33406,33134,33390,32634,32428,32545,33523,33339,33472,36278,36253,36165,6615,6586,6597,6580,6586,6615,6472,6384,6120,6693,6878,6624,26667,26425,26328,26550,26425,26667,31263,31186,31063,35672,35590,35764,36864,36731,36671,5675,5790,5894,5728,5858,5740,7662,7752,7869,8046,7999,8107,12096,11920,12099,12111,11920,12096,18521,18530,18291,17861,18129,17951,23241,23404,23379,22214,22279,22028,34251,34150,33947,33944,33938,33790,34344,34266,34321,7835,7869,7879,12748,12864,12719,28471,28303,28403,29650,29731,29742,34184,33938,33944,33945,33785,33771,5675,5894,5799,31872,31746,31464,31263,31257,31186,32012,31964,31872,32125,32110,32012,32261,32110,32125,32261,32170,32335,32428,32335,32545,12390,12256,12438,12968,13019,13466,12489,12549,12719,11216,11269,11157,34395,34448,34531,34395,34321,34448,32110,31964,32012,31441,31248,31706,32474,32492,32313,32530,32595,32628,32929,32857,32773,32773,32857,32849,32849,32968,32914,31759,31855,31706,19589,19391,19469,36775,36621,36652,16011,16064,16046,15668,15720,15522,15668,15522,15539,31038,31759,31248,32594,33216,33326,7342,7123,7510,7510,7123,7419,6704,6622,6819,8391,8573,8742,8479,8287,8521,8146,8046,8107,8870,8877,9143,13584,13706,13628,13628,13706,13749,13843,13844,14018,14797,15156,14956,13484,13628,13482,24925,24775,24952,23568,23483,23731,24925,24952,25032,33119,33131,33023,33013,33023,32914,8671,8742,8824,15436,15336,15273,6828,6976,7147,7096,7336,7224,6828,7147,6878,8402,8287,8479,14831,14152,14968,14616,14152,14831,15119,15565,15739,27453,27537,27466,27418,27537,27453,29956,30171,30017,29546,29632,29708,36242,36157,36105,32595,32492,32474,6588,6594,6727,35779,35590,35677,5719,5680,5763,5891,5922,5957,5788,5922,5891,6739,6828,6878,10060,10083,10112,10333,10645,10360,11011,11031,11157,9703,10064,9833,12469,12549,12489,12923,13063,12916,18521,18291,18388,21762,22028,21694,23174,23089,23149,23568,23731,23784,23404,23425,23439,23381,23425,23404,27418,27413,27355,27080,27413,27376,28210,28197,27998,27998,28090,27607,26606,26550,26667,28471,28621,28524,32041,31746,31872,31932,31706,31946,33326,33216,33284,35528,35420,35403,35484,35420,35529,35675,35467,35531,36009,35876,35862,35598,35427,35602,35113,35005,35294,14481,14496,14550,36047,35799,35841,35862,35171,35402,25276,25103,25655,36253,36242,36105,36262,36242,36253,10206,10274,10112,9986,10083,10060,7422,7444,7499,7585,7566,7756,7945,8018,7975,9546,9703,9833,7253,7336,7096,12923,12916,12864,28524,28621,28639,8146,8242,8246,7999,7930,7879,22214,22244,22314,28917,28509,28370,36748,36775,36652,36748,36652,36641,7793,7930,7832,11920,11680,11463,12256,12111,12096,11968,12111,11875,34344,34251,34004,34150,34184,33944,34281,34251,34344,11000,11031,11011,20682,20801,20832,20999,21005,21002,21002,21005,21092,22214,22108,22244,20393,20614,20380,20393,20380,20220,20614,20748,20682,30440,30490,30268,30490,30502,30559,29950,29650,29742,28631,28524,28639,33863,33401,33755,33443,33326,33284,33863,33755,33938,20748,20801,20682,36695,36597,36892,36881,36695,36892,36744,36830,36620,36769,36916,36797,36797,36864,36671,36597,36715,36892,36911,36910,36892,37066,36911,36715,21062,20897,20820,19589,19205,19391,23174,23149,23295,36610,36764,36878,10159,10010,10042,10042,10010,10061,8870,9143,8948,8855,8840,8877,10559,10657,10726,10559,10841,10781,31746,31513,31464,6101,6109,5991,6201,6071,6239,6478,6580,6615,6622,6908,6819,20231,20393,20220,18239,18291,18164,19029,18736,20063,24261,24463,24259,24595,24463,24261,25214,25276,25224,26633,27320,26954,26333,26219,25805,25621,25805,25592,35784,35677,35969,35672,35675,35531,7945,7975,7802,34017,33863,33938,36878,36764,36898,5759,5836,5705,23265,23174,23295,23784,23731,23815,12715,12358,12881,34373,34395,34531,12854,12923,12864,33443,33284,33339,5537,5719,5851,5680,5719,5595,19205,19117,19260,18747,18531,18732,19205,19260,19391,36898,36764,36965,36872,36748,36875,36607,36281,36452,10068,10206,10112,32695,32773,32628,20063,19700,20020,15990,16064,16011,17803,17861,17951,18129,18239,18164,15990,16011,15903,15990,15903,15918,25114,25460,25263,15436,15539,15522,15637,15485,15585,5651,5636,5655,5655,5560,6047,5678,5577,5782,5713,5626,5668,5584,5636,5651,5584,5651,5700,5584,5700,5593,5700,5699,5593,18596,18736,18557,36940,36595,36169,36284,36278,36165,36900,36607,36452,6101,5991,5956,6152,6384,6306,6588,6506,6594,5969,6122,6067,6067,6107,5886,25164,25137,25032,24431,24218,24320,26358,26328,26425,30502,30440,30216,30440,30502,30490,30171,30372,30234,30325,30372,30171,5523,5577,5462,5615,5995,5726,36922,36830,36744,36731,36940,36169,7444,7566,7585,12549,12748,12719,12758,12748,12469,12469,12489,12364,14481,14423,14496,28679,28917,28370,34663,34879,34694,34411,34426,34191,13706,13844,13843,13592,13844,13706,13484,13482,13376,13402,13133,13194,26411,26358,26425,26411,26425,26550,33390,33134,33088,33872,33945,33771,33981,34120,33777,33390,33088,33131,35420,35132,34735,35484,35132,35420,5593,5699,5603,5836,5822,5906,5759,5822,5836,17670,17626,17253,30268,30115,30275,30318,30171,29956,29396,29448,29272,34198,34150,34251,34198,34184,34150,36830,36862,36651,5886,6107,5870,7444,7289,7566,7096,7224,7079,7224,7045,7079,7930,7835,7879,7603,7465,7510,7793,7835,7930,11779,12188,12321,13194,13115,13189,28303,28197,28210,28179,28197,28414,28414,28303,28471,28917,29396,29272,7911,7930,7999,8124,8146,8246,8074,8146,8124,8402,8479,8573,33872,33771,33647,27537,27721,27623,27413,27418,27453,27313,27413,27080,5739,5755,5605,24064,24218,24142,32968,33013,32914,36764,36966,36965,5626,5726,5668,16584,16628,16404,36242,36368,36157,35784,35764,35779,36443,36278,36284,23265,23295,23483,23265,23483,23465,12945,13133,12923,5527,5626,5713,27218,27313,27080,7726,7662,7869,26562,26606,26652,29255,29100,28991,35779,35764,35590,35619,36118,35969,11031,11216,11157,10900,11216,11031,10869,11011,10645,32106,32008,31983,30211,29956,29801,10862,10869,10845,16243,16584,16404,15918,15832,15637,15832,15668,15637,35895,35841,35878,36571,36587,36354,35895,35878,35876,36011,36151,35727,33013,33119,33023,5605,5755,5680,31964,32041,31872,31746,31951,31513,32227,32041,31964,32444,32261,32335,32444,32335,32428,32227,32261,32238,36870,36734,36775,36870,36775,36872,23997,23815,23909,36571,36354,36344,9615,9703,9546,9986,10019,10083,10083,10068,10112,10862,11000,10869,12911,12968,13466,19117,18885,18870,19038,18885,19117,28631,28639,28729,32019,32096,32303,32492,32595,32530,32857,32968,32849,33013,33192,33119,32008,32096,32019,32008,32019,31932,32008,31932,31983,26770,26626,26556,26928,27111,26626,32227,31964,32110,30502,30693,30559,31932,31946,31983,16989,16282,16834,16989,16834,16921,36106,35895,35876,5858,5728,5799,5612,5605,5680,5740,5718,5709,18045,18239,18129,18521,18596,18557,18045,18129,17861,23614,23483,23568,23009,22806,23089,17230,17255,17740,16883,16982,16798,16883,16798,16628,7802,7975,7588,12111,11968,11920,12272,12111,12256,12272,12256,12358,29708,29774,29801,29396,29632,29448,29712,29632,29592,33945,34056,33981,34063,34056,33945,33872,33647,33826,32464,32313,32303,8877,8840,8824,9143,9169,8948,10805,10984,11030,7375,7465,7603,6704,6847,6877,12758,12854,12748,12748,12854,12864,6101,6071,6201,6101,6201,6109,6014,6022,5939,6152,6306,6242,6022,6122,5939,6152,6242,6168,6594,6542,6717,7079,7045,6639,7835,7726,7869,7662,7375,7603,7742,7726,7835,10869,11000,11011,10222,10360,10206,12153,12272,12358,15060,15273,15156,15060,15156,14797,16243,16404,16064,25276,25137,25164,24218,23997,23909,25083,25137,25276,25083,25276,25214,26562,26411,26550,26562,26550,26606,34395,34373,34344,34531,34448,34640,34120,34101,33777,36278,36262,36253,36457,36262,36278,36942,36864,36797,6704,6877,6699,6544,6597,6112,35708,35675,35672,35708,35672,35764,10078,10010,10159,10078,10159,10117,33826,33459,33874,17253,17436,17192,36571,36632,36704,36900,36801,36607,36872,36775,36748,9906,10078,10119,23790,23939,23694,23328,23381,23241,36864,36837,36731,6739,6976,6828,7253,7248,7422,7588,7975,7753,13484,13584,13628,14223,14325,14018,13376,13584,13484,13376,13482,13194,28197,28097,27998,28179,28097,28197,23009,23089,23107,16093,16243,16064,15637,15668,15539,25460,25621,25592,25967,25621,25493,25807,25967,26045,15641,15637,15585,7120,7248,7253,13189,13376,13194,5829,6282,6239,17740,17255,17945,16373,16052,16282,17189,17253,17192,17189,17192,16982,6451,6506,6588,16723,16883,16628,16516,16628,16584,26683,26770,26556,5612,5680,5595,6073,6152,6168,6465,6542,6506,6630,6806,6717,27330,27355,27313,27313,27355,27413,27418,27436,27537,27218,27080,27111,8291,8402,8206,7911,7999,8046,29712,29774,29708,29712,29708,29632,29632,29396,29592,34145,34120,34056,34056,34120,33981,7726,7639,7662,7911,8046,7896,34407,34281,34344,34341,34017,33938,33863,34017,33560,33523,33443,33339,34407,34344,34373,7248,7289,7422,23615,23614,23568,23107,23089,23174,24064,23997,24218,23790,23694,23425,32929,32968,32857,33506,33390,33131,5740,5923,5718,5595,5719,5567,18388,18596,18521,17779,18045,17861,17779,17861,17670,23381,23438,23425,23328,23438,23381,33506,33131,33119,34597,34411,34356,18703,18554,18747,18703,18747,18885,18388,18291,18239,34341,33938,34184,32739,32634,32594,5719,5537,5567,6071,5829,6239,6478,6586,6580,36262,36274,36242,36368,36274,36459,36801,36567,36607,6699,6877,7123,6622,6478,6615,27149,27218,27111,7643,7639,7726,7465,7370,7510,28960,28631,28729,28414,28197,28303,29607,29255,28991,29607,29501,29650,34640,34448,34740,7342,7370,7375,12854,12945,12923,12758,12945,12854,12748,12549,12469,12241,12311,12489,28960,28729,29100,35132,34811,34564,34740,34925,34791,35619,36194,36118,35528,35403,35467,5675,5799,5728,19071,19205,19589,20748,20728,20801,20801,20776,20999,22740,23100,22314,20614,20728,20748,20480,20728,20614,20480,20614,20393,20231,20220,20174,20220,20117,20174,5532,5636,5477,5532,5655,5636,5532,5560,5655,5577,5527,5713,5636,5584,5533,5584,5593,5533,5593,5478,5533,5603,5556,5593,5870,6107,5922,6022,6073,6168,5870,5922,5788,6561,6630,6717,6542,6594,6506,14223,14018,14106,15724,15823,15637,17230,17193,17255,17213,17193,17230,17550,17779,17670,17074,17189,16982,16723,16982,16883,20728,20776,20801,20897,20669,20245,21620,21405,21818,37388,36922,36744,36830,36990,36862,36862,36916,36769,36864,36942,36837,36881,36912,36822,36892,36912,36881,36910,36912,36892,36892,36715,36911,36711,37066,36715,5702,5675,5728,18554,18531,18747,18703,18531,18554,22806,22671,22488,23107,23174,23133,36727,36452,36587,25137,24925,25032,25083,24925,25137,33523,33472,33560,5705,6176,5908,5599,5908,5643,23615,23568,23784,23615,23784,23903,5560,5528,5892,5440,5615,5726,20174,20117,20020,20776,21005,20999,25621,25807,25805,24792,24401,24463,36711,36878,37066,5788,5891,5822,24142,24218,24431,23939,24135,24034,23953,24135,23939,9138,9169,9242,8840,8671,8824,20020,20117,20063,8074,8046,8146,7793,7742,7835,12241,12188,12311,29060,28960,29100,34341,34198,34281,34281,34198,34251,33721,33523,33560,36011,36176,36151,36344,36660,36632,35895,36047,35841,36235,36047,36106,36875,36748,36641,37003,36878,36898,5603,5486,5556,8124,8246,8287,8207,8287,8402,7737,8921,8575,7945,8028,8460,7802,8028,7945,37003,36898,36965,7832,7742,7793,7375,7370,7465,34481,34407,34373,34481,34373,34531,6561,6542,6466,35784,35708,35764,5952,6073,6022,6465,6506,6451,19700,20063,19551,32261,32227,32110,32041,31951,31746,32444,32428,32634,37091,36542,36822,7588,7753,7566,7248,7247,7289,7096,7120,7253,7079,7120,7096,7045,6976,6639,6878,6806,6624,18596,18636,18736,18211,18388,18239,18211,18239,18045,22899,22671,22806,23133,23174,23265,23147,23100,23028,23790,23953,23939,28090,27592,27607,28414,28471,28524,28414,28524,28710,32339,32464,32303,32595,32695,32628,32008,32106,32096,31706,31855,31946,30520,30372,30578,32634,32545,32594,32339,32303,32096,5462,5577,5678,5440,5726,5626,8870,8855,8877,19205,19038,19117,19071,19038,19205,30517,30372,30325,32464,32474,32313,36922,36990,36830,14106,14018,13831,14018,13844,13831,13377,13584,13376,13194,13133,13071,27392,27436,27355,27355,27436,27418,27330,27313,27218,27330,27218,27149,33443,33523,33709,32739,32594,33326,35528,35467,35633,8291,8207,8402,30440,30268,30275,29060,28916,28960,30693,30670,30559,30211,30318,29956,13071,13133,12945,23986,23784,23997,23465,23133,23265,28798,28524,28631,31038,31389,31759,33501,33326,33443,5556,5486,5478,12311,12188,12089,12921,13071,12945,34740,34448,34594,34740,34594,34811,36990,36943,36862,6624,6806,6630,24542,24142,24431,24064,23986,23997,26928,26626,26770,35633,35467,35675,35427,35598,35402,35294,35005,34799,34879,34663,34767,10010,9923,10061,8870,8846,8855,9977,9923,10010,9977,10010,10078,31038,30981,31389,32715,32695,32595,32968,33192,33013,5523,5527,5577,36943,36916,36862,36837,36999,36731,19038,18946,18885,19051,18946,19038,36764,36734,36966,36998,36875,36641,6526,6478,6622,13115,13071,13005,34767,34663,34585,34561,34426,34411,22899,22806,23009,23465,23483,23614,9923,9977,9850,9906,9977,10078,9852,10019,9986,9852,9986,9703,31389,30981,30660,7911,7832,7930,7375,7662,7406,7819,7832,7911,7896,8046,8074,7247,7566,7289,29704,29607,29650,28960,28916,28631,36734,36919,36966,6571,6624,6630,6561,6717,6542,30517,30578,30372,9513,9479,9805,10019,10068,10083,12364,12311,12366,18169,17740,17945,18454,17945,18531,17550,17670,17347,5426,5605,5612,5567,5612,5595,16093,16064,15990,17189,17074,17253,15823,15990,15918,15823,15918,15637,21005,21762,21502,8207,8124,8287,8120,8124,8207,12921,12945,12758,12311,12089,12366,33721,33560,34017,34407,34558,34281,34640,34481,34531,34558,34481,34628,34597,34561,34411,34063,33945,33872,5715,5702,5728,5537,5851,5790,5715,5728,5740,5715,5740,5709,18186,18211,18124,18388,18636,18596,23100,23328,23241,23147,23328,23100,9138,9044,9169,8391,8402,8573,10068,10149,10206,32695,32929,32773,34182,34063,33872,36734,36870,36919,6511,6526,6622,6511,6622,6704,6465,6451,5954,14654,14788,14797,14544,14788,14654,26965,26928,26770,35784,36153,35708,35742,35529,35528,36304,35662,36157,6120,6384,6152,5939,6122,5969,5939,5969,5826,16243,16516,16584,25429,25312,25224,24773,24542,24431,5615,5599,5643,5652,5788,5822,5787,5807,5886,5432,5599,5615,22899,23009,22995,27436,27721,27537,30511,30517,30318,27524,27721,27436,27524,27436,27458,6698,6976,6739,7036,7247,7248,6698,6739,6693,6698,6693,6599,8671,8840,8855,29950,29704,29650,31257,31263,31513,30318,30517,30325,31866,31855,31759,30211,29801,29774,34718,34740,34791,37119,36942,36797,36667,36443,36284,36919,37029,37090,9044,8948,9169,10149,10222,10206,5652,5822,5759,14353,14496,14423,13831,13844,13592,13377,13376,13189,36571,36623,36587,36998,36988,36875,36706,36660,36344,7823,7896,7762,7375,7406,7299,7819,7896,7823,33709,33501,33443,34341,34184,34198,5537,5790,5488,5923,6045,5718,5599,5705,5908,36988,36872,36875,37029,36870,37084,34145,34224,34270,6599,6693,6624,6040,6152,5920,6607,6699,6480,7342,7510,7370,6599,6624,6572,35484,35553,35132,35528,35529,35420,35633,35675,35814,36047,36143,36011,36235,36143,36047,7036,7248,7120,13071,13115,13194,12483,12758,12469,18773,18703,18885,18773,18885,18946,5826,5969,5886,17193,17148,16989,17489,17213,17230,17148,17213,17241,24595,24792,24463,26965,27040,26928,24595,24261,24135,35807,36907,36667,36274,36368,36242,12311,12364,12489,10862,11031,11000,21762,22108,22028,36942,36999,36837,6571,6630,6561,14353,14423,14223,16362,16516,16243,35742,35633,35814,7643,7742,7832,11349,11030,11149,11875,11920,11968,12550,12921,12758,28317,28370,28133,6101,5956,6071,5991,6109,6431,6597,6586,6339,6014,5952,6022,5840,5952,6014,23682,23465,23614,22995,23009,23107,24142,23986,24064,24044,23986,24142,23588,23425,23438,23588,23438,23328,36998,36641,36801,36113,36706,36344,8948,8846,8870,23682,23614,23615,9789,9513,9805,9138,9047,9044,9044,9047,8948,8948,8719,8846,9843,10061,9923,9843,9923,9850,18474,18636,18388,18296,18388,18211,23193,23107,23133,20464,20669,20851,32227,32065,32041,32397,32238,32261,32455,32261,32444,32455,32444,32692,32128,32212,32106,32106,32212,32096,32464,32565,32474,32474,32565,32595,32695,32877,32929,32128,32106,31983,32128,31983,31946,32128,31946,31923,31946,31855,31923,32397,32453,32358,36999,36989,36731,15318,15119,15739,12446,12715,12765,16052,15814,16282,26411,26562,26358,27592,27320,27607,32218,32065,32227,31923,31855,31866,6333,6308,6478,6663,6511,6704,6409,6571,6561,6466,6542,6465,7896,7819,7911,7896,8074,7979,11923,11875,12111,12153,12111,12272,12715,12881,12968,15119,14616,14831,26928,27040,27111,26333,25805,25807,29607,29508,29255,30141,30115,30268,29592,29396,29651,7946,8575,8264,10019,9841,10068,10068,10081,10149,10298,10333,10222,32703,32565,32464,34063,34145,34056,33459,33406,33778,33826,33874,33935,7643,7726,7742,14039,13466,14152,29060,29100,29255,28234,28097,28179,28090,27998,28097,34654,34767,34585,35137,35294,34799,34654,34426,34561,5939,5789,6014,5787,5886,5870,5787,5870,5788,9789,9843,9850,9651,9852,9703,17213,17148,17193,17241,17213,17489,24773,24431,24925,25066,24925,25083,32065,31951,32041,31866,31759,31882,32565,32715,32595,36989,36940,36731,7530,7643,7832,12412,12153,12358,34481,34558,34407,34718,34481,34640,34718,34640,34740,16634,16723,16516,16516,16723,16628,18186,18296,18211,15485,15637,15539,20851,20669,20897,22520,22488,22671,36912,37091,36822,36922,37015,36990,36990,37015,36943,36943,37047,36916,36916,37119,36797,36942,37049,36999,36999,37017,36989,36989,37017,36940,37026,37091,36912,37026,36912,36910,37026,36910,37129,36910,36911,37129,36878,37003,37066,37003,37007,37066,6339,6586,6478,6040,6120,6152,10845,10869,10627,10333,10360,10222,15060,14797,14788,33709,33721,34427,32692,32444,32634,5560,5273,5528,5528,5482,5678,5523,5446,5527,5532,5471,5560,5507,5471,5532,5507,5532,5477,20231,20480,20393,20885,20933,20776,20776,20933,21005,21005,21017,21762,21762,21925,22108,20342,20480,20231,20215,20231,20174,20215,20174,20020,5718,6045,5673,5589,5675,5702,14184,14353,14223,13592,13706,13584,13377,13189,13115,20606,20776,20728,23297,23588,23328,30514,30243,30268,30514,30268,30490,31389,31467,31518,35137,34799,34879,35862,34959,35103,37003,37086,37007,36727,36587,36623,36113,36078,36842,7083,7588,7566,7079,7028,7120,6574,7028,7079,7036,7028,6574,6512,6698,6599,14616,14039,14152,28234,28179,28275,28275,28179,28414,27721,28186,27952,28317,28186,28229,6571,6572,6624,6409,6466,5954,5477,5636,5533,5477,5533,5358,5273,5482,5528,5527,5440,5626,5589,5702,5578,19851,19071,19589,18703,18454,18531,19948,20215,20020,12364,12483,12469,12921,13005,13071,12366,12483,12364,34740,34811,34925,34767,35019,34879,34597,34654,34561,8846,8671,8855,7979,8074,8124,8391,8671,8478,26436,26333,26464,35689,35602,35113,5482,5462,5678,5578,5702,5715,18523,18454,18703,9050,9047,9138,19071,19051,19038,18852,19051,19071,30655,30559,30670,36727,36623,36740,37003,36965,37086,5478,5593,5556,6699,6663,6704,6308,6339,6478,6607,6663,6699,6607,6480,6516,12874,13005,12921,14496,14544,14654,14184,14223,14106,35602,35608,35598,37388,37015,36922,36965,37054,37086,5845,5829,6071,5845,6071,5956,16723,17074,16982,17089,17074,16766,24631,24595,24135,24792,25114,25263,24631,24135,24083,30202,30211,29774,29651,29396,29624,29768,29738,29908,5709,5578,5715,5673,6045,5926,5462,5446,5523,37015,37047,36943,14782,15060,14788,25214,25066,25083,26499,25655,26358,26954,26652,26606,5607,5787,5788,5807,5826,5886,5920,6152,6073,5652,5759,5642,5759,5705,5590,30243,30141,30268,29060,28798,28916,30419,30141,30243,30728,30660,30578,29768,29774,29712,37047,37071,36916,6409,6572,6571,6512,6572,6383,14388,14544,14496,19051,18943,18946,18852,18943,19051,22683,22520,22671,22683,22671,22899,27040,27149,27111,27031,27149,27040,28916,28798,28631,29060,29255,29260,15823,15802,15990,15746,15724,15641,19551,20063,18736,18211,18045,18124,23465,23193,23133,23110,23193,23136,23903,23784,23986,23903,23986,24012,23028,23100,22740,23588,23790,23425,36143,36176,36011,36235,36176,36143,5486,5603,5605,30728,30578,30517,37071,37119,36916,36965,36966,37054,6143,5991,6431,5924,5991,5934,30425,30511,30318,33192,32968,33104,34876,34767,34848,36457,36274,36262,35553,35600,35692,36457,36278,36443,5590,5705,5524,23668,23790,23588,36740,36623,36704,36740,36704,36632,5346,5486,5605,5488,5790,5675,5441,5537,5468,37054,36966,37094,37010,36998,36801,36966,36919,37094,5744,5826,5660,5826,5807,5621,12366,12550,12483,12483,12550,12758,24896,24773,24925,24595,24738,24792,24631,24738,24595,26722,26965,26770,29808,29607,29704,6478,6526,6333,26333,26436,26556,26539,26436,26464,7819,7766,7832,7406,7662,7639,7979,8124,8087,29738,29768,29712,30538,30517,30511,28913,28917,28679,34568,34341,34281,34628,34281,34558,18124,18045,17860,18418,18474,18388,23147,23297,23328,23281,23297,23147,28234,28090,28097,26761,26559,26652,28201,28090,28234,28275,28414,28456,33332,33192,33320,36706,36842,36934,8120,8207,8291,5496,5612,5567,37094,36919,37090,28201,28321,28178,28186,28317,28133,28229,28186,27721,27355,27330,27392,36574,36457,36443,27392,27330,27149,35529,35600,35484,35611,35600,35529,36153,35784,36330,32065,32231,31951,30670,30693,31257,32238,32278,32227,32455,32397,32261,32739,33326,33501,32212,32339,32096,32749,32877,32715,33104,32968,32929,32226,32339,32212,32226,32212,32128,32226,32128,31923,32226,31923,31984,9513,9439,9344,9565,9439,9513,9363,9615,9546,10081,10222,10149,18943,18773,18946,17489,17230,17740,18852,18773,18943,22520,22242,21818,22748,22683,22899,32397,32278,32238,32278,32218,32227,5357,5440,5527,37119,37049,36942,36574,36459,36457,36919,36870,37029,6663,6554,6511,6351,6348,6480,7299,7342,7375,9841,10019,9852,10862,10900,11031,10505,10869,10645,24357,24142,24542,23110,22995,23107,27458,27392,27553,8087,8120,8066,8391,8742,8671,11779,12321,11216,36413,36078,36151,36106,36047,35895,5591,5578,5709,5591,5709,5718,9843,9789,9805,9850,9977,9906,18418,18388,18296,17737,18045,17779,36870,36872,37084,12550,12874,12921,13080,13377,13115,14144,14184,14106,14353,14388,14496,12397,12874,12550,28317,28715,28370,34876,35019,34767,35634,35608,35602,35763,35862,35608,34270,34120,34145,10078,10117,10119,9651,9841,9852,33971,32739,33501,33709,33523,33721,36009,36106,35876,6572,6512,6599,6409,6561,6466,16373,16282,16989,17489,17504,17440,24488,24357,24542,36413,36151,36321,36868,36740,36632,10333,10468,10645,10366,10468,10333,30141,29950,29742,30333,29950,30141,30655,30490,30559,34280,34270,34224,34336,34270,34280,10119,10117,10559,37084,36872,36988,10845,10900,10862,10786,10900,10845,26559,26358,26562,25066,24896,24925,24773,24488,24542,30538,30511,30425,30538,30728,30517,36457,36459,36274,36389,36304,36157,37064,36595,36940,7406,7639,7643,17347,17670,17253,17089,17253,17074,34848,34767,34654,36760,36632,36660,37010,37121,36998,37121,37084,36988,6112,6143,6544,6333,6526,6397,26652,26559,26562,26954,27320,27592,27251,27392,27149,26436,26539,26556,26464,26333,26339,34356,34411,34120,35862,35598,35608,35862,35402,35598,9047,8976,8948,9439,9050,9138,35410,35113,35294,37049,37017,36999,10570,10505,10410,10468,10505,10645,35585,35410,35294,35137,34879,35019,9841,10081,10068,23808,23615,23903,24663,24488,24773,28090,27758,27592,28275,28201,28234,28710,28524,28798,28710,28798,28793,6120,5889,6451,5920,6073,5952,15724,15802,15823,15746,15802,15724,15724,15637,15641,36384,36157,36368,25212,24896,25066,34718,34628,34481,34925,34811,35078,34876,34952,35019,34738,34848,34654,37121,36988,36998,17135,16989,17148,15119,14598,14616,12911,13466,12994,15966,16093,15990,36479,36384,36368,36321,36151,36176,36321,36176,36235,36321,36396,36334,7028,7036,7120,6639,6976,6698,18418,18296,18322,18296,18186,18322,20480,20606,20728,20933,21017,21005,23490,23570,23297,20573,20606,20480,20342,20231,20215,23110,23107,23193,22605,22500,22520,23193,23463,23136,31063,31186,31257,30425,30318,30211,31882,31759,31652,29908,29774,29768,5559,5591,5718,5441,5567,5537,5441,5496,5567,5673,5926,5829,5652,5607,5788,5840,5920,5952,5558,5705,5464,20606,20885,20776,23297,23570,23588,24083,24135,23953,23668,23570,23681,10081,10115,10222,14544,14570,14788,14144,14106,14032,18169,17945,18454,17241,17135,17148,27392,27458,27436,27524,27737,27721,28317,28788,28715,27251,27149,27151,35638,35634,35602,11875,11680,11920,9748,9774,9906,11849,11680,11875,11923,12111,12153,11923,12153,11945,20485,20342,20067,29738,29712,29592,34270,34336,34120,34597,34738,34654,33935,33872,33826,10505,10627,10869,10570,10627,10505,12412,12358,12715,20885,21017,20933,36194,35619,35662,5537,5488,5468,5991,5924,5956,5934,5991,6143,16162,16362,16243,25214,25212,25066,25224,25276,25429,37017,37064,36940,5507,5417,5471,5213,5320,5482,5320,5357,5462,5462,5357,5446,5446,5357,5527,5477,5417,5507,5418,5417,5477,5418,5477,5358,5533,5478,5358,29908,30202,29774,37026,37258,37091,37673,37160,37015,37015,37160,37047,37047,37160,37071,37071,37160,37119,37119,37180,37049,37049,37180,37017,37017,37177,37064,37172,37129,36911,37172,36911,37066,37172,37066,37463,37066,37007,37391,37007,37086,37171,37086,37054,37171,37054,37094,37171,37094,37245,37171,6607,6554,6663,6516,6554,6607,14272,14388,14353,35712,35763,35608,36285,36106,36009,37094,37090,37245,20485,20480,20342,18322,18186,18195,22605,22520,22683,23682,23615,23808,16766,17074,16723,18195,18186,18124,23911,23953,23790,24738,25022,24792,35069,34952,34876,35137,34952,35181,36778,36667,36896,36576,36389,36384,5358,5478,5388,5675,5589,5488,26539,26683,26556,26511,26683,26539,37293,37090,37029,37010,36801,37296,5478,5369,5388,5590,5642,5759,5548,5642,5590,23808,23903,24012,23570,23668,23588,23281,23147,23210,30655,30514,30490,29950,29808,29704,30674,30514,30655,33778,33406,33390,7762,7896,7979,7762,7766,7823,7823,7766,7819,8719,8671,8846,10627,10692,10845,11455,11779,11216,10487,10692,10627,16500,16634,16516,24724,25022,24738,34427,33721,34017,34368,34017,34341,36628,36574,36443,5478,5486,5369,5320,5462,5482,5548,5581,5642,8755,8719,8948,10115,10298,10222,33192,33332,33119,32877,32695,32715,6112,6597,6339,6112,6339,6308,15802,15966,15990,16093,16162,16243,16362,16500,16516,15436,15485,15539,36252,36235,36106,36252,36106,36285,32218,32314,32065,32278,32323,32218,32397,32358,32278,32453,32397,32455,32692,32634,32732,15846,15966,15802,36384,36389,36157,36304,36194,35662,36476,36368,36459,5369,5486,5324,5488,5589,5429,8087,8124,8120,9615,9651,9703,10028,10115,10081,10028,10165,10115,10115,10165,10298,9475,9651,9615,9475,9615,9363,10921,11216,10900,12366,12397,12550,18384,18276,18454,18670,18703,18773,20342,20215,20067,17737,17779,17717,22605,22683,22748,22748,22899,22921,23463,23193,23465,30071,29808,29950,30077,30264,30202,29651,29738,29592,32749,32715,32565,31984,31923,31866,31984,31866,31882,34336,34356,34120,34513,34356,34336,36356,36194,36304,35611,35529,35726,37388,36744,37091,32732,32634,32739,7802,7946,8028,9031,9475,9363,7083,7566,7247,11779,12089,12188,13080,13115,13005,29603,29508,29607,34791,34628,34718,36586,36476,36459,5612,5496,5426,25226,25212,25224,27758,26954,27592,9906,9774,9850,9850,9774,9789,9789,9565,9513,8872,8976,9050,9050,8976,9047,10119,10559,10157,31759,31389,31652,33971,32732,32739,5642,5581,5652,5607,5581,5502,17717,17779,17550,24012,23986,24044,23682,23463,23465,24663,24357,24488,24663,24773,24694,28167,27758,28090,28178,28090,28201,27651,27737,27524,29651,29893,29738,27651,27524,27458,35600,35553,35484,34800,34706,34628,35528,35633,35742,10692,10786,10845,10704,10786,10692,26213,26333,25807,26683,26722,26770,13439,13377,13270,14184,14272,14353,8183,8120,8291,25022,25114,24792,24631,24724,24738,24851,24724,24631,30514,30419,30243,30536,30419,30514,31652,31389,31518,30264,30425,30211,30264,30211,30202,36667,36644,36443,36584,36479,36476,36778,36644,36667,18802,18852,19071,22899,22995,22921,37181,37029,37084,36900,36452,36727,5426,5496,5402,14032,14106,13831,14388,14461,14544,30660,31467,31389,32703,32464,32339,35675,35708,35814,35809,35906,35862,35634,35712,35608,35689,35638,35602,35689,35113,35410,17207,17347,17253,17207,17253,17089,37024,36900,36727,36706,36760,36660,36914,36760,36934,36868,36914,36957,18276,18169,18454,18230,18169,18276,18125,18195,18124,18636,19551,18736,23668,23911,23790,22314,22244,22740,36836,36727,36740,7080,7123,7342,7305,7406,7643,12446,12412,12715,11923,11849,11875,25045,25114,25022,37181,37084,37153,6554,6468,6511,7080,7342,7109,14144,14272,14184,35726,35742,35814,35638,35712,35634,26954,26761,26652,26694,26761,26713,26697,26722,26683,5465,5589,5578,5402,5496,5413,7232,7342,7299,18852,18777,18773,29107,28798,29060,34952,35137,35019,35069,34876,34848,5581,5607,5652,5705,5599,5464,8904,8976,8872,8567,8478,8671,8391,8206,8402,15746,15846,15802,15947,16162,16093,17228,17207,17188,15436,15273,15485,17860,18125,18124,17566,17717,17550,21816,21925,21762,23783,23911,23668,30660,31319,31467,32877,32988,32929,34088,34182,33935,34224,34145,34063,34532,34738,34597,34182,33872,33935,36496,36410,36389,36389,36410,36304,35726,35529,35742,36479,36368,36476,36868,36836,36740,37242,37180,37119,37064,37773,36595,10786,10921,10900,10704,10921,10786,31257,31513,31548,6516,6468,6554,14415,14461,14388,27031,27040,26965,5432,5615,5440,18474,18418,18356,17860,18045,17737,5944,5934,6143,5618,5673,5829,5591,5546,5578,5813,5934,5843,5744,5939,5826,5954,6466,6465,6088,6112,6308,15947,16093,15966,26464,26511,26539,26045,26213,25807,36760,36706,36934,36100,36009,35862,36586,36459,36574,30419,30333,30141,29498,29360,29508,30536,30333,30419,30773,30728,30538,30077,30202,29908,33778,33390,33692,5698,5807,5787,8640,8671,8719,10366,10333,10298,10366,10505,10468,29508,29360,29255,29603,29607,29808,34532,34597,34356,7088,7232,7299,32988,33104,32929,5845,5956,5924,5491,5698,5787,17489,17257,17241,17440,17257,17489,17428,17566,17550,16766,16723,16634,18777,18670,18773,17334,17135,17257,22921,23110,22913,22921,22995,23110,5828,5845,5924,16302,16500,16362,25224,25212,25214,26498,26358,26559,26694,26498,26559,26694,26559,26761,26722,27031,26965,26339,26511,26464,6355,6639,6698,6383,6409,6052,27020,27031,26722,35809,35862,35763,10157,10559,10289,10559,10805,10289,10028,10081,9925,30773,30538,30425,17717,17860,17737,17428,17550,17347,5559,5546,5591,5511,5621,5698,5558,5524,5705,5399,5524,5558,13377,13592,13584,14144,14234,14272,14272,14415,14388,13439,13592,13377,23607,23463,23682,23367,23463,23607,23281,23490,23297,23210,23490,23281,12316,11945,12153,12765,12715,12968,12911,12930,12703,29260,29107,29060,35302,34811,35132,34507,34376,34341,28321,28201,28275,26713,26761,26954,28321,28275,28456,28066,28229,27721,29738,29893,29908,28066,27721,27737,27651,27458,27553,35553,35394,35132,35473,35394,35699,35692,35600,35611,8478,8380,8391,8442,8380,8478,22913,23110,23066,5496,5441,5413,5441,5392,5413,5135,5432,5440,28788,28679,28715,34568,34281,34628,37180,37198,37017,37153,37084,37121,37153,37121,37214,13947,14032,13794,27553,27392,27578,35709,35692,35611,36153,35987,35814,35712,35809,35763,35638,35882,35712,35800,35689,35410,12316,12153,12412,29690,29603,29922,29360,29260,29255,33104,33320,33192,34706,34568,34628,8087,7873,7979,7766,7530,7832,7024,7109,7032,7892,7873,8087,15691,15846,15746,16501,16708,16500,15691,15746,15641,34513,34532,34356,34182,34224,34063,34206,34224,34182,15485,15273,15077,14570,14544,14461,17257,17135,17241,17489,17740,17504,26213,26339,26333,25967,25807,25621,5744,5789,5939,5660,5789,5744,5660,5826,5621,6397,6526,6511,16708,16634,16500,16708,16766,16634,17591,17717,17566,36644,36628,36443,36784,36628,36644,35708,36153,35814,5441,5468,5392,22353,22500,22458,22353,22520,22500,22353,22242,22520,18802,18777,18852,18802,18670,18777,18678,18591,18670,22500,22461,22458,37198,37177,37017,37165,37010,37296,37165,37121,37010,32358,32323,32278,32597,32453,32455,32323,32453,32509,32455,32692,32597,18670,18523,18703,18591,18523,18670,32453,32323,32358,26251,26339,26213,26511,26697,26683,12439,12316,12412,20606,20888,20885,20885,20888,21017,21017,21313,21762,20485,20573,20480,18418,18322,18356,23911,24083,23953,24724,25045,25022,25493,25621,25460,23904,24083,23911,32323,32314,32218,36760,36868,36632,36836,37024,36727,36334,36413,36321,18356,18322,18195,20673,20888,20606,33506,33119,33332,34071,34088,33935,37129,37258,37026,37160,37242,37119,37180,37279,37198,37198,37313,37177,37463,37258,37129,37463,37129,37172,37391,37007,37171,37245,37090,37293,8699,8640,8719,33320,33368,33332,14234,14415,14272,32877,32932,32988,32988,33176,33104,33104,33215,33320,33320,33387,33368,32719,32703,32339,32321,32339,32226,32247,32226,32206,32226,31984,32206,31832,31882,31652,36341,36118,36194,35882,35809,35712,36313,36235,36252,5845,5618,5829,5813,5828,5924,5813,5924,5934,6025,6100,6112,5789,5840,6014,5889,6120,6040,24694,24773,24896,25312,25226,25224,36825,36586,36574,36496,36392,36410,36410,36392,36304,7080,6909,7123,6261,6397,6468,6468,6397,6511,7232,7109,7342,7109,7232,7088,28827,28793,28891,29005,28793,28798,28583,28788,28317,5392,5468,5403,22500,22605,22461,32703,32749,32565,5417,5307,5471,5357,5263,5440,5309,5307,5417,5309,5417,5418,5309,5418,5245,5309,5245,5271,5358,5388,5319,5388,5369,5319,5369,5269,5319,25429,25276,25466,26713,26927,26885,26766,26697,26511,27031,27151,27149,18523,18384,18454,18499,18384,18523,22740,22244,22459,23490,23681,23570,23210,23028,23064,34738,34769,34848,34513,34336,34280,34455,34280,34224,5486,5346,5324,5273,5560,5471,6088,6025,6112,6480,6468,6516,6409,6383,6572,6747,7083,7247,5889,6040,5727,8640,8567,8671,8369,8206,8391,10281,10366,10298,10570,10487,10627,14415,14570,14461,24694,24857,24785,27020,27151,27031,30333,30071,29950,29498,29260,29360,30566,30071,30333,30536,30514,30582,29893,30077,29908,30264,30431,30425,29977,30077,29893,32274,31513,31951,33368,33506,33332,33498,33506,33368,35807,37037,36907,36629,36584,36813,5605,5426,5346,5403,5468,5366,5366,5468,5488,5506,5559,5718,5465,5559,5422,5524,5548,5590,5399,5548,5524,18213,18356,18195,17591,17860,17717,17428,17347,17228,22605,22748,22692,22461,22605,22692,23530,23681,23490,32899,32932,32877,17228,17347,17207,16138,16362,16162,24851,25045,24724,25096,25045,25170,8369,8391,8380,34088,34144,34182,33778,33874,33459,33892,33874,33778,15846,15865,15966,15688,15691,15641,15688,15641,15585,18055,17740,18169,16824,17089,16766,36496,36389,36576,36396,36321,36235,36313,36252,36285,30226,30431,30264,34133,34144,34088,6088,6308,5910,15077,15273,15060,26766,26707,26697,26045,26100,26213,26160,26100,26045,36100,35862,35906,31617,31832,31652,31617,31652,31518,32932,33045,32988,18213,18195,18125,23028,23210,23147,22244,22108,22459,27651,27793,27737,28922,28913,28788,27792,27793,27651,28178,28167,28090,28456,28414,28710,5426,5303,5346,5366,5488,5429,10366,10410,10505,11136,11455,11216,11888,12037,12089,22692,22748,22913,22748,22921,22913,33506,33549,33390,33712,33549,33506,37296,36801,36900,37293,37029,37181,14570,14782,14788,5828,5777,5845,5843,5934,5944,24857,24896,25084,25276,25655,25466,8976,8904,8948,8640,8596,8567,8872,9050,9088,9748,9789,9774,29005,29260,29351,28698,28456,28710,33045,33176,32988,27627,27553,27578,28827,28710,28793,5402,5303,5426,23681,23783,23668,23723,23783,23681,8206,8183,8291,7873,7762,7979,8168,8183,8206,8442,8478,8393,25269,25212,25226,23607,23682,23808,30431,30773,30425,36778,36784,36644,36503,36356,36392,36896,36784,36778,7828,7762,7873,5402,5283,5303,5429,5589,5169,7688,7530,7766,10366,10281,10410,10165,10188,10298,10073,10028,9925,12061,11849,11945,11945,11849,11923,13466,14039,12994,12446,12439,12412,12316,12061,11945,17440,17334,17257,15366,15318,16052,16052,15318,15739,17387,17334,17440,30077,30226,30264,30431,30854,30773,29253,29396,28917,31467,31617,31518,33176,33215,33104,35809,35928,35906,35957,35882,35638,35928,35882,35957,35585,35294,35137,25045,25096,25114,24851,24631,24371,5361,5464,5329,5464,5599,5329,8393,8478,8567,10410,10487,10570,10338,10487,10410,18384,18230,18276,18375,18230,18384,18235,18213,18125,20610,20656,20485,18354,18213,18235,33549,33692,33390,34271,34206,34144,33699,33692,33549,7943,7892,8087,34144,34206,34182,34133,34088,34137,14782,14891,15060,26499,26358,26498,26692,26713,26885,26697,26707,26722,27627,27792,27553,26297,26511,26339,36102,36100,35906,37358,37242,37160,35807,36185,37037,34864,34769,34738,34884,34769,34966,15691,15865,15846,15582,15688,15585,15582,15585,15485,25493,25460,25114,26100,26251,26213,36392,36356,36304,36384,36479,36576,8904,8755,8948,9742,9748,9906,11349,11149,11680,15717,15865,15691,31745,31467,31540,33215,33313,33320,36584,36476,36586,12911,12765,12968,28788,28913,28679,28583,28317,28229,23367,23136,23463,5413,5283,5402,5944,6143,6100,5910,6308,5885,26160,26251,26100,37293,37181,37337,5944,6100,6025,5813,5777,5828,8183,8066,8120,7943,8066,7937,15947,16138,16162,16708,16824,16766,25312,25269,25226,26499,26498,26694,36793,36574,36628,8334,8369,8442,8442,8369,8380,24142,24357,24044,5621,5807,5698,5789,5644,5840,5840,5685,5920,5787,5607,5491,16605,16824,16708,17428,17591,17566,25377,25493,25114,24371,24631,24083,8755,8699,8719,10130,10188,10165,17188,17207,17089,33313,33387,33320,5413,5392,5283,22242,21984,21818,22160,21984,22242,22160,22242,22305,22242,22353,22305,22353,22308,22305,37400,37181,37153,5465,5578,5546,5283,5392,5215,9925,10081,9841,10028,10073,10165,7946,8264,8028,15478,15582,15485,14782,14792,14891,14570,14701,14782,14542,14701,14570,14542,14570,14415,14542,14415,14299,22950,22740,22993,23210,23530,23490,7024,7080,7109,7762,7688,7766,7630,7688,7762,7828,7873,7892,26692,26499,26694,26692,26694,26713,34568,34507,34341,34376,34368,34341,32597,32692,32732,34613,34507,34568,34628,34791,34800,32314,32279,32065,32323,32351,32314,32509,32351,32323,32860,32681,32563,7825,7828,7892,13794,14032,13831,13080,13005,12874,12037,12366,12089,16302,16501,16500,28321,28167,28178,28331,28167,28321,28331,28321,28388,32351,32279,32314,32206,31984,32138,32703,32899,32749,32749,32899,32877,33001,33143,33045,33045,33143,33176,33176,33219,33215,33215,33309,33313,33313,33418,33387,31984,31882,32138,31882,32133,32138,35302,35078,34811,35699,35394,35553,35770,35553,35692,35709,35611,35726,35709,35726,35869,6574,6639,6355,34800,34791,34925,32279,32231,32065,31882,31832,31920,7024,6909,7080,6397,5930,6333,7299,7111,7088,37358,37279,37180,17372,17591,17428,24044,24357,24249,24357,24663,24563,35987,35726,35814,36868,36957,36836,37165,37214,37121,36914,36868,36760,8699,8596,8640,10130,10281,10188,10188,10281,10298,33387,33498,33368,33809,33892,33778,33457,33498,33387,5559,5465,5546,5506,5718,5673,9742,9906,9731,8904,8837,8755,8755,8686,8699,8699,8544,8596,31920,31832,31617,32967,32899,32703,10487,10704,10692,10473,10704,10487,33809,33778,33692,30674,30655,30670,29498,29508,29603,30674,30670,30794,34006,33935,33874,34864,34738,34532,20107,19928,20669,17544,17504,17740,23066,23110,23136,22353,22458,22308,22751,22913,23066,6480,6699,6351,5392,5403,5215,22458,22465,22308,34769,34884,34848,34455,34224,34337,36232,36102,35906,36472,36396,36313,36313,36396,36235,15478,15485,15077,15717,15947,15865,15865,15947,15966,16138,16302,16362,36650,36078,36413,36285,36009,36283,5502,5581,5548,17228,17372,17428,17068,17188,17089,17068,17089,16993,36629,36576,36584,37313,37064,37177,25328,25269,25312,26499,25466,25655,25377,25114,25096,26188,26297,26251,36584,36576,36479,36496,36503,36392,35784,35969,36330,36793,36628,36784,36961,36793,36784,7299,7406,7111,29005,28798,29107,29005,29107,29260,16373,16989,16562,26251,26297,26339,27392,27251,27578,26160,26045,25967,36283,36009,36100,36549,36194,36356,35957,35638,35689,35882,35928,35809,5303,5141,5253,5215,5403,5366,22458,22461,22465,37279,37313,37198,18591,18499,18523,18599,18499,18591,22740,22934,23028,23783,23904,23911,22950,22934,22740,11673,11468,11680,11673,11680,11849,11436,11455,11130,18114,18169,18230,17334,17321,17135,23643,23607,23808,23161,23530,23210,24012,23960,23808,24563,24663,24694,34485,34376,34507,34485,34368,34376,34337,34224,34206,37025,37024,36836,5307,5273,5471,5320,5231,5357,5163,5273,5307,5271,5307,5309,5418,5358,5245,5358,5319,5245,5319,5195,5245,5324,5269,5369,20573,20656,20606,20888,21041,21017,20485,20656,20573,18354,18474,18356,20656,20673,20606,25328,25312,25429,34133,34271,34144,33892,34006,33874,33973,34006,33892,8774,8872,8731,33001,33045,32932,33712,33699,33549,37258,37388,37091,37242,37358,37180,37279,37349,37313,37578,37388,37258,37391,37171,37245,21161,20464,20851,21836,21818,21984,22005,21984,22096,7111,7406,7172,12765,12578,12446,12703,12578,12765,12703,12765,12911,29498,29603,29690,35302,35132,35394,34613,34485,34507,34884,35069,34848,35181,35069,35172,7588,7946,7802,6960,7946,7588,11794,12089,11779,20891,21041,20888,26713,26954,26927,25468,25425,25466,29351,29498,29690,34246,34271,34133,22305,22239,22160,22465,22461,22627,22461,22692,22627,37407,37214,37165,37380,37391,37245,13947,14144,14032,14701,14656,14782,5273,5213,5482,8523,8567,8596,8523,8393,8567,8369,8168,8206,7571,7630,7828,33712,33506,33498,8872,8837,8904,33143,33219,33176,5213,5207,5320,17219,17372,17228,16993,17089,16824,16993,16824,16815,22934,23064,23028,22950,23064,22934,24785,24563,24694,5324,5268,5269,5622,5644,5660,5660,5644,5789,6355,6698,6512,5768,5944,6025,5843,5777,5813,5843,5944,5722,23530,23723,23681,25170,25377,25096,23688,23723,23530,35562,35302,35394,35770,35699,35553,35770,35692,35709,28167,27957,27758,28388,28321,28456,28698,28710,28827,10281,10338,10410,9925,9841,9612,15556,15691,15688,15077,15060,14891,15556,15688,15582,17504,17387,17440,17396,17387,17504,18235,18125,18001,17219,17228,17188,27020,26722,26707,26188,26160,25967,31467,31573,31617,31745,31573,31467,33219,33309,33215,36957,37025,36836,36557,36413,36334,5207,5231,5320,12578,12439,12446,13794,13831,13592,13794,13592,13768,27793,28066,27737,27553,27792,27651,26766,26511,26519,28913,29253,28917,29651,29977,29893,31745,31888,31573,29133,29253,28913,30536,30566,30333,30794,30670,31257,34006,34071,33935,34058,34071,34006,35885,35770,35709,12940,13080,12874,8393,8334,8442,8250,8334,8281,33699,33809,33692,33822,33809,33699,5324,5346,5268,5231,5263,5357,7828,7630,7762,7688,7487,7530,7825,7892,7943,30118,29977,30005,32509,32597,32563,34613,34568,34717,34598,34513,34455,34455,34513,34280,34337,34206,34271,35885,35869,35947,35987,35869,35726,5753,5777,5843,16145,16302,16138,24857,24694,24896,25425,25328,25429,25269,25328,25425,18213,18354,18356,18125,17860,18001,7943,8087,8066,22627,22692,22751,22308,22239,22305,34246,34337,34271,8680,8686,8755,10073,10130,10165,11136,11216,10921,33309,33418,33313,28780,28698,28827,28891,28793,29005,35266,35302,35393,34717,34568,34706,5404,5506,5204,5465,5169,5589,16605,16708,16501,17068,17067,17188,24896,25212,25084,24115,23960,24044,24044,23960,24012,12226,12178,12316,12037,12125,12366,12190,12125,12100,30847,30582,30674,32279,32237,32231,32351,32372,32279,34427,34017,34368,30674,30582,30514,32274,31951,32231,34071,34137,34088,34252,34137,34071,37037,36185,36595,36961,36825,36793,36541,36496,36576,7088,7032,7109,6765,6694,6909,6348,6365,6480,7069,7032,7088,16405,16605,16501,22375,22239,22308,22751,22692,22913,23136,23172,23066,26871,26766,26601,28780,28891,28924,28924,28891,28985,32465,32372,32351,32247,32321,32226,32899,33001,32932,33143,33297,33219,33412,33457,33309,33309,33457,33418,32256,32321,32247,32256,32247,32206,32256,32206,32201,35069,35181,34952,35255,35181,35347,8686,8544,8699,19551,18636,19327,5464,5399,5558,5621,5622,5660,5329,5599,5205,17465,17860,17591,19327,18636,18474,17465,17591,17372,32372,32237,32279,32325,32256,32201,9748,9634,9789,8872,8774,8837,8837,8680,8755,8686,8501,8544,9742,9634,9748,9906,10119,9731,36541,36503,36496,36541,36576,36629,36584,36586,36813,36570,36557,36334,36472,36334,36396,36472,36313,36589,36313,36285,36589,5268,5346,5253,5346,5303,5253,37380,37245,37293,37380,37293,37337,11468,11349,11680,11703,11673,11849,34800,34925,35204,34485,34634,34368,34513,34611,34532,34598,34611,34513,34598,34455,34737,9634,9742,9640,11509,11349,11468,19343,18802,19071,18375,18114,18230,37215,37296,36900,37215,36900,37024,5399,5502,5548,7305,7643,7530,23723,23904,23783,26188,26251,26160,23771,23904,23723,37038,37025,36957,37038,36957,36914,5677,5753,5843,5693,5618,5845,8544,8523,8596,7937,8066,7985,8501,8523,8544,16302,16405,16501,15947,16145,16138,15882,16145,15947,36557,36650,36413,5303,5283,5141,19784,19854,19948,35214,34925,35078,38103,37358,37160,37773,37037,36595,37337,37181,37400,33087,33001,32899,34137,34246,34133,34013,33973,33892,34058,33973,34013,33457,33387,33418,27809,28066,27793,27809,27793,27792,5539,5622,5621,5644,5683,5840,14542,14656,14701,15478,15556,15582,14532,14656,14542,16993,16937,17068,16605,16815,16824,16937,16815,16852,18375,18384,18499,24115,24044,24249,25084,25212,25269,26871,27020,26707,35255,35585,35137,35928,36030,35906,14002,14234,14144,13768,13592,13672,13270,13377,13080,27791,27809,27792,7630,7487,7688,7571,7487,7630,8250,8369,8334,34252,34246,34137,13232,13270,13080,28331,28349,28167,28601,28388,28456,28713,28456,28698,5215,5366,5429,31888,31920,31617,32133,32157,32191,37400,37153,37214,18802,18678,18670,18599,18284,18287,22375,22308,22465,23136,23367,23172,27304,27251,27151,35869,35885,35709,35770,35743,35699,35699,35792,35473,35947,35869,36003,5614,5683,5644,12178,12061,12316,12439,12226,12316,12534,12226,12439,12534,12439,12578,8731,8872,8759,9612,9841,9651,10073,10000,10130,11136,10943,11071,17387,17321,17334,18055,17544,17740,24357,24563,24249,36813,36586,36820,37318,37064,37313,37057,37038,36914,37486,37215,37024,6480,6365,6468,5677,5693,5753,6699,7123,6351,7123,6909,6694,13960,14144,13947,35983,35957,35689,37358,37349,37279,5361,5399,5464,5502,5491,5607,5344,5399,5361,18114,18055,18169,18147,18055,18114,27207,27304,27151,26766,26871,26707,26452,26511,26297,26452,26297,26361,28891,28780,28827,28713,28780,28733,29603,29808,29922,30847,30950,30934,35181,35255,35137,35172,35069,35155,11455,11436,11779,12125,12397,12366,11136,11071,11130,15468,15556,15478,29977,30118,30077,30005,29977,29651,30005,29651,29959,36283,36100,36102,36768,36789,36650,11524,11794,11779,18678,18599,18591,18496,18599,18287,34800,34717,34706,34613,34634,34485,34790,34717,34800,27130,27151,27020,36021,36030,35928,10338,10281,10247,12120,12061,12178,11673,11510,11468,35155,35069,35063,8650,8680,8837,8281,8334,8393,22375,22465,22356,37349,37318,37313,37407,37165,37450,37407,37400,37214,5683,5647,5840,5568,5647,5683,5614,5644,5622,23495,23367,23607,22239,22375,22241,24588,24563,24785,5506,5422,5559,5404,5422,5506,18599,18496,18499,18335,18496,18287,23064,23161,23210,22459,22108,22247,14888,15077,14891,14792,14782,14656,36232,36283,36102,5273,5163,5213,5213,5191,5207,5207,5149,5231,5231,5188,5263,5263,5135,5440,5094,5163,5307,5170,5307,5271,5170,5271,5245,5170,5245,5195,5319,5140,5195,14299,14532,14542,20673,20835,20888,21313,21816,21762,20656,20610,20673,20571,20610,20433,19784,20020,19700,27015,27130,27020,36341,35969,36118,8281,8393,8368,6747,7247,7036,12190,12397,12125,22239,22216,22134,37450,37165,37418,6639,6574,7079,6355,6512,6276,13794,13960,13947,14234,14299,14415,13448,13592,13439,13448,13439,13298,28625,28583,28229,27809,27963,28066,27814,27963,27809,27791,27792,27627,27791,27627,27578,35820,35743,35770,35302,35266,35078,35820,35770,35885,28388,28349,28331,28353,28349,28388,33412,33309,33219,34715,34337,34699,5163,5191,5213,11703,11510,11673,9640,9742,9731,11794,11888,12089,11436,11524,11779,11582,11524,11347,32133,31920,32157,29702,29651,29624,34717,34634,34613,34790,34634,34717,34611,34671,34532,34737,34455,34742,34252,34071,34058,37886,37463,37391,37391,37463,37066,37388,37578,37015,37358,38307,37349,37899,37773,38036,37541,37391,37380,37541,37380,37337,37541,37337,37607,24768,24588,24785,24768,24785,24857,24768,24857,24829,36842,36706,36113,37401,37024,37025,36789,36078,36650,13792,13960,13794,27578,27251,27304,32237,32274,32231,32372,32390,32237,32597,32509,32453,32563,32681,32649,5191,5149,5207,18496,18375,18499,17541,17396,17544,18335,18375,18496,20464,20107,20669,20057,20107,20464,21836,21984,22005,23643,23808,23774,22950,23078,23064,22993,23078,22950,32509,32465,32351,5693,5845,5777,5693,5777,5753,11729,11888,11794,29624,29396,29253,5727,6040,5920,15384,15468,15478,15556,15570,15691,16852,16815,16763,32465,32390,32372,32321,32558,32339,33579,33730,33457,32256,32325,32321,32201,32206,32138,5685,5727,5920,23774,23808,23960,23774,23960,23782,23161,23688,23530,24039,24308,24083,36541,36532,36503,36549,36341,36194,36574,36793,36825,5319,5269,5140,5269,5129,5140,15077,15002,15478,14567,14792,14656,14567,14656,14532,36030,36232,35906,5412,5491,5146,5647,5685,5840,6365,6261,6468,6909,7024,6765,9634,9565,9789,8774,8650,8837,9640,9565,9634,10119,9800,9731,17544,17396,17504,17321,17396,17383,27439,27578,27304,37170,37057,36914,28780,28713,28698,29351,29260,29498,5149,5188,5231,8250,8168,8369,7943,7723,7825,8104,8168,8250,9731,9800,9689,26188,25967,26272,27195,27207,27130,27130,27207,27151,32133,32201,32138,32133,31882,31920,36549,36356,36503,36283,36374,36285,36768,36650,36758,36445,36374,36441,7985,8066,8183,34058,34006,33973,12012,12125,12037,13232,13439,13270,30566,30536,30582,5677,5843,5722,36784,36896,37082,36570,36334,36472,6331,6261,6365,14141,14299,14234,35957,36021,35928,36429,36339,36232,36090,36021,35957,35800,35410,35585,35373,35585,35255,5399,5288,5502,5135,5599,5432,10289,10805,10286,22005,22096,22025,23495,23172,23367,23078,23161,23064,22993,23161,23078,30226,30077,30118,5088,5215,5104,12930,12911,12994,12120,11985,12061,11985,11703,11849,28985,28891,29005,35562,35394,35473,5269,5268,5129,5126,5169,5465,5204,5506,5673,5412,5539,5621,16815,16937,16993,16815,16605,16763,23685,23774,23782,23643,23495,23607,23688,23771,23723,23894,23771,23688,24459,24249,24563,25084,25269,25177,33730,33712,33498,33730,33498,33457,14792,14888,14891,15002,14888,14881,7571,7828,7673,7111,7069,7088,11510,11509,11468,11518,11703,11442,11524,11621,11794,11888,12012,12037,11582,11621,11524,19665,19784,19700,18317,18474,18354,19948,19968,20067,34598,34671,34611,34737,34671,34598,5470,5614,5622,25425,25429,25466,25466,25757,25468,37082,36896,36907,36789,36842,36078,37170,37182,37057,5491,5511,5698,5412,5511,5491,17396,17321,17387,17541,17544,17501,24459,24563,24588,24021,24083,23904,27015,27020,26871,36153,36135,35987,36209,36135,36153,34993,34864,34671,34013,33892,33809,7172,7069,7111,35266,35214,35078,35347,35373,35255,35063,35069,34884,5129,5268,5173,7319,7305,7530,12000,12012,11729,13232,13080,12940,29959,30107,30005,29701,29624,29253,34671,34864,34532,36696,36532,36541,36003,35987,36212,36696,36541,36803,36541,36629,36803,36589,36570,36472,36789,36854,36842,26903,27015,26871,25718,25967,25493,10247,10281,10142,11136,11130,11455,33712,33822,33699,33730,33822,33712,5173,5268,5253,9925,9903,10073,9862,9903,9925,9612,9651,9522,13232,13090,13298,13768,13792,13794,13960,14002,14144,13448,13672,13592,21984,22160,22096,22160,22239,22096,21313,21017,21041,5487,5645,5889,5568,5685,5647,26696,26499,26692,25170,25045,24851,36758,36650,36557,6833,7024,7032,6348,6331,6365,12305,12397,12190,13604,13792,13768,14881,14888,14714,28138,28229,28066,27791,27814,27809,27888,27814,27791,27888,27791,27914,26927,26954,27042,28601,28353,28388,28601,28456,28713,35933,35820,35885,35743,35889,35699,35266,35393,35214,26519,26511,26452,27207,27276,27304,26501,26519,26452,34966,35063,34884,5073,5173,5253,16763,16605,16405,17067,17219,17188,6694,6351,7123,5885,6308,6333,6276,6512,6383,6574,6747,7036,13792,14002,13960,28733,28780,28924,28748,28601,28713,28138,28066,27963,36003,35869,35987,5329,5344,5361,5248,5344,5329,7723,7828,7825,8168,7985,8183,8035,7985,8168,18375,18147,18114,18335,18147,18375,30794,30847,30674,31548,30794,31257,37182,37025,37038,37182,37038,37057,8680,8501,8686,8731,8650,8774,17067,17068,16937,24308,24371,24083,24297,24371,24308,7723,7943,7798,7487,7319,7530,11518,11509,11510,11518,11510,11703,30005,30107,30118,29959,29651,29702,8368,8393,8523,25004,24829,24857,24768,24459,24588,25425,25177,25269,24869,25170,24851,33822,33849,33809,34956,34864,34993,34406,33849,33822,36825,36820,36586,36961,36820,36825,37136,37088,36934,36954,36854,36937,34634,34664,34368,34932,34790,34951,22096,22239,22134,6256,6331,6348,28985,28733,28924,28985,29205,29069,35347,35172,35155,35347,35181,35172,7798,7943,7937,10628,10921,10704,12000,12100,12012,27500,27245,27042,23771,24021,23904,23894,24021,23771,24039,24021,24028,12012,12100,12125,11729,11794,11621,15468,15570,15556,15495,15570,15468,15002,15077,14888,22096,22134,22025,34864,34966,34769,35063,35153,35155,34956,34966,34864,34246,34699,34337,23685,23495,23643,22241,22216,22239,23685,23643,23774,23960,24115,24212,12703,12534,12578,12658,12534,12703,27195,27276,27207,27195,27130,27015,28985,29005,29205,5722,5944,5574,5693,5583,5618,5204,5342,5404,25425,25368,25177,26696,25466,26499,26519,26601,26766,26188,26361,26297,26501,26361,26273,26452,26361,26501,36954,36972,36854,36570,36758,36557,32325,32558,32321,32567,32558,32547,32420,32325,32201,32191,32201,32133,33849,34013,33809,34728,34013,34406,16852,17067,16937,16405,16302,16214,8650,8501,8680,24829,24459,24768,24249,24459,24349,5166,5141,5283,5166,5283,5215,5032,5135,5263,9689,9595,9640,9640,9595,9565,9088,9050,9439,8650,8603,8501,9689,9640,9731,9522,9651,9475,10383,10487,10338,32390,32274,32237,32409,32274,32390,32409,32390,32465,32563,32465,32509,9905,10119,10157,11985,11849,12061,11347,11524,11436,30107,30226,30118,29945,29959,29702,30082,29959,29945,5614,5568,5683,5645,5954,5889,5889,5954,6451,5457,5568,5614,5611,5568,5474,5622,5539,5470,5611,5727,5685,14340,14532,14299,16562,16989,17135,13787,14039,14616,16562,17135,17136,26718,26696,26692,26718,26692,26885,26501,26601,26519,35170,35153,35063,17976,17544,18055,17219,17465,17372,17243,17465,17219,24021,24039,24083,24371,24458,24851,23894,23688,23758,30252,30226,30107,37170,36914,36934,36934,36842,37120,5141,5166,5069,10805,10977,10286,18147,17976,18055,18006,17976,18147,28017,28138,27963,29701,29702,29624,27888,27963,27814,31888,31617,31573,22577,22993,22740,13232,13298,13439,13573,13604,13672,13672,13604,13768,14030,14141,14002,14002,14141,14234,12940,12874,12847,7432,7487,7378,7432,7319,7487,7305,7172,7406,7069,6921,7032,29922,29808,30071,35913,35840,35820,35820,35840,35743,34951,34790,34800,35933,35885,35947,35933,35947,36003,35754,35800,35585,36349,36283,36232,36441,36374,36283,36374,36445,36285,36905,36768,36758,35983,35800,35966,8501,8395,8523,8104,8035,8168,7985,7798,7937,8290,8395,8501,33297,33143,33001,20610,20679,20673,20754,20679,20610,35650,35562,35718,8104,8250,8281,7378,7487,7571,10473,10628,10704,11130,11179,11436,10281,10130,10142,20679,20835,20673,22247,22108,21925,35987,36135,36212,20835,20891,20888,7622,7798,7985,30706,30566,30582,30706,30582,30847,12120,12178,12226,13787,14616,14598,12847,12874,12397,12305,12190,12152,15570,15717,15691,15590,15717,15570,35562,35493,35302,36532,36549,36503,36803,36629,36832,16965,17067,16852,17219,17067,17126,37234,37082,37540,36832,36629,36813,37150,37082,37234,36972,36842,36854,5079,5094,5170,5170,5094,5307,5012,5095,5191,5191,5095,5149,5149,5108,5188,5188,5032,5263,5079,5170,5195,5079,5195,4772,5195,5140,4772,5140,5129,5080,5129,5173,5080,5043,5191,5163,6355,5895,6574,6052,6276,6383,14030,14002,13792,15384,15495,15468,36209,36153,36330,36653,36549,36532,7126,7172,7305,26954,27500,27042,26601,26903,26871,27914,27791,27578,37082,36961,36784,5344,5239,5399,5078,5205,5599,5613,5583,5693,5768,6025,6088,8395,8368,8523,8290,8368,8395,11302,11349,11509,9936,10073,9903,5404,5342,5422,5204,5077,5183,22241,22375,22356,24212,24115,24249,24349,24212,24249,24857,25084,25004,24039,24164,24308,24029,24164,24039,5080,5173,5073,5095,5108,5149,5885,6333,5930,36349,36232,36339,12930,12658,12703,35485,35393,35302,9088,9439,9480,9612,9862,9925,30660,30728,31319,33238,33297,33001,37407,37450,37400,37418,37165,37296,37418,37296,37468,14191,14340,14299,15309,15384,15478,5613,5693,5677,8035,7997,7985,8023,7997,8035,11422,11302,11509,11422,11509,11518,19784,19948,20020,18317,18354,18235,7084,7126,7305,7673,7828,7723,7673,7723,7678,5205,5248,5329,5185,5248,5205,5239,5248,5136,9862,9936,9903,18599,18434,18284,17553,17501,17544,18001,18317,18235,18001,17860,17769,33297,33412,33219,10943,10921,10628,10943,11136,10921,11729,12012,11888,10247,10383,10338,10263,10383,10247,6871,6921,7069,6174,6256,6126,6351,6256,6348,6871,7069,6895,12120,12226,12041,11729,11621,11698,14714,14888,14792,21931,21925,21816,23758,23688,23633,26995,26718,26885,25518,25368,25468,35180,35170,35063,35319,35347,35155,34455,34337,34742,36232,36030,36429,37468,37296,37215,14340,14447,14532,36330,35969,36397,24143,23782,23960,22465,22475,22356,17136,17135,17321,14598,15119,15318,17136,17321,17383,36854,36789,36937,36789,36935,36937,9936,10000,10073,21708,21836,21919,21708,21620,21836,21836,21620,21818,18176,18147,18335,21836,22005,21919,31319,30728,30773,37182,37401,37025,37088,37170,36934,37225,37170,37227,13573,13672,13448,14141,14191,14299,14340,14432,14447,13573,13448,13298,13090,13232,13008,35840,35889,35743,35541,35485,35493,35493,35485,35302,35904,35889,35840,35913,35820,35933,35913,35933,36173,36832,36813,36986,36696,36653,36532,36397,35969,36341,15495,15590,15570,17126,17067,16965,15309,15478,15002,36445,36589,36285,36662,36589,36445,12152,12190,12100,21919,22005,22025,35082,35063,34966,8368,8104,8281,7678,7723,7798,8290,8104,8368,10383,10473,10487,10351,10473,10383,14598,15318,15366,12930,12766,12658,35904,36134,36054,35800,35983,35689,35754,35585,35508,26927,26995,26885,27957,28167,28349,27957,28349,28475,28349,28353,28429,28353,28601,28429,35904,35840,35913,36481,36341,36549,10977,10805,11349,11442,11422,11518,13083,12994,14039,12011,12120,12041,30226,30348,30431,29959,30082,30107,29701,29253,29528,34790,34664,34634,34932,34664,34790,34742,34337,34715,34956,35082,34966,34808,34737,34906,34406,33822,33730,5521,5613,5677,5583,5517,5618,5517,5613,5481,5568,5611,5685,5412,5621,5511,25468,25368,25425,24212,24143,23960,25518,25468,25595,25518,25595,25457,33412,33579,33457,5930,6397,6261,6245,6256,6199,13744,14030,13792,12000,12152,12100,11698,11621,11582,36757,36481,36549,36349,36441,36283,36551,36441,36540,7475,7673,7552,7204,7305,7319,11071,11179,11130,11095,11179,11071,30252,30348,30226,24386,24458,24371,24028,23894,23758,32597,32860,32563,32274,31548,31513,32558,32719,32339,33297,33404,33412,33412,33458,33579,32547,32558,32325,32547,32325,32420,32201,32191,32420,32567,32719,32558,32420,32536,32538,12370,12847,12397,34951,34800,35204,35541,35493,35562,9480,9439,9565,8214,8290,8501,9501,9565,9595,9501,9595,9573,25004,25084,25177,32556,32409,32465,32547,32538,32591,5073,5253,5141,5073,5141,5069,23172,22895,23066,21634,21931,21816,37607,37400,37601,37607,37337,37400,37463,37578,37258,5248,5239,5344,5185,5205,5082,5288,5491,5502,9573,9595,9689,9031,9522,9475,9715,9794,9862,9862,9815,9936,9936,9918,10000,14025,14191,14141,14447,14567,14532,15507,15495,15384,17126,17243,17219,16302,16145,16214,24541,24349,24459,6921,6833,7032,7204,7319,7432,10000,10142,10130,10017,10142,10000,11442,11392,11422,11947,12120,12011,31955,31548,32274,35319,35155,35153,35267,35082,35264,10473,10494,10628,10418,10494,10473,36972,37120,36842,36789,36768,36935,10832,10943,10628,30321,29922,30071,30736,30706,30852,9528,9573,9689,36180,36030,36021,6765,6833,6871,35319,35153,35170,23172,23495,23598,37509,37468,37479,37418,37519,37450,32990,33087,32899,14291,14432,14340,15507,15590,15495,15309,15002,15019,36874,36653,36696,5239,5288,5399,23894,24028,24021,25718,25493,25377,24029,24028,24196,24029,24329,24297,7678,7622,7560,8603,8650,8731,10142,10227,10247,10195,10227,10124,5069,5166,5110,7475,7378,7571,7475,7571,7673,14810,15002,14881,23611,23495,23685,30321,30071,30566,29205,29005,29351,28429,28601,28620,33087,33238,33001,34737,34808,34671,34252,34699,34246,18176,18006,18147,19851,19589,20107,17769,17860,17465,19968,19948,19854,11076,11244,11179,11179,11244,11436,30362,30321,30566,30082,30252,30107,31335,31319,30773,30395,30252,30260,25230,25004,25177,26717,26696,26718,35330,35319,35170,35180,35063,35082,7183,7204,7432,6871,6833,6921,17383,17396,17541,17427,17484,17465,16965,16852,16893,24297,24308,24164,26705,26952,26601,26601,26952,26903,28922,28788,28583,9088,8759,8872,33238,33288,33297,34252,34058,34729,14030,14025,14141,14519,14567,14432,13604,13677,13792,13490,13573,13401,15366,16052,15871,16052,16373,15871,14432,14567,14447,14610,14567,14519,35889,35792,35699,35893,35792,35889,35904,36054,35893,35508,35373,35452,35508,35585,35373,35983,36090,35957,5910,5768,6088,6245,6261,6331,28601,28748,28620,28852,28922,28583,27439,27304,27276,36212,36135,36209,36017,35966,35800,29069,28733,28985,34925,35214,35204,35718,35562,35473,37109,37120,36972,36935,36768,36905,36758,37083,36905,37187,37083,36758,10106,9905,10157,10977,11349,11302,10629,10832,10628,11116,11347,11244,10227,10263,10247,10195,10263,10227,31335,30773,31290,32547,32420,32538,9794,9815,9862,17553,17544,17976,17427,17465,17243,24028,24029,24039,23161,22993,23062,33288,33404,33297,23661,23611,23685,23661,23685,23782,5110,5166,5215,12305,12277,12397,13490,13677,13573,12201,12152,12068,11798,12000,11729,35452,35373,35347,35267,35180,35082,35650,35541,35562,35452,35347,35476,6256,6245,6331,6199,6256,6174,36275,36090,35983,20835,20763,20891,20891,21313,21041,20679,20754,20835,20595,20754,20610,20067,20215,19948,20754,20763,20835,4787,5043,5163,5095,4930,5108,5108,5032,5188,5048,5163,5094,5048,5094,5079,5048,4772,4785,5140,5080,4989,8704,8603,8731,10106,10157,10289,9815,9918,9936,14610,14714,14792,14610,14792,14567,27042,26995,26927,26985,26995,27042,26903,26952,27015,26361,26188,26272,33404,33458,33412,36330,36292,36209,36481,36397,36341,36370,36397,36446,37673,37578,38010,37150,36961,37082,5669,5768,5910,7798,7622,7678,6999,7084,7204,8035,8104,8023,11422,11392,11302,11442,11703,11985,11244,11347,11436,11095,11071,10938,15454,15507,15384,15590,15571,15717,15571,15507,15454,34906,34742,34896,34808,34993,34671,28625,28229,28293,35476,35347,35319,11312,11698,11582,35768,35393,35485,32649,32556,32563,5088,5110,5215,5014,5080,5073,5043,5012,5191,5391,5470,5539,5918,6052,5571,5457,5470,5365,10263,10351,10383,10235,10351,10263,24829,24820,24459,24349,24143,24212,25297,25177,25368,37150,37101,36961,36961,37101,36820,36803,36861,36696,36907,37540,37082,37109,36972,36954,37170,37225,37182,36986,36813,37114,36653,36762,36549,5014,5073,4989,8023,8104,8290,10938,11071,10943,19784,19755,19854,9918,10017,10000,17501,17383,17541,15871,16373,16562,17553,17383,17501,17484,17769,17465,17310,17427,17243,17310,17243,17126,24541,24143,24349,37227,37170,37088,7183,7432,7378,7204,7084,7305,6256,6351,6126,12120,11947,11985,12455,12534,12658,29551,29351,29627,20723,20057,20464,21426,21062,21620,21426,21620,21548,21620,21678,21548,21708,21678,21620,20763,21313,20891,22577,22740,22459,5613,5517,5583,5104,5215,5429,5521,5677,5722,25457,25297,25368,25457,25368,25518,36937,37109,36954,36551,36445,36441,19784,19665,19755,10629,10628,10494,26823,26717,26718,26823,26718,26995,8214,8023,8290,32719,32967,32703,33087,33240,33238,33238,33240,33288,33288,33379,33404,33404,33379,33458,32567,32723,32719,32591,32723,32567,32591,32567,32547,32531,32536,32420,26952,27195,27015,32191,32531,32420,36370,36292,36330,36370,36330,36397,4983,5032,5108,4993,5098,5288,5391,5539,5289,5078,5599,5135,18284,18434,18301,17736,17553,17976,21708,21858,21678,21919,21858,21708,32409,32469,32274,32563,32556,32465,34828,34368,34664,32157,31888,31997,4989,5073,4907,5465,5422,5126,7737,9031,9363,9794,9918,9815,9794,9909,9918,9918,9909,10017,9082,9031,7624,9501,9480,9565,8711,8704,8759,8759,8704,8731,9528,9480,9501,9528,9501,9573,32556,32469,32409,32912,32967,32719,37098,36861,36832,37234,37540,37387,12152,12277,12305,12201,12277,12152,28017,28213,28138,28017,27963,27888,35792,35786,35473,35650,35670,35541,34828,34839,34930,35930,35786,35792,35893,35889,35904,13573,13677,13604,13573,13298,13401,20057,19851,20107,19700,19614,19665,21919,22040,21858,27914,28017,27888,29627,29351,29690,30321,30067,29922,30392,30067,30321,30362,30566,30736,34932,34839,34664,35632,35485,35541,36173,35933,36385,35786,35718,35473,5470,5457,5614,5954,6052,6409,5539,5412,5289,32469,32343,32274,30736,30566,30706,32967,32990,32899,7475,7268,7378,7678,7552,7673,7560,7552,7678,30706,30847,30934,30252,30395,30348,30160,30252,30082,29945,29702,29701,25718,25377,25589,24029,24297,24164,22577,22459,22336,37509,37519,37468,37386,37227,37088,37136,36934,37120,12994,12909,12930,13083,13060,12994,13083,14039,13302,28429,28475,28349,26985,26823,26995,28748,28713,28733,28293,28229,28138,30186,29945,30206,5768,5574,5944,19551,19327,19614,19700,19551,19614,21919,22025,22040,9905,9800,10119,10286,10106,10289,10139,10106,10286,31319,31540,31467,31485,31540,31319,14714,14810,14881,14291,14340,14191,22247,21925,21931,37468,37519,37418,37541,37886,37391,37468,37215,37479,5126,5422,5342,5185,5136,5248,5023,5136,5185,6245,6114,6261,5481,5521,5512,5512,5521,5574,6765,7024,6833,13941,14025,14030,18287,18176,18335,18284,18176,18287,28963,28748,28733,28963,28733,29069,33245,33240,33087,34252,34729,34699,10832,10938,10943,11312,11582,11347,11686,11729,11698,12201,12370,12277,10834,10938,10832,10629,10494,10418,18474,18317,19327,30847,30794,30950,24869,24851,24458,26952,27225,27195,36540,36441,36349,36540,36349,36529,37097,37109,36937,36662,36570,36589,29627,29690,29861,5204,5673,5077,5155,5204,5183,19327,19381,19516,22040,22025,22134,27195,27439,27276,27225,27439,27195,36292,36212,36209,36353,36212,36292,36090,36180,36021,36312,36180,36275,36180,36090,36275,35983,35966,36275,36017,35754,36147,5332,5412,5264,7069,7172,6895,7172,6856,6895,5914,6747,6574,7083,6960,7588,5916,6355,6276,10087,10227,10142,10087,10142,10017,25004,24820,24829,24711,24820,24859,24733,24869,24458,37401,37182,37225,37601,37400,37450,24297,24386,24371,24329,24386,24297,5169,5104,5429,5193,5126,5342,8603,8445,8501,8537,8704,8455,9849,9800,9905,14610,14810,14714,14755,14810,14610,25595,25757,25683,25297,25230,25177,26985,27042,27245,33240,33379,33288,37097,36937,36935,7552,7481,7475,7560,7481,7552,29133,28913,28922,10418,10473,10351,5889,5727,5424,7172,7126,6856,12277,12370,12397,12152,12000,12068,15507,15571,15590,15454,15384,15309,29340,29205,29351,5017,5069,5110,5017,5110,5088,25494,25377,25338,36832,36861,36803,36813,36820,37106,37601,37450,37519,9892,9849,9905,10195,10235,10263,10124,10235,10195,17383,16796,17136,17736,17976,18006,36551,36662,36445,37096,37097,36935,36719,36662,36551,37398,37401,37225,37398,37225,37227,25400,25457,25595,25338,25377,25170,37106,36820,37101,13677,13744,13792,14291,14519,14432,13232,12940,13008,28625,28852,28583,28213,28293,28138,28099,28293,28213,28099,28213,28017,13060,12909,12994,13302,14039,13787,13008,12940,12847,13490,13744,13677,15307,15454,15309,14072,14191,14025,27968,27914,27578,28620,28475,28429,28707,28475,28620,28707,28620,28748,36446,36397,36568,37127,37136,37120,37127,37120,37109,9862,9515,9715,5264,5412,5146,24820,24541,24459,23765,23661,23782,22627,22475,22465,24456,24541,24711,5112,5104,5169,36529,36349,36339,37589,37601,37519,37486,37479,37215,6747,6960,7083,11686,11698,11408,12819,13008,12847,11179,11095,11076,30542,30392,30362,30023,29922,30067,29983,29690,29922,29551,29340,29351,30950,30794,31548,13021,12909,13060,13744,13941,14030,35813,35650,35718,35766,35670,35650,35871,35718,35786,35930,35792,35893,35930,35893,36054,17605,18317,18001,22475,22307,22356,16214,16145,15882,17518,17769,17484,25400,25230,25297,37143,37106,37101,37096,36935,36905,29945,30160,30082,30589,30431,30348,30260,30160,30186,34839,34828,34664,35022,34839,34932,11076,11095,10938,35204,35214,35375,34906,34993,34808,35330,35476,35319,35452,35693,35508,34906,34737,34742,6856,7126,6915,7622,7985,7997,7622,7997,7669,10834,11076,10938,10834,10832,10672,6199,6114,6245,6174,6114,6199,6351,6694,6126,12909,12766,12930,11701,11442,11985,13941,14072,14025,29082,28963,29069,29082,29069,29205,28536,28852,28625,5044,5078,5135,5264,5289,5332,4770,5044,5135,22751,22475,22627,22001,22247,21931,22577,23062,22993,25468,25757,25595,26954,27758,27500,32469,32431,32343,32343,31955,32274,32556,32616,32469,33971,33501,33709,32912,32978,32967,32967,32978,32990,32990,33140,33087,33240,33272,33379,32591,32766,32723,32538,32536,32591,32157,31920,31888,36880,36762,36653,36874,36696,36861,36874,36861,36939,12041,12226,12534,9898,10139,10286,30023,30067,30392,35375,35214,35527,20763,20797,21313,21313,21634,21816,20754,20709,20763,20571,20595,20610,20610,20485,20433,20485,20257,20433,20067,20257,20485,20095,20257,20067,20095,20067,19968,20095,19968,19992,32616,32431,32469,32882,32719,32723,19890,19968,19854,5391,5365,5470,5457,5474,5568,5332,5289,5412,5491,5288,5146,5574,5521,5722,5574,5483,5512,9907,10087,10017,10235,10418,10351,10105,10418,10235,12766,12455,12658,14072,14291,14191,15307,15309,15200,19792,19890,19854,25494,25589,25377,26782,26705,26501,25530,25589,25494,25338,25170,25237,28852,29133,28922,30934,30852,30706,31006,30852,30934,35330,35170,35180,5298,5365,5391,37430,37398,37227,37138,37127,37109,37578,37673,37015,38010,37578,37463,9506,9528,9689,9480,9140,9088,9480,9528,9448,23598,23495,23611,32978,33140,32990,33730,33579,33641,37589,37519,37509,38047,37886,37541,5012,4930,5095,5032,4770,5135,5043,4944,5012,4878,4944,5043,4878,5043,4848,19755,19792,19854,5078,5082,5205,5007,5082,5078,22978,23062,22577,5155,5193,5342,5049,5112,5169,5155,5342,5204,23765,23782,24143,33140,33245,33087,37386,37088,37136,37401,37486,37024,37652,37589,37509,4944,4930,5012,19755,19665,19792,5405,5474,5457,16893,16852,16763,15882,15947,15717,15882,15717,15571,24733,24458,24556,25237,25170,24869,37097,37138,37109,37083,37096,36905,36758,36570,37187,11913,11985,11947,10106,9892,9905,30119,30023,30392,35341,35330,35180,33579,33458,33641,26501,26705,26601,27968,28099,27914,26827,26705,26782,4930,4983,5108,5006,5017,5088,5014,4989,5080,5006,5088,5104,6871,6821,6765,6821,6895,6781,9448,9528,9506,11259,11302,11392,10087,10124,10227,10859,11116,11076,11076,11116,11244,27500,27758,27957,27019,27225,26952,29522,29551,29627,29522,29340,29551,33641,33458,33693,35082,34956,35215,31997,31888,31745,31997,31745,31906,35904,36173,36134,35670,35632,35541,13090,13008,13161,11686,11798,11729,11496,11798,11686,21420,21426,21548,21420,21390,21426,21426,21390,20851,19963,19562,19851,21420,21548,21559,21548,21678,21559,21678,21770,21559,21858,21770,21678,35930,35871,35786,5049,5169,5126,13090,13401,13298,13759,13853,13744,13744,13853,13941,13941,13860,14072,14416,14439,14291,12386,12370,12286,17912,17736,18006,18599,18678,18434,23062,23175,23161,23613,23175,23414,13759,13744,13490,19640,19665,19614,22134,22151,22040,16893,16763,16405,24507,24458,24386,37150,37247,37101,36939,36861,37098,36907,37037,37540,5298,5427,5365,5365,5427,5457,36762,36757,36549,37114,36813,37106,37247,37143,37101,5049,5065,5112,5183,5077,5070,18080,18006,18176,17565,16796,17383,17518,17484,17427,19327,19516,19614,22307,22241,22356,24250,23765,24143,24456,24143,24541,23633,23688,23161,14439,14610,14519,14439,14519,14291,22134,22216,22151,35766,35632,35670,36886,36757,36762,36370,36353,36292,12011,11913,11947,12346,12041,12534,11887,12068,12000,24196,24329,24029,26827,27019,26952,29588,29522,29627,35215,34956,34993,36598,36397,36481,8704,8537,8603,8507,8537,8455,9862,9612,9515,9909,9907,10017,10087,10051,10124,31906,31745,31540,21602,21634,21313,22247,22336,22459,4907,5073,4910,4959,5006,5104,37601,37931,37607,37642,37589,37710,24711,24541,24820,25457,25400,25297,26696,26717,26794,26717,26823,26794,30119,29983,30023,31006,31160,31080,37259,37114,37106,37096,37138,37097,37456,37386,37136,37187,36570,36662,11442,11259,11392,11036,11259,11172,27916,27500,27957,26794,26823,26985,27916,27957,28506,28707,28748,28736,28748,28963,28736,30160,30260,30252,30186,30160,29945,36180,36312,36030,36722,36719,36551,36017,35800,35754,35754,35508,35823,35568,35476,35330,8537,8482,8603,30023,29983,29922,30321,30362,30392,32031,31906,32044,34951,35022,34932,34633,34427,34368,35116,35022,34951,35116,34951,35204,30589,30348,30395,5049,5126,5038,5112,5065,5104,5397,5618,5517,11259,10977,11302,30415,30589,30395,16871,16893,16736,17310,17518,17427,16987,16893,16871,11927,11913,12011,11798,11887,12000,12286,12370,12025,11784,11887,11798,26705,26827,26952,26782,26501,26698,25967,25718,26272,35145,35215,34993,35267,35341,35180,35145,34993,35109,36429,36529,36339,6895,6821,6871,7126,7084,6915,12455,12346,12534,12041,11927,12011,12462,12346,12455,12326,12346,12232,12455,12766,12462,29133,29234,29253,29195,29234,29133,29195,29133,28852,28383,28625,28293,28099,28017,27914,27578,27439,27968,27921,28044,27968,9864,9907,9909,10124,10071,10235,11214,11347,11116,33527,33458,33379,36444,36353,36370,36444,36370,36446,37284,37138,37096,19640,19516,19508,36568,36444,36446,36874,36880,36653,37089,36880,36874,34766,34368,34828,13083,13021,13060,13184,13302,13366,13302,13546,13366,16796,16562,17136,27334,27225,27019,32786,32766,32591,32978,33178,33140,33140,33178,33245,33245,33272,33240,32786,32591,32536,32531,32191,32337,32191,32157,32337,35813,35766,35650,35930,35958,35871,35904,35913,36173,32766,32882,32723,4928,5069,5017,22151,22216,22241,22151,22241,22307,7183,7378,7268,32431,32406,32343,32649,32616,32556,32681,32616,32649,32882,32912,32719,35527,35214,35393,35527,35393,35753,35350,35341,35267,14063,14179,14072,13454,13759,13490,13401,13090,13165,5521,5481,5613,5770,5910,5885,9448,9389,9480,8537,8507,8482,9689,9800,9506,11214,11312,11347,10832,10629,10486,30260,30415,30395,29961,29945,29701,32337,32157,32348,35022,34930,34839,34897,34930,35002,35215,35264,35082,34715,34896,34742,35004,34896,34715,6068,5930,6261,6068,6261,6114,36026,35930,36054,36598,36481,36757,29082,29205,29340,29347,29340,29522,35813,35718,35871,5674,5770,5885,7268,7475,7481,7268,7481,7217,9506,9800,9735,17565,17383,17553,18154,18080,18176,18184,18176,18284,17912,18080,18154,29983,29861,29690,30119,29861,29983,32590,32406,32431,33012,33178,32978,35456,35116,35204,34973,34993,34906,37564,37486,37696,37548,37401,37398,6369,6694,6354,6696,6765,6821,37234,37247,37150,37143,37259,37106,37098,36832,36986,37387,37247,37234,23598,23611,23661,4993,5239,5136,5289,5282,5391,24820,24916,24859,23673,23598,23661,24329,24507,24386,25440,25530,25338,26272,26051,26180,24436,24507,24329,24556,24507,24662,9735,9849,9760,9735,9800,9849,32127,32157,31997,32127,31997,32031,9990,10051,10087,5427,5405,5457,5424,5727,5611,5294,5405,5427,6105,6068,6114,7669,7997,8023,10486,10629,10418,6737,6696,6821,6999,6915,7084,12140,11927,12041,11172,11259,11242,11259,11036,10977,12326,12041,12346,11887,11949,12068,11784,11949,11887,29847,29588,29627,33178,33272,33245,35244,35264,35215,16987,17126,16965,19508,19516,19426,6781,6895,6856,29347,29082,29340,18080,17912,18006,18678,18802,18434,23673,23661,23765,36874,36939,37089,36741,36598,36757,5126,5193,5038,4932,4928,5017,5082,5023,5185,4918,5007,5078,4918,5078,5044,5770,5669,5910,5664,5669,5770,5664,5770,5674,5437,5611,5474,6052,5918,6276,6747,6084,6960,11312,11408,11698,11400,11408,11312,24820,25004,24916,27063,26985,27245,30362,30736,30542,29539,29522,29588,35145,35221,35215,34896,34973,34906,35083,34973,35076,36722,36551,36540,37268,37127,37138,36666,36540,36529,31006,30934,30950,30542,30736,30815,30276,30415,30260,30854,31290,30773,30276,30260,30186,5264,5282,5289,5098,5282,5264,9892,10106,10139,9794,9814,9909,9907,9990,10087,9407,9612,9522,24507,24556,24458,24196,24028,23758,31906,31540,32044,32031,31997,31906,10529,10486,10176,11245,11214,10997,10071,10124,10051,20595,20709,20754,20531,20709,20595,20531,20595,20571,20531,20571,20433,20531,20433,20405,20433,20257,20405,20257,20279,20405,34427,34323,33709,34351,34323,34389,20257,20095,20279,12878,12766,12909,20279,20095,20125,4787,5163,5048,4944,4874,4930,4930,4851,4983,4660,4770,5032,7183,6999,7204,6915,6781,6856,6881,6999,7183,22475,22751,22895,22001,22336,22247,23175,23633,23161,22001,21931,21634,35218,35221,35145,20125,20095,19992,14179,14291,14072,17055,16987,16871,4878,4874,4944,5405,5436,5474,5223,5436,5405,8482,8445,8603,8711,8759,9088,9715,9814,9794,23613,23633,23175,23873,24196,23758,26827,26906,27019,25718,25803,26051,31485,31319,31335,35693,35476,35635,35693,35452,35476,36676,36666,36529,35330,35491,35568,36886,36762,36880,36436,36212,36353,36676,36529,36429,28099,28383,28293,29854,29961,29701,28318,28383,28099,36026,35958,35930,35766,35780,35632,36436,36353,36444,4874,4851,4930,19992,19968,19890,21390,21161,20851,21238,21161,21390,21238,21390,21460,21390,21420,21460,21420,21559,21460,21559,21540,21460,13302,13021,13083,12878,13021,12971,35958,35813,35871,35139,35022,35116,4932,5017,5006,4772,5048,5079,21858,21891,21770,28623,27957,28475,28959,28736,28963,29019,28963,29082,29019,29082,29245,8507,8445,8482,9814,9864,9909,19792,19665,19640,19792,19992,19890,30983,31006,31080,5007,5023,5082,4922,5023,5007,16893,16987,16965,15882,15571,15489,18434,18802,18590,24456,24250,24143,25418,25230,25400,37268,37136,37127,37268,37138,37284,6068,5748,5930,6174,6105,6114,6027,6105,6174,36017,36275,35966,5294,5298,5223,5035,5298,5391,11496,11784,11798,10840,11076,10834,21858,22040,21891,26273,26272,26180,27084,27063,27245,27084,27245,27230,34930,34897,34828,35097,34930,35022,35139,35116,35328,36604,36568,36397,36902,36886,36880,36598,36604,36397,36902,36880,37089,37284,37096,37083,4910,5073,5069,4904,4932,5006,22895,22751,23066,21891,22040,22007,37589,37642,37601,37652,37509,37479,37652,37479,37734,5481,5397,5517,5070,5193,5155,5483,5574,5768,15489,15571,15454,29347,29522,29539,29854,29701,29884,35456,35204,35375,35491,35341,35350,34973,35109,34993,35083,35109,34973,35244,35215,35221,5098,5146,5288,19516,19381,19426,17055,17310,17126,24426,24250,24456,22512,22372,22475,30815,30736,30852,30188,29861,30119,29539,29588,29576,34729,34058,34728,33852,33730,33641,9914,9892,10139,9914,10139,9898,19640,19614,19516,21476,21602,21313,13860,13941,13853,15019,15002,14810,13860,13853,13759,9283,9140,9480,8311,8329,8445,9283,9480,9389,9283,9389,9285,9389,9448,9375,9375,9506,9464,32811,32786,32536,32766,32869,32882,32882,32869,32912,32912,33012,32978,33178,33255,33272,32811,32536,32531,32523,32531,32337,32523,32337,32429,32786,32869,32766,5353,5397,5481,5223,5437,5436,5436,5437,5474,9140,9060,9088,25534,25418,25400,25534,25400,25595,32616,32590,32431,31160,30950,31236,32860,32597,33971,35356,35244,35221,5070,5155,5183,5065,4959,5104,18301,18184,18284,17565,17553,17736,18295,18184,18301,29076,29195,28852,32681,32590,32616,33272,33513,33379,32869,33012,32912,35491,35330,35341,7622,7580,7560,7411,7669,7501,10486,10672,10832,10529,10672,10486,31006,30900,30852,30983,30900,31006,32429,32337,32348,30854,30589,30761,30854,30431,30589,32348,32157,32127,9864,9990,9907,22040,22151,22007,26960,26794,26985,26960,26985,27063,36741,36604,36598,36554,36436,36444,36666,36722,36540,37456,37284,37481,36429,36030,36312,5077,5673,5016,32348,32441,32438,14179,14416,14291,17565,17736,17625,24635,24426,24456,25179,25004,25230,36554,36444,36568,37247,37377,37143,37540,37037,37760,19226,19381,19327,22372,22151,22307,5298,5294,5427,5223,5298,5035,25418,25179,25230,37268,37456,37136,37284,37083,37481,24635,24456,24711,23832,23673,23765,24966,24869,24733,24196,24436,24329,24662,24436,24318,32348,32127,32441,37386,37430,37227,37398,37430,37543,6354,6694,6765,6733,6781,6790,6737,6781,6733,7414,7481,7560,11214,11400,11312,13165,13090,13161,11245,11400,11214,12326,12140,12041,11701,11985,11913,12232,12140,12326,29627,29861,29847,30074,30206,29945,30074,29945,29961,35350,35267,35264,12201,12025,12370,14362,14485,14416,35985,35802,35813,35813,35802,35766,36134,36026,36054,35933,36003,36385,6354,6765,6491,11701,11913,11907,18184,18154,18176,18159,18154,18184,34897,34766,34828,35043,34766,34897,9990,10071,10051,11907,11913,11927,18317,19226,19327,29528,29253,29234,15019,14810,14755,26272,26273,26361,28130,27968,28044,25530,25494,25338,28709,28475,28707,28709,28707,28736,28709,28736,28929,28318,28312,28408,28383,28536,28625,13021,12878,12909,13184,13021,13302,28959,28963,29019,35985,35813,35958,34782,34707,34766,34323,34351,33709,34389,34323,34427,27230,27245,27500,36385,36003,36212,36630,36554,36568,4886,4959,5065,4910,5069,4928,4921,5065,5049,7669,7580,7622,7301,7580,7296,10672,10840,10834,10859,10840,10747,30542,30525,30392,30900,30815,30852,30862,30815,30900,30761,30589,30614,34707,34633,34368,37744,37479,37486,5512,5353,5481,5059,5077,5016,5290,5353,5512,5483,5768,5669,6105,5951,6068,5975,6027,6174,25418,25383,25179,25683,25534,25595,25466,26696,25757,24717,24733,24556,4958,5038,5193,5061,5077,5059,17807,17736,17912,21602,22001,21634,22978,23175,23062,23633,23753,23758,33515,33513,33272,29245,28959,29019,5781,5885,5930,14755,14610,14638,36855,36722,36666,36855,36666,36676,35218,35145,35109,35356,35350,35244,35244,35350,35264,25179,24916,25004,24875,24635,24711,24875,24916,24995,31438,31485,31335,31438,31335,31290,5061,5193,5070,37696,37486,37401,36275,36340,36312,36343,36340,36275,36343,36275,36538,35823,35508,35693,35635,35476,35568,35635,35568,35995,4910,4928,4826,33513,33527,33379,11702,11519,11701,12870,12462,12766,36041,36225,36237,4849,4918,4831,5023,4993,5136,10176,10486,10418,32860,32702,32681,34511,34389,34427,9866,9760,9892,11242,11259,11442,11242,11442,11519,14485,14610,14439,14485,14439,14416,27085,26960,27063,27085,27063,27084,30614,30589,30415,29955,30074,29961,29955,29961,29854,35004,34973,34896,35004,34715,34699,4782,4928,4932,9892,9760,9849,9914,9898,9866,33527,33693,33458,36340,36429,36312,15321,15489,15307,15307,15489,15454,16893,16713,16736,15200,15309,15019,32438,32429,32348,31365,31438,31290,36918,36741,36757,36604,36630,36568,37098,36986,37263,30815,30662,30542,30862,30662,30815,31410,31365,31290,30276,30186,30206,34633,34582,34427,34766,34707,34368,35002,34930,35097,37263,36986,37114,6781,6737,6821,6781,6915,6790,12462,12232,12346,35768,35485,35632,11496,11686,11408,11496,11408,11400,11214,11116,10997,22978,22577,22789,4918,4923,5007,5146,5098,5264,4849,4923,4918,15321,15200,15241,22789,22577,22425,8445,8214,8501,8455,8445,8507,37387,37377,37247,37521,37377,37387,16987,17055,17126,17466,17769,17518,16405,16214,16107,24875,24711,24859,23832,23765,23917,24875,24859,24916,12878,12870,12766,12227,12198,12232,14237,13787,14598,13401,13454,13490,12386,12847,12370,13248,13454,13401,14755,14835,15019,14362,14416,14329,20709,20797,20763,22245,22336,22001,20531,20627,20709,20561,20627,20531,20561,20531,20405,20561,20405,20437,20405,20360,20437,19884,20125,19992,19884,19992,19792,19884,19792,19577,27599,27230,27500,5140,4989,4772,4785,4787,5048,4878,4810,4874,4874,4687,4851,4660,5032,4983,13184,12971,13021,13454,13641,13759,28452,28536,28383,29195,29528,29234,31955,32343,32406,35780,35768,35632,35998,35985,35958,35998,35958,36026,36098,36026,36134,36254,36173,36310,4787,4848,5043,36918,36757,36886,36554,36718,36436,22475,22372,22307,22895,23172,23598,29847,29861,30188,29300,29245,29082,29411,29528,29195,37373,37259,37143,4772,4989,4479,4848,4810,4878,32811,32839,32786,32786,32839,32869,32869,33169,33012,33012,33255,33178,33513,33515,33527,33527,33787,33693,32811,32531,32642,32531,32523,32642,32523,32636,32642,4923,4922,5007,4913,4922,4923,13641,13860,13759,19343,19071,19851,17887,17807,17912,32523,32429,32636,37543,37548,37398,37543,37430,37526,8329,8214,8445,10286,10977,10782,23765,24250,24311,23613,23616,23633,24662,24717,24556,23420,23616,23613,8960,8711,9060,8711,8455,8704,8329,8311,8214,9375,9448,9506,9506,9735,9587,10959,10977,11036,11519,11442,11701,11496,11245,11198,30074,30276,30206,30439,30276,30398,32590,32572,32406,32681,32702,32590,33971,33709,34351,35097,35022,35139,35073,35004,35121,35083,35218,35109,35350,35781,35491,21161,20909,20464,21282,21114,21161,21282,21161,21238,21380,21238,21460,21380,21460,21540,21559,21682,21540,32702,32572,32590,32446,32502,32441,11907,11927,12140,35076,35218,35083,7580,7414,7560,6629,6649,6737,7301,7414,7580,31547,31365,31410,30458,30614,30415,34982,34782,34766,34707,34582,34633,6027,5951,6105,6008,5951,6027,6126,6694,6369,9587,9735,9683,9715,9507,9814,9814,9672,9864,9853,10071,9990,9853,10105,10071,10071,10105,10235,9082,9407,9522,9515,9407,9157,13860,14063,14072,27916,27599,27500,28092,27599,27916,28623,28475,28709,28623,28709,28738,32572,32491,32406,33169,33255,33012,35780,35766,35802,35328,35097,35139,36340,36432,36429,36885,36855,36676,36432,36343,36433,37642,37755,37601,37869,37755,37642,37710,37589,37652,37710,37652,37734,5360,5483,5411,5743,5781,5930,14485,14638,14610,14484,14638,14485,36725,36630,36604,31732,31540,31485,4759,4989,4907,21559,21770,21682,24662,24507,24436,4922,4972,5023,4913,4972,4922,12198,12140,12232,11955,11907,12140,18434,18295,18301,18357,18295,18434,35218,35356,35221,35635,35823,35693,37373,37376,37521,37377,37376,37143,25534,25383,25418,25757,26696,26794,25757,26573,26027,34389,34377,34351,34847,34582,34707,19577,19792,19640,19426,19640,19508,5571,6052,5954,5877,5918,5798,5424,5611,5437,6737,6649,6696,7095,7183,7268,9407,9515,9612,12201,12068,12025,12068,11949,12025,14604,14237,14598,13621,13697,13503,17887,17912,18154,17565,17161,16796,22165,22129,22372,24311,24250,24426,23616,23753,23633,23871,23753,23750,33255,33352,33272,35073,35076,35004,4993,5288,5239,5294,5223,5405,24370,24311,24426,24622,24426,24635,37744,37486,37564,37526,37430,37386,37456,37268,37284,21682,21770,21725,9510,9587,9600,25520,25383,25534,33352,33515,33272,7217,7095,7268,21725,21770,21891,35070,35097,35179,35002,35043,34897,34517,34511,34641,35728,35781,35356,35004,35076,34973,33852,33641,33693,4943,4921,5049,4959,4904,5006,4910,4759,4907,4943,5049,5038,5061,5070,5077,7414,7325,7481,7301,7325,7414,22978,23234,23175,23034,23234,22978,30439,30458,30415,30697,30854,30761,30439,30415,30276,4830,4904,4959,5781,5674,5885,5625,5674,5781,6790,6915,6999,12227,12232,12462,14329,14416,14179,28929,28736,28959,30188,30119,30525,30119,30392,30525,29528,29884,29701,29955,29884,30000,28195,28318,28099,28536,29076,28852,26906,26827,26782,36254,36098,36134,35985,35973,35802,36254,36134,36173,13165,13248,13401,13454,13458,13641,13641,13563,13860,14134,14179,14063,14134,14329,14179,12819,13161,13008,17466,17518,17310,16107,16214,15882,24995,24916,25179,28408,28452,28383,36098,35998,36026,35768,35753,35393,5673,5045,5016,5618,5045,5673,6246,6369,6193,6246,6126,6369,5667,5743,5930,17807,17625,17736,16309,15871,16562,17687,17625,17807,23753,23873,23758,23871,23873,23753,35998,35973,35985,9777,9990,9864,10859,11076,10840,5534,5669,5664,8309,8455,8277,7244,7301,7296,19963,19851,20057,36902,37072,36886,36741,36725,36604,37098,37089,36939,37145,37089,37098,37263,37114,37259,37734,37479,37743,5483,5382,5512,15200,15321,15307,15958,16107,15882,15241,15200,15019,15241,15019,15121,27051,26794,26960,25683,25520,25534,25352,24995,25179,4921,4886,5065,4869,4943,5038,23234,23414,23175,23237,23414,23234,35961,35780,35802,36041,35823,35635,35635,36225,36041,5748,6068,5951,5674,5625,5664,5975,6008,6027,8455,8311,8445,15958,15882,15796,25566,25520,25683,26273,26698,26501,26405,26698,26273,26272,25718,26051,34582,34511,34427,34929,34707,34782,22425,22577,22336,22425,22336,22245,35804,35753,35768,5061,4958,5193,4806,4817,4889,7325,7217,7481,6881,6790,6999,7244,7217,7325,30697,30761,30614,30104,30276,30074,35070,35043,35002,35070,35002,35097,4660,4983,4851,11245,11496,11400,12386,12819,12847,10859,10747,10898,17164,17310,17055,22129,22007,22151,22129,22151,22372,31438,31547,31485,30646,30614,30458,36343,36432,36340,37187,36662,36719,36433,36343,36538,16713,16893,16405,16963,17164,17055,24717,24966,24733,24959,24966,24717,10840,10672,10747,23414,23420,23613,24318,24436,24196,23412,23420,23414,9914,9866,9892,10959,11036,11172,16963,17055,16871,32511,31955,32406,30983,30862,30900,33847,33852,33693,37773,37064,37318,37376,37373,37143,5035,5391,5282,19562,19343,19851,18159,17887,18154,18971,19075,19208,22895,23598,23309,25128,25237,24869,26709,26906,26782,37455,37373,37521,12025,11949,11716,4831,4918,5044,4972,4993,5023,5098,5035,5282,23309,23598,23673,23780,23673,23832,23917,23765,24311,22789,22888,22978,22735,22888,22789,37743,37479,37744,14362,14484,14485,13934,14063,13860,33121,33169,32869,33255,33353,33352,33352,33507,33515,33626,33787,33527,32811,32942,32839,32642,32770,32811,32657,32770,32642,32657,32642,32636,9283,9096,9140,8455,8309,8311,9303,9285,9389,9303,9389,9375,9303,9375,9292,32636,32429,32438,32942,32869,32839,37089,37072,36902,36385,36527,36422,37145,37072,37089,9464,9506,9587,32572,32622,32491,32491,32511,32406,32702,32622,32572,32826,32622,32702,4933,4958,5061,5290,5397,5353,17223,17466,17310,15796,15882,15694,14835,14755,14638,37072,36918,36886,6126,5975,6174,6765,6696,6491,13161,13248,13165,13073,13248,13161,28452,28559,28536,28318,28408,28383,28195,28099,27968,32622,32511,32491,35823,36147,35754,13248,13458,13454,28130,28195,27968,36092,35961,35973,35973,35961,35802,35780,35804,35768,36098,36092,35998,36212,36527,36385,5382,5290,5512,5321,5290,5382,5321,5382,5220,16609,16713,16405,15450,15489,15321,37361,37263,37259,11716,11949,11784,12354,12819,12386,29082,29347,29300,28567,28559,28452,30454,30458,30439,4824,4886,4921,4782,4826,4928,4869,4921,4943,22888,22965,22978,22885,22965,22888,37744,37564,37791,35456,35375,35527,35043,34982,34766,35076,35404,35218,36401,36167,36147,35121,35004,34699,4782,4932,4904,9510,9464,9587,16881,16963,16871,17164,17223,17310,16617,16713,16609,25352,25179,25383,24875,24622,24635,32441,32127,32446,33393,33353,33255,36952,36719,36722,37696,37401,37548,10981,10959,11172,10919,10959,10981,11330,11242,11519,11702,11701,11907,12194,12286,12025,10859,10997,11116,10898,10997,10859,24660,24622,24690,24085,24196,23873,24966,25128,24869,23753,23616,23750,30454,30646,30458,29955,29854,29884,37456,37526,37386,6491,6696,6649,6491,6649,6538,12971,12870,12878,10919,10782,10959,12662,12870,12738,13252,12971,13184,12239,12386,12286,35883,35456,35527,36092,35973,35998,26698,26709,26782,28130,28312,28195,26563,26709,26698,30104,29955,30000,36885,36676,36429,36718,36554,36630,9683,9735,9760,33353,33507,33352,20627,20797,20709,20405,20279,20360,20279,20125,20360,20285,20351,20142,20561,20797,20627,34511,34377,34389,34517,34377,34511,37373,37363,37259,37455,37363,37373,4787,4679,4848,4848,4679,4810,4810,4687,4874,4785,4720,4787,4702,4720,4785,4702,4785,4668,4651,4679,4787,6538,6649,6533,20360,20458,20437,21114,20909,21161,19282,19314,19343,20947,20909,21114,20947,21114,21011,21114,21282,21011,21380,21282,21238,21394,21282,21380,35945,35804,35780,4720,4702,4658,19481,19640,19426,21540,21394,21380,31034,30862,30983,29576,29347,29539,4849,4913,4923,4767,4913,4849,18159,18184,18295,17625,17687,17565,22965,23034,22978,22969,23034,22965,37577,37548,37543,5918,5877,6276,5798,5918,5688,21540,21682,21725,36674,36885,36429,36167,36275,36017,6881,7183,6836,35847,35527,35753,4611,4687,4810,4689,4831,4559,37005,36725,36741,6629,6737,6733,29576,29588,29847,5019,5424,4984,37291,37145,37098,37164,36927,36918,36918,36927,36741,37291,37098,37263,15317,15450,15321,15317,15321,15241,21979,22001,21602,25718,25589,25803,25440,25338,25237,9600,9557,9505,9630,9683,9760,21725,21891,21828,37931,37601,37755,38047,38100,38085,38606,37318,37349,37869,37642,37710,37869,37710,37856,37710,37734,37856,16881,16871,16736,16881,16736,16617,16736,16713,16617,24959,25128,24966,30525,30542,30599,30599,30542,30662,31410,31290,31422,30634,30454,30439,35179,34982,35043,35179,35043,35070,36941,36927,37178,18393,18357,18434,4933,5061,5059,4933,5059,4937,4752,4993,4972,5019,5325,5424,20797,21476,21313,4743,4782,4904,4826,4759,4910,4830,4959,4886,6790,6629,6733,8311,8163,8214,8711,9088,9060,33626,33527,33515,34406,34013,33849,37526,37577,37543,37591,37577,37526,6836,7183,7095,6577,6533,6629,6836,7095,6886,10959,10782,10977,11702,11907,11660,11955,12140,12198,31365,31547,31438,31290,31185,31422,25271,25440,25237,37363,37361,37259,37455,37361,37363,5514,5625,5781,5514,5781,5743,5792,5951,6008,14574,14835,14638,14484,14362,14381,13546,13302,13787,12070,11955,12198,28195,28312,28318,28567,28685,28559,28559,28685,28536,27439,27225,27334,36147,36167,36017,36041,36147,35823,36226,36092,36098,35961,35945,35780,35804,35824,35753,36226,36098,36294,36310,36173,36414,6113,6069,6126,6113,6126,6246,6314,6369,6354,6314,6354,6337,6354,6491,6387,13321,13546,13319,14237,13546,13787,13458,13563,13641,13446,13563,13458,13446,13458,13333,27334,27019,26906,36414,36173,36385,6387,6491,6345,23034,23237,23234,24662,24959,24717,23415,23237,23266,28567,28452,28408,29955,30104,30074,33787,33847,33693,37856,37734,37842,37734,37743,37842,6069,5975,6126,12227,12462,12392,17171,17223,17164,16405,16107,16609,29599,29576,29720,30826,30599,30662,31160,31006,30950,31034,31080,31114,6452,6491,6538,27203,27230,27308,27203,27085,27230,27230,27085,27084,29009,28929,28959,29009,28959,29245,36226,35945,35961,4958,4869,5038,4937,5059,5016,21828,21891,22007,21828,22007,21905,24199,23917,24311,22165,22007,22129,24370,24426,24477,23421,23616,23420,37577,37696,37548,32631,32636,32441,30697,30614,30646,26180,26369,26273,27050,27334,26906,25803,25589,25530,5424,5487,5889,5325,5487,5424,5877,5931,6276,9082,9522,9031,5801,5931,5877,13725,13934,13860,17293,17223,17171,19226,19481,19381,24477,24426,24622,26237,26369,26180,32770,32942,32811,33169,33246,33255,33533,33626,33507,34051,33987,33787,33787,33987,33847,32971,32942,32770,32971,32770,33063,32636,32438,32441,4889,4937,5016,5220,5382,5219,28506,27957,28623,25734,25566,25683,24622,24875,24690,24660,24477,24622,32622,32601,32511,32511,32638,31955,33971,32597,32732,36725,36718,36630,36983,36718,36725,37162,36918,37072,36927,36941,36741,37339,37291,37263,22727,22475,22895,30656,30697,30646,30000,29884,29763,32942,33121,32869,6533,6649,6629,6385,6452,6538,28685,29076,28536,35936,35824,35804,34949,34929,34982,7580,7669,7411,10747,10672,10501,10975,11198,11245,30656,30646,30454,34982,34929,34782,35179,35097,35328,18357,18159,18295,17887,17687,17807,18205,18159,18357,23237,23412,23414,23372,23412,23237,5625,5534,5664,5450,5534,5509,37162,37072,37145,9292,9464,9356,9232,9292,9356,9464,9292,9375,9303,9232,9285,8960,9060,9140,32658,32601,32622,31732,31485,31547,5571,5954,5645,13934,14134,14063,4852,4869,4958,5045,5397,5036,6577,6629,6557,6800,6790,6881,12638,12462,12870,12194,12239,12286,13333,13458,13248,12194,12025,11854,23871,23979,23873,25128,25124,25237,23967,23979,23871,29510,29300,29347,4913,4767,4972,4831,5044,4675,22810,22727,22837,22687,22735,22789,22687,22789,22425,31080,31034,30983,30468,30283,30188,29599,29510,29576,29421,29117,29300,30950,31839,31236,37842,37743,37944,37891,37931,37755,19381,19481,19426,19226,19173,19225,24951,24959,24662,26158,26096,26051,37283,37187,36719,36674,36429,36432,36923,36885,37244,4852,4958,4933,23412,23421,23420,23372,23421,23412,24370,24199,24311,23917,23780,23832,25566,25383,25520,27050,26906,26709,4697,4759,4826,4697,4826,4695,31662,31732,31547,31566,31547,31410,4824,4830,4886,12227,12070,12198,11578,11435,11702,11435,11330,11519,22735,22885,22888,22791,22885,22735,37891,37755,37950,37944,37743,37744,5411,5483,5669,5321,5244,5290,26051,26096,26180,26369,26405,26273,25803,25530,25440,30826,30662,30862,30634,30656,30454,31185,31290,30854,36952,36722,36855,37456,37591,37526,5882,5937,5975,5975,5937,6008,6175,6113,6246,6193,6369,6314,6193,6314,6210,6354,6387,6337,13563,13725,13860,14093,14231,14134,13333,13248,13130,6337,6387,6340,28738,28587,28623,28738,28709,28929,6886,7095,6991,26302,26405,26369,34377,33971,34351,34641,34511,34582,9683,9600,9587,9557,9683,9630,23979,24085,23873,23967,24085,23979,28435,28567,28408,29574,29411,29517,28130,28154,28312,27921,27968,27439,36422,36414,36385,36294,36098,36254,36029,35936,35945,35945,35936,35804,6345,6491,6452,6345,6452,6401,19343,19314,18802,19282,19343,19562,19379,19226,19225,22189,22165,22284,29049,28738,28929,37755,37869,37950,11716,11784,11586,10693,10747,10501,10672,10529,10501,25734,25683,25757,14894,15121,15019,16609,16107,16005,14381,14362,14329,14231,14329,14134,27085,27051,26960,27308,27230,27599,38103,37160,37673,37521,37376,37377,37459,37339,37263,5882,5975,5947,5450,5411,5669,5931,5916,6276,5825,5916,5931,5801,5877,5798,36527,36436,36945,36527,36212,36436,36923,36952,36855,36923,36855,36885,6401,6452,6385,15882,15489,15694,16881,16765,16963,19379,19481,19226,22885,22969,22965,23421,23750,23616,22836,22969,22885,29117,29009,29245,29117,29245,29300,35824,35847,35753,36226,35961,36092,37998,37771,37696,37696,37771,37564,37677,37591,37709,4695,4826,4782,21979,22245,22001,5937,5792,6008,5679,5801,5798,37521,37387,37540,37333,37162,37145,35920,35847,35824,20909,20723,20464,20815,20723,20909,20815,20909,20984,20909,20947,20984,20947,21011,20984,21011,21045,20984,21282,21045,21011,31034,30826,30862,30950,31548,31839,32826,32702,32860,34847,34641,34582,34847,34707,34929,4658,4651,4720,4720,4651,4787,4679,4611,4810,4494,4660,4851,4658,4702,4668,4785,4772,4668,21264,21415,21476,21476,21979,21602,20561,20547,20797,20437,20547,20561,20458,20547,20437,20458,20360,20351,20142,20351,20360,21282,21127,21045,37886,38010,37463,38053,38010,37886,4668,4772,4558,19577,19640,19481,24172,24199,24330,23994,24199,24070,38047,38041,37886,37950,37869,38045,4558,4772,4377,4560,4611,4679,5252,5571,5645,11435,11519,11702,10530,9898,10286,18159,17832,17887,18042,17832,18159,21540,21587,21394,27122,27051,27085,27122,27085,27203,38010,38011,37673,4743,4695,4782,4775,4824,4921,4775,4921,4869,4699,4767,4849,4562,5035,5098,4699,4849,4831,18590,18393,18434,21394,21587,21364,38011,37976,37673,5220,5244,5321,5450,5669,5534,31092,30826,31034,29510,29347,29576,37339,37145,37291,36941,37005,36741,5792,5748,5951,14093,14134,13949,6557,6629,6790,6836,6800,6881,6761,6800,6836,12239,12261,12386,11245,10997,10975,29076,29411,29195,30104,30183,30276,28928,29076,28685,33626,33515,33507,33847,33987,33852,4743,4904,4830,4697,4614,4759,5382,5483,5219,5509,5534,5451,14894,15019,14835,14574,14638,14484,15788,15871,16309,26405,26563,26698,28053,28154,28044,26475,26563,26405,26237,26180,26096,16617,16765,16881,16005,16107,15958,24959,25124,25128,24951,25124,24959,37742,37521,37540,37459,37263,37361,37541,38100,38047,32942,33058,33121,33121,33246,33169,33063,32770,32657,33063,32657,33068,32971,33058,32942,4698,4775,4757,4657,4743,4830,4852,4933,4937,18393,18348,18357,18285,18348,18393,21905,21725,21828,33099,33246,33121,34728,34058,34013,35568,35491,35781,6113,6091,6069,5937,5852,5792,5428,5624,5748,6193,6175,6246,6210,6175,6193,6210,6314,6337,6210,6337,6196,13366,13252,13184,12227,12050,12070,11578,11702,11660,13546,13321,13366,13252,13321,13319,13405,13725,13563,13073,13161,12819,23994,23780,23917,22189,22007,22165,23555,23750,23421,24085,24318,24196,28587,28506,28623,28723,28506,28587,28723,28587,28738,36294,36254,36310,35936,35920,35824,36294,36310,36428,36420,36414,36422,36424,36310,36414,37773,37760,37037,37818,37760,37773,37683,37696,37577,38045,37869,37856,24102,24318,24085,31185,30854,30697,32502,32631,32441,5748,5667,5930,5616,5667,5624,14308,14381,14329,14308,14329,14231,27215,27319,27217,6196,6337,6340,9232,9303,9292,9096,9283,9285,7669,8023,7501,9356,9464,9410,21264,21476,20797,28044,28154,28130,27921,27439,27816,37178,37005,36941,36952,37283,36719,37677,37683,37591,36674,36432,36433,37973,37856,37842,37541,37607,38100,37975,37931,38005,9410,9464,9510,9410,9510,9529,32127,32301,32446,5947,5975,6069,5821,5895,5916,5916,5895,6355,5825,5931,5801,10913,10997,10898,12738,12870,12971,13405,13563,13446,28053,27921,27950,35196,35179,35268,35404,35076,35073,36669,36674,36433,7301,7244,7325,8023,7498,7501,10981,11172,11242,10981,11242,11330,10693,10913,10898,10693,10898,10747,35091,34949,34982,6800,6690,6790,6991,7095,7217,11907,11955,11660,9529,9510,9600,31869,31540,31732,18348,18205,18357,17832,17687,17887,18285,18205,18348,4695,4614,4697,4761,4830,4824,5679,5825,5801,6340,6401,6318,6385,6538,6533,10530,10286,10782,29009,29049,28929,29834,29720,29576,31662,31869,31732,36962,36436,36718,4889,4852,4937,4698,4761,4824,14501,14574,14484,14535,14574,14501,17744,17687,17832,27248,27122,27203,25867,25734,26027,27248,27203,27308,32301,32127,32031,15121,15317,15241,15353,15317,15153,8163,8311,8309,15694,15489,15450,25566,25551,25383,24199,23994,23917,27061,26794,27051,25859,25803,25569,32826,32860,32955,34948,34847,34929,37459,37361,37511,37162,37164,36918,6761,6690,6800,11586,11784,11496,12194,12261,12239,37591,37683,37577,37677,37709,37728,5451,5534,5625,5377,5286,5411,5219,5483,5360,9505,9529,9600,9515,9507,9715,9157,9507,9515,8575,7946,7737,34406,33730,33852,33533,33507,33353,12119,12261,12194,13949,14134,13934,22396,22687,22425,23415,23372,23237,22812,22687,22797,36538,36275,36167,4494,4851,4687,19379,19577,19481,19173,19300,19225,22189,21905,22007,22810,22475,22727,23237,23034,23266,23750,23967,23871,31566,31662,31547,32044,32301,32031,32044,31540,31869,11198,11284,11496,11161,11284,11198,11058,10981,11330,9630,9793,9492,10983,10975,10830,10913,10975,10997,34949,34948,34929,35196,35091,34982,35196,34982,35179,24070,24199,24172,22837,22727,22895,24819,24951,24662,26009,25943,25859,23856,23967,23750,31839,31548,31955,31160,31114,31080,29847,29834,29576,4764,5098,4993,4675,5044,4770,22837,22895,23309,22687,22791,22735,22812,22791,22687,4752,4972,4767,5679,5688,5579,14228,14308,14231,14613,14894,14835,16609,16765,16617,16752,16765,16609,24819,24662,24318,29879,29834,29847,6886,6761,6836,6340,6345,6401,6796,6761,6886,6991,7217,7244,11435,11360,11330,11447,11578,11494,12157,12354,12261,11471,11586,11496,29763,29884,29528,31756,31566,31574,31422,31566,31410,30031,30000,30172,6175,6091,6113,5882,5852,5937,5514,5451,5625,6079,6091,6175,6079,6175,6210,6387,6345,6340,7411,7296,7580,7318,7296,7411,8225,8277,8455,10501,10529,10176,13321,13252,13366,12662,12638,12870,13319,13546,13436,12713,13073,12819,13333,13405,13446,13725,13883,13934,14228,14293,14308,23372,23491,23421,23415,23491,23372,28435,28408,28312,28435,28312,28200,13173,13405,13333,31879,32044,31869,31185,30697,31154,6533,6417,6385,25943,26158,26051,27816,27439,27334,26237,26158,26198,28690,28776,28685,5946,5947,6069,27921,28053,28044,27816,27688,27829,36702,36420,36422,36294,36682,36226,36029,35920,35936,35328,35116,35587,36424,36420,36519,5045,5618,5397,5286,5360,5411,15633,15694,15450,15796,15848,15958,15353,15450,15317,19173,19305,19300,37326,37164,37162,37005,36983,36725,4689,4699,4831,4643,4699,4565,19314,18590,18802,17863,17744,17832,18545,18590,18749,22284,22165,22372,23309,23673,23780,8277,8163,8309,6385,6417,6318,12738,12638,12662,27122,27061,27051,27215,27248,27308,5791,5852,5882,5895,5914,6574,5825,5821,5916,5735,5821,5825,5688,5918,5571,13762,13883,13725,27050,26709,26834,36654,36538,36167,37381,37244,37392,4698,4824,4775,5397,5290,5036,23273,23309,23535,23964,24070,24172,23967,24102,24085,23856,24102,23967,30737,30697,30656,34923,35121,34699,34923,34728,34858,37339,37333,37145,37511,37361,37455,37511,37455,37612,4660,4675,4770,17293,17466,17223,22512,22475,22810,38005,37931,37891,38005,37891,38082,37791,37564,37771,5377,5411,5450,5616,5743,5667,14484,14381,14501,14535,14835,14574,23491,23555,23421,23519,23555,23491,37998,37791,37771,6854,6991,7244,11514,11712,11586,10975,11089,11198,10983,11089,10975,35107,34948,34949,35883,35527,35847,5171,5290,5244,6656,6690,6761,6656,6790,6690,12638,12392,12462,12261,12354,12386,11771,12025,11716,11712,11716,11586,36029,35945,36226,11447,11435,11578,11447,11360,11435,30031,30183,30104,30031,30104,30000,35587,35116,35456,4775,4751,4757,4356,4614,4695,9898,9793,9866,10785,10782,10919,10785,10919,10981,9672,9777,9864,18590,18500,18393,18545,18500,18590,31868,31869,31662,31868,31662,31756,33058,33099,33121,33246,33393,33255,32971,32979,33058,33063,32979,32971,33151,32979,33063,32615,32631,32502,32498,32502,32446,32498,32446,32454,37683,37998,37696,37481,37083,37187,37920,37944,37744,32979,33099,33058,10782,10785,10612,35107,34949,35091,34696,34517,34641,9232,9096,9285,8412,8225,8455,8277,8092,8163,9033,9096,9156,9244,9232,9356,9343,9356,9410,9343,9410,9359,4657,4695,4743,38082,37891,38106,11471,11496,11284,27091,27061,27122,26834,26709,26563,37020,36983,37005,32601,32658,32511,32826,32658,32622,35013,34641,34847,33398,33393,33246,34482,34406,34302,4651,4536,4679,4611,4477,4687,4660,4494,4675,4490,4536,4651,4490,4651,4658,4558,4658,4668,20723,20635,20057,20777,20635,20723,20777,20723,20815,20777,20815,20984,20777,20984,20857,20984,21045,21127,21282,21394,21127,4536,4560,4679,5252,5645,5487,21127,21394,21364,9777,9853,9990,10830,10975,10913,9430,9410,9529,10176,10418,10105,38011,38121,37976,37976,38103,37673,38010,38142,38011,38265,38142,38010,38053,37886,38041,38053,38187,38153,38041,38047,38146,4670,4657,4830,4775,4869,4751,5377,5450,5509,5220,5171,5244,5424,5437,4984,26158,26237,26096,25943,26051,25803,37973,38045,37856,38020,37920,37744,4543,4989,4759,5275,5219,5360,20458,20351,20547,20547,20874,20797,22836,22885,22791,20360,20125,20142,20125,19884,20142,19400,19577,19379,25271,25237,25124,38146,38047,38176,38142,38121,38011,5352,5509,5451,5352,5377,5509,32454,32446,32301,33393,33533,33353,21540,21725,21587,5167,5171,5220,25734,25681,25566,25738,25681,25734,6091,5955,6069,5947,5791,5882,6196,6079,6210,5765,6079,5837,6161,6196,6340,13073,13130,13248,13593,13762,13725,13084,13130,12918,28776,28928,28685,28567,28690,28685,28200,28312,28154,28200,28154,28053,27950,27921,27816,6079,5955,6091,5624,5667,5748,13252,12738,12971,12338,12270,12392,13436,13546,13621,38121,38103,37976,30907,30599,30826,29221,29049,29117,29117,29049,29009,27215,27091,27248,27248,27091,27122,28618,28690,28567,32359,32454,32301,36420,36424,36414,36428,36424,36519,32311,31839,31955,31236,31265,31160,32289,32359,32301,31756,31662,31566,37607,38127,38100,5748,5792,5731,4670,4830,4761,4751,4869,4729,6784,6796,6886,5701,5955,5765,11911,11955,12070,10612,10785,10731,12467,12819,12354,12467,12713,12819,11246,11471,11284,11246,11284,11161,12495,12738,12744,12392,12270,12227,12467,12354,12527,28690,28928,28776,29763,29528,29574,30183,30398,30276,31574,31566,31422,21587,21725,21749,18042,18159,18205,15764,15788,16118,37760,37819,37540,37916,37818,37773,5847,5791,5947,13593,13725,13405,13883,13949,13934,27829,27950,27816,37919,37481,37187,37283,36952,37276,9760,9866,9630,9557,9600,9683,32289,32301,32044,6991,6784,6886,7296,7196,7244,7501,7318,7411,34948,34870,34847,35034,34870,34948,35202,35091,35196,11771,11716,11712,35905,35883,35847,35328,35268,35179,36116,36029,36400,13736,13949,13883,36538,36669,36433,36654,36669,36538,6796,6656,6761,11603,11771,11712,21749,21725,21905,21749,21905,21944,29574,29528,29411,31574,31422,31580,32087,32289,32044,8163,8040,8214,8092,8225,8109,9630,9866,9793,32087,32044,32142,14293,14381,14308,15153,15317,15121,23964,23780,23994,22837,22824,22810,23964,23994,24070,25867,25738,25734,27319,27204,27217,5219,5167,5220,5247,5275,5360,5247,5360,5286,5247,5286,5200,37485,37333,37339,37164,37178,36927,37510,37339,37459,24609,24819,24318,25157,25271,25124,24211,24318,24102,12544,12392,12638,15018,15121,14894,15694,15848,15796,26198,26302,26237,26237,26302,26369,27981,28053,27950,26475,26302,26348,37607,37931,38127,37931,37975,38127,15745,15848,15694,23720,23856,23750,23720,23750,23555,24660,24370,24477,25709,25738,25867,5688,5679,5798,5579,5688,5543,31839,31265,31236,10736,10913,10693,11471,11514,11586,10736,10693,10572,5362,5352,5451,9557,9492,9437,11161,11198,11089,14821,15018,14894,17171,17164,16963,16752,16963,16765,21944,21905,21998,36519,36420,36702,37309,37178,37164,38127,37975,38082,9853,10066,10105,31879,31869,31868,31756,31574,31737,4670,4761,4638,4614,4543,4759,10572,10693,10501,37973,37842,37944,37973,37944,37920,37973,37920,38020,12173,12050,12227,35905,35847,35920,37612,37455,37665,4729,4869,4852,4638,4761,4698,4827,4852,4889,4676,4752,4767,4643,4767,4699,11305,11514,11471,11771,11854,12025,23266,23034,22969,22425,22245,22396,35865,35587,35456,8092,8040,8163,31879,31868,31863,5415,5514,5616,5616,5514,5743,5731,5792,5852,14535,14613,14835,14228,14231,14093,13762,13736,13883,13949,14058,14093,13130,13173,13333,13084,13173,13130,13130,13073,12918,13073,12713,12918,29517,29411,29076,28690,28970,28928,28435,28618,28567,28628,28618,28435,5955,5946,6069,5791,5731,5852,5701,5946,5955,6318,6401,6385,5850,5914,5895,5850,5895,5821,12495,12544,12738,12738,12544,12638,12270,12173,12227,13621,13546,14237,25551,25566,25681,27981,28200,28053,27981,27950,27829,36424,36428,36310,36058,35905,35920,36962,36718,36983,37818,37819,37760,37985,37819,37818,16740,16752,16530,33099,33398,33246,33393,33702,33533,32979,33151,33099,32657,32636,33068,32615,32502,32498,32615,32498,32454,32615,32454,32462,32454,32359,32462,4638,4698,4617,4381,4543,4349,9096,9073,9140,8225,8092,8277,9033,9073,9096,9244,9356,9343,9244,9343,9359,9529,9505,9430,7737,7946,7163,9507,9672,9814,9777,9736,9853,9853,9710,10066,22835,22824,22837,22835,22837,23031,21979,21476,21415,31265,31114,31160,31289,31114,31265,5946,5847,5947,5760,5850,5821,9082,9157,9407,14604,14598,15366,13564,13593,13405,27816,27334,27688,34696,34377,34517,32658,32717,32511,31283,31092,31114,25097,25124,24951,25097,24951,24819,6656,6557,6790,6329,6557,6656,6329,6656,6398,11261,11330,11360,11959,11911,12070,11959,12070,12050,11780,11854,11771,16752,17171,16963,19300,19400,19225,29421,29300,29510,30188,30525,30468,37819,37742,37540,37677,37733,37683,37728,37733,37677,4479,4543,4303,21714,21979,21415,38082,37975,38005,13214,13252,13319,29421,29510,29594,5286,5377,5158,5200,5286,5158,5153,5167,5219,5171,5036,5290,4817,4827,4889,16309,16796,17161,18285,18042,18205,18285,18393,18500,23856,23863,24102,23415,23519,23491,23505,23519,23415,33461,33398,33099,34923,34729,34728,38036,37773,37318,5153,5219,5275,15633,15450,15353,15633,15745,15694,15848,16005,15958,26302,26475,26405,26198,26158,26009,35502,35268,35520,5775,5731,5791,5609,5735,5679,5679,5735,5825,9430,9505,9437,32761,32717,32658,14343,14501,14381,15197,15633,15353,14343,14381,14293,25734,25757,26027,28494,27916,28506,11514,11603,11712,11246,11344,11471,11161,11344,11246,11161,11089,11033,10736,10830,10913,10572,10830,10736,35202,35107,35091,34810,34696,34914,34923,34699,34729,36041,36237,36147,33852,33987,34406,19225,19400,19379,18317,19173,19226,6417,6533,6577,19014,18590,19314,22284,22179,22189,23031,22837,23309,22812,22836,22791,22797,22836,22812,38020,37744,37791,38106,37891,37950,32717,32638,32511,32366,32359,32289,5514,5362,5451,5415,5362,5514,5415,5616,5067,25709,25551,25681,25709,25681,25738,37013,37020,37190,37511,37510,37459,37621,37510,37511,4889,5016,4806,4617,4698,4757,4567,4764,4993,5100,5252,5325,32283,32366,32289,31863,31868,31756,31863,31756,31737,13856,14058,13949,10066,10176,10105,10211,10176,10066,11911,11660,11955,10612,10530,10782,11723,11660,11911,11668,11603,11514,12527,12713,12467,19741,19282,19562,19407,19300,19305,22284,22372,22512,11261,11360,11447,18042,17943,17832,18034,17943,18042,31114,31092,31034,30969,31092,31074,33787,33626,34051,6557,6417,6577,12338,12173,12270,29594,29510,29599,29736,29599,29720,35938,35865,35456,35257,35202,35268,36058,35920,36116,24690,24875,24995,23247,23273,23535,38073,38020,38077,37709,37591,37456,4543,4614,4349,4617,4757,4561,18545,18537,18500,18602,18537,18545,9359,9430,9372,9372,9430,9413,14877,14604,15366,15788,15366,15871,14551,14613,14535,14551,14535,14501,37190,37020,37005,37005,37178,37190,22512,22810,22824,38106,37950,38045,5543,5688,5571,14109,14228,14093,31580,31422,31614,32283,32289,32087,10972,11089,10983,11668,11780,11603,10972,10983,10830,30305,30398,30183,30305,30183,30031,30305,30031,30172,4806,5016,5045,4827,4729,4852,5247,5153,5275,4705,4609,4621,5250,5377,5352,24330,24199,24370,26009,26158,25943,26475,26834,26563,32283,32087,32193,35268,35202,35196,35107,35034,34948,35257,35268,35502,11953,11959,12050,15745,15859,15848,15153,15121,15018,28970,29076,28928,7498,8023,7851,7318,7196,7296,6164,6318,6417,12527,12354,12157,13173,13345,13405,13593,13736,13762,14058,14109,14093,17943,17863,17832,17817,17863,17943,20635,20343,20057,20777,20675,20635,20857,20675,20777,20857,20984,21127,20857,21127,21004,21127,21364,21309,21364,21356,21309,21356,21201,21309,23519,23720,23555,23536,23720,23519,37819,37955,37742,37899,37916,37773,38014,37916,37899,20675,20546,20635,38053,38175,38010,38142,38168,38121,38121,38240,38103,38696,38036,37318,38258,38175,38053,38053,38041,38187,38041,38146,38187,38146,38165,38187,38295,38165,38146,13224,13345,13173,4558,4490,4658,4428,4462,4560,4560,4462,4611,4559,4699,4689,4377,4490,4558,4428,4560,4536,4614,4356,4349,4646,4757,4751,4559,4831,4675,4752,4567,4993,14796,15153,15018,20546,20463,20635,21529,21365,21356,20543,20874,20547,20543,20547,20351,19884,19856,20142,28935,28723,28738,28935,28738,29049,37276,36952,36923,37481,37709,37456,38265,38157,38142,11551,11494,11578,11551,11578,11660,4462,4477,4611,20463,20343,20635,38157,38168,38142,13447,13564,13405,25352,24690,24995,27119,27061,27091,36702,36422,36527,36116,35920,36029,7155,7196,7318,9430,9437,9413,10731,10785,10981,20142,19856,20144,31092,30969,30826,31289,31265,31839,35028,35034,35225,38085,38176,38047,28973,28935,29049,35781,35350,35356,36669,36763,36674,32193,32087,32203,14613,14821,14894,14338,14343,14293,14338,14293,14228,19407,19577,19400,26140,26009,25900,25080,25097,24819,33702,33626,33533,37013,36962,36983,38322,38280,38176,24351,24330,24370,25352,25383,25551,5731,5428,5748,5197,5247,5200,5847,5775,5791,5701,5775,5847,5701,5847,5946,6161,6340,6318,5735,5760,5821,5850,5864,5914,5648,5760,5735,13540,13736,13593,14712,14821,14613,36790,36702,36527,36585,36654,36167,38176,38280,38295,21979,22396,22245,23139,23266,22969,22654,22396,22523,12119,12194,11854,11780,11771,11603,11838,11723,11911,11305,11471,11344,21905,22189,21998,20874,21264,20797,30283,29847,30188,29421,29342,29117,18537,18285,18500,18390,18285,18537,37665,37455,37521,37485,37326,37333,37020,37013,36983,37665,37521,37742,38172,38106,38045,37840,37683,37733,7851,8023,8214,8109,8225,8185,9561,9672,9354,32203,32087,32142,4693,4729,4827,5111,5171,5167,23309,23780,23535,24351,24370,24660,31283,31390,31308,36654,36763,36669,11634,11707,11723,12173,11953,12050,12544,12338,12392,12495,12338,12544,12173,12338,12113,29344,29342,29533,21998,22189,22179,22788,22512,22824,22868,22824,22835,38172,38045,37973,38085,38322,38176,11764,11876,11780,10531,10972,10830,10462,10501,10211,30398,30634,30439,32266,32283,32193,30737,30634,30493,35121,35299,35073,35150,35299,35121,35404,35299,35495,38192,38127,38082,31737,31580,31720,11167,11261,11291,11494,11261,11447,30468,30821,30640,30468,30525,30599,30172,30000,29763,14343,14551,14501,14588,14551,14343,37326,37162,37333,36962,36945,36436,5197,5153,5247,5197,5200,5158,9672,9736,9777,26198,26348,26302,25943,25803,25859,26338,26348,26198,37626,37339,37510,9073,8960,9140,9033,8960,9073,9096,9232,9156,33151,33461,33099,33398,33702,33393,33068,32636,32631,33068,32631,32615,32462,32359,32366,32462,32366,32367,4643,4676,4767,4522,4676,4643,5579,5609,5679,5543,5609,5579,5543,5272,5423,9156,9232,9179,14037,14109,14058,24118,23964,24172,23139,22969,22836,25080,25157,25097,38307,37358,38103,37955,37665,37742,25097,25157,25124,23863,23856,23720,37316,37164,37326,37985,37818,37916,5113,5111,5167,11707,11551,11660,11707,11660,11723,17713,17687,17744,15765,15859,15745,16752,16740,17171,15765,15745,15633,15197,15353,15153,15197,15153,15048,9179,9244,9202,9179,9232,9244,11876,11854,11780,11876,12119,11854,37316,37309,37164,37283,37346,37187,37350,37276,37244,4693,4827,4817,23769,23863,23720,9359,9410,9430,32638,32709,31955,32717,32764,32638,32826,32761,32658,32858,32761,32826,23247,23031,23273,24389,24351,24660,24328,24351,24389,4543,4479,4989,4436,4670,4638,4436,4638,4617,4297,4494,4687,10211,10501,10176,5050,5036,5171,4705,4693,4817,13564,13540,13593,13736,13856,13949,13345,13447,13405,13084,13224,13173,12926,13224,13084,12918,12713,12675,28618,28636,28690,29989,30172,29763,28200,28628,28435,28636,28628,28470,28106,28200,27981,36237,36401,36147,36654,36752,36763,36585,36401,36596,5252,5487,5325,14588,14712,14613,14187,14338,14228,14187,14228,14109,37189,36945,36962,36899,36945,37068,4505,4559,4401,5311,5415,5067,14796,14712,14793,37301,37190,37178,4729,4646,4751,5746,5864,5850,5914,5839,6747,5746,5850,5760,5746,5760,5648,13360,13447,13345,28935,28737,28723,27215,27378,27319,28973,28737,28935,9557,9437,9505,33639,33702,33398,11305,11344,11161,12119,12157,12261,29834,29736,29720,29342,29221,29117,29740,29736,29834,35728,35356,35218,11261,11058,11330,9630,9492,9557,11167,11058,11261,10972,11033,11089,11101,11033,10972,30179,29879,29847,30468,30599,30821,35299,35404,35073,35150,35121,34923,5736,5746,5648,28768,28970,28690,10378,10530,10612,11101,11305,11161,19208,19173,18971,16530,16752,16609,21998,22179,22118,22179,22163,22118,30316,30289,30516,30493,30634,30398,30634,30737,30656,37903,37709,37890,37728,37840,37733,22654,22797,22687,23266,23505,23415,22654,22687,22396,5334,5352,5362,5153,5113,5167,5111,5050,5171,7501,7155,7318,6329,6417,6557,7851,8214,8040,9836,10211,10066,10462,10572,10501,35028,34847,34870,35028,34870,35034,13720,13856,13736,27688,27334,27419,29344,29221,29342,36702,36802,36519,36116,36400,36241,36899,36790,36527,37843,37840,37728,14796,15018,14821,15859,16005,15848,27215,27217,27091,27308,27795,27505,10364,10572,10462,15620,15765,15633,22179,22284,22163,25757,26794,26573,25654,25352,25551,31283,31074,31092,31283,31114,31289,32367,32366,32283,32367,32283,32266,35225,35034,35107,35013,35028,35225,17863,17817,17744,18285,18034,18042,18351,18034,18285,23863,24211,24102,23360,23505,23266,38036,38014,37899,38065,38014,38036,11291,11261,11494,11838,11911,11959,11413,11668,11514,11935,12157,12119,29736,29594,29599,30179,29847,30283,5311,5334,5362,5311,5362,5415,37189,36962,37013,36865,36802,36790,37309,37301,37178,37325,37301,37309,37621,37511,37612,11954,12119,11876,27419,27334,27050,35905,36069,35883,36294,36428,36682,15889,16005,15859,19300,19407,19400,17605,18001,17769,22163,22284,22304,37626,37621,37859,37626,37859,37729,7982,7851,8040,8412,8455,8711,18749,18602,18545,19014,19314,19282,23031,22868,22835,23031,23309,23273,22797,22847,22836,22864,22847,22797,32044,31879,32142,34696,33971,34377,4531,4561,4646,4705,4817,4806,11058,10731,10981,11291,11494,11551,30468,30418,30283,30379,30418,30640,30493,30398,30305,31580,31737,31574,34406,34858,34728,34733,34858,34406,19173,19208,19249,22109,22158,22156,23505,23536,23519,23565,23536,23505,38077,38020,37791,37709,37843,37728,37940,37843,37903,11973,11953,12173,11572,11291,11551,13353,13319,13436,13353,13436,13453,11764,11954,11876,29740,29834,29879,29740,29594,29736,25654,25551,25709,4559,4565,4699,4676,4568,4752,4505,4565,4559,31862,31737,31720,12431,12527,12157,12675,12713,12635,13360,13540,13447,13447,13540,13564,17466,17605,17769,30316,30172,30289,28628,28636,28618,28470,28628,28200,28106,27981,27829,38106,38192,38082,38386,38192,38106,38073,37973,38020,13503,13436,13621,13621,14237,13697,5197,5113,5153,4816,4806,5045,4966,5113,4919,15765,15889,15859,15197,15620,15633,32142,31879,31998,4883,5045,5036,4531,4646,4523,13697,14237,13850,13360,13345,13224,13856,14037,14058,14588,14613,14551,14712,14796,14821,15741,15765,15620,23981,24211,23863,28225,28106,27829,37492,37316,37326,37301,37329,37190,37276,37346,37283,37350,37346,37276,37276,36923,37244,18034,17817,17943,17971,17817,18034,4477,4297,4687,4401,4559,4675,4462,4362,4477,4490,4428,4536,4345,4428,4490,20546,20415,20463,20463,20415,20343,20343,20218,20057,20675,20591,20546,20755,20591,20675,20755,20675,20807,20675,20857,20807,20857,21004,20807,21201,21004,21127,21201,21127,21309,21356,21364,21587,38168,38240,38121,38157,38427,38168,38175,38265,38010,38394,38265,38389,38258,38053,38153,38258,38153,38330,38153,38187,38330,38187,38165,38330,4966,5050,5111,6164,6161,6318,5067,5616,5180,6784,6991,6854,11668,11764,11780,12144,12431,12157,11682,11764,11668,11682,11668,11413,11101,11161,11033,12744,12738,13252,16497,16530,16609,15884,15889,15765,18602,18390,18537,18403,18390,18602,20274,20543,20285,20285,20543,20351,20874,21057,21264,22523,22396,22315,20274,20285,20142,20274,20142,20144,19856,20185,20144,21356,21587,21529,24328,24172,24330,21991,22118,22109,24328,24330,24351,25768,25654,25709,25768,25709,25867,29891,29740,29879,37621,37626,37510,37485,37626,37729,20591,20415,20546,20543,20915,20874,33063,33183,33151,33425,33068,33135,33068,32615,33135,32373,32462,32367,13850,14237,13889,13540,13720,13736,36790,36802,36702,36865,36790,36899,36951,36752,36981,36889,36752,36883,38295,38146,38176,33041,32955,32860,32761,32764,32717,5250,5158,5377,5428,5731,5472,14588,14343,14290,16497,16609,16005,17466,17293,17507,25157,25287,25271,26199,26338,26198,24897,25080,24819,20415,20269,20343,19856,20163,20185,21944,21971,21749,32203,32266,32193,31998,31879,31863,32955,32858,32826,20269,20218,20343,19249,19407,19305,38396,38240,38168,10636,10731,10615,11572,11551,11707,11838,11959,11953,12495,12304,12338,29533,29342,29421,29221,28973,29049,27204,27119,27217,29533,29421,29594,30418,30308,30283,30379,30308,30418,31862,31863,31737,30172,30316,30305,29517,29076,29335,36682,36428,36519,36058,36069,35905,11055,11058,11167,18839,18994,18813,21944,21998,21971,32858,32764,32761,35303,35150,34923,35898,35937,35781,38240,38249,38103,38249,38271,38103,18390,18351,18285,18403,18351,18390,22847,23139,22836,23769,23981,23863,23119,23139,22847,37998,37683,37840,24389,24660,24479,24660,24692,24479,8418,8412,8711,7982,8040,8092,8418,8711,8579,8956,8960,9033,8956,9033,9156,8956,9156,8955,9156,9042,8955,32764,32709,32638,7982,8092,8109,14187,14343,14338,21998,22118,21991,21971,21998,21991,27217,27119,27091,28506,28723,28494,32208,32266,32203,32039,31998,31863,31580,31614,31720,38085,38100,38322,29890,29594,29740,29495,29533,29594,29335,29076,28970,36241,36069,36058,34696,34781,33971,35028,35013,34847,35257,35107,35202,38100,38259,38293,38322,38100,38293,5250,5352,5334,4887,4935,4894,26573,26794,26876,25654,25367,25352,26348,26338,26475,27688,27785,27829,26140,26198,26009,5158,5250,4955,5311,5250,5334,25866,25768,25867,37316,37325,37309,37501,37325,37316,37903,37843,37709,36885,37392,37244,9372,9247,9359,9793,9433,9492,25080,25153,25157,25005,25153,25080,4646,4561,4757,4321,4345,4181,4646,4729,4523,22788,22824,22868,23535,23780,23964,21308,21415,21264,6854,7244,7196,7155,7501,7203,11115,11055,11167,11115,11167,11291,11072,11101,10964,10531,10830,10572,13353,13214,13319,12495,12422,12304,13337,13214,13353,13453,13436,13503,30373,30493,30305,30373,30305,30316,38250,37998,37840,37940,37840,37843,38271,38307,38103,38100,38127,38259,11973,11838,11953,11973,12173,12113,35781,35995,35568,35654,35218,35404,28636,28768,28690,29015,28768,28962,35268,35328,35520,24204,24118,24172,24204,24389,24479,5746,5736,5864,5864,5839,5914,5648,5735,5637,13660,13503,13697,13660,13453,13503,8412,8185,8225,9793,9543,9433,4935,5050,4894,5050,4935,5036,4599,4729,4693,14796,14826,15153,15741,15884,15765,14588,14793,14712,14826,14793,14728,30308,30179,30283,30443,30179,30308,34914,34696,34641,34914,34641,35013,36904,36674,36763,28883,29007,28872,29376,28973,29221,29221,29344,29376,28768,28987,28970,38259,38127,38244,5637,5735,5530,4410,4505,4369,4510,4568,4435,19014,18749,18590,18647,18749,18839,22654,22660,22797,22655,22660,22654,38219,38172,37973,38219,37973,38198,4377,4772,4479,4621,4693,4705,38090,37985,37916,38739,38065,38036,10311,9898,10530,38244,38127,38192,12518,12422,12495,12144,12157,11935,13266,13360,13224,13683,13856,13720,11935,11954,11764,31422,31185,31614,32208,32203,32142,11737,11723,11838,11737,11634,11723,11413,11514,11305,13889,14237,14604,30136,29891,29879,36815,36682,36519,36032,35883,36069,36899,36527,36945,36752,36889,36763,36883,36752,36951,24777,24897,24819,25803,25440,25569,24609,24318,24367,23720,23536,23769,23565,23505,23360,38090,37916,38014,22788,22868,23036,27416,27419,27050,25287,25157,25153,37189,37013,37273,37626,37485,37339,37492,37485,37645,25169,25287,25153,26876,26794,27061,28494,28723,28842,7968,7982,8109,6854,7155,6601,11935,12119,11954,18749,18654,18602,18351,18021,18034,18647,18654,18749,23036,22868,23031,23268,23031,23247,32208,32142,31998,15788,15764,15366,16309,16562,16796,17565,17687,17161,25569,25440,25271,34810,34781,34696,34939,35100,34961,18243,18021,18351,13683,14037,13856,13629,13720,13540,37329,37301,37325,5437,5223,4984,5530,5735,5609,4984,5035,4562,30640,30418,30468,30070,29890,29891,30826,30969,30907,31614,31185,31529,30516,30373,30316,29763,29574,29989,37501,37329,37325,31916,32039,31863,30697,30737,31154,25308,25569,25271,12113,12338,12304,11558,11935,11764,33068,33183,33063,34739,34733,34406,33425,33183,33068,35937,35995,35781,36318,35995,35937,22660,22864,22797,22765,22864,22660,38198,37973,38073,38386,38244,38192,9202,9359,9247,9202,9244,9359,8166,8057,8185,8185,8057,8109,9372,9347,9247,24204,24172,24328,24204,24328,24389,23981,24087,24211,24170,24087,23981,4822,4816,5045,14136,14187,14109,25287,25308,25271,24897,25005,25080,24798,25005,24897,26834,26475,26338,29015,28941,28768,5749,5864,5736,5749,5839,5864,5749,5736,5649,28842,28723,28737,28883,28737,28973,4522,4643,4565,18021,17971,18034,18048,17971,18021,24118,23535,23964,23280,23266,23139,31199,31283,31308,32764,32862,32709,32858,32859,32764,33041,32859,32858,33041,32858,32955,33041,32860,33971,19173,19249,19305,17293,17171,17269,24367,24318,24211,37709,37990,37890,38236,38198,38281,38291,38106,38172,5771,5749,5649,12409,12274,12422,12422,12274,12304,13453,13337,13353,13373,13337,13453,12527,12431,12635,12713,12527,12635,12926,13084,12918,14037,14136,14109,32311,31955,32709,36815,36519,36802,36815,36802,36970,4935,4883,5036,4887,4883,4935,5111,5113,4966,17713,17744,17817,25380,25308,25287,31916,31863,31862,31154,30737,31001,34858,35133,34923,35495,35654,35404,34406,33987,34302,12220,12431,12144,29495,29344,29533,28987,29137,28970,28768,28941,28987,28768,28636,28962,9372,9413,9347,4505,4504,4565,4410,4504,4505,38219,38291,38172,38077,37791,37998,28494,28092,27916,11634,11572,11707,11826,11737,11838,11826,11838,11973,26140,26199,26198,26065,26199,26140,25900,26009,25859,25900,25859,25912,29015,29137,28987,25739,25859,25569,9347,9413,9437,17269,17171,17174,26876,27061,27119,25899,25866,25867,24660,24690,24692,26876,27119,27078,30136,29879,30179,29887,29495,29594,30907,30969,31119,35520,35328,35710,35245,35225,35107,35456,35883,35938,4609,4705,4806,23434,23247,23535,25716,25654,25768,27378,27215,27308,31189,30969,31074,36889,36904,36763,36585,36167,36401,36899,36970,36865,37273,37013,37190,35728,35654,36114,7163,7946,6321,9354,9507,9157,9354,9672,9507,9672,9561,9736,15889,15884,16005,16530,16697,16740,15135,15620,15197,14826,14796,14793,32266,32373,32367,31916,31862,31720,4568,4567,4752,4510,4567,4568,10636,10612,10731,9347,9437,9433,9276,9347,9350,12744,13252,12807,12064,12220,12144,35995,36225,35635,36202,36225,35995,38065,38090,38014,37501,37492,37654,38278,38090,38065,38250,38077,37998,14566,14793,14588,27078,27119,27204,26492,26834,26338,4504,4522,4565,4410,4522,4504,18470,18403,18602,18470,18602,18654,22864,23119,22847,23057,23119,22864,4377,4479,4251,4428,4362,4462,38265,38427,38157,38240,38396,38249,38249,38416,38271,38271,38416,38307,38389,38265,38175,38389,38175,38258,38389,38258,38457,38165,38462,38330,38295,38462,38165,38280,38387,38295,38322,38387,38280,38322,38328,38387,4345,4362,4428,20591,20562,20415,20415,20280,20269,20269,20280,20218,20218,19963,20057,20688,20562,20591,20688,20591,20755,20688,20755,20807,20688,20807,20789,21158,21004,21201,21365,21201,21356,20543,20713,20915,20915,20982,20874,20274,20514,20543,20275,20514,20274,20275,20274,20144,20275,20144,20185,34939,34781,34810,34939,34810,34914,38394,38427,38265,38307,38606,37349,7203,7498,7297,13850,13660,13697,13966,13889,14061,20861,20982,20915,24609,24777,24819,25380,25578,25308,24478,24777,24609,24798,24777,24734,23769,23536,23565,27419,27785,27688,27561,27785,27419,31283,31189,31074,31199,31189,31283,30841,30737,30493,31702,31916,31720,11737,11572,11634,10989,10731,11058,11826,11572,11737,36032,36069,36097,20386,20280,20415,19577,19856,19884,20982,21057,20874,38322,38293,38328,12274,12113,12304,19577,19407,19856,29890,29740,29891,38427,38396,38168,31702,31720,31614,32208,32373,32266,34051,33626,33702,35495,35299,35150,14290,14566,14588,14224,14343,14187,27209,27078,27204,27209,27204,27319,4597,4609,4806,4386,4523,4729,4599,4609,4600,7982,7922,7851,8265,8185,8412,33919,34051,33702,20096,20049,20218,21057,21308,21264,23652,23769,23565,38396,38416,38249,13993,14136,14037,37176,37068,36945,35502,35351,35257,35710,35328,35587,4335,4356,4695,4523,4561,4531,20049,19963,20218,21529,21587,21749,21529,21749,21713,26199,26347,26338,26229,26347,26199,26065,26140,25900,25739,25569,25578,30443,30308,30379,30907,30821,30599,30917,30821,30907,30804,30841,30493,30804,30493,30516,35494,35351,35502,4984,5223,5035,5637,5736,5648,33038,33041,33111,35224,34914,35013,22487,22523,22315,23119,23280,23139,35865,35710,35587,36241,36058,36116,8057,7968,8109,14826,15048,15153,14930,15048,14826,32208,31998,32082,36487,36401,36237,38328,38293,38358,38293,38259,38358,5772,6084,6747,5749,5771,5839,5609,5473,5530,13337,13223,13214,11951,11826,12113,13141,13223,13337,35874,35710,35865,35654,35728,35218,36225,36487,36237,35133,34858,34998,4562,5098,4764,25912,25739,25927,28883,28842,28737,28494,28352,28092,27505,27378,27308,28872,28842,28883,24777,24798,24897,24367,24211,24170,35245,35107,35257,37890,38212,38029,37940,38250,37840,37187,37346,37919,16412,16497,16005,16697,16610,16748,13360,13452,13540,13266,13452,13360,12832,12918,12675,21713,21749,21971,22118,22163,22109,12355,12635,12431,18403,18243,18351,17778,17713,17817,18419,18243,18403,23057,23280,23119,27308,27599,27795,26942,27416,27050,26942,27050,26834,17778,17817,17971,26492,26942,26834,5609,5543,5473,9736,9665,9853,10211,10364,10462,9354,9084,9227,13781,13660,13850,13781,13850,13889,13452,13629,13540,17174,17171,16740,24170,24211,24087,24170,23981,23913,38358,38259,38473,4883,4822,5045,5113,5197,4919,30532,30379,30640,29495,29470,29344,36032,35938,35883,5473,5543,5423,13966,13781,13889,32082,31998,32039,31694,31702,31614,31238,31185,31154,34482,34739,34406,34549,34739,34482,36883,36904,36889,37244,37424,37350,36951,36904,36883,8348,8265,8412,7989,7922,7968,9042,9156,9179,9042,9179,9202,9042,9202,9151,18243,18119,18021,18191,18119,18243,22523,22655,22654,22594,22655,22523,23280,23360,23266,23324,23360,23280,32859,33041,33038,32859,32862,32764,33183,33461,33151,34051,34302,33987,33425,33461,33183,38236,38291,38219,38236,38219,38198,38198,38073,38281,36400,36029,36226,36032,36094,35938,36782,36226,36682,36318,36202,35995,9561,9665,9736,33818,33639,33461,32082,32039,32003,34229,34302,34051,11572,11115,11291,11063,10936,10877,38488,38358,38473,9276,9247,9347,9151,9202,9247,27302,27209,27319,27078,27095,26876,25865,25899,26026,27228,27209,27302,37903,37986,37940,37424,37346,37350,10989,11058,11055,35351,35245,35257,35225,35226,35013,35359,35245,35351,35225,35245,35231,35502,35543,35494,37485,37492,37326,37273,37176,37189,37189,37176,36945,37955,37819,38098,4814,4822,4883,33038,32862,32859,33461,33639,33398,4919,5197,4955,4833,4814,4883,5197,5158,4955,25899,26027,26026,25899,25867,26027,5543,5571,5272,16748,17174,16740,17269,17507,17293,24692,24690,25184,23434,23535,23606,22163,22158,22109,38098,37819,37985,11558,11997,11935,11935,11997,12144,12220,12355,12431,11177,11413,11305,11072,11305,11101,11889,11997,11558,15048,15135,15197,14728,14930,14826,14728,14793,14566,14224,14187,14136,18603,18647,18700,22655,22765,22660,22594,22765,22655,32862,32759,32709,35502,35520,35688,36241,36097,36069,37420,37424,37244,32615,32462,33135,32003,32039,31916,4599,4693,4621,4599,4621,4609,18099,18048,18119,18119,18048,18021,10504,10378,10612,10138,10364,10211,31176,30917,30907,30821,30775,30640,31283,31289,31390,31125,31238,31154,31702,32003,31916,34998,34858,34733,22109,22156,22052,4899,4894,5050,8813,8960,8956,7968,7922,7982,9433,9437,9492,5349,5423,5326,14051,14224,14136,26858,26573,26876,27795,27599,28092,36970,36802,36865,37273,37190,37448,37392,36885,36674,4435,4568,4676,4567,4455,4764,4401,4675,4304,38281,38073,38316,38291,38386,38106,4657,4670,4335,8265,8166,8185,12807,13252,13214,10989,11063,10877,12807,13214,13141,13214,13223,13141,17266,17507,17269,23268,23247,23434,38256,38098,37985,38256,37985,38090,11063,10989,11055,10636,10504,10612,11063,11055,11115,16497,16697,16530,17174,17266,17269,16697,16497,16610,34739,34998,34733,34302,34549,34482,34409,34549,34302,31119,30969,31189,12744,12518,12495,36970,36899,37155,36186,36145,36097,4427,4676,4522,4833,4883,4887,4600,4609,4597,4436,4617,4437,31238,31529,31185,4437,4617,4561,4966,4899,5050,4894,4833,4887,4955,5250,4971,13629,13683,13720,13514,13683,13629,13514,13629,13452,12832,12675,12607,15079,15135,15048,15079,15048,14930,18647,18470,18654,18603,18470,18647,27095,27078,27209,25354,24690,25352,26347,26492,26338,25739,25912,25859,26065,25912,25927,25569,25308,25578,29137,29335,28970,30841,31001,30737,29237,29335,29137,29015,28987,28941,28200,28106,28470,31199,31119,31189,31308,31119,31199,35231,35226,35225,34989,33971,34781,35520,35710,35688,37156,36899,37068,37176,37161,37068,37508,37190,37329,9543,9793,9898,4335,4695,4657,19208,19209,19249,19075,19209,19208,35728,35898,35781,36415,35898,36388,4730,4816,4822,4370,4437,4561,24367,24478,24609,23913,23981,23769,23652,23565,23587,4815,4899,4966,37381,37420,37244,38141,38029,38212,37440,37420,37381,13781,13646,13660,14061,13889,14604,13842,13966,13887,29698,29470,29495,28825,28352,28494,29541,29470,29698,4510,4499,4567,4390,4499,4510,23587,23565,23360,4436,4335,4670,4352,4437,4370,4709,4730,4822,4709,4822,4814,18470,18419,18403,18483,18419,18470,22971,23057,22864,22971,22864,22765,38492,38386,38291,38316,38073,38323,7989,7968,8057,4345,4321,4362,4362,4260,4477,4181,4345,4490,4216,4321,4181,4303,4543,4381,4303,4381,4185,20514,20632,20543,20982,20990,21057,21057,21014,21308,22194,22396,21979,20564,20632,20514,20564,20514,20411,20514,20275,20411,20562,20386,20415,20280,20096,20218,20049,19938,19963,19963,19920,19562,20789,20807,21004,21276,21201,21365,21276,21365,21353,21365,21529,21353,20632,20713,20543,35447,35495,35150,35133,34998,35750,38427,38565,38396,38396,38507,38416,38590,38479,38307,38394,38481,38427,38389,38481,38394,38457,38481,38389,38457,38258,38330,38457,38330,38589,38295,38452,38462,4321,4260,4362,20411,20275,20387,20713,20792,20915,23535,24118,23947,25716,25768,25866,38029,37986,37903,38029,37903,37890,38295,38387,38452,38559,38571,38452,20387,20275,20163,20792,20861,20915,30516,30493,30373,31692,31694,31529,35688,35710,35922,35303,34923,35133,10615,10504,10636,11826,11973,12113,30775,30532,30640,30775,30821,30889,29989,29574,29517,35874,35865,36070,20668,20386,20562,20163,20275,20185,4815,4833,4894,27228,27095,27209,27319,27378,27302,36904,37392,36674,5423,5349,5473,5473,5375,5530,5641,5736,5637,5641,5649,5736,5375,5349,5326,5571,5157,5272,10378,10311,10530,10615,10731,10989,12204,12113,12274,19856,19407,19249,27416,27561,27419,27584,27561,27416,27584,27416,27399,35359,35231,35245,34961,34781,34939,35584,35303,35133,36097,36145,36032,36094,36145,36186,37257,37161,37176,30443,30136,30179,36042,35865,35938,20200,20096,20280,38569,38507,38396,38387,38328,38512,4613,4806,4816,4370,4561,4523,8924,8813,8956,8265,8064,8166,8166,8064,8057,8924,8956,8955,8924,8955,8995,8955,9042,8995,17915,17778,17971,17713,17438,17687,14061,14328,14007,17915,17971,18048,38492,38291,38236,38323,38073,38077,12518,12409,12422,12744,12545,12518,13373,13453,13660,12607,12675,12635,12355,12220,12064,5765,5955,6079,6079,6196,5837,6656,6796,6398,5771,5689,5839,5641,5484,5564,8995,9042,8891,12926,13266,13224,21353,21529,21382,25912,26065,25900,25153,25005,25090,28825,28494,28842,36815,36782,36682,37146,36782,36815,37146,36815,36970,38512,38328,38358,8810,8801,8726,12606,12545,12744,28470,28106,28225,29335,29357,29517,36558,36487,36225,36981,36752,36654,36904,37059,37392,36596,36487,36558,37492,37501,37316,37257,37156,37161,37645,37485,37729,20096,19938,20049,21713,21971,21811,4304,4675,4138,4343,4427,4522,8579,8711,8960,10390,10311,10378,22194,21979,21714,25865,25716,25866,25865,25866,25899,31529,31694,31614,32251,32373,32208,31542,31529,31238,4058,4297,4477,4730,4613,4816,4623,4613,4730,6398,6796,6434,6854,7196,7155,14224,14290,14343,14051,14290,14224,13993,14037,13683,19938,19920,19963,12545,12409,12518,12531,12355,12166,29015,29237,29137,13694,13646,13781,32759,32311,32709,32862,32871,32759,32916,32871,32862,35224,35013,35226,36981,36654,36585,4343,4522,4315,18419,18191,18243,18329,18191,18419,24118,24204,24256,21811,21971,21991,23057,23324,23280,23652,23913,23769,23203,23324,23057,38346,38323,38353,38432,38236,38281,30532,30443,30379,30889,30821,30917,30889,30917,31037,17778,17675,17713,17797,17675,17778,23825,23913,23652,24170,24375,24367,30551,30443,30532,29541,29376,29470,4401,4359,4505,4294,4359,4401,4386,4729,4599,4542,4597,4806,10504,10390,10378,10564,10615,10408,10615,10989,10816,17507,17605,17466,17169,17266,17174,16748,16740,16697,22487,22594,22523,22548,22594,22487,24271,24375,24170,30910,31001,30841,30910,30841,30804,30910,30804,30802,35370,35224,35226,35494,35359,35351,35543,35359,35494,35543,35502,35688,38432,38281,38316,11063,11115,10936,12409,12204,12274,29470,29376,29344,30070,29891,30136,29306,29357,29335,38590,38307,38416,38488,38512,38358,13966,13842,13781,14061,14007,13887,9665,9710,9853,9629,9710,9665,9629,9665,9561,33639,33919,33702,35594,34998,34739,34130,33919,34188,32251,32208,32082,21811,21991,22052,14290,14494,14566,16412,16005,15884,14341,14494,14290,26026,26027,26453,27302,27378,27415,30324,30070,30136,10564,10390,10504,9350,9347,9433,35370,35226,35231,4427,4435,4676,4371,4562,4764,4343,4435,4427,23324,23331,23360,23203,23331,23324,4352,4335,4436,4320,4381,4349,4352,4436,4437,6329,6164,6417,12204,11951,12113,37621,37612,37859,37612,37665,37859,7203,7501,7498,8111,8064,8265,9354,8835,9084,5349,5375,5473,5100,5325,5019,14604,14328,14061,16412,16249,16331,37161,37156,37068,37155,37156,37246,37176,37359,37257,37547,37346,37424,38346,38316,38323,22052,21991,22109,38473,38259,38244,4684,4709,4814,4613,4542,4806,4684,4814,4833,4815,4894,4899,15741,15620,15548,15548,15620,15135,17478,17605,17507,17478,17507,17433,25367,25354,25352,27037,26876,27095,5013,5100,4990,5100,5019,4803,31845,32003,31702,31845,31702,31694,37420,37547,37424,37559,37547,37420,37440,37381,37392,17066,17169,17174,24375,24478,24367,24511,24478,24375,24168,24170,23913,4320,4349,4356,8064,7989,8057,4359,4369,4505,4290,4369,4359,5472,5731,5775,5837,6196,6161,5689,5786,5839,5689,5771,5649,12806,12926,12832,12832,12926,12918,13410,13514,13452,30802,30804,30516,31276,31542,31238,35303,35447,35150,35495,36114,35654,36558,36225,36202,35584,35447,35303,35584,35133,35750,13694,13781,13842,13373,13660,13646,13373,13141,13337,12807,12606,12744,12545,12606,12409,12409,12129,12204,12204,11943,11951,28225,27829,27785,29257,29306,29237,29237,29306,29335,36145,36094,36032,35666,35543,35688,36186,36097,36264,5899,5837,6161,22163,22304,22158,24256,24204,24479,24610,24479,24692,25090,25005,24798,26065,26088,26199,29007,28883,28973,27415,27378,27505,29007,28973,29398,31125,31154,31001,35100,34939,34914,22512,22304,22284,27142,27037,27095,27142,27095,27228,37447,37440,37392,38586,38473,38611,12355,12531,12635,12064,12144,11997,12064,11997,11889,11101,10926,10964,34130,34229,34051,31276,31125,31293,13410,13452,13266,36951,37059,36904,36770,36981,36585,18971,19173,18317,17433,17507,17266,18839,18749,19014,18099,17915,18048,22512,22788,22304,29694,29989,29517,29257,29237,29015,36462,36400,36226,36264,36400,36467,25367,25654,25716,29544,29517,29357,36094,36042,35938,35090,35100,35431,35224,35100,34914,36070,36042,36221,4464,4599,4600,4471,4542,4613,13887,13694,13842,17332,17433,17266,16997,17066,17174,16997,17174,16748,24743,24610,24692,37194,37059,36951,16118,15788,16309,18099,18119,18191,23331,23587,23360,23512,23587,23331,38739,38278,38065,38098,38223,37955,5641,5689,5649,5157,5571,5252,27795,28092,28462,4284,4320,4356,4284,4356,4186,22304,22788,22700,22161,22194,21714,23002,22971,22765,25726,25927,25739,27561,27746,27785,37605,37508,37501,37859,37665,38350,6321,7946,6960,7737,7624,9031,35361,35231,35359,33111,33041,33971,5772,6747,5839,29887,29594,29890,29387,29544,29357,4464,4600,4597,18603,18483,18470,18612,18483,18603,23002,22765,22890,33661,33425,33772,33919,34130,34051,32104,32251,32082,31692,31845,31694,31692,31529,31631,8418,8348,8412,8064,7899,7989,8813,8579,8960,8679,8579,8813,8810,8813,8924,8810,8924,8801,9247,9276,9151,9151,9098,9074,35922,35710,35874,11101,10697,10926,26940,26876,27037,26940,26858,26876,25705,25367,25716,5472,5775,5701,4919,4815,4966,14061,13887,13966,17438,17713,17675,13814,13993,13683,15343,15548,15135,27690,27795,28462,37156,37155,36899,37176,37273,37359,32104,32082,32003,34470,34409,34229,34229,34409,34302,4632,4623,4730,4666,4815,4919,4186,4356,4335,17644,17438,17675,18971,18317,17605,17332,17266,17191,23036,23031,23268,22194,22267,22396,23992,24168,23913,24993,25090,24798,25578,25665,25739,7498,7851,7525,6329,6158,6164,9350,9433,9340,10615,10564,10504,10816,10989,10877,34979,34781,34961,32871,32855,32759,35461,35361,35359,8410,8348,8418,7525,7851,7739,33038,32916,32862,6434,6796,6784,5747,5765,5837,36042,36070,35865,36264,36097,36241,4632,4730,4709,16412,16610,16497,17191,17266,17169,16331,16610,16412,24993,24798,24847,23022,23036,23219,22997,23036,23022,38346,38432,38316,38611,38473,38244,38126,37940,37986,4455,4567,4499,4455,4499,4390,16873,16997,16748,24543,24256,24479,24809,24743,24692,38029,38126,37986,38141,38126,38029,5013,5157,5252,5266,5326,5423,5165,5157,5057,27191,27142,27228,27191,27228,27302,37559,37581,37547,37547,37581,37346,37405,37447,37392,9898,10311,10024,19185,19856,19249,18971,17605,17710,22267,22315,22396,32916,32855,32871,4260,4058,4477,4213,4304,4138,4321,4216,4260,4181,4490,4168,4490,4377,4168,4479,4245,4251,5266,5423,5272,20688,20668,20562,20386,20241,20280,20096,19935,19938,19938,19935,19920,19920,19741,19562,20789,20668,20688,20789,21004,21158,21201,21276,21158,21276,21322,21158,21353,21322,21276,21382,21322,21353,21382,21529,21740,21529,21713,21740,20792,20829,20861,20861,20990,20982,22194,22161,22267,22267,22288,22315,20713,20829,20792,20632,20654,20713,20564,20654,20632,20550,20654,20564,20550,20564,20411,20550,20411,20476,20411,20387,20476,27399,27416,26942,37508,37329,37501,38457,38594,38481,38481,38540,38427,38507,38607,38416,38647,38594,38457,38589,38330,38462,38589,38462,38682,38462,38452,38571,38387,38559,38452,4479,4303,4245,9710,9722,10066,9566,9629,9561,20476,20387,20163,21740,21713,21811,20654,20829,20713,4815,4684,4833,20444,20476,20163,25354,25184,24690,25924,25716,25865,25169,25380,25287,31390,31289,32302,30551,30136,30443,30027,29887,30070,30070,29887,29890,32229,32104,32145,31631,31529,31542,38705,38540,38481,38479,38606,38307,5765,5650,5701,5586,5650,5765,5747,5691,5586,5786,5772,5839,5637,5530,5336,5899,6161,6164,5696,5772,5786,12926,13129,13266,13514,13657,13683,12680,12806,12832,12607,12635,12531,20668,20340,20386,20829,20990,20861,28872,28825,28842,28967,28825,28872,36487,36596,36401,36981,37194,36951,36770,36596,36716,38540,38565,38427,38387,38525,38559,5323,5530,5375,20340,20241,20386,20990,21014,21057,12759,12606,12807,11115,11064,10936,12759,12807,12855,12807,13141,12855,12279,12607,12531,29398,28973,29376,20241,20200,20280,38565,38569,38396,4315,4522,4410,4675,4494,4138,4469,4464,4597,4469,4597,4480,13129,13410,13266,17621,17605,17478,17191,17169,17066,19185,19249,19209,17621,17478,17473,22387,22407,22315,22315,22407,22487,24543,24479,24610,24168,24271,24170,24163,24271,24168,23825,23652,23587,23825,23587,23696,30691,30532,30775,29541,29398,29376,38232,38223,38098,15079,14930,14984,16249,16412,15773,26453,26027,26573,26453,26573,26516,21849,21740,21811,17915,17797,17778,17755,17797,17915,23203,23057,22971,4185,4320,4139,4289,4370,4214,14728,14566,14494,14728,14494,14444,23002,23203,22971,29080,29257,29015,29306,29387,29357,29544,29694,29517,29080,29015,28962,37533,37420,37440,38513,38492,38236,38387,38512,38525,38353,38323,38077,9629,9722,9710,21912,21849,21811,33661,33461,33425,31957,32003,31845,38641,38685,38525,5326,5339,5375,5165,5266,5272,11072,11177,11305,11068,11177,11072,27099,26940,27037,27690,27415,27505,27690,27505,27795,5489,5472,5701,4971,5250,5021,13410,13657,13514,37648,37492,37645,38284,37665,37955,19996,19935,20096,22052,21912,21811,38644,38607,38507,38512,38488,38550,4304,4294,4401,4213,4294,4304,4480,4597,4542,4626,4632,4709,7851,7922,7739,12216,12129,12409,25090,25169,25153,24993,25169,25090,29617,29398,29541,29283,29387,29306,31692,31957,31845,31651,31631,31542,31276,31238,31125,31125,31001,31293,31001,31120,31293,35090,34979,34961,35090,34961,35100,14051,14136,13993,17072,17191,17066,16914,16873,16748,16914,16748,16561,27099,27037,27142,37648,37645,37782,19935,19923,19920,38607,38590,38416,38550,38488,38527,30602,30516,30409,13657,13814,13683,4315,4410,4369,6398,6294,6329,6434,6294,6398,6434,6784,6375,36221,36042,36094,35370,35231,35361,35431,35100,35224,16182,16118,16309,17161,17687,17438,19146,19209,19075,25398,25501,25380,25380,25501,25578,25927,26088,26065,4350,4510,4435,7899,7922,7989,17797,17644,17675,17755,17644,17797,18099,18191,18329,38278,38256,38090,38377,38256,38278,4289,4308,4370,4584,4613,4623,7796,7899,8064,36186,36289,36094,36400,36264,36241,36462,36226,36782,36462,36591,36467,18839,19014,18994,4245,4303,4206,4303,4185,4206,19923,19741,19920,27255,27191,27302,27099,27191,27234,37508,37448,37190,37257,37246,37156,5156,5339,5326,13887,13964,13694,15169,15366,15764,13775,14051,13993,28549,28092,28352,33122,33111,33224,35370,35361,35461,5616,5624,5180,4626,4709,4684,4541,4623,4632,10531,10572,10364,12279,12680,12607,22052,21980,21912,22156,21980,22052,25983,26088,25927,26026,25924,25865,26716,26573,26858,26716,26858,26893,30937,30876,30943,31176,30907,31119,37782,37645,37806,37508,37515,37448,4343,4350,4435,4313,4350,4343,18329,18419,18483,38613,38353,38077,38513,38236,38432,18839,18720,18647,18734,18720,18839,38513,38432,38556,4583,4584,4623,4583,4623,4541,37990,37709,37481,38126,38250,37940,6230,6158,6329,14728,14984,14930,15079,15062,15135,15062,14984,14915,16412,15884,15773,16469,16331,16249,26893,26858,26940,4381,4320,4185,6625,6784,6854,6294,6230,6329,22156,22158,22181,31218,31176,31119,31330,31119,31308,35461,35359,35543,36596,36770,36585,37525,37533,37447,36558,36202,36795,38527,38488,38473,13609,13814,13657,13609,13775,13814,13814,13775,13993,12897,13129,12926,12897,12926,12806,12680,12832,12607,17473,17478,17433,17336,17433,17332,17066,16997,17072,23825,23992,23913,24734,24777,24478,23842,23992,23825,12606,12216,12409,13373,13646,13349,11682,11558,11764,4407,4599,4464,4414,4480,4542,17152,17161,17438,17561,17438,17644,17332,17191,17235,23036,23268,23219,24757,24543,24610,24757,24610,24743,25184,25354,25386,13349,13646,13521,29257,29283,29306,29590,29694,29544,28962,28636,28470,36318,35937,35898,37535,37359,37448,37448,37359,37273,4185,4139,4176,8810,8726,8813,8579,8410,8418,8348,8276,8265,8801,8924,8995,22181,22158,22304,22181,22304,22281,38586,38527,38473,4231,4290,4359,4252,4359,4294,8570,8477,8579,8891,9042,8926,8891,8801,8995,18720,18700,18647,18734,18700,18720,37447,37533,37440,38054,37990,37481,37525,37447,37724,8477,8410,8579,8926,9042,9151,23203,23512,23331,23529,23512,23543,33038,33035,32916,32916,32969,32855,32302,31289,31839,34989,34781,34979,29325,29283,29257,37238,36970,37155,36219,35922,36070,6138,6230,6294,32311,32759,32915,4308,4335,4352,33111,33035,33038,38611,38244,38609,8226,8276,8348,7899,7739,7922,33035,32969,32916,6730,6625,6854,6434,6228,6294,6518,6625,6578,11572,11064,11115,10162,10311,10390,11826,11951,11943,23992,24068,24168,25593,25665,25501,23842,24068,23992,30602,30802,30516,31658,31651,31542,30988,30802,30937,35922,35874,36070,35991,35666,35688,38605,38250,38126,4584,4471,4613,4626,4684,4616,24734,24478,24511,25983,26229,26088,4290,4315,4369,4231,4315,4290,11682,11413,11558,38499,38432,38346,38609,38244,38386,38499,38346,38353,10964,11068,11072,10939,11068,10964,38809,38606,38479,38609,38386,38492,4616,4684,4666,5157,5165,5272,5266,5156,5326,5013,5252,5100,10138,10531,10364,14051,14341,14290,14428,14341,13945,26088,26229,26199,25665,25578,25501,35580,35461,35543,35079,34979,35090,8276,8111,8265,15331,15169,15764,26716,26516,26573,26110,25924,26026,26689,26516,26716,27099,27142,27191,26317,26492,26347,27584,27746,27561,37648,37654,37492,37782,37654,37648,38223,38201,37955,37815,37645,37729,38238,38201,38223,38232,38098,38256,23512,23549,23587,23529,23549,23512,26225,26026,26453,9722,9744,10066,9629,9675,9722,9566,9675,9629,9566,9561,9388,14007,13964,13887,13962,13964,14007,27454,27746,27584,37378,37246,37257,37370,37257,37359,22997,22788,23036,21613,21415,21308,22890,22765,22594,15169,14877,15366,37533,37559,37420,37567,37559,37533,11558,11413,11145,29066,28967,29007,29007,28967,28872,28825,28967,28352,29887,29698,29495,29986,29698,29887,29590,29544,29387,35079,34989,34979,35079,35090,35431,36415,36318,35898,36114,35495,36107,4370,4308,4352,4407,4464,4469,23268,23434,23219,22548,22487,22407,31390,31330,31308,30792,30691,30889,30889,30691,30775,31394,31330,31390,25924,25705,25716,25398,25380,25169,4441,4407,4469,4441,4469,4480,24068,24163,24168,24226,24163,24068,33961,33919,33639,35810,35584,35750,33818,33461,33661,38422,38232,38256,22700,22281,22304,27234,27191,27255,27302,27415,27255,37600,37515,37508,37584,37525,37724,4350,4390,4510,4455,4371,4764,4691,5019,4984,4313,4390,4350,5641,5602,5689,5689,5696,5786,5772,5672,6084,6084,6321,6960,5564,5602,5641,5323,5375,5339,5602,5696,5689,9675,9744,9722,12759,12603,12606,13061,12855,13141,13061,13141,13131,12935,13061,13013,23549,23696,23587,23529,23696,23549,37550,37370,37359,12855,12603,12759,6625,6518,6784,6730,6854,6601,10162,10390,10208,11943,12204,12129,11145,11413,11177,10697,11101,10972,10697,10972,10531,25318,25398,25169,24511,24375,24271,31037,30917,31176,10390,10564,10408,23947,24118,24256,22114,22181,22281,31118,31037,31176,4626,4541,4632,4483,4471,4584,4666,4684,4815,25318,25169,25303,37919,37346,37581,38141,38162,38126,18971,19146,19075,19027,19146,18971,4181,4151,4216,4216,4132,4260,4168,4151,4181,4168,4377,4072,4377,4251,4143,4251,4092,4143,4151,4132,4216,20668,20645,20340,20340,20237,20241,20241,20237,20200,20200,19996,20096,19935,19996,19923,19923,19801,19741,19741,19499,19282,20696,20645,20668,20696,20668,20789,20696,20789,20818,20696,20818,20576,21158,20978,20789,21322,21382,21468,21382,21740,21617,21740,21849,21765,21849,21912,21765,21765,21912,21980,20829,20979,20990,20990,20979,21014,21014,21152,21308,20654,20712,20829,20550,20712,20654,20676,20712,20550,20676,20550,20444,20550,20476,20444,33179,33122,33224,35431,35224,35370,38565,38683,38569,38569,38644,38507,38607,38631,38590,38590,38754,38479,38540,38683,38565,38594,38705,38481,38647,38705,38594,38647,38457,38589,38647,38589,38734,38462,38571,38682,38571,38697,38682,38559,38697,38571,38685,38697,38559,38685,38559,38525,36289,36186,36264,35580,35443,35461,35461,35443,35370,38641,38525,38512,4251,4145,4092,20883,20979,20829,26229,26317,26347,27178,27399,26942,26093,26317,26229,25983,25927,25726,37732,37605,37501,37815,37729,37948,38735,38683,38540,20459,20237,20340,20979,21008,21014,25726,25739,25665,31330,31218,31119,31394,31218,31330,30988,31001,30910,31950,31957,31692,30988,30910,30802,38550,38641,38512,14984,15062,15079,14915,14984,14873,26516,26426,26453,25587,25503,25705,26661,26689,26812,17235,17336,17332,18901,19027,18971,16914,16997,16873,16469,16610,16331,24543,24306,24256,24521,24306,24543,24163,24282,24271,24226,24282,24163,36462,36467,36400,36591,36462,36600,37146,36970,37238,38683,38681,38569,4242,4186,4335,4251,4245,4145,4138,4494,4297,4315,4313,4343,14877,14328,14604,13131,13141,13373,19146,19185,19209,17710,17605,17621,22340,22387,22315,23703,23842,23696,22288,22267,22161,27454,27399,27468,17764,17755,17915,17161,16896,16309,14491,14877,15169,17764,17915,18013,38967,38377,38278,4246,4242,4335,4214,4370,4523,22114,22281,22360,23606,23219,23434,38566,38609,38492,38563,38499,38353,38556,38499,38563,25755,25726,25665,5265,5323,5339,4691,4984,4364,20126,19996,20200,17764,17698,17755,37515,37523,37448,37600,37708,37675,38681,38644,38569,38527,38726,38550,38550,38726,38641,7796,7739,7899,7525,7297,7498,4368,4541,4626,15884,15741,15773,25386,25354,25367,25503,25367,25705,4483,4584,4583,4407,4386,4599,5156,5266,5165,12048,11943,12129,13362,13657,13410,14341,14444,14494,13085,13410,13129,12897,12806,12680,12897,12680,12733,16561,16748,16610,24920,24809,24692,24734,24847,24798,25398,25593,25501,24679,24847,24734,29698,29617,29541,29662,29617,29698,30937,30802,30602,29519,29590,29387,29519,29387,29283,29325,29257,29080,28962,28470,28799,36467,36405,36264,38299,38162,38141,38644,38631,38607,38483,38422,38377,4245,4105,4145,4246,4335,4308,4213,4219,4294,4135,4219,4213,22387,22548,22407,22340,22548,22387,10738,10615,10816,10685,10738,10816,10685,10816,10877,11145,11177,11068,10406,10697,10531,38527,38586,38726,7198,7297,7525,30691,30551,30532,30792,30551,30691,30792,30889,31037,31651,31692,31631,32104,32229,32251,8748,8726,8801,8748,8679,8726,8726,8679,8813,8477,8404,8410,8410,8365,8348,8276,8197,8111,8111,8098,8064,8748,8801,8739,25933,25705,25924,8739,8801,8891,4360,4386,4407,5276,5624,5428,4754,4666,4919,4316,4482,4146,5276,5428,5241,5428,5472,5241,5701,5650,5494,5765,5747,5586,8439,8404,8477,14428,14444,14341,17473,17609,17621,17166,17235,17191,17755,17698,17644,18612,18603,18700,23696,23842,23825,24282,24511,24271,23512,23203,23202,27099,27003,26940,27255,27415,27690,37592,37523,37515,37370,37378,37257,37943,37729,37859,38232,38238,38223,38483,38238,38232,4206,4105,4245,7163,7624,7737,9675,9663,9744,6220,7624,7163,19996,19801,19923,21366,21613,21308,38726,38586,38663,10738,10408,10615,35580,35543,35666,4219,4252,4294,4142,4252,4219,5747,5837,5691,8404,8365,8410,8882,8926,9151,22548,22613,22594,22340,22613,22548,33111,33122,33035,33035,33179,32969,32915,32759,32855,33111,33341,33224,32462,32701,33135,36381,36289,36264,35629,35580,35666,37565,37378,37370,38566,38492,38513,4206,4158,4105,19801,19719,19741,8365,8226,8348,26549,26426,26516,26549,26516,26689,37806,37815,37948,37732,37501,37654,37605,37600,37508,5899,6164,5998,6164,6158,5998,13061,12935,12855,12855,12804,12603,12362,12216,12606,13131,13373,13193,12166,12355,12064,11860,12064,11889,5696,5672,5772,5580,5672,5696,5580,5696,5602,29066,29007,29189,28799,28470,28699,5484,5641,5637,13646,13694,13647,13070,13085,13129,5021,5250,5311,15062,15343,15135,14873,14984,14728,37559,37697,37581,37699,37697,37559,37567,37533,37525,4206,4185,4158,21980,22156,22114,22156,22181,22114,21613,21714,21415,33818,33961,33639,34130,34470,34229,4364,4984,4562,4056,4313,3867,4414,4441,4480,4482,4483,4583,4482,4583,4541,9579,9566,9388,10050,10138,10211,24757,24521,24543,24306,23947,24256,25184,24920,24692,24809,24920,24830,32966,32855,32969,5494,5489,5701,13647,13694,13964,13085,13362,13410,14429,14428,13956,4252,4231,4359,4082,4231,4252,18813,18734,18839,38663,38586,38611,38628,38566,38513,38556,38432,38499,5276,5180,5624,5067,5021,5311,5083,5180,5276,5323,5341,5530,4963,5156,5165,8197,8098,8111,7739,7405,7525,10939,10964,10926,17698,17561,17644,17691,17561,17698,17473,17433,17336,24209,23947,24306,27399,27454,27584,27468,27399,27178,36322,36221,36094,4158,4185,4176,12362,12606,12603,11064,11572,11826,29345,29325,29080,30172,29989,30289,4414,4542,4438,5489,5425,5472,17410,17473,17336,17072,17166,17191,17072,16997,16914,24757,24743,24809,24226,24511,24282,25521,25593,25398,37206,37194,36981,37116,36981,36770,36716,36596,36558,4939,5021,4915,27234,27003,27099,27057,27003,27234,37523,37535,37448,37732,37654,37844,37584,37567,37525,10697,10809,10926,10939,10809,10620,25828,26093,25983,25983,26093,26229,27178,26942,26492,25169,24993,25072,6601,7155,7203,6518,6375,6784,33961,34188,33919,35443,35547,35370,35629,35666,35759,4320,4284,4139,6435,6375,6518,38663,38611,38781,4139,4284,4141,4188,4246,4308,4188,4308,4244,4308,4289,4244,9566,9663,9675,32145,32104,32003,32145,32003,31957,5998,6158,5965,12216,12048,12129,29325,29519,29283,5233,5341,5323,31658,31542,31276,31836,31651,31658,4284,4186,4141,22788,22997,22700,22997,23022,23108,38738,38611,38609,14643,14873,14728,14341,14051,13945,27234,27255,27187,37585,37535,37523,4438,4542,4471,4368,4626,4616,4270,4360,4318,4341,4407,4441,17229,17336,17235,19053,19098,19027,38377,38422,38256,37943,37859,38115,38696,37318,38606,26426,26225,26453,25150,24920,25184,26365,26225,26426,26549,26689,26661,37815,37806,37645,37600,37592,37515,37955,38201,38284,5965,6158,6230,11665,11860,11889,11665,11889,11558,26365,26549,26274,35991,35688,35922,36289,36322,36094,36405,36381,36264,36482,36381,36405,36591,36405,36467,37379,37246,37378,4244,4289,4214,4141,4186,4028,16469,16561,16610,17166,17229,17235,15773,15741,15548,18734,18612,18700,18701,18612,18734,22613,22890,22594,24824,24679,24658,23123,22890,23118,25072,24993,24847,4186,4242,4028,5156,5265,5339,13928,13962,14007,13928,14007,14328,13647,13962,13858,23108,23022,23219,31960,32145,31957,32462,32373,32701,37428,37379,37378,4438,4471,4483,4292,4455,4390,5013,5057,5157,5175,5233,5265,16850,17072,16914,26110,25933,25924,38260,38201,38238,38421,38260,38238,8098,7796,8064,6495,6653,6502,15037,15343,15062,14643,14728,14444,23947,23606,23535,23604,23606,23947,23202,23203,23002,3926,4138,4297,4227,4288,4313,10738,10510,10408,10084,10024,10162,10811,11064,10664,10809,10939,10926,10973,10729,10993,6730,6653,6625,6375,6228,6434,6578,6653,6495,29989,29752,30289,4754,4919,4955,4799,4955,4971,10208,10390,10408,10162,10024,10311,8625,8748,8739,5542,5580,5602,5742,6321,6084,5542,5602,5564,5484,5637,5398,12216,12130,12048,12935,12804,12855,12959,12804,12935,13013,13061,13131,13013,13131,13193,18612,18463,18483,18701,18463,18612,22890,22963,23002,23123,22963,22890,29645,29590,29519,29040,29345,29080,28225,27785,27746,36490,36322,36289,38563,38353,38650,38566,38630,38609,13193,13373,13349,13569,13609,13657,13085,13208,13362,12897,13070,13129,12733,13070,12897,5586,5494,5650,5489,5350,5425,5697,5691,5837,5697,5837,5899,36859,36716,36558,36859,36558,36795,5336,5530,5341,5541,6084,5672,13350,13193,13349,13070,13208,13085,37535,37550,37359,37675,37592,37600,37567,37699,37559,38242,38212,37990,37990,38212,37890,37405,37392,37059,37213,37059,37194,31950,31960,31957,32373,32251,32701,31950,31692,31836,12365,12362,12603,10811,10877,10936,22224,22288,22161,16477,16561,16469,16477,16469,16249,4313,4288,4390,4227,4313,4056,28616,28225,28436,37238,37155,37246,36381,36490,36289,37238,37246,37379,4270,4299,4360,4316,4438,4483,4414,4438,4358,24830,24757,24809,24336,24209,24306,25386,25367,25503,24511,24679,24734,24226,24068,23842,25587,25386,25503,25318,25375,25398,25593,25755,25665,25303,25375,25318,4126,4242,4246,4214,4523,4236,4523,4386,4236,8625,8679,8748,8625,8570,8679,8679,8570,8579,8404,8345,8365,8365,8345,8226,8226,8197,8276,7655,7663,7796,8891,8926,8739,8739,8926,8799,8570,8439,8477,8882,9151,8983,33961,33969,34188,33818,33969,33961,32251,32229,32385,4126,4246,4129,14967,15062,14915,19027,19098,19146,19053,19027,18901,22288,22340,22315,26225,26110,26026,25684,25587,25705,26549,26365,26426,26689,26716,26812,5233,5323,5265,5246,5336,5341,13962,13647,13964,13338,13657,13362,14741,14967,14873,14873,14967,14915,37229,37238,37396,37206,37213,37194,4168,4026,4151,4151,4026,4132,4132,4058,4260,4006,4026,4168,4006,4168,4072,4377,3938,4072,4143,3938,4377,4092,4087,4143,4145,4087,4092,3976,4087,4145,3976,4145,4105,8439,8345,8404,20712,20791,20829,20979,21077,21008,21008,21100,21014,21613,21527,21714,21714,22123,22161,22288,22303,22340,20444,20163,19756,38647,38758,38705,38705,38735,38540,38683,38755,38681,38681,38772,38644,38644,38837,38631,38917,38696,38606,38734,38758,38647,38734,38589,38682,38734,38810,38830,38682,38810,38734,38697,38685,38747,38685,38748,38747,9836,10066,9744,20645,20576,20340,20237,20126,20200,19996,19837,19801,19801,19837,19719,18318,18329,18463,20696,20576,20645,20818,20789,20978,21158,21131,20978,21740,21765,21617,21617,21765,21876,20676,20791,20712,26893,26940,27003,37675,37585,37592,37943,37948,37729,38115,37948,37943,4158,4017,4105,20576,20459,20340,20791,20883,20829,37585,37550,37535,37585,37523,37592,38801,38735,38705,4158,4176,4017,9701,9836,9744,32385,32229,32236,31836,31692,31651,38735,38755,38683,38685,38641,38748,8983,9151,9074,33122,33179,33035,32993,33179,33146,32229,32145,32236,4261,4371,4455,10024,9543,9898,32222,32145,31960,6653,6578,6625,6435,6578,6495,10811,10685,10877,10811,10664,10715,30988,31120,31001,29989,29694,29752,21077,21100,21008,4138,4135,4213,4038,4135,4138,4288,4292,4390,4225,4292,4288,4803,4990,5100,8345,8197,8226,9151,9276,9098,15600,15773,15548,17200,17152,17438,13928,14328,13975,18013,17915,18099,19098,19185,19146,17710,17621,17609,26812,26893,27057,27057,26893,27003,33661,33969,33818,35284,34549,34409,37770,37699,37567,37697,37699,37817,38754,38590,38631,5246,5233,5145,18463,18329,18483,19014,19282,18994,22963,23202,23002,24824,24847,24679,23123,23202,22963,38688,38630,38566,38748,38641,38794,38613,38077,38250,20147,20126,20237,21100,21152,21014,31082,31120,30988,34470,34130,34188,38755,38772,38681,9098,9276,9350,17194,17166,17072,17194,17229,17166,16527,16477,16430,32993,32966,32969,3611,4058,4132,21152,21305,21308,29752,29694,29590,29752,29590,29645,29346,29519,29325,9663,9701,9744,9566,9579,9663,9227,9561,9354,21305,21366,21308,38641,38726,38794,4135,4142,4219,4033,4142,4135,9121,9098,9350,4990,5057,5013,25375,25521,25398,27454,27468,27746,25303,25521,25375,31950,31971,31960,31658,31276,31385,37654,37782,37937,37428,37238,37379,9189,9340,9192,10239,10208,10408,31344,31118,31176,30324,30027,30070,31538,31394,31390,31538,31390,32302,38837,38754,38631,38794,38726,38663,4129,4246,4117,4299,4386,4360,18329,18197,18099,18318,18197,18329,17573,17710,17609,17194,17072,16850,4341,4441,4414,5580,5554,5672,5363,5542,5564,5363,5564,5484,5398,5637,5336,17764,17691,17698,17620,17691,17764,17573,17609,17473,28799,28901,28962,28961,28901,28799,5421,5494,5373,5425,5241,5472,4915,5021,5067,5598,5586,5691,20016,19837,19996,21876,21765,21980,21876,21980,22101,5818,5697,5899,5818,5899,5998,4246,4188,4117,4017,4176,4030,19661,19741,19719,38688,38566,38628,26270,26110,26225,26270,26225,26365,26270,26365,26274,5494,5350,5489,5221,5398,5336,5246,5341,5233,13193,13221,13013,13013,12959,12935,12365,12331,12362,13521,13350,13349,13208,13338,13362,14643,14444,14429,13231,13338,13208,13231,13208,13070,4176,4139,4030,6578,6435,6518,6653,6730,6502,10685,10586,10738,11210,11943,12048,14051,13775,13945,16226,16157,16204,37898,37782,37806,12362,12331,12216,12130,12331,12237,29040,29080,28962,35580,35547,35443,35079,35448,34989,35759,35666,35929,9354,9157,8835,38260,38284,38201,37708,37605,37732,38395,38284,38260,38421,38238,38458,26971,26492,26795,28961,29040,28901,38162,38361,38126,37919,37581,37832,13647,13521,13646,13487,13521,13647,13928,13975,13858,13338,13569,13657,19837,19661,19719,31836,31971,31950,31385,31276,31293,37238,37229,37146,36600,36462,36895,37428,37378,37539,4030,4139,4141,4117,4188,4018,18813,18707,18734,18873,18707,18813,38850,38781,38611,38628,38513,38556,38628,38556,38733,5021,4939,4971,5026,5067,5180,14429,14444,14428,5831,5818,5998,36462,37224,36895,36219,36070,36221,4292,4261,4455,4839,4803,4721,4225,4261,4292,18984,19098,19053,17410,17573,17473,4358,4341,4414,4358,4438,4316,4483,4482,4316,9543,9340,9433,9236,9340,9189,17455,17438,17561,17229,17410,17336,16527,16914,16561,19661,19622,19741,25684,25705,25854,25386,25324,25184,5316,5241,5425,5175,5265,5156,4030,4141,3997,19622,19499,19741,3997,4141,4028,4018,4188,4244,4129,4117,4041,4236,4386,4241,18707,18701,18734,18197,18013,18099,17691,17455,17561,18740,18701,18707,30378,30409,30289,29575,29645,29519,36591,36482,36405,38738,38609,38630,38675,38556,38563,18248,18013,18197,5083,5026,5180,13945,13775,13716,35205,34470,34980,10334,10406,10531,9836,10050,10211,9664,10050,9836,9701,9663,9491,25854,25705,25933,26274,26549,26658,37832,37581,37697,37832,37697,37817,4988,5175,5156,10715,10586,10685,9236,9350,9340,10715,10685,10811,13858,13810,13714,13716,13775,13609,24824,25072,24847,23703,23696,23529,30937,30951,30988,31664,31833,31658,30943,30951,30937,30409,30516,30289,38212,38299,38141,38162,38299,38420,4318,4360,4407,17620,17455,17691,25446,25324,25386,23970,23604,23947,25446,25386,25587,31833,31971,31836,32385,32701,32251,31833,31836,31658,8503,8570,8625,8503,8522,8570,8570,8522,8439,8439,8367,8345,8345,8367,8197,8503,8625,8582,8799,8926,8882,8799,8882,8983,8799,8983,8751,8983,9074,8977,12020,12166,12064,11440,11665,11558,11145,11068,10973,26893,26812,26716,26658,26812,26943,4341,4318,4407,4482,4541,4368,35629,35547,35580,35736,35547,35629,38483,38232,38422,38091,37898,37948,8522,8367,8439,7655,7796,8098,6601,7203,6232,4242,4126,4028,6149,6228,6375,10973,11068,10939,22191,22123,22066,23118,22890,22613,30378,30289,29752,38738,38630,38688,36716,37116,36770,37213,37405,37059,37307,37116,36716,4241,4386,4299,3986,4315,4231,5305,5316,5350,5350,5316,5425,5697,5598,5691,5526,5598,5570,5598,5697,5570,9069,9074,9098,23606,23604,23219,24306,24521,24336,23202,23543,23512,23270,23543,23202,29345,29346,29325,28901,29040,28962,28961,28799,28699,13350,13221,13193,13465,13221,13350,13465,13350,13521,13338,13427,13569,13569,13716,13609,13271,13231,13044,26123,25933,26110,5093,5083,5276,5186,5276,5241,4823,4799,4971,5026,4915,5067,4914,4915,5026,22123,22224,22161,37756,37565,37550,37708,37600,37605,37898,37806,37948,31118,30792,31037,29189,29007,29398,31557,31538,31646,5421,5350,5494,13487,13465,13521,13271,13427,13338,32966,32915,32855,33179,32993,32969,33111,34429,33341,37116,37206,36981,12331,12130,12216,12365,12603,12804,12020,12064,11860,17397,17410,17229,18984,19053,18901,17536,17410,17397,16527,16561,16477,24336,24521,24640,24058,24226,23842,29645,29800,29752,29604,29346,29460,30324,30136,30595,28967,28968,28352,16226,16477,16249,16157,16249,15773,3926,4038,4138,4142,4082,4252,9121,9069,9098,9121,9350,9236,18984,19185,19098,18971,17710,18901,32993,32915,32966,4227,4225,4288,4803,5019,4649,4056,4225,4227,10586,10510,10738,10811,10936,11064,23543,23703,23529,23429,23703,23543,38671,38613,38250,38733,38738,38688,5246,5256,5336,5439,5580,5542,5145,5256,5246,37206,37405,37213,15062,14967,15037,15548,15343,15346,16157,16121,16204,10483,10809,10697,11145,11440,11558,11665,12020,11860,11506,12020,11665,29346,29575,29519,26270,26123,26110,26658,26549,26661,38115,37859,38348,23604,23108,23219,22997,23108,22984,22303,22613,22340,4892,4971,4939,9543,10024,10020,9227,9388,9561,8835,9157,9082,4126,4129,4048,4028,4126,4048,38734,38822,38758,38758,38801,38705,38735,38861,38755,38755,38836,38772,38772,38837,38644,38754,38790,38479,38830,38822,38734,38682,38697,38810,38697,38819,38810,4026,3611,4132,4058,3926,4297,4006,3994,4026,3877,3994,4006,3877,4006,4072,3938,4143,3921,4143,4087,3921,4087,3976,3921,20576,20500,20459,20459,20303,20237,20126,20016,19996,19837,19783,19661,19661,19630,19622,19622,19630,19499,20818,20500,20576,20634,20500,20818,21158,21322,21131,32685,32701,32385,31385,31293,31120,38822,38801,38758,4823,4892,4701,4915,4892,4939,5189,5186,5241,13928,13858,13962,14328,14116,13975,20500,20440,20459,37565,37370,37550,37403,36782,37146,36490,36381,36482,38801,38861,38735,4914,5026,4934,6228,6138,6294,6096,6138,6228,6061,6138,6096,30595,30136,30551,4197,4241,4299,4029,4244,4214,4195,4318,4341,4316,4341,4358,21468,21382,21617,24209,23970,23947,24640,24521,24757,25150,25184,25324,31359,31385,31120,31082,30988,30951,35547,35431,35370,35534,35431,35547,38669,38483,39306,38421,38395,38260,38739,38036,38696,38861,38836,38755,38697,38747,38819,25521,25755,25593,25669,25755,25521,25303,25169,25072,20440,20303,20459,21100,21085,21152,21152,21231,21305,21305,21237,21366,21366,21527,21613,22123,22191,22224,20883,21077,20979,20961,21077,20883,20961,20883,20791,20961,20791,20598,4197,4299,4270,4048,4129,4041,4105,4017,3976,19499,18994,19282,18306,18318,18463,17239,17200,17455,19297,18994,19499,19756,20163,19856,18901,17710,17649,20303,20147,20237,21077,21085,21100,38819,38747,38748,18306,18463,18495,23123,23126,23202,23118,23126,23123,38650,38675,38563,38947,38819,38748,16226,16430,16477,16753,16850,16914,21085,21231,21152,25129,25150,25202,25150,25324,25236,10020,10024,10084,9084,9256,9227,32236,32145,32222,33135,33455,33425,33661,33772,33969,35277,35284,34470,16753,16914,16527,25129,24830,24920,24658,24679,24511,24915,24824,24706,24058,23842,23703,38465,38395,38421,38420,38361,38162,38916,38733,38926,38242,38299,38212,4017,3886,3976,20147,20016,20126,21231,21237,21305,22224,22303,22288,38794,38663,38832,5072,5093,5276,13221,12959,13013,13106,12959,13221,13106,13221,13465,29604,29575,29346,29710,29800,29575,28699,28470,28225,31443,31218,31394,3949,4033,4135,3949,4135,4038,5174,5189,5241,5186,5072,5276,5373,5494,5586,5526,5586,5598,6061,5965,6230,10556,10510,10586,10454,10510,10556,19756,19856,19185,17649,17710,17573,17649,17573,17536,29986,29887,30027,29662,29398,29617,29979,29986,30108,30303,30027,30324,30943,31082,30951,30937,30602,30876,36395,36221,36322,36490,36395,36322,36599,36482,36591,36207,35898,35728,35495,36065,36107,38733,38688,38628,38986,38837,38772,10084,10162,10208,12278,12279,11733,12166,12279,12531,13444,13569,13427,12279,12166,11733,17152,16920,17161,17455,17200,17438,17620,17764,17630,18318,18248,18197,18306,18248,18318,4799,4754,4955,4727,4754,4799,4823,4971,4892,17536,17573,17410,10454,10239,10408,26363,26123,26270,26363,26270,26274,26658,26661,26812,25828,25983,25726,28616,28699,28225,25828,25726,25755,35678,35534,35547,33111,33971,34429,9491,9663,9579,10334,10531,10138,4017,4030,3874,20016,19788,19837,37937,37844,37654,37750,37550,37585,37937,37782,37898,37770,37567,37584,37919,38054,37481,38837,38790,38754,3925,4030,3997,4122,4214,4236,4033,4082,4142,3978,4082,4033,18994,18873,18813,18866,18873,18994,5256,5221,5336,5439,5554,5580,5097,5221,5256,5145,5233,5175,5145,5027,5097,13714,13487,13647,37396,37146,37229,37445,37396,37238,37445,37238,37428,25978,25854,25933,25873,25828,25784,38423,38054,37919,9256,9388,9227,19788,19783,19837,5570,5697,5818,6138,6061,6230,6293,6375,6435,17397,17229,17353,16650,16753,16527,38574,38242,37990,38451,38420,38299,38671,38650,38613,8582,8625,8739,8522,8195,8367,7655,8098,8197,8582,8739,8585,8739,8799,8740,8799,8751,8740,37864,37708,37732,37804,37770,37824,9074,9069,8977,4149,4122,4236,4149,4236,4241,3925,3997,3902,38790,38809,38479,10122,10084,10208,9189,9125,9236,3960,3997,4028,4018,4041,4117,4934,5026,5083,5114,5189,5174,4963,5165,5057,4963,5057,4856,5057,4990,4856,8977,9069,9056,13858,13714,13647,14328,14488,14211,13271,13338,13231,13444,13716,13569,13945,13956,14428,14741,14873,14643,18873,18740,18707,18866,18740,18873,22984,22700,22997,22984,23108,23314,29821,29662,29698,29821,29698,29986,39102,38739,38696,4195,4197,4270,4195,4270,4318,17359,17620,17538,17764,18013,17630,38350,37665,38284,38483,38458,38238,38669,38458,38483,6601,6232,6510,31636,31664,31385,32222,31971,32134,30715,30602,30409,32993,33018,32915,32371,32302,32311,35522,35079,35431,19783,19630,19661,21866,21876,22101,30792,30689,30551,30938,30689,30792,30876,31093,30943,30378,30715,30409,36219,35991,35922,35759,35736,35629,36219,36221,36395,33224,33146,33179,7663,7739,7796,4649,4721,4803,19630,19511,19499,38832,38663,38781,38675,38733,38556,38650,38353,38613,38832,38781,38850,5114,5072,5186,13810,13975,14003,36566,36490,36482,9056,9069,9121,9056,9121,9125,33146,33018,32993,31538,31557,31394,5570,5818,5767,5421,5305,5350,5189,5114,5186,5363,5484,5398,5363,5398,5194,16597,16650,16527,16157,16226,16249,15037,14967,14820,25183,25303,25072,24915,25072,24824,29066,28968,28967,29143,28968,29066,38850,38611,38816,4165,4241,4197,4652,4892,4645,4539,4649,5019,5217,5398,5221,9125,9121,9236,17229,17202,17353,17649,18942,18901,17194,17202,17229,23919,24058,23703,32302,31839,32311,37832,38423,37919,37770,37817,37699,37804,37817,37770,38350,38284,38395,37844,37864,37732,5831,5998,5965,12616,12365,12804,10664,10556,10715,12237,12365,12348,13106,13465,13310,13674,13487,13714,29478,29189,29398,13044,13231,13070,24714,24640,24757,24336,24269,24209,24714,24757,24830,25129,24920,25150,3924,4018,4244,3960,4028,4048,4029,4214,4122,9340,9543,9192,11051,11440,11145,12279,12733,12680,10993,11145,10973,37750,37585,37675,37750,37675,37708,38531,38250,38605,5097,5256,5145,5097,5217,5221,4839,4856,4990,5145,4988,5027,6214,6403,6347,6495,6403,6435,5872,5831,5965,30715,30876,30602,31359,31120,31082,29800,29645,29575,37405,37724,37447,37206,37365,37405,37498,37365,37206,37462,37365,37500,33007,32311,32915,32222,31960,31971,31971,31833,32134,6601,6502,6730,6510,6502,6601,10510,10454,10408,10239,10219,10208,10084,10122,10020,10556,10586,10715,10334,10138,10050,31344,31176,31218,35534,35522,35431,35918,35736,35759,35678,35711,35694,10729,10973,10939,30605,30595,30760,30689,30595,30551,29302,29182,29189,35495,35447,36065,36708,36202,36318,3960,4048,3975,3861,3926,3554,4082,3986,4231,22043,22123,21714,23126,23270,23202,38816,38611,38738,38816,38738,38857,21533,21617,21876,22869,22984,23060,36600,36599,36591,36286,36504,36369,36761,36599,36600,36612,36599,36761,17548,18942,17649,17536,17397,17459,38605,38126,38361,38671,38531,38854,37529,37445,37428,25446,25587,25599,38465,38350,38395,10368,10219,10239,31557,31443,31394,31473,31443,31557,22191,22303,22224,25599,25587,25684,25599,25684,25829,30396,30303,30324,4064,4149,4241,4616,4342,4368,4616,4666,4342,7655,8197,7909,17092,16920,17152,17092,17152,17200,16896,16920,16973,24953,24714,24830,24544,24269,24336,31664,31658,31385,4823,4727,4799,4701,4727,4823,14741,14643,14655,14643,14454,14655,27057,27234,27187,26123,25978,25933,38050,37937,37898,38091,37948,38115,5872,5965,6061,29979,29821,29986,29710,29575,29604,36612,36566,36482,26363,25978,26123,13975,13810,13858,14328,14877,14488,22345,23118,22613,37565,37539,37378,37529,37539,37575,14655,14454,14585,37994,37864,37844,38857,38738,38733,7663,7577,7739,20500,20413,20440,20440,20379,20303,20303,20298,20147,20147,20182,20016,20016,20059,19788,19788,19681,19783,19783,19681,19630,19630,19594,19511,20729,20634,20818,20602,20634,20729,31359,31082,31177,38836,38942,38772,39158,38914,38790,38790,38914,38809,38861,38887,38836,38801,38935,38861,38822,38912,38801,38901,38912,38822,38901,38822,38830,38901,38830,38956,38830,38810,38902,38810,38947,38902,38819,38947,38810,38794,38947,38748,38794,39454,38947,38912,38935,38801,4316,4195,4341,6403,6293,6435,6229,6293,6214,10454,10368,10239,11826,11210,11064,10406,10483,10697,10357,10483,10406,10334,10223,10357,24544,24336,24640,3994,3749,4026,3852,3877,4072,3852,4072,3870,4072,3938,3870,3938,3868,3870,20634,20413,20500,19043,19185,18984,21077,20961,21085,21085,21227,21231,21231,21227,21237,21237,21243,21366,22191,22066,22303,38935,38887,38861,38809,38904,38606,3938,3921,3868,20413,20379,20440,20598,20791,20676,5979,5872,6061,30203,29986,30027,5363,5439,5542,5554,5541,5672,5504,5439,5393,12901,12733,12551,13271,13290,13427,20379,20298,20303,31939,32134,31833,38887,38942,38836,38794,38832,38874,28225,28496,28436,29346,29345,29460,3868,3921,3688,3975,4048,4041,3975,4041,3871,3926,3949,4038,3861,3949,3926,5504,5541,5554,8887,8844,8927,26943,27057,27187,29189,29143,29066,29182,29143,29189,29189,29478,29302,3921,3976,3842,18495,18463,18701,18735,18701,18740,18866,18994,18843,20298,20182,20147,25236,25202,25150,25129,24953,24830,24707,24544,24640,25236,25324,25446,26971,27178,26492,26492,26317,26795,25873,26093,25828,30303,30203,30027,30595,30518,30324,30605,30518,30595,30938,30792,30941,31443,31344,31218,31511,31344,31443,31177,30943,31093,31177,31082,30943,35736,35678,35547,35929,35666,35991,36219,36659,36504,36114,36207,35728,36161,36207,36114,5373,5305,5421,4934,5083,5093,5373,5586,5526,5373,5526,5033,4671,4755,4766,8097,8197,8367,7393,7452,7577,8582,8585,8503,8740,8585,8739,8470,8585,8740,8751,8983,8977,8751,8977,8720,13050,13106,13276,33395,33455,33135,36065,35447,35584,33395,33135,33380,32388,32385,32236,32388,32236,32244,9388,9391,9579,9328,9391,9388,9328,9388,9256,9328,9256,9025,16920,16896,17161,17239,17359,17273,38458,38465,38421,38159,38091,38115,38669,38465,38458,20961,21227,21085,12365,12237,12331,12812,12804,12959,36708,36318,36518,3842,3976,3886,13137,13290,13271,21227,21243,21237,38874,38832,38936,3949,3978,4033,3727,4371,3560,3847,3978,3949,8304,8835,9082,5576,7163,6321,18901,18942,18984,17606,17649,17536,38916,38857,38733,38936,38832,38850,38733,39187,38926,26658,26439,26274,25340,25236,25446,26363,26439,26664,30238,30203,30303,29398,29662,29478,32302,31646,31538,31545,31636,31385,31825,31939,31833,17239,17455,17359,38050,38091,38158,37756,37750,37828,4054,4029,4122,4054,4122,4149,23118,23270,23126,24658,24511,24226,23150,23270,23118,37365,37460,37405,37462,37460,37365,7452,7405,7577,7577,7405,7739,6502,6347,6495,9391,9467,9579,9406,9467,9391,21533,21468,21617,21533,21876,21780,33018,33057,32915,31511,31473,31646,33146,33145,33018,33224,33145,33146,33341,33145,33224,38531,38671,38250,38605,38361,38761,14488,14877,14491,13050,12959,13106,10353,10368,10454,11826,11943,11210,10483,10620,10809,10993,11051,11145,11440,11506,11665,10578,10620,10483,22360,22281,22700,21243,21527,21366,23238,23429,23270,36286,35929,35991,29800,29853,29752,29345,29040,29460,36599,36612,36482,36566,36953,36490,36234,35918,35929,37403,37146,37396,37403,37396,37597,36518,36318,36415,3871,4041,4018,3886,4017,3874,19457,19499,19511,33145,33057,33018,4856,4797,4963,5393,5439,5363,4803,4839,4990,3662,4261,4225,14741,14820,14967,16338,16430,16226,13956,13945,13716,28549,28352,28968,36492,36518,36415,36161,36107,36258,37724,37770,37584,37817,38009,37832,38574,38336,38242,38242,38336,38299,7008,7203,7297,6149,6096,6228,10219,10122,10208,10353,10454,10556,10334,9935,10223,31240,31285,31325,31344,31285,31118,30518,30396,30324,24986,24953,25129,25684,25854,25829,38451,38336,38588,5174,5241,5316,24986,25129,25098,24658,24226,24491,25784,25828,25755,37539,37529,37428,37575,37539,37565,37750,37708,37828,4030,3925,3874,19252,19756,19185,9467,9491,9579,9406,9491,9467,32244,32236,32222,32244,32222,32134,3922,4054,4149,3933,3924,4244,3874,3925,3819,6149,6375,6293,5767,5818,5831,19680,19681,19788,30470,30396,30518,29914,29821,29979,39086,38790,38837,39306,38483,38377,18866,18735,18740,17170,17092,17239,18843,18735,18866,25937,25854,25978,29764,29853,29800,31825,31833,31664,36492,36415,36388,4195,4165,4197,4064,4165,4068,17459,17606,17536,16809,16850,16753,16527,16430,16597,23314,23108,23604,24707,24640,24714,38562,38361,38420,10304,10122,10219,9125,9038,9056,32371,31646,32302,31646,31473,31557,35694,35534,35678,35694,35522,35534,4934,5093,4953,37994,37844,37937,37912,37724,37405,13740,13956,13716,19681,19594,19630,5767,5831,5872,5305,5174,5316,13050,12812,12959,11210,12048,12130,13465,13487,13310,5541,5661,6084,5439,5504,5554,5393,5123,5240,12812,12616,12804,7405,7198,7525,7264,7198,7405,32392,32244,32418,34327,33772,34243,13674,13714,13810,3978,3986,4082,3820,3986,3978,3867,4313,4315,9122,9189,9192,12616,12348,12365,23270,23429,23543,23150,23118,23146,29143,29087,28968,30108,29986,30203,30238,30108,30203,36388,35898,36207,4342,4666,4337,4068,4165,4195,4652,4701,4892,5019,4691,4539,5194,5398,5217,10620,10729,10939,10587,10729,10620,14670,14820,14741,14798,14820,14670,31163,31118,31285,31163,30792,31118,30396,30238,30303,16597,16430,16338,24474,24413,24544,25043,24986,25098,24919,24986,25043,24915,25060,25072,25134,25060,24915,37597,37396,37445,37579,37445,37529,25599,25502,25446,26098,25937,25978,26363,26274,26439,25669,25521,25546,31240,31163,31285,31093,30876,31155,31622,31668,31636,31668,31825,31664,4342,4266,4300,17353,17459,17397,19036,19043,18942,32250,32244,32134,31668,31664,31636,3902,3960,3754,3902,3997,3960,6096,5979,6061,6229,6149,6293,19594,19457,19511,21948,22043,21714,30777,30595,30689,36107,36161,36114,36065,35584,35975,38936,38850,38877,38850,38883,38877,4953,5093,5072,4914,4790,4915,5003,5072,5114,14211,14116,14328,14013,14116,14161,4978,4766,4736,13539,13444,12999,13137,13444,13290,13290,13444,13427,17239,17092,17200,15331,15764,16118,17455,17620,17359,24491,24226,24179,37460,37599,37405,37500,37365,37498,37206,37495,37498,36795,36202,36708,36795,36708,36728,22984,22869,22700,24294,24209,24269,35711,35678,35736,33102,33057,33145,35918,35759,35929,37724,37824,37770,37804,37907,37817,37907,37824,37921,31155,30876,31079,29710,29764,29800,29460,29040,29397,36612,36739,36566,36895,36761,36600,36728,36708,36712,25546,25521,25303,22043,22066,22123,38850,38816,38883,6011,5979,6096,36698,36708,36518,36293,36388,36207,13754,13674,13810,10357,10406,10334,10357,10578,10483,8927,9256,9084,3813,3861,3646,5979,5767,5872,19457,19297,19499,18735,18495,18701,38914,38904,38809,38883,38816,38974,3933,4244,4029,3933,4029,3875,18462,18495,18735,33455,33772,33425,33135,32701,33084,16809,17194,16850,16204,16121,16148,31388,31385,31359,32121,32134,31939,38336,38451,38299,38562,38451,38588,26664,26439,26658,25829,25502,25599,32685,32385,32520,10871,11051,10993,10587,10520,10642,15346,15343,15269,31177,31215,31359,31215,31462,31388,35910,35918,36234,6149,6011,6096,6214,6293,6403,6403,6495,6347,30938,30777,30689,30605,30470,30518,31008,30777,30938,17092,16973,16920,17044,16973,17092,25686,25784,25669,24658,24706,24824,24574,24706,24658,37690,37575,37565,8809,8977,8888,7570,7577,7663,3883,3960,3975,6347,6502,6510,8367,8195,8097,38904,38917,38606,38650,38958,38675,38675,39187,38733,38974,38816,38983,3871,3883,3975,3922,4029,4054,4064,4241,4165,12298,12130,12237,10412,10353,10556,10368,10304,10219,10871,10993,10729,36161,36293,36207,36698,36518,36668,36351,36293,36161,5504,5461,5541,4797,4856,4839,12348,12298,12237,12616,12473,12348,12812,12691,12616,12808,12691,12812,12808,12812,13050,5371,5461,5504,12567,12473,12616,25669,25784,25755,25873,25985,26093,25183,25072,25060,8835,8887,9084,8304,9082,7624,22519,22360,22700,19036,18942,19024,16809,16753,16783,24413,24294,24269,22240,22101,22360,24413,24269,24544,24714,24953,24919,12473,12298,12348,14116,14003,13975,13492,13310,13487,14013,14003,14116,20634,20602,20413,20413,20321,20379,20379,20321,20298,20298,20321,20182,20182,20109,20016,19681,19587,19594,19594,19536,19457,19457,19339,19297,20729,20818,20978,20729,20978,21131,21322,21468,21131,20444,20598,20676,20961,21191,21227,21227,21191,21243,21243,21374,21527,21527,21626,21714,22043,22146,22066,20663,20598,20444,21131,21379,21123,29182,29177,29143,26943,26664,26658,29478,29662,29672,29662,29821,29760,39059,38993,38942,38942,38993,38772,38914,39105,38904,38904,39061,38917,38935,39001,38887,38912,39001,38935,38901,39001,38912,38956,39001,38901,38956,38830,38979,38830,38902,38979,39022,39024,38979,39022,38979,38902,39142,39057,38947,3877,3749,3994,3770,3749,3877,3770,3877,3852,3770,3852,3814,3852,3870,3814,3870,3709,3814,3868,3804,3870,3718,3804,3868,38874,38936,38987,4680,4797,4839,4680,4839,4721,16182,16309,16896,3842,3827,3921,38987,38936,38877,3842,3886,3827,33057,33007,32915,33102,33007,33057,35448,35079,35522,4068,4195,3890,25327,25183,25134,13492,13487,13674,20439,20321,20413,3861,3847,3949,3986,3867,4315,3753,3847,3861,18942,19043,18984,20622,20663,20565,17516,17606,17459,23532,23919,23703,22345,22613,22303,29914,29979,30108,36761,36739,36612,37224,36462,36782,36843,36895,36909,16973,16888,16896,17022,16888,16973,16783,16753,16650,16783,16650,16645,20321,20168,20182,21379,21468,21450,39059,38942,38887,25829,25854,25937,25395,25546,25303,3827,3886,3778,9122,9125,9189,9122,9038,9125,20168,20109,20182,20849,21191,20961,23489,23238,23403,38993,38986,38772,10578,10587,10620,9836,9701,9664,30777,30760,30595,31163,30941,30792,31282,30941,31163,31285,31344,31325,36130,36065,36156,5145,5175,4988,13754,13492,13674,13444,13539,13716,14670,14741,14655,13044,13070,12901,9472,9701,9491,21191,21295,21243,31511,31443,31473,31155,31215,31177,30378,29752,29853,33007,32371,32311,32244,32392,32388,31819,31939,31825,31819,31825,31668,38091,38050,37898,37750,37756,37550,38159,38115,38348,11218,11506,11440,10732,10871,10729,30750,30760,30777,36130,36258,36107,36561,36492,36388,5447,5661,5541,36843,36739,36761,36795,37001,36859,36362,36388,36293,4539,4691,4353,38348,37859,38573,3871,4018,3924,3778,3886,3786,3871,3785,3793,37575,37579,37529,37828,37708,37954,21295,21374,21243,8470,8503,8585,9192,9543,9022,17620,17630,17538,17409,17516,17459,17175,17202,17194,24093,23970,24209,24919,24953,24986,23150,23238,23270,25327,25261,25183,22146,22303,22066,23532,23703,23429,31546,31511,31583,35694,35686,35522,35711,35686,35694,35910,35736,35918,4988,5156,4963,4608,4680,4721,25875,25829,25937,37824,37907,37804,37921,37824,37724,4776,4790,4914,4978,5003,5114,4978,5114,5174,5174,4766,4978,13705,13754,14003,14003,13754,13810,13539,13740,13716,30111,30378,29853,36473,36362,36460,37690,37579,37575,5661,5742,6084,30194,29914,30108,36668,36518,36492,21374,21606,21527,19046,18843,18994,17231,17170,17273,19089,18994,19297,39278,39141,39370,38883,38987,38877,7655,7570,7663,6347,6510,6232,16204,16338,16226,16809,17175,17194,16148,16338,16204,14798,15037,14820,25183,25261,25303,25183,25060,25134,16645,16650,16597,25129,25202,25098,25202,25236,25340,3886,3874,3786,21606,21626,21527,3923,4195,4316,4549,4754,4727,4549,4727,4701,4776,4914,4934,37954,37708,37864,37787,37690,37565,5003,4953,5072,3786,3874,3819,5461,5447,5541,5661,5374,5742,5393,5371,5504,5240,5371,5393,6229,6011,6149,5979,6011,5767,7264,7405,7452,7570,7516,7577,10587,10732,10729,11054,11440,11051,10642,10732,10587,12696,12808,12730,12691,12567,12616,12473,12496,12298,10412,10664,10547,13276,13106,13310,13276,13310,12992,21866,21780,21876,24093,24209,24294,22101,21980,22114,24093,24294,24038,32520,32385,32388,36473,36388,36362,36065,36130,36107,36245,36130,36156,7008,7297,7198,17273,17170,17239,16182,15331,16118,17044,17170,17098,17409,17459,17353,16622,17175,16809,24179,24226,24058,31927,31819,31668,32392,32520,32388,36286,35991,36219,38465,38549,38350,38967,38278,38739,38974,38987,38883,38854,38531,38827,11054,11051,10871,12901,13070,12733,13539,13746,13740,29000,29040,28961,29604,29764,29710,28225,27746,28496,27746,27894,28496,29302,29177,29182,29169,29177,29417,29177,29302,29417,19680,19587,19681,22101,22114,22360,38050,38061,37937,38206,38061,38267,38158,38091,38159,5097,5194,5217,5120,5194,5097,12810,13276,12992,31545,31388,31462,31215,31388,31359,35910,35711,35736,35169,33971,34989,38267,38158,38369,8703,8751,8720,8703,8740,8751,8703,8470,8740,7389,7516,7570,7389,7366,7516,14643,14429,14454,38061,37994,37937,7516,7393,7577,7366,7393,7516,3819,3925,3902,3785,3924,3933,4064,3922,4149,3836,3922,4064,23238,23511,23429,23919,24179,24058,23489,23511,23238,3819,3902,3695,19587,19536,19594,21626,21948,21714,25784,25968,25873,25737,25968,25784,25686,25669,25546,16783,16633,16809,16533,16645,16597,16533,16597,16439,24868,24707,24714,25340,25446,25502,38451,38562,38420,38588,38336,38574,25697,25340,25502,8720,8977,8809,35669,35522,35686,33007,33227,32371,4221,4482,4368,17409,17353,17314,17353,17202,17314,22519,22700,22568,24362,24294,24413,30377,30238,30396,29914,29760,29821,30470,30605,30750,30605,30760,30750,31008,30941,31282,8977,9056,8888,14454,14252,14463,14454,14429,14252,38574,37990,38054,37967,37921,37724,37599,37460,37462,17170,17044,17092,17734,17630,18013,32250,32121,32213,32097,32121,31939,9328,9406,9391,10671,10807,10732,9374,9406,9365,32537,32520,32392,8888,9056,8982,25395,25303,25261,25690,25686,25546,4988,4696,4859,29999,29760,29914,29691,29764,29604,31155,31177,31093,36728,37001,36795,36698,36712,36708,36787,36712,36698,36668,36492,36561,23511,23532,23429,23489,23532,23511,3754,3960,3883,10732,10807,10871,10587,10578,10520,19536,19339,19457,18406,18306,18495,22240,22360,22382,21948,22146,22043,8982,9056,9038,8982,9038,8954,8982,8954,8889,33223,33102,33145,33061,32701,32943,33061,33084,32701,33395,33380,33455,31546,31325,31344,31546,31344,31511,31511,31646,31583,4555,4549,4701,4550,4776,4934,3586,3867,3986,3717,3813,3646,4696,4963,4797,7251,7264,7452,7366,7452,7393,9192,9022,9111,9406,9472,9491,10807,11054,10871,12551,12733,12278,16645,16633,16783,16439,16597,16338,18462,18735,18631,17516,17409,17355,19196,19185,19043,19196,19252,19185,19196,19043,19128,25327,25395,25261,23850,24179,23919,24868,24714,24919,25340,25098,25202,29764,29968,29853,30238,30194,30108,31008,30938,30941,32943,32701,32685,36561,36388,36564,37787,37565,37756,37723,37597,37445,36895,36843,36761,37822,37756,37828,38642,38549,38465,38816,38857,38983,16182,16896,16255,14170,14116,14211,13754,13705,13492,15269,15343,15037,15024,15037,14798,18765,18735,18843,4649,4608,4721,4680,4737,4797,4364,4562,3727,4562,4371,3727,14890,15024,14798,26363,26098,25978,25829,25875,25502,25616,24996,25098,26943,26812,27057,16255,16896,16483,16896,16888,16483,16121,16157,15863,24915,25028,25134,15346,15600,15548,25778,25985,25968,25968,25985,25873,25737,25784,25686,35711,35669,35686,35668,35669,35739,24868,24919,24996,4495,4608,4649,27187,27255,27341,5371,5364,5461,5240,5364,5371,5125,5363,5194,5125,5194,5120,29177,29087,29143,29169,29087,29177,13044,13137,13271,12733,12279,12278,33124,32943,32974,19339,19160,19297,19128,19043,19036,22700,22869,22568,38983,38916,38926,38983,38857,38916,5364,5447,5461,5030,5097,5027,13000,13137,13044,29000,28961,28699,29925,30111,29968,27746,27468,27629,3820,3978,3847,18462,18406,18495,18466,18406,18462,25778,25737,25686,14170,14211,14488,30377,30194,30238,29760,29672,29662,36362,36293,36460,4642,4737,4680,10807,10617,11054,10520,10578,10357,14585,14670,14655,13746,13956,13740,27341,27255,27690,29618,29460,29689,31282,31163,31240,30470,30377,30396,38002,37954,37864,38002,37864,37994,38002,37994,38148,38061,38050,38267,3779,3883,3871,3779,3754,3883,3813,3753,3861,19160,19089,19297,17649,17606,17548,37206,37116,37495,36716,36859,37307,36728,36712,37001,10412,10556,10664,10664,11064,10547,31008,30750,30777,20602,20597,20413,20321,20135,20168,20168,20135,20109,20109,20059,20016,19587,19680,19536,19536,19453,19339,19339,19286,19160,19160,19058,19089,20729,20597,20602,20706,20597,20729,20706,20729,21131,20706,21131,21123,21468,21379,21131,21450,21468,21533,20598,20849,20961,21191,21315,21295,21295,21315,21374,21374,21469,21606,21606,21644,21626,21626,21744,21948,21948,21977,22146,20663,20444,20565,19415,19756,19252,19415,19252,19162,21589,21450,21533,35668,35448,35522,39001,39037,38887,38993,39113,38986,38986,39084,38837,38956,39037,39001,39024,39037,38956,39024,38956,38979,38902,39057,39022,16396,16439,16338,16533,16633,16645,16396,16338,16148,20663,20849,20598,38549,38544,38350,38714,38544,38746,38958,38650,38968,38009,37817,37907,38902,38947,39057,29653,29672,29760,29618,29691,29604,36739,36953,36566,35739,35669,35711,36909,36895,37062,38947,39282,39142,9543,10020,9022,3804,3709,3870,3814,3709,3770,3770,3545,3749,3646,3861,3554,3813,3701,3753,3718,3709,3804,3718,3868,3645,3921,3827,3688,3827,3697,3688,3778,3697,3827,4980,5027,4988,4980,5030,5027,24996,24919,25043,24669,24474,24544,23314,23604,23456,24996,25043,25098,31325,31282,31240,31583,31786,31757,31388,31545,31385,32418,32537,32392,32520,32537,32685,30876,30715,31079,31155,31079,31239,37606,37599,37462,38669,38642,38465,38746,38642,38812,39155,39059,38887,39102,38967,38739,3922,3875,4029,3792,3875,3829,3703,3820,3753,3753,3820,3847,19089,19046,18994,19058,19046,19089,19162,19252,19196,17548,17606,17516,15863,16157,15773,7264,7008,7198,7072,7008,7264,21638,21589,21533,35415,35169,34989,39071,38874,38987,15346,15401,15600,15771,15863,15773,15024,15269,15037,15101,15269,15024,14302,14170,14488,30194,30155,29914,30616,30377,30470,37001,36993,37111,36351,36161,36258,37895,37822,37828,37414,37224,37403,3778,3734,3697,20354,20135,20321,4892,4915,4645,26415,26098,26363,25875,26098,26079,26363,26664,26415,20135,20059,20109,21168,21315,21191,39113,39084,38986,3793,3779,3871,3778,3786,3734,13757,13746,13516,19046,18905,18843,19017,18905,19046,23604,23644,23456,21780,21638,21533,38761,38361,38562,38974,39071,38987,17359,17231,17273,17304,17231,17359,18248,18172,18013,4645,4915,4790,14463,14670,14585,14789,14670,14678,21866,21638,21780,21315,21347,21374,37921,38009,37907,37967,38009,37921,39084,39086,38837,8176,7887,8059,9365,9406,9162,9406,9374,9472,3662,4225,4056,4476,4642,4608,4608,4642,4680,23604,23970,23644,38573,37859,38350,38000,37895,37828,10353,10304,10368,11210,12130,11579,21866,21791,21638,21347,21469,21374,23403,23238,23150,30111,29853,29968,10642,10671,10732,12825,12551,12708,10520,10671,10642,36130,36245,36258,34998,35653,35750,8195,8522,8503,8195,8503,8470,8536,8470,8703,8536,8703,8630,8703,8720,8630,8720,8735,8630,8809,8735,8720,8809,8888,8735,4093,4221,4368,3825,3836,3741,4300,4368,4342,16258,16396,16148,17314,17202,17262,16105,16148,16121,3786,3700,3734,7485,7570,7655,8735,8888,8746,18905,18880,18843,18951,18880,18905,21638,21791,21598,22250,22101,22240,23060,22568,22869,29925,29968,29764,33341,33382,33145,33102,33173,33007,33537,33382,33341,34998,35594,35653,33084,33380,33135,33204,33380,33084,33124,33084,33061,33124,33061,32943,12808,12567,12691,12696,12567,12808,12808,13050,12730,13705,14003,14013,12020,11733,12166,12901,13000,13044,13516,13746,13539,35479,35594,34739,6214,6011,6229,5174,5305,4766,4550,4934,4953,4431,4645,4439,4776,4645,4790,5255,6011,6214,6232,6214,6347,29087,28549,28968,29417,29302,29478,29653,29478,29672,37794,37787,37822,37822,37787,37756,12956,13000,12901,28999,28549,29087,33382,33256,33145,4337,4666,4754,22382,22360,22519,21469,21644,21606,5056,5120,5097,5123,5393,5363,5370,5456,5447,5056,5097,5030,17355,17548,17516,16633,16533,16519,24669,24544,24707,24669,24707,24678,33256,33223,33145,37987,37967,37724,37500,37606,37462,36698,36668,36787,3786,3819,3700,18880,18765,18843,18886,18765,18880,20059,19680,19788,21644,21744,21626,7008,6232,7203,7366,7251,7452,7082,7251,7366,15334,15401,15346,14890,15101,15024,32418,32244,32250,32134,32121,32250,35448,35415,34989,35669,35668,35522,35739,35935,35819,35500,35415,35448,33537,33364,33382,15334,15346,15269,29907,29925,29764,29460,29618,29604,29000,28699,28616,36659,36395,36490,37224,36782,37403,36787,36668,36561,36564,36388,36473,36460,36564,36473,4549,4337,4754,4652,4555,4701,4431,4555,4652,33223,33173,33102,3700,3819,3695,21744,21857,21948,37659,37606,37500,14170,14161,14116,14146,14161,14170,4014,4337,4549,26098,25875,25937,26415,26664,26855,10381,10304,10353,10398,10547,11064,11218,11440,11054,10223,10520,10357,36144,36156,36065,36245,36325,36258,16519,16533,16439,16519,16439,16449,23314,23060,22984,24038,23970,24093,23532,23739,23919,24574,24658,24491,22345,22303,22146,24806,24996,25462,38629,38693,38562,38629,38562,38588,3695,3902,3754,3785,3871,3924,3785,3933,3875,16182,15392,15331,14491,14302,14488,17022,16973,17044,25690,25778,25686,25737,25778,25968,24574,24491,24626,4978,4953,5003,4696,4988,4963,4495,4649,4539,36953,36739,36843,36391,36325,36245,38206,37994,38061,10381,10353,10412,35965,35975,35810,35810,35975,35584,33201,33124,32974,31622,31636,31545,5305,5373,4766,4871,4980,4988,18248,18306,18172,17098,17022,17044,24362,24038,24294,24362,24413,24474,38827,38531,38605,24678,24707,24868,24626,24491,24179,3695,3754,3704,15771,15773,15600,19680,19453,19536,31546,31506,31325,30616,30470,30750,30467,30155,30377,31565,31583,31757,31603,31622,31545,31239,31215,31155,34549,35284,34739,18765,18631,18735,18625,18631,18765,31079,30715,30879,29907,29764,29691,36873,36787,36561,36993,36787,36873,39102,38696,38917,12730,13050,12810,14491,15169,15331,3756,3836,3825,23489,23546,23532,23403,23546,23489,19453,19403,19339,19162,19196,19128,19162,19128,19142,39191,39105,38914,4696,4797,4737,9192,9111,9122,10086,10020,10122,38267,38050,38158,13705,14013,13876,12567,12496,12473,12560,12496,12567,37445,37579,37723,36909,37021,36843,37289,37307,36859,37498,37659,37500,37345,37319,37467,4221,4146,4482,4133,4146,4221,4133,4221,4093,17262,17202,17175,16449,16439,16396,25028,24915,24706,38693,38761,38562,38655,38629,38588,13516,13539,12999,14463,14585,14454,14670,14789,14798,12825,12956,12901,12825,12901,12551,17538,17367,17359,17447,17367,17538,3820,3679,3986,3611,4026,3749,3792,3785,3875,3704,3754,3779,19403,19286,19339,38639,38574,38054,39105,39061,38904,39089,39071,38974,39089,38974,38983,14429,13956,14252,15101,15102,15269,15617,15771,15600,30377,30155,30194,30616,30817,30702,31376,31282,31325,30244,30378,30111,28549,28462,28092,26855,26664,26943,28999,28462,28549,29172,29087,29169,28436,28538,28616,29618,29677,29691,27629,27468,27178,27629,27178,27257,35668,35569,35448,35156,33971,35169,35739,35569,35668,37483,37495,37116,37912,37405,37599,17098,17170,17231,24996,24678,24868,24646,24362,24474,24646,24678,24806,24626,24771,24574,24574,24771,24706,5447,5456,5661,5742,5724,6321,5302,5447,5364,5363,5125,5123,5056,5030,4994,23963,23644,23970,23177,23060,23314,23963,23970,24038,36325,36351,36258,36391,36351,36325,36295,36245,36156,36144,36065,35975,26317,26093,26795,25546,25395,25690,3704,3779,3693,3717,3701,3813,4187,4353,4364,19142,19128,19036,32213,32121,32097,32418,32410,32537,32402,32250,32403,39061,39107,38917,31583,31506,31546,31565,31506,31583,35750,35785,35810,35835,35785,35750,4994,5030,4980,4337,4266,4342,4249,4266,4084,4300,4266,4249,14326,14491,14396,14146,14013,14161,14252,13956,13906,15863,16105,16121,15617,15600,15484,25690,25395,25545,38294,38423,37832,37912,37599,37860,23177,23240,23154,22394,22382,22519,29999,29653,29760,29925,30083,30111,29689,29677,29618,8097,7909,8197,8181,8195,8470,8181,8470,8536,8746,8536,8630,17367,17304,17359,17447,17304,17367,17262,17175,16622,19024,19142,19036,3701,3703,3753,19286,19058,19160,17447,17278,17304,19024,18942,17548,22628,22519,22568,22112,22345,22146,39126,39089,39141,4871,4988,4859,4900,4994,4980,38795,38761,38693,38574,38655,38588,38752,38655,38574,20597,20439,20413,20135,20148,20059,20059,19775,19680,19366,19403,19453,19366,19286,19403,19366,19174,19286,19286,19174,19058,20706,20617,20597,20920,20617,20706,20508,20617,20658,21180,21123,21379,21421,21379,21450,21421,21450,21589,21421,21589,21598,20663,20622,20849,20849,20953,21191,21371,21547,21347,21347,21547,21469,21469,21547,21644,21644,21702,21744,21744,21724,21857,21857,21977,21948,20565,20444,20441,20444,19756,20019,19756,19654,19829,7966,7909,8097,19756,19517,19654,23546,23739,23532,23634,23739,23546,33173,33227,33007,33223,33197,33173,33256,33355,33223,33382,33364,33256,35317,35169,35415,34409,34470,35284,29677,29907,29691,20617,20439,20597,39037,39155,38887,39059,39113,38993,39084,39228,39086,39086,39158,38790,39105,39114,39061,39061,39114,39107,39239,39155,39037,39195,39037,39024,39195,39024,39022,39195,39022,39180,39022,39057,39180,39180,39057,39142,4066,4042,4316,4066,4316,4146,17022,16849,16888,14326,14302,14491,17098,16849,17022,38795,38693,38629,38968,38650,38671,13757,13956,13746,16026,16105,15863,16630,16809,16633,20439,20354,20321,38000,37828,37954,37787,37794,37690,38000,37954,38002,37659,37599,37606,38544,38573,38350,38352,38158,38159,38714,38573,38544,38544,38549,38746,39155,39144,39059,38794,38874,39454,26855,26943,26944,24514,24646,24806,38195,38148,37994,38352,38159,38348,3693,3779,3793,3829,3875,3922,3829,3922,3756,23177,23314,23240,23060,22628,22568,3693,3793,3604,8889,8888,8982,14789,14890,14798,15771,15833,15863,14854,14890,14789,14678,14670,14463,19058,19017,19046,18981,19017,19058,19271,19415,19162,17474,19024,17548,35997,36144,35975,35965,35810,35785,39194,39102,39107,39107,39102,38917,38746,38549,38642,3709,3545,3770,3717,3653,3701,3701,3653,3703,3718,3612,3709,3627,3612,3718,3627,3718,3645,3868,3688,3645,3688,3676,3645,3697,3676,3688,3734,3676,3697,38614,38352,38348,39122,38874,39071,4791,4871,4859,14146,14170,14302,12999,13137,13000,3734,3557,3676,3501,3611,3749,31506,31376,31325,30240,30066,30155,31575,31376,31506,31239,31462,31215,31545,31462,31603,35946,35965,35785,39206,39113,39059,33355,33197,33223,14684,14678,14463,38102,38148,38185,29999,30066,29963,30155,30066,29914,30058,30083,29925,17304,17278,17231,18306,18406,18172,17314,17355,17409,16630,16633,16519,24646,24474,24669,23644,23719,23456,24646,24669,24678,36351,36460,36293,37134,36859,37001,36640,36460,36351,38761,38827,38605,3696,3793,3785,3734,3488,3557,19017,18951,18905,18981,18951,19017,5125,5120,5074,5123,5125,5074,5120,5010,5074,9472,9540,9701,9406,9328,9162,11196,11210,11579,12696,12560,12567,12730,12560,12696,18172,18406,18428,23739,23850,23919,23869,23850,23739,28538,29000,28616,30058,29925,29907,30058,30146,30083,28538,28436,28496,37307,37345,37116,37651,37659,37498,37001,36712,36993,8954,9122,9111,8954,9038,9122,5120,5056,5010,12956,12924,13000,11218,11054,10669,18466,18462,18631,5240,5302,5364,29417,29478,29653,29417,29172,29169,35569,35500,35448,35530,35500,35569,3700,3695,3550,5010,5056,4965,21598,21589,21638,28694,28538,28496,39228,39158,39086,4093,4368,4300,38037,37794,37895,37895,37794,37822,38642,38669,38798,38552,38369,38352,5456,5374,5661,5302,5370,5447,29400,29417,29681,38102,38000,38002,37912,37987,37724,38294,37832,38009,38125,37987,37912,3756,3922,3836,3945,4066,4146,9022,8954,9111,18951,18886,18880,18981,18886,18951,21791,21866,21878,23115,22628,23060,19271,19162,19197,22250,22240,22382,21168,21347,21315,37752,37579,37690,4249,4211,4300,4249,4084,4211,12130,12298,11579,10547,10381,10412,10617,10807,10671,10617,10671,10520,37243,37062,36895,36234,35711,35910,37021,37062,37253,37134,37251,37255,32250,32410,32418,32402,32410,32250,35317,35156,35169,4064,3741,3836,3792,3696,3785,23312,23403,23150,23312,23150,23146,7486,7485,7655,7251,7072,7264,15220,15102,15039,14890,15102,15101,36144,36295,36156,35965,35997,35975,36004,35997,35965,24305,23963,24038,23177,23115,23060,38352,38369,38158,38272,37994,38206,38148,38102,38002,38587,38348,38573,4450,4495,4539,4581,4696,4737,4450,4539,4353,26944,26943,27187,24514,24549,24443,27341,27690,27988,3624,3695,3704,4900,4965,4994,4476,4737,4642,14326,14146,14302,12810,13050,13276,14491,14516,14396,35798,35835,35750,34470,35205,35277,15484,15600,15401,16105,16258,16148,30750,31008,31115,31583,31646,31786,35716,35750,35653,7485,7389,7570,11210,11040,11064,10304,10086,10122,10384,10287,10284,9374,9540,9472,16190,16258,16105,16449,16630,16519,25134,25291,25327,24771,25028,24706,24891,25028,24771,24626,24179,24376,31927,31668,31810,34826,34980,34470,37794,37752,37690,37723,37752,37935,3642,3696,3792,3589,3624,3704,3923,4316,4042,30066,29999,29914,31008,31282,31115,3901,3923,4042,3890,3923,3845,4042,4066,3864,4211,4093,4300,4266,3992,4084,17278,17098,17231,16849,16483,16888,17069,17098,17278,17447,17538,17467,24362,24305,24038,24996,24806,24678,24215,24179,23850,26769,26093,25985,25545,25395,25327,38662,38587,38573,14146,13876,14013,15392,16182,15851,27421,27341,27988,21950,21977,21857,31810,31668,31622,31810,31622,31695,39375,39191,38914,38798,39566,38909,4696,4791,4859,4788,4791,4733,10384,10381,10547,13878,13876,14146,36084,36154,35997,35997,36154,36144,37134,37001,37111,13310,13492,12992,12560,12536,12496,12825,12924,12956,12278,12708,12551,18663,18625,18765,17611,17538,17630,18663,18765,18886,30083,30146,30111,29797,29907,29677,3642,3792,3675,3733,3825,3741,7909,7824,7655,7485,7486,7389,8195,7966,8097,8089,7966,8195,8746,8630,8735,8746,8888,8831,11733,12020,11506,12786,12924,12825,13906,14217,14252,15102,14890,14854,15220,15269,15102,37345,37483,37116,37134,37289,36859,36712,36787,36993,37480,37483,37345,38968,38671,38854,3703,3679,3820,3554,3926,4058,15220,15334,15269,15617,15833,15771,14217,14463,14252,21977,22112,22146,35716,35653,35617,35912,35946,35835,35835,35946,35785,39126,39122,39071,39126,39071,39089,5074,5001,5123,5274,5302,5240,5274,5331,5302,5302,5331,5370,4965,5056,4994,36561,36564,36873,38868,38662,38573,39328,38967,39102,26362,26079,26415,27341,26944,27187,26795,26093,26769,27629,27894,27746,4016,4093,4211,7966,7824,7909,17734,18013,18172,17301,17355,17314,17301,17314,17262,3728,3829,3756,18625,18466,18631,18588,18466,18625,19274,19271,19197,19364,19271,19274,39191,39114,39105,4900,4980,4871,29397,29040,29000,29660,29689,29460,37062,37021,36909,37243,36895,37224,37414,37403,37597,37651,37498,37495,8831,8888,8889,8831,8889,8954,32097,31939,31819,31695,31622,31603,35519,35317,35415,36369,35929,36286,35617,35653,35594,7233,7366,7389,7233,7082,7366,9374,9355,9540,9540,9664,9701,8927,9084,8887,38000,38074,37895,38272,38206,38334,38206,38267,38334,9797,9664,9489,23963,23719,23644,23958,23719,23963,23403,23634,23546,23642,23634,23403,32097,31819,31927,35284,35479,34739,39141,39089,38983,39070,38968,38854,39070,38854,38827,38879,38827,38761,15686,15833,15617,16258,16449,16396,17205,17301,17262,3646,3653,3717,9022,8831,8954,19500,19453,19680,22394,22250,22382,22394,22519,22628,39114,39194,39107,38983,38926,39218,4788,4871,4791,4788,4900,4871,12999,13444,13137,37021,36953,36843,36873,36564,37124,18466,18428,18406,18494,18428,18466,23154,23115,23177,36504,36286,36219,10243,10216,10304,10243,10304,10381,9935,10334,10050,11403,11733,11506,37102,37292,37290,35946,36004,35965,35912,36004,35946,8844,8887,8176,19364,19415,19271,16622,16809,16630,24514,24305,24362,24514,24362,24646,32408,32410,32402,32664,32537,32410,32664,32685,32537,34188,34826,34470,35284,35400,35479,3589,3704,3693,39187,38675,39172,7082,7072,7251,6768,7072,7082,17069,16849,17098,16465,16483,16849,16304,16449,16258,13906,13956,13757,15431,15484,15401,14684,14789,14678,17877,17734,18172,17290,17069,17278,38164,38009,37967,38655,38795,38629,38125,37967,37987,4495,4476,4608,4353,4691,4364,20622,20738,20849,21547,21702,21644,21977,22089,22112,20643,20738,20622,20643,20622,20565,20441,20444,20304,31115,31282,31305,38334,38267,38369,38538,38348,38587,38798,38669,39566,38662,38538,38587,39211,39239,39195,39195,39239,39037,39155,39225,39144,39144,39206,39059,39113,39228,39084,39158,39375,38914,39191,39269,39114,39114,39269,39194,39211,39195,39180,39211,39180,39208,39180,39142,39208,39142,39282,39208,4733,4791,4696,20617,20508,20439,20439,20429,20354,20354,20306,20135,20920,20706,21123,20920,21123,21180,21379,21421,21180,20738,20785,20849,32403,32408,32402,32030,32097,31927,35604,35530,35569,35156,35012,33971,35604,35569,35757,35716,35798,35750,35479,35573,35594,35511,35573,35479,36295,36144,36296,3535,3545,3709,3611,3554,4058,3646,3593,3653,3535,3709,3612,3535,3612,3516,3612,3491,3516,3627,3645,3582,7824,7486,7655,20304,20444,20019,39239,39225,39155,39461,39335,39211,3582,3645,3676,15901,16026,15863,15431,15401,15334,21180,21421,21274,20785,20953,20849,31565,31575,31506,31786,31646,32297,31810,32030,31927,31603,31462,31475,35942,35798,35716,23240,23314,23456,22473,22394,22628,23240,23456,23514,19174,18981,19058,19107,18981,19174,20363,20306,20354,20019,19756,19829,22473,22628,22569,21561,21421,21598,39194,39160,39102,39221,39160,39194,39556,39461,39211,14382,14684,14463,38305,38195,37994,38102,38076,38000,12730,12536,12560,12720,12536,12730,20306,20148,20135,37706,37414,37597,37185,37044,36953,37723,37579,37752,37483,37620,37495,37319,37345,37307,37319,37307,37289,37319,37289,37446,37289,37134,37255,39339,39206,39144,37467,37507,37491,37467,37480,37345,21866,22101,21878,20953,21168,21191,32403,32250,32254,35519,35415,35500,33969,34704,34826,9355,9664,9540,8927,9025,9256,5370,5327,5456,8176,8887,8835,5274,5240,5091,5000,5074,5010,5000,5010,4942,5000,4996,5001,29172,28999,29087,29417,29400,29172,29681,29417,29653,29963,29653,29999,29807,29397,29570,30168,30244,30146,29660,29807,29829,37466,37243,37224,38868,38714,39047,3923,3890,4195,3636,3793,3615,3845,3923,3901,5010,4965,4942,12924,12999,13000,13836,13906,13757,12786,12999,12924,12786,12825,12708,38237,38125,38243,37624,37620,37483,19911,20019,19829,3653,3679,3703,3538,3679,3653,15039,14854,14719,13836,13757,13516,30146,30244,30111,29797,29677,29689,23634,23869,23739,25093,25134,25028,25093,25291,25134,23642,23869,23634,30879,30715,30378,36214,36144,36154,36214,36154,36084,14516,14491,14750,14326,14227,14146,12992,13365,13049,38185,38076,38102,37860,37599,37659,10384,10243,10381,8749,9022,8833,10216,10243,10217,22569,22628,22855,23514,23456,23719,23146,23118,22345,22089,22345,22112,39332,39228,39113,37649,37651,37495,25093,25028,24987,25774,25985,25778,32254,32250,32213,32210,32207,32255,32030,31810,32073,35530,35519,35500,35757,35569,35739,35798,35912,35835,35573,35617,35594,35664,35617,35573,35819,35757,35739,36659,36219,36395,36659,36490,36953,3557,3582,3676,19812,19911,19829,39228,39242,39158,15901,15863,15833,16552,16622,16630,31757,31575,31565,31801,31575,31757,31475,31462,31414,35942,35912,35798,38423,38639,38054,3636,3604,3793,3488,3734,3700,3793,3696,3615,11864,11733,11403,12645,12786,12708,29660,29797,29689,32254,32213,32210,33201,33204,33124,35277,35400,35284,35455,35400,35277,3500,3554,3611,37915,37752,37794,4458,4476,4495,4301,4353,4187,38195,38185,38148,38261,38185,38195,38584,38334,38369,7990,8181,8079,8079,8181,8536,7966,7757,7824,7824,7641,7486,7294,7233,7389,7294,7389,7486,8181,8089,8195,9025,9162,9328,10617,10520,10171,14684,14854,14789,15220,15431,15334,15566,15686,15617,14719,14684,14579,15474,15431,15044,19904,19775,20059,21371,21702,21547,27961,27894,27629,25774,25778,25690,30616,30467,30377,30522,30467,30607,35161,35012,35156,33364,33355,33256,35161,35156,35317,37044,36659,36953,38068,38037,37895,38074,38000,38076,3901,4042,3864,3733,3728,3825,24305,23958,23963,24305,24514,24443,17734,17611,17630,17700,17611,17734,17877,18172,18254,24231,23958,24305,30240,29963,30066,3550,3695,3523,3728,3756,3825,33937,33537,33341,33197,33294,33173,3695,3624,3523,19517,19756,19415,19517,19415,19364,21878,22101,22206,22101,22250,22206,21702,21724,21744,4458,4495,4450,4788,4718,4900,15566,15617,15484,35683,35519,35530,36234,35929,36369,38305,37994,38272,38167,38164,37967,38858,38752,38945,38167,37967,38125,32210,32213,32097,32664,32410,32408,32210,32097,32030,35968,35942,35716,35400,35463,35479,35455,35463,35400,36516,36234,36369,36505,36369,36504,36084,35997,36004,36295,36391,36245,36296,36214,36402,10548,10617,10171,9935,10050,9797,16552,16630,16449,17474,17548,17355,16552,16449,16498,22206,22250,22394,36296,36391,36295,38798,38812,38642,38538,38614,38348,38909,38812,38798,33502,33355,33364,4064,4068,3817,23320,23115,23154,23647,23514,23719,18719,18663,18886,18993,18886,18981,31805,31810,31695,31414,31462,31239,31414,31239,31079,17474,17355,17374,21724,21950,21857,15722,15901,15833,17611,17467,17538,17469,17467,17611,17374,17355,17301,33355,33294,33197,37480,37624,37483,37620,37649,37495,37651,37721,37659,37467,37477,37480,37491,37477,37467,37134,37111,37251,37111,36993,37092,38173,38074,38076,38031,37915,37794,38831,38662,38868,4612,4733,4696,38031,37794,38037,3817,4068,3890,3945,4146,4133,5091,5240,5123,5331,5327,5370,5001,5074,5000,17377,17278,17447,14443,14516,14546,29400,29315,29172,29374,29315,29400,4942,4965,4875,37635,37624,37480,5242,5327,5331,37243,37253,37062,37466,37253,37243,37466,37224,37414,37021,37302,37185,37092,36993,37102,33124,33204,33084,32664,32408,32401,4996,4942,4875,35683,35530,35604,35683,35604,35782,35463,35511,35479,35664,35511,35613,37736,37649,37620,31305,31282,31383,31801,31786,32055,3523,3624,3482,3642,3615,3696,4353,4405,4450,4581,4612,4696,4301,4405,4353,3675,3792,3829,3817,3890,3776,29797,29862,29907,31503,31414,31079,29397,29660,29460,28694,29000,28538,4254,4458,4450,38375,38305,38272,38173,38068,38074,38436,38272,38334,5374,5724,5742,3693,3604,3589,3508,3537,3646,19500,19366,19453,19162,19142,19197,21950,22089,21977,39345,39269,39191,39160,39328,39102,3967,3945,4133,3967,4133,4093,4016,4211,4084,4549,4555,4431,16622,17205,17262,16190,16105,16127,24891,24771,24626,25545,25774,25690,38847,38795,38655,38752,38574,38639,16127,16105,16026,15686,15722,15833,15474,15566,15484,15474,15484,15431,38719,38614,38538,16127,16026,15944,37466,37414,37713,38051,38031,38037,38068,37895,38074,38858,38977,38884,3776,3890,3845,3776,3845,3822,17469,17377,17467,17467,17377,17447,23869,24215,23850,24195,24215,23869,23642,23403,23481,31585,31376,31575,29973,29845,29963,37102,36993,36873,36214,36296,36144,36084,36004,35912,30879,30378,30485,31805,31695,31603,35942,36084,35912,14396,14227,14326,16182,16255,16265,29963,29845,29653,30240,30155,30467,29829,29862,29797,31016,30879,30899,36733,36505,36504,35782,35604,35757,36516,36505,36733,36564,36460,36710,38164,38294,38009,38237,38167,38125,3537,3593,3646,3613,4056,3867,19197,19142,19024,25545,25327,25291,35308,35161,35317,35739,36036,35935,3675,3829,3728,3817,3741,4064,18254,18172,18428,17752,17877,17765,23353,23403,23312,35775,35716,35617,3589,3604,3515,3604,3636,3515,3593,3538,3653,19177,19197,19088,10086,10304,10216,8441,8079,8746,29862,30058,29907,3675,3728,3546,39172,38675,38958,38947,39454,39282,39172,38958,38968,14419,14227,14396,38051,38068,38173,37935,37752,37915,24443,24231,24305,23958,23844,23719,25340,25616,25098,16552,16570,16622,16304,16498,16449,16304,16258,16190,28124,27894,27961,27178,26971,27257,19366,19107,19174,26803,26769,26587,39269,39221,39194,4431,4652,4645,3822,3845,3901,15944,16026,15901,25430,25545,25291,26587,26769,25985,25430,25291,25339,29315,28999,29172,27341,27421,26944,29391,28999,29315,37477,37635,37480,37624,37736,37620,37649,37721,37651,37507,37467,37319,37507,37319,37446,17877,17752,17734,18588,18625,18663,38905,38879,38761,38905,38761,38795,15566,15722,15686,15039,15431,15220,15039,15102,14854,38614,38552,38352,38261,38076,38185,38703,38552,38614,38719,38538,38662,5274,5242,5331,5327,5206,5456,5001,5018,5123,4947,5018,5001,4996,5000,4942,12536,11961,12496,13492,13365,12992,12999,12891,13516,13906,13836,14217,12645,12708,12278,11864,12278,11733,37629,37635,37477,4439,4645,4776,4736,4953,4978,20508,20429,20439,20306,20363,20148,20148,19904,20059,19775,19500,19680,19273,18996,19107,20920,20658,20617,20544,20658,20661,20658,20678,20661,21561,21598,21791,20785,20848,20953,20953,21143,21168,21168,21371,21347,21702,21771,21724,21724,21888,21950,21950,21888,22089,20738,20671,20785,20441,20643,20565,20400,20643,20441,20671,20643,20574,20400,20304,20336,20070,20019,19893,19812,19829,19772,19829,19654,19772,19654,19547,19772,19517,19547,19654,35664,35775,35617,35664,35573,35511,38309,38294,38164,38309,38164,38167,39225,39339,39144,39206,39352,39113,39228,39356,39242,39242,39375,39158,39269,39602,39221,39239,39287,39225,39335,39287,39239,39335,39239,39211,39454,39411,39282,39122,39126,39362,39287,39305,39225,20658,20429,20508,20671,20848,20785,29845,29681,29653,30522,30240,30467,23344,23146,23242,20429,20363,20354,4875,4965,4900,4875,4900,4700,13492,13705,13365,19107,18993,18981,18996,18993,19107,3491,3612,3627,3535,3516,3545,3545,3501,3749,3554,3508,3646,3537,3478,3593,3593,3360,3538,3491,3627,3511,3627,3582,3511,3416,3414,3511,3288,3501,3545,39377,39339,39225,37239,37251,37111,37239,37111,37092,3582,3557,3494,10217,10086,10216,10384,10398,10332,21027,21143,20953,23396,23353,23146,31801,31585,31575,30702,30467,30616,31613,31585,31700,4581,4737,4476,15755,15722,15566,38764,38719,38831,3494,3557,3488,4718,4788,4733,21143,21229,21168,37736,37721,37649,39339,39352,39206,39362,39126,39141,3492,3733,3741,3592,3675,3546,3864,4066,3945,24137,23844,23958,25502,25875,25697,24215,24376,24179,24235,24376,24215,24195,23869,23991,30280,30168,30058,30485,30378,30244,29660,29829,29797,29807,29660,29397,39352,39332,39113,3595,3636,3615,3488,3700,3550,3595,3615,3642,17752,17700,17734,17153,16919,17069,17765,17700,17752,23320,23154,23240,21710,21561,21791,23320,23240,23514,24137,23958,24231,33294,33271,33173,33355,33440,33294,33537,33502,33364,33667,33502,33537,3642,3675,3592,23392,23320,23514,38752,38847,38655,38858,38847,38752,3501,3500,3611,21229,21371,21168,39332,39356,39228,30616,30750,30817,30240,30326,29963,3811,3864,3945,24693,24891,24626,39306,38377,38967,38868,38573,38714,39525,39172,38968,39014,38905,38795,35308,35317,35334,33937,33667,33537,35782,35819,35935,16144,16304,16190,15902,15944,15901,19905,19904,20079,32401,32408,32403,32401,32403,32254,35758,35519,35683,34188,33969,34826,37185,36953,37021,35739,35711,36036,37935,37915,38084,36640,36351,36517,4458,4433,4476,4405,4254,4450,3586,3986,3679,3538,3586,3679,3359,3586,3538,14227,14140,14146,14168,14140,14227,14419,14396,14516,16255,16483,16265,21710,21791,21878,22855,22628,23115,38068,38051,38037,38261,38195,38305,33413,33271,33294,10384,10332,10287,19904,19815,19775,19517,19364,19471,22206,22394,22473,16265,16483,16357,38552,38584,38369,38703,38584,38552,38436,38584,38741,31805,31603,31726,30879,31016,31079,30168,30146,30058,3747,3822,3901,3546,3733,3492,5373,5033,4766,5570,5033,5526,4655,4718,4733,4655,4733,4612,23146,23353,23312,23396,23344,23492,38064,37915,38031,39187,39218,38926,39070,38827,38879,3488,3444,3459,19471,19364,19348,4207,4433,4458,8927,8844,9025,9025,9128,9162,9797,10050,9664,9059,8944,9067,33271,33227,33173,34175,33455,33380,32974,32943,32685,38375,38261,38305,38400,38309,38167,38294,38813,38423,35205,35229,35277,35250,35229,35205,18993,18719,18886,18888,18719,18993,30280,30058,29862,30522,30385,30240,30607,30702,30817,21520,21771,21702,31603,31475,31726,35775,35968,35716,36402,36214,36332,36402,36391,36296,36517,36351,36391,35572,35511,35463,3935,3967,4093,3864,3747,3901,3935,4093,4016,5018,5091,5123,4968,5091,5018,4947,5001,4996,4947,4996,4850,16919,16849,17069,16144,16190,16127,16498,16570,16552,19348,19274,19177,37854,37860,37721,37491,37629,37477,37446,37289,37441,37289,37255,37364,38847,38908,38795,38752,38639,38945,9374,9365,9355,11403,11506,11218,12810,12720,12730,12869,12720,12810,12872,12810,12992,24891,24987,25028,25545,25537,25774,25121,24987,24891,24657,24626,24376,31726,31475,31414,5091,5133,5274,37863,37597,37723,37364,37255,37251,3444,3550,3397,21771,21888,21724,13049,12872,12992,13341,13836,13516,3597,3613,3867,5124,5242,5274,23353,23481,23403,23396,23481,23353,37383,37364,37251,3992,4266,4337,39365,39218,39187,23764,23647,23719,23001,22855,23115,24549,24137,24231,3432,3508,3554,3597,3662,3613,3711,3747,3864,3741,3817,3656,19815,19500,19775,39522,39375,39242,39221,39328,39160,30596,30385,30522,30168,30410,30244,10669,11054,10617,12786,12838,12999,29842,29681,29845,37208,37239,37092,37208,37092,37290,10284,10217,10243,8833,9022,10020,10284,10243,10384,14719,14854,14684,15474,15755,15566,16016,16127,15944,16016,16144,16127,38584,38436,38334,38450,38633,38583,3508,3478,3537,19348,19364,19274,19274,19197,19177,39375,39345,39191,14382,14463,14217,37721,37860,37659,37639,37624,37635,38450,38375,38272,38276,38064,38051,38051,38064,38031,3589,3482,3624,3581,3595,3642,3581,3642,3592,18719,18588,18663,18613,18588,18719,23001,23115,23320,22366,22206,22473,33969,33772,34370,35440,35455,35277,37044,37277,36659,37362,37021,37253,3613,3662,4056,3597,3867,3390,4819,4850,4875,4429,4581,4366,37472,37362,37466,38173,38076,38261,16389,16570,16498,16389,16498,16304,3967,3879,3945,4084,3935,4016,15755,15901,15722,25339,25291,25093,35367,35277,35229,19088,19024,18638,14546,14516,14750,12869,12810,12872,17205,17374,17301,23991,23869,23642,25434,25537,25430,30385,30326,30240,30702,30607,30467,30817,30750,30992,17290,17278,17377,16887,16919,16843,8089,7914,7966,8181,7990,8089,8079,8536,8746,18588,18494,18466,18613,18494,18588,22474,22473,22569,23086,23001,23320,22761,22569,22855,39278,39362,39141,7990,7914,8089,23764,23719,23844,33937,33341,34429,33502,33440,33355,33271,33413,33227,10171,10520,10223,9128,9365,9162,35819,35782,35757,35711,36234,36036,38381,38173,38261,37863,37723,37991,7914,7757,7966,10217,10088,10086,11196,11040,11210,31383,31282,31376,31613,31376,31585,31757,31786,31801,32210,32401,32254,32664,32974,32685,32398,32401,32210,35455,35572,35463,35959,35968,35775,35703,35572,35455,4580,4655,4612,19088,19197,19024,12720,12548,12536,12665,12548,12720,12869,12872,12905,12475,12645,12322,37507,37629,37491,37617,37629,37507,37617,37507,37446,37441,37289,37364,3728,3733,3546,3463,3482,3589,30287,30326,30385,30100,30326,30287,7757,7641,7824,7233,6768,7082,4470,4550,4736,33667,33440,33502,4102,4187,4364,4182,4254,4405,4478,4580,4581,4581,4580,4612,5133,5124,5274,5096,5124,5133,4968,4947,4858,5096,5133,5091,5242,5224,5327,13705,13876,13365,24195,24235,24215,24575,24235,24446,29567,29374,29400,27988,27690,28462,29391,29374,29567,31646,32371,32297,37383,37251,37239,37383,37441,37364,37636,37639,37635,38375,38381,38261,38436,38450,38272,38703,38614,38764,39212,39070,38879,39370,38983,39218,39370,39141,38983,39048,38879,38905,16726,16465,16849,16265,16060,16182,14486,14419,14443,38884,38908,38847,38884,38847,38858,30992,30750,31115,36402,36332,36510,25430,25537,25545,25339,25093,25254,5178,5224,5242,12905,13049,13035,18638,19024,18098,33440,33413,33294,36036,36234,36270,37466,37362,37253,37723,37935,37991,38243,38125,37912,37639,37736,37624,38764,38614,38719,17290,17377,17338,16919,16887,16849,26079,26098,26415,24443,24549,24231,23796,23764,23844,26079,26362,26085,18254,17765,17877,23796,23844,24137,23605,23392,23514,35161,35295,35012,35550,35317,35519,35292,35250,35205,20643,20671,20738,20848,21027,20953,21143,21116,21229,21229,21331,21371,21371,21520,21702,21771,21840,21888,20400,20441,20304,20304,20019,20070,19911,19893,20019,19812,19893,19911,19789,19893,19812,19789,19812,19772,39305,39377,39225,39339,39408,39352,39352,39401,39332,39332,39401,39356,39356,39412,39242,39375,39570,39345,39287,39441,39305,39335,39441,39287,39461,39441,39335,39211,39208,39556,39411,39208,39282,4736,4550,4953,4431,4109,4549,3797,3967,3935,5767,5033,5570,20658,20544,20429,20429,20473,20363,20079,19904,20148,19505,19500,19815,19337,19402,19500,21211,20920,21180,21211,21180,21274,39441,39433,39305,3515,3636,3493,3817,3776,3656,6232,7008,6509,20544,20473,20429,19682,19789,19772,35703,35613,35572,35572,35613,35511,35782,35758,35683,37184,37044,37185,37412,37208,37290,38084,37915,38064,37846,37854,37721,39433,39377,39305,3636,3595,3493,4447,4439,4776,14443,14419,14516,14491,15331,14750,14719,14713,15039,15808,15712,15776,13936,14382,14217,14579,14515,14688,15755,15712,15808,16236,16389,16304,19273,19107,19366,17439,17469,17512,19402,19366,19500,30410,30485,30244,31503,31726,31414,32255,32398,32210,30473,30485,30410,30280,30410,30168,30280,30329,30375,39454,38874,39122,39370,39218,39475,20965,21027,20848,39377,39408,39339,21027,21116,21143,23396,23146,23344,17469,17611,17700,19542,19292,19610,16570,17205,16622,16475,17205,16570,34980,35149,35205,34370,33772,34366,3511,3414,3491,3491,3393,3516,3516,3393,3545,3343,3554,3238,3343,3432,3554,3508,3432,3478,3416,3511,3582,3416,3582,3426,3582,3494,3426,19471,19547,19517,21274,21421,21561,36373,36084,35942,39454,39122,39362,5206,5374,5456,9025,8844,8826,30100,29973,29963,29842,29973,30080,37302,37184,37185,31161,30992,31115,30287,30385,30596,31161,31115,31305,37412,37383,37208,36522,36517,36391,3426,3494,3459,3797,3879,3967,3656,3776,3678,3811,3879,3505,16465,16357,16483,16437,16357,16465,16726,16849,16887,16236,16304,16144,21298,21274,21388,35250,35367,35229,35346,35367,35250,38908,39014,38795,38945,38639,39216,39537,39401,39352,39365,39187,39172,39543,39454,39362,16843,16726,16887,7641,7294,7486,21256,21331,21229,23481,23547,23642,39401,39394,39356,15902,16016,15944,35950,35758,35782,4223,4405,4301,19471,19348,19547,39394,39412,39356,31272,31161,31305,32297,32371,32787,36516,36369,36505,35935,35950,35782,38703,38656,38584,38463,38381,38375,38741,38656,38703,18996,18888,18993,18705,18888,18785,3459,3494,3488,19547,19348,19326,33159,32974,32664,35000,35032,34826,34826,35027,34980,12905,12872,13049,14750,15331,14805,14382,14579,14684,15755,15902,15901,14713,14579,14688,38194,38084,38064,38463,38375,38583,17290,17153,17069,17138,17153,17290,17469,17700,17765,24806,24549,24514,35367,35440,35277,36020,35968,35959,35690,35440,35367,3493,3595,3446,3776,3822,3678,23605,23514,23647,22887,22761,22855,21874,21710,21878,23605,23647,23796,22002,22089,21888,37639,38095,37736,37736,37846,37721,37629,37636,37635,37441,37617,37446,37788,37617,37441,5178,5206,5224,5224,5206,5327,4864,5096,5091,4968,5018,4947,38831,38719,38662,4900,4718,4700,4850,4996,4875,12844,12665,12869,12869,12665,12720,11579,12298,11629,14146,14140,13878,12645,12656,12786,12475,12656,12645,37617,37636,37629,3595,3581,3446,3444,3488,3550,4700,4718,4655,13878,14140,13900,37863,37706,37597,37362,37302,37021,37905,37706,37863,39328,39221,39484,39422,39328,39484,38714,38746,39047,4478,4581,4454,12298,12496,11629,13900,14140,13994,16357,16269,16265,16245,16269,16357,16437,16465,16726,16294,16236,16144,16389,16392,16570,16392,16236,16294,21790,21710,21874,25537,25800,25774,27257,26971,26795,25254,25093,24987,24657,24376,24235,30100,29963,30326,31383,31376,31613,35027,35080,34980,31680,31383,31613,38309,38400,38294,38243,37912,38485,38243,38485,38397,3879,3811,3945,3864,3811,3712,5178,5242,5124,37208,37383,37239,36710,36460,36640,38095,37846,37736,8441,8746,8831,7782,7812,7914,7914,7812,7757,7757,7541,7641,7041,6970,7294,7782,7397,7243,36517,36649,36640,36522,36649,36517,36522,36391,36402,3550,3523,3397,39392,39362,39278,15808,15902,15755,35308,35295,35161,35673,35550,35519,35673,35519,35758,4075,4102,3977,4187,4223,4301,3385,3867,3586,31801,31700,31585,31808,31700,31801,31503,31079,31521,33005,32977,32891,3397,3523,3399,3446,3581,3592,7782,7914,7990,22887,22855,23001,39328,39350,38967,39422,39350,39328,18304,18428,18494,16712,16437,16726,24575,24657,24235,29973,29842,29845,30607,30596,30522,37184,37277,37044,37310,37302,37321,9059,9128,8826,9113,9128,9059,35080,35149,34980,3478,3450,3593,3554,3500,3238,4366,4476,4433,4162,4223,4187,4478,4700,4655,13574,13365,13876,19326,19348,19177,19326,19177,19088,4371,4261,3560,14546,14486,14443,14628,14750,14617,14579,14713,14719,14735,14713,14688,3523,3482,3399,3432,3450,3478,18705,18613,18719,18705,18719,18888,30903,30817,30992,36036,35950,35935,35977,35950,36071,36045,35968,36052,36052,35968,36020,3597,3547,3662,3412,3547,3334,23392,23086,23320,23796,23647,23764,23396,23547,23481,23492,23547,23396,14628,14486,14546,13197,13049,13365,32210,32030,32207,35741,35673,35758,35334,35295,35308,38378,38400,38167,38378,38167,38237,4550,4447,4776,4618,4631,4736,4618,4736,4766,9128,9196,9365,27894,28124,28496,27257,26795,26803,35334,35317,35567,35149,35292,35205,39035,39014,38908,39552,39365,39172,39035,38908,38884,25339,25434,25430,25254,25434,25339,10284,10148,10217,10384,10547,10398,19905,19815,19904,10171,10223,9840,12547,12838,12656,10223,9935,9840,31161,31046,30992,31126,31046,31161,31126,31161,31272,36649,36710,36640,36510,36522,36402,3678,3822,3747,3362,3463,3380,17469,17439,17377,17338,17439,17295,10148,10088,10217,24657,24693,24626,24575,24693,24657,38824,38741,38703,38583,38375,38450,38746,39127,39047,18613,18475,18494,18577,18475,18613,30903,30607,30817,30438,30280,30375,30485,30899,30879,4439,4347,4431,4376,4447,4550,19402,19273,19366,19326,19292,19542,28569,28462,28999,24779,24461,24549,29391,29315,29374,36785,36710,36649,37912,37860,38485,35567,35317,35550,38194,38064,38276,38051,38173,38276,29567,29400,29681,29567,29681,29749,29681,29842,29749,12656,12838,12786,12645,12278,12322,33314,32371,33227,31700,31680,31613,32977,33159,32664,32073,31810,31805,4858,4947,4850,4864,5091,4968,5075,5124,5096,5075,5178,5124,5206,5164,5374,29749,29842,29814,31800,31918,31805,31800,31805,31726,35968,36045,35942,35703,35455,35440,4223,4182,4405,4819,4875,4724,4130,4182,4223,3399,3482,3463,3589,3515,3463,4102,4162,4187,4075,4162,4102,12230,11961,12548,12905,12844,12869,13197,13035,13049,13197,13365,13269,16843,16919,17019,14617,14750,14805,22592,22474,22569,23408,23086,23392,39442,39365,39770,39475,39392,39278,17439,17338,17377,17138,17338,17295,14168,14227,14419,14750,14628,14546,16209,16265,16269,38450,38436,38633,25434,25486,25537,25491,25486,25434,30080,29973,30100,37383,37788,37441,37617,38095,37636,38357,37854,37846,37290,37092,37102,39216,38639,38423,26415,26841,26362,30438,30473,30410,9196,9355,9365,3712,3711,3864,3712,3811,3505,5033,4854,4779,4538,4470,4736,13574,13876,13878,17042,16919,17153,13873,13900,13994,35080,35290,35149,35149,35346,35292,35292,35346,35250,35027,35058,35080,34826,35032,35027,33772,34327,34366,38276,38173,38545,3463,3515,3380,10287,10148,10284,10398,11064,11040,36332,36214,36084,36522,36785,36649,39475,39278,39370,24162,23796,24137,23507,23408,23392,23709,23796,24015,10166,10148,10287,10088,10005,10086,31521,31079,31147,4447,4347,4439,4363,4347,4447,26803,26795,26769,38400,38813,38294,38355,38378,38237,38355,38237,38243,37302,37310,37184,37472,37302,37362,37472,37466,37748,37991,37935,38084,37292,36873,37287,37292,37102,36873,33350,33159,33542,32073,32207,32030,32073,31805,31918,20671,20887,20848,21027,21040,21116,21116,21256,21229,21331,21493,21371,20400,20574,20643,20336,20574,20400,20336,20304,20313,20304,20070,20313,20070,20151,20313,20122,20151,20070,20604,20887,20671,4755,4618,4766,20061,20122,20070,20887,20965,20848,37992,37991,38129,35032,35058,35027,3414,3393,3491,3432,3343,3450,3289,3393,3414,3373,3414,3416,3373,3416,3426,3373,3426,3336,3426,3459,3336,3459,3365,3336,6509,7008,7072,6768,7233,7294,19893,20061,20070,32055,31808,31801,31739,31800,31726,3483,3492,3741,3564,3678,3747,19893,19950,20061,35637,35550,35673,35637,35567,35550,39401,39537,39394,39394,39642,39412,39412,39522,39242,39408,39480,39352,39377,39480,39408,39668,39480,39377,39668,39377,39433,39668,39433,39441,39668,39441,39461,39556,39208,39411,39556,39411,39656,10669,11403,11218,19893,19796,19950,30287,30135,30100,30204,30135,30397,30903,30992,31104,39480,39537,39352,16294,16144,16172,16236,16392,16389,19531,19547,19326,16144,16016,16172,26587,25985,25774,25121,25254,24987,25121,24891,24922,38545,38173,38381,38288,37991,38084,3459,3444,3365,19950,19796,19985,21040,21256,21116,22592,22569,22701,22569,22761,22701,39442,39475,39218,39392,39543,39362,3711,3629,3747,3797,3935,4084,38741,38584,38656,38746,38812,39127,25800,25537,25486,38463,38482,38381,38703,38764,38824,19682,19772,19547,32057,32073,31918,32401,32891,32664,12838,12891,12999,12322,12278,11864,34505,34370,34366,35032,35071,35058,33159,33201,32974,5033,5767,4854,4535,4538,4618,10548,10669,10617,9813,9935,9797,10203,10166,10287,10661,10398,11040,10380,10398,10509,21256,21493,21331,31272,31305,31452,36373,36332,36084,36606,36785,36522,36373,35942,36045,36733,36504,36659,35977,35741,35758,38523,38482,38463,4825,4858,4850,4819,4724,4825,5107,5164,5206,5015,5075,5096,3461,3592,3546,3365,3444,3358,22701,22761,22887,30280,30438,30410,30473,30899,30485,30280,29862,30329,3444,3397,3358,4478,4655,4580,9196,9103,9355,9643,9813,9797,9128,9113,9196,9128,9025,8826,21493,21520,21371,31104,30992,31046,30713,30899,30473,31503,31739,31726,31800,31915,31918,31808,31680,31700,31814,31680,31808,31521,31739,31503,36606,36522,36510,23507,23392,23605,23507,23605,23709,33413,33441,33227,32297,32055,31786,33440,33561,33413,33667,33561,33440,33937,33561,33667,33971,35012,34429,35381,35295,35334,37310,37277,37184,37713,37414,37706,39385,39306,38967,39385,38967,39350,4538,4736,4631,4538,4631,4618,4581,4476,4366,13900,13873,13878,14168,14419,14284,39636,39522,39412,38378,38474,38400,38397,38355,38243,37860,38357,38485,13197,13143,13035,13035,12844,12905,13269,13143,13197,37992,37905,37863,37992,37863,37991,16392,16475,16570,15808,16016,15902,33561,33441,33413,34370,34704,33969,39014,39048,38905,38945,38977,38858,39035,38977,39140,22887,23001,23086,39484,39221,39613,16843,16712,16726,16245,16209,16269,16669,16712,16843,17042,17153,17138,39035,39048,39014,39365,39442,39218,19591,19682,19547,19591,19547,19531,21710,21790,21561,20678,20920,21211,20678,20658,20920,20544,20536,20473,20079,20148,20363,19402,19337,19273,21874,21878,22206,21874,22206,22237,22473,22474,22366,39522,39517,39375,35734,35381,35334,35734,35334,35567,35290,35346,35149,35290,35080,35058,9489,9664,9355,30897,30596,30607,31808,32055,32018,35775,35664,35959,9213,9489,9355,25724,25697,25875,25724,25875,26079,35977,35758,35950,38155,38194,38327,38155,38084,38194,3358,3270,3276,3483,3741,3656,3571,3656,3678,19531,19542,19591,22366,22474,22432,22878,22887,23086,23709,23605,23796,24267,24446,24195,23146,22345,22827,4207,4458,4254,4162,4130,4223,4040,4130,4162,17138,17290,17338,18475,18304,18494,18828,18888,18996,18828,18996,18978,24446,24235,24195,4207,4254,4182,4724,4875,4700,3977,4102,4364,4096,4207,4182,38824,38764,38878,38583,38523,38463,33441,33314,33227,34704,34908,34826,3450,3360,3593,3068,3500,3501,19531,19326,19542,31126,31104,31046,30645,30397,30596,31109,31104,31126,31305,31383,31452,4535,4618,4755,38888,38831,38868,38888,38764,38831,3391,3399,3463,3391,3397,3399,3343,3371,3450,34908,35000,34826,39736,39543,39392,39611,39543,39736,23286,23086,23408,22432,22474,22572,39281,38968,39070,3706,3797,4084,3564,3571,3678,4109,4431,4127,4363,4447,4376,16245,16357,16437,14284,14419,14486,16532,16437,16712,16503,16532,16712,24864,24891,24693,25254,25491,25434,9813,9840,9935,12387,12322,11786,9678,9840,9813,31797,31915,31800,32398,32891,32401,31797,31800,31739,3629,3711,3712,12475,12547,12656,12387,12547,12475,37868,37706,38046,37868,37713,37706,4376,4550,4470,13873,13715,13878,14617,14486,14628,14983,15431,15039,14735,15039,14713,17042,17019,16919,17138,17019,17042,25914,25724,26079,25697,25616,25340,32505,32207,32073,35000,35071,35032,35690,35703,35440,38355,38474,38378,38500,38397,38716,13994,13715,13873,27257,27961,27629,28277,28694,28496,27976,28075,28089,38327,38194,38276,38046,37706,37905,38545,38381,38482,4819,4825,4850,4858,4864,4968,4724,4463,4604,12963,12844,13035,12980,13035,13143,3461,3446,3592,3461,3546,3492,3371,3360,3450,13135,12980,13143,29585,28999,29391,28940,28569,28999,26415,26855,26841,29626,29391,29567,29814,29567,29749,29814,29842,30080,23515,23286,23408,23515,23709,23786,30204,30100,30135,30135,30287,30397,30897,30607,30903,31452,31383,31477,4127,4431,4097,4130,4156,4182,4340,4454,4429,4044,4156,4130,10203,10287,10332,10148,10005,10088,10203,10332,10249,31147,31079,31016,31147,31016,30899,38741,38633,38436,38664,38633,38778,4109,4014,4549,14805,15331,15392,38678,38523,38583,3560,4261,3355,4075,4040,4162,4261,3662,3355,13329,13269,13365,16532,16445,16437,16209,16060,16265,16503,16445,16532,16238,16475,16392,16238,16392,16294,38977,39035,38884,39048,39212,38879,39129,39035,39140,3916,3992,4337,25914,26085,25990,4429,4454,4581,4366,4237,4265,11629,12496,11961,13147,13135,13269,14168,13994,14140,14105,13994,14168,16196,16060,16209,25511,25491,25254,28083,27976,28089,34429,35012,35458,35741,35637,35673,35771,35637,35741,35690,35367,35346,37472,37321,37302,37351,37321,37453,32018,31814,31808,31829,31814,31938,31915,32057,31918,31794,31797,31739,7812,7541,7757,8079,7782,7990,7541,7782,7243,35012,35295,35458,33561,33570,33441,33441,33410,33314,3505,3629,3712,3747,3629,3574,25121,25180,25254,24575,24864,24693,24731,24864,24575,9113,9103,9196,9489,9643,9797,8304,7887,8176,5455,5724,5102,38500,38474,38355,3362,3391,3463,3571,3483,3656,3380,3515,3493,3381,3483,3293,22474,22592,22572,22592,22701,22572,34704,34802,34908,34908,34977,35000,35000,35135,35071,34370,34505,34704,33455,34243,33772,39034,38888,38868,38824,38808,38741,30397,30287,30596,37287,36873,37124,37290,37542,37412,37412,37542,37383,38397,38500,38355,36564,36710,37124,36606,36510,36699,36373,36045,36177,18374,18304,18475,18577,18613,18705,20678,21211,21298,21211,21274,21298,21561,21388,21274,20574,20604,20671,20940,21040,20965,20965,21040,21027,21256,21436,21493,21493,21436,21520,20533,20604,20574,20533,20574,20336,20533,20336,20300,20336,20313,20300,20313,20151,20300,20151,20156,20300,20122,20156,20151,20116,20156,20122,20116,20122,20061,21561,21790,21388,3393,3288,3545,3244,3320,3371,3371,3320,3360,2979,3288,3393,3289,3414,3298,3414,3373,3298,3373,3228,3298,3336,3228,3373,20661,20536,20544,19985,20116,20061,35959,35664,35613,22366,22237,22206,22795,22701,22887,31829,31663,31814,33678,33570,33561,34505,34650,34704,35071,35290,35058,39726,39411,39454,39744,39642,39537,39537,39642,39394,39522,39607,39517,9059,9103,9113,4091,4433,4207,4838,4858,4825,10023,10005,10148,10380,10332,10398,19950,19985,20061,20940,20965,20887,21520,21840,21771,23991,23642,23547,30897,30903,31104,31663,31383,31680,31794,32057,31797,31226,31147,31106,30509,30473,30438,36524,36510,36332,3336,3365,3321,19789,19796,19893,27961,27976,28124,27961,27883,27976,34650,34802,34704,3321,3365,3273,3937,4040,4075,4156,4096,4182,4838,4864,4858,4700,4478,4137,10023,10148,10166,11521,12322,11864,12547,12726,12838,10669,10548,10407,19789,19716,19796,31814,31663,31680,32787,32371,33200,4109,4086,4014,4014,3916,4337,4097,4431,4347,4080,4096,4156,14723,14805,14804,14617,14284,14486,30897,31104,31109,38633,38664,38583,38523,38578,38482,38678,38664,38843,25835,25616,25724,25724,25616,25697,24864,24922,24891,24795,24922,24864,12620,12726,12547,37713,37847,37466,38140,37905,37992,38129,37991,38288,3360,3359,3538,3128,3359,3360,10180,10548,10171,31109,31126,31272,39500,39385,39350,39306,39544,38669,39602,39269,39345,39570,39375,39517,3435,3461,3492,18304,18254,18428,16669,16503,16712,18258,18254,18304,23243,23286,23515,23408,23507,23515,39511,39350,39422,3992,3872,4084,3908,3916,4014,3911,3977,4364,38657,38578,38523,33609,33410,33441,4285,4478,4454,6970,6768,7294,11961,12536,12548,12980,12963,13035,12988,12963,12980,13135,13143,13269,19682,19691,19716,19789,19682,19716,28277,28496,28124,29814,29711,29567,29767,29711,29814,30080,30100,30204,20079,20363,20473,21346,21436,21256,24414,24457,24446,31797,32057,31915,31794,31739,31521,39744,39537,39943,38329,38327,38276,3380,3493,3326,3273,3365,3213,19168,18996,19273,26085,25914,26079,26855,26944,27171,38888,38878,38764,39034,38878,38888,3574,3564,3747,3453,3435,3492,3574,3629,3505,5033,4671,4766,4387,4376,4470,4065,4109,4127,4535,4671,4452,5107,5206,5178,5015,5178,5075,10661,11040,11196,12548,12665,12230,13329,13365,13574,13878,13715,13574,17295,17439,17384,16445,16245,16437,24446,24457,24575,23991,23547,23791,34802,34977,34908,35703,35959,35613,14222,14284,14218,37860,37854,38357,39140,38977,39279,19682,19591,19691,21436,21594,21520,30696,30645,30596,30184,30080,30204,39642,39636,39412,23472,23547,23492,22827,22345,22231,39385,39458,39306,39539,39458,39385,3365,3358,3276,16060,15851,16182,16503,16245,16445,19691,19591,19542,31452,31336,31272,30897,30696,30596,31489,31336,31452,37124,36710,37104,36635,36524,36332,34977,35135,35000,4671,4535,4755,13574,13533,13403,28083,28277,28124,30184,30204,30397,38298,38084,38155,39035,39117,39048,39129,39117,39035,3358,3397,3270,3326,3493,3446,10077,10023,10166,8749,8441,9022,10077,10166,10203,18828,18785,18888,18660,18785,18828,31654,31644,31663,31663,31644,31383,36071,35950,36112,37149,36733,36659,3397,3391,3270,19088,19292,19326,39636,39607,39522,35950,36036,36270,35637,35734,35567,36635,36699,36524,35919,35959,35703,4065,4086,4109,3916,3872,3992,4256,4347,4363,4265,4340,4366,4040,4044,4130,3919,4044,4040,4520,4470,4538,4366,4340,4429,4147,4207,4096,3453,3492,3483,3229,3326,3446,14579,14382,14515,15776,16172,16016,23344,23472,23492,23791,23472,23795,38329,38315,38327,38664,38678,38583,38778,38633,38811,21594,21840,21520,27171,26944,27421,39543,39611,39454,39580,39392,39475,39580,39475,39442,24457,24628,24575,25511,25800,25491,24568,24628,24457,24731,24628,24568,39351,39281,39070,3270,3249,3211,3376,3446,3461,3359,3385,3586,3125,3385,3359,4465,4520,4538,13574,13715,13533,22878,22795,22887,22367,22237,22366,22231,22345,22089,27976,28083,28124,27961,27257,27883,37321,37277,37310,37269,37277,37351,37292,37327,37290,36877,36785,36606,39578,39511,39422,39578,39422,39484,19088,18638,19292,39607,39570,39517,3707,3872,3685,35135,35290,35071,4771,5015,5096,4726,4838,4825,4726,4825,4724,16245,16196,16209,16071,16196,16132,15776,16016,15808,16475,16701,17205,39127,38812,38909,38808,38633,38741,3391,3362,3306,3331,3376,3461,3381,3453,3483,4771,5096,4864,18785,18577,18705,17512,17469,17765,18660,18577,18785,22367,22366,22432,22957,22878,23086,23243,23086,23286,29711,29626,29567,28569,27988,28462,29734,29626,29711,34650,34825,34802,34802,34893,34977,34977,35247,35135,35135,35247,35290,34505,34609,34650,33350,33204,33201,9970,10180,10171,9678,9643,9346,35890,35771,35741,36270,36234,36749,10661,11196,10718,36524,36699,36510,36736,36699,36635,31644,31477,31383,30971,30696,30897,31654,31477,31644,36877,36710,36785,38327,38315,38155,38329,38276,38545,4376,4256,4363,4327,4256,4376,14284,14222,14168,14218,14284,14243,14105,14222,14218,35890,35741,35977,5015,5107,5178,8826,8844,8432,15860,15851,16060,15712,15755,15302,25491,25800,25486,25180,25121,25015,30612,30397,30645,29876,29814,30080,29876,29767,29814,29570,29397,29000,29829,29807,30173,29807,29949,30173,34630,34609,34505,3306,3362,3278,3244,3371,3343,3284,3435,3453,3505,3879,3797,10509,10661,10445,12230,12665,12844,13135,12988,12980,13147,12988,13135,13147,13269,13329,13147,13329,13315,19505,19337,19500,24628,24731,24575,24267,24195,23991,36717,36877,36606,39570,39602,39345,9103,9095,9355,9059,9067,9103,5150,5374,5164,32018,32055,32117,32664,32891,32977,33159,33350,33201,31908,31794,31521,31908,31521,32011,34609,34673,34650,39566,39127,38909,39511,39500,39350,39577,39500,39511,4086,3951,4014,4037,4065,4127,5071,5150,5164,14735,14983,15039,14833,14983,14735,38678,38657,38523,38808,38824,39007,3977,3937,4075,4032,4147,4096,3889,3937,3977,19337,19312,19273,39030,38824,38878,4179,4097,4347,4080,4156,4044,13793,14217,13836,33410,33378,33314,33570,33609,33441,33678,33609,33570,33678,33561,33937,38843,38657,38678,31109,31272,31292,3606,4364,3727,3606,3911,4364,9067,9095,9103,25015,25121,24922,38977,38945,39279,39290,39351,39070,35996,35890,35977,35458,35295,35381,25253,25511,25254,19312,19168,19273,22367,22432,22572,25211,25253,25180,24099,24267,23991,24414,24384,24490,40001,39580,39442,39212,39048,39117,37341,37327,37287,37287,37327,37292,37240,37287,37124,4256,4179,4347,4178,4179,4256,18577,18374,18475,17138,16669,17019,18509,18374,18577,4520,4387,4470,4535,4465,4538,4452,4465,4535,4452,4671,4488,3412,3662,3547,39303,39212,39117,31314,31272,31336,31314,31336,31395,37235,37240,37124,36699,36717,36606,36736,36717,36699,33483,33378,33410,32255,32505,32398,3334,3547,3597,3390,3867,3385,16068,16238,16172,15302,15755,15474,31829,31654,31663,31945,31654,31829,22572,22701,22795,30329,29862,29829,37277,37269,36659,36749,36234,36516,36071,35996,35977,37351,37277,37321,37847,37713,37868,37847,37868,37908,37104,36710,36877,4605,4726,4604,4237,4366,4433,14222,14105,14168,14723,14617,14805,3331,3461,3435,3278,3362,3380,3331,3435,3284,28428,27988,28569,38046,37905,38140,38315,38298,38155,38347,38298,38315,20604,20831,20887,21040,21215,21256,21436,21346,21594,21594,21777,21840,20727,20831,20604,20468,20604,20533,20236,20533,20300,20236,20300,20156,20236,20156,20075,20156,20116,20075,20116,19985,20075,19985,20023,20075,19796,19843,19985,39809,39668,39793,39642,39677,39636,39636,39677,39607,39607,39703,39570,39570,39746,39602,39668,39461,39793,3278,3380,3202,19168,18978,18996,39602,39613,39221,39696,39613,39831,4285,4454,4340,4838,4796,4864,5063,5071,5107,5107,5071,5164,18137,17765,18254,16196,16071,16060,20831,20940,20887,21840,22002,21888,24267,24414,24446,24568,24414,24490,32117,32055,32297,19796,19716,19843,25180,25253,25254,25015,24922,24886,39047,39044,38868,39544,39306,39458,39129,39262,39117,39245,39140,39395,39688,39656,39411,3872,3796,4084,4065,3951,4086,3948,3951,4065,4037,4127,4097,3795,3919,3937,3937,3919,4040,4147,4091,4207,3889,3977,3911,3948,4037,4097,3919,4080,4044,14983,15044,15431,14677,14833,14735,14677,14735,14688,12726,12891,12838,12620,12891,12726,12387,12475,12322,38140,37992,38129,39116,39044,39047,9067,8944,9095,8176,8835,8304,3831,3889,3690,3941,4091,4147,19905,19505,19815,19337,19363,19312,19312,19267,19168,19168,19163,18978,20536,20079,20473,20331,20079,20536,20756,20536,20661,20756,20661,20678,21790,21568,21388,19843,19716,19743,21136,21215,21040,39726,39454,39611,39786,39688,39411,3194,3278,3202,2813,3390,3385,5576,6321,5724,5063,5107,5015,23515,23507,23709,22706,22572,22795,37527,37290,37327,37527,37542,37290,39500,39539,39385,39596,39539,39500,39736,39580,40115,21790,21892,21568,10380,10249,10332,10023,10077,10005,10343,10249,10380,10509,10398,10661,11196,11579,11078,31109,30971,30897,31489,31452,31477,31489,31477,31654,4397,4387,4520,4179,4178,4097,13315,13329,13574,12988,12230,12963,13724,13793,13341,38204,38140,38129,38298,38288,38084,38545,38482,38578,3321,3228,3336,3298,3124,3289,3289,2979,3393,3123,3238,3096,3109,3228,3107,3107,3321,3273,3213,3365,3276,3213,3276,3211,3276,3270,3211,10196,10077,10203,21932,21874,22023,21215,21346,21256,39845,39537,39480,3707,3796,3872,11078,10906,10760,36717,36853,36877,37240,37341,37287,36845,36853,36717,39525,38968,39281,39299,39290,39070,39299,39070,39212,22367,22294,22237,22903,22795,22878,39613,39578,39484,39696,39578,39613,32018,31938,31814,31945,31938,32117,36796,36516,36733,13403,13315,13574,19743,19716,19691,19743,19691,19610,39744,39677,39642,3194,3306,3278,3381,3293,3303,3571,3293,3483,18258,18137,18254,18258,18304,18374,34243,33455,34175,34366,34630,34505,34609,34793,34673,34673,34825,34650,35734,35637,35771,33609,33483,33410,16172,16238,16294,16068,16172,15776,16068,15776,15797,37099,37104,36877,5576,5724,5455,19902,19743,19610,24795,24864,24731,40159,39726,39611,30375,30509,30438,30173,30329,29829,28915,28694,28277,37269,37149,36659,37453,37321,37611,37415,37341,37240,4387,4327,4376,4265,4278,4340,4233,4278,4265,7782,7541,7812,8441,8831,9022,34521,34630,34366,38440,38347,38616,38778,38843,38664,38808,38811,38633,38906,38811,39016,4091,4124,4433,4080,4032,4096,3941,4032,4080,3795,4080,3919,14804,14805,15084,13308,13403,13461,14694,14723,14781,21629,21777,21594,24795,24568,24769,39677,39703,39607,28083,28089,28277,27883,27257,27910,27883,27910,28075,27769,27910,27257,25800,25511,25677,38398,38288,38298,38347,38315,38329,9643,9678,9813,11271,11864,11403,9346,9643,9489,9085,9355,9095,35890,35867,35771,36270,36112,35950,23243,22957,23086,24461,24137,24549,25462,24996,25616,25835,25724,25914,24414,24568,24457,23472,23344,23242,39320,39299,39212,39525,39281,39496,31314,31292,31272,31858,31489,31654,3320,3128,3360,3238,3500,3096,3954,4124,4091,4704,4796,4838,4731,4838,4726,10455,10343,10509,10509,10343,10380,10249,10196,10203,13724,13936,13793,11032,11403,10669,14219,14515,14382,14833,15044,14983,17679,17512,17765,16669,16843,17019,21777,21901,21840,31395,31292,31314,30145,30184,30612,33200,32371,33314,33704,33678,33793,34793,34825,34673,36177,36020,35959,36045,36052,36177,36853,37099,36877,36052,36020,36177,4605,4731,4726,12387,12620,12547,13936,14219,14382,18916,18660,18828,17505,17384,17512,18916,18828,18978,37611,37321,37663,38016,37908,37868,38016,37868,38046,38016,38046,38143,11078,11579,10996,30329,30509,30375,37207,37235,37124,37207,37124,37104,26303,25990,26085,25908,25990,26082,35544,35346,35290,34825,34893,34802,3270,3391,3249,3391,3306,3249,19580,19505,19905,39703,39746,39570,25426,25511,25253,38251,38204,38129,38545,38578,38689,39127,39116,39047,39044,39034,38868,39266,39116,39501,39245,39262,39129,39245,39129,39140,4278,4285,4340,4124,4237,4433,14555,14284,14617,13936,14217,13793,38689,38578,38823,3412,3355,3662,3390,3334,3597,3272,2756,3047,33704,33483,33609,39643,39544,39458,39643,39458,39539,39577,39511,39578,3238,3244,3343,18660,18578,18577,18775,18578,18660,21901,22002,21840,35681,35544,35290,39712,39577,39578,38357,37846,38402,37461,37527,37327,37461,37327,37341,39136,39034,39044,36375,36177,35959,17512,17384,17439,17679,17765,17883,30509,30713,30473,39281,39497,39496,39303,39320,39212,3249,3306,3194,19505,19363,19337,22002,22140,22089,27988,27707,27421,28382,28428,28673,29585,29391,29626,29734,29711,29767,38251,38129,38288,3951,3908,4014,3796,3706,4084,3815,3908,3951,3948,4065,4037,10278,10196,10249,9842,10086,10005,10278,10249,10343,9970,10171,9840,14723,14694,14617,14805,15392,15084,14515,14677,14688,14660,14677,14515,18578,18509,18577,18360,18509,18775,22903,22957,23127,22318,22294,22367,30184,30397,30612,30612,30645,30824,31489,31395,31336,31609,31395,31489,31945,31829,31938,36426,36635,36332,37271,37099,36853,36845,36635,36838,37748,37466,37847,37351,37354,37269,37415,37240,37235,37415,37461,37341,4233,4285,4278,14660,14833,14677,13793,13836,13341,27716,27707,28109,35544,35690,35346,35713,35690,35544,5724,5374,5102,5374,5150,5102,10445,10455,10509,19363,19267,19312,13147,13148,12988,13315,13148,13147,14107,13994,14105,14107,14105,14218,16669,17138,17295,38417,38251,38288,38398,38298,38347,39262,39303,39117,38813,38400,38474,4212,4178,4256,3454,3606,3727,3941,4147,4032,3485,3727,3560,16132,16196,16245,19610,19691,19542,15797,15776,15712,25630,25462,25616,22903,22878,22957,36101,35996,36071,36101,36071,36112,36101,36112,36261,3295,3446,3376,5089,5150,5071,22318,22367,22572,22140,22231,22089,36845,36717,36736,37453,37354,37351,18509,18438,18374,18360,18438,18509,39577,39596,39500,39711,39596,39577,24568,24795,24731,25223,25426,25253,23791,23547,23472,3707,3706,3796,6768,6509,7072,4854,5767,4532,6307,6509,6376,25990,25835,25914,25908,25835,25990,4796,4771,4864,4628,4771,4796,4704,4838,4731,4605,4704,4731,3284,3381,3303,3331,3295,3376,23242,23146,22827,4327,4212,4256,4183,4212,4327,4183,4327,4387,14243,14107,14218,22483,22318,22572,27883,28075,27976,28089,28915,28277,30329,30583,30509,30509,30583,30713,27257,26803,27208,38440,38398,38347,39580,39736,39392,39351,39290,39453,38143,38046,38151,38211,37748,37847,37438,37374,37354,38046,38140,38151,38428,38204,38251,29876,29734,29767,3223,3295,3331,34327,34521,34366,34630,34793,34609,34825,34964,34893,35173,35247,34977,34175,34091,34161,34225,34175,34161,34175,33380,34091,37394,37207,37104,10371,10278,10343,9842,10005,10077,10371,10343,10455,37384,36796,36733,4003,4097,4178,3856,3948,3846,3685,3872,3916,15084,15392,15452,14694,14555,14617,35996,36016,35890,36261,36112,36270,38811,38843,38778,38440,38417,38398,38906,38843,38811,39668,39845,39480,39744,39806,39677,39677,39806,39703,39703,39789,39746,39793,39461,39556,39793,39556,39656,39793,39656,39991,39656,39688,39847,39786,39411,39726,4880,5063,5015,30145,30080,30184,30145,29876,30080,34467,34521,34327,20236,20468,20533,20831,20860,20940,20940,21136,21040,21215,21266,21346,21346,21629,21594,21777,21732,21901,21901,22058,22002,22175,22251,22140,22140,22251,22231,20435,20468,20236,20023,20236,20075,20023,19985,19902,20727,20860,20831,3202,3380,3326,39831,39613,39602,39771,39602,39746,8176,8217,8844,8826,8944,9059,8059,8172,8176,14600,14555,14694,8172,8217,8176,13116,13148,13315,13116,13315,13308,16667,16669,17295,17917,17765,18137,20860,21136,20940,23791,23921,23991,23795,23921,23791,24795,24886,24922,25130,24886,24769,32117,31938,32018,29707,29734,29778,31794,31908,32057,31226,31521,31147,39453,39290,39299,39434,39303,39262,39453,39299,39477,8627,8944,8826,9758,9970,9840,32255,32207,32505,37639,37636,38095,38500,38716,38474,39434,39421,39303,5063,5089,5071,37788,37383,37542,37461,37514,37527,37613,37514,37616,3228,3124,3298,3238,3163,3244,3109,3124,3228,3228,3321,3107,3273,3213,3107,3213,3147,3107,18438,18258,18374,18360,18258,18438,22902,23242,22827,3213,3211,3147,3079,3202,3326,19163,18916,18978,34747,34793,34630,4604,4726,4724,4237,4233,4265,4124,4166,4237,4000,4166,4124,3831,3937,3889,19902,19985,19843,19902,19843,19743,21136,21266,21215,38485,38716,38397,37374,37149,37269,37374,37269,37354,3211,3159,3147,4465,4397,4520,4488,4671,5033,9842,10077,9917,7041,7294,7641,8217,8432,8844,24779,24549,24806,22903,22706,22795,24381,24461,24655,24298,24414,24267,39477,39299,39320,8944,9081,9095,9079,9081,8944,18098,19024,17474,39943,39806,39744,40159,39786,39726,36426,36332,36373,35690,35919,35703,35879,35919,35690,39696,39712,39578,39899,39712,39696,3272,3355,3412,3272,3412,3334,39525,39552,39172,39497,39281,39351,39596,39643,39539,39523,39116,39127,39843,39643,39596,21892,21790,21874,21388,21480,21298,20766,20756,20678,19880,19580,19905,19505,19436,19363,19363,19351,19267,19267,19163,19168,21892,21874,21932,4035,4003,4178,4324,4183,4387,4107,4233,4237,31106,31147,30899,31106,30899,30713,37394,37415,37207,37207,37415,37235,36635,36845,36736,36426,36373,36533,3457,3485,3560,3710,3889,3911,15905,15860,16071,16071,15860,16060,17412,17295,17384,4452,4397,4465,16132,16245,16503,25835,25630,25616,25799,25630,25835,38398,38417,38288,38863,38329,38545,14804,14781,14723,15461,15392,15851,14787,15044,14833,14660,14515,14395,36642,36426,36533,3211,3249,3159,21447,21629,21346,22669,22902,22827,14896,14781,14804,14285,14243,14284,13533,13715,13638,33483,33509,33378,33704,33509,33483,33704,33609,33678,5767,6011,4532,4024,4324,4397,10711,11032,10669,12517,12572,12620,21874,22237,22023,22957,23243,23127,3795,3831,3690,4166,4107,4237,15257,15302,15474,9081,9085,9095,10180,10407,10548,9079,9085,9081,4771,4804,5015,5040,5102,5089,4644,4804,4771,4392,4459,4463,12230,12844,12963,10598,10445,10661,12620,12572,12891,13936,13978,14219,12517,12620,12387,29707,29585,29734,29734,29585,29626,27565,27421,27707,31109,31307,30971,21629,21732,21777,27284,27171,27388,28382,27988,28428,36216,36016,35996,33676,33704,33793,36216,35996,36101,11961,11789,11629,18258,18065,18137,17679,17505,17512,18128,18065,18258,38150,37847,37908,38151,38140,38270,39421,39477,39320,39502,39497,39351,39421,39320,39303,17412,17505,17616,23921,24099,23991,23942,24099,23921,31945,31858,31654,32139,32277,32198,3244,3142,3320,3068,3501,3288,3338,3564,3574,3685,3916,3908,3856,3951,3948,20021,19905,20079,17954,17917,18065,17374,18098,17474,22237,22141,22023,39034,39030,38878,38823,38578,38657,39136,39030,39034,39136,39044,39243,39806,39789,39703,4183,4324,3964,4397,4324,4387,4035,4178,4212,13341,13516,12891,28075,28039,28089,26587,25774,25800,14285,14284,14555,38823,38657,38843,3159,3249,3131,3123,3163,3238,9085,9213,9355,9079,9213,9085,15860,15858,15851,16478,16132,16503,16478,16503,16669,22237,22294,22141,25211,25180,25015,25211,25015,25130,25015,24886,25130,35173,34977,34893,35867,35734,35771,36796,36749,36516,37053,36749,36796,3381,3284,3453,3174,3194,3202,3131,3249,3194,3571,3564,3338,9758,9840,9678,18065,17917,18137,17883,17917,17954,39619,39552,39525,40159,39847,39786,39619,39525,39629,15751,15858,15905,16206,16475,16238,15696,15797,15712,23127,23243,23515,22141,22294,22196,22397,22827,22231,24120,24182,24099,39266,39044,39116,39712,39711,39577,39791,39711,39878,3163,3142,3244,10718,11196,11078,10035,10077,10196,10049,10407,10180,19580,19436,19505,22294,22266,22196,28746,28428,28569,31109,31292,31307,29570,29000,29418,31027,31106,30713,32353,32057,31908,39789,39771,39746,24099,24182,24267,24298,24182,24326,3710,3911,3607,3345,3457,3560,39502,39351,39453,39434,39262,39245,14781,14600,14694,15084,14896,14804,15008,14896,15084,39007,38824,39027,39016,38811,38808,13724,13978,13936,13891,13978,13869,3831,3795,3937,3710,3552,3690,3795,3941,4080,14568,14600,14781,14395,14515,14219,15044,15257,15474,15439,15696,15712,15114,15257,15044,38716,38813,38474,39499,39427,39309,39027,38824,39030,3131,3194,3174,22196,22266,22193,35510,35458,35381,35894,35867,35890,35894,35890,36016,10598,10718,10603,34243,34467,34327,34521,34747,34630,34793,34964,34825,34175,34225,34243,33380,33204,34091,34091,33204,33997,37394,37104,37099,37788,37542,37684,38417,38338,38251,38440,38338,38417,39039,39499,39309,37542,37527,37684,3911,3606,3607,4035,4212,4183,4586,4628,4605,3970,4000,4124,8172,8060,8217,8217,8343,8432,8432,8411,8826,7887,8304,7714,14414,14395,14016,17917,17883,17765,16667,16478,16669,18509,18578,18775,34142,34091,34064,39168,39027,39030,35510,35381,35734,16041,16238,16068,22483,22572,22647,39771,39831,39602,16156,16478,16185,15751,15719,15858,24769,24568,24490,16014,16041,16068,16014,16068,15797,34591,34747,34521,4628,4796,4704,5089,5102,5150,4628,4704,4605,13236,13341,12891,12121,12517,12387,24182,24298,24267,23795,23472,23540,39502,39453,39529,3229,3446,3295,3142,3128,3320,3355,3345,3560,5545,6214,6232,4779,4488,5033,4804,4880,5015,19290,19163,19267,22058,22140,22002,29585,28940,28999,29778,29734,29876,38150,37908,38016,37149,37384,36733,38150,38016,38170,37684,37527,37679,3223,3229,3295,4057,4107,4166,15858,15719,15851,16156,16071,16132,15439,15712,15302,27910,28039,28075,28058,28039,27910,26587,26242,26577,30593,30583,30329,37438,37354,37453,8132,8343,8217,33740,33823,33350,32505,32073,32057,32505,32057,32475,37613,37527,37514,3200,3223,3331,3338,3574,3505,10371,10455,10445,10035,10196,10278,23540,23472,23242,23942,23795,23918,39552,39770,39365,39629,39525,39496,38270,38140,38204,8343,8411,8432,22251,22384,22231,32508,32117,32297,33678,33937,33793,35826,35713,35681,34902,34964,34793,3846,3948,4097,38906,38889,38843,38428,38251,38338,38948,38889,38906,39016,38808,39007,26587,25800,26242,39021,39016,39007,2869,3174,3202,3200,3331,3284,18850,18660,18916,37616,37514,37461,3941,3954,4091,4000,4008,4166,3899,3954,3764,3970,3954,3899,13148,13116,12988,10760,10906,10813,13308,13315,13403,13994,13638,13715,38347,38329,38616,38428,38270,38204,38889,38823,38843,3505,3797,3706,3505,3706,3526,8812,9079,8944,9213,9254,9489,24461,24381,24137,25322,24806,25462,24298,24384,24414,24326,24384,24298,25211,25223,25253,25267,25223,25211,39702,39629,39496,39529,39453,39477,39529,39477,39421,21388,21568,21480,20766,21298,21188,20766,20678,21298,19580,19575,19436,19436,19351,19363,21568,21892,21784,21892,21932,21784,21932,21999,21784,20578,20727,20604,20860,20989,21136,21325,21447,21266,21266,21447,21346,21629,21649,21732,21732,22058,21901,22251,22329,22384,20578,20604,20468,20578,20468,20435,20236,20023,20435,20724,20615,20435,20065,20724,20435,21932,22023,21999,3079,3326,3229,3723,3685,3908,3710,3690,3889,3402,3727,3485,16041,16122,16238,15904,16014,15797,20023,19902,19647,22384,22397,22231,22329,22397,22384,32775,32505,32668,36475,36261,36270,35867,35839,35734,36216,36266,36170,39355,39168,39030,39027,39021,39007,39566,38669,39544,39243,39386,39355,3009,3068,3288,3123,3096,3163,3163,3055,3142,3142,3055,3128,3009,3288,2979,3043,3124,3109,3043,3109,3072,3109,3107,3072,2967,2995,3072,3147,3056,3107,20756,20331,20536,39395,39434,39245,40014,39845,39668,39989,39875,39789,39789,39875,39771,39771,39859,39831,40014,39668,39809,40014,39809,39793,3272,3334,2844,3457,3468,3485,39691,39757,39552,39625,39496,39497,3993,4008,4000,4392,4463,4724,4929,5089,5063,5455,5367,5576,11032,11271,11403,10679,11271,11032,14456,14285,14555,14456,14555,14600,14879,14781,14896,34964,35173,34893,36533,36373,36177,13994,14107,13638,13236,12891,12969,14414,14660,14395,3128,3125,3359,3067,3125,3128,22647,22572,22706,21999,22023,22141,22647,22706,22575,10489,10371,10445,10598,10661,10718,10598,10603,10489,26303,26085,26362,25561,25322,25462,3147,3041,3056,20331,20021,20079,32027,31858,31945,29860,29778,29876,32139,31945,32117,32505,32891,32398,34241,34161,34142,35389,35290,35247,39845,39943,39537,39786,39847,39688,40159,39611,40331,7041,7641,7541,4150,4488,4280,35173,35259,35247,3224,3345,3355,37374,37549,37149,37538,37438,37453,10718,10760,10603,31609,31292,31395,3147,3159,3041,20021,19880,19905,18864,18850,18916,21118,21266,21136,19184,18916,19163,21999,22141,22193,22575,22706,22903,3187,3200,3284,3338,3293,3571,3526,3706,3707,3179,3187,2765,13638,13763,13598,23795,23942,23921,24769,24886,24795,23167,23242,22902,25561,25462,25630,38616,38329,38863,4784,4929,4880,4880,4929,5063,4285,4233,4137,33314,33378,33200,17616,17505,17679,18360,18128,18258,17954,18128,18033,3995,4233,4107,15127,15008,15084,35259,35389,35247,3340,3468,3457,3856,3815,3951,3576,3526,3707,3906,3846,4097,3906,4097,4003,3856,3846,3821,15956,15904,15939,15737,15904,15797,14660,14787,14833,14587,14787,14660,13891,14219,13978,16014,15956,16041,15291,15302,15257,39266,39243,39044,39661,39544,39643,9079,9204,9213,9105,9204,9079,33200,33378,33450,28984,28940,29445,29934,29876,30145,15114,15291,15257,25908,25799,25835,26841,26303,26362,26841,26855,27171,3954,3970,4124,4008,4057,4166,3993,3970,3899,13531,13461,13533,14568,14456,14600,26891,27208,26803,18850,18775,18660,18864,18775,18850,22397,22669,22827,22415,22669,22397,32668,32505,32475,30583,30734,30713,30593,30734,30583,30593,30329,30530,37415,37616,37461,37429,37394,37099,37191,36853,36845,36838,36635,36426,4784,4880,4804,11271,11521,11864,13240,13236,12969,30319,29934,30145,37613,37679,37527,37684,37778,37788,37904,38095,37617,37660,37679,37613,3068,3096,3500,22141,22196,22193,33450,33378,33509,34225,34332,34243,34747,34902,34793,34964,35152,35173,35173,35288,35259,35259,35324,35389,34241,34332,34225,34241,34225,34161,34161,34091,34142,34332,34467,34243,39826,39529,39421,39573,39625,39497,39573,39800,39760,3223,3168,3229,3187,3284,3303,3575,3607,3512,3954,3941,3764,8059,8060,8172,8343,8272,8411,8411,8627,8826,7714,8304,7652,7520,7529,7652,34091,33997,34064,36261,36216,36101,36475,36270,36749,23942,24120,24099,23972,24120,23942,7887,7984,8059,34064,33997,34062,34467,34591,34521,3930,4057,4008,3041,3159,2958,3159,3131,2958,19880,19575,19580,7984,8060,8059,22669,22753,22902,22576,22753,22669,34142,34064,34201,4929,5040,5089,5031,5367,5455,9204,9254,9213,10365,10711,10407,10407,10711,10669,11638,11786,11521,9105,9254,9204,36060,35894,36016,35458,35517,34429,37663,37321,37472,36456,36475,37028,37663,37472,37748,38016,38143,38170,38367,38151,38270,37627,37616,37415,32139,32027,31945,30762,30824,30906,32083,32027,32139,37433,37374,37438,16478,16156,16132,15001,14879,15008,17412,17384,17505,8060,8132,8217,13869,13978,13724,12891,12843,12969,26242,25800,25895,26587,26891,26803,24498,24490,24384,35648,35510,35734,38435,38428,38338,38516,38338,38440,40129,39789,39806,39831,39882,39696,39835,39661,39643,10049,10180,9970,34773,34902,34747,25728,25799,25908,18128,17954,18065,17872,17954,17953,39791,39596,39711,39691,39552,39619,39691,39619,39663,22753,22873,22902,23109,22873,22940,13456,13724,13341,27770,27716,27879,27614,27716,27770,2999,3041,2958,3096,3055,3163,3364,3340,3268,3821,3815,3856,4035,4183,3760,15008,14879,14896,15001,15008,15127,14787,14895,15044,15291,15439,15302,15226,14737,15202,19575,19477,19436,17872,17883,17954,22294,22318,22266,21973,22058,21732,39875,39867,39771,17616,17679,17883,24381,24162,24137,22266,22318,22483,24335,24162,24381,24779,24806,24988,39573,39497,39502,25165,24806,25322,39168,39021,39027,39038,38948,38906,38889,38948,38823,38863,38545,38689,13533,13461,13403,13308,13198,13116,13116,12230,12988,14107,14243,14086,14243,14285,14086,13240,13456,13341,19477,19351,19436,39867,39859,39771,33704,33676,33509,33793,33937,34605,4586,4605,4604,3970,3993,4000,3930,3993,3899,14016,14395,14219,27565,27171,27421,26303,26082,25990,4628,4644,4771,4949,5024,5040,4512,4644,4628,4586,4604,4463,26280,26082,26303,39196,39168,39214,39355,39030,39136,3995,4107,4057,38170,38143,38302,37778,37684,37679,37904,37617,37788,39039,38423,38813,30824,30696,30971,30824,30645,30696,30530,30329,30173,30734,30853,30713,37538,37433,37438,37538,37453,37611,3293,3187,3303,3158,3168,3223,3179,2765,2815,39661,39750,39544,39952,39750,39661,40076,39991,40325,39663,39619,39629,3468,3402,3485,3364,3402,3468,3340,3457,3345,25292,25165,25322,25292,25322,25402,39353,39279,38945,39529,39573,39502,39216,38423,39249,5031,5455,5102,6307,6080,6509,7243,7041,7541,10598,10489,10445,10067,10035,10278,10718,11078,10760,19351,19290,19267,22266,22483,22492,22058,22175,22140,33676,33564,33509,33228,32886,32787,35236,35152,34964,35826,35879,35713,39859,39854,39831,29647,29585,29707,29647,29707,29778,29860,29876,29934,29994,29860,29934,37764,37778,37679,37660,37613,37616,14086,14285,14253,28039,28058,28089,27769,28058,27910,4024,4397,4452,3930,3995,4057,14253,14285,14288,24120,24326,24182,24096,24326,24120,27716,27565,27707,27614,27565,27716,3268,3340,3345,2874,3385,3125,15905,15858,15860,15905,16071,16156,3158,3223,3161,19290,19184,19163,22492,22483,22647,33564,33450,33509,31904,31858,32027,35152,35288,35173,39896,39711,39712,39854,39882,39831,37670,37663,37923,37644,37660,37616,31787,31489,31858,30612,30648,30145,30746,30853,30734,39770,39552,39798,39680,39663,39629,39680,39629,39702,27153,26841,27171,27153,27171,27163,3815,3723,3908,3037,3179,2815,3614,3723,3815,14895,15114,15044,15226,15114,14737,25267,25426,25223,27208,27769,27257,2989,3067,3128,22175,22329,22251,22873,23167,22902,35510,35517,35458,35894,35839,35867,35925,35839,35894,36170,36016,36216,35713,35879,35690,35713,35544,35681,39882,39899,39696,8278,8627,8411,35288,35324,35259,4035,3906,4003,14647,14568,14781,14855,14781,14879,27163,27171,27284,36839,36838,36426,37394,37490,37415,5040,5024,5102,4949,5040,4888,13891,14016,14219,14587,14895,14787,13753,13869,13724,2999,3056,3041,3161,3223,3200,23325,23127,23515,23109,23167,22873,31904,31787,31858,32083,32139,32198,39791,39843,39596,40021,39843,39791,25165,24988,24806,24088,24015,24162,24162,24015,23796,25561,25630,25799,25561,25799,25728,25130,25267,25211,25151,25267,25130,15226,15439,15291,24326,24338,24384,24187,24338,24326,39750,39566,39544,39748,39566,39863,39662,39529,39826,15904,15956,16014,15737,15797,15696,25728,25908,25824,20727,20842,20860,21447,21649,21629,22058,22149,22175,22547,22485,22329,20578,20615,20727,20435,20615,20578,19532,19902,19610,36456,36216,36261,36138,36170,36195,40076,40014,39793,39845,39982,39943,39943,39958,39806,39875,39989,39867,39867,39978,39859,39859,39968,39854,39854,39959,39882,39882,40022,39899,39991,39656,39847,3993,3930,4008,4137,4478,4285,3552,3795,3690,3552,3710,3607,22329,22415,22397,22485,22415,22329,27423,27388,27565,27565,27388,27171,2859,3008,3096,3096,3008,3055,3055,2989,3128,2979,3289,3124,2979,3124,3043,2979,2776,2839,3043,3072,2995,20615,20842,20727,20842,20989,20860,39552,39757,39798,23705,23918,23795,39798,39920,39885,39702,39496,39625,3072,3107,2967,3107,3056,2967,9575,9758,9678,9346,9489,9254,20989,21039,21136,32023,32083,32093,40014,39982,39845,10067,10278,10371,10760,10813,10670,30593,30746,30734,30354,30530,30173,37433,37545,37374,37766,37538,37611,37505,37490,37394,21039,21118,21136,3576,3707,3685,38716,39115,39124,39279,39395,39140,3131,2624,2958,3037,3161,3200,3179,3200,3187,8060,8071,8132,8132,8272,8343,7984,7920,8060,7887,7916,7984,7396,7520,7652,34258,34241,34142,34258,34414,34241,34241,34414,34332,34332,34414,34467,34467,34479,34591,34591,34687,34747,35236,35318,35152,35152,35318,35288,35288,35409,35324,34258,34142,34201,39843,39835,39643,39932,39835,39843,39757,39691,39920,7654,7652,7529,7714,7858,7887,34414,34479,34467,22575,22492,22647,7858,7916,7887,33204,33350,33997,21118,21325,21266,13869,14016,13891,27707,27988,28159,29418,29000,28694,34479,34687,34591,37764,37679,37660,37928,37788,37888,37928,37904,37788,13598,13531,13638,13638,13531,13533,13461,13198,13308,13638,14107,13763,38302,38143,38151,38999,38689,38823,4137,4233,3987,4529,4659,4644,4739,4784,4804,24338,24498,24384,24599,24498,24338,38367,38270,38428,37923,37663,37748,37663,37670,37611,7920,8071,8060,33997,33350,33823,34687,34773,34747,40294,39958,39943,4659,4804,4644,3402,3454,3727,3370,3454,3402,40329,39395,39279,36838,36936,36845,37095,36936,36987,2967,3056,2999,3906,3821,3846,3723,3643,3685,3708,3821,3588,15461,15851,15719,14288,14285,14456,17121,16667,17295,17786,17616,17883,18722,18360,18775,18950,18864,18916,21784,21480,21568,20396,20370,20756,20756,20370,20331,19690,19880,19644,19690,19575,19880,19541,19477,19575,19541,19351,19477,19251,19215,19351,19351,19215,19290,19290,19215,19184,19184,18950,18916,21798,21480,21784,21798,21784,21999,21798,21999,22022,21999,22193,22022,22022,22193,22166,22962,22575,22903,24655,24461,24779,22162,22324,22639,23918,23972,23942,23954,23972,23918,26446,26280,26303,27153,26973,26841,27075,26973,27153,27163,27284,27306,30824,30762,30612,30725,30762,30906,31221,31226,31106,30597,30746,30593,30597,30593,30530,33823,33740,33856,39038,38906,39016,39038,39016,39021,39038,39021,39196,39196,39021,39168,28940,28746,28569,28984,28746,28940,29647,29778,29860,16185,15905,16156,15751,15461,15719,29810,29949,29807,35859,35648,35734,36138,36060,36016,37809,37764,37660,39770,39849,39442,39823,39691,39663,3340,3364,3468,3268,3345,3259,25133,24988,25165,25133,25165,25172,26446,26303,26841,25172,25165,25292,27306,27284,27388,35859,35734,35839,8039,8272,8132,32775,32891,32505,33623,33005,33500,33958,33823,33856,38454,38367,38428,3174,2624,3131,21329,21649,21447,29949,30149,30173,38211,37847,38150,39899,39896,39712,40035,39896,40105,33450,33599,33200,33564,33580,33450,33676,33643,33564,34605,33937,34429,3512,3607,3606,14288,14456,14357,27541,27565,27614,27541,27423,27565,24705,24655,24779,2859,3096,3068,22193,22266,22166,21649,21760,21732,23972,24096,24120,24187,24096,24113,23540,23242,23167,23540,23167,23277,39760,39702,39625,39680,39823,39663,39760,39625,39573,33793,33643,33676,13340,13198,13461,13340,13461,13531,13456,13413,13724,13869,14046,14016,13236,13240,13341,13359,13240,13213,12572,12843,12891,38516,38435,38338,38454,38435,38604,36170,36138,36016,35925,35859,35839,36060,36138,36108,36170,36266,36195,3229,3168,3079,4949,5064,5024,5024,5064,5102,30149,30354,30173,37490,37627,37415,37610,37627,37490,24988,24705,24779,25513,25322,25561,10067,10371,10254,8833,10020,10086,8441,8115,8079,9870,10049,9970,11638,11521,11285,33643,33580,33564,35236,34964,34902,35681,35290,35389,19292,19532,19610,19203,19532,19292,21760,21973,21732,25915,25908,26082,28159,27988,28382,28936,28915,28838,27691,27769,27208,36936,37055,36845,37095,37055,36936,35892,35919,35879,40129,39989,39789,32023,31904,32027,31060,30906,30971,32023,32027,32083,38402,37846,38095,39009,38485,38357,39216,39353,38945,3293,2765,3187,3079,3168,3158,13359,13413,13456,23705,23540,23672,28438,28159,28382,35648,35517,35510,35925,35894,36037,35681,35389,35595,3614,3643,3723,3526,2961,3505,26801,26446,26841,26280,26256,26082,26801,26841,26973,26801,26973,27062,27306,27388,27432,39093,38997,38948,38516,38440,38616,39355,39136,39243,30762,30648,30612,30725,30648,30762,30354,30597,30530,31027,30713,30853,37443,37505,37394,3079,3158,3044,4529,4644,4525,4888,5040,4929,4628,4586,4512,22166,22266,22324,24350,24335,24381,24629,24705,24735,35318,35409,35288,39989,39978,39867,37191,37271,36853,4280,4488,4779,3588,3821,3906,3821,3708,3815,6080,6232,6509,29994,29647,29860,28746,28673,28428,37904,38012,38095,37799,37788,37778,37799,37778,37764,37799,37764,37809,38170,38183,38150,38302,38183,38170,38302,38151,38339,3930,3881,3995,3764,3941,3207,27244,27306,27325,3584,3576,3685,15594,15461,15751,15001,14855,14879,15452,15461,15514,15439,15521,15696,15956,16122,16041,15319,15521,15439,15226,15291,15114,14046,14414,14016,29311,28915,29208,29570,29810,29807,29949,30113,30149,30843,30747,30922,30354,30747,30597,37888,37799,38042,38339,38151,38367,2928,2989,3055,3224,3047,3116,39978,39968,39859,3044,3158,3161,39896,39878,39711,39863,39566,39750,40010,39878,39896,3987,4233,3995,9064,9105,9079,9758,9870,9970,8812,8944,8627,13763,14107,14086,13763,14086,13837,15939,16122,15956,25579,25513,25561,24735,24705,25050,25579,25561,25728,35762,35517,35648,36037,35894,36060,35826,35892,35879,35954,35892,35826,18033,18128,18360,17616,17522,17412,23540,23705,23795,22873,22753,22744,25298,25172,25292,25677,25511,25426,26577,26891,26587,25201,25151,25130,25290,25151,25201,25290,25242,25299,28755,28673,28746,10603,10485,10489,10996,10906,11078,37888,37788,37799,37429,37443,37394,23786,23709,24015,22324,22492,22639,22324,22266,22492,39968,39959,39854,24350,24381,24655,24350,24655,24629,39702,39823,39680,39662,39573,39529,39662,39826,39819,15521,15737,15696,39485,39353,39216,10035,9917,10077,10009,9917,10035,3364,3370,3402,3471,3552,3575,2965,3125,3067,35762,35648,35859,6509,6768,6376,8071,8039,8132,8590,8812,8627,7916,7920,7984,7858,7839,7916,7714,7654,7858,7652,7654,7714,8304,7396,7652,10049,10365,10407,10246,10365,10049,37271,37429,37099,37055,37191,36845,37305,37191,37055,4888,4929,4778,5064,5042,5102,8304,7194,7396,7654,7839,7858,22485,22669,22415,28673,28438,28382,27652,27614,27770,27244,27163,27306,30370,30319,30145,30370,30145,30648,38997,38823,38948,38435,38454,38428,19880,20021,19644,18864,18722,18775,39959,40022,39882,6967,7171,7194,8304,7624,7194,7839,7920,7916,34062,34201,34064,34258,34459,34414,34414,34488,34479,34479,35105,34687,35532,35236,35535,35105,35236,34902,35318,35418,35409,34109,34201,34062,34109,34062,33997,3614,3708,3588,3643,3584,3685,14939,14855,15001,26377,26256,26280,27075,27153,27163,27075,27163,27244,31027,30853,30870,33823,33958,33997,35925,35896,35859,36108,36037,36060,37545,37433,37538,7163,5576,6220,15452,15127,15084,17872,17786,17883,17852,17786,17872,23915,23786,24015,39801,39823,39702,39874,39849,39770,27388,27423,27432,39181,38948,39038,8003,8039,8071,8233,8411,8272,35486,35324,35409,35595,35389,35324,10760,10668,10603,22962,22903,23127,30870,30853,30746,30747,30746,30597,3575,3552,3607,3512,3606,3210,15461,15452,15392,15594,15751,15599,26377,26280,26446,25299,25426,25267,3317,3370,3364,4960,5042,5064,13198,13230,13116,10760,10670,10668,13577,13340,13531,13577,13531,13598,13753,14046,13869,13240,13359,13456,11786,12322,11521,25151,25290,25267,24490,24498,24769,38717,38516,38616,3899,3881,3930,3764,3881,3899,14510,14456,14568,23109,23138,23167,24599,24338,24611,23277,23138,23109,25513,25402,25322,24629,24655,24705,25696,25579,25728,33542,33757,33740,39874,39770,39798,24988,25050,24705,23978,23915,24015,39557,39523,39127,39932,39661,39835,8099,8233,8272,33350,33542,33740,39991,40076,39793,40294,39943,39982,40294,40129,39958,40209,39978,39989,40299,40114,39978,39978,40114,39968,39968,40114,39959,39959,40114,40022,40325,39991,39847,4659,4739,4804,4949,4960,5064,4512,4586,4463,29311,29418,28694,29311,28694,28915,17786,17661,17616,17729,17661,17786,23786,23325,23515,23978,24015,24088,33828,33740,33757,32475,32057,32353,37928,38012,37904,37888,38012,37928,37660,37906,37809,4724,4700,4392,4453,4512,4463,8812,8920,9079,9105,9346,9254,8947,8920,8933,3346,3512,3210,9917,9835,9842,10067,10009,10035,39599,39243,39266,39196,39181,39038,37423,37429,37271,37616,37627,37644,36987,36936,36838,4566,4739,4659,10679,11032,10711,29836,29810,29570,37627,37610,37644,4463,4459,4453,13753,13724,13665,15850,15939,15737,29445,28940,29585,28632,28508,28438,28943,28984,29131,33856,33740,33828,38999,38863,38689,13612,13577,13598,30021,29994,29934,30906,30824,30971,30123,30354,30149,37586,37545,37538,37586,37538,37766,3037,3044,3161,2913,2999,2958,3037,3200,3179,23663,23325,23786,39849,40001,39442,39885,39874,39798,21325,21329,21447,21649,21622,21760,21760,21748,21973,22169,22329,22175,21118,21224,21325,21073,21224,21118,21073,21118,21039,20973,21039,20989,20973,20989,20842,20973,20842,20724,31609,31489,31787,32139,32117,32277,36533,36177,36573,35959,35919,36375,2861,2965,3067,19215,18950,19184,22149,22058,21973,30120,29934,30319,37610,37505,37593,28943,28755,28746,27541,27614,27652,38568,38339,38367,38302,38489,38183,37574,37586,37695,38568,38367,38454,38604,38435,38516,38411,38402,38095,3224,3355,3047,3268,3317,3364,35105,34773,34687,3576,3503,3526,3708,3614,3815,3534,3614,3588,39215,39181,39196,38997,38999,38823,2872,2920,2995,2995,2920,3043,2979,2718,3009,2755,2859,2628,3008,2897,3055,2989,2829,3067,2872,2995,2940,2995,2967,2940,2967,2913,2940,21480,21337,21298,19215,19137,18950,21504,21337,21480,21504,21480,21579,21480,21798,21579,21798,21650,21579,21224,21329,21325,25290,25299,25267,24326,24096,24187,39557,39127,39747,4778,4929,4784,23915,23864,23786,24088,24162,24173,24162,24335,24173,30220,30120,30319,14118,14086,14253,14647,14510,14568,14647,14781,14855,14647,14855,14776,15737,15939,15904,16122,16206,16238,15636,15737,15544,27075,27062,26973,26630,26502,26446,27716,28109,27879,9145,9346,9105,22485,22576,22669,22547,22576,22485,36456,36261,36475,36037,35896,35925,2967,2999,2913,21798,21873,21650,3197,3317,3268,3465,3471,3512,3534,3584,3643,13665,13724,13413,12843,12572,12517,36995,36475,36749,2913,2624,2639,3293,2679,2765,40021,39932,39843,40021,39791,39878,39946,40001,39849,39920,39798,39757,39920,39691,39942,33580,33599,33450,33687,33599,33580,33687,33580,33643,33687,33643,33894,35236,35418,35318,35681,35954,35826,10254,10371,10489,11404,11789,11679,14118,14253,14288,13665,13413,13525,31609,31787,32007,30672,30370,30648,32353,31908,32011,30843,30870,30746,30843,30746,30747,37334,37271,37191,2639,2665,2838,21798,22022,21873,22022,21923,21873,4891,4960,4949,5042,5031,5102,30220,30370,30346,37610,37490,37505,2848,2859,2724,10009,9835,9917,10254,10489,10306,22022,22030,21923,21329,21622,21649,32007,31787,31904,36839,36987,36838,37552,37593,37429,8947,9064,8920,8920,9064,9079,15452,15130,15127,15525,15594,15599,18950,18722,18864,18835,18722,18950,36108,35896,36037,34886,34605,34429,36199,35954,36131,36642,36839,36426,39355,39324,39168,39397,39324,39355,40105,39896,39899,40096,39899,40022,13340,13230,13198,13420,13230,13340,13420,13340,13577,12969,13213,13240,35418,35486,35409,10485,10603,10668,31370,31307,31292,3224,3259,3345,3116,3259,3224,24988,25133,25050,24769,24599,24611,23972,23954,24096,39942,39691,39823,39800,39662,39819,3202,3079,2869,2859,2864,3008,19644,20021,19855,17661,17522,17616,17557,17522,17661,18725,18033,18360,23978,24010,23915,24173,24335,24313,34022,33856,33828,31221,31106,31027,36195,36108,36138,36456,36266,36216,16066,16206,16122,25459,25402,25513,25459,25513,25579,25824,25908,25915,25299,25442,25426,25356,25442,25299,39523,39501,39116,39571,39501,39523,39127,39566,39747,2864,2897,3008,4969,5031,5042,10581,10485,10668,10581,10668,10670,18098,17374,17251,20724,20842,20615,22022,22079,22030,35486,35595,35324,37549,37384,37149,36287,36195,36398,37549,37374,37545,38211,38150,38183,37593,37505,37443,37593,37443,37429,40035,40010,39896,40148,40010,40035,32023,32007,31904,32277,32117,32508,36049,35919,35892,4529,4547,4659,4778,4891,4888,4888,4891,4949,4960,4969,5042,4527,4547,4529,4525,4644,4512,4525,4512,4453,4453,4459,4383,12339,12230,13116,29836,29850,29810,29810,29850,29949,29532,29311,29384,6376,6768,6970,6376,6970,6312,35954,36049,35892,36508,36049,36324,15050,15001,15127,14510,14357,14456,27074,27062,27075,27074,27075,27244,39181,39093,38948,38717,38604,38516,39149,39093,39181,2897,2928,3055,4392,4700,4137,19690,19541,19575,22166,22162,22079,22022,22166,22079,14587,14414,14348,14587,14660,14414,15939,16066,16122,34886,34429,35517,39336,39214,39168,39215,39214,39473,39039,39249,38423,39421,39434,39826,39309,39249,39039,18033,17953,17954,17852,17530,17729,29580,29570,29418,39801,39702,39760,39946,39849,39874,3207,3941,3795,3882,3987,3995,3267,3795,3552,14595,14357,14510,13763,13612,13598,4275,4392,4094,24313,24335,24350,25171,25133,25172,24599,24769,24498,23918,23705,23829,28728,28438,28673,28984,28943,28746,29445,29585,29647,29753,29647,29994,30021,29934,30120,40010,39972,39878,39932,39952,39661,40077,39972,40148,24088,24010,23978,24500,24350,24629,23672,23540,23621,39800,39801,39760,22079,22162,22021,7920,8003,8071,8039,8099,8272,8233,8278,8411,7927,8003,7920,7927,7920,7809,7598,7839,7654,7598,7654,7529,7598,7529,7497,11579,11629,10996,30870,31089,31027,30922,30747,30354,34201,34292,34258,35236,35532,35418,35418,35532,35486,35486,35532,35595,34082,34109,33997,34082,33997,33958,34082,33958,34022,33958,33856,34022,37574,37549,37545,30220,30021,30120,30220,30319,30370,30648,30725,30672,29850,30113,29949,3496,3503,3576,3496,3576,3584,3512,3471,3575,3465,3512,3346,3256,3370,3317,15594,15514,15461,15525,15514,15594,36508,36375,35919,36887,36839,36642,37305,37055,37095,36675,36642,36533,13595,13612,13763,12339,12192,12230,13753,13931,14046,13525,13413,13359,7497,7529,7520,6220,5576,5913,8003,8099,8039,33542,33159,32977,35956,35762,35859,36238,36108,36195,36238,36195,36287,2928,2862,2989,3115,3197,3259,14357,14118,14288,22030,22079,22021,21940,22149,21973,23277,23167,23138,27707,28159,28109,16206,16453,16475,16155,16066,16099,25442,25543,25426,25597,25543,25442,25298,25171,25172,25298,25292,25402,24827,25201,25130,35956,35859,35896,32198,32093,32083,31609,31370,31292,32160,32093,32198,39972,40008,39878,40077,40008,39972,39946,39874,40027,33005,33542,32977,4778,4784,4640,17953,17852,17872,15525,15404,15514,17729,17530,17499,17729,17499,17722,23829,23672,23621,31105,30971,31307,30672,30725,30801,40027,39874,39885,40108,39942,39823,38467,38211,38183,37586,37574,37545,38717,38616,38938,40129,39806,39958,26257,26082,26256,39599,39386,39243,33005,33623,33542,10721,10581,10670,10485,10306,10489,10003,9985,10067,10721,10670,10813,27062,26875,26801,26966,26875,27062,5913,5630,5684,4891,4969,4960,28109,28159,28245,27325,27074,27244,40008,40021,39878,39569,39545,39386,40077,40021,40008,3614,3534,3643,3588,3906,3382,14336,14414,14046,15226,15319,15439,26630,26446,26801,27432,27423,27541,33307,33500,33005,39214,39215,39196,38938,38616,38863,39336,39168,39324,17852,17729,17786,18725,18360,18722,23672,23829,23705,24187,24611,24338,25356,25242,25201,23277,23109,22940,38604,38717,38637,10067,9985,10009,10003,10067,10254,3534,3496,3584,2765,2679,2651,15514,15404,15452,14647,14595,14510,13837,14086,14118,17295,17412,17121,26377,26257,26256,31463,31370,31558,33228,32787,33200,33992,33643,33793,19251,19137,19215,25201,25242,25290,24827,25130,24769,39747,39566,39748,4547,4566,4659,4902,4976,4969,4525,4527,4529,4200,4527,4525,4511,4527,4446,4525,4453,4383,25543,25575,25426,26805,26891,26577,29532,29418,29311,25597,25575,25543,38498,38302,38339,38498,38339,38524,4511,4566,4547,29850,30101,30113,30922,30896,30843,29532,29580,29418,29311,29305,29384,38012,38080,38095,38402,38646,38357,37888,38080,38012,38042,38080,37888,38042,37799,37809,38042,37809,37906,10996,11629,11404,10535,10306,10485,30893,30725,30906,37766,37611,37670,37549,37556,37384,37384,37053,36796,37610,37666,37644,37305,37095,37135,40027,39885,39920,40331,39611,39736,8933,8920,8812,9064,9145,9105,9346,9575,9678,30079,30021,30220,30079,29994,30021,30079,29753,29994,28245,28159,28263,29580,29836,29570,36136,35956,35896,35676,34886,35517,36136,35896,36108,38211,37971,37748,31271,31105,31307,3259,3197,3268,2874,3125,2965,32800,32775,32668,2829,2861,3067,13612,13557,13577,13595,13557,13612,13420,13557,13585,13805,13931,13753,13358,13525,13359,13091,13359,13213,13020,13213,12969,19137,19020,18950,27718,27652,27770,28159,28438,28508,40192,40096,40022,26257,25915,26082,25447,25298,25402,27718,27770,27879,39386,39397,39355,39545,39397,39386,17729,17722,17661,17537,17722,17499,9639,9575,9509,10453,10679,10711,20435,20023,20065,21224,21250,21329,21329,21511,21622,21622,21748,21760,32093,32007,32023,32508,32297,32787,36375,36573,36177,37135,37095,36987,36636,36573,36603,36675,36573,36636,12610,12843,12517,12121,12387,11786,20973,21073,21039,2920,2838,2818,2776,2920,2818,2776,3043,2920,2776,2979,3043,2859,2848,2864,2864,2848,2897,2897,2786,2928,2928,2786,2862,2862,2829,2989,2872,2838,2920,4640,4784,4739,22547,22329,22169,22682,22753,22576,2872,2940,2838,10906,10721,10813,10453,10711,10365,21337,21188,21298,19690,19624,19541,19541,19251,19351,19137,19119,19020,21339,21188,21337,21339,21337,21504,21339,21504,21441,21504,21579,21441,21579,21650,21623,21650,21873,21623,21873,21819,21623,21073,21206,21224,22169,22175,22149,31013,30893,30906,30544,30346,30370,30843,30896,30870,31004,30896,30922,40096,40105,39899,26309,26577,26242,15130,15050,15127,26502,26377,26446,26257,26165,25915,26875,26630,26801,26742,26630,26875,26742,26875,26966,3047,3355,3272,24756,24500,24629,24152,24010,24088,24756,24629,24735,25050,25133,25171,40219,40002,39942,40002,40027,39920,39662,39800,39573,39434,39395,39826,2838,2940,2639,12843,13020,12969,21206,21250,21224,25696,25728,25785,37431,37053,37384,3810,3995,3881,3810,3881,3764,9911,9835,10009,9911,10009,9985,9639,9870,9758,21923,22021,21819,21873,21923,21819,25785,25728,25824,25785,25824,25909,25575,25677,25426,25597,25677,25575,15202,15319,15226,15114,14895,14737,26583,26377,26502,26247,26309,26242,30544,30370,30672,37810,37766,37670,37028,36995,37053,39149,38997,39093,39447,39336,39324,10535,10485,10581,17722,17557,17661,17537,17557,17722,24152,24088,24173,23910,23954,23829,23829,23954,23918,25356,25597,25442,37135,36987,37123,17389,17412,17522,15130,14939,15050,25120,25050,25171,2861,2874,2965,2797,2874,2861,19020,18835,18950,18927,18835,19020,22547,22611,22576,22689,22611,22547,2869,3079,2560,21250,21511,21329,40242,39982,40014,40114,40192,40022,40096,40195,40105,40275,40014,40076,8000,8182,8099,8099,8182,8233,7497,7520,7401,40115,39580,40060,40002,39920,39942,7286,7520,7396,3730,3810,3764,27619,27432,27541,27484,27432,27619,34109,34292,34201,34459,34292,34314,34292,34109,34314,34109,34220,34314,34082,34022,34220,33889,33828,33757,32277,32160,32198,31175,31060,31105,31105,31060,30971,32173,32160,32291,36573,36675,36533,36642,36675,36777,4769,5367,5031,7208,7286,7396,4976,5031,4969,33482,33200,33599,39580,40001,40060,7208,7396,7194,35676,35517,35762,34605,33992,33793,39397,39420,39324,39545,39420,39397,30893,30801,30725,31271,31307,31463,31004,31089,30870,31004,30870,30896,37451,37423,37271,37593,37666,37610,4845,4969,4891,10906,10897,10721,10721,10535,10581,11404,11629,11789,11789,11961,11679,37717,37666,37707,2560,3079,3044,2815,3044,3037,7171,7208,7194,8833,10086,9842,18835,18725,18722,18859,18725,18835,21923,22030,22021,22611,22682,22576,24125,24113,23954,22689,22682,22611,40060,40001,40206,3116,3115,3259,3210,3454,3370,3471,3406,3552,3091,3115,3116,24409,24611,24187,4566,4585,4739,4778,4845,4891,4527,4511,4547,4383,4459,4392,6995,7171,6967,23954,24113,24096,24149,24113,24125,29836,29837,29850,29727,29837,29836,28915,29034,29208,3808,3882,3995,4275,4383,4392,13639,13753,13665,13639,13665,13525,27826,27718,27879,27826,27879,27942,40048,39952,39932,40048,39932,40021,2859,3068,2628,20370,20021,20331,21517,21748,21622,4500,4585,4566,4150,4024,4452,3964,4024,3865,5820,6232,6080,13557,13420,13577,13595,13763,13687,16066,16155,16206,15964,16066,15939,25459,25447,25402,25298,25246,25171,25459,25579,25614,28673,28755,28728,39557,39571,39523,39751,39571,39557,4275,4094,4194,11285,11521,11271,13113,13091,13020,29727,29836,29580,37971,37980,37748,38094,37980,37971,38230,37971,38211,37906,37660,37644,38080,38184,38095,8749,8115,8441,7927,8099,8003,15050,14939,15001,15130,15452,15404,22682,22744,22753,22689,22744,22682,26630,26583,26502,25909,25824,25915,27106,27062,27074,27325,27306,27432,40134,40126,39736,40075,40001,39946,8950,8833,9842,10003,9911,9985,9882,9911,9819,9870,9897,10049,9868,9897,9870,9639,9758,9575,15636,15850,15737,19644,19624,19690,22166,22324,22162,26165,26257,26377,32475,32800,32668,33542,33665,33757,32490,32800,32475,36195,36266,36398,35887,35676,35762,37053,36995,36749,37570,37549,37574,37123,36987,37151,37305,37334,37191,7397,8079,8115,8950,9842,9835,31013,30801,30893,37695,37570,37574,37695,37586,37766,4392,4137,4094,38568,38454,38604,38568,38604,38637,15544,15737,15521,15403,15300,15377,12192,11961,12230,28728,28755,28943,30254,30079,30220,30033,30079,30254,37980,37923,37748,37932,37906,37644,8182,8278,8233,8910,9145,9064,27181,27325,27484,31463,31307,31370,31060,31013,30906,31089,31221,31027,31184,31221,31089,37338,37334,37305,37423,37552,37429,37666,37722,37644,2848,2786,2897,40108,39823,39801,40090,40075,39946,24361,24313,24350,24871,24756,24735,24871,24735,25050,24611,24725,24769,24465,24725,24611,39826,40110,40088,39800,39901,39801,2844,3334,3390,17557,17389,17522,17537,17389,17557,24113,24149,24187,23621,23540,23455,38999,38997,39222,40099,39863,40168,13837,14118,13968,12339,13116,13230,13931,13886,14046,13537,13639,13525,13091,13213,13020,3317,3197,3104,3256,3317,3104,3810,3808,3995,4742,4845,4778,15599,15751,15905,15599,15905,15626,37923,37810,37670,22492,22575,22639,8803,8933,8812,3882,3783,3987,3730,3808,3810,39149,39181,39215,39149,39215,39503,5823,5820,6080,6162,6080,6307,31175,31013,31060,30787,30544,30672,30123,30149,30113,31731,31521,31226,37570,37556,37549,37566,37556,37570,37451,37552,37423,15964,16099,16066,18656,19012,18638,15964,15939,15850,24901,24871,25050,25614,25579,25696,25614,25696,25790,3104,3197,3040,13113,13020,12890,28117,27879,28109,27181,27074,27325,29445,29647,29753,33623,33665,33542,38782,38637,38717,39599,39266,39501,40155,39747,39748,22744,22940,22873,22880,22940,22744,37717,37722,37666,40148,39972,40010,40099,39995,39863,40195,40035,40105,23864,23663,23786,23864,23915,24010,23455,23540,23277,39420,39447,39324,39599,39501,39571,31221,31731,31226,31778,31731,31980,2786,2829,2862,2874,2813,3385,19413,19251,19541,18725,18761,18033,22962,23127,23038,22055,22169,22149,24361,24350,24500,24361,24500,24482,31571,31370,31609,31271,31175,31105,13440,13230,13420,13968,14118,13897,13639,13805,13753,13756,13805,13639,3760,3906,4035,3534,3328,3496,3338,3505,2572,25246,25298,25447,24725,24827,24769,26949,26805,26861,24861,24827,24725,24409,24187,24149,27642,27691,27208,26309,26805,26577,26247,26242,25895,32111,32007,32093,32173,32093,32160,31731,32011,31521,33005,32891,33307,33665,33623,33695,36777,36887,36642,37512,37451,37334,37334,37451,37271,36573,36375,36603,36375,36562,36603,39910,39901,39800,40329,39279,39353,27181,27106,27074,26776,26583,26630,27325,27432,27484,39473,39214,39336,14939,14776,14855,15248,15130,15404,26776,26630,26742,28508,28263,28159,40090,39946,40027,40134,39736,40115,40090,40027,40002,10996,10897,10906,10966,10897,10996,4585,4640,4739,4511,4500,4566,4446,4500,4511,4481,4500,4446,10775,11285,11271,10246,10453,10365,13585,13557,13595,11026,10966,10996,29676,29445,29753,28508,28364,28263,29194,29611,29207,28915,28936,29034,29532,29727,29580,31085,31089,31004,31085,31184,31089,30123,30113,30101,37556,37431,37384,37566,37431,37556,37338,37305,37135,37707,37666,37593,38055,38080,38042,38055,38184,38080,38055,38042,37906,27797,28058,27769,36777,36636,36792,3465,3406,3471,3388,3406,3465,26431,26165,26377,25895,25800,25677,35887,35762,35956,39645,39447,39420,25228,25246,25447,25228,25447,25444,4591,4640,4585,17374,17205,17016,15945,15964,15940,25790,25696,25785,25356,25299,25242,38524,38489,38498,38498,38489,38302,38407,37810,37923,37698,38038,37781,38524,38339,38568,39751,39599,39571,39545,39645,39420,19251,19119,19137,40256,40192,40114,24482,24500,24756,23961,23864,24010,24482,24756,24751,4024,3964,4324,3865,4024,3702,13527,13585,13595,13687,13763,13837,13358,13537,13525,40077,40048,40021,40163,40048,40077,27642,27208,27365,7269,7286,7208,7334,7401,7286,7286,7401,7520,7497,7401,7598,7809,7920,7839,8182,8106,8278,7269,7208,7107,34292,34459,34258,34109,34082,34220,34022,33828,33978,4640,4742,4778,4845,4902,4969,4976,4769,5031,25120,24901,25050,28909,28728,28943,30101,29850,29837,38938,38863,39026,38765,38568,38637,38721,38524,38568,30123,30922,30354,15544,15521,15519,15521,15319,15519,15319,15403,15519,26064,25909,25915,25722,25895,25677,33889,33757,33786,31463,31340,31271,31763,31571,31609,37048,36839,36887,37048,36987,36839,2829,2849,2861,9911,9882,9835,10003,10254,10306,18638,19012,19292,16206,16155,16453,40134,40115,40172,7107,7208,7171,7809,7839,7598,8590,8803,8812,19647,19902,19532,21247,21206,21073,21389,21345,21206,21206,21345,21250,21250,21345,21511,21511,21517,21622,21748,21865,21973,23961,24010,24152,23663,23479,23325,31790,31763,31609,32886,32508,32787,32482,32508,32574,32353,32490,32475,32439,32490,32353,40325,40275,40076,40129,40209,39989,40377,40275,40427,2744,2718,2979,2848,2766,2786,2786,2608,2829,2829,2698,2849,2744,2979,2839,2744,2839,2739,2839,2702,2739,2776,2702,2839,2718,2714,3009,2776,2712,2702,11989,12121,11570,9897,10246,10049,10168,10246,9897,20938,20756,20766,19644,19603,19624,19624,19523,19541,19251,19151,19119,20938,20766,21188,21175,21188,21339,21175,21339,21307,21579,21562,21441,21623,21562,21579,40377,40242,40014,6995,7107,7171,2776,2818,2712,39078,38646,38402,39249,39485,39216,14780,14776,14939,26080,26064,26165,26165,26064,25915,27106,26966,27062,26994,26966,27106,40172,40115,40060,40146,40684,40611,2712,2818,2665,9509,9575,9476,32354,32160,32277,36636,36777,36675,35752,35681,35595,39039,38813,39124,35901,35887,35956,36136,36108,36238,36266,36423,36398,27541,27652,27619,28109,28245,28117,2662,2797,2849,2849,2797,2861,6967,7194,6888,19028,18927,19119,19119,18927,19020,40192,40195,40096,40218,40195,40192,40126,40331,39736,40172,40060,40182,2654,2712,2665,11363,11679,11415,13834,13687,13837,21623,21805,21562,39026,38863,38999,40242,40294,39982,3047,3091,3116,3210,3606,3454,3022,3091,2931,24152,24173,24313,24751,24756,24871,39910,39800,39819,39910,39819,39826,25107,25356,25201,25597,25700,25677,25393,25356,25107,10588,10535,10721,10588,10721,10897,30922,31085,31004,31980,31731,31623,31731,31778,32011,32290,32439,32353,31181,31085,30922,6888,7194,6785,8000,8106,8182,8933,8803,8947,33687,33731,33599,34752,33992,34605,33894,33992,34023,34752,34886,35234,4669,4902,4845,28571,28364,28508,30787,30672,30801,30787,30801,31013,37722,37852,37644,37562,37593,37552,37562,37552,37451,21389,21206,21247,23569,23479,23663,24152,24313,24361,27619,27652,27718,18927,18859,18835,19028,18859,18927,16109,16155,16099,32508,32461,32277,32482,32461,32508,6764,6970,7041,21819,21915,21805,21623,21819,21805,36266,36456,36423,6785,7194,7624,33992,33894,33643,33786,33757,33665,33786,33665,33695,3210,3370,3132,3687,3783,3808,15525,15248,15404,14531,14664,14649,16185,16478,16349,15945,16109,15964,15964,16109,16099,13886,13931,13805,26080,26165,26285,25909,25814,25785,25228,25120,25246,25246,25120,25171,24843,24751,24871,11638,12121,11786,13091,13113,13359,11271,10679,10775,29384,29549,29532,30123,31072,30922,29305,29549,29384,29305,29311,29208,2628,3068,3009,21819,22021,21915,21345,21517,21511,22800,22689,22630,31211,31221,31184,36984,37048,36887,37512,37562,37451,4500,4481,4585,4669,4682,4742,4742,4682,4845,4200,4525,4383,4274,4383,4275,29549,29727,29532,29382,29305,29208,31571,31558,31370,31596,31558,31571,32111,32093,32173,3808,3783,3882,3730,3764,3366,12192,11679,11961,13440,13420,13585,13527,13440,13585,13897,14004,13997,13756,13886,13805,13756,13639,13537,37984,38055,37906,38184,38411,38095,4194,4274,4275,6771,6785,6647,6344,6785,7624,13527,13595,13687,22630,22547,22169,23250,23455,23277,23910,24125,23954,29194,29131,28984,28728,28632,28438,29194,28984,29445,30001,29753,30079,30940,30787,31013,33894,33810,33687,33695,33623,33619,38038,37695,38301,36423,36456,36520,38094,37923,37980,38489,38467,38183,38612,38467,38489,38721,38489,38524,40219,40090,40002,40025,39910,40012,40182,40060,40206,40134,40214,40126,40001,40075,40206,2755,2724,2859,32223,32111,32173,17389,17121,17412,17852,17745,17530,23810,23829,23621,16349,16478,16667,23569,23663,23674,23250,23277,22940,29982,30101,29837,39796,39751,39557,39599,39569,39386,39796,39557,39747,39995,39748,39863,21915,22021,22162,29131,28909,28943,40704,40209,40129,14776,14664,14647,14664,14776,14780,26878,26776,26742,26878,26742,26966,26878,26966,26994,3040,3197,3115,25447,25459,25444,23663,23864,23820,23674,23663,23820,33810,33731,33687,32891,32775,33307,35661,35532,35535,39745,39569,39599,39447,39473,39336,39176,39026,38999,36288,36136,36238,37028,37053,37220,19012,19203,19292,18098,18656,18638,40195,40148,40035,39863,39750,40168,40236,40148,40195,40373,40214,40134,40206,40075,40146,15395,15248,15525,15130,14992,14939,32461,32354,32277,32501,32354,32461,36508,35919,36049,36777,36888,36887,39503,39473,39447,2724,2766,2848,19605,19603,19644,21669,21865,21748,4591,4742,4640,10775,10679,10458,28117,28245,28243,28909,28632,28728,10228,10121,10306,10663,10588,10897,37698,37566,37570,37698,37570,37695,37717,37852,37722,37338,37135,37266,19603,19523,19624,22454,21915,22162,21865,21940,21973,23038,23127,23325,24152,24361,24220,23455,23594,23621,23541,23594,23455,35887,35832,35676,36142,36136,36197,24843,24871,24901,3346,3388,3465,3305,3388,3346,4094,4137,3969,3267,3552,3406,15964,15850,15940,15403,15319,15202,25956,25814,25909,26489,26377,26583,24032,24152,24220,31340,31175,31271,32058,31609,32007,32058,32007,32111,37048,37151,36987,37236,37151,37222,2691,2813,2874,3046,3160,3104,2691,2874,2797,22689,22880,22744,23024,22880,23035,37858,37852,37717,40282,40134,40172,40146,40075,40090,5820,5545,6232,5601,5545,5820,13111,13113,12890,32063,32058,32111,39004,38782,38717,38765,38782,38807,21940,22055,22149,37266,37135,37123,3132,3370,3256,15850,15636,15621,36603,36792,36636,36199,36049,35954,33731,33482,33599,33307,33427,33397,33307,33250,33283,3104,3160,3256,3040,3115,3022,19523,19413,19541,17425,17346,17537,34459,34488,34414,34416,34488,34459,34416,34459,34314,34416,34314,34441,34022,33978,34220,33889,33978,33828,32354,32291,32160,32425,32291,32354,36888,36792,36930,3964,3760,4183,3865,3760,3964,7269,7107,7001,7220,7269,7001,7220,7286,7269,7220,7334,7286,7401,7179,7598,7927,7931,8099,7107,6995,7001,6995,6930,7001,13968,13834,13837,12892,12339,13230,13897,13834,13968,23038,23325,23395,23395,23325,23479,23820,23864,23867,25956,25909,26064,24970,24843,24901,28245,28263,28243,26994,27106,27181,31340,31463,31558,30001,30079,30033,33889,33786,33978,6248,6162,6307,37726,37707,37593,37858,37707,37873,7397,7782,8079,6376,6248,6307,6907,7243,6894,6777,6967,6888,7572,7809,7598,8590,8627,8278,26590,26489,26583,26010,25956,26064,27742,27181,27484,13113,13358,13359,14737,14895,14587,4481,4591,4585,4196,4446,4527,4200,4383,4274,14664,14595,14647,14531,14595,14664,38356,38230,38211,38356,38211,38445,17537,17346,17389,18761,18725,18859,40197,39952,40048,24220,24361,24482,23867,23864,23961,24970,24901,24984,26590,26583,26776,40209,40299,39978,40262,40163,40077,7809,7931,7927,33978,33786,33803,28666,28571,28632,28378,28263,28364,29131,29142,28909,30346,30254,30220,4440,4591,4481,30346,30561,30254,29727,29982,29837,30101,30133,30123,32107,32011,31778,29954,29982,29727,29687,29727,29549,38234,38094,37971,7931,8000,8099,4094,3969,4051,22962,22779,22575,23395,23479,23430,29636,29687,29549,28915,28089,28838,40025,39801,39901,40282,40172,40182,3388,3330,3406,3305,3330,3388,15621,15636,15544,14737,14587,14348,32768,32508,32886,36508,36562,36375,36688,36562,36508,19413,19151,19251,19080,19203,19012,40299,40256,40114,31763,31596,31571,31790,31596,31763,31790,31609,32058,32223,32173,32291,37502,37512,37334,37151,37266,37123,37236,37266,37151,36888,36777,36792,37566,37681,37431,37781,38038,37801,23430,23479,23569,24032,23961,24152,23594,23810,23621,24125,24409,24149,23541,23810,23594,30081,30133,30101,37932,37984,37906,38055,38289,38184,37932,37644,37852,4150,4452,4488,13655,13527,13687,13655,13687,13834,16109,16092,16155,15621,15544,15540,16539,16349,16667,15512,15395,15599,14118,14357,14004,25444,25459,25614,27706,27619,27718,28571,28508,28632,33803,33786,33695,32775,33127,33250,36006,35901,35956,36006,35956,36142,3722,3987,3783,38757,38721,38568,38765,38637,38782,3730,3687,3808,3618,3687,3366,27706,27718,27826,27365,27208,26891,27691,27797,27769,26949,26891,26805,26805,26309,26372,26309,26247,26372,30346,30544,30561,31596,31340,31558,32199,32223,32318,36984,36888,37074,2608,2698,2829,24222,24409,24125,26372,26247,25895,33803,33695,33722,40256,40233,40192,37858,37717,37707,37922,37932,37852,40262,40077,40148,3160,3132,3256,3196,3305,3346,3022,3115,3091,2844,3390,2813,15540,15544,15519,24790,24482,24751,24984,24901,25120,26010,26064,26080,25814,25790,25785,28666,28632,28752,38807,38782,39004,6785,6771,6888,6344,7624,6220,8811,8803,8752,23810,23910,23829,23885,23910,23810,33482,33228,33200,36238,36287,36411,36142,35956,36136,19151,19028,19119,40233,40218,40192,40282,40182,40253,40242,40530,40294,40445,40299,40209,40445,40337,40299,40299,40337,40256,40256,40386,40233,40233,40386,40218,40275,40377,40014,40325,39847,40159,14348,14414,14336,15534,15540,15519,26285,26010,26080,26878,26590,26776,26733,26811,26738,25700,25597,25523,2744,2673,2718,2718,2596,2714,2714,2628,3009,2755,2612,2724,2724,2632,2766,2574,2608,2786,2611,2673,2744,2611,2744,2739,2611,2739,2654,2739,2702,2654,32290,32353,32011,32107,32159,32294,32918,32768,32886,32199,32063,32223,26607,26590,26878,39309,39427,39249,39124,38813,38716,2654,2702,2712,13437,13756,13537,21098,21175,21153,21098,21188,21175,21098,20938,21188,19605,19523,19603,19605,19422,19523,19523,19422,19413,19413,19275,19151,19151,18959,19028,21175,21307,21153,21441,21307,21339,21384,21307,21441,28117,27942,27879,27619,27742,27484,27974,27942,28117,40427,40325,40818,11026,10996,11404,10588,10574,10535,11026,11404,11166,37873,37707,37726,2649,2844,2813,23024,23250,22940,23024,22940,22880,33810,33747,33731,33731,33538,33482,33482,33287,33228,34023,33747,33810,34023,33810,33894,34752,34605,34886,34886,35676,35552,33619,33623,33500,2665,2818,2838,21562,21384,21441,3046,3132,3160,13358,13437,13537,13113,13210,13358,13111,13210,13113,13020,12843,12890,28571,28378,28364,39817,39745,39599,39569,39745,39545,40155,39796,39747,17346,17121,17389,17256,17121,17346,24409,24465,24611,24562,24465,24409,31431,31175,31340,32016,31790,32058,32063,32111,32223,39427,39485,39249,39910,40025,39901,40012,39910,39826,40360,40236,40218,40218,40236,40195,2639,2940,2913,21562,21485,21384,15945,16092,16109,15621,15940,15850,15787,15940,15621,25393,25597,25356,21200,21049,21056,32501,32461,32482,31181,31184,31085,35832,35887,35901,36411,36287,36398,36888,36984,36887,37502,37334,37338,37016,36984,37074,25228,24984,25120,24790,24751,24843,24790,24984,24927,35532,35661,35595,37074,36888,36930,35105,34902,34773,29982,30081,30101,29636,29549,29305,38310,38055,38296,38310,38289,38055,39115,38716,38485,37977,37984,37932,2505,2628,2714,21517,21669,21748,21865,21885,21940,21955,22105,22055,22055,22105,22169,21345,21389,21517,21247,21073,20973,21599,21389,21247,37465,37338,37266,23430,23569,23592,22857,22779,22962,23569,23674,23592,40163,40197,40048,39995,40136,39748,40266,40197,40163,15534,15519,15403,25960,25790,25814,26431,26377,26489,32768,32690,32508,32754,32690,32768,36466,36423,36520,14336,14046,13886,13216,13437,13358,11363,11404,11679,13897,14118,14004,13877,13897,13997,27867,27706,27826,27867,27826,27942,27642,27797,27691,29382,29636,29305,27618,27797,27642,28378,28243,28263,39222,38997,39149,39503,39215,39473,9639,9469,9870,10246,10168,10453,9476,9575,9346,29197,29207,29284,29194,29207,29131,28571,28513,28378,28378,28285,28243,30544,30787,30754,30787,30940,30754,33616,33619,33500,33397,33500,33307,35661,35752,35595,2624,2913,2958,2624,3174,2869,2628,2612,2755,2616,2691,2797,33136,33033,33228,33228,33033,32886,36131,35954,35681,40212,40206,40146,40253,40182,40206,40088,40012,39826,2662,2849,2698,19028,18761,18859,18959,18761,19028,40253,40206,40212,40323,40331,40126,2612,2623,2724,21599,21669,21517,31013,31148,30940,25107,25201,24827,25700,25722,25677,10694,10663,10897,17852,17953,17745,24790,24843,24970,37698,37701,37566,37781,37701,37698,2961,3503,3496,3328,3534,3588,22857,22962,22991,23592,23674,23749,35832,35901,36007,25960,25814,25956,25827,25722,25761,39817,39599,39751,2623,2632,2724,13804,13886,13756,15377,15534,15403,24861,25107,24827,37222,37048,37218,37222,37151,37048,38765,38757,38568,38445,38211,38467,38230,38234,37971,37781,37681,37701,38807,38757,38765,26010,25960,25956,26542,26431,26489,26542,26489,26590,26542,26590,26607,34954,35105,34479,35861,35822,35752,34416,34494,34488,34326,34441,34314,34326,34314,34220,34326,34342,34375,34220,34342,34326,39637,39503,39447,31790,31897,31596,32063,32016,32058,32086,32016,32063,27706,27742,27619,28125,27974,28117,28125,28117,28243,32690,32574,32508,32619,32574,32677,9920,10168,9897,12610,12517,12121,10796,10694,10897,13506,13440,13527,37858,37922,37852,37894,37922,37858,37593,37562,37726,7809,7792,7931,7931,7867,8000,8000,8013,8106,7572,7792,7809,7775,7792,7572,7179,7334,7220,22962,23038,22991,34342,33978,34208,34954,34479,34488,40323,40126,40214,40108,39801,40025,33033,32918,32886,32999,32918,33033,36199,36324,36049,36555,36324,36464,6930,6995,6967,39009,38357,38952,39427,39488,39485,33471,33397,33427,32107,32290,32011,32294,32290,32107,31181,30922,31158,3196,3346,3038,3330,3282,3406,13210,13216,13358,13741,13804,13756,12610,12121,12094,15758,15787,15621,15403,15202,15300,39671,39645,39545,3040,3046,3104,3038,3346,3210,2918,3091,3047,2918,3047,2756,6428,6344,6262,6905,6930,6967,4792,4976,4902,4792,4902,4734,33619,33722,33695,33500,33397,33471,19203,19529,19532,19533,19529,19236,19080,19012,19048,19012,18892,19048,22991,23038,23079,23749,23674,23820,23517,23541,23455,24562,24861,24465,24465,24861,24725,23405,23455,23250,6905,6967,6777,7867,8013,8000,17499,17425,17537,17121,16805,16667,17530,17425,17499,40168,39750,39952,39796,39817,39751,40156,40108,40135,31211,31181,31158,4669,4845,4682,4669,4742,4591,4440,4481,4446,4440,4325,4338,23038,23395,23079,21153,21307,21200,37726,37562,37702,40323,40214,40373,40349,40611,40648,19605,19644,19855,15940,16092,15945,15787,16092,15940,25585,25523,25393,25393,25523,25597,2887,3046,3040,3687,3722,3783,4200,4274,4115,3618,3722,3687,13897,13877,13834,14939,14978,14780,13741,13756,13470,27967,27867,27942,27967,27942,27974,29905,29954,29727,29382,29208,29334,38445,38467,38612,32574,32501,32482,32619,32501,32574,38612,38489,38849,4274,4194,4115,38356,38234,38230,38289,38411,38184,38370,38310,38296,37977,37932,37922,33430,33287,33482,32918,32865,32768,33538,33731,33666,8910,9064,8947,9509,9469,9639,8811,8947,8803,32999,32865,32918,36466,36411,36398,36142,36197,36006,36466,36398,36423,6907,6764,7041,6907,7041,7243,19422,19392,19413,17324,17256,17425,21955,22055,21940,29194,29445,29611,29142,29207,29197,34098,34023,33992,38849,38489,38721,15395,15525,15599,15905,15927,15626,29905,29727,29687,32016,31897,31790,32086,31897,32016,21615,21485,21562,23079,23395,23399,40343,40262,40148,40207,40168,39952,40360,40148,40236,10663,10574,10588,9153,8950,9835,10796,10897,10966,26431,26285,26165,26607,26878,26733,37873,37894,37858,37702,37562,37512,4280,4779,4854,12121,11638,11570,13470,13756,13437,17079,16805,17121,24984,24790,24970,23867,23749,23820,25003,24984,25187,25444,25614,25790,24004,24125,23910,25379,25585,25393,14348,14611,14737,13926,14336,13886,32318,32223,32291,39471,39222,39561,38807,38731,38757,38757,38731,38721,39358,39222,39471,2574,2786,2766,2691,2649,2813,19392,19275,19413,35752,35822,35681,35105,35535,35236,37489,37502,37338,37465,37266,37236,40445,40209,40540,40134,40282,40373,6312,6248,6376,6162,5823,6080,8590,8278,8356,15905,16185,15927,15758,15621,15540,15300,15202,15190,39645,39637,39447,39671,39637,39645,39671,39545,39839,39031,38938,39026,38952,38357,38646,21615,21562,21805,23399,23395,23430,23399,23430,23586,23184,23024,23035,23741,23885,23810,4334,4669,4591,2231,2624,2869,40337,40386,40256,6344,6647,6785,23867,23961,24032,36288,36197,36136,37028,36475,36995,39499,39488,39427,39009,39115,38485,39967,39817,39796,9145,9476,9346,9469,9476,9027,32501,32425,32354,32619,32425,32501,10647,10574,10663,38023,37894,37873,37598,37702,37512,17953,18033,18229,17425,17256,17346,15927,16110,15818,15927,16185,16110,19012,18656,18892,40373,40282,40349,40282,40253,40349,37977,37894,38023,33616,33722,33619,33616,33500,33471,32677,32318,32425,33315,33136,33228,33315,33228,33287,36288,36238,36411,37016,37048,36984,37502,37598,37512,10228,10306,10535,7114,7243,7397,14004,14357,14180,14992,15130,15248,14992,15248,15207,30940,31148,30982,32199,32086,32063,32230,32086,32199,37763,37053,37431,36792,36603,36930,13804,13926,13886,13216,13210,13111,24220,23867,24032,23586,23430,23592,23741,23810,23541,3053,3328,3588,3466,3906,3760,3660,3760,3865,14978,14992,14837,26483,26607,26656,26483,26285,26431,40110,39826,40121,40012,40088,40025,39499,39039,39124,2608,2662,2698,19130,18959,19151,18626,18656,18098,2570,2596,2718,2628,2578,2612,2612,2578,2623,2623,2578,2632,2632,2574,2766,2608,2480,2662,2570,2718,2673,2570,2673,2542,2673,2611,2542,2611,2589,2542,2654,2589,2611,6016,5823,6162,5255,4532,6011,36408,36288,36411,36946,36520,36456,2654,2665,2589,2589,2665,2388,20721,20396,20756,19422,19399,19392,19392,19399,19275,19275,19192,19151,20721,20756,20938,20968,20938,21056,20938,21098,21056,21098,21200,21056,33896,33731,33747,33307,33283,33427,36007,35901,36006,35755,35752,35661,37260,37218,37016,40325,40427,40275,40646,40129,40294,40337,40445,40386,40818,40325,40159,40549,40159,40331,22779,22639,22575,10956,10796,10966,10437,10472,10574,10074,10003,10121,10956,10966,11026,10458,10679,10453,10458,10453,10168,31181,31211,31184,31158,30922,31136,37630,37598,37502,37848,37873,37726,2542,2589,2388,15758,15540,15619,15190,15202,14737,15190,14737,14716,22779,22772,22639,26483,26431,26542,25827,25895,25722,25989,26372,25895,26949,27365,26891,25722,25700,25667,32425,32318,32291,32574,32690,32754,38310,38411,38289,38370,38411,38310,40330,40266,40163,40099,40136,39995,40330,40163,40262,2756,3272,2844,3022,2887,3040,3196,3282,3305,4661,4902,4669,4051,4194,4094,6248,6087,6162,5941,6087,6009,15626,15547,15599,16539,16667,16805,29954,30081,29982,29875,29905,29687,29875,29687,29636,36204,36007,36006,36408,36411,36497,38356,38332,38234,37695,38038,37698,37701,37681,37566,38445,38497,38356,38612,38615,38445,38624,38615,38612,34441,34494,34416,35714,35755,35535,35535,35755,35661,34375,34494,34441,34375,34441,34326,34659,34494,34734,2662,2616,2797,2480,2616,2662,40465,40476,40331,40349,40253,40212,29207,29142,29131,29753,29816,29676,29919,30033,30063,30056,30081,29954,8811,8910,8947,8356,8278,8106,34220,33978,34342,32775,33250,33307,33127,32775,32800,23885,24004,23910,24861,24889,25107,23741,24004,23885,40207,39952,40197,39009,39051,39115,39632,39499,39124,39052,38952,39159,13877,13655,13834,14357,14595,14180,13741,13926,13804,13642,13926,13741,15627,15547,15626,39358,39176,38999,38849,38624,38612,39358,38999,39222,22779,22857,22772,3969,4137,3798,5255,6214,5545,8013,7903,8106,7792,7867,7931,7775,7867,7792,7598,7179,7572,6905,7001,6930,22772,22857,22991,22772,22991,23047,23586,23592,23749,23306,23405,23250,23184,23250,23024,28838,28089,28058,28838,28626,28823,40551,40360,40218,40429,40360,40551,5235,5255,5545,10121,10003,10306,10228,10535,10472,32754,32865,32881,32754,32768,32865,6087,6016,6162,5823,5665,5820,5912,6016,5941,36204,36006,36197,36497,36411,36466,36497,36466,36520,7333,7132,7397,6295,6312,6970,6777,6888,6771,10472,10535,10574,2507,2578,2628,6295,6970,6479,21389,21599,21517,21669,21766,21865,22105,22121,22169,21247,20973,20724,19647,19532,19529,19647,19529,19627,33538,33430,33482,33819,33722,33616,32328,32439,32290,36357,36197,36288,2918,2931,3091,2809,2931,2918,24280,24562,24409,14780,14649,14664,14624,14649,14780,14978,14939,14992,3798,4137,3987,12610,12890,12843,13057,12890,12910,15207,15248,15395,28971,28632,28909,26656,26607,26733,31980,32107,31778,37894,37977,37922,37848,37726,37767,39031,38717,38938,25817,25444,25790,23833,23749,23867,23833,23586,23749,6735,6777,6771,6735,6771,6647,21599,21657,21669,34023,33896,33747,33538,33525,33430,34880,34098,33992,33967,34086,33942,35552,35676,35858,17199,17530,17745,16853,16539,16805,13682,13655,13877,13827,13877,13997,18071,18626,18098,15758,15619,15763,23405,23517,23455,24668,24782,24562,23394,23517,23405,40266,40207,40197,40374,40207,40266,3305,3282,3330,3669,3798,3987,3210,3132,3038,15409,15207,15395,15540,15466,15619,14280,14348,14336,17158,17121,17256,15627,15512,15547,15547,15512,15599,10647,10663,10694,19627,19529,19533,21657,21766,21669,32330,32328,32294,31136,30922,31072,38365,38094,38234,37598,37674,37702,37786,37674,37751,37465,37236,37449,6508,6647,6344,6517,6735,6647,33372,33315,33430,33430,33315,33287,33605,33616,33471,32800,33056,33127,4792,4769,4976,4661,4734,4902,4661,4669,4508,28666,28513,28571,30940,30982,30838,20985,21056,21049,23047,22991,23079,40349,40212,40611,40465,40331,40323,5601,5665,5703,36511,36497,36520,36408,36357,36288,36408,36497,36511,20319,20021,20370,17268,17324,17199,19529,19203,19236,21766,21885,21865,3038,3132,2930,15409,15512,15364,39637,39679,39503,39839,39545,39745,39839,39745,39817,24562,24782,24861,24222,24125,24004,33967,33896,34023,39826,40177,40121,40108,40219,39942,37016,37218,37048,36603,36562,36811,23190,23047,23079,24220,24482,24817,2578,2574,2632,4498,4280,4854,4150,3853,4024,10003,9819,9911,10089,10074,10121,10089,10121,10228,11570,11638,11285,19236,19203,19080,21885,21955,21940,24817,24482,24790,24056,24222,24004,37399,37236,37222,38572,38497,38445,38580,38445,38615,40168,40149,40099,40269,40149,40168,40135,40108,40025,38497,38332,38356,39147,39052,39159,38191,38055,37984,4200,4196,4527,4175,4196,4200,4115,4194,4051,29334,29208,29034,29905,30056,29954,30081,30430,30133,38624,38580,38615,2494,2649,2691,2494,2691,2616,3366,3687,3730,4059,4115,4051,13808,13827,13997,16453,16155,16092,19111,19236,19080,36688,36508,36555,3669,3987,3722,4734,4769,4792,4639,4769,4734,15787,16112,16092,15779,16112,15787,28513,28285,28378,32230,32199,32318,30838,30982,30796,31175,31148,31013,32800,32490,33056,33605,33471,33586,37767,37726,37702,38124,38191,37984,37767,37702,37674,3840,4051,3969,29142,28971,28909,28666,28724,28513,28296,28228,28285,29753,30001,29816,30561,30544,30754,6517,6508,6493,35822,35979,35681,35714,35535,35428,16112,16453,16092,4532,4498,4854,4280,4498,4076,13506,13527,13655,11415,11679,11480,10796,10647,10694,14180,14595,14531,14978,14824,14780,14752,14824,14837,14624,14824,14752,15534,15466,15540,25585,25700,25523,28859,28838,28823,38124,37984,37977,39681,39353,39485,39244,39124,39115,39967,39839,39817,29256,28971,29142,32999,33033,33136,32619,32677,32425,3282,3267,3406,3208,3267,3282,25992,25960,26010,26607,26483,26542,27967,27706,27867,19605,19399,19422,21955,22121,22105,40530,40242,40377,40412,40343,40148,13919,14280,14336,15763,15779,15758,13919,14336,13926,40429,40148,40360,40269,40136,40149,32881,32677,32754,33896,33666,33731,35755,35861,35752,11363,11166,11404,10214,10101,10228,17530,17324,17425,19013,18761,18959,24222,24280,24409,25379,25393,25107,24395,24280,24266,23741,23541,23695,40088,40135,40025,39681,39485,39655,28971,28752,28632,29191,29334,29034,28058,28626,28838,8752,8910,8811,10126,10458,10168,8752,8803,8590,33605,33586,33668,33056,32925,33072,13682,13506,13655,13682,13877,13827,28228,28125,28243,28228,28243,28285,37681,37763,37431,38407,37923,38094,37848,38023,37873,37786,37767,37674,39176,39031,39026,38665,38572,38580,39157,39031,39176,38952,39051,39009,39052,39051,38952,40465,40323,40402,15512,15409,15395,15223,15409,15364,15626,15927,15627,39671,39679,39637,39900,39679,39671,39655,39485,39488,14624,14531,14649,39123,39244,39115,37465,37489,37338,37218,37399,37222,37409,37399,37218,34494,34659,34488,36057,35979,35861,33427,33586,33471,4338,4591,4440,11052,10956,11026,23190,23079,23399,21153,21200,21098,23190,23399,23287,30673,30561,30754,38124,38023,38138,40343,40330,40262,40420,40330,40343,33666,33525,33538,33616,33605,33668,36131,35979,36057,35861,35979,35822,25667,25379,25845,37619,37489,37465,3293,3338,2732,2815,2560,3044,2414,2542,2388,24220,23833,23867,23482,23351,23361,23578,23541,23517,40156,40219,40108,40402,40323,40373,40252,40219,40156,19399,19192,19275,32754,32677,32574,30940,30838,30754,32999,33136,33171,36555,36508,36324,37173,37260,37016,40402,40373,40349,33978,33803,33994,25992,26010,26153,25003,24927,24984,25948,25872,25827,25827,25872,25895,33186,33136,33315,35858,35676,35832,36511,36357,36408,36511,36520,36707,17324,17279,17256,17268,17279,17324,32294,32328,32290,31731,31221,31623,36858,36930,36603,40149,40136,40099,40303,40168,40452,40141,40135,40088,7867,7903,8013,7401,7334,7179,7220,7019,7179,6711,6905,6777,6532,6777,6735,33819,33803,33722,40110,40141,40088,40177,39826,39395,3618,3669,3722,3798,3873,3969,3490,3669,3434,11975,11679,12192,13808,13682,13827,19192,19130,19151,27972,27967,27974,27972,27974,28125,30673,30838,30796,33525,33434,33430,20968,21056,20985,23287,23399,23361,23035,22880,22800,7775,7903,7867,13057,13216,13111,13057,13111,12890,39031,39004,38717,39223,39004,39031,26733,26878,26994,26153,26010,26285,30001,30033,29919,29816,30001,29919,29256,28953,28971,28971,28953,28752,11989,12094,12121,11793,12094,11989,37801,37775,37781,38504,38365,38332,38580,38572,38445,38721,38731,38792,4325,4440,4446,4325,4446,4196,4325,4196,4153,29628,29875,29636,29628,29636,29382,29191,29034,28936,38792,38731,38807,19130,19013,18959,2542,2501,2570,2570,2501,2596,2596,2540,2714,2578,2280,2574,2414,2501,2542,2665,2639,2388,2501,2524,2596,11363,11231,11166,11166,11052,11026,13230,13440,12892,20900,20938,20968,20900,20721,20938,20396,20319,20370,19605,19408,19399,19399,19311,19192,19192,19311,19130,19130,19156,19013,20900,20968,20985,21200,21307,21384,29875,30056,29905,31367,31221,31211,38273,38296,38191,38191,38296,38055,39078,38402,38411,2524,2540,2596,36688,36811,36562,36808,36811,36688,2540,2505,2714,21268,21200,21384,5665,5601,5820,6016,5912,5823,5941,6016,6087,6151,6248,6312,21615,21805,21642,32999,32946,32865,33115,32946,32999,33434,33372,33430,40427,40530,40377,40646,41176,40821,40549,40331,40512,2930,3132,3046,3196,3208,3282,2887,3022,2857,21642,21805,21915,23361,23399,23482,23184,23306,23250,23201,23306,23184,25585,25667,25700,24681,24861,24782,31362,31211,31158,37173,37016,37074,37399,37449,37236,37173,37074,37144,37555,37449,37399,37751,37674,37598,38138,38023,38166,38023,38124,37977,10748,10796,10797,10748,10647,10796,20341,20319,20396,22454,22162,22639,17279,17158,17256,17268,17158,17279,36025,35832,36007,34098,33967,34023,33896,33841,33666,33666,33776,33525,33618,33487,33434,33434,33487,33372,11243,11231,11363,13216,13470,13437,13374,13470,13216,26811,26994,26990,28296,28285,28513,28724,28666,28752,39051,39123,39115,39123,39052,39147,40512,40331,40476,40515,40402,40694,2809,3022,2931,16453,16701,16475,16509,16701,16453,16509,16453,16337,22772,22819,22639,29256,29142,29197,28838,28859,28936,27365,26949,27132,38919,38792,38807,26153,26285,26090,25960,25817,25790,25872,25989,25895,25948,25989,25872,34086,34098,34113,11128,11052,11166,37807,37848,37767,2417,2466,2628,2574,2510,2608,8753,8752,8647,9027,9476,9145,23482,23399,23586,22772,23047,22819,23482,23586,23833,40439,40374,40266,40439,40266,40330,40218,40386,40551,18759,18892,18656,18759,18656,18626,3840,3873,3826,28953,28724,28752,2466,2507,2628,23047,23096,22819,32946,32881,32865,31596,31495,31340,33115,32881,32946,36811,36858,36603,36464,36324,36199,5761,5665,5823,5255,4901,4532,6508,6517,6647,6493,6508,6428,10521,10437,10574,10521,10574,10647,9469,9509,9476,10976,11570,11285,14824,14624,14780,14004,13808,13997,15223,14992,15207,15223,15207,15409,14374,14611,14348,15758,15779,15787,14716,14611,14471,31072,30123,30430,33967,33841,33896,33348,33186,33315,36924,36858,36811,37781,37775,37681,38365,38234,38332,37630,37502,37489,26090,26375,26183,27920,27706,27967,17158,17079,17121,17050,17079,17158,24280,24668,24562,24395,24668,24280,24681,24668,24535,13470,13642,13741,13602,13642,13578,23047,23190,23096,28228,27972,28125,27999,27972,28228,30838,30673,30754,30547,30673,30796,18779,18759,18626,40540,40386,40445,3267,3207,3795,3136,3208,3196,15627,15927,15818,15377,15466,15534,25667,25761,25722,25845,25761,25667,2419,2756,2844,2419,2844,2257,5214,5235,5545,10089,9819,10003,10089,10003,10074,37260,37409,37218,37792,37807,37786,37343,37409,37260,6428,6508,6344,16701,17016,17205,16337,16453,16112,33348,33315,33372,33841,33791,33666,33668,33819,33616,33427,33467,33586,33283,33394,33427,2765,2614,2815,2651,2614,2765,23096,23190,23143,23482,23833,23469,10101,10089,10228,39222,39149,39561,38930,38849,38792,37073,37074,36930,29494,29628,29382,29875,30197,30056,31264,31158,31136,29494,29382,29334,4537,4639,4661,4175,4200,4115,29676,29611,29445,29113,28542,28724,30033,30254,30400,3038,3176,3196,3136,3176,3015,5190,5198,5235,5912,5761,5823,5824,5761,5912,10797,10796,10956,10214,10228,10472,23190,23287,23143,25939,25817,25960,26738,26483,26656,37018,37073,36930,36555,36658,36688,36638,36658,36555,40429,40412,40148,40547,40412,40429,4022,4175,4115,38535,38332,38497,38624,38665,38580,38777,38665,38803,38849,38721,38792,31264,31362,31158,31264,31136,31072,10976,11285,10763,12910,12890,12610,30400,30254,30561,38535,38497,38572,6144,6344,6220,33250,33262,33394,33283,33250,33394,8779,9145,8910,2473,2809,2918,2887,2930,3046,3840,4059,4051,12892,13440,13506,11243,11128,11231,11231,11128,11166,10825,10797,10956,13731,13506,13682,17079,17029,16805,17050,17029,17079,16764,17016,16701,24668,24681,24782,23767,24004,23741,29179,29191,28859,28859,29191,28936,40135,40252,40156,40494,40465,40515,40121,40141,40110,40248,40141,40121,13950,13808,14004,27972,27920,27967,28542,28296,28513,28542,28513,28724,23433,23578,23517,23394,23405,23306,34777,34954,34659,34659,34954,34488,35979,36131,35681,34503,34494,34375,34503,34375,34418,34375,34342,34418,38231,38273,38191,38296,38494,38370,38221,38191,38124,33186,33171,33136,33193,33171,33186,40165,39967,39796,39839,39909,39671,40321,40269,40168,40168,40207,40452,6479,6970,6764,8115,8749,8315,6532,6517,6462,6532,6735,6517,7220,7001,7019,7775,7784,7903,7829,8356,8106,40512,40476,40494,40476,40465,40494,38919,38807,39045,34418,34342,34208,6479,6764,6498,33994,33803,33819,33056,33072,33091,11243,11363,11415,30547,30400,30561,16395,16337,16227,16680,16764,16701,15377,15300,15466,25939,25960,25992,33994,33819,33839,35552,35234,34886,33967,33942,33841,33841,33927,33791,35430,35234,35552,10724,10521,10748,10748,10521,10647,37786,37807,37767,37630,37489,37619,3208,3257,3267,3826,3873,3655,3145,3257,3208,5235,5198,5255,5190,5235,5214,9868,9920,9897,10763,11285,10775,26861,26805,26372,26289,26372,25989,39499,39655,39488,40329,40177,39395,40057,39655,39499,39632,39124,39244,3905,3853,4150,3801,3853,3809,4150,4280,3932,3873,3840,3969,3873,3798,3655,7724,7784,7775,28626,28058,28440,38930,38919,39046,23578,23695,23541,23590,23695,23578,39430,39157,39176,39052,39123,39051,38575,38411,38370,2420,2510,2574,10082,10101,10214,10089,9919,9819,9969,10126,10168,19555,19408,19605,17014,16853,17029,37619,37465,37449,37619,37449,37576,40708,40540,40209,40515,40694,40636,6048,6087,6248,5761,5703,5665,5758,5913,5684,4740,5367,4769,30673,30547,30561,31251,31148,31175,31495,31596,31897,33127,33056,33101,33056,33091,33101,37924,38023,37848,17029,16853,16805,17324,17530,17199,40359,40252,40135,33618,33434,33525,33776,33666,33791,35923,35861,35755,37173,37343,37260,37018,36930,36858,37144,37073,37223,3176,3136,3196,3113,3136,3015,27365,27618,27642,3853,3763,4024,12910,12155,12889,14374,14348,14280,19408,19311,19399,19111,19048,19002,19111,19080,19048,19761,19647,19563,19761,19861,19647,20290,21247,20724,21599,21785,21657,21657,21785,21766,21766,21785,21885,21885,21863,21955,21955,21863,22121,19048,18892,19002,29113,28724,28953,27999,27920,27972,28440,28058,27797,40515,40465,40402,31362,31367,31211,31347,31264,31429,37775,37769,37681,37801,37769,37775,40231,39748,40136,39561,39149,39503,4661,4639,4734,4334,4591,4338,11081,10956,11052,10214,10472,10437,23143,23287,23304,21268,21485,21642,23287,23361,23304,22800,22880,22689,22689,22547,22630,32086,32230,31897,40412,40420,40343,40529,40420,40412,2788,2930,2887,15921,16112,15779,2732,3338,2572,2388,2639,2039,3526,3503,2961,23695,23767,23741,23718,23767,23695,40402,40349,40648,6180,6151,6312,6180,6312,6295,33487,33348,33372,32318,32575,32230,33516,33348,33487,33839,33819,33899,33262,33250,33127,36407,36204,36197,36407,36197,36357,5774,5824,5941,5941,5824,5912,13808,13731,13682,13800,13731,13808,14180,14531,14366,16185,16349,16110,14837,14824,14978,15763,15921,15779,15466,15300,15227,14716,14737,14611,25761,25948,25827,25845,25948,25761,26023,25948,25880,27999,28228,28296,26733,26738,26656,26153,26090,25992,36946,36456,37028,40013,39909,39839,39358,39471,39176,29816,29683,29676,29841,29683,29816,29869,29816,29919,29869,29919,29967,30033,30330,30063,38707,38535,38572,37695,37766,38301,38707,38572,38665,38707,38665,38777,18033,18761,18368,16110,16349,16141,24266,24280,24222,30200,30197,29875,29419,29494,29334,29419,29334,29191,28875,28859,28823,40269,40238,40136,40564,40238,40269,3763,3702,4024,30033,30400,30330,38535,38504,38332,38567,38494,38541,38541,38494,38296,14837,14992,14991,13919,13926,13778,2809,2857,3022,2693,2857,2809,2788,2857,2716,18779,18892,18759,16680,16701,16509,24984,25228,25187,3985,4022,4059,4059,4022,4115,4175,4153,4196,4309,4334,4338,9920,9969,10168,10763,10775,10666,9868,9969,9920,29438,29284,29207,6462,6517,6493,6462,6493,6400,34086,33967,34098,33839,33936,33950,35428,35535,35105,2510,2480,2608,3257,3264,3267,3167,3264,3257,3113,3208,3136,4309,4338,4325,19002,18892,18779,30330,30400,30349,21485,21615,21642,23304,23361,23351,23035,23201,23184,23239,23201,23039,4635,4740,4769,4635,4769,4639,30491,30400,30547,32677,32575,32318,37807,37924,37848,38138,38221,38124,38039,37924,37807,37220,37132,37028,37073,37144,37074,37812,37792,37786,36808,36688,36658,14366,14531,14624,6151,6048,6248,6180,6048,6151,8752,8753,8910,9469,9868,9870,8647,8752,8590,11265,11243,11415,11128,11081,11052,11975,12192,12339,30491,30547,30600,31347,31367,31362,31347,31362,31264,33243,33262,33127,33839,33899,33936,33243,33127,33101,3015,3176,2734,15513,15364,15512,6633,6764,6907,6400,6493,6428,33467,33427,33394,18779,18626,18410,40540,40551,40386,2501,2414,2524,2524,2451,2540,2540,2451,2505,2505,2417,2628,2466,2441,2507,2507,2402,2578,2510,2392,2480,2560,2815,2614,20721,20641,20396,20319,19855,20021,19408,19428,19311,20704,20641,20721,20704,20721,20833,20721,20900,20833,20900,20985,20833,20985,20914,20833,21049,21124,20985,21200,21124,21049,21200,21268,21124,2414,2451,2524,3702,3660,3865,15908,15921,15763,16337,16441,16509,15550,15763,15619,20641,20530,20396,21384,21485,21268,36633,36638,36555,36808,36638,36754,39123,39450,39244,39064,38952,38646,28735,28875,28823,28657,28823,28626,38919,38930,38792,39045,38807,39004,2451,2453,2505,2453,2417,2505,2562,2560,2614,4334,4508,4669,11121,11081,11128,10214,10437,10272,20530,20341,20396,22639,22819,22680,23351,23482,23469,23201,23254,23306,23767,24056,24004,23239,23254,23201,30895,30547,30796,37132,36946,37028,38166,38221,38138,40420,40439,40330,40561,40439,40420,2961,3496,3328,2376,2562,2614,14062,13950,14004,11695,11975,11739,13602,13926,13642,27920,27742,27706,27938,27742,27920,27999,28055,27938,27618,27711,27797,27647,27711,27618,27647,27618,27365,2208,2388,1921,22819,22854,22680,33115,32999,33171,30982,30895,30796,33890,33776,33791,37836,37220,37053,37766,37810,38418,38340,38231,38262,37751,37598,37630,25948,26023,25989,25845,25379,25880,39909,39900,39671,40013,39900,39909,40013,39839,40087,6048,6009,6087,5214,5545,5208,5988,6009,6048,8753,8779,8910,8761,8779,8753,33340,33186,33348,33340,33193,33186,33356,33467,33394,32925,33056,32490,40530,40646,40294,40712,40591,40551,40980,40530,40427,40703,40159,40549,40612,40549,40624,40549,40512,40624,3932,3909,3863,3853,3801,3763,3763,3721,3702,3702,3671,3660,13578,13642,13470,12910,12610,12155,28706,28657,28626,40452,40207,40374,40238,40231,40136,22819,23096,22981,19861,20023,19647,19627,19563,19647,19533,19563,19627,4508,4537,4661,5198,4901,5255,5703,5761,5824,10775,10458,10666,10036,9868,9677,2355,2441,2466,2209,2414,2208,2376,2614,2651,23469,23833,23545,22981,23096,23143,23254,23394,23306,23239,23394,23254,32575,32677,33209,37132,37385,36946,37763,37681,37769,40439,40443,40374,40570,40443,40439,8461,8749,8833,6609,6633,6907,9153,9835,9882,10101,10082,10089,10724,10748,10797,37555,37399,37409,2480,2494,2616,2367,2494,2480,6224,6262,6344,13374,13216,13195,26811,26733,26994,25003,24817,24927,27999,28087,28055,26990,26994,27181,34629,34734,34494,34954,35146,35105,34629,34494,34503,34629,34503,34576,34503,34418,34576,36196,36025,36007,36196,36007,36204,36407,36357,36484,14180,14062,14004,14554,14366,14624,14554,14624,14752,14095,14374,14280,15227,15300,15190,13991,14280,13919,5600,5703,5604,36638,36808,36658,37144,37343,37173,36464,36199,36131,2441,2402,2507,34208,33978,33994,35189,35146,34954,17268,17050,17158,15098,15175,15364,17199,17050,17268,40363,40231,40238,3113,3145,3208,3264,3207,3267,3015,3145,3113,3167,3145,2804,15364,15175,15223,15609,15512,15627,19918,19855,20319,16929,17014,17050,19533,19540,19563,16349,16539,16141,33193,33115,33171,33522,33115,33193,33356,33394,33262,32159,32107,31980,36602,36464,36627,36633,36464,36622,4537,4635,4639,5987,6220,5913,10825,10724,10797,31367,31555,31221,30197,30081,30056,37889,37763,37769,37823,37763,37889,37719,37751,37630,38166,38023,38218,39872,40107,39990,38981,38875,38930,2732,2679,3293,12892,13506,13120,11243,11121,11128,11081,10825,10956,19533,19442,19540,17796,18098,17647,22981,23143,23469,24889,24861,24681,23923,24056,23767,29284,29256,29197,29683,29611,29676,29733,29611,29683,29733,29683,29841,29967,29919,30063,29967,30063,30039,38494,38575,38370,38567,38575,38494,38231,38191,38221,38856,38407,38365,38535,38723,38504,38803,38624,38849,40303,40321,40168,40505,40321,40303,40551,40547,40429,40591,40547,40551,2857,2788,2887,2693,2809,2473,40231,40155,39748,40319,40177,40482,40141,40248,40135,40636,40494,40515,4022,3998,4175,4334,4422,4508,4508,4521,4537,4537,4521,4635,3985,3998,4022,3985,4059,3840,4153,4309,4325,6144,6224,6344,6144,6220,5987,19236,19442,19533,29611,29438,29207,30157,30063,30330,30157,30330,30340,33720,33618,33525,23394,23433,23517,23239,23433,23394,34880,33992,34752,33942,33927,33841,33776,33814,33525,35558,35430,35552,3905,3932,3863,29281,29256,29284,29589,29875,29628,28875,29179,28859,28969,29179,28875,30349,30400,30491,29589,29628,29494,14832,15190,14716,16395,16441,16337,21247,21785,21599,26090,26285,26375,3654,3671,3702,3660,3601,3760,3721,3763,3801,13602,13778,13926,13195,13216,13057,13700,13778,13602,22630,22169,22121,34147,34208,33994,33950,33994,33839,35705,35558,35831,40547,40529,40412,40443,40452,40374,40591,40529,40547,31148,31084,30982,31193,31084,31148,30430,30123,30133,11265,11121,11243,19236,19397,19442,21785,21863,21885,30340,30349,30508,30197,30430,30081,38039,37807,37792,38930,38875,38849,39045,39004,39223,5208,5545,5328,3745,3905,3759,17050,17014,17029,18582,19013,18692,37223,37343,37144,37827,37812,37751,40319,40248,40121,9589,9882,9819,5600,5552,5703,6173,6180,6295,6322,6295,6479,6051,6144,5987,33720,33516,33618,33618,33516,33487,33356,33262,33269,23433,23590,23578,23718,23590,23433,40570,40452,40443,6894,7243,7114,15098,15164,15175,16702,16539,16853,32230,31495,31897,31623,31555,31534,31534,31555,31367,14691,14554,14752,14157,14062,14180,13950,13800,13808,14992,15223,15164,19855,19555,19605,19236,19136,19397,40624,40512,40494,40624,40494,40636,3181,3207,3264,3167,3257,3145,15164,15223,15175,14580,14832,14716,14471,14611,14374,26104,26039,26090,26731,26811,26990,26747,26861,26372,3745,3809,3853,3655,3798,3495,16337,16112,16227,16764,16892,17016,24889,24681,24888,26636,26747,26372,3176,3038,2734,14991,15164,15098,34981,34752,35234,2280,2420,2574,3548,3601,3660,3548,3660,3671,14397,14471,14374,13374,13578,13470,19555,19428,19408,19236,19111,19136,40146,40611,40212,8310,8647,8590,8779,9027,9145,33516,33340,33348,31391,31500,31536,33812,33340,33516,33645,33668,33586,33269,33262,33243,33269,33243,33101,31431,31251,31175,30340,30330,30349,37751,37812,37786,37719,37630,37619,36946,36707,36520,36025,35858,35832,36683,36707,36747,36924,37018,36858,36464,36633,36555,35923,35755,35714,3404,3466,3760,5703,5552,5601,5774,5941,6009,14164,14180,14366,28440,28706,28626,28657,28735,28823,27478,27647,27365,3082,3181,3167,2606,2693,2473,2716,2693,2606,3739,3721,3801,6633,6498,6764,16680,16892,16764,19136,19111,19002,22854,22981,23206,22464,22454,22639,23143,23304,23469,24927,24817,24790,25815,25444,25817,34086,33927,33942,33645,33586,33554,35949,35858,36117,39046,39045,39213,39147,39308,39123,39078,39064,38646,24056,24266,24222,24104,24266,24056,37343,37442,37409,37532,37442,37518,6180,5988,6048,6009,5988,5915,8647,8761,8753,33091,33269,33101,33554,33586,33467,36484,36357,36559,3998,4153,4175,4355,4422,4334,4005,4153,3998,6303,6400,6428,6462,6400,6532,7019,7001,6711,7829,7903,7784,7829,8106,7903,8647,8665,8761,6303,6428,6262,6303,6262,6153,29438,29281,29284,29256,29218,28953,29611,29489,29438,29841,29816,29869,29841,29869,29967,29841,29967,29997,30063,30157,30039,33927,33890,33791,35940,35923,35714,30039,30157,30210,38575,39078,38411,38541,38296,38449,38296,38273,38449,16441,16680,16509,16227,16112,16004,16112,15921,16004,29560,29489,29611,38707,38723,38535,38803,38665,38624,38803,38849,38934,40155,40165,39796,39900,40036,39679,40301,40165,40155,40368,40155,40231,40363,40238,40564,3415,3519,3601,3601,3519,3760,13578,13700,13602,40529,40555,40420,40405,40363,40532,40715,40555,40529,11975,11480,11679,10272,10521,10386,11332,11480,11464,13450,13818,13700,13272,13450,13578,12889,13195,13057,12889,13057,12910,12610,12094,12155,17251,17374,17016,19034,19136,19002,30895,30982,31003,39064,39159,38952,40482,40177,40475,39147,39159,39373,3826,3985,3840,29432,29281,29438,38934,38849,38875,2847,2961,3328,2384,2359,2679,26039,25939,25992,26039,25992,26090,40087,39839,39967,2345,2392,2510,11091,11081,11121,10272,10437,10521,10082,9998,10089,31193,31087,31084,31495,31431,31340,31500,31431,31495,31353,31431,31391,37661,37719,37619,38218,38023,37924,40359,40219,40252,36633,36754,36638,36714,36754,36633,15416,15550,15466,13991,13919,13778,11332,11265,11415,18582,18761,19013,16880,16702,16853,17103,17251,17016,17103,17016,16892,40248,40359,40135,40392,40359,40248,6153,6224,6144,6153,6262,6224,7724,7775,7675,33890,33814,33776,35923,36057,35861,2693,2716,2857,2386,2649,2494,3167,3181,3264,3490,3798,3669,3146,3181,3082,3809,3739,3801,3553,3548,3671,3932,3905,4150,5090,5198,5190,15164,14991,14992,14837,14691,14752,14297,14164,14366,15609,15627,15818,24535,24668,24395,36924,36811,36808,14062,13800,13950,14297,14366,14554,28440,27797,27977,27425,27478,27365,27425,27365,27283,35561,34981,35234,34086,34097,33927,33927,33975,33890,33890,34016,33814,35462,35234,35430,35462,35430,35558,19034,19002,18779,36273,36196,36204,36559,36357,36511,7001,6905,6711,6777,6532,6711,34734,34777,34659,36158,35940,36063,35923,36073,36057,34794,34777,34734,34794,34734,34629,34576,34418,34658,40555,40561,40420,40584,40561,40555,4406,4422,4355,5987,5913,5909,7397,7076,7114,6633,6576,6498,6894,6795,6751,11265,11091,11121,35207,35189,34954,3654,3702,3721,19063,18998,19110,17251,17647,18098,23773,23923,23767,24266,24535,24395,23718,23695,23590,34674,34658,34851,33783,33720,33814,33814,33720,33525,31536,31611,31508,33554,33467,33356,33950,34147,33994,3466,3382,3906,3519,3404,3760,3431,3404,3519,13818,13991,13778,13818,13778,13700,16398,16680,16441,15550,15619,15466,19034,18998,19063,22464,22639,22680,37532,37555,37442,37442,37555,37409,40346,40087,39967,5214,5090,5190,5328,5545,5601,5328,5601,5552,32158,32159,31980,33375,33554,33356,31623,31221,31555,5656,5703,5824,4406,4521,4508,20530,20496,20341,20341,20157,20319,19855,19778,19555,19555,19455,19428,20641,20496,20530,20662,20496,20641,20662,20641,20704,20662,20704,20685,21111,20985,21124,21111,21124,21268,37827,37751,37719,38039,37792,37812,2417,2347,2466,2441,2355,2402,2402,2299,2578,2420,2345,2510,2453,2328,2417,2451,2328,2453,2228,2328,2451,2228,2451,2209,2451,2414,2209,7675,7775,7572,24425,24535,24266,31534,31367,31347,31429,31264,31379,35560,35462,35558,35558,35552,35831,40505,40303,40452,40188,40013,40087,23039,23201,23035,22953,23035,22800,2328,2357,2417,3729,3739,3809,12155,12094,11793,13450,13700,13578,20496,20350,20341,27797,27711,27977,29419,29589,29494,30197,30451,30430,39045,39046,38919,39223,39031,39157,39223,39157,39430,2357,2363,2417,32490,32439,32925,36273,36204,36407,36683,36559,36511,36683,36511,36707,36707,36946,36747,15809,15818,16110,15552,15609,15818,15227,15190,14832,16880,16853,17014,16398,16441,16395,17251,17421,17647,22781,22854,23206,22565,22464,22680,25187,25228,25444,26731,26483,26738,25815,25187,25444,2363,2347,2417,7724,7829,7784,20350,20157,20341,21440,21111,21268,21884,21642,21915,22565,22680,22781,33899,33819,33668,33375,33356,33269,36273,36407,36417,14625,14837,14886,14625,14691,14837,31431,31353,31251,31500,31495,31611,37857,37827,37719,2347,2355,2466,19861,20065,20023,22125,21863,22004,22481,22121,22433,19990,20065,19861,19990,19861,19711,19861,19761,19711,19761,19563,19711,19563,19704,19711,19540,19704,19563,19424,19704,19540,31087,30982,31084,5905,5915,6180,5538,5525,5600,6713,6609,6907,14095,14397,14374,14471,14580,14716,26811,26731,26738,26990,27181,27612,27938,27920,27999,26101,25989,26023,26101,26023,26000,3530,3654,3721,3384,3466,3404,3366,3764,3207,3860,3944,3985,27530,27647,27478,27810,27711,27647,40561,40570,40439,40584,40570,40561,19442,19424,19540,22351,21915,22454,22854,22819,22981,22619,22630,22481,22630,22121,22481,40712,40551,40540,38775,38723,38707,38775,38707,38777,38775,38777,38834,29419,29179,29287,29419,29191,29179,30430,31065,31072,38567,38679,38575,38449,38273,38455,3384,3382,3466,3431,3519,3415,3075,3366,3207,5600,5525,5552,5774,6009,5750,5913,5866,5909,6711,6532,6317,6609,6576,6633,8950,8558,8833,8461,8558,8508,14164,14157,14180,14201,14157,14164,14840,15227,14832,16576,16141,16539,17008,17103,16892,20157,19918,20319,17063,17050,17199,27425,27530,27478,29281,29218,29256,29489,29432,29438,29560,29432,29489,29336,29432,29536,29611,29733,29560,29831,29841,29997,28969,28875,28735,34880,34113,34098,36465,36407,36484,36196,36117,36025,36913,36924,36808,37563,37576,37555,36913,36808,36754,40363,40368,40231,40405,40368,40363,40646,40704,40129,40821,40704,40646,40703,40549,40702,40549,40612,40702,33346,33375,33269,32925,32439,32569,36747,36946,37298,36577,36465,36484,36602,36622,36464,11265,11280,11091,11091,10825,11081,11480,11332,11415,11464,11480,11695,38340,38273,38231,38231,38221,38262,19918,19827,19855,40702,40612,40701,29336,29218,29281,37555,37576,37449,37223,37073,37256,38981,38934,38875,16442,16576,16556,16702,16576,16539,23923,24104,24056,24014,24104,23923,23718,23433,23239,2383,2386,2494,2367,2480,2392,22630,22673,22800,22619,22673,22630,31193,31148,31251,30600,30349,30491,30657,31065,30430,38407,38094,38365,37763,37836,37053,37941,38039,37812,37941,37812,37827,40611,40684,40686,40701,40612,40698,34113,34097,34086,30600,30547,30751,38856,38365,38504,38262,38221,38166,19063,19397,19136,22476,22454,22464,3579,3553,3671,3932,4280,3909,5201,5328,5552,32159,32330,32294,32460,32330,32159,31768,31980,31623,37256,37073,37018,39046,38981,38930,39430,39176,39471,40036,39900,40013,3415,3601,3433,13948,13800,14062,14095,13818,13670,14095,14417,14397,15609,15513,15512,15552,15513,15609,26039,26157,25939,26183,26104,26090,25880,25948,25845,25667,25585,25379,24888,24681,24535,27863,27810,27647,33812,33193,33340,31193,31003,31087,31429,31534,31347,40062,40036,40013,40062,40013,40204,3905,3745,3853,3540,3579,3654,3654,3579,3671,5090,5214,5115,28735,28657,28706,28735,28706,28576,39056,38981,39046,6197,6400,6303,5913,5758,5866,33346,33269,33091,33899,33668,33645,40612,40624,40698,33720,33812,33516,34097,33975,33927,33899,33883,34070,36355,36464,36131,35428,35105,35146,4540,4740,4635,4422,4406,4508,4226,4334,4309,4226,4309,4153,4005,3998,3944,10458,10126,10123,10126,9969,10036,30751,30547,30895,38318,38262,38166,17063,16929,17050,19130,19311,19156,32569,32439,32328,33072,33231,33091,40698,40624,40636,32330,32569,32328,28576,28706,28440,3181,3146,3207,3038,2930,2745,17095,17421,17251,18071,18098,17796,26747,26809,26861,27617,27863,27647,26737,26809,26747,14157,14022,14062,14261,14297,14513,14164,14297,14201,39872,39561,39503,3434,3669,3618,3944,3998,3985,3434,3618,3366,33899,33645,33883,39373,39308,39147,40177,40319,40121,39373,39429,39541,10623,10825,10723,10214,9998,10082,10036,9969,9868,15112,15098,15364,6153,6144,6051,4540,4635,4521,19455,19311,19428,22781,22688,22570,22565,22476,22464,36577,36484,36559,36273,36320,36196,36577,36559,36800,40803,40698,40800,40146,40090,40684,5172,5214,5208,37518,37442,37343,37576,37661,37619,10160,9998,10214,19586,19455,19555,37689,37661,37576,38039,38218,37924,40704,40708,40209,40718,40584,40555,40694,40402,40693,5328,5261,5208,5154,5261,5201,34016,33783,33814,2672,2930,2788,7074,7565,7572,7724,7727,7829,6153,6051,6063,15227,15416,15466,15908,16004,15921,16227,16398,16395,16823,17008,16892,17570,17666,17421,15457,15416,15141,14417,14471,14397,23432,23718,23239,24104,24252,24266,34674,34794,34629,34777,35207,34954,35189,35345,35146,34674,34629,34576,34674,34851,34833,16929,16880,17014,16576,16442,16141,15701,15552,15818,15188,15112,15364,17013,16880,16929,3594,3826,3655,22784,22953,22800,22784,22800,22673,24157,24252,24104,34794,34674,34833,38835,38418,38407,38834,38777,38803,38834,38803,39003,38541,38679,38567,38704,38679,38541,38591,38541,38449,38591,38449,38582,4489,4540,4415,4590,4540,4489,31193,31251,31206,31087,31003,30982,31500,31391,31431,31536,31500,31611,31379,31264,31072,31534,31682,31623,33072,33064,33097,31534,31429,31632,37889,37769,37801,37889,37801,38048,37801,38038,38048,37902,37857,37719,38455,38273,38340,3983,4226,4153,7076,6894,7114,6324,6498,6576,5261,5328,5201,6894,7076,6897,11332,11280,11265,11342,11464,11423,38455,38340,38477,6063,6051,5985,5576,5630,5913,36417,36320,36273,36800,36559,36683,3490,3495,3798,3436,3434,3344,3540,3654,3530,3909,4280,3849,27999,28296,28087,26731,26714,26483,29218,29113,28953,29432,29336,29281,29831,29733,29841,29997,30039,30026,30508,30349,30600,3433,3601,3548,3729,3809,3745,15908,15763,15642,7565,7675,7572,8227,8310,8356,8583,8665,8647,2152,2345,2420,38477,38340,38262,6051,5987,5985,8558,8461,8833,8508,8558,8617,16198,16398,16227,3790,3759,3905,7675,7727,7724,22953,23039,23035,23033,23039,22953,26000,25880,26066,26478,26636,26372,29193,29113,29218,29217,29071,29014,28969,29071,29179,29419,29553,29589,29589,30200,29875,29071,28969,29014,26974,26990,27044,23718,23773,23767,23902,23773,23718,4203,4355,4334,30758,30508,30600,19455,19156,19311,31206,31251,31353,30912,30751,30895,26289,25989,26101,27016,26949,26861,24252,24425,24266,24323,24425,24252,27016,26861,26809,27810,27977,27711,37256,37018,37252,37518,37343,37551,37594,37563,37532,37532,37563,37555,37902,37941,37857,4992,4901,5198,5261,5172,5208,5154,5172,5261,5988,6180,5915,40435,40319,40482,40359,40490,40219,3759,3729,3745,6479,6498,6322,36622,36714,36633,36355,36131,36277,8461,8315,8749,8617,8558,8623,36417,36407,36465,3436,3495,3490,4992,5198,5090,9677,9868,9469,8665,8779,8761,39429,39159,39064,39308,39450,39123,18582,18368,18761,18692,18368,18582,19034,19063,19136,17666,17796,17647,30912,30895,31003,40838,40712,40540,40638,40505,40452,26170,26289,26101,37179,37018,36924,3431,3384,3404,3186,3053,3588,3383,3384,3431,3548,3553,3498,17421,17666,17647,17095,17251,17103,40601,40452,40570,40188,40087,40346,16004,16198,16227,16823,16892,16680,15555,15763,15550,2269,2367,2392,2473,2918,2756,10386,10521,10724,8623,8558,8950,10386,10724,10549,38056,38038,38301,37385,37132,37220,37902,37719,37661,37857,37941,37827,40693,40402,40648,40693,40920,40924,8333,8315,8461,9919,10089,9998,36435,36417,36465,36435,36465,36536,30976,30912,31003,38057,38218,38039,40406,40392,40248,20496,20537,20350,20350,20381,20157,20157,20068,19918,19918,19778,19827,19827,19778,19855,19455,19393,19156,20685,20704,20833,20685,20833,20914,20985,20943,20914,20985,21111,20943,20662,20537,20496,18368,18229,18033,18526,18229,18368,40715,40529,40591,2357,2292,2363,2363,2190,2347,2347,2278,2355,2207,2299,2402,2345,2269,2392,2328,2228,2357,2414,2388,2208,5774,5656,5824,5597,5656,5774,15809,16110,16141,15098,14886,14991,20943,21111,21047,25880,26000,26023,25379,25107,24889,33375,33346,33554,32925,33064,33072,33028,33064,32925,32925,33024,33028,37385,37688,37573,36602,36714,36622,36891,36714,36602,39872,39740,39561,40605,40155,40368,2228,2292,2357,2716,2606,2788,2844,2649,2257,20537,20381,20350,21047,21111,21440,36117,36196,36240,36117,35858,36025,35475,34880,34981,33783,34016,34283,34450,34016,34097,34097,34016,33975,33975,34016,33890,3498,3553,3579,20065,20290,20724,20097,20290,20065,20097,20065,19997,20065,19990,19997,20769,20983,20674,26974,26804,26990,28087,28309,28174,27863,27977,27810,39783,39430,39471,39148,39056,39046,39003,38803,38934,39740,39471,39561,39541,39450,39308,39595,39450,39555,22615,22476,22565,22615,22565,22781,27132,27016,27038,27038,27016,26809,27617,27647,27530,26478,26372,26289,40915,40648,40611,30340,30428,30157,30157,30241,30210,29997,29967,30039,29336,29193,29218,29113,29193,28542,3530,3721,3739,3495,3594,3655,4173,4190,4226,4226,4190,4334,3860,3405,3791,29730,29560,29733,38856,38504,38723,39060,38934,38981,5172,5115,5214,5154,5115,5172,14095,14280,13991,15416,15457,15550,14095,13991,13818,24888,25379,24889,23773,24014,23923,23902,24014,23773,30340,30508,30428,37397,37343,37223,37563,37689,37576,37397,37223,37256,39082,39078,38575,38591,38704,38541,38661,38704,38591,38582,38449,38455,3146,3080,3207,3434,3436,3490,3495,3476,3594,2804,3082,3167,3065,3082,2973,26804,26714,26731,26104,26157,26039,26804,26731,26990,2190,2278,2347,9975,9919,9998,19997,19990,19872,37703,37689,37563,3934,4153,4005,4540,4521,4415,11464,11342,11332,11695,11480,11975,30428,30508,30381,30013,30200,29589,38661,38582,38517,6322,6498,6324,8781,8623,8950,8333,8461,8508,8310,8590,8356,33231,33346,33091,34576,34658,34674,37368,37397,37256,6565,6576,6609,31495,31795,31611,34880,34752,34981,38418,37810,38407,38218,38318,38166,38069,38057,38039,38069,38039,37941,3313,3302,3384,3384,3302,3382,12753,13195,12889,14389,14095,13985,39595,39632,39244,40584,40600,40570,40720,40600,40584,2367,2383,2494,2240,2383,2367,3729,3635,3739,3759,3647,3729,3863,3790,3905,3802,3790,3863,22476,22412,22454,22781,22680,22854,22121,21863,22125,23039,23212,23239,26409,26478,26289,40812,40818,40703,40703,40818,40159,40704,40944,40708,40708,40838,40540,40812,40703,40702,40812,40702,40810,40702,40701,40810,40701,40809,40810,10272,10160,10214,10317,10160,10272,10036,10123,10126,9822,10123,10036,31193,30976,31003,31415,31206,31353,31743,31554,31611,16199,16198,16004,16398,16198,16278,24347,24535,24425,26000,26170,26101,30758,30751,30916,30758,30600,30751,16556,16576,16702,17224,17063,17199,40564,40269,40321,40564,40321,40505,40684,40090,40219,40435,40406,40248,40435,40248,40319,5656,5604,5703,5597,5604,5656,8712,9027,8779,36714,36856,36754,36891,36856,36714,41176,40646,40530,40863,40601,40600,3540,3498,3579,3387,3383,3431,3530,3498,3540,36435,36320,36417,36110,36117,36240,39213,39045,39223,40701,40805,40809,3387,3431,3415,27617,27530,27425,28599,28576,28440,29071,29287,29179,38892,38723,38775,15141,15416,15227,26183,26157,26104,24842,24220,24817,17892,18071,17796,17892,17796,17666,40600,40601,40570,40715,40591,40845,35560,35558,35705,35560,35234,35462,34833,34875,34794,34794,34875,34777,36277,36131,36057,33950,33936,34147,34875,35207,34777,2207,2402,2355,10317,10386,10431,19819,19778,19918,19156,19044,19013,31415,31353,31391,38056,38048,38038,37836,37763,37823,38058,38048,38056,34147,33936,34070,3583,3635,3729,35207,35345,35189,2299,2280,2578,6322,6173,6295,5443,5538,5604,8485,8508,8617,8227,8356,8180,8665,8626,8779,19424,19442,19397,19424,19397,19329,40701,40698,40805,38406,38318,38218,38319,38218,38057,4945,4992,5090,5201,5552,5335,6894,6713,6907,5948,5949,6173,6897,7076,6893,7747,8356,7829,7675,7665,7727,7074,7572,7179,7526,7565,7074,14417,14580,14471,14389,14580,14417,22521,22412,22476,24842,24817,25003,22619,22784,22673,22737,22784,22619,27016,27132,26949,27038,26809,26814,35345,35428,35146,37397,37436,37343,37686,37703,37563,37689,37753,37661,37368,37436,37397,17063,17013,16929,16616,17013,17224,16823,16680,16585,3082,3065,3146,2973,3082,2646,9901,9975,9871,10160,9975,9998,9919,9786,9819,14580,14840,14832,26375,26285,26483,26990,27612,27044,31632,31682,31534,31379,31072,31065,5604,5538,5600,5838,6009,5915,36856,36913,36754,37100,36913,37002,3344,3434,3366,3860,3934,3944,40805,40698,40803,6751,6713,6894,7565,7665,7675,24014,24157,24104,24213,24157,24014,35552,35858,35831,40595,40564,40505,6099,6197,6303,5866,5734,5909,5576,4420,5630,34070,33936,33899,33097,33231,33072,33097,33064,33028,39503,40107,39872,40346,39967,40165,40301,40155,40605,15410,15364,15513,14129,14022,14157,11739,11975,12339,15410,15513,15552,16858,16702,16880,25815,25817,25939,3335,3387,3415,3599,3530,3739,28599,28440,28490,39314,39213,39223,39314,39223,39507,5985,5987,5903,6713,6619,6609,40698,40636,40800,14201,14297,14261,27863,27909,27977,27506,27617,27425,31536,31415,31391,31206,30976,31193,31508,31415,31536,31648,31379,31384,11793,11989,11570,10763,10793,10976,10579,10666,10458,30916,30976,31043,40843,40591,40712,40601,40638,40452,11342,11280,11332,13506,13731,13120,29560,29536,29432,29831,29730,29733,29746,29730,29831,29746,29831,29997,30026,30039,30210,30026,30210,30241,3849,4280,3927,3790,3647,3759,3635,3599,3739,3751,3909,3725,11695,11423,11464,29730,29536,29560,30241,30157,30428,6619,6565,6609,35831,35858,35949,19329,19397,19063,40636,40694,40792,40800,40636,40940,15425,15410,15552,26157,26106,25939,26375,26483,26714,26737,26747,26636,26066,26170,26000,26066,25880,25952,3751,3802,3863,4190,4203,4334,4589,5367,4740,4173,4203,4190,3934,4005,3944,11390,11280,11342,17013,16858,16880,16616,16858,17013,17684,17892,17666,16351,16680,16398,16351,16398,16278,19176,19329,19063,17570,17460,17614,25014,24842,25003,29217,29287,29071,31640,31632,31379,30381,30241,30428,39062,39003,38934,38351,38301,38579,39060,38981,39056,40177,40462,40475,40684,40219,40898,40725,40638,40601,24157,24323,24252,24213,24323,24157,36913,37113,36924,37100,37113,36913,3220,3219,3302,3433,3548,3498,3436,3430,3495,3189,3344,3366,5903,5987,5909,6197,6532,6400,7132,7076,7397,8623,8485,8617,8333,8485,8438,36073,35923,35940,40715,40718,40555,40846,40718,40715,40359,40392,40490,35927,35831,35949,36008,35949,36117,4590,4740,4540,5827,5903,5909,19534,19393,19455,16616,16556,16858,33645,33554,33883,33028,33024,33128,40944,40838,40708,40792,40694,40693,4945,5090,5115,4945,5115,5084,9104,9677,9469,10123,10579,10458,37436,37551,37343,37537,37551,37436,37594,37532,37518,4521,4406,4385,38286,38069,38268,38582,38661,38591,39082,38575,38679,38444,38477,38262,38368,38262,38318,39161,39060,39056,2672,2745,2930,2688,2745,2613,16278,16199,16239,16198,16199,16278,40532,40363,40564,40614,40368,40405,3219,3382,3302,3186,3588,3382,2961,2572,3505,5335,5552,5525,19393,19262,19156,18410,18626,18071,26781,26375,26714,27612,27742,27938,27991,27938,28055,32925,32911,33024,31379,31632,31429,31682,31632,31766,33554,33346,33883,37909,37823,37889,36536,36465,36646,37252,37368,37256,40188,40204,40013,40211,40204,40188,18451,18410,18358,22784,23033,22953,22737,23033,22784,40924,40792,40693,40490,40392,40406,3313,3384,3383,14022,13948,14062,14513,14554,14691,14837,14991,14886,30916,30751,30912,30916,30912,30976,38406,38368,38318,39253,39046,39213,39253,39148,39046,40432,40036,40062,5949,6180,6173,5949,5905,6180,5538,5443,5525,5888,5903,5827,6303,6153,6099,8310,8583,8647,9027,9104,9469,8220,8583,8310,36800,36683,36747,2257,2649,2049,2152,2269,2345,3530,3433,3498,3311,3313,3383,2911,3433,3530,3341,3430,3436,19110,19176,19063,24323,24347,24425,24213,24347,24323,24347,24888,24535,33433,33346,33231,36110,36008,36117,33097,33128,33231,31768,31623,31682,9975,9901,9919,10386,10317,10272,10549,10724,10825,37113,37179,36924,37131,37179,37113,3311,3383,3387,14129,13948,14022,26183,26106,26157,25187,25014,25003,26831,26714,26804,3583,3599,3635,13120,13731,13180,31387,30976,31206,38015,37909,37889,38418,38301,37766,38892,38775,38834,23033,23212,23039,23070,23212,23033,40838,40843,40712,36240,36196,36320,36158,36073,35940,37369,37252,37179,2375,2419,2293,2745,2688,3038,2672,2788,2606,5905,5838,5915,5745,5838,5905,8583,8626,8665,8609,8626,8583,37691,37594,37551,37551,37594,37518,37703,37753,37689,37537,37436,37368,2380,2672,2235,16442,16233,16141,16334,16233,16442,16952,17008,16823,17095,17103,17008,15555,15550,15457,9871,9975,9964,31766,31768,31682,30451,30197,30200,37865,37753,37703,38444,38262,38368,2269,2260,2367,3985,3405,3860,4271,4406,4355,19141,19044,19156,22521,22476,22615,22521,22615,22588,40777,40611,40686,10623,10549,10825,11423,11390,11342,11695,11526,11423,11523,11526,11695,2405,2473,2756,3311,3335,3064,3433,3335,3415,3476,3826,3594,15536,15555,15457,14934,15227,14840,26255,26417,26390,26737,26636,26478,27132,27283,27365,40733,40532,40564,40524,40737,40614,40720,40584,40718,40594,40490,40406,40594,40406,40435,3430,3476,3495,4420,5576,5367,4271,4355,4203,10431,10549,10430,9645,9786,9747,11788,11739,11918,13180,13731,13800,39321,39314,39452,40852,40720,40718,2292,2190,2363,2278,2167,2355,2299,2176,2280,2280,2068,2420,2269,2162,2260,2228,2209,2292,2639,2624,2074,2869,2155,2231,2515,2572,2961,2305,2560,2562,3983,4173,4226,7747,7829,7727,11406,11390,11423,20537,20481,20381,20381,20229,20157,19778,19586,19555,19393,19279,19262,19262,19141,19156,20662,20499,20537,20674,20499,20662,20674,20662,20685,20769,20685,20914,20769,20914,20983,20914,20943,20983,20943,21047,20983,22588,22615,22781,25140,25014,25187,36346,36240,36320,38517,38455,38477,38517,38582,38455,38517,38477,38444,39353,39681,40329,2869,2560,2155,3065,3080,3146,3344,3341,3436,3430,3322,3476,2994,3080,3065,3802,3647,3790,3909,3751,3863,4280,4076,3927,11137,11570,10976,14389,14840,14580,14886,15098,15112,14201,14129,14157,14886,15112,15015,20499,20481,20537,26737,26478,26409,27617,27909,27863,34833,34899,34875,34875,35183,35207,35514,35428,35345,35514,35618,35428,36327,36299,36073,34851,34899,34833,34418,34208,34658,31415,31387,31206,32230,31795,31495,38015,37889,38048,3219,3186,3382,3053,2952,3328,3135,3186,3219,3220,3302,3254,27269,27283,27132,39632,39829,39499,39869,39829,39926,39595,39244,39450,6619,6470,6565,5623,5750,5686,6713,6626,6619,6751,6678,6713,6678,6897,6664,34658,34208,34670,2948,2952,3053,15188,15364,15410,14473,14934,14840,14389,14417,14095,20481,20229,20381,26409,26289,26170,36627,36464,36355,37179,37252,37018,2376,2651,2359,2020,2240,2260,2260,2240,2367,10793,11137,10976,10579,10763,10666,22412,22351,22454,22588,22570,22463,21863,21785,22004,30241,30381,30026,29746,29536,29730,29326,29336,29536,30758,30381,30508,30999,30381,30758,31043,30758,30916,30771,30451,30609,38444,38368,38528,2209,2190,2292,5838,5750,6009,6173,6322,6042,6897,6795,6894,17095,17008,16952,17892,17988,18071,35029,35035,35138,36656,36627,36355,29326,29193,29336,29326,29536,29511,29287,29553,29419,29014,28969,28735,29014,28735,28918,38992,38892,38834,39060,39062,38934,39161,39062,39060,39161,39056,39148,3254,3302,3313,13948,13180,13800,14261,14129,14201,27389,27506,27425,2190,2167,2278,20229,20068,20157,5888,6063,5985,7565,7526,7665,7665,7690,7727,7074,7179,7019,15425,15188,15410,26307,26409,26170,36299,36277,36073,36073,36277,36057,20097,20249,20290,22004,21785,21247,19872,19990,19711,19872,19711,19846,19711,19747,19846,19704,19747,19711,4112,4271,4203,30451,30657,30430,38319,38057,38069,28918,28735,28576,7526,7690,7665,15817,15809,16141,22463,22351,22412,22463,22570,22419,35560,35561,35234,34450,34097,34113,35705,35644,35560,35850,35644,35705,35850,35705,35831,35850,35831,35927,35949,36008,35927,38156,38058,38056,38156,38056,38351,40978,40980,40427,40821,40944,40704,40838,41000,40843,40965,40966,40818,40965,40818,40812,40965,40812,40961,40812,40810,40961,40810,40960,40961,40809,40960,40810,40983,40960,40809,16585,16680,16351,40532,40524,40405,40301,40346,40165,40595,40505,40730,9901,9786,9919,9786,9901,9871,37753,37902,37661,37594,37686,37563,37749,37686,37594,39555,39450,39649,5597,5443,5604,5084,5115,5154,37002,36913,36856,37478,37537,37368,2167,2207,2355,9786,9589,9819,19704,19608,19747,37366,37368,37252,40805,40983,40809,7690,7747,7727,15616,15701,15711,16858,16556,16702,17745,17953,18229,40482,40594,40435,40139,39681,39655,2419,2405,2756,2516,2380,2387,2375,2405,2419,4271,4385,4406,36435,36346,36320,37314,36800,36747,36646,36800,36781,40728,40505,40638,26208,26106,26183,26208,26183,26375,40283,40139,39655,5750,5597,5774,6470,6576,6565,19460,19526,19424,19424,19526,19608,19704,19424,19608,39321,39253,39213,39321,39213,39314,40843,40845,40591,40863,40725,40601,41000,40845,40843,6527,6470,6619,35927,36008,36031,36008,36110,36079,2207,2176,2299,19378,19460,19424,40805,40803,40983,3080,3075,3207,2943,3075,3080,39829,39892,39499,39869,39892,39829,3271,3341,3344,3791,3866,3860,28087,28296,28309,26974,26831,26804,38058,38015,38048,37909,37836,37823,38078,38015,38058,2804,3145,3015,27044,26831,26974,26737,26814,26809,27269,27389,27283,27283,27389,27425,26925,26814,26737,2176,2172,2280,19819,19689,19778,27780,27909,27617,27168,27132,27038,41092,40944,40821,40983,40803,40986,4589,4740,4590,4385,4415,4521,36079,36110,36256,19044,18692,19013,18953,18692,19044,22695,22737,22619,23432,23736,23718,22695,22619,22481,5903,5888,5985,5827,5909,5734,5690,5758,5684,37100,37131,37113,37369,37131,37340,36891,36602,36817,5623,5597,5750,4589,4590,4467,9153,8929,8950,7397,8115,7333,15809,15701,15818,15607,15701,15616,19689,19586,19778,19329,19378,19424,26106,25815,25939,26208,25815,26106,33028,33128,33097,34070,34187,34147,33024,32911,33006,36817,36602,36627,38992,38834,39003,39063,39003,39062,17821,17988,17892,17821,17892,17684,40863,40600,40720,3153,3254,3313,3220,3135,3219,3186,3011,3053,3311,3387,3335,3064,3049,3153,29338,29553,29287,30451,30771,30657,29338,29287,29217,29338,29217,29187,6470,6324,6576,5949,5745,5905,19586,19534,19455,19329,19176,19378,40845,40846,40715,41096,40846,40845,28309,28296,28542,29746,29997,30026,29148,29217,29014,39178,39063,39062,38788,38679,38704,38788,38704,38661,38788,38661,38864,10549,10431,10386,10825,11091,10723,15188,15015,15112,14513,14691,14625,14513,14297,14554,15607,15425,15552,26409,26508,26737,26066,26255,26170,26255,26066,25952,6715,7074,6711,5734,5866,5758,8626,8712,8779,8510,8609,8583,8220,8310,8227,36646,36465,36577,36646,36577,36800,3311,3064,3153,19378,19176,19110,28045,27909,27780,31508,31387,31415,30644,29746,30026,32575,31784,31795,31648,31640,31379,32925,32569,32911,36256,36110,36240,37885,37902,37753,37865,37703,37686,37865,37686,37795,39926,39829,39632,39541,39308,39373,39440,39161,39253,39253,39161,39148,2359,2651,2679,19034,18661,18998,17684,17666,17570,40734,40524,40532,40725,40727,40638,40867,40727,40725,33999,33883,33346,32158,31980,31768,37369,37366,37252,36891,37002,36856,37080,37002,36891,40846,40852,40718,40909,40852,41024,40684,40777,40686,40792,40940,40636,40898,40777,40684,40915,40777,41020,18779,18661,19034,20249,21247,20290,2688,2734,3038,2672,2613,2745,2246,2606,2473,5384,5335,5443,5443,5335,5525,4992,4546,4901,40388,40346,40487,40204,40211,40062,40361,40346,40388,2973,2994,3065,3271,3374,3341,2891,2994,2973,7747,8180,8356,36403,36256,36240,16278,16399,16351,17614,17684,17570,16239,16399,16278,15642,15763,15555,28950,28918,28576,39078,39217,39064,40475,40496,40482,40329,40462,40177,2516,2734,2688,4467,4590,4489,15536,15642,15555,40361,40211,40188,39452,39314,39507,3117,3220,3254,3117,3135,3220,2717,2709,2961,6099,6063,5888,5690,5734,5758,5690,5684,5630,8609,8702,8626,8534,8702,8609,14129,14066,13948,14850,14625,14886,36543,36346,36435,37356,36946,37385,2231,2158,2624,1994,1754,1737,2068,2152,2420,2257,2049,2156,6711,7074,7019,7526,7581,7690,7690,7649,7747,7747,7658,8180,5869,5888,5827,15026,15015,15188,3341,3374,3430,3189,3366,3148,39429,39373,39159,18225,17745,18229,15817,16141,16233,22737,23070,23033,25041,25086,24888,26390,26307,26255,23000,23070,22737,40727,40728,40638,40872,40728,40727,5084,5154,5201,8180,8220,8227,8191,8220,8180,33212,33231,33128,35618,35714,35428,36277,36372,36355,5181,5084,5201,3148,3366,2976,31640,31766,31632,31649,31766,31640,31768,31766,31881,2152,2162,2269,39783,39471,39740,41001,40940,40792,6795,6678,6751,6470,6423,6324,6897,6678,6795,8333,8508,8485,2734,2804,3015,26255,26307,26170,26814,27010,27038,27678,27617,27506,26508,26307,26390,6678,6626,6713,6042,5948,6173,6715,7581,7526,35597,35345,35207,35183,34875,34899,35183,34899,35151,34899,35029,35151,5734,5869,5827,5640,5690,5630,8702,8712,8626,12034,11793,11815,8534,8712,8702,4498,4027,4076,3674,3647,3802,3934,3983,4153,4173,4112,4203,4271,4306,4385,4374,4489,4415,4374,4467,4489,3860,3866,3934,3985,3826,3405,5384,5443,5340,5181,5226,5335,5335,5226,5201,11640,11739,11681,11526,11406,11423,10935,11091,11280,11739,11788,11681,13578,13374,13272,11483,11793,11570,10579,10123,10118,23070,23168,23212,23121,23168,23070,37478,37366,37419,37202,37100,37002,4498,4532,4027,3866,3983,3934,9822,10036,9677,11640,11523,11695,38286,38319,38069,38715,38661,38517,38406,38319,38415,38715,38517,38444,39204,39361,39217,19279,19141,19262,18692,18526,18368,18779,18410,18661,22463,22412,22521,22463,22521,22588,38579,38301,38418,39068,38992,39003,39068,39003,39063,39068,39063,39178,40139,40329,39681,40258,40329,40139,3946,4076,3989,3983,3996,4173,6042,6322,6324,8438,8485,8623,16399,16585,16351,16199,16004,15908,18661,18410,18451,17570,17421,17460,23736,23902,23718,36697,36435,36536,36299,36372,36277,36371,36372,36299,40728,40730,40505,40874,40730,40728,7581,7649,7690,28087,27991,28055,28174,27991,28087,27909,28045,27977,27503,27506,27389,39178,39062,39161,39361,39429,39217,39217,39429,39064,3996,4112,4173,15701,15607,15552,15026,14920,15015,16334,16442,16556,38730,38715,38444,40352,40258,40139,40057,39499,39892,39632,39595,39720,39595,39555,39720,19141,19026,19044,18071,18358,18410,22125,22433,22121,2953,3011,3186,2233,2562,2376,26831,26866,26714,27612,27181,27742,26925,27010,26814,3135,3032,3186,2996,3032,3135,3117,3254,3153,14934,15141,15227,12753,12889,12155,27168,27269,27132,39503,40133,40107,39720,39555,39765,3674,3802,3751,17224,17013,17063,2233,2305,2562,2679,2732,2384,15026,15188,15176,15015,14920,14886,20499,20586,20481,20481,20244,20229,20229,20203,20068,20068,19819,19918,19689,19678,19586,19595,19439,19534,19534,19439,19393,19141,19127,19026,20769,20674,20685,20983,21047,21440,5460,5443,5597,9017,9104,8928,20674,20586,20499,40978,40427,40818,40978,40818,40975,40818,40966,40975,40966,40974,40975,40972,40974,40966,5518,5640,5630,4306,4415,4385,38015,37997,37909,38351,38056,38301,3153,3313,3311,8929,8781,8950,8821,8781,8929,8756,8781,8821,9645,9589,9786,14261,14066,14129,14189,14066,14261,21440,21268,21642,36879,36817,36627,20392,20244,20481,19997,20249,20097,22273,22448,22433,20036,20249,19997,20036,19997,19964,19997,19872,19964,19872,19810,19964,19846,19810,19872,19747,19810,19846,19774,19810,19747,19774,19747,19664,19747,19608,19664,2405,2366,2473,2386,2049,2649,17460,17421,17095,18071,17988,18358,19026,18953,19044,19015,18953,19026,23304,23351,23469,22351,21884,21915,40965,40972,40966,40920,40693,40648,40920,40648,40915,20244,20203,20229,40971,40972,40965,20203,20084,20068,40961,40971,40965,36132,36008,36079,36132,36031,36008,35927,36062,35850,35829,35701,35644,35644,35701,35560,36132,36079,36314,16417,16585,16399,15674,16199,15908,16239,16199,16222,19664,19608,19615,39649,39450,39541,40909,40863,40720,40909,40720,40852,40867,40863,40902,40961,41078,40971,40961,41156,41078,40915,40611,40777,2167,2069,2207,2207,2108,2176,2176,2106,2172,2172,2106,2280,2152,2085,2162,2048,2069,2167,2048,2167,2190,2048,2190,1968,2190,1839,1968,5631,5869,5734,5640,5734,5690,8220,8510,8583,8928,9104,9027,8473,8510,8466,19615,19608,19526,40800,40986,40803,16616,16608,16556,16480,16608,16616,16417,16399,16239,25281,25140,25187,25014,25140,24842,25281,25187,25815,31554,31387,31508,31554,31508,31611,38156,38078,38058,38344,38078,38156,40462,40496,40475,40589,40496,40634,40482,40496,40589,2069,2108,2207,6099,6153,6063,33883,34187,34070,33999,34187,33883,36314,36079,36256,36063,35940,35714,36756,36879,36627,40800,40940,40986,2847,3328,2952,2384,2732,2572,17988,17847,18358,17390,17460,17095,10935,11280,11390,9975,10160,9964,38319,38406,38218,38069,37941,38224,20084,19819,20068,19512,19615,19526,22560,22695,22481,23941,24213,23902,22560,22481,22433,3110,3271,3344,3374,3322,3430,3110,3344,3189,3366,3075,2976,39719,39649,39665,39665,39649,39721,39869,40043,39892,40011,40043,39869,40011,39869,39996,3011,2948,3053,2805,2948,3011,2953,3186,3032,10160,10075,9964,14920,14850,14886,14827,14850,14920,14743,14850,14710,19460,19512,19526,26919,26866,26831,26919,26831,27044,27168,27401,27269,27269,27401,27389,27168,27038,27010,31969,32158,31768,33024,33212,33128,31379,31065,31356,3849,3725,3909,3927,3858,3849,3805,3858,3891,3946,3927,4076,11523,11406,11526,11739,11640,11695,12339,12892,12685,28918,29148,29014,29338,29187,29553,31649,31648,31634,28490,28440,27977,28490,27977,28045,4049,4112,3996,4104,4271,4112,4123,4306,4271,3866,3876,3983,3405,3826,3476,8510,8534,8609,8473,8534,8510,10323,10317,10431,11640,11406,11523,37926,37836,37909,36646,36697,36536,36302,36062,36132,37691,37551,37537,37885,37865,38032,16827,16952,16823,39097,39082,38679,39151,39082,39097,39078,39082,39151,19378,19482,19460,19460,19482,19512,2780,2847,2952,2943,3080,2994,10623,10430,10549,10323,10430,10544,15081,15141,14473,17821,17742,17988,26307,26508,26409,25880,25379,25952,27991,27612,27938,28132,27612,27991,27503,27678,27506,38406,38528,38368,38030,37941,37902,39872,39783,39740,39440,39178,39161,39990,39783,39872,40898,41168,41059,40986,41073,41074,40211,40446,40062,40346,40361,40188,40614,40405,40524,40564,40595,40733,2375,2366,2405,2605,2804,2734,2646,3082,2804,2252,2366,2375,2050,2260,2162,23902,24213,24014,23239,23212,23432,30451,30364,30609,37995,37997,38089,38078,37997,38015,37983,38030,37902,32911,32569,32809,39068,39198,38992,38856,38723,38867,39452,39253,39321,34899,34851,35029,35618,36063,35714,2038,2106,2176,1994,2074,2158,2159,2233,2376,7589,8115,7636,6505,6527,6626,6626,6527,6619,8333,8147,8315,8255,8147,8333,19378,19396,19482,22124,21884,22351,35183,35241,35207,40863,40867,40725,40872,40867,40902,37573,37356,37385,7298,7333,7424,37067,36781,36800,2158,2074,2624,2155,2560,2305,2106,2068,2280,19378,19110,19396,28950,29148,28918,40792,40924,41001,1806,2155,2305,26334,26208,26375,35597,35514,35345,39719,39765,39555,39719,39555,39649,36062,35927,36031,35829,35644,35850,32881,33209,32677,36062,36031,36132,36366,36371,36299,37691,37537,37623,36327,36073,36158,38502,38461,38406,38178,38224,37941,16952,16934,17095,17821,17684,17742,16772,16827,16823,16772,16823,16585,16417,16239,16222,19595,19534,19586,17224,17199,17745,16480,16334,16608,19396,19110,19126,20686,22004,21247,40733,40892,40866,40589,40594,40482,40440,40462,40329,40440,40329,40660,41001,40924,41004,40867,40872,40727,40874,40872,40890,2310,2384,2572,2359,2159,2376,6664,6626,6678,5686,5750,5838,7649,7648,7747,7581,7542,7649,7512,7542,7581,7543,7542,7512,12584,12753,12155,15355,15536,15141,12034,12155,11793,28770,28950,28576,28770,28576,28599,39204,39217,39078,2996,2953,3032,2727,2717,2847,3094,3135,3117,14547,14513,14625,14066,13910,13948,14743,14625,14850,27143,27168,27010,27401,27503,27389,27678,27780,27617,4104,4112,4049,5518,5630,4420,22695,23000,22737,22718,23000,22695,32809,32569,32330,33155,33212,33024,40316,40329,40258,2646,2891,2973,2605,2734,2472,15375,15425,15607,26538,26334,26375,27121,26919,27044,26688,26925,26737,40043,40057,39892,40289,40057,40216,19126,19110,18998,37573,37344,37356,37997,37926,37909,37995,37926,37997,38252,38268,38224,37865,37885,37753,37080,36891,36817,7542,7648,7649,14513,14189,14261,27572,27503,27401,16608,16334,16556,17224,17745,17533,16222,16199,16266,22570,22588,22781,25193,25255,25217,5745,5949,5948,5230,5181,5335,5226,5181,5201,5084,4926,4945,5869,6099,5888,5367,4589,4420,8781,8756,8623,8821,8929,9035,15817,15701,15809,36427,36355,36372,40361,40385,40211,40446,40385,40536,40403,40316,40258,15375,15188,15425,26508,26688,26737,26390,26688,26508,36371,36427,36372,36523,36427,36521,5230,5335,5384,4027,4532,4134,2068,2085,2152,19439,19279,19393,6527,6423,6470,39507,39223,39568,3064,2911,3019,3583,3729,3647,27604,27780,27678,2366,2358,2473,2386,2383,2018,23259,23212,23168,25086,25379,24888,31387,31539,30976,33720,33783,33812,17684,17558,17742,19016,19126,18998,4306,4374,4415,38723,38892,38867,16827,16934,16952,16614,16772,16585,40614,40605,40368,40917,40605,40614,2300,2358,2366,18781,18692,18953,40876,40595,40730,2511,2515,2961,2847,2717,2961,2780,2952,2948,15279,15375,15607,25193,25281,25255,26781,26714,26866,3692,3725,3849,3805,3849,3858,4532,4425,4134,36314,36256,36403,35989,36063,35618,38867,39073,38984,39193,39068,39178,7424,7333,8115,8547,8438,8623,4409,4589,4467,6032,6099,5687,8756,8547,8623,9153,9882,9589,33155,33024,33006,3725,3674,3751,4546,4992,4749,39256,39193,39315,39926,39632,39930,39649,39541,39721,28433,28490,28045,39256,39198,39193,39568,39223,39430,40487,40346,40301,19016,18998,18931,17684,17614,17558,37478,37368,37366,16334,16284,16233,15279,15176,15375,16418,16284,16334,16417,16466,16585,15674,15908,15642,19279,19127,19141,18998,18661,18931,36063,36083,36158,38178,37941,38030,37749,37795,37686,2257,2293,2419,2156,2293,2257,10430,10323,10431,9871,9747,9786,9602,9153,9589,10544,10430,10623,23736,23847,23902,23874,23847,23736,38224,38268,38069,37983,37902,37885,40872,40874,40728,41000,40838,41094,3674,3583,3647,4306,4322,4374,3876,3996,3983,29098,29187,29148,29148,29187,29217,29098,29148,28950,39721,39541,39429,39151,39204,39078,39097,38788,38864,37369,37179,37131,2943,2976,3075,3110,3322,3271,3271,3322,3374,2943,2994,2891,39503,39679,40133,39693,39568,39430,39679,40036,40133,39632,39720,39930,40283,40352,40139,10075,10160,10317,31648,31649,31640,33003,33006,32911,33003,33155,33006,31356,31065,30657,37385,37220,37688,38089,37997,38078,38043,37983,37885,36767,36697,36646,36767,36646,36781,37344,36946,37356,36879,37080,36817,36427,36656,36355,36523,36656,36427,40733,40734,40532,40605,40487,40301,40866,40734,40733,2805,2780,2948,2939,3011,2953,19127,19015,19026,18702,18661,18451,22463,22419,22351,24244,23545,23833,26880,26866,26919,26880,26781,26866,41094,40838,40944,41004,40924,40920,41004,40920,41062,40634,40496,40462,40898,40219,41168,40594,40589,40669,3153,3094,3117,3049,3094,3153,14189,14133,14066,14182,14133,14189,14182,14189,14513,14547,14625,14743,14547,14743,14612,39930,39720,39939,23129,23259,23168,23121,23070,23000,38461,38528,38406,41024,40852,41169,40673,40490,40594,33433,33999,33346,33003,32911,33016,36996,37080,36879,3283,3322,3262,3799,3876,3866,39440,39253,39452,39693,39430,39783,20203,20150,20084,19820,19744,19819,19819,19744,19689,19439,19498,19279,18902,19015,19127,18902,18845,19015,20244,20150,20203,20586,20392,20481,20448,20392,20586,20448,20586,20674,20448,20674,20566,21768,21642,21884,37220,37836,37688,37304,37131,37100,15375,15176,15188,15279,15607,15386,23847,23941,23902,23874,23941,23847,26970,27143,26925,26925,27143,27010,27381,27572,27401,27503,27572,27678,24888,24347,24348,40874,40876,40730,40883,40876,40874,41083,40975,40974,41083,40978,40975,41083,41084,40978,40978,41084,40980,41176,41092,40821,41083,40974,41080,40974,40972,41080,40972,41079,41080,40971,41079,40972,38415,38319,38286,38145,38178,38030,40971,41078,41079,41062,40920,40915,6187,6042,6324,6197,6317,6532,5563,5734,5640,36403,36240,36346,8636,8547,8756,7424,8115,7589,8636,8756,8821,16106,15817,16233,28910,28770,28848,28667,28770,28599,36419,36403,36346,37067,36767,36781,38415,38286,38268,40133,40036,40432,40629,40487,40741,41156,40961,41175,2069,2048,2108,2108,2038,2176,2106,1985,2068,2068,1943,2085,1839,2209,2208,40983,41076,40960,37825,37749,37853,37691,37749,37594,38130,38145,37983,37983,38145,38030,37623,37537,37478,40734,40737,40524,40856,40737,40734,24220,24244,23833,21936,21768,21884,22448,22560,22433,31781,31881,31766,31781,31766,31649,2074,2039,2639,1905,2039,2074,5181,5004,5084,4926,5004,4974,5460,5597,5623,37632,37623,37478,40983,40986,41076,2516,2688,2613,6706,6664,6897,6527,6399,6423,6423,6305,6324,7333,7218,7132,8315,7636,8115,15141,15536,15457,15355,15141,15081,25220,25086,25041,35701,35561,35560,35740,35561,35701,35829,35850,35953,35514,35696,35618,36063,36115,36083,35241,35597,35207,35536,35597,35241,35468,35241,35183,34851,34658,35029,33433,33231,33212,35953,35850,36062,36543,36435,36697,3725,3561,3674,3674,3561,3583,3891,3858,3927,3891,3927,3946,3891,3946,3989,12685,12892,13120,11640,11681,11406,10886,10935,11390,33373,33433,33212,32809,32330,32460,37369,37419,37366,37080,37202,37002,37133,37202,37080,39918,40201,40082,39509,39452,39507,39973,39930,39939,39721,39429,39928,41076,40986,41074,3989,4076,4027,3900,3876,3799,6893,7076,7132,8255,8333,8306,35597,35696,35514,36521,36427,36371,38856,38845,38407,38351,38344,38156,38867,38892,39073,39198,39068,39193,3683,3692,3849,2926,2996,3094,3051,3189,3148,2850,2943,2891,14710,14850,14827,27612,27121,27044,27047,27121,27250,26970,26925,26688,28667,28599,28490,39918,39666,39693,40211,40385,40446,38430,38415,38268,38252,38224,38178,3855,3989,4027,38873,38845,38856,3094,2996,3135,2939,2737,2789,9781,9747,9871,10323,10075,10317,9950,10075,10040,38043,37885,38032,39926,39996,39869,40289,40283,40057,40634,40462,40663,39973,39996,39926,2048,2038,2108,2191,2252,2293,11483,11570,11137,13272,13374,13195,19810,19803,19964,19964,20045,20036,20036,20045,20249,22273,22125,22004,22273,22433,22125,19774,19803,19810,19718,19803,19774,19718,19774,19664,19718,19664,19615,19718,19615,19618,19615,19512,19446,19512,19482,19446,19482,19396,19446,39626,39507,39568,39730,39429,39361,39097,38679,38788,38710,38444,38528,38537,38528,38461,6664,6505,6626,18845,18953,19015,18845,18781,18953,22560,22718,22695,23259,23432,23212,22759,22718,22560,27047,26880,26919,26781,26538,26375,26240,25815,26208,37434,37419,37369,25088,24842,25140,23476,23432,23259,23941,24324,24213,40909,40902,40863,40892,40733,40595,41100,40902,40909,4104,4123,4271,3833,4049,3996,8306,8333,8438,19820,19819,20084,19446,19396,19148,7542,7543,7648,7648,7658,7747,7538,7543,7512,35740,35829,35842,39720,39765,39939,16870,16934,16827,16870,16827,16772,16466,16417,16266,26681,26538,26781,25281,25193,25140,40669,40673,40594,40634,40663,40668,15817,15711,15701,14827,14920,15026,15678,15711,15817,16106,16233,16284,19744,19678,19689,22124,22351,22159,18668,18702,18451,19148,19396,19126,18668,18451,18398,4077,4123,4104,4374,4409,4467,6505,6399,6527,7543,7658,7648,11303,11390,11406,30013,29589,29553,30013,29553,29947,2293,2252,2375,2516,2613,2380,2383,2240,2018,4373,4409,4374,13867,13180,13948,13910,14066,14133,17100,16480,16616,16334,16480,16418,16266,16417,16222,26240,26208,26334,29061,29098,28950,28910,28950,28770,38502,38537,38461,38283,38252,38178,39666,39626,39568,39618,39626,39741,40660,40329,40316,9104,9039,9677,11222,11483,11137,8928,9027,8712,8473,8712,8534,37344,37298,36946,36625,36543,36697,37314,37298,37499,37202,37304,37100,37248,37304,37202,36756,36627,36656,2038,1985,2106,9950,9871,9964,19678,19595,19586,41176,40530,41290,41169,40852,40846,7214,7298,7424,8467,8306,8438,8467,8438,8547,36625,36697,36794,35953,36182,36064,36188,36158,36083,2717,2615,2709,2548,2615,2717,2727,2847,2780,6399,6305,6423,5671,5745,5695,35828,35989,35618,40283,39655,40057,30920,30026,30381,28309,28542,28634,33812,33783,34283,32014,31781,32015,31881,31969,31768,38145,38161,38178,38032,37865,37795,38130,38043,38052,37715,37691,37623,37632,37478,37587,10935,10723,11091,10075,9950,9964,38640,38579,38418,37959,37836,37926,38502,38406,38415,40986,40940,41073,40940,41001,41073,13180,12685,13120,28667,28490,28573,17558,17614,17460,16757,16870,16772,1994,2158,1754,1829,1784,1795,2135,2305,2233,2996,2939,2953,3335,2911,3064,19148,19126,19016,41092,41094,40944,41073,41001,41144,2135,2159,2045,2159,2359,2045,2252,2300,2366,2215,2300,2252,14371,14182,14513,15260,15026,15176,28433,28045,28335,26743,26970,26688,26417,26688,26390,2511,2961,2709,5745,5948,5695,13272,13195,12753,28542,29193,29301,36358,36314,36403,36794,36697,36767,38447,38502,38415,38217,38161,38145,39939,39765,39719,39482,39361,39204,14371,14513,14547,4204,4322,4306,10723,10544,10623,22718,23014,23000,23906,23874,23736,22759,23014,22718,38430,38268,38252,41030,41020,40777,41030,40777,40898,15536,15674,15642,16466,16614,16585,15355,15674,15536,25699,25952,25379,5448,5460,5623,2621,2727,2780,2478,2511,2709,5340,5230,5384,4749,4992,4945,6305,6187,6324,9602,9589,9645,22159,22351,22419,22159,22419,22392,26538,26467,26334,26880,26681,26781,26984,26681,26880,27047,26919,27121,36115,36188,36083,37304,37340,37131,37375,37340,37304,28433,28441,28573,39618,39509,39507,39618,39507,39626,29061,28950,28910,30025,30013,29947,29947,29553,29916,3530,3599,2911,3667,3561,3725,3805,3683,3849,3680,3683,3805,3767,3805,3891,11681,11591,11406,10606,10567,10723,10723,10567,10544,11918,11739,12339,31539,31387,31554,38864,38661,38715,39928,39665,39721,38710,38528,38537,3876,3900,3996,4049,4077,4104,4123,4204,4306,3799,3866,3699,38867,38873,38856,38835,38640,38418,38984,38873,38867,38892,38992,39170,22392,22419,22541,31898,31969,31881,31898,31881,31781,2050,2162,2085,17558,17460,17390,18931,19148,19016,40902,40890,40872,40737,40854,40614,41042,40890,41101,6187,6086,6042,23014,23121,23000,23076,23121,23014,36188,36327,36158,36779,36756,36656,5745,5686,5838,5575,5686,5671,8466,8510,8191,15549,15607,15616,15260,15279,15221,36779,36656,36523,3667,3725,3692,40668,40669,40589,41059,41030,40898,40668,40589,40634,37959,37926,37995,36614,36543,36625,37587,37478,37419,38043,38130,37983,38579,38344,38351,38825,38344,38579,38711,38710,38537,38345,38430,38252,38283,38178,38161,40879,40595,40876,3322,3283,3476,2972,3148,2976,3833,4077,4049,28573,28564,28649,28877,29061,28910,30364,30451,30200,32014,31898,31781,4802,4945,4926,3989,3767,3891,13450,13670,13818,13654,13670,13477,18931,18661,18702,31795,31743,31611,31784,31743,31795,38200,38089,38424,37825,37795,37749,41144,41001,41004,8678,8928,8712,9316,9822,9677,6916,6944,7132,6664,6553,6505,6505,6371,6399,6399,6169,6305,6169,6077,6187,6187,6077,6086,7218,7333,7298,7218,7298,7214,36327,36366,36299,6944,6893,7132,34658,35035,35029,35597,35721,35696,36150,36115,35989,35989,36115,36063,36188,36297,36327,36327,36379,36366,15861,16266,16199,17390,17095,16934,32460,32159,32158,33331,33212,33155,37340,37434,37369,37375,37434,37340,23121,23129,23168,25086,25301,25379,23076,23129,23121,41096,40845,41000,40771,40490,40673,41020,41062,40915,38835,38407,38845,38711,38537,38502,1943,2050,2085,2156,2191,2293,2132,2191,2156,2478,2709,2615,2789,2805,3011,2789,3011,2939,2943,2884,2976,2850,2884,2943,6893,6706,6897,8315,8147,7636,14536,14371,14547,14012,13910,14133,11918,12339,12088,14612,14743,14710,14827,14612,14710,23476,23736,23432,27250,27121,27612,35066,35138,35165,35066,35029,35138,40385,40361,40536,40107,40284,39990,40361,40388,40536,40536,40388,40629,33142,33155,33003,6706,6600,6664,12034,12584,12155,12471,12584,12034,28848,28770,28667,4373,4411,4409,4409,4411,4589,4373,4374,4322,38430,38447,38415,38412,38283,38161,40057,40043,40216,40798,40673,40669,40043,40011,40199,40011,39996,40199,40866,40856,40734,40897,40856,40866,40883,40874,40890,6600,6553,6664,34807,34113,34880,35829,35740,35701,36419,36346,36543,28174,28132,27991,29301,29193,29326,36614,36419,36543,37314,36747,37298,22541,22570,22688,22541,22419,22570,20686,21247,20249,4926,5084,5004,38412,38345,38283,37715,37749,37691,37715,37623,37638,5002,5004,5181,5159,5181,5230,5340,5443,5460,32317,32460,32158,37499,37298,37344,38122,37688,37836,2972,3051,3148,5376,5340,5460,9039,9104,9017,15279,15260,15176,15678,15616,15711,26503,26467,26538,26503,26538,26681,26201,26417,26255,28045,28173,28335,26558,26417,26201,31969,32147,32158,32006,31898,32014,32927,33016,32911,32927,32911,32809,37741,37344,37573,38089,37959,37995,38110,37959,38089,38110,38089,38200,20392,20150,20244,19744,19710,19678,19678,19710,19595,20566,20674,20764,21683,21642,21768,21683,21768,21936,21884,22124,21936,28573,28490,28433,28649,28848,28667,41206,41140,40980,41822,41251,41094,41206,40980,41084,41206,41084,41205,41084,41083,41205,41083,41191,41205,41080,41191,41083,41079,41191,41080,41150,41191,41079,17390,16930,17419,18668,18931,18702,41042,40883,40890,41078,41150,41079,2050,2020,2260,5518,5563,5640,7512,7581,7403,5503,5563,5518,7636,8147,7746,8147,8255,8084,7658,7646,8180,7543,7538,7658,6032,6197,6099,8663,8636,8821,18451,18358,18398,22688,22781,23206,21936,22124,22031,36302,36132,36314,36756,36996,36879,36967,36996,36756,2246,2473,2358,2605,2598,2804,2246,2358,2215,16224,16160,16284,16106,16160,16139,20307,20150,20392,18902,19127,19279,36442,36371,36366,36442,36521,36371,41290,40530,40980,41391,41096,41000,41078,41156,41150,2039,1921,2388,2048,1910,2038,2038,1957,1985,1985,1943,2068,2050,1898,2020,1595,1921,2039,1839,2190,2209,11788,11616,11681,11624,11616,11788,11591,11616,11624,31743,31593,31554,31784,31593,31743,38345,38447,38430,38345,38252,38283,40960,41175,40961,3683,3667,3692,3806,3767,3989,3900,3833,3996,4191,4373,4322,3699,3866,3791,10793,10763,10579,32006,31969,31898,30013,30025,30200,29553,29187,29916,29187,29098,29248,38873,38886,38845,39170,38992,39198,2215,2358,2300,3680,3667,3683,2988,3020,3049,8084,8255,8306,7538,7646,7658,39256,39170,39198,40856,40854,40737,40897,40854,40856,40798,40771,40673,40403,40258,40352,19915,20045,19964,19915,19964,19803,19915,19803,19718,19915,19718,19618,19615,19446,19464,3051,3110,3189,3699,3772,3799,28301,28132,28174,28301,28174,28309,40393,40403,40352,18781,18564,18692,19498,19439,19595,16581,16614,16466,16772,16614,16620,25193,25088,25140,25217,25088,25193,40663,40462,40661,27168,27381,27401,28848,28877,28910,29746,29511,29536,29379,29511,29512,39440,39193,39178,39666,39568,39693,2926,2939,2996,2620,2621,2780,3020,3094,3049,35828,35618,35696,40883,40879,40876,41045,40879,40883,19464,19446,19148,34807,34880,34962,40960,41076,41175,41076,41185,41175,9153,9035,8929,8769,9035,8658,9602,9645,9747,14897,15026,15260,14897,14827,15026,14612,14536,14547,33016,33142,33003,32825,32927,32809,40283,40393,40352,39973,39926,39930,29511,29301,29326,1968,1910,2048,1944,2018,2020,2020,2018,2240,1997,2215,2252,3599,3583,3462,2875,2972,2976,3051,3100,3110,2875,2976,2884,5503,5540,5563,4204,4123,3931,4425,4532,4901,4802,4749,4945,4722,4749,4802,4841,4802,4926,18845,18727,18781,18758,18727,18845,22124,22073,22031,23206,22981,23469,24348,24347,24213,23129,23476,23259,23162,23476,23129,32799,32825,32809,32006,32147,31969,30657,30902,31356,37638,37623,37632,37825,37887,37795,37587,37419,37434,37925,37887,37825,38217,38145,38130,38710,38730,38444,38711,38730,38710,38711,38502,38740,39939,39719,39665,39939,39665,39928,39204,39151,39260,41169,41096,41291,41045,40892,40879,41076,41204,41185,26294,26240,26334,26637,26503,26681,26984,26880,27047,1829,1905,2074,1829,2074,1994,22159,22073,22124,16160,16106,16284,16418,16480,17100,10040,10075,10323,10567,10323,10544,31593,31539,31554,32575,31795,32230,37759,37587,37784,38107,38052,38043,2045,2359,2384,2621,2717,2727,3203,3262,3171,3110,3262,3322,15141,14934,14473,13033,13272,12753,13033,12753,12888,39369,39073,39170,39693,40201,39918,40629,40388,40487,40446,40432,40062,4425,4901,4546,38740,38502,38447,8928,8952,9017,8473,8514,8712,8191,8510,8220,36358,36302,36314,36977,36794,36767,36996,37133,37080,36521,36779,36523,36678,36779,36521,1910,1957,2038,3480,3583,3561,19731,19710,19744,39260,39151,39097,41076,41074,41204,19414,19464,19148,17847,17988,17742,22609,22759,22560,22883,22759,22609,41209,41062,41020,41209,41020,41030,17789,17847,17742,16757,16934,16870,24324,23941,24005,40879,40892,40595,41013,40487,40605,40897,40892,41114,5695,5948,5751,5448,5376,5460,6169,6187,6305,5687,6099,5869,36358,36403,36419,36115,36297,36188,24529,24220,24842,2472,2598,2605,2472,2734,2516,5260,5159,5230,5575,5623,5686,26294,26334,26467,37008,37133,36996,19710,19638,19595,28933,28877,28848,28649,28667,28573,41204,41216,41230,4421,4425,4546,5260,5230,5340,31620,31539,31593,33076,33142,33016,32935,32825,32950,3968,4123,4077,10606,10723,10935,31539,31043,30976,18727,18564,18781,18691,18564,18727,19638,19498,19595,22159,22272,22073,36560,36358,36419,36297,36379,36327,41204,41074,41216,3171,3262,3110,2630,2850,2891,27193,27250,27560,26393,26294,26467,5671,5686,5745,5563,5631,5734,5540,5631,5563,8466,8514,8473,8497,8514,8414,27154,26984,27047,2707,2780,2805,3020,2926,3094,2905,2926,3020,9635,9602,9747,9635,9747,9781,37872,37853,37715,37715,37853,37749,37887,38032,37795,37638,37632,37587,7015,6916,7132,6944,6903,6893,6893,6692,6706,6706,6636,6600,6600,6535,6553,6215,6169,6399,7015,7132,7218,7015,7218,7029,2159,2135,2233,2310,2572,2261,3447,3480,3561,3767,3680,3805,3558,3680,3767,7214,7424,7384,11616,11591,11681,11918,11915,11916,12003,11915,12088,16106,15959,15817,15883,15959,16001,17597,17742,17558,19618,19464,19492,22392,22361,22272,22159,22392,22272,24005,23941,23874,24348,24324,24281,27168,27143,27381,30850,30803,30609,29135,29098,29061,30148,29947,30236,32147,32317,32158,30803,30771,30609,35488,35468,35183,36115,36171,36297,36563,36442,36379,35488,35183,35151,35066,35151,35029,38059,38032,37887,38052,38217,38130,38800,38740,38447,39170,39073,38892,38971,38886,38873,38640,38806,38579,39452,39584,39440,11483,11815,11793,11760,11815,11412,3799,3772,3900,3405,3476,3226,11591,11303,11406,37850,37638,37835,34670,35035,34658,33990,33999,33433,35468,35536,35241,2598,2646,2804,2403,2472,2516,2707,2805,2789,2630,2646,2309,15883,15678,15817,26984,26637,26681,14133,14182,14012,39452,39509,39584,39248,39260,39097,38864,38715,38730,7384,7394,7265,7384,7424,7589,16139,16367,16126,18564,18526,18692,18508,18526,18564,36678,36442,36563,36379,36442,36366,37375,37248,37133,40668,40798,40669,41168,40219,41148,40661,40462,40440,40661,40440,40660,3742,3833,3900,13867,13910,13915,14536,14612,14827,38971,38873,38984,38927,38864,38730,38740,38730,38711,33076,33016,32927,32935,32927,32825,37133,37248,37202,36967,36756,36920,1836,1943,1985,22392,22478,22361,38107,38217,38052,3447,3561,3667,29511,29379,29301,28634,28301,28309,27193,27154,27250,29512,29511,29622,4134,3917,4027,3855,3917,3904,38886,38835,38845,5631,5687,5869,5565,5540,5503,8636,8557,8547,8663,8557,8636,8467,8557,8413,37034,36967,37060,7394,7589,7636,35475,34981,35561,35717,35561,35740,35842,35829,35953,35842,35953,35941,35717,35842,35941,35848,35828,35696,13729,14095,13670,16232,16466,16266,16620,16757,16772,26393,26467,26503,25627,25281,25815,40575,40432,40446,39918,39741,39666,40566,40446,40536,40503,40393,40517,40393,40283,40517,40199,39996,40184,2049,2132,2156,2380,2613,2672,2049,2386,2018,3262,3203,3283,2896,3051,2972,39666,39741,39626,39783,39990,40284,8014,8191,8180,13477,13670,13450,13729,13654,13421,16620,16614,16581,17390,17597,17558,22972,23076,23014,22883,23014,22759,40808,40798,40668,3226,3476,3283,39584,39509,39618,2084,2252,2191,7646,7696,8180,7538,7553,7646,7403,7581,6715,24324,24348,24213,23906,23736,23476,40892,40897,40866,40890,40902,41101,10765,10793,10409,30902,30803,30850,22392,22541,22478,22517,22273,22447,6032,6317,6197,6046,6317,6032,7512,7553,7538,25301,25699,25379,27103,27143,26970,25301,25086,25220,40917,40614,40854,8541,8663,8769,9878,9871,9950,5376,5260,5340,4974,4872,4926,4749,4421,4546,5131,5260,5212,8758,8952,8928,10409,10793,10579,8497,8712,8514,5002,5181,5159,16418,16224,16284,15747,15549,15678,16139,16224,16418,25408,25301,25220,40184,39996,39973,40216,40199,40571,2737,2707,2789,2548,2717,2621,2503,2478,2615,2261,2572,2515,9807,9878,9950,10683,10606,10935,15678,15549,15616,15386,15549,15500,23545,23206,23469,22736,22811,22684,23076,23162,23129,22972,23162,23076,37850,37715,37638,36967,37008,36996,37034,37008,36967,40606,40566,40536,36794,36614,36625,35941,35953,36064,36703,36614,36713,36419,36614,36703,9781,9878,9739,37959,38122,37836,37228,37067,37314,38089,38078,38424,38032,38107,38043,38800,38447,38659,38059,38107,38032,37925,37825,37853,37872,37715,37850,2836,2875,2884,2836,2884,2850,23891,23906,23617,26743,26688,26417,41100,40909,41024,1943,1898,2050,7553,7696,7646,22721,22541,22688,15047,14897,15260,26558,26743,26417,28173,28045,27780,28933,29135,28877,5068,5002,5159,2463,2515,2511,17419,17597,17390,16581,16466,16232,39722,39584,39618,39722,39618,39797,3064,2988,3049,2926,2737,2939,3019,2988,3064,13910,13867,13948,14012,14182,14163,31539,31639,31043,31043,30999,30758,31784,31620,31593,31639,31620,31773,41062,41144,41004,41361,41144,41343,15386,15221,15279,26581,26393,26503,25896,25815,26021,25088,24900,24842,26581,26503,26637,26581,26637,26912,41169,41100,41024,41169,40846,41096,5575,5448,5623,5948,6042,5751,6042,6086,5846,3772,3742,3900,3833,3968,4077,3641,3347,3502,11303,10886,11390,11591,11467,11303,11624,11467,11591,11624,11788,11916,11916,11788,11918,41140,41290,40980,41251,41000,41094,41263,41290,41140,41263,41140,41234,41140,41206,41234,41206,41223,41234,41205,41223,41206,41392,41223,41205,41244,41205,41191,41244,41191,41150,41244,41150,41451,41321,41150,41156,2132,2084,2191,2672,2606,2235,1901,2084,2132,3641,3742,3772,12088,12339,12685,18346,18398,18358,19414,19148,19317,17390,16934,16930,23906,24005,23874,24348,25041,24888,23891,24005,23906,32799,32809,32678,33142,33331,33155,33285,33331,33142,39179,38971,38984,38886,38964,38835,39256,39271,39170,39315,39271,39256,39315,39193,39440,39319,39248,39097,39604,39482,39204,39319,39097,38864,41175,41279,41156,1921,1839,2208,1736,1885,1910,1910,1885,1957,1957,1836,1985,1943,1860,1898,1609,1839,1595,41175,41273,41279,2406,2463,2511,2330,2463,2381,2606,2114,2235,2472,2470,2598,2749,2836,2850,25699,25729,25952,25687,25729,25699,25687,25699,25301,1898,1944,2020,1689,1944,1898,2214,2246,2215,19118,18902,19279,18526,18404,18229,40526,40316,40403,40820,40808,40668,20134,19820,20084,19710,19625,19638,19638,19625,19498,19498,19504,19279,20448,20307,20392,20288,20307,20448,21440,21642,21683,21440,21683,21544,21683,21716,21544,21936,21716,21683,22031,22037,21936,3917,3855,4027,3447,3462,3480,3904,3917,3850,3904,3850,3757,12088,12136,12073,2980,3100,3051,3203,3226,3283,3502,3347,3396,20307,20158,20150,4872,4841,4926,4588,4841,4872,32115,32317,32147,32115,32147,32006,37925,37872,37850,32014,32115,32006,2071,2214,2215,41175,41185,41273,40393,40526,40403,40630,40526,40393,41209,41059,41236,41011,40771,40798,30902,30657,30771,2493,2548,2621,2588,2737,2495,3480,3462,3583,3447,3316,3296,3716,3968,3833,4310,4411,4373,5503,5518,5237,5002,4974,5004,4998,4974,5002,5068,5159,5131,8557,8467,8547,8663,8821,9035,14937,14827,14897,14529,14536,14827,16930,16934,16757,15861,16199,15674,27250,27154,27047,27250,27612,27615,26826,27103,26970,27572,27604,27678,26826,26970,26743,33209,32881,33115,33209,33115,33522,40199,40216,40043,40184,39973,40474,40820,40668,40663,2875,2896,2972,2630,2891,2646,27103,27381,27143,40112,39973,39939,38110,38122,37959,38227,38200,38511,38110,38200,38227,2470,2646,2598,26837,26826,26743,41042,41045,40883,41019,40917,40854,41112,41045,41042,2988,2905,3020,2871,2905,2988,2692,2896,2875,12088,12685,12136,14163,14182,14371,27608,27604,27572,22031,22073,22037,33522,33193,33812,12244,12471,12034,11760,12034,11815,30803,30902,30771,30364,30200,30025,30148,30025,29947,39604,39204,39260,5131,5159,5260,6916,6903,6944,6827,6903,6916,6827,6916,7015,7029,7218,7214,7029,7214,7265,41100,41101,40902,41308,41101,41100,2620,2780,2707,3052,3171,3110,3052,3110,3100,18902,18758,18845,18829,18758,18902,22736,22721,22688,22037,22073,22080,26197,26240,26294,26912,26637,26984,26201,26255,25952,35349,35488,35151,35468,35606,35536,35848,35955,35828,35828,35955,35989,37034,37375,37008,35165,35151,35066,20134,20084,20150,22073,22201,22080,6903,6692,6893,7265,7214,7384,34147,34670,34208,6692,6636,6706,34147,34187,34670,2387,2403,2516,2268,2403,2387,2239,2387,2380,5540,5565,5631,4589,4411,4420,8361,8514,8466,8361,8466,8191,33905,33522,33812,2911,3335,3433,13654,13729,13670,13477,13450,13272,1736,1910,1968,19820,19731,19744,41273,41185,41230,41185,41204,41230,34670,34703,34756,35842,35717,35740,34590,34450,34113,36182,36360,36316,26197,26294,26368,23206,22736,22688,40808,40943,40798,40837,40820,40663,40837,40663,40661,1905,1795,2039,1829,1994,1784,4570,4722,4592,4841,4722,4802,4627,4722,4570,8108,8084,8306,17704,17419,17554,19148,18931,19149,18758,18691,18727,18786,18691,18758,22073,22272,22201,22721,22736,22684,36703,36560,36419,37067,36800,37314,38107,38412,38217,37872,37925,37853,37375,37304,37248,41074,41073,41216,2396,2470,2472,15221,15047,15260,15549,15386,15607,15883,15817,15959,26368,26294,26393,26553,26201,26437,26055,26201,25952,40395,40284,40133,40566,40575,40446,40580,40575,40566,40606,40536,40743,1896,2049,1790,1997,2071,2215,1896,1790,1886,8769,8658,8595,9878,9781,9871,10040,10323,10141,9687,9781,9739,32115,32391,32317,32678,32809,32460,32015,31781,31649,31384,31379,31356,38227,38122,38110,38806,38640,38835,37925,38059,37887,35953,36062,36182,35721,35597,35536,37008,37375,37133,36756,36779,36920,19731,19625,19710,19464,19618,19615,19937,20255,20045,22517,22456,22273,19148,19149,19317,13151,13477,13272,28335,28441,28433,27948,28173,27780,27154,27046,26984,26404,26368,26393,27893,27612,28132,30228,30148,30236,5544,5448,5575,5582,5575,5671,6433,6711,6317,4420,4411,4310,37741,37573,37688,36678,36521,36442,36182,36062,36302,2588,2620,2707,2493,2620,2479,2831,2926,2905,12685,12207,12136,14314,14163,14371,14372,14371,14536,22460,22560,22448,23617,23906,23476,22456,22448,22273,32935,33076,32927,32678,32460,32663,1757,1836,1957,4310,4373,4191,19625,19504,19498,41216,41073,41361,30148,30364,30025,31352,31384,31356,36182,36302,36360,36713,36614,36794,36563,36379,36468,39184,38984,39073,39184,39073,39369,39504,39315,39440,41019,40854,40897,41112,40892,41045,41013,40741,40487,7696,8014,8180,7553,7607,7696,7403,7607,7553,7403,7553,7512,24005,24281,24324,24230,24281,24005,35955,36150,35989,3855,3806,3989,3806,3904,3757,13729,13985,14095,15296,15861,15674,13822,13985,13729,14790,15047,14822,26553,26680,26558,26558,26680,26743,26826,26889,27103,27429,27572,27381,27429,27608,27572,28588,28441,28392,30364,30586,30609,1836,1826,1943,22272,22306,22201,26021,26240,26197,26021,25815,26240,40743,40536,40629,41230,41216,41777,2114,2606,2246,2403,2396,2472,2125,2246,2214,25011,24900,25088,25401,25255,25281,22883,22972,23014,22889,22972,22883,41094,41092,41822,41329,41112,41042,6371,6505,6553,36150,36171,36115,5068,4998,5002,5212,5260,5376,10793,10765,11137,10118,10123,10045,10123,9822,10045,30586,30850,30609,32950,33076,32935,33331,33373,33212,38921,38806,38835,5448,5389,5376,5953,6086,6077,17789,17742,17659,22272,22361,22306,36894,36713,36794,36703,36750,36560,4131,4322,4204,28392,28441,28335,28564,28441,28588,31352,31356,31203,8467,8318,8306,9687,9602,9635,8497,8678,8712,8565,8678,8497,33285,33373,33331,4722,4627,4749,4906,4872,4974,9781,9687,9635,10323,10567,10141,37759,37638,37587,37925,38484,38059,2443,2503,2548,2548,2503,2615,2463,2330,2515,2842,2980,3051,3098,3226,3203,3006,2980,2933,2692,2875,2836,2749,2850,2584,26404,26393,26581,17659,17742,17597,17659,17597,17704,7895,7746,8147,7895,8147,8084,19149,18931,18969,22478,22541,22721,25011,25088,25217,34590,34113,34807,4877,4998,5068,18508,18404,18526,16001,15959,16106,18508,18564,18691,18346,18358,18226,32101,32115,32014,32663,32460,32513,32824,32950,32825,24281,24392,24348,24230,24392,24281,38412,38107,38059,38412,38161,38217,39658,39634,39482,39482,39634,39361,39464,39260,39248,2406,2511,2478,1979,2045,2384,5695,5582,5671,5632,5582,5695,8413,8318,8467,8048,8361,8191,16139,16160,16224,14674,14937,14790,15125,15674,15355,16930,16757,16874,25896,25627,25815,25126,25011,25217,25816,25627,25896,36977,36894,36794,36713,36750,36703,36977,36767,37067,36678,36851,36779,37034,37745,37375,37784,37587,37772,36766,36851,36678,2692,2749,2668,14937,14897,15047,14529,14372,14536,13180,13867,13553,1733,1860,1943,18895,18931,18668,27145,27046,27154,26912,27046,27145,6169,5953,6077,34450,34283,34016,15861,16232,16266,40982,40943,40808,40941,40837,40901,40660,40316,40657,2503,2406,2478,2949,3052,3100,3006,3100,2980,10524,10567,10606,26176,26197,26368,26176,26021,26197,28634,28542,29301,28232,28301,28407,31620,31639,31539,31773,31620,31784,31773,32029,31926,40133,40432,40395,40284,40107,40133,39584,39916,39440,39730,39928,39429,40517,40289,40571,40517,40283,40289,8697,8758,8678,8678,8758,8928,14937,15047,14790,32824,32825,32799,33495,33604,33373,3833,3742,3686,4123,3968,3896,4172,4131,4063,4063,4131,4204,18398,18607,18668,18226,18358,18085,18085,18358,17847,17704,17597,17419,23264,23476,23162,39797,39618,39741,39634,39730,39361,41502,41092,41176,3019,2871,2988,2620,2493,2621,2271,2381,2406,2877,2871,3019,2877,3019,2911,13985,14070,14389,13870,13822,13729,13909,13822,13870,39369,39170,39271,38971,38964,38886,39179,39184,39275,1997,2252,2084,2125,2071,2028,22684,22811,22708,22684,22478,22721,24900,25011,24967,24832,25041,24348,26736,26837,26680,24979,25041,24832,40982,40808,40820,41059,41209,41030,30868,30902,30850,31203,31356,30902,30364,30521,30586,30148,30228,30364,29135,29061,28877,5582,5544,5575,4872,4906,4588,5495,5544,5582,8541,8413,8557,7953,7895,8084,8541,8557,8663,8361,8414,8514,8452,8414,8326,36819,36750,36713,37081,36977,37142,36851,36920,36779,36833,36920,36851,12088,11915,11918,11916,11617,11624,11624,11348,11467,11203,10886,11303,13867,13864,13728,26912,26404,26581,40289,40216,40571,32015,32101,32014,32831,32824,32799,32015,31649,31634,3904,3806,3855,3850,4134,3748,20255,20249,20045,22972,23264,23162,4998,4906,4974,4627,4421,4749,4877,5068,4873,35488,35606,35468,36331,36319,36150,36319,36380,36171,35305,35349,35151,35305,35151,35165,35305,35165,35138,35305,35273,35364,38163,37741,37688,38163,37688,38122,37850,37946,37925,37587,37434,37772,18488,18607,18398,18085,17847,17928,22959,23264,22972,35305,35138,35273,40219,40490,41148,3316,3667,3680,13915,14012,14163,4131,4191,4322,4310,4209,4420,5394,5475,5503,31203,30902,31195,35574,35606,35488,36468,36379,36297,36380,36297,36171,2330,2261,2515,1784,1994,1737,2406,2381,2463,2234,2381,2271,3098,3203,3171,2949,3006,2933,4400,4421,4351,6636,6535,6600,6169,6092,5953,6692,6535,6636,6632,6535,6692,6708,6692,6903,6827,7015,7029,12888,12753,12584,12888,12584,12594,28441,28564,28573,27948,27780,27604,35606,35721,35536,39369,39271,39315,39918,39797,39741,40741,40743,40629,40606,40580,40566,40833,40743,40741,41290,41454,41176,41334,41322,41290,41334,41290,41263,41334,41263,41351,41263,41234,41351,41234,41367,41351,41223,41367,41234,41385,41367,41223,41385,41223,41392,41392,41205,41244,11348,11303,11467,41401,41392,41415,17100,16616,17224,15883,15747,15678,41325,41321,41279,41279,41321,41156,41273,41325,41279,7394,7384,7589,7394,7636,7454,22863,22811,22736,22456,22460,22448,35475,34962,34880,34450,34681,34283,35475,35561,35717,35827,35717,35941,35721,35848,35696,20158,20134,20150,19820,19802,19731,19731,19668,19625,19625,19668,19504,19118,18829,18902,20307,20288,20158,20332,20288,20448,20566,20764,20759,21328,21440,21544,21716,21936,21821,21936,22037,21821,22037,21954,21821,32831,32799,32678,33085,33142,33076,41273,41230,41325,2470,2255,2646,2313,2396,2403,2391,2396,2313,40746,40580,40606,39940,39838,39797,33373,33604,33433,33085,33076,32950,36920,37060,36967,37745,37060,37789,14372,14314,14371,14674,14529,14827,14364,14529,14445,6535,6371,6553,5438,5448,5544,14364,14314,14372,40585,40432,40575,10886,10683,10935,23264,23397,23476,24126,24230,24005,23257,23397,23264,20288,20134,20158,26680,26837,26743,26553,26558,26201,27197,27381,27103,28933,28848,28649,7454,7636,7514,8326,8414,8361,6715,7526,7074,6715,6711,6433,9807,9739,9878,8769,8663,9035,10283,10141,10567,9039,9017,8952,19118,19279,19504,17983,17533,17745,22460,22609,22560,18225,18229,18404,41329,41042,41101,40917,41013,40605,41308,41100,41169,6371,6215,6399,34670,34187,34703,26648,26553,26535,33423,33085,32950,37759,37835,37638,37820,37835,37759,40657,40316,40526,40982,41011,40943,40571,40199,40184,2871,2831,2905,2911,3599,2898,13915,13910,14012,28015,27893,28132,26381,26368,26404,27608,27948,27604,28564,28933,28649,31634,31648,31384,32513,32460,32317,32824,32831,32950,38424,38078,38344,38424,38649,38553,17928,17847,17789,18488,18398,18392,17928,17789,17818,5438,5389,5448,5632,5695,5608,8108,8306,8318,8769,8595,8424,8651,9039,8952,8452,8565,8497,8452,8497,8414,18829,18786,18758,18675,18786,18618,22037,22080,22131,24836,24842,24900,33604,33650,33433,33465,33495,33373,2234,2261,2330,2234,2330,2381,2866,3171,3052,4131,4172,4191,19971,19802,19820,28640,28933,28564,36819,36713,36894,35891,35827,36027,36819,36894,37081,36634,36678,36563,36634,36766,36678,41325,41230,41777,25401,25335,25255,25879,25816,25896,25879,25896,26021,26176,26368,26381,40630,40393,40503,2071,2125,2214,1901,2132,2049,35037,34590,34807,33955,33905,33812,33522,33789,33209,36251,36182,36316,41114,41019,40897,1829,1795,1905,1609,1736,1968,1885,1757,1957,1836,1757,1826,1826,1733,1943,2231,1754,2158,1711,1736,1455,2049,2018,1753,19802,19720,19731,38649,38344,38825,38659,38412,38530,3641,3772,3699,4191,4209,4310,31515,31634,31384,31195,30902,31031,2396,2391,2470,2933,2980,2842,2239,2380,2139,26912,26984,27046,40580,40585,40575,40746,40585,40580,40829,40606,40743,40656,40630,40503,1979,2384,2015,3699,3347,3641,10826,10524,10683,11473,11348,11624,11617,11916,11915,12003,12088,12073,39184,39179,38984,39369,39315,39383,18786,18675,18691,18508,18675,18618,6021,6092,6169,11222,11815,11483,11222,11137,10765,19720,19668,19731,22080,22201,22131,39582,39440,39723,39628,39319,39633,39634,39833,39730,38927,38730,38740,41361,41073,41144,3006,2949,3100,2692,2836,2749,3641,3686,3742,28301,28232,28132,28634,29301,29111,39179,39080,38971,2018,1944,1753,19414,19350,19488,17704,17789,17659,5846,6086,5953,13033,13151,13272,12594,12584,12471,29512,29301,29379,33955,33812,34139,33209,32864,32575,36302,36546,36360,37081,36894,36977,36766,36833,36851,37772,37434,37375,36724,36833,36766,11998,12003,12073,26889,26826,26837,26889,27197,27103,27955,28102,27948,2231,1702,1754,1736,1757,1885,2668,2749,2546,19618,19693,19915,22742,22609,22460,22742,22889,22609,19492,19632,19618,19492,19464,19488,19464,19414,19488,18346,18392,18398,22131,22201,22306,27197,27429,27381,3806,3558,3767,3850,3917,4134,37741,37499,37344,37803,37499,37741,39080,38964,38971,5389,5300,5376,5308,5300,5389,8565,8697,8678,8651,8697,8390,27145,27154,27193,27145,27193,27395,6092,5990,5953,36319,36171,36150,3447,3369,3462,3296,3369,3447,12207,12685,12238,18346,18226,18392,23050,22889,22742,22609,22889,22883,24126,24005,23891,41391,41291,41096,41391,41000,41251,2125,2114,2246,2028,2114,2125,24967,24836,24900,24967,25011,25126,40943,41011,40798,40941,40820,40837,2822,2831,2871,2822,2871,2877,13728,13553,13867,14147,13915,14163,14147,14163,14314,13822,13909,13985,13870,13729,13491,19414,19317,19350,2139,2380,2235,3716,3907,3968,16139,16001,16106,14529,14364,14372,16126,16001,16139,38964,38921,38835,38897,38927,38740,26553,26648,26680,26437,26201,26313,25208,25217,25255,26139,25879,26021,26139,26021,26176,40630,40657,40526,40901,40837,40661,2231,2155,1702,2015,2384,2036,23617,23476,23397,26666,26736,26648,23691,23617,23397,33085,33285,33142,32513,32317,32391,37835,37946,37850,37820,37784,37797,19350,19317,19294,29097,29248,29135,29135,29248,29098,30704,30850,30586,29097,29135,28933,28335,28173,28281,36380,36468,36297,13022,13151,13033,13022,13033,12888,18675,18508,18691,18381,18508,18618,18392,18226,18161,19294,19317,19149,22889,22959,22972,23050,22959,22889,28232,28015,28132,28108,28015,28232,31444,30999,31043,31761,31043,31639,39928,40112,39939,40656,40657,40630,40878,40660,40657,39970,40112,39928,39970,39928,40081,5300,5212,5376,4592,4722,4841,5099,5212,5300,26386,26381,26404,33495,33650,33604,33540,33285,33532,2305,2135,1830,1757,1733,1826,19294,19149,19321,22306,22361,22309,8651,8952,8758,5990,5846,5953,5495,5438,5544,8108,8318,8413,12244,12594,12471,10118,10409,10579,9623,10045,9822,32777,32678,32663,31419,31384,31352,31419,31352,31203,34962,35037,34807,35816,35475,35717,5475,5631,5565,6876,6827,7029,6320,6275,6371,6371,6275,6215,6215,6021,6169,6092,5880,5990,5658,5751,5846,6750,6827,6876,7110,7265,7394,35349,35574,35488,35796,35868,35721,35721,35868,35848,35848,36035,35955,36380,36478,36468,35305,35364,35349,35273,35138,35035,35588,35697,35624,35588,35574,35349,24836,24529,24842,22309,22361,22478,25704,25627,25712,41019,41013,40917,41118,41013,41019,41114,40892,41112,1896,1901,2049,1807,1901,1896,23617,23836,23891,23691,23836,23617,1830,2135,1875,18895,18668,18754,2036,2384,2310,1875,2135,1766,2170,2268,2109,1922,1997,2084,5503,5475,5565,5394,5503,5237,8697,8651,8758,8014,7696,7390,7696,7607,7458,24230,24447,24392,24334,24447,24230,33465,33650,33495,41207,41114,41112,4172,4170,4191,3931,4063,4204,10143,10409,10118,18508,18373,18404,15840,15807,16001,18381,18373,18508,18754,18668,18607,18161,18226,18085,30521,30364,30228,14674,14827,14937,40613,40395,40432,39985,39797,39918,40613,40432,40585,1907,2036,1961,2352,2406,2503,2239,2268,2387,2668,2896,2692,2139,2235,2008,25712,25627,25816,25712,25816,25839,36109,35941,36064,36251,36064,36182,35730,35721,35606,41226,40833,40741,40106,39970,40081,2064,2235,2114,5721,5751,5658,5846,5751,6042,7458,7607,7403,25401,25281,25627,36478,36634,36468,36468,36634,36563,37946,37820,38034,40901,40661,40891,9991,9950,10040,9991,10040,10141,10524,10606,10683,22309,22478,22386,38227,38190,38122,38279,38190,38227,38163,38190,38279,41343,41144,41062,41343,41062,41396,9039,9316,9677,37784,37820,37759,37996,37798,37938,39797,39838,39722,39985,39918,40082,2588,2707,2737,26648,26736,26680,27668,27674,27429,24979,25220,25041,11998,11915,12003,11827,11617,11915,10826,10683,10886,11998,12073,12136,10819,11222,10765,12948,12888,12822,30065,30236,29947,6442,6371,6535,13915,13864,13867,13717,13864,13915,13909,14070,13985,13421,13654,13477,13421,13477,13151,39319,39464,39248,39628,39464,39319,18058,18161,18085,16757,16620,16874,16620,16581,16448,16581,16232,16448,30236,30521,30228,41148,40490,40771,41148,40771,41159,4010,4170,4172,22708,22478,22684,31809,31773,31926,5495,5582,5632,32777,32831,32678,33816,33990,33650,32115,32101,32179,2135,2045,1766,1925,2036,1907,7514,7636,7558,24603,24529,24836,24603,24836,24753,24832,24348,24392,29622,29511,29824,28176,28108,28232,39582,39504,39440,39275,39111,39179,39179,39111,39080,39080,39111,38964,38964,39095,38921,26313,26201,26055,5573,5721,5658,5751,5721,5695,5466,5687,5631,30558,30704,30586,28102,28173,27948,30677,30558,30567,27948,27608,27731,2949,2866,3052,3226,3231,3405,2842,3051,2896,2947,2933,2852,13495,13553,13728,28407,28301,28634,27615,27612,27893,26386,26176,26381,27674,27608,27429,7558,7636,7746,7371,7458,7403,36358,36546,36302,18373,18225,18404,18381,18225,18373,22959,23257,23264,23836,24126,23891,24447,24516,24392,23050,23257,22959,3757,3737,3806,4218,4134,4425,4218,4425,4421,3907,3896,3968,4063,4010,4172,3768,3896,3907,3716,3833,3686,3716,3686,3619,32050,32015,31634,30704,30868,30850,38927,39190,38864,38800,38897,38740,38447,38345,38659,16001,15807,15883,15747,15807,15840,25489,25401,25627,25208,25126,25217,25839,25816,25879,26139,26176,26386,40833,40831,40743,40942,40831,40833,1901,1922,2084,1902,2028,2071,1807,1922,1901,25489,25627,25704,40891,40661,40660,40988,40982,40820,40891,40660,40882,41266,41236,41059,41159,40771,41011,4148,4191,4170,4148,4209,4191,10045,10143,10118,10409,10413,10765,9788,10143,10045,41531,41351,41367,41531,41439,41351,41351,41439,41334,41334,41439,41322,41322,41454,41290,41531,41367,41385,41401,41385,41392,41392,41244,41415,41244,41451,41415,21196,21440,21328,21196,20983,21440,20288,20317,20134,20134,19971,19820,19802,19853,19720,19720,19752,19668,19668,19318,19504,21544,21697,21328,21716,21697,21544,21797,21697,21716,7623,7558,7746,36560,36617,36546,36358,36560,36546,36155,36150,35955,41520,41454,41322,4592,4841,4588,4906,4998,4783,5573,5608,5721,5721,5608,5695,7483,7445,7558,7876,8108,7986,8108,8413,7986,33905,33911,33522,34139,33812,34283,33911,33955,33928,33465,33373,33285,33650,33990,33433,2368,2352,2503,1961,1798,1815,2423,2443,2548,2495,2737,2926,2495,2926,2831,20566,20332,20448,26386,26404,26779,27615,27893,27862,32179,32101,32015,32179,32015,32188,33540,33465,33285,33423,32950,32831,37395,37228,37314,37395,37314,37614,37820,37946,37835,37996,37892,37798,40829,40746,40606,41454,41448,41176,41515,41391,42044,41157,41019,41114,3098,3231,3226,20332,20317,20288,19937,20045,19915,19937,19915,19693,19618,19632,19693,19632,19492,19693,19492,19599,19693,41150,41321,41451,22736,23206,22863,24753,24836,24967,3896,3931,4123,11203,11303,11348,38923,38800,38959,27924,27893,28015,27668,27429,27531,26889,26837,26736,18754,18607,18645,18058,18085,17928,25208,25255,25244,40988,40820,40941,20317,20114,20134,21821,21797,21716,32630,32777,32663,37060,36920,37789,41451,41321,41460,28027,27924,28015,28391,28407,28476,36560,36750,36617,39579,39383,39504,39693,39783,40201,20114,20055,20134,18607,18488,18502,19492,19488,19334,23908,24126,23836,2423,2548,2493,2911,2822,2877,20055,19971,20134,19488,19350,19334,22037,22131,21954,26437,26535,26553,26490,26535,26437,27862,27924,28027,40747,40613,40585,40201,39783,40284,41460,41321,41325,10065,9991,10141,9583,9602,9687,31773,31688,31639,29824,29511,29746,31809,31688,31773,3931,4010,4063,37798,37797,37772,36319,36478,36380,19971,19886,19802,2230,2406,2352,2230,2271,2406,15807,15747,15883,16139,16418,16367,16001,16126,15946,25244,25255,25335,25656,25489,25704,25656,25704,25712,41091,40988,40941,40656,40503,40814,41266,41059,41168,41558,41460,41557,41266,41168,41269,19334,19350,19294,18502,18488,18392,23206,23289,22863,21954,22131,22278,41396,41062,41209,19886,19853,19802,41451,41460,41558,1902,2071,1997,2170,2403,2268,16448,16232,15841,17766,17818,17789,25068,24753,24967,23206,23545,23289,25068,24967,25126,39518,39184,39369,38279,38227,38390,39383,39315,39504,39584,39722,39916,1784,1648,1795,1795,1595,2039,1736,1711,1757,1757,1723,1733,1622,1648,1784,1636,1784,1737,1636,1737,1708,2443,2368,2503,2898,3462,3369,2898,3599,3462,2933,2947,2949,2850,2630,2584,3652,3737,3757,3652,3757,3620,3898,4025,4010,3896,3887,3931,3619,3686,3559,11617,11473,11624,12207,11998,12136,13399,13421,13151,16648,16448,16566,13022,12888,12948,13937,13909,13870,19853,19752,19720,22131,22306,22278,25244,25335,25361,28446,28476,28525,29824,29746,30261,30798,31031,30868,31419,31203,31423,30521,30558,30586,30567,30558,30521,30521,30236,30567,36617,36750,36847,40832,40656,40814,40571,40184,40474,40982,41064,41011,41033,40941,40901,28588,28640,28564,28560,28640,28588,28281,28173,28102,32513,32630,32663,31203,31195,31423,39985,39940,39797,39957,39940,39985,5463,5495,5632,5438,5308,5389,5550,5632,5608,8452,8390,8565,9039,8863,9316,8048,8326,8361,8390,8326,8289,37142,36977,37067,37142,37067,37228,24126,24158,24230,25640,25687,25408,24219,24158,24126,4025,4148,4170,5237,5518,4089,4025,4170,4010,22278,22306,22309,24220,24529,24244,31031,30902,30868,38163,37803,37741,38163,38122,38190,37772,37797,37784,38530,38412,38059,36724,36766,36634,1609,1968,1839,1753,1944,1689,19334,19294,19321,2584,2630,2389,2470,2391,2255,2045,1979,1833,1979,2015,1925,1898,1860,1689,1842,1902,1997,3716,3768,3907,6750,6708,6903,5658,5846,5776,6750,6903,6827,7029,7052,6876,7265,7052,7029,7394,7177,7110,12238,12685,12418,35574,35607,35606,35868,36035,35848,36319,36506,36478,35364,35588,35349,35021,35035,34670,39937,39722,39838,6708,6632,6692,7110,7177,7052,26933,26889,26736,27674,27731,27608,35588,35607,35574,4351,4421,4627,4240,4400,4228,35607,35730,35606,9583,9687,9739,36847,36750,36978,13681,13937,13870,27668,27731,27674,6632,6442,6535,35730,35796,35721,2399,2423,2493,2443,2276,2368,2479,2620,2588,2479,2588,2432,14473,14840,14389,41157,41118,41019,41013,41226,40741,40831,40829,40743,40746,40747,40585,41328,41169,41291,41161,41064,40982,3782,3887,3896,6046,6433,6317,7365,7371,7403,7953,8084,8108,7454,7156,7177,7394,7454,7177,22386,22478,22506,24244,24529,24424,30798,30868,30704,35475,35093,34962,35576,35093,35475,35816,35717,35827,35827,35941,36027,36268,36251,36316,36268,36316,36360,36268,36360,36489,39604,39658,39482,39970,40106,40112,39604,39260,39464,39604,39464,39628,1708,1737,1754,22478,22558,22506,2146,2261,2234,2206,2230,2352,2169,2230,2095,5687,6046,6032,5475,5466,5631,5518,4420,4089,37081,37011,36819,37249,37142,37228,40942,40829,40831,24424,24529,24548,24529,24603,24548,24158,24334,24230,24219,24334,24158,35117,35021,34967,36051,36035,35868,1602,1708,1754,1925,2015,2036,1886,1807,1896,1688,1807,1886,4240,4218,4421,9820,9807,9950,10163,10065,10141,10283,10567,10524,17766,17789,17704,18313,18502,18392,23671,23691,23460,23691,23397,23460,2947,2866,2949,2726,2842,2896,25178,25068,25126,25361,25335,25401,25361,25401,25489,7876,7953,8108,36478,36724,36634,37056,36724,36478,36035,36155,35955,10143,10413,10409,12244,12034,11919,10491,10413,10209,1723,1860,1733,18313,18392,18161,19321,19149,18969,26779,26404,26912,25839,25656,25712,27146,26912,27145,27560,27250,27615,40756,40508,40395,40815,40747,40746,41515,41328,41291,41515,41291,41391,32179,32391,32115,32777,32850,32831,32286,32391,32179,32647,32630,32513,1806,2305,1830,1711,1723,1757,18931,18895,18969,7458,7416,7696,7365,7403,7261,5495,5308,5438,5229,5308,5495,2028,2016,2114,1926,2016,2028,41118,41119,41013,41147,41119,41118,2668,2726,2896,2313,2403,2170,6021,6215,6123,2852,2866,2947,3559,3686,3641,2852,2933,2842,13553,13346,13180,13495,13346,13553,13495,13728,13589,14147,14314,14364,17922,18058,17928,17554,17766,17704,17818,17766,17922,30567,30236,30695,28250,28281,28102,40508,40284,40395,39940,39937,39838,40081,39928,39730,41269,41168,41148,41236,41396,41209,2146,2234,2271,2169,2271,2230,2706,2831,2822,11448,11473,11617,11340,11473,11448,11915,11998,11827,14822,15221,15181,22506,22558,22631,24548,24603,24784,24334,24355,24447,26535,26666,26648,24383,24355,24334,32651,32850,32777,34881,34670,34756,35117,35035,35021,40756,40395,40613,41429,41207,41492,3737,3558,3806,3572,3558,3737,6123,6215,6275,5348,6046,5687,14431,14147,14364,13937,14070,13909,14057,14070,13937,18969,18895,18918,27609,27560,27615,27862,27893,27924,28015,28108,28027,36687,36360,36546,36647,36546,36617,36155,36331,36150,39095,38806,38921,39518,39275,39184,39371,39275,39384,39579,39504,39582,1659,1806,1830,1659,1830,1875,18225,17983,17745,18618,18786,18776,22742,22460,22517,24383,24516,24355,41328,41308,41169,41568,41308,41328,2169,2146,2271,2276,2443,2192,5314,5237,5134,3898,4010,3931,10320,10283,10524,25178,25126,25208,26028,25879,26139,25687,25301,25408,31688,31761,31639,31773,31784,32029,3887,3784,3931,3768,3782,3896,3716,3726,3768,3559,3641,3502,2268,2239,2109,26386,26028,26139,25839,25868,25751,40656,40850,40657,40891,41033,40901,40988,41091,40982,40848,40850,40656,2479,2399,2493,2697,2706,2822,2697,2822,2911,28391,28232,28407,27731,27802,27948,27762,27802,27731,27429,27367,27531,3532,3726,3716,30558,30677,30704,31423,31515,31419,31419,31515,31384,29187,29248,29916,39658,39833,39634,38982,38927,38897,5573,5550,5608,5395,5550,5573,23050,23188,23257,23073,23188,23050,41411,41396,41236,41295,41269,41148,41295,41148,41389,4420,4209,4128,5419,5466,5475,37427,37395,37614,37158,37011,37081,3726,3782,3768,40747,40751,40613,40815,40751,40747,40752,40751,40806,1723,1689,1860,2016,2064,2114,1926,2064,2016,9820,9950,9991,10283,10163,10141,10131,10163,10283,13421,13491,13729,12034,11760,11919,25178,25208,25244,31423,31195,31219,1869,1833,1979,1961,2036,2310,23935,23545,24244,24784,24603,24753,24355,24516,24447,24219,24126,23908,38200,38424,38511,37372,37249,37395,11412,11815,11222,11967,11998,12207,13589,13728,13864,13399,13491,13421,39957,39937,39940,40217,40201,40447,9820,9991,9999,32068,32050,32024,32533,32647,32513,32630,32651,32777,37797,38034,37820,37772,37938,37798,18895,18754,18721,18918,18895,18721,22478,22708,22558,22708,22710,22558,1842,1997,1922,1753,1790,2049,1656,1790,1753,5550,5463,5632,4351,4627,4570,5395,5463,5550,5419,5475,5394,15747,15589,15549,15946,15840,16001,17100,17224,17533,18381,18267,18225,18344,18267,18381,25687,25736,25729,25640,25736,25687,33955,33911,33905,34139,34283,34436,37158,37081,37142,38800,38923,38897,38659,38345,38412,40878,40882,40660,41338,41236,41266,41460,41325,41557,25568,25361,25489,25568,25489,25656,41105,41033,40891,2584,2546,2749,2389,2546,2584,27456,27395,27560,27560,27395,27193,41331,41338,41266,41159,41011,41064,14674,14593,14529,13717,13589,13864,14460,14593,14539,27172,27146,27145,26028,25839,25879,40474,39973,40112,40900,40878,40657,40832,40848,40656,8390,8697,8565,9316,9623,9822,8390,8452,8326,41448,41510,41176,41454,41628,41448,41439,41520,41322,41621,41520,41439,41531,41385,41535,41385,41401,41535,41401,41614,41535,41415,41614,41401,14842,15125,15081,13892,14057,13937,27779,27609,27615,27779,27615,27862,28254,28392,28281,27762,27668,27531,41415,41451,41552,1806,1702,2155,1602,1702,1487,3748,3620,3850,4400,4240,4421,5131,4873,5068,18721,18754,18645,20114,20121,20055,20055,19899,19971,19971,19899,19886,19886,19899,19853,19853,19728,19752,19752,19728,19668,20317,20183,20114,20332,20367,20317,20566,20367,20332,20616,20367,20566,20674,20983,20764,21208,21196,21328,21208,21328,21303,21328,21697,21462,22708,22811,22710,21462,21697,21537,28476,28407,28634,28281,28392,28335,27955,27948,27802,31809,31761,31688,31818,31761,31809,41552,41451,41558,1869,1979,1925,1961,2310,1798,1842,1922,1683,17307,17100,17533,41225,41159,41064,20367,20267,20317,41590,41510,41448,36755,36647,36617,1595,1839,1921,1711,1625,1723,1723,1625,1689,1595,1795,1648,1595,1648,1622,1784,1636,1622,20267,20183,20317,35607,35624,35730,35730,35846,35796,35796,35943,35868,36035,36201,36155,36155,36178,36331,35588,35624,35607,35697,35588,35364,39957,39985,40103,5466,5490,5687,5314,5419,5394,21697,21684,21537,33911,33789,33522,33948,33789,33911,36978,36750,36819,37249,37158,37142,37249,37228,37395,41510,41502,41176,3791,3347,3699,2682,2726,2668,13508,13681,13491,13491,13681,13870,27896,27955,27802,6442,6420,6371,5844,5846,5990,6632,6437,6442,6432,6437,6632,6651,6632,6708,6651,6708,6750,6651,6750,6876,7052,7265,7110,35021,34670,34967,35117,35273,35035,35941,36109,36027,35891,35816,35827,35093,35037,34962,35624,35846,35730,11473,11340,11348,11967,12207,12122,15081,15125,15355,17922,17766,17632,14473,14389,14070,26459,26490,26437,40751,40752,40613,40217,40187,40201,40815,40746,40951,5131,5212,4999,21697,21797,21684,24237,24244,24424,3098,3171,2866,3619,3532,3716,3740,3784,3782,6437,6420,6442,7454,7514,7445,11275,11203,11348,36064,36251,36109,35846,35943,35796,36331,36506,36319,32286,32188,32068,32050,32188,32015,38163,38326,37803,38511,38424,38553,29111,29301,29395,29709,29787,29697,19937,20048,20255,22866,22742,22762,19693,19983,19937,20048,19983,19840,19410,19492,19334,19410,19334,19321,19410,19321,19319,41325,41777,41557,5880,6092,6021,6420,6320,6371,7445,7514,7558,30677,30798,30704,31515,31621,31634,29916,29706,29858,34967,34670,34881,36109,36251,36268,35943,36051,35868,1798,2310,2261,2206,2352,2368,2109,2239,2139,2313,2255,2391,2109,2139,1991,15840,15735,15747,15790,15735,15840,25839,26019,25868,41188,40942,40833,41226,41013,41119,40882,41105,40891,41033,41091,40941,40900,40657,40850,40900,40850,40848,1622,1636,1490,3316,3447,3667,3316,3680,3212,11827,11967,11946,20121,19899,20055,21842,21797,21821,31057,31195,31031,39723,39579,39582,38424,38344,38649,41557,41600,41558,17922,17928,17818,17419,17519,17554,2752,2852,2842,9999,9991,10065,9807,9583,9739,9999,10065,10163,19319,19321,18969,18645,18607,18502,28322,28176,28232,28322,28232,28391,29097,28933,28640,28129,28250,28102,29709,29824,29787,32029,31784,32575,35099,35037,35093,33999,34371,34187,36404,36109,36268,38806,39095,38579,40201,40187,40082,40217,40447,40372,13022,13399,13151,12822,12888,12594,25068,24784,24753,24450,24237,24424,24636,24784,24721,25334,25244,25361,39916,39723,39440,40103,39985,40082,41207,41157,41114,41278,41157,41207,10951,10826,10886,30700,30798,30677,21954,21842,21821,41557,41777,41600,5212,5099,5052,4999,5212,5052,8048,8191,8014,36978,36819,37011,37314,37499,37614,40814,40503,40517,39916,39722,39937,6115,6123,6275,7371,7455,7458,7261,7403,6715,6335,6715,6433,33999,33990,34371,36201,36178,36155,37772,37375,37938,14593,14445,14529,14460,14445,14593,14154,14473,14070,14154,14070,14057,27146,27118,26912,27395,27172,27145,27280,27172,27395,27456,27560,27682,19899,19728,19853,21954,22278,21842,34159,34139,34436,36978,37011,37125,36647,36687,36546,27682,27560,27609,1869,1925,1907,1869,1907,1815,24516,24832,24392,23785,23836,23691,3740,3782,3631,3782,3784,3887,5314,5394,5237,5314,5378,5419,38923,38982,38897,38959,38982,38923,19319,19172,19306,18664,18645,18551,20686,20249,20255,23460,23397,23257,1490,1636,1403,22309,22349,22278,7623,7895,7745,7623,7746,7895,7365,7455,7371,16874,16620,16448,18206,18313,18161,27842,27779,27862,28304,28254,28250,27668,27762,27731,27429,27197,27367,33540,33650,33465,38070,37925,37946,39814,39833,39658,40106,40481,40112,39814,39658,39604,28139,28027,28108,29709,29512,29622,39986,39916,39937,40261,40103,40082,40137,40081,39730,5300,5308,5099,22309,22386,22349,26490,26666,26535,26614,26666,26490,25952,25729,26055,32533,32513,32391,33532,33285,33423,32533,32391,32436,2170,2142,2313,2008,2235,2064,7712,8048,8014,16367,15946,16126,15735,15672,15747,16819,16874,16648,24523,24832,24516,25708,25568,25656,25708,25656,25751,37278,37011,37158,36847,36755,36617,33672,33540,33532,1914,2142,2170,15698,15672,15735,41160,41091,41033,40932,40900,40848,18837,18786,18829,18267,18144,18225,2301,2432,2226,2443,2423,2263,2165,2276,2192,2663,2697,2911,4472,4570,4592,4399,4351,4570,3199,3316,3234,4783,4998,4877,13717,13915,13983,13495,13441,13346,28139,28108,28176,1774,1766,2045,1815,1907,1961,1683,1922,1807,1887,2008,2064,2992,3098,2481,24450,24424,24548,24450,24548,24636,1926,2028,1902,4714,4783,4877,41105,40882,41106,41331,41269,41295,23460,23257,23188,24219,24383,24334,41308,41329,41101,41676,41329,41308,41216,41361,41669,41331,41266,41269,41331,41295,41389,5658,5627,5573,5907,5880,6021,2432,2399,2479,1798,1554,1642,26055,25729,25736,40752,40756,40613,40187,40261,40082,40951,40746,40829,40951,40829,40942,37614,37499,37669,38459,38390,38227,38964,39111,39233,11164,11412,11222,12579,12822,12594,34068,33928,33955,32034,32029,32085,34159,33955,34139,3559,3596,3619,3035,3405,3231,11203,10951,10886,10451,10320,10524,11340,11275,11348,11364,11275,11340,11827,11998,11967,29097,28640,28560,30567,30700,30677,13225,13399,13125,13892,14154,14057,13399,13022,13125,28402,28322,28391,28402,28391,28476,28250,28254,28281,28129,28102,27955,3502,3596,3559,5880,5844,5990,7745,7895,7953,7483,7623,7402,14445,14431,14364,14460,14431,14445,18969,18918,18924,38326,38163,38279,37249,37278,37158,12507,12594,12244,1835,1926,1743,2644,2831,2706,3296,3217,3369,3757,3850,3620,12122,12207,12191,13892,13937,13882,14473,14842,15081,27993,28129,27955,27367,27197,26889,27367,26889,27036,29824,29709,29622,31137,30999,31444,41157,41147,41118,41293,41147,41157,41298,41161,40982,4134,4218,3748,11135,10951,11203,23671,23785,23691,23591,23785,23671,30835,30700,30567,30798,31057,31031,32286,32179,32188,24300,24383,24219,25408,25220,24979,25524,25334,25361,25751,25656,25839,25408,24979,24814,1053,1625,999,1510,1656,1283,1790,1688,1886,18918,18721,18865,18924,18918,18865,22742,23073,23050,23068,23073,22742,4656,4588,4906,32647,32651,32630,32286,32463,32379,3199,3217,3296,12685,13180,12418,2697,2644,2706,2663,2644,2697,28027,27842,27862,27779,27682,27609,27280,27118,27172,25839,26028,26019,27859,27842,27940,31621,31515,31423,40799,40756,40752,15672,15589,15747,15679,15589,15672,25777,26055,25736,26313,26459,26437,5844,5776,5846,34218,34371,33990,2008,1991,2139,2109,2056,2170,1958,1991,2008,25524,25361,25568,5419,5378,5466,6036,6335,6433,4209,4060,4128,8390,8378,8651,8651,8863,9039,10413,10491,10765,8048,8239,8326,8259,8239,8048,37798,37892,37797,37893,37960,37938,22349,22386,22441,22386,22506,22441,31926,31818,31809,33843,33209,33789,13190,13180,13346,35988,35891,36027,35988,35816,35891,35988,35576,35816,35816,35576,35475,34681,34450,34590,35988,36027,36109,1774,2045,1833,1702,1602,1754,1774,1654,1668,2111,2313,2142,2111,2255,2313,2535,2682,2668,2726,2610,2842,13589,13586,13495,13717,13586,13589,13412,13491,13399,13412,13508,13491,18618,18344,18381,15651,15790,15826,18246,18344,18622,18206,18161,18058,18206,18106,18252,23785,23908,23836,23778,23908,23785,26287,26459,26313,28453,28139,28322,28322,28139,28176,27993,27955,27896,28560,28588,28392,40201,40284,40447,39964,39937,39957,41389,41148,41159,41638,41558,41600,30962,31057,30798,36721,36755,36827,36755,36847,37004,35944,35970,35846,35846,35970,35943,35943,35970,36051,36051,36201,36035,35579,35697,35364,35117,35289,35273,35125,35289,35117,35125,35117,34967,35125,34967,35008,34967,34881,35008,36178,36506,36331,35944,35846,35624,4999,4873,5131,4783,4656,4906,4962,4873,4999,22441,22506,22631,24636,24548,24784,24383,24523,24516,24377,24523,24383,1487,1702,1499,19318,19118,19504,22811,22814,22710,6036,6433,6046,7345,7416,7455,6634,6651,6876,6297,6320,6420,6181,6115,6320,6320,6115,6275,6123,5974,6021,5880,5803,5844,5844,5659,5776,7177,7023,7052,7156,7023,7177,7156,7454,7213,5378,5490,5466,4209,4148,4060,8239,8289,8326,8259,8289,8239,13225,13412,13399,12302,12507,12244,28560,28392,28481,33540,33816,33650,33672,33816,33540,39964,39957,40276,39723,39728,39579,39233,39111,39371,39111,39275,39371,38459,38227,38511,15589,15500,15549,15946,15790,15840,15698,15790,15651,27118,27146,27172,25708,25524,25568,24721,24784,24874,35008,34881,34756,27467,27507,27669,27901,27896,27762,10451,10524,10826,31057,31219,31195,1656,1753,1283,1835,2064,1926,18865,18721,18664,18206,18058,18106,23289,23545,23628,23935,24244,24136,27280,27395,27446,27682,27779,27761,5776,5627,5658,5510,5627,5776,26448,26287,26238,26493,26614,26459,24814,24979,24832,2276,2206,2368,2165,2206,2276,4351,4228,4400,4588,4472,4592,4417,4472,4588,13441,13190,13346,15503,15500,15589,27761,27779,27842,28446,28402,28476,27859,27761,27842,32627,32651,32647,32379,32436,32391,32379,32391,32286,40081,40143,40106,40571,40814,40517,40832,40932,40848,40355,40143,40081,40815,40806,40751,40987,40951,40942,1766,1659,1875,1674,1774,1668,6432,6420,6437,17519,17419,17215,24136,24244,24237,36317,36201,36051,4746,4656,4783,32627,32647,32533,37892,38034,37797,37996,38034,37892,38459,38511,38701,4714,4746,4783,5099,5308,5142,20764,20983,21196,20367,20308,20267,20267,20308,20183,20183,20121,20114,19899,19832,19728,19728,19318,19668,20764,21196,21095,21196,21208,21095,21208,21236,21095,21303,21236,21208,21303,21328,21462,21303,21462,21363,21462,21537,21586,21537,21684,21586,37417,37372,37395,37669,37499,37901,41701,41621,41531,41531,41621,41439,41520,41628,41454,41510,41617,41502,41502,41738,41092,41701,41531,41688,41614,41415,41552,41614,41552,41638,41552,41558,41638,21586,21684,21751,39986,40378,40079,41621,41664,41520,41664,41628,41520,2131,2146,2169,18721,18645,18664,24165,24136,24237,24784,25068,24874,29916,29918,29947,31142,31167,31057,31057,31167,31219,30041,29918,29858,41188,41122,40942,41339,41278,41207,10199,10283,10320,11275,11135,11203,11364,11135,11275,11448,11617,11827,11946,11967,12122,41628,41590,41448,2852,2752,2866,2499,2668,2546,13586,13441,13495,13983,13915,14147,13983,14147,14099,20282,20308,20367,34606,34187,34371,34606,34703,34187,33285,33085,33423,37417,37395,37427,41590,41617,41510,39833,40137,39730,39633,39319,38864,39685,39628,39633,3834,4148,4025,3596,3532,3619,3403,3532,3596,3396,3596,3502,3066,3231,3098,18344,18144,18267,18246,18144,18344,31219,31448,31423,31481,31448,31432,33928,33948,33911,34681,34590,35037,39728,39723,39776,39728,39383,39579,21751,21684,21797,41343,41702,41643,4140,4228,4351,40958,40806,40815,40790,40761,40508,41189,40814,41340,41106,40882,40878,41375,41225,41161,5976,5974,6123,7455,7416,7458,7261,7455,7365,20308,20121,20183,21842,21751,21797,41617,41637,41502,12123,11946,12122,12191,12207,12238,11727,11919,11760,39776,39723,39898,39628,39713,39604,3652,3572,3737,3316,3199,3296,3748,4218,4071,19118,18837,18829,19078,18837,19118,18645,18502,18551,19983,20048,19937,19840,19983,19693,19599,19492,19452,19492,19410,19452,19410,19306,19452,21842,22278,21751,24427,24237,24450,23935,23628,23545,41411,41236,41338,41336,41389,41159,41225,41064,41161,2095,2131,2169,14539,14593,14674,15790,15698,15735,15679,15698,15651,25507,25524,25708,26019,26028,26386,2610,2752,2842,12128,12191,12238,13336,13441,13586,13022,12949,13125,13882,13937,13681,12579,12594,12507,41411,41338,41436,25373,25524,25507,5974,5907,6021,7623,7483,7558,8413,8252,7986,8541,8252,8413,35099,34681,35037,34606,34614,34655,36201,36506,36178,12418,13180,13190,39825,39814,39604,18144,18014,18225,18117,18014,18144,20121,19927,19899,23171,23460,23188,24741,24814,24523,23171,23188,23073,34159,34068,33955,33948,34068,34227,39233,39095,38964,38349,38279,38390,41436,41338,41331,41669,41361,41643,5052,4962,4999,4954,4962,5052,5495,5463,5229,25178,25244,25334,24636,24427,24450,41298,40982,41091,18837,18776,18786,18690,18776,18715,22814,22811,22863,21751,22278,22434,22814,22863,22856,31481,31621,31423,31481,31423,31448,37582,37417,37427,36721,36647,36755,37582,37427,37614,40814,40932,40832,42044,41391,41251,41339,41293,41278,14790,14822,14709,13354,13336,13586,33423,32831,32850,32587,32627,32533,32068,32188,32050,38349,38326,38279,38511,38553,38701,4656,4534,4588,4472,4408,4570,4563,4534,4656,19927,19832,19899,22278,22349,22457,27367,27467,27531,28304,28481,28254,26933,26736,26666,32587,32533,32436,38034,38070,37946,38659,38959,38800,38067,38070,38034,1970,2056,2109,1835,1887,2064,1926,1902,1743,25373,25178,25334,5907,5803,5880,34703,34606,34655,2992,3066,3098,12424,12418,12667,14539,14790,14699,14257,14147,14431,13882,13681,13723,14154,14310,14473,17419,16930,17215,27842,28027,27940,27446,27395,27456,26246,26019,26278,38699,38553,38649,40481,40474,40112,41105,41106,41479,40481,40106,40438,4071,4218,4240,30835,30798,30700,39094,38959,39235,4714,4877,4873,19410,19319,19306,18551,18502,18535,18502,18427,18535,22457,22349,22441,22856,22863,23289,28402,28448,28322,28525,28476,28634,1674,1659,1766,1674,1766,1774,1656,1688,1790,1587,1688,1656,18014,17983,18225,18039,17983,18014,23460,23591,23671,24523,24814,24832,23597,23591,23460,1622,1490,1595,1205,1455,1609,1609,1455,1736,1403,1636,1415,1636,1708,1415,22457,22441,22631,36721,36687,36647,36847,36978,37004,26459,26614,26490,26287,26313,26055,40934,40799,40806,40806,40799,40752,40793,40799,40934,2644,2495,2831,2263,2423,2399,2206,2095,2230,2492,2663,2532,3120,3369,3217,27896,27802,27762,30041,30065,29918,12503,12579,12507,13723,13681,13508,39964,39986,39937,40276,39957,40103,40358,40187,40217,41106,40878,40900,3898,3931,3719,18969,19172,19319,32034,31818,31926,32034,31926,32029,38737,38699,38649,4962,4794,4873,5229,5463,5234,15698,15679,15672,15651,15826,15546,25178,24874,25068,24440,24427,24636,22923,22856,23004,24300,24219,23908,25777,25736,25640,41278,41293,41157,41339,41207,41429,3740,3931,3784,8681,8863,8651,12112,12027,11970,8319,8390,8289,18969,18924,19172,18502,18313,18427,22631,22558,22710,23628,23935,23859,3347,3791,3235,3631,3782,3567,11664,11448,11827,10199,10320,10245,11364,11448,11664,11827,11946,11811,17726,17307,17533,23778,24300,23908,29918,30065,29947,29918,29916,29858,34681,34436,34283,37278,37249,37372,6855,6876,7052,6115,6098,6123,5974,5976,5907,5907,5860,5803,6548,6651,6634,35579,35364,35273,35970,36317,36051,36201,36317,36506,35401,35273,35289,35401,35289,35445,35401,35445,35593,23859,23935,23949,39518,39369,39383,39342,39173,39095,38953,38825,38579,39518,39383,39728,41643,41361,41343,41461,41436,41331,41461,41331,41389,2263,2399,2266,1798,2261,1554,25777,25640,25408,8143,8259,7807,37205,37278,37444,37278,37372,37444,6367,6432,6632,35008,34756,34895,35806,35944,35624,3234,3316,3212,3572,3652,3620,3470,3572,3620,18924,19092,19172,29709,29697,29512,29787,29971,29868,37765,37669,37901,38459,38349,38390,38333,38349,38495,2309,2389,2630,2682,2610,2726,2309,2646,2255,6432,6297,6420,14460,14410,14431,14539,14410,14460,14539,14674,14790,18427,18313,18252,18924,18865,18811,27522,27456,27682,27522,27682,27761,36489,36360,36687,36404,35988,36109,35576,35099,35093,34681,34750,34436,2491,2495,2644,2389,2499,2546,2945,2550,2694,10199,10131,10283,10826,10951,10552,27859,27522,27761,31432,31448,31219,32024,32050,31634,31601,31481,31719,38495,38349,38459,38953,38579,39095,6297,6209,6320,3199,3120,3217,12027,11919,11970,11919,12027,12244,29697,29488,29512,39898,39723,39916,39814,39917,39833,39713,39825,39604,39772,39825,39713,39685,39713,39628,38484,38530,38059,2554,2644,2663,2554,2569,2644,13983,13795,13717,13441,13267,13190,13965,13795,13983,13892,13976,14154,17519,17632,17554,13723,13508,13554,12948,12793,13022,27940,28139,28063,27940,28027,28139,1970,2109,1991,1958,2008,1887,6209,6181,6320,5395,5573,5627,7213,7454,7445,24440,24636,24721,24300,24377,24383,26132,25777,26094,24741,24377,24454,2266,2399,2432,2164,2309,2255,40799,40793,40756,40958,40815,40970,2063,2095,2206,1774,1833,1654,2063,2206,2165,5659,5844,5803,4399,4354,4257,8259,8319,8289,8143,8319,8259,25507,25708,25703,25524,25373,25334,25178,25209,24874,24440,24165,24427,26779,26912,27118,18865,18801,18811,18252,18313,18206,22866,23068,22742,23591,23597,23785,19524,19318,19728,18622,18344,18618,18664,18801,18865,1866,1958,1887,3782,3726,3567,3834,4060,4148,10154,10413,10143,12154,12302,12244,40004,39916,39986,40004,39898,39916,41146,41160,41033,41324,41336,41159,41146,41033,41105,6181,6098,6115,7201,7213,7445,7402,7445,7483,7416,7390,7696,7191,7261,6519,34895,34756,34792,34756,34703,34792,9732,9807,9820,28857,28525,28634,28481,28392,28254,37009,37004,36978,36474,36489,36841,2581,2610,2682,3834,4025,3898,4013,5134,5237,10131,9999,10163,9983,9999,10131,40761,40284,40508,18664,18551,18801,41343,41827,41702,6098,5976,6123,7261,7345,7455,34792,34703,34655,40970,40815,40951,1833,1869,1654,1499,1702,1806,4228,4071,4240,3513,3470,3620,4417,4408,4472,4417,4588,4534,5062,5052,5099,17554,17632,17766,16930,16874,16819,22923,22814,22856,23949,23935,24136,12302,12503,12507,23068,23171,23073,22935,23171,23068,29395,29301,29512,38382,37803,38326,37205,37125,37011,1776,1902,1842,41342,41298,41091,41324,41159,41225,41616,41396,41411,9168,9623,9316,9168,9316,8863,5229,5142,5308,5101,5142,5229,4052,4420,4128,5297,5490,5378,6335,6238,6715,5297,5378,5314,7876,7745,7953,8252,8541,8403,8319,8378,8390,8143,8378,8319,7345,7390,7416,19318,19078,19118,17983,17868,17533,34606,34371,34614,36827,36687,36721,26055,25777,26132,41250,41106,40900,41452,41375,41298,41512,41538,41405,14410,14257,14431,15047,15221,14822,40790,40508,40756,40790,40756,40793,13336,13267,13441,12123,12122,12191,13586,13717,13597,12948,12822,12793,40358,40261,40187,40276,40261,40358,2499,2535,2668,2393,2535,2499,2393,2499,2389,3474,3726,3532,3235,3791,3405,3035,3231,3066,11448,11364,11340,12128,12238,12418,25708,25751,25703,24427,24165,24237,39371,39346,39233,39742,39518,39980,39533,39518,39742,41479,41146,41105,10917,11164,11222,12027,12154,12244,12368,12484,12503,1914,2111,2142,2338,2393,2238,1914,2170,2056,1970,1991,1958,5976,5860,5907,15679,15503,15589,15651,15503,15679,18690,18618,18776,18801,18551,18491,18106,18058,18068,33922,33816,33873,34614,34371,34545,40923,40790,40793,41122,40987,40942,3743,3898,3719,3743,3834,3898,10451,10826,10552,22631,22710,22814,22631,22814,22923,2263,2192,2443,2267,2266,2432,2267,2432,2301,40934,40806,40958,1499,1806,1505,1654,1869,1673,39384,39346,39371,41482,41461,41389,2492,2554,2663,3199,3149,3120,3212,3680,3558,29697,29630,29488,29488,29395,29512,30920,30381,30999,39825,39917,39814,39190,38927,38982,39190,38982,39175,2898,3369,3120,2569,2491,2644,2992,3035,3066,2475,2561,2682,5330,5395,5407,27480,27446,27522,27312,27175,27280,25373,25507,25437,28448,28402,28446,28448,28446,28525,28304,28250,28129,27669,27762,27531,28041,27896,27901,26933,26666,26614,26493,26459,26287,36906,36827,36755,37205,37011,37278,20759,20616,20566,20308,20282,20121,20121,20060,19927,19927,19917,19832,19832,19769,19728,19318,19000,19078,20798,20616,20759,20798,20759,20764,20798,20764,20847,20764,20922,20847,21095,20922,20764,21155,20922,21095,21155,21095,21236,20534,20686,20255,20283,20255,20193,20255,20048,20193,20048,20092,20193,19906,20092,20048,30780,30835,30567,30780,30567,30695,41590,41695,41617,41617,41695,41637,41637,41742,41502,41912,41795,41590,41664,41724,41628,41621,41724,41664,41701,41724,41621,41531,41535,41688,41535,41614,41688,41614,42037,41688,41688,41863,41761,1637,1776,1842,1835,1866,1887,21303,21155,21236,41293,41315,41147,41207,41112,41492,41495,41482,41389,41375,41324,41225,41375,41161,41298,21303,21363,21155,29722,29630,29697,28678,28448,28525,33423,32850,32827,32827,32651,32627,32463,32436,32379,34218,33990,33922,41486,41411,41436,41701,41688,41761,21462,21586,21363,42037,41863,41688,2075,2164,2255,26448,26493,26287,20616,20282,20367,19767,19840,19693,18246,18117,18144,16367,16418,17100,18039,18117,18246,18551,18535,18491,18068,18058,17922,19599,19767,19693,41795,41695,41590,41437,41315,41339,4408,4399,4570,4563,4656,4746,31481,31601,31621,30860,30962,30798,38349,38333,38326,38701,38553,38699,38701,38699,38737,39094,38982,38959,31258,31219,31167,1205,1609,1595,1510,1587,1656,1589,1683,1807,2685,2694,2550,12214,12128,12418,12793,12822,12579,12112,12154,12027,19599,19683,19767,21363,21586,21273,29477,29395,29488,39969,39917,39825,1572,1807,1688,16874,16448,16648,17923,18068,17922,1806,1520,1505,1490,1469,1595,18535,18427,18491,19599,19600,19683,22856,23105,23004,21155,21363,21283,5138,6036,6046,5134,5297,5314,5322,5297,5243,20161,20060,20121,34227,34068,34159,34068,33948,33928,34227,34159,34421,36906,36755,37004,37516,37372,37417,37582,37614,37676,38070,38484,37925,39143,39094,39235,37375,37893,37938,41695,41742,41637,9999,9732,9820,9983,9732,9999,24440,24721,24504,25703,25751,25868,27175,27118,27280,31820,31634,31621,20060,19942,19927,22434,22278,22457,10062,9983,10131,10552,10951,10616,30962,31142,31057,39175,39094,39143,40987,40970,40951,41153,40970,40987,6651,6548,6632,6432,6223,6297,6297,6223,6209,6142,6024,6181,6181,6024,6098,6098,5958,5976,5976,5732,5860,6855,7052,7023,6855,7023,6851,6855,6851,6746,14233,14257,14410,14099,14257,14233,18491,18427,18376,17923,17922,17632,27446,27456,27522,28063,27522,27859,2261,2146,1812,1673,1798,1642,2550,2945,2992,39898,40029,39776,40079,40004,39986,35697,35806,35624,36141,36317,35970,38193,38067,37996,35401,35579,35273,35593,35579,35401,35281,35125,35186,34975,35008,34895,34975,34895,34792,34975,34792,34846,35704,35806,35697,41742,41738,41502,5041,5062,5099,4961,5062,5041,37676,37614,37669,6548,6367,6632,19452,19454,19599,17999,18252,18106,35806,35911,35944,1804,1866,1835,2111,2075,2255,1743,1902,1776,7750,7745,7876,7750,7876,7672,36906,37004,37009,2160,2192,2263,2432,2588,2226,2431,2491,2569,2435,2491,2431,4855,4794,4962,13882,13976,13892,13723,13976,13882,13508,13412,13325,15221,15386,15181,26759,26933,26614,1403,1469,1490,6953,7156,7213,19306,19454,19452,4036,4071,4228,3215,3212,3558,12793,12579,12484,28988,28634,29111,27333,27312,27446,29330,29248,29097,28123,28129,27993,28041,27993,27896,31711,31820,31621,31711,31621,31601,40261,40276,40103,40358,40217,40372,1590,1659,1674,1673,1869,1815,24440,24504,24366,23356,23289,23447,5292,5322,5243,3670,4052,4060,3719,3931,3740,10451,10245,10320,19306,19382,19454,29134,28988,29111,2160,2263,2266,2561,2581,2682,2418,2581,2561,2475,2682,2535,18715,18776,18837,19000,18837,19078,27669,27531,27467,41009,40761,40790,40460,40447,40563,40563,40447,40765,41002,40934,41127,1753,1100,1283,1706,1743,1776,17660,17923,17632,18979,18811,18746,23402,23597,23460,26238,26055,26132,23402,23460,23171,41577,41486,41436,41577,41436,41729,1415,1708,1602,19306,19172,19229,37009,36978,37137,36978,37125,37137,29916,29248,29706,30835,30860,30798,31111,31258,31142,1861,1970,1958,9732,9583,9807,9083,9583,9732,4667,4563,4746,4154,4140,4351,6142,6181,6209,5407,5395,5627,4961,4954,5062,5348,5687,5490,7277,7363,7345,7345,7363,7390,8794,9168,8863,9623,9788,10045,14769,14699,14709,16367,17100,16623,35023,36269,35143,35099,35576,36430,36404,36268,36489,36404,36489,36474,37996,38067,38034,36833,36724,37056,39533,39384,39275,39376,39095,39233,39533,39275,39518,1637,1842,1683,1570,1861,1958,3215,3558,3275,3234,3149,3199,16975,16819,16648,17600,17660,17632,29706,29248,29513,41339,41315,41293,41592,41328,41515,41495,41389,41336,41416,41375,41452,41324,41375,41416,4794,4714,4873,5062,4954,5052,4855,4954,4908,8378,8681,8651,8794,8681,8491,37237,37125,37205,37765,37676,37669,1590,1674,1616,1430,1415,1602,18690,18622,18618,16623,17100,17045,18623,18622,18690,22631,22504,22457,23717,23628,23859,22517,22460,22456,42362,41592,41515,3028,3149,3234,6024,5958,6098,29513,29248,29330,34846,34792,34655,34846,34655,34816,36489,36687,36841,39685,39772,39713,40438,40106,40143,39969,39772,39685,39969,39685,40414,17868,17983,17946,1565,1637,1683,2196,2389,2309,1900,2075,2111,4036,4140,4039,4071,3980,3748,9502,9788,9623,11293,11412,11164,12424,12214,12418,13597,13717,13795,29330,29269,29439,28123,28304,28129,31137,30920,30999,32085,32029,32864,31820,32024,31634,32068,32463,32286,31931,32024,31820,38333,38409,38326,38737,38649,38894,40460,40358,40372,40079,40029,40004,4732,4714,4794,13986,14154,13976,12484,12579,12503,37056,36478,36506,33922,33990,33816,34371,34218,34404,36901,36687,36827,37137,37125,37237,1587,1572,1688,1516,1572,1587,18039,18014,18117,23862,23717,23859,31043,31761,31703,29722,29477,29630,29630,29477,29488,29214,29134,29111,30780,30860,30835,31719,31711,31601,27446,27312,27280,25863,25868,25955,28063,27859,27940,7390,7712,8014,7277,7345,7261,12128,12123,12191,10827,10951,11135,10451,10299,10245,12214,12123,12128,12368,12503,12302,11727,11760,11412,11727,11412,11293,29447,29477,29524,29330,29439,29399,36994,36827,36906,2196,2309,2164,14257,14099,14147,14233,14410,14287,14699,14790,14709,18924,18811,18979,19092,18924,18979,15386,15500,15181,26933,27036,26889,28041,28123,27993,27139,27036,26933,26759,26614,26493,3375,3596,3396,3375,3396,3347,3319,3347,3235,10062,10131,10199,10426,10552,10373,39376,39233,39346,39094,39175,38982,38959,38659,39235,2449,2475,2535,2418,2752,2610,7398,7402,7623,34816,34655,34614,10114,10199,10245,31258,31167,31142,12418,13190,12667,29369,29330,29399,4954,4855,4962,5330,5463,5395,26772,26759,26493,26287,26055,26238,37085,36994,36906,37516,37417,37582,1616,1674,1668,1616,1668,1654,1572,1589,1807,1532,1589,1572,16975,17215,16930,23949,23862,23859,25239,25178,25373,32129,32068,32024,32364,32463,32068,37628,37516,37662,37372,37516,37484,38495,38409,38333,41002,40923,40934,41188,40833,41275,4475,4515,4563,4563,4515,4534,4667,4746,4714,1430,1602,1487,1520,1806,1659,3664,3719,3740,3670,4060,3834,31040,31142,30962,41592,41568,41328,41676,41568,41953,1430,1487,1466,28036,28123,28041,29097,29269,29330,35023,34750,34681,40137,39833,40053,40474,41195,40571,4662,4667,4714,39329,39143,39372,37938,37982,37996,38193,37982,38099,2986,2898,3120,12368,12302,12154,13412,13225,13325,29447,29111,29395,28988,28857,28634,28448,28453,28322,26040,26094,25777,5659,5803,5860,5297,5322,5490,4052,4128,4060,37085,36906,37009,37390,37237,37205,5732,5659,5860,34750,34604,34436,31994,31933,32034,4140,4036,4228,4257,4351,4399,18979,18746,18925,17600,17632,17519,23447,23289,23628,23949,24136,24117,32034,31933,31818,32395,32153,32152,31840,31931,31820,31840,31820,31711,38894,38649,38825,38701,38495,38459,39189,38953,39095,1798,1673,1815,2146,2131,1812,3235,3405,3035,3631,3664,3740,3235,3035,3004,41226,41119,41432,41492,41112,41329,3319,3375,3347,39384,39470,39346,39173,39189,39095,39980,39728,40150,40029,39898,40004,13986,14310,14154,13225,13245,13325,2267,2160,2266,2014,2063,2165,2226,2588,2244,2588,2495,2244,3375,3403,3596,18106,18068,17999,39533,39470,39384,27367,27036,27177,27757,27669,27616,27507,27467,27367,29156,28857,28988,40053,39833,39917,11664,11811,11606,11858,11811,11946,10819,10765,10491,12074,12368,12154,30695,30236,30636,30860,31040,30962,30128,30331,30041,29706,29776,29858,29817,29776,29706,29817,29706,29513,29369,29513,29330,34404,34545,34371,33816,33672,33873,3513,3620,3748,3028,3048,3149,3149,3048,3120,3410,3474,3532,10377,10819,10491,30236,30065,30636,31719,31840,31711,39470,39376,39346,2205,2160,2267,1978,2196,2164,2338,2449,2535,1978,2164,2075,15373,15500,15503,14287,14410,14539,15373,15503,15451,36050,36141,35911,36141,35970,35944,35579,35704,35697,35609,35704,35579,35289,35281,35445,35125,35281,35289,40934,40958,41127,40934,40923,40793,40447,40460,40372,4515,4417,4534,4475,4417,4515,6855,6634,6876,6548,6377,6367,6367,6223,6432,5725,5732,5958,5958,5732,5976,6536,6634,6589,32463,32587,32436,32827,32587,32772,5330,5234,5463,4832,4732,4794,4667,4475,4563,5148,5234,5209,33873,33672,33532,4354,4399,4408,6536,6377,6548,12949,13022,12793,28295,28481,28304,27757,27901,27762,35008,35186,35125,38617,38495,38701,38409,38382,38326,1466,1487,1374,3028,3234,3212,11727,11970,11919,12811,12949,12793,18910,19000,18997,18465,18039,18246,17999,18068,17923,1562,1616,1654,1530,1520,1659,1457,1487,1499,18026,17999,17964,17451,17600,17519,22600,22631,22923,24117,24136,24165,35008,34975,35186,38314,38382,38493,38953,38894,38825,38973,38894,38953,3474,3567,3726,6192,6223,6367,6036,6238,6335,6159,6238,5871,31703,31761,31818,33843,33789,33948,1743,1804,1835,1970,1863,2056,1637,1666,1776,1552,1666,1637,7515,7398,7623,7402,7201,7445,7672,7876,7986,35186,34975,35209,34309,34404,34218,37085,37009,37137,41429,41437,41339,41504,41437,41429,1664,1804,1743,5041,5099,5142,20616,20424,20282,20282,20161,20121,20060,19940,19942,19942,19917,19927,20798,20758,20616,20847,20758,20798,20934,20758,20847,20934,20847,20922,20934,20922,21155,20934,21155,21159,41761,41861,41701,41701,41861,41724,41912,41590,41628,41695,41795,41742,41742,41864,41738,41738,41822,41092,41638,42072,41614,41600,41960,41638,6223,6142,6209,12452,12793,12484,22447,22273,21712,20283,20534,20255,20240,20534,20283,20240,20283,20193,20240,20193,20211,19906,20048,19840,19906,19840,19805,19840,19767,19805,19767,19683,19600,19599,19454,19600,28857,28678,28525,28857,28760,28678,29134,29156,28988,29477,29447,29395,29722,29697,29787,28295,28304,28123,34975,34846,34921,39986,39964,40378,40553,40276,40749,41216,41669,41777,1457,1499,1505,19000,18945,18837,18910,18945,19000,22600,22504,22631,23628,23717,23447,23269,23402,23171,20787,22004,20686,42158,41669,41643,21159,21155,21283,40563,40765,40598,40481,40486,40474,41336,41324,41530,40433,40438,40143,1530,1659,1542,1506,1706,1666,1402,1510,1273,3566,3664,3631,3681,3834,3743,4832,4794,4855,10552,10426,10451,10827,11135,10891,23447,23717,23567,22935,23068,22866,23597,23714,23785,31703,31818,31933,29971,29787,29824,39481,38864,39190,39969,40053,39917,38484,38070,38429,34816,34614,34647,36141,35944,35911,8403,8541,8769,20273,20161,20282,34085,33843,33948,34442,34309,34218,33915,33873,33532,37232,37085,37137,37484,37444,37372,37718,37582,37676,41912,41628,41724,21283,21363,21273,41119,41147,41432,41127,40958,40970,23830,23717,23862,24366,24117,24165,24366,24165,24440,25239,25373,25437,41495,41336,41654,41671,41343,41396,41160,41342,41091,5118,5101,5229,5510,5479,5627,5510,5776,5659,11901,11858,12123,13122,13190,13267,13122,13267,13336,13965,13983,14099,12356,12368,12074,21273,21586,21483,22667,22600,22923,29447,29214,29111,32364,32587,32463,31719,31481,31432,34647,34614,34545,34404,34309,34439,37232,37137,37237,40056,40079,40378,41467,41147,41315,41616,41411,41486,22434,22457,22504,41795,41858,41742,14287,14539,14361,2301,2205,2267,2435,2495,2491,24741,24523,24377,26615,26772,26493,10426,10299,10451,9983,9979,9732,8424,8403,8769,20024,19940,20060,41858,41864,41742,1673,1630,1654,1542,1659,1590,1940,2131,2095,2165,2192,2014,1666,1706,1776,1565,1683,1589,2431,2569,2554,2663,2911,2532,4154,4039,4140,3413,3513,3748,4417,4354,4408,4296,4354,4417,7283,7201,7402,7363,7200,7390,7191,7277,7261,14096,13965,14099,13820,13986,13976,13820,13976,13723,16819,16975,16930,17450,17451,17519,16232,15861,15841,15861,15296,15841,27901,28036,28041,27669,27757,27762,27507,27367,27177,36841,36463,36474,36474,36463,36404,36404,36537,35988,35099,35023,34681,34750,34726,34604,36901,36827,36994,38617,38382,38409,38409,38495,38617,18465,18246,18622,17868,17726,17533,17999,17923,17964,17923,17842,17964,23105,22856,23289,23830,23862,23949,41577,41616,41486,13212,13122,13336,28678,28453,28448,28515,28453,28554,40375,40081,40137,40375,40355,40081,2073,2205,2301,19940,19917,19942,19600,19454,19545,41864,41844,41738,32827,32850,32651,37958,37499,37803,18945,18715,18837,18910,18715,18945,4677,4662,4732,5148,5229,5234,37628,37484,37516,37390,37232,37237,5479,5407,5627,5359,5407,5479,34421,34159,34436,34257,34227,34421,41844,41840,41738,7623,7745,7515,7398,7283,7402,3403,3410,3532,3474,3423,3567,3622,3719,3664,3368,3410,3403,3319,3286,3375,2945,3035,2992,13696,13597,13795,28515,28063,28139,25703,25868,25863,27855,28036,27901,40378,39964,40553,40447,40284,40765,41729,41436,41461,41160,41146,41342,4732,4662,4714,4832,4855,4908,38196,37958,37803,11811,11664,11827,10114,10245,10299,11858,11946,12123,19917,19769,19832,29971,29824,30261,29447,29332,29214,41840,41822,41738,9788,10154,10143,10209,10154,9921,3368,3403,3375,10819,10917,11222,12154,12112,12074,12356,12452,12368,10516,10917,10819,4154,4351,4257,3681,3719,3622,3681,3743,3719,22517,22762,22742,22964,22762,22775,1468,1457,1505,1542,1590,1432,1510,1516,1587,1402,1516,1510,18039,17946,17983,17770,17946,17799,41616,41671,41396,41635,41461,41482,5663,5732,5725,7515,7745,7750,34647,34545,34695,1694,1958,1866,1863,1861,1742,12288,12214,12424,12288,12123,12214,29868,29722,29787,28992,28760,28857,3074,3028,3212,3980,4071,4036,39376,39342,39095,38617,38701,38893,39405,39342,39376,39405,39376,39540,39376,39470,39540,40150,39776,40029,41342,41146,41512,5322,5292,5490,5243,5297,5196,37019,36901,36994,37390,37205,37444,12217,12288,12424,13523,13354,13586,13245,13225,13125,13245,13125,12949,28423,28295,28227,28453,28515,28139,29156,29134,29214,40438,40486,40481,40355,40433,40143,40568,40433,40355,19382,19306,19229,19172,19092,19229,41926,41777,41669,41960,41777,41926,4908,4954,4961,2014,2192,2160,5101,5041,5142,5118,5041,5101,7302,7515,7395,9153,8658,9035,15546,15503,15651,14242,14096,14233,15790,15946,15826,27118,27175,26779,29564,29524,29477,40900,40932,41250,1468,1505,1520,8140,7986,8252,34556,34545,34404,34556,34404,34439,34218,33922,34164,31052,31040,30860,31111,31040,31052,29817,29858,29776,39342,39259,39173,1924,2014,1858,2226,2073,2301,2259,2244,2495,31892,31703,31933,30644,30026,30920,31892,31933,31994,32129,32024,31931,33766,33532,33423,31432,31219,31258,14233,14096,14099,13965,13806,13795,13597,13523,13586,14769,14709,14822,26772,26933,26759,27757,27855,27901,28423,28589,28295,38429,38070,38067,38429,38067,38193,1260,1468,1520,1432,1590,1375,1516,1532,1572,1470,1532,1516,23504,23714,23597,23504,23597,23402,2475,2418,2561,2338,2535,2393,2393,2389,2238,2418,2610,2581,13038,13190,13122,13902,13806,13965,13986,13951,14310,13554,13820,13723,27788,27855,27757,29534,29332,29447,39969,39825,39772,4039,3980,4036,4232,4154,4257,4296,4257,4354,4475,4667,4662,5292,5306,5490,5281,5243,5196,31994,32034,32085,34227,34085,33948,34257,34085,34227,37019,36994,37085,37557,37390,37444,37557,37444,37484,37516,37582,37662,39259,39189,39173,22531,22434,22504,23105,23289,23356,23105,23356,23343,23830,23949,23929,22762,22935,22866,22964,22935,22762,13102,13038,13122,13212,13336,13354,26615,26493,26448,26463,26448,26238,40923,41009,40790,41127,40970,41208,40987,41122,41153,41514,41467,41315,41153,41122,41264,41514,41315,41437,41492,41810,41626,41659,41635,41495,41703,41616,41577,41463,41452,41298,27333,27175,27312,2063,1940,2095,1948,1940,2063,1863,1914,2056,15373,15181,15500,15451,15546,15488,19229,19092,19258,6634,6536,6548,6377,6192,6367,6223,6192,6142,5890,5958,6024,6746,6634,6855,7023,7156,6851,7156,6953,6851,7102,6953,7213,1580,1630,1673,1580,1673,1642,2532,2911,2455,2270,2259,2495,2986,3120,3048,13696,13523,13597,13429,13554,13325,13325,13554,13508,40579,40486,40438,40579,40438,40433,41504,41492,41626,23567,23539,23443,23714,23778,23785,23577,23778,23714,36050,35911,35806,35593,35609,35579,35578,35609,35593,35578,35593,35445,35578,35445,35396,35445,35281,35396,35281,35357,35396,3972,3980,4039,8681,8794,8863,9296,9502,9623,8440,8681,8378,12368,12452,12484,12112,11970,12074,29160,29156,29214,28554,28453,28678,31703,31444,31043,31994,32085,32152,35281,35186,35357,37958,37901,37499,37972,37901,37958,37972,37958,38109,35209,34975,35228,34002,33922,33873,37019,37085,37232,1520,1530,1337,1345,1468,1260,3566,3631,3567,6211,6192,6377,7201,7102,7213,23343,23356,23447,22531,22504,22600,31592,31444,31703,31286,31432,31258,38193,37996,37982,35818,35806,35704,1415,1289,1403,1403,1205,1469,1469,1205,1595,1352,1402,1273,1382,1363,1415,1382,1415,1430,1382,1430,1466,1382,1466,1322,19369,19229,19258,5209,5234,5330,4936,4908,4961,5209,5330,5407,5510,5659,5562,8219,8140,8252,15372,15181,15373,26290,26463,26238,33915,34002,33873,33915,33532,33766,41275,40833,41226,7283,7170,7201,7201,7170,7102,34846,34816,34921,3241,3286,3319,3410,3442,3474,3241,3319,3235,3286,3368,3375,29722,29564,29477,29524,29534,29447,29332,29160,29214,29868,29902,29722,30644,30920,30701,31138,30920,31137,37056,36506,37183,39235,38659,39341,7283,7398,7302,12206,12123,12288,13394,13212,13354,12811,13245,12949,5562,5659,5536,34921,34816,34838,34442,34439,34309,37065,37019,37128,37065,37128,37115,36418,36506,36317,2270,2495,2296,2244,2151,2226,3074,3212,3045,3386,3442,3410,4247,4475,4662,4062,3972,4039,4677,4732,4832,16975,17048,17215,17999,18026,18252,15674,15125,15296,17770,17726,17868,17770,17868,17946,27480,27333,27446,27480,27522,28063,29399,29817,29513,31040,31111,31142,29399,29513,29369,37960,37982,37938,41405,41463,41298,41530,41324,41416,41405,41298,41342,40324,40247,40137,27507,27616,27669,27079,27139,26933,27177,27139,27079,27855,27825,28036,28589,28560,28481,27654,27616,27507,34816,34647,34838,41323,41275,41226,41492,41504,41429,41514,41504,41576,4936,4961,5041,10114,10062,10199,8403,8219,8252,10114,10299,10185,1861,1863,1970,1900,1978,2075,1694,1866,1804,1664,1743,1497,15296,15125,15203,41232,41275,41323,1374,1487,1457,3028,2986,3048,2945,3004,3035,2984,3004,2902,29818,29564,29722,6926,7102,6835,2492,2431,2554,2365,2431,2492,5148,5118,5229,5162,5118,5148,8140,8078,7986,8331,8219,8403,13523,13394,13354,13806,13696,13795,13761,13696,13806,14047,13965,14096,25474,25408,24814,27079,26933,26930,34002,34038,33922,33766,33876,33866,41264,41122,41188,23929,23949,24117,25516,25437,25507,25516,25507,25703,38314,37803,38382,37901,37808,37765,37893,37375,37745,5510,5359,5479,5414,5359,5510,22935,23269,23171,23029,23269,22935,41703,41671,41616,41635,41482,41495,3518,3566,3567,7277,7200,7363,7191,7200,7277,7191,6519,7020,22531,22600,22667,28589,28481,28295,31260,31138,31137,31076,31138,31260,31052,30860,30780,36553,36404,36463,36425,35576,35988,36841,36687,36928,40079,40056,40029,39342,39413,39259,39259,39201,39189,40528,40358,40460,40247,40375,40137,2014,2160,1858,1554,1580,1642,1900,2111,1914,2341,2532,2236,40563,40528,40460,40598,40528,40563,40284,40896,40765,40923,41002,41009,41189,40932,40814,40568,40579,40433,1812,2131,1940,1630,1562,1654,1611,1664,1492,16900,17048,16975,16900,16975,16648,34545,34556,34695,34838,34647,34695,20534,20702,20686,20638,20702,20534,20193,20092,20211,20092,19951,20211,19906,19951,20092,41861,41958,41724,41795,41873,41858,41858,41866,41864,41864,41865,41844,41844,41872,41840,41840,41874,41822,41974,41958,41861,41974,41861,41761,41974,41761,41919,41761,41863,41919,41919,41863,42037,37956,37808,37901,41960,41600,41777,4106,4296,4136,4232,4296,4222,18715,18623,18690,18997,19000,19318,22667,22923,22776,22923,22900,22776,5281,5306,5292,5281,5292,5243,34726,34436,34604,32864,33209,33991,37972,38017,37901,38701,38737,38893,4079,4089,4052,5196,5297,5134,3566,3622,3664,12452,12811,12793,12074,11970,11896,21090,20959,20934,20934,20959,20758,20273,20101,20161,20161,20101,20060,19940,19979,19917,19917,19979,19769,19769,19524,19728,21090,20934,21159,21090,21159,21273,21159,21283,21273,29327,29160,29332,29156,28992,28857,33916,34038,34002,33915,33766,33866,31931,31961,32129,31840,31937,31961,37662,37582,37718,41958,41912,41724,41822,41881,41251,23567,23343,23447,23567,23717,23830,19906,19805,19951,1809,1812,1940,41275,41232,41188,41229,41002,41127,41432,41147,41467,19767,19600,19805,21273,21483,21240,1459,1562,1630,1345,1374,1457,2259,2151,2244,2296,2495,2435,2259,2270,2157,24721,24874,24504,25337,25516,25612,26839,26779,27175,27488,27664,27533,34695,34556,34560,41530,41416,41580,20491,20616,20758,27139,27177,27036,27616,27788,27757,26615,26448,26463,38196,38109,37958,37960,38099,37982,38193,38359,38429,38215,38099,37960,41912,41873,41795,1813,1914,1863,1813,1900,1914,15546,15451,15503,14913,14769,14822,15488,15546,15826,28824,28678,28760,2449,2418,2475,2238,2389,2148,2389,2196,2079,27654,27788,27616,20101,20024,20060,21090,21273,21084,41873,41866,41858,3368,3386,3410,3442,3423,3474,3504,3555,3622,3304,3386,3368,3119,3241,3235,15116,14822,15181,29971,29902,29868,29564,29534,29524,30531,30261,29746,30531,29746,30644,4062,4039,4154,3413,3357,3513,3357,3572,3470,30701,30531,30644,31774,31660,31703,30929,30701,30920,33924,33843,34085,2984,3235,3004,2984,3119,3235,5333,5209,5407,5118,4936,5041,4908,4677,4832,5333,5407,5359,7182,7191,7020,5196,5134,4853,9153,9602,8658,10373,10299,10426,11606,11364,11664,11606,11811,11858,20024,19979,19940,19805,19600,19573,24454,24377,24300,24454,24300,24412,29210,28992,29156,29210,29156,29160,41504,41514,41437,41676,41308,41568,41622,41530,41580,41580,41452,41463,41866,41865,41864,1352,1565,1589,1689,1100,1753,17923,17660,17842,19573,19600,19545,23269,23504,23402,23376,23504,23269,41926,41669,42283,41782,41703,41762,1664,1694,1804,1611,1694,1664,35023,34726,34750,34560,34556,34439,41250,40932,41189,3304,3368,3286,30929,30920,30942,30636,30065,30041,30636,30041,30331,2986,2870,2898,3028,3003,2986,3357,3470,3513,11901,11606,11858,11901,12123,12206,30142,29902,29971,2327,2418,2449,40553,39964,40276,41208,40970,41153,41865,41872,41844,1345,1457,1468,21084,21240,21133,22923,23004,22900,4672,4936,5118,37718,37676,37765,37264,37232,37534,37718,37765,37808,4573,4677,4908,3386,3423,3442,31076,30920,31138,38973,38737,38894,39540,39470,39588,19454,19382,19545,26450,26615,26463,26290,26238,26132,41872,41874,41840,41827,41343,41671,1352,1589,1532,12927,13038,13102,12217,12424,12515,40324,40357,40247,40247,40357,40375,39329,39190,39175,39329,39175,39143,41635,41729,41461,41654,41659,41495,5663,5659,5732,41874,41878,41822,4222,4296,4106,4296,4232,4257,38973,38953,39177,38314,38196,37803,1402,1470,1516,1352,1470,1402,3423,3518,3567,5348,5490,5306,4089,4420,4052,8077,8078,8140,7995,8078,8077,17842,17660,17451,19545,19382,19369,21273,21240,21084,22900,23004,22949,25178,25239,25209,22949,23004,23105,27488,27480,27664,28874,28824,28760,28874,28760,28992,31260,31137,31444,31111,31286,31258,30695,31052,30780,31774,31703,31892,33916,34002,33915,35663,35609,35578,35663,35818,35609,35609,35818,35704,36141,36308,36317,35663,35578,35615,35578,35396,35470,35186,35235,35357,35209,35235,35186,39201,38953,39189,38659,38530,38804,38530,38484,38804,40814,40571,41340,41953,41568,41592,41819,41827,41671,13418,13394,13523,13761,13523,13696,41384,41189,41766,40664,40568,40355,40397,40355,40375,29915,29534,29564,35209,35228,35235,37896,37718,37808,38202,38196,38257,41878,41881,41822,5893,5890,6142,6170,6211,6156,6211,6377,6156,6589,6634,6746,6675,6746,6851,6926,6851,6953,4118,4062,4154,3413,3748,3356,2014,1948,2063,1554,1539,1580,1924,1948,2014,15203,15125,14842,15841,16566,16448,14473,14310,14842,14310,14441,14842,26226,26290,26132,41297,41208,41153,41264,41188,41232,40474,40486,40776,41523,41432,41467,41523,41467,41656,5562,5476,5510,5209,5162,5148,5414,5476,5401,19745,19776,19537,34975,34921,34947,34442,34560,34439,37019,37065,36901,37557,37484,37583,42158,41643,41702,2157,2151,2259,2296,2435,2378,37583,37484,37628,38017,37972,38109,2378,2435,2431,2378,2431,2365,31372,31260,31444,31052,31286,31111,33866,33916,33915,38804,39103,38925,1432,1530,1542,18699,18623,18715,18716,18715,18910,22434,22531,22624,22949,23105,23083,34921,34889,34947,12515,12424,12667,29364,29327,29332,14769,14623,14699,14577,14623,14769,38202,38017,38109,41133,41009,41229,1375,1590,1616,1337,1432,1333,1539,1630,1580,2365,2492,2341,19573,19545,19655,17451,17660,17600,17519,17215,17450,27788,27825,27855,27654,27825,27788,27654,27507,27177,26933,26772,26930,1284,1289,1415,1284,1415,1363,1284,1177,1234,1363,1177,1284,19602,19524,19769,19573,19655,19765,7102,6926,6953,7302,7398,7515,34921,34838,34889,7807,8259,8048,10241,10209,10014,34096,34085,34293,34096,33924,34085,34420,34442,34218,32827,32627,32587,37583,37628,37685,28687,28554,28678,28687,28678,28824,5476,5414,5510,5310,5414,5401,7195,7712,7390,34726,34421,34436,34889,34838,34812,34164,33922,34038,10154,10209,10413,10917,11293,11164,8817,9168,8794,26839,27175,27332,27488,27333,27480,31502,31372,31444,18623,18465,18622,17726,17405,17307,18699,18465,18623,22531,22667,22699,23370,23105,23343,22775,22762,22517,23504,23523,23714,12667,13190,13038,1742,1813,1863,1881,1995,1978,38617,38493,38382,38196,38202,38109,38560,38493,38617,41381,41264,41232,41229,41009,41002,7200,7195,7390,5210,5306,5281,31931,31840,31961,1322,1466,1374,1565,1552,1637,1570,1742,1861,1443,1552,1565,3670,3834,3681,3555,3681,3622,25314,25239,25437,23443,23370,23343,25314,25437,25516,41810,41492,41329,29902,29818,29722,29534,29364,29332,30261,30193,29971,30399,30193,30261,30501,30261,30531,30501,30531,30701,30845,30701,30929,30845,30929,30861,30920,31076,30942,17799,17946,18039,25337,25314,25516,30695,30799,31052,31934,31742,31606,30041,29858,30128,30331,30371,30342,8143,8240,8378,8186,8240,8143,37558,37583,37685,37115,36901,37065,37628,37662,37685,3748,3543,3356,5414,5333,5359,4055,4475,4247,5310,5333,5414,7712,7807,8048,7735,7807,7712,10616,10827,10701,10891,11135,11364,11364,11606,11001,12206,12288,12217,13986,13820,13786,15753,15992,15841,13820,13554,13786,22964,23029,22935,22988,23029,22964,30942,31194,31011,39405,39413,39342,39742,39470,39533,39468,39190,39329,39468,39481,39190,7191,7195,7200,31337,31076,31260,31660,31592,31703,31722,31592,31660,31774,31892,31989,34838,34695,34812,3074,3003,3028,2974,3003,3074,2865,3004,2945,3119,3182,3241,3241,3144,3286,3386,3304,3423,3329,3398,3518,29984,29818,29902,28952,28874,28992,32864,32029,32575,31840,31719,31937,31719,31432,31742,38804,38484,38712,39378,39468,39329,12927,12667,13038,12262,12206,12217,13122,13212,13102,27332,27488,27533,29210,29160,29327,40324,40137,40304,40137,40053,40304,3312,3413,3356,10827,10616,10951,31321,31260,31372,39540,39413,39405,38973,38893,38737,39372,39143,39235,2161,2270,2296,2161,2157,2270,1976,2160,2205,14537,14539,14699,2338,2327,2449,2798,2865,2945,2079,2196,1995,14069,14047,14096,1995,2196,1978,2889,2870,2986,2121,2161,2296,2798,2945,2694,15116,15181,15372,14577,14537,14623,14623,14537,14699,27231,27079,27028,5890,6024,6142,7395,7515,7477,34812,34695,34841,41656,41467,41514,41549,41323,41226,41678,41729,41635,41885,41819,41671,41678,41635,41679,41654,41336,41530,41654,41530,41630,1554,2261,1812,41560,41463,41405,41827,41901,41702,41782,41671,41703,5152,5210,5281,5152,5281,5196,41264,41297,41153,41381,41323,41549,2308,2327,2338,13774,13761,13806,39378,39372,39341,40766,40765,40896,40598,40757,40528,39980,39518,39728,40757,40765,40766,13786,13554,13429,1948,1809,1940,1840,1809,1948,15826,15946,16367,26290,26450,26463,25618,25777,25408,31989,31892,31994,31496,31321,31372,12262,12217,12515,29915,29364,29534,34841,34695,34560,34509,34560,34442,36928,36687,36901,34817,34421,34726,34382,34293,34421,36928,36901,37115,4062,3800,3972,4232,4118,4154,4118,4222,4106,4118,4081,4061,12667,12642,12515,13102,13212,13394,28800,28687,28824,28800,28824,28874,40411,40397,40375,40659,40486,40579,40411,40375,40357,13761,13418,13523,31502,31444,31592,39366,39201,39259,17770,17564,17726,17645,17564,17770,38017,37956,37901,38257,38196,38314,38257,38314,38374,38099,38215,38193,38247,38215,38239,41762,41703,41577,41679,41635,41659,19296,18997,19318,17829,17799,18039,2073,2226,2151,15372,15373,15451,5333,5162,5209,5278,5162,5333,5222,5348,5306,4853,5152,5196,34125,34164,34038,34125,34038,33916,37019,37264,37128,29364,29210,29327,17234,17297,17450,16900,16566,16583,41538,41560,41405,41654,41679,41659,41405,41342,41512,41549,41226,41608,41626,41576,41504,41700,41576,41626,41622,41630,41530,7659,7672,7986,9979,9983,10062,9979,10062,10114,8240,8440,8378,8094,8440,8240,20684,20491,20758,20101,20100,20024,20024,20100,19979,19885,19602,19769,19524,19349,19318,20893,20758,20959,20893,20959,21084,20959,21090,21084,20702,20787,20686,20638,20787,20702,20638,20534,20446,20076,20240,20211,20076,20211,19951,20076,19951,20000,19951,19858,20000,31722,31502,31592,32152,31989,31994,32123,31989,32152,32249,32364,32068,31742,31432,31488,39182,38893,38973,20491,20424,20616,22667,22776,22699,31722,31660,31774,23443,23343,23567,22699,22776,22900,23029,23376,23269,24741,25474,24814,23116,23376,23029,35986,36050,35818,35818,36050,35806,38247,38255,38215,35986,35818,35663,35470,35396,35357,35470,35357,35385,35357,35235,35385,35235,35405,35385,37558,37390,37557,38081,37956,38017,41919,42113,41974,41974,42325,41958,42300,42127,41912,42127,42025,41873,41873,42025,41866,41866,42025,41865,41865,42025,41872,41872,42033,41874,41874,42033,41878,41878,42051,41881,42072,42037,41614,42113,42037,42072,41638,41960,42072,1867,1978,1900,1570,1958,1694,2157,2073,2151,2189,2296,2378,14319,14242,14287,14287,14242,14233,14047,13902,13965,13761,13364,13418,14069,14242,14162,27763,27664,27480,26278,26019,26386,41323,41381,41232,41226,41432,41608,3099,3119,2982,3099,3182,3119,3504,3622,3566,10922,11293,10917,12356,12221,12452,29858,29936,30128,31432,31286,31435,2051,2073,2157,3275,3572,3357,3275,3558,3572,3003,2889,2986,3275,3357,3312,12613,12642,12667,13244,13102,13394,12927,13102,13074,20424,20273,20282,27079,27231,27177,28295,28123,28227,26930,26772,26615,30399,30507,30429,30622,30501,30701,30193,30142,29971,29818,29915,29564,28955,28952,29434,30701,30845,30808,30929,30942,30861,37558,37557,37583,39728,39776,40150,39540,39588,39413,39250,39177,39201,25618,25474,25584,26094,26226,26132,14042,13902,14047,22699,22900,22672,3253,3141,3152,3144,3304,3286,6589,6675,6660,6722,6675,6851,5893,6142,6192,18252,18376,18427,17450,17215,17234,39481,39633,38864,39729,39633,39481,39729,39481,39764,1758,1840,1948,1420,1140,1198,1805,1840,1758,12427,12642,12613,15488,15432,15451,14577,14361,14537,15314,15432,15488,26278,26386,26779,26231,26226,26094,40304,40053,40365,41349,41297,41264,20273,20100,20101,19951,19805,19858,19805,19765,19858,33991,33209,33843,34293,34085,34257,34293,34257,34421,2341,2492,2532,3013,2974,3074,1265,1322,1374,1265,1374,1345,1337,1530,1432,2148,2308,2238,2238,2308,2338,1783,1900,1813,27028,26930,26703,34975,34947,35228,36255,36308,36141,19805,19573,19765,2833,2898,2870,4222,4118,4232,4417,4136,4296,41793,41679,41935,41580,41416,41452,35228,35222,35314,34947,35124,35222,1506,1743,1706,2794,2889,3003,2865,2902,3004,2772,2902,2865,25314,25209,25239,23929,23567,23830,25337,25209,25314,38320,38081,38017,38546,38314,38493,38215,38255,38193,37034,37060,37745,41560,41580,41463,41512,41146,41479,42127,41873,41912,41881,42044,41251,41739,41656,41576,7659,7986,8078,7216,7170,7283,23083,22900,22949,24316,24117,24366,23376,23523,23504,23462,23523,23376,34420,34509,34442,41762,41577,41729,42134,41901,42123,41762,41729,41763,10185,9979,10114,31887,31722,31774,31337,31260,31321,30799,30695,30636,6170,6192,6211,5459,5476,5562,8440,8491,8681,8499,8491,8223,8186,8143,8043,18836,18716,18910,18836,18910,18997,23083,23105,23326,41880,41827,41819,17564,17405,17726,17373,17405,17564,17234,17215,17048,18026,17964,17908,28063,28515,28208,28952,28800,28874,28952,28992,29210,40485,40411,40357,40664,40659,40568,40538,40411,40485,41679,41654,41809,1138,1205,1289,1289,1205,1403,1175,1289,1284,2481,2550,2992,11773,11970,11727,17964,17842,17908,42025,42033,41872,8499,8817,8794,8043,8143,7875,37685,37662,37779,37896,37808,37956,5890,5867,5958,34885,34889,34812,36639,36553,36463,36639,36463,36841,36985,36841,36928,36985,36928,37058,10446,10373,10552,10446,10552,10616,10446,10616,10566,11677,11901,12206,10209,10377,10491,10241,10377,10209,4417,4475,4136,5633,5659,5663,5222,5306,5210,5222,5210,5127,7701,7735,7712,17908,17842,17851,25474,25618,25408,25628,25618,25584,34639,34841,34560,34234,34420,34218,34234,34218,34164,1333,1432,1375,1616,1562,1375,17456,17842,17451,1182,1265,1236,1234,1175,1284,18716,18699,18715,18782,18699,18716,22714,22775,22517,1805,1812,1809,1413,1506,1666,1413,1666,1552,5867,5725,5958,7216,7283,7302,7195,7085,7712,7191,7182,7195,7261,6715,6519,41576,41656,41514,41700,41626,41810,19655,19545,19537,31742,31937,31719,32249,32068,32129,33876,33766,33423,31961,31937,31934,42033,42051,41878,12427,12262,12515,12427,12515,12642,12074,12221,12356,15432,15372,15451,15314,15372,15432,25612,25516,25703,26403,26278,26597,26226,26319,26290,26231,26319,26226,14242,14069,14096,13902,13774,13806,12613,12667,12755,14361,14539,14537,14913,14822,15116,3398,3566,3518,5127,5210,5152,10373,10185,10299,2073,1976,2205,2051,1976,2073,2051,2157,2011,2327,2307,2418,2148,2389,2079,13901,13774,13902,13429,13325,13245,19885,19769,19979,38690,38560,38617,38081,37896,37956,42051,42053,41881,8658,9602,8795,8424,8331,8403,8658,8399,8409,24504,24316,24366,38374,38202,38257,36920,36833,37789,5725,5711,5663,7515,7750,7477,7395,7216,7302,28123,28036,28227,33991,33843,33924,31989,31887,31774,6159,6715,6238,4013,5237,4089,34817,34726,35023,34096,33991,33924,34043,33866,34028,37779,37662,37839,37058,36928,37115,3959,4079,4052,32249,32129,32232,1269,1260,1520,1459,1630,1539,1470,1352,1532,1283,1131,1219,41885,41880,41819,41763,41729,41915,40365,40053,39969,15170,14913,15116,40765,40757,40598,41133,40761,41009,3329,3518,3423,3182,3144,3241,3099,3144,3182,3119,2984,2982,30501,30399,30261,31337,31321,31440,30331,30342,30636,29858,29817,29936,3215,3045,3212,2974,2794,3003,2889,2833,2870,3070,3045,3215,3253,3215,3275,2982,2984,2937,5711,5633,5663,30267,30142,30193,29936,29817,29943,3126,3253,3152,1363,1382,1177,25618,25628,25777,25584,25474,25305,42053,42044,41881,1506,1497,1743,1701,1783,1742,1452,1497,1506,3045,3013,3074,2854,2984,2902,2772,2865,2798,3555,3670,3681,3570,3670,3555,18376,18252,18026,22775,22988,22964,24412,24300,24059,22858,22988,22775,29452,29817,29399,38690,38546,38560,39201,39177,38953,39366,39259,39519,41809,41654,41815,41915,41729,41678,41564,41580,41560,41564,41560,41538,41106,41250,41479,1742,1783,1813,1927,2148,2079,1570,1694,1611,31496,31372,31502,32153,32123,32152,38804,38925,38659,39372,39378,39329,38712,38484,38429,38712,38429,38548,41381,41349,41264,41229,41127,41474,41464,41349,41536,39699,39588,39470,39699,39470,39742,5138,6046,5348,4853,5127,5152,34639,34560,34509,34125,34234,34164,1350,1459,1539,1278,1443,1565,11594,11773,11727,12074,12146,12221,11896,11773,11736,17450,17456,17451,18043,18376,18026,17245,17234,16926,17450,17297,17446,41810,41329,41676,41823,41432,41523,25868,26019,25955,25209,24504,24874,41384,41250,41189,1382,1322,1217,1177,1382,1217,1269,1520,1337,1326,1375,1562,5633,5536,5659,7477,7750,7672,18516,18039,18465,17045,17100,17307,19509,19349,19524,17524,17645,17829,34639,34509,34584,37058,37115,37128,41885,41671,41782,41793,41678,41679,8454,8331,8424,27361,27654,27231,28227,28036,28032,26319,26450,26290,26308,26450,26319,29269,29097,28560,27654,27177,27231,38359,38193,38255,37789,36833,37056,8595,8454,8424,8595,8658,8409,28515,28554,28719,29434,29210,29364,18043,18026,17908,19776,19765,19655,23326,23105,23370,20828,20893,20917,23326,23370,23443,22988,23116,23029,22858,23116,22988,2736,2833,2889,14069,14042,14047,14361,14319,14287,14418,14319,14361,19349,19296,19318,3329,3423,3205,10185,10167,9979,10373,10167,10185,10891,11001,10901,39341,39372,39235,40485,40324,40304,2308,2307,2327,2042,2079,1995,27028,27079,26930,38215,37960,38239,1899,2042,1995,5536,5459,5562,5310,5278,5333,7496,7477,7672,14874,14577,14769,37019,37232,37264,41313,41208,41297,8077,8140,8219,34043,34125,33916,34665,34639,34584,34043,33916,33866,1497,1492,1664,1452,1492,1497,17045,17307,17405,14986,14874,14913,14913,14874,14769,38359,38247,38239,2204,2307,2308,40896,40284,40761,40276,40358,40749,1217,1322,1265,17799,17645,17770,18516,18465,18699,24316,23929,24117,23966,23929,24316,32364,32772,32587,32232,32129,31961,32232,31961,32061,2866,2481,3098,29452,29439,29444,24337,24504,24586,23577,23714,23523,1269,1337,1245,1283,1100,1131,1391,1413,1443,5867,5754,5725,5725,5716,5711,5711,5629,5633,5633,5520,5536,5536,5354,5459,5890,5848,5867,6156,6377,6536,6589,6746,6675,6851,6926,6835,7102,6997,6835,7170,6997,7102,7170,7216,6997,36050,36255,36141,36308,36418,36317,35470,35615,35578,35620,35615,35470,35405,35470,35385,35405,35235,35228,41885,41782,42059,42072,42390,42256,3398,3504,3566,3481,3959,4052,10377,10516,10819,9743,10154,9788,15170,15116,15372,27332,27175,27333,25955,26019,26246,27332,27333,27488,31496,31502,31722,39519,39259,39413,38690,38617,38893,39378,39548,39764,39153,39341,38659,1840,1805,1809,1554,1420,1539,1758,1948,1924,40659,40579,40568,40355,40397,40664,5354,5401,5459,5459,5401,5476,35426,35405,35228,34304,34420,34234,37232,37390,37534,2365,2189,2378,1639,1758,1924,2455,2911,2898,28032,28036,27825,29269,28560,28589,40538,40397,40411,11851,11677,12206,12667,12927,12836,12927,12903,12836,40358,40528,40749,8174,8077,8219,7995,7659,8078,8174,8219,8331,8186,8094,8240,8906,8984,8667,7875,8143,7807,7703,7807,7735,34231,34304,34234,34028,33866,34076,5927,5893,6192,6997,7216,7162,34885,34812,34841,1800,1867,1900,1800,1900,1783,15184,15170,15372,20893,21084,20917,23199,23326,23125,31785,31496,31722,42136,41953,41592,41960,42390,42072,41893,41782,41762,41893,41762,41908,21712,22273,22004,7162,7216,7395,7496,7295,7293,41625,41564,41538,41712,41630,41622,41625,41538,41512,1450,1570,1611,1443,1413,1552,1391,1443,1330,3045,2963,3013,3013,2910,2974,3126,3070,3215,3126,3215,3253,3312,3357,3413,5893,5848,5890,17305,17045,17405,15826,15314,15488,30142,30144,29902,30399,30267,30193,30429,30267,30399,30861,30942,31011,36553,36537,36404,36639,36537,36553,36639,36841,36956,36841,36985,36956,41700,41739,41576,41785,41739,41700,38560,38546,38493,37839,37662,37718,37685,37779,37558,39182,38973,39177,3012,2963,3045,2236,2282,2341,39836,39699,39963,39588,39519,39413,40150,40029,40056,4118,4061,4062,4672,5118,4774,14319,14162,14242,14418,14162,14319,14418,14361,14577,14418,14298,14183,38515,38374,38314,38247,38359,38255,39103,39153,38925,38239,37960,38253,2121,2157,2161,3748,3980,3665,7293,7395,7477,7701,7703,7735,5254,5348,5222,13102,13024,13074,21712,22402,22447,20446,20534,20240,20120,20240,20076,20120,20076,20000,20120,20000,19895,20000,19858,19787,19858,19765,19787,20491,20549,20424,20424,20278,20273,20273,20278,20100,19885,19509,19602,19602,19509,19524,19349,19359,19296,20893,20684,20758,20828,20684,20893,21084,21133,20917,26228,26246,26278,24337,24316,24504,30942,31076,31194,36956,36985,37200,2174,2189,2365,20684,20549,20491,21244,21240,21402,22531,22699,22624,42037,42113,41919,42025,42090,42033,42033,42090,42051,42051,42175,42053,42053,42070,42044,41702,41901,42158,1245,1337,1333,1182,1217,1265,1326,1333,1375,1283,1273,1510,1219,1273,1283,1450,1611,1492,39250,39182,39177,39250,39201,39366,7801,7659,7995,8156,8174,8331,26323,26228,26278,26040,26231,26094,26703,26930,26615,26040,25777,25628,41349,41313,41297,41464,41313,41349,41901,41827,42123,5401,5278,5310,5354,5278,5401,5176,5254,5222,5176,5222,5127,7154,7195,7182,17446,17456,17450,17234,17245,17297,16900,17234,17048,32249,32357,32364,31934,31937,31742,41712,41622,41580,2710,2772,2798,2982,2997,3099,3099,2997,3144,3205,3423,3304,3398,3445,3504,2854,2772,2710,3665,3980,3972,3205,3304,3162,3445,3570,3555,10312,10516,10377,11773,11896,11970,12414,12811,12452,11594,11727,11293,22624,22672,22571,39689,39519,39588,40339,40150,40056,42314,41912,41958,42044,42199,41515,5704,5716,5725,7020,7154,7182,28363,28589,28423,27922,28032,27825,28147,28032,27997,19787,19765,19776,1265,1345,1236,19064,18836,18997,17524,17373,17564,19064,18997,19296,23040,22900,23083,21538,21751,22197,23391,23462,23376,23213,23376,23116,29439,29452,29399,30301,30371,30128,30128,30371,30331,31201,31286,31052,28284,28423,28227,13394,13418,13364,12414,12452,12221,40378,40339,40056,40749,40528,40946,40485,40357,40324,40428,39969,40414,28326,28284,28227,5871,6238,6036,4977,5176,5127,18836,18782,18716,18846,18782,18836,22447,22714,22517,22402,22714,22447,32123,31887,31989,31496,31440,31321,32153,31887,32123,30591,30636,30342,34957,34885,34841,34231,34234,34125,34231,34125,34043,15184,15314,14999,17524,17564,17645,16566,16900,16648,17456,17851,17842,19382,19229,19369,37839,37718,37927,37200,36985,37058,3824,3800,4062,4136,4475,4055,38691,38690,38749,38546,38515,38314,37927,37718,37896,18925,19258,19092,38555,38515,38546,26130,25955,26246,25863,25612,25703,34999,34885,34957,37200,37058,37128,10279,10167,10373,8409,8454,8595,10279,10373,10446,12430,12262,12427,12430,12427,12613,25661,25612,25770,25305,25474,24741,24914,24741,24454,29279,29269,28589,31484,31440,31496,9296,9623,9168,10312,10527,10516,8984,9168,8817,18979,18925,19092,42165,42090,42025,23462,23577,23523,23391,23577,23462,41953,41937,41676,42136,41937,41953,41908,41762,41763,41885,42056,41880,1236,1345,1260,2126,2121,2296,1858,2160,1857,2126,2296,2189,2282,2365,2341,22714,22815,22775,22750,22815,22714,13364,13761,13567,14690,14577,14874,38359,38491,38429,38253,37960,37893,1420,1554,1140,1311,1326,1562,1897,1976,2051,1881,1899,1995,2092,2204,2148,2148,2204,2308,1701,1800,1783,16367,16623,16600,15170,14986,14913,26278,26779,26597,26403,26323,26278,26228,26130,26246,1633,1812,1805,1184,1236,1260,41741,41712,41580,41913,41908,41763,41741,41580,41750,2866,2752,2481,2092,2148,1927,40766,40794,40757,41034,40896,40761,41034,40761,41133,8499,8794,8491,7703,7875,7807,7691,7875,7703,12836,12755,12667,14042,14069,14162,34293,34273,34096,32054,31785,31887,35143,34817,35023,41652,41625,41512,1895,1897,2051,1881,1978,1867,26703,26615,26450,28032,28147,28227,26703,26450,26524,9502,9743,9788,30267,30144,30142,30622,30399,30501,30622,30701,30808,29943,29817,29688,30048,30128,29936,2455,2898,2272,2783,2910,2963,3126,3012,3070,3141,3253,3275,3188,3275,3312,3012,2825,2783,3445,3555,3504,4079,4013,4089,17784,17851,17456,16685,16926,16900,24337,24228,24316,23199,23083,23326,23199,23040,23083,24504,25209,24586,30808,30845,30861,30371,30591,30342,39182,39289,38893,39425,39250,39366,41928,41810,41676,41749,41523,41656,1689,1625,1053,1175,1138,1289,1146,1138,1175,1146,1175,1234,1146,1234,1177,1146,1177,1085,2937,2997,2982,3329,3445,3398,2937,2984,2854,30412,30144,30267,1085,1177,1217,1184,1260,1269,22815,22858,22775,22750,22858,22815,37534,37390,37558,38017,38202,38320,2910,3013,2963,3162,3304,3144,28284,28363,28423,27922,27825,27654,31011,30808,30861,30745,30799,30636,39764,39481,39468,39764,39468,39378,39378,39341,39548,40905,40794,40766,40659,40776,40486,41596,41479,41250,40855,40776,40659,38320,38202,38374,3012,3045,3070,2854,2902,2772,11992,12146,12074,11156,11594,11293,30144,29984,29902,28554,28687,28719,29688,29817,29452,18043,17851,17784,35790,35986,35663,38522,38491,38239,35790,35663,35772,35663,35615,35772,41937,41928,41676,42100,41928,41937,42059,42056,41885,41913,41763,41915,1857,2160,1976,14999,14986,15170,26524,26450,26308,35772,35615,35843,5520,5354,5536,4045,4081,4106,7659,7496,7672,7801,7995,7929,20130,19979,20100,42175,42070,42053,5848,5754,5867,5716,5629,5711,5893,5808,5848,6170,5927,6192,6145,6156,6536,6587,6536,6589,6587,6589,6660,6675,6722,6660,5277,5348,5254,7020,7049,7154,6851,6835,6722,35450,35470,35405,36224,36255,36050,31194,31076,31337,2710,2798,2694,6722,6835,6755,11691,11736,11773,41749,41656,41771,41474,41127,41208,41596,41250,41384,25877,26040,25628,1413,1452,1506,1338,1701,1742,1355,1452,1413,38515,38487,38374,38691,38555,38546,38691,38546,38690,41815,41654,41630,41750,41580,41564,41750,41564,41715,4106,4081,4118,4677,4247,4662,3959,4013,4079,6755,6835,6769,36255,36409,36308,42070,42087,42044,12772,12755,12836,12903,12927,13074,31887,31785,31722,31208,31194,31337,32152,32085,32395,28326,28363,28284,29269,29444,29439,31208,31337,31440,8094,8186,8043,9704,9921,9743,2685,2710,2694,6638,6755,6769,17784,17456,17574,15296,15282,15583,23326,23443,23539,24586,25209,25047,24059,24300,23778,26308,26231,26040,24059,23778,23920,41704,41652,41512,41815,41630,41712,37128,37264,37315,15314,15184,15372,16600,16623,16864,42059,41782,41893,41915,41678,41793,1160,1217,1182,19509,19359,19349,17829,17645,17799,18801,18746,18811,32232,32234,32249,32347,32234,32232,32357,32347,32445,8174,7929,8077,8658,8795,8689,37315,37264,37534,38025,37927,37896,38025,37896,38081,5927,5808,5893,28687,28800,28955,35314,35426,35228,35228,34947,35222,2011,1895,2051,1897,1857,1976,2030,2126,2189,14081,14042,14162,13901,14042,14081,14162,14418,14081,23567,23929,23539,22624,22503,22434,39519,39474,39366,38636,38515,38555,39498,39474,39519,39689,39588,39699,39689,39699,39836,2249,2447,2481,11871,12074,11896,19359,19272,19296,18801,18491,18746,29279,29444,29269,33876,34000,33983,35124,34889,34999,40442,40365,39969,40538,40664,40397,5808,5754,5848,28147,28326,28227,27964,27922,27654,27997,27922,27964,34947,34889,35124,36537,36425,35988,36639,36664,36537,36816,36664,36639,37105,36639,36956,5184,5277,5254,5184,5254,5176,7085,7701,7712,7875,8094,8043,7081,7195,7154,1452,1404,1492,1355,1404,1452,41771,41656,41739,41785,41700,41810,41839,41815,41712,41715,41564,41625,13024,12903,13074,1740,1857,1897,1858,1772,1924,1394,1539,1420,1927,2079,1871,1696,1881,1867,1663,1867,1800,1311,1562,1285,1236,1160,1182,41931,41915,41793,42059,41893,42036,41931,41793,41935,1394,1350,1539,1633,1805,1758,1278,1565,1352,41882,41785,41810,41839,41712,41741,5754,5704,5725,6937,7049,7020,34889,34885,34999,1631,1633,1758,1620,1414,1500,26323,26130,26228,25955,26044,25863,25364,25209,25337,26403,26130,26323,41536,41349,41381,41536,41381,41549,1110,1184,1269,22571,22503,22624,23966,24316,24228,22858,23213,23116,22874,23213,22858,31785,31484,31496,13786,13951,13986,13075,13429,13245,13075,13245,12811,3102,3188,3356,4045,4136,4055,12566,12613,12755,12566,12430,12613,12336,12414,12221,40365,40477,40304,37558,37779,37829,38118,38025,38081,38636,38487,38515,39247,39182,39250,38239,38491,38359,37951,37893,37745,4977,5184,5176,3473,4052,3670,4081,4045,3974,5704,5629,5716,7049,7081,7154,19272,19064,19296,34841,34639,34665,2997,3059,3144,2774,3445,3329,3570,3473,3670,3084,3059,2990,3059,2997,2990,2997,2937,2925,2937,2758,2793,5138,5871,6036,5160,5184,5081,30723,30622,30808,30723,30507,30622,30622,30507,30399,30429,30412,30267,30144,30034,29984,29984,29915,29818,30723,30808,30997,30808,31011,31068,34708,34382,34421,34385,34382,34708,2825,3012,3126,2910,2794,2974,3188,3312,3356,30048,30301,30128,30579,30745,30591,30591,30745,30636,30799,31180,31052,30048,29936,29943,34122,33991,34096,37862,37789,37056,3059,3162,3144,10891,11364,11001,26955,27194,27028,26308,26319,26231,26600,26524,26521,31245,31011,31194,30579,30591,30371,30069,30034,30248,30159,30048,29943,643,1455,645,1273,1218,1352,23213,23262,23376,23131,23262,23213,38434,38320,38374,38111,38253,37893,41893,41908,42036,4062,4061,3824,10891,10701,10827,8351,8409,8399,24063,23966,24228,24063,24228,24534,39742,40113,39963,39699,39742,39963,40428,40442,39969,40365,40489,40477,39548,39341,39391,39425,39366,39474,39322,39247,39250,1404,1450,1492,1355,1450,1404,2725,2794,2910,2030,2011,2126,3824,4061,4081,5629,5520,5633,11736,11871,11896,12146,12336,12221,11594,11691,11773,11306,11691,11594,10527,10917,10516,16864,16623,17045,17305,17405,17373,22539,22406,22616,29917,29915,29984,31785,31930,31484,32165,32153,32395,34509,34420,34584,41756,41596,41384,40894,40664,40538,42134,42158,41901,1285,1562,1459,1321,1394,1198,12772,12566,12755,10734,10701,10891,12772,12836,12903,40477,40485,40304,40489,40485,40477,10701,10566,10616,1857,1772,1858,2011,2157,2121,2011,2121,2126,2752,2249,2481,2204,2092,2044,14042,13901,13902,14081,14418,14082,13536,13951,13786,40896,40905,40766,40946,40528,40757,40578,40339,40378,41138,41034,41141,34382,34273,34293,34385,34273,34382,11691,11871,11736,18043,17908,17851,18746,18491,18485,22624,22699,22672,22900,22906,22672,20549,20278,20424,19509,19371,19359,19359,19371,19272,19272,19371,19064,20684,20670,20549,20828,20670,20684,20665,20670,20855,20950,20828,20917,20950,20917,21133,20950,21133,21129,1219,1187,1273,1302,1355,1413,1131,1187,1219,23262,23391,23376,23318,23391,23262,42036,41908,41913,42123,41827,41880,42036,41913,41915,20259,20446,20240,21712,22004,20787,20361,20446,20259,19895,20000,19787,19895,19787,19745,19895,19745,19955,19776,19745,19787,27922,27997,28032,29431,29450,29444,27194,27231,27028,34028,34231,34043,33876,33423,34000,37789,37816,37745,37963,38024,38111,41014,40905,40896,41474,41208,41599,42113,42325,41974,42127,42165,42025,42090,42175,42051,42070,42179,42087,42072,42245,42113,42256,42245,42072,21216,21133,21240,31537,31208,31440,31245,31208,31537,39391,39341,39153,1326,1245,1333,1285,1459,1291,18780,18699,18782,20403,20278,20549,23692,23778,23577,26124,25877,25862,41935,41679,41809,41935,41809,41940,42390,41960,41926,4136,4045,4106,4936,4672,4908,29444,29450,29452,29279,28589,29020,2631,2898,2833,19064,18846,18836,18780,18846,18688,20278,20130,20100,21244,21216,21240,22672,22906,22731,21402,21240,21483,42279,42165,42127,37315,37200,37128,37779,37839,37829,41642,41536,41549,41785,41771,41739,41909,41771,41785,41882,41810,42060,42199,42044,42087,41832,41715,41625,41849,41839,41741,41832,41625,41652,41704,41512,41479,2455,2236,2532,13607,13761,13774,21216,21244,21289,26524,26600,26703,25877,25628,25862,28211,28326,28147,32234,32357,32249,32061,31961,31934,34076,34231,34028,40664,40855,40659,40776,40855,40908,3071,3329,3205,39498,39425,39474,38434,38374,38487,39153,38659,38925,17456,17510,17574,35986,36139,36050,36255,36416,36409,36409,36418,36308,35790,35948,35986,35772,35948,35790,35994,35948,35772,35450,35405,35426,35450,35426,35417,35426,35314,35417,35314,35222,35417,35948,36139,35986,5754,5628,5704,5704,5628,5629,5629,5368,5520,5808,5766,5754,6156,6029,6170,6217,6145,6536,6217,6536,6587,6555,6587,6660,6555,6660,6638,36139,36224,36050,2418,2307,2086,2685,2652,2710,6145,6029,6156,6638,6660,6722,6638,6722,6755,12135,12336,12146,12581,12833,12811,13429,13536,13786,28727,28589,28579,18846,18780,18782,18518,18780,18594,18485,18491,18376,19655,19537,19776,21586,21751,21483,23124,23040,23199,42158,42283,41669,42123,41880,42172,20120,19955,20204,37816,37951,37745,37963,37951,38024,1244,1245,1326,1291,1459,1299,1459,1350,1299,1163,1278,1352,7162,7395,7293,6769,6835,6997,17524,17368,17373,17201,17368,17250,42194,42036,41915,42076,41880,42056,41940,41809,41815,25993,25877,26124,34584,34420,34506,35417,35222,35159,37829,37839,38087,41599,41208,41313,41608,41432,41811,38025,38118,37927,38320,38179,38081,38269,38179,38320,38690,38893,38749,41823,41523,41749,2174,2365,2282,1740,1772,1857,6029,5927,6170,14859,14874,14986,13370,13244,13364,14859,14986,14977,26597,26779,26839,28955,28800,28952,36664,36425,36537,36677,36425,36664,37105,36956,37186,36416,36418,36409,11606,11901,11677,13244,13024,13102,13244,13394,13364,25993,26308,26040,40946,40757,40794,29434,28952,29210,30034,29917,29984,30507,30412,30429,30386,30412,30507,30248,30412,30386,1244,1326,1311,1022,1138,984,3162,3185,3205,3059,3084,3162,2925,2937,2793,23966,23539,23929,23581,23539,24020,30987,31180,30799,30486,30579,30371,30486,30371,30301,30486,30301,30444,29688,29452,29450,32395,32085,32864,34273,34122,34096,34223,34122,34273,1138,1088,1205,1022,1088,1138,1160,1236,1156,1156,1236,1184,2652,2854,2710,16566,15841,15992,17456,17446,17510,22674,22750,22714,23391,23692,23577,22539,22714,22402,35222,35124,35159,41849,41741,41750,42076,42056,42059,42211,42217,42158,2725,2736,2794,2794,2736,2889,3188,3141,3275,3102,3141,3188,3084,3185,3162,40302,39980,40150,39689,39670,39519,30069,29917,30034,35159,35124,35119,34506,34420,34304,38749,38893,39096,42419,42175,42090,35124,34999,35119,39906,39670,39689,2236,2174,2282,2145,2174,2236,38610,38434,38487,1194,1244,1311,1299,1350,1321,1278,1330,1443,1193,1330,1278,17368,17305,17373,17201,17305,17368,42060,41810,41928,41816,41642,41608,2631,2736,2619,2188,2145,2236,1824,1897,1895,1321,1350,1394,8893,8795,9602,8280,8156,8331,9743,9921,10154,10014,9921,9704,22750,22874,22858,22774,22874,22750,1187,1218,1273,1130,1218,1187,10566,10411,10446,10538,10411,10566,10538,10566,10701,12307,12430,12486,24532,24454,24412,23338,23692,23391,30883,30799,30745,42194,41915,42207,41915,41931,42207,7967,8094,7921,9704,9743,9562,7691,7703,7701,34415,34506,34304,33876,34076,33866,33983,34076,33876,42175,42179,42070,38335,38269,38320,38160,38118,38081,5184,5160,5277,4853,5134,3991,7595,7691,7701,12860,12772,12903,12860,12903,13024,25877,25993,26040,24532,24412,24059,29434,29364,29915,34957,34841,34779,34415,34304,34301,41608,41642,41549,41141,41133,41301,41823,41749,41961,2541,2652,2685,2541,2685,2550,11871,11992,12074,12336,12258,12414,11878,11992,11871,11878,11871,11691,40817,40378,40553,13105,13244,12993,1302,1413,1391,1620,1663,1701,7081,7085,7195,7049,7054,7081,6937,7054,7049,6937,7020,6519,34841,34665,34779,41942,41940,41815,41967,41849,41970,41955,41849,41967,18780,18516,18699,18518,18516,18780,20259,20120,20204,18097,18485,18376,18097,18376,18043,39758,39498,39519,39425,39322,39250,42179,42162,42087,1655,1639,1924,1701,1663,1800,1871,2042,1899,1701,1414,1620,26130,26044,25955,26901,26839,27332,1194,1311,1285,1321,990,1180,41942,41815,41839,1802,1824,1895,1772,1655,1924,2058,2030,2189,7293,7477,7496,7054,7085,7081,17446,17413,17510,27533,27428,27332,27763,27480,28063,11992,12135,12146,29279,29431,29444,29573,29431,29404,19848,19371,19509,1802,1895,2011,34708,34421,34817,32395,32864,33137,34779,34665,34697,34301,34304,34231,8223,8491,8440,38160,38081,38179,39360,39182,39247,38691,38636,38555,38434,38335,38320,38405,38160,38179,8280,8331,8454,38087,37839,37927,1017,1085,988,1110,1156,1184,1110,1269,1056,23125,23124,23199,21751,21538,21483,38491,38548,38429,38522,38548,38491,38522,38239,38433,28955,28719,28687,28561,28719,28740,34665,34584,34697,37186,36956,37200,37186,37200,37270,14999,15170,15184,13607,13774,13901,15826,16367,16104,38466,38335,38434,2086,2307,2204,2086,2204,2019,16104,16367,16600,40485,40697,40538,40710,40489,40607,40626,40489,40710,39737,39764,39548,41134,40474,40776,28561,28208,28515,1194,1285,1186,23692,23920,23778,23510,23920,23692,1533,1812,1633,1186,1285,1291,3084,2969,3185,3309,3473,3445,2925,2990,2997,2901,2990,2830,2937,2854,2758,17305,17177,17045,17201,17177,17305,24716,24532,24359,30579,30727,30745,30576,30486,30573,41882,41894,41785,42047,41894,41882,41955,41942,41839,41940,42207,41935,41955,41839,41849,1025,1085,1017,12206,12262,11851,30576,30727,30579,42162,42199,42087,7929,7995,8077,23470,23125,23326,21538,21376,21483,23470,23326,23539,22874,23131,23213,22917,23131,22874,34300,34301,34231,34602,34584,34506,34553,34301,34624,3445,3473,3570,4865,4624,4723,3071,3205,3185,7295,7496,7412,9921,10014,10209,9296,9168,8984,32153,32165,31887,29939,30069,30170,34223,33991,34122,37122,37186,37270,39448,39322,39425,41596,41704,41479,2758,2854,2652,29917,29939,29915,30248,30034,30144,31245,31194,31208,30727,30883,30745,31180,31201,31052,1639,1631,1758,1669,1655,1772,1663,1696,1867,1620,1696,1663,8351,8454,8409,8351,8280,8454,7978,7929,8174,26955,27028,26703,27997,28211,28147,29465,29450,29431,26308,26521,26524,26639,26521,26479,26595,26521,26639,2618,2758,2652,12307,12262,12430,38226,38160,38403,38118,38087,37927,10312,10377,10241,11992,11957,12135,12486,12430,12566,13244,13105,13024,13607,13901,13773,6447,6587,6555,6338,6217,6587,6145,6093,6029,6029,6001,5927,5927,5832,5808,6447,6555,6467,6447,6467,6372,6217,6157,6145,34602,34506,34553,1625,860,999,1163,1193,1278,1212,1302,1391,6157,6093,6145,6769,6997,6863,17820,18097,18043,17446,17297,17413,23131,23318,23262,23255,23318,23131,42479,42136,41592,42211,42158,42134,42065,42076,42059,42065,42059,42036,27648,27428,27533,27648,27533,27664,2736,2631,2833,2174,2058,2189,2725,2910,2783,11632,11878,11691,12135,12258,12336,29465,29688,29450,29465,29431,29573,27873,27763,28063,38405,38179,38269,38749,38636,38691,38610,38636,38770,41034,41085,40896,40905,41014,40794,40457,40302,40339,41141,41034,41133,41593,41464,41536,41018,41134,40776,41018,40776,40908,6093,6001,6029,5162,4774,5118,7847,7929,7818,7241,7181,7293,8906,9296,8984,25364,25337,25612,26955,26703,26600,31284,31245,31537,31166,31201,31180,34385,34223,34273,34965,34223,34385,41894,41909,41785,42003,41909,41894,42211,42134,42205,6001,5928,5927,38610,38466,38434,2079,2042,1871,14082,13901,14081,41085,41014,40896,40908,40855,40664,3800,3665,3972,2783,2963,3012,3761,3824,4081,5278,4774,5162,32165,32090,31887,33137,32864,33991,1824,1740,1897,1802,1740,1824,26595,26955,26600,41195,41340,40571,1623,1631,1639,1533,1631,1559,5928,5832,5927,35478,35450,35417,35478,35583,35450,35450,35583,35470,35948,35994,36139,36198,36416,36224,36224,36416,36255,35478,35417,35589,35417,35159,35261,2465,2550,2481,2465,2541,2550,14944,14999,15440,16346,16104,16600,28589,28363,28579,34936,34708,34817,1625,1711,860,20687,20787,20638,42205,42134,42176,7978,8174,8156,9583,8893,9602,17763,18043,17784,19895,19955,20120,20446,20651,20638,20572,20651,20446,20240,20120,20259,20651,20687,20638,23318,23338,23391,24716,24914,24532,23255,23338,23318,31201,31435,31286,34000,33423,33768,37951,37963,37893,37951,37816,38024,42178,42065,42194,42176,42134,42123,42245,42325,42113,42595,42285,42175,42175,42285,42179,42179,42391,42162,42162,42303,42199,42270,42325,42245,42270,42245,42256,42270,42256,42539,12993,12860,13024,12749,12860,12767,20130,19969,19979,20278,20145,20130,20670,20403,20549,20665,20403,20670,20670,20828,20855,21129,21133,21216,21129,21216,21289,42325,42314,41958,6863,6997,6979,6997,7162,6979,19545,19369,19537,20687,20930,20787,35119,34999,34957,42314,42300,41912,42283,42158,42310,1186,1291,1203,1244,1173,1245,984,1146,1025,1291,1299,1203,17693,17763,17784,17413,17297,17245,16926,17234,16900,24534,24228,24337,9583,9083,8893,19537,19369,19258,42300,42279,42127,2127,2145,2098,1709,1802,2011,41014,40946,40794,41029,40908,40664,20235,20145,20278,19102,19537,19258,22571,22676,22503,14183,14082,14418,14977,14999,14944,26788,26597,26839,26211,26044,26130,26521,26595,26600,26124,26308,25993,3659,3665,3800,6979,7162,6964,15841,15296,15583,32185,32090,32165,31606,32061,31934,39103,38804,38712,39391,39562,39548,39103,38712,38882,42310,42158,42217,42176,42123,42269,41961,41749,41990,41685,41593,41536,2447,2465,2481,12486,12566,12772,7691,7621,7875,8094,8148,8440,7085,7595,7701,35026,35119,34957,34553,34506,34415,34553,34415,34301,20145,20009,20130,18350,17829,18516,1131,1130,1187,1106,1130,1131,22571,22672,22676,23581,23470,23539,7181,7162,7293,7085,7040,7595,7054,7063,7085,6185,6715,6159,20009,19969,20130,18925,19033,19258,23040,22906,22900,3824,3659,3800,5278,5354,5086,2990,2969,3084,2901,2969,2990,2743,2925,2793,3071,2969,2841,2730,2758,2666,10901,10734,10891,9732,9194,9083,11204,11001,11606,10892,10908,10842,30883,30987,30799,31543,31488,31435,30831,30987,30883,30486,30576,30579,30159,30301,30048,30159,29943,30163,39836,39906,39689,39616,39425,39498,39448,39360,39322,40113,39742,39980,40113,39980,40203,22539,22674,22714,22603,22674,22539,42310,42217,42211,42172,41880,42076,1165,1173,1244,1203,1299,1180,1163,1352,1218,1355,1213,1450,2249,2752,2418,1871,1899,1604,14418,14577,14298,13607,13567,13761,17400,17413,17245,17693,17784,17574,19969,19885,19979,23040,23124,22906,30265,30159,30223,38636,38610,38487,38405,38269,38335,38577,38610,38667,38433,38239,38253,41134,41195,40474,41550,41195,41134,41136,41134,41018,42100,42060,41928,41989,41811,41823,8689,8399,8658,7978,8156,7950,7241,7293,7295,1686,1899,1881,15296,15203,15282,1927,2044,2092,14082,13773,13901,28208,27873,28063,27763,27648,27664,26901,26788,26839,27747,27873,27804,27873,27956,27804,11204,11606,11677,12749,12486,12772,12749,12772,12860,40489,40626,40485,40697,40626,40816,2022,2188,2455,3126,2942,2825,7595,7621,7691,8667,8984,8817,7849,7621,7494,30069,29939,29917,30248,30144,30412,30717,30883,30727,31435,31488,31432,35026,34957,34779,34300,34231,34076,39322,39360,39247,39448,39425,39609,22906,23124,23187,24020,23539,23966,1241,1391,1330,1696,1686,1881,41942,42019,41940,41849,41750,41970,41832,41652,41704,41832,41704,41787,18925,18928,19033,38882,38712,38899,39565,39562,39391,23124,23125,23187,22674,22774,22750,22793,22774,22674,2127,2102,2174,2127,2174,2145,13709,13567,13607,2725,2619,2736,30987,31166,31180,41787,41704,41596,7659,7801,7719,35026,34779,34891,1165,1244,1139,1180,1299,1321,1193,1241,1330,1136,1241,1193,1198,1394,1420,1740,1669,1772,1594,1669,1740,14999,14977,14986,14727,14977,14944,26444,26130,26403,27444,27332,27428,42060,42047,41882,42251,42047,42060,10014,10312,10241,11839,11957,11878,10288,10312,10014,11878,11957,11992,13951,14126,14310,12110,11957,11839,39565,39391,39600,860,1711,1455,984,1138,1146,1146,1085,1025,12504,12749,12596,11851,12262,12307,42419,42090,42165,42199,42362,41515,42373,42100,41937,1053,1100,1689,1130,1163,1218,939,1100,1053,21376,21402,21483,23187,23125,23275,22774,22917,22874,24532,24059,24359,22793,22917,22774,7847,7801,7929,18516,17829,18039,17177,17056,17045,18780,18688,18594,34697,34584,34602,37186,37122,37105,37169,36816,36639,36269,35023,35099,37270,37200,37315,37270,37315,37353,38226,38118,38160,38476,38335,38466,8031,8148,8094,32445,32364,32357,34624,34697,34602,32099,32054,32090,32090,32054,31887,30386,30507,30463,32185,32165,32395,26444,26403,26597,24586,24534,24337,24063,24020,23966,41685,41536,41642,41811,41432,41823,25770,25612,25863,4055,3974,4045,3884,3974,3841,18925,18863,18928,24532,24914,24454,23510,23692,23338,42008,42019,41942,42211,42205,42318,41970,41750,41715,29895,29434,29915,31225,31435,31201,1338,1570,1225,26644,26444,26597,32347,32357,32234,32347,32232,32061,18846,19087,18688,1217,988,1085,8156,8038,7950,8229,8216,8399,10279,10446,10411,27194,27361,27231,27339,27361,27194,27088,27194,26955,26806,26955,26595,27747,27648,27763,26788,26644,26597,27747,27763,27873,37534,37558,37595,38577,38476,38466,38577,38466,38610,38899,38712,38548,38475,38433,38253,41014,41130,40946,41138,41085,41034,41317,41133,41229,41749,41771,41990,8280,8351,8216,1244,1194,1139,1533,1633,1631,17250,17368,17524,14690,14727,14760,1194,1186,1139,1108,1163,986,2102,2058,2174,1936,2058,2102,1920,2019,2044,2044,2019,2204,1920,2044,1927,1920,1927,1852,5871,6185,6159,6447,6338,6587,6217,6141,6157,6003,5962,6093,6093,5962,6001,6001,5933,5928,5928,5854,5832,6372,6338,6447,6555,6638,6467,6390,6388,6467,6390,6467,6638,6449,6638,6769,12767,12860,12770,13773,13709,13607,13680,13709,13773,14052,13773,14082,17574,17510,17559,17693,17574,17559,18925,18746,18863,17510,17400,17559,27750,27964,27654,30265,30301,30159,35470,35583,35620,35843,35615,35620,35843,35994,35772,37939,37816,37789,35583,35630,35620,41203,41085,41138,40302,40150,40339,6863,6979,6964,1217,1160,988,5368,5354,5520,6035,6093,6157,6964,7162,7016,35583,35478,35630,36198,36224,36139,38596,38561,38433,5766,5808,5832,8148,8223,8440,8167,8223,8148,3665,3543,3748,3634,3659,3824,31068,31011,31245,32099,32185,32216,39963,39906,39836,40553,40749,40817,2465,2523,2541,1987,2418,2086,38770,38636,38749,39616,39498,39758,11001,10892,10901,11851,12052,11880,31166,31225,31201,31243,31225,31166,30576,30717,30727,30573,30717,30576,30265,30223,30444,3126,3152,2942,2725,2636,2619,2188,2236,2455,29939,29895,29915,31068,31245,31284,30159,30163,30223,1610,1686,1696,2898,2631,2272,27975,28211,27997,2969,3071,3185,2730,2793,2758,10892,10734,10901,40097,39906,39963,42391,42303,42162,42310,42211,42318,42172,42076,42178,5933,5854,5928,5138,5348,5277,35261,35159,35119,2618,2652,2594,42008,41942,41955,41832,41970,41715,42022,41970,41832,24577,24534,24586,25840,25770,25863,25840,25863,26044,1623,1639,1655,1623,1655,1669,5160,5138,5277,4977,4853,4865,4977,4865,5047,25862,25628,25584,867,1160,1156,1139,1186,1147,5854,5766,5832,10734,10538,10701,18746,18550,18863,17510,17413,17400,25364,25612,25661,23275,23125,23470,31930,31785,32054,42008,41955,41999,42248,42388,42278,41996,41771,41909,2523,2652,2541,40817,40749,40984,1269,1245,1056,25679,25364,25661,41927,41787,41914,41787,41596,41914,42303,42307,42199,23275,23470,23362,21289,21402,21376,39737,39565,39755,38722,38548,38522,42178,42076,42065,5081,5138,5160,35348,35261,35374,34624,34602,34553,9298,9979,9596,8795,8644,8689,9296,9262,9502,8667,8817,8499,38438,38405,38335,37595,37558,37829,39289,39182,39360,38433,38561,38522,38111,37893,37963,1523,1623,1669,1620,1610,1696,1500,1610,1620,2597,2631,2619,32099,31930,32054,40626,40697,40485,40908,41136,41018,39633,40414,39685,31537,31440,31484,32437,32347,32061,31243,31166,30987,12378,12307,12486,11546,11851,11761,39633,39729,40414,4672,4573,4908,4004,4573,4120,37862,37536,37970,34060,34000,34095,31606,31742,31488,42318,42205,42176,5766,5628,5754,14690,14874,14859,12504,12486,12749,27648,27444,27428,25874,25840,26044,27686,27444,27648,28561,28515,28719,27361,27750,27654,27964,27975,27997,27835,27750,27630,7016,7181,7135,8216,8351,8399,8446,8667,8499,7921,8094,7875,7921,7875,7849,7063,7054,6937,38035,37862,37970,1756,2011,2030,1971,2030,2058,1971,2058,1936,38438,38335,38476,41474,41317,41229,41141,41203,41138,1147,1186,1203,1056,1245,1103,1147,1203,1180,18485,18550,18746,17400,17245,17289,24288,24020,24063,1245,1173,1103,1100,1106,1131,1021,1106,939,16292,16583,16566,22197,21751,22434,23362,23470,23581,22967,23255,23131,22967,23131,22917,41811,41816,41608,41599,41313,41754,42003,41894,42133,4977,5081,5184,5138,5028,5871,38087,38118,38226,39758,39519,39670,38620,38476,38577,39562,39737,39548,39391,39153,39600,17201,17056,17177,14977,14727,14859,17172,17056,17201,16933,17056,17060,42133,41894,42047,42194,42065,42036,41999,41955,41967,41999,41967,42159,2446,2465,2447,2446,2523,2465,11957,12110,12135,16416,16685,16583,11156,11293,11020,27835,27975,27964,28579,28363,28326,860,1455,643,7016,7162,7181,7181,7241,7135,18300,18550,18485,35261,35119,35148,25770,25679,25661,26211,26130,26444,25820,25862,25725,26479,26521,26308,25305,24741,24914,15314,15440,14999,27277,26901,27332,1623,1559,1631,885,1147,1180,1444,1559,1398,3659,3543,3665,3443,3543,3659,3884,4081,3974,12530,12811,12414,26337,26211,26444,28579,28326,28455,40984,40749,40946,41130,41014,41085,41899,41816,42043,7135,7241,7122,6931,7063,6937,831,988,1160,18097,18300,18485,31543,31606,31488,13123,13383,13429,41931,41935,42207,42269,42318,42176,20855,20828,20950,20403,20235,20278,20145,20087,20009,20009,19993,19969,19969,19991,19885,19885,19848,19509,20855,20950,21129,20855,21129,21113,21244,21402,21289,4573,4526,4677,4328,4526,4004,20687,20957,20930,20930,21712,20787,20651,20666,20687,20404,20572,20446,20404,20446,20361,20404,20361,20369,20361,20259,20369,20259,20225,20369,20204,20225,20259,19955,20062,20204,19956,20062,19955,12110,12258,12135,19745,19956,19955,22731,22676,22672,38561,38722,38522,39600,39813,39828,38638,38722,38561,42100,42071,42060,42248,42071,42100,7967,8031,8094,7865,8031,7967,19976,20041,19956,20918,20957,20687,38111,38475,38253,37862,37939,37789,37966,37939,38035,20260,20235,20403,20957,21075,20930,26854,26644,26788,26282,26308,26124,2793,2730,2743,2830,2925,2743,2830,2990,2925,5047,4927,5058,20235,20205,20145,30717,30831,30883,31225,31543,31435,30444,30573,30486,30444,30301,30265,1302,1213,1355,1136,1212,1391,1136,1391,1241,1213,1212,1014,2666,2758,2618,5628,5368,5629,7719,7801,7847,11020,11293,10922,12110,12199,12258,17056,16933,17045,16864,16933,16905,30248,30170,30069,29039,28719,28955,30463,30507,30723,30997,30808,31068,29943,29965,30163,36677,36664,36816,36430,35576,36425,34708,34946,34385,34408,33137,33991,37353,37122,37270,42003,41996,41909,41961,41989,41823,42141,41996,42003,42207,41940,42019,42159,41967,41970,18043,17763,17820,19757,19976,19956,22616,22603,22539,42269,42123,42172,20205,20087,20145,38405,38403,38160,38620,38438,38476,39390,39360,39448,38596,38475,38570,42279,42419,42165,42285,42391,42179,42303,42375,42307,42455,42419,42279,42488,42279,42300,42488,42300,42314,42488,42314,42325,42488,42325,42560,42390,41926,42496,41926,42283,42496,3023,3102,3356,2783,2636,2725,20087,19993,20009,19258,19033,19102,22731,22780,22676,31101,30997,31068,31127,31068,31284,1103,1173,1165,857,922,988,23255,23510,23338,23144,23510,23255,39674,39390,39448,12833,13075,12811,13007,13075,12884,29039,28955,29434,28727,29020,28589,28696,28579,28584,2563,2636,2513,2594,2666,2618,11851,11546,11677,10456,10538,10537,10456,10279,10538,13105,12993,13024,13656,14126,13951,13536,13429,13383,40302,40332,39980,39705,39758,39953,39884,39758,39670,39616,39609,39425,40464,40332,40302,41317,41301,41133,41239,41301,41378,4853,4977,5127,5081,5085,5138,5047,5058,5081,7818,7719,7847,7818,7929,7978,13364,13567,13417,12581,12530,12371,12258,12530,12414,19993,19991,19969,19102,19033,18989,22676,22780,22677,26152,25874,26044,25748,25679,25770,25229,25047,25209,24534,24288,24063,26152,26044,26211,41834,41685,41642,41834,41642,41816,1936,2102,1915,1398,1559,1389,2098,2145,2188,2019,1987,2086,2397,2594,2652,1852,1927,1773,1927,1871,1763,27956,27873,28208,27747,27686,27648,26929,26854,26901,26901,26854,26788,41239,41203,41141,17727,17763,17693,17393,17400,17289,22731,22906,22780,23134,23187,23275,31461,31127,31284,42401,42283,42310,26310,26337,26668,26668,26337,26444,26253,26282,26124,8031,8167,8148,8085,8167,8031,33983,34135,34076,34697,34891,34779,34106,34000,34060,37939,38024,37816,37966,38024,37939,40578,40457,40339,14727,14690,14859,13417,13567,13709,15951,15826,16104,1909,1987,2019,13361,13536,13383,21522,21538,21651,41374,41130,41085,40522,40464,40457,41178,41136,40908,41830,41384,41766,40778,40538,40697,16933,16864,17045,17250,17524,17407,6141,6338,6247,6034,6141,6247,6338,6141,6217,5962,5933,6001,5854,5587,5766,5766,5587,5628,5227,5086,5368,6338,6372,6247,6372,6467,6388,7000,6964,7016,10538,10279,10411,10842,10734,10892,35994,36198,36139,38035,37939,37862,36159,36198,35994,36159,35994,35843,36033,35843,35620,40097,39963,40113,39565,39737,39562,39153,39103,39298,6141,6035,6157,7412,7496,7659,7135,7000,7016,35143,34936,34817,34944,34891,34894,35589,35630,35478,37475,37353,37315,37475,37315,37504,16864,16346,16600,22603,22793,22674,22679,22793,22603,38859,38770,38749,3841,3974,4055,2942,3141,3102,6035,6003,6093,8906,9262,9296,10922,10917,10527,9289,9040,9212,6003,5933,5962,12504,12378,12486,14052,14082,14183,40816,40778,40697,40489,40365,40607,14808,14944,15440,4201,4247,4677,8893,8828,8795,8871,8828,8893,1001,1103,1165,1554,1812,1140,2022,2098,2188,6185,6519,6715,7849,7875,7621,6937,6481,6782,6519,6481,6937,41130,40984,40946,39705,39609,39616,38728,38610,38770,39755,39828,39941,7122,7000,7135,7719,7412,7659,7310,7412,7276,18518,18350,18516,18846,19064,19087,18989,19033,18928,17727,17693,17721,22793,22886,22917,22818,22886,22793,35589,35417,35348,36639,37105,37169,35147,34946,34936,42412,42269,42172,42369,42401,42310,42287,42172,42178,922,1017,988,1001,1165,1139,8229,8399,8238,15282,15203,14933,17721,17559,17532,42126,42019,42008,2326,2446,2447,25748,25840,25847,25748,25770,25840,35348,35417,35261,38620,38403,38438,38438,38403,38405,1140,1812,1533,1212,1213,1302,1136,1193,1107,41996,41990,41771,42239,41990,41996,42307,42370,42199,42251,42133,42047,42595,42391,42285,1920,1931,2019,1987,2249,2418,1763,1871,1677,1407,1686,1610,27861,27686,27747,27861,27747,27804,1414,1701,1365,1677,1871,1604,14355,14577,14690,14355,14298,14577,26282,26479,26308,26946,27088,26955,28455,28211,28478,28455,28326,28211,26253,26479,26282,26253,26124,26142,4672,4774,4120,4781,4774,5278,4526,4201,4677,8150,8499,8223,7040,7085,7063,25001,25305,24914,24059,23920,24359,1658,1931,1920,18594,18497,18518,18688,18497,18594,22886,22967,22917,22994,22967,22886,28095,27956,28208,28579,28696,28727,28455,28478,28584,37169,37105,37122,40903,40894,40778,40778,40894,40538,959,935,1025,1025,935,984,984,935,1022,1455,1205,645,959,1025,1017,959,1017,922,2942,3152,3141,2636,2597,2619,2942,2604,2825,11156,11290,11594,10922,10527,10814,26806,26595,26639,40370,40203,39980,39758,39705,39616,40370,39980,40332,1073,1193,1163,1163,1130,986,3023,3356,3543,10814,10527,10714,16864,16674,16346,17094,17250,17407,40190,40097,40113,3715,5134,4013,2830,2760,2901,2634,2743,2730,2634,2730,2566,11099,11290,11156,30684,30831,30573,30573,30831,30717,29573,29688,29465,12596,12378,12504,12596,12749,12767,17721,17693,17559,16685,16900,16583,35148,35119,35026,3884,3761,4081,3775,3761,3884,13680,13417,13709,34408,33991,34646,32185,32099,32090,31930,31851,31484,38728,38667,38610,39289,39360,39390,26929,26901,27100,25847,25840,25874,26799,26806,26639,41313,41464,41754,41301,41239,41141,41203,41374,41085,41130,41128,40984,41464,41877,41754,2563,2597,2636,2397,2652,2523,11306,11632,11691,12530,12581,12811,13075,13123,13429,40457,40464,40302,40578,40378,41027,40414,40499,40621,40414,40621,40544,8038,8156,8280,8038,8280,8216,34000,34135,33983,35200,35148,35026,34106,34135,34000,4977,5047,5081,3715,4013,3959,6890,6931,6782,16292,16566,15992,25229,25209,25364,23658,23362,23581,25679,25374,25364,26152,26211,26310,34522,34624,34301,37653,37595,38132,37209,37169,37122,41899,41834,41816,1156,1110,1023,1559,1444,1533,1594,1740,1618,26060,26152,26218,42391,42375,42303,42369,42310,42318,3761,3634,3824,8828,8644,8795,8597,8644,8677,8150,8223,8167,17250,17172,17201,17094,17172,17250,42251,42060,42071,41990,41980,41961,1021,1130,1106,2446,2409,2523,1891,2249,1987,12770,12596,12767,12371,12530,12258,18300,18646,18550,17393,17559,17400,28561,28468,28208,29251,29039,29434,28937,29020,28727,28937,28727,28696,13007,13123,13075,14422,14441,14126,14126,14441,14310,28486,28468,28537,28211,28442,28478,12052,11851,12307,11546,11204,11677,12052,12307,12224,11778,11839,11878,25607,25374,25679,40522,40578,40640,41787,41927,41832,41999,42126,42008,41756,41384,41830,1023,1110,1056,7122,7241,7295,7122,7295,7211,35258,35148,35200,18497,18350,18518,18170,18350,18497,39609,39674,39448,40033,39670,39906,39600,39755,39565,39298,39103,38882,41378,41301,41425,40471,40472,40501,9562,9743,9502,9562,9289,9421,32273,32185,32395,39623,39289,39390,2333,2409,2446,12224,12307,12378,13656,13951,13536,18989,18928,18806,18928,18863,18806,42375,42370,42307,42548,42369,42580,42483,42318,42269,7310,7295,7412,8229,8038,8216,7865,8085,8031,7865,7967,7921,38024,38072,38111,38963,38899,38994,38722,38899,38548,37056,37536,37862,7310,7276,7211,1629,1618,1802,1915,2102,2127,1998,2127,2098,1931,1909,2019,1823,1909,1931,1734,1920,1852,1773,1927,1763,3761,3577,3634,4247,3841,4055,3830,3841,3720,38596,38433,38475,38667,38620,38577,38426,38087,38226,38859,38728,38770,42069,41980,41990,41988,42022,41832,1136,1099,1212,1108,1073,1163,982,1073,1108,969,1023,1056,969,1056,1103,969,1103,924,939,1106,1100,939,1053,999,17172,17060,17056,14808,14760,14944,17094,17060,17172,24774,24577,24586,24774,24586,25047,29039,28740,28719,40938,40903,40778,40894,41029,40664,41995,41832,42018,42251,42141,42133,42133,42141,42003,42159,42126,41999,42194,42287,42178,15583,15753,15841,15603,15753,15583,25055,24774,25047,25748,25607,25679,25921,25847,25874,25921,25874,26060,41834,41779,41685,41954,41779,41834,1618,1740,1802,14944,14760,14727,13286,13370,13398,14609,14760,14665,26310,26211,26337,27277,27332,27444,27551,27444,27686,27551,27686,27713,27804,27956,27861,27835,27964,27750,26806,26946,26955,26799,26946,26806,26419,26639,26479,18646,18863,18550,1389,1559,1623,1444,1140,1533,4328,4201,4526,25881,26124,25862,38623,38620,38667,38648,38596,38570,2022,1998,2098,13417,13370,13364,12168,12224,12378,14052,14183,14194,13211,13361,13383,13211,13383,13123,2283,2326,2447,2283,2447,2249,12168,12378,12254,40607,40365,40442,40097,40078,39906,40203,40190,40113,40239,40190,40203,40472,40332,40464,11761,11880,11753,11761,11851,11880,11074,11204,11049,6035,6034,6003,6003,5810,5933,5933,5587,5854,6141,6034,6035,6247,6372,6231,6449,6390,6638,6388,6390,6316,10908,10892,11001,8985,9083,9194,10922,10994,11020,11298,11306,11290,11290,11306,11594,11632,11778,11878,10714,10527,10288,30684,30573,30541,31606,31831,32061,30573,30444,30541,36198,36378,36416,36140,36159,35843,36166,36159,36140,35722,35630,35589,35603,35589,35348,40240,40078,40097,9692,10288,10014,9684,9655,9692,23658,23581,24020,21435,21376,21538,32380,32273,32395,42393,42287,42194,42370,42362,42199,31976,31930,32099,31976,31851,31930,30463,30723,30997,30463,30170,30386,30386,30170,30248,29039,28958,28740,11298,11290,11099,12722,12833,12581,12884,13075,12833,31101,31068,31127,20572,20666,20651,20957,20970,21075,21075,21712,20930,20399,20666,20572,20399,20572,20404,20399,20404,20369,20225,20204,20222,20204,20062,20222,20062,20041,20222,1073,1107,1193,1338,1742,1570,982,1107,1073,6372,6388,6316,38426,38226,38403,37966,38072,38024,38114,38072,37966,39705,39674,39609,40078,40033,39906,42248,42100,42388,20666,20918,20687,42560,42325,42603,42419,42595,42175,42647,42493,42375,42375,42493,42370,42370,42542,42362,42325,42270,42603,42496,42283,42401,6449,6374,6390,7818,7978,7950,37504,37315,37534,37504,37534,37615,20087,20083,19993,19993,20083,19991,19991,19919,19885,20205,20083,20087,20235,20260,20205,20327,20260,20403,20518,20403,20665,20518,20665,20717,21113,21129,21289,21113,21289,21351,21289,21376,21435,20062,19956,20041,2597,2530,2631,2678,2636,2783,2530,2563,2513,2783,2825,2678,40522,40472,40464,41128,40817,40984,40428,40565,40442,39729,39764,40050,41980,41989,41961,42069,41989,41980,42069,41990,42234,41995,41988,41832,42022,42159,41970,41340,41776,41837,23794,23658,24020,25229,25364,25374,10537,10538,10734,40033,39884,39670,13370,12993,13244,11993,12110,11839,19745,19757,19956,22677,22503,22676,20970,21138,21075,29404,29431,29279,28455,28584,28579,27750,27361,27630,40903,41029,40894,41194,41029,40903,42488,42455,42279,2187,2283,2077,22967,23144,23255,22406,22539,22402,40710,40816,40626,40938,40816,40967,1909,1935,1987,1677,1773,1763,7898,7818,7950,7898,7950,8038,8085,8150,8167,7494,7621,7595,20260,20083,20205,27861,27956,27884,34135,34300,34076,35258,35261,35148,34347,34300,34135,34095,34115,34060,14609,14355,14690,12788,12827,12993,28095,28208,28420,27477,27361,27339,38620,38623,38403,38774,38623,38667,38869,38859,38749,1001,1139,1147,890,857,988,1001,1147,885,11610,11753,11543,11880,12052,12069,11670,11778,11632,19745,19537,19757,40544,40565,40428,2832,2942,3102,3841,3775,3884,3830,3775,3841,26060,25874,26152,25320,25229,25374,26644,26854,26853,27270,27108,27281,25820,25881,25862,26142,25881,26136,41302,41134,41136,32228,31976,32099,31851,31537,31484,5058,5085,5081,3445,2774,3309,19757,19703,19762,37615,37534,37595,38596,38638,38561,38648,38638,38596,42043,41816,42112,41464,41593,41877,41374,41203,41239,1500,1407,1610,1570,1450,1225,14933,15203,14842,17820,17763,17727,17289,17245,16926,17532,17393,17364,15886,15992,15753,42126,42207,42019,42551,42207,42126,1823,1935,1909,14760,14609,14690,15314,15826,15557,22780,22906,23114,22616,22679,22603,22818,22679,22616,28420,28208,28468,36816,36869,36677,35147,34936,35143,36931,36869,36816,37122,37353,37209,20083,19919,19991,21522,21435,21538,8597,8689,8644,8597,8399,8689,2409,2397,2523,2634,2760,2743,2333,2397,2409,2333,2446,2326,11735,11993,11839,29404,29279,29252,40565,40607,40442,19919,19848,19885,21580,21522,21651,31924,31537,31851,31243,31543,31225,17060,16905,16933,16942,16905,17060,12827,12770,12860,12827,12860,12993,12621,12722,12581,28537,28468,28561,28964,28958,29039,28697,28937,28696,29057,28937,28975,1021,986,1130,945,986,1021,8677,8644,8828,25607,25748,25786,42150,42159,42022,42018,41832,41927,19087,19064,19371,17407,17524,17829,17820,17727,17721,19864,19757,19762,21580,21510,21522,23114,22906,23187,23114,23187,23134,1398,1360,1444,1503,1523,1669,1503,1669,1594,2030,1971,1756,2851,2969,2901,13361,13328,13536,14725,14933,14842,13007,13211,13123,12830,13211,13007,14725,14842,14441,19079,19102,18989,37209,37353,37470,37653,37615,37595,41282,41128,41130,41646,41317,41474,41883,41685,41779,35258,35374,35261,35026,34891,35200,9562,9684,9704,9684,9562,9421,8793,8906,8634,31976,31967,31851,32273,32216,32185,32239,32216,32273,2180,2333,2326,2187,2326,2283,12080,12199,12110,29252,29279,29020,793,1088,1022,793,1022,935,793,935,839,21386,21712,21075,42248,42251,42071,42012,41954,41899,42278,42251,42248,1225,1450,1213,1685,1734,1773,1099,1136,1026,25965,25748,25847,26853,26854,26929,15680,15886,15753,15320,15583,15282,42528,42496,42557,42448,42401,42369,17843,17820,17721,18182,17820,17843,23610,23658,23794,23431,23658,23610,35200,34891,34944,37353,37475,37470,1935,1891,1987,1773,1734,1852,1899,1686,1604,2743,2760,2830,2730,2666,2566,2666,2594,2566,2711,2851,2901,11074,10908,11204,11204,10908,11001,10842,10537,10734,14194,14183,14298,14194,14298,14355,29931,29895,29939,31058,30463,30997,31152,31243,30987,30541,30444,30506,29680,29688,29573,1407,1500,1361,2566,2594,2350,10756,10994,10922,11520,11670,11632,11778,11735,11839,11993,12080,12110,10288,10527,10312,11099,11156,11020,12722,12884,12833,12830,12884,12722,34891,34697,34894,32364,32445,32772,38570,38475,38111,37970,37536,38123,14052,13680,13773,12247,12371,12258,12247,12258,12199,29563,29680,29573,29070,29252,29020,29057,29020,28937,1756,1971,1782,15886,16292,15992,26946,27108,27088,28697,28696,28584,26305,26479,26253,42150,42022,41988,42236,42018,41927,2634,2566,2585,10605,10537,10842,8961,9083,8985,31233,31101,31127,31461,31284,31537,40472,40471,40332,40190,40240,40097,40078,40052,40033,40033,40061,39884,40522,40457,40578,6931,7040,7063,6942,7040,6931,6931,6937,6782,5028,5138,5085,34522,34301,34300,37470,37475,37504,775,939,477,22852,22994,22886,22818,22793,22679,42408,42412,42172,42408,42172,42407,32228,31967,31976,32405,32380,32395,1998,1915,2127,1952,1915,1998,1823,1891,1935,41272,41178,40908,41302,41178,41304,40938,40778,40816,2563,2530,2597,2678,2825,2604,11761,11610,11546,12069,12052,12224,11520,11632,11416,30161,29939,30170,31152,30987,30831,32772,32445,32347,40640,40889,40729,1389,1360,1398,1442,1503,1594,5058,5025,5085,3481,4052,3473,14368,14194,14355,15951,16104,16346,27100,26853,26929,27277,27444,27551,27713,27686,27861,34625,34522,34300,23134,23275,23362,21538,22197,21651,42540,42448,42369,42407,42172,42287,42407,42287,42477,34760,34743,34682,32772,32437,32917,38035,38114,37966,38133,38114,38035,41899,41954,41834,41816,41811,42112,1389,1623,1390,12444,12621,12371,12371,12621,12581,25881,26142,26124,25862,25584,25725,28211,27975,28112,29514,29573,29404,29514,29404,29318,40834,40816,40710,41756,41914,41596,41766,41189,41340,25229,25055,25047,23431,23134,23362,24954,25055,25024,42239,41996,42141,42150,41988,41995,42150,41995,42236,1888,2022,1818,28732,28561,28740,27884,27713,27861,28732,28740,28958,28602,28478,28442,42483,42269,42432,3775,3694,3761,3720,3841,4247,3694,3830,3720,31633,31606,31543,38899,38963,38882,38829,38899,38722,38779,38722,38638,36159,36166,36198,36140,36085,36200,35843,36085,36140,35348,35374,35603,6316,6231,6372,6247,6134,6034,6034,5810,6003,7037,7000,7122,7310,7211,7295,7479,7412,7719,7479,7719,7463,34894,34697,34624,35603,35374,35449,35374,35258,35449,37618,37504,37615,37618,37470,37504,6501,6449,6769,6621,6501,6769,12168,12069,12224,12378,12596,12508,11735,12080,11993,14052,13913,13680,13286,12993,13370,14368,14355,14609,18182,18300,18097,18803,18806,18863,18182,18097,17820,22503,22197,22434,23431,23362,23658,22994,23144,22967,23099,23144,22994,27339,27194,27088,27630,27477,27473,29318,29404,29252,31627,31633,31543,38774,38667,38728,37653,37618,37615,38860,38728,38859,38869,38749,39096,38312,38111,38072,42432,42269,42412,42393,42194,42387,42542,42493,42748,42373,41937,42136,1856,1936,1915,1782,1971,1936,1393,1458,1503,27884,27956,28021,41465,41301,41491,40640,40501,40522,41646,41474,41599,1501,1629,1802,1458,1623,1523,13370,13417,13398,28486,28420,28468,28964,28732,28958,35270,35258,35200,34743,34894,34624,34743,34624,34522,7956,8150,8085,7865,7921,7849,867,1156,1023,922,839,959,920,904,876,969,906,1023,912,982,1108,912,1108,986,4004,4526,4573,5086,5354,5368,14933,15059,15282,16033,16416,16292,14422,14725,14441,13328,13361,13211,13328,13079,13209,41754,41646,41599,924,906,969,18803,18863,18646,17532,17559,17393,983,1136,1107,2835,3329,3071,2760,2711,2901,2642,2711,2760,2642,2760,2634,2642,2634,2585,2841,2969,2851,12131,12285,12080,11298,11262,11306,10756,10922,10814,10756,10814,10714,12080,12247,12199,13572,13328,13387,12285,12247,12080,15948,15951,16225,18170,17829,18350,25725,25584,25305,27339,27088,27108,29943,29688,29965,30506,30444,30223,31100,31152,30831,31627,31676,31633,40370,40332,40471,40379,40239,40203,39953,39674,39705,41213,41194,40903,40607,40834,40710,40912,40834,40607,40721,40607,40565,40544,40428,40414,39764,39737,39941,41954,41883,41779,42147,41883,41954,42035,41914,41756,42035,41756,41830,2711,2841,2851,10658,10756,10714,2022,1952,1998,1888,1952,2022,3443,3659,3634,1855,1856,1952,13656,13328,13572,40501,40472,40522,40534,40370,40471,1338,1365,1701,1309,1365,1338,755,890,988,40240,40052,40078,29251,28964,29039,30255,30161,30170,30255,30170,30463,29965,29688,29785,1011,1225,1213,35270,35200,35096,36869,36726,36677,37169,36931,36816,37230,36931,37169,37217,37169,37209,37595,37829,38132,37411,37217,37209,30874,30831,30684,39096,38893,39270,30161,29931,29939,29785,29688,29680,40507,40501,40642,39941,39737,39755,3830,3694,3775,3637,3694,3720,1361,1500,1414,1677,1685,1773,1747,1823,1931,14951,15059,14933,38860,38774,38728,38132,37829,38087,38648,38779,38638,38751,38779,38648,17289,16926,16830,16416,16583,16292,28655,28537,28561,28655,28561,28732,29057,29070,29020,29827,29785,29680,28478,28602,28584,28112,27975,27835,8597,8238,8399,8004,7898,8038,8302,8238,8597,20666,20689,20918,20918,20970,20957,21138,21386,21075,22778,22818,22616,20535,20689,20666,20399,20369,20225,20399,20389,20423,20225,20222,20284,20222,20041,20080,20041,20038,20080,28975,29070,29057,32228,32099,32216,30401,30255,30463,38114,38312,38072,38290,38312,38114,40834,40967,40816,41070,40967,41149,20717,20665,20855,20260,20232,20083,20083,19881,19919,19919,19881,19848,19384,19304,19371,20717,20855,20817,21510,21289,21435,21510,21435,21522,20689,20796,20918,42488,42512,42455,42455,42595,42419,42539,42256,42390,42539,42390,42737,9692,10014,9704,9692,9704,9684,20041,19976,20038,39828,39755,39600,39600,39153,39813,42560,42541,42488,20518,20327,20403,20796,20970,20918,42226,42150,42236,42486,42387,42495,42541,42512,42488,29865,29785,29867,17094,16942,17060,16731,16942,16719,24359,23920,23804,1756,1709,2011,1458,1523,1503,1687,1709,1756,1614,1685,1677,2077,2283,2249,2585,2422,2486,41378,41374,41239,41491,41301,41317,7831,7865,7849,20327,20232,20260,36506,36418,37183,4865,4927,5047,4917,4927,4882,6327,6316,6390,7447,7479,7448,7358,7494,7595,35096,35200,34944,34347,34135,34106,37411,37209,37470,38426,38403,38793,7040,7358,7595,6519,6185,5875,1540,1604,1686,13092,13286,13199,14524,14368,14609,14665,14760,14808,13988,14422,14126,14951,15211,15059,20970,21093,21138,27279,27277,27579,25965,25921,26060,25965,25847,25921,27224,27277,27279,42652,42390,42496,18803,18646,18791,18803,18791,18821,20038,19976,19867,21093,21167,21138,22677,22780,22808,24534,24524,24288,39298,38882,38963,42387,42194,42551,42432,42412,42436,42557,42496,42401,2450,2631,2530,1952,1856,1915,1658,1920,1734,28067,28112,27835,27630,27361,27477,41178,41302,41136,41272,40908,41029,19867,19976,19757,21167,21297,21138,16674,16864,16905,26444,26644,26668,24534,24577,24524,42140,41811,41989,41877,41593,41685,1594,1618,1442,965,990,1198,14472,14665,14618,15211,15320,15282,15211,15282,15059,26218,26346,26193,41837,41766,41340,42236,41995,42018,6890,6942,6931,35096,34944,35056,37411,37470,37497,982,983,1107,1099,1014,1212,932,983,982,21297,21386,21138,42251,42239,42141,42069,42140,41989,42479,41592,42362,3408,3443,3634,19864,19867,19757,18646,18332,18791,28505,28420,28486,29251,29434,29516,32239,32228,32216,30401,30463,30830,32239,32273,32380,32239,32380,32386,42547,42481,42362,42542,42370,42493,42412,42408,42436,20113,19881,20083,16731,16905,16942,19537,19703,19757,22780,22987,22808,38431,38658,38453,13417,13680,13671,12508,12596,12770,28505,28486,28537,7865,7956,8085,8317,8446,8499,7942,7956,7865,10167,10279,9596,31633,31676,31606,31627,31543,31243,38287,38132,38087,38796,38829,38779,37970,38133,38035,38123,38133,37970,40017,39758,39884,42616,42239,42251,9083,8871,8893,16033,16292,15886,19537,19199,19703,22780,23114,22987,37646,37618,37653,37497,37470,37618,38774,38920,38623,38869,38860,38859,38900,38860,38869,38779,38829,38722,38570,38111,38312,42229,42140,42069,920,924,1103,906,867,1023,920,1103,1001,775,945,1021,868,945,664,1442,1618,1629,22987,23114,23025,24577,24774,24524,42620,42373,42136,42436,42408,42553,42226,42126,42159,11753,11610,11761,11049,11204,11270,10908,10829,10842,12508,12770,12711,23114,23134,23025,22778,22616,22406,23573,23920,23510,42481,42479,42362,42568,42479,42481,19537,19102,19079,22197,22503,22261,7447,7412,7479,8871,8677,8828,40239,40240,40190,40061,40017,39884,40379,40240,40239,40379,40203,40370,2711,2555,2841,3078,3315,2923,2594,2397,2332,11543,11546,11610,10537,10158,10456,10994,11099,11020,10930,11099,10994,11207,11099,11168,30315,30223,30163,30315,30506,30223,30541,30793,30684,31684,31831,31676,30315,30163,30147,40535,40379,40370,2678,2513,2636,2908,2832,3102,24954,24774,25055,2001,2397,2333,11099,11262,11298,19079,18989,18806,29931,30010,29895,30161,30166,29931,31924,31851,31967,30110,29965,29969,30110,30163,29965,35056,34944,34894,15524,15603,15583,15524,15583,15320,27339,27108,27270,32001,31924,31967,39674,39623,39390,39767,39623,39674,39951,40050,39941,39941,40050,39764,41465,41425,41301,40501,40507,40471,41644,41425,41465,41491,41317,41597,42043,42012,41899,42147,42012,42166,28964,28655,28732,28526,28655,28522,29865,29965,29785,28602,28697,28584,28654,28697,28602,28442,28211,28112,39388,39538,39652,39911,39951,39941,26241,26253,26142,41597,41317,41646,2404,2513,2678,22818,22852,22886,22778,22852,22818,29573,29514,29563,40578,40889,40640,42408,42407,42553,42557,42401,42448,17738,17843,17721,17738,17721,17716,1393,1390,1458,1856,1782,1936,1662,1782,1856,2077,2249,2033,6231,6134,6247,6316,6134,6231,6327,6134,6316,7037,7122,7211,28021,27956,28095,27277,27100,26901,28021,28095,28185,41399,41374,41378,14951,14933,14725,25024,25055,25112,42239,42234,41990,42140,42121,41811,42321,42234,42636,42229,42234,42321,40061,40033,40052,5694,5810,6034,8153,8499,8150,14665,14524,14609,13913,14052,14143,14472,14524,14665,27224,27100,27277,839,922,784,839,935,959,922,857,784,2513,2450,2530,5227,5368,5628,7447,7276,7412,7719,7818,7689,25112,25025,25024,25467,25320,25607,25607,25320,25374,29318,29252,29070,34936,34946,34708,36726,36425,36677,41300,40817,41128,42212,42121,42140,42557,42448,42540,6863,6621,6769,1823,1841,1891,1747,1841,1823,1658,1734,1685,983,1026,1136,932,1026,983,6863,6964,6621,16830,16926,16685,22261,22503,22677,23025,23134,23319,23134,23431,23319,25647,25725,25305,23477,23510,23144,36831,36726,36869,36831,36869,36931,36831,37197,36950,42540,42369,42548,42477,42287,42393,31590,31461,31537,39270,38893,39435,38431,38287,38426,42318,42580,42369,9562,9502,9289,10677,10994,10756,1407,1479,1686,1603,1658,1685,1361,1479,1407,1361,1414,1309,1414,1365,1309,851,867,906,990,1321,1198,945,912,986,868,912,945,23946,23794,24020,23946,24020,24057,5670,5587,5933,6621,6707,6667,40732,40721,40565,41070,40903,40938,40732,40565,40544,2187,2180,2326,2033,2249,1891,28697,28975,28937,29154,28975,29053,4917,5025,5058,4917,5058,4927,7482,7831,7849,7956,8153,8150,6868,7358,7040,1818,2022,2455,3694,3577,3761,3337,3023,3543,3637,3577,3694,3609,3649,3720,13286,13092,12993,14052,14194,14143,28526,28537,28655,28526,28505,28537,28480,28442,28112,6621,6964,6707,15453,15524,15320,15829,16033,15886,17271,17364,17289,25977,26136,25881,25855,25725,25713,25977,25881,25820,39388,39813,39153,851,906,901,7880,8153,7956,22261,22677,22365,23533,23431,23610,37754,37646,37653,38426,38287,38087,38920,38774,38860,16731,16674,16905,14367,14368,14524,18170,18497,18688,24906,24524,24774,25112,25055,25229,42234,42229,42069,42321,42728,42508,2450,2272,2631,784,857,748,19384,19371,19848,22677,22808,22741,39388,39298,39538,38695,38570,38763,42318,42483,42580,1140,1444,1360,1458,1390,1623,1442,1629,1433,1309,1338,1063,7804,7831,7709,24906,24774,24954,34296,34347,34106,34743,34760,34894,34115,34106,34060,33423,32827,33411,42121,42112,41811,41877,41685,41883,42212,42112,42121,1782,1687,1756,1662,1687,1782,1540,1686,1479,1614,1677,1604,2003,2187,2077,14143,14194,14316,27630,27813,27835,27339,27473,27477,27270,27473,27339,41374,41282,41130,41425,41399,41378,41498,41399,41644,41658,41465,41491,4920,4917,4882,7090,7037,7211,8038,8229,8004,32228,32192,31967,31590,31233,31461,32405,32395,33137,34682,34743,34522,37754,37653,38188,37393,37230,37217,748,857,890,901,906,924,1551,1540,1454,13865,13671,13680,13328,13656,13536,14457,14951,14725,15206,15453,15320,12444,12722,12621,12285,12371,12247,26668,26644,26853,27277,27551,27680,27551,27713,27680,28185,28095,28420,31676,31831,31606,31627,31243,31427,39132,39085,39096,39947,39767,39674,831,1160,867,6942,6900,7040,6890,6770,6942,5875,6185,5871,5875,5871,5500,22741,22808,22915,35407,35449,35258,36200,36166,36140,36390,36378,36166,37036,36418,36829,35407,35258,35270,35407,35270,35477,30506,30549,30541,30510,30549,30506,30510,30506,30315,30510,30315,30343,29969,29965,29865,11074,10829,10908,11049,10829,11074,11880,12069,11753,30255,30166,30161,31058,30997,31101,2003,2180,2187,2033,1891,1868,11735,11778,11670,29154,29318,29070,29154,29070,28975,39096,38985,38869,39085,38985,39096,10829,10605,10842,3337,3543,3443,4247,3609,3720,11753,12069,12168,13671,13398,13417,19304,19087,19371,18821,19079,18806,18821,18806,18803,25024,24906,24954,25320,25112,25229,26218,26152,26310,30271,30166,30255,35477,35270,35096,40642,40534,40507,40507,40534,40471,40379,40436,40240,40273,40061,40052,39773,39659,39947,40642,40501,40640,41503,41282,41374,42150,42226,42159,42486,42477,42393,42236,41927,41914,23711,23533,23610,24057,24020,24288,24057,24288,24186,25725,25855,25820,26136,26241,26142,25647,25305,25550,35062,35056,34894,34625,34682,34522,40436,40052,40240,42373,42388,42100,42441,42388,42954,7783,7898,8004,7831,7942,7865,7804,7942,7831,7849,7494,7482,38133,38290,38114,36378,36198,36166,1026,1024,1099,954,1024,1026,782,831,867,873,901,924,18644,18170,18688,26668,26853,26815,26161,26241,26136,41766,41868,41830,42111,41868,41766,42580,42483,42619,42486,42393,42387,3309,3315,3473,2835,3071,2841,12770,12827,12711,11416,11632,11306,11207,11306,11262,11207,11262,11099,29867,29969,29865,40729,40642,40640,10658,10714,10288,9289,9502,9262,9262,8906,8878,8317,8499,8153,32239,32192,32228,32370,32570,32336,42479,42571,42136,42647,42375,42391,42483,42432,42514,3337,3443,3408,2832,2604,2942,2513,2404,2450,2450,2216,2272,3562,3720,3649,5587,5227,5628,39911,39941,39828,40499,40414,39729,39911,39828,39813,12711,12827,12736,12285,12444,12371,12131,12444,12285,29053,28975,28697,29318,29563,29514,29053,28697,28777,26815,26853,27008,29036,28655,28964,28361,28185,28420,41070,40938,40967,41776,41340,41195,41877,41883,42238,11548,11753,11540,11692,11735,11670,34524,34625,34300,34905,34894,34760,34524,34300,34347,42542,42547,42362,42514,42432,42436,863,932,982,868,982,912,23711,23610,23794,22915,22808,22987,24519,24288,24524,39388,39153,39298,39895,39911,39813,1658,1747,1931,1551,1614,1604,1551,1604,1540,7090,7211,7276,7090,7276,7307,13913,13865,13680,13371,13199,13398,14316,14194,14368,14367,14524,14472,34946,34965,34385,35360,35147,35143,13730,13865,13770,12463,12711,12556,27593,27813,27630,28067,27813,27811,42539,42603,42270,42560,42643,42541,42541,42643,42512,42512,42681,42455,42895,42607,42547,42790,42905,42897,42652,42496,42711,42496,42528,42676,42528,42557,42676,42557,42760,42676,16674,16502,16346,16526,16502,16674,20796,20890,20970,20970,21140,21093,21093,21140,21167,21167,21190,21297,21297,21293,21386,22379,22406,21712,20689,20771,20796,20399,20535,20666,20423,20535,20399,20399,20225,20389,20225,20284,20389,20153,20284,20222,20153,20222,20080,20153,20080,20069,20080,20038,20069,20535,20771,20689,8187,8317,8153,20069,20038,20066,20771,20890,20796,33002,32827,32772,42603,42643,42560,1024,1014,1099,910,1014,1024,1454,1540,1479,15557,15826,15951,27713,27884,27773,27680,27713,27773,27008,26853,27100,27281,27108,27242,41825,41597,41646,41399,41420,41374,3408,3634,3577,20232,20113,20083,19677,19384,19848,19304,19207,19087,20327,20390,20232,20518,20390,20327,20482,20390,20518,21351,21289,21510,21351,21510,21500,21510,21580,21500,21580,21654,21500,20066,20038,19930,32370,32192,32239,30010,30076,29938,42643,42681,42512,20390,20302,20232,19930,20038,19867,29591,29563,29318,1661,1747,1293,3401,3408,3577,4941,5278,5086,3481,3715,3959,39017,38900,38869,39564,39289,39623,39017,38869,38985,19866,19930,19867,21072,21140,20970,26218,25965,26060,25786,25965,25935,18646,18300,18332,19864,19866,19867,18300,18182,18332,1501,1802,1709,1216,1360,1389,20302,20113,20232,19831,19866,19864,21140,21190,21167,35843,36033,36085,35630,36033,35620,7307,7276,7447,35147,35094,34946,34905,34760,34682,35630,35722,36033,37647,37497,37618,37647,37618,37646,38308,38132,38287,1380,1454,1312,1215,1309,1063,1868,1891,1841,5054,5085,5025,12508,12254,12378,12508,12711,12463,26241,26305,26253,26364,26305,26241,35603,35722,35589,41710,41658,41791,42147,41954,42012,42495,42387,42551,42553,42514,42436,10658,10493,10665,8906,8667,8588,35603,35687,35722,7783,7689,7818,19762,19831,19864,38570,38751,38648,38695,38751,38570,6374,6327,6390,5694,5670,5810,5810,5670,5933,5587,5147,5227,6449,6327,6374,6454,6327,6449,6454,6449,6501,6454,6501,6525,6501,6621,6525,17289,17364,17393,16830,16685,16756,35603,35449,35687,1888,1855,1952,1471,1501,1408,1818,1855,1888,1787,1868,1841,19762,19670,19831,21580,21651,21654,41194,41272,41029,41304,41272,41309,19762,19703,19670,18332,18182,18081,19703,19199,19670,21654,21692,21525,21654,21651,22197,2529,2604,2832,1768,1818,2455,2908,3102,3023,1255,1389,1390,876,873,924,11270,11204,11546,10829,10769,10605,11270,11546,11543,11270,11543,11373,15149,14951,15157,16756,16685,16513,15453,15603,15524,30147,30163,30110,30793,30874,30684,30084,30110,29969,4920,5054,5025,4920,5025,4917,30793,30541,30549,2529,2373,2284,3401,3577,3417,32405,32386,32380,31233,31127,31461,32370,32386,32405,38994,38899,38829,6525,6621,6667,7482,7494,7358,5875,6481,6519,36726,36430,36425,35147,35360,35094,37230,37169,37217,39767,39659,39623,39953,39758,40017,876,924,920,782,867,851,11373,11543,11474,11520,11692,11670,12029,12131,12004,10288,9692,9655,19670,19780,19831,23711,23794,23901,40622,40535,40534,40534,40535,40370,40273,39953,40017,40729,40534,40642,42553,42407,42477,42552,42495,42901,42557,42540,42632,2344,2835,2841,2555,2711,2642,2555,2642,2486,2332,2397,2001,30874,31100,30831,6964,7000,6707,22915,22987,22966,22852,23099,22994,22406,22402,21712,35687,35449,35564,42607,42481,42547,42607,42568,42481,42632,42540,42665,42553,42610,42622,21654,21707,21692,42913,42595,42455,2222,2404,2302,11207,11416,11306,30166,30076,29931,30271,30076,30166,31537,31723,31590,30042,30084,29969,3134,3023,3337,32001,31967,32114,1747,1787,1841,1614,1603,1685,1477,1603,1614,1439,1614,1551,26346,26310,26668,26193,25965,26218,28022,27884,28021,15948,15557,15951,27571,27473,27270,25855,25977,25820,25822,25977,25855,24914,24716,25001,28517,28420,28505,29802,29434,29895,1408,1709,1687,12827,12788,12736,13984,13865,13913,14367,14316,14368,14393,14316,14367,41597,41658,41491,41465,41658,41710,6707,7000,6848,35564,35449,35407,1699,1662,1856,4951,4941,5086,4951,5086,5227,4925,4920,4882,5054,5028,5085,6667,6707,6537,7448,7307,7447,19639,19782,19780,25713,25647,25741,32917,33002,32772,32772,32347,32437,38793,38403,38623,39085,39017,38985,38966,39145,39043,41498,41420,41399,41282,41300,41128,2350,2080,2237,11438,11692,11520,29827,29867,29785,29827,29680,29563,29291,29318,29154,1393,1503,1442,1254,1255,1390,33002,33300,32827,38751,38796,38779,38943,38796,38751,782,851,901,904,920,1001,21525,21500,21654,22884,22915,22966,22778,22879,22852,22918,22879,22778,23901,23794,23946,23337,23319,23431,23901,23946,23950,24906,25024,25025,39715,39564,39623,39715,39623,39659,40273,40017,40061,42568,42571,42479,42601,42571,42568,7000,7037,6848,16225,15951,16346,16719,16942,17094,25025,25112,25026,28517,28505,28526,38920,38860,38900,4925,5054,4920,3315,3481,3473,3280,3481,3315,42184,42012,42043,42330,42212,42140,42321,42140,42229,42251,42278,42616,42249,42236,41914,42551,42194,42207,860,744,999,684,767,860,1205,1088,645,585,793,839,42595,42647,42391,42540,42548,42665,7463,7448,7479,7898,7783,7818,8004,8229,8238,8486,8597,8677,8486,8677,8490,7942,7880,7956,8588,8667,8446,6770,6890,6782,34922,34905,34682,35570,35564,35407,34115,34296,34106,34320,34296,34115,4941,4863,5278,4867,4863,4941,6558,6667,6537,7463,7719,7689,8790,8677,8871,8790,8871,8961,8871,9083,8961,37740,37754,37830,37457,37217,37411,38442,38570,38312,6481,6770,6782,31427,31243,31152,37457,37411,37497,39911,40006,39951,40499,39729,40050,41149,40967,40834,40034,39895,39813,16830,17271,17289,17716,17721,17532,16940,17271,16830,29251,29036,28964,28856,29036,29106,28777,28697,28654,40912,40607,40721,782,901,835,784,691,839,1331,1393,1442,41550,41134,41302,41868,42035,41830,41304,41178,41272,767,744,860,28522,28517,28526,41517,41300,41282,17716,17532,17364,6770,6900,6942,25977,26161,26136,25996,26161,25977,42111,42035,41868,1216,1389,1255,1216,1140,1360,25965,25786,25748,26218,26310,26346,25647,25713,25725,25001,24716,24935,42184,42043,42112,41499,41498,41570,19852,19848,19881,19087,19008,18688,16679,16526,16731,1014,1011,1213,736,1011,1014,954,1026,932,24763,24519,24524,25026,25112,25350,24650,24716,24359,22879,23099,22852,22939,23099,22879,42552,42477,42486,42665,42548,42629,42552,42486,42495,4863,4781,5278,4837,4781,4863,7037,6972,6848,7567,7463,7689,7337,7482,7358,34320,34524,34296,33002,33156,33300,32437,32061,31831,1393,1254,1390,7804,7880,7942,7803,7880,7804,9979,9194,9732,8588,8446,8528,38943,38915,38796,38796,38915,38829,40032,40006,39895,751,954,932,2486,2642,2585,3078,3280,3315,19384,19243,19304,24373,24519,24508,31509,31684,31627,30874,30996,31100,30772,30793,30549,30772,30549,30510,30147,30110,30084,37596,37457,37497,39435,38893,39289,39017,38966,38900,42548,42580,42629,29219,29291,29154,30042,30147,30084,28654,28602,28442,28067,27835,27813,27630,27473,27593,835,901,821,785,904,1001,797,904,810,775,1021,939,18081,18182,17843,19537,19079,19199,17756,17716,17696,23337,23431,23533,23950,23946,24057,28246,28022,28185,28185,28022,28021,26346,26700,26335,27593,27473,27571,2422,2585,2566,9655,9684,9421,11207,11395,11416,11416,11438,11520,9655,9421,9431,30891,30996,30874,1215,1479,1361,1661,1787,1747,1476,1454,1380,14346,14472,14618,14027,13984,14143,8528,8446,8317,12463,12254,12508,13092,12788,12993,29219,29154,29053,11168,11395,11207,12830,12722,12444,30042,29969,29867,40286,40050,39951,755,748,890,901,873,821,702,939,999,18081,17843,17738,19243,19207,19304,32114,31967,32192,32370,32239,32386,39576,39435,39289,39773,39715,39659,3562,3577,3637,3408,3352,3337,3352,3401,3277,39576,39289,39564,1864,1933,2033,2350,2332,2080,2332,2350,2594,1741,1787,1661,41238,41272,41194,41238,41194,41249,4781,4690,4774,4738,4690,4781,7674,7567,7689,7090,6972,7037,7674,7689,7783,8004,8238,7940,2404,2342,2450,1576,1585,1662,2222,2342,2404,2404,2678,2302,2003,2077,2033,30076,30010,29931,30271,30255,30401,31058,31101,31233,40535,40717,40379,39620,39576,39686,41027,40378,41120,40621,40732,40544,1042,965,1198,16731,16526,16674,14346,14393,14472,16415,16526,16447,42441,42278,42388,42212,42184,42112,25713,25822,25855,26419,26479,26305,25741,25822,25713,36390,36350,36440,36461,36390,36440,36200,36390,36166,36378,36486,36416,38123,38290,38133,36200,36350,36390,35981,36033,35722,36390,36486,36378,42629,42580,42619,8302,8597,8486,15206,15320,15211,15206,15211,15149,13988,14126,13656,13007,12884,12830,27212,27008,27100,25350,25112,25320,38542,38290,38668,39002,38994,38915,751,863,700,868,863,982,751,910,954,954,910,1024,24723,24650,24359,25001,25550,25305,755,988,831,821,873,809,23337,23533,23572,22197,21707,21654,23099,23288,23144,23197,23288,23099,1933,2003,2033,13286,13398,13199,4925,5028,5054,4927,4865,4882,15680,15753,15603,17756,17738,17716,30010,29802,29895,28856,28522,28655,28517,28361,28420,29729,29827,29563,39895,40006,39911,40032,39895,40034,40732,40873,40721,1760,1818,1715,1662,1585,1687,1501,1433,1629,993,1216,1254,5694,6034,6134,5694,6134,5596,6298,6327,6454,6444,6454,6525,6444,6525,6558,28856,28655,29036,41249,41194,41213,755,673,748,9257,9421,9289,19207,19008,19087,21398,21712,21386,42619,42483,42628,8793,8878,8906,8839,8878,8793,33077,33156,33002,33077,33002,32917,39132,39096,39270,39132,39017,39085,38915,38994,38829,38943,38751,38941,39348,39132,39270,34296,34524,34347,35687,35749,35722,33411,32827,33300,8588,8634,8906,8528,8634,8588,33449,33411,33300,1760,1856,1855,6558,6525,6667,7131,6972,7090,41420,41503,41374,40717,40622,40858,41644,41399,41425,41465,41710,41644,41468,41302,41304,41468,41550,41302,42258,42062,42035,755,695,673,809,873,797,873,876,797,22261,22365,22197,23572,23533,23711,23572,23711,23706,29802,29605,29434,29410,29591,29318,29410,29318,29291,31627,31684,31676,31427,31152,31324,40873,40912,40721,42954,42388,42373,42615,42136,42571,831,650,667,1471,1433,1501,1454,1476,1551,1439,1476,1380,1361,1309,1215,4867,4951,4818,4882,4865,4723,14472,14393,14367,14206,14393,14337,37754,37647,37646,37740,37647,37754,37754,38188,37830,1140,1042,1198,885,1180,990,923,1042,1140,1216,1255,1254,12080,12004,12131,41471,41468,41304,7307,7249,7090,21113,21351,21202,20817,21113,21044,20817,20855,21113,20390,20318,20302,20302,20170,20113,20113,20053,19881,19384,19206,19243,19243,19206,19207,19207,19065,19008,21351,21411,21202,33768,34095,34000,36829,36418,36416,20771,20830,20890,20890,21072,20970,21140,21223,21190,21190,21293,21297,20535,20515,20771,20423,20515,20535,20389,20515,20423,20563,20515,20414,20589,20563,20618,20515,20563,20589,20414,20515,20389,20258,20069,20066,19794,20066,19930,19800,19930,19866,19800,19866,19831,19800,19831,19780,21351,21500,21411,20515,20830,20771,20717,20482,20518,42681,42722,42455,42848,42493,42647,42643,42742,42681,42603,42742,42643,42795,42742,42603,42737,42390,42652,42737,42652,42798,42652,42711,42699,42676,42711,42496,1864,2033,1868,2413,2422,2349,1864,1868,1741,13398,13671,13371,28777,28914,29053,28751,28914,28777,42742,42722,42681,42748,42547,42542,15532,15680,15453,15453,15680,15603,26041,25935,25965,24278,24288,24373,26041,25965,26193,20482,20318,20390,20830,21072,20890,645,793,406,645,1088,793,427,702,744,744,702,999,993,1254,1393,3401,3352,3408,2302,2678,2604,3562,3637,3720,7880,7842,8153,7482,7709,7831,7803,7709,7635,20318,20170,20302,27224,27212,27100,32370,32405,32570,31212,31058,31233,37036,37183,36418,42676,42760,42711,42628,42483,42514,42628,42697,42718,16225,16346,16502,26419,26305,26364,25741,25550,25662,42293,42184,42212,42252,42078,41877,42330,42140,42321,12080,11735,12004,29219,29410,29291,797,876,904,725,782,835,1818,1760,1855,1718,1760,1682,13730,13671,13865,19079,18823,19199,17756,18081,17738,17716,17604,17696,22741,22365,22677,21072,21223,21140,23288,23477,23144,23357,23477,23288,27579,27277,27680,28521,28361,28517,28268,28361,28521,30642,30772,30510,30793,30891,30874,31324,31152,31100,30642,30510,30343,30042,29867,30008,29867,29827,30008,42611,42552,42901,42632,42760,42557,4925,4882,4884,10658,10677,10756,11395,11438,11416,10665,10677,10658,30884,30891,30793,35062,34905,35092,34922,34682,34625,691,784,748,20170,20053,20113,21223,21293,21190,24278,24186,24288,24288,24519,24373,31537,31924,31723,30010,29894,29802,29802,29819,29605,2350,2422,2566,2486,2413,2555,2774,3329,2835,1941,2180,2003,30427,30271,30401,35570,35407,35477,40729,40622,40534,40378,40817,41120,20053,19978,19881,21293,21398,21386,8790,8490,8677,9979,9298,9194,42748,42493,42848,42813,42826,42760,42622,42514,42553,4247,4201,3609,643,684,860,11238,11438,11395,16526,16415,16502,16719,17094,17407,29729,29563,29591,38991,38920,38900,38991,38900,38966,40034,39813,39388,38962,38943,38941,42340,42330,42321,38290,38442,38312,38619,38442,38542,37454,37393,37217,37197,36831,36931,36831,36950,36726,37454,37217,37457,1933,1941,2003,1741,1868,1787,22741,22915,22884,23706,23711,23901,23477,23573,23510,25741,25647,25550,23448,23573,23477,29163,29219,29053,28600,28654,28442,28480,28112,28184,41238,41309,41272,41213,40903,41070,4690,4519,4774,4773,4837,4863,4867,4941,4951,18821,18823,19079,23025,22966,22987,29163,29053,28914,29555,29729,29591,32300,32114,32192,42851,42813,42632,7709,7803,7804,7842,7803,7635,34275,34320,34115,34104,34115,34095,31959,32437,31831,31324,31100,31135,25996,25977,25822,42607,42601,42568,42768,42601,42607,29605,29516,29434,29938,29894,30010,1433,1331,1442,1408,1501,1709,1408,1687,1522,1476,1439,1551,1338,1225,1063,8464,8490,8591,7448,7290,7249,8634,8839,8793,9040,9289,9262,8279,8528,8317,13984,13913,14143,41498,41499,41420,41597,41825,41658,18821,18791,18823,23025,23319,22966,26107,26041,26193,25467,25607,25786,26335,26193,26346,26008,25996,25822,42035,42062,41914,42611,42477,42552,42111,41766,42143,24519,24763,24508,24119,23950,24057,7463,7290,7448,7307,7448,7249,6900,6898,7040,6797,6898,6900,6797,6900,6770,6797,6770,6686,6770,6481,6686,5500,5871,5028,4948,5028,4925,37725,37497,37647,37520,37454,37596,42184,42166,42012,42293,42166,42184,15149,15211,14951,26364,26241,26161,1760,1699,1856,1718,1699,1760,41903,41776,41195,41867,41776,41903,41645,41550,41587,31995,31924,32001,40006,40286,39951,40887,40873,40732,40887,40912,40873,41222,40834,40912,39183,38963,38994,725,835,821,921,990,965,29555,29591,29410,22966,23319,23249,22760,22918,22778,22760,22778,22406,882,921,965,894,921,882,4837,4738,4781,4735,4738,4837,17407,17829,17671,16513,16685,16416,16513,16416,16033,16513,16033,16075,42665,42629,42743,7674,7783,7721,12736,12556,12711,12463,12306,12254,11474,11543,11753,11270,11012,11049,12788,12556,12736,12788,13092,13014,16387,16225,16415,16415,16225,16502,14206,14316,14393,32114,31995,32001,32370,32300,32192,32336,32300,32370,39782,39576,39564,39435,39284,39270,39043,38991,38966,39564,39715,39773,41149,41174,41070,41387,41309,41238,41149,40834,41222,1864,1822,1933,1747,1658,1293,3562,3417,3577,3580,3649,3609,27773,27884,28022,28600,28534,28658,28654,28751,28777,29163,29555,29410,41387,41238,41249,8829,8839,8715,38308,38287,38453,38950,38991,39043,38943,39002,38915,38962,39002,38943,24119,24057,24186,23249,23319,23337,25026,24906,25025,22734,22365,22741,23249,23337,23310,22918,22939,22879,22760,22939,22918,42601,42606,42571,42365,42212,42330,42773,42606,42601,29471,29516,29605,29163,29410,29219,41120,40817,41418,39526,39284,39435,17716,17364,17604,18823,18791,18579,36486,36829,36416,37036,37195,37183,36390,36461,36486,36200,36085,36350,42743,42629,42619,25996,26144,26161,27281,27571,27270,26008,26144,25996,25550,25549,25662,25822,25741,25883,30343,30315,30147,30772,30884,30793,31103,31100,30996,30343,30147,30266,30147,30042,30192,10930,11168,11099,10493,10658,10288,10493,10175,10571,12004,11659,11856,10930,10994,10677,16719,16679,16731,16559,16679,16719,25467,25786,25964,30192,30042,30105,14206,14143,14316,13014,13092,13199,15314,15557,15440,27805,27773,27927,28268,28185,28361,41499,41503,41420,42135,41950,41825,15440,15557,15834,1063,1225,1034,1769,1822,1864,13626,13671,13730,12406,12830,12444,15157,15063,15150,12406,12444,12131,15206,15193,15453,13579,13656,13572,32100,31995,32114,31822,31831,31684,33156,33449,33300,34049,34104,34095,31509,31627,31427,38625,38619,38670,36751,36829,36486,41388,41213,41174,41174,41213,41070,42606,42615,42571,42769,42615,42606,42610,42553,42477,42763,42743,42619,42610,42477,42611,1699,1576,1662,1537,1576,1699,13770,13626,13730,34922,34625,34685,34905,35062,34894,33768,33423,33411,41570,41503,41499,11049,10769,10829,12306,12168,12254,12306,12463,12389,30008,29827,29745,4884,4948,4925,4884,4882,4723,12389,12463,12556,34625,34524,34685,35640,35749,35687,41116,41280,41142,894,885,990,8490,8302,8486,8464,8302,8490,24119,24186,24239,24763,24524,24906,36915,36950,37197,37197,36931,37274,725,821,732,785,810,904,18086,18332,18081,17604,17364,17363,31103,30996,30891,1682,1760,1715,1741,1769,1864,1293,1658,1603,1477,1614,1439,13209,13387,13328,28521,28517,28522,29106,29036,29246,29819,29471,29605,30256,29938,30076,30256,30076,30271,30427,30401,30627,31445,31233,31590,30105,30008,30215,41753,41471,41691,41309,41471,41304,7721,7783,8004,23573,23804,23920,22939,23197,23099,23059,23197,22939,42615,42620,42136,42755,42620,42615,42763,42619,42628,42126,42642,42551,19008,18644,18688,19342,19206,19384,17802,18081,17756,31482,31509,31427,3609,4201,3630,4744,4867,4818,4948,4884,4896,6606,6537,6707,6558,6537,6444,6039,6134,6327,4744,4773,4867,6606,6707,6786,6707,6848,6786,7290,7463,7461,35640,35687,35564,37653,38132,38188,36931,37230,37274,17363,17364,17271,15829,15886,15680,1845,1933,1822,1845,1941,1933,15834,15557,15948,16062,15948,16225,40887,40732,40895,41354,41387,41249,673,691,748,821,809,732,484,744,767,664,863,868,736,1014,910,3517,3417,3562,3352,3277,3337,3580,3562,3649,19206,19065,19207,22259,22365,22734,23048,22884,22966,21902,22379,21712,28480,28600,28442,30105,30042,30008,28184,28112,28067,27811,27813,27593,41354,41249,41213,42848,42647,42877,885,785,1001,732,809,797,17696,17802,17756,17363,17271,17327,24119,24239,24069,6786,6848,6799,35570,35640,35564,732,797,750,23310,23337,23332,25964,25786,25935,24278,24239,24186,23999,24119,24069,25964,25935,26041,31995,31723,31924,40032,40065,40006,39694,40034,39388,7461,7463,7567,7711,7721,8004,4867,4773,4863,4735,4773,4744,6701,6786,6799,7461,7567,7540,35477,35096,35399,34720,34524,34320,37230,37393,37274,38431,38426,38658,35096,35056,35399,42763,42628,42718,1471,1331,1433,874,965,1042,921,894,990,1522,1687,1585,1522,1585,1576,1271,1477,1439,13984,13770,13865,12450,12556,12788,14206,14138,14143,14209,14138,14206,27773,27579,27680,26700,26346,26668,27549,27579,27733,27108,26946,27242,42135,42015,41950,41644,41570,41498,41035,41027,41116,1537,1522,1576,13857,13770,13984,27775,27811,27593,41561,41468,41484,41561,41550,41468,41776,41896,41837,3204,3277,3401,2547,2835,2344,3481,3411,3715,32300,32100,32114,31789,31659,31723,32570,32405,33137,39576,39620,39435,38966,39017,39145,39659,39767,39947,1312,1454,1479,14618,14665,14808,26799,26639,26419,42078,41754,41877,13387,13579,13572,13288,13579,13387,41484,41468,41471,695,755,831,750,797,810,23197,23357,23288,23323,23357,23197,42628,42514,42697,42126,42226,42642,23950,23706,23901,24763,24906,25026,29413,29251,29516,28268,28246,28185,7131,7090,7249,6898,6868,7040,6721,6657,6724,5500,5028,4986,16679,16447,16526,16559,16447,16679,35570,35477,35623,695,831,682,923,801,874,763,810,785,652,725,580,24639,24763,24969,31714,31822,31509,30825,30884,30772,30825,30772,30642,30825,30642,30658,30266,30147,30192,40717,40436,40379,40717,40535,40622,40889,40578,41035,8961,8798,8790,7540,7674,7592,10167,9596,9979,32984,33077,32917,33156,33077,33280,2422,2413,2486,2349,2422,2350,20717,20594,20482,20482,20233,20318,20318,20233,20170,20170,20219,20053,19949,19874,19978,19978,19874,19881,19206,19195,19065,20817,20594,20717,20904,20594,20817,21044,21113,21202,21044,21202,21102,21202,21109,21102,20830,21000,21072,21072,21178,21223,21223,21178,21293,21293,21286,21398,21398,21342,21712,20515,20589,20830,20284,20153,20414,19794,19930,19800,19794,19800,19780,20589,20757,20830,42913,42647,42595,42742,42967,42722,42790,42795,42603,42603,42903,42905,42539,42737,42833,42737,42866,42833,42699,42798,42652,42699,42780,42798,20594,20498,20482,27212,27224,27279,29471,29413,29516,38442,38619,38570,39002,39066,38994,37536,37056,37183,41867,41896,41776,42062,42249,41914,10665,10639,10677,13079,13211,12830,10639,10571,10630,30884,31103,30891,31509,31822,31684,38991,38950,38920,39348,39270,39284,38941,38751,38695,1543,1537,1699,1768,2455,2272,1768,1544,1578,7803,7842,7880,8715,8839,8634,7635,7709,7372,10279,9626,9596,9040,9262,8878,8829,8878,8839,11238,11395,11168,13079,13328,13211,34104,34275,34115,34338,34275,34104,38453,38287,38431,39398,39348,39284,26752,26668,26815,26144,26364,26161,26264,26364,26144,26008,25822,25883,41991,41766,41837,2237,2349,2350,11373,11237,11270,11474,11237,11373,11182,11238,11168,30105,30266,30192,29827,29729,29745,20498,20233,20482,21500,21525,21411,42166,42265,42147,42365,42293,42212,42340,42321,42508,6797,6868,6898,40436,40273,40052,42699,42785,42780,42514,42622,42697,20233,20219,20170,21411,21525,21551,42711,42785,42699,23357,23448,23477,23329,23448,23357,21087,21178,21072,32183,32100,32300,39398,39255,39348,39947,39674,39953,12389,12556,12450,11753,12168,11540,11548,11474,11753,29745,29729,29555,17671,17829,18170,17637,17802,17696,16940,16830,16756,42521,42226,42236,21178,21286,21293,2547,2774,2835,26996,26752,26815,41983,41991,41837,643,633,684,684,450,767,462,633,643,529,643,474,585,839,691,7540,7567,7674,7093,7131,7249,7674,7721,7592,34720,34685,34524,35655,35570,35623,42711,42910,42785,471,585,691,682,831,667,2216,2450,2342,1721,1769,1741,2001,2333,2180,1712,1741,1661,12317,12389,12342,12315,12406,12131,28856,28681,28522,28812,28681,28856,28862,29163,28914,28751,28654,28600,41753,41484,41471,41388,41354,41213,41388,41174,41314,42711,42760,42831,42697,42622,42706,42622,42610,42706,923,833,801,16447,16387,16415,16348,16387,16447,42234,42239,42636,41035,40578,41027,41517,41282,41503,40895,40732,40939,20015,19978,20053,21551,21525,21692,13371,13671,13626,14138,14027,14143,14031,14027,14138,14337,14393,14346,14337,14346,14209,36461,36751,36486,36829,36971,37036,36350,36085,36311,36085,36033,36311,35722,35749,35821,35749,35769,35821,35749,35640,35769,40034,40065,40032,40205,40065,40179,41925,41570,41644,41925,41644,41710,14206,14337,14209,19874,19852,19881,18729,18644,19008,19782,19794,19780,19780,19670,19639,21707,22197,21823,21707,21551,21692,42760,42826,42831,27679,27571,27567,25550,25419,25549,42258,42035,42111,42258,42249,42062,588,691,673,831,652,650,782,652,831,18992,19008,19065,22678,22760,22406,22490,22406,22379,42895,42768,42607,42837,42616,42441,42895,42547,42748,42632,42813,42760,42706,42610,42710,3204,3134,3277,4519,4690,4738,8897,8798,8961,8897,8961,8985,8715,8634,8436,8829,9040,8878,10175,10288,9824,19639,19670,19199,24935,24716,24650,28260,28246,28268,27549,27212,27279,26793,26700,26752,27811,28184,28067,28061,28184,27811,27775,27593,27571,27775,27571,27679,38970,38623,38920,39255,39017,39132,39255,39132,39348,38962,39066,39002,39183,39066,39164,39606,39435,39620,41116,41027,41120,42010,41983,41896,41896,41983,41837,41561,41587,41550,41480,41309,41387,42429,42265,42293,42293,42265,42166,41825,41791,41658,42851,42632,42665,15149,15193,15206,17556,17604,17363,15157,15193,15149,1600,1712,1661,1271,1368,1477,1185,1312,1153,1312,1479,1153,6973,7131,7064,7711,8004,7940,36950,36915,36726,37725,37647,37740,36949,36971,36829,31482,31427,31324,1793,1845,1822,1793,1822,1769,19852,19677,19848,22259,22197,22365,23249,23048,22966,23999,23706,23950,23999,23950,24119,23448,23651,23573,23655,23651,23448,763,785,697,874,882,965,24723,24935,24650,782,725,652,588,673,525,4986,5028,4948,6797,6721,6868,42768,42773,42601,42804,42773,42768,1721,1712,1600,15157,14911,15063,13209,13288,13387,13082,13079,13066,16387,16217,16225,16348,16217,16387,25467,25350,25320,24439,24373,24508,25331,25350,25467,26107,26193,26335,28543,28521,28681,28681,28521,28522,6972,7131,6973,19607,19639,19544,37849,37725,37740,37712,37725,37849,11735,11692,11475,12406,12360,12830,29106,28886,28856,29819,29802,29894,29819,29894,29996,30463,31058,30830,41418,40817,41300,37849,37740,37830,38970,38920,38950,42280,42258,42111,41195,41550,41903,35769,35640,35655,35640,35570,35655,37274,37393,37426,36971,37195,37036,31103,31135,31100,31067,31135,31103,30537,30642,30343,30537,30343,30461,30343,30266,30442,40309,40499,40050,10769,11012,10970,11237,11012,11270,11086,11237,11201,30442,30266,30215,33449,33768,33411,34720,34827,34685,33449,33156,33280,38619,38763,38570,38625,38763,38619,39686,39606,39620,39782,39564,39773,42792,42851,42665,10493,10639,10665,11475,11692,11438,9431,9421,9257,673,695,605,750,810,763,8436,8634,8528,7372,7709,7482,11073,11182,11168,31659,31590,31723,30461,30442,30635,40858,40729,40893,40858,40622,40729,40380,40210,40273,39864,39782,39773,40729,40889,40893,42773,42769,42606,42804,42769,42773,31067,31103,30884,35056,35062,35399,37426,37393,37454,785,683,697,15385,15532,15453,15385,15453,15193,17637,17696,17604,17637,17604,17556,23651,23804,23573,23655,23804,23651,26740,26107,26335,26700,26668,26752,42743,42792,42665,15729,15829,15680,1671,1793,1769,2001,1731,1950,2202,2222,2181,2349,2303,2413,2344,2841,2555,2303,2237,1984,27571,27281,27567,28886,28812,28856,29561,29745,29555,28658,28751,28600,28862,28751,28846,41040,40889,41035,41354,41480,41387,41314,41174,41149,41222,40912,41235,31135,31297,31324,40205,40286,40006,40309,40286,40351,41950,41791,41825,41588,41517,41503,12389,12317,12306,13371,13468,13281,12029,12315,12131,12299,12315,12029,7940,8238,8058,8925,8897,8985,8783,8897,8925,24935,25065,25001,25094,25065,24935,35399,35062,35252,39025,38970,38950,39255,39145,39017,39188,39145,39406,41484,41587,41561,41723,41587,41484,14725,14422,14457,42238,41883,42147,695,682,605,3580,3517,3562,2529,2832,2908,3407,3517,3428,605,682,599,578,652,580,23310,23048,23249,22760,23059,22939,22783,23059,22760,42769,42755,42615,42804,42755,42769,42710,42610,42611,42743,42801,42792,27549,27279,27579,27579,27773,27733,28260,28268,28394,41903,41550,41645,2202,2216,2342,11540,12168,12306,40939,40732,40621,42429,42238,42147,42340,42365,42330,42497,42365,42340,39526,39398,39284,39947,39953,40158,33280,33077,33242,31297,31482,31324,13857,13626,13770,13857,13984,14027,13285,13288,13209,13285,13209,13079,28394,28268,28521,41588,41503,41570,6786,6701,6606,6563,6298,6537,6298,6454,6444,6799,6848,6972,6721,6551,6657,6788,7337,7358,37520,37426,37454,4773,4735,4837,5147,5587,5139,7346,7337,7121,7093,7290,7137,6846,6799,6972,8490,8790,8649,16755,16559,16719,17826,17671,18170,18441,18791,18332,17556,17720,17656,42913,42455,42988,42763,42801,42743,32130,31982,32100,31789,31723,31982,32588,32570,33130,34965,34946,35094,8649,8790,8798,29449,29251,29413,29996,29894,29938,30215,29745,30059,41113,41035,41167,41113,41040,41035,11719,11540,12306,12458,12450,12788,31723,31995,31982,6846,6972,6901,22734,22741,22884,37596,37497,37712,37596,37454,37457,37402,37536,37183,42763,42718,42801,1768,1715,1818,1543,1699,1718,1346,1372,1408,1408,1372,1471,1578,1715,1768,2180,1731,2001,1712,1721,1741,1671,1721,1600,13371,13014,13199,15829,15872,16033,15532,15729,15680,15625,15729,15532,1034,827,926,1368,1603,1477,751,932,863,15249,15385,15193,15150,15193,15157,16217,16189,16225,16340,16559,16755,42252,42238,42624,41825,41646,42135,42555,42521,42236,42143,41766,41991,42143,41991,42146,39782,39686,39576,39844,39686,39782,7337,7372,7482,8187,8153,7906,7346,7372,7337,34685,34827,34922,34720,34320,34621,590,650,578,761,885,756,18086,18081,17906,17556,17363,17327,24639,24508,24763,23332,23337,23572,24969,24763,25026,25095,25026,25350,11475,11438,11336,13082,13285,13079,42848,42836,42748,42801,42718,42943,6799,6846,6780,36269,35360,35143,35092,34905,34922,37712,37497,37725,38763,38941,38695,38542,38442,38290,23176,23310,23332,23048,23063,22884,23059,23323,23197,24710,24723,24359,23042,23323,23059,25984,25964,26041,26996,26815,27008,34295,34338,34104,40210,39953,40273,42146,41991,41983,42943,42718,42697,42916,42710,42901,42706,42710,42806,1346,1408,1522,923,874,1042,9257,9289,9212,8729,8911,9040,7676,7842,7635,27773,28022,27927,27212,26996,27008,28113,28022,28246,39560,39435,39606,38297,38308,38576,682,667,599,667,590,599,1372,1331,1471,1615,1718,1682,11336,11438,11238,10790,10930,10677,10790,10677,10639,28249,28113,28246,28249,28246,28260,28394,28521,28543,30635,30658,30537,30537,30658,30642,31053,31067,30884,31135,31223,31297,31490,31714,31482,30461,30343,30442,41957,41588,42220,41687,41418,41300,41925,41710,41791,41646,41754,42135,29449,29413,29471,28751,28862,28914,28600,28480,28534,10930,11073,11168,30537,30461,30635,30635,30442,30570,31053,30884,30825,40499,40759,40621,41111,40912,40887,40604,40759,40499,40205,40006,40065,38862,38941,38763,4896,4986,4948,4896,4884,4834,36530,36430,36619,36430,36726,36619,36726,36818,36619,37076,37197,37303,37553,37274,37426,37546,37426,37520,29598,29449,29471,882,794,894,923,1140,833,2237,2303,2349,1780,1845,1793,6537,6606,6563,6298,6444,6537,6606,6701,6563,23323,23329,23357,23552,23329,23503,23176,23048,23310,24239,24278,24373,30427,30256,30271,29819,29598,29471,30417,30256,30427,31445,31212,31233,31145,31223,31135,31959,31831,31822,36655,36751,36461,36971,37035,37195,37195,37402,37183,36350,36655,36440,35981,36311,36033,35981,35722,35821,35981,35821,35974,35821,35769,35974,36849,36751,36844,40286,40309,40050,39298,38963,39538,1621,1615,1682,1621,1682,1715,14457,14422,13988,12360,12406,12315,22400,22490,22379,27137,26996,27212,28543,28681,28817,39581,39560,39756,39756,39560,39606,39183,38994,39066,42781,42697,42706,24710,24359,24027,25702,25883,25662,25662,25883,25741,25984,26041,26107,25984,26107,26740,25550,25001,25419,26008,26001,26144,20757,20725,20830,21178,21230,21286,21286,21342,21398,20589,20618,20757,20389,20284,20414,20258,20337,20414,20337,20472,20414,20618,20725,20757,42795,42927,42742,42848,43120,42836,42790,42927,42795,42952,42927,42790,42952,42790,42897,42603,42905,42790,42903,42603,42539,42903,42539,42833,42903,42833,42888,42833,42866,42888,42798,42866,42737,43053,42866,42798,42935,42798,42780,42999,42935,42780,1544,1768,2272,2222,2202,2342,2908,2373,2529,6901,6972,6973,8058,8238,8302,11193,11238,11182,12299,12360,12315,20066,19794,19835,30256,30068,29938,40380,40273,40650,39581,39526,39560,41012,40436,40717,40851,40717,40858,41113,40893,40889,41113,40889,41040,42785,42999,42780,19835,19794,19782,19835,19782,19740,20936,20904,21044,21044,20904,20817,20594,20560,20498,20498,20292,20233,20233,20292,20219,20219,20015,20053,19874,19913,19852,19852,19770,19677,20936,21044,21109,21044,21102,21109,21202,21292,21109,21411,21292,21202,42711,42831,42910,4865,3991,4624,8464,8248,8302,8208,8248,8464,21411,21551,21490,20725,21000,20830,25419,25001,25065,37568,37546,37520,38188,38132,38308,38188,38308,38297,42910,42831,43033,474,643,645,633,450,684,474,645,455,6683,6701,6799,20368,20292,20498,19677,19598,19384,18158,17826,18170,37079,37035,36971,18081,17802,17906,20292,20138,20219,21490,21551,21611,21000,21087,21072,43033,42831,42826,17906,17802,17876,12450,12342,12389,12458,12342,12450,1721,1671,1769,1439,1380,1271,29561,29555,29163,28534,28480,28184,28534,28184,28611,38950,39043,39025,40179,40065,40034,42143,42241,42111,42154,42146,41983,42010,41896,41867,42813,42936,42826,35834,35769,35655,3630,4201,3658,3134,3337,3277,8897,8783,8798,8925,8985,9194,39054,39066,38962,20138,20015,20219,16559,16348,16447,14131,14031,14138,16340,16348,16559,35601,35623,35477,35120,35092,34922,35252,35092,35120,37897,37849,37830,37553,37546,37568,42365,42475,42293,42616,42278,42441,588,573,691,667,650,590,814,794,882,650,652,578,1378,1346,1522,1372,1242,1331,745,814,874,1378,1522,1366,1185,1380,1312,14209,14346,14618,12668,12788,13014,12458,12329,12342,20015,19949,19978,21275,21342,21286,22490,22678,22406,22726,22678,22661,26799,26419,26609,33768,34049,34095,34338,34456,34275,31714,31509,31482,39025,39043,39188,39043,39145,39188,27549,27273,27212,27805,27733,27773,28113,27927,28022,27994,27927,28113,39560,39526,39435,39864,39773,39947,40147,40179,40034,39240,39538,38963,19949,19913,19874,21611,21551,21707,21611,21707,21717,42813,42858,42936,1780,1941,1845,31659,31725,31590,31982,31995,32100,38743,38862,38763,38941,39054,38962,38769,38542,38668,38290,38123,38668,18086,18189,18332,17876,17802,17656,17802,17637,17656,1446,1543,1615,1615,1543,1718,26740,26335,26700,25319,25331,25414,24439,24239,24373,25883,26001,26008,25917,26001,25883,28394,28249,28260,28096,28249,28224,28113,28249,28096,37210,37402,37195,19740,19782,19639,21717,21707,21823,42988,42455,42722,525,573,588,732,580,725,1153,1479,1215,15806,15872,15829,15806,15829,15729,15625,15532,15553,22678,22783,22760,23552,23655,23448,22961,22783,22919,25549,25702,25662,25600,25702,25549,38743,38763,38625,42082,42010,41867,41723,41645,41587,1641,1793,1671,1641,1780,1793,7372,7676,7635,7597,7676,7372,37897,37870,37849,38576,38308,38453,42238,42252,41877,42429,42147,42265,23572,23706,23332,21823,22197,22259,24439,24508,24639,42842,42373,42620,42854,42620,42755,42804,42768,43015,4735,4664,4738,4818,4951,5227,4865,4853,3991,19913,19770,19852,19607,19740,19639,9257,9212,9197,9212,8911,9197,35601,35477,35399,1578,1621,1715,32183,32300,32334,11012,10769,11049,10970,11012,11237,10970,11237,11086,11073,11193,11182,10930,10968,11073,10630,10790,10639,21904,21668,21717,30256,30153,30068,31182,30830,31058,31182,31058,31212,31182,31212,31445,3407,3417,3517,10571,10639,10493,756,885,894,874,814,882,1140,858,833,11502,11474,11548,10837,10968,10930,11659,12004,11735,30830,30627,30401,30068,29996,29938,18158,18170,18644,17034,16719,17407,18149,18189,18086,17656,17637,17556,23552,23448,23329,25782,25917,25702,732,403,580,525,673,605,25331,25467,25414,42508,42497,42340,42582,42497,42508,1018,1153,1215,26609,26419,26364,31725,31659,31789,31421,31482,31297,31067,31145,31135,31053,31145,31067,31053,30825,30735,30825,30658,30735,42146,42241,42143,42806,42916,42951,42010,42154,41983,1288,2272,2216,2529,2302,2604,11097,11193,11073,30627,30417,30427,28681,28812,28817,41017,40851,40858,41017,40858,40893,7592,7721,7711,6780,6683,6799,6686,6721,6797,6686,6551,6721,6481,5875,5676,4812,5500,4986,4903,4986,4896,35610,35601,35557,37870,37712,37849,37682,37596,37712,8707,8649,8798,8696,8925,9077,19770,19598,19677,23063,23048,23176,42813,42851,42858,8707,8798,8783,7833,7770,7940,33829,34049,33768,35834,35623,35610,38793,38658,38426,38542,38670,38619,38743,38670,38769,38970,38793,38623,39145,39255,39406,39050,39054,38941,39183,39240,38963,39050,38941,39005,3428,3517,3580,3524,3580,3609,4744,4664,4735,4554,4664,4744,6788,7358,6868,11193,11336,11238,30351,30153,30256,664,945,775,1063,1018,1215,664,270,502,7940,7770,7711,7833,7940,7780,7676,7759,7842,7906,7759,7738,24621,24439,24639,23706,23478,23332,525,605,539,732,750,607,3280,3030,3481,2923,3315,3309,2923,3309,2774,12342,12329,12317,12458,12788,12668,31948,31725,31789,32334,32300,32336,32334,32336,32550,40100,39864,39947,39200,39188,39219,40158,39953,40210,41111,40887,40895,41855,41723,41484,42891,42748,42836,42806,42781,42706,42858,42851,42792,42806,42951,42781,1346,1242,1372,1460,1522,1537,1460,1537,1543,6721,6759,6868,27824,27733,27805,26996,26793,26752,27824,27805,27927,13281,13014,13371,14618,14808,15440,23655,23800,23804,23772,23800,23655,41950,41925,41791,41588,41670,41517,42024,41925,41950,10279,10456,10158,28096,27994,28113,29036,29251,29246,39756,39606,39686,41480,41354,41388,42281,42241,42292,2456,2923,2774,2001,2080,2332,1929,2080,2001,11580,11540,11719,30127,29996,30068,13656,13579,13988,13304,13579,13288,26936,27242,26946,28703,28534,28700,41860,41670,41957,7131,7093,7064,16348,16189,16217,16340,16189,16348,19598,19342,19384,42497,42475,42365,42582,42475,42497,42913,42877,42647,42858,42792,43038,605,599,539,607,750,587,23548,23478,23690,31948,31789,31982,31421,31297,31223,40380,40158,40210,40205,40351,40286,40309,40604,40499,40759,40939,40621,39694,39388,39652,39694,39652,39538,43038,42792,43140,42415,42249,42258,41142,41035,41116,756,894,794,7249,7290,7093,8058,8302,8248,7906,8153,7842,38670,38743,38625,38928,38743,39018,36430,36269,35099,36619,36818,36799,3204,3401,3417,3078,3155,3280,3030,3155,2927,11371,11502,11504,13857,14027,14031,16940,16756,16488,17980,18086,17906,19544,19639,19331,29246,29251,29449,32550,32336,32570,32183,32130,32100,37076,36915,37197,41222,41314,41149,41443,41314,41555,26799,26936,26946,26778,26936,26799,26264,26144,26001,36588,36269,36430,37035,37203,37195,37402,37416,37536,36751,36849,36829,36655,36461,36440,36655,36350,36693,36691,36311,36309,35974,35769,35834,1115,1600,1661,1731,2180,1941,1293,1603,1368,1271,1380,1232,3658,3735,3661,3245,3204,3417,8114,8208,8170,8791,8707,8783,8791,8783,8925,28817,28812,28886,28061,27775,27679,28658,28846,28751,33242,33077,33090,33765,33829,33768,38996,38793,38970,39255,39398,39542,39054,39164,39066,39210,39164,39054,4834,4903,4896,4834,4884,4723,7461,7540,7438,2555,2413,2344,23999,24069,24223,21717,21823,21904,36849,36949,36829,1034,1225,827,1319,1271,1176,4664,4519,4738,4396,4519,4664,19342,19195,19206,29721,29598,29819,41280,41116,41120,42943,42697,42955,25331,25095,25350,24223,24069,24239,24969,25095,25058,37303,37197,37274,36949,37079,36971,683,785,885,677,756,794,677,794,814,10630,10725,10790,10790,10837,10930,10968,11097,11073,11213,11309,11336,10595,10725,10630,37079,37203,37035,40541,40604,40309,477,939,702,694,736,910,16189,16062,16225,16101,16062,16189,42154,42241,42146,42292,42154,42367,13880,13857,14031,14131,14138,14209,27733,27518,27549,25319,25095,25331,27906,27824,27927,27906,27927,27994,1380,1185,1232,5147,4818,5227,4624,4834,4723,7592,7711,7770,10175,10493,10288,13959,14131,13971,27508,27518,27733,27491,27567,27281,27491,27281,27242,31333,31421,31223,30266,30105,30215,37458,37303,37274,37897,37830,38341,37830,38188,38341,41932,41903,41645,41932,41645,41820,7759,7906,7842,7915,7906,7815,7759,7651,7738,10769,10158,10605,10970,10812,10769,11201,11237,11474,11502,11548,11540,10878,11097,10968,11856,12029,12004,13285,13082,13288,17980,17906,17876,42886,42854,42755,42616,42636,42239,42886,42755,42804,1575,1641,1671,1575,1671,1600,3332,3417,3407,2128,2013,2034,32344,32130,32183,32588,32550,32570,39558,39398,39526,39792,39756,39686,39844,39782,39864,39905,39694,39538,32344,32183,32334,993,1393,1331,1357,1460,1543,1446,1615,1621,2344,2413,2303,35834,35655,35623,35623,35601,35610,37553,37426,37546,8591,8490,8649,7385,7592,7427,8187,8279,8317,8095,8279,8187,27424,27273,27549,35446,35399,35252,33765,33768,33449,38658,38576,38453,39200,38970,39025,41925,42510,41570,42135,41754,42297,42024,42015,42107,2302,2181,2222,2128,2181,2302,2090,2181,2128,29472,29408,29449,29106,29055,28886,40990,40939,40759,599,532,539,590,532,599,7780,7770,7833,19195,18992,19065,21902,22400,22379,23389,23329,23323,43120,42891,42836,9516,9655,9431,9824,10288,9741,30218,30351,30925,30925,30351,30627,30351,30256,30417,30127,30068,30153,30036,29906,29996,29996,29906,29819,29598,29472,29449,31725,31445,31590,31674,31445,31725,31333,31223,31145,33273,33242,33267,40263,40351,40205,40263,40205,40179,35601,35399,35557,13468,13371,13626,7137,7290,7222,11294,11502,11371,11719,12329,11867,15219,14618,15440,683,885,761,3630,3524,3609,3590,3524,3630,8707,8591,8649,8618,8791,8696,16101,16027,16062,18532,18158,18644,21567,21717,21668,24223,24239,24439,33280,33437,33449,31780,31822,31714,39164,39240,39183,39210,39240,39164,16488,16756,16513,15276,15532,15385,15249,15193,15150,25702,25917,25883,27322,27491,27242,24710,24935,24723,16075,16033,15872,17823,17980,17876,24027,24359,23804,23896,23804,23800,6901,6902,6780,6846,6901,6780,6563,6683,6273,6563,6701,6683,6039,6327,6298,5139,5670,5431,5139,5587,5670,6901,6973,6902,42891,42895,42748,8618,8591,8707,33273,33437,33280,39005,38941,38862,40100,39844,39864,16062,16027,15948,16719,17034,16755,30351,30417,30627,40998,41111,40895,42927,42967,42742,42913,43007,42877,42877,43007,42848,42891,43015,42895,42952,42968,42927,42986,42968,42952,42986,42952,42897,42986,42897,42991,42897,42905,42991,42905,43003,42991,42903,43003,42905,43018,43003,42903,43018,42903,42888,43018,42888,43020,43020,42888,42866,529,462,643,455,645,442,11735,11475,11659,20788,20904,20936,20788,20594,20904,20788,20560,20594,20292,20368,20138,20138,20316,20015,19795,19824,19949,19949,19824,19913,19913,19824,19770,19770,19733,19598,19598,19549,19342,19342,19320,19195,19195,19320,18992,20788,20936,21079,20936,21109,21079,21411,21490,21292,21490,21567,21292,21611,21567,21490,21611,21717,21567,20725,20838,21000,21000,21069,21087,21087,21230,21178,21342,21902,21712,20618,20838,20725,20509,20838,20618,20509,20618,20563,20509,20563,20414,20509,20414,20472,19702,19835,19740,29308,29246,29408,29408,29246,29449,28488,28249,28394,42968,42967,42927,43053,43020,42866,20838,20854,21000,42935,43053,42798,2090,2216,2202,9212,9040,8911,41496,41480,41388,41443,41388,41314,20560,20368,20498,35557,35399,35446,37568,37520,37596,520,793,585,42935,43118,43053,3991,5134,3715,499,520,585,590,578,532,31865,31780,31714,40194,40147,40034,42854,42842,42620,42857,42842,42854,42785,42910,42999,440,462,529,21069,21230,21087,24621,24223,24439,41903,42054,41867,41820,41645,41723,1731,1941,1780,2026,2344,2303,11309,11475,11336,29754,29721,29819,41142,41167,41035,41098,41017,40893,40399,40380,40650,40158,40234,39947,41311,41167,41142,41300,41517,41687,41855,41820,41723,22884,23063,22734,21230,21275,21286,42999,42910,43102,6721,6724,6759,6759,6788,6868,6788,6724,6657,4780,4986,4903,4800,4903,4834,16061,16340,16149,34456,34338,34295,37682,37568,37596,37682,37712,37747,694,910,751,42015,42024,41950,41754,42078,42297,42075,42054,41903,42808,42636,42616,42297,42078,42252,499,585,471,532,578,483,18992,18729,19008,18532,18729,18693,39844,39792,39686,39558,39526,39581,39188,39200,39025,39860,39792,39844,43309,42988,42722,29125,29055,29106,28880,29055,29125,41687,41517,41670,41758,41855,41484,41496,41443,41555,25917,26067,26001,25836,26067,25917,19094,19199,18823,17720,17876,17656,22961,23059,22783,4120,4573,4672,4120,4774,4519,8208,8058,8248,6902,7064,6998,8061,8058,8208,27186,27137,27212,27186,27212,27273,27424,27549,27518,27424,27518,27508,42429,42293,42475,1984,2237,2080,2927,3078,2923,6902,6973,7064,7064,7093,6998,11086,10812,10970,8170,8591,8465,11103,10812,11086,15063,15249,15150,17435,17341,17420,15157,14951,14911,34295,34104,34049,34295,34049,34424,35252,35062,35092,37747,37712,37870,42241,42280,42111,42281,42280,42241,376,450,633,3395,3332,3407,3735,4201,4328,19795,19949,20015,22734,23063,23081,39558,39581,39812,38677,38576,38658,29595,29472,29598,30215,30008,29745,31406,31333,31145,31421,31490,31482,41540,41280,41120,691,489,471,483,578,403,23081,23063,23176,23300,23176,23332,42955,42697,42781,43033,42826,42936,42955,42781,42951,664,700,863,622,700,540,2908,3023,2340,3428,3580,3524,13281,13081,13014,11294,11201,11474,13006,13081,13145,13468,13626,13857,13880,14031,13959,13066,13079,12830,13066,12830,12706,16940,17327,17271,15806,15729,15743,11294,11474,11502,19824,19733,19770,30627,30830,30925,29906,29754,29819,29721,29595,29598,43033,42936,43062,31449,31333,31437,8279,8436,8528,8247,8436,8279,7998,8187,7906,39050,39210,39054,40270,40147,40255,40270,40263,40147,38928,39005,38862,38928,38862,38743,25095,24969,25026,25467,25480,25414,7438,7540,7592,27137,26793,26996,1279,1346,1378,593,683,761,2181,2090,2202,3154,3134,3204,11213,11336,11193,12044,12299,12029,11213,11193,11097,10703,10790,10725,10703,10725,10595,25467,25964,25480,30218,30127,30153,29420,29163,28862,36530,36588,36430,34856,34965,35112,33388,32570,33137,36686,36588,36530,36686,36530,36619,36686,36619,36799,36915,36818,36726,37076,36818,36915,37275,36818,37076,37303,37157,37076,35652,35834,35610,36309,35974,36189,36693,36691,36807,36693,36350,36311,36849,37041,36949,36949,37041,37079,37241,37210,37203,37203,37210,37195,35652,35610,35557,41409,41314,41222,40939,40998,40895,40990,40998,40939,41111,40998,41117,40541,40309,40351,42555,42236,42249,7311,7438,7446,32550,32588,32334,32130,31948,31982,31188,30830,31182,34965,35094,35360,37303,37306,37157,42806,42710,42916,43062,42936,42858,37274,37553,37458,36655,36844,36751,31449,31490,31421,33090,33077,32984,40893,41113,41098,41012,40717,40851,18441,18332,18189,1714,1731,1780,1525,1575,1441,5817,6039,5940,5619,5406,5555,6134,6039,5619,28880,28817,28886,28880,28886,29055,28534,28846,28658,28703,28846,28534,27580,27679,27567,11914,12029,11856,8058,7780,7940,35120,34922,34827,33959,34049,33829,38677,38658,38924,587,750,763,593,761,756,1303,1279,1378,1366,1522,1460,1271,1319,1368,1232,1185,1080,42414,42415,42258,42414,42258,42280,450,484,767,967,1185,1153,1018,1063,1034,1563,1621,1578,1357,1366,1460,4725,4800,4834,4780,4800,4725,27906,27733,27824,27137,27077,26793,27192,27242,26936,35446,35652,35557,34320,34275,34621,43062,42858,43038,40147,40263,40179,40270,40336,40347,15743,15729,15625,42582,42429,42475,22726,22783,22678,22678,22490,22661,37458,37553,37530,42792,42801,43140,42710,42611,42901,587,763,697,23552,23772,23655,25420,25419,25306,23542,23772,23552,926,1018,1034,42292,42241,42154,9440,9516,9431,10595,10630,10571,9440,9431,9257,3658,3590,3630,3556,3590,3658,33437,33765,33449,33242,33273,33280,32917,32437,32984,34621,34275,34456,573,489,691,501,489,573,3245,3154,3204,3520,3428,3524,27336,27186,27273,27124,27192,26936,42135,42153,42015,42024,42107,41925,42222,42153,42135,37241,37203,37079,648,745,874,1950,1929,2001,1771,1929,1950,29472,29531,29408,30036,29754,29906,25319,25219,25095,25480,25964,25487,25480,25487,25439,25477,25619,25600,26067,26264,26001,42728,42582,42508,42728,42321,42636,42901,42495,42960,42672,42555,42249,4818,4715,4744,4554,4715,4578,4715,4818,4578,6902,6585,6780,7137,6998,7093,7290,7461,7222,32344,31948,32130,37879,37897,38007,37530,37553,37561,500,501,573,43265,43007,43458,43146,42886,42804,42801,42943,42984,18371,18441,18189,18149,18086,18012,700,694,751,696,1225,1011,622,694,700,1544,1563,1578,4004,3897,4328,4034,4120,3913,7759,7676,7597,13082,13163,13288,12706,12830,12360,500,539,483,617,587,697,617,697,683,17435,17720,17556,17435,17556,17327,23772,23896,23800,23828,23896,23772,29754,29595,29721,37553,37568,37561,525,500,573,3988,3897,4004,39234,39210,39050,38769,38670,38542,34491,34621,34456,34890,35120,34827,34491,34456,34424,3245,3417,3332,10595,10571,10438,11309,11500,11475,30570,30735,30635,30635,30735,30658,31333,31449,31421,30570,30442,30215,905,926,827,1132,1176,1080,26342,26264,26067,6998,6945,6902,7222,7461,7438,15930,16075,15872,15553,15743,15625,15276,15385,15249,35774,35652,35446,34890,34827,34720,43015,42768,42895,42954,42837,42441,42984,42943,42965,42495,42551,42960,37561,37568,37682,42943,42955,42965,13959,14031,14131,12887,12668,13014,13959,13971,13811,1188,1242,1279,1279,1242,1346,1303,1378,1366,27491,27580,27567,27472,27580,27491,27322,27242,27192,13006,13014,13081,14911,14951,14849,26486,26609,26364,28488,28394,28543,29125,29106,29246,28846,28854,28862,28822,28854,28846,41443,41496,41388,41820,42020,41932,42082,41867,42054,42338,42154,42010,41235,40912,41111,42281,42414,42280,42415,42653,42249,42082,42054,42075,2090,1972,2216,1972,2128,2034,11201,11103,11086,8464,8591,8170,11502,11540,11504,10878,11213,11097,13127,13163,12953,30127,30036,29996,29796,29531,29595,30351,30218,30153,30036,30218,30594,41098,41113,41228,41113,41167,41220,801,648,874,519,617,472,858,1140,1216,15690,15219,15440,16340,16101,16189,16061,16101,16340,15967,16101,16061,15930,15872,15806,25414,25480,25439,25221,25219,25319,25419,25477,25549,25600,25619,25692,3452,3520,3590,3590,3520,3524,3428,3395,3407,23896,24027,23804,23927,24027,23896,28488,28543,28725,27290,27077,27186,31974,31959,31780,31499,31449,31437,41471,41309,41691,525,539,500,18853,19094,18823,35354,35446,35252,37747,37561,37682,3339,3395,3428,27124,27322,27192,42075,41903,42108,3735,3658,4201,4120,4034,4004,3897,3735,4328,3943,4034,3913,9197,9440,9257,7915,7998,7906,7852,7998,7915,23302,23300,23478,21645,21292,21567,23176,23300,23157,24728,24639,24969,7137,6945,6998,7311,7222,7438,36593,35360,36269,11315,11500,11309,34907,34890,34720,34424,34456,34295,1563,1446,1621,1461,1446,1563,41691,41309,41480,539,532,483,3307,3245,3332,2128,2302,2013,33568,33765,33437,33568,33437,33273,39036,38996,38970,37879,37870,37897,39036,38970,39200,25221,25319,25439,11500,11659,11475,41181,41199,41111,40990,40759,40604,677,814,745,578,580,403,18012,18086,17980,18441,18579,18791,18012,17980,17986,23042,23389,23323,23042,23059,22961,42886,42857,42854,43025,42857,42886,15264,15276,15249,15828,15930,15806,42485,42414,42281,42415,42414,42464,40380,40234,40158,39792,39779,39756,40399,40234,40380,40263,40458,40351,39437,39538,39240,732,607,403,30711,31053,30735,28822,28703,28700,41496,41660,41480,41578,41660,41496,43120,43015,42891,7446,7438,7592,7009,6945,7137,34907,34720,34621,35435,35354,35252,6724,6788,6759,5676,5875,5500,16101,15967,16027,15931,15967,15991,25477,25600,25549,26787,26778,26609,25477,25419,25420,38188,38297,38443,37879,37747,37870,9980,10238,10175,8829,8729,9040,20560,20434,20368,20316,19795,20015,19824,19795,19733,19733,19705,19598,20788,20612,20560,20726,20612,20788,20726,20779,20708,21109,21292,21079,21079,21024,20923,40122,39860,39844,455,384,474,474,440,529,462,376,633,450,287,484,76,384,455,442,645,406,793,520,406,520,388,406,499,388,520,393,388,499,20838,20995,20854,20854,20995,21000,21230,21212,21275,22661,22490,22400,20153,20258,20414,20069,20258,20153,42967,43309,42722,43265,43120,43007,43007,43120,42848,42968,43078,42967,43153,43078,42968,43153,42968,42986,43153,42986,43189,43126,42991,43003,43126,43003,43018,43126,43018,43166,43018,43020,43166,43020,43053,43166,42935,42999,43118,42999,43102,43118,953,993,1331,4034,3988,4004,3943,3988,4034,7597,7372,7240,7998,8095,8187,8058,7768,7780,7385,7446,7592,8114,8061,8208,8208,8464,8170,8925,8696,8791,7980,8095,7998,14849,14951,14652,15063,15264,15249,20612,20434,20560,20066,19835,20258,26486,26364,26264,26609,26778,26799,11659,11914,11856,20258,19835,19959,20928,20995,20838,41199,41235,41111,42910,43033,43102,36588,36680,36269,36686,36609,36588,36774,36609,36686,36774,36686,36799,36774,36799,36917,36799,36818,36917,36818,37254,36917,37303,37324,37306,37458,37324,37303,36655,36730,36844,36844,37041,36849,36807,36955,37000,243,440,474,5433,5676,5500,19702,19740,19607,21823,21913,21904,20995,21069,21000,37458,37503,37324,36693,36730,36655,427,477,702,427,744,484,3395,3307,3332,3520,3440,3428,3372,3440,3394,3556,3658,3661,31959,31822,31780,1232,1176,1271,1319,1293,1368,1525,1780,1641,967,1153,1018,31865,31714,31490,40234,40200,39947,1145,1303,1366,1242,1126,1331,1132,1293,1319,3569,3556,3661,18533,18579,18441,17986,17980,17823,23389,23503,23329,25692,25782,25600,23625,23503,23398,28096,27906,27994,26740,26700,26793,27951,27906,27979,39234,39050,39154,42642,42226,42521,42965,42955,42977,17496,17435,17420,42954,42373,42842,4800,4780,4903,4725,4834,4624,35188,35252,35120,36823,36807,37000,42153,42107,42015,41311,41142,41280,42222,42107,42153,42297,42252,42673,42082,42202,42010,42108,41903,41932,42020,41820,42007,41758,41484,41753,39779,39581,39756,1145,1357,1154,1446,1357,1543,41780,41758,41753,25058,24918,24969,25439,25319,25414,27077,27137,27186,42684,42642,42521,42684,42521,42555,471,393,499,648,677,745,756,677,615,3684,3735,3897,7281,7446,7385,7311,7158,7222,10703,10837,10790,11213,11315,11309,11500,11325,11659,12046,12044,11948,10438,10571,10238,10595,10837,10703,38677,38443,38576,39219,39036,39200,42955,42951,42977,43102,43033,43173,1771,1731,1704,1913,1984,2080,16333,16488,16513,15504,15553,15532,15504,15532,15276,29595,29531,29472,28725,28543,28817,29796,29595,29754,41235,41330,41222,41660,41691,41480,27336,27273,27424,27048,27124,26936,27322,27348,27491,28700,28534,28611,41199,41306,41235,41442,41453,41330,41180,40990,40604,341,376,462,13066,13163,13082,12280,12360,12299,15834,15948,16027,15089,15264,15063,15089,15063,14911,18371,18189,18220,17823,17876,17720,23503,23542,23552,23625,23542,23503,28725,28817,28880,37458,37530,37503,39860,39779,39792,40200,40100,39947,41817,41691,41836,42857,42950,42842,43034,42950,42857,39812,39779,39913,4780,4777,4986,4745,4725,4633,15967,15931,16027,15834,15931,15798,15828,15806,15743,37503,37530,37602,38443,38297,38576,7738,7815,7906,7637,7815,7738,20316,20138,20368,18729,18532,18644,43033,43193,43173,7592,7770,7647,10537,10605,10158,33765,33959,33829,34491,34617,34621,33956,33959,33765,471,489,393,478,607,587,411,483,196,2128,1972,2090,2302,2000,2013,1913,2080,1929,2927,2923,2425,2927,3155,3078,11294,11103,11201,11504,11540,11580,11325,11315,11213,13127,13304,13163,22661,22400,22542,31449,31499,31490,31437,31333,31406,31145,31053,31406,37687,37561,37747,40347,40458,40263,40347,40263,40270,40650,40273,40436,40221,40178,40200,40200,40178,40100,41311,41280,41540,40990,41117,40998,43193,43062,43256,42977,42951,42978,19795,19714,19733,21823,22259,21913,905,967,1018,905,1018,926,14652,14951,14457,42313,42297,42368,42624,42429,42709,5431,5670,5694,3913,4120,3958,5596,6134,5619,25058,25095,25219,29531,29308,29408,41453,41409,41222,41453,41222,41330,1262,1544,2272,1775,1913,1929,18189,18149,18220,17593,17823,17720,17593,17720,17435,19714,19705,19733,19544,19702,19607,19639,19199,19331,33090,33267,33242,33396,33267,33248,39210,39302,39240,39402,39302,39210,39050,39005,39154,40255,40147,40194,43140,42801,43116,3245,3108,3154,3440,3339,3428,3372,3339,3440,3440,3520,3394,33090,32984,33248,33030,32984,32437,18149,18012,18220,22726,22919,22783,22745,22919,22726,42978,42951,42916,43116,42801,42984,1091,1188,1074,1303,1188,1279,1188,1303,1074,3735,3668,3661,3569,3668,3591,13145,13081,13281,12306,12317,11719,14131,14209,13971,13766,13988,13579,33396,33568,33273,41969,41820,41855,42464,42414,42583,41969,41855,41758,19705,19572,19598,22071,22046,21939,1143,1126,1242,10438,10837,10595,8829,8715,8729,8247,8279,8095,15413,15504,15276,15553,15665,15743,15413,15276,15264,38668,38123,37536,38668,39150,39186,42464,42458,42415,42281,42292,42485,15931,15834,16027,17671,17594,17407,25600,25782,25702,26778,27048,26936,24124,24710,24027,40333,40255,40194,489,421,393,19572,19549,19598,19331,19199,19094,23081,23176,23157,21846,21913,21939,13163,13304,13288,12165,12299,12044,41817,41753,41691,41817,41780,41753,688,1011,736,7971,8247,8095,7121,7372,7346,26574,26486,26264,38658,38793,38924,18987,18729,18992,43116,42984,43068,42979,42978,42916,42979,42916,42901,14975,15089,14911,14390,14477,14457,41540,41120,41418,42313,42222,42135,7980,7998,7852,23542,23828,23772,23625,23828,23542,42950,42954,42842,42875,42728,42636,43046,42954,42950,29308,29125,29246,41409,41555,41314,41623,41555,41629,25136,25058,25219,23157,23300,23302,25136,25219,25205,489,501,421,19549,19425,19342,3155,3030,3280,2774,2547,2456,42902,42960,42551,42672,42684,42555,1544,1461,1563,1453,1461,1544,6551,6686,6481,6788,7121,7337,13691,13857,13880,40100,40122,39844,40221,40200,40234,41687,41670,41860,19401,19331,19189,23332,23478,23300,22919,23042,22961,22876,23042,22919,27077,26964,26793,27064,26964,27077,27508,27733,27951,27733,27906,27951,615,593,756,648,801,704,694,622,736,540,700,664,12044,12029,11914,10837,10878,10968,10804,10878,10837,10571,10175,10238,3183,3411,3481,39542,39398,39586,39542,39406,39255,38924,38793,38996,39812,39581,39779,3988,3771,3897,4120,3939,3958,3451,3991,3715,7971,7980,7852,11314,11103,11294,11314,11294,11371,39465,39219,39188,40333,40336,40255,39028,39005,38928,7597,7651,7759,7551,7651,7597,501,500,401,421,501,401,251,427,484,456,540,664,3339,3307,3395,3290,3307,3339,3520,3379,3394,19425,19320,19342,31865,31974,31780,30570,30215,30059,42653,42672,42249,42202,42082,42075,25782,25836,25917,25773,25836,25782,1323,1453,1262,2890,3134,3154,1984,2026,2303,1951,2026,1984,1951,1984,1913,18220,18012,18253,18771,18853,18823,18012,18022,18253,24621,24639,24728,21745,21904,21846,41555,41578,41496,41623,41578,41555,42984,42965,43068,43185,42979,42901,704,801,833,858,1216,993,550,688,476,42808,42616,42928,42311,42203,42222,1126,953,1331,1188,1143,1242,1091,1143,1188,10158,10769,10812,11914,11659,11763,27906,28096,27979,33568,33737,33765,34357,34424,34049,34890,35188,35120,33728,33737,33568,33396,33273,33267,40170,40122,40100,41442,41330,41235,43007,42913,43458,43146,43025,42886,15006,15089,14975,42193,42202,42075,41911,41969,41758,41911,41758,41780,3036,3108,3245,39913,39779,39860,41012,40851,41017,40178,40170,40100,41012,41017,41143,40577,40448,40347,40347,40448,40458,40458,40541,40351,41254,41181,41287,41117,41181,41111,40336,40270,40255,4745,4777,4780,4745,4780,4725,12317,12329,11719,15834,15690,15440,13811,13691,13959,17407,17594,17252,15930,16081,16075,15870,16081,15930,15665,15553,15504,29359,29125,29308,29359,29045,29125,30218,30036,30127,31188,31182,31445,37879,37831,37747,38007,37831,37879,41181,41117,41287,42902,42551,42642,42653,42415,42458,7446,7281,7311,7770,7780,7647,24728,24969,24918,24728,24918,24870,42928,42616,42837,14477,14652,14457,13988,14390,14457,14642,14390,14312,36979,37041,36844,36693,36807,36730,36311,36691,36693,42108,41932,42020,6273,6683,6780,17496,17593,17435,401,500,411,3894,3988,3943,5596,5508,5694,18771,18823,18579,18012,17986,18022,21904,21913,21846,23706,23690,23478,36979,36844,36730,43146,42804,43172,42954,43094,42837,34537,34424,34357,35354,35435,35446,39171,38996,39036,38443,38341,38188,39018,39028,38928,37416,37402,37210,40399,40367,40234,39437,39240,39302,5508,5431,5694,41311,41220,41167,41228,41220,41346,14642,14652,14477,26813,26740,26793,27198,27064,27077,26787,27048,26778,27124,27348,27322,26787,26609,26486,4747,4745,4633,411,500,483,42965,42977,43068,37041,37241,37079,688,668,1011,584,668,569,3036,3086,3108,3569,3661,3668,8729,8436,8188,8729,8715,8436,9655,9741,10288,33248,33267,33090,34357,34049,33959,33030,32913,33015,39586,39398,39558,39406,39465,39188,39219,39171,39036,13006,12887,13014,13145,12887,13006,15743,15665,15727,15413,15665,15504,29045,28725,28880,29045,28880,29125,42203,41925,42107,752,858,993,7009,7137,7222,7647,7780,7768,8170,8061,8114,17758,17986,17823,17435,17327,17341,23927,24124,24027,23927,23896,23828,628,615,677,478,587,480,628,677,648,23706,23999,23690,25136,24918,25058,40084,39913,39860,39513,39406,39542,40383,40221,40234,43025,43031,42857,43162,43031,43025,33563,33728,33568,39241,39171,39219,1731,1771,1950,1525,1641,1575,564,683,593,16061,15991,15967,13959,13691,13880,15894,15991,16061,43068,42977,43079,7009,7222,7158,26813,26793,26964,26596,26787,26486,37382,37416,37210,42338,42367,42154,42688,42684,42672,13634,13691,13692,20612,20532,20434,20434,20323,20368,19795,19736,19714,19714,19736,19705,19705,19659,19572,19572,19628,19549,19483,19353,19425,19425,19353,19320,20726,20708,20612,20779,20726,20788,20779,20788,20923,20788,21079,20923,21292,21024,21079,21354,21024,21292,27479,27336,27424,27012,26813,26964,28224,28249,28258,42341,42338,42010,42128,42108,42020,42007,41820,41969,43078,43309,42967,43189,42986,42991,43189,42991,43126,43189,43345,43313,43053,43167,43166,43118,43167,43053,43282,43337,43167,20708,20532,20612,21668,21645,21567,20338,20461,20337,20337,20461,20472,20472,20461,20509,20768,20928,20838,20995,21076,21069,21069,21076,21230,20338,20337,20258,20338,20258,20330,19835,19702,19753,20532,20323,20434,19753,19702,19708,21668,21745,21645,31674,31188,31445,31674,31725,31948,29561,29163,29420,28822,28846,28703,41143,41017,41098,40399,40426,40367,40367,40383,40234,1441,1575,1600,1441,1600,1115,1661,1293,1115,1319,1176,1132,3036,3245,3307,3108,3086,3154,3755,3771,3988,4744,4715,4554,8618,8707,8791,13634,13468,13857,18771,18579,18666,19708,19702,19544,18579,18553,18666,20323,20316,20368,21668,21904,21745,20928,21076,20995,27479,27424,27508,28258,28249,28488,29359,29308,29531,28056,27979,28224,37602,37530,37561,37355,37275,37306,37275,37076,37157,36774,36723,36609,37602,37561,37687,42222,42203,42107,42313,42135,42297,42187,42193,42075,21908,21939,22046,24587,24223,24621,43031,43034,42857,43135,43034,43031,40265,40170,40178,40265,40178,40221,18253,18371,18220,17341,17327,16940,17341,16940,17052,42902,43249,43101,43079,42977,42978,43118,43102,43282,1515,1714,1780,11325,11500,11315,12953,13163,13066,13304,13766,13579,41629,41555,41409,41836,41691,41660,41306,41442,41235,1453,1544,1262,2000,2302,1993,5619,6039,5817,7158,7311,7279,7311,7281,7279,35123,35188,34890,376,363,450,440,341,462,299,341,440,277,474,384,277,384,113,297,442,291,345,406,388,345,388,350,388,393,350,393,351,350,37687,37747,37737,31437,31493,31499,31406,31493,31437,40577,40541,40448,40448,40541,40458,41254,41306,41199,40577,40347,40336,13468,13145,13281,11580,11314,11504,12280,12299,12165,14911,14849,14975,41836,41660,41578,42368,42297,42438,18579,18533,18553,19708,19544,19550,23398,23503,23389,21463,21342,21275,2134,2547,2344,1775,1951,1913,1775,1929,1771,11504,11314,11371,9195,9330,9173,11931,11867,12329,10804,11213,10878,10911,11325,11213,41228,41158,41098,41228,41113,41220,43033,43062,43193,9516,9741,9655,8188,8436,8247,7971,8095,7980,39586,39558,39683,39513,39465,39406,39402,39437,39302,39402,39210,39234,26342,26574,26264,25419,25065,25094,33396,33563,33568,33081,33030,33015,39683,39558,39812,43034,43044,42950,43135,43044,43034,341,363,376,3640,3668,3735,3372,3290,3339,33469,33563,33396,34537,34491,34424,34537,34617,34491,39276,39241,39219,38896,38534,38677,6657,6655,6788,6266,6551,6481,6562,6551,6438,4812,4986,4777,31958,31674,31948,32344,32334,32588,37672,37687,37737,40559,40426,40399,3771,3684,3897,4818,4574,4578,550,668,688,502,270,422,775,270,664,17823,17593,17758,16513,16075,16333,43079,42978,42979,42720,42642,42684,6298,5940,6039,7279,7281,7361,6736,7121,6788,7754,7852,7815,7240,7551,7597,11931,11776,11867,12169,12165,12044,12169,12280,12165,19544,19331,19550,18441,18371,18533,33765,33737,33956,41246,41228,41382,41694,41540,41418,41736,41418,41687,43062,43038,43256,43079,42979,43694,1461,1252,1446,1912,1972,2034,1349,1704,1714,1176,1232,1080,27012,26964,27064,25487,25964,25649,28878,28822,28741,27775,28061,27811,3755,3684,3771,20010,19736,19795,19320,19100,18992,19331,19401,19550,21913,22071,21939,39154,39028,39267,39018,38743,38769,17671,17826,17594,17826,17962,17594,301,704,305,6551,6655,6657,42688,42720,42684,42565,42458,42464,40426,40383,40367,39933,39683,39812,1080,1185,976,1185,967,899,23398,23389,23042,25619,25773,25692,43044,43046,42950,42808,42875,42636,43121,43046,43044,19736,19659,19705,19094,18853,18932,23081,23157,23179,13691,13634,13857,13468,13237,13145,14209,14618,13971,27628,27479,27508,27336,27290,27186,28224,27979,28096,28258,28488,28761,42045,42007,41969,42108,42187,42075,18932,18853,18810,18533,18371,18299,43038,43140,43158,43091,42901,42960,12668,12887,12828,12458,11931,12329,27628,27508,27701,41943,41911,41817,41817,41911,41780,41254,41199,41181,42185,42187,42108,42341,42010,42202,42604,42565,42464,595,827,1225,696,1011,668,7361,7281,7385,6563,6273,6298,42485,42292,42367,23179,23157,23302,43140,43183,43158,28761,28488,28725,41409,41453,41629,6655,6736,6788,17120,17252,17318,15991,15798,15931,15894,15798,15991,15727,15828,15743,15413,15264,15117,25692,25773,25782,24935,24710,25094,3913,3894,3943,3958,3894,3913,7852,7915,7815,26938,27090,27048,26049,26067,25836,41629,41453,41711,7768,8058,8061,34909,34907,34621,33710,33737,33728,40453,40265,40221,393,313,351,421,313,393,3487,3556,3569,3452,3590,3556,3487,3569,3521,18853,18771,18810,33563,33710,33728,33081,33248,32984,33081,32984,33030,3640,3735,3684,8925,9194,9077,7902,7768,8061,18643,18771,18666,17593,17496,17502,33491,33469,33396,23625,23792,23828,23699,23792,23625,43046,43048,42954,42624,42238,42429,43235,43048,43046,5596,5529,5508,5508,5420,5431,5431,5192,5139,6585,6273,6780,36807,36823,36730,37282,37382,37241,37241,37382,37210,36189,35834,35652,1714,1704,1731,1515,1780,1525,5619,5529,5596,29420,28862,28854,37275,37355,37254,37306,37324,37355,37275,37157,37306,36609,36723,36588,36823,36979,36730,30570,30711,30735,30638,30711,30570,39614,39513,39542,39444,39276,39219,39860,40122,40157,41957,41670,41588,42510,41925,42203,41721,41836,41578,4745,4747,4777,4633,4725,4518,35434,35435,35252,35434,35252,35188,43140,43116,43183,584,696,668,25487,25649,25488,24728,24587,24621,25094,24710,24893,43249,42902,42642,42787,42688,42672,2013,1912,2034,1993,2302,2529,3626,3640,3684,39028,39154,39005,39018,39053,39074,6945,7009,7011,7320,7361,7385,34909,34621,34617,38534,38341,38443,38534,38443,38677,42312,42202,42193,31865,31490,31499,31399,31406,31053,40153,40157,40278,40426,40559,40383,40841,40650,40436,40841,40436,41012,41143,41098,41158,565,564,593,565,593,615,15894,15690,15798,17252,17120,17407,17826,18158,17962,37672,37602,37687,37672,37503,37602,43224,42928,42837,421,401,313,19497,19425,19549,1928,1912,2013,40157,40122,40170,40040,39905,40186,39707,39905,39538,41303,41143,41158,41246,41158,41228,41220,41311,41346,480,587,617,23792,23927,23828,23699,23927,23792,37416,37608,37536,37282,37241,37041,7427,7320,7385,7902,8061,8170,28822,28878,28854,27679,27580,28061,38136,38007,37897,41876,41736,41687,12706,12953,13066,12046,12169,12044,15006,15264,15089,14849,14652,14642,29045,28899,28725,29796,29359,29531,28899,29359,29375,28878,29420,28854,29561,30059,29745,313,401,304,3894,3755,3988,3766,3755,3894,13634,13538,13468,13971,14618,14762,15798,15690,15834,15894,16149,15843,16333,16075,16081,15587,15727,15665,19353,19289,19320,25773,25831,25836,25902,25831,25773,976,1185,899,1132,1171,1293,1377,1775,1704,29809,30059,29561,41346,41311,41440,41180,41117,40990,41818,41711,41941,42294,42312,42193,42174,42185,42108,42128,42020,42007,42128,42007,42131,5299,5192,5431,13534,13538,13634,704,628,648,615,628,402,25205,25219,25221,25420,25619,25477,24340,24710,24124,478,403,607,43172,42804,43015,43048,43096,42954,43172,43015,43326,14390,13988,14159,14642,14477,14390,26574,26596,26486,26473,26596,26574,42530,42485,42367,42565,42653,42458,42570,42485,42637,283,313,304,25384,25487,25488,27377,27290,27336,27198,27290,27289,27290,27377,27289,42294,42193,42187,3521,3452,3487,3487,3452,3556,3394,3290,3372,1969,1928,2000,3591,3668,3640,3411,3451,3715,4706,4812,4747,3225,3451,3411,3025,3481,3030,8618,8465,8591,9099,9194,9298,9099,9298,9330,25345,25205,25221,25984,25649,25964,2456,2547,2134,3265,3290,3394,33248,33491,33396,33698,33710,33563,32156,32437,31959,519,480,617,402,565,615,17120,17034,17407,17112,17034,17120,24870,24587,24728,23478,23373,23302,4818,4577,4574,478,14,403,617,683,472,154,477,427,688,736,476,18214,18158,18532,41440,41311,41559,3549,3591,3640,8320,8465,8401,33698,33563,33469,35423,35188,35251,9330,9298,9596,43116,43068,43208,43183,43116,43208,41699,41629,41818,41623,41721,41578,42045,41969,41911,18207,18214,18446,17502,17496,17420,18643,18666,18553,17502,17420,17381,31569,31499,31493,41534,41180,40604,40194,40034,39694,3549,3521,3591,4198,4120,4519,7971,8042,8247,7637,7738,7651,7637,7651,7551,7637,7551,7564,13766,13304,13425,27198,27012,27064,42429,42582,42934,42334,42311,42222,41876,41789,41736,1453,1359,1461,1143,1091,1126,858,639,833,1252,1359,1323,12706,12360,12280,27348,27124,27164,28878,29047,29420,4262,4198,4519,33710,33956,33737,10158,10812,10752,11580,11488,11314,11719,11488,11580,12828,12887,13145,16333,16081,16298,25136,24870,24918,25345,25221,25439,37737,37747,37831,41559,41311,41540,42641,42653,42565,43208,43280,43308,27090,27124,27048,26049,26342,26067,26473,26342,26298,502,456,664,422,456,502,10812,11103,10776,17381,17420,17341,23548,23373,23478,23072,23398,23042,23993,24177,24124,22745,22726,22661,9440,9383,9516,11763,12044,11914,32131,32156,31959,25538,25619,25420,25306,25419,25094,15006,15117,15264,15820,15828,15727,15870,15930,15828,14642,14975,14849,1114,1171,1132,1114,1132,1080,6551,6562,6655,6655,6598,6736,6736,6993,7121,6438,6551,6266,9440,9233,9383,13811,13692,13691,13012,12828,13145,13971,13692,13811,13227,13304,13127,15073,15006,14975,18643,18553,18533,37914,37737,37831,37914,37831,38007,42045,41911,42081,42185,42294,42187,43208,43386,43280,1074,1303,1145,42128,42174,42108,42312,42341,42202,42604,42641,42565,41699,41721,41623,41699,41623,41629,2890,3154,3086,3452,3379,3520,3265,3379,3452,3521,3569,3591,39754,39586,39683,39614,39542,39586,39252,38996,39171,41943,41817,41836,1323,1359,1453,2000,1928,2013,3036,3307,3133,41254,41363,41306,41534,40604,41490,27048,26787,26884,42334,42222,42313,11763,11659,11600,12065,12706,12280,43189,43313,43153,43153,43329,43078,43345,43189,43126,43345,43126,43310,43126,43166,43310,43166,43327,43310,43167,43327,43166,43337,43327,43167,43167,43118,43282,113,384,76,177,287,363,363,287,450,442,406,291,406,288,291,345,288,406,20532,20494,20323,20323,20432,20316,19445,19628,19652,19736,19628,19659,19659,19628,19572,19353,19357,19289,20708,20494,20532,20605,20494,20708,20605,20708,20802,20708,20779,20802,20779,20873,20802,20923,21024,20873,21908,21645,21745,21939,21745,21846,43313,43329,43153,3626,3684,3755,277,243,474,33511,33491,33248,33710,34027,33956,32913,33030,32437,39808,39754,39683,39933,39812,39913,40157,40170,40322,3638,3626,3755,4198,4174,4120,4155,4174,4198,20768,20838,20509,21076,21212,21230,20338,20330,20461,20322,20330,20258,19959,19835,19753,19959,19753,19694,19753,19708,19576,20503,20509,20461,43329,43309,43078,43282,43102,43173,43162,43135,43031,43162,43025,43146,243,299,440,4747,4812,4777,4725,4624,4518,43335,43282,43173,472,683,564,480,443,478,472,564,481,17694,17758,17593,18580,18643,18533,17303,17381,17341,23993,24124,23927,41180,41287,41117,736,622,476,696,595,1225,976,1114,1080,16488,16779,16940,15870,15828,15820,40453,40221,40383,41736,41694,41418,42220,41588,41570,42013,41943,41836,43193,43335,43173,40650,40559,40399,40587,40559,40822,41294,41012,41143,41303,41158,41246,41382,41228,41346,40391,40577,40336,40391,40336,40333,23690,23999,24223,25054,24870,25136,26884,26787,26596,42354,42341,42312,3766,3894,3958,20928,21212,21076,3133,3307,3290,39997,39933,39913,42918,42787,42915,43185,43091,43207,43101,43091,42960,42583,42414,42485,21212,21239,21275,26342,26473,26574,25902,25836,25831,42570,42583,42485,38136,37897,38341,38104,37914,38007,2134,2344,1567,1704,1775,1771,1515,1525,1447,4554,4396,4664,4449,4396,4554,14762,14618,15219,16149,16340,16755,15448,15665,15413,19576,19708,19550,41545,41382,41346,41545,41346,41440,43193,43256,43335,1447,1525,1204,36926,36774,36917,36926,36723,36774,36926,36917,37050,36818,37275,37254,37631,37355,37324,5619,5555,5529,5529,5420,5508,4818,5147,4577,7009,7158,7011,9440,9197,9233,9197,9109,9233,22924,22734,23081,23690,23813,23676,37503,37631,37324,40415,40391,40333,43135,43121,43044,43162,43121,43135,13534,13468,13538,29420,29678,29561,28700,28741,28822,28701,28741,28700,345,272,288,350,272,345,216,272,350,7011,7158,7279,519,443,480,481,564,565,5555,5420,5529,4798,5433,5500,7240,7372,7121,7852,7814,7971,26618,26884,26596,3713,3766,3958,3939,4120,4174,39087,39018,39074,39280,39402,39234,39905,40040,39694,43038,43158,43256,2856,2890,3086,9197,8911,8938,18299,18371,18253,19448,19576,19550,22542,22745,22661,23398,23699,23625,40157,40084,39860,40153,40084,40157,37503,37672,37631,4812,4798,5500,4706,4633,4622,35684,35774,35446,35423,35434,35188,34909,34617,34992,12904,13030,12953,12953,13030,13127,11600,11659,11325,967,905,799,1171,1115,1293,13692,13534,13634,15470,15219,15690,16472,16779,16488,15912,16298,16081,16472,16488,16333,25205,25168,25136,25384,25345,25439,25384,25439,25487,25333,25306,25094,25832,25902,25773,39276,39171,39241,39754,39614,39586,39837,39614,39754,39808,39683,39933,42928,42875,42808,42368,42334,42313,43365,42875,42928,351,283,350,177,363,341,27472,27348,27371,27472,27491,27348,27712,28061,27580,33241,33248,33081,34992,34617,34537,39280,39234,39154,42045,42131,42007,42128,42167,42174,42174,42294,42185,42167,42131,42164,9383,9741,9516,32958,32913,32892,33015,33182,33081,31974,32131,31959,32074,32131,31974,31569,31493,31406,31399,31053,31442,37738,37672,37737,27164,27124,27090,42530,42367,42338,42531,42294,42174,4396,4262,4519,4220,4262,4202,7361,7320,7279,7427,7592,7519,7592,7647,7519,23179,23302,23294,23690,24223,23813,23548,23690,23676,23501,23699,23398,24177,24340,24124,34357,33959,33956,42787,42720,42688,43256,43158,43412,9024,9077,9099,9099,9077,9194,8401,8465,8618,8465,8320,8170,9195,9099,9330,32982,32913,32958,39945,39808,39933,351,313,283,3626,3549,3640,3237,3265,3452,3379,3265,3394,3036,2856,3086,3529,3549,3626,8401,8618,8476,22745,22876,22919,23072,22876,23148,41789,41694,41736,42081,42131,42045,41959,42013,41836,41453,41442,41711,943,953,1126,435,481,402,879,953,884,27140,26740,26813,27290,27198,27077,27336,27479,27377,27951,28056,27701,27133,27164,27090,42220,42142,41957,41773,41540,41694,42438,42334,42368,42378,42354,42312,287,251,484,2031,1993,2529,2272,1288,1262,2373,2908,2340,5147,4606,4577,20010,19795,20316,19289,19193,19320,19331,19094,19189,21463,21902,21342,24314,24340,24177,38441,38136,38341,37914,37838,37737,43158,43183,43308,15073,15117,15006,16350,16333,16298,15073,14975,14898,42504,42338,42341,42591,42604,42464,11763,11948,12044,41579,41559,41540,3638,3529,3626,4031,3939,4174,7637,7754,7815,7591,7754,7637,34646,33991,34223,34646,34223,34965,12280,12169,12053,13766,14159,13988,28061,28611,28184,28741,28951,28878,2340,3023,2346,31530,31399,31442,31053,31412,31442,9980,9824,9798,8938,8911,8713,40069,39997,40084,40084,39997,39913,39707,39538,39437,401,411,304,19628,19497,19549,23302,23373,23294,7878,8042,7971,43426,43015,43120,43235,43096,43048,17694,17593,17502,17694,17598,17633,6585,6902,6945,7035,7011,7279,7519,7647,7554,39219,39465,39444,584,627,696,543,627,584,25238,25168,25205,27140,26813,27012,25306,25436,25420,27014,26938,26884,26884,26938,27048,25333,25436,25306,31530,31569,31406,26474,26596,26473,19497,19483,19425,355,443,519,481,565,402,12053,12169,12046,29359,28899,29045,28761,28899,29375,29754,30036,29796,28772,28951,28741,34196,33388,33137,22876,23072,23042,23699,23993,23927,23232,23072,23148,19189,18932,19085,19189,19094,18932,32982,33015,32913,31569,31865,31499,33491,33698,33469,32982,33182,33015,32437,32892,32913,41382,41362,41246,41457,41362,41382,41287,41363,41254,41610,41363,41287,41610,41287,41180,40791,40541,40577,43308,43183,43208,40322,40170,40265,40453,40383,40559,40040,40194,39694,40391,40647,40577,33528,33698,33491,39294,39276,39444,39465,39627,39444,39837,39754,39808,39945,39933,39948,39402,39547,39437,40828,40637,40801,39267,39280,39154,15117,15448,15413,15476,15448,15445,18180,18299,18253,17806,17694,17633,42709,42429,42934,42949,42787,42918,42591,42464,42583,42591,42583,42589,43235,43046,43121,1114,1052,1171,799,905,827,13611,13534,13692,13611,13692,13971,14216,14159,13987,13425,13304,13227,7778,7814,7754,7754,7814,7852,39252,38924,38996,304,411,83,39948,39933,39997,43366,42913,42988,7035,7279,7320,6654,6993,6736,6598,6655,6562,274,799,827,3486,3521,3549,4108,4155,4198,4220,4198,4262,7427,7332,7320,7554,7647,7768,14898,14975,14876,34408,34196,33137,34856,34646,34965,415,622,540,627,595,696,415,540,456,27198,27140,27012,27508,27951,27701,40587,40453,40559,40194,40415,40333,18180,18253,18022,23294,23373,23349,23373,23436,23349,43172,43159,43146,43330,43159,43172,8320,8154,8170,8017,8154,8178,25436,25538,25420,25404,25538,25436,42739,42653,42641,196,483,403,19269,19193,19289,18214,17962,18158,18810,18771,18709,35684,35446,35435,36823,37000,36979,36979,37103,37041,35684,35435,35434,38104,38007,38136,37965,37838,37914,355,519,329,323,422,192,23940,23993,23699,24664,24893,24710,43096,43094,42954,42934,42582,42983,43204,43094,43096,40153,40069,40084,40278,40069,40153,953,879,993,1006,1126,1091,799,899,967,1359,1252,1461,1873,1912,1928,12799,12904,12953,12799,12953,12706,28611,28701,28700,31442,31412,31480,28772,28701,28775,28772,28930,28977,27712,27580,27472,27371,27348,27164,42673,42438,42297,41773,41789,41890,42489,42504,42341,42489,42341,42354,42378,42312,42294,6993,7168,7121,7146,7168,6988,19193,19100,19320,17594,17318,17252,15608,15630,15843,18446,18214,18532,18709,18771,18643,18022,17986,17758,21913,22259,22071,23975,23870,23813,40453,40322,40265,4633,4706,4747,4622,4633,4518,6583,6598,6562,35682,35684,35434,34890,34907,35123,8017,7902,8170,7814,7878,7971,8713,8911,8729,7778,7878,7814,10438,10804,10837,12065,12053,11984,11948,12053,12046,10911,10804,10836,10232,10438,10238,9980,10175,9824,3230,3265,3237,2595,3023,3134,3755,3766,3638,4155,4031,4174,4021,4031,4155,7300,7332,7427,7679,7554,7768,7493,7564,7551,34646,34631,34408,34824,34631,34646,15894,15630,15690,16898,16755,17034,25832,25773,25619,26049,26298,26342,27307,27371,27164,40318,40157,40322,41255,40841,41012,42604,42739,42641,42589,42583,42570,42533,42466,42438,42582,42728,42983,550,569,668,398,569,550,1993,1969,2000,1853,1969,1993,2031,2529,2284,16350,16472,16333,17694,17502,17598,17806,18022,17758,16350,16298,16307,25238,25205,25345,25238,25345,25384,3127,3133,3290,32437,32156,32316,33182,33241,33081,19100,18987,18992,43280,43386,43398,36723,36680,36588,36926,36828,36723,37022,36828,36926,37050,36917,37163,36917,37254,37163,36311,35981,36309,37382,37474,37416,35981,35974,36309,422,436,456,323,436,422,2373,2200,2284,2595,3134,2890,10776,11103,11024,11488,11719,11566,31569,31678,31865,32284,32156,32131,31399,31530,31406,29678,29420,29686,36890,36680,36723,35974,35834,36189,37163,37422,37192,37000,37103,36979,1145,1366,1357,911,1052,1114,1171,1052,975,41303,41294,41143,41303,41246,41362,41545,41440,41559,42131,42167,42128,42081,41911,41943,42081,41943,42145,996,1006,1091,3713,3958,3780,16307,16298,16186,15107,15448,15117,14876,14975,14642,27951,27979,28056,27305,27140,27198,37163,37254,37437,39294,39252,39171,39294,39171,39276,39513,39627,39465,39505,39547,39402,39156,39267,39028,39087,39028,39018,43159,43162,43146,43332,43162,43159,11812,11948,11763,31674,31764,31188,32812,32344,32588,1154,1357,1446,7146,7240,7168,7168,7240,7121,13227,13127,13030,14802,14876,14784,13227,13030,12973,38534,38441,38341,38660,38441,38534,38660,38534,38896,42164,42081,42531,5420,5299,5431,3947,3966,4031,5555,5299,5420,5406,5299,5555,5406,5619,5817,6273,5940,6298,6182,5940,6273,37103,37282,37041,2919,3025,3030,3451,3333,3991,2919,3030,2927,8178,8154,8320,8154,8017,8170,9454,9330,9596,43185,42901,43091,43412,43280,43398,2134,1567,1882,9966,9980,9893,9980,9798,9893,27465,27377,27479,27014,27090,26938,31530,31678,31569,42531,42378,42294,42777,42604,42591,20494,20432,20323,19445,19483,19497,19445,19357,19483,19483,19357,19353,19193,19155,19100,18980,18899,18987,20779,20923,20873,4031,3966,3939,4484,4554,4578,20330,20503,20461,20928,21221,21212,21212,21221,21239,21239,21463,21275,20466,20503,20330,20322,20258,20172,20258,19959,20172,20221,20226,20172,21037,20966,20873,20873,20966,20912,20503,20768,20509,23232,23398,23072,34631,34552,34408,34610,34552,34631,299,177,341,287,220,251,251,221,427,243,187,299,277,187,243,113,187,277,142,442,297,186,297,291,186,291,117,291,288,198,288,272,198,20605,20432,20494,21908,21745,21939,36189,35652,35774,37282,37474,37382,43400,43389,43345,43345,43389,43313,43313,43496,43329,43329,43496,43309,43309,43366,42988,43400,43345,43310,43400,43310,43327,43400,43327,43440,43327,43337,43394,43337,43453,43394,43282,43453,43337,43335,43409,43282,4493,4574,4577,37738,37631,37672,38171,38104,38136,39018,38769,39053,43335,43256,43409,18709,18643,18580,17806,17758,17694,23232,23501,23398,23993,24191,24177,22876,23032,23148,19753,19576,19583,18533,18299,18290,23940,24191,23993,25885,26049,25902,569,574,584,799,796,899,451,574,380,402,353,319,849,884,953,17502,17381,17598,15587,15665,15448,19576,19448,19583,23813,23870,23747,25488,25238,25384,27305,27198,27289,11588,11600,11460,19550,19401,19448,36386,36189,36282,15476,15587,15448,25902,26049,25836,26298,26474,26473,25832,25619,25538,42777,42739,42604,42589,42570,42599,1515,1349,1714,2344,2026,1567,1204,1525,1441,4202,4262,4396,7300,7427,7519,7011,6585,6945,7517,7519,7554,21225,21221,21023,26618,26474,26544,42530,42338,42504,39449,39402,39280,40724,40511,40415,39449,39280,39293,3133,2985,3036,3265,3251,3290,3230,3251,3265,33144,33241,33182,35123,34907,34909,33144,33182,32982,39563,39707,39437,12904,12873,12973,12873,12697,12818,28701,28772,28741,29047,28772,28977,43409,43892,43891,552,595,627,18290,18299,18180,19448,19315,19435,37738,37737,37838,4493,4484,4574,4574,4484,4578,35684,35682,35774,34357,33956,34236,136,177,299,39252,39205,38924,39837,39808,39922,43474,43366,43309,43332,43121,43162,32316,32156,32284,43101,42960,42902,42642,43182,43249,14898,14876,14952,15107,15117,15073,42651,42530,42685,41579,41545,41559,41687,41860,41876,198,272,208,21370,21463,21239,436,415,456,323,415,436,17342,17318,17448,17962,18214,18207,24191,24314,24177,24151,24314,24191,42949,42720,42787,34027,33710,33698,27628,27465,27479,27377,27305,27289,28056,28224,28258,13673,13611,13971,13534,13237,13468,11566,11719,11867,42167,42531,42174,42378,42489,42354,42081,42164,42131,41818,41721,41699,451,543,574,574,543,584,16940,16779,17052,15912,16081,15870,25152,25333,25094,249,476,622,1006,943,1126,933,943,1006,996,1091,1074,2200,2031,2284,1969,1873,1928,7902,7817,7768,8618,8696,8476,24664,24710,24340,27639,27465,27628,39128,39156,39087,39087,39156,39028,4073,4108,4167,4220,4108,4198,3780,3958,3939,3054,3127,3251,34824,34856,34935,2149,2373,2340,2149,2200,2373,177,202,287,2653,2919,2927,3025,3183,3481,4484,4449,4554,4404,4449,4484,42466,42311,42334,41818,41629,41711,37777,37738,37837,9626,9558,9596,8476,8696,8487,22259,22477,22071,24587,24870,24881,43208,43068,43386,43101,43207,43091,31530,31480,31678,32284,32131,32074,30638,30570,30059,15630,15470,15690,15608,15470,15630,15748,15820,15727,15107,15073,15035,41759,41579,41540,208,272,216,350,283,216,202,220,287,1853,1873,1969,1252,1154,1446,872,849,953,628,353,402,42438,42466,42334,42673,42252,42624,42685,42850,42744,15035,15073,14898,42637,42599,42570,42589,42777,42591,42787,42672,42915,42589,42599,42767,15748,15727,15635,6266,6481,5501,6598,6654,6736,6481,5676,5501,24444,24343,24314,24314,24343,24340,220,221,251,19401,19315,19448,43412,43158,43308,43412,43308,43280,41294,41319,41012,41457,41303,41362,41457,41382,41524,3251,3127,3290,3452,3521,3237,2773,3183,3025,8188,8247,8042,9550,9741,9383,39922,39808,39945,39948,39997,40152,40278,40157,40318,8696,9077,8966,39294,39325,39252,39627,39513,39614,39293,39280,39267,39547,39563,39437,7912,7817,7902,7708,7817,7749,7878,7885,8042,7591,7778,7754,7591,7637,7564,7493,7551,7240,34610,34290,34552,34552,34290,34408,33388,33130,32570,4283,4331,4317,4449,4331,4396,216,283,80,4073,4021,4108,4108,4021,4155,7332,7035,7320,7495,7517,7554,7178,7493,7240,22734,22477,22259,9558,9454,9596,16779,16878,17052,18100,18290,18180,19085,18932,18977,25054,25136,25106,22734,22924,22477,40509,40322,40453,40559,40650,40822,40618,40587,40700,43094,43149,42837,43242,43235,43121,43326,43426,43347,43326,43015,43426,476,482,550,398,482,335,25106,25136,25168,25106,25168,25262,25984,25772,25649,15246,14762,15219,6438,6583,6562,25333,25404,25436,27133,27014,27069,25289,25404,25333,25152,25094,24893,11326,11488,11352,10158,9626,10279,9558,9549,9454,2216,1972,1288,892,996,1074,40132,39997,40069,8135,8178,8320,7900,8188,8042,80,283,304,18932,18810,18977,23179,23294,23349,481,435,472,443,14,478,993,879,752,1116,1074,1145,943,872,953,24343,24483,24340,24444,24483,24343,40587,40545,40453,40415,40511,40391,41941,41959,41818,40647,40511,40637,40511,40724,40637,18693,18446,18532,18881,18729,18987,43326,43330,43172,43347,43330,43326,812,933,1006,4706,4607,4812,4518,4624,4272,6583,6654,6598,6988,7168,6993,19445,19497,19628,23373,23548,23436,34992,35123,34909,35423,35682,35434,35787,35682,35724,15635,15727,15587,16186,16397,16307,16779,16472,16878,15635,15587,15612,18000,18180,18022,16472,16350,16397,34935,34856,35112,36828,36890,36723,37022,36890,36828,37022,36926,37050,37022,37050,37192,37437,37355,37664,37000,37014,37103,37103,37352,37282,37588,37608,37474,36691,36955,36807,36850,36955,36691,36850,36691,36804,36850,36976,36969,36955,37014,37000,39053,38769,38668,13335,13237,13534,13493,13534,13611,13719,14159,13766,14952,15035,14898,12973,13030,12904,12904,12799,12873,15107,15250,15448,14952,14876,14802,4021,3947,4031,3984,3947,4021,7473,7591,7493,7493,7591,7564,7778,7885,7878,828,872,943,752,879,739,3869,3939,3966,7855,7885,7778,27362,27305,27377,27362,27377,27465,34290,34196,34408,34386,34196,34290,37608,37416,37474,39347,39293,39267,19357,19269,19289,25262,25168,25238,23747,23676,23813,41662,41382,41545,41789,41773,41694,41876,41860,42142,9549,9626,9504,8966,9077,9024,3127,2985,3133,3486,3549,3529,3183,3225,3411,3333,3225,3258,9362,9383,9253,8538,8713,8729,8938,8713,8767,18000,18022,17992,3225,3333,3451,8401,8293,8320,9099,9195,9024,33511,33528,33491,35201,35251,35123,33511,33248,33241,33511,33241,33539,39449,39505,39402,39575,39505,39589,543,552,627,116,796,799,899,796,976,451,552,543,25984,26740,25772,42830,42653,42739,43468,43305,43207,329,519,472,879,884,739,1181,1233,1252,1181,1252,1323,9024,9195,9173,17318,17112,17120,17217,17112,17318,16397,16350,16307,24483,24664,24340,24564,24664,24483,39948,39922,39945,39701,39627,39614,40120,39922,39948,40132,40069,40278,41959,41836,41721,42530,42504,42685,41959,41721,41818,29047,28878,28951,11024,11103,11314,3638,3486,3529,17992,18022,17806,17303,17598,17381,23737,23940,23699,23527,23699,23501,28701,28611,28775,28772,29047,28951,26993,27014,26884,27133,27069,27179,39514,39325,39294,38441,38171,38136,38060,37965,37914,39344,39325,39469,39347,39267,39156,43235,43204,43096,42825,42673,42624,43242,43204,43235,31442,31480,31530,31412,31053,31192,18977,18810,18891,22876,22745,22591,3984,3869,3947,5147,5139,4728,4487,4518,4272,38687,38171,38441,37738,37704,37631,31974,31865,32074,40478,40318,40322,3713,3638,3766,3947,3869,3966,4108,4220,4167,7517,7300,7519,7817,7679,7768,7708,7679,7817,7902,8017,7970,37352,37474,37282,42767,42777,42589,42637,42485,42530,42637,42530,42651,15912,15870,15820,15612,15587,15476,42899,42830,42739,26596,26474,26618,25191,25152,24893,9980,9966,10238,11118,11600,11325,9109,9197,9051,1707,1972,1912,3192,3638,3713,27685,27472,27371,42142,41860,41957,41674,41545,41579,41442,41306,41711,18891,18810,18709,43068,43483,43386,15035,15250,15107,15035,14952,14802,37777,37704,37738,42867,42624,42709,42510,42203,42311,42504,42489,42685,329,472,435,335,482,476,380,574,569,270,775,477,17112,16951,17034,17078,16951,17112,43204,43149,43094,43295,43149,43204,11488,11326,11314,11566,11867,11776,41303,41319,41294,40618,40509,40545,40545,40509,40453,41759,41540,41773,42983,42728,43108,42949,43182,42720,43068,43079,43483,42915,42672,42653,23436,23548,23557,23548,23676,23557,43330,43332,43159,43408,43332,43330,25388,25238,25488,27511,27362,27465,27639,27628,27701,40511,40647,40391,40194,40040,40186,34044,34027,33698,33144,32982,32958,39824,39837,40018,39824,39614,39837,39505,39563,39547,39575,39563,39505,930,1154,1233,1233,1154,1252,828,943,933,786,849,872,6438,6461,6583,6583,6461,6654,6484,6988,6993,5343,5676,5433,4607,4706,4622,18980,18987,19100,16990,16898,16951,22924,23081,23179,37837,37738,37838,40018,39837,39922,42979,43185,43305,8352,8293,8401,8352,8401,8476,12458,12124,11931,11600,11588,11763,11575,11588,11460,187,136,299,177,10,202,202,48,220,94,427,221,142,455,442,142,297,186,142,186,111,186,107,111,516,827,595,975,1115,1171,3869,3780,3939,3499,3780,3869,7970,8017,8178,7576,7495,7554,27014,27133,27090,25832,25538,25517,42667,42533,42438,3054,2985,3127,3054,3251,3230,3036,2985,2892,3230,3002,3054,8581,8487,8696,9173,9330,9454,20605,20504,20432,19652,19628,19736,19357,19445,19269,19269,19155,19193,20652,20504,20605,20652,20605,20802,20912,20802,20873,21024,21037,20873,21645,21908,21974,21908,22046,21974,43464,43496,43313,43366,43458,42913,43464,43313,43389,43464,43389,43440,43389,43400,43440,43327,43549,43440,43394,43549,43327,43282,43484,43453,20326,20330,20322,20326,20466,20330,20503,20736,20768,21023,21221,20928,21221,21370,21239,21463,21621,21902,20326,20322,20226,20322,20172,20226,19959,20221,20172,20177,20221,20046,21974,22046,21976,41892,41759,41773,41890,41789,41876,65,270,477,154,427,94,15912,15820,15768,17806,17633,17952,17992,17806,17952,18506,18580,18533,17303,17341,17277,23008,22924,23179,23557,23676,23747,25152,25289,25333,25191,25289,25152,24691,24893,24664,37965,37837,37838,40618,40545,40587,40354,40132,40278,19583,19694,19753,23940,24151,24191,24232,24151,24327,43496,43493,43309,43282,43409,43484,18899,18881,18987,18948,18881,18899,43484,43409,43507,43305,43185,43207,77,136,187,4283,4396,4331,15470,15246,15219,13488,13673,14054,15843,15630,15894,19583,19568,19694,34856,34824,34646,36593,36269,36680,36691,36309,36572,35123,35251,35188,34992,34537,34357,1162,1181,1323,1162,1323,1262,16951,16898,17034,17962,18207,18282,16413,16878,16472,15238,15250,15035,15768,15820,15748,19583,19556,19568,33671,33698,33528,20867,20928,20768,43493,43474,43309,12458,12668,12124,29678,29809,29561,29686,29809,29678,15768,15748,15687,42918,43028,42949,42830,42915,42653,42908,42915,42830,42908,42830,43045,186,117,107,135,117,291,2892,2856,3036,40152,40132,40235,786,884,849,786,872,828,42759,42767,42599,42881,42850,42887,42145,41943,42013,198,135,291,2031,1919,1993,1873,1730,1912,2200,1919,2031,1496,1919,1665,21225,21370,21221,32998,33144,32958,32074,31865,31890,40509,40478,40322,43474,43470,43366,43409,43891,43507,2026,1951,1567,2456,2425,2923,2690,3225,3183,17636,17962,17995,18506,18533,18290,18100,17952,18134,22822,22924,23008,24881,24870,25054,23232,23527,23501,23345,23527,23232,43468,43207,43101,13493,13673,13488,12124,12668,12828,28717,28056,28258,28761,28725,28899,1919,1853,1993,198,153,135,198,208,153,319,329,435,319,435,402,4317,4331,4449,6986,6988,6484,7343,7473,7493,7713,7855,7778,17448,17318,17594,17277,17341,17052,21370,21461,21463,43149,43224,42837,43257,43224,43149,43470,43458,43366,42094,41890,41876,41470,41303,41457,42067,42145,42013,41711,41306,41610,1154,1116,1145,938,1116,930,911,1114,976,1447,1349,1515,13479,13335,13534,4487,4607,4622,4615,4607,4466,38060,38104,38171,38060,37914,38104,39074,39128,39087,39589,39505,39449,39186,39053,38668,4073,3984,4021,3521,3486,3237,4009,3984,4073,7576,7679,7692,7576,7554,7679,7178,7240,7146,8538,8729,8188,18881,18693,18729,18713,18693,18881,208,216,153,552,491,595,398,550,482,476,249,335,1752,1730,1873,33526,33671,33528,33526,33528,33511,41470,41319,41303,40509,40492,40478,41737,41579,41759,42724,42667,42791,42673,42667,42438,43108,42728,42875,13012,13145,13237,25146,24881,25054,25146,25054,25106,25262,25238,25388,41949,41737,41759,41610,41306,41363,33795,33130,33388,29796,30036,30355,34079,33388,34196,32892,32437,32778,196,403,51,43565,43412,43398,15608,15511,15470,15559,15511,15608,828,933,812,13719,13766,13425,15333,15448,15250,12799,12697,12873,23527,23724,23699,24151,24444,24314,23708,23724,23527,27133,27179,27164,26474,26298,26433,37413,37352,37103,36955,37033,37014,36309,36386,36572,36890,36738,36680,37192,37050,37163,37254,37355,37437,37192,37212,37022,37704,37664,37631,36969,37033,36955,42067,42013,41959,41524,41470,41457,8293,8135,8320,8093,8135,8271,36852,36738,36890,37884,37777,37837,39325,39344,39252,39514,39294,39444,39630,39444,39627,39630,39627,39701,42759,42599,42637,42759,42637,42751,4808,5139,5192,4404,4317,4449,4423,4577,4517,5406,5317,5337,37965,37884,37837,38113,38060,38169,4798,5343,5433,19583,19448,19556,19448,19435,19556,227,443,355,9051,9197,8938,8767,8713,8538,16782,16755,16898,16149,15894,16061,15912,16186,16298,16984,17052,16878,16984,17277,17052,15687,15748,15635,18506,18290,18420,23179,23221,23008,21976,22046,22071,32778,32437,32316,4283,4202,4396,4317,4202,4283,6986,7178,6988,6988,7178,7146,17342,17217,17318,17236,17217,17342,18242,18100,18134,18420,18290,18331,16984,16878,16844,24232,24444,24151,39258,39128,39186,37201,37103,37014,80,153,216,19189,19315,19401,1882,2425,2456,40822,40650,40841,40354,40278,40318,40647,40651,40577,40186,39905,39707,7418,7300,7517,7692,7679,7708,34822,34610,34631,34822,34631,34824,42094,41892,41890,42867,42709,42934,42881,42863,42850,23221,23349,23436,23751,23747,23870,23724,23737,23699,23708,23737,23724,39053,39128,39074,39563,39753,39707,39156,39128,39258,43397,43242,43121,43365,43108,42875,43397,43121,43332,19189,19161,19315,18180,18000,18100,19085,19161,19189,21976,22071,22111,43426,43120,43265,16250,16208,16218,2856,2763,2890,2638,2763,2856,3486,3201,3237,908,911,861,487,911,976,908,975,1052,1204,1349,1447,8581,8696,8966,7749,7692,7708,8825,8767,8684,13673,13493,13611,13335,13235,13237,13479,13493,13488,20286,20316,20432,19085,18977,19161,22111,22071,22190,33662,33526,33539,34044,34126,34027,34645,34992,34357,33526,33511,33539,40152,39997,40132,39701,39614,39824,39589,39449,39605,4202,4167,4220,3486,3178,3201,4009,4167,4202,11612,11604,11776,11776,11604,11566,11566,11352,11488,11024,10752,10776,9549,9558,9626,11944,11776,11931,34126,33956,34027,36309,36189,36386,39091,38924,39205,39091,38677,38924,41674,41662,41545,41674,41579,41737,329,271,355,353,156,138,15511,15411,15470,15496,15411,15511,15333,15445,15448,15986,16186,15912,15333,15250,15238,19161,18891,19291,18100,18000,17952,43347,43408,43330,43428,43408,43347,13178,13235,13335,32892,32998,32958,33067,32998,32892,25517,25538,25404,25885,25832,25893,42915,43028,42918,42899,42739,42777,42794,42777,42767,22003,22111,22190,26433,26298,26049,41890,41892,41773,42311,42466,42510,42751,42637,42651,27179,27307,27164,29047,29150,29420,27253,27307,27179,7418,7517,7495,7970,8178,8093,380,398,286,413,491,552,43365,42928,43224,42983,42969,42934,18709,18580,18560,41939,41674,41737,14216,14390,14159,12065,12280,12053,42510,42466,42752,8093,8178,8135,9024,9008,8966,9417,9173,9454,9549,9504,9441,32706,32778,32316,34044,33698,33671,40354,40318,40582,1853,1752,1873,1730,1707,1912,1181,1162,1233,1690,1752,1853,1690,1496,1502,2346,2149,2340,2763,2595,2890,10752,10812,10776,22542,22400,22171,32284,32368,32316,32400,32368,32284,31865,31678,31890,7418,7495,7576,34610,34546,34290,35112,34965,35646,244,271,329,353,20,156,17217,17078,17112,15843,15559,15608,17162,17078,17217,17448,17594,17668,24444,24564,24483,24451,24564,24444,24691,24564,24642,19445,19155,19269,18693,18459,18446,18560,18580,18506,1690,1707,1730,40788,40492,40509,40948,40822,40979,40822,40841,41087,41518,41319,41470,41524,41382,41624,43242,43295,43204,43378,43295,43446,39648,39514,39444,39682,39701,39877,39575,39753,39563,39724,39753,39575,28775,28611,28449,31626,31678,31480,1204,1441,1058,12501,12124,12828,11812,12053,11948,11575,11763,11588,15612,15687,15635,15238,15035,14809,43522,43426,43265,43378,43339,43295,3499,3869,3984,2763,2638,2595,8767,8825,8938,9798,9824,9741,7900,8042,7885,15612,15476,15533,16413,16472,16397,25832,25885,25902,25251,25404,25289,975,1015,1115,911,908,1052,861,911,487,2595,2346,3023,11604,11352,11566,11612,11352,11604,39648,39444,39630,40822,40700,40587,40637,40651,40647,40791,40651,40828,41624,41382,41662,398,380,569,395,380,96,9441,9454,9549,9441,9417,9454,25175,25191,25145,40152,40120,39948,40492,40318,40478,27695,27639,27701,25649,25772,25555,27511,27639,27695,27559,27685,27371,27712,27685,27626,27069,27014,26993,42649,42466,42533,4167,4009,4073,4404,4484,4493,11905,11944,12124,13493,13479,13534,13673,13971,14054,7579,7418,7576,7300,7035,7332,7579,7576,7692,34935,34822,34824,34958,34822,34935,42744,42751,42651,42802,42794,42767,42744,42651,42685,48,221,220,622,415,249,3054,2892,2985,2595,1725,2346,8825,9051,8938,10911,11213,10804,19155,18980,19100,40287,40120,40152,413,552,451,16250,16397,16186,17992,17952,18000,24564,24691,24664,24151,23940,24084,43318,42969,42983,42667,42649,42533,43230,42983,43108,43137,43028,42915,43037,42915,42908,43295,43339,43149,43404,43332,43408,786,739,884,752,639,858,812,1006,996,812,996,826,4607,4615,4812,4487,4622,4518,6266,6461,6438,6439,6461,6426,7547,7579,7692,8271,8135,8293,7970,8093,7958,8293,8352,8271,34126,34236,33956,34110,34044,34279,34126,34044,34110,33671,33986,34044,39128,39053,39186,39258,39347,39156,42510,42220,41570,42001,41949,42093,41524,41624,41745,41826,41624,41662,18290,18100,18242,18524,18560,18506,43428,43404,43408,10804,10438,10348,32923,32892,32778,31053,30711,31192,41949,41759,41892,18980,18948,18899,728,739,786,7274,7035,7300,7713,7778,7693,7178,7047,7493,6524,6993,6654,26715,26884,26618,42724,42649,42667,6570,6585,7011,4577,4423,4493,6461,6524,6654,38060,38113,37965,38149,38113,38169,38060,38171,38169,40354,40235,40132,40287,40235,40449,30830,31188,30925,28449,28611,28061,31517,31412,31378,42145,42233,42081,42276,42067,41959,42186,42067,42276,41959,41941,42276,37033,37201,37014,37352,37528,37474,36850,36969,36955,35774,35682,35787,36738,36593,36680,37022,37070,36890,37212,37070,37022,37355,37631,37664,36960,36852,36890,37112,37201,37033,20504,20445,20432,19254,19068,19155,19155,19068,18980,18980,19068,18948,20825,20652,20802,20825,20802,20912,20825,20912,20966,21354,21037,21024,20466,20736,20503,21225,21251,21370,21251,21621,21461,21461,21621,21463,20426,20736,20466,20426,20466,20326,20177,20326,20226,20177,20226,20221,20221,19959,20046,19959,19694,20046,19694,19568,19675,19568,19556,19675,19556,19435,19389,27140,27305,27569,23751,23656,23747,25191,25251,25289,25175,25251,25191,2,142,111,2,455,142,2,76,455,113,77,187,136,10,177,2,111,107,2,107,54,107,117,54,21645,21354,21292,20736,20795,20768,43493,43554,43474,43474,43546,43470,43470,43543,43458,43630,43522,43265,43496,43563,43493,43464,43563,43496,43609,43563,43464,43573,43464,43440,43573,43440,43549,244,329,319,54,135,153,54,117,135,244,319,353,7778,7591,7693,11575,11812,11763,13016,12984,12818,15706,15559,15843,15411,15246,15470,15842,15912,15768,15533,15476,15445,15533,15445,15399,17668,17594,17962,16990,16782,16898,20652,20445,20504,20795,20867,20768,25885,26011,26049,25893,26011,25885,31958,31948,32344,40696,40509,40618,42969,42867,42934,43339,43257,43149,43378,43257,43339,43404,43397,43332,43532,43397,43404,43549,43394,43453,43549,43453,43524,625,639,752,15420,15246,15411,14876,14559,14784,26011,26433,26049,42867,42825,42624,42802,42767,42759,42802,42759,42889,76,77,113,21645,21974,21354,20867,20956,20928,43563,43554,43493,21354,21974,21801,20956,21023,20928,11024,11314,11326,39534,39469,39325,39682,39648,39630,39682,39630,39701,39701,39824,39877,39528,39449,39293,40381,40186,39707,19389,19435,19315,21023,21134,21225,43524,43453,43518,43565,43398,43386,29150,29047,28977,35682,35423,35724,37714,37704,37777,491,514,595,389,514,491,4272,4624,3991,27511,27305,27362,10232,10238,9966,11575,11651,11812,54,153,80,43554,43546,43474,13425,13227,13204,42489,42887,42685,27685,27712,27472,27559,27371,27307,39534,39325,39514,18948,18713,18881,18818,18713,18948,31517,31626,31480,43611,43483,43694,43386,43483,43575,11516,11024,11352,11352,11024,11326,10911,11083,11325,28930,29150,28977,28930,28772,28775,77,10,136,861,1015,975,1058,1015,887,22003,21974,21976,22003,21976,22111,22822,22477,22924,43546,43543,43470,43514,43428,43347,43518,43453,43484,9418,9441,9504,9417,9259,9173,12124,11944,11931,13012,13237,13235,11941,11984,11812,11812,11984,12053,12984,13227,12973,12984,12973,12873,23872,23940,23737,25145,25191,24893,40463,40186,40431,43257,43266,43224,43039,42825,42867,43462,43266,43257,43543,43542,43458,43507,43518,43484,9383,9233,9253,4239,4009,4202,4808,5192,4912,163,236,249,380,395,451,7912,7902,7970,7418,7274,7300,15842,15768,15713,18524,18420,18413,192,422,270,16990,16951,17078,23656,23436,23557,23656,23557,23747,13124,13012,13235,13178,13335,13479,12083,12706,12065,42067,42233,42145,42186,42233,42067,7958,7912,7970,8476,8487,8352,34110,34236,34126,35724,35423,35773,33148,33144,32998,39186,39150,39261,39407,39528,39293,27069,27253,27179,27267,27253,27069,15559,15496,15511,14495,13971,14762,15327,15496,15559,15713,15768,15687,15399,15445,15333,15399,15333,15277,42922,42899,42777,42922,42777,42794,80,304,83,21251,21461,21370,23474,23708,23527,43892,43256,43412,4239,4202,4317,24082,23975,23813,23345,23232,23148,26433,26544,26474,26547,26544,26433,26715,26544,26547,32233,31958,32344,32812,32588,33130,40700,40696,40618,40404,40235,40354,40797,40696,40700,40797,40700,40948,41518,41470,41524,42889,42759,42751,42794,42802,43050,6250,6182,6273,6250,6273,6585,6250,6131,6116,389,522,514,514,522,595,11118,11460,11600,15713,15687,15612,2762,2856,2892,2762,2638,2856,2762,2892,2713,4394,4404,4423,4423,4404,4493,9253,9233,9109,9253,9109,9051,8845,9051,8825,18524,18506,18420,19291,19389,19315,18420,18331,18413,21621,21709,21902,39648,39534,39514,40018,39922,40120,40287,40152,40235,42094,41876,42142,41620,41518,41524,83,411,196,180,244,353,17448,17236,17342,17272,17236,17448,1164,1162,1262,625,701,610,30638,30059,30209,28843,28930,28775,4912,5192,4897,6116,6131,6066,9008,9024,9173,39781,39534,39648,39205,39252,39344,39589,39724,39575,39407,39293,39347,10,48,202,150,192,270,14559,14876,14642,15041,15277,15238,8862,9008,8941,32923,33067,32892,32706,32316,32368,32706,32710,32771,34724,34546,34610,34724,34610,34822,39205,39344,39368,11534,11651,11575,11984,12083,12065,16782,16149,16755,16452,16149,16782,24223,24082,23813,25555,25388,25488,25555,25488,25649,3,477,154,23221,23179,23349,24587,24082,24223,19291,19315,19161,18290,18242,18331,22190,22071,22477,23221,23436,23716,4808,4728,5139,13483,13488,13295,38149,37884,37965,38149,37965,38113,7897,7958,8008,7912,7749,7817,27639,27511,27465,27695,27701,28056,28175,28449,28061,27540,27559,27307,27626,27559,27540,34236,34432,34357,33662,33671,33526,13012,12821,12828,13312,13178,13479,22190,22477,22256,15496,15420,15411,15286,15420,15496,15277,15333,15238,15767,15713,15612,43045,43037,42908,43028,43064,42949,43050,42922,42794,43061,42922,43050,9893,10232,9966,11014,11118,11083,11083,11118,11325,11534,11678,11651,10348,9890,10447,17236,17162,17217,17272,17162,17236,24232,24451,24444,25251,25344,25404,24327,24451,24232,40404,40354,40582,9362,9550,9383,428,516,522,522,516,595,413,451,395,4728,4606,5147,16149,15706,15843,15852,15713,15767,16218,16413,16250,43045,42830,42899,19161,18977,18891,17952,17633,17509,17633,17598,17509,31626,31686,31678,31412,31517,31480,30638,30749,30714,1349,1377,1704,2134,1882,2456,1204,1377,1349,227,355,271,19675,19389,19291,1127,1164,1262,1752,1690,1730,1613,1690,1502,1601,1690,1613,1496,1690,1853,17636,17668,17962,25146,25106,25262,23716,23436,23656,23708,23872,23737,23912,23872,23708,30059,29809,30209,42220,42230,42142,42291,42230,42446,42230,42220,42446,8631,8581,8966,8008,7958,8093,8016,8538,8188,9362,9457,9550,25245,25146,25262,31589,31686,31626,7786,7912,7843,7786,7749,7912,7480,7274,7418,7855,7900,7885,7693,7591,7609,7047,7178,6986,34546,34386,34290,34538,34386,34546,34276,34432,34236,39399,39407,39347,38668,38651,39033,8381,8352,8487,39528,39605,39449,39638,39605,39528,286,398,335,339,413,395,4606,4593,4577,4404,4326,4317,6883,7047,6986,6461,6439,6524,6426,6461,6266,6426,6259,6356,4798,4812,4615,10915,11083,10911,22629,22477,22822,35423,35251,35773,38169,38171,38687,40183,40018,40120,39510,39469,39644,41620,41524,41745,41662,41674,41939,43137,43064,43028,43630,43265,43458,43446,43295,43242,739,701,752,207,271,244,728,786,828,18709,18560,18891,17277,17509,17303,23008,22828,22822,23716,23656,23751,42649,42752,42466,42791,42667,42673,42791,42673,42825,42791,42825,42909,43514,43347,43588,9008,8862,8966,9441,9418,9417,9504,9626,9832,24451,24642,24564,24509,24642,24451,31686,31890,31678,40651,40791,40577,40828,40651,40637,40415,40194,40724,43182,42642,42720,48,94,221,3333,3467,3991,3258,3467,3333,2773,3025,2919,39399,39347,39258,11941,11812,11678,11941,12083,11984,37201,37285,37103,36969,37112,37033,37167,37112,36969,36804,36691,36572,892,1074,1116,1127,1262,1288,2653,2773,2919,2653,2927,2425,5863,5940,6182,5406,5817,5317,4808,4717,4728,4728,4571,4606,4606,4497,4593,23865,23716,23751,24082,24587,24506,36852,36871,36738,37070,36960,36890,37141,36960,37070,37212,37192,37422,37163,37437,37422,42230,42094,42142,36960,36871,36852,37422,37437,37554,37280,37285,37201,4497,4517,4593,4593,4517,4577,4487,4466,4607,4403,4466,4487,36624,36804,36572,35201,35123,34992,37664,37704,37714,38687,38441,38660,36624,36572,36663,37285,37413,37103,6484,6993,6524,15767,15612,15533,14809,15035,14802,35408,35201,35237,43061,43045,42899,43133,43137,42915,43061,42899,42922,892,1116,938,13178,13124,13235,13488,13483,13479,13312,13295,13257,17277,16984,17021,18560,18524,18424,27559,27626,27685,27789,27626,27658,36189,36074,36282,37777,37866,37714,19254,19155,19445,18713,18795,18693,24799,24893,24691,26544,26715,26618,43579,43230,43108,43369,43224,43266,26547,26433,26351,37413,37528,37352,42909,42825,43039,812,728,828,7480,7418,7579,7843,7912,7958,13257,13124,13178,11944,11612,11776,14784,14809,14802,14216,14312,14390,14079,14312,14216,13016,13227,12984,28146,28061,27712,28930,28896,29150,34432,34527,34357,34204,34276,34236,34204,34236,34110,39091,38896,38677,39368,39344,39469,39368,39469,39410,8867,9253,9051,9888,10232,9893,24506,24587,24637,25347,25245,25262,25582,25555,25772,33539,33241,33556,32706,32368,32710,17162,16990,17078,15327,15559,15362,17117,16990,17162,37528,37588,37474,207,227,271,207,244,180,23865,23751,23870,24587,24881,24637,43446,43242,43532,1058,1115,1015,1058,1441,1115,40016,39877,39824,40016,39824,40018,33148,32998,33067,39704,39724,39605,39605,39724,39589,18524,18413,18424,16413,16397,16250,23032,23345,23148,24828,24799,24642,36189,35774,36074,37777,37884,37866,35646,34965,35360,9057,9008,9173,8581,8516,8487,8352,8256,8271,13051,12821,13012,14312,14559,14642,28449,28843,28775,33052,33148,33067,42531,42167,42164,42276,41941,42342,42843,42731,42724,42724,42731,42649,41949,41892,42093,51,83,196,10232,10348,10438,9798,9741,9550,22171,22400,21902,43575,43565,43386,43575,43483,43611,4897,5192,4995,36074,35774,35787,38044,37884,38149,4517,4394,4423,2713,2892,2853,4264,4394,4517,11678,11812,11651,10836,10915,10911,16250,16186,16208,15912,15842,15852,25347,25262,25388,30638,30714,30711,31517,31589,31626,31686,31986,31890,29686,29420,29150,43064,43182,42949,43168,43182,43064,180,353,138,14,51,403,20652,20636,20445,20445,20286,20432,20707,20636,20652,20707,20652,20825,20707,20825,20872,20825,20966,20872,20966,21080,20872,21037,21080,20966,22035,21974,22003,31561,31589,31517,32710,32368,32560,43573,43609,43464,43563,43632,43554,43554,43650,43546,43546,43645,43543,43543,43645,43542,43542,43630,43458,43743,43609,43573,43743,43573,43728,43647,43549,43524,43647,43524,43610,43524,43725,43610,23345,23474,23527,24642,24799,24691,23722,23474,23538,20177,20426,20326,20736,20911,20795,20795,20911,20867,20867,20911,20956,20956,20911,21023,21023,20911,21134,21134,21251,21225,21621,21737,21709,21709,22171,21902,20046,20426,20177,20426,20911,20736,43696,43632,43563,145,415,323,128,323,192,16646,16844,16878,24327,24151,24084,25175,25344,25251,3178,3157,3201,2638,2506,2595,4912,4829,4808,4634,4798,4615,6250,6116,6182,6570,7011,7035,19068,18818,18948,17483,17272,17448,18883,18818,19068,43524,43518,43725,43611,43694,43697,43385,43101,43249,43632,43650,43554,1690,1601,1707,1613,1502,1507,7713,7900,7855,9325,9457,9253,7631,7900,7713,20483,20286,20445,34454,34527,34432,34381,34204,34440,39263,38896,39091,39410,39469,39510,516,416,827,413,389,491,339,389,413,43133,42915,43037,43133,43037,43123,1116,1154,930,653,739,728,930,1233,1036,1288,1972,1707,7480,7579,7547,15852,15842,15713,14559,14809,14784,35112,34958,34935,34991,34958,35077,25772,26740,26440,28029,27695,28056,28029,28056,28451,27626,27789,27712,29030,28896,28938,27540,27307,27267,12818,12984,12873,11575,11460,11534,4394,4326,4404,4264,4326,4394,43518,43507,43725,1060,1162,1164,13124,13051,13012,13483,13312,13479,13257,13233,13078,4829,4717,4808,35860,35787,35724,36082,36074,36010,94,3,154,18818,18795,18713,18883,18795,18818,19675,20046,19694,19675,19556,19389,20911,21251,21134,40948,40700,40822,41939,41737,41949,41746,41610,41180,43647,43610,43725,65,150,270,18413,18331,18338,17509,17598,17303,8518,8516,8581,7547,7692,7749,33662,33770,33671,33556,33241,33144,43667,43645,43546,43514,43404,43428,9887,9530,9888,40788,40603,40492,40183,40016,40018,41668,41319,41518,40791,40956,40541,40724,40194,40753,23982,23940,23872,12799,12523,12697,14312,14440,14559,14559,14440,14809,39469,39534,39644,40183,40120,40287,40603,40318,40492,4552,4634,4615,4552,4615,4466,8381,8256,8352,16413,16646,16878,15533,15399,15767,25392,25347,25388,25081,24881,25146,25582,25388,25555,25277,25344,25175,25385,25344,25431,38174,38044,38149,38174,38149,38169,40801,40724,40860,39610,39638,39528,39610,39528,39407,39399,39258,39285,7451,7591,7473,34454,34432,34276,35773,35860,35724,34454,34276,34381,22872,22828,23008,22100,22035,22003,22629,22828,22872,4326,4239,4317,4103,4239,4326,42889,42751,42744,43645,43630,43542,40305,40183,40287,39251,39091,39205,26715,26993,26884,26351,26433,26011,39977,39753,39724,23865,23870,23975,23865,23975,24110,389,428,522,333,428,389,15767,15399,15143,39285,39258,39186,43338,43168,43064,43123,43037,43045,861,975,908,4509,4552,4466,6439,6492,6524,7343,7451,7473,5501,5676,5343,28843,28896,28930,28627,28843,28449,18331,18242,18338,21251,21737,21621,23722,23708,23474,14,443,227,144,180,138,17483,17448,17668,15270,15286,15327,43465,43369,43266,43039,42867,43277,43462,43257,43378,43242,43397,43532,43387,43385,43249,43387,43249,43448,11905,12124,12291,11905,11612,11944,9832,9956,9949,9832,9626,10158,11534,11460,11451,12799,12706,12523,26751,26993,26715,42531,42081,42233,32846,32812,33130,31958,31764,31674,34079,34196,34386,33556,33654,33539,32706,32771,32778,32851,32771,32745,6426,6492,6439,31589,31561,31686,30986,31192,30711,30986,30711,30714,35773,35251,35537,723,861,487,9956,10002,9949,9259,9057,9173,8518,8381,8516,28068,28146,27712,28175,28146,28202,40449,40305,40287,40788,40509,40696,249,286,335,236,286,249,16686,16646,16423,18424,18338,17967,15986,16208,16186,25344,25385,25404,25145,24893,24799,43186,43064,43137,5387,5501,5343,6426,6356,6492,5387,5343,5039,4641,4798,4634,35646,35077,35112,36960,36933,36871,37212,37141,37070,37288,37141,37212,37288,37212,37342,37554,37437,37664,37774,37664,37714,3467,3585,3991,3173,3585,3467,10915,11014,11083,10447,10836,10804,10846,10836,10447,27267,27307,27253,35860,35773,35857,34489,34454,34528,37141,36933,36960,37167,36969,36976,37167,37280,37112,37112,37280,37201,37285,37348,37413,37413,37469,37528,37528,37604,37588,39261,39285,39186,36821,36804,36624,36663,36572,36470,36572,36386,36470,36386,36507,36470,133,227,207,7343,7493,7047,13312,13257,13178,14943,14762,15246,37280,37348,37285,3638,3178,3486,39675,39704,39638,39638,39704,39605,1601,1507,1707,1919,1496,1853,10846,11014,10915,12501,12828,12821,29668,29686,29385,42001,41939,41949,41892,42094,42093,31765,31764,31958,29796,29654,29359,22100,22003,22190,25081,25146,25245,24327,24509,24451,24665,24509,24274,23912,23708,23722,36386,36282,36507,34645,34357,34527,36282,36074,36247,26997,27267,27069,15852,15986,15912,15023,15399,15277,42731,42752,42649,42791,42843,42724,42867,42969,43165,7994,8016,7900,7900,8016,8188,9457,9798,9550,7631,7713,7693,42186,42328,42233,42276,42328,42186,41620,41668,41518,40797,40788,40696,41675,41668,41620,9798,9887,9893,9457,9362,9253,18282,18207,18446,24110,23975,24082,22629,22822,22828,22256,22100,22190,22591,22745,22542,40979,40822,41087,40936,40956,40828,40828,40956,40791,40801,40637,40724,43347,43426,43600,9259,9417,9418,8093,8271,8008,22256,22477,22532,32851,32923,32778,33539,33654,33662,32851,32778,32771,25185,25081,25245,25392,25245,25347,24929,25145,24799,36247,36074,36082,428,416,516,96,339,395,25431,25517,25385,25385,25517,25404,26981,26997,26993,26993,26997,27069,701,625,752,610,701,739,735,728,812,826,996,892,6131,6250,6150,7626,7749,7786,7843,7958,7897,26751,26715,26547,34785,34724,34822,34991,34822,34958,42957,42843,42791,18338,18242,18134,21737,22171,21709,29686,30209,29809,41826,41745,41624,41939,41826,41662,42093,42094,42315,4912,4765,4829,4829,4692,4717,4571,4497,4606,4995,5192,5299,5168,5299,5406,8381,8487,8516,37866,37774,37714,37866,37884,37900,37536,38651,38668,39399,39610,39407,1127,1060,1164,800,826,892,1105,1060,1127,3,65,477,98,128,192,17967,18338,18134,17509,17277,17030,40925,40788,40797,40449,40235,40404,40860,40724,40753,43601,43426,43522,24506,24110,24082,24946,24637,24881,43369,43365,43224,43472,43365,43369,43385,43468,43101,43405,43249,43182,895,892,938,9361,9259,9418,13449,13719,13425,16208,16283,16218,13204,13227,13016,22532,22477,22629,23912,23982,23872,25148,25156,25145,24067,23982,23912,43637,43468,43385,4897,4765,4912,6116,6066,6182,6250,6585,6150,37874,37866,37900,818,895,938,8631,8862,8682,8631,8966,8862,28068,27712,27789,28146,28175,28061,28896,29030,29150,27658,27626,27540,27658,27540,27576,33556,33144,33435,8941,9008,9057,15420,15286,15246,15327,15286,15496,15706,16149,15876,16782,16990,16693,25893,26351,26011,43318,42983,43230,42909,42946,42791,826,735,812,27874,27658,27760,333,416,428,3585,4272,3991,4533,4641,4634,11678,11902,11941,11451,11460,11368,43061,43123,43045,43133,43186,43137,43168,43321,43182,43376,43123,43061,32503,32233,32344,39704,39827,39724,39695,39610,39617,26859,26751,26830,27066,27373,27267,28371,28518,28449,29686,30328,30209,43051,42946,42909,42850,42889,42744,42863,42889,42850,4765,4692,4829,6570,7035,6596,8862,8941,8757,25517,25893,25832,25145,25156,25175,25277,25156,25210,36074,35787,36010,735,653,728,42822,42731,42948,42822,42752,42731,42291,42094,42230,42039,41826,41939,7626,7547,7749,6783,7035,7274,7626,7786,7748,7415,7609,7451,7451,7609,7591,16646,16413,16423,15622,15986,15852,15041,15238,14809,25081,24946,24881,25772,25963,25752,17636,17483,17668,17495,17483,17636,17021,16984,16844,23008,23221,22872,24089,24110,24156,24089,24156,24134,23982,24084,23940,24274,24084,24067,4533,4634,4552,30961,30925,31188,30961,31188,31213,31192,31378,31412,31315,31378,31192,35787,35860,35963,36010,35787,35963,43767,43601,43872,35077,34958,35112,8008,8271,8256,39682,39890,39781,39648,39682,39781,39368,39379,39205,38814,38687,38660,40249,40016,40183,12706,12083,12523,33435,33144,33148,32284,32074,32400,40582,40318,40603,144,207,180,653,610,739,8845,8825,8684,40690,40582,40603,31378,31561,31517,23221,23716,23689,43601,43600,43426,35963,35860,35857,1613,1507,1601,2200,2149,1665,10752,10109,10002,10158,10002,9956,9504,9361,9418,32021,31765,31958,40690,40615,40582,40948,40925,40797,41087,40841,41255,41012,41319,41255,15286,15270,15246,17117,17162,17272,43049,43050,42802,25156,25277,25175,24828,24642,24729,7962,8008,8256,8606,8518,8581,8606,8581,8631,34632,34489,34528,34454,34489,34527,33052,33067,32923,144,133,207,704,301,628,7,192,150,286,200,380,339,333,389,43606,43318,43230,43446,43462,43378,43561,43462,43815,43532,43404,43514,1036,1233,1162,960,1105,1127,12393,12501,12510,11516,11352,11612,13078,13124,13257,58,14,227,38814,38660,38896,163,249,415,24665,24642,24509,826,729,735,535,528,653,653,528,610,895,800,892,729,800,818,2853,2892,3054,2762,2583,2638,3638,3192,3178,3758,4009,3910,2690,3258,3225,4348,4403,4255,2690,3183,2773,7748,7786,7843,6783,7274,6834,7748,7843,7856,28497,28627,28518,27874,28068,27789,27874,27789,27658,34770,34538,34724,34724,34538,34546,32718,32503,32344,33770,33662,33654,39610,39675,39638,39695,39675,39610,42345,42531,42233,42889,43049,42802,43650,43668,43546,43645,43698,43630,43630,43698,43522,43601,43767,43600,43632,43794,43650,43609,43696,43563,43743,43696,43609,43573,43549,43728,43549,43647,43728,43647,43873,43728,43891,43893,43725,21080,21354,21263,21080,21037,21354,20707,20483,20636,20636,20483,20445,18830,18883,19068,18795,18687,18693,21354,21801,21263,22035,22100,22226,43412,43565,43770,13719,13987,14159,13816,13987,13719,20010,20316,20286,18424,18891,18560,18424,18413,18338,22226,22100,22256,23689,23716,23824,22171,22591,22542,6883,7343,7047,32094,32021,31958,32094,31958,32233,41072,40925,40948,40801,40936,40828,41490,40604,40541,41031,40936,40801,42946,42957,42791,43051,42957,42946,42900,42957,43047,43338,43186,43340,43340,43186,43133,4571,4728,4717,4403,4487,4272,4348,4509,4466,6492,6484,6524,6259,6426,6266,35857,35773,35881,38285,38174,38169,8682,8606,8631,9259,9129,9057,9265,9361,9364,40582,40493,40404,40615,40493,40582,22226,22256,22430,43804,43668,43650,43668,43667,43546,3002,3230,3237,32851,33052,32923,33089,33052,33189,40569,40249,40305,40305,40249,40183,7962,8256,8051,38852,38814,38907,39682,39877,39890,1036,1162,1060,28518,28627,28449,28371,28449,28175,36976,36850,36804,37389,37469,37348,37348,37469,37413,36976,36804,36821,36624,36663,36821,36663,36835,36821,36470,36594,36663,36507,36594,36470,5863,6182,6066,5317,5449,5285,4897,4828,4765,4765,4630,4692,4692,4571,4717,20054,20010,20286,36593,36738,36871,37141,37262,36933,37554,37212,37422,37554,37826,37569,37664,37826,37554,11754,11902,11678,11368,11460,11118,11368,11118,10857,10846,10915,10836,10804,10348,10447,36367,36507,36282,40463,40194,40186,41745,41675,41620,42039,41939,42115,43736,43532,43514,6356,6484,6492,36276,36367,36282,35408,35251,35201,133,58,227,833,305,704,128,145,323,98,145,128,5337,5168,5406,36276,36282,36247,37389,37348,37280,43462,43465,43266,43561,43465,43462,43719,43565,43575,14816,14495,14762,14303,14440,14312,43323,43321,43168,43387,43536,43385,37874,37774,37866,25185,24946,25081,23824,23716,23865,24828,24929,24799,24833,24929,24828,25040,24929,25008,2643,2583,2762,18883,18687,18795,18548,18687,18830,40539,40449,40404,40539,40404,40493,43722,43611,43697,43719,43611,43722,973,1036,1060,973,1060,1105,7343,7415,7451,8222,8385,8016,8016,8385,8538,7574,7415,7511,13633,13816,13719,11978,12083,11941,34991,34785,34822,34898,34785,35009,42149,41939,42001,42625,42220,42510,42725,42510,42752,42328,42345,42233,42342,41941,42465,42000,41711,41610,7856,7843,7897,7590,7480,7547,245,333,211,416,274,827,200,286,236,1507,1288,1707,4403,4199,4255,7590,7547,7626,5977,5863,6066,26740,27140,27385,25582,25392,25388,5011,4995,5299,6059,6066,6131,36181,36276,36247,65,7,150,2468,2506,2583,3085,3002,3237,8051,8256,8159,7826,7856,7897,8682,8862,8757,23824,23865,23934,23538,23474,23345,33756,33770,33654,33756,33654,33556,39890,40016,39975,39890,39877,40016,39675,39827,39704,39695,39827,39675,39610,39399,39617,43843,43698,43645,43600,43588,43347,1567,1951,1775,1567,1775,1377,903,1377,1204,30925,30594,30218,31213,31188,31647,31188,31764,31647,30749,30986,30714,31378,31579,31561,32154,32074,31890,30523,30638,30209,26751,26981,26993,26859,26981,26751,26751,26547,26830,25893,25517,25562,42957,42900,42843,43051,42909,43099,42850,42685,42887,43338,43064,43186,43338,43323,43168,38120,38044,38174,39379,39368,39410,39379,39410,39510,4995,4876,4897,17483,17242,17272,17495,17242,17483,18687,18632,18693,18548,18632,18687,23097,22872,23221,22430,22256,22532,36082,36181,36247,43736,43588,43906,10348,10232,9888,13987,14079,14216,13204,13016,13072,28320,28371,28175,27576,27540,27267,34405,34079,34386,34162,34079,34405,39816,39644,39534,40690,40603,40782,40979,41072,40948,41255,41319,41930,1058,1047,1204,871,1047,1058,887,1015,723,134,200,236,163,415,145,4393,4517,4497,4393,4264,4517,3201,3157,3237,4876,4828,4897,12777,13016,12818,13940,14079,13987,16916,16693,16990,16747,16646,16686,17967,18134,17952,16844,16646,16747,24929,25040,25145,24509,24327,24274,25372,25392,25505,27373,27576,27267,28938,28896,28843,28202,28146,28068,30557,30594,30675,36082,36010,36181,37884,38044,37969,37900,37884,37969,43477,43108,43365,43340,43123,43552,43411,43405,43182,11754,11678,11534,13434,13449,13204,11754,11534,11429,32047,31827,31765,32718,32344,32812,39921,39890,39975,40603,40788,40782,23560,23097,23221,24089,23865,24110,24089,24134,23934,2680,2653,2416,18632,18459,18693,18548,18459,18632,9956,9832,10158,8757,8941,8843,11516,11612,11905,6150,6059,6131,36181,36010,36248,37969,38044,38120,7650,7590,7626,7826,7897,8008,39585,39379,39510,41977,41675,41745,41977,41745,41826,42276,42345,42328,42887,42489,43084,42499,42345,42276,42948,42731,42843,34551,34386,34538,36980,36871,36933,43125,43049,42889,43024,42889,42863,144,58,133,833,639,305,17099,17117,17242,17242,17117,17272,43350,43165,42969,42948,42835,42822,43465,43472,43369,43561,43472,43465,43477,43472,43569,6130,6150,6585,32315,32094,32233,38285,38169,38380,17967,17952,17509,22591,23032,22876,24274,24327,24084,11384,11368,11248,7574,7693,7609,39317,39313,39428,39781,39816,39534,40557,40305,40449,2583,2506,2638,2643,2762,2713,8256,8381,8159,9265,9259,9361,9364,9361,9504,32846,32718,32812,32503,32549,32233,33052,33089,33148,31986,31686,31796,40615,40539,40493,40557,40539,40964,16675,16590,16693,16693,16590,16782,14192,14054,14495,43411,43182,43321,43411,43321,43414,1036,934,930,818,800,895,1002,973,1105,28938,28843,28627,42887,43084,43112,40161,39707,39753,39617,39399,39285,43340,43133,43123,4630,4571,4692,4528,4533,4509,4509,4533,4552,4641,4569,4798,5862,6259,6266,6356,6260,6484,7650,7626,7748,6043,6059,6150,7650,7748,7856,7415,7574,7609,7631,7574,7511,34489,34632,34527,35857,36061,35963,34528,34454,34381,39313,39251,39205,38233,38285,38380,39313,39205,39379,37536,37608,38651,33189,33052,32992,34381,34276,34204,22430,22532,22653,22532,22629,22653,18459,18282,18446,18288,18282,18459,98,163,145,245,338,333,800,729,826,305,639,158,818,938,815,25431,25344,25277,24729,24580,24949,11747,11516,11905,12291,12124,12501,815,938,930,14309,14303,14114,13204,13449,13425,12777,12818,12697,28104,28202,28068,28371,28497,28518,28104,28068,28018,14495,14054,13971,15040,15246,15270,42835,42725,42752,42835,42752,42822,56,58,144,15362,15559,15706,6484,6427,6986,5862,6266,5501,333,338,416,333,339,71,25431,25277,25210,27066,27267,26997,27576,27760,27658,13295,13312,13483,28357,28497,28371,31647,31764,31650,30557,30488,30594,12132,12291,12234,31765,32021,32047,32884,32846,33069,39977,39724,39827,43099,42909,43152,27066,26997,26981,41930,41319,41668,40683,40690,40782,42948,42843,43032,16590,16452,16782,16507,16452,16590,16916,16990,17117,39921,39781,39890,41077,40979,41087,40745,40753,40194,41031,41126,40936,41126,40541,40956,43443,43448,43249,43414,43321,43323,31650,31765,31827,31650,31764,31765,31612,31579,31378,31315,31192,31332,11429,11534,11451,12800,12777,12697,35237,35201,34992,42149,42001,42093,41065,41072,41267,42149,42093,42171,639,625,405,138,56,144,38852,38687,38814,1507,1419,1288,960,1002,1105,1919,2200,1665,11978,11941,11902,20,353,628,6205,6585,6570,7826,7650,7856,7574,7631,7693,7640,7631,7511,16733,16916,17099,16747,17021,16844,16218,16423,16413,16283,16423,16218,24665,24729,24642,24833,24729,24949,35199,35237,34992,34204,34279,34440,39334,38814,38896,39585,39510,39644,43472,43477,43365,43350,43277,43165,43099,43047,43051,43462,43446,43815,5337,5257,5168,5168,5011,5299,4995,4861,4876,4876,4685,4828,4828,4630,4765,5317,5817,5449,5225,5317,5216,5977,6066,6059,4569,5343,4798,37167,37389,37280,38651,37608,37953,36976,37140,37167,37069,37140,36976,37069,36976,37012,36976,36821,37012,36663,36729,36835,36594,36613,36663,36692,36613,36594,5317,5257,5337,10002,10158,10752,9412,9364,9504,17534,17495,17636,24506,24156,24110,23824,23560,23689,36692,36729,36613,37117,36980,36933,37554,37342,37212,37590,37342,37554,37664,37774,37826,37911,37874,37900,38018,37900,37969,37140,37389,37167,41427,41077,41087,3758,3984,4009,3002,2853,3054,39921,39816,39781,40557,40449,40539,2785,2853,3002,8437,8518,8606,8876,8941,9057,8695,8757,8843,22222,22430,22653,26934,27066,26981,37262,37141,37288,43376,43061,43050,43413,43414,43323,42881,43024,42863,42881,42887,43013,1429,1419,1507,30594,30925,30866,30594,30488,30036,25505,25582,25772,36507,36692,36594,4533,4569,4641,4403,4348,4466,4403,4272,4199,9412,9570,9309,35537,35881,35773,5051,5011,5168,8564,8606,8682,7776,7994,7900,31738,31686,31561,32710,32745,32771,39768,39585,39644,973,934,1036,934,1002,960,2853,2643,2713,1482,1429,1502,11802,11978,11902,11978,12523,12083,29030,29077,29150,29050,29077,29030,35408,35537,35251,34645,34527,34632,39263,39091,39251,41930,41668,41675,42315,42094,42291,29668,30328,29686,36507,36552,36690,16452,16380,16149,16507,16380,16452,28202,28320,28175,28743,28938,28627,27516,27760,27576,27516,27576,27373,29,134,236,7,98,192,13078,13051,13124,13381,13295,13475,28241,28320,28202,4857,4861,4995,24729,24833,24828,24067,23912,23722,43443,43249,43405,43443,43405,43441,26830,26547,26351,27396,27516,27373,26934,26859,26830,43051,43047,42957,43042,43047,43111,31986,32154,31890,20,56,156,488,625,610,43206,43050,43049,20896,20483,20707,20010,19652,19736,20896,20707,20872,20896,20872,21080,20896,21080,21263,21974,22035,21801,43611,43719,43575,43079,43694,43483,43668,43804,43667,43667,43818,43645,43698,43787,43522,43696,43794,43632,43844,43794,43696,43844,43696,43743,43844,43743,43873,43743,43728,43873,34592,34645,34632,33986,33671,33770,43794,43804,43650,11754,11802,11902,11368,11429,11451,11384,11429,11368,11384,11248,11402,13108,13051,13078,12777,13072,13016,14303,14312,14079,12800,13072,12777,33400,33435,33148,32734,32745,32710,40683,40539,40615,40683,40615,40690,3157,3085,3237,2853,2740,2643,3050,3085,3157,8695,8564,8682,8695,8682,8757,33400,33148,33089,33628,33756,33556,6043,5977,6059,6043,6150,6130,20483,20054,20286,21801,22035,22222,32154,32400,32074,17493,17967,17509,23032,23538,23345,43032,42843,42900,42880,42817,42725,42411,42315,42291,24067,24084,23982,36593,35646,35360,34898,34724,34785,43413,43323,43338,2680,2690,2773,3258,3216,3467,2680,2773,2653,3137,3216,3258,8159,8381,8190,7962,7826,8008,8684,8767,8538,9888,9893,9887,8684,8538,8385,29050,28938,29044,29385,29686,29150,39816,39768,39644,39317,39251,39313,39317,39263,39251,39888,39768,39816,29,236,163,9887,9798,9530,17030,17493,17509,15986,16091,16283,14809,14949,15041,30020,29866,29796,30488,30355,30036,31213,31149,30961,31128,31149,31213,31570,31213,31647,43441,43405,43520,42979,43305,43694,31579,31738,31561,32163,32260,32154,32154,32260,32400,31332,31192,30986,4571,4496,4497,3910,4009,4239,4685,4630,4828,7480,6834,7274,6130,6585,6205,15327,15139,15270,13228,13233,13295,15362,15139,15327,38120,38018,37969,38120,38174,38233,41126,40956,40936,34592,34528,34502,34592,34632,34528,39313,39379,39428,38233,38174,38285,43719,43770,43565,43536,43387,43629,9673,9504,9832,9997,10002,10109,32549,32503,32589,31612,31738,31579,7925,7826,7962,8434,8684,8385,7631,7776,7900,7640,7776,7631,9877,9832,9949,8876,9057,9129,32589,32503,32718,32589,32718,32763,39975,40609,40083,40782,40788,40918,40753,40950,40860,40599,40745,40194,40599,40194,40463,4103,4326,4264,7480,6975,6834,26859,26934,26981,26830,26351,26832,35537,35408,35441,36061,35857,35881,36061,36010,35963,38169,38687,38380,43047,43042,42900,43032,43042,43111,43013,43024,42881,43340,43413,43338,43013,42887,43112,35441,35408,35237,1419,1168,1288,1502,1429,1507,2149,1591,1665,27882,28068,27874,28743,28627,28705,27882,27874,27760,30866,30925,30961,42446,42220,42625,41977,41826,42104,43505,43350,43318,43619,43561,43848,43569,43561,43619,43528,43387,43448,9929,9877,9949,18282,18256,17962,18830,18687,18883,41077,41072,40979,41267,41072,41427,42115,41939,42149,41031,40801,40860,43858,43770,43719,43694,43305,43842,13295,13233,13257,12030,11905,12291,12030,11747,11905,13228,13295,13381,29866,29654,29796,29870,29654,29866,29385,29150,29077,31645,31612,31315,42171,42115,42149,20054,19652,20010,22222,22226,22430,22222,22035,22226,27180,27373,27066,4630,4496,4571,4416,4528,4509,4416,4509,4348,25392,25372,25245,25505,25392,25582,25505,25772,25752,25148,25145,25040,25008,24929,24833,43418,43509,43513,43520,43405,43411,43691,43637,43536,16916,16675,16693,15043,15040,15139,16715,16675,16916,16507,16675,16715,17030,17277,17021,14809,14433,14949,24949,25008,24833,30496,30355,30488,41746,41824,41610,42345,42774,42531,43418,43411,43414,40031,39977,39827,39784,39827,39695,43843,43787,43698,2643,2468,2583,2627,2785,2705,2740,2785,2627,8437,8381,8518,8051,7925,7962,9259,9265,9129,8222,8016,7994,9530,9798,9457,33862,33986,33770,33435,33576,33556,33189,33400,33089,33576,33607,33628,42510,42725,42817,42625,42510,42814,4302,4416,4348,2690,3137,3258,8437,8606,8564,33862,33770,33756,535,653,735,535,735,557,581,729,818,7061,7590,7650,34502,34528,34381,34645,35199,34992,39263,39337,38896,39428,39379,39531,40804,40950,40753,40531,40599,40463,43669,43305,43468,43858,43719,43722,39654,39617,39285,37604,37528,37469,15139,15040,15270,15362,15706,15876,13434,13719,13449,4272,4157,4199,6259,6260,6356,6243,6260,6110,36015,36061,35881,38380,38911,38506,211,333,71,338,253,416,11429,11409,11754,12947,12800,12699,12978,13204,13072,11118,11014,10857,156,56,138,105,628,301,2690,2489,3137,2587,2680,2416,8843,8876,8747,43561,43569,43472,43736,43514,43588,39654,39285,39521,32400,32560,32368,32163,32154,31986,40804,40753,40745,1002,934,973,960,1127,902,28627,28497,28705,28938,29050,29030,42446,42411,42291,42275,42171,42093,42465,41941,42363,36980,36593,36871,37342,37262,37288,37360,37262,37342,37774,37874,37911,37900,38018,37911,5257,5116,5168,5011,4946,4995,4861,4685,4876,4630,4557,4496,5317,5225,5257,5216,5317,5279,5480,5863,5594,5992,5977,6043,43042,43032,42900,43277,42867,43165,16675,16507,16590,17449,17242,17495,25008,25148,25040,25027,25148,25008,25210,25148,25127,37262,37117,36933,37389,37531,37469,37140,37308,37389,37069,37308,37140,36835,37012,36821,37023,37012,36835,36729,36663,36613,36507,36690,36692,6260,6418,6484,37911,38018,38144,38363,38380,38506,24506,24565,24156,27569,27511,27695,25431,25469,25517,25443,25469,25431,5117,5116,5257,37506,37531,37389,2394,2468,2537,40947,40804,40745,40488,40531,40463,5116,5051,5168,28357,28371,28320,27891,27882,27760,28018,27882,27891,38018,38120,38139,12978,13434,13204,12800,12697,12699,19652,19254,19445,22653,22629,22872,23934,23865,24089,39033,39150,38668,39330,39150,39357,40683,40964,40539,40918,40788,41065,40739,40745,40599,8022,8222,7994,7511,7415,7284,34592,34711,34645,36326,36181,36248,34440,34502,34381,38362,38363,38506,39531,39379,39585,39714,39585,39768,30557,30496,30488,31149,31073,30961,31128,31073,31149,31570,31647,31650,5051,4946,5011,18394,18288,18459,18394,18459,18548,36367,36276,36365,43767,43588,43600,686,815,930,34279,34204,34110,33607,33576,33435,33052,32851,32992,1725,2595,2506,1429,1341,1419,15040,14943,15246,15876,16149,16311,31073,30866,30961,30355,30020,29796,3178,3050,3157,2394,2433,2468,4272,3585,4157,7644,7994,7776,31847,31570,31650,31738,31796,31686,31315,31612,31378,30749,30638,30523,33846,33862,33756,40016,40609,39975,4946,4857,4995,25185,25245,25372,36365,36276,36326,43350,42969,43318,13940,13987,13816,15043,14943,15040,16283,16208,15986,14433,14809,14440,43152,42909,43039,43024,43125,42889,43147,43125,43024,1496,1482,1502,9997,9929,10002,12291,12501,12393,30866,30675,30594,30523,30209,30328,30523,30328,30633,10002,9929,9949,9877,9791,9832,8843,8941,8876,10752,11024,10134,8867,8845,8690,8867,9051,8845,11402,11409,11384,32047,32021,32094,31675,31796,31738,34079,33795,33388,32066,32047,32094,34785,34991,35009,39790,39714,39768,15023,15277,15041,17030,17021,16747,25190,25185,25249,24729,24665,24580,25148,25210,25156,267,1567,1377,723,1015,861,12697,12583,12699,28357,28320,28272,29090,29385,29077,42342,42499,42276,42472,42499,42342,18288,18256,18282,18394,18256,18288,32763,32718,32846,40723,40739,40599,305,184,301,158,184,305,25508,25562,25469,25469,25562,25517,27891,27760,27866,30749,30523,30882,43579,43108,43477,4157,3585,4001,4857,4685,4861,4159,4103,4264,32543,32233,32549,32452,32560,32400,31796,32032,31986,38139,38120,38197,98,29,163,96,380,200,43569,43574,43477,43619,43574,43569,528,488,610,405,488,432,42489,42378,43084,17030,16747,16578,23097,22653,22872,24506,24637,24565,23538,24067,23722,34502,34711,34592,34279,34044,34167,39312,39263,39317,39647,39531,39585,43892,43770,43858,43722,43697,43858,6058,5992,6043,6058,6043,6130,36010,36061,36248,36326,36276,36181,42104,41826,42039,42275,42093,42315,42411,42385,42315,42454,42385,42411,42454,42411,42446,42835,42864,42725,32032,32163,31986,40950,41031,40860,41126,41490,40541,41534,41746,41180,41025,41031,40950,40914,40950,40804,245,253,338,211,253,245,3192,3713,3780,4393,4497,4496,6783,6596,7035,6552,6596,6783,7699,7650,7826,28717,28258,28761,29375,29359,29654,27882,28018,28068,27180,27066,27013,2468,2433,2506,2740,2853,2785,32884,32763,32846,32589,32543,32549,40954,40914,40804,40531,40586,40599,40488,40586,40531,40161,39753,39977,184,105,301,6205,6058,6130,36248,36061,36223,38197,38120,38263,38363,38233,38380,39647,39423,39531,39921,39888,39816,40016,40249,40569,42835,42948,43019,43019,42948,43032,43528,43448,43443,43536,43637,43385,43413,43418,43414,43418,43413,43509,43872,43601,43522,43599,43579,43574,8159,8001,8051,8695,8552,8564,8747,8552,8695,9265,9364,9278,40101,40161,39977,39784,39695,39617,14957,14816,14943,14943,14816,14762,15043,15139,15362,26086,26351,25893,43099,43111,43047,43232,43111,43099,43152,43372,43342,11384,11409,11429,11014,10846,10857,30285,30020,30355,2785,3002,2705,3499,3984,3758,17534,17449,17495,16311,16149,16380,23221,23689,23560,24973,24637,24946,39865,39784,39851,43528,43443,43525,43525,43443,43441,16311,16380,16507,40954,40804,40947,9278,9364,9412,32992,32851,32745,33576,33628,33556,34167,34044,33986,40161,40381,39707,7640,7644,7776,7284,7415,7343,34809,34711,34502,34478,34502,34440,36015,35881,36043,43804,43818,43667,43787,43872,43522,43794,43844,43804,43873,43647,43893,19254,18830,19068,18256,17995,17962,23824,23934,23560,12501,12821,12510,11747,11690,11516,12821,13051,12510,29572,29375,29654,29090,29077,29050,29044,28938,28743,43893,43647,43725,1371,1341,1482,1591,1431,1483,30675,30496,30557,30778,30496,30675,31073,30985,30866,31198,31128,31213,31541,31213,31570,31541,31570,31847,34025,33986,33862,41586,41682,41803,41824,42000,41610,41490,41126,41682,2416,2653,2425,903,1204,1047,27013,27066,26934,43136,43019,43160,11965,11690,11747,30020,29870,29866,29924,29870,30020,43844,43818,43804,4302,4419,4416,4416,4419,4528,4528,4569,4533,6243,6288,6260,6260,6288,6418,4302,4348,4255,40431,40488,40463,40947,40745,40739,17958,17995,18256,32047,32116,31827,32525,32543,32640,32452,32400,32260,9929,9839,9877,10109,10752,10134,16521,16311,16507,41586,41746,41534,253,250,416,229,250,253,43205,43152,43342,43160,43019,43032,43891,43725,43507,24580,24665,24274,25210,25443,25431,26945,26917,26830,43574,43579,43477,43232,43205,43251,43446,43532,43815,43520,43525,43441,43618,43629,43387,1482,1341,1429,686,737,815,1436,1482,1496,9940,9839,9929,35471,35441,35237,4375,4393,4496,4103,3957,4239,6418,6370,6484,5862,5501,5485,8517,8437,8564,8517,8564,8552,33607,33435,33400,33846,33628,33655,35641,35881,35537,39423,39317,39428,40381,40431,40186,40574,40431,40409,40031,40101,39977,39531,39423,39428,39647,39585,39714,902,1127,1288,815,737,818,8263,8190,8381,12132,12030,12291,13108,13078,13233,26830,26917,26934,26086,25893,25903,33846,34025,33862,40083,39888,39921,39790,39888,39893,43125,43206,43049,43513,43520,43411,43013,43147,43024,43179,43147,43013,3002,3085,2705,5225,5177,5257,5116,5005,5051,5051,4967,4946,4946,4890,4857,4857,4694,4685,4685,4557,4630,5279,5317,5285,5940,5449,5817,37193,37308,37012,37012,37308,37069,37531,37604,37469,37023,36835,36921,36835,36729,36921,36729,36973,36921,36692,36810,36729,36690,36810,36692,37262,37130,37117,37117,37078,36980,37464,37360,37342,37464,37342,37590,37554,37569,37590,37569,37947,37590,5216,5177,5225,37360,37130,37262,37774,37911,37826,686,930,934,487,976,796,887,871,1058,13295,13488,13475,28241,28202,28104,28241,28104,28018,27760,27516,27638,5177,5117,5257,37130,37078,37117,35009,34991,35077,36552,36507,36367,37513,37506,37389,32164,32066,32094,8456,8517,8552,9281,9278,9412,43818,43843,43645,581,735,729,488,405,625,37,20,105,42817,42814,42510,43124,42864,42835,42880,42864,43005,5117,5005,5116,36485,36552,36367,37826,37911,37934,37506,37604,37531,8001,7925,8051,4210,4255,4199,4210,4302,4255,6288,6370,6418,8690,8845,8684,8198,8385,8222,40292,40381,40161,40723,40599,40586,5005,4967,5051,12800,12947,13072,14309,14433,14303,12434,12523,12116,25343,25443,25210,28769,28717,28761,28769,28761,29375,28357,28705,28497,42386,42275,42315,42613,42532,42446,42515,42532,42679,105,20,628,37,105,184,6427,6883,6986,16733,16715,16916,16521,16715,16733,24949,25027,25008,25101,25027,24949,4967,4890,4946,36365,36485,36367,11427,11802,11754,10857,10846,10764,32426,32315,32233,32951,32992,32745,32163,32306,32260,32067,32306,32163,32067,32163,32032,32067,32032,31796,31675,31738,31612,31332,30986,31280,42104,42039,42115,41065,40788,40925,42104,42115,42266,42079,42000,41824,14303,14433,14440,14949,15023,15041,13633,13719,13434,43892,43409,43256,43892,43412,43770,250,274,416,204,274,250,12195,12030,12132,9933,9940,9997,12234,12291,12393,13185,13108,13228,14957,15043,15074,14957,15074,14846,16073,15876,16311,15143,15023,14733,36365,36326,36485,38144,38018,38139,42487,42315,42385,43152,43205,43099,43039,43372,43152,7230,7284,7343,7511,7505,7640,35009,35077,35174,33069,32846,33130,32763,32698,32589,32543,32426,32233,96,200,134,34672,34551,34538,1591,1560,1431,2537,2468,2643,9278,9129,9265,9281,9129,9278,29052,29044,28743,30955,30749,30882,32854,32884,33069,42515,42454,42446,42499,42774,42345,42465,42472,42342,43670,43669,43468,43618,43387,43528,43618,43528,43615,4569,4528,4419,5485,5501,5387,6288,6270,6370,37078,36593,36980,36485,36326,36267,1051,1168,1419,8190,8001,8159,8437,8263,8381,8747,8695,8843,32525,32426,32543,32306,32452,32260,40782,40907,40683,41065,40925,41072,40723,40586,40488,41123,41099,41031,42266,42115,42171,33628,33846,33756,34025,34167,33986,34279,34478,34440,34711,35199,34645,33607,33400,33488,39784,40031,39827,40174,40292,40161,39865,40031,39784,26917,27013,26934,26945,27013,26917,18830,18394,18548,17099,17242,17449,24053,23934,24134,43670,43468,43637,16715,16521,16507,17534,17636,17995,25027,25127,25148,25443,25508,25469,25101,25127,25027,36267,36248,36223,36267,36326,36248,41490,41586,41534,41746,41898,41824,41099,41126,41031,43513,43411,43418,25478,25508,25443,581,464,392,557,392,458,464,581,818,7925,7838,7826,7993,8001,8190,27396,27373,27180,28357,28660,28705,29052,29090,29044,34053,34167,34025,39888,39790,39768,39821,39790,39893,3173,3467,3216,4302,4192,4419,28019,28241,28018,43843,43872,43787,43767,43906,43588,1341,1051,1419,1485,1436,1496,1371,1328,1286,42864,42880,42725,42532,42515,42446,43136,42835,43019,9776,9940,9872,12510,12234,12393,13228,13108,13233,14192,14495,14437,3885,3957,4103,4444,4557,4685,9839,9791,9877,9997,9940,9929,11965,11747,12030,38197,38144,38139,38120,38233,38263,39312,39317,39423,10425,10846,10447,10425,10447,9890,34898,34770,34724,34878,34770,34898,39337,39312,39424,39150,39330,39261,39357,39150,39033,16578,16747,16686,16578,16686,16423,24067,24580,24274,43857,43532,43736,43498,43277,43350,11427,11754,11409,11427,11409,11402,2539,2537,2643,1485,1496,1665,2544,2643,2740,32734,32710,32656,34551,34405,34386,34574,34405,34551,39821,39647,39714,39521,39285,39261,27287,27396,27180,9776,9791,9839,15043,14957,14943,15043,15362,15074,35262,35199,35276,36223,36061,36015,43205,43232,43099,43039,43277,43372,43147,43206,43125,43333,43206,43147,43858,43697,43694,43803,43670,43637,43691,43536,43629,28717,28451,28056,25249,25372,25505,29401,28769,29375,35641,35537,35507,38263,38233,38362,42613,42446,42625,42454,42487,42385,42242,42124,42104,29674,29572,29654,30778,30675,30866,30985,31073,31128,32116,32047,32066,32164,32094,32315,35507,35537,35441,41977,41930,41675,42242,41930,41977,42124,41977,42104,43858,43694,43842,29,96,134,25185,25190,24946,24156,24053,24134,25249,25185,25372,25249,25505,25646,43615,43528,43525,43509,43413,43879,32393,32164,32315,32507,32315,32426,41072,41077,41427,40918,40907,40782,41025,40950,40914,41025,40914,40954,40723,40488,40623,36043,36223,36015,38362,38233,38363,432,528,378,432,488,528,11146,11248,11368,30496,30285,30355,40174,40161,40101,40174,40101,40054,29674,29654,29806,32656,32710,32560,40875,40723,40861,43615,43525,43608,39708,39784,39617,12234,12195,12132,12493,12510,12701,28841,28743,28705,29044,29090,29050,30959,30986,30749,42563,42487,42454,42472,42579,42499,42363,41941,41711,42472,42465,42574,7303,7511,7284,7303,7505,7511,7230,7343,7027,17958,17534,17995,24100,24053,24156,34784,34672,34770,34770,34672,34538,4159,4264,4393,2705,3085,2767,36005,36043,35881,35471,35507,35441,33279,33234,33118,32992,33234,33189,34346,34279,34167,6596,6205,6570,5594,5977,5706,5964,6205,6148,13666,13633,13498,14433,14575,14949,13633,13434,13498,28241,28272,28320,27891,28019,28018,28081,28019,27891,38380,38687,38911,40989,41025,40954,42959,42814,42817,42515,42563,42454,42840,42814,42894,13475,13488,14054,12701,12510,13051,28332,28272,28241,42840,42757,42625,274,116,799,211,229,253,165,229,211,581,557,735,845,934,960,8001,7838,7925,7993,7838,8001,12583,12697,12523,11385,11427,11402,39654,39708,39617,39766,39708,39654,42406,42171,42275,25190,24973,24946,27305,27511,27569,43608,43525,43520,43894,43509,43879,43872,43884,43767,42757,42613,42625,5177,5143,5117,4940,4916,5005,5005,4916,4967,4967,4809,4890,4890,4694,4857,5216,5143,5177,5940,5863,5449,14596,14495,14816,5279,5143,5216,5449,5863,5444,37078,37168,36593,37130,37154,37078,37360,37300,37130,37464,37421,37360,37678,37421,37464,37452,37421,37488,37947,37569,37826,37934,37911,37964,37911,38144,37964,38144,38207,37964,6370,6427,6484,6243,6270,6288,12076,12195,12234,11965,12195,12076,17534,17395,17449,17529,17395,17534,29572,29401,29375,29625,29401,29572,30959,30749,30955,32552,32510,32452,32452,32510,32560,32893,32951,32745,32893,32745,32734,36005,35881,35801,37300,37154,37130,35174,35077,35296,37039,37193,37023,37023,37193,37012,37308,37513,37389,37506,37560,37604,37953,37608,37588,37039,37023,36921,37039,36921,36973,36729,36834,36973,36810,36834,36729,36737,36834,36810,36737,36810,36690,36737,36690,36618,37580,37513,37308,38144,38197,38317,38907,38687,38852,42487,42386,42315,42522,42386,42487,43788,43691,43629,43608,43520,43894,3957,3910,4239,3750,3910,3885,4413,4496,4557,10857,11146,11368,11248,11385,11402,9890,10348,9888,35424,35471,35237,35801,35881,35641,35424,35237,35199,39334,38907,38814,39337,39263,39312,31847,31650,31827,30151,30020,30285,5444,5863,5480,36618,36690,36552,37513,37560,37506,32164,32116,32066,32698,32543,32589,32698,32763,32854,32552,32452,32306,41023,40907,40918,40875,40947,40739,40875,40739,40723,31198,30985,31128,29806,29654,29870,30328,29668,29927,4940,5005,5117,36485,36618,36552,31645,31675,31612,7027,7343,6883,7505,7549,7640,7557,7549,7413,36531,35646,36593,39330,39521,39261,39530,39521,39330,12523,11978,12116,42574,42579,42472,42574,42465,42621,1436,1371,1482,902,845,960,2506,2433,1725,10674,10764,10846,30985,30778,30866,40574,40488,40431,40054,40101,40031,40026,40031,39865,40026,39865,39961,36485,36267,36569,78,37,184,458,528,535,43206,43376,43050,42945,42378,42531,39851,39784,39708,4157,4210,4199,4001,4210,4157,6270,6427,6370,36301,36267,36223,43842,43305,43817,43305,43669,43817,16521,16244,16311,14205,14075,14192,16426,16244,16521,16091,15986,15622,16578,16283,16091,18394,17958,18256,24100,23560,23934,24100,23934,24053,25903,25893,25562,27013,27287,27180,25127,25343,25210,25101,25343,25127,25903,25562,25781,27396,27638,27516,35801,35641,35627,35262,35424,35199,34478,34279,34346,39424,39312,39423,39790,39821,39714,40083,39921,39975,43505,43318,43606,43160,43032,43111,9309,9281,9412,8117,8263,8118,8337,8263,8437,32126,32116,32248,32854,32763,32884,33130,33260,33069,34722,34551,34672,32629,32656,32560,32629,32560,32510,40431,40381,40409,17099,16916,17117,16426,16515,16314,25142,24973,25190,38197,38263,38317,43730,43599,43574,43730,43574,43619,43864,43608,43894,43711,43629,43618,43711,43864,43788,32507,32426,32525,31817,32067,31796,788,845,781,778,871,730,903,871,778,11844,11978,11802,11844,11752,11885,40409,40381,40292,11433,11802,11427,29924,30020,30064,11028,11146,10857,42956,42945,42531,26832,26945,26830,37953,37588,37604,37168,36531,36593,38385,38263,38362,13381,13185,13228,13363,13185,13381,7230,7303,7284,7092,7303,7230,35009,34878,34898,34784,34878,35042,39424,39423,39494,557,458,535,378,458,342,7549,7644,7640,7557,7644,7549,14192,14075,14054,14846,14816,14957,34053,34025,33846,33400,33189,33279,33234,32992,33118,39521,39592,39654,39551,39592,39521,41682,41586,41490,41025,41123,41031,41137,41123,41025,41137,41025,40989,4332,4569,4419,6110,6260,6259,6270,6301,6427,28769,28662,28717,28894,28662,28769,28894,28769,29401,28841,28660,28532,28532,28660,28357,29090,29324,29385,28357,28272,28447,43711,43618,43615,11254,11385,11248,33069,33260,33026,31988,31827,32116,32726,32893,32734,32726,32734,32656,158,639,9,639,405,352,8747,8876,8902,7838,7699,7826,39669,39423,39647,40569,40305,40557,40026,40054,40031,40513,40409,40292,40267,40054,40026,33279,33189,33234,27321,27287,27013,43255,43111,43232,42713,42613,42832,42679,42532,42613,11844,12116,11978,11885,12116,11844,229,204,250,152,204,229,26086,26266,26351,27220,27321,27013,26077,26266,26086,40964,40569,40557,41065,41023,40918,41060,41023,41065,41087,41255,41427,8054,7993,8190,39965,39893,39888,39799,39851,39708,2680,2587,2690,3137,3173,3216,1211,2425,1882,8902,8876,9129,12978,13072,12947,12434,12583,12523,12743,12583,12546,28865,29052,28743,33022,32992,32951,40513,40292,40546,40574,40623,40488,40875,40989,40947,42386,42406,42275,42648,42563,42515,42840,42625,42814,352,405,432,43884,43906,43767,30064,30020,30151,28647,28451,28662,30151,30285,30585,30985,31039,30778,31541,31198,31213,31197,31198,31578,30959,31280,30986,31332,31645,31315,31675,31817,31796,30955,31280,30959,39055,38911,38907,38413,38385,38486,38486,38385,38362,39669,39647,39821,1485,1483,1336,902,1288,1168,4424,4413,4557,36333,36223,36183,36333,36301,36223,31597,31645,31332,32552,32629,32510,7413,7549,7505,6952,7027,6805,10860,11028,10857,11146,11254,11248,10425,10674,10846,10764,10674,10759,43200,43179,43013,43200,43013,43112,40051,39669,39821,39698,39766,39592,39592,39766,39654,31988,31847,31827,32640,32543,32698,31653,31817,31675,32626,32640,32698,34518,34162,34405,32893,33022,32951,33118,33022,32898,40699,40623,40689,8964,8902,9129,9570,9412,9504,9673,9832,9791,9776,9839,9940,8867,9325,9253,9395,9325,9221,32507,32640,32626,32552,32306,32554,13423,13475,13651,13185,13207,13108,42959,42817,42880,43005,42959,42880,15852,15767,15622,16283,16578,16423,24580,25101,24949,25606,25562,25508,4413,4375,4496,38911,38687,38907,41803,41898,41746,41803,41746,41586,43606,43230,43579,43279,43124,43136,43606,43579,43679,27447,27638,27396,28660,28841,28705,27447,27396,27287,28662,28451,28717,29625,29572,29674,43124,42835,43136,43114,43005,42864,11024,11516,10134,29924,29806,29870,29886,29806,29924,11385,11433,11427,10860,10857,10764,39334,38896,39337,2537,2286,2394,3085,3050,2767,3750,3758,3910,4375,4253,4393,6427,6689,6883,6110,6259,5862,14114,14303,14079,13940,13816,13852,29713,29668,29385,28532,28357,28447,34129,34053,34094,33279,33488,33400,33370,33488,33279,34784,34722,34672,34784,34770,34878,39622,39530,39330,42444,42406,42386,42713,42679,42613,43251,43205,43342,42945,43084,42378,43216,43357,43301,8117,8054,8190,7993,7699,7838,8117,8190,8263,33655,33628,33607,35507,35471,35627,39893,40039,39821,40083,39965,39888,40039,39965,40059,43817,43669,43670,71,165,211,871,887,730,9776,9673,9791,26663,26832,26351,25606,25508,25478,43384,43251,43342,33544,33655,33488,32742,32726,32656,32898,32726,32742,40699,40861,40723,41682,41126,41526,5076,4940,5117,4916,4809,4967,4413,4424,4375,3999,4159,4253,5279,5199,5143,5285,5203,5279,5313,5203,5285,5313,5285,5449,5338,5313,5449,37154,37168,37078,37452,37300,37360,37211,37300,37408,37360,37421,37452,38033,37934,38088,11098,11254,11146,12743,12699,12583,40964,40683,40907,3039,3173,2951,15074,15362,15201,16733,16426,16521,17099,17449,17395,39766,39799,39708,39851,39961,39865,40546,40292,40174,40409,40513,40574,40623,40699,40723,39780,39799,39766,5076,5117,5143,5313,5338,5249,5385,5444,5480,36974,37030,36973,36973,37030,37039,37039,37030,37193,37193,37580,37308,37513,37580,37560,39232,39033,39118,36974,36973,36834,36974,36834,36737,29806,29625,29674,29886,29625,29806,42124,42242,41977,42522,42487,42563,6243,6301,6270,35641,35507,35627,36720,36974,36737,35471,35732,35627,96,71,339,25478,25443,25343,40989,40954,40947,302,352,432,378,528,458,845,788,934,902,678,829,36618,36485,36569,42579,42590,42499,42363,41711,42000,43255,43160,43111,43473,43376,43206,43216,43200,43112,3885,3910,3957,4842,4809,4916,43801,43803,43637,43608,43711,43615,43711,43608,43864,11376,11433,11385,17958,17529,17534,24565,24100,24156,30285,30496,30585,42266,42242,42104,12978,12947,12868,12947,12699,12743,42696,42648,42679,42959,42911,42814,42987,42911,42959,42894,42911,42985,43119,42864,43124,3563,3499,3758,39462,39334,39337,39462,39337,39424,39462,39424,39494,39530,39551,39521,39268,39357,39033,4809,4694,4890,13475,13363,13381,10134,11516,10013,13423,13363,13475,13207,13363,13309,7644,8022,7994,7413,7505,7303,7413,7303,7313,34722,34574,34551,34721,34574,34722,39698,39551,39660,13852,13816,13633,43466,43372,43277,43251,43255,43232,43333,43147,43179,32640,32507,32525,32626,32698,32821,33026,32854,33069,32554,32306,32067,33370,33279,33118,40861,40989,40875,41335,40989,40861,1591,1485,1665,2286,2433,2394,25903,26071,26086,25961,26071,25903,9668,9570,9673,9997,10109,9973,2627,2544,2740,2767,3050,2823,12583,12434,12546,29198,29090,29052,28081,28241,28019,32992,33022,33118,33488,33655,33607,36569,36267,36535,5469,5594,5522,8118,8263,8337,8437,8517,8456,1286,1341,1371,871,903,1047,1567,1423,1882,487,796,320,16202,16311,16244,26663,26351,26266,27866,28081,27891,31597,31653,31645,31645,31653,31675,31817,31944,32067,28865,28743,28841,41126,41099,41526,42214,42363,42000,41099,41123,41526,43219,43119,43279,43401,43255,43251,31597,31332,31298,818,737,464,392,557,581,27349,27447,27287,43114,43119,43219,2512,2544,2627,33022,32893,32898,42348,42266,42171,42348,42171,42406,42648,42515,42679,1328,1371,1436,36535,36267,36458,39799,39848,39851,39954,39848,39799,43784,43730,43619,43556,43384,43372,43801,43637,43691,2750,4001,3585,4210,4192,4302,36535,36720,36569,35199,34711,35276,34502,34684,34809,12021,12434,12116,28451,28386,28029,29026,28894,29401,28829,28894,29026,29035,28865,28841,42613,42757,42832,42594,42590,42579,43084,43216,43112,42594,42579,42574,43906,43857,43736,8964,9129,9123,9129,9281,9123,9570,9504,9673,32898,32893,32726,39334,39478,38907,39460,39462,39494,43311,43333,43179,43355,43084,43315,41427,41483,41414,41427,41731,41581,41023,41057,40907,34502,34478,34684,165,152,229,75,152,165,3837,3885,4103,4444,4424,4557,11752,11844,11802,26071,26077,26086,26168,26077,26071,38413,38317,38263,38413,38263,38385,38362,38506,38486,42079,41824,41898,43372,43384,43342,43109,43114,43219,43498,43350,43505,43749,43579,43599,902,781,845,829,781,902,730,887,654,29058,29198,29052,42308,42079,41898,43788,43801,43691,43822,43817,43670,43788,43629,43711,9668,9673,9776,13666,13852,13633,13369,13498,13434,13369,13434,13191,27866,27760,27638,29035,29058,28865,28865,29058,29052,42911,42894,42814,42987,42959,43005,43114,42864,43119,116,274,204,13828,13852,13695,13940,14114,14079,15143,15399,15023,27514,27447,27523,27514,27638,27447,27823,27866,27638,13363,13207,13185,13475,14054,13651,28482,28386,28451,25142,24565,24973,24973,24565,24637,27569,27695,27904,25478,25781,25606,25606,25781,25562,32742,32629,32552,32742,32656,32629,43311,43179,43200,43520,43513,43894,43905,43498,43505,38486,38506,39040,39965,40039,39893,40059,39965,40083,40059,40280,40066,39848,39961,39851,39954,39961,39848,39698,39592,39551,13917,14114,13940,27904,27695,28029,27013,26945,27053,43124,43279,43119,11433,11583,11802,11254,11376,11385,11151,11376,11254,11098,11146,11028,10860,10764,10759,30064,29886,29924,28829,28647,28662,30585,30496,30778,31039,30985,31198,31039,31198,31197,7857,8022,7644,7092,7230,7027,28829,28662,28894,33795,34079,34162,35061,34878,35009,35077,35425,35296,34684,34586,34849,42904,42757,42840,42627,42522,42563,42590,42774,42499,43301,43311,43200,42766,42774,42590,2512,2539,2544,2544,2539,2643,2336,2539,2281,40267,40174,40054,41252,41060,41065,3750,3563,3758,2336,2537,2539,4159,4393,4253,36267,36301,36458,35725,35627,35732,35934,36133,36095,43822,43670,43803,35077,35540,35425,39594,39622,39330,39232,39268,39033,37668,37604,37560,11885,12021,12116,12743,12868,12947,11738,12021,11885,6301,6226,6427,6243,6222,6301,6081,6110,5961,5485,5387,5039,38413,38486,38505,16299,16202,16244,16314,16244,16426,27053,26945,26832,267,1377,903,1211,1423,55,43606,43905,43505,43730,43749,43599,43784,43749,43730,12246,12546,12434,28562,28841,28532,29198,29324,29090,42598,42594,42574,11376,11583,11433,31198,31541,31741,31653,31835,31817,31715,31597,31712,31332,31280,31298,8902,8818,8747,9123,9281,9309,32930,33026,33293,32126,31988,32116,42308,41898,42188,40689,40623,40574,13309,13423,13460,15298,15362,15876,32930,32698,32854,5249,5203,5313,5249,5199,5203,5203,5199,5279,4940,4842,4916,4809,4710,4694,4694,4444,4685,5449,5385,5338,1286,1247,1341,1300,1328,1436,1300,1436,1485,5199,5076,5143,5449,5444,5385,9973,9933,9997,9570,9545,9309,11965,12030,12195,31715,31835,31653,41163,41057,41060,42558,41930,42650,4113,4192,4210,4113,4210,4001,6110,6222,6243,158,78,184,9,78,158,9,639,92,5977,5594,5863,37300,37211,37154,37421,37678,37488,38207,38144,38317,38207,38360,38210,37735,37580,37524,37524,37193,37030,37043,37030,36974,37043,36974,36720,5992,5706,5977,37211,37168,37154,37580,37668,37560,35276,35337,35262,34346,34167,34237,34167,34053,34237,34053,34129,34237,34094,34053,33846,1248,1247,1286,5992,5666,5706,5039,5343,4569,6081,6226,6222,6952,7092,7027,10644,10674,10554,11587,11614,11583,27097,27053,26988,27220,27053,27097,32116,32164,32248,35174,35061,35009,34518,34405,34574,35184,35061,35174,36720,36737,36618,36720,36618,36569,39268,39307,39357,39283,39307,39268,43301,43200,43216,43333,43473,43206,8198,8022,7857,9395,9530,9457,7400,7557,7413,13423,13651,13460,12493,12234,12510,42894,42883,42840,42980,42883,42894,42774,42956,42531,43043,42956,42865,28299,28029,28386,28299,27904,28029,25963,25646,25752,43109,42987,43005,43109,43005,43114,12021,12246,12434,12183,12246,12021,29165,29324,29198,42696,42679,42713,42627,42563,42754,42266,42420,42242,4553,4842,4940,4019,4159,3999,11614,11802,11583,11614,11752,11802,42468,42348,42406,28647,28482,28451,28665,28482,28647,29314,29423,29324,28332,28447,28272,28332,28241,28081,28332,28183,28389,27523,27638,27514,27349,27287,27321,4253,4375,4111,4192,4332,4419,4163,4113,4070,43401,43160,43255,16202,16073,16311,16067,16073,16202,15023,14949,14575,25101,25478,25343,25961,26168,26071,4842,4710,4809,7699,7993,7872,9737,9668,9776,10860,11098,11028,37758,37953,37604,41057,40964,40907,41057,41023,41060,33655,34094,33846,8814,8818,8902,8814,8902,8964,12546,12868,12743,13695,13852,13666,13852,13828,13940,12917,12868,12632,29026,29401,29568,35934,36005,35801,42793,42696,42713,15441,15298,15876,13260,13309,13460,43449,43401,43251,43746,43466,43277,43372,43466,43556,27262,27349,27321,17529,17099,17395,25142,25190,25249,43801,43822,43803,43552,43123,43376,9395,9457,9325,35899,35934,35801,35801,35627,35899,42079,42214,42000,42621,42598,42574,42308,42214,42079,41123,41137,41526,7092,7252,7303,7313,7252,7151,35061,35042,34878,35050,35042,35061,39462,39460,39334,39494,39423,39669,13051,13108,12701,39622,39551,39530,39961,40267,40026,40513,40689,40574,41414,41267,41427,42537,42444,42386,42537,42386,42522,43857,43815,43532,778,834,903,654,887,526,12701,13108,13207,42594,42766,42590,42621,42465,42363,2336,2286,2537,2627,2705,2674,33026,32930,32854,32248,32164,32393,34518,34574,34601,36458,36301,36333,38207,38317,38360,37964,38210,38088,43311,43359,43333,43359,43301,43480,16073,15980,15876,16067,15980,16073,8117,8091,8054,8456,8552,8577,8577,8552,8747,9221,9325,8867,41252,41065,41267,36223,36043,36183,9933,9872,9940,10013,11516,11331,36095,36005,35934,34586,34684,34478,33655,33926,34094,40109,39954,39799,42883,42904,42840,42987,42985,42911,43081,42985,42987,43240,42987,43109,13423,13309,13363,14816,14846,14663,13191,13434,12978,14282,14433,14309,27385,27140,27569,28463,28299,28386,28463,28386,28482,27937,28081,27866,28447,28562,28532,42980,42904,42883,42627,42537,42522,10134,9973,10109,9668,9577,9570,31597,31715,31653,31835,31944,31817,33488,33370,33544,31849,31715,31712,378,302,432,686,934,788,10860,10858,11098,11738,11885,11752,10554,10674,10425,9865,9888,9519,7252,7313,7303,7362,7313,7151,15298,15201,15362,15283,15201,15298,38317,38413,38360,40185,39494,39669,40066,39821,40039,40280,40127,40066,28575,28562,28447,42937,42832,42757,671,686,788,722,829,678,730,834,778,12246,12318,12546,12917,13191,12978,11962,12183,12021,11583,11376,11587,29324,29423,29385,29165,29198,29058,42563,42648,42754,42420,42266,42348,40,116,204,526,887,723,71,75,165,9910,9872,9933,9890,9865,9859,31849,31944,31835,36183,36043,36005,10754,10759,10674,9519,9888,9530,8777,9221,8867,11587,11376,11274,30232,29886,30064,28829,28828,28647,30232,30064,30151,34721,34722,34784,35077,35646,35540,39310,39232,39118,39594,39330,39357,39698,39780,39766,3050,3178,2823,1248,1286,1328,3885,3773,3750,4019,3837,4103,4019,4103,4159,7872,7993,8054,34721,34784,34786,39811,39780,39698,40783,40689,40881,40699,40802,40861,15980,15924,15876,16515,16426,16733,43749,43679,43579,43776,43679,43749,753,788,781,12493,12076,12234,13260,12701,13207,31741,31541,31847,30933,30585,30778,32315,32507,32393,16067,15924,15980,25752,25646,25505,27385,27569,27552,30933,30778,31039,43848,43784,43619,43864,43822,43788,43788,43822,43801,27349,27523,27447,27053,27220,27013,27262,27220,27317,3192,3780,3499,9737,9577,9668,8463,8337,8456,41358,41252,41267,40016,40569,40609,42468,42406,42444,3837,3773,3885,3828,3773,3837,1247,1051,1341,1048,1051,1247,1300,1485,1336,33370,33409,33544,34237,34242,34346,40569,40964,41253,7313,7400,7413,9401,9395,9221,7362,7400,7313,9148,9123,9309,29464,29713,29385,29464,29385,29423,39431,39357,39307,42544,42468,42444,42659,42444,42537,29035,29165,29058,36095,36183,36005,35627,35725,35899,42598,42766,42594,43357,43216,43084,42704,42917,42939,35296,35184,35174,35322,35184,35296,39532,39283,39426,39232,39283,39268,40,204,152,14068,14309,14114,16314,16299,16244,16515,16299,16314,37168,36938,36531,37211,37216,37168,37464,37590,37678,38033,37826,37934,431,464,737,4553,4620,4842,4842,4620,4710,4710,4620,4694,5199,5179,5076,5249,5179,5199,5338,5262,5249,5258,5262,5338,5258,5338,5385,5355,5385,5480,5355,5480,5469,37452,37408,37300,3173,3039,3585,2951,3173,3137,2951,3137,2941,14770,14846,15074,13309,13260,13207,12917,12978,12868,13695,13666,13498,13695,13498,13566,37408,37216,37211,39088,39118,38651,37668,37758,37604,37580,37693,37668,37735,37693,37580,37785,37693,37735,37524,37043,36720,36513,36720,36535,36513,36535,36458,36513,36458,36450,5469,5480,5594,37693,37758,37668,15014,14770,15074,15014,15074,15201,15014,15201,15231,43449,43251,43384,43449,43384,43551,4113,4163,4192,4070,4113,4001,6222,6226,6301,6202,6226,6179,36450,36458,36333,35424,35262,35337,5522,5594,5516,392,342,458,22,342,392,12318,12246,12183,12525,12868,12546,13917,14068,14114,27445,27523,27349,28747,28841,28562,28747,29035,28841,42832,42793,42713,42937,42793,42832,42937,42757,42904,42980,42894,42985,43279,43136,43160,5992,5756,5666,10013,9984,10134,12033,12076,12493,12033,12493,12248,29386,29464,29423,29748,29927,29668,29606,29464,29638,40689,40802,40699,40783,40802,40689,40267,39961,40223,39961,39954,40109,31741,31847,32056,39622,39660,39551,39283,39431,39307,39532,39431,39283,1485,1591,1483,2956,3192,3499,11151,11254,11098,10644,10754,10674,10467,10554,10425,33913,33795,34162,34913,34784,35042,39832,39660,39622,4553,4940,5076,38088,37934,37964,37964,38207,38210,4111,4375,4424,3773,3563,3750,3918,4070,4001,11614,11738,11752,10858,10860,10759,29748,29668,29713,42566,42420,42348,42566,42348,42468,342,302,378,730,642,834,55,1423,1567,526,248,407,9865,9890,9888,9519,9530,9401,26168,26266,26077,27220,27262,27321,28829,29026,28871,29568,29401,29625,29568,29886,29813,28389,28447,28332,32801,32742,32552,31715,31849,31835,31298,31280,30955,42704,42766,42598,42704,42598,42621,2658,2674,2767,2767,2674,2705,8118,8091,8117,8456,8337,8437,8577,8747,8818,34469,34162,34518,32930,32821,32698,1300,1248,1328,2893,2823,3178,8134,8091,8118,10498,10754,10644,30948,30933,31214,34849,34809,34684,33079,33118,32898,7480,7061,6975,5588,5706,5666,38413,38505,38360,8725,8577,8818,25961,25903,25781,41310,41163,41060,41483,41427,41581,14770,14663,14846,14711,15014,14940,26399,26663,26266,43556,43466,43636,43254,43227,43219,4069,4163,4070,2489,2690,2587,10852,10858,10759,38486,39040,38505,32554,32067,32413,36393,36333,36183,34711,34809,35276,41414,41358,41267,686,512,737,829,753,781,722,753,829,902,1168,678,8865,8814,8964,9013,8964,9123,12337,12318,12183,14711,14663,14770,42811,42648,42696,43301,43359,43311,43071,42945,42956,13651,14054,14075,12520,12493,12701,42793,42811,42696,43081,42980,42985,43227,43109,43219,11645,11614,11587,11645,11738,11614,29646,29748,29713,29927,30230,30328,29606,29713,29464,13828,13917,13940,14068,14282,14309,13389,13498,13369,13389,13369,13191,13389,13191,13175,27823,27937,27866,27823,27638,27523,43867,43776,43749,43907,43746,43498,43815,43848,43561,36393,36183,36303,42974,42937,42904,5,320,796,34721,34601,34574,34786,34601,34721,43240,43227,43254,6818,6834,6812,9577,9545,9570,9619,9545,9577,9737,9776,9872,9910,9933,9973,9984,9973,10134,9401,9530,9395,8434,8385,8198,17099,16515,16733,15330,15441,15662,25481,25142,25249,34971,34913,35042,35540,35646,35665,34242,34237,34129,43867,43749,43784,28871,28828,28829,27800,27569,27904,25646,25481,25249,29568,29625,29886,43088,42811,42793,4119,4192,4163,4119,4332,4192,6081,6222,6110,38506,38911,39110,30055,30230,29927,9148,9013,9123,14232,14282,14068,28001,27904,28299,92,639,352,8091,7872,8054,8337,8134,8118,8224,8134,8337,8463,8456,8577,8463,8425,8323,40109,39799,40009,43797,43552,43376,8725,8818,8814,8198,8222,8022,30232,30151,30356,29909,30055,29927,29314,29324,29165,29314,29165,29228,15143,15622,15767,15262,15622,15143,26024,25963,26440,26168,26399,26266,25478,25961,25781,2603,2658,2767,2981,2893,3178,2824,2893,2811,8045,7872,8091,34233,34242,34129,34233,34129,34094,40059,40066,40039,39536,39334,39460,40609,40569,41253,36183,36095,36227,36303,36183,36227,39536,39460,39494,978,2416,2425,8434,8690,8684,12318,12525,12546,12337,12525,12318,41171,40964,41057,42811,42754,42648,42627,42646,42537,8101,8198,7857,7151,7252,7092,35050,35061,35184,39660,39811,39698,39431,39594,39357,39532,39594,39431,3789,3828,3837,3789,3837,4019,6818,6552,6783,35732,35471,35424,30262,30055,30213,1159,1172,1248,671,722,678,2100,2433,2286,2100,2286,2005,6805,7027,6883,14663,14596,14816,14645,14596,14663,14437,14596,14475,14282,14575,14433,27262,27445,27349,26988,27053,26832,26988,26832,26663,43776,43766,43679,43867,43766,43776,11969,11690,11965,34692,34469,34601,34601,34469,34518,36227,36095,36133,13460,13408,13260,13678,13651,13801,28137,28001,28299,9013,8865,8964,8975,8865,9013,9148,9201,9152,13712,13917,13828,14282,14522,14575,13175,13191,12917,40802,41218,40861,40881,40689,40957,42937,42981,42793,42861,42732,42754,42980,42974,42904,43163,42974,42980,42865,42956,42774,10467,10498,10554,10716,10852,10754,10754,10852,10759,9771,9859,9865,9771,9865,9519,41310,41060,41252,41414,41509,41358,41427,41255,41731,13712,13828,13695,27966,27800,27904,26440,25963,25772,43227,43240,43109,43279,43160,43432,43894,43513,43509,570,631,686,213,302,342,213,183,302,1172,1247,1248,1159,1248,1300,10916,11151,11098,11962,12337,12183,10498,10644,10554,42732,42627,42754,42702,42646,42627,41731,41255,41918,42827,42774,42766,42827,42865,42774,36938,36515,36531,37408,37406,37216,37452,37517,37408,37488,37517,37452,37678,37517,37488,37678,37590,37731,37590,37947,37731,38033,37947,37826,38027,37947,38033,5262,5179,5249,3666,3773,3828,5258,5179,5262,5258,5385,5355,5351,5355,5469,5351,5469,5515,5469,5522,5515,9705,9737,9872,11507,11645,11587,26465,26399,26168,43449,43438,43401,43636,43466,43746,4069,4119,4163,3918,4001,2750,36133,35934,35899,37517,37406,37408,38088,38027,38033,2674,2512,2627,2729,2767,2823,8134,8045,8091,8323,8224,8337,8323,8337,8463,33795,33260,33130,32056,31847,31988,34132,33913,34162,38088,38105,38027,37758,37821,37953,37693,37785,37758,37580,37193,37524,37524,36720,37294,36450,36333,36393,36450,36393,36338,27345,27445,27262,28183,28332,28081,27317,27220,27097,34287,34132,34162,34913,34786,34784,34971,34786,34913,34586,34478,34346,35732,35838,35725,43430,43160,43401,30345,30328,30230,30345,30633,30328,2893,2824,2823,2729,2824,2625,671,788,753,302,183,352,2551,2512,2674,5516,5594,5588,28828,28665,28647,28890,28871,29153,33660,33544,33409,34523,34586,34346,37785,37821,37758,2194,2286,2336,8865,8725,8814,9029,9148,9152,38088,38303,38105,6226,6202,6427,5561,5862,5485,5588,5594,5706,4985,5561,5485,5039,4569,4344,8660,8725,8865,33391,33260,33795,37947,38027,38105,10916,11098,10858,30262,30345,30230,30533,30345,30426,7058,7151,7092,6204,6689,6427,14596,14437,14495,14711,14770,15014,35322,35050,35184,35665,35646,36111,42659,42544,42444,42659,42537,42646,42896,42754,42811,42704,42621,42917,42779,42704,42939,5992,6058,5756,3936,3918,3862,4298,4569,4332,7058,7092,6952,8301,8559,8434,35322,35296,35425,34579,34287,34469,39572,39536,39735,37841,37947,38028,39832,39811,39660,39310,39283,39232,13651,13504,13460,13678,13504,13651,42974,42981,42937,43286,43081,42987,43286,42987,43240,43154,43071,43043,43043,43071,42956,43359,43473,43333,43315,43071,43354,116,5,796,75,40,152,5756,6058,5830,26399,26572,26663,26465,26572,26399,43556,43551,43384,43279,43254,43219,43676,43551,43556,39832,39622,39594,40267,40546,40174,13566,13712,13695,13277,13175,13039,12632,12868,12525,28183,28081,27937,30533,30633,30345,27663,27523,27445,27663,27823,27523,15441,15876,15924,13615,13678,13801,26926,26988,26663,41171,41163,41270,43529,43438,43449,43572,43473,43359,43879,43413,43340,526,723,248,654,642,730,583,526,523,2512,2427,2539,2658,2551,2674,2579,2551,2658,3602,3563,3773,2824,2729,2823,4444,4694,4620,4312,4444,4380,6834,6818,6783,5638,5588,5666,7480,7590,7061,7650,7699,7061,6689,6805,6883,6680,6805,6689,8224,8275,8134,8425,8463,8577,28890,28665,28828,27801,27552,27800,28551,28665,28544,35540,35457,35425,35559,35457,35540,2811,2893,2795,1044,1159,1300,1591,2149,1560,41526,41137,41698,27966,27904,28001,27800,27552,27569,12076,11969,11965,11969,12033,12248,42702,42659,42646,41509,41414,41483,42702,42627,42732,10852,10916,10858,10467,10425,10253,30882,30523,30743,30882,31061,30955,32413,32067,31944,33782,33655,33544,9148,9309,9201,9984,9910,9973,10013,9910,9984,8690,8777,8867,8434,8559,8690,7374,7857,7644,2951,2883,3039,2487,2941,3137,40009,39799,39780,30743,30523,30633,526,583,654,2382,2452,2143,10253,10425,9890,9342,9771,9519,42779,42827,42766,42779,42766,42704,255,392,464,35390,34971,35050,35050,34971,35042,43355,43357,43084,11151,11274,11376,11728,12021,11738,10716,10916,10852,30619,30743,30633,29927,29748,29909,36338,36393,36303,36338,36303,36298,35838,35899,35725,35732,35424,35337,34305,34346,34242,40020,39883,40037,39811,39883,39780,39118,39033,38651,40020,40009,39883,3794,3789,4019,16067,16202,16299,35732,35723,35877,43746,43277,43498,43848,43867,43784,512,431,737,722,671,753,918,1168,1051,1048,1247,1172,12374,12337,12293,29127,29165,29035,30262,30230,30055,512,686,631,28575,28747,28562,28052,28183,27937,28516,28183,28342,36298,36303,36227,13566,13498,13389,14232,14522,14282,14575,14733,15023,13917,13712,13821,14711,14645,14663,14871,14645,14711,28024,27966,28001,2729,2603,2767,2551,2527,2512,2625,2603,2729,7270,7400,7362,28551,28463,28482,28551,28482,28665,33782,33926,33655,32834,32898,32742,43074,42981,42974,43074,42974,43163,2508,2527,2551,1560,2149,2346,8323,8275,8224,8505,8425,8577,8505,8577,8725,9029,9013,9148,9619,9577,9737,2981,3192,2956,2981,3178,3192,33926,34233,34094,43432,43254,43279,36099,36133,35899,35276,34809,35128,39478,39055,38907,11039,11274,11151,28575,28447,28389,29646,29713,29606,6202,6204,6427,5961,6110,5862,5638,5666,5646,7061,7699,7077,35421,35322,35425,35498,35425,35457,35383,35276,35307,34809,34849,35128,32909,32821,33010,33637,33391,33795,33637,33795,33908,34162,34469,34287,16515,16067,16299,25916,25481,25646,25916,25646,25963,26740,27385,26440,9334,9401,9221,8777,8690,8559,31917,31944,31849,4298,4332,4215,5561,5961,5862,39883,40009,39780,40572,40546,40267,39883,39811,39902,183,92,352,22,213,342,12033,11969,12076,12248,12493,12520,29509,29638,29464,29386,29423,29314,43357,43480,43301,43879,43340,43828,43315,43084,42945,43357,43355,43487,4380,4444,4620,5351,5258,5355,5287,5258,5351,5515,5522,5516,5515,5516,5588,5515,5588,5638,15441,15283,15298,15330,15283,15441,37841,37731,37947,37841,37705,37731,37731,37705,37678,37678,37705,37517,37517,37802,37406,35645,35665,35715,37841,38028,37814,37821,37945,37953,37785,37793,37821,37917,37999,38040,36483,36513,36450,43529,43430,43438,43438,43430,43401,43606,43679,43905,15231,14940,15014,38210,38303,38088,37735,37793,37785,583,642,654,562,642,583,562,583,523,28942,29127,29035,42827,43027,42865,42578,42363,42214,3936,4069,4070,3936,4070,3918,6081,6179,6226,6089,6179,6081,31061,31298,30955,31121,31298,31061,31005,31061,30882,31005,30882,31030,30882,30743,30856,35646,36531,36399,39310,39426,39283,39088,38651,39106,10498,10518,10754,11304,11328,11274,9856,9890,9859,9856,9859,9771,32056,31988,32126,31197,31214,31039,30933,30885,30585,28544,28665,28890,31298,31712,31597,37793,37945,37821,41163,41171,41057,40127,40051,40066,40066,40051,39821,41402,41252,41358,42242,42650,41930,1206,1300,1336,1206,1336,1258,6205,5830,6058,9538,9856,9771,30856,30743,30822,42566,42468,42544,6205,5900,5830,7077,7699,7280,7151,7185,7362,6728,7058,6952,6728,6952,6805,13972,14068,13917,26988,27155,27097,26926,27155,26988,43529,43449,43639,2527,2427,2512,2603,2579,2658,2508,2579,2603,8349,8275,8323,8349,8323,8425,43797,43376,43473,4215,4332,4171,3026,3585,3039,6179,6204,6202,6178,6204,6179,36099,35899,36024,36338,36483,36450,35852,35838,35732,1159,1048,1172,9910,9705,9872,9619,9705,9812,13504,13408,13460,14392,14192,14437,14475,14596,14645,30619,30533,30631,30619,30633,30533,34093,34168,34026,41581,41509,41483,2459,2427,2527,2416,2452,2587,2883,3026,3039,2489,2452,2382,8975,9013,9029,8660,8505,8725,29780,29909,29748,29286,29386,29314,42600,42566,42544,42800,42702,42732,13821,13972,13917,13566,13389,13277,28024,27801,27966,28828,28871,28890,29127,29228,29165,28747,28942,29035,28516,28575,28389,28516,28389,28183,6552,6343,6254,29646,29606,29638,42600,42544,42659,6661,6680,6689,35322,35421,35050,35665,35559,35540,35645,35559,35665,40059,40083,40280,39224,39110,39055,9201,9309,9545,32821,32930,33010,33026,33260,33293,32801,32834,32742,32801,32552,32554,30426,30345,30262,32393,32507,32553,42188,41898,41803,14733,15262,15143,26572,26926,26663,25961,26465,26168,2427,2281,2539,570,555,631,431,255,464,570,686,671,27588,27385,27552,27801,27800,27966,29054,28942,28747,57,92,183,57,183,213,14940,14871,14711,14843,14871,14940,15231,15201,15283,7018,7185,7058,7058,7185,7151,1048,918,1051,6812,6834,6860,30213,30426,30262,29909,30213,30055,29509,29646,29638,29509,29464,29386,6860,6834,6975,6860,6975,6885,35559,35498,35457,35554,35498,35559,12337,12374,12525,11696,11738,11645,11328,11587,11274,14508,14475,14645,29286,29228,29261,43487,43480,43357,43315,42945,43071,9152,8975,9029,8884,8975,9152,5900,6205,5964,34132,34093,33913,34601,34786,34692,2452,2489,2587,6955,7077,6936,8435,8349,8425,8435,8425,8505,8198,8301,8434,8101,8301,8198,40223,39961,40109,40783,40881,40802,42299,42188,41803,10872,11151,10916,30164,30213,29909,14289,14733,14522,14522,14733,14575,13277,13389,13175,34692,34786,34815,34233,34305,34242,36298,36227,36205,34431,34305,34233,34374,34305,34431,39478,39334,39536,40280,40083,40617,43014,42896,42811,43163,42980,43081,43286,43240,43374,13566,13821,13712,28024,28001,28137,36498,36483,36338,35852,35900,36012,43154,43043,42865,43639,43449,43551,43374,43240,43254,43905,43679,43766,1560,2346,1725,1159,1046,1048,1048,1040,918,31712,31861,31849,31671,31861,31712,31671,31712,31298,31671,31624,31816,31061,31005,31121,30882,30856,31030,30856,30892,31030,10467,10518,10498,10465,10518,10467,555,512,631,479,512,555,35383,35337,35276,39055,39110,38911,39478,39536,39572,918,678,1168,5769,5756,5830,6885,6975,7061,29646,29780,29748,29424,29509,29386,35498,35421,35425,35554,35421,35498,35128,34849,34928,39456,39426,39310,40009,40171,40109,39456,39310,39292,43639,43551,43665,27801,27588,27552,1725,2433,2100,2625,2508,2603,2184,2281,2427,2103,2194,2113,2956,3499,3014,2883,2951,2941,31578,31312,31197,32248,32056,32126,32069,32056,32262,39832,39594,39532,10610,10716,10754,42308,42426,42214,42413,42188,42405,2281,2194,2336,2508,2551,2579,8605,8777,8559,10562,10031,10561,9856,10253,9890,9187,9201,9545,8668,8660,8865,32641,32801,32554,33409,33370,33118,40957,40689,40513,4312,4111,4424,3789,3666,3828,4312,4424,4444,6204,6661,6689,6605,7018,7058,6089,5973,6041,42729,42600,42659,43088,42793,42981,9705,9619,9737,9812,9705,9910,41698,41137,40989,10774,10872,10916,14475,14392,14437,14508,14392,14475,14843,14645,14871,27155,27317,27097,28575,28926,28747,29261,29228,29127,29780,29646,29795,27370,27317,27346,4111,3999,4253,36205,36227,36133,39923,39832,39532,32553,32507,32626,32553,32626,32788,33908,33795,33913,33908,33913,33929,33079,32898,32834,41613,41402,41509,41509,41402,41358,40617,40083,40609,41655,41509,41581,37705,37929,37517,37841,37814,37705,38210,38379,38303,39536,39494,39735,41210,40964,41171,40171,40223,40109,40546,40957,40513,40171,40009,40020,39572,39735,39550,43867,43905,43766,43746,43726,43636,43802,43726,43838,29852,29780,30003,30003,29780,29795,30743,30619,30822,41918,41255,42558,42729,42659,42786,678,634,671,570,634,546,9756,10013,9707,12520,12701,12672,13408,13504,13678,42861,42800,42732,4981,5076,5179,4111,3961,3999,5515,5434,5351,5549,5434,5515,5287,5434,5549,5646,5666,5756,5646,5756,5769,13559,13408,13678,43675,43154,42865,43580,43572,43480,43027,42827,42779,8556,8660,8668,7699,7582,7280,4119,4069,4020,2751,2883,2469,6089,6178,6179,34305,34523,34346,34374,34523,34305,36099,36205,36133,35899,35838,36024,43432,43160,43430,43074,43088,42981,42896,42861,42754,43432,43430,43590,27932,27937,27823,40,5,116,43480,43572,43359,43487,43355,43512,1949,1725,2100,41402,41310,41252,38210,38360,38379,7185,7184,7362,6189,6661,6204,34815,34786,34971,36399,36531,36515,27430,27663,27445,512,361,431,445,479,555,6552,6818,6343,8134,8275,8045,6728,6805,6680,39478,39553,39055,38321,38303,38379,39669,40051,40185,36024,36076,36174,36024,35838,35852,39832,39902,39811,40024,39902,39832,1258,1336,1483,596,634,678,1258,1483,1335,1483,1431,1335,10716,10774,10916,10518,10610,10754,9334,9519,9401,31578,31198,31741,31578,31741,31791,38360,38853,38379,9120,9152,9201,8668,8865,8723,9869,10013,9803,27317,27345,27262,27370,27345,27317,31861,31917,31849,30533,30426,30631,41310,41270,41163,43590,43430,43529,43540,43487,43512,10253,10465,10467,642,461,834,2382,2487,2489,523,526,407,12672,12701,13260,12248,12289,11969,2194,2005,2286,2625,2824,2811,2489,2487,3137,2452,2416,2143,11304,11507,11328,11328,11507,11587,12764,13175,12917,11304,11274,11039,15662,15441,15924,33445,33293,33391,34026,33913,34093,34093,34132,34259,2719,2625,2811,2795,2893,2981,31816,31917,31861,41395,41219,41270,41449,41270,41310,41672,41731,41918,6661,6728,6680,6515,6728,6661,35645,35554,35559,35657,35554,35645,43676,43556,43636,43676,43636,43726,1044,1046,1159,6811,6812,6860,10560,10610,10518,31214,30933,31039,30631,30426,30651,16067,15662,15924,26024,25916,25963,26440,25916,26024,41672,41655,41581,2731,2795,2843,34928,34849,34586,34431,34233,34313,35852,35732,35900,10719,10774,10716,2731,2719,2795,4981,5179,5020,4332,4119,4171,5039,4957,5485,5961,6089,6081,4119,4020,4171,41219,41210,41171,41219,41171,41270,419,361,512,43316,43163,43081,43316,43081,43286,6989,7184,7018,7018,7184,7185,8301,8231,8559,12682,12672,12936,13801,13651,14075,13801,14075,13916,27563,27440,27588,27588,27440,27385,28137,28299,28464,28544,28463,28551,34928,34586,34801,40881,41049,40802,41049,40957,40977,40957,41170,40977,11507,11696,11645,11704,11696,11507,29780,29852,29909,29286,29314,29228,43811,43552,43832,43811,43340,43552,28871,29026,29153,43181,43088,43074,42786,42659,42702,30164,30426,30213,42413,42379,42308,42426,42379,42457,27753,27778,27663,27663,27778,27823,30044,29909,29852,34815,35390,34763,39902,40037,39883,40024,40037,39902,4069,3952,4020,6885,6811,6860,6885,7061,6955,39292,39310,39118,39426,39587,39532,39106,38651,37953,32956,33079,32834,33660,33782,33544,31917,32413,31944,723,487,248,12520,12382,12248,12672,13260,12936,29153,29026,29173,15330,15231,15283,15254,15231,15330,43639,43634,43529,43802,43676,43726,27563,27588,27620,27345,27430,27445,27370,27430,27345,4069,3936,3952,6205,6596,6148,36483,37294,36513,37735,37917,37793,37793,37917,37945,37945,38062,37953,36298,36498,36338,36329,36498,36298,36329,36298,36205,36329,36205,36190,7644,7557,7374,10562,10465,10031,14812,14843,14940,33908,33752,33637,34259,34132,34287,43456,43374,43254,43665,43634,43639,2103,2005,2194,1335,1431,1395,32956,32834,32801,2508,2459,2527,2316,2459,2372,2459,2508,2372,33842,33752,33908,33800,33782,33660,2795,2719,2811,3666,3789,3677,7374,7557,7400,7184,7270,7362,7073,7270,7184,3794,4019,3999,32413,32641,32554,634,570,671,479,419,512,596,678,469,8660,8556,8505,9187,9545,9280,12644,12382,12520,43014,42861,42896,41255,41930,42558,6148,6596,6552,6955,7061,7077,3952,3936,3862,5900,5964,5881,37168,37216,36938,14569,14508,14645,43487,43580,43480,43540,43580,43487,10941,11151,10872,29127,28942,29261,30044,30164,29909,42520,42578,42214,43154,43354,43071,34692,34579,34469,34741,34579,34692,35733,35421,35554,1072,1044,1300,1046,1040,1048,1431,1560,1395,31791,31741,32056,31312,31214,31197,31791,32056,32069,4180,4215,4177,4180,4298,4215,4344,4569,4298,4610,4957,5039,30948,30885,30933,31531,31214,31312,1395,1560,1290,32056,32248,32262,32459,32514,32413,32669,32801,32641,31671,31816,31861,31624,31671,31298,31121,31005,31030,30892,30856,30822,300,431,361,300,255,431,13615,13559,13678,12672,12644,12520,13675,13559,13615,27620,27588,27801,28464,28299,28463,28464,28463,28544,13566,13751,13821,14232,14068,13972,12632,12525,12374,12632,12374,12457,1072,1300,1206,10774,10941,10872,10719,10806,10774,10465,10560,10518,10562,10560,10465,9334,9221,8899,1257,1395,1290,2184,2194,2281,40957,41049,40881,42413,42308,42188,40572,40267,40394,37993,37917,38040,1949,2100,2005,4177,4215,4171,3862,3918,3803,6178,6155,6204,6913,6989,7018,6041,5973,6085,9120,9187,9185,9869,9812,9910,9869,9910,10013,13916,14075,14127,36190,36205,36099,37524,37030,37043,36190,36099,36174,40290,40127,40280,41563,41310,41402,41613,41563,41402,41731,41672,41581,42729,42566,42600,43456,43254,43432,43222,43014,43088,43088,43014,42811,3666,3602,3773,3551,3602,3666,36111,35715,35665,445,419,479,248,487,127,5434,5287,5351,5549,5515,5638,5549,5638,5569,5638,5646,5569,486,445,555,546,469,495,43797,43473,43572,962,1040,1046,30924,30885,30963,31007,30892,30867,14232,13972,13839,26465,26926,26572,6148,6552,6207,8045,8275,8349,26969,26440,27385,27620,27801,27704,34627,34586,34523,35128,35307,35276,34497,34523,34374,35331,35307,35465,39572,39550,39478,40185,40051,40127,40185,40127,40290,40394,40267,40223,39520,39587,39426,39520,39426,39456,33293,33260,33391,34026,33929,33913,34168,33929,34026,40171,40020,40037,34433,34259,34287,8556,8435,8505,8284,8435,8502,10806,10941,10774,11728,11696,11704,11728,11738,11696,42786,42702,42953,43181,43074,43163,3990,4171,4020,3952,3862,3803,6089,6155,6178,6041,6155,6089,36720,36513,37294,36174,36099,36024,1911,1949,2005,33391,33637,33726,33079,33409,33118,32944,32956,32801,32944,32801,32750,5569,5646,5710,37814,37929,37705,38112,38028,37947,38303,38321,38105,38360,38505,38853,33906,33926,33782,34431,34497,34374,35715,35657,35645,34579,34433,34287,35737,35657,35715,39202,39292,39118,39202,39118,39088,40617,40609,41217,22,57,213,2316,2184,2427,2103,2012,2005,2113,2184,2076,8723,8865,8975,33252,33409,33079,10941,11039,11151,42379,42426,42308,42917,42621,42363,42188,42417,42405,11704,11507,11300,42702,42800,42953,5830,5900,5865,5769,5830,5865,38343,38379,38853,3677,3455,3429,3961,3794,3999,12162,12293,12337,29424,29286,29261,31007,31030,30892,27932,27823,27778,27932,27778,27753,36399,36111,35646,36260,36111,36399,42917,42363,42771,32788,32626,32821,7073,6989,6913,7270,7374,7400,39550,39553,39478,40271,39735,39494,43676,43665,43551,43535,43456,43432,43805,43665,43676,255,231,392,118,300,361,266,361,419,43482,43316,43286,43482,43286,43374,3448,3563,3602,3348,3499,3563,2719,2602,2625,7254,7374,7270,8070,8231,8101,34815,34971,35390,39923,40024,39832,39731,39532,39587,13801,13708,13615,12936,13260,13408,13875,13708,13801,27753,27663,27566,28645,28464,28544,27704,27801,27808,28645,28544,28814,43307,43181,43163,42953,42800,42861,43904,43354,43854,43580,43602,43572,30641,30151,30585,2113,2012,2103,1258,1335,1183,43905,43907,43498,39292,39472,39456,39508,39472,39292,486,555,570,8101,8231,8301,8070,8101,7857,26969,27385,27440,27801,28024,27808,33929,33842,33908,33965,33842,33929,34168,34093,34259,33800,33906,33782,34286,34168,34259,41253,40964,41210,3940,4020,3952,5865,5900,5881,11728,11962,12021,11808,11962,11728,42953,42861,43127,41613,41655,41708,1089,1072,1206,1044,962,1046,1040,791,918,410,486,570,1169,1206,1258,1169,1258,1237,1258,1183,1237,2843,2795,2981,2184,2113,2194,31007,31121,31030,31816,31873,31917,30822,30631,30685,34525,34433,34579,34497,34627,34523,35465,35307,35474,34313,34233,33926,39820,39710,39735,40369,40290,40459,9444,9545,9619,9187,9120,9201,9753,9869,9803,31999,31873,31816,30003,30044,29852,546,634,596,1043,962,1044,6807,6811,6885,12632,12764,12917,13751,13972,13821,12351,12457,12374,12351,12374,12293,27346,27317,27155,30822,30619,30631,43055,43027,42779,43055,42779,42939,43512,43355,43315,31791,31903,31578,30963,30948,31313,30924,30641,30885,30885,30641,30585,32262,32248,32393,6804,6807,6885,6804,6885,6955,39508,39520,39472,39472,39520,39456,9598,9619,9812,2316,2427,2459,1335,1257,1183,32909,32788,32821,32389,32262,32393,33726,33637,33752,34815,34741,34692,34763,34741,34815,41082,40977,41170,41049,41052,40802,41052,40977,41082,10719,10716,10610,10941,10713,11039,11300,11507,11304,10562,10610,10560,30651,30426,30452,42592,42363,42578,41859,41682,41526,9753,9598,9812,32389,32393,32561,5945,5881,5964,546,596,469,11962,12162,12337,12115,12162,11962,14843,14569,14645,14205,14192,14392,14602,14569,14843,14812,14940,15231,29286,29424,29386,28624,28575,28516,42520,42214,42426,43627,43602,43580,11300,11304,11281,28151,28342,28183,28052,27937,27932,27908,28052,27932,30232,30132,29886,30885,30948,30963,30452,30426,30164,30631,30651,30685,9598,9444,9619,41613,41509,41655,41219,41395,41210,41655,41672,41708,8899,9221,8777,8141,8070,7941,28342,28624,28516,3677,3551,3666,2956,2843,2981,3677,3789,3794,39286,39202,39374,2372,2508,2265,2469,2883,2941,3990,3940,3843,1211,1882,1423,903,834,267,642,562,461,3803,3940,3952,3918,2750,3803,5020,5179,5258,5020,5258,5287,4866,4840,4982,5372,5549,5569,5710,5646,5769,5710,5769,5865,8435,8284,8349,8502,8435,8556,8607,8556,8668,34261,34313,33926,33409,33800,33660,33917,33800,33836,33117,33079,32956,14205,14392,14278,12936,13408,12972,27633,27440,27563,27808,28024,28074,27566,27663,27430,43590,43529,43634,43307,43222,43181,43143,42861,43014,7582,7699,7872,7374,7312,7857,7073,7254,7270,7073,7184,6989,33150,33010,32930,35307,35331,35383,35307,35128,35474,34627,34497,34431,39710,39553,39550,39710,39550,39735,12382,12289,12248,13675,13615,13708,12457,12764,12632,12425,12764,12457,30641,30356,30151,28074,28024,28137,38112,37947,38105,38112,38105,38181,38105,38248,38181,37917,37993,37945,36345,36498,36329,42660,42520,42633,8571,8607,8668,8884,9152,9120,8899,8777,8605,15662,15254,15330,27633,27563,27620,41489,41449,41310,43845,43590,43634,43838,43726,43746,5,68,320,14127,14205,14241,14278,14392,14508,14289,14232,13839,2265,2508,2625,2781,2843,2956,34744,34627,34431,40024,40171,40037,40073,40171,40024,39731,39587,39676,4753,4553,5076,38105,38321,38248,37993,38062,37945,6155,6189,6204,6089,5901,5973,15254,14812,15231,43832,43828,43811,43811,43828,43340,38248,38321,38343,12115,12351,12162,12162,12351,12293,29054,29261,28942,30273,30164,30044,42994,43055,42939,43027,43263,42865,43354,43512,43315,43540,43627,43580,42994,42939,42917,1072,1043,1044,469,678,918,1725,1949,1879,1911,2005,2012,370,562,523,31069,31121,31007,31398,31405,31121,31121,31405,31298,32514,32641,32413,30867,30892,30822,31405,31624,31298,11281,11304,11039,11704,11808,11728,30356,30132,30232,42520,42592,42578,38343,38321,38379,40977,41052,41049,40957,40546,40795,1169,1089,1206,6679,6812,6811,7280,6936,7077,6804,6936,6889,32836,32788,32909,38331,38343,38471,40271,39494,40185,39676,39587,39520,41449,41395,41270,43845,43634,43665,5853,5710,5865,6679,6811,6807,6041,6189,6155,36190,36345,36329,36076,36024,36012,1038,1043,1072,11272,11281,11122,10635,10562,10561,41854,41859,41526,42413,42457,42379,42520,42660,42592,4319,4298,4248,4319,4344,4298,6089,5961,5901,6041,6085,6189,39166,39110,39224,33753,33726,33752,33293,33150,32930,33010,32836,32909,34168,33965,33929,33989,33965,34171,34462,34259,34433,118,231,300,300,231,255,325,419,445,325,445,263,28342,28400,28624,28926,29054,28747,28052,28151,28183,28006,28151,28052,40326,40394,40223,40326,40223,40171,10562,10719,10610,31531,31312,31578,30433,30279,30356,30356,30279,30132,31903,31791,32069,32194,32069,32262,30685,30651,30659,30685,30867,30822,32282,32194,32262,42299,41803,41682,33881,33752,33842,13854,13875,13916,13916,13875,13801,14127,14075,14205,42786,42898,42729,43222,43088,43181,263,445,486,495,570,546,12682,12644,12672,12972,13408,13559,43307,43163,43349,43163,43316,43349,43802,43805,43676,43838,43805,43802,34593,34525,34579,34691,34579,34741,35144,34863,34830,40290,40241,40185,40369,40241,40290,40271,40241,40369,37294,36483,36498,36012,36024,35852,32413,31917,32459,30452,30164,30273,32561,32393,32553,41563,41489,41310,41449,41481,41395,42420,42566,43029,42422,42457,42413,14278,14508,14569,28103,28191,28151,27370,27566,27430,27346,27566,27370,43640,43512,43737,43851,43797,43572,2113,1911,2012,2032,2076,2184,2032,2184,2316,5853,5865,5881,407,370,523,273,370,407,12705,12644,12682,29646,29509,29795,29074,29054,29027,6913,7018,6605,7254,7259,7374,35737,35554,35657,6804,6679,6807,5945,5853,5881,6804,6955,6936,29280,29424,29261,32645,32561,32553,32671,32553,32788,32688,32514,32487,39635,39508,39292,39731,39923,39532,39286,39292,39202,41647,41489,41563,41395,41253,41210,3915,4177,4171,3990,4020,3940,3551,3509,3602,3961,4111,4312,36345,36190,36174,35900,35732,35877,35337,35723,35732,43640,43627,43540,11662,11808,11704,11662,11704,11470,29373,29813,29629,30132,29813,29886,43055,43090,43027,43128,42994,42917,42771,42363,42592,1844,1911,2113,8607,8502,8556,8284,8045,8349,8881,8884,9120,8241,8559,8231,10635,10719,10562,8141,8231,8070,33312,33150,33293,1796,1879,1911,2602,2719,2731,2602,2731,2843,33726,33445,33391,33965,33881,33842,33989,33881,33965,34462,34433,34525,5945,5964,5960,36938,37216,37406,36039,35737,35715,43832,43797,43851,2768,2602,2843,9444,9280,9545,9186,9280,9258,9537,9444,9598,9753,9812,9869,28151,28191,28342,27908,27932,27753,32724,32671,32788,32514,32669,32641,34476,34462,34525,82,487,320,43198,43143,43014,43482,43374,43544,8571,8502,8607,27838,27908,27753,39903,39923,39731,36345,36174,36259,35337,35383,35723,1089,1038,1072,917,1038,1089,1237,1057,1169,1257,1335,1395,14812,14602,14843,14748,14602,14812,3585,3026,2750,5960,5964,6148,32189,31903,32069,32189,32069,32194,32189,32194,32282,32522,32389,32561,43029,42566,42729,41613,41647,41563,946,1040,962,1057,1089,1169,42633,42520,42426,42405,42422,42413,42117,42299,41682,34763,34691,34741,34830,34691,34763,9636,9753,9621,8884,8723,8975,8815,8723,8884,30924,30939,30641,31313,30948,31214,30867,31018,31007,31405,31568,31624,31900,31999,31816,32688,32750,32669,31062,31018,30867,31069,31018,31062,41052,41218,40802,42339,42374,42299,40795,40546,40572,40795,40572,40655,42299,42417,42188,4981,4753,5076,3420,3509,3677,5020,4866,4982,4981,5020,4982,5610,5710,5853,32671,32645,32553,32953,32836,33010,32724,32836,32874,36174,36076,36249,37993,38225,38062,39527,39286,39436,38028,37929,37814,38093,37929,38028,38213,38028,38112,38213,38112,38181,38213,38181,38282,29373,29026,29568,29373,29568,29813,29054,29074,29261,31069,31007,31018,28926,28575,28624,42953,42898,42786,43198,43014,43222,37999,37917,37735,5945,5805,5853,6037,5960,6148,36249,36076,36012,3677,3509,3551,3448,3509,3420,9753,9590,9598,8469,8571,8549,13713,13675,13875,13875,13675,13708,12936,12705,12682,14292,14278,14569,14232,14289,14522,13751,13566,13301,13039,13175,12764,13039,12764,12801,27838,28006,27908,26926,27346,27155,35723,35383,35331,36096,36249,36012,39508,39676,39520,38404,37953,38062,41948,41708,41672,41360,41253,41508,43851,43572,43602,43512,43640,43540,43709,43640,43737,8469,8284,8502,8444,8045,8284,7073,7259,7254,6924,7259,7073,43707,43432,43590,43544,43374,43456,43907,43838,43746,39710,39762,39553,38282,38181,38248,39820,39762,39710,39923,40073,40024,39635,39676,39508,38282,38248,38331,33881,33753,33752,34462,34286,34259,34390,34286,34462,33917,33926,33906,35465,35723,35331,33917,33906,33800,33252,33079,33117,33861,33753,33881,1911,1879,1949,2032,2113,2076,2751,3026,2883,5878,5805,5945,6207,6037,6148,6362,6515,6661,5961,5723,5901,11808,11892,11962,11756,11662,11565,36547,36260,36399,36217,36260,36364,38331,38248,38343,41481,41449,41489,39820,39687,39762,41333,41218,41052,946,962,1043,325,266,419,29292,29373,29556,7535,7582,7872,6254,6207,6552,13854,13916,13923,28680,28926,28624,27908,28006,28052,27838,27753,27566,34691,34593,34579,34804,34593,34691,43535,43707,43633,43307,43258,43222,8723,8571,8668,8815,8884,8881,33867,33445,33726,3509,3448,3602,3961,4312,3838,6121,6661,6189,36013,35715,36111,36096,36012,35900,34801,34586,34627,174,266,325,231,22,392,12236,12457,12351,39040,38506,39110,32652,32645,32671,32724,32788,32836,31,22,231,43544,43535,43633,42633,42426,42457,4344,4610,5039,4248,4298,4180,4248,4180,4177,4248,4177,4095,37739,36938,37406,6085,6121,6189,6090,6121,6085,9803,10013,9756,12776,12705,12936,30659,30651,30452,28400,28342,28191,35903,35900,35877,37768,37867,37524,6605,7058,6728,7259,7359,7374,7257,7359,7259,39988,40073,39923,41433,41335,41403,9185,9187,9280,11756,11892,11808,33117,32956,32944,32750,32801,32669,42993,42898,42953,42993,42953,43127,3915,4171,3990,31398,31568,31405,991,1057,1237,1038,946,1043,994,1057,991,31255,31398,31121,31255,31121,31069,9186,9185,9280,32652,32724,32894,32688,32669,32514,3448,3348,3563,3285,3348,3448,6514,6605,6515,6515,6605,6728,495,410,570,371,410,495,7645,8070,7857,28619,28137,28464,27704,27633,27620,29373,29173,29026,29292,29173,29373,30867,30685,30659,33452,33293,33445,32652,32671,32724,34193,33965,34168,34193,34168,34286,34744,34801,34627,33836,33800,33409,42994,43090,43055,43128,43090,42994,34390,34193,34286,42660,42771,42592,1290,1560,1725,5878,5945,5960,6818,6812,6343,39224,39055,39603,917,946,1038,29509,29424,29795,42417,42422,42405,42660,42698,42771,42299,42374,42417,42117,41682,41859,34593,34476,34525,34529,34476,34593,9590,9537,9598,9753,9636,9590,12289,12382,12644,30946,30939,30963,32282,32262,32389,32522,32561,32645,30963,30939,30924,31531,31672,31635,42503,42422,42417,28006,28103,28151,27838,28103,28006,28240,28400,28191,43494,43349,43316,43494,43316,43482,43548,43494,43482,43544,43456,43535,41218,41335,40861,41335,41218,41333,370,461,562,32,461,370,11966,12115,11962,9535,9537,9590,41708,41727,41613,41862,41727,41963,41948,41672,41918,5878,5960,5999,6343,6812,6679,29795,29424,29430,29027,29054,28926,36217,36013,36111,35390,35050,35421,36217,36111,36260,38384,38282,38331,39603,39055,39553,248,273,407,233,273,248,2265,2258,2372,2372,2258,2316,2778,2781,2956,12648,12609,12705,14034,13916,14127,13713,13854,13780,29104,28890,29153,34804,34830,34863,34744,34431,34569,43370,43258,43307,43548,43544,43658,30643,30659,30452,43797,43832,43552,43709,43602,43627,43709,43627,43640,4380,4620,4553,3843,3915,3990,3843,3940,3803,5960,6037,5999,12705,12609,12644,12972,13253,13009,29130,29027,28926,43258,43198,43222,32635,32522,32645,32836,32953,32874,41727,41647,41613,14292,14241,14278,15254,14748,14812,27386,26969,27440,42529,42633,42457,43175,43128,42917,2265,2285,2175,1161,1290,1725,8141,8241,8231,10253,10031,10465,8360,8241,7941,8621,8571,8723,8571,8469,8502,8045,7535,7872,9000,8881,9120,8838,8881,8875,33763,33836,33409,33043,33117,32944,33043,32944,32750,34261,34569,34313,33343,33409,33252,6121,6362,6661,6924,7073,6913,7124,7257,7259,6002,6362,6121,38086,37999,38006,35916,35903,35877,35916,35877,35723,33312,33293,33383,34193,34171,33965,34476,34390,34462,34529,34390,34476,3832,3843,3803,5773,5878,5815,40073,40245,40171,39903,39988,39923,39804,39731,39676,4982,4862,4981,5287,5549,5372,5569,5710,5610,5610,5853,5773,11892,11966,11962,11662,11756,11808,11470,11704,11300,10941,10806,10713,10806,10719,10635,30207,30273,30044,29280,29261,29074,6889,6936,7280,5773,5805,5878,6343,6410,6342,35474,35419,35482,39762,39687,39553,40271,40185,40241,40280,40459,40290,8727,8723,8815,12609,12289,12644,29173,29104,29153,29556,29373,29629,33445,33602,33452,32459,31917,32124,38040,38225,37993,40222,40080,40243,38006,37999,37735,36259,36174,36249,41647,41481,41489,43737,43904,43760,2781,2768,2843,2742,2768,2781,35548,35474,35482,34569,34431,34313,40369,40459,40334,40222,40245,40073,9945,10031,10253,30207,30044,30003,38086,38225,38040,30433,30356,30462,31531,31578,31672,31996,31903,32189,32282,32389,32355,5961,5467,5723,42151,42117,41859,42374,42503,42417,42422,42529,42457,28400,28547,28624,28103,28240,28191,28325,28240,28103,31531,31313,31214,31278,31338,31255,31255,31338,31398,31398,31642,31568,32124,31917,31873,31278,31255,31069,31278,31069,31062,37929,37802,37517,38213,38324,38028,38282,38241,38213,38384,38241,38282,38384,38331,38471,68,82,320,13854,13713,13875,12609,12521,12289,14034,14127,14091,13301,13566,13277,13839,13751,13301,12104,12351,12115,377,469,331,994,917,1089,994,1089,1057,8838,8727,8815,8838,8815,8881,33726,33753,33861,32472,32389,32522,32953,33010,33019,41508,41395,41481,41727,41862,41647,42654,41948,41918,337,263,486,266,118,361,852,1040,946,4333,4380,4553,11756,11966,11892,12104,11966,11988,39040,39110,39166,38225,38404,38062,43127,42861,43143,42898,43029,42729,9519,9334,9342,31151,30946,30963,42425,42503,42374,7359,7312,7374,6924,6913,6829,14241,14205,14278,27808,27633,27704,27741,27633,27808,39988,40080,40073,39635,39292,39527,6362,6514,6515,5973,6090,6085,36096,36259,36249,36096,35900,35903,39304,39040,39166,39304,39166,39224,11281,11470,11300,11272,11470,11281,32472,32522,32602,29292,29104,29173,29068,29104,29292,42519,42529,42422,43175,42917,43180,6541,6514,6443,32635,32645,32652,32798,33043,32750,31816,31624,31900,39820,39684,39687,41217,40609,41253,40245,40326,40171,40441,40326,40245,34152,33917,33836,32798,32750,32688,36013,36039,35715,34861,34529,34593,36547,36399,36515,36547,36515,36783,2210,2032,2316,1109,1237,1183,2210,2316,2258,33019,33010,33150,32802,32635,32652,33861,33881,33989,30455,30643,30452,30455,30452,30273,29795,29840,30003,29993,29840,29795,30011,29840,29993,4152,4095,4083,4083,4095,4177,4248,4152,4319,4144,4610,4344,5973,5879,6090,5773,5853,5805,6037,6207,5999,469,371,495,377,371,469,6541,6913,6605,43184,43127,43143,42993,43086,42898,43184,43143,43198,43393,43198,43258,43370,43307,43349,43454,43349,43494,43737,43512,43904,42698,42660,42633,32894,32724,32874,7257,7312,7359,7207,7312,7257,159,118,266,43544,43548,43482,43535,43432,43707,273,234,370,127,233,248,12972,13559,13253,13559,13675,13253,28498,28547,28400,39527,39292,39286,40080,40222,40073,43488,43370,43349,36217,36077,36013,36172,36077,36217,42746,42698,42633,8727,8621,8723,7617,7535,8045,9000,9120,9185,14034,13923,13916,14091,13923,14034,43845,43665,43805,337,486,410,2265,2625,2285,40655,40572,40394,42343,42299,42117,9258,9280,9444,9258,9444,9351,9535,9590,9636,32767,32798,32688,31526,31642,31398,32459,32487,32514,31526,31398,31338,1170,1183,1257,917,852,946,5999,6207,6118,30279,29813,30132,31313,31151,30963,31531,31396,31313,31635,31396,31531,31996,32189,32182,32189,32282,32182,39040,38853,38505,38519,38724,38532,39684,39553,39687,34804,34691,34830,34390,34529,34193,31062,30867,30863,42343,42339,42299,42503,42519,42422,42617,42746,42633,41698,40989,41335,11516,11690,11331,32182,32282,32355,31900,31624,31568,14292,14569,14602,43709,43778,43602,43263,43027,43090,30776,30867,30659,30011,30207,30003,30011,30003,29840,36077,36039,36013,36093,36039,36077,371,337,410,282,337,371,43127,43086,42993,43297,43184,43198,897,852,917,11122,11281,11039,9238,9334,8886,30776,30659,30643,39820,39735,40028,42339,42425,42374,43838,43845,43805,1653,1725,1879,32355,32389,32472,36968,36515,36938,2335,2941,2487,3843,3912,3915,2335,2487,2287,35733,35554,35737,32602,32355,32472,33318,33150,33312,33383,33293,33452,41170,41052,41082,8714,8621,8727,8714,8727,8838,33476,33383,33452,40795,41170,40957,4862,4844,4981,4840,4844,4862,4840,4862,4982,5372,5569,5535,8820,8714,8838,9585,9535,9636,32602,32522,32635,37881,37802,37929,38324,38213,38241,38324,38241,38337,41698,41854,41526,4844,4753,4981,233,234,273,82,127,487,28240,28375,28400,29280,29074,29227,28325,28375,28240,43297,43155,43184,43564,43454,43494,43488,43454,43614,43494,43643,43564,3746,3539,3648,6443,6514,6362,6923,7124,6924,4985,5485,4957,11966,12104,12115,11988,11966,11756,11988,11756,11683,30565,30462,30356,28814,28544,28890,39374,39202,39088,38225,38304,38404,37999,38086,38040,38006,37735,37867,3014,2778,2956,2175,2210,2265,3342,3420,3429,3420,3677,3429,4330,4312,4380,6410,6343,6679,6889,7280,7582,35825,35916,35723,37867,37735,37524,35825,35723,35706,28680,28624,28547,30441,30455,30273,217,174,325,217,325,263,2287,2487,2382,28814,28890,28893,28669,28680,28547,34529,34171,34193,34018,34171,34021,13829,13780,13923,13923,13780,13854,13301,13277,13039,13751,13839,13972,27346,27838,27566,41433,41698,41335,7312,7544,7857,6924,7124,7259,7207,7124,7097,963,1220,1161,2265,2210,2258,2659,2602,2768,738,2143,2416,1986,2211,2335,34018,33861,33989,33917,34152,34261,33926,33917,34261,34941,34801,34744,35596,35474,35548,39684,39603,39553,40306,39735,40271,39635,39804,39676,40658,40655,40394,39672,39804,39635,38337,38241,38384,41508,41253,41395,40369,40334,40271,41765,41481,41647,41433,41792,41698,41350,41333,41052,6118,6207,6254,5535,5569,5610,36039,35793,35737,36547,36364,36260,36172,36694,36229,14241,14091,14127,14292,14091,14241,30441,30273,30207,43175,43195,43128,42617,42633,42529,40459,40280,40963,9351,9444,9537,8886,9334,8899,8605,8559,8241,35960,35793,36039,35706,35723,35465,35916,36096,35903,39374,39088,39106,4333,4330,4380,5535,5610,5454,38337,38471,38509,38853,38471,38343,12104,12236,12351,12010,12236,12104,29130,29074,29027,30819,30643,30678,43184,43155,43127,43393,43258,43370,43128,43195,43090,42917,42771,43180,31368,31338,31278,31368,31526,31338,31830,31900,31568,31999,32124,31873,31368,31278,31311,43737,43778,43709,43760,43778,43737,8444,8284,8469,9000,9185,9186,11122,11039,10713,30641,30565,30356,33383,33318,33312,32953,32894,32874,33476,33318,33383,41360,41217,41253,808,791,852,1167,1170,1257,1220,1257,1290,3014,3499,3348,7124,7207,7257,6541,6605,6514,31830,31568,31642,42339,42482,42425,42425,42519,42503,42482,42343,42451,42151,41859,41854,33042,32894,32953,1930,2113,2032,4095,4152,4248,4083,4177,3915,5454,5610,5773,32182,32120,31996,31672,31578,31878,30641,30682,30565,32143,32120,32182,31996,32120,32143,32009,32124,31999,159,31,118,118,31,231,2143,2287,2382,2335,2469,2941,3323,3285,3448,3342,3448,3420,6002,6121,6090,28375,28498,28400,29063,29130,28926,28325,28498,28375,35793,35733,35737,34140,34171,34214,35864,35733,35793,35596,35706,35465,36040,36096,35916,39777,39603,39684,39802,39684,39820,39527,39590,39635,40243,40080,40260,39718,39590,39664,43454,43488,43349,43658,43544,43633,43798,43658,43633,852,791,1040,219,217,263,174,159,266,928,917,994,5999,5898,5878,6137,6118,6254,6342,6254,6343,9621,9585,9636,9535,9351,9537,9011,9000,9186,9621,9753,9803,9621,9803,9756,36364,36172,36217,36093,36172,36229,42612,42519,42425,43298,43263,43195,219,263,282,112,234,233,141,978,1211,331,469,284,11454,11662,11470,12972,12776,12936,13009,12776,12972,12648,12776,12569,12624,12801,12764,12425,12457,12236,28619,28074,28137,28893,28890,29104,29068,29292,29422,29648,29629,29813,43150,43086,43127,43150,43127,43155,43581,43393,43370,3912,4083,3915,3912,3843,3832,8549,8571,8621,33252,33117,33336,35474,35596,35465,33117,33043,33336,39887,39802,39820,40963,40280,40617,11272,11454,11470,43778,43851,43602,43888,43707,43590,8875,9000,9011,8624,8549,8621,32143,32182,32355,33100,33019,33150,41333,41403,41335,41698,41786,41854,41350,41403,41333,41350,41052,41170,41377,41170,41245,30819,30776,30643,30441,30207,30290,41963,41727,41708,41551,41444,41217,41963,41708,41948,41888,41786,41792,42682,42617,42529,6829,6923,6924,1917,1930,2032,1844,1930,1814,8624,8621,8714,8360,8605,8241,7544,7312,7142,33318,33100,33150,33602,33476,33452,33867,33726,33861,34018,33989,34171,12648,12521,12609,29422,29292,29556,29280,29430,29424,29227,29130,29088,2778,2742,2781,2704,2742,2778,39903,39731,39804,39590,39672,39635,39718,39672,39590,36040,35916,35825,39106,37953,38404,13829,13713,13780,14748,14292,14602,27633,27386,27440,27741,27386,27633,9405,9351,9535,9238,9342,9334,10713,10806,10635,11272,11263,11454,9241,9342,9238,3903,3912,3746,29467,29422,29556,29467,29556,29629,29227,29430,29280,1844,1796,1911,8605,8832,8899,33336,33043,33333,40562,40394,40326,41792,41786,41698,41377,41350,41170,34861,34593,34804,43488,43581,43370,43423,43297,43198,43643,43494,43548,43643,43548,43658,6005,5898,5999,6410,6679,6361,6923,6994,7124,6962,6994,6923,90,159,174,90,174,217,127,112,233,49,112,127,10496,10635,10561,12010,12104,11988,28619,28464,28645,28787,28645,28814,28893,29104,29068,29782,29648,29813,31374,31313,31396,30214,30207,30011,35706,35888,35825,35128,35419,35474,34668,34744,34569,37175,36968,37988,37978,37881,37929,37978,37929,38093,38028,38324,38093,40306,40271,40334,38509,38471,38519,4169,4152,4023,4169,4319,4152,4144,4344,4319,38337,38384,38471,38086,38186,38225,36498,36982,37294,9945,10253,9856,31578,31903,31878,31903,31996,31878,1170,1109,1183,1167,1109,1170,1167,1257,1220,9829,9945,9856,32124,32487,32459,31900,32009,31999,31744,31830,31642,31744,31642,31526,31278,31210,31311,991,928,994,331,322,377,31635,31374,31396,30863,30867,30776,282,371,322,282,263,337,12776,12648,12705,9756,9707,9666,13675,13380,13253,28074,27741,27808,29011,28893,29068,2742,2659,2768,1930,1844,2113,2601,2659,2742,34863,34861,34804,40527,40306,40334,40424,40306,40527,963,1167,1220,31830,32009,31900,38006,38186,38086,928,897,917,42519,42682,42529,42343,42482,42339,42451,42343,42117,29258,29011,29068,29782,29813,29911,38186,38304,38225,6005,5999,6118,5901,5879,5973,6541,6829,6913,5784,5879,5901,38709,39106,38404,39810,39804,39672,9474,9405,9535,9585,9548,9474,1796,1653,1879,1917,2032,2210,8549,8444,8469,8820,8624,8714,8875,8881,9000,9186,9258,9112,10072,10496,10561,30819,30863,30776,30094,30214,30011,40527,40334,40459,41611,41508,41481,2754,2704,2778,3677,3794,3455,6304,6410,6361,6083,6005,6118,35144,34830,34763,36093,35960,36039,36093,36077,36172,322,371,377,3392,3429,3455,4357,4333,4553,4357,4553,4753,4686,4753,4844,5020,5008,4866,5400,5372,5535,12954,13301,13039,12251,12425,12236,11565,11662,11454,29130,29227,29074,29942,29993,29795,29063,28926,28680,39304,39224,39603,42816,41963,41948,43341,43297,43382,43195,43263,43090,43778,43895,43851,42771,42698,42944,42944,42746,42829,43895,43760,43904,41862,41794,41647,41973,42409,42041,11414,11565,11454,10646,10713,10635,30643,30455,30678,39590,39527,39574,39810,39903,39804,40222,40441,40245,42929,42682,42519,5270,5251,5130,6083,6118,6137,34018,33867,33861,33322,33100,33318,33019,33042,32953,34021,33867,34018,5815,5878,5898,32586,32487,32124,41973,41794,41862,469,918,284,1607,1653,1796,8820,8875,8859,11263,11272,11122,29634,29467,29629,29634,29629,29648,30094,29993,29942,30214,30290,30207,33322,33318,33476,43294,43150,43155,42944,42698,42746,3342,3323,3448,3239,3323,3342,5911,6443,6362,35960,35864,35793,35844,35864,35914,35765,35888,35706,36498,36345,36982,35765,35706,35596,82,49,127,34882,34668,34475,34475,34569,34261,41245,41170,40795,40548,40441,40222,43671,43643,43658,43294,43341,43382,43297,43341,43155,43671,43658,43798,4023,4152,4083,1884,1917,1778,1844,1748,1796,30094,30011,29993,28498,28669,28547,28762,28669,28498,33675,33602,33445,5794,5815,5898,6137,6254,6342,9538,9829,9856,8886,9241,9238,6421,6829,6541,7097,7312,7207,8721,8886,8832,9553,9538,9460,3903,4023,4083,3903,4083,3912,3912,3832,3746,12425,12624,12764,12420,12624,12425,28893,28787,28814,28074,27812,27741,29356,29068,29422,29911,29813,30057,30864,30939,30946,3014,3348,3027,2285,2625,2602,40123,40080,39988,1814,1748,1844,963,1109,1167,29467,29356,29422,29813,30279,30057,33613,33322,33476,31878,31996,32143,32866,33043,32798,36345,36259,36982,35679,35765,35596,39436,39286,39374,39903,40123,39988,41350,41667,41403,41786,41888,41854,41245,41410,41554,5794,5898,6005,6221,6137,6342,6304,6342,6410,825,808,897,897,808,852,1109,991,1237,963,991,1109,1161,1725,1396,32635,32802,32602,31635,31638,31374,31374,31348,31313,32009,32108,32124,32076,32108,32009,31470,31744,31526,31470,31526,31368,31311,31470,31368,31278,31062,31173,41508,41529,41360,41765,41611,41481,1917,1814,1930,2078,2175,2182,9945,9924,10031,10584,10646,10496,10496,10646,10635,9538,9771,9342,33042,33019,33100,43198,43393,43423,43029,42898,43086,43175,43298,43195,43904,43512,43354,43319,43298,43175,31439,31348,31374,31173,31062,31024,11141,11263,11122,11715,12010,11988,11141,11122,11035,30235,30290,30214,29795,29430,29942,31793,32009,31830,32487,32767,32688,7097,7124,6994,40441,40562,40326,40658,40562,40865,825,897,928,31348,31151,31313,31024,31062,30863,43845,43888,43590,3746,3648,3705,2557,2601,2704,3838,4312,4330,10584,10496,10545,30964,31024,30863,36611,36364,36547,35390,35421,35733,39574,39788,39815,39106,39436,39374,36040,35825,35888,35548,35679,35596,39802,39777,39684,39887,39777,39802,40243,40548,40222,39718,39810,39672,39664,39810,39718,33105,33042,33100,41730,41529,41508,40028,39887,39820,1884,1814,1917,1748,1607,1796,2704,2601,2742,3348,3285,3184,11683,11756,11565,29649,29634,29648,29649,29648,29782,30279,30433,30282,34861,34758,34529,33867,33675,33445,33342,33188,33322,33322,33188,33100,34758,34863,35010,40926,40795,40655,41792,41433,41667,3762,3746,3705,28934,28787,28893,28934,28893,29011,41794,41765,41647,41611,41730,41508,41963,41973,41862,43029,43086,43765,41433,41403,41667,42829,42617,42682,30214,30094,30235,30678,30455,30478,43459,43029,43591,30455,30441,30478,5020,5287,5008,4333,4293,4330,5287,5109,5008,36040,35888,35921,38264,38304,38186,38264,38401,38304,38304,38401,38404,5008,5109,5046,38388,38093,38324,37978,38093,37881,37739,37406,37802,38388,38324,38337,32802,32652,32894,41667,41350,41677,5971,6005,6083,6361,6679,6429,6094,5971,6083,6361,6429,6271,35921,35888,35765,4866,5008,4938,34020,34021,34090,8624,8444,8549,8875,8820,8838,9112,9258,9182,30864,30641,30939,33613,33476,33602,32964,32802,32894,40279,40123,40281,7544,7645,7857,7764,7645,7349,35679,35707,35765,35128,34928,35419,38519,38471,38724,40422,39735,40306,11513,11565,11414,11513,11683,11565,29502,29356,29467,30282,30433,30414,4372,4357,4753,38117,38186,38006,8076,8444,8221,29502,29467,29634,33865,33675,33867,43341,43294,43155,43614,43454,43564,43614,43564,43643,32964,32894,33042,32866,32767,32792,5879,5904,6090,6962,6923,6829,7059,7097,6994,5784,5904,5879,4357,4293,4333,34863,34758,34861,35844,35733,35864,38853,39040,39363,6094,6083,6137,6304,6361,6271,11035,11122,10713,39436,39574,39527,40279,40260,40123,39664,39936,39955,42829,42746,42617,42612,42425,42482,12954,13039,12801,12954,12801,12834,12801,12712,12834,27838,28325,28103,28669,29063,28680,4293,4208,4330,31064,30864,30946,31348,31249,31151,31672,31638,31635,31669,31638,31672,31769,31672,31878,31769,31910,31792,39304,39603,39774,9829,9924,9945,10646,10584,10713,9825,9924,9829,31669,31769,31792,32620,32767,32487,31744,31793,31830,31673,31793,31744,31637,31744,31470,31637,31470,31311,31210,31278,31173,31210,31173,31171,13675,13713,13380,12648,12569,12521,42564,42451,42669,42151,41854,42125,43798,43633,43707,33336,33343,33252,35419,34928,35272,33333,33343,33336,598,918,791,726,825,928,808,825,708,31439,31249,31348,31171,31173,31024,31171,31024,30964,4786,4866,4938,6094,6137,6033,5904,6002,6090,3184,3285,3323,3184,3323,3166,28787,28686,28645,28997,28934,29011,32143,32355,32197,33027,32964,33042,33105,33100,33188,35548,35707,35679,34928,34801,35104,42125,41854,41888,6962,6829,6793,40123,40125,40281,40123,40260,40080,41446,41377,41245,43831,43798,43707,240,195,282,282,195,219,219,90,217,766,791,808,29356,29258,29068,29864,29649,29782,29864,29782,29911,30433,30462,30414,708,766,808,34065,34152,33836,3929,4023,3880,3929,4007,4023,4023,4007,4169,4169,4144,4319,5312,5961,5561,5904,5842,6002,8886,8899,8832,9460,9538,9342,35914,35864,35960,35914,35960,36093,39574,39664,39590,39810,39664,39955,240,282,322,159,90,31,29278,29258,29356,34021,33865,33867,33330,33105,33188,34020,33865,34021,31169,30946,31151,43760,43895,43778,43675,42865,43263,43478,43263,43298,5008,5046,4938,6221,6342,6304,39291,39304,39459,2256,2469,2335,3746,3762,3903,2256,2335,2211,978,2425,1211,834,461,267,370,234,1,37739,37802,38026,8574,8832,8605,9474,9535,9585,8820,8610,8624,11969,11331,11690,33613,33602,33675,32070,32049,31968,1814,1767,1748,1854,1917,2210,2078,2210,2175,2602,2356,2285,33764,33613,33675,35844,35390,35733,33930,33792,33865,35482,35581,35548,34941,34744,34668,30864,30682,30641,30478,30441,30290,30478,30290,30366,42929,42829,42682,43180,43319,43175,29649,29502,29634,29794,29502,29649,43180,42771,42944,35104,34941,34997,3392,3342,3429,2602,2659,2356,9688,9756,9666,13829,13923,14091,41917,41765,41794,40963,40617,41444,41917,41794,41973,43808,43643,43671,43721,43614,43643,36694,36172,36364,35844,35984,35390,148,90,219,12251,12236,12010,11715,11988,11683,28619,28686,28739,28739,28686,28787,27741,27812,27386,29183,29011,29258,43614,43581,43488,14292,13829,14091,28338,27812,28074,29415,29430,29227,33901,34065,33836,32866,33333,33043,32866,32798,32767,2750,3026,2751,7059,6962,6793,4647,4957,4610,36968,36783,36515,97,148,195,195,148,219,2754,2778,3014,28762,29063,28669,34152,34262,34261,33763,33409,33343,43566,43423,43393,43459,43269,43029,9182,9258,9351,32620,32487,32586,31769,31669,31672,31492,31439,31374,31249,31169,31151,30864,30811,30682,32049,31910,31968,11513,11715,11683,11863,11715,11671,1,234,112,3731,3794,3961,5400,5270,5372,6271,6221,6304,6679,6804,6429,7097,7153,7312,7941,8241,8141,5911,6362,6002,7941,8070,7764,10072,10561,10031,9697,9825,9829,9896,9825,9818,34020,34090,33930,33865,33792,33675,33613,33342,33322,33901,33763,33844,3838,3731,3961,5723,5784,5901,36783,36611,36547,42650,42242,42846,42242,42420,42846,2950,3027,3083,3184,3027,3348,12289,12521,12303,9405,9337,9351,31878,32143,31968,32937,32802,32964,4840,4686,4844,4357,4279,4293,4293,4279,4208,4208,3982,4330,4786,4686,4840,4786,4840,4866,5270,5400,5251,4507,4647,4610,5723,5737,5784,4763,4647,4507,5815,5764,5773,11863,12251,12010,29183,29278,29525,29502,29278,29356,43423,43382,43297,30608,30462,30565,30608,30565,30682,38026,37802,37881,37175,36746,36783,36783,36746,36611,38026,37881,38093,38388,38337,38468,38401,38460,38404,37867,38117,38006,38079,38117,37867,5815,5794,5764,31331,31169,31249,31425,31637,31311,32586,32124,32108,30964,30863,30819,30964,30819,30678,40617,41217,41444,39887,39857,39777,42602,42650,42719,42327,42125,41888,42431,42451,42117,42451,42564,42482,41920,41888,41792,38117,38264,38186,9061,9011,9112,9112,9011,9186,6429,6489,6414,41446,41350,41377,40658,40394,40562,38468,38337,38509,38468,38509,38532,9896,10031,9924,30546,30964,30678,7617,8045,7705,5959,5971,6094,9548,9585,9621,4372,4279,4357,38532,38509,38519,38472,38460,38401,331,254,322,294,254,331,30282,30057,30279,30169,30057,30282,2879,2754,3014,6962,7059,6994,7153,7059,7056,7764,8070,7645,12712,12801,12624,12954,12831,13301,34065,34262,34152,34029,34262,34065,36163,36259,36096,35556,35581,35482,35556,35482,35419,35104,34801,34941,40422,40028,39735,38724,38471,38853,40479,40548,40243,40123,39903,40125,39903,39955,40125,41217,41360,41551,30972,30811,30864,5959,6094,6033,38724,38975,38787,7705,8045,7728,40548,40562,40441,9390,9337,9405,33494,33343,33333,33844,33763,33681,33763,33901,33836,31886,32009,31793,34021,34140,34090,33617,33342,33613,41838,41730,41611,42041,41917,41973,36163,36096,36040,39291,39040,39304,29063,29088,29130,30478,30546,30678,29185,29088,29063,6033,6137,6221,6889,7582,7535,35390,35144,34763,36066,35914,36088,35914,36093,36088,40424,40390,40306,40963,40527,40459,30784,30608,30682,9337,9182,9351,9011,8859,8875,32620,32792,32767,5794,5959,5855,30057,29864,29911,30152,29864,30057,39774,39603,39777,254,240,322,148,97,90,226,240,254,2934,2879,3014,2950,3014,3027,3027,3184,3083,7059,7153,7097,7142,7153,7056,35065,35144,35390,34997,34941,34668,9825,9896,9924,9697,9829,9538,9342,9248,9460,9976,10072,10031,31425,31311,31210,32620,32679,32792,31673,31637,31696,31492,31374,31638,31169,31064,30946,30811,30784,30682,31968,31769,31878,33027,33042,33105,33617,33613,33733,41667,41920,41792,41426,41446,41245,30608,30414,30462,30534,30414,30608,31691,31638,31669,32937,32602,32802,42558,42562,41918,42602,42562,42558,42602,42558,42650,42302,42117,42151,43070,43180,42944,42302,42151,42263,9130,9061,9112,39857,39887,40028,39857,39774,39777,41838,41611,41765,41910,41765,41917,2557,2704,2580,2522,2659,2601,1778,1767,1884,8397,8574,8360,9342,9241,9248,7349,7645,7544,9756,9688,9621,9474,9390,9405,9160,9130,9182,9182,9130,9112,12569,12776,12841,28739,28787,28934,28686,28619,28645,29183,29258,29278,43798,43808,43671,43621,43566,43581,43581,43566,43393,43423,43654,43382,43831,43808,43798,33962,33901,33844,34882,34997,34668,49,1,112,12552,12712,12624,12834,12831,12954,12420,12425,12251,11863,12010,11715,43596,43581,43614,42846,42420,43029,284,294,331,766,679,791,708,679,766,726,928,731,1767,1814,1884,9560,9548,9621,8574,8605,8360,11454,11397,11414,11263,11141,11189,31162,31064,31169,43888,43831,43707,29525,29278,29502,30272,30169,30282,30272,30282,30414,8916,9011,9061,8916,8859,9011,1778,1917,1854,12300,12420,12251,29794,29649,29864,33342,33330,33188,33764,33675,33792,33764,33792,33871,35612,35707,35548,35612,35548,35581,39846,39857,39966,39774,39881,39304,2580,2704,2754,35144,35010,34863,35065,35010,35144,35104,35272,34928,34668,34569,34475,40519,40390,40424,40422,40390,40519,40424,40527,40519,36611,36694,36364,35098,35065,35293,36694,36746,36897,42041,41910,41917,41551,41360,41529,42031,41920,41994,12325,12552,12420,11035,10713,10584,29415,29942,29430,31821,31673,31696,37988,36968,36938,38066,38026,38093,38066,38093,38437,38469,38388,38468,38469,38468,38694,38468,38532,38694,43070,42944,42829,43319,43415,43298,4647,4763,4957,4144,4169,4007,43424,43415,43319,2070,2182,2124,2285,2182,2175,37603,37768,37524,38117,38393,38264,38264,38393,38401,37603,37524,37294,40658,40926,40655,41446,41677,41350,40870,40926,40658,1667,1607,1748,1534,1416,1396,33349,33330,33342,5794,6005,5971,5794,5971,5959,5784,5737,5904,5519,5737,5723,33901,34029,34065,33962,34029,33901,4763,4985,4957,2362,2356,2659,43723,43721,43835,43835,43721,43643,35216,35272,35104,35216,35104,35134,40479,40243,40260,39903,39810,39955,2879,2826,2754,2557,2522,2601,3239,3342,3392,3239,3392,3193,4686,4596,4753,4545,4596,4686,4545,4686,4786,5109,5287,5372,5109,5372,5270,35873,35921,35765,35556,35612,35581,38460,38709,38404,38518,38393,38539,43723,43596,43614,43566,43560,43423,9049,9130,9160,11189,11035,11082,41910,41838,41765,33617,33517,33342,33930,33865,34020,5130,5109,5270,38694,38532,38724,38694,38724,38787,38393,38472,38401,2525,2522,2557,10432,10545,10496,9896,9976,10031,9951,9976,9896,12841,12776,13009,12841,13009,13018,12420,12552,12624,12712,12831,12834,12300,12251,12150,29183,28997,29011,28954,28997,29299,30152,30057,30169,31439,31331,31249,31792,31691,31669,31804,31691,31792,31910,31769,31968,31210,31171,31425,31637,31673,31744,33763,33343,33624,34475,34261,34262,40479,40260,40279,43621,43560,43566,4931,5046,5109,6033,6221,6124,6221,6271,6124,5737,5842,5904,5812,5842,5682,9697,9818,9825,31968,32143,32070,31821,31886,31793,31691,31492,31638,1161,1220,1290,9553,9697,9538,9693,9697,9553,31886,32076,32009,42564,42612,42482,42263,42151,42125,140,164,240,240,164,195,21,284,918,598,791,679,29928,29794,29864,30972,30864,31064,731,928,991,31466,31331,31439,42674,42602,42819,42562,42654,41918,41910,41895,41838,42762,42612,42564,3455,3794,3731,3166,3239,3172,3929,4144,4007,4023,3903,3880,7893,8360,7941,33129,33027,33105,33733,33517,33617,41554,41426,41245,41920,42031,41888,9160,9182,9337,9688,9560,9621,9666,9560,9688,30178,30235,30094,33221,33105,33330,31234,31162,31169,226,254,294,11671,11715,11513,12150,12251,12040,43434,43478,43298,43434,43298,43415,2950,2934,3014,2946,2934,2950,5842,5911,6002,5812,5911,5842,4985,5312,5561,35134,35104,34997,35651,35873,35612,1396,1725,1653,9248,9241,8796,31162,30972,31064,2469,2390,2751,2335,2287,1986,41554,41532,41426,40865,40870,40658,34021,34171,34140,33764,33733,33613,34029,34315,34262,34950,35134,34997,33343,33494,33624,3705,3903,3762,3239,3166,3323,3455,3731,3400,35873,35765,35707,35873,35707,35612,199,226,294,140,226,108,43744,43723,43870,43721,43723,43614,43596,43621,43581,1607,1534,1653,1667,1748,1767,2318,2390,2469,11397,11454,11263,11189,11141,11035,29942,30052,30094,31425,31171,31417,30337,30052,30125,33349,33221,33330,32049,31804,31910,33349,33342,33517,30872,30784,30811,3982,4208,3914,11331,11969,12289,13018,13009,13253,12325,12831,12552,12552,12831,12712,12325,12420,12300,28954,28739,28934,28619,28338,28074,28954,28934,28997,29088,29415,29227,28325,28762,28498,43744,43621,43596,42719,42650,42846,1854,2210,2078,1973,2078,2182,1973,2182,2070,5312,5467,5961,33871,33733,33764,43854,43354,43154,2934,2826,2879,2522,2362,2659,2775,2826,2934,40281,40328,40279,40662,40865,40562,39664,39574,39815,2648,2580,2754,7153,7142,7312,7764,7789,7941,7056,7059,6793,34171,34529,34873,35984,35844,35914,35387,35419,35272,34950,34997,34882,39857,39846,39774,40390,40422,40306,40519,40748,40627,5467,5557,5723,3166,3083,3184,3101,3083,3166,36038,36163,36040,35387,35272,35239,39966,39857,40028,5400,5535,5251,6124,6271,6218,11568,11671,11513,11568,11513,11414,33505,33349,33517,32937,32964,33027,6794,6889,6880,7700,7705,7728,8045,8444,7728,2138,2285,2356,9693,9818,9697,9948,9951,9801,9818,9951,9896,10432,10496,10329,31910,31804,31792,31691,31734,31492,31382,31234,31331,31331,31234,31169,31162,31035,30972,30972,30872,30811,32937,33027,33039,32586,32679,32620,31886,31981,32076,31673,31821,31793,31425,31417,31501,3746,3464,3539,9130,9049,9061,9390,9474,9548,29185,29415,29088,33129,33105,33221,43478,43675,43263,43424,43434,43415,43424,43319,43180,32070,32143,32197,31821,31981,31886,30366,30290,30235,42602,42674,42562,42975,42941,42846,10978,11035,10584,30337,30366,30235,30178,30094,30052,43098,43070,42829,2462,2362,2522,1904,1854,2078,1778,1667,1767,9461,9390,9548,11331,12289,11816,34014,33871,33930,33930,33871,33792,33733,33505,33517,33333,33603,33494,34155,34315,34029,726,708,825,612,708,616,731,991,661,2390,2750,2751,7545,7535,7617,31466,31439,31492,35239,35272,35216,35239,35216,35233,43294,43382,43911,5535,5454,5251,6218,6271,6429,36038,36040,35921,36038,35921,35939,40762,39966,40028,39363,39040,39291,40215,40328,40281,39574,39436,39788,13829,13380,13713,28742,28338,28619,13380,13018,13253,12841,12752,12569,43654,43423,43560,43723,43744,43596,43835,43643,43808,38026,37989,37739,38066,37989,38026,38093,38388,38470,4805,4786,4938,4975,4938,5046,4975,5046,4931,38470,38388,38469,608,598,679,10496,10072,10329,43654,43560,43621,4144,4507,4610,5034,5211,4985,4985,5211,5312,5312,5301,5467,5467,5458,5557,4002,4507,4144,3979,4144,3929,40558,40519,40627,40422,40498,40028,32075,31804,32049,33116,33129,33221,33359,33221,33349,1577,1667,1778,1534,1396,1653,32840,32866,32792,41551,41681,41571,41895,41730,41838,12798,12752,12841,28739,28742,28619,28742,28954,29299,29804,29502,29794,30721,30608,30784,9461,9548,9560,12303,12521,12569,12040,12251,11863,11189,11397,11263,11100,11397,11189,30337,30178,30052,31501,31637,31425,4596,4372,4753,5764,5794,5657,31035,30872,30972,37768,38079,37867,38393,38518,38472,37522,37603,37294,3227,3193,3392,2600,2648,2826,2826,2648,2754,2525,2462,2522,3227,3392,3455,6278,6218,6429,5855,5959,6033,140,97,164,164,97,195,140,240,226,30125,30052,29942,28762,29185,29063,2138,2182,2285,1973,1904,2078,1577,1566,1667,2138,2356,2290,7774,7789,7680,8796,9241,8886,8721,8832,8574,9460,9693,9553,32586,32108,32076,33970,33962,33844,34155,34029,33962,42409,41973,41963,41994,41920,41667,42302,42431,42117,42612,42762,42519,41532,41446,41426,2946,2950,2917,35939,35921,35873,35378,35239,35233,40215,40281,40125,41554,41410,41602,2775,2946,2917,6489,6595,6507,6889,6595,6804,1953,1904,1973,34529,34758,34988,33708,33505,33733,7700,7545,7617,7700,7617,7705,5855,5741,5657,8397,8721,8574,39868,39774,39846,30842,30721,30784,5855,6033,5741,5797,6421,6443,5682,5842,5737,5519,5723,5557,139,267,461,199,294,284,5454,5773,5764,5128,5211,5034,2525,2557,2580,8822,8820,8859,9126,9160,9337,42041,41895,41910,6053,6013,6124,6414,6278,6429,36088,36093,36229,34037,34014,34090,36694,36611,36746,35556,35419,35387,37040,36982,36903,39788,39436,39927,40491,40479,40573,39936,39815,39858,3914,4208,4279,5211,5301,5312,10978,11082,11035,11717,11863,11671,30592,30534,30608,31234,31035,31162,30872,30842,30784,30721,30592,30608,31804,31734,31691,32195,31734,31804,32355,32653,32197,31501,31696,31637,31821,31823,31981,32672,32586,32329,31171,31217,31417,42738,42431,42302,657,731,661,708,608,679,149,199,284,991,663,661,31734,31466,31492,30546,30478,30366,35378,35387,35239,35433,35556,35387,9948,10072,9976,10593,10978,10584,9200,9693,9460,32355,32602,32653,34102,33733,33871,32075,32197,32224,34075,33970,33844,32960,33333,32866,41551,41529,41681,40498,40558,40627,41595,41532,41631,7680,7789,7764,6421,6541,6443,40328,40479,40279,40215,40125,40293,3982,3838,4330,3705,3880,3903,3787,3880,3705,5301,5408,5467,42669,42762,42564,42327,42263,42125,42327,41888,42031,149,284,21,6489,6429,6804,6278,6140,6218,6489,6804,6595,5797,6443,5911,5797,5911,5812,36066,35984,35914,35990,35984,36066,35931,35939,35873,36982,36259,36903,39984,39868,39846,39881,39868,39984,39815,39936,39664,39955,39936,40064,2021,1988,2070,2070,1988,1973,1716,1524,1854,612,608,708,9948,9976,9951,2290,2356,2362,2390,2101,2750,2256,2318,2469,1986,2287,1937,2287,2143,1937,6546,6648,6604,8822,8859,8916,34315,34475,34262,34355,34475,34315,30446,30414,30534,30446,30272,30414,5592,5764,5657,5592,5454,5764,5408,5458,5467,9531,9461,9560,9126,9036,9160,9601,9560,9666,34758,35010,34988,34090,34014,33930,33681,33763,33624,2211,2318,2256,3539,3464,3522,31478,31035,31234,42762,42929,42519,43500,43424,43547,1566,1607,1667,1416,1534,1607,8916,9061,9049,9036,9049,9160,41595,41677,41446,33603,33615,33494,32586,32076,32329,5458,5519,5557,36089,36163,36038,6421,6793,6829,40118,40125,39955,33615,33681,33624,33615,33624,33494,6414,6290,6278,6507,6595,6648,31035,30842,30872,2462,2290,2362,2648,2525,2580,2440,2525,2531,2775,2934,2946,40519,40558,40422,41706,40963,41444,43434,43521,43478,43273,43180,43070,43831,43835,43808,43660,43654,43621,41784,41994,41667,3705,3648,3623,41677,41784,41667,41532,41595,41446,41108,40926,40870,40562,40548,40662,2021,2124,2138,2138,2124,2182,1988,1953,1973,6648,6595,6889,8076,7728,8444,11082,11100,11189,10514,10584,10545,30744,30592,30721,30272,30152,30169,30339,30546,30366,30337,30235,30178,4582,4545,4786,4596,4506,4372,4372,4305,4279,3982,3914,3838,4805,4938,4905,4938,4975,4905,4975,4931,4905,2021,1953,1988,4545,4506,4596,34037,34140,34214,34014,34118,33871,35233,35216,35134,33970,34155,33962,34260,34155,34105,43660,43621,43870,5109,5053,4931,3193,3172,3239,3112,3227,3236,3172,3227,3112,2324,2290,2462,5519,5682,5737,6623,6815,6793,40662,40548,40665,5109,5106,5053,9126,9337,9205,7436,7685,7728,34950,34882,34945,35556,35651,35612,35939,36089,36038,6257,6290,6414,6889,6731,6712,40491,40548,40479,40064,40118,39955,39788,39927,39858,9801,9951,9818,10432,10514,10545,9801,9818,9693,9801,9686,9837,31696,31823,31821,31750,31823,31696,31516,31696,31501,4448,4305,4372,5109,5130,5106,38543,38470,38469,38066,38208,37989,37175,36783,36968,38543,38469,38654,42431,42669,42451,43192,43098,42929,42623,42669,42431,42623,42431,42716,9801,9693,9686,31466,31382,31331,31478,30744,30842,30842,30744,30721,31860,31382,31466,31860,31466,31734,32075,32049,32070,31217,31171,30964,32602,32937,32653,33027,33129,33039,1,32,370,5106,5130,5119,5106,5119,5060,11568,11414,11353,38654,38469,38694,43424,43521,43434,43603,43521,43595,43273,43070,43433,34945,34882,34917,30459,30534,30592,30459,30446,30534,36938,37739,37988,39459,39363,39291,39459,39304,40045,21,918,598,616,708,726,657,726,731,10093,10329,10072,31228,31217,30964,5130,5251,5119,38787,38654,38694,3227,3172,3193,2525,2440,2462,3101,3172,3112,33985,34075,33844,32840,32792,32679,32840,32679,32672,35293,35065,35695,36272,36088,36229,38709,38460,38472,41551,41548,41444,41571,41548,41551,41595,41714,41677,41627,41554,41602,8990,8916,9049,5519,5606,5682,5458,5513,5519,5408,5383,5458,5301,5218,5408,5211,5218,5301,5034,4985,4973,4748,4911,4973,3979,3929,3848,10470,10514,10432,11353,11414,11397,2917,2950,3083,6257,6414,6489,7608,7545,7700,35433,35387,35378,35433,35651,35556,199,108,226,140,35,97,149,108,199,35286,35233,35134,39881,39774,39868,38940,38787,38975,3848,3929,3880,5128,5218,5211,30446,30152,30272,28954,28742,28739,30140,30152,30446,38654,38787,38866,43742,43675,43478,7685,7608,7700,7685,7700,7728,34140,34037,34090,34988,35010,35065,3172,3101,3166,3083,3101,3005,6459,6489,6507,36088,35990,36066,36127,35990,36088,39984,39846,39966,41631,41714,41595,42716,42431,42738,3787,3848,3880,3787,3705,3623,41627,41631,41554,41554,41631,41532,40479,40328,40417,40328,40215,40417,30848,30744,31250,3623,3648,3539,5218,5383,5408,5682,5717,5812,7587,7436,7329,9036,8990,9049,9321,9337,9390,9321,9390,9461,32960,32840,32921,11100,11082,10978,30152,29928,29864,30018,29928,30152,11899,12040,11863,12150,12325,12300,40293,40125,40118,5383,5513,5458,40045,39486,39459,40067,39984,40167,40498,40422,40558,661,663,638,1577,1778,1854,1577,1558,1528,1524,1558,1577,40519,40527,40748,41681,41529,41807,41529,41730,41807,41730,42042,41807,42654,42562,42674,42654,42674,42694,40795,41410,41245,41714,41784,41677,11003,11100,10978,30744,30459,30592,42694,42674,42819,42602,42719,42819,1388,1161,1396,497,598,608,11029,9707,10013,31450,31516,31417,31417,31516,31501,32672,32679,32586,31450,31417,31217,32197,32075,32070,29987,30060,30092,30092,30060,30140,33039,33129,33116,42819,42719,42846,43675,43854,43154,9019,8990,9036,9019,9036,9126,33116,33221,33359,6604,6648,6889,8624,8610,8444,7789,7893,7941,8721,8796,8886,7774,7893,7789,7544,7142,7349,7142,7056,7349,34155,34260,34315,35372,35378,35233,34105,34155,33970,33700,33681,33615,657,616,726,9707,9601,9666,42941,42819,42846,3832,3464,3746,11644,11717,11671,11644,11671,11568,29898,29804,29794,29898,29794,29928,35372,35233,35286,35372,35433,35378,37410,37294,36982,31228,31450,31217,30125,29942,29812,43098,42829,42929,43521,43603,43478,43675,43825,43854,2531,2525,2648,2021,2070,2124,3005,2917,3083,3227,3455,3236,6546,6459,6507,5657,5794,5855,6546,6507,6648,39858,39815,39788,40030,40064,39936,3623,3539,3578,6033,5857,5741,5513,5606,5519,42034,41784,41714,12752,12303,12569,9380,9531,9521,12259,12303,12752,12798,12841,13018,11765,12325,12040,12040,12325,12150,29185,29277,29415,28762,29277,29185,43500,43521,43424,2021,2138,1992,1566,1416,1607,2600,2826,2775,7883,8397,8360,33603,33700,33615,4650,4648,4544,4650,4786,4805,4650,4582,4786,4545,4513,4506,4506,4448,4372,3920,3914,4279,4805,4905,4836,4514,4445,4492,4931,4836,4905,9385,9321,9461,38013,38079,37768,38013,37768,38004,37522,37294,37410,4582,4513,4545,4931,4820,4836,4513,4448,4506,38680,38543,38654,38602,38470,38543,38602,38437,38470,38470,38437,38093,38680,38846,38750,38853,38975,38724,4931,4870,4820,6033,6124,6013,5606,5717,5682,9321,9205,9337,8820,8822,8610,38539,38393,38117,43017,42929,42762,42824,42762,42669,3506,3731,3838,30060,30152,30140,30060,30018,30152,1992,2138,2290,2671,3803,2750,2211,2037,2318,1937,2143,1672,34260,34355,34315,34499,34355,34333,43521,43500,43595,43547,43424,43180,5513,5410,5606,5606,5639,5717,5383,5410,5513,5218,5132,5383,5128,5182,5218,4985,4748,4973,3965,4144,3979,3752,3979,3848,3823,3848,3787,3823,3787,3698,38853,39363,38975,38518,38709,38472,34075,34105,33970,1362,1416,1566,1388,1416,1259,36089,35939,35931,35286,35134,35160,40293,40417,40215,40491,40665,40548,40662,40826,40865,41631,41831,41714,40527,41104,40748,41730,41895,42042,6124,6218,6053,6604,6889,6712,13380,12798,13018,29525,29502,29804,29299,28997,29183,5034,5105,5128,35442,35651,35433,5547,5454,5592,6257,6489,6392,11229,11353,11397,11717,11899,11863,10593,11003,10978,10593,10584,10514,10470,10432,10329,10242,10329,10093,9837,9948,9801,32840,32960,32866,34333,34260,34105,32076,31981,32113,2600,2775,2747,2241,2324,2440,2440,2324,2462,35098,34988,35065,33177,33116,33359,35011,34945,34917,40644,40665,40491,3920,4279,4305,5105,5182,5128,43870,43621,43744,43654,43911,43382,36000,35390,35984,36218,36127,36088,36272,36229,36575,39927,39436,39106,40189,40293,40118,42327,42031,42183,551,548,616,548,608,612,991,963,663,108,35,140,548,612,616,32,139,461,267,55,1567,11501,11644,11568,30060,29898,29928,30060,29928,30018,38975,39295,39076,5639,5797,5717,5717,5797,5812,42073,42031,41994,40795,40926,41410,9601,9531,9560,9116,9100,9205,9521,9531,9601,9385,9531,9380,6392,6489,6459,6889,6794,6731,30337,30339,30366,30125,30339,30337,33039,32985,32937,34118,34014,34037,40417,40573,40479,40189,40118,40064,35160,35134,34950,35372,35442,35433,40963,41104,40527,39486,39363,39459,40588,40573,40417,3698,3787,3623,3698,3623,3651,40019,39881,39984,1672,2143,738,3832,3803,3464,7893,7883,8360,7349,7056,6873,42073,41994,41784,7685,7587,7608,8610,8916,8827,34499,34565,34475,34945,35160,34950,34499,34475,34355,34355,34260,34333,3112,3005,3101,3073,3005,3112,6392,6459,6474,40067,40019,39984,39858,40030,39936,39949,40030,39858,3651,3623,3578,5137,5410,5383,38208,37739,37989,6815,7056,6793,149,35,108,21,35,149,11740,11899,11717,11740,11717,11644,33844,33681,33985,32113,31981,31823,32113,31823,31977,1416,1388,1396,1528,1566,1577,11229,11397,11100,41797,41548,41571,41796,41807,41889,2747,2775,2917,6474,6459,6546,7535,6880,6889,3240,3361,3464,35164,35160,34945,35343,35442,35372,40067,40045,40019,41797,41571,41681,40588,40644,40573,40573,40644,40491,40665,40826,40662,40588,40675,40670,5635,5592,5657,6053,6218,6140,6278,6290,6140,6474,6546,6581,9205,9100,9126,9019,9100,9116,42183,42073,42103,43720,43742,43603,43603,43742,43478,43595,43500,43735,34917,34882,34475,33603,33333,32960,34873,34214,34171,29987,29804,29898,29743,29525,29804,43547,43649,43646,43547,43180,43273,9200,9460,9248,11150,11229,11100,8796,8721,8457,33116,32985,33039,31478,31234,31382,33177,32985,33116,4513,4445,4448,3714,3920,4305,4582,4492,4513,4544,4492,4582,5635,5657,5653,38437,38208,38066,38529,38208,38437,38602,38543,38673,38543,38680,38673,42816,42409,41963,42694,42721,42654,42778,42721,42694,42958,42694,42819,38079,38539,38117,38518,38674,38709,40225,40189,40030,38004,37768,37603,37692,37603,37522,31750,31696,31516,5653,5657,5741,6140,6290,6257,36575,36229,36694,36000,35984,35990,34330,34219,34214,2600,2593,2648,1716,1953,2021,1577,1854,1524,2549,2593,2600,3449,3506,3477,2777,2747,2917,3506,3838,3477,3803,3240,3464,5653,5741,5707,6623,6793,6421,35343,35372,35286,35343,35286,35325,5060,5053,5106,6095,6140,6257,6581,6546,6604,6581,6604,6611,39927,39106,39983,40030,40189,40064,551,616,657,638,657,661,42975,42846,43269,38673,38680,38750,38787,38940,38866,42964,42958,42941,43835,43870,43723,36000,35990,36127,40670,40667,40644,40644,40667,40665,5182,5132,5218,5105,5092,5182,5034,5066,5105,4985,4763,4748,3965,3979,3752,3848,3823,3752,3823,3698,3752,38866,38940,39076,10242,10470,10329,8357,8721,8397,43768,43786,43742,43742,43786,43675,1904,1716,1854,663,963,602,3506,3400,3731,3299,3400,3297,3573,3698,3651,2750,2101,2671,5119,5251,5454,5635,5653,5566,11765,11740,11644,11899,11765,12040,11765,11644,11501,41108,40870,40865,41627,41831,41631,5119,5454,5029,11150,11100,11003,6328,6257,6392,5857,6033,6013,36272,36218,36088,36091,36218,36192,10470,10593,10514,3942,4305,4448,3578,3539,3507,5547,5592,5635,5066,5092,5105,5410,5639,5606,6702,6873,6815,2593,2531,2648,2777,2917,3005,6474,6328,6392,6611,6604,6712,2458,2531,2593,6815,6873,7056,7349,7680,7764,7774,7883,7893,6623,6421,6346,35931,35873,35651,35325,35286,35160,40045,39304,39881,40045,39881,40019,5092,5132,5182,39076,38940,38975,41807,41796,41681,42042,42215,42088,32195,31804,32075,35931,35651,35908,39984,39966,40167,34917,34475,34565,37221,37410,36982,40667,40826,40665,40962,40826,40667,9100,9019,9126,9245,9205,9321,9385,9461,9531,32672,32921,32840,34796,34917,34565,32823,32921,32672,36897,36575,36694,36897,36746,37175,6581,6523,6474,6731,6611,6712,7136,6880,7535,6309,6421,5797,963,706,602,548,497,608,40588,40417,40675,42816,41948,42654,42958,42778,42694,42958,42819,42941,42815,42824,42669,42815,42669,42623,42302,42263,42738,42183,42031,42073,32243,32224,32197,33263,33603,32960,43786,43825,43675,43774,43768,43742,43720,43603,43595,638,551,657,31228,30964,30546,32784,32823,32672,40045,40074,39486,40628,40028,40498,40628,40498,40627,42846,43029,43269,32985,32653,32937,33086,33177,33359,139,87,267,32,60,139,43381,43070,43098,3299,3236,3455,3299,3455,3400,34217,34333,34105,41003,41108,40865,41003,40865,40826,42964,42975,43066,10899,11150,11003,11501,11568,11353,8610,8822,8916,11029,10013,11331,8827,8916,8990,33985,33681,33700,43774,43720,43595,35060,35164,34945,35343,35325,35442,34969,35020,35142,3507,3539,3522,3507,3522,3422,7545,7136,7535,6611,6523,6581,5857,6013,5873,9385,9245,9321,33074,32653,32985,1528,1421,1566,1904,1953,1716,1412,1421,1558,2747,2549,2600,2790,2777,3005,3422,3522,3464,5566,5547,5635,6013,6053,5873,35060,34945,35011,41104,40963,41516,29812,29942,29415,30339,30495,30546,43435,43192,42929,4492,4445,4513,3106,3073,3236,4544,4582,4650,4650,4805,4648,4805,4688,4648,4836,4688,4805,4836,4820,4688,5053,4870,4931,5053,4956,4870,43768,43825,43786,43869,43825,43768,9245,9116,9205,42319,42183,42371,41719,41627,41602,5053,5060,4956,38727,38602,38673,38727,38529,38602,38602,38529,38437,36575,36897,36753,38727,38673,38750,38654,38846,38680,38366,38539,38079,40480,40417,40293,38766,38844,38848,36091,36127,36218,34214,34873,34330,36897,37175,37226,3236,3073,3112,3400,3269,3297,38805,39106,38709,4956,5060,4997,7431,7680,7349,7779,7698,7781,38654,38866,38846,38539,38674,38518,8968,8990,9019,7779,7883,7774,34709,34565,34499,34969,35060,35011,34153,34217,34105,34153,34105,34075,6620,6523,6611,7545,7608,7136,4997,5060,5119,38846,38976,38932,38674,38745,38709,33177,33074,32985,33086,33074,33177,34118,34037,34214,30060,29987,29898,29525,29299,29183,30446,30459,30140,33893,33985,33700,33893,33700,33739,504,497,551,1231,1161,1388,5132,5137,5383,5092,5066,5132,4973,5066,5034,4952,5066,4973,4763,4507,4398,3752,3698,3573,38750,38846,38932,42824,42884,42762,42439,42263,42327,31450,31750,31516,34263,34153,34202,31940,31750,31753,42778,42828,42721,42976,42828,42778,42976,42778,42958,42852,42815,42623,3573,3651,3578,2390,2318,2101,34969,35011,34917,35306,35325,35160,32224,32195,32075,32653,32243,32197,32195,32243,32276,11188,11029,11331,11816,12289,12303,30125,30495,30339,39927,39949,39858,40588,40670,40644,40130,39949,40091,551,497,548,504,551,638,10470,10375,10593,11153,11217,11150,10093,10072,9948,10093,9948,9837,9200,9248,9062,42975,42964,42941,42972,42964,43066,42505,42439,42327,1558,1421,1528,2290,2324,2118,41813,41719,41602,42183,42384,42327,41726,41444,41548,42042,41895,42215,3573,3578,3507,5066,5137,5132,3400,3506,3449,2037,2211,1986,6620,6611,6731,6688,6620,6731,7136,7608,7587,6794,6880,6684,35306,35160,35164,36903,36259,36163,40750,40628,40627,40067,40046,40045,40750,40627,40748,42505,42384,42445,11217,11229,11150,11217,11353,11229,11740,11765,11899,30469,30626,30495,29277,29812,29415,10899,11003,10778,41797,41681,41796,34219,34118,34214,36000,36127,36091,34709,34499,34669,35198,35306,35164,34157,34153,34075,33700,33603,33739,40167,40046,40067,9062,9248,8796,2671,3240,3803,3422,3573,3507,5381,5029,5454,5873,6053,5980,42042,41889,41807,42066,41889,42042,34263,34333,34217,12798,12259,12752,29743,29299,29525,2118,2324,2117,1421,1362,1566,33739,33603,33870,2667,2549,2747,2689,2747,2777,2790,3005,2855,6523,6328,6474,6688,6731,6794,3422,3464,3361,11217,11501,11353,11211,11501,11217,35198,35164,35060,35908,35651,35442,40762,40167,39966,40811,40750,40748,40225,40293,40189,41952,41831,41813,2855,3005,2914,6579,6328,6523,6623,6702,6815,6253,6309,6160,36218,36528,36192,38975,39363,39295,40762,40028,40628,3143,3106,3236,3143,3236,3299,5707,5566,5653,5980,6053,6140,1316,1362,1421,41889,41797,41796,41934,41797,42085,41719,41831,41627,41256,40926,41108,30495,30626,30546,30469,30495,30125,31885,31977,31823,31885,31823,31750,36903,36163,36670,37410,37692,37522,42716,42852,42623,42815,42884,42824,42439,42738,42263,42655,42738,42439,42505,42327,42384,42834,42852,42716,10778,11003,10593,9686,10093,9837,32243,32195,32224,32276,32243,32326,33126,32653,33074,42852,42884,42815,43649,43547,43273,43547,43646,43500,43720,43774,43742,7883,7884,8397,7680,7779,7774,7431,7349,7152,33359,33349,33505,42964,42972,42958,42409,41895,42041,43150,43765,43086,2241,2440,2360,1524,1412,1558,40962,41003,40826,3608,3610,3920,4544,4514,4492,4648,4514,4544,4663,4514,4648,4663,4648,4688,4711,4688,4820,4711,4820,4870,4711,4870,4847,3106,3081,3073,3097,3081,3106,5707,5741,5857,6095,5980,6140,6684,6688,6794,6620,6579,6523,6328,6095,6257,7136,7587,7160,6545,6702,6623,43649,43273,43555,3233,3361,3240,3327,3422,3361,5707,5857,5738,9385,9273,9245,9245,9142,9116,9116,8968,9019,9521,9601,9707,31288,31228,30546,42319,42384,42183,2360,2440,2531,2790,2689,2777,2855,2689,2790,6309,6346,6421,6623,6346,6380,35908,35442,35735,40670,40962,40667,40130,40225,40030,40130,40030,39949,4860,4870,4956,38729,38708,38840,38840,38708,38727,38727,38708,38529,38490,38246,38208,40074,40045,40046,2458,2593,2483,43735,43774,43595,1440,1412,1524,1362,1259,1416,34202,34153,34157,34153,34263,34217,34969,35198,35060,33870,33603,33788,41797,41726,41548,41104,40811,40748,41706,41726,41934,4843,5639,5410,5066,4950,5137,4398,4507,4002,4144,3965,4002,3965,3625,4002,9380,9273,9385,6864,7136,6927,38745,38805,38709,38674,38766,38745,38539,38766,38674,38366,38079,38013,5029,4997,5119,4911,4952,4973,37796,37692,37410,38766,38805,38745,5876,6095,5874,5738,5857,5873,9273,9142,9245,32784,32672,32329,42103,42073,41784,43890,43654,43660,5381,5454,5547,46,21,598,29812,30187,30125,30626,31288,30546,41145,41256,41108,42034,42103,41784,41145,41108,41003,2483,2593,2549,43646,43735,43500,43800,43735,43646,1992,2118,1990,1992,2290,2118,1801,1716,2021,1937,1672,1986,738,2416,978,34118,34102,33871,35195,34988,35098,34075,33985,34157,36406,36089,35931,2117,2324,2241,1231,1259,1230,1230,1259,1316,3838,3914,3610,2914,3005,3073,2325,2360,2458,5497,5381,5547,5738,5873,5795,6513,6579,6620,8221,8444,8610,9041,8968,9116,10264,10470,10242,40220,40074,40046,40220,40046,40167,40933,40962,40670,39295,39363,39486,43870,43890,43660,31940,31885,31750,31977,32140,32113,31468,31450,31228,43381,43098,43192,42852,43017,42884,42738,42834,42716,42885,42834,42873,42852,42834,42885,3129,3233,3240,3625,3752,3573,3129,3240,2671,5497,5547,5566,5876,5873,5980,5876,5980,6095,31990,32140,31977,43381,43192,43360,30140,30848,30334,29987,29976,29804,32326,32243,32653,32326,32653,32457,497,383,598,507,504,638,400,504,414,43077,42976,42972,42972,42976,42958,6513,6620,6688,40225,40480,40293,40470,40480,40225,2458,2360,2531,2483,2549,2520,7136,6864,6880,40676,40675,40417,30274,30469,30125,42654,42721,42816,42034,41714,41831,42834,42738,42873,400,383,497,10178,10264,10242,10178,10242,10093,43077,43314,43170,43269,43066,42975,2970,3073,3081,35695,35065,35390,36218,36272,36528,36272,36575,36528,39983,39949,39927,36903,37221,37040,37040,37221,36982,3327,3573,3422,3233,3129,3170,34669,34499,34333,41952,42034,41831,41288,41145,41003,41081,41003,40962,34219,34102,34118,34354,34102,34219,1791,1801,2021,2150,2117,2241,5497,5492,5356,39700,39295,39486,33263,32960,32921,34669,34333,34618,34669,34796,34709,32329,32076,32113,42816,42721,42828,1259,1231,1388,1316,1421,1412,1440,1524,1519,30187,30274,30125,30469,30649,30626,30298,30274,30187,33708,33359,33505,42355,42384,42319,41831,41719,41813,2053,1990,2117,2667,2747,2689,1519,1524,1716,2855,2667,2689,3143,3097,3106,3143,3299,3297,35695,35390,36000,40789,40811,40921,40750,40758,40628,41706,41444,41726,3610,3914,3920,5304,5497,5356,5566,5492,5497,9142,9041,9116,8968,8909,8990,9046,9041,9142,9046,9142,9273,8968,9041,8943,9200,9686,9693,8586,9062,8796,3327,3361,3324,4911,4868,4952,10899,11018,11150,11501,11211,11765,10735,10778,10593,43017,42762,42884,3714,4305,3942,4711,4663,4688,4683,4663,4711,4860,4956,4997,4860,4997,5029,4860,4924,4847,38311,38376,38599,37692,38004,37603,38766,38848,38805,31860,31734,32195,42355,42319,42371,41410,40926,41256,3324,3361,3255,34102,33708,33733,34873,34529,34988,36337,36163,36089,38311,38013,38004,36337,36089,36406,41352,41410,41256,41352,41256,41145,3097,2970,3081,2828,2970,3097,35735,35325,35306,40320,40470,40225,40597,40676,40417,39727,39983,39106,38972,39106,38805,3625,3965,3752,2117,1990,2118,2150,2241,2186,8943,8909,8968,42088,42066,42042,42409,42215,41895,6726,6684,6864,6864,6684,6880,6579,6406,6328,6513,6684,6726,42869,42816,42828,42382,42204,42215,42869,42828,42989,32269,31860,32195,32285,32195,32276,2186,2241,2360,2576,2667,2855,4847,4924,4683,4748,4868,4911,4952,4950,5066,10947,11018,10899,30445,30649,30469,38844,38766,38539,43911,43150,43294,43066,43077,42972,42885,43017,42852,42183,42103,42196,33249,33074,33086,32140,32329,32113,32267,32329,32140,31990,31977,31885,504,400,497,383,362,598,362,400,346,10264,10375,10470,10778,10947,10899,10191,10178,10093,42976,43077,43170,4868,4950,4952,37226,37175,38152,38976,38846,38866,38976,38866,39058,2385,2458,2483,3449,3269,3400,3367,3269,3449,3327,3263,3573,3255,3361,3233,3255,3233,3170,35293,35195,35098,35368,35195,35293,35142,35198,34969,34796,34565,34709,2970,2914,3073,2637,2914,2661,39983,40091,39949,40675,40780,40670,40366,40437,40410,10319,10375,10264,31231,31288,30626,39058,38866,39076,42196,42103,42099,41774,41813,41602,42204,42066,42088,42204,42088,42215,60,87,139,11067,11150,11018,11067,11153,11150,30274,30445,30469,31567,31468,31736,30298,30445,30274,39700,39486,40151,39139,39076,39295,39139,39058,39076,3076,3129,2671,3324,3291,3327,40228,40225,40130,40811,40758,40750,40789,40758,40811,40597,40417,40480,43735,43869,43774,43774,43869,43768,43800,43869,43735,43800,43646,43649,1316,1259,1362,1791,2021,1992,1791,1992,1874,41410,41774,41602,41475,41352,41145,7779,7884,7883,7152,7349,6866,7349,6873,6866,6873,6702,6676,33985,34081,34157,33893,34081,33985,4448,4445,3942,7781,7884,7779,33893,33739,33870,42103,42034,42099,36091,36152,36000,36637,36575,36753,430,507,663,1316,1412,1343,10637,10735,10593,43435,43360,43192,43381,43433,43070,6545,6623,6380,35735,35442,35325,35020,34969,34917,3243,3143,3269,3269,3143,3297,30092,29976,29987,30140,30459,30848,37739,38208,38246,38004,37692,37796,36337,36670,36163,36776,36670,36805,41934,41726,41797,2667,2520,2549,2150,2053,2117,2533,2520,2667,2385,2520,2421,6684,6513,6688,6874,6864,6927,6253,6346,6309,43479,43433,43381,3610,3477,3838,38208,38529,38490,6927,7136,6980,40676,40780,40675,40767,40780,40676,31567,31750,31450,32921,32823,33263,31468,31228,31288,42816,43006,42409,42989,42828,43082,42906,42869,42989,43435,43479,43360,43635,43531,43613,42655,42439,42505,36192,36152,36091,36243,36152,36192,40762,40220,40167,40091,40228,40130,40470,40597,40480,40366,40228,40437,3255,3291,3324,3095,3076,3018,36637,36528,36575,36684,36528,36637,507,638,663,1343,1412,1440,32269,32285,32324,34255,33708,34102,34354,34219,34330,32326,32285,32276,30334,30088,30140,33249,33086,33359,8909,8827,8990,8943,8827,8909,9046,9273,9222,31468,31288,31424,33319,33249,33359,42084,41797,41889,42195,42204,42382,42099,42034,41952,42639,42655,42505,42099,42101,42237,30088,29976,30092,30088,30092,30140,42445,42384,42355,400,362,383,1161,706,963,10375,10405,10593,10178,10319,10264,10191,10319,10178,10947,11067,11018,11153,11211,11217,10947,10778,10802,43433,43555,43273,43531,43555,43433,1564,1519,1716,1582,1716,1801,33424,33512,33263,34927,34938,34796,34796,35020,34917,35208,35306,35198,34938,35020,34796,2520,2385,2483,2325,2385,2421,6503,6618,6545,6545,6618,6702,34428,34354,34330,36129,35695,36000,38490,38529,38713,38529,38708,38713,38708,38729,38713,38311,38366,38013,40366,40320,40228,37075,37221,36903,40677,40597,40470,5144,5029,5381,5795,5876,5874,38750,38840,38727,3477,3367,3449,2533,2667,2576,10285,10405,10375,5639,6309,5797,38881,38805,38848,40228,40320,40225,38246,37988,37739,38750,38932,38840,38932,38910,38840,42421,42445,42355,42049,41952,41813,42421,42355,42371,1462,1343,1440,1161,705,706,2227,2186,2360,6874,6726,6864,5874,6095,5943,7164,7587,7329,8300,8221,8610,33512,33547,33521,41039,40933,40780,40780,40933,40670,41845,41774,41410,4398,4748,4763,4868,4909,4950,4950,4881,5137,4269,4748,4398,4269,4398,4002,38932,39162,38910,12259,11816,12303,8943,8736,8728,29976,29743,29804,30088,29743,29976,43695,43800,43649,10815,11211,11067,11067,11211,11153,30445,30836,30649,29812,30298,30187,4860,4847,4870,4663,4282,4514,3351,3367,3477,3198,3243,3367,5304,5381,5497,10405,10637,10593,39139,38976,39058,38838,38844,38539,3170,3291,3255,8827,8619,8610,9521,9707,9551,4748,4909,4868,38844,38881,38848,1874,1992,1990,1519,1462,1440,1651,1582,1801,2385,2325,2458,1876,1874,1990,2855,2637,2576,6710,6726,6874,6618,6676,6702,7698,7680,7509,7698,7779,7680,6734,6676,6503,7680,7431,7509,7884,8357,8397,8970,9686,9200,34873,34988,35195,33319,33126,33249,6253,6380,6346,6160,6380,6253,35208,35198,35142,35197,34873,35195,34263,34202,34438,34333,34263,34438,35136,35208,35142,40151,39486,40074,8221,8030,8076,6927,6892,6874,8300,8030,8221,34010,34081,33893,34010,33893,33870,30459,30744,30848,43555,43695,43649,43687,43695,43555,31940,31990,31885,32036,31990,31940,31567,31450,31468,35136,35142,35020,40933,40985,40962,41075,40985,40933,41081,40985,41075,42869,42906,42816,42828,42976,43082,705,609,706,1221,1230,1316,8879,9200,9062,10319,10285,10375,10405,10558,10637,40220,40175,40074,40169,40175,40268,40762,40628,40758,43479,43381,43360,42655,42788,42738,42873,42788,43002,507,414,504,31753,31567,31736,39229,39139,39295,42929,43017,43435,3095,3170,3129,3732,4269,4002,3095,3129,3076,36377,36243,36192,36129,35880,35695,36929,36753,36897,37107,36897,37226,36670,36776,36903,37075,36776,36805,362,46,598,414,346,400,10102,10191,10093,10802,10778,10735,42084,41889,42066,40921,40811,41397,42195,42066,42204,2325,2227,2360,2855,2914,2637,33208,32784,33114,42192,42195,42382,2312,2227,2325,6676,6748,6873,6734,6748,6676,41516,40963,41706,7794,8357,7884,7125,7431,7152,36550,36192,36528,35695,35368,35293,1438,1564,1582,2053,2150,2122,11816,11188,11331,2987,3263,3291,3018,3076,2671,36753,36684,36637,36786,36684,36753,1343,1221,1316,1582,1564,1716,1651,1801,1791,34428,34255,34354,34354,34255,34102,10495,10558,10461,2122,2150,2186,7164,7160,7587,6899,7125,7152,35208,35735,35306,35101,35136,35020,35101,35020,34938,40985,41081,40962,40767,40676,40597,42445,42639,42505,42371,42183,42196,42371,42502,42490,42192,42066,42195,42192,42084,42066,6328,5943,6095,5795,5873,5876,5492,5707,5380,34438,34202,34157,34103,34010,33949,41845,41410,41778,2219,2122,2186,2533,2421,2520,2439,2421,2533,43117,43017,42885,43531,43635,43555,3095,2964,3170,2895,3018,2671,5874,5943,5793,40320,40410,40470,40228,40091,40437,42237,42196,42099,6980,6892,6927,6748,6866,6873,6714,6866,6748,35647,35368,35695,34873,34428,34330,5492,5566,5707,43890,43911,43654,43082,42976,43170,37046,37107,37267,38246,38399,37988,38490,38425,38246,38439,38425,38490,38833,38490,38713,38773,38713,38729,38773,38729,38851,38838,38880,38844,38844,38880,38881,38881,38972,38805,37796,37410,37221,1049,1221,1343,67,46,362,10654,10735,10637,1720,1732,1681,1874,1732,1791,1564,1462,1519,1903,1990,2053,7794,7884,7781,7433,7509,7431,7698,7509,7457,34438,34157,34215,42788,42873,42738,42783,42788,42655,42783,42655,42856,42190,42192,42382,43066,43314,43077,41848,41706,41934,41848,41516,41706,31567,31753,31750,32219,32267,32140,31736,31468,31629,32219,32140,31990,34215,34081,34103,38851,38729,38840,38910,39162,39010,42639,42445,42421,43748,43269,43459,5380,5707,5442,6406,6513,6389,5795,5785,5738,36377,36203,36243,37107,37226,37267,4924,4860,5029,4847,4683,4711,5144,5381,5304,5144,5304,5259,1161,1231,705,602,536,663,507,446,414,292,259,346,346,259,362,40770,40762,40758,40175,40169,40074,40770,40758,40789,1438,1462,1564,2219,2186,2227,2914,2970,2828,3243,3269,3367,38976,39139,39229,38851,38944,38820,38838,38539,38855,10191,10285,10319,10558,10654,10637,10276,10285,10102,42747,42639,42421,2312,2325,2421,6779,6710,6874,7014,6980,7136,7014,7136,7160,11190,11102,11188,11188,11102,11029,35368,35274,35195,35586,35274,35368,35197,35274,35416,43733,43591,43029,38880,38972,38881,3542,3477,3610,37107,36929,36897,37046,36929,37107,42084,42085,41797,43006,42816,42906,42101,42099,41952,42371,42490,42421,40268,40175,40220,4282,4445,4514,3714,3608,3920,4821,5410,5137,6503,6676,6618,36929,36884,36753,37051,36884,36929,2339,2312,2421,6779,6874,6892,6866,6899,7152,6503,6545,6380,40313,40268,40220,40921,40770,40789,40677,40767,40597,41081,41288,41003,41774,42049,41813,1903,2053,2122,1720,1651,1732,1732,1651,1791,10495,10654,10558,42190,42085,42084,42077,42085,42190,3608,3542,3610,39229,39295,39621,40288,40268,40313,1792,2037,1986,1792,1986,1672,6872,6779,6892,7164,7014,7160,35274,35197,35195,36203,36152,36243,41039,41075,40933,41397,40811,41104,41966,41848,41934,9046,8943,9041,7587,7685,7436,9222,9273,9380,10722,10802,10735,10947,10815,11067,33249,33126,33074,32285,32269,32195,33319,33359,33367,33359,33708,33367,36884,36786,36753,36893,36786,36884,42989,42998,42906,43234,42998,42989,43210,42989,43082,534,536,602,534,602,706,2312,2219,2227,2444,2439,2533,2444,2533,2576,33521,33263,33512,32081,32219,31990,430,446,507,42995,42885,42873,43130,43117,42885,42995,42873,43002,43314,43066,43792,43911,43765,43150,9981,9707,11029,1981,2219,2312,6872,6892,6980,5943,6328,6028,40288,40169,40268,41423,41104,41516,43586,43459,43591,7695,7781,7698,10276,10405,10285,7695,7698,7457,42085,41982,41934,42077,41982,42085,42502,42371,42196,43002,42788,42783,42130,42049,41774,2828,3097,2820,2568,2637,2476,5639,6160,6309,36673,36528,36684,8784,8768,8827,8784,8827,8943,33367,33436,33403,43751,43586,43591,43613,43531,43433,43695,43823,43800,43568,43433,43479,36786,36673,36684,36773,36673,36786,292,346,414,7457,7509,7433,6899,6866,6741,1719,1553,1561,7014,6872,6980,7031,7164,7098,35136,35101,35208,36805,36670,36337,35014,35101,34938,35014,34938,34927,34157,34081,34215,6529,6503,6456,36123,35735,35917,38855,38366,38742,40767,40884,40780,40593,40677,40470,40410,40320,40366,43800,43823,43869,43908,43823,43695,3018,2944,3095,2814,2895,2671,5259,5304,5356,5874,5793,5795,6579,6513,6406,4456,4282,4663,3714,3639,3608,3608,3525,3542,4456,4663,4683,4748,4846,4909,4909,4881,4950,3263,3327,3291,11228,11190,11188,11102,10702,11029,38425,38399,38246,38833,38439,38490,38820,38713,38773,38851,38840,38910,43765,43733,43029,43314,43201,43170,1726,1876,1903,2439,2339,2421,2637,2568,2576,3097,3143,2820,10654,10722,10735,10461,10558,10405,10285,10191,10102,40437,40091,39983,43612,43435,43017,43635,43687,43555,2037,2101,2318,1792,2101,2037,6513,6726,6389,7031,6872,7014,6714,6748,6734,40151,40074,40169,38972,39727,39106,38880,38978,38972,38855,38539,38366,38855,38937,38871,42502,42196,42237,87,55,267,10495,10722,10654,10802,10815,10947,43435,43568,43479,36291,36211,36203,37267,37226,37323,6726,6446,6389,5259,5356,5293,40288,40151,40169,40288,40313,40272,4678,4846,4748,6060,6380,6160,38954,38978,38880,1799,1732,1874,1651,1624,1582,1462,1246,1343,609,534,706,1876,1990,1903,8509,8457,8354,7139,7431,7125,8357,8457,8721,7794,7781,7695,41982,41966,41934,41848,41814,41516,42190,42084,42192,42049,42101,41952,42180,42101,42130,41288,41081,41075,34081,34010,34103,1799,1876,1726,34927,34796,34669,35917,35735,35208,41383,41288,41075,4846,4881,4909,8768,8619,8827,8728,8784,8943,43612,43534,43435,43435,43534,43568,42747,42655,42639,42995,43130,42885,280,292,414,536,430,663,386,549,705,32457,32653,33036,32457,32285,32326,43624,43613,43568,43568,43613,43433,31753,32036,31940,34772,34618,34656,30836,30626,30649,42382,42215,42409,43170,43201,43082,43210,43201,43314,3644,3639,3714,3542,3351,3477,1231,386,705,32324,32457,32416,259,67,362,280,414,290,39717,39295,39700,40220,40945,40313,567,705,549,42890,42747,42421,42655,42747,42879,3639,3525,3608,39717,39700,39852,10344,10276,10215,10495,10324,10722,8728,8619,8768,33319,33311,33126,34335,33708,34255,37051,36893,36884,36129,36000,36152,37051,36929,37046,11228,11084,11190,11190,11084,11102,43733,43751,43591,43779,43751,43733,43717,43687,43635,43717,43635,43613,2568,2444,2576,2476,2444,2568,6749,6710,6779,6899,6985,7125,6610,6714,6734,6529,6734,6503,6741,6714,6725,40677,40884,40767,41050,40884,40677,10344,10461,10405,1720,1624,1651,1599,1624,1720,1799,1874,1876,34438,34618,34333,32281,32267,32219,1726,1553,1719,34857,34927,34669,35014,35246,35101,1493,1438,1582,7522,7794,7695,7471,7695,7457,5795,5793,5785,5356,5492,5293,36893,36773,36786,37118,36773,36893,42068,41966,41982,43006,42906,42998,6872,6749,6779,7164,7031,7014,7728,8076,7436,6741,6985,6899,11816,11228,11188,30088,30334,29743,30842,31035,31478,42068,41982,42077,40911,40762,40770,3458,3351,3542,5785,5793,5833,2444,2339,2439,2361,2339,2444,36211,36152,36203,34434,34428,34547,2895,2944,3018,2814,2944,2895,5833,5793,5943,6977,6749,6872,5730,5833,5943,6714,6741,6866,6503,6396,6456,41058,41039,41050,40884,41039,40780,41475,41410,41352,40593,40470,40410,36377,36192,36550,10324,10815,10722,10722,10815,10802,30298,30836,30445,496,430,536,496,536,534,496,534,498,5380,5293,5492,31736,32036,31753,32081,32036,32109,498,609,567,498,534,609,43344,43017,43117,42995,43105,43130,42856,43002,42783,42856,42655,42879,8619,8300,8610,43201,43210,43082,43066,43269,43855,32269,32150,31860,32457,32324,32285,32416,32639,32551,42859,42747,43011,38439,38399,38425,38698,38399,38439,38820,38773,38851,292,197,259,290,414,446,1799,1681,1732,1624,1493,1582,1643,1681,1799,7139,7125,6985,7367,7433,7431,34618,34857,34669,34927,35246,35014,34772,34857,34618,41606,41423,41516,43748,43459,43586,387,498,437,1508,1493,1624,7367,7139,6914,39010,38851,38910,38932,38976,39162,40635,40437,40692,38838,38895,38880,37075,36903,36776,3007,3143,3243,2987,3291,3170,2294,2814,2671,6028,6328,6406,5267,5259,5293,31231,31424,31288,2964,3095,2868,34010,33870,33949,39852,39700,40311,40272,40151,40288,41475,41145,41288,42101,42261,42237,6637,6914,6985,5950,6160,5639,38855,38895,38838,36211,36129,36152,36323,36129,36211,4881,4807,5137,4846,4795,4881,4269,4678,4748,4719,4678,4653,39162,38976,39229,38895,38954,38880,10461,10324,10495,10276,10344,10405,10102,10093,9611,30836,31231,30626,42180,42261,42101,4678,4795,4846,36406,35931,35908,36406,36222,36509,38092,37796,37979,40911,40770,40921,43344,43117,43130,3639,3587,3525,3525,3458,3542,2545,2661,2828,3942,3644,3714,3942,4445,4282,4924,5029,5144,4924,5144,5121,39338,39162,39229,1681,1599,1720,1367,1462,1438,1643,1599,1681,7433,7471,7457,8354,8457,8357,10006,10102,9611,7367,7471,7433,7367,7431,7139,41615,41475,41288,40514,40593,40410,41058,41075,41039,42130,42101,42049,6529,6610,6734,6456,6610,6529,35854,35647,35880,35880,35647,35695,41022,40911,41135,3644,3587,3639,5122,5144,5259,5122,5259,5267,35178,34873,35197,32416,32457,32639,1643,1726,1719,1903,2122,1981,42261,42502,42237,42130,41774,41845,10791,11102,11084,10791,10702,11102,9521,9304,9380,8784,8728,8768,8619,8563,8300,43687,43908,43695,43534,43624,43568,2828,2661,2914,3007,3243,2991,35702,35586,35647,36550,36528,36673,36550,36673,36732,36406,35908,36222,39621,39295,39717,38988,39010,39020,40945,40220,40762,34473,34618,34438,36509,36605,36406,33521,33603,33263,42546,42502,42261,43779,43748,43586,43765,43874,43733,43911,43874,43765,32036,32081,31990,32190,32081,32109,32036,31736,31772,260,290,446,496,387,430,1367,1438,1399,3266,3367,3351,2868,3095,2944,4758,4719,4653,2868,2944,2814,43063,43006,42998,43063,42998,43234,42989,43210,43234,260,446,430,280,197,292,32298,32150,32269,33311,33319,33367,42859,42879,42747,43141,43105,43002,43002,43105,42995,43777,43717,43624,43624,43717,43613,43687,43717,43777,5707,5738,5442,6446,6726,6710,6292,6389,6332,6977,6872,7031,169,197,280,8509,8796,8457,10344,10324,10461,42228,42068,42077,41966,41814,41848,41022,40913,40911,42228,42077,42190,42213,42130,42332,42180,42394,42261,9315,9304,9521,6610,6725,6714,6641,6725,6610,35647,35586,35368,35854,35880,36056,43246,42382,42409,5738,5553,5442,36377,36291,36203,36323,36291,36480,40583,40437,40635,41050,41039,40884,55,141,1211,3625,3573,3177,2964,2868,2873,38376,38004,38306,36605,36805,36337,1399,1438,1493,1726,1643,1799,2122,2219,1981,7436,8076,7488,7436,7488,7440,8354,8357,8234,7193,7367,6914,1399,1493,1508,34428,34335,34255,34434,34335,34428,42027,41814,41966,3325,3266,3351,197,67,259,8357,7933,8234,32784,32329,33114,35586,35416,35274,36056,35880,36129,2534,2476,2637,3007,2820,3143,2876,2820,3007,38376,38478,38520,36406,36605,36337,34772,34927,34857,2552,2637,2661,40437,40514,40410,40680,40514,40583,3266,3198,3367,37323,37226,37761,41475,41615,41410,40679,40677,40593,3587,3458,3525,3248,3165,3198,3644,3544,3587,4046,3942,4282,4456,4683,4924,8586,8879,9062,38988,38851,39010,38988,38944,38851,38820,38833,38713,38152,37175,37988,39010,39162,39020,39207,38972,38978,38895,39000,38954,38855,38871,38895,38599,38366,38311,38311,38004,38376,39020,39162,39272,38871,39000,38895,5267,5380,5296,5122,5121,5144,8509,8586,8796,8357,7794,7933,34473,34438,34413,33521,33788,33603,33805,33788,33521,42068,42027,41966,42372,42228,42190,42372,42190,42382,7329,7098,7164,7316,7436,7440,34438,34215,34413,35830,35747,35854,36548,36550,36732,43779,43586,43751,567,609,705,1508,1624,1599,1508,1599,1643,34413,34215,34359,290,169,280,197,89,67,498,387,496,1230,386,1231,4795,4762,4881,4678,4719,4795,2987,3170,2964,32081,32190,32219,31772,31736,31629,39338,39229,39621,43006,43275,42409,43234,43210,43272,43141,43002,42856,43141,42856,43057,42747,42890,43011,43272,43210,43314,9078,8943,9046,33403,33311,33367,7212,7098,7329,6389,6292,6406,9304,9222,9380,9719,9551,9707,31629,31468,31424,31629,31424,31420,35854,35747,35647,36056,36129,36104,40911,40913,40762,39621,39717,39889,40911,40921,41135,4719,4762,4795,1230,1221,386,31420,31424,31231,43057,42859,43011,37267,37051,37046,36893,37051,37118,35545,35416,35586,3456,3544,3644,9315,9222,9304,10102,10215,10276,10006,10215,10102,31447,31420,31231,43748,43747,43269,43874,43779,43733,8728,8563,8619,8620,8563,8728,10006,10324,10215,8316,8586,8509,40151,40311,39700,2873,2987,2964,3001,2987,2873,6446,6710,6463,36323,36211,36291,35702,35545,35586,36291,36377,36480,40680,40679,40593,40680,40593,40514,41048,41050,40677,41801,41615,41288,3544,3458,3587,2538,2552,2482,1246,1462,1367,1598,1508,1643,41299,41075,41058,42130,42213,42180,1981,2312,2339,7078,6977,7031,7316,7212,7329,7316,7329,7436,43777,43908,43687,43777,43624,43750,33436,33367,33821,34547,34428,34984,34473,34656,34618,34555,34413,34359,41615,41778,41410,2545,2552,2661,2476,2461,2444,2876,3007,2991,6060,5950,5994,6725,6641,6741,3165,3243,3198,5087,5121,5122,5267,5293,5380,7078,7031,7098,41814,41606,41516,42223,42027,42068,42223,42068,42228,43781,43747,43748,40151,40272,40384,387,358,430,324,358,387,437,498,420,32411,32269,32324,32411,32324,32416,32109,31772,31775,32172,32109,32175,31772,32109,32036,32190,32281,32219,33788,33949,33870,324,437,420,32172,32281,32190,43063,43113,43006,43261,43113,43063,43241,43063,43234,43221,43344,43130,43057,42856,42879,43057,42879,42859,34984,34428,34873,35702,35647,35747,43379,43272,43314,43221,43130,43105,2538,2534,2552,2552,2534,2637,35902,35830,35854,36548,36377,36550,32551,32411,32416,32457,33036,32639,42546,42490,42502,8354,8353,8509,8642,8970,8879,7522,7695,7471,8353,8234,8316,42332,42130,41845,5730,5785,5833,34183,33708,34335,43750,43624,43534,1276,1367,1399,8661,8620,8728,9551,9315,9521,9222,9315,9165,91,160,141,141,160,978,7150,7078,7098,8076,8030,7488,38510,38478,38376,38871,38937,39000,40583,40514,40437,38599,38706,38366,36975,37075,36805,38706,38742,38366,4485,4456,4924,3353,3458,3544,3353,3349,3458,5087,4924,5121,38931,38833,38820,38931,38820,38944,38931,38944,39098,38931,39098,38903,38988,39098,38944,38742,38785,38855,2101,2275,2671,1660,1792,1573,6463,6710,6749,7150,7098,7212,55,91,141,6028,6406,6292,6000,5730,5943,38833,38931,38903,38785,38937,38855,3248,3198,3266,2442,2461,2534,3349,3351,3458,6411,6446,6463,6396,6503,6380,36034,35854,36056,2361,2461,2298,2534,2461,2476,33263,32823,33424,35702,35501,35545,35545,35501,35416,38988,39020,39098,40384,40272,40313,3177,3573,3263,4719,4758,4762,4762,4807,4881,6471,6610,6456,4741,4758,4653,36323,36104,36129,36732,36673,36773,36732,36773,37118,40389,40384,40313,40945,40762,40913,45,738,978,43865,43750,43534,7221,7150,7212,6463,6749,6415,7488,7656,7460,8030,7656,7488,41998,41606,41814,2461,2361,2444,2538,2482,2442,8234,8353,8354,7522,7471,7193,33727,33805,33521,33727,33521,33547,36328,36104,36323,35497,35365,35501,41271,41299,41058,41043,41048,40677,38978,38954,39207,41397,41104,41423,40769,40677,40679,42394,42500,42443,42332,42309,42213,42213,42309,42180,41845,42366,42332,34434,34417,34335,35365,35197,35416,34413,34555,34473,36705,36509,36579,34359,34215,34278,7221,7212,7316,41541,41397,41423,3165,2991,3243,3031,2991,3165,2987,3001,3263,2873,2868,2791,5553,5738,5785,5267,5087,5122,5553,5785,5572,42608,42546,42261,33424,32823,33208,32109,32172,32190,31657,31772,31629,43865,43839,43750,43141,43221,43105,43289,43221,43213,43221,43141,43213,324,260,358,358,260,430,324,387,437,9981,9719,9707,11228,10791,11084,31478,31382,31860,35501,35365,35416,35702,35747,35791,35246,34927,34772,36605,36975,36805,115,169,290,31420,31643,31629,31447,31643,31420,3001,3177,3263,2791,2868,2814,5280,5087,5267,5572,5785,5730,3353,3544,3456,33805,33949,33788,33988,33949,33805,2099,2275,1851,6411,6332,6389,6411,6389,6446,31204,31447,31231,33424,33208,33363,36104,36034,36056,36175,36034,36104,40772,40769,40680,40680,40769,40679,2154,1981,2339,1719,1598,1643,1348,1276,1399,6568,6641,6610,6396,6380,6060,35791,35747,35830,3349,3325,3351,5296,5380,5409,2828,2820,2545,2361,2154,2339,2820,2715,2545,7066,6977,7078,7199,7221,7316,8433,8300,8563,34567,34656,34473,34567,34473,34555,10215,10324,10344,8970,9200,8879,30836,31204,31231,1561,1598,1719,2803,3177,3001,2746,2791,2814,5409,5380,5442,5692,5572,5730,7157,7221,7199,41606,41541,41423,41135,41007,41022,41537,41541,41591,42014,41814,42027,1348,1399,1508,420,498,567,34547,34417,34434,34544,34417,34547,35178,35197,35365,34278,34215,34103,3325,3248,3266,34492,34555,34359,33677,33727,33547,33677,33547,33512,42498,42372,42382,42890,42421,42490,42309,42394,42180,41845,41778,42366,41058,41050,41053,7066,7078,7150,6074,6028,6292,6373,6396,6265,35497,35178,35365,36034,35902,35854,36175,35902,36034,41007,40945,40913,40317,39889,39852,41007,40913,41022,37323,37051,37267,36548,36480,36377,6074,6292,6332,41053,41050,41048,39207,38954,39000,38706,38732,38742,38742,38839,38785,38785,38946,38937,38937,39274,39000,38599,38635,38706,38376,38520,38599,38478,38510,38585,38520,38635,38599,38520,38478,38585,2907,3001,2873,38152,37988,38399,38833,38817,38439,38903,38817,38833,39162,39327,39272,38732,38839,38742,39162,39338,39327,38839,38946,38785,43747,43855,43269,43272,43241,43234,42498,42400,42372,43866,43781,43748,43866,43748,43779,38581,38152,38399,43383,43241,43272,260,115,290,420,567,372,32172,32293,32281,32175,32293,32172,31657,31629,31643,31657,31643,31587,43792,43379,43314,372,567,549,1276,1246,1367,1356,1348,1508,1356,1508,1445,5409,5442,5445,5442,5553,5445,34492,34567,34555,34656,34844,34772,34278,34103,34349,39852,39889,39717,40311,40151,40384,9087,9046,9222,9087,9222,9165,32823,32784,33208,34384,34278,34349,169,89,197,47,115,260,160,147,978,64,147,160,31775,31657,31693,40389,40311,40384,43129,43011,43177,43221,43289,43344,7157,7066,7150,7157,7150,7221,7316,7440,7199,35497,35501,35525,6411,6311,6332,6752,6749,6977,6396,6471,6456,7193,7471,7367,6373,6471,6396,35902,35791,35830,36018,35791,35902,40857,40389,40313,41135,40921,41528,1196,1246,1276,34103,33949,34349,42089,42014,42027,41528,40921,41397,43702,43383,43379,43874,43866,43779,32150,31478,31860,31965,31478,32150,32298,32269,32411,33126,33036,32653,4758,4741,4762,4653,4678,3892,3892,4516,4603,39327,39338,39393,39301,39207,39274,5553,5572,5499,5445,5553,5499,41053,41048,41056,4741,4807,4762,8620,8484,8563,39393,39338,39621,39207,39349,38972,42400,42228,42372,42400,42223,42228,40311,40434,39852,40461,40389,40525,39866,39393,39621,39327,39288,39272,2791,2907,2873,3732,4002,3625,2746,2907,2791,6000,5943,6028,40685,40772,40680,40685,40680,40583,6471,6568,6610,6373,6568,6471,40996,40313,40945,41537,41397,41541,41043,40677,40769,34567,34844,34656,34690,34844,34567,3325,3246,3248,2820,2876,2715,3349,3246,3325,3456,3644,3942,3456,3209,3354,4046,4456,4043,5280,5267,5296,5280,5296,5409,6163,6219,6233,7453,7440,7488,41591,41541,41606,41591,41606,42260,33821,33367,33708,34600,34544,34547,34384,34359,34278,34384,34492,34359,36780,36480,36548,36455,36480,36780,41299,41383,41075,41271,41383,41299,42223,42089,42027,42189,42089,42223,43213,43141,43057,43213,43057,43202,43275,43006,43113,43379,43383,43272,43855,43747,43781,43129,43057,43011,6315,6311,6411,6219,6311,6233,41053,41271,41058,40772,40886,40769,40899,40886,40772,31657,31775,31772,33363,33512,33424,31587,31643,31447,47,89,115,420,95,324,95,372,36,33436,33311,33403,42443,42261,42394,42890,42490,42876,115,89,169,47,260,324,31693,31587,31447,41801,41778,41615,2538,2442,2534,1548,1508,1598,3031,3165,3248,6074,6000,6028,36480,36347,36323,35525,35501,35702,35178,34984,34873,36455,36347,36480,40691,40635,40692,3732,3625,3419,2415,2746,2814,33490,33436,33821,1246,1049,1343,1348,1196,1276,1548,1598,1561,6311,6315,6233,7656,7716,7681,7139,6985,6914,8561,8879,8586,1726,1903,1553,7288,7199,7440,6985,6741,6637,41187,41132,41135,41998,41814,42014,9326,9315,9551,8417,8433,8484,8484,8433,8563,37196,37174,37637,36455,36328,36347,38817,38698,38439,38768,38698,38815,38698,38817,38815,39098,39020,39264,39020,39272,39264,38635,38732,38706,38839,38969,38946,39301,39349,39207,39301,39400,39349,38520,38718,38635,38585,38718,38520,38376,38306,38510,1250,1196,1348,33677,33805,33727,34492,34690,34567,33677,33512,33518,38698,38581,38399,38004,37796,38306,38718,38732,38635,42089,41998,42014,42189,41998,42089,6637,6741,6641,38306,38275,38373,5379,5280,5409,5762,5692,5730,6568,6637,6641,6265,6396,6060,40886,41043,40769,40899,41043,40886,38306,37796,38092,3063,3031,3248,5379,5409,5445,8587,8484,8620,33114,33190,33208,42500,42394,42309,5620,5572,5692,6219,6074,6332,6219,6332,6311,36347,36328,36323,36175,36328,36471,39727,38972,39349,40688,40685,40635,40635,40685,40583,39264,39272,39288,39264,39296,39112,41383,41801,41288,42668,42608,42443,41155,41271,41053,4807,4821,5137,4741,4716,4807,3625,3177,3419,39327,39451,39288,2298,2154,2361,2821,2876,2991,36509,36705,36605,36123,35908,35735,35208,35101,35246,40389,40461,40311,40973,40945,41007,41132,41007,41135,4653,4716,4741,43261,43063,43241,43777,43839,43908,43750,43839,43777,43612,43017,43344,41528,41397,41537,41043,41056,41048,41166,41056,41043,2275,2294,2671,2099,2294,2275,2415,2294,2248,36328,36175,36104,37174,37051,37323,41666,41528,41537,41666,41537,41591,41666,42260,41788,9981,11029,10702,32456,32298,32411,32456,32411,32551,43383,43261,43241,43402,43261,43425,8736,8661,8728,7439,7453,7460,9078,9046,9087,32267,33114,32329,34047,34349,33949,3031,2880,2991,5499,5379,5445,5499,5572,5531,32484,32456,32551,38209,37226,38152,43604,43612,43344,43213,43288,43289,43129,43202,43057,43285,43202,43129,4282,4456,4046,3456,3441,3209,3353,3246,3349,3031,2881,2880,4716,4821,4807,38969,38937,38946,34384,34543,34492,33988,33805,33677,9333,9326,9551,10379,9981,10702,33281,33126,33311,35525,35702,35656,33490,33281,33436,2545,2482,2552,2337,2482,2407,9220,9165,9315,2715,2821,2645,2880,2821,2991,4924,5087,4485,5531,5572,5620,37174,37118,37051,37196,37118,37174,2298,2461,2442,5620,5692,5714,6977,7066,6752,9012,9078,9087,35246,34772,34844,40774,40899,40772,40774,40772,40685,42876,42490,42862,41166,41155,41056,41056,41155,41053,41933,41801,42132,7017,7066,7157,7460,7453,7488,8030,7716,7656,41379,41383,41271,42443,42608,42261,35656,35702,36018,36780,36548,36732,1548,1445,1508,1142,1049,1196,1553,1903,1981,3105,3246,3353,41562,41187,41135,41594,41666,41788,2337,2298,2442,2821,2715,2876,2640,2715,2645,5087,5280,5151,5730,6000,5762,8336,8433,8417,8336,8300,8433,34423,34543,34384,34423,34384,34349,8587,8620,8661,42360,42189,42223,42657,42498,42730,3246,3139,3248,7491,7933,7522,7522,7933,7794,7144,7522,7193,7144,7193,6933,42380,42223,42400,6373,6483,6568,6060,6160,5950,41132,40973,41007,41125,40973,41132,33436,33281,33311,34061,33827,33821,5280,5379,5151,5966,6000,6074,40691,40688,40635,41281,41227,41155,41166,41043,41407,41155,41227,41271,39015,38969,38839,38718,38653,38732,38585,38653,38718,38526,38653,38585,38526,38585,38510,38526,38510,38373,38581,38595,38152,38698,38684,38581,38815,38817,38998,38817,38903,38998,38903,39104,38998,3139,3063,3248,38373,38510,38306,38903,39098,39104,43202,43288,43213,43285,43288,43202,32639,32484,32551,32456,32275,32298,31708,31250,31478,31478,31250,30744,32526,32484,32623,34047,33988,33984,37796,37952,37979,39104,39098,39112,39098,39264,39112,40781,40774,40688,39015,38839,38732,42423,42380,42400,42423,42400,42498,91,64,160,147,45,978,1660,2101,1792,2837,3001,2907,4603,4703,4716,4716,4703,4821,2837,2907,2746,8632,8587,8661,7681,7563,7656,32623,32484,32639,34471,34417,34544,39451,39296,39288,42500,42309,42332,43325,43285,43129,1561,1445,1548,1196,1049,1246,1426,1445,1561,9012,8999,9078,9078,8736,8943,9326,9220,9315,9333,9220,9326,9333,9551,9613,35291,34984,35178,35291,35178,35497,40466,40311,40461,35702,35791,36018,37118,36780,36732,37196,36780,37118,40525,40466,40461,35111,35246,34844,34690,34492,34543,34468,34423,34349,37796,37221,37952,36975,36605,36705,1846,1553,1981,2337,2442,2482,2482,2545,2407,40688,40774,40685,39727,39349,39400,39327,39393,39451,39274,39207,39000,8215,8417,8342,8587,8417,8484,35497,35525,35563,8316,8509,8353,42862,42490,42546,10791,10379,10702,9799,9696,9719,32275,32150,32298,5994,5950,5929,4603,4716,4653,33750,33988,33677,33988,34047,33949,33308,33208,33190,32175,32109,31775,2640,2545,2715,3139,3058,3063,3105,3058,3139,3456,3354,3353,5379,5499,5151,2664,2837,2746,6219,6163,6074,7017,7157,7199,36123,36222,35908,36290,36222,36123,7453,7288,7440,7439,7288,7453,7563,7460,7656,41274,41166,41407,41227,41379,41271,42511,42500,42332,7681,7716,7633,34984,34600,34547,34471,34600,34615,1250,1348,1356,1846,1981,2154,7256,7017,7199,41666,41594,41528,40731,40525,40389,42156,41606,41998,42156,41998,42305,42838,42862,42546,42366,41778,42474,1792,1672,1422,2294,2415,2814,33490,33408,33281,33555,33408,33490,1250,1356,1243,1422,1672,579,6822,6752,7066,32526,32275,32456,32526,32456,32484,9799,9719,9981,8999,8736,9078,43674,43612,43604,43177,43011,42890,43177,42890,43229,39651,39727,39400,9613,9551,9719,9611,10093,9686,31587,31693,31657,31204,31693,31447,1851,2275,2101,6163,5966,6074,6315,6411,6463,33750,33677,33813,34577,34690,34543,42500,42668,42443,41933,41778,41801,41166,41281,41155,41274,41281,41166,40922,40899,40774,42695,42668,42782,2821,2880,2728,2298,2177,2154,40692,40437,40695,3016,3031,3063,2415,2664,2746,2708,3419,3177,2700,2683,2769,36908,36975,36705,7017,6822,7066,7288,7256,7199,7563,7439,7460,7435,7439,7563,41657,41801,41383,1553,1426,1561,1401,1426,1553,3105,3139,3246,8300,8336,8193,7569,7681,7633,34600,34471,34544,34615,34600,34657,5551,5499,5531,3118,3105,3353,5551,5531,5620,38768,38684,38698,38890,38684,38768,39067,38768,38815,38961,38815,38998,39174,38998,39104,39174,39104,39112,38918,39008,38732,38969,39274,38937,39301,39651,39400,38526,38725,38653,38618,38725,38526,38618,38526,38373,38275,38306,38092,42838,42546,42608,7933,8316,8234,8970,9494,9686,8325,8316,8133,34446,34335,34417,32155,31965,32275,33308,33363,33208,33518,33512,33363,39008,39015,38732,6415,6315,6463,5993,5966,6163,6415,6749,6752,41187,41125,41132,40466,40434,40311,40525,40434,40466,39333,39174,39112,43866,43855,43781,42657,42423,42498,2959,3016,3058,3058,3016,3063,2130,2248,2294,2130,2294,2099,5993,6163,6050,40922,40781,40691,40691,40781,40688,38383,38235,38152,38199,38275,38092,39296,39264,39288,6483,6637,6568,6483,6373,6360,41327,41379,41281,41281,41379,41227,9087,9165,9012,32267,32281,33114,42695,42608,42668,42695,42838,42608,38235,38209,38152,38203,38199,38092,39130,39274,38969,40695,40437,39983,3016,2881,3031,2147,2298,2337,2728,2881,2753,39451,39866,39490,40000,39621,39889,40996,40945,40973,42380,42360,42223,41562,41135,41528,43275,43113,43402,42366,42511,42332,42474,42511,42366,9611,9494,9294,7282,7256,7288,7282,7288,7439,7569,7563,7681,9696,9613,9719,9012,9165,9133,9846,9799,9981,32275,31965,32150,33126,33281,33036,1294,1445,1426,1294,1356,1445,34468,34349,34047,34577,34543,34423,35851,35917,35208,33036,33281,33120,4654,4843,4703,2803,3001,2837,8316,8561,8586,8642,8561,8325,33308,33518,33363,34474,34599,34678,37952,37720,37949,40000,39889,40166,6050,6163,6233,6582,6415,6752,35902,36175,36018,35499,35291,35497,36002,35917,35851,36222,36579,36509,41125,41124,40973,41125,41187,41165,43447,43289,43288,43447,43288,43285,42890,42876,42990,2147,2177,2298,2407,2545,2374,4843,5410,4821,34484,34446,34471,34471,34446,34417,34468,34599,34474,2700,2803,2837,2700,2837,2664,37957,37952,37949,2374,2545,2640,5752,5762,6000,5752,6000,5966,4703,4843,4821,4678,4269,3854,34312,34183,34335,33120,33281,33265,42423,42360,42380,42305,42360,42494,8215,8336,8417,9165,9220,9133,33555,33490,33821,2769,2683,2748,2803,2738,3177,37637,37174,37323,36947,36471,36455,2065,1846,2154,2082,2154,2177,6933,7193,6914,6360,6373,6265,41326,41274,41434,41379,41507,41383,42527,42500,42511,1370,1294,1426,34474,34423,34468,33308,33593,33518,33114,32281,32293,1660,1728,2101,2248,2288,2415,579,1672,738,1158,1142,1250,1250,1142,1196,95,420,372,95,47,324,6582,6822,6668,8417,8587,8512,35001,34600,34984,34446,34312,34335,34690,34818,34844,34474,34577,34423,34690,34577,34761,40695,39983,39727,41434,41274,41407,42305,41998,42189,2223,2337,2407,3118,3353,3354,8632,8661,8736,34061,33821,33708,34061,33708,34183,1422,1573,1792,6050,6233,6172,6822,7017,6668,34363,34312,34446,8732,8632,8736,8561,8642,8879,8325,8561,8316,41165,41124,41125,41165,41187,41607,9669,9613,9696,8999,8732,8736,9465,9613,9541,9494,9611,9686,9660,9611,9294,32415,32241,32275,31965,31708,31478,32499,32275,32526,386,1221,1049,10008,9846,9981,1573,1728,1660,41326,41327,41274,41274,41327,41281,32774,32639,32948,32774,32623,32639,32948,32639,33036,34112,34061,34183,40317,39852,40434,40317,40434,40502,31880,31708,31965,33555,33821,33808,38235,38274,38209,38209,38180,37226,38684,38595,38581,38789,38595,38684,38961,38998,39090,38998,39174,39090,39112,39296,39333,39333,39296,39463,39641,39651,39301,39015,39109,38969,38918,38732,38653,38918,38653,38725,38414,38373,38275,38414,38275,38254,38275,38199,38254,42990,42876,42862,42990,42862,42838,8533,8587,8632,8533,8512,8587,7282,7435,7331,33808,33821,33827,42782,42668,42500,42474,41778,41933,39008,39109,39015,1142,1039,1049,1294,1243,1356,1152,1243,1294,6695,6914,6637,7569,7435,7563,8030,8300,7716,34761,34818,34690,33988,33750,33984,38595,38383,38152,38203,38092,38097,38092,37979,38097,37979,37962,38097,43855,43792,43066,9133,9220,9167,33120,32948,33036,8193,8336,8215,33813,33677,33518,1152,1158,1243,2223,2147,2337,2728,2880,2881,5762,5714,5692,6233,6315,6172,6315,6415,6172,6302,6360,6213,6500,6662,6637,5929,5950,5345,38274,38180,38209,37979,37952,37962,39463,39296,39451,43612,43865,43534,43912,43865,43612,33265,33281,33408,43233,42990,43134,8375,8417,8512,8375,8342,8417,34003,33808,33827,33480,33265,33408,33593,33813,33518,6500,6637,6483,36471,36328,36455,34484,34471,34615,34484,34363,34446,34199,34112,34183,34061,34003,33827,4843,4768,5639,3854,4269,3732,37962,37952,37957,39490,39463,39451,4603,4654,4703,37221,37720,37952,5752,5714,5762,8930,8732,8999,33606,33408,33555,34818,34995,34844,36002,36290,36123,35111,34995,34963,34995,34818,34761,2147,2082,2177,2065,2082,2123,2047,2130,2099,5935,5752,5966,6172,5936,5897,36002,36123,35917,41124,40996,40973,41184,40996,41124,1728,1851,2101,1923,1851,1759,2099,1851,1923,2885,2881,3016,2700,2769,2803,3672,3854,3732,2311,2664,2415,6075,6265,6060,8173,8193,8215,8173,8215,8342,1243,1158,1250,1401,1553,1846,1392,1401,1306,8133,8316,7947,6695,6933,6914,6695,6637,6662,32774,32948,32861,32623,32696,32613,32499,32623,32613,32499,32526,32623,32265,32155,32241,32241,32155,32275,8608,8533,8632,4756,4768,4843,32071,32048,31965,32861,32948,32965,7890,7716,8300,7470,7435,7569,6012,6172,5897,33627,33606,33555,35001,34984,35068,41184,41165,41224,42360,42305,42189,42567,42360,42423,5935,5966,5993,5714,5551,5620,40857,40731,40389,39490,39417,39463,40692,40922,40691,40929,40695,40994,6500,6695,6662,35656,35563,35525,35660,35563,35656,41441,41507,41379,41441,41379,41327,43402,43113,43261,43390,43325,43177,43177,43325,43129,2728,2645,2821,40502,40434,40525,3105,2959,3058,2728,2641,2645,3092,3118,3090,3118,3354,3209,38180,37761,37226,35660,35499,35563,9012,8930,8999,8732,8608,8632,9167,9220,9333,9167,9333,9465,32774,32861,32696,33206,32948,33120,34343,34183,34312,42695,42782,42838,43390,43285,43325,42575,42474,42775,7282,7439,7435,6012,5935,5993,8342,8375,8261,8533,8375,8512,7682,7633,7716,40922,40774,40781,2179,2223,2136,1392,1370,1401,2089,2248,2130,2199,2288,2248,36290,36579,36222,37159,37166,37297,40590,40502,40525,40996,40857,40313,40997,40857,40996,7593,7569,7633,7593,7633,7682,1401,1370,1426,2065,2154,2082,7682,7716,7761,3092,2959,3105,2374,2223,2407,35563,35499,35497,34363,34343,34312,36455,36780,36997,42730,42498,42382,3672,3732,3279,4636,4756,4654,4654,4756,4843,38797,38918,38725,39008,39135,39109,39109,39130,38969,38618,38373,38446,38373,38414,38446,38414,38354,38446,38918,38990,39008,34430,34343,34363,33627,33555,33808,41666,41591,42260,38203,38222,38254,38199,38203,38254,39119,39174,39231,39119,39090,39174,38961,39067,38815,38408,38274,38383,38383,38274,38235,38180,38266,37761,39417,39333,39463,5585,5714,5712,5585,5551,5714,36579,36908,36705,40317,40166,39889,40590,40525,40726,40525,40731,40726,2959,2885,3016,6012,5993,6050,6012,6050,6172,5994,5968,6060,6386,6500,6483,5232,5950,5639,36997,36780,37196,38203,38097,38222,39135,39130,39109,40929,40692,40695,40929,40922,40692,6386,6483,6360,6798,7006,6933,42575,42527,42474,41326,41441,41327,41455,41441,41326,64,45,147,32621,32415,32499,32499,32415,32275,32155,32071,31965,32623,32774,32696,37087,36997,37335,38464,38383,38595,38222,38097,37962,43390,43177,43290,43481,43447,43285,32265,32071,32155,32048,31880,31965,42657,42567,42423,42305,42316,42156,42518,42567,42644,42474,42527,42511,41657,41383,41507,33206,33120,33265,43425,43261,43501,43275,43246,42409,2885,2792,2881,5551,5151,5499,32071,31880,32048,31708,31689,31250,40376,40166,40317,43604,43344,43289,39451,39393,39866,34995,35111,34844,34761,34577,34678,5712,5714,5752,5551,5416,5151,34003,34061,34169,33299,33593,33308,34678,34577,34474,33299,33308,33190,40468,40376,40317,40726,40731,40877,33885,33750,33813,9133,9065,9012,9465,9333,9613,43396,43246,43275,9726,9696,9799,10379,10008,9981,31880,31689,31708,35851,35208,35246,37347,37286,37295,39624,39490,39866,2047,2089,2130,2683,2700,2664,2769,2748,2803,2047,2099,1923,1728,1645,1851,5757,5712,5752,6172,6415,6135,5929,5968,5994,6075,5968,5816,41190,40997,40996,41184,41124,41165,7890,8300,8193,7593,7470,7569,7282,7039,7256,7890,8193,8020,34343,34199,34183,34657,34484,34615,42494,42316,42305,9167,9065,9133,2792,2753,2881,2683,2664,2498,37221,37075,37720,39641,39301,39274,42567,42518,42360,43486,42730,42382,5757,5752,5935,5585,5416,5551,9065,8930,9012,32643,33114,32293,40468,40317,40502,40877,40731,40857,8173,8342,8261,34430,34199,34343,4768,4835,5639,4516,4654,4603,37286,37075,36975,2311,2415,2288,2748,2738,2803,40468,40502,40645,39624,39417,39490,2123,2082,2147,2179,2147,2223,2199,2311,2288,1728,1549,1645,4756,4835,4768,33114,33299,33190,33593,33636,33813,35068,34984,35248,34484,34430,34363,34918,35001,34978,1207,1152,1294,1158,1039,1142,1287,1392,1306,7531,7593,7682,7531,7470,7593,34918,34657,34600,7890,7761,7716,8608,8375,8533,34169,34112,34199,34169,34061,34112,33606,33480,33408,2199,2248,2089,5835,5757,5935,5712,5416,5585,5835,5935,5897,40645,40502,40590,40906,40877,40857,40906,40857,40997,2374,2640,2502,2681,2641,2753,2885,2787,2792,2959,2929,2885,3118,3092,3105,3456,3942,3441,40645,40590,40719,39445,39417,39624,41441,41657,41507,41478,41657,41441,7628,7761,7710,8674,8608,8732,33543,33480,33606,34534,34430,34484,7522,7149,7491,8653,8970,8642,9294,9494,8970,9611,9660,10006,31693,32175,31775,33582,33593,33299,43447,43604,43289,43545,43604,43447,43402,43396,43275,42789,42689,42730,43702,43261,43383,32613,32621,32499,32384,32265,32241,32071,32177,31880,31880,32177,31689,32965,32696,32861,43425,43396,43402,43229,42890,42990,2183,2199,2029,1728,1573,1549,41562,41528,41788,1759,1645,1451,37286,36908,37295,37962,37957,38108,35516,35851,35246,35516,35246,35111,41434,41455,41326,41043,40899,41407,2640,2645,2502,1207,1287,1190,2607,2748,2683,2199,2089,1996,5757,5729,5712,5897,5935,6012,34200,34169,34199,33880,33627,33808,40719,40590,40726,40999,40906,40997,42845,42782,42500,42428,42474,41933,33338,33206,33265,33880,33808,34003,33749,33636,33738,33582,33636,33593,34761,34963,34995,42661,42500,42527,43792,43702,43379,43855,43834,43792,2912,2929,2959,38753,38725,38618,38753,38797,38725,38918,38949,38990,38990,39135,39008,39641,39759,39651,38753,38618,38632,38618,38558,38632,38446,38558,38618,38414,38254,38354,38354,38254,38222,39174,39333,39231,39119,39075,39090,39090,39075,38961,39333,39445,39231,1287,1294,1370,1287,1370,1392,7377,7331,7435,7377,7435,7470,34657,34534,34484,34430,34200,34199,35001,34918,34600,34984,35291,35248,43233,43229,42990,1401,1568,1306,39333,39417,39445,1061,1039,1158,7628,7531,7682,7628,7682,7761,8020,8193,8173,38692,38464,38595,38274,38266,38180,40000,40166,40140,35248,35291,35371,37637,37323,37761,40295,40166,40376,40719,40726,40871,38464,38408,38383,37957,37961,38108,38222,37962,38108,33338,33265,33480,8203,8261,8144,33996,33880,34003,33543,33338,33480,33996,34003,34169,33749,33885,33813,33749,33813,33636,2179,2123,2147,2136,2123,2179,41190,40999,40997,40871,40726,40877,40295,40376,40396,41788,41528,41594,41032,40906,40999,41606,42156,42260,4756,4636,4835,4835,5232,5639,3892,4603,4653,3892,4678,3854,37957,37949,37961,2607,2738,2748,2498,2664,2311,40401,40376,40468,8144,8261,8375,8930,8674,8732,8880,8674,8930,8880,8930,9065,8880,9065,8953,33543,33606,33627,2641,2728,2753,40506,40401,40468,40871,40877,40880,4516,4598,4654,37961,37949,37968,8203,8020,8173,7861,8020,7957,43248,43290,43229,42575,42661,42527,42596,42661,42575,42132,41801,41657,34855,34534,34657,36018,36175,36471,32384,32241,32415,32621,32613,32696,32621,32696,32760,9726,9799,9846,43481,43390,43578,43481,43285,43390,43481,43545,43447,1152,1061,1158,980,1061,966,1207,1294,1287,6582,6752,6822,7508,7377,7470,7508,7470,7531,2681,2753,2792,3092,2912,2959,3089,3209,3029,4598,4636,4654,6500,6412,6695,6213,6360,6265,6075,6060,5968,10008,9726,9846,36539,36018,36471,37286,36975,36908,39651,39759,39727,39641,39274,39515,43425,43501,43396,43834,43702,43792,2787,2885,2929,4793,5232,4835,32965,32948,33166,42260,42156,42430,43290,43177,43229,33166,32948,33206,33711,33543,33627,33711,33627,33880,844,919,1039,1039,919,1049,7710,7761,7890,34855,34657,34918,35729,35660,35656,40506,40468,40645,40880,40877,40906,40880,40906,41032,40999,41115,41032,33166,33206,33376,42990,42838,43134,2641,2564,2645,2521,2564,2641,37311,37331,37297,40716,40645,40719,39185,39231,39230,3209,3090,3118,4636,4793,4835,7522,7144,7149,33268,33299,33114,34599,34468,34392,34571,34200,34430,42689,42567,42657,42689,42657,42730,42382,43246,43486,8203,8173,8261,8953,9065,9167,43134,42838,42782,5816,5968,5929,6302,6386,6360,6326,6386,6302,41455,41478,41441,41066,40899,40922,37667,37720,37075,2199,2183,2311,1996,2089,2047,1996,2047,1956,40853,40716,40719,40996,41184,41190,40003,40695,39727,42320,42132,41657,2564,2502,2645,2168,2136,2223,1401,1846,1568,2521,2502,2564,2183,2498,2311,3279,3732,3419,35068,34978,35001,34571,34205,34200,35371,35291,35499,33207,33268,33114,42845,42500,42661,43161,43134,42782,7006,7144,6933,33984,33750,33885,35851,36119,36002,34205,34169,34200,34205,33996,34169,33543,33736,33338,33749,33984,33885,33738,33984,33749,43377,43246,43396,2909,2912,3092,35660,35546,35499,35636,35546,35660,35680,35516,35777,38063,37637,37761,35628,35729,35972,36018,35729,35656,37494,37667,37075,7861,7710,7890,7628,7546,7531,7017,7039,6668,7861,7890,8020,42545,42494,42518,42518,42494,42360,38797,38949,38918,38753,38802,38797,38759,38802,38753,38759,38753,38632,38759,38632,38676,38446,38354,38558,38354,38676,38558,38222,38214,38354,38108,38214,38222,38929,38949,38797,38108,38116,38214,39185,39119,39231,39185,39075,39119,39185,39067,39075,39075,39067,38961,38464,38666,38408,38408,38266,38274,39185,39230,39192,38949,39101,38990,2723,3177,2738,4501,4564,4598,4598,4564,4636,4636,4564,4793,39621,40000,39866,39101,39135,38990,41066,41008,40994,41224,41165,41380,40853,40719,40871,41618,41562,41788,41008,40929,40994,40929,41008,40922,2912,2787,2929,9107,8953,9167,9669,9541,9613,32177,32384,32609,32621,32384,32415,32265,32177,32071,32870,32696,32965,9726,9669,9696,9649,9669,9726,35516,35845,35851,38108,37961,38116,41605,41478,41434,41434,41478,41455,36,372,549,43702,43501,43261,42689,42644,42567,42518,42644,42745,42775,42596,42575,43390,43422,43578,43545,43481,43578,43656,43545,43616,43656,43604,43545,43785,43674,43604,43785,43912,43674,43674,43912,43612,33918,33711,33880,33736,33711,33918,43444,43377,43396,1846,2065,1568,1061,980,1039,541,386,1049,6798,6933,6695,35248,35192,35068,35395,35192,35248,2607,2723,2738,2607,2683,2590,39866,40000,40140,40853,40871,40880,9107,9167,9465,8880,8515,8674,7605,7546,7628,7508,7546,7605,34392,34468,34047,34678,34832,34761,35516,35680,35845,1645,1759,1851,1939,2454,2498,1549,1573,1422,6386,6412,6500,6075,6213,6265,6183,6213,6075,6326,6183,6287,1956,2047,1923,5835,5729,5757,3441,3942,4046,7256,7039,7017,37968,37949,37933,40396,40376,40401,39404,39274,39130,2723,2708,3177,2723,2607,2650,33268,33351,33299,34748,34678,34599,32997,33207,33114,1451,1549,1174,7282,7331,7127,35546,35371,35499,35636,35729,35628,41607,41618,42200,41046,40853,40880,42430,42316,42494,8375,8608,8400,40506,40396,40401,41046,40880,41032,37494,37075,37286,37933,37720,37855,37933,37949,37720,33422,33351,33268,37295,36908,37159,40506,40645,40713,41224,41190,41184,6213,6326,6302,6412,6326,6287,7006,7149,7144,8133,8653,8325,6798,7149,7006,2912,2812,2787,2681,2521,2641,3090,3010,3092,3209,3089,3090,3441,4046,3425,37855,37720,37716,40140,40166,40312,1050,1061,1152,34978,34855,34918,34978,35068,35129,34748,34599,34583,34748,34832,34678,42596,42740,42661,43390,43290,43399,42775,42740,42596,42845,42810,42874,1207,1050,1152,1568,2065,1513,2304,2374,2502,35565,35371,35546,43290,43248,43399,43656,43701,43604,33351,33582,33299,3089,3010,3090,37716,37720,37667,43229,43233,43248,2733,2792,2787,5936,5729,5897,7250,7331,7377,7508,7531,7546,35729,35636,35660,35565,35636,35628,37159,36908,37166,35376,35516,35111,37711,37716,37667,37166,36908,37042,40312,40166,40295,40713,40645,40716,40713,40716,40849,42789,42745,42689,43501,43444,43396,43471,43444,43562,43715,43501,43896,3010,2909,3092,37494,37286,37347,41115,41046,41032,41380,41165,41607,43248,43233,43194,34571,34430,34534,33376,33206,33338,33657,33738,33636,42845,42914,42782,2054,2065,2123,6326,6412,6386,5816,5929,5396,2168,2223,2374,5897,5729,5835,6135,6415,6582,37473,37494,37347,36964,37042,36579,41115,40999,41151,33736,33543,33711,43194,43233,43134,980,844,1039,1151,1050,1207,1190,1287,1306,34855,34662,34534,35175,35068,35192,35175,35192,35275,34900,34963,34761,34900,34761,34832,39192,39067,39185,39042,38890,39067,39067,38890,38768,39192,39230,39152,38818,38802,38759,38818,38929,38802,38802,38929,38797,38949,39137,39101,39326,39364,39135,39135,39364,39130,38818,38759,38676,38632,38558,38676,38354,38214,38676,38364,39072,38676,37968,38116,37961,1151,1190,1306,38890,38789,38684,37968,37974,38116,39067,39192,39152,7605,7628,7710,7769,7710,7861,34757,34748,34940,38789,38692,38595,37968,37933,37974,35636,35565,35546,36947,36455,36997,36997,37196,37335,43161,43194,43134,39137,39135,39101,40003,39727,39759,8515,8608,8674,42914,42996,42782,42740,42845,42661,42775,42474,42428,37335,37196,37637,40849,40716,40853,40497,40295,40396,39382,39583,39492,2812,2733,2787,2055,2054,2136,2650,2708,2723,2590,2683,2498,4485,5087,4594,3089,2977,3010,3010,2812,2909,2909,2812,2912,39364,39404,39130,7834,7769,7861,42745,42545,42518,41357,41190,41224,42745,42644,42689,2304,2502,2137,2136,2054,2123,1996,2029,2199,1956,2029,1996,1956,1923,1722,5345,5950,5232,41151,40999,41190,40919,40849,40853,41151,41190,41357,41008,41066,40922,41478,41605,41657,39732,39759,39641,39404,39515,39274,41733,41605,41434,34757,34832,34748,33582,33657,33636,33351,33504,33582,33422,33504,33351,33422,33268,33207,4501,4598,4516,4793,4579,5232,2708,3279,3419,38508,38266,38408,2733,2681,2792,2553,2681,2733,37473,37347,37295,37974,37933,37855,43686,43661,43656,43656,43661,43701,43701,43785,43604,43616,43545,43578,43616,43578,43659,43390,43399,43422,43422,43489,43510,2168,2304,2094,10008,9649,9726,9669,9649,9541,9282,9107,9465,8953,8994,8880,32384,32177,32265,32662,32384,32621,37087,36947,36997,36788,36947,36846,40919,40853,41046,40497,40396,40506,43758,43785,43701,4594,5087,5151,8203,7957,8020,7935,7957,7983,39515,39732,39641,42789,42730,43731,45,15,738,34978,34774,34855,35395,35248,35371,35490,35371,35565,1050,966,1061,1000,966,1050,1000,1050,1151,1207,1190,1151,34757,34900,34832,34963,35088,35111,34047,34250,34392,32957,32870,32965,33918,33880,33996,33918,33996,34247,33573,33657,33582,2573,2590,2454,1938,1956,1722,1923,1759,1722,9392,9465,9541,32957,32965,33166,35628,35490,35565,40844,40713,40849,41187,41562,41607,43422,43399,43489,43296,43248,43194,3441,3180,3209,3892,3854,3663,37974,37855,37861,2607,2590,2573,2708,2565,3279,9107,8994,8953,3180,3029,3209,37861,37855,37716,2304,2168,2374,2054,1893,2065,2136,2168,1982,2168,2024,1982,7957,7834,7861,7769,7605,7710,7352,7250,7377,7935,7834,7957,37367,37335,37727,39904,40003,39759,6391,6798,6695,6183,6326,6213,6183,6075,5868,8325,8653,8642,7614,7933,7491,7442,7491,7149,33736,33376,33338,33725,33376,33736,33504,33573,33582,35210,35088,34900,33278,33422,33207,35175,35129,35068,35275,35129,35175,34900,35088,34963,36290,36002,36672,37159,37297,37295,33984,34250,34047,42430,42156,42316,42430,42494,42545,37711,37667,37655,37711,37861,37716,35490,35395,35371,35767,35395,35490,35729,36018,36028,40308,40994,40695,41066,41407,40899,7101,7442,7149,33984,34238,34250,37295,37297,37331,42745,42841,42545,43486,43246,43377,36681,36471,36947,2977,2812,3010,37655,37667,37494,40711,40506,40713,40711,40713,40844,541,1049,919,8443,8515,8880,43661,43758,43701,43616,43686,43656,43714,43686,43616,43659,43578,43422,43686,43758,43661,43785,43900,43912,8949,9294,8970,32175,32643,32293,41107,41046,41115,41357,41380,41857,3663,3854,3672,3663,3672,3484,38692,38666,38464,38266,38063,37761,38789,38821,38692,38913,38821,38789,39152,39042,39067,39231,39457,39230,43834,43849,43702,43444,43471,43377,3484,3672,3279,38913,38789,38890,39231,39445,39457,39732,39904,39759,39515,39752,39732,39404,39546,39515,39364,39546,39404,39167,39137,38949,38960,38949,38929,38960,38929,38818,38960,38818,39072,38119,38214,38116,38119,38116,37974,38119,37974,38128,41107,41115,41197,32870,32760,32696,32957,32760,32870,4101,4043,4456,2904,2977,3180,3180,2977,3029,3029,2977,3089,38821,38736,38692,39209,39230,39382,1982,2055,2136,1893,2055,1889,36788,36681,36947,41197,41115,41151,38128,37974,37861,37622,37655,37494,4286,4101,4485,4485,4101,4456,38736,38666,38692,7352,7377,7508,6023,6135,6133,7983,7957,8203,42874,42996,42914,42428,41933,42132,42810,43059,43041,8307,8400,8515,9107,9063,8994,8980,9063,9107,43628,43444,43501,42874,42914,42845,950,844,980,1151,1306,1068,1068,1306,1076,7763,7769,7834,35395,35275,35192,34774,34662,34855,35411,35275,35395,35767,35490,35628,38666,38508,38408,36657,36539,36681,2573,2650,2607,1850,2183,2029,37476,37622,37494,37871,37861,37711,40707,40497,40506,40919,40844,40849,950,980,966,34774,34978,34916,38508,38410,38266,6104,6135,6023,5498,5416,5712,6391,6695,6412,5868,6075,5816,41320,41407,41066,2055,1893,2054,1834,1893,1889,1956,1938,2029,1451,1645,1549,36681,36539,36471,36788,36846,36735,41097,40919,41046,41237,41197,41151,41357,41224,41380,33422,33448,33504,32997,33278,33207,43161,43296,43194,7808,7763,7834,8299,8144,8375,8400,8608,8515,34247,33996,34205,32957,32662,32760,43171,43161,42782,42810,42845,42740,3301,3484,2954,2577,2573,2454,7808,7834,7935,33682,33738,33657,35193,35210,34900,4564,4602,4793,4379,4501,4516,40707,40506,40711,41097,41046,41107,33358,33448,33422,43171,42782,42996,4501,4602,4564,37871,37711,37877,37877,37711,37655,37331,37473,37295,35777,35845,35680,40707,40711,40840,39209,39152,39230,6010,5936,6172,6010,6172,6135,8067,7983,8203,8067,8203,8144,42789,42841,42745,41607,41562,41618,43840,42841,42789,43097,43171,42996,42775,42810,42740,42320,41657,41905,1000,950,966,844,804,919,937,950,1000,937,1000,891,7250,7127,7331,7605,7352,7508,7605,7769,7611,7614,8316,7933,6237,6412,6287,8299,8400,8307,9649,9392,9541,2502,2521,2137,3232,3180,3441,4602,4629,4793,32760,32662,32621,32957,33166,33180,43715,43628,43501,43471,43486,43377,43686,43900,43758,43510,43659,43422,43399,43248,43489,8515,8443,8307,816,804,844,7611,7769,7763,34771,34571,34662,34662,34571,34534,43489,43248,43375,35376,35777,35516,35242,35111,35088,37877,37655,37641,36908,36579,37042,43375,43248,43296,43375,43296,43407,5498,5712,5729,6104,6010,6135,7795,7808,7935,7795,7935,7983,40830,40840,40991,40840,40711,40844,41618,41788,42200,37476,37494,37473,43407,43296,43245,42200,41788,42260,36122,36028,36018,34771,34774,34916,36947,37367,36846,40994,41069,41066,41755,41657,41605,41241,41069,40994,41241,40994,41665,4575,5345,5232,6183,6237,6287,40840,40844,40919,39445,39624,39457,7128,7127,7250,7039,7127,7128,7128,7352,7141,41488,41434,41407,38364,38214,38119,39125,39072,39265,39137,39326,39135,38666,38536,38508,38508,38448,38410,38325,38063,38266,38736,38762,38666,38821,38913,38736,39042,39032,38890,39220,39032,39042,39220,39042,39152,39583,39457,39785,33278,33358,33422,33448,33573,33504,33438,33358,33278,34978,35129,34916,33845,33751,33918,33918,33751,33736,39032,38913,38890,38960,39167,38949,39866,40142,39624,3663,3617,3892,4379,4468,4501,4501,4468,4602,4602,4556,4629,2565,2708,2650,7808,7611,7763,8165,8067,8144,8299,8375,8400,38913,38762,38736,39167,39326,39137,40312,40295,40497,6135,6582,6133,5498,5729,5809,5809,5936,6010,7795,7611,7808,37471,37476,37473,36579,36840,36964,40342,40312,41186,41182,41107,41197,40830,40497,40707,38762,38536,38666,33492,33573,33448,34940,34900,34757,36788,36657,36681,36735,36657,36788,41237,41182,41197,41237,41151,41305,41069,41154,41066,41320,41347,41459,43097,42996,43023,42996,42874,43023,1339,1451,1174,2454,2590,2498,38536,38448,38508,43819,43900,43686,43758,43900,43785,43714,43616,43659,43714,43659,43810,43659,43510,43657,43510,43489,43657,43896,43501,43702,43628,43562,43444,43577,43489,43375,2573,2577,2650,2498,2183,1939,34238,33984,33738,36119,35851,35845,37471,37473,37331,8273,8299,8307,8067,7981,7983,33725,33751,33848,43245,43296,43161,43023,42874,43041,386,36,549,69,36,386,33180,33166,33376,43663,43562,43628,804,541,919,950,816,844,1041,1000,1151,41505,41488,41407,1893,1834,2065,2521,2193,2137,5452,5868,5816,41305,41151,41357,41097,40840,40919,43562,43486,43471,4629,4579,4793,6195,6132,6188,4379,4516,3892,37311,37297,37166,38022,38128,37861,8299,8165,8144,8653,8949,8970,7614,7491,7442,7101,7149,6798,38325,38266,38410,38022,37861,37871,43245,43161,43171,43041,42874,42810,43245,43171,43328,1850,2029,1938,2577,2528,2650,41424,41305,41357,41097,41107,41182,40840,40830,40707,41369,41305,41424,33573,33682,33657,33358,33492,33448,33438,33492,33358,43178,43171,43097,6132,6237,6183,35777,36119,35845,36512,36119,36434,7127,7039,7282,7128,7250,7352,7352,7605,7141,34940,34748,34859,34599,34392,34583,34583,34392,34588,42907,43174,43083,42469,42733,42638,42320,42428,42132,42593,42428,42320,8065,7981,8067,2521,2273,2193,1076,1306,1054,33751,33725,33736,33845,33918,33979,33492,33682,33573,43225,43178,43097,43144,43097,43023,34401,34392,34250,9392,9282,9465,8299,8273,8165,8165,8065,8067,9312,9282,9392,37641,37655,37622,37641,37622,37634,37311,37166,37188,39167,39396,39326,39326,39387,39364,38960,39165,39167,39125,39165,38960,38960,39072,39125,37188,37166,37042,39354,39220,39209,39209,39220,39152,39032,39023,38913,38786,38536,38762,38622,38621,38536,38536,38621,38448,38514,38325,38410,39238,39220,39354,41257,41182,41237,39354,39209,39382,36122,36018,36213,34247,34205,34619,36608,36539,36657,41488,41733,41434,41634,41733,41488,41755,41733,41799,1982,1889,2055,2024,1889,1982,36947,37087,37367,7981,7795,7983,7820,7795,7981,8880,8994,8443,34771,34662,34774,39396,39387,39326,39387,39546,39364,6379,6582,6668,7038,7128,7141,6803,7101,6798,1786,2065,1834,798,816,950,42469,42200,42260,3425,3310,3441,2647,2733,2812,3425,4046,4043,3781,4043,4101,36771,36608,36735,38786,38762,38913,869,950,937,34916,35129,35411,37634,37622,37476,37877,38022,37871,2647,2812,2846,3310,3232,3441,39546,39752,39515,6104,6006,6010,6379,6487,6378,7141,7605,6925,8142,8065,8165,7981,8065,7926,42924,42810,42775,36735,36608,36657,37087,37335,37367,4468,4556,4602,4402,4379,4307,4451,4379,4402,41733,41755,41605,43292,43144,43041,41320,41066,41154,37487,37634,37476,38216,38022,37877,43245,43439,43407,43577,43657,43489,43714,43819,43686,43178,43328,43171,43352,43328,43262,39752,39904,39732,2137,2094,2304,1797,1786,1834,2119,2094,2137,5809,5729,5936,4895,4594,5151,8443,8994,8420,9649,9312,9392,32983,32609,32662,32662,32609,32384,32983,32662,32957,33585,33376,33725,34619,34205,34571,33845,33848,33751,35193,34900,34940,35193,35242,35210,33682,34238,33738,35193,34940,35031,35210,35242,35088,36840,36579,36290,37322,37471,37331,43715,43663,43628,43562,43557,43486,43486,43537,42730,42430,42469,42260,43795,43663,43715,816,741,804,891,869,937,1041,1151,1068,1811,1834,1889,6006,6104,6023,6006,5809,6010,41305,41369,41237,41364,41369,41424,41320,41154,41347,6237,6391,6412,6018,6132,6015,6183,6015,6132,41585,41634,41488,43577,43375,43439,4895,5151,5416,4451,4556,4468,2094,2024,2168,2119,2024,2094,36840,36290,36672,39230,39457,39382,41257,41097,41182,15,53,738,43648,43557,43780,43439,43375,43407,37322,37331,37311,37851,37877,37641,37640,37641,37634,34247,33979,33918,43041,43144,43023,43352,43439,43245,42924,42775,42428,34238,34401,34250,43352,43245,43328,1339,1722,1759,1339,1759,1451,36028,35972,35729,34660,34619,34571,34066,33848,33979,36213,36018,36494,41585,41683,41634,41634,41683,41733,41755,41905,41657,36494,36018,36539,37335,37637,37727,37317,37322,37311,36964,36840,37027,37625,37640,37634,37188,37042,37032,7128,7038,7039,7729,7611,7795,35242,35376,35111,34859,34748,34583,1054,1306,1568,869,798,950,780,798,869,35411,35129,35275,2846,2812,2977,39297,39396,39167,39387,39396,39546,39546,39738,39752,40042,40111,39904,38818,38676,39072,39220,39238,39032,38600,38410,38448,40140,40251,39866,40140,40342,40251,39023,38786,38913,40140,40312,40342,41459,41505,41320,39297,39167,39165,34778,34571,34771,34401,34588,34392,6133,6006,6023,5009,5416,5498,4418,4286,4594,41320,41505,41407,41585,41505,41609,2024,1811,1889,1786,1644,2065,2273,2521,2681,2647,2553,2733,43663,43780,43562,43849,43896,43702,1764,1811,2024,38786,38622,38536,41364,41257,41237,40312,40497,41186,41364,41237,41369,43896,43795,43715,43775,43657,43753,43775,43659,43657,43775,43810,43659,36122,36044,36028,36125,36044,36122,7926,7820,7981,8142,8165,8273,43144,43225,43097,43439,43523,43577,43059,42924,43052,41905,41755,41799,8656,8653,8550,8656,8949,8653,32643,32997,33114,33492,33438,33682,34449,34361,34238,34238,34361,34401,34401,34361,34588,33979,33848,33845,33801,33848,34066,43292,43225,43144,2454,2528,2577,2408,2528,2454,37487,37476,37471,39318,39297,39125,37487,37471,37322,1076,1041,1068,936,1041,1076,35362,35376,35242,35362,35242,35193,798,741,816,1041,891,1000,6379,6668,6487,7584,7605,7611,37032,37042,36964,37032,36964,37027,780,741,798,34066,33979,34211,34916,34778,34771,34883,34778,34916,34588,34859,34583,34719,34859,34588,41505,41585,41488,40111,40003,39904,1811,1797,1834,1647,1797,1764,40497,40830,40991,41424,41357,41857,4379,4451,4468,5161,5396,5345,4556,4451,4402,38600,38448,38621,6274,6379,6283,6195,6391,6237,7246,7614,7442,6195,6237,6132,36044,35972,36028,36125,35972,36044,41799,41733,41683,7947,7614,7562,37317,37487,37322,36672,36002,36119,2647,2467,2553,2254,2273,2681,1647,1644,1797,2899,2904,3180,2899,3180,3232,2899,3232,2807,40042,39904,39752,38214,38364,38676,37317,37311,37299,43262,43178,43225,43262,43328,43178,2904,2846,2977,1797,1644,1786,2119,2137,2193,40840,41097,40991,41412,41424,41543,41373,41412,41371,41585,41799,41683,41241,41154,41069,36771,36735,36846,36615,36539,36608,7614,7947,8316,42924,43059,42810,43052,42924,42428,891,780,869,777,780,891,777,891,843,37299,37188,37032,34859,35031,34940,35054,35031,35217,1332,1054,1568,41097,41257,41371,8994,9063,8980,6939,6940,7141,33848,33801,33725,34211,34247,34723,43467,43262,43225,43896,43812,43795,43795,43812,43663,43557,43537,43486,43810,43819,43714,43753,43657,43577,43523,43439,43352,2254,2681,2371,34778,34660,34571,34883,34660,34778,35783,35628,35972,36162,35783,35972,41373,41257,41364,33585,33180,33376,41459,41511,41505,41525,41511,41459,34449,34238,34181,8235,8142,8273,7176,7246,7021,7992,8133,7947,5396,5929,5345,38622,38600,38621,38786,38799,38622,39238,39023,39032,39226,39023,39238,39409,39238,39354,39409,39354,39382,40142,39866,40251,41770,41799,41585,43093,43052,43209,37727,37637,38021,37637,38063,38021,37851,37641,37640,37299,37311,37188,37299,37032,37027,39396,39738,39546,39125,39297,39165,37625,37634,37487,40308,40695,40003,43648,43537,43557,43753,43523,43871,39297,39466,39396,2528,2565,2650,2411,2565,2528,35031,35163,35193,35054,35163,35031,36059,35767,35783,35783,35767,35628,36125,36122,36213,38021,38063,38325,2273,2119,2193,843,1041,936,2254,2119,2273,35886,35777,35376,37657,37625,37487,41511,41609,41505,41684,41609,41511,36615,36771,36944,37110,36771,36846,41424,41373,41364,41857,42264,42092,41365,41347,41241,41241,41347,41154,4594,4286,4485,2904,2810,2846,4895,5416,5009,5498,5809,5617,6379,6274,6582,6940,7039,7038,6133,6274,6283,8142,7926,8065,8307,8235,8273,8980,9107,9282,2201,2408,2454,39919,40042,39752,41398,41365,41241,43775,43819,43810,43753,43819,43775,4579,4629,4556,35767,35411,35395,33585,33725,33801,35817,35411,35767,35163,35362,35193,35297,35362,35163,2519,2467,2647,2807,3232,3088,780,718,741,6,69,386,843,891,1041,1513,2065,1644,8443,8235,8307,35046,35031,34859,1764,1797,1811,6195,6167,6391,6015,6183,5868,36745,36672,36679,37757,37625,37780,37780,37625,37657,2899,2810,2904,1700,1764,2024,40335,40142,40251,40335,40251,40423,42469,42907,42733,43780,43557,43562,37006,37027,36840,2371,2681,2553,541,804,636,4443,4579,4556,4379,3892,3816,3663,3484,3301,8653,8133,8129,8550,8653,8129,636,804,741,2201,2411,2408,1174,1549,1422,6274,6133,6582,6940,7038,7141,6018,6188,6132,6078,6188,6018,777,718,780,936,1076,1054,7729,7795,7820,43731,42730,43537,7881,7926,8142,579,1174,1422,38119,38128,38364,39297,39443,39466,39725,39738,39396,38364,38128,38022,39265,39318,39125,34361,34719,34588,35054,35297,35163,34700,34719,34361,3421,3425,4043,2899,2807,2810,4286,3781,4101,3738,3781,4286,39492,39409,39382,39041,38891,38786,39318,39443,39297,39041,38786,39023,39583,39382,39457,1647,1513,1644,1579,1513,1647,38891,38799,38786,41089,40991,41097,39238,39409,39476,41371,41257,41373,2677,2647,2846,1678,1764,1700,2687,2846,2810,37757,37851,37640,37757,37640,37625,2024,2119,1700,37487,37317,37657,36672,36863,36840,36745,36863,36672,36672,36119,36679,41347,41525,41459,42061,42046,41799,42083,42320,41905,40308,40003,40111,40308,40111,40042,1513,1332,1568,36246,36125,36213,36615,36608,36771,39725,39396,39466,7813,7729,7820,34181,34238,33682,43871,43523,43909,43523,43753,43577,43059,43292,43041,42046,41905,41799,39738,39834,39752,957,936,1054,724,718,777,2408,2411,2528,1606,1938,1722,4625,4895,5009,39359,39237,39254,37332,37299,37027,38767,38600,38622,37110,36846,37367,43648,43631,43537,43662,43631,43648,38600,38514,38410,7992,7947,7562,5452,6015,5868,5452,5816,5396,36963,37006,36840,36679,36119,36512,2467,2371,2553,2428,2371,2467,5161,5452,5396,3617,3663,3301,42061,41799,42038,2488,2807,2351,1425,1606,1722,1425,1722,1339,37643,37367,37727,36963,36840,36863,36765,36679,36798,41428,41525,41347,41428,41347,41365,2807,2687,2810,7926,7813,7820,6925,6939,7141,7881,7813,7926,7881,8142,7960,43052,43076,43059,43093,43076,43052,724,843,823,724,777,843,151,6,386,1781,1850,1938,4575,5232,4579,9312,8980,9282,8177,8142,8235,33180,32983,32957,33453,32983,33180,34723,34619,34660,34883,34916,35039,36963,36863,36867,43631,43731,43537,43812,43780,43663,43846,43780,43812,43467,43352,43262,600,636,741,34719,34788,34859,34700,34788,34719,39956,40308,40042,43780,43662,43648,38514,38021,38325,36125,36162,35972,36494,36246,36213,38799,38767,38622,38600,38643,38514,38514,39100,38021,38891,38933,38799,39340,39226,39238,39340,39238,39476,39409,39492,39476,39318,39419,39443,39443,39725,39466,39738,39919,39834,39834,39919,39752,39265,39237,39318,39072,39237,39265,38364,38022,38277,2436,2565,2411,1606,1781,1938,2504,3279,2565,36867,36863,36745,37332,37317,37299,37757,37780,37851,36867,36745,36765,39476,39492,39583,39785,39624,40142,41412,41373,41424,3088,3232,3310,2626,2677,2687,3781,3421,4043,3738,3421,3781,39226,39041,39023,39457,39624,39785,39237,39419,39318,39041,38980,38891,2436,2504,2565,2436,2411,2353,6378,6283,6379,4625,4594,4895,6844,6939,6826,35217,35297,35054,870,957,866,718,600,741,1070,1054,1332,1189,1332,1308,1678,1647,1764,38980,38933,38891,39785,39830,39761,53,52,738,7584,7611,7729,8177,8235,8443,38933,38767,38799,40423,40342,41186,1700,1486,1517,2519,2428,2467,2677,2846,2687,2504,2471,3279,1939,2183,1850,41286,41089,41097,36812,36494,36615,36615,36494,36539,35046,35217,35031,34642,34700,34361,34642,34361,34449,38767,38643,38600,39956,39919,39738,2250,2254,2371,37332,37027,37281,36765,36745,36679,41543,41424,41857,41371,41286,41097,41770,41585,41609,41398,41428,41365,41525,41428,41567,42046,42083,41905,41770,41609,41684,2428,2369,2371,2250,2369,2320,37027,37006,37281,43759,43705,43662,43662,43705,43631,43896,43846,43812,4402,4395,4556,3893,4307,4379,43076,43157,43059,42844,43052,42428,1765,1939,1850,8341,8177,8443,7772,7729,7813,36119,35777,36359,35046,34859,34788,4307,4395,4402,41583,41511,41525,1678,1579,1647,1545,1579,1678,37281,37006,37265,35376,35362,35538,43759,43662,43898,41543,41422,41412,710,600,718,19,73,541,843,936,823,35039,35411,35130,35039,34916,35411,4625,4418,4594,5809,6006,5617,4395,4443,4556,6668,7039,6487,6844,6940,6939,42061,42083,42046,42091,42083,42061,8656,8550,8949,7442,7101,7246,32997,33438,33278,34700,34803,34788,41450,41286,41371,39830,39785,39935,8036,7960,8142,6078,6195,6188,34644,34642,34449,1657,2119,1738,2626,2687,2807,4443,4502,4579,41770,41870,41799,41567,41583,41525,41684,41850,41798,8177,8036,8142,8598,8420,8994,6015,6078,6018,5983,6078,6015,5983,6015,5902,41891,41870,41770,7772,7813,7881,1781,1765,1850,2353,2430,2436,1676,1765,1781,1676,1781,1606,1425,1339,1267,43093,43157,43076,43336,43157,43270,6283,5783,6133,6705,7039,6940,2677,2519,2647,34644,34803,34700,35538,35362,35472,34788,34803,34986,1267,1339,1005,35238,35297,35217,37006,36963,37265,38933,38957,38767,38767,38756,38643,38643,38756,38514,37643,37110,37367,38980,39013,38933,39131,39013,38980,39131,38980,39041,39343,39041,39226,39343,39226,39340,39343,39340,39403,39483,39476,39583,41583,41684,41511,41398,41665,41542,39785,39761,39583,39785,40044,39935,39919,39956,40042,39419,39725,39443,39598,39725,39419,39359,39419,39237,1308,1332,1513,2250,2371,2369,2436,2430,2504,2201,2454,1939,41412,41422,41371,40251,40342,40423,41380,41607,41857,41567,41398,41619,1308,1513,1253,42028,42038,41870,41870,42038,41799,42083,42593,42320,8121,8036,8177,7960,7934,7881,34211,33979,34247,41221,41089,41286,38957,38756,38767,823,936,957,35046,35238,35217,42756,42593,42926,6844,6705,6940,6753,6705,6844,35472,35362,35297,81,579,738,6200,6798,6391,7992,8129,8133,36162,36125,36246,34723,34247,34619,37281,37265,37336,38277,38022,38216,6378,6334,6283,6705,6487,7039,35538,35886,35376,33640,33585,33801,7936,7934,7960,43157,43292,43059,43336,43292,43157,41386,41221,41286,41450,41543,41477,2320,2369,2428,4502,4474,4579,4443,4389,4502,4395,4391,4443,4307,4267,4395,3893,4267,4307,4277,4267,4189,7936,7797,7934,8420,8341,8443,8598,8341,8420,37877,37851,38216,36963,37148,37265,36867,36765,36882,41450,41371,41422,4267,4391,4395,37657,37317,37609,2213,1785,2057,2430,2438,2504,1676,1939,1765,7797,7772,7881,7797,7881,7934,37800,37657,37833,817,823,957,35538,35671,35886,36798,36679,36512,35358,35472,35297,35358,35297,35238,724,710,718,151,386,541,618,710,724,1189,1070,1332,1410,1513,1579,1545,1678,1700,1292,1676,1606,1005,1339,1174,6078,6026,6195,6007,5983,5902,42038,42091,42061,41916,41891,41770,41798,41770,41684,3310,3425,3088,2488,2626,2807,2677,2488,2519,2519,2320,2428,38216,37851,37882,41010,40773,40682,34066,34008,33801,34078,34008,34066,43753,43871,43819,43909,43523,43352,4457,4474,4502,37800,37851,37780,40518,41010,40682,1093,1070,1189,7772,7584,7729,6350,6357,6487,7599,7584,7772,4474,4575,4579,5983,6026,6078,6007,6026,5983,42011,42028,41891,41891,42028,41870,1292,1606,1425,36812,37643,36631,36363,36162,36246,41221,41386,41089,41543,41450,41422,41607,42200,42677,39013,39077,38933,36812,36944,37643,39483,39340,39476,39483,39583,39734,39483,39591,39512,39761,39830,39931,39072,38364,38564,39254,39072,38564,39254,39237,39072,41567,41428,41398,41725,41684,41583,38391,38364,38277,6925,6826,6939,34008,33640,33801,33585,33453,33180,33854,33640,34008,35472,35671,35538,35300,35358,35238,35046,34788,34986,39343,39131,39041,39785,40142,40044,866,957,1054,823,747,724,35469,35671,35472,2353,2411,2213,2353,2438,2430,34986,34803,34854,42593,42844,42428,43292,43467,43225,42756,42844,42593,6925,6753,6826,7936,7960,8036,43209,43157,43093,6487,6357,6378,6564,6487,6705,40044,40142,40335,151,541,73,618,600,710,2277,2320,2519,1517,1545,1700,2213,2411,2201,41732,41843,41717,42028,42091,42038,41916,41798,41971,37110,36944,36771,39011,38514,38756,40277,40070,39962,39935,40044,39962,6026,6167,6195,5982,6167,6026,36363,36246,36494,34723,34660,34883,42011,42091,42028,43388,43467,43292,42844,43209,43052,37657,37800,37780,38216,38391,38277,37609,37317,37332,37336,37332,37281,43388,43292,43336,36882,36765,36798,870,817,957,768,817,870,866,1054,1070,1093,1189,1075,43392,43270,43209,42397,42593,42083,43705,43759,43631,43898,43662,43780,41798,41916,41770,42091,42173,42083,41241,41665,41398,34644,34700,34642,35515,35469,35358,35358,35469,35472,1700,1657,1486,4474,4457,4575,5982,6200,6167,4391,4389,4443,4267,4277,4391,4311,4277,4189,3484,2840,2954,36512,36434,36700,36798,36512,36700,41665,41800,41572,1785,2201,1939,2353,2331,2438,43759,43731,43631,34723,34883,34867,1075,1189,1308,4277,4389,4391,6167,6200,6391,6015,5347,5902,35130,34883,35039,34780,34644,34449,41450,41386,41286,41406,41386,41450,4389,4457,4502,37250,37265,37148,36119,36359,36434,41567,41725,41583,41916,42011,41891,41697,41725,41567,5161,5345,4885,36162,36059,35783,36592,36363,36494,41971,42011,41916,6826,6753,6844,6925,7605,7104,35515,35358,35591,35110,35046,34986,43209,43270,43157,43388,43270,43392,747,823,817,582,618,724,689,866,690,8341,8121,8177,7620,7599,7772,8161,8121,8341,37800,37882,37851,37439,37609,37332,37439,37332,37336,6357,6334,6378,6350,6334,6357,36023,36059,36164,39131,39169,39013,39343,39236,39131,39512,39403,39340,39512,39340,39483,39483,39734,39591,39830,39935,39931,39403,39236,39343,39931,39935,39962,39236,39169,39131,36963,36867,37148,35926,35886,35671,41725,41850,41684,41971,41850,41725,541,636,19,7620,7772,7797,39956,39738,39725,2279,2353,2171,2279,2331,2353,5009,5498,5617,3531,3738,3950,2277,2178,2320,7755,7620,7797,8980,8598,8994,33640,33453,33585,33963,33453,33640,33854,34008,34078,39962,40070,39971,6753,6644,6705,6564,6644,6534,39931,39962,39971,39897,39956,39725,39598,39419,39359,39598,39359,39803,7246,7562,7614,7021,7246,7101,7021,7101,6803,35285,35130,35481,34078,34066,34151,37833,37882,37800,37833,37657,37845,5617,6006,5783,6564,6350,6487,35788,35926,35671,35515,35671,35469,4885,5345,4575,43270,43388,43336,43467,43909,43352,43392,43209,43442,43209,42844,43016,42173,42091,42011,1545,1410,1579,582,747,699,2178,2254,2250,42277,42173,42011,41542,41619,41398,41572,41619,41542,34644,34854,34803,34780,34854,34644,34066,34211,34151,41971,41798,41850,2320,2178,2250,2488,2677,2626,38300,38391,38216,37845,37657,37609,4457,4382,4575,4389,4384,4457,4277,4311,4389,3816,3892,3617,7104,7605,7584,8029,8036,8121,870,866,768,768,747,817,19,636,600,52,81,738,579,1005,1174,1267,1123,1425,8161,8029,8121,34151,34211,34268,6644,6564,6705,7476,7584,7599,1517,1410,1545,1473,1410,1517,41857,41732,41543,41386,41494,41089,41732,41857,41843,6007,5982,6026,5834,5902,5347,36359,35777,35886,36959,36882,36798,35130,34867,34883,36059,35817,35767,36023,35817,36059,4311,4384,4389,38300,38216,37882,41843,41857,41964,43759,43898,43731,43846,43898,43780,36809,36798,36700,37833,37845,37882,41477,41406,41450,340,1005,579,2274,2279,2171,8029,7936,8036,7620,7476,7599,36944,36812,36615,36582,36164,36162,37643,38154,37811,36685,36809,36700,5902,5982,6007,5884,5982,5902,36434,36685,36700,36271,36359,35886,36434,36359,36439,39908,39931,39971,41717,41477,41543,6534,6644,6613,6006,6133,5783,6644,6753,6613,2323,2504,2438,4311,4295,4384,7888,8129,7992,6405,6798,6200,39169,39077,39013,39236,39273,39169,39549,39273,39236,39524,39236,39403,39524,39403,39512,39583,39761,39734,39761,39908,39734,39761,39931,39908,41697,41567,41619,39803,39359,39254,7844,7755,7797,43388,43455,43467,43455,43392,43442,40335,40277,40044,3738,4286,3950,39273,39077,39169,7562,7246,7148,33438,33968,33682,34854,35110,34986,3281,3816,3617,35036,34867,35130,39077,38957,38933,40335,40423,40518,1410,1253,1513,1364,1253,1410,36812,36626,36494,35047,35036,35130,36631,36626,36812,36534,36685,36434,37357,37336,37265,41697,41971,41725,43016,42844,42756,41542,41665,41572,3816,3893,4379,40991,41186,40497,41697,41572,41800,7148,7246,7176,34078,33963,33854,33854,33963,33640,34268,34211,34339,33968,34181,33682,36959,36798,36826,37357,37439,37336,34780,35110,34854,36439,36534,36434,36626,36592,36494,36631,36592,36626,36826,36798,36809,36439,36359,36383,1486,1473,1517,36826,36809,36685,41732,41717,41543,41494,41386,41406,42200,42469,42638,41572,41697,41619,40994,40308,41665,3893,4189,4267,4384,4382,4457,5884,6234,5982,37918,37845,37609,38391,38564,38364,7755,7634,7620,7936,7844,7797,8012,7844,7936,8012,7936,8029,43392,43455,43388,42397,42083,42173,42397,42173,42277,4189,4295,4311,37439,37918,37609,37250,37357,37265,1657,1700,2119,2400,2488,2247,4295,4382,4384,41494,41406,41477,1473,1364,1410,768,689,676,1373,1364,1473,37148,36867,36882,36948,36826,36685,36648,36685,36534,41717,41582,41477,42430,42907,42469,7844,7634,7755,35300,35238,35046,36383,36359,36271,35599,35300,35110,35110,35300,35046,38686,38300,37882,38564,38592,38702,37357,37371,37439,37148,36882,36959,34713,34211,34723,35047,35130,35285,5982,6234,6200,7760,7888,7562,6405,6289,6441,42277,42011,42282,38957,39011,38756,39077,39092,38957,39134,39092,39077,39591,39524,39512,39549,39524,39612,39524,39591,39612,39876,39734,39908,39876,39908,39960,7148,7176,7021,7562,7888,7992,34117,33963,34078,34713,34723,34901,7533,7476,7620,34901,34723,34867,43841,43909,43467,3950,4286,4418,5783,6334,6255,6255,6350,6564,36992,36959,36826,37108,37148,36959,36271,35886,35926,2119,2254,1738,37108,36959,36992,37250,37371,37357,41673,41582,41717,39134,39077,39273,39960,39908,39971,39598,39897,39725,40138,39897,39598,2400,2277,2519,2331,2279,2438,2353,2213,2171,3816,3769,3893,3893,3765,4189,4189,4224,4295,4295,4258,4382,3281,3769,3816,3765,3769,3424,40070,39960,39971,747,582,724,768,676,713,689,768,866,6405,6803,6798,699,768,713,6613,6753,6729,35515,35776,35671,35614,35776,35515,43174,42907,42430,41841,41673,41717,42926,43016,42756,43455,43841,43467,36164,36059,36162,35036,34901,34867,36631,36363,36592,35055,34901,35036,34117,34151,34268,8598,8161,8341,7550,7533,7634,7634,7533,7620,37148,37371,37250,36545,36534,36439,41841,41717,41843,41582,41494,41477,39692,39876,39929,36447,36545,36439,36208,36271,35926,42397,42480,42593,42282,42011,41971,42480,42277,42404,1738,2254,2178,1280,1253,1364,6729,6753,6925,7550,7634,7844,8161,8012,8029,4382,4367,4575,4090,4224,4189,38592,38564,38391,38391,38300,38592,768,699,747,1424,1473,1486,5783,6283,6334,7104,7584,7386,41964,41841,41843,42545,43174,42430,1005,1123,1267,1150,802,1097,36447,36439,36383,37233,37371,37148,36948,36992,36826,41612,41494,41582,41964,41857,42092,6803,7148,7021,6234,6405,6200,5884,5902,5834,7386,7584,7476,34117,34268,34339,35130,35411,35481,4224,4258,4295,36075,36208,35926,36387,36447,36383,37126,37148,37108,41743,41582,41673,151,73,6,19,600,261,473,618,582,1816,1738,2178,2488,2400,2519,3088,3425,3421,7533,7386,7476,7550,7386,7533,34400,34780,34449,35300,35591,35358,35776,35788,35671,34400,34449,34181,6334,6350,6255,41906,41743,41673,42677,42200,42638,2279,2323,2438,2274,2323,2279,6015,5452,5347,36387,36383,36271,36545,36648,36534,36992,37126,37108,6255,6564,6534,6861,6729,6925,7048,6925,7104,35614,35591,35599,36306,36387,36271,35884,35788,35776,42735,42677,42638,42735,42638,42733,43436,43442,43209,43436,43209,43429,39092,39099,38957,39524,39549,39236,39612,39591,39692,39591,39734,39692,39734,39876,39692,39876,39960,39992,39992,39960,40070,2171,2213,2057,35967,36075,35926,42277,42480,42397,42282,42376,42404,39567,39134,39273,39134,39099,39092,39962,40044,40277,1509,1424,1486,2166,2178,2277,3484,3279,2840,3281,3617,3301,3769,3765,3893,4224,4090,4258,40277,40335,40495,2120,2166,2277,2274,2225,2323,1512,1939,1676,1509,1486,1657,41906,41673,41841,40495,40335,40518,42002,41841,41964,36449,36387,36477,36447,36648,36545,41902,41971,41697,40991,41089,41186,2166,2110,2178,43840,42789,43731,42264,41857,41607,42480,42926,42593,43211,42926,42480,699,606,582,1075,1308,1253,43026,42735,42733,6255,6534,6613,7115,7048,7104,7287,7104,7386,1123,1150,1425,1097,802,997,6255,6613,6286,4268,4625,4426,35481,35411,35795,36582,36631,37152,36449,36648,36447,42106,42092,42301,1424,1373,1473,1344,1373,1424,1280,1373,1324,2110,1989,2178,7666,7550,7844,8161,7961,8012,8598,8113,8161,34117,34078,34151,34211,34554,34339,34713,34653,34211,7666,7844,8012,43442,43533,43455,43429,43209,43016,713,606,699,594,606,713,1373,1280,1364,1509,1657,1498,1150,1292,1425,35788,35967,35926,36306,36271,36208,36387,36449,36447,35591,35614,35515,35599,35591,35300,36848,36685,36648,36848,36948,36685,38686,37882,37845,977,1075,1253,7048,6861,6925,6778,6861,6842,8113,7961,8161,34713,34903,34653,35884,35967,35788,171,340,579,1078,1512,1292,6850,7148,6460,6441,6803,6405,1569,1657,1738,1292,1512,1676,41693,41582,41743,41693,41612,41582,36582,36162,36363,35055,35036,35047,2163,2225,2274,2163,2274,2171,81,171,579,42092,41979,41964,42106,41979,42092,36306,36208,36075,40071,40086,40296,41906,41693,41743,2840,3279,2471,2471,2504,2323,2057,2163,2171,43898,43840,43731,606,556,582,547,556,606,866,1070,690,6289,6405,6234,6289,6234,6070,35967,36148,36075,35614,35884,35776,35760,35884,35614,40450,40086,40070,40070,40086,39992,39929,39842,39692,39673,39639,39612,39612,39639,39549,39120,39099,39134,39108,39011,39099,41089,41494,41186,35411,35817,35795,81,8,171,43436,43533,43442,43519,43533,43436,2471,2323,2297,39099,39011,38957,39554,39273,39549,36250,36148,36081,41979,42002,41964,42264,41607,42677,41979,42106,42137,42526,42418,42264,1075,1037,1093,1280,1209,1253,1481,1344,1424,1481,1424,1509,36948,37126,36992,37061,37126,36948,36848,36648,36932,42282,42404,42277,43519,43429,43752,41665,40308,42577,42376,42282,42352,2297,2323,2225,1785,2213,2201,34987,34713,34901,43429,43016,43252,1652,1569,1738,556,473,582,453,473,556,594,713,676,6861,6778,6729,6842,6861,7048,7287,7386,7550,35182,35055,35047,35795,35817,36124,2297,2225,2141,4258,4367,4382,3765,4090,4189,4193,4090,4164,38564,39438,39254,40533,40308,39956,38592,38300,38686,7348,7309,6850,5970,6234,5884,41800,41902,41697,42026,41902,41800,1989,1816,2178,1960,1963,1989,1960,1989,2110,1983,2110,2166,1750,1963,1670,3088,3421,3738,38686,37845,38503,7309,7760,7562,7888,7760,8129,7309,7562,7148,35643,35599,35110,33968,34400,34181,36148,36306,36075,36250,36306,36148,36477,36306,36488,1456,1498,1547,1569,1498,1657,1324,1209,1280,41829,42119,42005,7523,7287,7550,41186,41494,41546,41821,41612,41693,1963,1816,1989,1324,1373,1344,42137,42002,41979,42526,42461,42418,977,1037,1075,5347,5452,5161,42997,42733,42907,2141,2225,2163,4193,4367,4258,6778,6528,6729,6849,6842,7048,690,1070,1093,1498,1481,1509,1456,1481,1498,1816,1788,1738,4367,4885,4575,39554,39639,39673,39612,39842,39673,35182,35047,35285,2115,2141,2163,2115,2163,2057,1785,1939,1512,42404,42573,42480,42463,42573,42404,42282,41971,42352,3151,3088,3738,1963,1750,1816,1816,1750,1788,4418,4625,3950,2954,3033,3301,4090,4193,4258,3150,3033,2509,3150,2509,2900,2093,2840,2471,2253,2471,2297,39277,39120,39134,37643,37727,38626,36124,36023,36164,36477,36648,36449,37126,37233,37148,34339,34329,34117,34117,34383,33963,34554,34329,34339,34554,34211,34653,39120,39108,39099,37061,37233,37126,36148,35967,36081,36306,36477,36387,42463,42376,42501,35398,35110,34780,43083,42997,42907,689,594,676,626,594,689,35131,34987,35055,36124,35817,36023,36124,36164,36228,36228,36164,36582,6849,6740,6842,7758,7666,8012,7555,7666,7758,34727,34554,34653,34987,34901,35055,531,547,594,977,889,1037,1305,1324,1344,1383,1344,1481,42116,41906,42002,42002,41906,41841,42137,42106,42227,35429,35285,35481,40682,40495,40518,40678,40495,40682,41764,41494,41612,43833,43455,43533,43833,43841,43455,43519,43436,43429,5834,5970,5884,6289,6268,6441,5814,5970,5834,43104,43016,42926,42376,42463,42404,42536,42463,42513,7555,7523,7550,34783,34727,34653,43104,42926,43211,594,547,606,261,600,618,690,1093,889,35599,35760,35614,35808,35760,35643,4587,4811,4885,5390,5814,5834,4047,4090,3765,6842,6740,6778,3950,4625,4268,6849,7048,7062,35797,35429,35481,34987,34903,34713,35797,35481,35795,42849,42677,42735,43174,42545,42841,37918,37439,37371,36958,37061,36948,36958,36948,36848,36958,36848,36932,626,690,604,6528,6613,6729,35287,35182,35285,1547,1498,1569,1324,1122,1209,1652,1738,1788,4193,4281,4367,41010,40518,40423,42463,42536,42573,42501,42376,42352,2120,2277,2400,1529,1785,1512,2212,2253,2297,1097,1292,1150,35127,34903,34987,37061,37045,37233,36932,36648,36643,41875,41821,41693,41186,41010,40423,42227,42106,42301,39120,39133,39108,39639,39554,39549,39612,39692,39842,40071,39929,39876,39992,40071,39876,39992,40086,40071,5970,6070,6234,5347,5161,4893,42849,42735,43026,40070,40277,40450,1750,1652,1788,1571,1652,1588,1318,1383,1456,1456,1383,1481,41665,41829,41800,42005,42119,42139,2247,2120,2400,5009,4426,4625,2351,2247,2488,40450,40277,40495,40773,40678,40682,41162,41010,41186,690,626,689,889,1093,1037,43026,42733,42997,7115,7104,7287,6740,6528,6778,43151,43026,42997,43320,43174,42841,7205,7115,7287,7666,7555,7550,7758,8012,7961,34714,34573,34727,34727,34573,34554,34554,34383,34329,43519,43623,43533,43607,43623,43519,39277,39133,39120,37727,38021,38626,36179,35951,35795,35287,35131,35182,35182,35131,35055,34903,34783,34653,36582,36363,36631,36081,35967,36019,7407,7287,7523,35287,35285,35429,2120,1983,2166,1965,1983,1946,1150,1123,802,802,1005,86,41,340,171,42137,42116,42002,42301,42092,42264,42301,42264,42395,1383,1305,1344,1208,1305,1383,1547,1569,1652,977,1253,1209,36376,36488,36306,43211,42480,42573,42352,41971,42206,453,556,547,261,618,473,7381,7407,7523,35127,34783,34903,1983,1960,2110,1965,1960,1983,1571,1547,1652,626,531,594,604,531,626,35760,35808,35884,36265,36376,36306,35971,35808,35993,42640,42573,42536,4114,4336,4367,4193,4230,4281,4012,4047,3962,4047,3424,3962,35131,35127,34987,35438,35287,35429,36019,35967,35884,1016,977,1209,524,453,531,1208,1324,1305,42219,42116,42137,42395,42264,42418,41829,42026,41800,42005,42026,41829,4047,4164,4090,40672,40678,41054,40678,40773,41054,7314,7205,7287,6870,6742,6849,6849,6742,6740,36265,36306,36250,36643,36648,36477,42501,42513,42463,42708,42513,42634,1588,1652,1750,2221,2247,2017,2115,2297,2141,2115,2057,1975,4164,4230,4193,42219,42137,42227,42322,42219,42227,42461,42395,42418,42820,42677,42849,42206,41971,41902,43623,43708,43533,43752,43607,43519,604,690,740,531,453,547,43199,42997,43083,359,343,473,7062,7048,7115,5009,5617,4991,43174,43199,43083,43320,43199,43174,524,396,447,35971,36019,35884,36184,36265,36250,35971,35884,35808,43073,42820,42849,41875,41693,41906,6987,7062,7115,5859,6070,5970,5859,5970,5814,36184,36250,36081,36643,36477,36488,37643,36944,37110,39554,39567,39273,39769,39567,39554,39769,39554,39673,39769,39673,39842,39979,39842,39929,39979,39929,40071,42513,42640,42536,43783,43708,43752,42703,42640,42708,2297,2115,2112,40098,39979,40071,39567,39277,39134,8113,7758,7961,7381,7314,7407,7407,7314,7287,6987,6928,7062,34329,34383,34117,34573,34383,34554,34714,34383,34573,34714,34727,34783,36958,37045,37061,36491,36488,36376,42116,41875,41906,42322,42227,42301,42322,42301,42450,7381,7523,7555,6268,6803,6441,1547,1417,1456,740,690,889,1588,1750,1605,35438,35127,35287,35287,35127,35131,39011,39108,39100,42526,42264,42677,42169,41875,42116,41341,41162,41186,36019,36072,36081,36502,36491,36376,35999,35971,35993,343,261,473,252,261,343,359,473,453,6742,6720,6740,7062,6870,6849,6928,6870,7062,43199,43253,42997,42803,42678,42820,42678,42526,42677,43903,43320,42841,40672,40495,40678,40672,40450,40495,1946,1983,2120,41764,41612,41821,43607,43708,43623,43252,43016,43104,1571,1556,1547,1538,1556,1571,42322,42450,42344,42329,42322,42344,41879,41821,41875,35795,36124,36179,1318,1208,1383,604,524,531,4893,5161,4885,5617,5228,4991,2351,2807,3088,2247,2221,2120,36502,36376,36265,42678,42677,42820,1556,1417,1547,1538,1417,1556,4230,4099,4281,4164,4121,4230,4047,4012,4164,3150,3301,3033,2093,2471,2253,43840,43852,42841,740,889,977,444,359,453,43211,43237,43104,1208,1122,1324,1135,1122,1208,4012,4121,4164,35999,36072,36019,6987,7115,7205,6870,6720,6742,6987,7205,7175,42208,42116,42219,41879,41764,41821,42208,42219,42329,1670,1963,1960,2771,3088,3151,2112,2212,2297,2112,2115,1975,42329,42219,42322,43073,42849,43026,8,41,171,1975,2057,1693,997,1292,1097,36932,37045,36958,36857,37045,36932,36643,36488,36491,42395,42450,42301,3218,3150,2900,3033,2954,2509,4078,4099,4121,39277,39316,39133,39567,39446,39277,39987,39769,39842,39925,39769,39987,40098,40071,40296,3150,3281,3301,447,444,524,524,444,453,1201,1135,1208,1820,1960,1965,41546,41341,41186,40296,40086,40450,42004,41879,41875,39559,39446,39567,40296,40450,40387,6070,6268,6289,6127,6268,6070,34789,34714,34783,34789,34783,35127,36072,36184,36081,35971,35999,36019,35643,35760,35599,43237,43252,43104,43380,43252,43237,42703,42573,42640,40773,41010,41054,42708,42640,42513,42513,42501,42634,6671,6720,6870,7175,7205,7314,802,1123,1005,1825,1946,2120,42169,42004,41875,42395,42516,42450,1588,1538,1571,1122,1016,1209,1484,1538,1588,42026,42206,41902,40338,39956,39897,39803,39254,39438,38564,38702,39438,7309,7348,7760,6850,7309,7148,34400,34887,34780,1946,1820,1965,36128,36184,36072,35398,35643,35110,36179,36124,36228,36179,36228,36525,39100,39108,39133,252,343,359,212,215,261,261,215,19,252,359,444,36525,36228,36582,36128,36072,35999,41054,41010,41162,1318,1456,1417,1318,1417,1256,42005,42152,42026,43708,43833,43533,43752,43708,43607,754,740,977,36412,36502,36265,1820,1670,1960,3962,4121,4012,4121,4099,4230,5681,5859,5814,7758,7381,7555,34714,34869,34383,34869,34789,35127,43756,43752,43897,43252,43752,43429,42152,42206,42026,42703,42799,42573,396,524,604,35951,35797,35795,35805,35797,36257,228,252,444,6982,6928,6987,6982,6870,6928,43320,43253,43199,42516,42461,42666,43457,43253,43320,35993,36128,35999,36184,36412,36265,35993,35808,36048,1256,1417,1277,1135,1016,1122,7053,6982,6987,1670,1605,1750,36220,36412,36184,36502,36643,36491,42550,42501,42352,39446,39316,39277,39769,39778,39567,39925,39778,39769,39840,39778,39925,39979,40098,40072,38686,38702,38592,42005,42139,42152,42152,42168,42206,37371,37878,37918,3424,4047,3765,3150,3218,3281,2087,2253,2212,39778,39749,39567,2112,2087,2212,1693,2057,1785,5617,5783,5228,3151,3738,3531,1724,1820,1946,1717,1670,1820,1717,1581,1670,1670,1581,1605,39749,39559,39567,39559,39516,39446,43756,43833,43783,43783,43833,43708,43756,43783,43752,39487,39316,39446,1428,1529,1340,4587,4885,4434,36500,36643,36502,42437,42550,42352,6720,6528,6740,6669,6528,6720,43253,43151,42997,43457,43151,43253,36128,36220,36184,36412,36500,36502,36048,35808,35643,40610,40387,40450,40610,40450,40672,252,212,261,215,38,19,130,212,122,228,444,447,35797,35438,35429,42942,42803,42820,42329,42344,42208,41546,41494,41744,42708,42799,42703,42847,42799,42708,4811,4893,4885,4898,4893,4813,42395,42461,42516,42550,42634,42501,42206,42437,42352,42119,41829,41665,42663,42634,42550,41546,41744,41601,6982,6671,6870,7381,7328,7314,7308,7328,7381,5228,5783,5634,4336,4885,4367,3424,3769,3281,429,396,604,429,604,373,42741,42526,42678,43151,43073,43026,43239,43073,43343,35993,36220,36128,36048,36220,35993,42139,42168,42152,42177,42168,42139,42004,41764,41879,42741,42678,42803,42359,42437,42206,43073,42942,42820,3962,4078,4121,1318,1201,1208,1277,1417,1538,1484,1588,1605,36581,36500,36412,37371,37233,37878,42882,42741,42803,1975,2087,2112,2027,2087,1975,7328,7175,7314,36857,36932,36643,1724,1946,1825,42116,42208,42169,40098,40296,40274,1004,1016,1135,1340,1529,1512,1693,1918,1975,16,1005,340,42169,42208,42344,42666,42461,42526,39516,39487,39446,39316,39100,39133,39657,39487,39516,39749,39840,39559,39778,39840,39749,39842,39979,39987,39979,40072,39987,40098,40162,40072,40098,40274,40162,43211,42799,42962,43211,42573,42799,43897,43752,43252,1256,1201,1318,1222,1201,1256,6528,6286,6613,6687,6671,6982,40296,40451,40274,42658,42344,42450,39657,39516,39559,40274,40310,40297,39803,40138,39598,40063,40138,39803,3151,3531,3314,3218,3424,3281,3928,4099,4078,3222,3424,3218,40610,40672,41015,130,38,215,130,215,212,212,252,228,40138,40338,39897,1340,1512,1078,42847,42708,42634,42561,42523,42437,42254,42119,41665,42516,42680,42450,42741,42666,42526,42680,42666,42715,42923,42803,42942,41054,41162,41404,1825,2120,2221,1484,1277,1538,6485,6286,6528,36581,36791,36500,36791,36857,36643,36149,36048,35643,2771,2351,3088,228,447,223,1918,2027,1975,1351,1340,1317,4893,4898,5347,6460,7148,6803,4681,4893,4811,4281,4114,4367,42971,42923,42942,42882,42923,42971,1016,909,977,1201,1113,1135,989,1113,1201,42119,42177,42139,42201,42177,42119,1724,1717,1820,1697,1717,1724,7175,7053,6987,6671,6669,6720,7308,7053,7175,5390,5834,5347,1484,1605,1581,4281,4099,4114,4801,5291,5347,7328,7308,7175,7758,7308,7381,34789,34869,34714,35414,34869,35127,35414,35127,35438,35605,35438,35805,36257,35951,36454,42523,42550,42437,1113,1004,1135,916,1004,1113,5390,5291,5318,349,447,396,6687,6982,6896,6687,6669,6671,36791,36643,36500,42359,42206,42168,5859,6127,6070,6111,6127,5942,2087,2093,2253,2093,2027,2006,41067,41054,41421,41601,41341,41546,41494,41764,41744,41744,41764,41767,42680,42516,42666,42750,42847,42634,39840,39657,39559,39487,39415,39316,39925,39914,39840,39998,39914,39925,39998,39925,39987,39998,39987,40181,40259,40072,40162,40297,40162,40274,40296,40387,40451,1004,909,1016,916,909,1004,5291,5390,5347,5318,5291,5238,42523,42663,42550,42288,42359,42168,42288,42168,42177,40451,40387,40653,37493,37762,37045,36581,36412,36590,39657,39415,39487,37643,37152,36631,39246,39438,38702,40419,40533,40338,39246,38702,38686,42715,42666,42741,42614,42663,42523,1277,1222,1256,1717,1484,1581,1310,1484,1717,4587,4681,4811,4576,4681,4587,41404,41162,41341,41767,41764,42004,1959,1825,2221,40310,40542,40400,373,604,740,228,122,212,130,122,38,103,122,228,6669,6560,6528,5634,5783,6255,6659,6687,6652,43655,43457,43320,42923,42882,42803,43852,43903,42841,40338,40533,39956,40419,40338,40138,42971,42942,43069,42847,42932,42799,42872,42932,42847,3878,4078,3962,4707,4813,4681,4681,4813,4893,39100,38514,39011,41404,41341,41601,40310,40274,40451,42080,41767,42004,42663,42750,42634,42359,42507,42437,42554,42507,42359,39415,39100,39316,42353,42169,42476,42692,42450,42680,42254,42201,42119,42797,42715,42741,42784,42750,42717,4336,4434,4885,429,349,396,356,349,429,6659,6560,6669,6659,6669,6687,42962,42799,42932,43541,43380,43653,43211,43380,43237,3424,3878,3962,4361,4430,4434,3928,3878,3835,41,79,340,1078,1292,997,42882,42797,42741,43069,42942,43073,4430,4461,4434,4434,4461,4587,42507,42561,42437,42784,42872,42847,42614,42561,42686,42201,42288,42177,42416,42288,42201,2027,2093,2087,1785,1529,1693,1529,1428,1351,3878,3928,4078,36791,36860,36857,36590,36412,36453,42818,42797,43012,42715,42692,42680,1484,1222,1277,909,881,977,1148,1222,1112,4461,4576,4587,4801,5347,4898,4491,4576,4461,862,916,1113,4801,4898,4813,5390,5681,5814,1351,1428,1340,3928,4114,4099,36743,36860,36791,6560,6485,6528,6556,6659,6652,349,247,447,369,373,518,39438,39924,39803,40063,39924,40092,38995,38885,39100,39914,39657,39840,40181,39987,40072,40181,40072,40259,40387,40610,40653,43012,42797,42882,43239,43069,43073,43073,43151,43343,3314,3531,3632,1932,2017,2002,1762,1697,1825,3531,3950,3632,3950,4268,3981,39924,40063,39803,42577,42254,41665,4491,4674,4576,4576,4674,4681,40093,39657,39914,40063,40131,40138,4426,5009,4991,6460,6268,6111,6460,6803,6268,34887,35398,34780,36453,36412,36220,36581,36743,36791,41067,40672,41054,42962,42872,43089,42784,42847,42750,916,881,909,862,881,916,1386,1351,1317,4665,4707,4674,4674,4707,4681,42288,42399,42359,42399,42416,42442,5505,5681,5390,5859,5681,5841,42095,41744,41767,42818,42692,42715,42818,42715,42797,6556,6485,6560,373,356,429,369,356,373,43012,42882,42971,43343,43452,43364,1825,1697,1724,1222,1148,1201,2017,2247,2351,42872,42962,42932,42750,42663,42717,4713,4426,4991,4707,4801,4813,4314,4434,4336,43075,42971,43069,42259,42004,42169,41404,41601,41924,42614,42523,42561,43756,43897,43833,43862,43897,43252,43541,43252,43380,4430,4491,4461,356,247,349,242,247,356,2017,2351,2002,1890,2006,2027,2093,2059,2840,3835,4067,3928,3928,4067,4114,4114,4229,4336,4430,4361,4491,1890,2027,1918,41775,41651,41421,43343,43151,43452,43239,43075,43069,122,27,38,223,103,228,5634,6255,6057,6659,6556,6560,6896,6982,7053,6255,6286,6057,42416,42399,42288,42416,42675,42471,42554,42561,42507,43243,43075,43239,43903,43655,43320,2017,1959,2221,1118,1148,1112,1837,1890,1918,3835,3878,3274,1222,1484,1112,238,223,247,37152,36525,36582,37878,37233,37875,36453,36220,36382,4067,4098,4114,38885,38626,38021,37834,37152,37643,38885,38021,39100,40259,40162,40297,39998,40093,39914,38995,39100,39999,40259,40297,40310,40131,40230,40138,40063,40124,40131,40092,40124,40063,40092,39924,40119,40257,40259,40345,40124,40230,40131,6313,6286,6485,42770,42717,42614,42614,42717,42663,43138,43089,42872,43653,43380,43211,1351,1386,1529,1078,997,878,4637,4665,4551,4491,4665,4674,40230,40419,40138,878,997,805,373,740,518,247,223,447,4098,4229,4114,242,369,238,37233,37045,37875,36382,36220,36048,43092,42971,43075,43092,43012,42971,42080,42004,42259,43243,43239,43343,1386,1693,1529,4229,4314,4336,41015,40672,41067,40807,40653,40610,42169,42353,42259,1144,1646,1693,1078,1317,1340,5228,4713,4991,4426,4339,4268,4088,3621,3475,36743,36581,36590,42534,42554,42359,42442,42359,42399,36742,36743,36590,4713,4339,4426,4314,4361,4434,6111,6268,6127,6127,5859,5942,369,242,356,754,977,881,4665,4801,4707,4760,4801,4637,35789,36149,35643,36453,36437,36590,40119,39924,39438,37880,37878,37875,43364,43243,43343,41028,41015,41177,36168,36382,36048,43218,43092,43075,42344,42658,42169,42554,42686,42561,42717,42871,42784,42534,42686,42554,1954,2006,1890,1954,2041,2006,2006,2041,2093,4161,4229,4098,4161,4314,4229,4243,4263,4314,4314,4263,4361,1954,1890,1837,39862,39415,39657,38626,38154,37643,43317,42818,43012,40652,40653,40807,1959,1762,1825,2017,1932,1959,2243,2351,2771,2243,2771,2289,2771,2317,2289,1837,1918,1646,4088,3981,4268,886,862,1113,1118,1201,1148,42416,42201,42254,43092,43218,43012,43243,43218,43075,43452,43151,43457,43036,42770,42686,42686,42770,42614,1646,1918,1693,223,27,103,103,27,122,104,27,223,238,247,242,43089,43211,42962,1112,951,1009,40181,40093,39998,40244,40093,40181,40257,40181,40259,40259,40310,40345,38503,37845,37918,40124,40232,40230,40230,40413,40419,40419,40554,40533,40345,40310,40400,40310,40451,40542,1729,1762,1959,40542,40451,40643,40521,40413,40230,40643,40653,40652,40643,40451,40653,40413,40554,40419,862,787,881,820,787,862,42871,42872,42784,42442,42534,42359,42569,42534,42442,41421,41054,41404,41924,41601,41744,1009,989,1118,1118,989,1201,40807,40610,40949,43550,43452,43457,43351,43218,43243,43550,43457,43734,5942,5859,5841,36149,36168,36048,36382,36437,36453,37875,37045,37762,36300,36168,36149,2464,2474,2460,1932,1729,1959,40949,40610,41015,35805,35438,35797,35571,35605,35622,4361,4263,4491,5238,5390,5318,3956,4098,4067,38205,38503,37918,37880,37918,37878,5238,5291,4789,36168,36437,36382,42871,42717,42770,37875,37930,38003,2243,2140,2351,3981,3632,3950,3475,3632,3981,4088,4268,4339,41028,40949,41015,7308,6896,7053,6556,6313,6485,35571,35414,35438,820,754,787,787,754,881,43021,42871,43036,42471,42675,42630,41177,41015,41067,42871,42770,43036,37880,38049,37918,37883,37875,38003,120,238,369,3252,3878,3424,2954,2840,2509,2093,2041,2059,754,518,740,989,886,1113,819,886,776,1064,951,1112,805,997,802,1078,1086,1317,1144,1693,1386,43351,43243,43364,42080,42095,41767,35622,35605,35805,35605,35571,35438,3835,3956,4067,4789,5291,4801,1619,1697,1762,42169,42658,42476,41129,40949,41028,38603,38154,38626,38995,38626,38885,43452,43485,43364,43903,43856,43655,2059,2041,1892,3835,3851,3956,1821,1729,1932,38503,38780,38686,38720,38780,38503,42577,40308,40533,40413,40521,40554,40092,40232,40124,40145,40232,40092,886,820,862,819,820,886,4665,4491,4551,3024,3222,3218,238,104,223,120,104,238,6422,6313,6556,5634,5236,5228,3895,4088,4339,40787,40652,40807,40787,40643,40652,40687,40516,40643,40643,40516,40542,40542,40516,40400,40400,40516,40345,40244,40181,40257,40244,40202,40093,40093,40202,39657,40787,40807,40949,40787,40949,40916,6313,6057,6286,1892,2041,1849,1086,1386,1317,4011,4161,4098,3973,4098,3956,5942,5932,6111,5505,5841,5681,4161,4243,4314,4011,4243,4161,2140,2002,2351,2243,2197,2140,2464,2771,2474,41177,41067,41243,37883,38049,37880,37883,37880,37875,42450,42692,42658,41193,41177,41243,39138,39246,38686,39138,38686,39081,1009,1118,1112,2197,2072,2140,79,16,340,43734,43457,43655,43218,43317,43012,43485,43351,43364,38049,38205,37918,38049,37883,38003,6313,6203,6057,6896,6652,6687,35797,35951,36257,35571,35622,35414,2072,2002,2140,2041,1954,1849,5841,5932,5942,6065,6457,6460,5861,5932,5841,37834,37643,37811,42416,42471,42442,42871,43021,42872,42586,42471,42630,42095,42080,42259,886,989,948,733,754,820,418,518,754,42707,42686,42534,43666,43653,43211,3418,3851,3835,5187,5505,5238,1484,1129,1064,878,773,1078,1849,1954,1837,59,805,802,42471,42569,42442,42586,42569,42471,43351,43264,43218,43570,43485,43452,43570,43452,43550,6065,6460,6111,6460,6457,6850,36454,36179,36525,36661,36742,36437,38182,38147,38131,35398,35789,35643,43541,43862,43252,43371,43211,43089,5932,5997,6111,5238,5505,5390,4801,4665,4637,3851,3973,3956,43353,43264,43351,1691,1762,1729,40041,40119,39438,40232,40521,40230,40257,40345,40350,40244,40257,40350,40345,40632,40350,40119,40145,40092,38147,38205,38049,40340,40298,40119,38147,38049,38003,3222,3252,3424,3851,3418,3973,2900,3024,3218,2886,3024,2900,40504,40444,40364,40345,40516,40632,43021,43138,42872,43188,43138,43197,1744,1691,1729,4673,4713,5228,2771,2543,2474,3973,4011,4098,3603,4011,3973,2289,2197,2243,1916,1877,2002,2002,1821,1932,3151,2543,2771,40421,40521,40232,2464,2317,2771,38627,38720,38503,37493,37045,36857,38456,38503,38205,93,369,518,1009,948,989,913,948,1009,43617,43570,43550,43504,43353,43351,43504,43351,43485,42658,42692,42700,43771,43734,43655,2317,2197,2289,5779,5861,5841,5800,5861,5779,43138,43223,43089,43188,43223,43138,42462,42095,42259,41177,41193,41028,42476,42259,42353,43653,43862,43541,43820,43862,43653,42692,42921,42700,2059,2509,2840,1849,1837,1713,41243,41067,41513,877,1086,1078,773,878,805,4491,4263,4551,93,120,369,104,100,27,733,820,819,6057,5708,5634,6652,6422,6556,948,776,886,853,776,948,743,773,805,951,913,1009,1877,1821,2002,1713,1837,1646,41513,41067,41421,42569,42605,42534,40868,40533,40554,4760,4789,4801,4708,4789,4760,42095,41924,41744,41404,41900,41775,1467,1713,1646,3024,2968,3222,4551,4263,4243,2701,2886,2900,2509,2232,2343,2059,1892,1859,776,733,819,769,733,776,4789,5187,5238,42476,42462,42259,42692,43106,42921,42586,42605,42569,42707,42605,42630,40244,40314,40202,39862,39100,39415,40350,40364,40244,40916,40643,40787,40916,40949,41129,37152,37093,36525,37147,37093,37152,36925,37093,37199,6422,6203,6313,43353,43317,43264,43570,43558,43485,43617,43558,43570,1859,1892,1849,43734,43704,43550,43771,43704,43734,1619,1762,1691,5800,5932,5861,5800,5997,5932,38147,38182,38205,38720,38870,38780,38003,38189,38131,1916,2002,2072,2061,1916,2197,2464,2460,2317,3151,3314,3042,1608,1619,1691,1744,1729,1821,41129,41028,41193,41651,41513,41421,36824,36689,36525,43223,43267,43089,43197,43138,43021,40521,40868,40554,40736,40868,40521,40298,40232,40145,40298,40145,40119,41129,41193,41265,475,418,754,913,853,948,888,853,913,37093,36925,36525,36824,36925,36991,42707,43036,42686,43704,43617,43550,43558,43504,43485,41265,41193,41243,43677,43642,43617,43856,43771,43655,5779,5841,5430,4789,4970,5187,4708,4637,4551,36860,37493,36857,38496,38456,38205,5841,5505,5430,43188,43267,43223,43283,43267,43188,38496,38205,38392,656,754,733,1064,1112,1484,1916,2072,2197,36925,36824,36525,36454,35951,36179,37147,37152,37320,4637,4708,4760,4712,4708,4619,1877,1744,1821,1713,1770,1849,1703,1770,1713,968,1386,1086,41513,41366,41243,41419,41366,41556,41651,41775,41686,93,100,120,120,100,104,35805,35811,35622,36454,36525,36689,43642,43558,43617,43642,43504,43558,43371,43666,43211,771,769,776,771,776,853,36583,36454,36689,37834,37811,38154,36709,36689,36824,38872,38870,38720,1717,1697,1310,2886,2968,3024,2556,2701,2900,2806,2701,2757,40455,40298,40340,5733,5708,6057,36876,36709,36824,2903,2968,2886,42630,42605,42586,40298,40421,40232,2061,2197,1977,1877,1761,1744,3175,3314,3632,2993,2921,3042,3175,2993,3042,40687,40643,40953,40687,40632,40516,39976,39657,40202,40687,40779,40705,769,656,733,418,93,518,624,656,769,3140,3252,3222,40643,40916,40953,42658,42700,42476,43317,43218,43264,43197,43283,43188,43267,43371,43089,42605,42707,42534,42416,42254,42675,830,888,951,951,888,913,41366,41265,41243,41603,41651,41686,6203,6103,6057,6422,6252,6203,6236,6252,6422,6490,6422,6652,43790,43617,43704,43700,43317,43353,6896,6490,6652,36279,35811,36257,36257,35811,35805,35622,35811,35414,36556,36257,36454,43771,43790,43704,43876,43790,43771,5800,5925,5997,5997,6065,6111,5430,5505,5103,43416,43317,43508,43122,43021,43036,38456,38627,38503,39081,38686,38780,38496,38627,38456,1310,1697,1619,38003,38131,38147,36860,37425,37493,36814,36583,36689,37199,36991,36925,36876,36991,37077,43191,43122,43036,1744,1608,1691,2334,2317,2460,877,968,1086,743,1078,773,1770,1859,1849,1703,1859,1770,39081,38780,38870,41417,41265,41366,43642,43677,43504,43790,43677,43617,43856,43876,43771,36556,36583,36814,43406,43371,43283,43283,43371,43267,39019,39081,38870,38392,38205,38182,888,771,853,656,586,754,830,771,888,43191,43228,43122,43122,43197,43021,42675,42254,42577,1848,1761,1877,624,769,771,38872,38720,38826,43228,43197,43122,4708,4712,4789,4551,4460,4601,40314,40244,40364,41556,41366,41513,41556,41513,41603,38826,38720,38627,38313,38392,38182,38826,38627,38783,41603,41513,41651,3252,3274,3878,2968,3140,3222,2701,2806,2886,2556,2900,2509,40444,40314,40364,40364,40350,40504,40350,40632,40504,40632,40581,40504,40705,40581,40632,2695,2543,3151,2474,2334,2460,1916,1848,1877,2559,2556,2536,2806,2903,2886,40687,40705,40632,6236,6108,6252,6252,6108,6203,2800,2921,2703,40953,40779,40687,3175,3042,3314,5236,5634,5708,41038,40953,40916,38603,37834,38154,36814,36689,36709,38392,38597,38496,38131,38313,38182,38342,38313,38372,2379,2334,2474,2903,3140,2968,41129,41038,40916,40738,40736,40521,40738,40521,40421,40455,40421,40298,39871,40023,40041,39871,40041,39438,41129,41200,41038,41421,41404,41775,41265,41200,41129,41265,41318,41200,624,586,656,925,951,1064,41366,41419,41417,41404,41924,41900,41924,42267,41900,41419,41556,41417,36860,36743,37425,1977,2197,2317,1275,1310,1619,6108,6103,6203,6490,6236,6422,43763,43677,43790,43190,42692,42818,16,86,1005,41417,41556,41501,41900,42357,41945,41556,41603,41720,4712,4970,4789,4551,4412,4460,43190,42818,43317,1945,1848,1916,613,743,397,1467,1703,1713,42630,42749,42707,42807,42675,42577,1608,1744,1761,41924,42095,42267,41720,41603,41686,43197,43331,43283,43850,43820,43666,43191,43036,42707,1033,925,1064,4551,4619,4708,4601,4619,4551,2536,2556,2509,1010,1386,968,41720,41686,41945,6055,6103,6108,5925,6065,5997,5925,5800,5779,35789,36300,36149,42675,42749,42630,42807,42749,42675,36876,36824,36991,36583,36556,36454,1583,1608,1761,1310,1129,1484,743,877,1078,968,877,806,37762,37930,37875,38313,38342,38392,37790,37930,37762,1223,1129,1310,37199,37093,37147,40041,40023,40047,38189,38313,38131,43228,43331,43197,43299,43331,43228,2315,2291,2334,2334,2291,2317,2061,1945,1916,1684,1583,1761,2800,2695,3151,2800,3151,3042,3140,3274,3252,2903,2801,3140,2806,2801,2903,2617,2757,2701,2559,2701,2556,2536,2509,2410,2695,2800,2703,2757,2801,2806,40444,40456,40314,40314,39976,40202,40567,40456,40444,40567,40444,40504,40567,40504,40581,40567,40581,40722,40581,40705,40722,40705,40823,40722,40779,40823,40705,41021,40823,40779,39138,39081,39197,40736,40859,40868,2410,2509,2343,40953,41021,40779,40455,40560,40421,2509,2091,2232,40456,39976,40314,37219,37320,37404,39019,38870,38872,1608,1511,1619,1526,1511,1608,1883,2059,1859,39976,39862,39657,40953,41038,41021,40560,40738,40421,586,475,754,674,624,771,830,951,925,36742,36590,36437,42749,42796,42707,42947,42796,42749,2457,2474,2543,41139,41038,41200,40738,40859,40736,5103,5505,5187,37320,37152,37834,37320,37199,37147,1129,1045,1064,1095,1045,1129,803,830,925,38597,38627,38496,41233,41139,41200,41945,41686,41775,41945,41775,41900,43666,43820,43653,43850,43666,43371,5662,5925,5779,2960,3274,3140,36866,36814,36876,36876,36814,36709,36661,36437,36168,43331,43406,43283,43431,43406,43331,2291,1977,2317,41318,41265,41417,1045,1033,1064,1029,1033,1045,1275,1619,1295,38372,38189,38229,38228,38189,38003,38501,38597,38392,1977,1945,2061,43300,43190,43317,42462,42476,43030,1794,1883,1859,1794,1859,1703,1295,1619,1511,43677,43881,43504,43876,43763,43790,1650,1794,1703,41501,41318,41417,36742,37031,36743,38372,38313,38189,36300,36661,36168,37199,37139,36991,37139,37320,37219,1228,1223,1275,1275,1223,1310,38501,38342,38372,38501,38392,38342,38965,39019,38872,624,475,586,830,674,771,670,674,830,670,830,803,4530,4970,4712,5430,5453,5779,4601,4712,4619,1526,1583,1435,38965,38872,38826,39029,38965,38826,38003,37930,38228,6103,5733,6057,6236,6055,6108,6049,6055,6236,38645,38627,38597,2695,2669,2543,2291,1974,1977,1977,1967,1945,1945,1819,1848,2703,2669,2695,2800,3042,2921,2759,2960,3140,2757,2617,2801,2559,2617,2701,2477,2617,2559,2477,2559,2536,2477,2536,2424,2536,2410,2424,2410,2343,2354,40191,40340,40119,40455,40552,40560,40560,40592,40738,40738,40847,40859,43212,43191,42796,40191,40119,40041,40191,40041,40047,43190,43106,42692,41233,41200,41376,43300,43106,43190,2509,2059,2091,39805,39871,39438,40500,40552,40455,2395,2457,2543,39246,39805,39438,2457,2379,2474,39197,39081,39019,1087,1095,1129,1087,1129,1223,37790,37762,37658,38547,38645,38597,2379,2315,2334,2091,2059,1883,41036,40864,40823,40823,40864,40722,40722,40616,40567,40567,40616,40456,40456,40654,39976,39976,39999,39862,41021,41038,41071,41071,41139,41233,41071,41038,41139,4970,5103,5187,5055,5103,4970,783,1010,968,1794,1803,1883,806,877,712,41501,41556,41713,37320,37139,37199,37077,37139,37219,42796,43191,42707,43406,43699,43371,43299,43358,43463,37658,37762,37493,1974,1967,1977,1376,1295,1511,1526,1608,1583,42476,42700,43030,36661,36759,36742,36806,36759,36661,38001,38228,37930,38547,38597,38501,460,475,624,530,624,674,925,841,803,925,1033,841,38547,38501,38608,38965,39197,39019,37139,37077,36991,36645,36279,36556,36556,36279,36257,38603,38626,38995,37063,37031,36742,37790,38001,37930,43416,43300,43317,43176,42700,42921,43191,43299,43228,40533,42246,42577,1491,1650,1703,4243,3603,4551,4551,3603,4412,43176,42921,43106,39432,38603,38995,39999,39100,39862,39257,39197,38965,38608,38501,38372,38229,38189,38228,38783,38627,38645,41852,41556,41720,41852,41720,41945,173,93,418,5315,5236,5708,1029,1045,1095,1684,1761,1848,1087,1223,1098,412,423,475,330,173,418,1144,1467,1646,712,877,743,38083,38001,38075,423,418,475,1228,1275,1295,2669,2497,2543,2107,2185,2379,2379,2185,2315,2315,2185,2291,1967,1819,1945,3175,3069,2993,40552,40592,40560,40340,40500,40455,40469,40500,40340,40469,40340,40191,40213,40191,40047,40055,40047,40023,2354,2424,2410,2477,2424,2617,3121,3418,3274,2354,2343,2232,40869,40616,40722,40869,40722,40864,40869,40864,41036,40823,41021,41036,40500,40592,40552,2083,2354,2232,1144,1386,1102,2091,1894,2010,2779,2921,2882,39871,40055,40023,41036,41021,41088,40592,40847,40738,2370,2379,2457,39805,39246,39709,5811,5733,6103,6490,6049,6236,36866,36556,36814,1087,1029,1095,949,1029,1087,42462,42267,42095,41945,42357,41981,1803,1794,1710,39709,39246,39138,1526,1376,1511,1354,1376,1526,41376,41200,41318,41804,41852,41968,37077,36866,36876,37052,36866,37077,43463,43431,43331,43463,43331,43299,38220,38229,38228,38700,38783,38645,39855,39856,39805,38220,38228,38001,1831,1819,1967,41376,41318,41533,613,712,743,1102,1386,1010,5453,5386,5295,5037,5386,5430,5925,5720,6065,1710,1794,1650,1710,1650,1491,41533,41318,41501,1376,1228,1295,1304,1228,1376,38700,38645,38547,43763,43881,43677,43300,43176,43106,43876,43881,43763,4601,4530,4712,3418,3835,3274,38608,38700,38547,38083,38220,38001,1819,1684,1848,1640,1710,1491,5453,5662,5779,530,670,511,530,674,670,173,66,93,841,1033,1029,37031,37425,36743,37272,37425,37031,42912,42807,42966,1228,1121,1223,1019,1121,1031,1102,1010,1032,40055,39871,40164,38371,38372,38229,5386,5453,5430,5493,5453,5295,38220,38371,38229,38075,38001,38019,1121,1098,1223,949,1098,1019,1491,1703,1467,783,968,806,511,670,568,37680,37658,37493,42807,42947,42749,42912,42947,42807,41852,41713,41556,41804,41713,41852,5811,6103,6055,2675,2703,2599,36772,36645,36866,36866,36645,36556,40213,40047,40176,40213,40469,40191,40641,40740,40592,40592,40740,40847,41521,40868,40859,40047,40055,40176,40055,40164,40176,2675,2497,2669,2185,2129,2291,1819,1789,1684,2675,2669,2703,2703,2921,2779,3103,3069,3175,2497,2395,2543,39871,39805,39856,2395,2370,2457,3981,4088,3475,39138,39467,39709,40768,40764,40869,40869,40764,40616,40654,39999,39976,41021,41071,41088,41071,41201,41088,40641,40592,40500,43508,43317,43700,41968,41852,41945,43699,43850,43371,43358,43299,43191,4339,4291,3895,40654,40456,40616,41071,41233,41201,41968,41945,41981,2107,2129,2185,1435,1354,1526,3140,2801,2759,2354,2083,2424,2091,2104,2232,2010,2104,2091,2091,1883,1894,1883,1803,1894,39138,39197,39467,41233,41259,41201,2129,1974,2291,1894,1803,1751,41233,41355,41259,530,460,624,423,330,418,434,460,449,42947,43010,42796,43004,43010,42947,38784,38826,38783,38177,38371,38220,38177,38220,38083,41533,41501,41705,41938,41968,41981,37404,37910,37783,37052,37219,37404,37572,37680,37493,38019,38001,37790,37063,37272,37031,1640,1803,1710,38784,38783,38771,41533,41573,41544,5022,4673,5236,6049,5811,6055,1974,1831,1967,38771,38783,38700,86,59,802,712,687,806,949,841,1029,949,1087,1098,460,412,475,434,412,460,397,743,805,1101,1467,1144,1081,1144,1102,2485,2617,2424,39257,39467,39197,4673,5228,5236,41808,41713,41804,687,783,806,4460,4503,4601,4412,4503,4460,1032,1081,1102,1472,1491,1268,39029,39257,38965,5493,5720,5662,5662,5720,5925,5493,5662,5453,36759,37063,36742,37272,37432,37425,36300,36806,36661,412,330,423,434,330,412,37544,37432,37435,38480,38608,38372,38922,39029,38826,43010,43212,42796,40928,40859,40847,43115,43212,43010,4503,4530,4601,4524,4530,4503,5055,5430,5103,37219,37052,37077,37320,37910,37404,36806,37063,36759,38019,37790,37936,38480,38372,38371,40264,40213,40176,40537,40469,40213,40537,40641,40469,40469,40641,40500,40740,40928,40847,40264,40176,40164,39871,39974,40164,39856,39974,39871,39856,39855,39974,1435,1583,1684,449,460,530,38922,38826,38784,39805,39709,39855,39709,39870,39855,40969,41036,41102,40969,40869,41036,40969,40768,40869,40764,40935,40616,41036,41088,41102,37572,37425,37544,37572,37493,37425,42912,43004,42947,43115,43004,43085,2993,2882,2921,2779,2599,2703,2675,2434,2497,2107,2370,2062,1966,2107,2062,2370,2107,2379,2129,2043,1974,1974,1964,1831,1831,1789,1819,2858,2882,2993,41102,41088,41172,40931,40928,40740,37231,37404,37694,43699,43406,43431,43699,43431,43638,43431,43463,43638,2434,2395,2497,39709,39467,39495,1019,1098,1121,38177,38083,38075,38533,38480,38371,38771,38922,38784,43358,43191,43212,397,687,613,613,687,712,1032,1101,1081,37936,37790,37658,1354,1304,1376,1240,1304,1354,2107,2043,2129,2104,2083,2232,2010,1980,2104,1862,1980,2010,1862,2010,1894,1751,1803,1640,3103,3175,3632,39495,39467,39506,41172,41088,41201,41408,41233,41376,41968,41938,41804,41981,42114,42052,2043,1964,1974,3221,3103,3632,43416,43508,43300,43700,43353,43504,3475,3221,3632,3300,3221,3475,41408,41376,41544,39506,39467,39257,38771,38700,38608,41544,41376,41533,41981,42335,42114,790,803,841,4750,5055,4970,37544,37425,37432,37876,37936,37658,37981,37936,38008,38071,38177,38075,38776,38771,38608,1964,1789,1831,1101,1144,1081,1751,1640,1695,1727,1751,1695,43302,43358,43212,39506,39257,39455,41501,41713,41808,949,790,841,765,790,949,1121,1228,1111,4979,5037,5055,3603,4243,4011,43699,43883,43850,43598,43638,43463,41808,41804,41938,37981,38019,37936,37435,37432,37272,37435,37272,37330,43461,43176,43300,1032,1010,783,38922,39006,39029,38557,38608,38480,38075,38019,38071,4412,4524,4503,4432,4524,4412,38071,38019,37981,1261,1435,1684,1111,1228,1304,998,1032,563,1695,1640,1596,37658,37680,37876,37330,37272,37312,43729,43684,43638,43322,43302,43212,43115,43010,43004,43142,43148,43156,43816,43700,43504,41847,41808,41884,41705,41808,41847,40300,40264,40164,40418,40537,40264,40264,40537,40213,40641,40839,40740,42246,40533,40868,40300,40164,40254,40164,39974,40102,2882,2599,2779,2107,1966,2043,2043,1966,1964,1964,1634,1789,1789,1634,1684,2799,2599,2882,2858,2993,3069,2858,3069,2998,38533,38557,38480,37680,37572,37730,40102,40246,40254,40102,39974,39855,40742,40839,40641,39049,39006,38955,38776,38557,38842,40839,40931,40740,39870,39709,39739,42966,43004,42912,41259,41172,41201,41102,41285,40969,40969,40935,40768,40768,40935,40764,39999,39432,38995,41268,41172,41259,41355,41233,41456,41233,41408,41456,37571,37572,37544,37312,37272,37063,38791,38922,38771,5315,5708,5733,3087,3069,3103,38071,38096,38177,39049,39146,39006,37571,37544,37435,1751,1727,1894,1980,2083,2104,4979,4572,4879,1640,1491,1596,41456,41408,41566,4291,4339,4713,1596,1472,1612,3318,3300,3475,41566,41408,41544,41521,40859,40928,5055,5037,5430,5493,5435,5720,4750,4970,4530,37700,37671,37776,4486,4750,4530,3603,3973,3418,1491,1467,1268,39146,39257,39029,5037,5295,5386,37496,37571,37435,37204,37312,37063,1019,931,949,568,670,803,1020,1111,929,1111,1304,1117,41705,41573,41533,41705,41501,41808,1111,1031,1121,1020,1031,1111,1032,998,1101,470,1032,783,621,783,687,43638,43684,43699,43503,43463,43358,43469,43358,43302,43322,43212,43115,41808,41938,41884,43276,43322,43115,182,66,330,330,66,173,707,803,790,37981,38096,38071,39006,39146,39029,37730,37876,37680,37730,37572,37700,43087,42966,42807,315,330,434,5202,5435,5295,5295,5435,5493,5202,5295,5037,37700,37572,37571,36806,37204,37063,43469,43503,43358,41884,41938,42052,765,707,790,40418,40264,40300,40596,40742,40537,40537,40742,40641,41260,41258,40931,43203,43087,43217,40254,40164,40102,3895,3621,4088,3568,3621,3895,38791,38771,38776,39981,40102,39855,42267,42357,41900,42052,41938,41981,41268,41259,41355,41212,41102,41172,41026,40935,41061,41268,41345,41212,41355,41345,41268,41544,41573,41566,41573,41747,41566,511,449,530,318,449,511,38008,38096,37981,37435,37330,37496,43738,43598,43503,42966,43085,43004,43276,43085,43324,1942,2083,1980,1862,1894,1779,1894,1727,1779,1727,1635,1779,5811,5654,5733,4673,4291,4713,6049,5654,5811,36645,36772,36279,37052,36772,36866,37231,36772,37052,37231,37052,37404,2062,2370,2009,3087,3103,3221,3087,3221,3122,38008,37936,37876,41573,41705,41747,42267,42664,42357,2434,2675,2599,43503,43598,43463,43469,43302,43419,1727,1695,1635,3122,3221,3190,41705,41907,41747,1635,1695,1612,3190,3221,3300,449,315,434,308,315,262,37328,37330,37312,38134,38008,37942,41747,41907,41722,43030,42700,43176,3650,4291,3888,3318,3190,3300,765,949,727,465,568,707,707,568,803,38008,37876,37942,38776,38608,38557,43516,43469,43419,1749,1634,1964,1612,1695,1596,3318,3191,3261,43700,43875,43508,43881,43816,43504,1472,1596,1491,3190,3318,3214,931,1019,1031,43598,43729,43638,43684,43764,43699,43738,43729,43598,41847,41907,41705,5315,5022,5236,43148,43030,43176,1240,1354,1435,39323,39455,39257,38557,38533,38842,40620,39432,39999,39323,39257,39146,41566,41747,41722,41884,42032,41847,39311,39323,39146,1020,931,1031,727,931,789,38955,39006,38922,38533,38177,38096,42691,42267,42462,33,397,805,1268,1467,1071,43729,43764,43684,43761,43764,43729,2322,2434,2599,1966,1749,1964,1227,1240,1435,2799,2882,2858,2998,3069,3087,2998,3087,3122,2998,3122,2808,397,621,687,43087,42807,42577,39709,39495,39739,39495,39506,39739,3206,3603,3418,4750,4979,5055,3214,3122,3190,3214,3318,3261,2485,2801,2617,2485,2424,2262,1942,1980,1862,1692,1862,1779,1692,1779,1635,40935,41026,40616,41268,41212,41172,41345,41355,41506,41355,41456,41506,41456,41598,41506,38955,38922,38791,39739,39506,39601,38008,38134,38096,38939,38955,38791,37942,37876,37730,37942,37730,37805,1843,1749,1966,39506,39455,39601,41456,41566,41598,43085,42966,43324,43276,43115,43085,43516,43503,43469,43740,43738,43503,39601,39455,39535,38939,38791,38828,3568,3895,3565,3409,3475,3621,39455,39323,39418,41598,41566,41722,318,315,449,315,308,330,318,511,391,651,707,765,4432,4530,4524,43403,43276,43348,59,33,805,979,998,779,4979,5202,5037,5435,5284,5720,37204,37328,37312,37261,37328,37204,43419,43302,43322,39418,39323,39311,42160,42052,42114,39121,39146,39049,38828,38791,38776,1557,1692,1635,1467,979,1071,672,651,765,727,949,931,42357,42335,41981,43054,42691,42462,43054,42462,43030,43901,43761,43738,43738,43761,43729,43764,43883,43699,39121,39049,39163,38842,38828,38776,38898,38828,38842,42584,42335,42357,308,182,330,188,182,308,43276,43403,43322,43516,43740,43503,40931,40839,41260,37805,37730,37700,43148,43278,43156,39049,38955,39163,4987,5284,5202,5202,5284,5435,37776,37805,37700,36806,37261,37204,4346,4432,4412,4979,4987,5202,4486,4432,4442,1472,1334,1437,1467,1101,979,40254,40418,40300,40408,40418,40254,39981,39855,39870,39981,39870,39886,39870,39739,39886,1261,1684,1634,3409,3568,3497,262,258,188,465,511,568,38371,38177,38533,37496,37330,37328,41285,41212,41390,41285,41102,41212,41061,40935,41192,41212,41345,41390,41345,41413,41390,37482,37496,37328,43403,43419,43322,43576,43419,43403,1749,1698,1634,2009,2370,2395,2009,2395,1999,2799,2858,2894,2858,2998,2894,43901,43883,43761,43761,43883,43764,2894,2998,2796,4432,4486,4530,4346,4412,4329,39069,38955,38939,39706,39739,39601,38898,38939,38828,2062,1843,1966,3114,3122,3214,41390,41413,41332,39706,39601,39631,41722,41506,41598,318,262,315,465,707,490,38096,38134,38533,37671,37700,37571,1843,1698,1749,1557,1612,1437,1557,1635,1612,929,931,1020,672,727,709,490,707,651,43142,43054,43030,42377,42306,42335,42335,42306,42114,43142,43030,43148,1698,1574,1634,2960,3121,3274,2490,3121,2960,42664,42267,42691,3191,3318,3475,3121,3206,3418,39535,39455,39418,727,672,765,929,1111,1117,37496,37671,37571,38134,37942,37913,37650,37671,37496,41907,41847,42032,42618,42664,42764,43148,43176,43278,1117,1304,1240,39414,39535,39418,37942,37805,37913,39311,39146,39121,4365,4979,4750,4329,4412,3603,42032,41884,42160,41884,42052,42160,39414,39311,39367,37913,37805,37813,37813,37805,37776,42664,42892,42764,43278,43176,43461,39311,39121,39367,42160,42114,42231,40418,40596,40537,40408,40596,40418,40408,40254,40246,40102,39981,40246,39981,40425,40246,4346,4442,4432,4378,4442,4346,2262,2424,2083,3121,2936,3206,39631,39601,39535,1079,1117,1240,1698,1504,1574,1843,1777,1698,2062,1828,1843,1999,2395,2434,2322,2599,2586,2819,2799,2894,41192,40969,41285,41192,40935,40969,41026,40654,40616,41192,41285,41277,41285,41332,41277,41390,41332,41285,41640,41413,41345,42231,42114,42273,1592,1942,1862,1592,1862,1692,2485,2759,2801,4378,4329,4273,41337,41277,41332,1880,1828,2062,2796,2819,2894,41722,41835,41640,42691,43080,42892,43461,43300,43582,37671,37813,37776,37261,37482,37328,41986,41907,42032,42584,42664,42618,592,651,672,492,490,651,465,391,511,709,727,601,1261,1634,1574,789,931,929,38672,38533,38521,39414,39418,39311,38533,38134,38521,391,465,490,258,262,318,262,188,308,182,30,66,1472,1268,1334,1437,1612,1472,3261,3114,3214,3191,3114,3261,3191,3475,3409,390,391,490,43681,43740,43516,41258,40928,40931,1101,998,979,3409,3621,3568,42160,42097,42032,42424,42377,42335,42584,42357,42664,709,592,672,492,592,494,4442,4378,4486,4329,4184,4273,39414,39631,39535,38955,39069,39163,37633,37650,37496,43054,43142,43215,43582,43300,43508,1117,974,929,1385,1261,1574,43681,43516,43419,1261,1227,1435,3565,3895,3650,38939,38898,39069,43142,43156,43215,42231,42097,42160,2242,2322,2586,2009,1947,2062,1828,1777,1843,1141,1066,1227,2217,2322,2242,2796,2998,2808,3122,3114,2808,391,258,318,354,258,391,390,490,492,43087,43324,42966,43203,43324,43087,42114,42306,42273,137,30,188,188,30,182,37482,37633,37496,37746,37813,37671,39069,38898,38989,37656,37633,37482,2035,1999,2434,1999,1947,2009,42273,42306,42398,43215,43156,43303,1947,1880,2062,41260,40839,40742,40754,40813,40596,39886,39739,39706,39886,39706,39818,41337,41247,41277,41277,41247,41192,41192,41276,41061,41061,41276,41026,41337,41332,41413,40813,40742,40596,1066,1079,1240,1066,1240,1227,783,621,470,3497,3565,3510,3111,3114,3191,4291,4673,4473,5654,5315,5733,37320,37834,37910,38292,38135,37910,41345,41506,41640,42306,42377,42398,1880,1777,1828,3111,3191,3389,41506,41722,41640,41722,41907,41956,37746,37671,37650,43324,43348,43276,43495,43348,43324,1079,974,1117,927,974,1079,470,621,397,38898,38842,38989,39818,39706,39631,41956,41907,41986,42398,42377,42424,258,137,188,492,651,592,42032,42097,41986,40755,40408,40633,38989,38842,38841,41986,42221,41992,42424,42335,42584,3389,3191,3409,43816,43875,43700,43461,43421,43278,42631,42424,42584,37656,37746,37650,38841,38842,38533,43582,43421,43461,1557,1334,1475,964,1334,1268,1437,1334,1557,1550,1592,1692,2262,2496,2485,2485,2496,2759,390,354,391,365,354,390,43303,43156,43278,43217,43087,43009,974,893,929,813,893,855,39367,39121,39163,38841,38533,38672,42631,42584,42618,42097,42289,41986,42231,42273,42289,3497,3568,3565,3427,3389,3409,42440,42273,42398,893,789,929,813,789,893,354,298,258,185,298,354,42892,42664,42691,43361,43303,43278,43361,43278,43421,43789,43582,43508,601,592,709,394,470,24,1550,1557,1475,4329,4378,4346,4273,4184,4323,2490,2960,2759,40754,40596,40408,41258,41521,40928,40754,40408,40755,39367,39163,39199,39199,39163,39069,38134,37913,38521,2262,2083,1942,1179,1227,1261,1880,1675,1777,1947,1955,1880,1999,1955,1947,2035,1955,1999,2035,2434,2322,2035,2322,2217,2586,2599,2799,1627,1698,1777,789,601,727,3650,3895,4291,2808,3114,2906,39199,39069,38989,43530,43361,43421,42691,43054,43080,41400,41337,41413,41400,41370,41337,41337,41370,41247,41247,41276,41192,41400,41413,41661,41413,41640,41751,41260,41356,41258,41835,41722,41956,41992,41956,41986,41992,41835,41956,43054,43215,43214,1586,1627,1777,1550,1692,1557,1550,1546,1592,41356,41521,41258,1627,1504,1698,1550,1475,1546,2975,3111,3389,4473,4673,5022,39227,39199,38989,39818,39631,39794,126,137,258,185,258,298,185,235,167,692,601,789,893,974,927,39631,39414,39491,4548,4473,5022,43203,43284,43324,43622,43681,43419,42870,43087,42577,43576,43403,43348,43740,43901,43738,1504,1385,1574,39491,39414,39380,42440,42398,42424,42631,42618,42764,42683,42440,42424,43250,43215,43303,42246,42870,42577,1385,1251,1261,33,13,397,1325,1465,1475,4365,4750,4486,43495,43576,43348,43284,43203,43217,43361,43250,43303,43410,43250,43361,43530,43421,43582,43271,43284,43217,365,390,492,927,1079,1066,1251,1179,1261,42289,42097,42231,4378,4388,4486,4329,3616,4184,1179,1141,1227,39380,39414,39367,42839,42631,42764,42524,42289,42273,42812,42764,42892,126,185,167,40813,41260,40742,41356,41575,41521,40754,40952,40813,40398,40408,40246,40398,40246,40425,39981,40196,40425,4879,4987,4979,4572,4987,4879,37746,38137,37813,39227,39367,39199,39416,39380,39367,37633,37656,37650,37261,37656,37482,42860,42812,42892,43789,43589,43582,43597,43622,43576,43576,43622,43419,1379,1266,1385,1385,1266,1251,1251,1229,1179,1179,1166,1141,1379,1385,1504,1955,1675,1880,3427,3409,3497,3510,3427,3497,3510,3565,3541,39227,38989,39083,39894,39886,39818,41521,42246,40868,42257,42246,41521,39894,39818,39794,41661,41276,41370,41370,41276,41247,41661,41370,41400,41751,41640,41835,40952,41260,40813,4273,4388,4378,4323,4388,4273,43690,43901,43681,43681,43901,43740,2906,3114,3111,3541,3565,3650,1546,1584,1592,1592,1584,1942,4184,4110,4234,964,1475,1334,3377,3389,3427,185,126,258,137,11,30,494,592,601,1096,1066,1141,952,927,1066,537,494,601,3510,3377,3427,3628,3541,3650,42631,42683,42424,41929,41751,41835,43214,43215,43250,1475,1465,1546,43622,43690,43681,43597,43690,43622,43597,43576,43620,43271,43217,43391,43410,43214,43250,563,1032,470,41929,41835,41992,39794,39631,39491,38521,37913,38554,39593,39794,39491,42690,42683,42631,42992,42860,42892,43214,43080,43054,43589,43530,43582,1489,1504,1627,43009,43087,42870,1266,1229,1251,759,813,795,759,789,813,43420,43009,43417,855,893,927,1229,1166,1179,42690,42631,42839,42920,42812,42860,43495,43324,43284,43690,43863,43901,43495,43284,43271,3955,3888,4291,4964,4548,5022,1166,1096,1141,3350,3510,3541,3350,3377,3510,375,404,494,494,404,492,24,470,397,4388,4365,4486,2490,2759,2496,43187,43080,43312,2819,2796,2586,2799,2819,2586,1680,1675,1955,1266,1214,1229,1229,1214,1166,1166,1067,1096,40796,40952,40754,41260,41431,41356,43420,43395,43009,40796,40754,40755,40796,40755,40633,2586,2796,2686,2097,2262,1942,1527,1942,1584,1536,1584,1546,40633,40408,40398,40510,40633,40398,40425,40510,40398,1067,1028,1096,1096,1028,1066,334,365,404,42221,42289,42272,42524,42273,42440,2686,2796,2808,126,11,137,365,185,354,43620,43495,43682,1847,1955,2035,2635,2686,2808,404,365,492,537,601,692,1675,1586,1777,1028,952,1066,875,952,1028,1586,1489,1627,1465,1536,1546,1535,1536,1465,1489,1409,1504,2975,2906,3111,952,855,927,875,855,952,39083,38989,38841,39894,40005,39886,39083,38841,38876,692,789,759,42992,42920,42860,42992,42892,43080,1409,1379,1504,2922,2975,3389,2938,2975,2834,43001,42992,43095,43589,43688,43530,43875,43789,43508,42221,41929,41992,41751,41661,41413,42221,41986,42289,42524,42440,42683,43410,43361,43594,1274,1214,1266,39593,39491,39380,43495,43620,43576,43597,43863,43690,43863,43620,43682,43594,43361,43530,39646,39593,39380,38876,38841,38672,537,375,494,4,11,167,367,375,332,692,759,698,4323,4365,4388,2936,3603,3206,38137,37913,37813,1214,1067,1166,39743,39593,39646,42764,42812,42839,795,813,855,42839,42812,42933,42812,42920,42933,2173,2242,2398,2173,2217,2242,2173,2067,2217,2217,2067,2035,1675,1555,1586,1555,1464,1489,1489,1464,1409,1409,1369,1379,1379,1274,1266,1214,1239,1067,2591,2586,2686,2591,2686,2635,40654,41026,41276,37834,38292,37910,40760,40796,40633,40784,40930,40796,40796,40930,40952,41469,41431,41260,43538,43495,43271,40760,40633,40510,40005,39894,39794,42933,42920,43001,43789,43688,43589,41692,40654,41276,41661,41751,41707,41707,41751,42058,42337,42272,42484,1838,1847,2035,367,334,375,375,334,404,3955,4291,4473,2635,2808,2770,39646,39380,39416,38744,38876,38672,42662,42524,42683,42920,42992,43001,1847,1680,1955,2808,2906,2770,41469,41260,40952,2938,2906,2975,1536,1535,1584,4287,4323,4184,1268,1071,964,41751,41929,42105,41431,41575,41356,167,11,126,235,185,365,5315,4964,5022,3844,3777,3888,37783,37694,37404,38101,37694,37783,42576,42524,42662,42992,43080,43095,742,875,1028,692,603,537,792,875,742,1555,1489,1586,779,1071,979,4287,4365,4323,2490,2496,2066,2834,2975,2922,875,795,855,334,235,365,792,795,875,563,779,998,42105,41929,42262,42683,42772,42662,1369,1274,1379,39938,40005,39794,39743,39794,39593,42683,42690,42772,43367,43214,43410,37834,38593,38292,43688,43594,43530,43497,43367,43410,43875,43853,43789,43789,43773,43688,43688,43773,43594,43008,42839,42933,43187,43095,43080,760,698,795,795,698,759,39367,39227,39416,39416,39227,39300,463,375,537,505,563,470,24,317,394,43008,42933,43001,43312,43080,43214,43312,43214,43367,43312,43363,43291,1521,2097,1942,1527,1584,1535,1527,1535,1397,2398,2242,2586,1838,1755,1847,1617,1555,1680,1680,1555,1675,1464,1369,1409,2398,2586,2591,2571,2591,2635,698,603,692,611,603,698,3888,3777,3650,2660,2571,2635,3955,4160,3963,40930,41131,40952,41985,41521,41575,40556,40760,40510,39981,39886,40196,39886,40005,40196,43853,43773,43789,2770,2906,2938,40196,40005,40193,505,470,394,1397,1535,1465,4365,4572,4979,4234,4287,4184,43008,43001,43095,43312,43367,43497,1755,1680,1847,742,1028,1067,1397,1465,1342,39300,39227,39083,39938,39794,39743,39300,39650,39608,1527,1397,1427,2660,2770,2696,41661,41692,41276,42337,42221,42272,42576,42289,42524,1434,1369,1464,39938,39743,39822,1239,1214,1274,603,463,537,39667,39743,39646,39479,39300,39608,43008,43095,43274,538,463,603,1427,1397,1342,317,505,394,43260,43095,43187,1296,1239,1274,742,760,792,792,760,795,42484,42272,42289,42772,42690,42853,39667,39646,39733,3777,3628,3650,3528,3628,3777,42853,42690,42839,42484,42289,42576,41648,41575,41431,41985,42257,41521,39489,39646,39416,693,611,760,760,611,698,43008,42853,42839,42484,42576,42588,42931,42853,43056,43291,43187,43312,13,24,397,317,347,505,42576,42662,42712,40760,40784,40796,40556,40784,40760,40556,40510,40425,40556,40425,40227,40425,40196,40227,1369,1296,1274,510,538,611,1555,1434,1464,1838,2035,2067,1838,2067,1827,2398,2591,2571,332,375,463,332,246,367,367,246,334,43652,43410,43594,2448,2398,2571,2660,2635,2770,611,538,603,742,669,646,1755,1617,1680,40227,40196,40193,3469,3350,3541,39479,39489,39416,40193,40005,40085,39615,39489,39479,42712,42772,42931,42712,42662,42772,1427,1521,1527,1527,1521,1942,4276,4365,4287,1071,734,964,779,734,1071,4276,4572,4365,2496,2262,2066,37834,38603,38593,37910,38101,37783,38603,38652,38593,38521,38744,38672,37656,38137,37746,1617,1434,1555,559,563,222,2696,2770,2938,43620,43863,43597,43391,43217,43009,2834,2696,2938,3628,3469,3541,3528,3469,3628,205,235,246,246,235,334,43395,43391,43009,2655,2696,2834,40005,39938,40085,1434,1296,1369,40085,39938,40117,39822,39743,39667,3844,3955,3963,43773,43741,43594,43291,43260,43187,43718,43741,43902,43651,43682,43495,43652,43497,43410,348,332,463,348,463,409,70,347,317,38554,38744,38521,39733,39822,39667,559,779,563,39733,39646,39615,38603,39065,38652,43451,43538,43391,43391,43538,43271,39615,39646,39489,43363,43312,43491,43363,43260,43291,41728,41131,41497,40784,41131,40930,43644,43651,43538,40993,40784,40556,40356,40556,40227,40229,40227,40193,40229,40193,40085,40229,40085,40356,2004,2067,2173,1755,1705,1617,1617,1495,1434,1434,947,1296,2004,2173,2052,2567,2571,2660,742,1067,669,1838,1745,1755,41131,41469,40952,39479,39416,39300,40117,39938,39822,43741,43652,43594,43538,43651,43495,43682,43821,43863,42821,43417,43009,1347,2097,1521,2066,2262,2097,1463,1521,1427,41469,41648,41431,4110,3736,4053,38603,39432,39653,42609,42337,42484,43491,43312,43497,42870,42821,43009,1342,1463,1427,39880,39822,39733,39300,39083,39650,1325,1342,1465,2696,2655,2660,3389,2978,2922,3377,2978,3389,41648,41783,41575,39690,39733,39615,43567,43491,43497,43741,43718,43652,43673,43718,43769,693,742,646,3955,3844,3888,3955,4473,4160,4234,4276,4287,4235,4276,4234,43567,43497,43652,42772,42853,42931,43644,43451,43712,43395,43451,43391,3377,3250,2978,41783,41985,41575,3377,3350,3250,2735,2936,3121,42262,42221,42381,42262,41929,42221,41707,41692,41661,43008,43056,42853,742,693,760,623,693,620,43095,43260,43274,332,205,246,257,348,409,3724,3528,3777,4160,4473,4205,43476,43260,43363,43626,43567,43652,3724,3777,3844,222,563,505,964,1325,1475,222,505,347,43476,43363,43491,42712,42588,42576,38419,38245,38292,38292,38245,38135,38135,38101,37910,38551,38292,38593,43451,43644,43538,43651,43672,43682,43680,43644,43712,1746,1705,1745,1745,1705,1755,1962,2004,2052,2567,2660,2655,2567,2655,2517,39763,39690,39615,39763,39615,39479,1746,1745,1838,203,205,332,235,4,167,257,332,348,3818,3724,3844,4125,4160,4205,4053,3744,3953,40620,39999,40654,2741,2834,2922,3818,3844,3857,1705,1495,1617,203,4,205,43553,43476,43491,43718,43673,43652,43902,43741,43773,43644,43672,43651,43680,43672,43644,2741,2655,2834,3350,3469,3250,43420,43451,43395,41783,41976,41985,41648,41790,41783,41922,41790,41648,41604,41648,41469,41500,41469,41131,41500,41728,41757,3250,3469,3308,3857,3844,3963,559,734,779,4110,4235,4234,4276,4238,4572,4053,4235,4110,38652,38551,38593,38634,38551,38652,39608,39763,39479,38137,38554,37913,43100,42712,42931,42776,42588,42712,43553,43491,43567,1342,1282,1463,1817,2066,2097,2490,2735,3121,1282,1325,1238,4110,4184,3736,2622,2735,2490,42138,42058,42105,42105,42058,41751,42182,42138,42105,3971,3857,3963,3469,3528,3308,4964,4595,4548,4160,3971,3963,38419,38101,38245,38245,38101,38135,623,611,693,205,4,235,43626,43553,43567,43527,43274,43260,39880,40117,39822,39880,39733,39690,1067,762,669,3528,3724,3605,42381,42221,42337,42381,42337,42609,409,463,538,3605,3724,3818,4015,3971,4160,43334,43274,43527,43238,43164,43334,43739,43626,43652,43853,43902,43773,38551,38419,38292,38634,38419,38551,43739,43652,43673,39841,39880,39690,42467,42381,42609,225,203,257,257,203,332,3807,3818,3857,4125,4015,4160,623,510,611,448,510,623,43164,43056,43008,43164,43008,43274,2004,1827,2067,1705,1178,1495,1067,1239,762,2052,2173,2203,2173,2398,2203,1962,1827,2004,2203,2398,2245,1827,1746,1838,1358,1521,1463,2245,2398,2448,2448,2571,2567,42198,42257,41985,40356,40227,40229,40356,40085,40285,43260,43476,43527,43769,43739,43673,43672,43821,43682,41976,41783,41790,3807,3857,3971,2329,2448,2321,39083,38876,39650,40285,40085,40117,41500,41604,41469,2741,2922,2845,40976,40620,41202,42096,41707,42058,42182,42058,42138,42182,42105,42271,3682,3807,3971,4205,4473,4548,510,409,538,309,409,510,40285,40117,40058,39697,39608,39650,1325,1282,1342,1238,1325,964,43902,43769,43718,43476,43553,43683,2735,2720,2936,2218,2622,2490,39841,39690,39763,42030,41976,41790,669,762,635,42271,42105,42262,43100,42776,42712,43100,42931,43056,4050,3971,4015,43782,43626,43739,4125,4050,4015,4259,4205,4548,2845,2978,2888,2845,2922,2978,646,620,693,640,620,646,2888,2978,3000,42271,42262,42467,42467,42262,42381,4100,4050,4125,4595,4259,4548,102,225,257,203,34,4,309,257,409,635,468,560,1827,1327,1746,1962,1934,1827,2052,1934,1962,2203,2025,2052,2096,2025,2203,2096,2203,2153,2203,2245,2153,2245,2144,2153,734,774,964,577,774,734,577,734,357,39697,39841,39763,39697,39763,39608,2245,2448,2329,2448,2429,2321,4100,4125,4205,3807,3605,3818,4235,4238,4276,4085,4053,3953,42870,42246,42821,3598,3605,3633,2448,2567,2429,2517,2741,2500,39650,38876,39079,1263,1358,1463,2066,2218,2490,1263,1463,1282,43769,43782,43739,43164,43238,43056,42609,42484,42588,43902,43782,43769,1238,1263,1282,43334,43164,43274,24,70,317,4053,4116,4235,4085,4116,4053,38419,38598,38101,38865,38634,38652,620,561,623,1434,1495,947,3598,3308,3528,39861,39653,39432,757,1238,964,40620,40430,39432,40341,40430,40639,42096,42058,42182,41976,42064,41985,41922,42030,41790,41922,41648,41604,41922,41604,41757,41500,41131,41728,40117,39880,40058,42030,42064,41976,669,640,646,635,640,669,43680,43821,43672,43793,43821,43680,42609,42588,42776,43527,43476,43683,40058,39880,40104,4116,4238,4235,4085,4238,4116,39012,39079,38744,40154,40058,40104,38137,38601,38554,3000,2978,3250,39787,39841,39697,43517,43451,43420,43724,43712,43451,3057,3060,3017,3057,3250,3060,3057,3000,3250,42295,42096,42182,42609,42776,42693,42821,42246,42257,3598,3528,3605,3633,3605,3807,2025,1934,2052,2023,1934,2025,2023,2025,2096,2023,2096,2153,2088,2153,2144,2567,2517,2429,2741,2517,2655,43712,43793,43680,43772,43793,43712,43100,43056,43238,1313,1358,1263,1313,1347,1358,1358,1347,1521,4329,3603,3616,1313,1263,1191,1263,1238,1191,2592,2500,2741,3603,3378,3616,43417,43517,43420,43724,43517,43882,3060,3250,3308,3682,3633,3807,3533,3633,3472,2845,2592,2741,42456,42821,42257,42155,42198,42064,41757,41604,41500,40784,41497,41131,2915,2888,3000,3017,3000,3057,42295,42271,42492,42295,42182,42271,640,561,620,560,468,521,39079,38876,38744,40744,40356,40285,42198,41985,42064,4259,4100,4205,4250,4100,4259,42155,42064,42030,635,561,640,560,561,635,42492,42271,42467,70,222,347,3682,3971,4050,4217,4250,4259,43772,43724,43882,43517,43724,43451,38634,38598,38419,39065,38865,38652,39065,38603,39381,3308,3077,2966,3060,2955,3021,43678,43100,43238,42758,42492,42467,43515,43238,43334,3533,3598,3633,40094,39861,39432,40094,39432,40430,1239,947,762,2088,2023,2153,2245,2329,2144,2329,2321,2144,2321,2229,2144,2429,2229,2321,4085,3953,4238,3603,2936,3378,43683,43553,43626,2429,2348,2229,4074,4050,4100,2915,3000,3017,41922,42155,42030,42198,42456,42257,40154,40285,40058,39650,39787,39697,39879,39787,39807,1488,1817,2097,1191,1238,1155,1226,1191,1155,225,34,203,306,309,510,506,623,561,3378,2936,3260,4250,4074,4100,42157,42155,41922,43882,43517,43887,1296,947,1239,3527,3736,3616,3616,3736,4184,39381,38603,39653,39012,38744,38554,43809,43683,43626,43527,43515,43334,43809,43626,43782,560,506,561,521,506,560,309,102,257,201,102,309,3736,3744,4053,3657,3744,3736,40104,39880,39841,39879,39841,39787,42693,42776,43000,42693,42467,42609,42295,42346,42096,40341,40094,40430,4250,4217,4074,3689,3682,3812,3021,3017,3060,4595,4217,4259,38760,38634,38865,38760,38598,38634,42758,42693,42940,43829,43809,43782,43724,43772,43712,43793,43882,43821,43517,43417,43887,433,448,506,506,448,623,39795,39381,39653,38951,38760,38865,39795,39653,39861,3021,2915,3017,3060,3308,2955,40430,40959,40639,26,34,102,102,34,225,3744,3839,3953,3953,3788,4238,3691,3839,3744,2916,3021,2955,43902,43829,43782,43515,43527,43889,42155,42191,42198,42157,42191,42155,41760,41728,41734,39807,39787,39650,40744,40556,40356,43527,43683,43889,1495,985,947,2088,1649,2023,2144,2220,2088,2348,2429,2517,2348,2517,2377,448,306,510,310,306,448,1281,2097,1347,1191,1226,1313,1155,1238,758,2845,2888,2592,38951,38865,39065,39944,39795,39861,39879,40104,39841,39678,39807,39650,757,964,774,2592,2888,2629,42006,41922,41757,40007,40104,39879,39203,39678,39650,39331,39065,39381,2784,2888,2915,2784,2915,2916,1746,1178,1705,40116,39944,39861,40430,40620,40959,42346,42295,42492,42435,42346,42549,42758,42467,42693,3682,4050,3812,306,201,309,521,433,506,374,433,521,2720,2735,2622,2916,2915,3021,43889,43683,43809,1746,1327,1178,2955,3308,2966,40007,39879,39891,3472,3598,3533,39891,39879,39807,39891,39807,39907,1202,1347,1313,1202,1313,1226,327,310,448,327,448,433,3378,3479,3616,3527,3479,3438,41728,41760,41757,42191,42392,42198,40327,40285,40154,40327,40154,40291,2229,2220,2144,2264,2220,2229,2264,2229,2348,2377,2517,2445,2517,2500,2445,2500,2518,2445,2592,2518,2500,41760,41887,41757,357,734,559,1157,1202,1226,39795,39640,39381,40144,39861,40094,40291,40154,40198,40038,39891,39907,1157,1226,1155,41887,42006,41757,2592,2484,2518,42006,42157,41922,310,201,306,170,201,310,3479,3527,3616,3536,3527,3438,2518,2484,2426,2592,2629,2484,762,468,635,374,468,279,222,121,559,72,121,222,3536,3657,3527,3527,3657,3736,1827,1934,1327,42232,42392,42191,40154,40104,40198,42392,42456,42198,70,72,222,632,757,577,3600,3472,3633,2426,2445,2518,3812,4050,4074,3657,3691,3744,3839,3788,3953,3536,3691,3657,2514,2720,2622,40198,40104,40007,43772,43882,43793,43887,43417,43827,374,521,468,360,327,433,40341,40144,40094,39640,39331,39381,40348,40144,40341,40038,40198,40007,3859,3812,4074,3600,3633,3682,3691,3788,3839,3460,3788,3691,39853,39907,39678,39891,40038,40007,38601,39012,38554,41692,41707,42096,43000,42776,43100,39907,39807,39678,1202,1281,1347,1817,2218,2066,1224,1281,1202,1157,1155,1065,4217,3859,4074,3600,3682,3673,2314,2218,2046,3682,3689,3673,39640,39795,39994,39203,39650,39079,757,774,577,2426,2264,2445,2445,2264,2377,2377,2264,2348,1327,1934,1649,2784,2629,2888,40315,40327,40291,40576,40285,40327,40576,40744,40285,42102,42006,41887,42244,42232,42006,42006,42232,42157,42157,42232,42191,42392,42572,42456,40315,40291,40226,40291,40198,40226,42023,41887,41760,43827,43417,42821,2784,2764,2629,2784,2916,2764,3673,3689,3812,3292,3479,3378,3260,2936,2983,39012,39203,39079,39994,39795,39944,42435,42096,42346,42549,42346,42492,43678,43000,43100,2916,2761,2764,591,468,762,327,170,310,662,762,947,3164,3260,2983,40639,40407,40341,42549,42492,42726,3774,3673,3812,2764,2761,2656,2764,2656,2629,40198,40038,40095,40226,40198,40307,42726,42492,42758,374,360,433,170,360,232,3260,3292,3378,3156,3292,3260,40116,39861,40144,357,559,123,2802,2761,2916,40015,40038,39907,40173,40116,40144,40576,40327,40473,41734,41497,41696,41485,41497,40784,42240,42096,42435,42240,41692,42096,40639,40520,40407,40407,40348,40341,3292,3438,3479,3536,3460,3691,3294,3438,3292,1224,1297,1281,1281,1488,2097,2218,2314,2622,1224,1202,1157,1200,1224,1077,41202,40620,40654,39853,40015,39907,40473,40327,40315,42938,42626,42435,43000,42940,42693,43287,42940,43000,43678,43238,43515,40976,40959,40620,1735,2218,1817,39915,39853,39678,40473,40315,40416,2582,2484,2629,2582,2401,2484,2484,2401,2426,2426,2401,2264,591,662,381,2582,2629,2656,2817,2936,2720,40714,40520,40639,40473,40416,40543,2955,2802,2916,40095,40038,40015,1200,1297,1224,123,559,121,2955,2966,2802,40520,40348,40407,40116,40068,39944,3156,3294,3292,3438,3460,3536,3156,3260,3164,2023,1649,1934,3598,3077,3308,40348,40237,40144,42940,42726,42758,3489,3472,3600,2609,2817,2720,40237,40173,40144,360,170,327,201,26,102,232,360,275,3294,3363,3438,3460,3363,3093,1297,1488,1281,2314,2514,2622,1320,1488,1297,1320,1297,1200,41497,41734,41728,42232,42410,42392,41485,40784,40993,40835,40744,40735,40173,40068,40116,39389,38951,39331,39950,40095,40015,40735,40744,40576,39950,40015,39853,1224,1157,1065,40976,40981,40959,40959,40819,40639,40520,40619,40348,40348,40208,40237,40237,40208,40173,40173,40208,40068,41316,41202,40654,41316,40654,41692,2558,2656,2657,2558,2582,2656,2558,2401,2582,1327,971,1210,2088,2220,1649,1065,1155,758,3673,3489,3600,3859,3774,3812,4217,3774,3859,38760,38951,38598,39331,38951,39065,39493,39331,39640,2860,2983,2817,2817,2983,2936,40068,39994,39944,40208,39994,40068,39915,39950,39853,40735,40576,40543,40095,39950,40371,758,1238,757,40981,40819,40959,40576,40473,40543,170,26,201,124,26,170,360,374,275,3514,3489,3673,43829,43889,43809,42940,43287,42726,2983,3156,3164,2863,3156,2983,2437,2514,2314,632,758,757,2657,2656,2761,2657,2761,2722,2722,2761,2802,2514,2609,2720,591,762,662,381,662,515,41734,42023,41760,40993,40556,40744,41565,41485,41589,41248,40981,40976,40819,40714,40639,41569,41316,41692,99,123,121,357,632,577,42016,42023,41734,2721,2860,2817,42023,42102,41887,41051,40981,41086,42543,42240,42626,41984,42074,42055,42102,42244,42006,3489,3437,3472,3514,3437,3489,1178,985,1495,907,985,1178,1679,1649,2220,3287,3598,3472,2657,2195,2558,42244,42410,42232,40937,40714,40819,39597,39493,39716,40315,40226,40416,2609,2670,2817,2514,2575,2609,2412,2437,2364,1735,1817,1488,1272,1488,1320,1272,1320,1125,1320,1200,1120,40416,40226,40307,279,275,374,232,124,170,279,468,591,2412,2575,2514,40307,40095,40371,40307,40198,40095,1077,1224,1065,43,632,357,2575,2670,2609,39915,39678,39203,2827,2802,2966,2827,2722,2802,2670,2721,2817,2860,2863,2983,3093,3363,3294,40619,40208,40348,3437,3287,3472,3242,3287,3437,41485,41565,41497,42023,42016,42102,42102,42298,42244,42433,42572,42410,40993,40744,40835,40993,40835,41016,40993,41016,41121,40735,40543,40842,41565,41696,41497,41696,41805,41734,1120,1200,1077,2437,2412,2514,2526,2684,2670,2670,2684,2721,1597,1735,1449,2924,2827,2966,41805,42016,41734,1077,1065,970,42572,42392,42410,42973,42821,42456,123,43,357,72,99,121,39493,39640,39873,970,942,1003,970,1065,680,2957,2924,2966,2684,2863,2721,2721,2863,2860,1077,970,1003,40976,41202,41248,41086,40981,41248,40981,41051,40819,40714,40619,40520,40550,40543,40416,41051,40937,40819,39873,39640,39994,3093,3294,3156,3363,3460,3438,39012,39439,39203,40307,40550,40416,3077,2957,2966,275,124,232,218,279,125,3130,3077,3598,39439,39915,39203,2364,2437,2081,2863,2867,3156,3774,3514,3673,3287,3130,3598,43889,43678,43515,41772,41569,41692,40371,40550,40307,3061,3130,3062,157,124,275,2526,2670,2575,40483,40371,39950,41772,41692,41984,41051,41095,40937,114,218,125,279,218,275,1808,1679,2220,1808,2220,2264,2699,2722,2827,2782,2827,2924,2932,2924,2957,2932,2957,2971,42433,42410,42244,41805,41946,42016,41904,41946,41805,41904,41805,41696,41828,41696,41565,41121,41485,40993,40835,40910,41016,1013,1120,1077,1013,1125,1120,1120,1125,1320,1449,1735,1488,1735,2046,2218,2412,2319,2575,970,680,942,1013,1003,942,2081,2046,1908,41445,41202,41316,41006,40619,40714,40835,40735,40910,40910,40735,40842,2971,2957,3077,2971,3077,3061,2816,2867,2684,2684,2867,2863,40602,40543,40550,42298,42102,42016,2401,1808,2264,3061,3077,3130,2081,2437,2314,41006,40714,40937,279,161,125,2657,2722,2195,3242,3130,3287,124,12,26,218,157,275,114,157,218,42878,42973,42456,2924,2932,2782,3247,3242,3437,41109,41121,41016,41828,41589,41781,41121,41589,41485,42210,42298,42016,42572,42878,42456,41636,41445,41316,41086,41095,41051,41984,41692,42240,1327,1210,1178,2932,2878,2782,2932,2971,2878,41636,41316,41569,41984,42240,42224,41445,41248,41202,39493,39389,39331,39873,39994,40049,39994,40128,40049,1125,1083,1272,2046,2081,2314,1003,1013,1077,1083,1013,958,41248,41164,41086,42122,42016,41946,2878,2971,2962,41164,41095,41086,1870,2046,1735,2364,2319,2412,41095,41006,40937,42298,42433,42244,2962,2971,3061,1808,2401,1878,2198,2319,2364,3514,3439,3437,3062,2962,3061,3774,3439,3514,39716,39389,39597,39597,39389,39493,40910,41109,41016,40371,40602,40550,40483,40602,40371,40483,39950,39915,157,12,124,279,178,161,39994,40344,40128,39439,39934,39915,2319,2526,2575,2816,3093,3156,43847,43287,43000,43889,43880,43678,114,12,157,125,12,114,40649,40483,40362,41589,41828,41565,42298,42336,42433,41781,41589,41553,40842,40543,40602,41164,41242,41095,41095,41242,41006,39775,39716,39873,41248,41344,41164,41445,41359,41248,41846,41636,41569,41846,41569,41772,41846,41772,41965,41828,41904,41696,41904,42029,41946,42736,42878,42572,3439,3247,3437,2699,2827,2782,39873,39716,39493,40208,40344,39994,971,898,1210,662,947,515,2699,2782,2878,42029,42122,41946,1013,1083,1125,2081,2198,2364,2319,2133,2526,1065,758,680,41584,41359,41445,2935,2699,2878,1597,1870,1735,680,758,597,2105,2198,2081,40625,40619,40955,597,758,632,40706,40842,40602,40706,40602,40608,40608,40602,40483,907,1178,1210,3062,3130,3242,1878,2401,2060,40484,40608,40483,43859,43827,42821,42736,42572,42433,3138,3062,3242,2401,2558,2195,3138,3242,3247,40674,40484,40649,2935,2878,2962,3195,3138,3247,39993,39775,39873,39716,39850,39389,40089,39873,40049,41359,41344,41248,41584,41344,41359,42055,41772,41984,42224,42240,42543,1870,1810,2046,1449,1488,1353,1062,1272,1083,1062,1083,1035,958,1013,942,42240,42435,42626,42122,42210,42016,42029,42210,42122,42323,42210,42284,42210,42029,42086,42029,41904,42086,41109,40910,40927,40910,40842,40927,40842,40706,40927,41584,41445,41636,2935,2962,3062,3439,3195,3247,840,958,942,746,907,811,2935,3062,3034,1638,1810,1870,41344,41242,41164,43847,43000,43678,2198,2133,2319,1810,1908,2046,1908,2040,2081,40927,40786,41005,40344,40208,40625,2040,2105,2081,2816,3156,2867,40927,40706,40786,42805,42736,42433,3169,3062,3138,40128,40089,40049,40180,40089,40128,43060,42973,42878,43859,42821,42973,265,597,632,680,840,942,99,43,123,2816,2684,2526,40649,40484,40483,40786,40706,40608,39439,39912,39934,40625,40208,40619,41447,41196,41242,41846,41689,41636,42055,41965,41772,42074,41965,42055,42074,41984,42224,1810,1739,1908,1908,1739,2040,2040,1739,2105,2676,2816,2526,1597,1638,1870,1353,1488,1128,1094,1272,1062,1094,1062,1035,41965,41689,41846,3195,3169,3138,2195,2722,2699,3034,3169,3195,41689,41584,41636,42181,42074,42224,1035,1083,941,1083,958,941,941,958,840,42736,43060,42878,42210,42323,42298,42086,41904,41828,41589,41121,41553,40619,41006,40992,666,907,746,558,459,515,1035,941,914,42323,42336,42298,42435,42549,42938,40344,40224,40128,40089,39993,39873,40250,40224,40467,42938,42549,42726,40927,41005,41109,40786,40608,40674,125,85,12,178,279,591,2133,2198,2105,40224,40180,40128,40250,40180,40224,40180,39993,40089,39775,39850,39716,40160,39993,40180,515,947,985,40992,41006,41196,1449,1400,1597,1128,1488,1272,1128,1272,1094,1027,1094,1035,1027,1035,914,41215,41121,41109,42323,42491,42336,42118,42086,41828,42805,43060,42736,42535,42224,42543,42364,42181,42224,42074,42040,41965,41965,42040,41689,41689,41897,41584,41196,41006,41242,381,307,591,914,941,840,840,680,597,1541,1638,1597,914,840,900,307,178,591,41211,41215,41109,41394,41215,41214,42645,42535,42543,42645,42543,42626,178,166,161,161,85,125,40763,40344,40625,40467,40224,40344,42961,42938,43236,42855,42938,42961,40674,40608,40484,40483,39915,40362,178,168,166,307,175,178,381,316,307,366,316,381,1069,1137,1092,40362,39915,39934,42253,42040,42074,42253,42074,42181,42364,42224,42460,1353,1400,1449,972,1128,1094,915,1094,1027,1192,1082,1235,41997,42118,41828,42086,42284,42210,41997,41828,41781,41394,41121,41215,41109,41005,41211,41005,41152,41211,3169,3034,3062,3439,3034,3195,40160,39850,39993,39993,39850,39775,40353,40180,40250,1307,1400,1353,1638,1739,1810,1400,1541,1597,42460,42224,42535,176,175,307,42645,42460,42535,40775,40786,40674,43880,43847,43678,42734,42645,42626,2195,2699,2306,316,176,307,42809,42626,42938,42855,42809,42938,168,178,175,168,85,166,166,85,161,41242,41344,41633,42938,42726,43236,515,985,558,2306,2699,2295,40992,40955,40619,43236,42726,43287,42805,42433,42336,40671,40775,40674,40671,40674,40649,515,366,381,40955,40763,40625,40968,40671,40862,1400,1008,1541,1626,1739,1638,1128,1192,1353,915,1027,914,915,914,900,42118,42243,42086,41947,41997,41781,41947,41781,41632,41121,41394,41553,1192,1307,1353,41553,41539,41632,41997,42243,42118,42243,42284,42086,900,840,836,42284,42383,42323,880,900,836,41005,40786,41047,42383,42491,42323,176,168,175,43,146,632,40523,40467,40344,1626,1638,1541,42919,42734,42809,42809,42734,42626,42645,42734,42460,42331,42253,42333,42364,42253,42181,41768,41344,41584,40992,41292,40955,40836,40709,40763,40763,40523,40344,42919,42809,42855,42919,42855,42982,40467,40353,40250,40523,40353,40467,41897,41689,42040,40885,40786,40775,2195,2060,2401,666,985,907,515,426,366,366,241,316,1906,2060,2195,42982,42855,42961,1210,811,907,1739,2133,2105,2816,2676,3093,459,426,515,40785,40885,40775,40785,40775,40671,40353,40160,40180,40454,40160,40353,40968,40785,40671,43244,43236,43287,426,241,366,241,176,316,1307,1235,1400,1739,1865,2133,1192,1235,1307,1082,1192,1128,1082,1128,972,1094,915,972,41951,41975,41947,41947,41975,41997,41997,42225,42243,42243,42268,42284,42284,42470,42383,42383,42470,42491,43910,42973,43060,41632,41781,41553,41553,41394,41539,41394,41519,41539,42805,42336,42491,43910,43859,42973,972,915,856,42364,42460,42671,42253,42364,42671,42925,42734,43022,880,915,900,42225,42268,42243,836,840,268,41215,41211,41214,41231,40992,41196,40631,40523,40709,268,840,597,1008,1626,1541,41214,41211,41152,1210,898,811,459,408,426,426,344,241,241,194,176,146,265,632,43,17,146,41152,41005,41047,666,558,985,41047,40786,40885,2116,2526,2133,2224,2676,2526,39912,40362,39934,40968,41047,40885,43132,42982,42961,43132,42961,43236,466,408,459,41055,41047,41063,43244,43132,43236,230,265,39,43587,43244,43287,42009,41897,42040,42009,42040,42331,42040,42253,42331,42734,42671,42460,41897,41768,41584,42268,42470,42284,42517,42470,42268,42225,41997,41975,41951,41947,41632,41653,41632,41539,41653,41539,41519,41394,41438,41519,836,807,880,880,856,915,972,854,1082,1082,1008,1235,1008,1628,1626,1626,1628,1739,715,807,836,41768,41633,41344,41394,41214,41438,558,466,459,666,589,558,971,865,898,41633,41487,41242,41214,41307,41393,41438,41214,41393,746,665,666,41487,41447,41242,41214,41152,41307,665,589,666,41055,41152,41047,589,571,558,408,344,426,41447,41231,41196,571,466,558,40968,40885,40785,379,344,408,40862,40671,40649,1649,971,1327,2633,2699,2935,41709,41632,41653,41951,42225,41975,42470,42581,42491,41709,41653,41649,41653,41519,41649,41519,41438,41649,41438,41735,41649,41487,41641,41447,41493,41292,41231,41633,41641,41487,41886,41641,41633,41897,42050,41768,42734,42925,42671,807,856,880,854,856,832,466,379,408,571,517,466,589,576,571,665,576,589,746,655,665,1069,971,1649,41438,41393,41473,42517,42581,42470,40523,40631,40353,40709,40523,40763,40763,41041,40836,41886,41633,41768,41307,41152,41289,660,655,746,1008,1400,1235,655,576,665,42581,42805,42491,41289,41152,41055,576,517,571,41283,41289,41055,40631,40454,40353,40160,40382,39850,40681,40454,40631,42919,42982,43022,43814,43703,43287,517,379,466,3034,2633,2935,2306,1906,2195,40454,40382,40160,40666,40382,40454,40995,41063,41047,40995,41047,40968,1865,2116,2133,41037,40995,40968,43847,43814,43287,42919,43022,42734,344,194,241,176,44,168,168,44,85,162,194,344,265,268,597,39,265,146,2633,2295,2699,40763,40955,41041,42009,42050,41897,43226,43022,42982,42331,42050,42009,194,44,176,40955,41183,41041,379,162,344,194,162,44,517,399,379,424,399,517,655,637,576,811,714,746,1679,1069,1649,856,854,972,1628,1865,1739,832,856,807,41735,41951,41709,41709,41951,41632,42225,42517,42268,42581,42517,42805,41735,41709,41649,41735,41438,41473,41393,41307,41473,41283,41055,41063,715,832,807,42349,42517,42225,764,714,811,681,715,836,43587,43287,43703,714,660,746,43689,43587,43703,42982,43132,43226,43368,43132,43244,424,517,576,230,268,265,40995,41068,41063,41037,41068,40995,40862,41037,40968,43559,43368,43244,40992,41231,41292,40709,40681,40631,40362,40862,40649,42050,42017,41768,42235,42129,42050,42509,42333,42253,42509,42253,42671,42509,42671,42635,42930,42925,42970,660,637,655,714,675,660,898,837,811,1137,1069,1679,42129,42017,42050,865,837,898,837,764,811,715,721,832,832,720,854,854,1008,1082,681,721,715,40836,40681,40709,40666,40681,40824,629,681,836,41951,42349,42225,41473,41307,41466,41307,41289,41466,41289,41462,41466,675,637,660,399,162,379,41063,41068,41283,41283,41068,41198,2116,2224,2526,1832,1865,1593,41090,41068,41037,43293,43226,43132,43293,43132,43368,43293,43693,43445,43826,43060,43899,43826,43910,43060,43899,42805,43813,43559,43244,43587,554,629,836,230,209,268,129,209,230,41110,41090,41037,39,129,230,41851,41447,41641,17,39,146,40862,40888,41037,40827,40888,40862,43689,43559,43587,1329,1137,1679,865,772,837,837,772,764,764,675,714,1808,1329,1679,971,846,865,42017,41886,41768,42235,42050,42331,42635,42671,42705,42970,43022,43356,43259,43226,43293,2007,2224,2116,40362,40827,40862,846,772,865,42,162,399,721,720,832,1865,2007,2116,647,720,721,647,721,681,647,681,629,268,554,836,42129,41886,42017,772,675,764,629,641,647,629,554,641,40681,40666,40454,40904,40681,40836,40904,40836,41041,43445,43259,43293,43796,43689,43703,41198,41090,41110,41198,41068,41090,41458,41462,41283,41283,41462,41289,41466,41462,41473,41473,41812,41735,41735,41812,41951,41493,41231,41447,43293,43368,43693,41292,41183,40955,41110,41037,41044,424,576,637,41183,41103,41041,41044,41037,40888,40827,41044,40888,41093,40904,41041,846,838,772,772,717,675,675,544,637,971,944,846,987,944,971,987,971,1069,987,1069,1092,1878,1329,1808,944,896,846,1384,1270,1329,896,838,846,1329,1270,1195,41886,41851,41641,41262,41103,41183,41262,41093,41103,41103,41093,41041,42235,42331,42333,42235,42333,42434,42705,42671,42930,641,711,647,647,711,720,649,1008,854,268,63,554,1906,2306,2295,40666,40825,40382,40904,40824,40681,40825,40824,40904,554,438,572,41871,41851,41886,41458,41574,41476,41458,41283,41312,41690,41473,41462,41690,41812,41473,513,544,675,614,554,572,43689,43796,43559,42930,42671,42925,43836,43796,43703,41283,41198,41296,1832,2007,1865,41368,41183,41292,1007,1092,1090,1007,987,1092,1007,956,987,987,956,944,944,859,896,896,822,838,838,717,772,956,859,944,544,424,637,1090,1092,1137,649,854,720,685,720,711,685,711,614,859,822,896,1030,1090,1059,1059,1090,1137,41851,41493,41447,42129,42063,41886,42434,42333,42509,42727,42509,42635,822,717,838,42235,42063,42129,614,711,641,614,641,554,42925,43022,42970,268,209,63,42063,41871,41886,43022,43226,43356,2633,2251,2295,40824,40825,40666,41173,40825,40904,41173,40904,41093,41476,41462,41458,41476,41690,41462,41812,42048,41951,43356,43226,43259,513,424,544,43837,43693,43559,43814,43836,43703,41856,41493,41851,41296,41198,41110,41493,41472,41292,41472,41368,41292,41368,41262,41183,41179,41296,41110,41179,41110,41044,162,42,44,84,42,399,2251,1906,2295,41240,41179,41044,822,824,717,717,644,675,424,84,399,859,824,822,956,842,859,1007,842,956,1030,842,1007,1030,1007,1090,842,824,859,1059,1137,1119,1119,1137,1329,824,644,717,572,649,685,685,649,720,1593,1865,1628,572,685,614,1195,1119,1329,42963,42705,42930,42963,42727,42705,42705,42727,42635,42235,42247,42063,42063,42247,41871,41639,41472,41493,41547,41368,41472,41435,41348,41368,41368,41348,41262,42963,42930,42970,1329,1878,1384,41690,41476,41769,41923,41690,41769,41923,41812,41690,41923,42048,41812,1384,1878,1411,41312,41283,41296,533,513,675,1411,1878,2060,1406,1411,1514,41856,41851,41871,41262,41173,41093,41261,41312,41296,41179,41261,41296,41240,41261,41179,41372,41173,41262,42324,42349,42048,42048,42349,41951,42324,42048,41923,41769,41476,41748,1134,1195,1133,1134,1119,1195,995,1059,1119,995,992,1059,1059,992,1030,1030,992,842,842,864,824,527,533,644,644,533,675,1195,1270,1133,42286,42247,42235,41348,41372,41262,42434,42597,42525,1264,1384,1301,1264,1270,1384,527,644,454,513,368,424,649,658,1008,63,209,129,1301,1384,1411,43899,43060,42805,41972,41856,41871,1514,1411,2060,1301,1406,1298,41856,41716,41493,41716,41639,41493,41639,41547,41472,41547,41435,41368,43693,43368,43559,39,63,129,41435,41372,41348,41261,41353,41312,41240,41353,41261,2007,1832,2224,1593,1628,1480,40827,41240,41044,42247,42120,41871,41856,41842,41716,41716,41842,41639,41639,41650,41547,41547,41527,41435,41435,41527,41372,42434,42509,42597,42434,42402,42235,1012,995,1134,1134,995,1119,992,864,842,1133,1270,1249,42402,42286,42235,575,630,649,575,649,572,533,485,513,454,644,824,385,575,572,1249,1270,1264,42286,42120,42247,527,485,533,1301,1411,1406,1301,1249,1264,43067,42963,42970,63,438,554,1514,2060,1906,42120,41972,41871,41972,41842,41856,41458,41522,41574,41748,41476,41574,43813,42805,43732,41458,41312,41522,1478,1514,1531,41842,41650,41639,41522,41312,41430,43445,43356,43259,43539,43356,43445,41650,41527,41547,41430,41312,41353,41240,41430,41353,43837,43559,43796,41972,41978,41842,41842,41680,41650,41650,41680,41527,42120,42161,41972,42250,42161,42120,42402,42358,42286,42434,42449,42402,42597,42509,42727,42597,42727,42765,42727,42963,43040,42525,42449,42434,43040,42963,43067,1012,1133,981,940,1012,981,1133,1012,1134,995,940,992,454,417,485,1124,1249,1301,385,566,575,575,566,630,658,850,1008,545,566,452,42358,42120,42286,43067,43268,43169,454,485,527,485,417,513,42161,41978,41972,43067,42970,43268,417,368,513,1315,1298,1406,41663,41574,41522,41853,41748,41574,41853,41769,41748,41853,41921,41769,41769,41921,41923,1514,1478,1406,1531,1514,1632,41430,41663,41522,850,1628,1008,43693,43539,43445,2251,1872,1906,41718,41372,41527,41718,41284,41372,41372,41284,41173,41173,41284,40825,43791,43706,43539,43836,43837,43796,658,649,630,41936,41680,41842,42161,42109,41978,42449,42358,42402,42525,42556,42449,42597,42765,42525,42893,42765,42727,42893,42727,43040,43103,43040,43067,42970,43356,43268,1012,940,995,417,269,368,981,1133,1084,1133,1249,1124,1301,1298,1124,42478,42358,42449,566,545,630,385,572,438,1315,1406,1381,864,454,824,42358,42250,42120,88,385,438,43268,43356,43492,1381,1406,1478,43169,43247,43103,1387,1381,1478,41663,41853,41574,41921,42324,41923,42109,41842,41978,155,84,368,368,84,424,1632,1514,1906,1872,1632,1906,1055,1480,1628,553,658,630,553,630,545,42250,42109,42161,42358,42350,42250,42687,42556,42525,42687,42525,42765,42893,43040,43103,940,864,992,328,269,417,961,864,940,961,940,981,1124,1298,1199,1298,1315,1199,1315,1381,1199,42556,42478,42449,452,553,545,42478,42350,42358,43103,43067,43169,43103,43196,43107,385,452,566,457,452,312,42296,42324,41921,43103,43247,43196,1199,1381,1387,42170,42109,42250,41680,41833,41527,328,417,454,1387,1478,1448,42109,41936,41842,41853,41869,41921,41806,41869,41853,41806,41853,41663,41806,41663,41752,1448,1478,1531,41936,41802,41680,41752,41663,41430,1494,1448,1531,1494,1531,1632,41740,41752,41430,1518,1494,1632,42805,43641,43732,42109,42148,41936,41936,41944,41802,42350,42326,42250,42478,42453,42350,42556,42687,42478,42823,42687,42765,42823,42765,42893,42761,43058,42714,43035,42823,42893,42324,42506,42349,42351,42506,42324,42351,42324,42296,41921,42110,42296,452,457,553,553,509,658,1055,1628,850,312,452,385,278,328,285,1084,961,981,1084,1133,1124,1084,1124,1199,1084,1199,1197,1199,1387,1314,42110,41869,41993,42453,42326,42350,269,155,368,328,454,285,1314,1387,1448,42326,42170,42250,42170,42148,42109,42148,42021,41936,41802,41833,41680,50,155,269,42021,41944,41936,63,88,438,41944,41833,41802,1494,1405,1448,1518,1405,1494,1593,1480,1832,542,850,658,41752,41740,41806,41240,41740,41430,1872,1518,1632,42148,42197,42021,42021,42098,41944,41944,41962,41833,42170,42216,42148,42347,42216,42170,42687,42714,42478,42823,42761,42687,43107,42893,43103,457,509,553,321,509,457,955,847,961,961,847,864,328,278,269,955,961,1084,1314,1448,1405,43169,43346,43247,25,312,385,42351,42427,42506,42805,42517,43641,42110,41921,41869,43169,43268,43346,42347,42170,42326,43346,43268,43492,41993,41869,41806,43492,43356,43706,41740,41993,41806,43706,43356,43539,1418,1314,1405,1518,1418,1405,1474,1418,1518,42761,42714,42687,43058,42761,42823,43035,42893,43139,42893,43107,43139,43107,43231,43139,43196,43231,43107,503,509,425,503,542,509,509,542,658,493,503,425,43196,43362,43231,42714,42453,42478,42216,42197,42148,43196,43247,43362,770,454,864,1149,955,1084,1197,1199,1314,43362,43247,43346,770,864,847,42304,42197,42216,42296,42396,42351,42110,42255,42296,42144,42255,42110,42144,42110,41993,42218,42144,41993,43492,43437,43346,43592,43437,43492,1149,1197,1314,41987,41962,41944,41833,41718,41527,43791,43539,43824,1418,1149,1314,1872,1474,1518,41962,41718,41833,43824,43539,43693,43837,43824,43693,749,1055,850,503,493,542,425,509,321,848,770,847,848,847,955,848,955,883,42197,42098,42021,41962,42057,41718,42453,42347,42326,42452,42347,42453,43035,43058,42823,43131,43058,43035,43131,43035,43139,43131,43139,43304,43139,43231,43304,43346,43437,43362,43437,43584,43362,321,457,312,43492,43706,43592,295,321,191,1149,1084,1197,278,206,269,770,285,454,42452,42453,42701,42255,42396,42296,42427,42396,42459,285,206,278,155,50,84,42347,42304,42216,43592,43706,43710,206,50,269,42317,42098,42197,42098,41987,41944,43710,43706,43791,43692,43710,43754,295,425,321,295,382,425,425,382,493,336,850,542,42396,42427,42351,42290,42396,42255,43584,43437,43592,43475,43304,43716,43362,43304,43231,43131,43281,43058,42452,42304,42347,42361,42317,42304,42304,42317,42197,42098,42057,41987,206,239,50,285,239,206,109,239,285,467,285,770,42453,42714,42701,42218,42290,42144,42144,42290,42255,42209,42218,41993,43585,43584,43592,1474,1149,1418,848,703,770,42274,42057,42098,41987,42057,41962,42517,42349,43641,619,703,848,191,321,312,336,542,493,42317,42403,42098,42701,42714,43145,42714,43058,43145,43641,42349,43605,42389,42459,42396,42389,42396,42290,42452,42361,42304,42218,42389,42290,88,25,385,326,493,382,42218,42209,42389,41740,42209,41993,43716,43304,43362,43692,43585,43592,43692,43592,43710,43754,43710,43791,42349,42506,43605,43824,43754,43791,256,326,382,256,382,295,42538,42403,42361,43281,43131,43304,43281,43304,43475,43762,43585,43692,191,256,295,25,191,312,43605,42506,43713,42389,42473,42459,42209,42473,42389,42538,42361,42452,42361,42403,42317,43732,43877,43813,42506,42427,42753,43754,43762,43692,43886,43762,43754,43362,43584,43716,42701,42538,42452,61,224,191,191,224,256,256,264,326,326,336,493,42585,42538,42868,42057,42163,41718,42403,42356,42098,42447,42356,42403,43641,43727,43732,42753,42427,42459,42356,42274,42098,1149,883,955,703,467,770,1474,1104,1149,42274,42163,42057,43824,43886,43754,43860,43716,43585,619,467,703,239,74,50,264,336,326,190,264,256,659,619,848,224,190,256,61,190,224,42587,42753,42459,42587,42459,42473,281,109,285,42723,42587,42656,109,74,239,42538,42585,42403,42356,42447,42274,42274,42559,42163,42868,42538,42701,43145,43058,43306,1104,883,1149,42585,42447,42403,43605,43727,43641,43755,43727,43605,42585,42559,42447,43306,43058,43281,508,749,850,264,293,336,214,293,264,43475,43306,43281,190,214,264,61,214,190,883,659,848,314,281,467,467,281,285,109,131,74,43716,43584,43585,43727,43877,43732,43755,43877,43727,43755,43605,43713,314,467,619,25,61,191,210,276,293,42587,42723,42753,42656,42587,42473,289,314,364,883,719,659,716,719,883,508,850,336,276,336,293,42209,42656,42473,43072,42701,43145,42670,42559,42868,42447,42559,42274,43220,43145,43306,43373,43220,43306,43860,43585,43762,43713,42506,42753,311,314,289,281,131,109,43373,43306,43490,110,293,214,43490,43306,43475,189,131,281,61,110,214,43511,43490,43475,43716,43511,43475,43713,42753,43807,43799,43713,43807,314,311,281,289,364,296,276,303,336,210,303,276,311,189,281,132,210,293,43460,43072,43220,43220,43072,43145,43427,43220,43373,43427,43373,43490,110,132,293,61,132,110,303,508,336,43511,43526,43490,43625,43526,43511,1104,716,883,364,619,659,42868,42559,42585,42559,42670,42163,43745,43625,43511,43886,43860,43762,289,172,311,311,172,189,189,18,131,303,193,508,210,181,303,23,181,210,43072,42868,42701,43526,43427,43490,43499,43427,43526,131,18,74,172,18,189,43065,42868,43072,43745,43511,43716,43860,43745,43716,181,237,303,119,237,181,172,62,18,314,619,364,43427,43460,43220,43499,43460,43427,43499,43526,43625,43571,43499,43806,43713,43861,43755,43755,43861,43877,43110,42753,42723,43799,43861,43713,296,179,289,289,179,172,237,193,303,508,439,749,119,193,237,119,181,23,23,210,132,364,659,441,61,23,132,441,659,719,193,439,508,42656,43110,42723,43799,43807,43861,43110,43807,42753,193,101,439,119,143,193,23,143,119,43460,43571,43072,42868,43065,42670,43499,43571,43460,43757,43499,43625,43757,43625,43745,716,441,719,106,62,296,296,62,179,43450,43065,43072,43830,43757,43745,43571,43506,43072,43860,43830,43745,106,296,364,179,62,172,0,101,143,143,101,193,43830,43806,43757,43757,43806,43499,43807,43885,43861,43583,43885,43807,23,0,143,101,0,439,43593,43506,43685,43110,43583,43807,441,106,364,43506,43450,43072,43506,43502,43450,43685,43506,43571,43685,43571,43806,43878,43685,43806,441,28,106,106,28,62,43664,43502,43593,43593,43502,43506,43450,43502,43065,43830,43878,43806,43685,43664,43593,43878,43664,43685,43583,43868,43885,43664,43913,43502,43878,43913,43664};*/ - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/util_tests.cpp b/unittests/tntn/util_tests.cpp deleted file mode 100644 index 5a46323..0000000 --- a/unittests/tntn/util_tests.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -#include "tntn/util.h" - -namespace tntn { -namespace unittests { - - TEST_CASE("tokenize simple line", "[tntn]") - { - std::vector tokens; - tokenize("abc def ", tokens); - REQUIRE(tokens.size() == 2); - CHECK(tokens[0] == "abc"); - CHECK(tokens[1] == "def"); - } - - TEST_CASE("tokenize empty line", "[tntn]") - { - std::vector tokens; - tokenize("", tokens); - CHECK(tokens.empty()); - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/vertex_points.cpp b/unittests/tntn/vertex_points.cpp deleted file mode 100644 index cff670a..0000000 --- a/unittests/tntn/vertex_points.cpp +++ /dev/null @@ -1,10991 +0,0 @@ -#include "vertex_points.h" -namespace tntn { -namespace unittests { - void init_vertex_list(std::vector& data) - { - - data = { - 536784.75, 188160.25, 536784.75, 188080.25, 536784.75, 188032.75, 536784.75, 188047.75, - 536784.75, 187940.25, 536784.75, 188070.25, 536784.75, 187965.25, 536784.75, 188052.75, - 536784.75, 188110.25, 536784.75, 188005.25, 536784.75, 188040.25, 536784.75, 187942.75, - 536784.75, 187932.75, 536784.75, 188127.75, 536784.75, 188020.25, 536784.75, 188100.25, - 536784.75, 188117.75, 536784.75, 188142.75, 536784.75, 187915.25, 536784.75, 187960.25, - 536784.75, 188012.75, 536784.75, 187985.25, 536784.75, 187997.75, 536784.75, 188157.75, - 536784.75, 188130.25, 536784.75, 188152.75, 536784.75, 187935.25, 536784.75, 187955.25, - 536784.75, 187910.75, 536784.75, 188057.75, 536784.75, 187945.25, 536784.75, 187995.25, - 536784.75, 188082.75, 536784.75, 188125.25, 536784.75, 187937.75, 536784.75, 187987.75, - 536784.75, 187970.25, 536784.75, 188010.25, 536784.75, 187957.75, 536784.75, 188145.25, - 536784.75, 188067.75, 536784.75, 188112.75, 536784.75, 187925.25, 536784.75, 188140.25, - 536784.75, 187927.75, 536784.75, 188097.75, 536784.75, 187982.75, 536784.75, 187975.25, - 536784.75, 188042.75, 536784.75, 188077.75, 536784.75, 187920.25, 536784.75, 188022.75, - 536784.75, 188105.25, 536784.75, 188102.75, 536784.75, 188030.25, 536784.75, 188090.25, - 536784.75, 188015.25, 536784.75, 188000.25, 536784.75, 188017.75, 536784.75, 188122.75, - 536784.75, 188085.25, 536784.75, 188155.25, 536784.75, 187912.75, 536784.75, 188147.75, - 536784.75, 188095.25, 536784.75, 188050.25, 536784.75, 187947.75, 536784.75, 187980.25, - 536784.75, 188072.75, 536784.75, 187967.75, 536784.75, 188132.75, 536784.75, 188062.75, - 536784.75, 188135.25, 536784.75, 187962.75, 536784.75, 187917.75, 536784.75, 188065.25, - 536784.75, 188035.25, 536784.75, 188037.75, 536784.75, 188007.75, 536784.75, 188115.25, - 536784.75, 188027.75, 536784.75, 188107.75, 536784.75, 188075.25, 536784.75, 188025.25, - 536784.75, 187922.75, 536784.75, 187930.25, 536784.75, 188120.25, 536784.75, 188087.75, - 536784.75, 188150.25, 536784.75, 187977.75, 536784.75, 187992.75, 536784.75, 188092.75, - 536784.75, 188002.75, 536784.75, 187950.25, 536784.75, 188045.25, 536784.75, 187972.75, - 536784.75, 188060.25, 536784.75, 187990.25, 536784.75, 188055.25, 536784.75, 188137.75, - 536784.75, 187952.75, 536785.25, 188159.75, 536785.25, 187937.25, 536785.25, 187955.25, - 536785.25, 187953.75, 536785.25, 188011.25, 536785.25, 187911.25, 536785.25, 188031.25, - 536785.25, 187987.75, 536785.25, 187917.25, 536785.25, 188156.25, 536785.25, 188031.75, - 536785.25, 188078.75, 536785.25, 188036.25, 536785.25, 187932.25, 536785.25, 187977.25, - 536785.25, 188067.75, 536785.25, 188030.75, 536785.25, 187994.75, 536785.25, 188158.25, - 536785.25, 187952.75, 536785.25, 188135.75, 536785.25, 187956.25, 536785.25, 188137.75, - 536785.25, 187933.25, 536785.25, 187931.75, 536785.25, 187943.25, 536785.25, 188077.75, - 536785.25, 188055.25, 536785.25, 188145.75, 536785.25, 187956.75, 536785.25, 187915.75, - 536785.25, 188156.75, 536785.25, 188016.75, 536785.25, 188058.75, 536785.25, 188030.25, - 536785.25, 188038.25, 536785.25, 187943.75, 536785.25, 188015.25, 536785.25, 188085.25, - 536785.25, 187988.75, 536785.25, 188092.75, 536785.25, 188032.25, 536785.25, 188158.75, - 536785.25, 188016.25, 536785.25, 188055.75, 536785.25, 188142.75, 536785.25, 188094.75, - 536785.25, 187991.25, 536785.25, 187986.75, 536785.25, 188052.25, 536785.25, 187963.75, - 536785.25, 188065.75, 536785.25, 188029.25, 536785.25, 188046.25, 536785.25, 187921.25, - 536785.25, 188014.25, 536785.25, 187932.75, 536785.25, 188007.75, 536785.25, 187993.25, - 536785.25, 188093.75, 536785.25, 187930.75, 536785.25, 187925.75, 536785.25, 188057.25, - 536785.25, 187989.75, 536785.25, 188064.75, 536785.25, 187930.25, 536785.25, 187942.75, - 536785.25, 187929.25, 536785.25, 187977.75, 536785.75, 187934.25, 536785.75, 188111.75, - 536785.75, 187914.25, 536785.75, 187948.75, 536785.75, 187992.75, 536785.75, 187929.25, - 536785.75, 187928.25, 536785.75, 188040.25, 536785.75, 187929.75, 536785.75, 187913.25, - 536785.75, 188015.75, 536785.75, 188157.75, 536785.75, 187945.25, 536785.75, 188000.25, - 536785.75, 188009.25, 536785.75, 187942.75, 536785.75, 188031.25, 536785.75, 188037.25, - 536785.75, 187944.25, 536785.75, 187914.75, 536785.75, 188155.25, 536785.75, 188154.25, - 536785.75, 188053.25, 536785.75, 188158.75, 536785.75, 187926.75, 536785.75, 187990.25, - 536785.75, 188023.25, 536785.75, 187978.25, 536785.75, 188029.75, 536785.75, 187987.25, - 536785.75, 188059.25, 536785.75, 187935.75, 536785.75, 188041.75, 536785.75, 187938.75, - 536785.75, 188066.25, 536785.75, 187939.25, 536785.75, 187919.25, 536785.75, 188016.75, - 536785.75, 188028.75, 536785.75, 188146.25, 536785.75, 188157.25, 536785.75, 188064.25, - 536785.75, 187956.75, 536785.75, 187999.75, 536785.75, 188155.75, 536785.75, 187957.25, - 536785.75, 188028.25, 536785.75, 187992.25, 536785.75, 187932.25, 536785.75, 187991.75, - 536785.75, 188042.25, 536785.75, 188042.75, 536785.75, 188134.75, 536785.75, 187954.25, - 536785.75, 188154.75, 536785.75, 187938.25, 536785.75, 187988.25, 536785.75, 188017.25, - 536785.75, 187955.75, 536785.75, 188065.25, 536785.75, 188145.25, 536785.75, 187995.75, - 536785.75, 187933.75, 536785.75, 188078.75, 536785.75, 188079.75, 536785.75, 187940.25, - 536785.75, 188058.25, 536785.75, 188158.25, 536785.75, 187953.25, 536785.75, 187918.75, - 536785.75, 187989.25, 536786.25, 187927.75, 536786.25, 187953.25, 536786.25, 188037.25, - 536786.25, 188015.75, 536786.25, 188064.25, 536786.25, 187939.75, 536786.25, 187953.75, - 536786.25, 188078.25, 536786.25, 188058.25, 536786.25, 188065.75, 536786.25, 188042.75, - 536786.25, 187956.25, 536786.25, 188065.25, 536786.25, 187988.25, 536786.25, 187995.75, - 536786.25, 188154.75, 536786.25, 187938.25, 536786.25, 187943.25, 536786.25, 187978.75, - 536786.25, 187975.75, 536786.25, 187957.25, 536786.25, 187944.25, 536786.25, 187991.75, - 536786.25, 188155.75, 536786.25, 188144.75, 536786.25, 187993.25, 536786.25, 188085.75, - 536786.25, 188146.25, 536786.25, 187920.75, 536786.25, 188051.75, 536786.25, 188016.75, - 536786.25, 188028.75, 536786.25, 188079.25, 536786.25, 188066.25, 536786.25, 187932.75, - 536786.25, 188157.25, 536786.25, 188036.75, 536786.25, 187919.25, 536786.25, 187932.25, - 536786.25, 187977.75, 536786.25, 187915.25, 536786.25, 187990.25, 536786.25, 188027.25, - 536786.25, 187987.25, 536786.25, 187918.75, 536786.25, 188059.25, 536786.25, 188041.75, - 536786.25, 188029.75, 536786.25, 187913.25, 536786.25, 187977.25, 536786.25, 188030.25, - 536786.25, 187978.25, 536786.25, 188156.25, 536786.25, 187987.75, 536786.25, 188154.25, - 536786.25, 187912.75, 536786.25, 188031.25, 536786.25, 187942.75, 536786.25, 188038.25, - 536786.25, 187995.25, 536786.25, 188009.25, 536786.25, 188000.25, 536786.25, 188157.75, - 536786.25, 188026.75, 536786.25, 188008.75, 536786.25, 187935.75, 536786.25, 187929.25, - 536786.25, 187944.75, 536786.25, 187936.25, 536786.25, 187935.25, 536786.25, 187914.25, - 536786.75, 188152.75, 536786.75, 188026.75, 536786.75, 187914.25, 536786.75, 187944.75, - 536786.75, 187928.25, 536786.75, 188132.25, 536786.75, 187943.75, 536786.75, 188015.25, - 536786.75, 188073.75, 536786.75, 188153.75, 536786.75, 187988.75, 536786.75, 188054.75, - 536786.75, 187974.25, 536786.75, 187992.75, 536786.75, 188155.25, 536786.75, 187934.25, - 536786.75, 187919.75, 536786.75, 188016.25, 536786.75, 187946.25, 536786.75, 187987.75, - 536786.75, 187938.75, 536786.75, 188063.75, 536786.75, 187940.25, 536786.75, 188058.75, - 536786.75, 188156.25, 536786.75, 187990.25, 536786.75, 188064.75, 536786.75, 188062.25, - 536786.75, 188113.25, 536786.75, 188039.75, 536786.75, 187998.75, 536786.75, 187956.75, - 536786.75, 187926.25, 536786.75, 188028.75, 536786.75, 187978.75, 536786.75, 188133.25, - 536786.75, 187938.25, 536786.75, 187953.75, 536786.75, 188027.75, 536786.75, 188027.25, - 536786.75, 188001.25, 536786.75, 188014.75, 536786.75, 187942.25, 536786.75, 188017.25, - 536786.75, 187953.25, 536786.75, 188138.75, 536786.75, 187975.25, 536786.75, 187956.25, - 536786.75, 187933.75, 536786.75, 187994.75, 536786.75, 187979.25, 536786.75, 188040.75, - 536786.75, 187912.25, 536786.75, 187940.75, 536786.75, 187927.75, 536786.75, 187939.75, - 536786.75, 187921.25, 536786.75, 187952.75, 536787.25, 188080.75, 536787.25, 187989.25, - 536787.25, 187972.75, 536787.25, 187952.75, 536787.25, 187933.25, 536787.25, 187939.75, - 536787.25, 188040.75, 536787.25, 187988.25, 536787.25, 187999.25, 536787.25, 187925.25, - 536787.25, 188060.25, 536787.25, 187928.25, 536787.25, 188154.75, 536787.25, 187979.25, - 536787.25, 188035.25, 536787.25, 188151.75, 536787.25, 187966.75, 536787.25, 187974.75, - 536787.25, 188028.25, 536787.25, 188063.25, 536787.25, 187941.75, 536787.25, 187942.25, - 536787.25, 187997.75, 536787.25, 188027.25, 536787.25, 188131.75, 536787.25, 188061.25, - 536787.25, 187954.25, 536787.25, 188128.25, 536787.25, 188059.75, 536787.25, 187924.75, - 536787.25, 187978.75, 536787.25, 188025.75, 536787.25, 188014.75, 536787.25, 188021.75, - 536787.25, 187940.25, 536787.25, 188001.25, 536787.25, 188028.75, 536787.25, 188079.25, - 536787.25, 187926.25, 536787.25, 187936.75, 536787.25, 187990.25, 536787.25, 188025.25, - 536787.25, 187945.75, 536787.25, 188062.25, 536787.25, 187977.75, 536787.25, 188055.75, - 536787.25, 188064.75, 536787.25, 187920.75, 536787.25, 187949.25, 536787.25, 187992.75, - 536787.25, 187973.25, 536787.25, 188026.25, 536787.25, 188054.25, 536787.25, 187946.25, - 536787.25, 187922.75, 536787.25, 188154.25, 536787.25, 187926.75, 536787.25, 188044.75, - 536787.25, 188063.75, 536787.25, 187953.25, 536787.25, 187975.75, 536787.25, 187995.25, - 536787.25, 188000.75, 536787.25, 187934.25, 536787.25, 187945.25, 536787.25, 188015.25, - 536787.25, 188054.75, 536787.25, 187974.25, 536787.25, 188150.75, 536787.25, 188160.25, - 536787.25, 188038.25, 536787.25, 187910.75, 536787.25, 188032.25, 536787.25, 188017.75, - 536787.25, 187955.25, 536787.25, 187992.25, 536787.25, 187976.75, 536787.25, 187954.75, - 536787.25, 187934.75, 536787.25, 187944.25, 536787.75, 188041.25, 536787.75, 188061.25, - 536787.75, 188152.75, 536787.75, 187955.25, 536787.75, 187919.75, 536787.75, 188033.75, - 536787.75, 188054.75, 536787.75, 188153.25, 536787.75, 187998.75, 536787.75, 187926.25, - 536787.75, 187945.25, 536787.75, 188083.25, 536787.75, 188039.25, 536787.75, 187938.25, - 536787.75, 187995.75, 536787.75, 187942.25, 536787.75, 187925.25, 536787.75, 187914.75, - 536787.75, 187933.25, 536787.75, 187988.25, 536787.75, 188131.25, 536787.75, 188027.25, - 536787.75, 188016.25, 536787.75, 187956.75, 536787.75, 188036.75, 536787.75, 187946.25, - 536787.75, 188058.75, 536787.75, 188047.25, 536787.75, 188018.25, 536787.75, 187992.25, - 536787.75, 188017.75, 536787.75, 188015.25, 536787.75, 188059.25, 536787.75, 188023.75, - 536787.75, 188043.25, 536787.75, 187920.75, 536787.75, 187990.75, 536787.75, 188074.75, - 536787.75, 188001.25, 536787.75, 188026.25, 536787.75, 187941.75, 536787.75, 188062.75, - 536787.75, 187940.75, 536787.75, 188154.75, 536787.75, 187939.75, 536787.75, 187989.25, - 536787.75, 187974.75, 536787.75, 187979.25, 536787.75, 187974.25, 536787.75, 188027.75, - 536787.75, 188025.25, 536787.75, 188025.75, 536787.75, 188054.25, 536787.75, 188154.25, - 536787.75, 187978.25, 536787.75, 188133.75, 536787.75, 187934.25, 536787.75, 187976.75, - 536787.75, 188159.25, 536787.75, 188153.75, 536787.75, 187936.25, 536787.75, 187943.75, - 536787.75, 187992.75, 536787.75, 187921.75, 536787.75, 188063.25, 536787.75, 187926.75, - 536787.75, 188064.25, 536787.75, 187924.75, 536787.75, 187949.75, 536787.75, 188016.75, - 536787.75, 188028.25, 536787.75, 187933.75, 536787.75, 188063.75, 536787.75, 188080.25, - 536787.75, 187954.75, 536788.25, 188024.75, 536788.25, 188079.25, 536788.25, 187920.25, - 536788.25, 188000.25, 536788.25, 188038.25, 536788.25, 187944.75, 536788.25, 187954.75, - 536788.25, 188023.75, 536788.25, 187920.75, 536788.25, 187974.25, 536788.25, 187998.75, - 536788.25, 187974.75, 536788.25, 187938.75, 536788.25, 187937.25, 536788.25, 188024.25, - 536788.25, 188055.75, 536788.25, 187961.75, 536788.25, 188154.75, 536788.25, 188061.25, - 536788.25, 187922.25, 536788.25, 188152.75, 536788.25, 187989.25, 536788.25, 187955.25, - 536788.25, 187979.25, 536788.25, 187972.25, 536788.25, 188059.75, 536788.25, 187978.75, - 536788.25, 188062.25, 536788.25, 188153.25, 536788.25, 188149.75, 536788.25, 187991.75, - 536788.25, 187956.25, 536788.25, 187997.75, 536788.25, 187925.25, 536788.25, 188135.75, - 536788.25, 187933.75, 536788.25, 187934.25, 536788.25, 188081.25, 536788.25, 188134.25, - 536788.25, 188015.25, 536788.25, 188014.75, 536788.25, 188152.25, 536788.25, 187972.75, - 536788.25, 187942.75, 536788.25, 188060.25, 536788.25, 187990.25, 536788.25, 187924.75, - 536788.25, 188151.25, 536788.25, 188025.75, 536788.25, 188060.75, 536788.25, 188151.75, - 536788.75, 187923.75, 536788.75, 188139.75, 536788.75, 188022.75, 536788.75, 188112.75, - 536788.75, 188022.25, 536788.75, 187996.75, 536788.75, 187956.75, 536788.75, 188080.75, - 536788.75, 188060.75, 536788.75, 188027.75, 536788.75, 187946.25, 536788.75, 188018.25, - 536788.75, 188025.75, 536788.75, 187924.25, 536788.75, 188023.25, 536788.75, 187930.25, - 536788.75, 187940.25, 536788.75, 188015.25, 536788.75, 187954.75, 536788.75, 188063.25, - 536788.75, 187988.75, 536788.75, 188144.75, 536788.75, 187980.75, 536788.75, 188023.75, - 536788.75, 187959.75, 536788.75, 187939.25, 536788.75, 187974.75, 536788.75, 187937.25, - 536788.75, 187953.75, 536788.75, 188024.25, 536788.75, 187955.75, 536788.75, 188018.75, - 536788.75, 187980.25, 536788.75, 187973.25, 536788.75, 188001.25, 536788.75, 187936.75, - 536788.75, 187979.75, 536788.75, 188128.25, 536788.75, 188150.75, 536788.75, 188014.25, - 536788.75, 187979.25, 536788.75, 188017.25, 536788.75, 187958.25, 536788.75, 187913.75, - 536788.75, 187934.75, 536788.75, 188130.25, 536788.75, 188056.75, 536788.75, 187935.25, - 536788.75, 187945.75, 536788.75, 188001.75, 536788.75, 187954.25, 536788.75, 188061.75, - 536788.75, 188012.25, 536788.75, 188149.75, 536788.75, 188152.25, 536788.75, 187991.75, - 536788.75, 188142.25, 536788.75, 188040.25, 536788.75, 187989.75, 536788.75, 187933.75, - 536788.75, 187960.25, 536788.75, 187922.75, 536788.75, 187977.75, 536788.75, 188004.75, - 536788.75, 187934.25, 536788.75, 188150.25, 536788.75, 188081.25, 536789.25, 188038.75, - 536789.25, 187920.25, 536789.25, 188032.25, 536789.25, 187934.25, 536789.25, 188150.25, - 536789.25, 188012.25, 536789.25, 188151.75, 536789.25, 188022.75, 536789.25, 187940.75, - 536789.25, 188022.25, 536789.25, 187999.75, 536789.25, 188080.75, 536789.25, 187923.25, - 536789.25, 187946.25, 536789.25, 187978.25, 536789.25, 188154.25, 536789.25, 187912.75, - 536789.25, 187922.75, 536789.25, 187977.75, 536789.25, 187930.25, 536789.25, 187976.25, - 536789.25, 188054.25, 536789.25, 187923.75, 536789.25, 187924.25, 536789.25, 188023.25, - 536789.25, 188060.25, 536789.25, 187933.75, 536789.25, 187944.25, 536789.25, 187989.75, - 536789.25, 187940.25, 536789.25, 188025.25, 536789.25, 187944.75, 536789.25, 187921.75, - 536789.25, 187954.75, 536789.25, 188013.75, 536789.25, 187988.75, 536789.25, 187980.75, - 536789.25, 188144.75, 536789.25, 188149.75, 536789.25, 188023.75, 536789.25, 188015.75, - 536789.25, 188040.75, 536789.25, 188151.25, 536789.25, 187991.75, 536789.25, 188129.25, - 536789.25, 188059.75, 536789.25, 187954.25, 536789.25, 187953.75, 536789.25, 188026.25, - 536789.25, 187937.25, 536789.25, 187935.25, 536789.25, 188056.75, 536789.25, 188024.25, - 536789.25, 188061.75, 536789.25, 188017.25, 536789.25, 187936.75, 536789.25, 187955.75, - 536789.25, 188055.75, 536789.25, 188001.75, 536789.25, 188045.75, 536789.25, 187914.75, - 536789.25, 188010.75, 536789.25, 187972.25, 536789.25, 187973.25, 536789.25, 187941.75, - 536789.25, 187979.75, 536789.25, 187939.75, 536789.25, 187958.25, 536789.25, 188150.75, - 536789.25, 188128.25, 536789.25, 187955.25, 536789.75, 187922.25, 536789.75, 188149.75, - 536789.75, 187910.75, 536789.75, 187920.25, 536789.75, 187958.75, 536789.75, 187911.75, - 536789.75, 188150.75, 536789.75, 188150.25, 536789.75, 187989.25, 536789.75, 188077.75, - 536789.75, 187957.75, 536789.75, 188021.25, 536789.75, 187979.25, 536789.75, 187939.75, - 536789.75, 187999.75, 536789.75, 187996.75, 536789.75, 188081.25, 536789.75, 187978.25, - 536789.75, 188020.75, 536789.75, 187946.25, 536789.75, 188137.75, 536789.75, 187998.25, - 536789.75, 188058.25, 536789.75, 187994.25, 536789.75, 188102.75, 536789.75, 188001.25, - 536789.75, 187951.25, 536789.75, 187960.25, 536789.75, 187934.75, 536789.75, 188127.25, - 536789.75, 188043.75, 536789.75, 188012.75, 536789.75, 187923.25, 536789.75, 187956.25, - 536789.75, 188025.75, 536789.75, 188160.25, 536789.75, 188018.75, 536789.75, 188056.25, - 536789.75, 188002.75, 536789.75, 187989.75, 536789.75, 187947.75, 536789.75, 188025.25, - 536789.75, 188014.75, 536789.75, 188141.75, 536789.75, 188142.75, 536789.75, 187937.25, - 536789.75, 187935.75, 536789.75, 188015.25, 536789.75, 187931.25, 536789.75, 188017.75, - 536789.75, 187921.75, 536789.75, 187940.75, 536789.75, 187980.75, 536789.75, 188043.25, - 536789.75, 187955.25, 536789.75, 187945.75, 536789.75, 187915.25, 536789.75, 187945.25, - 536790.25, 187920.75, 536790.25, 188126.25, 536790.25, 188139.25, 536790.25, 188050.25, - 536790.25, 187945.75, 536790.25, 187958.75, 536790.25, 188081.75, 536790.25, 188136.25, - 536790.25, 187959.25, 536790.25, 187990.25, 536790.25, 188021.75, 536790.25, 188130.25, - 536790.25, 188026.75, 536790.25, 188017.75, 536790.25, 188000.75, 536790.25, 187947.25, - 536790.25, 187990.75, 536790.25, 187937.75, 536790.25, 187941.25, 536790.25, 187981.25, - 536790.25, 187935.25, 536790.25, 188028.75, 536790.25, 188013.75, 536790.25, 187935.75, - 536790.25, 188070.75, 536790.25, 188019.25, 536790.25, 187959.75, 536790.25, 188068.25, - 536790.25, 187996.25, 536790.25, 188010.75, 536790.25, 188122.25, 536790.25, 187942.75, - 536790.25, 187961.25, 536790.25, 188125.75, 536790.25, 188129.25, 536790.25, 188149.25, - 536790.25, 187980.25, 536790.25, 188020.25, 536790.25, 188018.25, 536790.25, 187922.25, - 536790.25, 187998.25, 536790.25, 187937.25, 536790.25, 188013.25, 536790.25, 187993.75, - 536790.25, 187960.25, 536790.25, 187956.25, 536790.25, 187995.25, 536790.25, 187946.25, - 536790.25, 187946.75, 536790.25, 188020.75, 536790.25, 187919.75, 536790.25, 187956.75, - 536790.25, 187919.25, 536790.25, 187979.75, 536790.25, 187996.75, 536790.25, 188065.75, - 536790.25, 187999.75, 536790.25, 187989.25, 536790.25, 187943.75, 536790.25, 188022.75, - 536790.25, 188150.25, 536790.25, 188009.75, 536790.25, 188082.75, 536790.25, 188021.25, - 536790.25, 188148.75, 536790.25, 187921.25, 536790.25, 187920.25, 536790.25, 188027.25, - 536790.75, 188147.75, 536790.75, 187941.25, 536790.75, 187918.75, 536790.75, 187957.75, - 536790.75, 187960.75, 536790.75, 187990.25, 536790.75, 187920.25, 536790.75, 187915.25, - 536790.75, 187914.25, 536790.75, 188000.75, 536790.75, 188155.25, 536790.75, 188021.75, - 536790.75, 187980.75, 536790.75, 187944.75, 536790.75, 188150.75, 536790.75, 187935.75, - 536790.75, 188150.25, 536790.75, 188026.25, 536790.75, 188005.25, 536790.75, 187919.25, - 536790.75, 188042.25, 536790.75, 188076.25, 536790.75, 187946.75, 536790.75, 188054.25, - 536790.75, 187916.25, 536790.75, 187920.75, 536790.75, 187955.25, 536790.75, 188022.25, - 536790.75, 188053.75, 536790.75, 187959.25, 536790.75, 187955.75, 536790.75, 188081.75, - 536790.75, 188000.25, 536790.75, 188019.75, 536790.75, 188011.75, 536790.75, 187935.25, - 536790.75, 188019.25, 536790.75, 188128.75, 536790.75, 188125.75, 536790.75, 188001.75, - 536790.75, 188149.25, 536790.75, 187947.75, 536790.75, 188013.25, 536790.75, 187911.75, - 536790.75, 188001.25, 536790.75, 188015.25, 536790.75, 187946.25, 536790.75, 188079.75, - 536790.75, 187944.25, 536790.75, 187951.25, 536790.75, 188025.75, 536790.75, 187958.75, - 536790.75, 187996.25, 536790.75, 187937.25, 536790.75, 188014.25, 536790.75, 187995.25, - 536790.75, 187919.75, 536790.75, 187979.75, 536790.75, 187921.25, 536790.75, 188070.25, - 536790.75, 188148.75, 536790.75, 188021.25, 536790.75, 187989.25, 536790.75, 188082.75, - 536790.75, 188018.25, 536791.25, 188067.75, 536791.25, 188021.25, 536791.25, 187924.25, - 536791.25, 188075.25, 536791.25, 187947.75, 536791.25, 188057.25, 536791.25, 188074.75, - 536791.25, 188053.25, 536791.25, 187944.25, 536791.25, 188148.25, 536791.25, 188149.25, - 536791.25, 187947.25, 536791.25, 187980.25, 536791.25, 187984.25, 536791.25, 187961.75, - 536791.25, 188018.75, 536791.25, 188013.25, 536791.25, 188026.75, 536791.25, 188011.25, - 536791.25, 188019.75, 536791.25, 187942.75, 536791.25, 188066.25, 536791.25, 187935.75, - 536791.25, 187978.75, 536791.25, 187937.75, 536791.25, 187993.25, 536791.25, 187938.75, - 536791.25, 188054.75, 536791.25, 187998.75, 536791.25, 187991.25, 536791.25, 188028.25, - 536791.25, 187956.75, 536791.25, 187959.25, 536791.25, 187994.75, 536791.25, 188049.25, - 536791.25, 187916.25, 536791.25, 188147.75, 536791.25, 188146.75, 536791.25, 187999.25, - 536791.25, 187919.25, 536791.25, 188052.25, 536791.25, 187980.75, 536791.25, 187929.25, - 536791.25, 187944.75, 536791.25, 187940.25, 536791.25, 187959.75, 536791.25, 187943.75, - 536791.25, 187935.25, 536791.25, 188000.75, 536791.25, 188056.75, 536791.25, 187914.25, - 536791.25, 187918.75, 536791.25, 187956.25, 536791.25, 188147.25, 536791.25, 188027.25, - 536791.25, 187990.25, 536791.25, 187915.25, 536791.75, 187981.25, 536791.75, 187975.25, - 536791.75, 188139.25, 536791.75, 188012.25, 536791.75, 187959.75, 536791.75, 188069.25, - 536791.75, 188129.25, 536791.75, 188020.25, 536791.75, 188145.75, 536791.75, 187919.25, - 536791.75, 188150.25, 536791.75, 187991.25, 536791.75, 187936.25, 536791.75, 188076.25, - 536791.75, 188073.25, 536791.75, 187949.75, 536791.75, 188095.75, 536791.75, 188135.75, - 536791.75, 187960.25, 536791.75, 187915.75, 536791.75, 188054.25, 536791.75, 188055.25, - 536791.75, 188028.25, 536791.75, 187926.75, 536791.75, 188052.25, 536791.75, 187918.75, - 536791.75, 188025.25, 536791.75, 187945.25, 536791.75, 188013.75, 536791.75, 187977.25, - 536791.75, 187917.25, 536791.75, 188003.25, 536791.75, 187978.75, 536791.75, 187916.75, - 536791.75, 187997.25, 536791.75, 188123.25, 536791.75, 188133.25, 536791.75, 188046.25, - 536791.75, 187959.25, 536791.75, 188017.75, 536791.75, 187990.75, 536791.75, 188146.25, - 536791.75, 187947.25, 536791.75, 188118.75, 536791.75, 187998.25, 536791.75, 187918.25, - 536791.75, 188153.75, 536791.75, 187944.25, 536791.75, 188130.75, 536791.75, 188059.25, - 536791.75, 187916.25, 536791.75, 188146.75, 536791.75, 188057.75, 536791.75, 188077.25, - 536791.75, 187947.75, 536791.75, 188026.75, 536791.75, 188067.75, 536791.75, 187939.25, - 536791.75, 187938.25, 536791.75, 188050.75, 536791.75, 188029.25, 536791.75, 188021.25, - 536791.75, 188057.25, 536791.75, 188027.75, 536791.75, 188056.25, 536791.75, 188148.75, - 536791.75, 187934.75, 536791.75, 187940.75, 536791.75, 187917.75, 536791.75, 187938.75, - 536791.75, 188132.75, 536791.75, 187941.75, 536791.75, 188066.25, 536791.75, 188148.25, - 536791.75, 187991.75, 536791.75, 187950.75, 536791.75, 187980.25, 536791.75, 187961.25, - 536791.75, 187981.75, 536791.75, 187957.25, 536791.75, 188011.75, 536791.75, 187980.75, - 536792.25, 187980.75, 536792.25, 187941.25, 536792.25, 187981.25, 536792.25, 188081.75, - 536792.25, 187982.25, 536792.25, 187962.75, 536792.25, 187959.25, 536792.25, 187984.25, - 536792.25, 188075.25, 536792.25, 188046.75, 536792.25, 187956.25, 536792.25, 188160.25, - 536792.25, 188020.25, 536792.25, 187978.75, 536792.25, 188080.25, 536792.25, 187917.25, - 536792.25, 187991.25, 536792.25, 187960.25, 536792.25, 188148.25, 536792.25, 188066.25, - 536792.25, 187942.25, 536792.25, 188145.25, 536792.25, 187935.25, 536792.25, 187933.75, - 536792.25, 187957.25, 536792.25, 187918.75, 536792.25, 187953.75, 536792.25, 188136.25, - 536792.25, 187980.25, 536792.25, 188054.25, 536792.25, 187996.75, 536792.25, 187950.75, - 536792.25, 187956.75, 536792.25, 188146.25, 536792.25, 188126.75, 536792.25, 187935.75, - 536792.25, 188073.25, 536792.25, 188132.75, 536792.25, 188150.75, 536792.25, 188147.75, - 536792.25, 187914.25, 536792.25, 188026.75, 536792.25, 188128.75, 536792.25, 187940.25, - 536792.25, 188030.25, 536792.25, 187979.75, 536792.25, 187917.75, 536792.25, 187998.25, - 536792.25, 187918.25, 536792.25, 187953.25, 536792.25, 188148.75, 536792.25, 187940.75, - 536792.25, 187934.25, 536792.25, 188122.75, 536792.25, 187939.75, 536792.25, 188057.25, - 536792.25, 188048.75, 536792.25, 188133.25, 536792.25, 188132.25, 536792.25, 188019.25, - 536792.25, 187910.75, 536792.25, 187990.75, 536792.25, 188050.75, 536792.25, 188054.75, - 536792.25, 188053.75, 536792.25, 187976.75, 536792.25, 188021.25, 536792.25, 187938.25, - 536792.25, 187944.25, 536792.25, 187946.75, 536792.25, 188074.25, 536792.25, 188077.25, - 536792.25, 187994.75, 536792.25, 187936.25, 536792.25, 187944.75, 536792.75, 187916.75, - 536792.75, 188146.75, 536792.75, 187939.25, 536792.75, 187947.75, 536792.75, 188121.25, - 536792.75, 187914.25, 536792.75, 188147.25, 536792.75, 187999.25, 536792.75, 187990.75, - 536792.75, 188150.25, 536792.75, 187940.75, 536792.75, 188051.75, 536792.75, 188050.75, - 536792.75, 188074.25, 536792.75, 187915.75, 536792.75, 187916.25, 536792.75, 187947.25, - 536792.75, 188056.25, 536792.75, 187917.75, 536792.75, 188029.25, 536792.75, 188017.75, - 536792.75, 188008.25, 536792.75, 187934.25, 536792.75, 187961.25, 536792.75, 187998.75, - 536792.75, 188132.75, 536792.75, 187995.25, 536792.75, 188027.75, 536792.75, 188016.25, - 536792.75, 187944.75, 536792.75, 187911.75, 536792.75, 188121.75, 536792.75, 187957.75, - 536792.75, 187959.75, 536792.75, 188069.25, 536792.75, 187993.75, 536792.75, 188143.75, - 536792.75, 188022.25, 536792.75, 188144.75, 536792.75, 187960.75, 536792.75, 187981.25, - 536792.75, 188023.75, 536792.75, 187973.25, 536792.75, 187991.75, 536792.75, 188053.25, - 536792.75, 187991.25, 536792.75, 188018.25, 536792.75, 187933.75, 536792.75, 187975.75, - 536792.75, 187986.25, 536792.75, 187978.75, 536792.75, 187976.25, 536792.75, 188075.25, - 536792.75, 187982.25, 536792.75, 188018.75, 536792.75, 188117.25, 536793.25, 188028.25, - 536793.25, 188073.75, 536793.25, 188026.75, 536793.25, 187925.75, 536793.25, 187933.75, - 536793.25, 188015.75, 536793.25, 187992.25, 536793.25, 188023.75, 536793.25, 187977.25, - 536793.25, 188021.75, 536793.25, 188070.75, 536793.25, 188016.75, 536793.25, 188051.25, - 536793.25, 187997.75, 536793.25, 187952.75, 536793.25, 187957.75, 536793.25, 188143.75, - 536793.25, 188151.25, 536793.25, 188055.25, 536793.25, 188017.25, 536793.25, 187916.25, - 536793.25, 187962.25, 536793.25, 187912.25, 536793.25, 188013.25, 536793.25, 187913.75, - 536793.25, 188146.25, 536793.25, 187945.75, 536793.25, 188144.75, 536793.25, 188016.25, - 536793.25, 188082.25, 536793.25, 188030.75, 536793.25, 187979.25, 536793.25, 187958.25, - 536793.25, 187947.25, 536793.25, 187948.75, 536793.25, 187923.75, 536793.25, 188094.25, - 536793.25, 188057.75, 536793.25, 188058.75, 536793.25, 187932.75, 536793.25, 188067.75, - 536793.25, 188005.25, 536793.25, 188024.75, 536793.25, 188052.75, 536793.25, 188050.75, - 536793.25, 187975.25, 536793.25, 187966.25, 536793.25, 187944.75, 536793.25, 187939.75, - 536793.25, 188145.75, 536793.25, 188062.25, 536793.25, 188144.25, 536793.25, 187934.75, - 536793.25, 187938.75, 536793.25, 187933.25, 536793.25, 187967.25, 536793.25, 187967.75, - 536793.25, 188072.75, 536793.25, 187992.75, 536793.25, 188027.75, 536793.25, 188151.75, - 536793.25, 188023.25, 536793.25, 187977.75, 536793.25, 188142.75, 536793.25, 187931.75, - 536793.25, 187935.75, 536793.25, 188055.75, 536793.25, 187998.75, 536793.25, 187960.25, - 536793.25, 188018.25, 536793.25, 188019.75, 536793.25, 187962.75, 536793.25, 187982.75, - 536793.25, 187981.75, 536793.25, 187915.25, 536793.25, 187960.75, 536793.75, 187933.25, - 536793.75, 187992.75, 536793.75, 187950.25, 536793.75, 188004.25, 536793.75, 188004.75, - 536793.75, 187945.25, 536793.75, 187975.75, 536793.75, 187977.75, 536793.75, 187967.25, - 536793.75, 188021.75, 536793.75, 187934.25, 536793.75, 187991.25, 536793.75, 188143.25, - 536793.75, 187915.25, 536793.75, 188023.75, 536793.75, 187932.75, 536793.75, 188120.25, - 536793.75, 188136.75, 536793.75, 188020.75, 536793.75, 187915.75, 536793.75, 188073.25, - 536793.75, 188147.75, 536793.75, 188051.25, 536793.75, 187931.75, 536793.75, 187939.25, - 536793.75, 187962.25, 536793.75, 187944.75, 536793.75, 188055.25, 536793.75, 187997.75, - 536793.75, 187948.75, 536793.75, 188145.75, 536793.75, 188142.75, 536793.75, 188050.25, - 536793.75, 188027.75, 536793.75, 188016.75, 536793.75, 187982.25, 536793.75, 187958.25, - 536793.75, 187986.75, 536793.75, 188028.75, 536793.75, 187974.75, 536793.75, 188016.25, - 536793.75, 188123.25, 536793.75, 188075.25, 536793.75, 187959.75, 536793.75, 187938.75, - 536793.75, 187930.75, 536793.75, 188146.25, 536793.75, 187914.25, 536793.75, 188015.75, - 536793.75, 187980.75, 536793.75, 187914.75, 536793.75, 188058.25, 536793.75, 187996.75, - 536793.75, 187937.25, 536793.75, 187947.25, 536793.75, 187957.25, 536793.75, 188151.75, - 536793.75, 187951.75, 536793.75, 188066.75, 536793.75, 187939.75, 536793.75, 188017.25, - 536793.75, 188070.75, 536793.75, 188144.25, 536793.75, 187912.25, 536793.75, 187913.75, - 536793.75, 187966.25, 536793.75, 188128.75, 536793.75, 187945.75, 536793.75, 188074.25, - 536793.75, 188146.75, 536793.75, 188015.25, 536793.75, 188024.75, 536793.75, 187991.75, - 536793.75, 187947.75, 536793.75, 188142.25, 536793.75, 188018.25, 536793.75, 187923.75, - 536793.75, 187981.75, 536793.75, 187916.75, 536793.75, 188055.75, 536793.75, 188000.25, - 536793.75, 187953.25, 536794.25, 188019.25, 536794.25, 188138.75, 536794.25, 187976.75, - 536794.25, 187979.25, 536794.25, 188019.75, 536794.25, 188065.25, 536794.25, 188119.25, - 536794.25, 188127.75, 536794.25, 187983.25, 536794.25, 188142.25, 536794.25, 187965.25, - 536794.25, 187947.75, 536794.25, 188023.25, 536794.25, 187998.25, 536794.25, 188144.25, - 536794.25, 187961.25, 536794.25, 188083.25, 536794.25, 188015.25, 536794.25, 188128.75, - 536794.25, 188052.75, 536794.25, 188151.25, 536794.25, 187936.75, 536794.25, 188058.75, - 536794.25, 187960.75, 536794.25, 187995.25, 536794.25, 188143.75, 536794.25, 187992.75, - 536794.25, 188006.25, 536794.25, 188067.75, 536794.25, 187966.75, 536794.25, 188027.25, - 536794.25, 187949.25, 536794.25, 188066.25, 536794.25, 187996.25, 536794.25, 187962.75, - 536794.25, 188073.75, 536794.25, 187930.75, 536794.25, 187958.25, 536794.25, 187982.25, - 536794.25, 187998.75, 536794.25, 187948.25, 536794.25, 188024.25, 536794.25, 188018.75, - 536794.25, 187937.75, 536794.25, 188084.25, 536794.25, 187997.75, 536794.25, 187931.75, - 536794.25, 188071.75, 536794.25, 187913.25, 536794.25, 188026.25, 536794.25, 187946.75, - 536794.25, 187915.25, 536794.25, 187932.75, 536794.25, 188129.25, 536794.25, 187912.75, - 536794.25, 187968.25, 536794.25, 188005.25, 536794.25, 188004.25, 536794.25, 188056.75, - 536794.25, 187957.75, 536794.25, 188002.75, 536794.25, 188014.75, 536794.75, 187975.75, - 536794.75, 187968.75, 536794.75, 188141.75, 536794.75, 188005.75, 536794.75, 187961.75, - 536794.75, 188152.25, 536794.75, 187957.75, 536794.75, 188051.75, 536794.75, 188029.75, - 536794.75, 188059.25, 536794.75, 187911.75, 536794.75, 187914.25, 536794.75, 188068.25, - 536794.75, 187998.75, 536794.75, 187931.25, 536794.75, 187949.25, 536794.75, 187914.75, - 536794.75, 187965.75, 536794.75, 188057.25, 536794.75, 188066.75, 536794.75, 188027.25, - 536794.75, 187967.75, 536794.75, 187945.25, 536794.75, 187911.25, 536794.75, 187983.75, - 536794.75, 188013.75, 536794.75, 187966.25, 536794.75, 188113.75, 536794.75, 188092.25, - 536794.75, 187947.75, 536794.75, 188121.25, 536794.75, 187958.75, 536794.75, 188142.25, - 536794.75, 188128.25, 536794.75, 187983.25, 536794.75, 188025.75, 536794.75, 187976.75, - 536794.75, 188019.25, 536794.75, 188000.25, 536794.75, 187929.75, 536794.75, 187935.75, - 536794.75, 187981.75, 536794.75, 188138.75, 536794.75, 187962.75, 536794.75, 188072.25, - 536794.75, 187965.25, 536794.75, 188079.75, 536794.75, 188001.75, 536794.75, 188056.25, - 536794.75, 188006.25, 536794.75, 187959.25, 536794.75, 187994.25, 536794.75, 188082.25, - 536794.75, 187912.25, 536794.75, 188151.25, 536794.75, 188059.75, 536794.75, 188117.75, - 536794.75, 188058.75, 536794.75, 187992.25, 536794.75, 188071.25, 536794.75, 188039.25, - 536794.75, 187946.25, 536794.75, 188023.25, 536794.75, 188003.25, 536794.75, 188015.75, - 536794.75, 187995.75, 536794.75, 187993.25, 536794.75, 187963.75, 536794.75, 188142.75, - 536794.75, 187930.75, 536794.75, 188141.25, 536794.75, 188025.25, 536794.75, 188134.75, - 536794.75, 188022.25, 536794.75, 188030.75, 536794.75, 188052.25, 536794.75, 187999.75, - 536794.75, 188137.75, 536794.75, 187948.75, 536794.75, 187910.75, 536794.75, 188140.25, - 536794.75, 188071.75, 536794.75, 188073.25, 536794.75, 187913.25, 536794.75, 188069.25, - 536794.75, 188160.25, 536794.75, 187946.75, 536794.75, 187982.75, 536794.75, 187977.75, - 536794.75, 187943.25, 536795.25, 187979.25, 536795.25, 187947.75, 536795.25, 188024.75, - 536795.25, 188148.25, 536795.25, 187930.75, 536795.25, 188029.75, 536795.25, 188136.25, - 536795.25, 188059.25, 536795.25, 187961.75, 536795.25, 187911.75, 536795.25, 187928.25, - 536795.25, 187981.75, 536795.25, 188058.75, 536795.25, 187946.25, 536795.25, 188023.25, - 536795.25, 188067.25, 536795.25, 187999.75, 536795.25, 187982.75, 536795.25, 188002.75, - 536795.25, 187931.75, 536795.25, 188022.25, 536795.25, 188058.25, 536795.25, 187983.75, - 536795.25, 187960.75, 536795.25, 187946.75, 536795.25, 188051.25, 536795.25, 187937.75, - 536795.25, 188125.25, 536795.25, 187951.25, 536795.25, 187913.25, 536795.25, 188082.25, - 536795.25, 188052.25, 536795.25, 187948.75, 536795.25, 187911.25, 536795.25, 187963.75, - 536795.25, 188020.75, 536795.25, 188142.75, 536795.25, 187997.25, 536795.25, 188003.25, - 536795.25, 187965.25, 536795.25, 188080.75, 536795.25, 187936.75, 536795.25, 188142.25, - 536795.25, 187966.25, 536795.25, 188128.25, 536795.25, 188019.75, 536795.25, 187912.25, - 536795.25, 188052.75, 536795.25, 188006.25, 536795.25, 187968.75, 536795.25, 188141.75, - 536795.25, 188141.25, 536795.25, 187995.75, 536795.25, 187944.25, 536795.25, 188015.25, - 536795.25, 188071.25, 536795.25, 188152.75, 536795.25, 188019.25, 536795.25, 187995.25, - 536795.25, 187992.25, 536795.25, 187949.25, 536795.25, 188140.75, 536795.25, 187945.25, - 536795.25, 187959.25, 536795.25, 188116.75, 536795.25, 188140.25, 536795.25, 188071.75, - 536795.25, 188056.25, 536795.25, 187958.25, 536795.25, 188013.75, 536795.25, 187929.75, - 536795.25, 187944.75, 536795.25, 188139.25, 536795.25, 187965.75, 536795.25, 188005.75, - 536795.25, 187975.75, 536795.25, 187958.75, 536795.25, 188017.25, 536795.25, 187993.25, - 536795.25, 187963.25, 536795.25, 188055.25, 536795.25, 187967.25, 536795.25, 188090.75, - 536795.75, 187954.25, 536795.75, 187945.75, 536795.75, 188062.25, 536795.75, 187944.25, - 536795.75, 188052.75, 536795.75, 188115.25, 536795.75, 187932.75, 536795.75, 188079.75, - 536795.75, 187996.25, 536795.75, 187966.25, 536795.75, 187992.75, 536795.75, 187949.75, - 536795.75, 188014.75, 536795.75, 187942.75, 536795.75, 187962.75, 536795.75, 187936.75, - 536795.75, 188141.25, 536795.75, 187997.25, 536795.75, 187930.25, 536795.75, 188052.25, - 536795.75, 187943.75, 536795.75, 188053.25, 536795.75, 188018.75, 536795.75, 187978.75, - 536795.75, 188140.75, 536795.75, 188159.75, 536795.75, 188002.25, 536795.75, 188031.25, - 536795.75, 188137.75, 536795.75, 188151.75, 536795.75, 187959.25, 536795.75, 187960.75, - 536795.75, 188078.75, 536795.75, 187983.75, 536795.75, 188026.25, 536795.75, 188073.75, - 536795.75, 188071.75, 536795.75, 187943.25, 536795.75, 188121.75, 536795.75, 187968.25, - 536795.75, 187937.25, 536795.75, 188038.75, 536795.75, 188067.75, 536795.75, 188060.25, - 536795.75, 188138.25, 536795.75, 187983.25, 536795.75, 188073.25, 536795.75, 187994.25, - 536795.75, 188017.75, 536795.75, 187928.75, 536795.75, 188001.25, 536795.75, 187938.75, - 536795.75, 188067.25, 536795.75, 187993.75, 536795.75, 188029.75, 536795.75, 188004.25, - 536795.75, 187961.25, 536795.75, 188044.75, 536795.75, 188154.25, 536795.75, 187931.25, - 536795.75, 188155.25, 536795.75, 188000.75, 536795.75, 188015.75, 536795.75, 188005.75, - 536795.75, 187911.75, 536796.25, 188006.25, 536796.25, 187933.25, 536796.25, 188138.75, - 536796.25, 188028.75, 536796.25, 188055.75, 536796.25, 188153.25, 536796.25, 188004.75, - 536796.25, 188137.25, 536796.25, 188080.25, 536796.25, 188014.25, 536796.25, 187959.75, - 536796.25, 187950.75, 536796.25, 188117.25, 536796.25, 188132.75, 536796.25, 187950.25, - 536796.25, 188030.25, 536796.25, 187920.75, 536796.25, 188136.25, 536796.25, 187961.25, - 536796.25, 187944.25, 536796.25, 187969.25, 536796.25, 188016.75, 536796.25, 188004.25, - 536796.25, 188050.75, 536796.25, 187946.25, 536796.25, 188074.25, 536796.25, 188019.75, - 536796.25, 188115.25, 536796.25, 188077.25, 536796.25, 187996.75, 536796.25, 188067.25, - 536796.25, 188059.75, 536796.25, 187979.25, 536796.25, 188057.25, 536796.25, 187966.75, - 536796.25, 188017.75, 536796.25, 188003.25, 536796.25, 187942.75, 536796.25, 188079.25, - 536796.25, 188108.75, 536796.25, 188015.25, 536796.25, 188018.25, 536796.25, 187929.75, - 536796.25, 188123.75, 536796.25, 188072.25, 536796.25, 187949.25, 536796.25, 187920.25, - 536796.25, 187929.25, 536796.25, 187960.25, 536796.25, 187994.25, 536796.25, 188054.75, - 536796.25, 187935.25, 536796.25, 188073.25, 536796.25, 188069.25, 536796.25, 187997.75, - 536796.25, 188052.25, 536796.25, 188045.75, 536796.25, 187983.25, 536796.25, 187938.75, - 536796.25, 188139.75, 536796.25, 188131.75, 536796.25, 188060.25, 536796.25, 188138.25, - 536796.25, 188067.75, 536796.25, 187940.75, 536796.25, 187932.25, 536796.25, 187995.25, - 536796.25, 187948.75, 536796.25, 188065.75, 536796.25, 188025.25, 536796.25, 188135.25, - 536796.25, 188083.75, 536796.25, 187927.25, 536796.25, 188057.75, 536796.25, 187984.25, - 536796.25, 188027.75, 536796.25, 187998.75, 536796.25, 188136.75, 536796.25, 188042.25, - 536796.25, 188078.25, 536796.25, 188133.75, 536796.25, 188083.25, 536796.25, 187993.25, - 536796.25, 187963.25, 536796.25, 187941.75, 536796.25, 187994.75, 536796.25, 187959.25, - 536796.25, 187960.75, 536796.25, 188078.75, 536796.25, 188120.75, 536796.25, 188044.25, - 536796.75, 187941.25, 536796.75, 187972.75, 536796.75, 187959.25, 536796.75, 188138.75, - 536796.75, 188116.75, 536796.75, 187938.75, 536796.75, 187983.75, 536796.75, 188083.25, - 536796.75, 187960.75, 536796.75, 188044.25, 536796.75, 188073.75, 536796.75, 188150.75, - 536796.75, 188041.75, 536796.75, 188027.75, 536796.75, 187945.25, 536796.75, 188154.75, - 536796.75, 188002.25, 536796.75, 188078.25, 536796.75, 188064.25, 536796.75, 188058.25, - 536796.75, 187937.25, 536796.75, 187927.25, 536796.75, 187926.25, 536796.75, 188076.25, - 536796.75, 187968.25, 536796.75, 187932.25, 536796.75, 187943.75, 536796.75, 188138.25, - 536796.75, 187983.25, 536796.75, 188049.25, 536796.75, 188027.25, 536796.75, 187927.75, - 536796.75, 187997.75, 536796.75, 188042.75, 536796.75, 188005.25, 536796.75, 188118.75, - 536796.75, 187994.25, 536796.75, 187936.75, 536796.75, 187939.25, 536796.75, 188072.25, - 536796.75, 187949.25, 536796.75, 188123.75, 536796.75, 188018.25, 536796.75, 187966.75, - 536796.75, 187992.75, 536796.75, 188079.25, 536796.75, 188134.75, 536796.75, 188084.25, - 536796.75, 188003.25, 536796.75, 188073.25, 536796.75, 188017.75, 536796.75, 188085.75, - 536796.75, 188057.25, 536796.75, 187930.75, 536796.75, 187966.25, 536796.75, 188139.25, - 536796.75, 188080.75, 536796.75, 188123.25, 536796.75, 187996.75, 536796.75, 188065.25, - 536796.75, 188029.25, 536796.75, 188128.25, 536796.75, 187950.75, 536796.75, 188077.25, - 536796.75, 187944.25, 536796.75, 187933.75, 536796.75, 188050.75, 536796.75, 187961.25, - 536796.75, 188113.75, 536796.75, 188079.75, 536796.75, 188136.25, 536796.75, 188030.25, - 536796.75, 187968.75, 536796.75, 187950.25, 536796.75, 188014.25, 536796.75, 187959.75, - 536796.75, 188066.75, 536796.75, 187961.75, 536796.75, 188000.75, 536796.75, 188137.25, - 536796.75, 188059.75, 536796.75, 188006.25, 536796.75, 188022.25, 536797.25, 188052.75, - 536797.25, 187918.75, 536797.25, 188006.25, 536797.25, 188153.25, 536797.25, 187949.75, - 536797.25, 188007.75, 536797.25, 188065.25, 536797.25, 187967.25, 536797.25, 188014.75, - 536797.25, 187943.75, 536797.25, 188148.75, 536797.25, 187993.25, 536797.25, 187934.25, - 536797.25, 187941.75, 536797.25, 187937.25, 536797.25, 188079.75, 536797.25, 188076.25, - 536797.25, 188001.25, 536797.25, 187940.25, 536797.25, 188043.75, 536797.25, 187925.75, - 536797.25, 187930.75, 536797.25, 188029.75, 536797.25, 188019.75, 536797.25, 187933.75, - 536797.25, 188160.25, 536797.25, 188016.75, 536797.25, 187950.75, 536797.25, 188059.25, - 536797.25, 188043.25, 536797.25, 188133.25, 536797.25, 187926.75, 536797.25, 188037.75, - 536797.25, 188005.75, 536797.25, 188076.75, 536797.25, 188055.75, 536797.25, 187931.25, - 536797.25, 187967.75, 536797.25, 188080.75, 536797.25, 187954.75, 536797.25, 187928.25, - 536797.25, 187935.75, 536797.25, 188134.75, 536797.25, 188123.75, 536797.25, 188117.75, - 536797.25, 188073.75, 536797.25, 187982.75, 536797.25, 187965.25, 536797.25, 187994.25, - 536797.25, 187995.75, 536797.25, 188002.75, 536797.25, 188003.25, 536797.25, 188135.75, - 536797.25, 188045.25, 536797.25, 188062.75, 536797.25, 188139.75, 536797.25, 188063.75, - 536797.25, 188079.25, 536797.25, 188157.75, 536797.25, 188060.25, 536797.25, 188067.75, - 536797.25, 188077.75, 536797.25, 188016.25, 536797.25, 188152.75, 536797.25, 188071.75, - 536797.25, 187910.75, 536797.25, 187983.75, 536797.25, 187960.25, 536797.25, 188019.25, - 536797.25, 187959.25, 536797.25, 187936.75, 536797.25, 187917.25, 536797.25, 187969.75, - 536797.25, 187930.25, 536797.25, 188069.25, 536797.25, 188092.75, 536797.25, 188136.75, - 536797.25, 187966.75, 536797.25, 188041.75, 536797.25, 188052.25, 536797.75, 188060.25, - 536797.75, 187993.75, 536797.75, 187949.75, 536797.75, 188133.25, 536797.75, 188076.75, - 536797.75, 188135.25, 536797.75, 187950.75, 536797.75, 188138.75, 536797.75, 188000.75, - 536797.75, 188052.25, 536797.75, 188001.75, 536797.75, 188045.75, 536797.75, 188070.25, - 536797.75, 188066.25, 536797.75, 188053.25, 536797.75, 188057.25, 536797.75, 187958.75, - 536797.75, 187964.25, 536797.75, 188030.25, 536797.75, 187912.25, 536797.75, 188015.25, - 536797.75, 188153.75, 536797.75, 188075.75, 536797.75, 188041.25, 536797.75, 187969.25, - 536797.75, 187984.75, 536797.75, 188085.75, 536797.75, 188065.25, 536797.75, 187995.25, - 536797.75, 187935.75, 536797.75, 187966.75, 536797.75, 188132.75, 536797.75, 187981.75, - 536797.75, 188074.75, 536797.75, 188032.75, 536797.75, 188054.25, 536797.75, 188119.25, - 536797.75, 188004.25, 536797.75, 188015.75, 536797.75, 188058.75, 536797.75, 188073.25, - 536797.75, 187984.25, 536797.75, 188084.75, 536797.75, 187967.25, 536797.75, 188075.25, - 536797.75, 187938.25, 536797.75, 188080.25, 536797.75, 187924.25, 536797.75, 188076.25, - 536797.75, 187996.25, 536797.75, 188109.25, 536797.75, 188121.25, 536797.75, 188124.75, - 536797.75, 188006.75, 536797.75, 188081.25, 536797.75, 188141.75, 536797.75, 188044.25, - 536797.75, 188046.75, 536797.75, 187934.75, 536797.75, 187941.25, 536797.75, 187929.75, - 536797.75, 188005.25, 536797.75, 187970.25, 536797.75, 188084.25, 536797.75, 188086.75, - 536797.75, 187994.75, 536797.75, 187963.75, 536797.75, 188133.75, 536797.75, 187929.25, - 536797.75, 188120.75, 536797.75, 188042.25, 536797.75, 188061.25, 536797.75, 187938.75, - 536797.75, 187942.25, 536797.75, 188014.75, 536797.75, 187925.25, 536797.75, 187943.25, - 536797.75, 187932.75, 536797.75, 187941.75, 536797.75, 187931.75, 536797.75, 187934.25, - 536797.75, 188039.25, 536797.75, 187983.25, 536797.75, 188062.75, 536797.75, 187997.25, - 536798.25, 187985.25, 536798.25, 187963.75, 536798.25, 187932.75, 536798.25, 188131.75, - 536798.25, 188001.75, 536798.25, 187934.25, 536798.25, 188067.75, 536798.25, 188016.25, - 536798.25, 188139.75, 536798.25, 187955.75, 536798.25, 187949.25, 536798.25, 187941.75, - 536798.25, 188086.75, 536798.25, 188042.75, 536798.25, 188109.75, 536798.25, 188076.25, - 536798.25, 187963.25, 536798.25, 187943.25, 536798.25, 187959.75, 536798.25, 188061.25, - 536798.25, 187960.25, 536798.25, 187982.75, 536798.25, 188028.25, 536798.25, 188069.75, - 536798.25, 188120.75, 536798.25, 188056.25, 536798.25, 187994.75, 536798.25, 187929.25, - 536798.25, 187983.75, 536798.25, 188084.25, 536798.25, 187936.75, 536798.25, 188081.25, - 536798.25, 187925.25, 536798.25, 187969.75, 536798.25, 188133.75, 536798.25, 188159.75, - 536798.25, 188060.75, 536798.25, 187929.75, 536798.25, 188139.25, 536798.25, 187998.75, - 536798.25, 187969.25, 536798.25, 187984.25, 536798.25, 188004.25, 536798.25, 188015.75, - 536798.25, 188058.75, 536798.25, 187938.25, 536798.25, 188047.75, 536798.25, 188075.25, - 536798.25, 188046.75, 536798.25, 187962.25, 536798.25, 187993.75, 536798.25, 187923.25, - 536798.25, 187948.75, 536798.25, 187924.25, 536798.25, 188087.25, 536798.25, 188132.75, - 536798.25, 188057.75, 536798.25, 188121.25, 536798.25, 187998.25, 536798.25, 187981.75, - 536798.25, 187967.25, 536798.25, 188080.25, 536798.25, 187984.75, 536798.25, 187928.25, - 536798.25, 188015.25, 536798.25, 188113.75, 536798.25, 188041.25, 536798.25, 188031.75, - 536798.25, 188154.25, 536798.25, 188134.25, 536798.25, 188070.75, 536798.25, 187932.25, - 536798.25, 188074.75, 536798.25, 188016.75, 536798.25, 188152.75, 536798.25, 188119.75, - 536798.25, 188039.75, 536798.25, 188052.25, 536798.25, 188045.75, 536798.25, 188000.75, - 536798.25, 187924.75, 536798.25, 187958.75, 536798.25, 187950.75, 536798.25, 187950.25, - 536798.25, 188063.25, 536798.25, 188129.25, 536798.25, 187996.75, 536798.25, 188135.25, - 536798.25, 187915.75, 536798.25, 187934.75, 536798.25, 187930.25, 536798.25, 188005.25, - 536798.25, 188059.25, 536798.25, 187952.25, 536798.75, 188147.75, 536798.75, 187926.75, - 536798.75, 188043.25, 536798.75, 188040.25, 536798.75, 187962.75, 536798.75, 188056.75, - 536798.75, 187936.25, 536798.75, 188000.75, 536798.75, 188028.75, 536798.75, 188066.75, - 536798.75, 187967.75, 536798.75, 188080.75, 536798.75, 187964.25, 536798.75, 188070.75, - 536798.75, 188085.75, 536798.75, 188153.75, 536798.75, 187952.25, 536798.75, 188141.25, - 536798.75, 188054.25, 536798.75, 188044.75, 536798.75, 188075.75, 536798.75, 188132.75, - 536798.75, 187922.75, 536798.75, 188120.25, 536798.75, 187985.25, 536798.75, 188139.25, - 536798.75, 188074.25, 536798.75, 188133.75, 536798.75, 187948.25, 536798.75, 188006.75, - 536798.75, 187923.75, 536798.75, 188145.75, 536798.75, 187994.25, 536798.75, 188118.75, - 536798.75, 187970.75, 536798.75, 188114.75, 536798.75, 187995.75, 536798.75, 187968.75, - 536798.75, 188139.75, 536798.75, 188154.75, 536798.75, 188042.75, 536798.75, 187931.75, - 536798.75, 188040.75, 536798.75, 188062.75, 536798.75, 187942.75, 536798.75, 188065.75, - 536798.75, 188131.75, 536798.75, 187968.25, 536798.75, 188058.25, 536798.75, 188131.25, - 536798.75, 188158.25, 536798.75, 187959.25, 536798.75, 187959.75, 536798.75, 187947.25, - 536798.75, 187941.25, 536798.75, 187998.75, 536798.75, 187957.75, 536798.75, 187951.25, - 536798.75, 187962.25, 536798.75, 188057.75, 536798.75, 187998.25, 536798.75, 187995.25, - 536798.75, 187984.75, 536798.75, 187932.25, 536798.75, 188119.75, 536798.75, 188007.75, - 536798.75, 188053.25, 536798.75, 188156.75, 536798.75, 188092.25, 536798.75, 188019.25, - 536798.75, 187950.25, 536799.25, 187947.75, 536799.25, 187961.75, 536799.25, 188061.25, - 536799.25, 187936.25, 536799.25, 188130.75, 536799.25, 188064.75, 536799.25, 188106.75, - 536799.25, 187922.25, 536799.25, 187994.75, 536799.25, 188008.75, 536799.25, 187951.75, - 536799.25, 188073.75, 536799.25, 187978.25, 536799.25, 187958.25, 536799.25, 188000.25, - 536799.25, 188044.75, 536799.25, 187923.25, 536799.25, 187953.25, 536799.25, 188023.25, - 536799.25, 188053.25, 536799.25, 187999.75, 536799.25, 188027.25, 536799.25, 188019.25, - 536799.25, 188002.75, 536799.25, 187999.25, 536799.25, 188045.25, 536799.25, 188130.25, - 536799.25, 188067.75, 536799.25, 188005.25, 536799.25, 187942.25, 536799.25, 188039.25, - 536799.25, 187949.25, 536799.25, 188007.75, 536799.25, 188064.25, 536799.25, 188129.75, - 536799.25, 188042.25, 536799.25, 187925.75, 536799.25, 187995.75, 536799.25, 187964.25, - 536799.25, 188041.75, 536799.25, 187952.25, 536799.25, 187943.75, 536799.25, 187950.75, - 536799.25, 188082.25, 536799.25, 187984.75, 536799.25, 187962.75, 536799.25, 188121.75, - 536799.25, 187967.75, 536799.25, 187932.25, 536799.25, 187957.75, 536799.25, 188081.75, - 536799.25, 187993.75, 536799.25, 187997.75, 536799.25, 188038.75, 536799.25, 188053.75, - 536799.25, 188003.75, 536799.25, 187947.25, 536799.25, 187968.75, 536799.25, 187915.25, - 536799.25, 188069.25, 536799.25, 187935.25, 536799.25, 188154.75, 536799.25, 188121.25, - 536799.25, 187979.75, 536799.25, 188127.25, 536799.25, 187985.75, 536799.25, 187923.75, - 536799.25, 188074.75, 536799.25, 188002.25, 536799.25, 188006.25, 536799.25, 188040.75, - 536799.25, 188034.75, 536799.25, 188036.75, 536799.25, 187965.25, 536799.25, 188110.25, - 536799.25, 188132.25, 536799.25, 188127.75, 536799.25, 188057.25, 536799.25, 188056.25, - 536799.25, 187986.25, 536799.25, 187926.75, 536799.25, 188151.25, 536799.25, 187956.75, - 536799.25, 187921.25, 536799.25, 187939.75, 536799.75, 187985.25, 536799.75, 187950.75, - 536799.75, 188160.25, 536799.75, 188130.75, 536799.75, 188000.75, 536799.75, 187956.75, - 536799.75, 188037.25, 536799.75, 187921.25, 536799.75, 188007.25, 536799.75, 188025.25, - 536799.75, 188139.75, 536799.75, 188019.75, 536799.75, 188008.75, 536799.75, 188060.75, - 536799.75, 187994.75, 536799.75, 188086.75, 536799.75, 188073.75, 536799.75, 188062.75, - 536799.75, 188046.75, 536799.75, 187958.25, 536799.75, 187926.25, 536799.75, 187935.75, - 536799.75, 188000.25, 536799.75, 187923.25, 536799.75, 188057.25, 536799.75, 187939.75, - 536799.75, 188120.25, 536799.75, 188080.75, 536799.75, 187944.25, 536799.75, 187910.75, - 536799.75, 188055.25, 536799.75, 188132.25, 536799.75, 187945.75, 536799.75, 188067.25, - 536799.75, 188110.25, 536799.75, 188053.25, 536799.75, 187965.25, 536799.75, 187999.75, - 536799.75, 188046.25, 536799.75, 188009.75, 536799.75, 188145.75, 536799.75, 188003.25, - 536799.75, 187920.25, 536799.75, 187964.75, 536799.75, 188002.75, 536799.75, 188002.25, - 536799.75, 188063.25, 536799.75, 188045.25, 536799.75, 187999.25, 536799.75, 188007.75, - 536799.75, 187988.75, 536799.75, 187946.25, 536799.75, 188130.25, 536799.75, 188118.25, - 536799.75, 188005.25, 536799.75, 187942.25, 536799.75, 188039.25, 536799.75, 188129.75, - 536799.75, 188042.25, 536799.75, 187968.25, 536799.75, 187995.75, 536799.75, 188081.25, - 536799.75, 187979.75, 536799.75, 187962.25, 536799.75, 187970.25, 536799.75, 188107.75, - 536799.75, 188121.25, 536799.75, 187935.25, 536799.75, 187960.75, 536799.75, 187932.75, - 536799.75, 188037.75, 536799.75, 188053.75, 536799.75, 188119.25, 536799.75, 187912.75, - 536799.75, 187998.75, 536799.75, 188131.25, 536799.75, 187952.25, 536799.75, 188041.75, - 536799.75, 188055.75, 536799.75, 188001.25, 536799.75, 187984.25, 536799.75, 188087.25, - 536799.75, 187948.75, 536799.75, 188021.25, 536799.75, 187913.25, 536799.75, 188075.25, - 536799.75, 188074.75, 536799.75, 188068.75, 536799.75, 188012.75, 536799.75, 188121.75, - 536799.75, 187956.25, 536799.75, 188065.25, 536799.75, 188152.25, 536799.75, 187932.25, - 536800.25, 187965.75, 536800.25, 187934.25, 536800.25, 188111.75, 536800.25, 188155.25, - 536800.25, 187943.25, 536800.25, 187921.75, 536800.25, 187927.25, 536800.25, 188130.75, - 536800.25, 187959.25, 536800.25, 187956.25, 536800.25, 188082.25, 536800.25, 188075.25, - 536800.25, 188037.25, 536800.25, 187922.25, 536800.25, 188008.75, 536800.25, 188129.25, - 536800.25, 188085.25, 536800.25, 188082.75, 536800.25, 187932.75, 536800.25, 188108.25, - 536800.25, 187969.25, 536800.25, 187951.25, 536800.25, 188074.25, 536800.25, 187954.75, - 536800.25, 187978.25, 536800.25, 187995.25, 536800.25, 187986.25, 536800.25, 188139.75, - 536800.25, 188089.75, 536800.25, 188044.75, 536800.25, 187976.25, 536800.25, 188038.75, - 536800.25, 187920.75, 536800.25, 188087.25, 536800.25, 188085.75, 536800.25, 187937.25, - 536800.25, 188006.25, 536800.25, 188128.75, 536800.25, 188140.75, 536800.25, 188039.75, - 536800.25, 187961.25, 536800.25, 188037.75, 536800.25, 188056.25, 536800.25, 188017.25, - 536800.25, 187957.25, 536800.25, 187953.25, 536800.25, 187960.75, 536800.25, 188038.25, - 536800.25, 188154.75, 536800.25, 187996.25, 536800.25, 188055.25, 536800.25, 188046.25, - 536800.25, 188005.75, 536800.25, 187944.25, 536800.25, 187930.75, 536800.25, 187944.75, - 536800.25, 187965.25, 536800.25, 187978.75, 536800.25, 187949.25, 536800.25, 188054.25, - 536800.25, 188019.25, 536800.25, 187920.25, 536800.25, 187997.25, 536800.25, 187931.75, - 536800.25, 188061.75, 536800.25, 188008.25, 536800.25, 188106.25, 536800.25, 188047.25, - 536800.25, 188016.25, 536800.75, 187955.75, 536800.75, 188047.75, 536800.75, 188063.75, - 536800.75, 188033.25, 536800.75, 188071.75, 536800.75, 188111.75, 536800.75, 188066.25, - 536800.75, 188045.25, 536800.75, 188073.25, 536800.75, 187970.75, 536800.75, 187930.25, - 536800.75, 188065.75, 536800.75, 188083.75, 536800.75, 187923.75, 536800.75, 188003.25, - 536800.75, 187940.75, 536800.75, 187918.75, 536800.75, 188040.75, 536800.75, 188064.25, - 536800.75, 187985.75, 536800.75, 188054.75, 536800.75, 188006.75, 536800.75, 187950.25, - 536800.75, 188127.25, 536800.75, 188083.25, 536800.75, 188140.25, 536800.75, 188127.75, - 536800.75, 188154.75, 536800.75, 188088.25, 536800.75, 188035.75, 536800.75, 188121.25, - 536800.75, 188104.25, 536800.75, 188037.75, 536800.75, 188075.75, 536800.75, 188053.75, - 536800.75, 188043.75, 536800.75, 187955.25, 536800.75, 188087.25, 536800.75, 188003.75, - 536800.75, 188141.25, 536800.75, 188096.25, 536800.75, 187919.25, 536800.75, 187966.75, - 536800.75, 187943.75, 536800.75, 187921.25, 536800.75, 188128.75, 536800.75, 187996.75, - 536800.75, 188001.75, 536800.75, 187971.25, 536800.75, 187928.25, 536800.75, 187997.75, - 536800.75, 188128.25, 536800.75, 188154.25, 536800.75, 188129.25, 536800.75, 187954.75, - 536800.75, 187958.75, 536800.75, 188040.25, 536800.75, 187951.75, 536800.75, 188004.25, - 536800.75, 187954.25, 536800.75, 187919.75, 536800.75, 188082.75, 536800.75, 188081.75, - 536800.75, 187922.25, 536800.75, 188074.75, 536800.75, 187986.75, 536800.75, 188036.75, - 536800.75, 188105.25, 536800.75, 188037.25, 536800.75, 188125.75, 536800.75, 187992.25, - 536800.75, 188094.75, 536800.75, 187931.25, 536800.75, 187956.75, 536800.75, 187965.75, - 536800.75, 187933.25, 536800.75, 187952.75, 536800.75, 187959.75, 536800.75, 188008.25, - 536801.25, 187933.25, 536801.25, 188082.25, 536801.25, 188040.25, 536801.25, 187943.75, - 536801.25, 187970.75, 536801.25, 188111.25, 536801.25, 188066.25, 536801.25, 188132.75, - 536801.25, 188064.75, 536801.25, 188056.75, 536801.25, 187932.25, 536801.25, 188074.75, - 536801.25, 187952.75, 536801.25, 188141.25, 536801.25, 188006.75, 536801.25, 188001.75, - 536801.25, 188045.75, 536801.25, 188081.75, 536801.25, 187950.75, 536801.25, 187955.75, - 536801.25, 187918.75, 536801.25, 188145.25, 536801.25, 188087.75, 536801.25, 188106.75, - 536801.25, 187940.75, 536801.25, 188106.25, 536801.25, 188149.25, 536801.25, 187997.75, - 536801.25, 187995.75, 536801.25, 188003.25, 536801.25, 188047.25, 536801.25, 187998.75, - 536801.25, 188146.25, 536801.25, 187929.75, 536801.25, 188124.25, 536801.25, 188073.25, - 536801.25, 187919.75, 536801.25, 188035.75, 536801.25, 187947.75, 536801.25, 188005.25, - 536801.25, 188128.75, 536801.25, 188037.25, 536801.25, 187971.75, 536801.25, 188040.75, - 536801.25, 187965.25, 536801.25, 188139.25, 536801.25, 188044.25, 536801.25, 188007.75, - 536801.25, 187966.75, 536801.25, 187985.75, 536801.25, 188154.25, 536801.25, 188009.25, - 536801.25, 188063.75, 536801.25, 187920.75, 536801.25, 187919.25, 536801.25, 187942.75, - 536801.25, 187955.25, 536801.25, 187947.25, 536801.25, 187959.75, 536801.25, 188083.25, - 536801.25, 188036.25, 536801.25, 187958.75, 536801.25, 188156.25, 536801.25, 187966.25, - 536801.25, 188127.25, 536801.25, 187981.25, 536801.25, 187986.75, 536801.25, 187957.25, - 536801.25, 187995.25, 536801.25, 187954.75, 536801.25, 187952.25, 536801.25, 188073.75, - 536801.25, 188140.75, 536801.25, 187969.75, 536801.25, 187951.75, 536801.25, 187968.25, - 536801.25, 188036.75, 536801.75, 188083.25, 536801.75, 188034.75, 536801.75, 187931.25, - 536801.75, 187967.75, 536801.75, 187950.25, 536801.75, 188072.25, 536801.75, 188092.25, - 536801.75, 188004.25, 536801.75, 187955.75, 536801.75, 188082.25, 536801.75, 187965.75, - 536801.75, 187951.75, 536801.75, 187944.25, 536801.75, 187996.75, 536801.75, 188088.75, - 536801.75, 188140.75, 536801.75, 187959.25, 536801.75, 187917.25, 536801.75, 188141.25, - 536801.75, 188021.25, 536801.75, 188075.25, 536801.75, 188020.75, 536801.75, 187986.25, - 536801.75, 187947.25, 536801.75, 188128.25, 536801.75, 188086.25, 536801.75, 187921.75, - 536801.75, 187953.25, 536801.75, 187997.25, 536801.75, 188035.25, 536801.75, 187923.25, - 536801.75, 188012.75, 536801.75, 188126.25, 536801.75, 188043.25, 536801.75, 188155.25, - 536801.75, 187953.75, 536801.75, 188126.75, 536801.75, 188041.25, 536801.75, 187965.25, - 536801.75, 187958.75, 536801.75, 188075.75, 536801.75, 187917.75, 536801.75, 187971.25, - 536801.75, 188071.75, 536801.75, 188087.25, 536801.75, 187924.25, 536801.75, 188103.75, - 536801.75, 188001.25, 536801.75, 188033.75, 536801.75, 188125.75, 536801.75, 187923.75, - 536801.75, 187919.25, 536801.75, 187956.75, 536801.75, 188085.25, 536801.75, 187973.75, - 536801.75, 188036.25, 536801.75, 187986.75, 536801.75, 188066.25, 536802.25, 187927.75, - 536802.25, 187956.25, 536802.25, 187959.75, 536802.25, 187962.25, 536802.25, 187964.75, - 536802.25, 187982.75, 536802.25, 188065.75, 536802.25, 188059.25, 536802.25, 188125.75, - 536802.25, 188044.75, 536802.25, 188155.25, 536802.25, 188076.25, 536802.25, 188034.25, - 536802.25, 188041.25, 536802.25, 188062.75, 536802.25, 188020.25, 536802.25, 188005.75, - 536802.25, 188046.75, 536802.25, 188142.25, 536802.25, 188085.25, 536802.25, 187987.25, - 536802.25, 188002.25, 536802.25, 188003.75, 536802.25, 188151.25, 536802.25, 188041.75, - 536802.25, 188026.75, 536802.25, 187963.75, 536802.25, 187941.25, 536802.25, 187967.25, - 536802.25, 188040.25, 536802.25, 187917.75, 536802.25, 188069.25, 536802.25, 187987.75, - 536802.25, 188042.25, 536802.25, 187910.75, 536802.25, 188087.25, 536802.25, 187923.25, - 536802.25, 187986.25, 536802.25, 187952.75, 536802.25, 187972.25, 536802.25, 188030.75, - 536802.25, 187948.75, 536802.25, 187946.75, 536802.25, 188088.25, 536802.25, 187969.75, - 536802.25, 187997.25, 536802.25, 187947.75, 536802.25, 188068.25, 536802.25, 187943.75, - 536802.25, 187957.75, 536802.25, 188048.75, 536802.25, 188126.75, 536802.25, 188018.75, - 536802.25, 188083.75, 536802.25, 188101.75, 536802.25, 188033.25, 536802.25, 187921.75, - 536802.25, 187917.25, 536802.25, 187916.75, 536802.25, 187965.25, 536802.25, 187960.25, - 536802.25, 187922.25, 536802.25, 187951.75, 536802.25, 188046.25, 536802.25, 187996.25, - 536802.25, 188123.25, 536802.25, 188032.75, 536802.25, 188085.75, 536802.25, 187954.25, - 536802.25, 188072.75, 536802.25, 187929.75, 536802.25, 188155.75, 536802.25, 188116.75, - 536802.25, 188061.25, 536802.25, 188034.75, 536802.25, 187965.75, 536802.25, 187928.75, - 536802.25, 188160.25, 536802.25, 187941.75, 536802.25, 187984.25, 536802.25, 188017.25, - 536802.25, 188102.75, 536802.25, 187945.75, 536802.25, 188075.25, 536802.25, 188124.75, - 536802.25, 188156.25, 536802.25, 188082.75, 536802.25, 187923.75, 536802.75, 187941.75, - 536802.75, 188063.25, 536802.75, 187954.25, 536802.75, 188103.25, 536802.75, 188047.75, - 536802.75, 188072.75, 536802.75, 188058.25, 536802.75, 188082.75, 536802.75, 187929.75, - 536802.75, 187921.75, 536802.75, 187996.25, 536802.75, 188045.75, 536802.75, 187914.25, - 536802.75, 188124.25, 536802.75, 188141.25, 536802.75, 188033.25, 536802.75, 187928.75, - 536802.75, 187959.25, 536802.75, 187966.25, 536802.75, 187997.25, 536802.75, 188001.75, - 536802.75, 188126.75, 536802.75, 188006.25, 536802.75, 188083.75, 536802.75, 188088.75, - 536802.75, 188032.75, 536802.75, 187969.75, 536802.75, 188036.75, 536802.75, 187948.75, - 536802.75, 188058.75, 536802.75, 188005.25, 536802.75, 188035.25, 536802.75, 187962.75, - 536802.75, 188154.25, 536802.75, 188156.25, 536802.75, 187915.75, 536802.75, 188126.25, - 536802.75, 188041.75, 536802.75, 187986.25, 536802.75, 188075.25, 536802.75, 188003.75, - 536802.75, 187947.25, 536802.75, 187964.25, 536802.75, 188086.25, 536802.75, 187962.25, - 536802.75, 188015.25, 536802.75, 187945.25, 536802.75, 188064.75, 536802.75, 188151.25, - 536802.75, 187987.25, 536802.75, 188001.25, 536802.75, 188125.75, 536802.75, 188033.75, - 536802.75, 187967.75, 536802.75, 187920.25, 536802.75, 187959.75, 536802.75, 188087.25, - 536802.75, 188034.25, 536802.75, 188062.75, 536802.75, 188122.75, 536802.75, 187955.25, - 536802.75, 188125.25, 536802.75, 188071.75, 536802.75, 188114.75, 536802.75, 188111.75, - 536802.75, 188076.75, 536802.75, 187946.75, 536802.75, 187958.25, 536802.75, 188041.25, - 536802.75, 188054.75, 536802.75, 188142.25, 536802.75, 188085.25, 536802.75, 188146.75, - 536802.75, 188088.25, 536802.75, 187916.75, 536802.75, 187970.75, 536802.75, 187972.25, - 536802.75, 187917.25, 536802.75, 188018.75, 536802.75, 188042.75, 536802.75, 187965.25, - 536802.75, 187960.75, 536802.75, 188124.75, 536802.75, 187922.25, 536802.75, 187934.75, - 536803.25, 188084.25, 536803.25, 188101.75, 536803.25, 188093.25, 536803.25, 187955.75, - 536803.25, 188032.75, 536803.25, 187954.25, 536803.25, 187959.25, 536803.25, 187927.75, - 536803.25, 188003.25, 536803.25, 187960.25, 536803.25, 187914.25, 536803.25, 187984.75, - 536803.25, 187917.75, 536803.25, 187967.75, 536803.25, 188043.25, 536803.25, 187945.25, - 536803.25, 188059.75, 536803.25, 188001.25, 536803.25, 187953.75, 536803.25, 188122.75, - 536803.25, 187946.25, 536803.25, 188086.25, 536803.25, 187986.75, 536803.25, 187962.25, - 536803.25, 187924.25, 536803.25, 188046.75, 536803.25, 188083.25, 536803.25, 187925.25, - 536803.25, 187929.25, 536803.25, 188142.75, 536803.25, 187916.25, 536803.25, 188124.75, - 536803.25, 188066.75, 536803.25, 188001.75, 536803.25, 188142.25, 536803.25, 187941.25, - 536803.25, 187923.25, 536803.25, 188057.75, 536803.25, 187941.75, 536803.25, 187963.25, - 536803.25, 187944.25, 536803.25, 188048.75, 536803.25, 188121.25, 536803.25, 188020.25, - 536803.25, 188159.25, 536803.25, 188155.75, 536803.25, 188032.25, 536803.25, 187924.75, - 536803.25, 187950.25, 536803.25, 187948.25, 536803.25, 187996.75, 536803.25, 187964.25, - 536803.25, 187963.75, 536803.25, 187983.75, 536803.25, 187956.75, 536803.25, 187915.25, - 536803.25, 187950.75, 536803.25, 188044.75, 536803.25, 188087.75, 536803.25, 187997.75, - 536803.25, 187981.75, 536803.25, 187988.25, 536803.25, 187920.75, 536803.25, 188091.25, - 536803.25, 188072.25, 536803.25, 188124.25, 536803.25, 188031.25, 536803.25, 188033.25, - 536803.25, 188134.75, 536803.25, 188089.75, 536803.25, 188075.75, 536803.25, 187961.25, - 536803.25, 188050.75, 536803.25, 187919.75, 536803.25, 187942.25, 536803.25, 188004.25, - 536803.25, 188042.25, 536803.25, 188046.25, 536803.25, 188071.25, 536803.25, 188089.25, - 536803.25, 188076.75, 536803.25, 187968.25, 536803.25, 188084.75, 536803.25, 187953.25, - 536803.25, 187971.75, 536803.25, 188058.75, 536803.75, 187925.75, 536803.75, 188041.75, - 536803.75, 188156.75, 536803.75, 188046.25, 536803.75, 188044.25, 536803.75, 188157.25, - 536803.75, 188042.25, 536803.75, 188083.75, 536803.75, 188077.25, 536803.75, 188157.75, - 536803.75, 188122.25, 536803.75, 188024.25, 536803.75, 187988.25, 536803.75, 187997.25, - 536803.75, 188031.25, 536803.75, 188123.25, 536803.75, 188047.25, 536803.75, 188073.25, - 536803.75, 187949.25, 536803.75, 187996.75, 536803.75, 187913.75, 536803.75, 187956.75, - 536803.75, 187947.75, 536803.75, 187946.75, 536803.75, 187926.75, 536803.75, 188110.25, - 536803.75, 188071.75, 536803.75, 187945.75, 536803.75, 188141.75, 536803.75, 188059.25, - 536803.75, 187918.75, 536803.75, 187987.75, 536803.75, 187972.75, 536803.75, 188069.75, - 536803.75, 187970.25, 536803.75, 187963.25, 536803.75, 187924.75, 536803.75, 188121.25, - 536803.75, 188073.75, 536803.75, 188042.75, 536803.75, 187990.75, 536803.75, 187941.25, - 536803.75, 188140.75, 536803.75, 188088.75, 536803.75, 188084.25, 536803.75, 188142.75, - 536803.75, 187941.75, 536803.75, 187998.25, 536803.75, 187922.25, 536803.75, 188123.75, - 536803.75, 187979.75, 536803.75, 187944.25, 536803.75, 187986.25, 536803.75, 187995.25, - 536803.75, 187944.75, 536803.75, 188029.75, 536803.75, 187952.25, 536803.75, 187917.75, - 536803.75, 187917.25, 536803.75, 187954.75, 536803.75, 188056.75, 536803.75, 188100.25, - 536803.75, 188031.75, 536803.75, 187927.75, 536803.75, 187920.25, 536803.75, 188095.75, - 536803.75, 187914.75, 536803.75, 188086.75, 536803.75, 187999.25, 536803.75, 188098.75, - 536803.75, 188043.25, 536803.75, 187945.25, 536803.75, 188060.75, 536803.75, 188057.25, - 536803.75, 187914.25, 536803.75, 188076.25, 536803.75, 187956.25, 536803.75, 187912.75, - 536803.75, 188151.75, 536803.75, 188085.75, 536803.75, 187921.75, 536803.75, 188000.75, - 536803.75, 188030.75, 536803.75, 188109.25, 536803.75, 187982.75, 536803.75, 188070.75, - 536803.75, 188121.75, 536803.75, 188082.25, 536803.75, 187955.75, 536803.75, 188076.75, - 536803.75, 188002.75, 536804.25, 188076.75, 536804.25, 187955.75, 536804.25, 188109.25, - 536804.25, 188003.25, 536804.25, 188000.75, 536804.25, 188135.75, 536804.25, 187916.75, - 536804.25, 187960.25, 536804.25, 187914.25, 536804.25, 188028.25, 536804.25, 187945.25, - 536804.25, 188147.25, 536804.25, 188007.25, 536804.25, 187912.75, 536804.25, 187985.75, - 536804.25, 188122.75, 536804.25, 188046.75, 536804.25, 187914.75, 536804.25, 188030.25, - 536804.25, 188142.75, 536804.25, 188088.75, 536804.25, 187951.75, 536804.25, 187913.75, - 536804.25, 188073.75, 536804.25, 188069.25, 536804.25, 187986.75, 536804.25, 187921.75, - 536804.25, 188071.75, 536804.25, 187942.75, 536804.25, 187919.25, 536804.25, 188033.75, - 536804.25, 188075.75, 536804.25, 187961.25, 536804.25, 188085.75, 536804.25, 188156.75, - 536804.25, 188084.75, 536804.25, 187970.25, 536804.25, 187988.25, 536804.25, 188123.25, - 536804.25, 187997.25, 536804.25, 188044.25, 536804.25, 188088.25, 536804.25, 187948.25, - 536804.25, 188081.75, 536804.25, 187926.75, 536804.25, 188069.75, 536804.25, 188031.25, - 536804.25, 187999.75, 536804.25, 188086.75, 536804.25, 187924.75, 536804.25, 188029.25, - 536804.25, 187918.25, 536804.25, 188123.75, 536804.25, 187967.25, 536804.25, 187987.25, - 536804.25, 188083.75, 536804.25, 187953.75, 536804.25, 188076.25, 536804.25, 187949.25, - 536804.25, 188042.25, 536804.25, 188037.25, 536804.25, 187943.75, 536804.25, 188001.75, - 536804.25, 187984.75, 536804.25, 187986.25, 536804.25, 187956.75, 536804.25, 188066.25, - 536804.25, 187946.25, 536804.25, 187917.75, 536804.25, 188121.25, 536804.25, 187996.75, - 536804.25, 187998.25, 536804.25, 187917.25, 536804.25, 188057.75, 536804.25, 187979.25, - 536804.25, 188141.75, 536804.25, 188100.75, 536804.25, 188110.75, 536804.75, 187955.75, - 536804.75, 187987.25, 536804.75, 187942.75, 536804.75, 188099.25, 536804.75, 187946.75, - 536804.75, 188000.25, 536804.75, 188136.75, 536804.75, 187910.75, 536804.75, 188082.75, - 536804.75, 187971.25, 536804.75, 188020.75, 536804.75, 188063.25, 536804.75, 188109.75, - 536804.75, 188058.75, 536804.75, 188028.25, 536804.75, 187928.25, 536804.75, 188032.25, - 536804.75, 188021.25, 536804.75, 187985.25, 536804.75, 188060.25, 536804.75, 188055.25, - 536804.75, 187988.25, 536804.75, 187997.75, 536804.75, 187965.25, 536804.75, 188074.75, - 536804.75, 188077.25, 536804.75, 188002.25, 536804.75, 187968.75, 536804.75, 188043.75, - 536804.75, 188029.25, 536804.75, 187917.75, 536804.75, 187945.75, 536804.75, 188088.25, - 536804.75, 187917.25, 536804.75, 187913.25, 536804.75, 187912.25, 536804.75, 187946.25, - 536804.75, 187996.75, 536804.75, 188069.25, 536804.75, 188081.75, 536804.75, 188045.75, - 536804.75, 188037.75, 536804.75, 187925.75, 536804.75, 187984.75, 536804.75, 188090.25, - 536804.75, 188031.25, 536804.75, 187952.25, 536804.75, 187986.75, 536804.75, 188070.75, - 536804.75, 188121.25, 536804.75, 187913.75, 536804.75, 188097.25, 536804.75, 188022.75, - 536804.75, 188070.25, 536804.75, 187951.75, 536804.75, 188068.75, 536804.75, 187954.75, - 536804.75, 188088.75, 536804.75, 187965.75, 536804.75, 187972.25, 536804.75, 187924.75, - 536804.75, 187935.25, 536804.75, 187943.25, 536804.75, 187943.75, 536804.75, 188056.75, - 536804.75, 187944.25, 536804.75, 188160.25, 536804.75, 187998.75, 536804.75, 188121.75, - 536804.75, 188042.25, 536804.75, 187951.25, 536804.75, 188080.75, 536804.75, 188086.75, - 536804.75, 188076.25, 536804.75, 187953.75, 536804.75, 187981.25, 536805.25, 187925.25, - 536805.25, 188059.75, 536805.25, 187944.75, 536805.25, 187951.25, 536805.25, 188030.25, - 536805.25, 187971.75, 536805.25, 188031.75, 536805.25, 188076.25, 536805.25, 187922.25, - 536805.25, 187952.75, 536805.25, 188066.75, 536805.25, 187922.75, 536805.25, 188057.25, - 536805.25, 188056.75, 536805.25, 187998.75, 536805.25, 187944.25, 536805.25, 188086.25, - 536805.25, 187988.75, 536805.25, 188148.75, 536805.25, 187924.25, 536805.25, 188042.75, - 536805.25, 188032.75, 536805.25, 188046.75, 536805.25, 187983.75, 536805.25, 187969.25, - 536805.25, 188045.25, 536805.25, 188121.25, 536805.25, 187913.25, 536805.25, 188026.75, - 536805.25, 188061.25, 536805.25, 187969.75, 536805.25, 187973.75, 536805.25, 187999.25, - 536805.25, 188066.25, 536805.25, 188107.25, 536805.25, 187911.75, 536805.25, 187945.75, - 536805.25, 188144.25, 536805.25, 187982.25, 536805.25, 188043.75, 536805.25, 187950.25, - 536805.25, 188087.75, 536805.25, 188067.25, 536805.25, 188069.25, 536805.25, 188028.75, - 536805.25, 188073.75, 536805.25, 187987.75, 536805.25, 188138.75, 536805.25, 187931.25, - 536805.25, 187983.25, 536805.25, 187997.75, 536805.25, 187972.75, 536805.25, 188098.25, - 536805.25, 188157.75, 536805.25, 187965.25, 536805.25, 188021.75, 536805.25, 188027.75, - 536805.25, 188060.25, 536805.25, 188021.25, 536805.25, 188089.25, 536805.25, 188043.25, - 536805.25, 188157.25, 536805.25, 187947.25, 536805.25, 187954.25, 536805.25, 188067.75, - 536805.25, 188022.25, 536805.25, 187911.25, 536805.25, 188122.25, 536805.25, 188077.75, - 536805.25, 187953.25, 536805.25, 188109.25, 536805.25, 188025.75, 536805.25, 187928.25, - 536805.25, 188065.75, 536805.25, 188125.25, 536805.25, 187964.25, 536805.25, 188019.75, - 536805.25, 187942.25, 536805.25, 188068.25, 536805.25, 188087.25, 536805.25, 188102.75, - 536805.25, 187955.25, 536805.25, 188089.75, 536805.25, 188000.25, 536805.75, 188019.25, - 536805.75, 187981.75, 536805.75, 188074.25, 536805.75, 187923.75, 536805.75, 187922.25, - 536805.75, 187960.75, 536805.75, 187953.25, 536805.75, 188025.75, 536805.75, 187911.25, - 536805.75, 188065.75, 536805.75, 188058.75, 536805.75, 187947.25, 536805.75, 187987.75, - 536805.75, 188020.25, 536805.75, 187965.25, 536805.75, 188025.25, 536805.75, 188078.25, - 536805.75, 187972.75, 536805.75, 188089.75, 536805.75, 188149.25, 536805.75, 188069.25, - 536805.75, 188067.25, 536805.75, 187942.75, 536805.75, 188062.25, 536805.75, 188027.75, - 536805.75, 187986.75, 536805.75, 188028.75, 536805.75, 187923.25, 536805.75, 187983.75, - 536805.75, 188107.75, 536805.75, 187988.75, 536805.75, 188139.75, 536805.75, 187999.25, - 536805.75, 187998.75, 536805.75, 187924.75, 536805.75, 188142.75, 536805.75, 188021.75, - 536805.75, 188056.75, 536805.75, 188103.75, 536805.75, 188080.25, 536805.75, 187952.75, - 536805.75, 188031.75, 536805.75, 188022.25, 536805.75, 187968.25, 536805.75, 188081.25, - 536805.75, 187940.25, 536805.75, 188121.75, 536805.75, 187987.25, 536805.75, 188086.25, - 536805.75, 187951.25, 536805.75, 187965.75, 536805.75, 188042.75, 536805.75, 187953.75, - 536805.75, 188121.25, 536805.75, 188087.25, 536805.75, 187912.25, 536805.75, 187948.75, - 536805.75, 188043.75, 536805.75, 187971.75, 536805.75, 187945.25, 536805.75, 187911.75, - 536805.75, 187946.25, 536805.75, 188026.75, 536805.75, 187917.75, 536805.75, 187968.75, - 536805.75, 188144.25, 536805.75, 187983.25, 536805.75, 187998.25, 536805.75, 188122.25, - 536805.75, 188060.25, 536805.75, 188067.75, 536805.75, 188106.75, 536805.75, 188057.25, - 536805.75, 188157.25, 536805.75, 187922.75, 536805.75, 188077.75, 536805.75, 188124.25, - 536805.75, 188068.25, 536806.25, 187968.25, 536806.25, 187946.75, 536806.25, 188067.75, - 536806.25, 188058.25, 536806.25, 187949.25, 536806.25, 188027.75, 536806.25, 188076.25, - 536806.25, 188053.75, 536806.25, 188029.75, 536806.25, 188145.75, 536806.25, 187982.75, - 536806.25, 188028.25, 536806.25, 187973.75, 536806.25, 188025.25, 536806.25, 188130.75, - 536806.25, 188098.25, 536806.25, 188139.75, 536806.25, 188067.25, 536806.25, 188078.25, - 536806.25, 188019.75, 536806.25, 187955.25, 536806.25, 188087.75, 536806.25, 187912.75, - 536806.25, 188036.75, 536806.25, 188033.25, 536806.25, 187969.25, 536806.25, 188123.25, - 536806.25, 188157.75, 536806.25, 188017.75, 536806.25, 188158.25, 536806.25, 188021.75, - 536806.25, 187988.25, 536806.25, 187949.75, 536806.25, 188032.75, 536806.25, 187950.25, - 536806.25, 187923.75, 536806.25, 188136.25, 536806.25, 187998.75, 536806.25, 188018.75, - 536806.25, 188089.25, 536806.25, 188065.75, 536806.25, 188025.75, 536806.25, 187970.25, - 536806.25, 187916.75, 536806.25, 188095.25, 536806.25, 187939.75, 536806.25, 187996.75, - 536806.25, 187981.75, 536806.25, 187997.75, 536806.25, 187930.25, 536806.25, 188096.25, - 536806.25, 187987.75, 536806.25, 188059.25, 536806.25, 187923.25, 536806.25, 188086.75, - 536806.25, 188044.25, 536806.25, 188030.25, 536806.25, 188077.25, 536806.25, 187954.75, - 536806.25, 188122.75, 536806.25, 187945.75, 536806.75, 188023.75, 536806.75, 188123.25, - 536806.75, 188003.75, 536806.75, 188091.25, 536806.75, 188066.25, 536806.75, 188020.75, - 536806.75, 187970.75, 536806.75, 188105.25, 536806.75, 188052.25, 536806.75, 187996.25, - 536806.75, 188030.75, 536806.75, 187974.75, 536806.75, 188015.75, 536806.75, 187969.75, - 536806.75, 188058.25, 536806.75, 188076.25, 536806.75, 187954.25, 536806.75, 188043.25, - 536806.75, 188075.25, 536806.75, 188056.75, 536806.75, 188065.25, 536806.75, 188086.75, - 536806.75, 187955.75, 536806.75, 187945.25, 536806.75, 187918.25, 536806.75, 187946.75, - 536806.75, 187973.75, 536806.75, 187944.75, 536806.75, 187943.75, 536806.75, 188054.25, - 536806.75, 187980.75, 536806.75, 187982.25, 536806.75, 188028.25, 536806.75, 188046.75, - 536806.75, 188044.75, 536806.75, 188122.25, 536806.75, 188024.75, 536806.75, 188158.75, - 536806.75, 188059.25, 536806.75, 188029.25, 536806.75, 188073.25, 536806.75, 187948.25, - 536806.75, 188088.75, 536806.75, 187989.25, 536806.75, 188060.75, 536806.75, 188043.75, - 536806.75, 187969.25, 536806.75, 188032.25, 536806.75, 188076.75, 536806.75, 188087.75, - 536806.75, 188021.75, 536806.75, 187919.75, 536806.75, 188157.25, 536806.75, 187968.25, - 536806.75, 188024.25, 536806.75, 188018.75, 536806.75, 187998.75, 536806.75, 187997.25, - 536806.75, 187997.75, 536806.75, 188048.25, 536806.75, 188089.25, 536806.75, 187996.75, - 536806.75, 188065.75, 536806.75, 187920.75, 536806.75, 188050.75, 536806.75, 188026.25, - 536806.75, 187953.25, 536806.75, 188033.75, 536806.75, 187968.75, 536806.75, 187970.25, - 536807.25, 188087.25, 536807.25, 188026.75, 536807.25, 188091.75, 536807.25, 188026.25, - 536807.25, 187949.75, 536807.25, 187973.25, 536807.25, 188060.25, 536807.25, 188088.75, - 536807.25, 187997.75, 536807.25, 188081.75, 536807.25, 188066.25, 536807.25, 187970.75, - 536807.25, 187973.75, 536807.25, 187920.75, 536807.25, 188089.25, 536807.25, 188103.25, - 536807.25, 188053.25, 536807.25, 187981.25, 536807.25, 188032.75, 536807.25, 187996.25, - 536807.25, 188032.25, 536807.25, 187972.25, 536807.25, 188148.25, 536807.25, 188129.25, - 536807.25, 187954.25, 536807.25, 187936.75, 536807.25, 188123.25, 536807.25, 188090.25, - 536807.25, 188141.75, 536807.25, 187937.25, 536807.25, 188030.75, 536807.25, 187919.75, - 536807.25, 187969.75, 536807.25, 187953.25, 536807.25, 188076.75, 536807.25, 187997.25, - 536807.25, 188043.25, 536807.25, 187995.25, 536807.25, 188075.25, 536807.25, 188020.25, - 536807.25, 188076.25, 536807.25, 187912.25, 536807.25, 188158.75, 536807.25, 187910.75, - 536807.25, 187969.25, 536807.25, 187940.25, 536807.25, 188089.75, 536807.25, 187974.75, - 536807.25, 188028.25, 536807.25, 188093.25, 536807.25, 188022.75, 536807.25, 187988.75, - 536807.25, 187955.25, 536807.25, 187948.25, 536807.25, 188043.75, 536807.25, 188104.25, - 536807.25, 187967.75, 536807.25, 188019.75, 536807.25, 188061.25, 536807.25, 187951.75, - 536807.25, 187943.75, 536807.25, 188057.75, 536807.25, 187945.25, 536807.25, 188029.25, - 536807.25, 188160.25, 536807.25, 188021.25, 536807.25, 187989.75, 536807.25, 188024.75, - 536807.25, 188122.25, 536807.25, 188065.75, 536807.25, 187998.25, 536807.25, 188107.75, - 536807.25, 188059.25, 536807.25, 187917.75, 536807.75, 187982.25, 536807.75, 188065.75, - 536807.75, 187913.25, 536807.75, 188094.75, 536807.75, 188089.75, 536807.75, 187923.25, - 536807.75, 188078.25, 536807.75, 187947.25, 536807.75, 188043.75, 536807.75, 188158.25, - 536807.75, 187989.25, 536807.75, 188099.25, 536807.75, 188025.75, 536807.75, 188018.75, - 536807.75, 188133.25, 536807.75, 188059.25, 536807.75, 187965.25, 536807.75, 187967.25, - 536807.75, 188029.25, 536807.75, 187912.25, 536807.75, 188076.25, 536807.75, 188033.25, - 536807.75, 188020.25, 536807.75, 188023.75, 536807.75, 188030.25, 536807.75, 188076.75, - 536807.75, 188005.75, 536807.75, 187919.75, 536807.75, 187994.75, 536807.75, 187959.25, - 536807.75, 188040.25, 536807.75, 188038.25, 536807.75, 188087.25, 536807.75, 188006.25, - 536807.75, 188092.75, 536807.75, 188010.75, 536807.75, 187949.25, 536807.75, 188123.25, - 536807.75, 188043.25, 536807.75, 187954.75, 536807.75, 187919.25, 536807.75, 188032.75, - 536807.75, 188064.75, 536807.75, 187981.75, 536807.75, 187911.25, 536807.75, 188024.25, - 536807.75, 188033.75, 536807.75, 187970.75, 536807.75, 188091.25, 536807.75, 187996.75, - 536807.75, 187968.75, 536807.75, 187966.75, 536807.75, 188122.75, 536808.25, 188026.75, - 536808.25, 187968.75, 536808.25, 187945.25, 536808.25, 188007.25, 536808.25, 188158.75, - 536808.25, 187916.25, 536808.25, 187965.25, 536808.25, 187993.25, 536808.25, 187931.25, - 536808.25, 188088.75, 536808.25, 187914.25, 536808.25, 188004.25, 536808.25, 188034.25, - 536808.25, 188159.25, 536808.25, 188044.25, 536808.25, 188045.25, 536808.25, 188122.75, - 536808.25, 187993.75, 536808.25, 187918.75, 536808.25, 187945.75, 536808.25, 187975.25, - 536808.25, 187944.25, 536808.25, 188034.75, 536808.25, 188020.75, 536808.25, 188052.25, - 536808.25, 187995.25, 536808.25, 187965.75, 536808.25, 188027.75, 536808.25, 187954.75, - 536808.25, 188066.25, 536808.25, 187994.75, 536808.25, 188041.25, 536808.25, 188093.25, - 536808.25, 187967.75, 536808.25, 188029.75, 536808.25, 187984.75, 536808.25, 188087.75, - 536808.25, 188058.25, 536808.25, 187989.25, 536808.25, 187971.25, 536808.25, 187956.75, - 536808.25, 188015.25, 536808.25, 187919.75, 536808.25, 188091.75, 536808.25, 188090.75, - 536808.25, 187920.75, 536808.25, 187966.75, 536808.25, 188094.25, 536808.25, 188016.75, - 536808.25, 187982.75, 536808.25, 188124.25, 536808.25, 188014.25, 536808.25, 188065.25, - 536808.25, 188006.25, 536808.25, 187972.75, 536808.25, 188123.75, 536808.25, 187994.25, - 536808.25, 187970.25, 536808.25, 188022.25, 536808.25, 188031.25, 536808.25, 187990.25, - 536808.25, 188005.25, 536808.25, 188109.75, 536808.25, 188047.25, 536808.25, 187944.75, - 536808.25, 188002.75, 536808.25, 188025.25, 536808.25, 187968.25, 536808.25, 187966.25, - 536808.25, 188021.75, 536808.25, 188044.75, 536808.25, 188078.25, 536808.25, 188023.25, - 536808.25, 188088.25, 536808.25, 188051.75, 536808.25, 187914.75, 536808.25, 187992.75, - 536808.25, 187912.75, 536808.25, 187995.75, 536808.25, 187955.25, 536808.75, 188151.25, - 536808.75, 188024.75, 536808.75, 187914.75, 536808.75, 188062.25, 536808.75, 188065.25, - 536808.75, 187945.25, 536808.75, 187968.75, 536808.75, 187946.25, 536808.75, 188039.25, - 536808.75, 188033.25, 536808.75, 188051.75, 536808.75, 188003.75, 536808.75, 188023.25, - 536808.75, 188158.25, 536808.75, 188136.75, 536808.75, 188074.75, 536808.75, 188088.25, - 536808.75, 187982.25, 536808.75, 187921.25, 536808.75, 188092.75, 536808.75, 188123.25, - 536808.75, 188026.25, 536808.75, 188128.75, 536808.75, 187965.25, 536808.75, 188032.75, - 536808.75, 187916.75, 536808.75, 188013.75, 536808.75, 187968.25, 536808.75, 188091.25, - 536808.75, 187926.75, 536808.75, 187914.25, 536808.75, 187973.75, 536808.75, 187992.25, - 536808.75, 188024.25, 536808.75, 187971.75, 536808.75, 187963.75, 536808.75, 187944.75, - 536808.75, 187965.75, 536808.75, 188086.75, 536808.75, 188022.25, 536808.75, 188004.75, - 536808.75, 187944.25, 536808.75, 188031.25, 536808.75, 188044.25, 536808.75, 187990.25, - 536808.75, 188122.75, 536808.75, 187970.25, 536808.75, 187918.75, 536808.75, 188123.75, - 536808.75, 187982.75, 536808.75, 188045.25, 536808.75, 187993.75, 536808.75, 188078.25, - 536808.75, 188016.75, 536808.75, 188159.25, 536808.75, 187967.75, 536808.75, 187974.75, - 536808.75, 187995.25, 536808.75, 187967.25, 536808.75, 188052.25, 536808.75, 188133.75, - 536808.75, 188091.75, 536808.75, 187975.25, 536808.75, 187954.75, 536808.75, 187987.75, - 536808.75, 187966.75, 536808.75, 188075.25, 536808.75, 188094.25, 536808.75, 187994.75, - 536808.75, 188132.75, 536808.75, 187912.25, 536808.75, 187989.25, 536808.75, 188021.25, - 536808.75, 188029.75, 536808.75, 187953.75, 536808.75, 188015.75, 536808.75, 188046.75, - 536809.25, 187986.25, 536809.25, 188093.25, 536809.25, 187912.75, 536809.25, 187987.25, - 536809.25, 187965.25, 536809.25, 188005.75, 536809.25, 188087.75, 536809.25, 188073.75, - 536809.25, 188030.75, 536809.25, 187912.25, 536809.25, 188066.25, 536809.25, 188159.75, - 536809.25, 187987.75, 536809.25, 188025.25, 536809.25, 187971.75, 536809.25, 188026.75, - 536809.25, 188022.75, 536809.25, 188029.75, 536809.25, 188124.25, 536809.25, 188086.25, - 536809.25, 188028.25, 536809.25, 188045.25, 536809.25, 187994.25, 536809.25, 188045.75, - 536809.25, 188025.75, 536809.25, 188122.75, 536809.25, 188007.75, 536809.25, 188006.75, - 536809.25, 188002.75, 536809.25, 188033.75, 536809.25, 188065.75, 536809.25, 188013.75, - 536809.25, 188013.25, 536809.25, 187963.25, 536809.25, 187944.75, 536809.25, 188101.25, - 536809.25, 188088.75, 536809.25, 188044.75, 536809.25, 188032.75, 536809.25, 188092.25, - 536809.25, 187970.75, 536809.25, 187993.25, 536809.25, 188074.75, 536809.25, 188004.25, - 536809.25, 187915.25, 536809.25, 187988.25, 536809.25, 188089.25, 536809.25, 188060.25, - 536809.25, 188020.25, 536809.25, 187991.75, 536809.25, 188073.25, 536809.25, 187950.25, - 536809.25, 188130.75, 536809.25, 188019.75, 536809.25, 188029.25, 536809.25, 187966.25, - 536809.25, 188158.75, 536809.25, 187983.25, 536809.25, 187932.75, 536809.25, 187992.75, - 536809.25, 188091.25, 536809.25, 188019.25, 536809.75, 188087.25, 536809.75, 188092.75, - 536809.75, 188159.25, 536809.75, 187991.25, 536809.75, 188121.75, 536809.75, 188014.75, - 536809.75, 187980.25, 536809.75, 188035.25, 536809.75, 187956.75, 536809.75, 187989.25, - 536809.75, 188125.75, 536809.75, 188045.75, 536809.75, 188026.25, 536809.75, 187964.25, - 536809.75, 188020.25, 536809.75, 187983.25, 536809.75, 187958.75, 536809.75, 187990.75, - 536809.75, 187997.25, 536809.75, 187972.25, 536809.75, 188122.25, 536809.75, 187993.25, - 536809.75, 188071.75, 536809.75, 188140.75, 536809.75, 187963.75, 536809.75, 187985.75, - 536809.75, 188089.75, 536809.75, 188140.25, 536809.75, 188034.75, 536809.75, 187964.75, - 536809.75, 188086.75, 536809.75, 187955.75, 536809.75, 187910.75, 536809.75, 187971.75, - 536809.75, 188015.75, 536809.75, 187916.25, 536809.75, 188029.75, 536809.75, 188025.25, - 536809.75, 187962.25, 536809.75, 187934.75, 536809.75, 188090.25, 536809.75, 188074.25, - 536809.75, 188090.75, 536809.75, 188022.75, 536809.75, 188028.75, 536809.75, 188124.25, - 536809.75, 188160.25, 536809.75, 187954.75, 536809.75, 187990.25, 536809.75, 188084.25, - 536809.75, 188021.75, 536809.75, 188023.75, 536809.75, 187953.25, 536809.75, 188067.25, - 536809.75, 188007.25, 536809.75, 188010.25, 536809.75, 188077.25, 536809.75, 188086.25, - 536809.75, 187974.75, 536809.75, 187992.75, 536809.75, 187989.75, 536809.75, 188119.75, - 536809.75, 188032.75, 536809.75, 187986.75, 536809.75, 187983.75, 536809.75, 187914.25, - 536809.75, 188073.25, 536809.75, 187992.25, 536809.75, 188072.75, 536809.75, 188012.75, - 536809.75, 187911.75, 536809.75, 188044.75, 536809.75, 188034.25, 536809.75, 188003.25, - 536809.75, 188139.75, 536809.75, 188016.75, 536809.75, 187914.75, 536809.75, 188027.75, - 536809.75, 188046.25, 536809.75, 188002.25, 536809.75, 188015.25, 536809.75, 188124.75, - 536809.75, 187973.75, 536809.75, 188019.75, 536809.75, 188079.75, 536809.75, 188030.25, - 536809.75, 187955.25, 536809.75, 188020.75, 536809.75, 187971.25, 536809.75, 188066.75, - 536809.75, 188120.75, 536810.25, 188087.75, 536810.25, 188093.25, 536810.25, 188146.75, - 536810.25, 188019.75, 536810.25, 187955.25, 536810.25, 187947.75, 536810.25, 188159.75, - 536810.25, 188079.75, 536810.25, 187971.25, 536810.25, 188030.25, 536810.25, 188120.75, - 536810.25, 187914.75, 536810.25, 188015.25, 536810.25, 188002.25, 536810.25, 188046.25, - 536810.25, 188124.75, 536810.25, 187987.25, 536810.25, 187981.75, 536810.25, 188147.25, - 536810.25, 188034.25, 536810.25, 187992.25, 536810.25, 188133.25, 536810.25, 187983.75, - 536810.25, 188002.75, 536810.25, 187914.25, 536810.25, 187986.75, 536810.25, 187911.25, - 536810.25, 188083.75, 536810.25, 188044.75, 536810.25, 188119.25, 536810.25, 187989.75, - 536810.25, 188013.25, 536810.25, 187995.75, 536810.25, 188084.75, 536810.25, 188049.75, - 536810.25, 188032.25, 536810.25, 187961.75, 536810.25, 188033.25, 536810.25, 188023.75, - 536810.25, 188006.75, 536810.25, 188079.25, 536810.25, 188028.25, 536810.25, 188021.75, - 536810.25, 188086.25, 536810.25, 188034.75, 536810.25, 188145.25, 536810.25, 188011.25, - 536810.25, 188124.25, 536810.25, 188072.25, 536810.25, 188074.25, 536810.25, 188025.25, - 536810.25, 187971.75, 536810.25, 187955.75, 536810.25, 188029.75, 536810.25, 188090.75, - 536810.25, 187916.25, 536810.25, 188066.25, 536810.25, 188015.75, 536810.25, 187985.75, - 536810.25, 188135.25, 536810.25, 188140.25, 536810.25, 187963.75, 536810.25, 187920.25, - 536810.25, 188090.25, 536810.25, 187965.25, 536810.25, 188092.75, 536810.25, 188071.75, - 536810.25, 188086.75, 536810.25, 188014.75, 536810.25, 188026.75, 536810.25, 188122.25, - 536810.25, 187983.25, 536810.25, 187990.75, 536810.25, 188001.25, 536810.25, 188089.75, - 536810.25, 188004.75, 536810.25, 187988.75, 536810.25, 187956.75, 536810.25, 188065.75, - 536810.25, 188121.75, 536810.75, 187963.25, 536810.75, 187946.25, 536810.75, 188121.25, - 536810.75, 188005.75, 536810.75, 187983.25, 536810.75, 188118.25, 536810.75, 188067.75, - 536810.75, 187945.75, 536810.75, 188030.75, 536810.75, 188020.25, 536810.75, 188014.75, - 536810.75, 188022.75, 536810.75, 188027.25, 536810.75, 188044.75, 536810.75, 187986.25, - 536810.75, 188145.75, 536810.75, 188124.25, 536810.75, 188072.25, 536810.75, 188091.25, - 536810.75, 187990.25, 536810.75, 188022.25, 536810.75, 188084.75, 536810.75, 188010.25, - 536810.75, 188118.75, 536810.75, 188067.25, 536810.75, 188032.25, 536810.75, 187962.25, - 536810.75, 188120.25, 536810.75, 188070.25, 536810.75, 187941.75, 536810.75, 187963.75, - 536810.75, 188083.75, 536810.75, 188012.25, 536810.75, 187985.25, 536810.75, 187961.25, - 536810.75, 188002.75, 536810.75, 188046.25, 536810.75, 187928.25, 536810.75, 188004.25, - 536810.75, 188119.75, 536810.75, 188159.75, 536810.75, 188070.75, 536810.75, 187914.75, - 536810.75, 188147.25, 536810.75, 187956.25, 536810.75, 187962.75, 536810.75, 188098.75, - 536810.75, 188025.75, 536810.75, 187950.75, 536810.75, 188144.75, 536810.75, 187914.25, - 536810.75, 187995.75, 536810.75, 188126.25, 536810.75, 187961.75, 536810.75, 188010.75, - 536810.75, 188089.25, 536810.75, 188079.25, 536810.75, 188071.25, 536810.75, 187913.75, - 536810.75, 187975.75, 536810.75, 188147.75, 536810.75, 187971.75, 536810.75, 188024.75, - 536810.75, 188029.75, 536810.75, 188066.25, 536810.75, 188046.75, 536810.75, 188125.25, - 536810.75, 187976.25, 536810.75, 187925.25, 536810.75, 187947.25, 536810.75, 188085.75, - 536810.75, 187960.75, 536810.75, 188082.25, 536810.75, 188048.25, 536810.75, 188075.25, - 536810.75, 187964.25, 536810.75, 187984.75, 536810.75, 188120.75, 536810.75, 188108.25, - 536810.75, 188006.25, 536810.75, 188071.75, 536810.75, 188035.25, 536811.25, 188073.25, - 536811.25, 188086.75, 536811.25, 188026.25, 536811.25, 188082.75, 536811.25, 187952.25, - 536811.25, 188071.75, 536811.25, 188117.25, 536811.25, 188128.25, 536811.25, 188000.25, - 536811.25, 187964.25, 536811.25, 188084.25, 536811.25, 188034.75, 536811.25, 188123.75, - 536811.25, 188072.25, 536811.25, 187959.25, 536811.25, 188092.25, 536811.25, 188148.25, - 536811.25, 188144.25, 536811.25, 188099.25, 536811.25, 188004.75, 536811.25, 187913.25, - 536811.25, 188009.75, 536811.25, 188028.75, 536811.25, 188023.25, 536811.25, 187953.75, - 536811.25, 188120.25, 536811.25, 187960.75, 536811.25, 188082.25, 536811.25, 188123.25, - 536811.25, 187995.25, 536811.25, 188092.75, 536811.25, 188035.75, 536811.25, 187984.25, - 536811.25, 188025.75, 536811.25, 188021.25, 536811.25, 188027.75, 536811.25, 187961.25, - 536811.25, 188069.75, 536811.25, 188046.75, 536811.25, 187963.75, 536811.25, 187998.75, - 536811.25, 187976.25, 536811.25, 188002.75, 536811.25, 188045.25, 536811.25, 187975.75, - 536811.25, 188067.75, 536811.25, 188024.25, 536811.25, 188013.75, 536811.25, 187935.75, - 536811.25, 188068.25, 536811.25, 187972.25, 536811.25, 187938.75, 536811.25, 188143.75, - 536811.25, 188024.75, 536811.25, 188088.25, 536811.25, 187912.75, 536811.25, 188080.25, - 536811.25, 188096.25, 536811.25, 188159.25, 536811.25, 188020.75, 536811.25, 187971.25, - 536811.25, 188051.75, 536811.25, 188072.75, 536811.25, 188039.75, 536811.25, 188081.75, - 536811.25, 188094.75, 536811.25, 187973.25, 536811.25, 187974.75, 536811.25, 188091.75, - 536811.25, 188018.75, 536811.25, 188003.25, 536811.25, 188013.25, 536811.25, 188146.75, - 536811.25, 188017.25, 536811.25, 188119.25, 536811.25, 188118.25, 536811.25, 187976.75, - 536811.25, 188034.25, 536811.25, 187960.25, 536811.25, 187911.75, 536811.25, 188066.75, - 536811.25, 187985.25, 536811.25, 188088.75, 536811.25, 188145.25, 536811.25, 188098.25, - 536811.25, 188069.25, 536811.25, 187972.75, 536811.25, 188047.25, 536811.25, 188122.75, - 536811.25, 188008.75, 536811.25, 188159.75, 536811.25, 188003.75, 536811.25, 188030.25, - 536811.25, 187923.75, 536811.75, 188098.25, 536811.75, 188143.25, 536811.75, 188070.75, - 536811.75, 188030.25, 536811.75, 188010.25, 536811.75, 188079.75, 536811.75, 188122.75, - 536811.75, 188069.25, 536811.75, 188001.75, 536811.75, 188147.25, 536811.75, 188145.25, - 536811.75, 187911.75, 536811.75, 187935.25, 536811.75, 188066.75, 536811.75, 187955.75, - 536811.75, 188088.75, 536811.75, 188029.25, 536811.75, 187972.25, 536811.75, 188073.25, - 536811.75, 187960.25, 536811.75, 188003.25, 536811.75, 188158.75, 536811.75, 187951.75, - 536811.75, 188087.75, 536811.75, 188118.25, 536811.75, 188146.75, 536811.75, 188081.75, - 536811.75, 188159.75, 536811.75, 188023.75, 536811.75, 187973.25, 536811.75, 188119.25, - 536811.75, 187963.25, 536811.75, 188144.75, 536811.75, 188020.75, 536811.75, 188089.25, - 536811.75, 188071.25, 536811.75, 187912.75, 536811.75, 188024.75, 536811.75, 188002.75, - 536811.75, 188095.25, 536811.75, 188024.25, 536811.75, 188068.25, 536811.75, 188091.75, - 536811.75, 188036.25, 536811.75, 188011.25, 536811.75, 187981.75, 536811.75, 188046.25, - 536811.75, 187971.75, 536811.75, 188075.75, 536811.75, 188044.75, 536811.75, 188027.75, - 536811.75, 187975.75, 536811.75, 188026.25, 536811.75, 188046.75, 536811.75, 188030.75, - 536811.75, 188125.25, 536811.75, 188029.75, 536811.75, 188012.25, 536811.75, 188070.25, - 536811.75, 188093.25, 536811.75, 188019.25, 536811.75, 187991.25, 536811.75, 188035.75, - 536811.75, 188123.25, 536811.75, 188084.25, 536811.75, 187974.75, 536811.75, 187960.75, - 536811.75, 188068.75, 536811.75, 188116.75, 536811.75, 188028.75, 536811.75, 187953.75, - 536811.75, 187913.25, 536811.75, 188148.25, 536811.75, 188067.25, 536811.75, 188118.75, - 536811.75, 188144.25, 536811.75, 188017.75, 536811.75, 188072.25, 536811.75, 187959.25, - 536811.75, 188034.75, 536811.75, 188123.75, 536811.75, 188092.75, 536811.75, 188120.75, - 536811.75, 188092.25, 536811.75, 188086.75, 536811.75, 187961.25, 536811.75, 188082.75, - 536811.75, 188028.25, 536811.75, 188121.75, 536811.75, 188000.25, 536812.25, 188000.25, - 536812.25, 188121.75, 536812.25, 188035.25, 536812.25, 188068.75, 536812.25, 187998.25, - 536812.25, 188157.25, 536812.25, 188028.25, 536812.25, 188025.75, 536812.25, 188067.25, - 536812.25, 188023.25, 536812.25, 188142.25, 536812.25, 188086.75, 536812.25, 188092.75, - 536812.25, 188118.75, 536812.25, 188144.25, 536812.25, 188080.75, 536812.25, 188016.25, - 536812.25, 188082.75, 536812.25, 188017.75, 536812.25, 187960.75, 536812.25, 188116.75, - 536812.25, 188082.25, 536812.25, 187968.25, 536812.25, 187958.75, 536812.25, 188087.25, - 536812.25, 188091.25, 536812.25, 187912.25, 536812.25, 188028.75, 536812.25, 188069.75, - 536812.25, 187947.25, 536812.25, 188093.75, 536812.25, 188117.75, 536812.25, 188009.25, - 536812.25, 187998.75, 536812.25, 188046.25, 536812.25, 188021.25, 536812.25, 188121.25, - 536812.25, 188036.25, 536812.25, 187910.75, 536812.25, 187977.75, 536812.25, 188046.75, - 536812.25, 187959.75, 536812.25, 188011.25, 536812.25, 187972.75, 536812.25, 188068.25, - 536812.25, 188142.75, 536812.25, 188052.75, 536812.25, 188086.25, 536812.25, 188052.25, - 536812.25, 187976.25, 536812.25, 188147.75, 536812.25, 188144.75, 536812.25, 188047.75, - 536812.25, 187973.25, 536812.25, 188073.75, 536812.25, 188158.75, 536812.25, 188159.25, - 536812.25, 188019.75, 536812.25, 188072.75, 536812.25, 188160.25, 536812.25, 187957.25, - 536812.25, 187977.25, 536812.25, 188018.75, 536812.25, 188025.25, 536812.25, 188148.75, - 536812.25, 188022.25, 536812.25, 188029.25, 536812.25, 188023.75, 536812.25, 187968.75, - 536812.25, 188122.75, 536812.25, 188008.75, 536812.25, 187911.25, 536812.25, 188030.25, - 536812.25, 188047.25, 536812.75, 187953.25, 536812.75, 188069.25, 536812.75, 188117.25, - 536812.75, 187999.25, 536812.75, 187973.75, 536812.75, 188143.25, 536812.75, 187911.75, - 536812.75, 188036.75, 536812.75, 188054.25, 536812.75, 187959.75, 536812.75, 188148.75, - 536812.75, 187955.75, 536812.75, 188073.25, 536812.75, 188008.25, 536812.75, 188141.25, - 536812.75, 187925.75, 536812.75, 188131.25, 536812.75, 188017.25, 536812.75, 188088.75, - 536812.75, 188115.75, 536812.75, 188156.75, 536812.75, 188081.25, 536812.75, 188080.25, - 536812.75, 188159.25, 536812.75, 188141.75, 536812.75, 188073.75, 536812.75, 187946.25, - 536812.75, 187988.25, 536812.75, 188144.75, 536812.75, 187940.75, 536812.75, 187958.25, - 536812.75, 188026.75, 536812.75, 188074.25, 536812.75, 187932.25, 536812.75, 188158.25, - 536812.75, 188052.75, 536812.75, 188021.75, 536812.75, 188048.25, 536812.75, 187917.75, - 536812.75, 188053.25, 536812.75, 187946.75, 536812.75, 188046.75, 536812.75, 188142.75, - 536812.75, 187972.75, 536812.75, 188040.75, 536812.75, 188121.75, 536812.75, 188018.25, - 536812.75, 188009.25, 536812.75, 188067.75, 536812.75, 188117.75, 536812.75, 188028.75, - 536812.75, 188046.25, 536812.75, 187944.75, 536812.75, 188090.25, 536812.75, 188140.75, - 536812.75, 188022.75, 536812.75, 188085.75, 536812.75, 188093.25, 536812.75, 188142.25, - 536812.75, 187950.25, 536812.75, 188051.25, 536812.75, 188148.25, 536812.75, 188048.75, - 536812.75, 188014.25, 536812.75, 187957.75, 536812.75, 188016.25, 536812.75, 188123.25, - 536812.75, 188027.25, 536812.75, 188035.75, 536812.75, 188091.25, 536812.75, 188157.25, - 536812.75, 187996.75, 536812.75, 188084.75, 536812.75, 187956.75, 536812.75, 187998.25, - 536812.75, 187966.75, 536812.75, 188155.75, 536812.75, 187947.75, 536813.25, 187958.25, - 536813.25, 188120.75, 536813.25, 187946.75, 536813.25, 188086.25, 536813.25, 188024.25, - 536813.25, 188147.75, 536813.25, 188007.25, 536813.25, 188085.25, 536813.25, 187923.25, - 536813.25, 188073.75, 536813.25, 188015.25, 536813.25, 188009.25, 536813.25, 188050.75, - 536813.25, 188123.25, 536813.25, 188035.75, 536813.25, 188155.75, 536813.25, 188000.25, - 536813.25, 188117.25, 536813.25, 188027.25, 536813.25, 188051.25, 536813.25, 187975.25, - 536813.25, 188022.75, 536813.25, 188067.75, 536813.25, 187972.75, 536813.25, 188088.25, - 536813.25, 188026.75, 536813.25, 187946.25, 536813.25, 188014.75, 536813.25, 188047.25, - 536813.25, 188017.25, 536813.25, 188148.75, 536813.25, 188036.75, 536813.25, 187999.25, - 536813.25, 188064.25, 536813.25, 188158.25, 536813.25, 188073.25, 536813.25, 188144.75, - 536813.25, 188010.75, 536813.25, 188048.25, 536813.25, 188021.75, 536813.25, 188055.75, - 536813.25, 187944.75, 536813.25, 188092.75, 536813.25, 188091.25, 536813.25, 187952.75, - 536813.25, 187998.25, 536813.25, 188031.75, 536813.25, 188156.75, 536813.25, 188139.25, - 536813.25, 187947.75, 536813.25, 188027.75, 536813.25, 188143.25, 536813.25, 188081.25, - 536813.25, 188142.75, 536813.25, 188089.75, 536813.25, 188018.25, 536813.25, 187997.25, - 536813.25, 188157.25, 536813.25, 188142.25, 536813.25, 188052.75, 536813.25, 188141.75, - 536813.25, 188080.25, 536813.25, 187953.75, 536813.25, 187956.25, 536813.25, 188141.25, - 536813.25, 187959.25, 536813.25, 187995.75, 536813.25, 188130.25, 536813.25, 187973.75, - 536813.25, 187976.25, 536813.25, 188046.75, 536813.25, 188140.75, 536813.25, 188116.75, - 536813.25, 187956.75, 536813.25, 188068.25, 536813.75, 188088.75, 536813.75, 188016.75, - 536813.75, 187973.25, 536813.75, 188092.75, 536813.75, 188048.75, 536813.75, 188093.25, - 536813.75, 188154.25, 536813.75, 187952.25, 536813.75, 188014.75, 536813.75, 188090.75, - 536813.75, 188118.25, 536813.75, 187972.25, 536813.75, 187930.25, 536813.75, 188118.75, - 536813.75, 188094.75, 536813.75, 187976.75, 536813.75, 188088.25, 536813.75, 187956.25, - 536813.75, 187951.75, 536813.75, 187978.25, 536813.75, 187923.25, 536813.75, 188050.75, - 536813.75, 188036.25, 536813.75, 188073.75, 536813.75, 188148.75, 536813.75, 188001.75, - 536813.75, 188155.75, 536813.75, 188070.75, 536813.75, 188148.25, 536813.75, 188051.25, - 536813.75, 188022.75, 536813.75, 188022.25, 536813.75, 188014.25, 536813.75, 188000.25, - 536813.75, 188084.75, 536813.75, 188015.25, 536813.75, 188156.25, 536813.75, 188141.75, - 536813.75, 187950.25, 536813.75, 187942.25, 536813.75, 188083.75, 536813.75, 187999.25, - 536813.75, 187943.25, 536813.75, 187957.75, 536813.75, 188068.75, 536813.75, 188140.25, - 536813.75, 187994.75, 536813.75, 188081.25, 536813.75, 188074.25, 536813.75, 188053.75, - 536813.75, 187938.25, 536813.75, 188142.75, 536813.75, 188069.75, 536813.75, 188080.75, - 536814.25, 188153.75, 536814.25, 188148.75, 536814.25, 188037.25, 536814.25, 188080.75, - 536814.25, 188016.25, 536814.25, 187995.25, 536814.25, 188116.75, 536814.25, 188092.25, - 536814.25, 188139.75, 536814.25, 188015.75, 536814.25, 187997.25, 536814.25, 188013.75, - 536814.25, 187973.25, 536814.25, 187914.25, 536814.25, 188142.75, 536814.25, 187970.75, - 536814.25, 188070.75, 536814.25, 188037.75, 536814.25, 188074.75, 536814.25, 188029.75, - 536814.25, 188015.25, 536814.25, 188084.25, 536814.25, 188012.75, 536814.25, 188013.25, - 536814.25, 187957.25, 536814.25, 187933.25, 536814.25, 188156.25, 536814.25, 188116.25, - 536814.25, 187990.75, 536814.25, 188091.25, 536814.25, 188034.75, 536814.25, 188149.25, - 536814.25, 187942.25, 536814.25, 187956.75, 536814.25, 188042.25, 536814.25, 188069.25, - 536814.25, 187953.25, 536814.25, 187954.25, 536814.25, 187985.25, 536814.25, 188052.75, - 536814.25, 188083.75, 536814.25, 188139.25, 536814.25, 188142.25, 536814.25, 188154.25, - 536814.25, 188049.25, 536814.25, 188047.75, 536814.25, 187943.25, 536814.25, 188128.25, - 536814.25, 188088.25, 536814.25, 188117.75, 536814.25, 188052.25, 536814.25, 188083.25, - 536814.25, 188081.75, 536814.25, 187942.75, 536814.25, 187941.25, 536814.25, 187971.75, - 536814.25, 188137.75, 536814.25, 187955.25, 536814.25, 188115.25, 536814.25, 187960.75, - 536814.25, 187995.75, 536814.25, 188089.25, 536814.25, 188049.75, 536814.25, 188020.25, - 536814.25, 188154.75, 536814.25, 188082.25, 536814.25, 187966.25, 536814.25, 188082.75, - 536814.25, 188118.75, 536814.75, 188082.75, 536814.75, 188154.75, 536814.75, 188020.75, - 536814.75, 187984.75, 536814.75, 188118.75, 536814.75, 187972.25, 536814.75, 187994.75, - 536814.75, 188035.75, 536814.75, 188089.25, 536814.75, 187995.75, 536814.75, 188068.25, - 536814.75, 188090.75, 536814.75, 188011.75, 536814.75, 188014.75, 536814.75, 188028.25, - 536814.75, 187941.25, 536814.75, 187942.75, 536814.75, 187977.25, 536814.75, 188083.25, - 536814.75, 187913.25, 536814.75, 188003.25, 536814.75, 187997.75, 536814.75, 188152.75, - 536814.75, 188117.75, 536814.75, 187947.25, 536814.75, 187957.75, 536814.75, 188002.75, - 536814.75, 188140.75, 536814.75, 187951.75, 536814.75, 188034.25, 536814.75, 188047.75, - 536814.75, 188036.75, 536814.75, 188021.25, 536814.75, 188057.75, 536814.75, 187971.25, - 536814.75, 188139.25, 536814.75, 188049.25, 536814.75, 188083.75, 536814.75, 188052.75, - 536814.75, 188052.25, 536814.75, 188120.75, 536814.75, 187974.25, 536814.75, 187953.25, - 536814.75, 188160.25, 536814.75, 187965.75, 536814.75, 187956.75, 536814.75, 188143.25, - 536814.75, 188149.25, 536814.75, 187955.75, 536814.75, 187957.25, 536814.75, 188141.75, - 536814.75, 188074.75, 536814.75, 188073.75, 536814.75, 187942.25, 536814.75, 188012.75, - 536814.75, 188013.25, 536814.75, 188084.25, 536814.75, 188081.25, 536814.75, 188148.75, - 536814.75, 187972.75, 536814.75, 188092.75, 536814.75, 188091.75, 536814.75, 188085.75, - 536814.75, 187973.25, 536814.75, 187954.75, 536814.75, 187931.25, 536814.75, 187910.75, - 536814.75, 187943.25, 536814.75, 188015.75, 536814.75, 188138.25, 536814.75, 188016.75, - 536814.75, 188016.25, 536814.75, 188153.75, 536814.75, 188139.75, 536814.75, 188137.25, - 536814.75, 188080.75, 536815.25, 188080.75, 536815.25, 187954.25, 536815.25, 188116.75, - 536815.25, 188069.75, 536815.25, 188016.25, 536815.25, 188127.25, 536815.25, 188037.75, - 536815.25, 188074.25, 536815.25, 188013.75, 536815.25, 188026.75, 536815.25, 188117.25, - 536815.25, 188010.25, 536815.25, 188022.25, 536815.25, 187995.25, 536815.25, 188153.25, - 536815.25, 187949.25, 536815.25, 188016.75, 536815.25, 188116.25, 536815.25, 188012.25, - 536815.25, 188112.75, 536815.25, 187927.75, 536815.25, 188010.75, 536815.25, 187974.75, - 536815.25, 188081.75, 536815.25, 188140.25, 536815.25, 187952.25, 536815.25, 187995.75, - 536815.25, 188011.75, 536815.25, 188115.25, 536815.25, 188118.25, 536815.25, 188090.25, - 536815.25, 188138.75, 536815.25, 188152.25, 536815.25, 188022.75, 536815.25, 188089.75, - 536815.25, 188085.75, 536815.25, 188118.75, 536815.25, 188070.75, 536815.25, 188049.75, - 536815.25, 188082.25, 536815.25, 188001.25, 536815.25, 188020.75, 536815.25, 188128.25, - 536815.25, 187940.75, 536815.25, 188068.75, 536815.25, 187941.75, 536815.25, 188035.25, - 536815.25, 188001.75, 536815.25, 188136.25, 536815.25, 188137.75, 536815.25, 188075.25, - 536815.25, 187971.75, 536815.25, 188024.25, 536815.25, 188034.75, 536815.25, 188083.25, - 536815.25, 188042.75, 536815.25, 188088.75, 536815.25, 187969.75, 536815.25, 187939.75, - 536815.25, 187959.75, 536815.25, 188150.25, 536815.25, 188008.75, 536815.25, 187970.25, - 536815.25, 188034.25, 536815.25, 188087.75, 536815.25, 188023.75, 536815.25, 187993.75, - 536815.25, 187965.25, 536815.25, 187916.25, 536815.25, 188149.75, 536815.25, 188044.75, - 536815.25, 188050.75, 536815.75, 187968.25, 536815.75, 188134.75, 536815.75, 188037.25, - 536815.75, 188070.25, 536815.75, 188149.75, 536815.75, 188087.25, 536815.75, 187938.25, - 536815.75, 188010.25, 536815.75, 187951.25, 536815.75, 187943.25, 536815.75, 188038.75, - 536815.75, 187940.25, 536815.75, 188048.25, 536815.75, 187961.25, 536815.75, 188064.75, - 536815.75, 187952.75, 536815.75, 188017.25, 536815.75, 187949.75, 536815.75, 188025.75, - 536815.75, 188073.25, 536815.75, 188026.75, 536815.75, 188022.25, 536815.75, 188048.75, - 536815.75, 188077.25, 536815.75, 188002.75, 536815.75, 188034.25, 536815.75, 188137.25, - 536815.75, 188081.25, 536815.75, 188016.75, 536815.75, 188116.25, 536815.75, 188150.25, - 536815.75, 188152.75, 536815.75, 188011.25, 536815.75, 187949.25, 536815.75, 187939.75, - 536815.75, 188153.25, 536815.75, 187921.25, 536815.75, 187969.75, 536815.75, 187958.25, - 536815.75, 188136.75, 536815.75, 187953.25, 536815.75, 188075.75, 536815.75, 188135.25, - 536815.75, 188034.75, 536815.75, 188069.25, 536815.75, 187974.25, 536815.75, 188112.75, - 536815.75, 188079.25, 536815.75, 188114.25, 536815.75, 188080.25, 536815.75, 188003.75, - 536815.75, 187953.75, 536815.75, 188018.25, 536815.75, 188012.25, 536815.75, 188080.75, - 536815.75, 187969.25, 536815.75, 188074.75, 536815.75, 188089.25, 536815.75, 187959.75, - 536815.75, 187996.25, 536815.75, 188071.25, 536815.75, 187960.75, 536815.75, 188084.75, - 536815.75, 188090.75, 536815.75, 188136.25, 536815.75, 188086.75, 536815.75, 188024.75, - 536815.75, 187959.25, 536815.75, 188114.75, 536815.75, 187970.75, 536815.75, 188115.25, - 536815.75, 188133.25, 536815.75, 187975.25, 536815.75, 188156.25, 536815.75, 188020.75, - 536815.75, 188051.25, 536815.75, 187944.75, 536815.75, 188004.75, 536815.75, 187994.25, - 536815.75, 188138.75, 536815.75, 188021.75, 536815.75, 188135.75, 536815.75, 188027.75, - 536815.75, 188152.25, 536815.75, 188022.75, 536816.25, 188135.75, 536816.25, 188129.75, - 536816.25, 188054.75, 536816.25, 187952.25, 536816.25, 187994.25, 536816.25, 188049.75, - 536816.25, 188138.75, 536816.25, 188090.25, 536816.25, 188043.75, 536816.25, 188082.25, - 536816.25, 188031.75, 536816.25, 187959.75, 536816.25, 187963.25, 536816.25, 188021.75, - 536816.25, 187999.75, 536816.25, 188115.25, 536816.25, 188086.75, 536816.25, 187989.25, - 536816.25, 188114.75, 536816.25, 187960.75, 536816.25, 188025.25, 536816.25, 187970.75, - 536816.25, 188084.75, 536816.25, 188033.75, 536816.25, 187942.75, 536816.25, 188035.25, - 536816.25, 188075.25, 536816.25, 188152.75, 536816.25, 188000.25, 536816.25, 188074.75, - 536816.25, 188089.25, 536816.25, 188139.75, 536816.25, 187969.25, 536816.25, 188135.25, - 536816.25, 188081.75, 536816.25, 188071.25, 536816.25, 188119.25, 536816.25, 188003.75, - 536816.25, 188114.25, 536816.25, 188151.25, 536816.25, 187974.75, 536816.25, 188069.25, - 536816.25, 188083.25, 536816.25, 187941.25, 536816.25, 188016.25, 536816.25, 188136.75, - 536816.25, 187953.25, 536816.25, 187949.25, 536816.25, 188038.25, 536816.25, 188149.25, - 536816.25, 188116.25, 536816.25, 188150.25, 536816.25, 188010.75, 536816.25, 188008.75, - 536816.25, 188012.75, 536816.25, 188016.75, 536816.25, 187958.25, 536816.25, 188079.25, - 536816.25, 187939.75, 536816.25, 188137.25, 536816.25, 188011.25, 536816.25, 188002.75, - 536816.25, 188022.25, 536816.25, 188079.75, 536816.25, 188026.75, 536816.25, 188017.25, - 536816.25, 187951.75, 536816.25, 187952.75, 536816.25, 188023.25, 536816.25, 188048.25, - 536816.25, 187968.25, 536816.25, 188010.25, 536816.25, 188113.75, 536816.25, 188139.25, - 536816.25, 187940.25, 536816.25, 187960.25, 536816.25, 188080.75, 536816.25, 188070.25, - 536816.25, 187943.25, 536816.25, 187973.75, 536816.25, 187948.75, 536816.25, 188138.25, - 536816.25, 187944.25, 536816.25, 188087.25, 536816.25, 188134.75, 536816.25, 187938.25, - 536816.25, 188037.25, 536816.75, 188048.75, 536816.75, 188079.25, 536816.75, 188039.25, - 536816.75, 188018.25, 536816.75, 188108.75, 536816.75, 187987.75, 536816.75, 187968.25, - 536816.75, 188070.75, 536816.75, 187950.25, 536816.75, 188080.25, 536816.75, 188074.75, - 536816.75, 187938.25, 536816.75, 187950.75, 536816.75, 187944.25, 536816.75, 187960.25, - 536816.75, 188081.25, 536816.75, 188110.25, 536816.75, 187942.75, 536816.75, 187959.25, - 536816.75, 188133.75, 536816.75, 188020.25, 536816.75, 187939.25, 536816.75, 188075.25, - 536816.75, 187973.25, 536816.75, 187969.75, 536816.75, 188038.75, 536816.75, 188077.75, - 536816.75, 187951.25, 536816.75, 187970.25, 536816.75, 188037.75, 536816.75, 188159.75, - 536816.75, 188084.25, 536816.75, 188135.25, 536816.75, 188112.25, 536816.75, 188010.75, - 536816.75, 188112.75, 536816.75, 188147.75, 536816.75, 188022.75, 536816.75, 188009.75, - 536816.75, 188086.75, 536816.75, 188017.25, 536816.75, 187949.75, 536816.75, 188087.25, - 536816.75, 188002.25, 536816.75, 188149.75, 536816.75, 188009.25, 536816.75, 187928.25, - 536816.75, 188113.75, 536816.75, 187951.75, 536816.75, 188150.25, 536816.75, 188008.75, - 536816.75, 188076.25, 536816.75, 187977.75, 536816.75, 188088.75, 536816.75, 188114.25, - 536816.75, 188024.75, 536816.75, 187940.75, 536816.75, 187972.25, 536816.75, 188027.75, - 536816.75, 187967.25, 536816.75, 188134.25, 536816.75, 188027.25, 536816.75, 188133.25, - 536816.75, 187952.25, 536816.75, 188049.75, 536816.75, 188000.25, 536817.25, 188001.25, - 536817.25, 187948.75, 536817.25, 188111.75, 536817.25, 188048.75, 536817.25, 188007.25, - 536817.25, 188112.25, 536817.25, 188021.25, 536817.25, 188049.75, 536817.25, 188049.25, - 536817.25, 187935.75, 536817.25, 188112.75, 536817.25, 187973.25, 536817.25, 188111.25, - 536817.25, 188025.75, 536817.25, 188085.75, 536817.25, 188039.25, 536817.25, 187940.25, - 536817.25, 188025.25, 536817.25, 188018.25, 536817.25, 187998.75, 536817.25, 188009.75, - 536817.25, 187966.25, 536817.25, 188017.75, 536817.25, 187941.75, 536817.25, 188001.75, - 536817.25, 187948.25, 536817.25, 187959.75, 536817.25, 188078.25, 536817.25, 188020.75, - 536817.25, 188038.25, 536817.25, 187975.25, 536817.25, 187949.75, 536817.25, 188079.75, - 536817.25, 188113.25, 536817.25, 188087.25, 536817.25, 188134.25, 536817.25, 187959.25, - 536817.25, 188133.75, 536817.25, 187997.75, 536817.25, 187967.75, 536817.25, 188004.75, - 536817.25, 187938.75, 536817.25, 188126.75, 536817.25, 188018.75, 536817.25, 188023.75, - 536817.25, 188087.75, 536817.25, 187967.25, 536817.25, 187968.75, 536817.25, 188071.75, - 536817.25, 187910.75, 536817.25, 188077.25, 536817.25, 188007.75, 536817.25, 187949.25, - 536817.25, 188080.25, 536817.25, 188088.25, 536817.25, 188155.25, 536817.25, 188003.25, - 536817.25, 188050.25, 536817.25, 188132.75, 536817.25, 187972.25, 536817.25, 187940.75, - 536817.25, 188088.75, 536817.25, 188109.75, 536817.25, 187996.25, 536817.25, 188158.25, - 536817.25, 188075.75, 536817.25, 187944.75, 536817.25, 187943.75, 536817.25, 188039.75, - 536817.25, 188063.75, 536817.25, 188130.75, 536817.25, 188114.25, 536817.25, 188160.25, - 536817.25, 188074.75, 536817.25, 188028.25, 536817.25, 188069.75, 536817.25, 187921.75, - 536817.25, 187976.25, 536817.25, 188053.25, 536817.25, 188076.25, 536817.25, 187950.75, - 536817.25, 188078.75, 536817.25, 187938.25, 536817.25, 187971.75, 536817.75, 187968.75, - 536817.75, 188078.75, 536817.75, 188079.25, 536817.75, 187971.75, 536817.75, 187996.75, - 536817.75, 187973.25, 536817.75, 187948.75, 536817.75, 188024.75, 536817.75, 188049.25, - 536817.75, 187941.75, 536817.75, 187924.75, 536817.75, 188078.25, 536817.75, 187949.75, - 536817.75, 188038.25, 536817.75, 188069.75, 536817.75, 188028.25, 536817.75, 188083.75, - 536817.75, 188017.25, 536817.75, 188025.75, 536817.75, 188079.75, 536817.75, 188065.25, - 536817.75, 187943.75, 536817.75, 188001.75, 536817.75, 187913.75, 536817.75, 188050.25, - 536817.75, 188087.25, 536817.75, 188112.25, 536817.75, 188000.25, 536817.75, 188075.75, - 536817.75, 188113.25, 536817.75, 187937.75, 536817.75, 188076.25, 536817.75, 188088.75, - 536817.75, 188040.75, 536817.75, 187989.75, 536817.75, 188132.75, 536817.75, 188058.75, - 536817.75, 188009.75, 536817.75, 188157.75, 536817.75, 188020.25, 536817.75, 188126.25, - 536817.75, 188086.75, 536817.75, 187966.25, 536817.75, 188088.25, 536817.75, 188037.25, - 536817.75, 188045.25, 536817.75, 188012.75, 536817.75, 187940.75, 536817.75, 188110.75, - 536817.75, 188033.25, 536817.75, 188021.25, 536817.75, 188008.75, 536817.75, 187949.25, - 536817.75, 187968.25, 536817.75, 187939.75, 536817.75, 188112.75, 536817.75, 188157.25, - 536817.75, 188077.25, 536817.75, 188071.25, 536817.75, 188111.25, 536817.75, 188017.75, - 536817.75, 187938.75, 536817.75, 188018.25, 536817.75, 187967.25, 536817.75, 188085.25, - 536817.75, 188087.75, 536817.75, 188022.75, 536817.75, 188133.75, 536818.25, 188000.75, - 536818.25, 187970.75, 536818.25, 188026.75, 536818.25, 188018.25, 536818.25, 188085.25, - 536818.25, 187997.75, 536818.25, 188027.75, 536818.25, 188078.75, 536818.25, 188083.25, - 536818.25, 187946.75, 536818.25, 188017.75, 536818.25, 188049.25, 536818.25, 188032.25, - 536818.25, 188028.75, 536818.25, 188110.75, 536818.25, 188049.75, 536818.25, 187998.75, - 536818.25, 187973.75, 536818.25, 188111.75, 536818.25, 187959.25, 536818.25, 187933.75, - 536818.25, 188025.25, 536818.25, 188086.25, 536818.25, 187975.75, 536818.25, 188081.25, - 536818.25, 188133.75, 536818.25, 187998.25, 536818.25, 188033.25, 536818.25, 188038.75, - 536818.25, 188082.25, 536818.25, 188076.25, 536818.25, 188055.75, 536818.25, 187967.25, - 536818.25, 188068.75, 536818.25, 187965.75, 536818.25, 188087.25, 536818.25, 188156.25, - 536818.25, 188023.25, 536818.25, 188133.25, 536818.25, 187939.25, 536818.25, 188084.75, - 536818.25, 188039.75, 536818.25, 187940.25, 536818.25, 188026.25, 536818.25, 188008.25, - 536818.25, 188021.75, 536818.25, 188007.25, 536818.25, 187996.75, 536818.25, 187975.25, - 536818.25, 187948.75, 536818.25, 187948.25, 536818.25, 187965.25, 536818.25, 187938.25, - 536818.25, 188077.75, 536818.25, 187934.25, 536818.75, 187934.25, 536818.75, 188079.75, - 536818.75, 188082.75, 536818.75, 188078.25, 536818.75, 188020.75, 536818.75, 188108.75, - 536818.75, 188133.25, 536818.75, 188029.25, 536818.75, 187939.25, 536818.75, 187969.75, - 536818.75, 188134.25, 536818.75, 188082.25, 536818.75, 188105.75, 536818.75, 188044.75, - 536818.75, 188050.75, 536818.75, 188134.75, 536818.75, 188111.25, 536818.75, 187954.25, - 536818.75, 188029.75, 536818.75, 188027.25, 536818.75, 187966.25, 536818.75, 187947.25, - 536818.75, 187934.75, 536818.75, 188075.25, 536818.75, 188055.75, 536818.75, 187955.25, - 536818.75, 187964.75, 536818.75, 188039.25, 536818.75, 188085.75, 536818.75, 187930.75, - 536818.75, 188108.25, 536818.75, 188006.75, 536818.75, 187974.25, 536818.75, 188018.75, - 536818.75, 188072.75, 536818.75, 188070.75, 536818.75, 188005.25, 536818.75, 187970.75, - 536818.75, 188110.25, 536818.75, 188147.25, 536818.75, 187963.75, 536818.75, 188036.25, - 536818.75, 188085.25, 536818.75, 188071.75, 536818.75, 188026.75, 536818.75, 188007.75, - 536818.75, 187949.25, 536818.75, 188021.25, 536818.75, 188032.25, 536818.75, 188008.75, - 536818.75, 187974.75, 536818.75, 188028.75, 536818.75, 187995.25, 536818.75, 188074.25, - 536818.75, 188109.25, 536818.75, 187947.75, 536818.75, 188083.75, 536818.75, 187945.25, - 536818.75, 187999.25, 536818.75, 187972.25, 536818.75, 188133.75, 536818.75, 188018.25, - 536818.75, 188109.75, 536818.75, 188050.25, 536818.75, 187997.25, 536818.75, 188154.75, - 536818.75, 188040.25, 536818.75, 187996.75, 536818.75, 187976.25, 536818.75, 188038.75, - 536818.75, 187953.25, 536818.75, 188019.25, 536818.75, 188077.75, 536818.75, 188030.75, - 536818.75, 188107.75, 536818.75, 188006.25, 536818.75, 187976.75, 536818.75, 187946.25, - 536819.25, 188005.75, 536819.25, 187973.25, 536819.25, 188159.75, 536819.25, 187946.25, - 536819.25, 188018.25, 536819.25, 188049.75, 536819.25, 188084.25, 536819.25, 188039.25, - 536819.25, 187974.75, 536819.25, 187963.75, 536819.25, 188108.75, 536819.25, 188133.25, - 536819.25, 187968.25, 536819.25, 188038.75, 536819.25, 187975.25, 536819.25, 188025.25, - 536819.25, 187947.25, 536819.25, 188076.75, 536819.25, 188133.75, 536819.25, 188007.25, - 536819.25, 188007.75, 536819.25, 188076.25, 536819.25, 188109.25, 536819.25, 188060.75, - 536819.25, 188083.75, 536819.25, 187947.75, 536819.25, 187972.25, 536819.25, 187957.75, - 536819.25, 187918.75, 536819.25, 187965.75, 536819.25, 187970.75, 536819.25, 188040.25, - 536819.25, 188142.25, 536819.25, 188074.75, 536819.25, 187964.75, 536819.25, 187976.25, - 536819.25, 187914.75, 536819.25, 188104.75, 536819.25, 188154.25, 536819.25, 188051.25, - 536819.25, 188080.75, 536819.25, 187996.75, 536819.25, 188083.25, 536819.25, 188107.75, - 536819.25, 188008.75, 536819.25, 188031.25, 536819.25, 188075.25, 536819.25, 188006.25, - 536819.25, 188050.25, 536819.25, 187945.75, 536819.25, 188003.75, 536819.25, 187938.75, - 536819.25, 188068.75, 536819.25, 188028.25, 536819.25, 188109.75, 536819.25, 187977.25, - 536819.25, 188075.75, 536819.25, 187948.25, 536819.25, 187944.25, 536819.25, 187934.25, - 536819.25, 187969.75, 536819.25, 187974.25, 536819.25, 187945.25, 536819.25, 188040.75, - 536819.25, 188056.75, 536819.25, 188074.25, 536819.25, 188072.25, 536819.25, 187933.25, - 536819.25, 188028.75, 536819.25, 188029.25, 536819.25, 187939.75, 536819.25, 188032.25, - 536819.25, 188071.75, 536819.25, 188036.25, 536819.25, 188082.25, 536819.25, 188006.75, - 536819.25, 187998.25, 536819.25, 188110.25, 536819.25, 187962.25, 536819.25, 187946.75, - 536819.25, 187932.25, 536819.25, 188108.25, 536819.25, 188057.25, 536819.75, 188026.75, - 536819.75, 188160.25, 536819.75, 187946.25, 536819.75, 188005.75, 536819.75, 187942.75, - 536819.75, 188054.25, 536819.75, 188057.25, 536819.75, 188009.25, 536819.75, 188152.75, - 536819.75, 188108.25, 536819.75, 187933.75, 536819.75, 188060.25, 536819.75, 188159.25, - 536819.75, 187932.25, 536819.75, 188107.25, 536819.75, 188059.75, 536819.75, 187951.25, - 536819.75, 187967.75, 536819.75, 188133.75, 536819.75, 188081.75, 536819.75, 188027.25, - 536819.75, 187934.75, 536819.75, 187993.75, 536819.75, 188108.75, 536819.75, 188033.25, - 536819.75, 187966.75, 536819.75, 188032.25, 536819.75, 187962.25, 536819.75, 188002.75, - 536819.75, 188133.25, 536819.75, 187945.75, 536819.75, 188106.25, 536819.75, 187910.75, - 536819.75, 187995.25, 536819.75, 187947.75, 536819.75, 188153.25, 536819.75, 188030.25, - 536819.75, 188039.75, 536819.75, 188008.25, 536819.75, 188107.75, 536819.75, 188074.75, - 536819.75, 188028.75, 536819.75, 188066.25, 536819.75, 188073.25, 536819.75, 188083.25, - 536819.75, 187973.75, 536819.75, 188050.25, 536819.75, 187964.25, 536819.75, 188082.75, - 536819.75, 188056.75, 536819.75, 187962.75, 536819.75, 188003.25, 536819.75, 187971.75, - 536819.75, 188075.75, 536819.75, 187948.25, 536819.75, 187945.25, 536819.75, 188073.75, - 536819.75, 187969.75, 536819.75, 188075.25, 536819.75, 188019.25, 536819.75, 188121.75, - 536819.75, 188051.25, 536819.75, 188144.25, 536819.75, 188028.25, 536819.75, 188151.25, - 536819.75, 188109.75, 536820.25, 188073.25, 536820.25, 187994.75, 536820.25, 187943.75, - 536820.25, 188003.75, 536820.25, 188009.75, 536820.25, 187960.75, 536820.25, 187944.25, - 536820.25, 187934.25, 536820.25, 188040.75, 536820.25, 188031.25, 536820.25, 187962.75, - 536820.25, 188006.25, 536820.25, 188050.75, 536820.25, 188003.25, 536820.25, 188078.75, - 536820.25, 188081.25, 536820.25, 188059.25, 536820.25, 188024.75, 536820.25, 188091.25, - 536820.25, 187958.75, 536820.25, 188029.75, 536820.25, 188082.75, 536820.25, 188080.75, - 536820.25, 187940.25, 536820.25, 187992.25, 536820.25, 188085.75, 536820.25, 188073.75, - 536820.25, 187968.75, 536820.25, 188004.25, 536820.25, 188106.75, 536820.25, 187931.25, - 536820.25, 187932.75, 536820.25, 187935.25, 536820.25, 188008.25, 536820.25, 188134.75, - 536820.25, 187970.75, 536820.25, 187944.75, 536820.25, 188158.25, 536820.25, 188124.75, - 536820.25, 188030.25, 536820.25, 187967.25, 536820.25, 188153.25, 536820.25, 188058.25, - 536820.25, 188025.75, 536820.25, 188080.25, 536820.25, 188105.75, 536820.25, 187964.25, - 536820.25, 188146.25, 536820.25, 188010.25, 536820.25, 188077.25, 536820.25, 188051.75, - 536820.25, 187939.75, 536820.25, 187961.25, 536820.25, 188026.75, 536820.25, 188025.25, - 536820.25, 188018.75, 536820.25, 188060.75, 536820.25, 187948.75, 536820.25, 187963.25, - 536820.25, 188134.25, 536820.25, 187931.75, 536820.25, 188135.25, 536820.25, 188005.75, - 536820.25, 188056.25, 536820.25, 188026.25, 536820.25, 187962.25, 536820.25, 188002.25, - 536820.25, 187927.25, 536820.25, 188033.25, 536820.25, 188031.75, 536820.25, 188106.25, - 536820.25, 187951.25, 536820.25, 187993.75, 536820.25, 188019.75, 536820.25, 188072.75, - 536820.25, 188064.75, 536820.25, 187995.75, 536820.25, 188027.25, 536820.25, 188059.75, - 536820.25, 187997.75, 536820.25, 188023.75, 536820.25, 188157.25, 536820.25, 187952.25, - 536820.25, 188044.75, 536820.25, 188120.75, 536820.25, 187942.75, 536820.25, 188159.75, - 536820.25, 188061.25, 536820.25, 188061.75, 536820.25, 187966.75, 536820.75, 188080.25, - 536820.75, 188043.25, 536820.75, 188025.75, 536820.75, 187931.75, 536820.75, 187970.75, - 536820.75, 187944.75, 536820.75, 187931.25, 536820.75, 188040.75, 536820.75, 188082.25, - 536820.75, 187967.25, 536820.75, 187945.25, 536820.75, 188004.25, 536820.75, 188003.25, - 536820.75, 188147.25, 536820.75, 188158.75, 536820.75, 187937.25, 536820.75, 188090.25, - 536820.75, 188083.25, 536820.75, 188059.75, 536820.75, 188134.75, 536820.75, 187960.75, - 536820.75, 187968.75, 536820.75, 188081.25, 536820.75, 188039.75, 536820.75, 187965.25, - 536820.75, 188050.75, 536820.75, 188020.25, 536820.75, 188106.75, 536820.75, 188134.25, - 536820.75, 188025.25, 536820.75, 187943.75, 536820.75, 188059.25, 536820.75, 188034.75, - 536820.75, 187996.25, 536820.75, 188073.75, 536820.75, 188061.25, 536820.75, 188105.75, - 536820.75, 187961.75, 536820.75, 188031.75, 536820.75, 188030.25, 536820.75, 187962.75, - 536820.75, 187944.25, 536820.75, 188009.75, 536820.75, 188038.75, 536820.75, 188006.75, - 536820.75, 188077.75, 536820.75, 188127.75, 536820.75, 188029.25, 536820.75, 188066.75, - 536820.75, 188024.25, 536820.75, 187994.75, 536820.75, 188108.25, 536820.75, 188055.25, - 536820.75, 187933.75, 536820.75, 188159.25, 536820.75, 187993.75, 536820.75, 187965.75, - 536820.75, 188026.25, 536820.75, 187934.75, 536820.75, 187926.25, 536820.75, 187930.75, - 536820.75, 188117.75, 536820.75, 188124.25, 536820.75, 188053.75, 536820.75, 188104.75, - 536820.75, 188080.75, 536820.75, 188155.75, 536820.75, 188018.75, 536820.75, 188033.25, - 536820.75, 187951.75, 536820.75, 188003.75, 536820.75, 187962.25, 536820.75, 188055.75, - 536820.75, 188008.75, 536820.75, 188135.25, 536820.75, 188002.25, 536820.75, 187942.75, - 536821.25, 187942.75, 536821.25, 188010.75, 536821.25, 188103.25, 536821.25, 188135.25, - 536821.25, 187959.25, 536821.25, 188009.25, 536821.25, 187943.25, 536821.25, 188040.25, - 536821.25, 188051.75, 536821.25, 187971.75, 536821.25, 187991.25, 536821.25, 188041.25, - 536821.25, 188038.25, 536821.25, 187950.75, 536821.25, 188074.75, 536821.25, 187930.25, - 536821.25, 188032.75, 536821.25, 188031.25, 536821.25, 188003.75, 536821.25, 187939.25, - 536821.25, 187960.25, 536821.25, 188024.75, 536821.25, 187970.75, 536821.25, 188057.75, - 536821.25, 188104.75, 536821.25, 188081.25, 536821.25, 188079.25, 536821.25, 188072.25, - 536821.25, 187966.25, 536821.25, 187975.75, 536821.25, 188020.25, 536821.25, 187935.25, - 536821.25, 188052.75, 536821.25, 187941.25, 536821.25, 187964.75, 536821.25, 187928.75, - 536821.25, 187972.25, 536821.25, 187931.25, 536821.25, 188080.75, 536821.25, 187950.25, - 536821.25, 188029.75, 536821.25, 188134.75, 536821.25, 188051.25, 536821.25, 188019.25, - 536821.25, 188035.25, 536821.25, 188129.25, 536821.25, 187961.25, 536821.25, 188104.25, - 536821.25, 188078.25, 536821.25, 188105.25, 536821.25, 187934.75, 536821.25, 188026.25, - 536821.75, 188060.75, 536821.75, 187940.75, 536821.75, 187990.25, 536821.75, 188070.25, - 536821.75, 187930.75, 536821.75, 187964.25, 536821.75, 188008.75, 536821.75, 187966.75, - 536821.75, 188091.75, 536821.75, 188040.25, 536821.75, 188020.75, 536821.75, 188072.75, - 536821.75, 188079.75, 536821.75, 188053.25, 536821.75, 187965.75, 536821.75, 188010.75, - 536821.75, 188031.25, 536821.75, 187928.25, 536821.75, 187992.75, 536821.75, 187955.25, - 536821.75, 187942.25, 536821.75, 188022.25, 536821.75, 188052.25, 536821.75, 188019.75, - 536821.75, 187935.75, 536821.75, 188030.75, 536821.75, 187943.25, 536821.75, 188026.75, - 536821.75, 187950.75, 536821.75, 187969.25, 536821.75, 187991.25, 536821.75, 188047.75, - 536821.75, 187971.25, 536821.75, 187972.75, 536821.75, 188078.75, 536821.75, 188029.75, - 536821.75, 187970.25, 536821.75, 188027.75, 536821.75, 188136.25, 536821.75, 188053.75, - 536821.75, 187964.75, 536821.75, 188073.25, 536821.75, 187939.25, 536821.75, 188061.75, - 536821.75, 188027.25, 536821.75, 188010.25, 536821.75, 188059.75, 536821.75, 188046.25, - 536821.75, 188000.25, 536821.75, 187921.25, 536821.75, 188012.75, 536821.75, 187950.25, - 536821.75, 187929.75, 536821.75, 188056.75, 536821.75, 188058.25, 536821.75, 187968.25, - 536821.75, 187999.75, 536821.75, 188002.75, 536821.75, 188041.75, 536821.75, 187963.25, - 536821.75, 187957.25, 536821.75, 187958.75, 536821.75, 188102.75, 536821.75, 188105.25, - 536821.75, 187965.25, 536821.75, 187959.75, 536821.75, 187916.75, 536821.75, 187935.25, - 536821.75, 188032.25, 536821.75, 188075.75, 536821.75, 187941.75, 536821.75, 188139.25, - 536821.75, 188103.75, 536821.75, 188077.75, 536821.75, 188052.75, 536822.25, 188046.75, - 536822.25, 188059.25, 536822.25, 188067.25, 536822.25, 187940.75, 536822.25, 188060.75, - 536822.25, 188075.75, 536822.25, 188077.75, 536822.25, 187993.25, 536822.25, 188031.75, - 536822.25, 188053.25, 536822.25, 187934.75, 536822.25, 187910.75, 536822.25, 188032.25, - 536822.25, 187969.75, 536822.25, 187935.25, 536822.25, 187963.25, 536822.25, 187961.25, - 536822.25, 188058.25, 536822.25, 188084.25, 536822.25, 188159.75, 536822.25, 187959.75, - 536822.25, 188003.75, 536822.25, 187972.75, 536822.25, 187941.75, 536822.25, 188000.25, - 536822.25, 188041.75, 536822.25, 188004.75, 536822.25, 187953.75, 536822.25, 187965.75, - 536822.25, 188080.25, 536822.25, 188015.75, 536822.25, 188002.75, 536822.25, 188022.75, - 536822.25, 188121.25, 536822.25, 188009.75, 536822.25, 188038.75, 536822.25, 188073.25, - 536822.25, 188027.25, 536822.25, 188155.25, 536822.25, 188136.25, 536822.25, 188060.25, - 536822.25, 188102.75, 536822.25, 188061.75, 536822.25, 187966.75, 536822.25, 188107.75, - 536822.25, 188072.75, 536822.25, 188078.75, 536822.25, 188103.75, 536822.25, 187991.25, - 536822.25, 187929.75, 536822.25, 188010.75, 536822.25, 187952.25, 536822.25, 187965.25, - 536822.25, 188079.75, 536822.25, 187990.75, 536822.25, 188056.25, 536822.25, 188029.75, - 536822.25, 188030.75, 536822.25, 187994.25, 536822.25, 188021.25, 536822.25, 187971.25, - 536822.25, 187958.25, 536822.25, 188051.25, 536822.25, 187942.25, 536822.25, 187933.75, - 536822.25, 187914.25, 536822.25, 188019.75, 536822.25, 187939.75, 536822.25, 187959.25, - 536822.25, 187927.75, 536822.25, 188040.75, 536822.25, 187928.25, 536822.25, 188020.75, - 536822.25, 187958.75, 536822.25, 188136.75, 536822.25, 188019.25, 536822.25, 188026.25, - 536822.25, 188160.25, 536822.25, 187964.25, 536822.25, 188009.25, 536822.25, 188134.75, - 536822.25, 188087.75, 536822.75, 187958.75, 536822.75, 188042.25, 536822.75, 188062.75, - 536822.75, 188021.25, 536822.75, 187926.25, 536822.75, 187930.25, 536822.75, 187997.25, - 536822.75, 187960.25, 536822.75, 187911.75, 536822.75, 188104.25, 536822.75, 188074.75, - 536822.75, 188076.75, 536822.75, 188135.75, 536822.75, 187933.25, 536822.75, 188028.75, - 536822.75, 188020.25, 536822.75, 187934.75, 536822.75, 188085.25, 536822.75, 188001.25, - 536822.75, 188058.25, 536822.75, 187966.25, 536822.75, 188075.75, 536822.75, 187992.25, - 536822.75, 187999.25, 536822.75, 188077.25, 536822.75, 187968.25, 536822.75, 187963.75, - 536822.75, 187927.75, 536822.75, 188010.25, 536822.75, 187957.75, 536822.75, 188028.25, - 536822.75, 187940.75, 536822.75, 187927.25, 536822.75, 188103.25, 536822.75, 188052.25, - 536822.75, 188075.25, 536822.75, 187971.25, 536822.75, 187928.25, 536822.75, 188026.25, - 536822.75, 187936.25, 536822.75, 187992.75, 536822.75, 187956.25, 536822.75, 187987.25, - 536822.75, 188006.25, 536822.75, 187939.75, 536822.75, 188003.75, 536822.75, 188077.75, - 536822.75, 188079.75, 536822.75, 187938.25, 536822.75, 187969.25, 536822.75, 187996.75, - 536822.75, 187962.25, 536822.75, 188010.75, 536822.75, 188030.75, 536822.75, 188158.25, - 536822.75, 188041.25, 536822.75, 188001.75, 536822.75, 188039.25, 536822.75, 187920.25, - 536822.75, 188135.25, 536822.75, 187931.25, 536822.75, 188079.25, 536822.75, 188055.25, - 536822.75, 188053.75, 536822.75, 188058.75, 536822.75, 188023.75, 536823.25, 187996.75, - 536823.25, 187998.25, 536823.25, 187931.25, 536823.25, 187935.75, 536823.25, 187931.75, - 536823.25, 188026.75, 536823.25, 188137.75, 536823.25, 188073.25, 536823.25, 188021.75, - 536823.25, 188158.25, 536823.25, 188073.75, 536823.25, 188031.75, 536823.25, 187961.25, - 536823.25, 188039.25, 536823.25, 187938.25, 536823.25, 188030.75, 536823.25, 188056.75, - 536823.25, 187957.25, 536823.25, 187924.25, 536823.25, 187953.75, 536823.25, 187911.25, - 536823.25, 188136.75, 536823.25, 188010.75, 536823.25, 188153.25, 536823.25, 187936.75, - 536823.25, 188146.25, 536823.25, 187948.25, 536823.25, 187988.75, 536823.25, 188028.25, - 536823.25, 187973.75, 536823.25, 188074.75, 536823.25, 188052.75, 536823.25, 187971.75, - 536823.25, 187970.25, 536823.25, 188074.25, 536823.25, 188057.75, 536823.25, 188104.75, - 536823.25, 188011.25, 536823.25, 188014.75, 536823.25, 187940.25, 536823.25, 187987.25, - 536823.25, 187956.25, 536823.25, 187930.75, 536823.25, 188152.75, 536823.25, 187926.75, - 536823.25, 188052.25, 536823.25, 187991.75, 536823.25, 187967.75, 536823.25, 188078.25, - 536823.25, 188060.75, 536823.25, 188157.25, 536823.25, 188136.25, 536823.25, 188010.25, - 536823.25, 187961.75, 536823.25, 188011.75, 536823.25, 187963.25, 536823.25, 187996.25, - 536823.25, 187957.75, 536823.25, 188042.25, 536823.25, 188075.75, 536823.25, 188025.25, - 536823.25, 187997.25, 536823.25, 187938.75, 536823.25, 187955.75, 536823.25, 187935.25, - 536823.25, 188041.75, 536823.25, 187933.25, 536823.25, 188020.75, 536823.25, 188155.25, - 536823.25, 187960.75, 536823.25, 188157.75, 536823.25, 188128.75, 536823.25, 187944.75, - 536823.25, 188076.75, 536823.25, 187939.25, 536823.25, 188103.25, 536823.25, 187958.25, - 536823.25, 188147.25, 536823.25, 188105.25, 536823.25, 188054.75, 536823.25, 188116.25, - 536823.75, 187986.25, 536823.75, 187932.75, 536823.75, 187931.25, 536823.75, 188119.25, - 536823.75, 187931.75, 536823.75, 188073.75, 536823.75, 187937.75, 536823.75, 188135.25, - 536823.75, 187961.25, 536823.75, 187938.75, 536823.75, 187996.75, 536823.75, 188042.25, - 536823.75, 188152.25, 536823.75, 188003.75, 536823.75, 188056.75, 536823.75, 188041.25, - 536823.75, 188105.25, 536823.75, 188065.75, 536823.75, 187957.75, 536823.75, 188053.25, - 536823.75, 188038.25, 536823.75, 187957.25, 536823.75, 188022.75, 536823.75, 188075.25, - 536823.75, 188021.25, 536823.75, 187925.75, 536823.75, 187936.75, 536823.75, 187988.75, - 536823.75, 187939.25, 536823.75, 188134.75, 536823.75, 188151.25, 536823.75, 188104.75, - 536823.75, 188135.75, 536823.75, 187967.25, 536823.75, 188052.75, 536823.75, 187960.75, - 536823.75, 188047.75, 536823.75, 188103.75, 536823.75, 188004.75, 536823.75, 188136.75, - 536823.75, 187970.25, 536823.75, 188102.25, 536823.75, 188076.75, 536823.75, 187967.75, - 536823.75, 188074.75, 536823.75, 188039.75, 536823.75, 188072.75, 536823.75, 188041.75, - 536823.75, 188061.75, 536823.75, 188025.75, 536823.75, 188054.25, 536823.75, 188020.25, - 536823.75, 188011.25, 536823.75, 188159.75, 536823.75, 188015.75, 536823.75, 187956.25, - 536823.75, 187955.75, 536823.75, 188145.25, 536823.75, 188001.25, 536823.75, 188074.25, - 536823.75, 188157.75, 536823.75, 187954.75, 536823.75, 188010.25, 536823.75, 187926.75, - 536823.75, 187924.75, 536823.75, 187997.25, 536823.75, 188026.25, 536823.75, 188058.25, - 536823.75, 187947.25, 536823.75, 187969.75, 536823.75, 188157.25, 536823.75, 187930.75, - 536823.75, 188007.75, 536823.75, 187938.25, 536823.75, 187995.25, 536823.75, 187996.25, - 536824.25, 187965.75, 536824.25, 187966.25, 536824.25, 188142.75, 536824.25, 187998.25, - 536824.25, 188060.25, 536824.25, 187962.75, 536824.25, 188068.25, 536824.25, 187994.75, - 536824.25, 188011.75, 536824.25, 188053.75, 536824.25, 187959.25, 536824.25, 187935.25, - 536824.25, 187937.75, 536824.25, 188132.75, 536824.25, 187954.75, 536824.25, 188021.75, - 536824.25, 187938.75, 536824.25, 187986.25, 536824.25, 187927.25, 536824.25, 188027.25, - 536824.25, 188145.75, 536824.25, 188057.25, 536824.25, 188153.75, 536824.25, 187935.75, - 536824.25, 188029.75, 536824.25, 188134.75, 536824.25, 187960.25, 536824.25, 187996.75, - 536824.25, 187959.75, 536824.25, 187943.25, 536824.25, 188027.75, 536824.25, 187984.75, - 536824.25, 187932.25, 536824.25, 188039.25, 536824.25, 188151.75, 536824.25, 188150.75, - 536824.25, 188041.25, 536824.25, 188105.25, 536824.25, 188025.25, 536824.25, 188104.25, - 536824.25, 187968.25, 536824.25, 188025.75, 536824.25, 187962.25, 536824.25, 188010.75, - 536824.25, 187942.75, 536824.25, 187926.75, 536824.25, 188145.25, 536824.25, 188042.75, - 536824.25, 188021.25, 536824.25, 188158.75, 536824.25, 187987.75, 536824.25, 187936.75, - 536824.25, 187928.25, 536824.25, 187955.25, 536824.25, 188136.25, 536824.25, 187954.25, - 536824.25, 188054.25, 536824.25, 187936.25, 536824.25, 187923.25, 536824.25, 188151.25, - 536824.25, 187997.75, 536824.25, 187968.75, 536824.25, 187924.25, 536824.25, 187983.25, - 536824.25, 187926.25, 536824.25, 187933.25, 536824.25, 188059.75, 536824.25, 188149.75, - 536824.25, 187970.25, 536824.25, 188031.25, 536824.75, 188149.75, 536824.75, 188028.75, - 536824.75, 188040.75, 536824.75, 187960.75, 536824.75, 188059.75, 536824.75, 187923.25, - 536824.75, 187958.75, 536824.75, 188006.25, 536824.75, 188151.25, 536824.75, 187997.75, - 536824.75, 187928.25, 536824.75, 187955.25, 536824.75, 188043.25, 536824.75, 188022.25, - 536824.75, 188108.75, 536824.75, 187934.25, 536824.75, 187953.25, 536824.75, 187953.75, - 536824.75, 188113.25, 536824.75, 187937.25, 536824.75, 188032.75, 536824.75, 187948.75, - 536824.75, 188063.75, 536824.75, 188134.25, 536824.75, 187964.25, 536824.75, 187942.75, - 536824.75, 188028.25, 536824.75, 188017.75, 536824.75, 188111.25, 536824.75, 188033.25, - 536824.75, 187968.25, 536824.75, 187910.75, 536824.75, 187926.25, 536824.75, 188104.75, - 536824.75, 188071.75, 536824.75, 187932.75, 536824.75, 188054.75, 536824.75, 187911.25, - 536824.75, 188040.25, 536824.75, 187913.75, 536824.75, 187942.25, 536824.75, 187943.25, - 536824.75, 188145.25, 536824.75, 187985.25, 536824.75, 188025.25, 536824.75, 188105.75, - 536824.75, 188027.75, 536824.75, 188160.25, 536824.75, 187943.75, 536824.75, 188056.75, - 536824.75, 187998.75, 536824.75, 187995.75, 536824.75, 188154.75, 536824.75, 188012.25, - 536824.75, 188029.25, 536824.75, 188060.75, 536824.75, 187927.75, 536824.75, 188146.75, - 536824.75, 188025.75, 536824.75, 187963.25, 536824.75, 188150.75, 536824.75, 187993.75, - 536824.75, 187973.25, 536824.75, 188132.75, 536824.75, 188027.25, 536824.75, 187935.75, - 536824.75, 188083.25, 536824.75, 188134.75, 536824.75, 187963.75, 536824.75, 187969.75, - 536824.75, 188005.75, 536824.75, 188133.75, 536824.75, 188135.25, 536824.75, 187994.25, - 536824.75, 187961.75, 536824.75, 187954.75, 536824.75, 187935.25, 536824.75, 187931.75, - 536824.75, 187984.25, 536824.75, 188053.75, 536824.75, 187959.25, 536824.75, 188107.75, - 536824.75, 188007.75, 536824.75, 188011.75, 536824.75, 188032.25, 536824.75, 187911.75, - 536824.75, 187923.75, 536824.75, 187998.25, 536824.75, 188030.25, 536824.75, 188055.25, - 536825.25, 187911.75, 536825.25, 188011.25, 536825.25, 188131.75, 536825.25, 188158.25, - 536825.25, 188005.75, 536825.25, 187994.25, 536825.25, 187998.75, 536825.25, 187959.25, - 536825.25, 187943.75, 536825.25, 188035.75, 536825.25, 187935.75, 536825.25, 188050.75, - 536825.25, 188063.75, 536825.25, 188135.25, 536825.25, 188057.75, 536825.25, 187959.75, - 536825.25, 187933.75, 536825.25, 188029.75, 536825.25, 187995.75, 536825.25, 188156.75, - 536825.25, 188021.25, 536825.25, 188039.25, 536825.25, 187942.25, 536825.25, 187943.25, - 536825.25, 188149.25, 536825.25, 187921.75, 536825.25, 187951.75, 536825.25, 187923.75, - 536825.25, 188042.75, 536825.25, 187935.25, 536825.25, 187984.75, 536825.25, 188022.25, - 536825.25, 187932.25, 536825.25, 187953.25, 536825.25, 187957.75, 536825.25, 188008.25, - 536825.25, 188104.75, 536825.25, 187954.75, 536825.25, 188038.25, 536825.25, 188025.75, - 536825.25, 187937.25, 536825.25, 187983.25, 536825.25, 187942.75, 536825.25, 187967.75, - 536825.25, 188061.75, 536825.25, 188105.75, 536825.25, 188044.75, 536825.25, 188134.25, - 536825.25, 187955.25, 536825.25, 187954.25, 536825.25, 187987.25, 536825.25, 188116.75, - 536825.25, 188142.25, 536825.25, 187990.75, 536825.25, 187970.25, 536825.25, 187926.75, - 536825.25, 187988.25, 536825.25, 188026.25, 536825.25, 188037.25, 536825.25, 188151.75, - 536825.25, 188060.75, 536825.25, 187961.75, 536825.25, 187955.75, 536825.25, 188027.25, - 536825.25, 187925.75, 536825.25, 187965.75, 536825.25, 187997.75, 536825.25, 187993.75, - 536825.25, 188048.75, 536825.25, 188025.25, 536825.25, 188133.75, 536825.25, 188133.25, - 536825.25, 187967.25, 536825.25, 187958.75, 536825.25, 187944.25, 536825.25, 188148.25, - 536825.25, 188027.75, 536825.25, 188118.25, 536825.25, 188055.25, 536825.25, 187963.25, - 536825.25, 188150.25, 536825.25, 188134.75, 536825.25, 188032.25, 536825.75, 188032.25, - 536825.75, 187956.75, 536825.75, 187993.25, 536825.75, 188040.25, 536825.75, 188150.25, - 536825.75, 187992.25, 536825.75, 188108.25, 536825.75, 188054.75, 536825.75, 187998.25, - 536825.75, 188152.25, 536825.75, 188011.75, 536825.75, 188133.25, 536825.75, 187912.25, - 536825.75, 188133.75, 536825.75, 187940.75, 536825.75, 188039.25, 536825.75, 187936.25, - 536825.75, 188027.25, 536825.75, 187958.25, 536825.75, 187992.75, 536825.75, 187956.25, - 536825.75, 188028.75, 536825.75, 188147.75, 536825.75, 187981.75, 536825.75, 187960.75, - 536825.75, 188037.25, 536825.75, 187953.75, 536825.75, 187933.25, 536825.75, 187926.75, - 536825.75, 188101.25, 536825.75, 187934.25, 536825.75, 188132.25, 536825.75, 187957.25, - 536825.75, 188105.25, 536825.75, 188023.75, 536825.75, 188132.75, 536825.75, 188042.75, - 536825.75, 187984.25, 536825.75, 187982.25, 536825.75, 187986.25, 536825.75, 187951.75, - 536825.75, 187976.75, 536825.75, 187926.25, 536825.75, 188153.25, 536825.75, 188033.25, - 536825.75, 187911.25, 536825.75, 188149.25, 536825.75, 188114.75, 536825.75, 188012.75, - 536825.75, 188030.75, 536825.75, 188021.75, 536825.75, 188061.25, 536825.75, 188131.75, - 536825.75, 188024.75, 536825.75, 187998.75, 536825.75, 187994.25, 536825.75, 187952.25, - 536825.75, 187968.75, 536825.75, 188053.75, 536825.75, 187943.75, 536825.75, 188026.75, - 536825.75, 187911.75, 536826.25, 188142.25, 536826.25, 187935.75, 536826.25, 187916.75, - 536826.25, 187998.25, 536826.25, 187931.75, 536826.25, 188043.75, 536826.25, 188130.25, - 536826.25, 188130.75, 536826.25, 187999.75, 536826.25, 188105.75, 536826.25, 188024.75, - 536826.25, 188046.25, 536826.25, 188145.75, 536826.25, 188127.75, 536826.25, 188028.25, - 536826.25, 188156.25, 536826.25, 188031.25, 536826.25, 188131.75, 536826.25, 187933.75, - 536826.25, 188040.75, 536826.25, 187945.25, 536826.25, 187921.25, 536826.25, 187959.75, - 536826.25, 188073.25, 536826.25, 188061.25, 536826.25, 187932.75, 536826.25, 188035.75, - 536826.25, 188053.75, 536826.25, 188036.75, 536826.25, 188014.75, 536826.25, 187920.25, - 536826.25, 188033.75, 536826.25, 188012.25, 536826.25, 187914.75, 536826.25, 188148.75, - 536826.25, 188131.25, 536826.25, 188154.75, 536826.25, 187932.25, 536826.25, 188025.75, - 536826.25, 187927.75, 536826.25, 187982.25, 536826.25, 187985.75, 536826.25, 187966.75, - 536826.25, 188028.75, 536826.25, 187957.75, 536826.25, 187948.25, 536826.25, 188054.25, - 536826.25, 188013.25, 536826.25, 188132.25, 536826.25, 188147.75, 536826.25, 188106.25, - 536826.25, 187934.25, 536826.25, 187962.25, 536826.25, 188061.75, 536826.25, 187970.75, - 536826.25, 188004.25, 536826.25, 188141.25, 536826.25, 188032.75, 536826.25, 187926.75, - 536826.25, 187967.75, 536826.25, 187912.75, 536826.25, 187992.75, 536826.25, 187925.75, - 536826.25, 187951.25, 536826.25, 188110.75, 536826.25, 187990.25, 536826.25, 188043.25, - 536826.25, 187958.75, 536826.25, 188087.75, 536826.25, 187964.75, 536826.25, 188024.25, - 536826.25, 187963.75, 536826.25, 188054.75, 536826.25, 188148.25, 536826.25, 187950.25, - 536826.25, 187930.75, 536826.25, 187986.75, 536826.25, 188011.75, 536826.25, 187999.25, - 536826.25, 187927.25, 536826.25, 188002.75, 536826.25, 187919.25, 536826.25, 188113.75, - 536826.25, 188022.75, 536826.25, 187992.25, 536826.25, 187952.75, 536826.25, 188004.75, - 536826.25, 187991.25, 536826.25, 188039.75, 536826.25, 187934.75, 536826.75, 187934.75, - 536826.75, 188104.25, 536826.75, 187991.25, 536826.75, 188141.75, 536826.75, 187980.25, - 536826.75, 187998.75, 536826.75, 188043.75, 536826.75, 187918.75, 536826.75, 187998.25, - 536826.75, 188037.75, 536826.75, 188016.25, 536826.75, 187992.25, 536826.75, 188073.75, - 536826.75, 188130.25, 536826.75, 187919.25, 536826.75, 188023.25, 536826.75, 188024.75, - 536826.75, 188147.25, 536826.75, 187933.75, 536826.75, 188136.75, 536826.75, 188011.75, - 536826.75, 188031.25, 536826.75, 187999.25, 536826.75, 188040.25, 536826.75, 187956.75, - 536826.75, 188028.25, 536826.75, 187993.75, 536826.75, 188131.75, 536826.75, 187959.75, - 536826.75, 187952.25, 536826.75, 188145.75, 536826.75, 187950.25, 536826.75, 187983.75, - 536826.75, 187968.75, 536826.75, 187956.25, 536826.75, 187919.75, 536826.75, 187921.25, - 536826.75, 188142.75, 536826.75, 188013.25, 536826.75, 188043.25, 536826.75, 188070.75, - 536826.75, 188062.25, 536826.75, 187990.25, 536826.75, 188148.25, 536826.75, 187991.75, - 536826.75, 187951.25, 536826.75, 187927.75, 536826.75, 187950.75, 536826.75, 188150.75, - 536826.75, 187931.25, 536826.75, 188033.75, 536826.75, 188025.75, 536826.75, 188021.75, - 536826.75, 188145.25, 536826.75, 188001.25, 536826.75, 187985.25, 536826.75, 187961.75, - 536826.75, 188106.75, 536826.75, 187990.75, 536826.75, 188053.75, 536826.75, 187981.75, - 536826.75, 188059.75, 536826.75, 188154.25, 536826.75, 187928.25, 536826.75, 188012.25, - 536826.75, 188035.75, 536826.75, 188070.25, 536826.75, 187934.25, 536826.75, 187926.75, - 536826.75, 188148.75, 536826.75, 188032.75, 536826.75, 187932.25, 536826.75, 187925.25, - 536826.75, 188054.75, 536826.75, 187989.25, 536826.75, 188131.25, 536826.75, 188061.75, - 536826.75, 187958.25, 536826.75, 188139.75, 536826.75, 187911.75, 536826.75, 187962.25, - 536826.75, 188029.25, 536826.75, 188036.75, 536826.75, 188129.75, 536826.75, 188132.25, - 536826.75, 188105.75, 536826.75, 187933.25, 536826.75, 188022.25, 536826.75, 188009.25, - 536826.75, 187957.25, 536826.75, 188113.25, 536826.75, 187984.75, 536827.25, 187982.25, - 536827.25, 188022.25, 536827.25, 187957.75, 536827.25, 188128.25, 536827.25, 188129.75, - 536827.25, 188046.75, 536827.25, 188155.25, 536827.25, 187958.25, 536827.25, 188138.25, - 536827.25, 187948.75, 536827.25, 188055.25, 536827.25, 187926.75, 536827.25, 187952.25, - 536827.25, 188034.75, 536827.25, 187949.75, 536827.25, 188012.25, 536827.25, 188067.25, - 536827.25, 187990.75, 536827.25, 188044.25, 536827.25, 187949.25, 536827.25, 188030.75, - 536827.25, 188145.25, 536827.25, 188160.25, 536827.25, 188059.25, 536827.25, 187931.25, - 536827.25, 188159.25, 536827.25, 188129.25, 536827.25, 188106.75, 536827.25, 187926.25, - 536827.25, 188027.25, 536827.25, 188068.75, 536827.25, 188069.25, 536827.25, 187951.75, - 536827.25, 188000.75, 536827.25, 188061.25, 536827.25, 187962.75, 536827.25, 188145.75, - 536827.25, 188062.75, 536827.25, 188054.25, 536827.25, 187930.75, 536827.25, 188024.25, - 536827.25, 188040.75, 536827.25, 188029.75, 536827.25, 188003.75, 536827.25, 187965.25, - 536827.25, 187999.25, 536827.25, 188122.75, 536827.25, 188031.25, 536827.25, 188147.25, - 536827.25, 188130.75, 536827.25, 187913.25, 536827.25, 188022.75, 536827.25, 187919.25, - 536827.25, 188040.25, 536827.25, 187931.75, 536827.25, 187910.75, 536827.25, 187991.25, - 536827.25, 188130.25, 536827.25, 188106.25, 536827.25, 188033.75, 536827.25, 187981.25, - 536827.25, 188026.75, 536827.25, 188013.25, 536827.25, 187964.75, 536827.75, 188028.75, - 536827.75, 188148.25, 536827.75, 187949.25, 536827.75, 187980.25, 536827.75, 188144.25, - 536827.75, 188058.75, 536827.75, 187960.75, 536827.75, 188068.75, 536827.75, 187931.25, - 536827.75, 188106.25, 536827.75, 187971.75, 536827.75, 187979.75, 536827.75, 188001.75, - 536827.75, 188071.25, 536827.75, 187928.75, 536827.75, 188137.75, 536827.75, 188137.25, - 536827.75, 187999.75, 536827.75, 188106.75, 536827.75, 187982.75, 536827.75, 188121.25, - 536827.75, 188023.25, 536827.75, 188031.75, 536827.75, 188041.25, 536827.75, 187929.75, - 536827.75, 188129.75, 536827.75, 187948.75, 536827.75, 188002.25, 536827.75, 187961.25, - 536827.75, 187914.25, 536827.75, 188144.75, 536827.75, 188044.75, 536827.75, 188059.75, - 536827.75, 188107.25, 536827.75, 187989.75, 536827.75, 187917.25, 536827.75, 187958.75, - 536827.75, 187954.75, 536827.75, 187947.75, 536827.75, 187990.25, 536827.75, 188013.75, - 536827.75, 188023.75, 536827.75, 188138.25, 536827.75, 188069.25, 536827.75, 188034.25, - 536827.75, 188007.75, 536827.75, 188143.25, 536827.75, 187930.75, 536827.75, 188025.25, - 536827.75, 187955.75, 536827.75, 188045.25, 536827.75, 188012.75, 536827.75, 188127.25, - 536827.75, 187937.25, 536827.75, 187960.25, 536827.75, 188000.25, 536827.75, 187952.25, - 536827.75, 187912.75, 536827.75, 187987.75, 536827.75, 187948.25, 536827.75, 188040.75, - 536827.75, 187913.25, 536827.75, 188069.75, 536827.75, 188127.75, 536827.75, 187946.25, - 536827.75, 187917.75, 536827.75, 187962.75, 536827.75, 188060.75, 536827.75, 188025.75, - 536827.75, 188146.25, 536827.75, 188028.25, 536827.75, 187940.75, 536827.75, 188070.25, - 536827.75, 188070.75, 536827.75, 188055.25, 536827.75, 188075.25, 536827.75, 188048.75, - 536827.75, 187963.75, 536827.75, 187989.25, 536827.75, 187981.75, 536827.75, 187929.25, - 536827.75, 188004.25, 536827.75, 187930.25, 536827.75, 187922.75, 536827.75, 188128.75, - 536827.75, 188055.75, 536827.75, 187942.25, 536827.75, 188004.75, 536827.75, 187952.75, - 536827.75, 188067.25, 536828.25, 187952.75, 536828.25, 188007.75, 536828.25, 188026.75, - 536828.25, 188058.75, 536828.25, 188018.75, 536828.25, 188068.75, 536828.25, 187931.25, - 536828.25, 187939.25, 536828.25, 188005.75, 536828.25, 188128.75, 536828.25, 188071.25, - 536828.25, 187959.75, 536828.25, 187979.75, 536828.25, 188031.25, 536828.25, 188012.25, - 536828.25, 187930.25, 536828.25, 188137.75, 536828.25, 187947.25, 536828.25, 187999.75, - 536828.25, 188024.75, 536828.25, 187963.25, 536828.25, 188145.25, 536828.25, 187929.75, - 536828.25, 188032.75, 536828.25, 187916.75, 536828.25, 188011.75, 536828.25, 188004.25, - 536828.25, 188060.25, 536828.25, 188023.25, 536828.25, 188143.75, 536828.25, 187962.25, - 536828.25, 187929.25, 536828.25, 187948.75, 536828.25, 188002.25, 536828.25, 188142.25, - 536828.25, 188070.75, 536828.25, 187982.25, 536828.25, 187961.25, 536828.25, 188059.75, - 536828.25, 188066.75, 536828.25, 187989.25, 536828.25, 188070.25, 536828.25, 188044.75, - 536828.25, 187957.25, 536828.25, 187963.75, 536828.25, 187954.75, 536828.25, 188060.75, - 536828.25, 187958.75, 536828.25, 188147.75, 536828.25, 187951.75, 536828.25, 188074.75, - 536828.25, 188023.75, 536828.25, 188146.25, 536828.25, 188013.75, 536828.25, 188061.75, - 536828.25, 187917.75, 536828.25, 188064.75, 536828.25, 188027.25, 536828.25, 188106.25, - 536828.25, 187930.75, 536828.25, 187990.25, 536828.25, 188054.75, 536828.25, 187955.75, - 536828.25, 187911.25, 536828.25, 187981.25, 536828.25, 188129.25, 536828.25, 188127.75, - 536828.25, 187987.25, 536828.25, 188127.25, 536828.25, 188057.75, 536828.25, 187912.75, - 536828.25, 187952.25, 536828.25, 188136.25, 536828.25, 188148.25, 536828.25, 188000.25, - 536828.25, 187960.25, 536828.25, 188049.75, 536828.25, 188012.75, 536828.25, 187948.25, - 536828.25, 187922.25, 536828.25, 187913.25, 536828.25, 188040.75, 536828.75, 187913.25, - 536828.75, 188011.25, 536828.75, 188041.75, 536828.75, 188026.25, 536828.75, 187952.75, - 536828.75, 188144.25, 536828.75, 188026.75, 536828.75, 187960.75, 536828.75, 187934.25, - 536828.75, 188136.25, 536828.75, 188057.25, 536828.75, 188055.75, 536828.75, 187945.75, - 536828.75, 187928.25, 536828.75, 188065.75, 536828.75, 188125.75, 536828.75, 187912.75, - 536828.75, 187928.75, 536828.75, 188135.75, 536828.75, 187987.25, 536828.75, 188045.25, - 536828.75, 187958.25, 536828.75, 188071.75, 536828.75, 187994.25, 536828.75, 188148.75, - 536828.75, 187990.75, 536828.75, 188034.75, 536828.75, 188072.25, 536828.75, 187999.75, - 536828.75, 188043.25, 536828.75, 187946.25, 536828.75, 188143.25, 536828.75, 188014.25, - 536828.75, 188000.75, 536828.75, 187918.25, 536828.75, 187959.25, 536828.75, 187947.75, - 536828.75, 187956.75, 536828.75, 188043.75, 536828.75, 187927.25, 536828.75, 188110.75, - 536828.75, 187929.75, 536828.75, 187961.75, 536828.75, 188145.25, 536828.75, 188114.75, - 536828.75, 188008.25, 536828.75, 188069.25, 536828.75, 188034.25, 536828.75, 188023.75, - 536828.75, 187913.75, 536828.75, 188126.25, 536828.75, 187951.75, 536828.75, 188044.75, - 536828.75, 188126.75, 536828.75, 188145.75, 536828.75, 187927.75, 536828.75, 188068.25, - 536828.75, 188136.75, 536828.75, 187916.25, 536828.75, 187980.75, 536828.75, 187929.25, - 536828.75, 188055.25, 536828.75, 187989.25, 536828.75, 188144.75, 536828.75, 188107.25, - 536828.75, 188128.25, 536828.75, 187989.75, 536828.75, 188013.25, 536829.25, 188072.25, - 536829.25, 187914.75, 536829.25, 188145.75, 536829.25, 187914.25, 536829.25, 188055.25, - 536829.25, 188042.75, 536829.25, 188059.75, 536829.25, 187953.25, 536829.25, 188080.75, - 536829.25, 188144.75, 536829.25, 187926.25, 536829.25, 187956.25, 536829.25, 187961.25, - 536829.25, 187923.75, 536829.25, 187917.25, 536829.25, 188056.25, 536829.25, 187951.25, - 536829.25, 188053.75, 536829.25, 188041.25, 536829.25, 188042.25, 536829.25, 188126.75, - 536829.25, 188009.75, 536829.25, 187986.25, 536829.25, 188030.25, 536829.25, 188008.25, - 536829.25, 187964.75, 536829.25, 187991.25, 536829.25, 188060.25, 536829.25, 188031.75, - 536829.25, 187971.25, 536829.25, 187950.25, 536829.25, 188124.75, 536829.25, 188106.75, - 536829.25, 188023.75, 536829.25, 188062.75, 536829.25, 188024.75, 536829.25, 188056.75, - 536829.25, 188032.25, 536829.25, 188107.75, 536829.25, 187915.25, 536829.25, 187926.75, - 536829.25, 187944.75, 536829.25, 187989.25, 536829.25, 188124.25, 536829.25, 187938.75, - 536829.25, 187983.75, 536829.25, 188106.25, 536829.25, 187946.25, 536829.25, 188063.25, - 536829.25, 188127.75, 536829.25, 188057.75, 536829.25, 187987.75, 536829.25, 188034.75, - 536829.25, 188014.75, 536829.25, 188141.75, 536829.25, 187928.75, 536829.25, 187960.75, - 536829.25, 187985.75, 536829.25, 188125.75, 536829.25, 188151.25, 536829.25, 187945.75, - 536829.25, 187986.75, 536829.25, 188044.25, 536829.25, 188027.75, 536829.25, 188155.75, - 536829.25, 187933.25, 536829.25, 188136.25, 536829.25, 188069.75, 536829.25, 187934.25, - 536829.25, 188007.25, 536829.25, 188033.75, 536829.25, 188004.75, 536829.25, 187934.75, - 536829.25, 187935.25, 536829.25, 188055.75, 536829.25, 188068.75, 536829.25, 188142.75, - 536829.25, 188024.25, 536829.25, 188010.25, 536829.25, 187935.75, 536829.25, 188001.25, - 536829.25, 188045.75, 536829.25, 187990.25, 536829.25, 187923.25, 536829.25, 188013.75, - 536829.75, 188041.75, 536829.75, 188061.75, 536829.75, 187917.25, 536829.75, 187956.25, - 536829.75, 188072.25, 536829.75, 188140.25, 536829.75, 188026.75, 536829.75, 188042.75, - 536829.75, 188054.75, 536829.75, 187991.25, 536829.75, 187935.75, 536829.75, 187951.25, - 536829.75, 187986.25, 536829.75, 188010.25, 536829.75, 188056.25, 536829.75, 188069.25, - 536829.75, 188024.25, 536829.75, 188032.25, 536829.75, 187914.75, 536829.75, 188055.25, - 536829.75, 187917.75, 536829.75, 188068.75, 536829.75, 187945.25, 536829.75, 188000.75, - 536829.75, 187946.25, 536829.75, 187914.25, 536829.75, 188160.25, 536829.75, 187952.75, - 536829.75, 188001.25, 536829.75, 188041.25, 536829.75, 187980.75, 536829.75, 187953.75, - 536829.75, 187989.25, 536829.75, 188058.25, 536829.75, 188014.75, 536829.75, 188045.25, - 536829.75, 187934.75, 536829.75, 187915.25, 536829.75, 188044.75, 536829.75, 187949.75, - 536829.75, 187927.75, 536829.75, 188033.75, 536829.75, 188145.25, 536829.75, 188055.75, - 536829.75, 188126.25, 536829.75, 188043.25, 536829.75, 187913.75, 536829.75, 187990.25, - 536829.75, 187926.25, 536829.75, 188143.25, 536829.75, 187927.25, 536829.75, 188013.75, - 536829.75, 187955.75, 536829.75, 188000.25, 536829.75, 188071.75, 536829.75, 188027.75, - 536829.75, 187928.25, 536829.75, 187986.75, 536829.75, 188049.25, 536829.75, 188134.25, - 536829.75, 188031.75, 536829.75, 187934.25, 536829.75, 187985.75, 536829.75, 188064.25, - 536829.75, 188106.75, 536829.75, 187930.25, 536829.75, 188124.25, 536829.75, 188020.75, - 536829.75, 187926.75, 536829.75, 187958.25, 536829.75, 187961.25, 536829.75, 187989.75, - 536829.75, 187910.75, 536829.75, 187960.25, 536829.75, 188125.75, 536829.75, 188145.75, - 536829.75, 188125.25, 536829.75, 187944.75, 536829.75, 187944.25, 536829.75, 187957.25, - 536829.75, 188011.25, 536829.75, 188108.25, 536829.75, 188053.75, 536829.75, 187963.75, - 536829.75, 188001.75, 536829.75, 187994.25, 536829.75, 188031.25, 536829.75, 188034.75, - 536830.25, 188034.75, 536830.25, 188139.25, 536830.25, 188148.25, 536830.25, 187988.25, - 536830.25, 187957.25, 536830.25, 188009.75, 536830.25, 188050.75, 536830.25, 188001.75, - 536830.25, 188062.75, 536830.25, 187990.75, 536830.25, 188041.75, 536830.25, 188140.25, - 536830.25, 188139.75, 536830.25, 187916.25, 536830.25, 187951.75, 536830.25, 187926.75, - 536830.25, 187913.25, 536830.25, 188015.25, 536830.25, 188108.25, 536830.25, 188123.75, - 536830.25, 188045.75, 536830.25, 188149.75, 536830.25, 188034.25, 536830.25, 188062.25, - 536830.25, 187933.25, 536830.25, 188122.75, 536830.25, 188052.25, 536830.25, 187917.75, - 536830.25, 187918.25, 536830.25, 188069.25, 536830.25, 188124.75, 536830.25, 188064.75, - 536830.25, 187957.75, 536830.25, 187942.75, 536830.25, 188054.25, 536830.25, 188027.25, - 536830.25, 188007.75, 536830.25, 188014.25, 536830.25, 188043.75, 536830.25, 188061.75, - 536830.25, 188136.75, 536830.25, 187952.25, 536830.25, 188045.25, 536830.25, 187933.75, - 536830.25, 188061.25, 536830.25, 188007.25, 536830.25, 188069.75, 536830.25, 188036.25, - 536830.25, 188082.75, 536830.25, 188030.25, 536830.25, 188141.25, 536830.25, 188042.25, - 536830.25, 187948.75, 536830.25, 188057.25, 536830.25, 188055.75, 536830.25, 188107.25, - 536830.25, 188063.25, 536830.25, 188066.75, 536830.25, 187967.75, 536830.25, 188005.25, - 536830.25, 187945.75, 536830.25, 187944.25, 536830.25, 188030.75, 536830.25, 187934.75, - 536830.25, 188073.25, 536830.25, 187924.75, 536830.25, 188025.25, 536830.25, 187949.25, - 536830.25, 187926.25, 536830.25, 188032.75, 536830.25, 187912.75, 536830.25, 188063.75, - 536830.25, 188053.25, 536830.75, 188146.75, 536830.75, 188132.25, 536830.75, 187912.75, - 536830.75, 188131.75, 536830.75, 188138.75, 536830.75, 188015.75, 536830.75, 187983.75, - 536830.75, 188046.25, 536830.75, 188130.75, 536830.75, 188140.75, 536830.75, 188107.75, - 536830.75, 188040.25, 536830.75, 187950.25, 536830.75, 187943.25, 536830.75, 187987.25, - 536830.75, 187947.75, 536830.75, 188108.75, 536830.75, 188051.25, 536830.75, 188014.25, - 536830.75, 188016.75, 536830.75, 188025.25, 536830.75, 188151.25, 536830.75, 188008.25, - 536830.75, 187974.25, 536830.75, 187942.25, 536830.75, 188046.75, 536830.75, 187941.25, - 536830.75, 188044.75, 536830.75, 188064.25, 536830.75, 187925.75, 536830.75, 187956.75, - 536830.75, 187948.25, 536830.75, 187922.75, 536830.75, 188138.25, 536830.75, 188111.75, - 536830.75, 188121.75, 536830.75, 188156.25, 536830.75, 188073.25, 536830.75, 187953.75, - 536830.75, 187992.25, 536830.75, 188024.75, 536830.75, 188068.25, 536830.75, 188135.75, - 536830.75, 188076.75, 536830.75, 187956.25, 536830.75, 188006.25, 536830.75, 187925.25, - 536830.75, 187991.75, 536830.75, 188002.25, 536830.75, 188052.75, 536830.75, 187939.75, - 536830.75, 188077.75, 536830.75, 187946.25, 536830.75, 187918.75, 536830.75, 187919.25, - 536830.75, 188124.75, 536830.75, 187966.75, 536830.75, 188036.75, 536830.75, 188002.75, - 536830.75, 188053.75, 536830.75, 188073.75, 536830.75, 188064.75, 536830.75, 188132.75, - 536830.75, 187914.75, 536830.75, 188122.25, 536830.75, 188070.25, 536830.75, 188065.75, - 536830.75, 187954.25, 536830.75, 187911.75, 536830.75, 188122.75, 536830.75, 188015.25, - 536830.75, 188142.75, 536830.75, 188052.25, 536830.75, 188137.75, 536830.75, 188141.75, - 536830.75, 188001.25, 536830.75, 187934.25, 536830.75, 187913.25, 536830.75, 188123.75, - 536830.75, 187943.75, 536830.75, 188055.25, 536830.75, 187923.75, 536830.75, 188001.75, - 536830.75, 188062.75, 536830.75, 187990.75, 536830.75, 188018.25, 536830.75, 188070.75, - 536830.75, 187972.75, 536830.75, 188139.25, 536830.75, 188113.25, 536830.75, 188028.25, - 536830.75, 187960.75, 536830.75, 187933.75, 536830.75, 187924.25, 536830.75, 188076.25, - 536831.25, 187992.75, 536831.25, 188122.75, 536831.25, 187972.25, 536831.25, 188081.75, - 536831.25, 187988.25, 536831.25, 188123.25, 536831.25, 188070.75, 536831.25, 188059.25, - 536831.25, 187991.25, 536831.25, 188008.75, 536831.25, 187945.75, 536831.25, 188026.75, - 536831.25, 188136.75, 536831.25, 187943.25, 536831.25, 188028.25, 536831.25, 187985.25, - 536831.25, 188076.25, 536831.25, 188141.75, 536831.25, 187924.25, 536831.25, 188055.75, - 536831.25, 188051.75, 536831.25, 188153.25, 536831.25, 187951.25, 536831.25, 188052.25, - 536831.25, 187914.75, 536831.25, 188025.75, 536831.25, 188034.25, 536831.25, 188108.25, - 536831.25, 188054.75, 536831.25, 187992.25, 536831.25, 187954.25, 536831.25, 187990.75, - 536831.25, 188001.75, 536831.25, 188068.25, 536831.25, 187961.25, 536831.25, 187913.25, - 536831.25, 188054.25, 536831.25, 188069.25, 536831.25, 188051.25, 536831.25, 188006.75, - 536831.25, 188076.75, 536831.25, 188130.25, 536831.25, 187947.25, 536831.25, 187996.75, - 536831.25, 188140.75, 536831.25, 188146.25, 536831.25, 187988.75, 536831.25, 187919.25, - 536831.25, 187918.75, 536831.25, 188015.75, 536831.25, 188050.75, 536831.25, 187944.25, - 536831.25, 187957.75, 536831.25, 188032.75, 536831.25, 188062.75, 536831.25, 187947.75, - 536831.25, 187926.75, 536831.25, 187942.75, 536831.25, 188055.25, 536831.25, 188147.25, - 536831.25, 188045.25, 536831.25, 187918.25, 536831.25, 188142.75, 536831.25, 188067.25, - 536831.25, 188150.25, 536831.25, 188001.25, 536831.25, 188131.75, 536831.25, 188072.25, - 536831.25, 188157.75, 536831.25, 188151.75, 536831.25, 187923.75, 536831.25, 188137.75, - 536831.25, 188145.75, 536831.25, 188142.25, 536831.25, 188122.25, 536831.25, 187980.25, - 536831.25, 187952.75, 536831.25, 187923.25, 536831.25, 187941.75, 536831.25, 188008.25, - 536831.25, 187925.75, 536831.25, 188014.25, 536831.25, 187948.75, 536831.25, 188093.25, - 536831.25, 187925.25, 536831.25, 188046.75, 536831.25, 188014.75, 536831.25, 188061.75, - 536831.25, 188131.25, 536831.25, 188024.75, 536831.25, 187950.25, 536831.25, 188107.75, - 536831.25, 187989.25, 536831.25, 188052.75, 536831.25, 188027.75, 536831.25, 187911.75, - 536831.25, 188156.25, 536831.25, 187953.75, 536831.25, 188132.25, 536831.25, 188111.75, - 536831.25, 188065.25, 536831.25, 187948.25, 536831.25, 188121.75, 536831.25, 187986.75, - 536831.25, 188138.75, 536831.25, 188138.25, 536831.25, 188035.75, 536831.25, 188031.25, - 536831.25, 188064.25, 536831.25, 188063.25, 536831.25, 188028.75, 536831.25, 188121.25, - 536831.25, 188066.25, 536831.75, 188149.25, 536831.75, 188107.75, 536831.75, 188121.75, - 536831.75, 187981.25, 536831.75, 188015.25, 536831.75, 187974.25, 536831.75, 187922.75, - 536831.75, 188121.25, 536831.75, 187951.25, 536831.75, 188049.25, 536831.75, 187977.75, - 536831.75, 187987.75, 536831.75, 187912.75, 536831.75, 188065.25, 536831.75, 188141.25, - 536831.75, 188108.25, 536831.75, 188046.75, 536831.75, 188029.25, 536831.75, 187946.25, - 536831.75, 187923.75, 536831.75, 187952.25, 536831.75, 187955.75, 536831.75, 188016.25, - 536831.75, 187949.75, 536831.75, 187984.25, 536831.75, 187956.25, 536831.75, 188014.75, - 536831.75, 188109.25, 536831.75, 187923.25, 536831.75, 187942.25, 536831.75, 188008.25, - 536831.75, 188075.25, 536831.75, 188025.25, 536831.75, 188006.25, 536831.75, 188045.75, - 536831.75, 188001.25, 536831.75, 188004.75, 536831.75, 188136.25, 536831.75, 188046.25, - 536831.75, 187991.75, 536831.75, 187971.25, 536831.75, 188059.75, 536831.75, 188073.25, - 536831.75, 188068.75, 536831.75, 188074.75, 536831.75, 188060.25, 536831.75, 188039.75, - 536831.75, 188131.75, 536831.75, 187947.75, 536831.75, 188002.25, 536831.75, 187962.75, - 536831.75, 187982.75, 536831.75, 188050.75, 536831.75, 188155.75, 536831.75, 188078.25, - 536831.75, 188077.25, 536831.75, 187944.25, 536831.75, 187919.25, 536831.75, 187972.75, - 536831.75, 188137.25, 536831.75, 188076.75, 536831.75, 188139.75, 536831.75, 188051.75, - 536831.75, 187921.75, 536831.75, 188140.75, 536831.75, 188070.25, 536831.75, 188140.25, - 536831.75, 188001.75, 536831.75, 188119.75, 536831.75, 188013.25, 536831.75, 188028.25, - 536831.75, 187973.25, 536831.75, 187954.75, 536831.75, 188058.75, 536831.75, 188020.75, - 536831.75, 187985.25, 536831.75, 188108.75, 536831.75, 188139.25, 536831.75, 188049.75, - 536831.75, 188004.25, 536831.75, 188054.75, 536831.75, 187938.25, 536831.75, 188073.75, - 536831.75, 187945.75, 536831.75, 188120.75, 536831.75, 188009.25, 536831.75, 187941.25, - 536831.75, 187932.25, 536832.25, 187941.25, 536832.25, 187920.75, 536832.25, 187950.75, - 536832.25, 188136.25, 536832.25, 188049.75, 536832.25, 188108.75, 536832.25, 187913.25, - 536832.25, 187921.75, 536832.25, 188078.25, 536832.25, 187943.75, 536832.25, 188062.75, - 536832.25, 187997.25, 536832.25, 187947.75, 536832.25, 187969.25, 536832.25, 187946.75, - 536832.25, 187981.75, 536832.25, 187976.25, 536832.25, 187956.25, 536832.25, 187991.75, - 536832.25, 187938.75, 536832.25, 187982.75, 536832.25, 187949.75, 536832.25, 188136.75, - 536832.25, 188050.25, 536832.25, 187988.25, 536832.25, 188003.25, 536832.25, 187944.75, - 536832.25, 187910.75, 536832.25, 188159.75, 536832.25, 187946.25, 536832.25, 187941.75, - 536832.25, 188141.25, 536832.25, 188137.75, 536832.25, 187912.25, 536832.25, 188051.25, - 536832.25, 187923.25, 536832.25, 188016.25, 536832.25, 187981.25, 536832.25, 187987.75, - 536832.25, 187940.25, 536832.25, 188063.25, 536832.25, 188015.25, 536832.25, 188053.25, - 536832.25, 188050.75, 536832.25, 187983.75, 536832.25, 188073.75, 536832.25, 188029.25, - 536832.25, 187911.25, 536832.25, 187923.75, 536832.25, 188027.75, 536832.25, 187920.25, - 536832.25, 187939.75, 536832.25, 187956.75, 536832.25, 188109.75, 536832.25, 188026.25, - 536832.25, 188075.75, 536832.25, 188128.75, 536832.25, 188074.25, 536832.25, 188005.25, - 536832.25, 188057.25, 536832.25, 188025.25, 536832.25, 187992.75, 536832.25, 188134.75, - 536832.25, 188071.25, 536832.25, 188120.25, 536832.25, 188129.25, 536832.25, 188068.75, - 536832.25, 188160.25, 536832.25, 188144.75, 536832.25, 188012.75, 536832.25, 188002.75, - 536832.25, 187918.75, 536832.25, 188069.25, 536832.25, 188047.25, 536832.25, 188072.75, - 536832.25, 188010.25, 536832.25, 188048.75, 536832.25, 188126.75, 536832.25, 188140.75, - 536832.25, 188009.25, 536832.25, 187940.75, 536832.25, 188138.25, 536832.25, 188120.75, - 536832.25, 188070.25, 536832.25, 188119.25, 536832.25, 187972.25, 536832.25, 188148.25, - 536832.75, 188046.25, 536832.75, 188028.75, 536832.75, 187992.75, 536832.75, 188119.25, - 536832.75, 188129.25, 536832.75, 188002.25, 536832.75, 188140.25, 536832.75, 187991.75, - 536832.75, 188025.75, 536832.75, 187919.75, 536832.75, 187986.25, 536832.75, 188016.25, - 536832.75, 188069.25, 536832.75, 187911.25, 536832.75, 188048.75, 536832.75, 188005.75, - 536832.75, 187954.75, 536832.75, 187940.75, 536832.75, 187913.75, 536832.75, 188010.25, - 536832.75, 188014.25, 536832.75, 187970.75, 536832.75, 188120.75, 536832.75, 188068.75, - 536832.75, 188070.75, 536832.75, 187972.25, 536832.75, 187953.75, 536832.75, 187948.75, - 536832.75, 188108.25, 536832.75, 187959.25, 536832.75, 187950.25, 536832.75, 188057.75, - 536832.75, 188138.25, 536832.75, 188109.75, 536832.75, 187950.75, 536832.75, 188118.25, - 536832.75, 188011.75, 536832.75, 187973.25, 536832.75, 187990.25, 536832.75, 187912.25, - 536832.75, 188015.25, 536832.75, 188047.25, 536832.75, 188056.75, 536832.75, 187981.25, - 536832.75, 187946.25, 536832.75, 188137.75, 536832.75, 187983.25, 536832.75, 188135.25, - 536832.75, 188120.25, 536832.75, 188025.25, 536832.75, 187938.25, 536832.75, 187996.75, - 536832.75, 188075.25, 536832.75, 188073.75, 536832.75, 188077.25, 536832.75, 188072.25, - 536832.75, 187955.75, 536832.75, 188052.75, 536832.75, 188027.75, 536832.75, 187939.75, - 536832.75, 188071.75, 536832.75, 188051.75, 536832.75, 188050.25, 536832.75, 188146.75, - 536832.75, 187986.75, 536832.75, 188148.25, 536832.75, 188008.75, 536832.75, 187920.75, - 536832.75, 187923.25, 536832.75, 188059.75, 536832.75, 187941.75, 536832.75, 187921.25, - 536832.75, 187922.75, 536832.75, 188006.25, 536832.75, 188153.25, 536832.75, 188013.25, - 536832.75, 188078.25, 536832.75, 187952.25, 536832.75, 187941.25, 536832.75, 187944.75, - 536832.75, 187944.25, 536832.75, 188001.75, 536832.75, 188021.25, 536832.75, 188134.75, - 536832.75, 187972.75, 536832.75, 187921.75, 536832.75, 187953.25, 536832.75, 188119.75, - 536833.25, 188076.25, 536833.25, 188148.25, 536833.25, 188119.25, 536833.25, 188047.75, - 536833.25, 187921.75, 536833.25, 187942.75, 536833.25, 188070.25, 536833.25, 187943.75, - 536833.25, 188069.75, 536833.25, 187992.25, 536833.25, 188027.25, 536833.25, 188015.75, - 536833.25, 188003.25, 536833.25, 188009.75, 536833.25, 187919.75, 536833.25, 188148.75, - 536833.25, 188072.75, 536833.25, 188133.75, 536833.25, 188025.75, 536833.25, 187985.25, - 536833.25, 187913.75, 536833.25, 187948.25, 536833.25, 188005.25, 536833.25, 187944.75, - 536833.25, 187936.75, 536833.25, 187984.75, 536833.25, 188128.25, 536833.25, 187951.25, - 536833.25, 188071.25, 536833.25, 187970.25, 536833.25, 187969.75, 536833.25, 187986.75, - 536833.25, 187922.25, 536833.25, 188016.75, 536833.25, 188008.75, 536833.25, 188152.75, - 536833.25, 188049.25, 536833.25, 188133.25, 536833.25, 188127.25, 536833.25, 187938.25, - 536833.25, 187947.75, 536833.25, 188109.75, 536833.25, 187978.75, 536833.25, 188077.75, - 536833.25, 188060.25, 536833.25, 187979.25, 536833.25, 188074.75, 536833.25, 188050.75, - 536833.25, 187999.75, 536833.25, 188137.25, 536833.25, 188058.25, 536833.25, 188037.75, - 536833.25, 187918.75, 536833.25, 188147.75, 536833.25, 187993.25, 536833.25, 188136.75, - 536833.25, 188117.75, 536833.25, 188009.25, 536833.25, 187952.75, 536833.25, 187949.75, - 536833.25, 187971.75, 536833.25, 187938.75, 536833.25, 188012.75, 536833.25, 187939.25, - 536833.25, 188108.75, 536833.25, 188046.75, 536833.25, 188150.25, 536833.25, 187912.25, - 536833.25, 188066.25, 536833.25, 187975.75, 536833.75, 188115.75, 536833.75, 188051.25, - 536833.75, 188058.75, 536833.75, 188109.25, 536833.75, 187987.75, 536833.75, 187919.25, - 536833.75, 187993.75, 536833.75, 187913.25, 536833.75, 188075.75, 536833.75, 187929.25, - 536833.75, 188002.75, 536833.75, 188048.25, 536833.75, 188117.75, 536833.75, 188017.25, - 536833.75, 187942.25, 536833.75, 187965.25, 536833.75, 188116.75, 536833.75, 188117.25, - 536833.75, 188143.25, 536833.75, 187927.25, 536833.75, 187918.75, 536833.75, 187936.25, - 536833.75, 188032.25, 536833.75, 188137.75, 536833.75, 187912.75, 536833.75, 188132.25, - 536833.75, 187984.25, 536833.75, 188118.25, 536833.75, 187938.75, 536833.75, 187911.75, - 536833.75, 188012.25, 536833.75, 188138.25, 536833.75, 187952.25, 536833.75, 188050.75, - 536833.75, 187983.75, 536833.75, 188063.25, 536833.75, 188158.25, 536833.75, 187920.75, - 536833.75, 188133.25, 536833.75, 188115.25, 536833.75, 188080.25, 536833.75, 187943.25, - 536833.75, 188034.25, 536833.75, 187920.25, 536833.75, 187971.25, 536833.75, 187985.75, - 536833.75, 188113.25, 536833.75, 188010.75, 536833.75, 188136.25, 536833.75, 188003.75, - 536833.75, 187937.75, 536833.75, 187972.25, 536833.75, 188068.75, 536833.75, 187937.25, - 536833.75, 187982.25, 536833.75, 188116.25, 536833.75, 187930.25, 536833.75, 188009.75, - 536833.75, 187914.75, 536833.75, 188078.75, 536833.75, 188026.25, 536833.75, 187926.25, - 536833.75, 188083.25, 536833.75, 187954.25, 536833.75, 187935.75, 536833.75, 188133.75, - 536833.75, 187941.25, 536833.75, 187919.75, 536833.75, 188019.75, 536833.75, 188125.75, - 536833.75, 188026.75, 536833.75, 188131.75, 536833.75, 188110.25, 536833.75, 187914.25, - 536833.75, 188036.25, 536833.75, 188034.75, 536833.75, 188007.25, 536833.75, 187992.25, - 536833.75, 188027.25, 536833.75, 187917.75, 536833.75, 188069.75, 536833.75, 188118.75, - 536833.75, 187926.75, 536833.75, 188135.75, 536833.75, 188047.25, 536834.25, 187917.25, - 536834.25, 187992.75, 536834.25, 188047.75, 536834.25, 188155.75, 536834.25, 188027.25, - 536834.25, 188014.75, 536834.25, 187927.75, 536834.25, 188026.25, 536834.25, 188026.75, - 536834.25, 187913.75, 536834.25, 188126.25, 536834.25, 187982.25, 536834.25, 187950.75, - 536834.25, 188098.25, 536834.25, 188070.75, 536834.25, 187935.75, 536834.25, 188006.75, - 536834.25, 187918.75, 536834.25, 188019.75, 536834.25, 187986.25, 536834.25, 188136.75, - 536834.25, 188016.25, 536834.25, 187919.75, 536834.25, 187913.25, 536834.25, 188130.25, - 536834.25, 187953.75, 536834.25, 188133.25, 536834.25, 188003.75, 536834.25, 187990.25, - 536834.25, 188137.25, 536834.25, 187967.25, 536834.25, 188058.25, 536834.25, 187989.25, - 536834.25, 188138.25, 536834.25, 188143.75, 536834.25, 188118.25, 536834.25, 187939.25, - 536834.25, 188117.25, 536834.25, 188116.75, 536834.25, 187935.25, 536834.25, 188132.25, - 536834.25, 188109.25, 536834.25, 188064.75, 536834.25, 188109.75, 536834.25, 187970.75, - 536834.25, 187920.75, 536834.25, 188002.75, 536834.25, 188117.75, 536834.25, 187947.25, - 536834.25, 188076.25, 536834.25, 188075.75, 536834.25, 187990.75, 536834.25, 187971.75, - 536834.25, 188032.75, 536834.25, 188115.75, 536834.25, 187911.75, 536834.25, 188072.25, - 536834.25, 188017.25, 536834.25, 187981.75, 536834.25, 188049.25, 536834.25, 188077.75, - 536834.25, 187947.75, 536834.25, 187984.25, 536834.25, 187942.25, 536834.25, 188115.25, - 536834.25, 188130.75, 536834.25, 188050.25, 536834.25, 187983.75, 536834.25, 187937.75, - 536834.25, 188146.75, 536834.25, 187920.25, 536834.25, 187919.25, 536834.25, 188033.25, - 536834.25, 188078.25, 536834.25, 187926.25, 536834.25, 188013.25, 536834.25, 188075.25, - 536834.25, 187986.75, 536834.25, 187943.25, 536834.25, 188116.25, 536834.25, 188125.75, - 536834.25, 187937.25, 536834.25, 188135.75, 536834.25, 187993.75, 536834.25, 188148.75, - 536834.25, 188118.75, 536834.25, 187994.25, 536834.25, 188148.25, 536834.25, 187932.75, - 536834.25, 187926.75, 536834.25, 188125.25, 536834.25, 188055.75, 536834.75, 188125.25, - 536834.75, 188022.75, 536834.75, 187926.75, 536834.75, 188003.25, 536834.75, 188031.25, - 536834.75, 187937.25, 536834.75, 188129.75, 536834.75, 187918.25, 536834.75, 187941.25, - 536834.75, 188124.25, 536834.75, 188135.75, 536834.75, 188109.75, 536834.75, 188033.25, - 536834.75, 187919.25, 536834.75, 188049.75, 536834.75, 188035.25, 536834.75, 187944.75, - 536834.75, 188004.25, 536834.75, 187941.75, 536834.75, 187998.25, 536834.75, 187984.25, - 536834.75, 188115.25, 536834.75, 188027.75, 536834.75, 187989.75, 536834.75, 188115.75, - 536834.75, 187926.25, 536834.75, 187915.25, 536834.75, 188054.25, 536834.75, 188032.75, - 536834.75, 188046.25, 536834.75, 188007.75, 536834.75, 188031.75, 536834.75, 188124.75, - 536834.75, 188002.75, 536834.75, 188096.25, 536834.75, 188132.25, 536834.75, 187973.25, - 536834.75, 188048.25, 536834.75, 188046.75, 536834.75, 187989.25, 536834.75, 188032.25, - 536834.75, 188029.25, 536834.75, 187949.25, 536834.75, 187952.25, 536834.75, 188116.75, - 536834.75, 187935.25, 536834.75, 187936.25, 536834.75, 187948.75, 536834.75, 187994.25, - 536834.75, 187992.75, 536834.75, 188080.25, 536834.75, 188133.75, 536834.75, 187913.25, - 536834.75, 188079.25, 536834.75, 187966.75, 536834.75, 187910.75, 536834.75, 188131.25, - 536834.75, 188160.25, 536834.75, 187918.75, 536834.75, 187986.25, 536834.75, 187917.25, - 536834.75, 188144.75, 536834.75, 188016.75, 536834.75, 187987.25, 536834.75, 187993.75, - 536834.75, 187938.75, 536834.75, 187917.75, 536834.75, 187940.75, 536834.75, 188026.75, - 536834.75, 187914.25, 536835.25, 188045.75, 536835.25, 188146.75, 536835.25, 188114.25, - 536835.25, 188137.75, 536835.25, 187994.25, 536835.25, 188134.75, 536835.25, 188147.75, - 536835.25, 187939.75, 536835.25, 188148.75, 536835.25, 187964.75, 536835.25, 187942.25, - 536835.25, 188114.75, 536835.25, 188029.25, 536835.25, 187935.75, 536835.25, 188008.25, - 536835.25, 188079.25, 536835.25, 188145.75, 536835.25, 188033.75, 536835.25, 188030.75, - 536835.25, 188113.25, 536835.25, 187988.75, 536835.25, 188149.75, 536835.25, 187916.25, - 536835.25, 187972.25, 536835.25, 187913.75, 536835.25, 187983.25, 536835.25, 188012.25, - 536835.25, 188051.25, 536835.25, 187945.25, 536835.25, 188083.75, 536835.25, 188130.25, - 536835.25, 188129.75, 536835.25, 188031.25, 536835.25, 188045.25, 536835.25, 188124.75, - 536835.25, 187916.75, 536835.25, 188112.75, 536835.25, 188079.75, 536835.25, 188034.25, - 536835.25, 187965.75, 536835.25, 187914.75, 536835.25, 188134.25, 536835.25, 188132.75, - 536835.25, 187994.75, 536835.25, 187937.25, 536835.25, 187943.75, 536835.25, 187987.75, - 536835.25, 187915.75, 536835.25, 188010.25, 536835.25, 188068.75, 536835.25, 187987.25, - 536835.25, 187967.75, 536835.25, 187984.75, 536835.25, 187934.25, 536835.25, 188031.75, - 536835.25, 187985.25, 536835.25, 188115.75, 536835.25, 188046.25, 536835.25, 188129.25, - 536835.25, 187988.25, 536835.25, 187940.25, 536835.25, 187917.25, 536835.25, 187989.25, - 536835.25, 188017.75, 536835.25, 188028.25, 536835.25, 187933.25, 536835.25, 188110.75, - 536835.25, 188011.25, 536835.25, 188069.75, 536835.25, 188130.75, 536835.25, 187935.25, - 536835.25, 187912.75, 536835.25, 188004.25, 536835.25, 188037.75, 536835.25, 187944.75, - 536835.25, 187993.25, 536835.25, 188128.25, 536835.25, 188004.75, 536835.25, 187975.75, - 536835.25, 188133.75, 536835.25, 188047.25, 536835.25, 188076.75, 536835.25, 188135.75, - 536835.25, 187934.75, 536835.25, 188141.75, 536835.25, 188110.25, 536835.25, 188027.25, - 536835.25, 188018.25, 536835.25, 187917.75, 536835.25, 188047.75, 536835.75, 188016.75, - 536835.75, 188010.25, 536835.75, 188129.25, 536835.75, 188046.25, 536835.75, 188114.25, - 536835.75, 188027.25, 536835.75, 187989.75, 536835.75, 188047.75, 536835.75, 187994.25, - 536835.75, 187931.25, 536835.75, 187985.25, 536835.75, 188036.25, 536835.75, 188126.25, - 536835.75, 187948.75, 536835.75, 188034.75, 536835.75, 188134.75, 536835.75, 187989.25, - 536835.75, 188130.25, 536835.75, 187914.25, 536835.75, 188003.75, 536835.75, 188147.75, - 536835.75, 188148.75, 536835.75, 188135.25, 536835.75, 188061.25, 536835.75, 188110.25, - 536835.75, 188159.75, 536835.75, 188017.25, 536835.75, 187918.25, 536835.75, 188007.25, - 536835.75, 187984.75, 536835.75, 188146.75, 536835.75, 188076.25, 536835.75, 187950.75, - 536835.75, 187987.25, 536835.75, 187934.75, 536835.75, 187942.25, 536835.75, 187972.75, - 536835.75, 188136.75, 536835.75, 188053.75, 536835.75, 187937.25, 536835.75, 188114.75, - 536835.75, 188074.25, 536835.75, 188028.25, 536835.75, 188132.25, 536835.75, 188048.25, - 536835.75, 188000.25, 536835.75, 187967.75, 536835.75, 188004.75, 536835.75, 187987.75, - 536835.75, 187935.75, 536835.75, 188079.25, 536835.75, 187965.75, 536835.75, 188132.75, - 536835.75, 188110.75, 536835.75, 188030.75, 536835.75, 187993.25, 536835.75, 188028.75, - 536835.75, 188111.25, 536835.75, 188128.25, 536835.75, 187973.75, 536835.75, 188034.25, - 536835.75, 188044.75, 536835.75, 187933.25, 536835.75, 187914.75, 536835.75, 188112.75, - 536835.75, 188076.75, 536835.75, 187944.75, 536835.75, 187988.75, 536835.75, 188113.25, - 536835.75, 188079.75, 536835.75, 188152.25, 536835.75, 187913.75, 536835.75, 187916.75, - 536835.75, 187912.75, 536835.75, 187983.25, 536835.75, 188047.25, 536835.75, 188031.25, - 536835.75, 187940.25, 536835.75, 188145.25, 536835.75, 188129.75, 536835.75, 187983.75, - 536835.75, 188002.75, 536835.75, 188083.75, 536835.75, 188087.75, 536835.75, 188156.75, - 536836.25, 188031.25, 536836.25, 188054.75, 536836.25, 187943.25, 536836.25, 188016.25, - 536836.25, 188045.25, 536836.25, 187949.75, 536836.25, 188004.25, 536836.25, 188078.75, - 536836.25, 188129.75, 536836.25, 187916.75, 536836.25, 187935.25, 536836.25, 188060.25, - 536836.25, 187913.75, 536836.25, 187911.25, 536836.25, 187933.75, 536836.25, 188033.75, - 536836.25, 188027.75, 536836.25, 188042.75, 536836.25, 187966.75, 536836.25, 188128.25, - 536836.25, 187973.75, 536836.25, 188044.75, 536836.25, 187935.75, 536836.25, 188134.25, - 536836.25, 188028.75, 536836.25, 188004.75, 536836.25, 188008.25, 536836.25, 188081.25, - 536836.25, 187994.75, 536836.25, 188052.75, 536836.25, 187943.75, 536836.25, 187985.75, - 536836.25, 188133.75, 536836.25, 187915.75, 536836.25, 187974.25, 536836.25, 187916.25, - 536836.25, 188110.75, 536836.25, 187982.25, 536836.25, 187948.25, 536836.25, 188018.25, - 536836.25, 188074.25, 536836.25, 187972.75, 536836.25, 187965.25, 536836.25, 188075.25, - 536836.25, 188158.25, 536836.25, 187932.25, 536836.25, 188138.25, 536836.25, 187945.75, - 536836.25, 187993.75, 536836.25, 187981.75, 536836.25, 188133.25, 536836.25, 187988.25, - 536836.25, 188113.75, 536836.25, 187932.75, 536836.25, 188052.25, 536836.25, 188112.25, - 536836.25, 187941.25, 536836.25, 188073.25, 536836.25, 188031.75, 536836.25, 188062.25, - 536836.25, 187934.25, 536836.25, 188011.75, 536836.25, 188034.75, 536836.25, 188046.25, - 536836.25, 187911.75, 536836.25, 188114.25, 536836.25, 188121.75, 536836.25, 188012.25, - 536836.75, 188137.75, 536836.75, 187936.25, 536836.75, 188081.75, 536836.75, 188005.25, - 536836.75, 187917.25, 536836.75, 188080.25, 536836.75, 188140.75, 536836.75, 187980.25, - 536836.75, 188029.75, 536836.75, 187994.25, 536836.75, 187995.25, 536836.75, 188075.75, - 536836.75, 188085.75, 536836.75, 187912.25, 536836.75, 187922.25, 536836.75, 188128.75, - 536836.75, 188079.25, 536836.75, 188043.25, 536836.75, 188017.75, 536836.75, 187981.25, - 536836.75, 187913.25, 536836.75, 188031.75, 536836.75, 187942.75, 536836.75, 188112.25, - 536836.75, 187975.25, 536836.75, 188066.75, 536836.75, 188135.25, 536836.75, 188126.75, - 536836.75, 188019.25, 536836.75, 187928.25, 536836.75, 187987.25, 536836.75, 188009.25, - 536836.75, 188123.25, 536836.75, 188077.75, 536836.75, 187993.75, 536836.75, 187933.25, - 536836.75, 188018.75, 536836.75, 188073.75, 536836.75, 187931.75, 536836.75, 188051.75, - 536836.75, 188044.75, 536836.75, 187973.25, 536836.75, 187938.75, 536836.75, 188110.75, - 536836.75, 188111.25, 536836.75, 187938.25, 536836.75, 188033.75, 536836.75, 188072.75, - 536836.75, 187972.25, 536836.75, 187915.25, 536836.75, 187983.25, 536836.75, 187915.75, - 536836.75, 188070.25, 536836.75, 188006.75, 536836.75, 188143.25, 536836.75, 188111.75, - 536836.75, 187995.75, 536836.75, 188074.75, 536836.75, 187986.25, 536836.75, 188045.75, - 536836.75, 187923.75, 536836.75, 187945.25, 536836.75, 187946.25, 536836.75, 187964.25, - 536836.75, 188031.25, 536836.75, 188064.75, 536836.75, 188022.75, 536836.75, 188028.75, - 536836.75, 187950.75, 536836.75, 188129.25, 536836.75, 188077.25, 536836.75, 187984.25, - 536836.75, 188064.25, 536836.75, 187965.75, 536836.75, 188081.25, 536836.75, 187930.75, - 536836.75, 187974.75, 536836.75, 187935.25, 536836.75, 188127.75, 536836.75, 188133.75, - 536836.75, 188035.25, 536836.75, 187967.25, 536836.75, 187970.75, 536836.75, 188112.75, - 536836.75, 188011.25, 536836.75, 188142.75, 536837.25, 188081.75, 536837.25, 188011.25, - 536837.25, 187980.25, 536837.25, 188080.25, 536837.25, 188114.25, 536837.25, 187987.25, - 536837.25, 187949.25, 536837.25, 187973.75, 536837.25, 188081.25, 536837.25, 187970.75, - 536837.25, 187994.25, 536837.25, 187910.75, 536837.25, 187937.75, 536837.25, 187958.25, - 536837.25, 188044.25, 536837.25, 187931.25, 536837.25, 187930.75, 536837.25, 188004.25, - 536837.25, 187984.25, 536837.25, 187912.25, 536837.25, 188078.25, 536837.25, 187992.25, - 536837.25, 187985.25, 536837.25, 188018.75, 536837.25, 188075.75, 536837.25, 188043.75, - 536837.25, 187995.25, 536837.25, 188160.25, 536837.25, 188062.75, 536837.25, 188028.75, - 536837.25, 188111.75, 536837.25, 188156.75, 536837.25, 187930.25, 536837.25, 187935.25, - 536837.25, 188066.25, 536837.25, 188008.75, 536837.25, 188005.25, 536837.25, 188034.75, - 536837.25, 187946.25, 536837.25, 188144.25, 536837.25, 187914.25, 536837.25, 188126.25, - 536837.25, 187915.75, 536837.25, 188017.75, 536837.25, 187986.25, 536837.25, 187952.25, - 536837.25, 188128.75, 536837.25, 188010.25, 536837.25, 188130.25, 536837.25, 188073.25, - 536837.25, 188055.75, 536837.25, 188130.75, 536837.25, 187936.25, 536837.25, 188074.75, - 536837.25, 187943.75, 536837.25, 188068.75, 536837.25, 188028.25, 536837.25, 187932.75, - 536837.25, 188030.25, 536837.25, 187911.25, 536837.25, 188037.75, 536837.25, 187975.25, - 536837.25, 188017.25, 536837.25, 187915.25, 536837.25, 187972.25, 536837.25, 188129.25, - 536837.25, 187981.25, 536837.25, 188033.75, 536837.25, 187937.25, 536837.25, 188072.75, - 536837.25, 188110.75, 536837.25, 187917.25, 536837.25, 187944.75, 536837.25, 188042.75, - 536837.25, 188110.25, 536837.25, 187913.25, 536837.25, 187935.75, 536837.25, 188027.75, - 536837.25, 188119.25, 536837.25, 187965.25, 536837.25, 188113.75, 536837.25, 187982.75, - 536837.25, 188051.75, 536837.25, 187973.25, 536837.25, 188126.75, 536837.25, 188133.25, - 536837.25, 188136.25, 536837.25, 188007.25, 536837.25, 187932.25, 536837.25, 188121.25, - 536837.25, 188037.25, 536837.25, 187917.75, 536837.25, 187992.75, 536837.25, 187966.25, - 536837.25, 187997.75, 536837.25, 187969.75, 536837.25, 188142.25, 536837.25, 188050.75, - 536837.25, 188065.25, 536837.25, 188032.75, 536837.25, 188077.75, 536837.25, 187916.25, - 536837.75, 188039.25, 536837.75, 188010.75, 536837.75, 187982.25, 536837.75, 187984.75, - 536837.75, 187938.25, 536837.75, 188076.25, 536837.75, 188029.25, 536837.75, 188018.25, - 536837.75, 187988.25, 536837.75, 187992.75, 536837.75, 187976.75, 536837.75, 187917.75, - 536837.75, 187942.25, 536837.75, 188111.25, 536837.75, 188019.25, 536837.75, 187945.75, - 536837.75, 188119.75, 536837.75, 187921.75, 536837.75, 188139.75, 536837.75, 188129.25, - 536837.75, 187929.75, 536837.75, 187974.25, 536837.75, 187969.75, 536837.75, 188119.25, - 536837.75, 188055.25, 536837.75, 187941.75, 536837.75, 188043.25, 536837.75, 188143.75, - 536837.75, 187995.75, 536837.75, 188113.25, 536837.75, 188152.25, 536837.75, 187913.75, - 536837.75, 188073.25, 536837.75, 188030.25, 536837.75, 187941.25, 536837.75, 188124.25, - 536837.75, 188126.75, 536837.75, 188144.75, 536837.75, 187986.75, 536837.75, 188010.25, - 536837.75, 188041.75, 536837.75, 188012.25, 536837.75, 187986.25, 536837.75, 188134.75, - 536837.75, 187938.75, 536837.75, 188052.75, 536837.75, 187980.75, 536837.75, 188048.75, - 536837.75, 187946.25, 536837.75, 188031.25, 536837.75, 188028.25, 536837.75, 187951.25, - 536837.75, 187933.75, 536837.75, 187994.75, 536837.75, 188025.25, 536837.75, 188124.75, - 536837.75, 188004.25, 536837.75, 187916.75, 536837.75, 188044.25, 536837.75, 187931.25, - 536837.75, 188086.25, 536837.75, 187971.75, 536837.75, 188036.75, 536837.75, 188047.75, - 536837.75, 188017.75, 536837.75, 188032.75, 536837.75, 187991.75, 536837.75, 187934.25, - 536837.75, 188112.75, 536837.75, 187914.75, 536837.75, 188005.75, 536837.75, 187929.25, - 536837.75, 187970.25, 536837.75, 187974.75, 536837.75, 188114.25, 536837.75, 188133.75, - 536837.75, 187943.25, 536837.75, 187980.25, 536837.75, 188070.75, 536838.25, 188019.75, - 536838.25, 187927.75, 536838.25, 188045.25, 536838.25, 188006.25, 536838.25, 187985.25, - 536838.25, 187992.25, 536838.25, 188124.75, 536838.25, 187978.75, 536838.25, 187983.75, - 536838.25, 188073.75, 536838.25, 187934.75, 536838.25, 188016.75, 536838.25, 188037.25, - 536838.25, 188016.25, 536838.25, 188039.25, 536838.25, 188009.75, 536838.25, 187914.75, - 536838.25, 187920.25, 536838.25, 188143.25, 536838.25, 187939.25, 536838.25, 188029.75, - 536838.25, 188106.25, 536838.25, 188049.75, 536838.25, 187950.75, 536838.25, 187913.75, - 536838.25, 188031.75, 536838.25, 187975.25, 536838.25, 188119.25, 536838.25, 187975.75, - 536838.25, 187988.25, 536838.25, 188075.75, 536838.25, 188042.75, 536838.25, 187952.75, - 536838.25, 188154.25, 536838.25, 188131.75, 536838.25, 187949.25, 536838.25, 188125.25, - 536838.25, 187935.75, 536838.25, 188022.25, 536838.25, 187993.25, 536838.25, 187929.25, - 536838.25, 188008.75, 536838.25, 188155.75, 536838.25, 188123.75, 536838.25, 188076.75, - 536838.25, 188041.75, 536838.25, 187976.25, 536838.25, 188030.75, 536838.25, 187944.25, - 536838.25, 188082.25, 536838.25, 187951.75, 536838.25, 187980.75, 536838.25, 187995.25, - 536838.25, 187918.25, 536838.25, 187929.75, 536838.25, 188015.25, 536838.25, 188014.75, - 536838.25, 187992.75, 536838.25, 187912.25, 536838.25, 187917.25, 536838.25, 188112.25, - 536838.25, 188050.25, 536838.25, 187968.75, 536838.25, 188047.75, 536838.25, 188033.25, - 536838.25, 187970.25, 536838.25, 187928.75, 536838.25, 188012.75, 536838.25, 187942.75, - 536838.25, 187933.75, 536838.25, 188152.75, 536838.25, 188152.25, 536838.25, 188082.75, - 536838.25, 188118.25, 536838.25, 188151.25, 536838.25, 188037.75, 536838.25, 188032.25, - 536838.25, 188146.75, 536838.25, 188122.75, 536838.25, 188005.25, 536838.25, 188040.75, - 536838.25, 188070.25, 536838.25, 187969.25, 536838.25, 188038.75, 536838.25, 187968.25, - 536838.25, 187979.25, 536838.25, 187981.25, 536838.25, 188000.75, 536838.25, 188019.25, - 536838.25, 187995.75, 536838.75, 187995.75, 536838.75, 188071.75, 536838.75, 187916.75, - 536838.75, 188050.75, 536838.75, 188085.25, 536838.75, 188125.75, 536838.75, 187985.75, - 536838.75, 187981.25, 536838.75, 187932.75, 536838.75, 188038.75, 536838.75, 188016.25, - 536838.75, 188073.25, 536838.75, 188139.75, 536838.75, 188006.25, 536838.75, 188010.75, - 536838.75, 188076.25, 536838.75, 187992.25, 536838.75, 188124.75, 536838.75, 187981.75, - 536838.75, 187999.25, 536838.75, 187980.25, 536838.75, 188032.25, 536838.75, 187978.75, - 536838.75, 187995.25, 536838.75, 188148.75, 536838.75, 188030.25, 536838.75, 187942.25, - 536838.75, 187914.75, 536838.75, 187934.75, 536838.75, 187983.75, 536838.75, 187945.25, - 536838.75, 187968.75, 536838.75, 188009.75, 536838.75, 188018.25, 536838.75, 188005.25, - 536838.75, 188067.25, 536838.75, 187942.75, 536838.75, 187969.25, 536838.75, 188112.75, - 536838.75, 187971.75, 536838.75, 187948.75, 536838.75, 188123.25, 536838.75, 188016.75, - 536838.75, 188055.75, 536838.75, 187917.75, 536838.75, 187970.25, 536838.75, 187986.25, - 536838.75, 187912.25, 536838.75, 188081.75, 536838.75, 188049.75, 536838.75, 188015.25, - 536838.75, 187944.25, 536838.75, 187928.75, 536838.75, 188061.75, 536838.75, 188014.75, - 536838.75, 187992.75, 536838.75, 188073.75, 536838.75, 188039.25, 536838.75, 188076.75, - 536838.75, 188112.25, 536838.75, 187918.25, 536838.75, 188142.75, 536838.75, 187927.75, - 536838.75, 188134.75, 536838.75, 187931.25, 536838.75, 187950.75, 536838.75, 187968.25, - 536838.75, 188127.75, 536838.75, 187959.75, 536838.75, 187980.75, 536838.75, 187913.25, - 536838.75, 187925.25, 536838.75, 187976.25, 536838.75, 188131.75, 536838.75, 188041.75, - 536838.75, 188019.75, 536838.75, 188048.25, 536838.75, 188040.25, 536838.75, 188035.75, - 536838.75, 188123.75, 536838.75, 188015.75, 536838.75, 187943.25, 536838.75, 187975.25, - 536838.75, 187929.75, 536838.75, 188151.75, 536838.75, 188018.75, 536838.75, 188028.75, - 536838.75, 188083.25, 536838.75, 187952.75, 536838.75, 187994.75, 536838.75, 187929.25, - 536838.75, 187938.25, 536838.75, 187935.75, 536838.75, 188122.25, 536838.75, 187949.25, - 536838.75, 188082.25, 536839.25, 187926.25, 536839.25, 187965.25, 536839.25, 188047.75, - 536839.25, 188013.75, 536839.25, 188122.25, 536839.25, 188082.25, 536839.25, 188019.25, - 536839.25, 187934.25, 536839.25, 187968.75, 536839.25, 187980.75, 536839.25, 187984.25, - 536839.25, 188041.75, 536839.25, 188048.25, 536839.25, 187976.25, 536839.25, 187987.25, - 536839.25, 187918.25, 536839.25, 187951.75, 536839.25, 187939.25, 536839.25, 187933.75, - 536839.25, 188057.25, 536839.25, 188042.25, 536839.25, 187938.75, 536839.25, 188128.25, - 536839.25, 188029.25, 536839.25, 188074.25, 536839.25, 188076.75, 536839.25, 188039.25, - 536839.25, 188049.25, 536839.25, 188123.25, 536839.25, 188015.25, 536839.25, 188129.75, - 536839.25, 188006.25, 536839.25, 187978.25, 536839.25, 187926.75, 536839.25, 187966.75, - 536839.25, 188030.25, 536839.25, 187928.25, 536839.25, 187996.25, 536839.25, 187975.75, - 536839.25, 187952.25, 536839.25, 188152.75, 536839.25, 188121.25, 536839.25, 188037.75, - 536839.25, 187916.75, 536839.25, 188013.25, 536839.25, 188122.75, 536839.25, 187914.75, - 536839.25, 187932.75, 536839.25, 187930.75, 536839.25, 187932.25, 536839.25, 188046.25, - 536839.25, 188076.25, 536839.25, 187984.75, 536839.25, 187967.25, 536839.25, 187979.25, - 536839.25, 188005.75, 536839.25, 188017.25, 536839.25, 188019.75, 536839.25, 187995.25, - 536839.25, 188133.25, 536839.25, 187985.25, 536839.25, 188014.75, 536839.25, 188008.75, - 536839.75, 188073.75, 536839.75, 187916.25, 536839.75, 188121.75, 536839.75, 188073.25, - 536839.75, 187964.25, 536839.75, 187975.75, 536839.75, 188139.25, 536839.75, 188029.75, - 536839.75, 187992.25, 536839.75, 187947.75, 536839.75, 188019.75, 536839.75, 187994.25, - 536839.75, 187978.75, 536839.75, 187996.75, 536839.75, 188077.25, 536839.75, 187949.75, - 536839.75, 187990.75, 536839.75, 187925.25, 536839.75, 188160.25, 536839.75, 188009.75, - 536839.75, 187930.75, 536839.75, 188046.25, 536839.75, 188059.25, 536839.75, 188037.25, - 536839.75, 187927.25, 536839.75, 187948.75, 536839.75, 187952.25, 536839.75, 188143.75, - 536839.75, 188049.75, 536839.75, 188155.25, 536839.75, 188006.75, 536839.75, 187918.75, - 536839.75, 187931.25, 536839.75, 188124.25, 536839.75, 188044.25, 536839.75, 187979.75, - 536839.75, 188020.75, 536839.75, 188074.75, 536839.75, 187967.25, 536839.75, 187926.25, - 536839.75, 187997.25, 536839.75, 187983.25, 536839.75, 188148.25, 536839.75, 188086.75, - 536839.75, 187993.25, 536839.75, 187928.75, 536839.75, 187984.25, 536839.75, 187968.75, - 536839.75, 187988.25, 536839.75, 187932.75, 536839.75, 187966.25, 536839.75, 188120.75, - 536839.75, 188023.75, 536839.75, 187965.75, 536839.75, 188153.25, 536839.75, 187917.25, - 536839.75, 188133.25, 536839.75, 188038.25, 536839.75, 188117.75, 536839.75, 187936.75, - 536839.75, 188014.25, 536839.75, 188007.25, 536839.75, 187995.75, 536839.75, 187943.25, - 536839.75, 187979.25, 536839.75, 187940.25, 536839.75, 187910.75, 536839.75, 188047.25, - 536839.75, 188008.25, 536839.75, 188045.75, 536839.75, 188005.75, 536839.75, 187976.75, - 536839.75, 188044.75, 536839.75, 188146.75, 536839.75, 187931.75, 536839.75, 187926.75, - 536839.75, 187915.75, 536839.75, 188121.25, 536839.75, 187921.75, 536839.75, 188020.25, - 536839.75, 188082.75, 536839.75, 188012.75, 536839.75, 187984.75, 536839.75, 187989.25, - 536839.75, 188030.75, 536839.75, 187951.75, 536839.75, 187935.25, 536840.25, 187919.25, - 536840.25, 187917.75, 536840.25, 187925.25, 536840.25, 188017.75, 536840.25, 187951.25, - 536840.25, 187924.75, 536840.25, 187966.75, 536840.25, 188121.25, 536840.25, 188114.75, - 536840.25, 187984.75, 536840.25, 188015.25, 536840.25, 187963.75, 536840.25, 187931.75, - 536840.25, 187916.25, 536840.25, 188068.75, 536840.25, 188133.75, 536840.25, 188037.25, - 536840.25, 187948.75, 536840.25, 188082.75, 536840.25, 188044.75, 536840.25, 188047.25, - 536840.25, 187979.25, 536840.25, 188076.25, 536840.25, 188155.75, 536840.25, 188014.75, - 536840.25, 187940.25, 536840.25, 188010.75, 536840.25, 188008.25, 536840.25, 188119.75, - 536840.25, 188038.75, 536840.25, 187936.75, 536840.25, 187977.25, 536840.25, 188125.75, - 536840.25, 188045.75, 536840.25, 188157.75, 536840.25, 187995.75, 536840.25, 188006.25, - 536840.25, 188159.75, 536840.25, 188030.25, 536840.25, 187942.75, 536840.25, 188039.25, - 536840.25, 187927.25, 536840.25, 187917.25, 536840.25, 188038.25, 536840.25, 187947.75, - 536840.25, 188019.25, 536840.25, 188120.75, 536840.25, 187988.25, 536840.25, 188131.75, - 536840.25, 187926.75, 536840.25, 188008.75, 536840.25, 187993.25, 536840.25, 187980.75, - 536840.25, 188074.75, 536840.25, 188043.75, 536840.25, 187915.25, 536840.25, 187983.25, - 536840.25, 188013.75, 536840.25, 187939.25, 536840.25, 188124.25, 536840.25, 187967.25, - 536840.25, 187977.75, 536840.25, 188127.25, 536840.25, 187931.25, 536840.25, 188054.75, - 536840.25, 188141.25, 536840.25, 188073.75, 536840.25, 187978.25, 536840.25, 188077.25, - 536840.25, 188019.75, 536840.25, 187941.25, 536840.25, 188143.75, 536840.25, 188063.75, - 536840.25, 188046.25, 536840.25, 188029.75, 536840.25, 188048.25, 536840.25, 187930.75, - 536840.25, 187934.75, 536840.25, 188124.75, 536840.25, 187992.25, 536840.25, 187978.75, - 536840.25, 187986.75, 536840.25, 188011.75, 536840.25, 188121.75, 536840.25, 187964.25, - 536840.25, 187975.75, 536840.25, 187985.25, 536840.75, 187985.25, 536840.75, 187936.25, - 536840.75, 188044.25, 536840.75, 188048.25, 536840.75, 187996.25, 536840.75, 187971.75, - 536840.75, 188122.25, 536840.75, 188138.75, 536840.75, 187924.75, 536840.75, 188135.25, - 536840.75, 188074.25, 536840.75, 188001.75, 536840.75, 188013.25, 536840.75, 187979.25, - 536840.75, 187963.75, 536840.75, 188149.25, 536840.75, 188037.75, 536840.75, 187925.75, - 536840.75, 188047.25, 536840.75, 187927.75, 536840.75, 187967.25, 536840.75, 187925.25, - 536840.75, 187918.25, 536840.75, 188137.25, 536840.75, 188033.25, 536840.75, 187976.25, - 536840.75, 187915.75, 536840.75, 188030.75, 536840.75, 188025.75, 536840.75, 187962.75, - 536840.75, 187916.25, 536840.75, 188036.75, 536840.75, 188035.75, 536840.75, 187966.25, - 536840.75, 187965.25, 536840.75, 188069.75, 536840.75, 187982.75, 536840.75, 187994.75, - 536840.75, 188075.25, 536840.75, 188084.25, 536840.75, 187962.25, 536840.75, 187929.25, - 536840.75, 187966.75, 536840.75, 187955.25, 536840.75, 187997.25, 536840.75, 187964.25, - 536840.75, 188119.25, 536840.75, 188119.75, 536840.75, 188042.75, 536840.75, 187978.25, - 536840.75, 187949.25, 536840.75, 187930.75, 536840.75, 188124.75, 536840.75, 187975.75, - 536840.75, 188020.75, 536840.75, 188120.25, 536840.75, 188051.25, 536840.75, 187983.75, - 536840.75, 188083.75, 536840.75, 188076.75, 536840.75, 188013.75, 536840.75, 188139.25, - 536840.75, 187919.25, 536840.75, 187946.25, 536841.25, 188028.25, 536841.25, 188031.25, - 536841.25, 188076.75, 536841.25, 188006.75, 536841.25, 187976.75, 536841.25, 187990.75, - 536841.25, 188045.25, 536841.25, 188145.25, 536841.25, 187985.75, 536841.25, 188120.25, - 536841.25, 188046.75, 536841.25, 187949.25, 536841.25, 188013.25, 536841.25, 187936.25, - 536841.25, 187918.75, 536841.25, 188021.25, 536841.25, 188042.75, 536841.25, 188074.75, - 536841.25, 188007.75, 536841.25, 187984.25, 536841.25, 187937.75, 536841.25, 187935.75, - 536841.25, 188075.25, 536841.25, 188134.25, 536841.25, 188128.75, 536841.25, 187940.25, - 536841.25, 188150.75, 536841.25, 187982.75, 536841.25, 187936.75, 536841.25, 187965.25, - 536841.25, 188032.75, 536841.25, 187966.75, 536841.25, 187997.75, 536841.25, 188118.25, - 536841.25, 188025.75, 536841.25, 188030.75, 536841.25, 188065.25, 536841.25, 188041.75, - 536841.25, 188033.25, 536841.25, 187963.25, 536841.25, 187967.25, 536841.25, 188118.75, - 536841.25, 188116.25, 536841.25, 187967.75, 536841.25, 187927.75, 536841.25, 187925.25, - 536841.25, 187982.25, 536841.25, 188129.75, 536841.25, 187928.25, 536841.25, 188014.25, - 536841.25, 187923.75, 536841.25, 187948.75, 536841.25, 187922.25, 536841.25, 188020.25, - 536841.25, 187981.75, 536841.25, 188139.75, 536841.25, 188113.75, 536841.25, 187919.75, - 536841.25, 187939.75, 536841.25, 188135.25, 536841.25, 188033.75, 536841.25, 187961.75, - 536841.25, 188147.75, 536841.25, 187954.75, 536841.25, 188049.25, 536841.25, 188107.75, - 536841.25, 188007.25, 536841.25, 187977.25, 536841.25, 187924.75, 536841.25, 188134.75, - 536841.25, 187980.75, 536841.25, 188059.25, 536841.25, 188034.75, 536841.25, 187929.75, - 536841.25, 188111.25, 536841.25, 188141.75, 536841.25, 187979.75, 536841.25, 188061.25, - 536841.25, 188031.75, 536841.25, 188034.25, 536841.25, 188044.25, 536841.25, 188047.75, - 536841.25, 187996.75, 536841.25, 188036.25, 536841.25, 187994.25, 536841.25, 187980.25, - 536841.25, 187985.25, 536841.75, 187996.75, 536841.75, 187984.25, 536841.75, 187922.75, - 536841.75, 188044.25, 536841.75, 188037.75, 536841.75, 187931.25, 536841.75, 188127.75, - 536841.75, 188032.75, 536841.75, 187927.25, 536841.75, 188021.25, 536841.75, 188142.75, - 536841.75, 188046.75, 536841.75, 188036.25, 536841.75, 187979.75, 536841.75, 187938.25, - 536841.75, 187976.75, 536841.75, 188006.75, 536841.75, 187985.75, 536841.75, 187923.75, - 536841.75, 187929.75, 536841.75, 187980.75, 536841.75, 188134.75, 536841.75, 188154.25, - 536841.75, 187914.25, 536841.75, 187924.75, 536841.75, 187965.25, 536841.75, 188040.25, - 536841.75, 187925.25, 536841.75, 187997.75, 536841.75, 188148.75, 536841.75, 188108.75, - 536841.75, 187962.75, 536841.75, 187961.75, 536841.75, 188047.75, 536841.75, 187966.25, - 536841.75, 188033.75, 536841.75, 187939.75, 536841.75, 188043.25, 536841.75, 188034.25, - 536841.75, 188050.75, 536841.75, 187936.25, 536841.75, 187981.75, 536841.75, 188146.75, - 536841.75, 188015.25, 536841.75, 188067.25, 536841.75, 187928.25, 536841.75, 187982.25, - 536841.75, 187977.25, 536841.75, 188048.75, 536841.75, 188132.25, 536841.75, 188007.25, - 536841.75, 188077.75, 536841.75, 187919.75, 536841.75, 188119.75, 536841.75, 188137.75, - 536841.75, 188033.25, 536841.75, 188020.25, 536841.75, 188082.75, 536841.75, 187991.25, - 536841.75, 187921.75, 536841.75, 188014.25, 536841.75, 188030.75, 536841.75, 188044.75, - 536841.75, 188116.75, 536841.75, 188087.25, 536841.75, 188041.75, 536841.75, 188010.25, - 536841.75, 187967.25, 536841.75, 187935.75, 536841.75, 187965.75, 536841.75, 188110.75, - 536841.75, 188124.25, 536841.75, 187949.25, 536841.75, 187914.75, 536841.75, 188078.25, - 536841.75, 188007.75, 536841.75, 188117.75, 536841.75, 187987.25, 536841.75, 187985.25, - 536841.75, 188031.25, 536841.75, 188042.25, 536841.75, 188139.25, 536841.75, 188035.25, - 536841.75, 188045.25, 536841.75, 187930.75, 536841.75, 188013.25, 536841.75, 187918.75, - 536842.25, 188115.25, 536842.25, 188077.25, 536842.25, 188078.25, 536842.25, 188117.75, - 536842.25, 187978.75, 536842.25, 188160.25, 536842.25, 187950.75, 536842.25, 188045.75, - 536842.25, 188125.25, 536842.25, 187913.75, 536842.25, 187961.25, 536842.25, 187967.25, - 536842.25, 187967.75, 536842.25, 188076.75, 536842.25, 188008.25, 536842.25, 187982.75, - 536842.25, 187968.75, 536842.25, 187936.75, 536842.25, 188074.75, 536842.25, 188044.75, - 536842.25, 187927.75, 536842.25, 188076.25, 536842.25, 187932.25, 536842.25, 188084.75, - 536842.25, 187919.75, 536842.25, 188007.25, 536842.25, 188156.25, 536842.25, 188014.25, - 536842.25, 187982.25, 536842.25, 187998.25, 536842.25, 187996.25, 536842.25, 187926.25, - 536842.25, 187977.25, 536842.25, 187963.75, 536842.25, 188014.75, 536842.25, 188021.75, - 536842.25, 187910.75, 536842.25, 188015.25, 536842.25, 187962.25, 536842.25, 187964.75, - 536842.25, 188131.25, 536842.25, 187936.25, 536842.25, 188041.25, 536842.25, 188034.25, - 536842.25, 187985.25, 536842.25, 188033.75, 536842.25, 187921.25, 536842.25, 188072.25, - 536842.25, 188032.25, 536842.25, 187981.25, 536842.25, 187913.25, 536842.25, 187966.75, - 536842.25, 188040.25, 536842.25, 188062.25, 536842.25, 188011.25, 536842.25, 187915.25, - 536842.25, 187923.75, 536842.25, 188034.75, 536842.25, 187986.75, 536842.25, 188019.25, - 536842.25, 188043.75, 536842.25, 188046.75, 536842.25, 188020.75, 536842.25, 187986.25, - 536842.25, 187931.25, 536842.25, 188044.25, 536842.25, 188040.75, 536842.25, 187922.75, - 536842.75, 187914.75, 536842.75, 187926.75, 536842.75, 188055.25, 536842.75, 188012.25, - 536842.75, 187998.75, 536842.75, 188124.75, 536842.75, 188031.25, 536842.75, 187920.25, - 536842.75, 187984.75, 536842.75, 188079.25, 536842.75, 187959.75, 536842.75, 187983.25, - 536842.75, 187931.75, 536842.75, 188111.75, 536842.75, 188043.25, 536842.75, 188122.75, - 536842.75, 188044.25, 536842.75, 187926.25, 536842.75, 188031.75, 536842.75, 188098.75, - 536842.75, 188015.75, 536842.75, 187968.25, 536842.75, 188001.75, 536842.75, 187946.75, - 536842.75, 187921.25, 536842.75, 188022.25, 536842.75, 187962.25, 536842.75, 188126.75, - 536842.75, 188136.25, 536842.75, 187919.25, 536842.75, 187966.75, 536842.75, 188045.25, - 536842.75, 187978.25, 536842.75, 188013.75, 536842.75, 187918.75, 536842.75, 187977.75, - 536842.75, 187997.25, 536842.75, 187921.75, 536842.75, 187977.25, 536842.75, 188140.75, - 536842.75, 187989.25, 536842.75, 187993.75, 536842.75, 188075.75, 536842.75, 188046.75, - 536842.75, 187963.25, 536842.75, 187930.25, 536842.75, 188039.25, 536842.75, 188114.25, - 536842.75, 187971.75, 536842.75, 187922.25, 536842.75, 188152.75, 536842.75, 187912.75, - 536842.75, 188117.75, 536842.75, 187914.25, 536842.75, 188076.75, 536842.75, 188114.75, - 536842.75, 187996.25, 536842.75, 187963.75, 536842.75, 188008.25, 536842.75, 187995.25, - 536842.75, 188025.25, 536842.75, 187968.75, 536842.75, 187964.25, 536842.75, 188007.75, - 536842.75, 188014.75, 536842.75, 187932.75, 536842.75, 187915.75, 536842.75, 188116.25, - 536842.75, 188007.25, 536842.75, 188115.75, 536842.75, 188103.25, 536843.25, 187937.25, - 536843.25, 188108.75, 536843.25, 188116.25, 536843.25, 188041.75, 536843.25, 187915.75, - 536843.25, 187973.25, 536843.25, 188040.25, 536843.25, 187998.75, 536843.25, 187984.25, - 536843.25, 188014.75, 536843.25, 188042.25, 536843.25, 188007.75, 536843.25, 188115.25, - 536843.25, 187968.75, 536843.25, 188057.25, 536843.25, 187963.75, 536843.25, 187932.75, - 536843.25, 187920.25, 536843.25, 188079.25, 536843.25, 188076.75, 536843.25, 188114.75, - 536843.25, 188124.25, 536843.25, 188117.75, 536843.25, 187996.25, 536843.25, 187912.75, - 536843.25, 188020.25, 536843.25, 188140.75, 536843.25, 188033.75, 536843.25, 187960.75, - 536843.25, 187922.25, 536843.25, 188114.25, 536843.25, 188073.25, 536843.25, 188019.25, - 536843.25, 187919.75, 536843.25, 188021.25, 536843.25, 188030.75, 536843.25, 187982.25, - 536843.25, 187924.75, 536843.25, 187963.25, 536843.25, 187961.75, 536843.25, 187926.75, - 536843.25, 188075.75, 536843.25, 187962.75, 536843.25, 187920.75, 536843.25, 187997.25, - 536843.25, 188113.75, 536843.25, 187928.25, 536843.25, 187921.75, 536843.25, 187981.25, - 536843.25, 188003.25, 536843.25, 187914.25, 536843.25, 188043.75, 536843.25, 188044.25, - 536843.25, 188017.75, 536843.25, 188045.75, 536843.25, 187977.75, 536843.25, 188009.25, - 536843.25, 187971.25, 536843.25, 188013.75, 536843.25, 187919.25, 536843.25, 187980.25, - 536843.25, 188031.75, 536843.25, 188120.25, 536843.25, 188029.75, 536843.25, 188045.25, - 536843.25, 187926.25, 536843.25, 188015.75, 536843.25, 187992.25, 536843.25, 187965.25, - 536843.25, 187925.75, 536843.25, 187946.75, 536843.25, 188079.75, 536843.25, 187997.75, - 536843.25, 187967.75, 536843.25, 188103.75, 536843.25, 188032.25, 536843.25, 187985.25, - 536843.25, 187921.25, 536843.75, 188022.25, 536843.75, 188112.75, 536843.75, 187988.25, - 536843.75, 188079.75, 536843.75, 187915.25, 536843.75, 187991.25, 536843.75, 187913.75, - 536843.75, 188129.75, 536843.75, 187978.75, 536843.75, 188017.75, 536843.75, 188029.75, - 536843.75, 187990.75, 536843.75, 187930.75, 536843.75, 187980.25, 536843.75, 188018.25, - 536843.75, 188071.75, 536843.75, 187987.25, 536843.75, 188031.75, 536843.75, 187967.25, - 536843.75, 187998.25, 536843.75, 188003.25, 536843.75, 187921.75, 536843.75, 188030.25, - 536843.75, 187995.75, 536843.75, 187923.75, 536843.75, 187923.25, 536843.75, 187924.75, - 536843.75, 188038.75, 536843.75, 187961.75, 536843.75, 188043.25, 536843.75, 188015.25, - 536843.75, 187960.75, 536843.75, 188078.75, 536843.75, 187935.25, 536843.75, 187931.75, - 536843.75, 188114.25, 536843.75, 188138.75, 536843.75, 188008.75, 536843.75, 187983.25, - 536843.75, 188152.75, 536843.75, 187925.25, 536843.75, 187966.25, 536843.75, 188076.75, - 536843.75, 188117.25, 536843.75, 187920.25, 536843.75, 187984.75, 536843.75, 188068.75, - 536843.75, 187992.75, 536843.75, 188052.75, 536843.75, 187995.25, 536843.75, 188014.75, - 536843.75, 188136.75, 536843.75, 188116.75, 536843.75, 187998.75, 536843.75, 188076.25, - 536843.75, 187994.75, 536844.25, 188018.75, 536844.25, 188031.25, 536844.25, 187999.25, - 536844.25, 187914.75, 536844.25, 188145.75, 536844.25, 187916.25, 536844.25, 187982.25, - 536844.25, 188043.75, 536844.25, 187998.25, 536844.25, 187980.75, 536844.25, 188109.25, - 536844.25, 188029.75, 536844.25, 188016.25, 536844.25, 188086.25, 536844.25, 187979.75, - 536844.25, 187968.25, 536844.25, 188140.25, 536844.25, 187985.25, 536844.25, 188017.25, - 536844.25, 187962.25, 536844.25, 187979.25, 536844.25, 188149.25, 536844.25, 188029.25, - 536844.25, 188038.25, 536844.25, 188149.75, 536844.25, 187978.25, 536844.25, 188077.25, - 536844.25, 187967.25, 536844.25, 187919.25, 536844.25, 188028.75, 536844.25, 187965.75, - 536844.25, 188151.25, 536844.25, 188062.75, 536844.25, 188047.25, 536844.25, 188039.25, - 536844.25, 188027.25, 536844.25, 188142.25, 536844.25, 188117.75, 536844.25, 187989.75, - 536844.25, 188109.75, 536844.25, 188138.25, 536844.25, 187922.75, 536844.25, 187929.25, - 536844.25, 188049.75, 536844.25, 188076.25, 536844.25, 188134.25, 536844.25, 188008.25, - 536844.25, 187992.75, 536844.25, 187928.75, 536844.25, 188036.25, 536844.25, 188039.75, - 536844.25, 188050.75, 536844.25, 187987.25, 536844.25, 188009.25, 536844.25, 188012.75, - 536844.25, 187990.75, 536844.25, 187918.75, 536844.25, 188022.75, 536844.25, 187992.25, - 536844.25, 187965.25, 536844.25, 188079.75, 536844.25, 187927.75, 536844.25, 188021.75, - 536844.25, 187923.75, 536844.25, 187927.25, 536844.25, 187911.25, 536844.25, 187969.75, - 536844.25, 188020.25, 536844.25, 187969.25, 536844.25, 187993.75, 536844.75, 187991.25, - 536844.75, 188050.75, 536844.75, 188136.25, 536844.75, 188074.75, 536844.75, 187992.75, - 536844.75, 187968.25, 536844.75, 188076.25, 536844.75, 188160.25, 536844.75, 188037.75, - 536844.75, 188133.75, 536844.75, 187989.75, 536844.75, 187933.75, 536844.75, 188073.25, - 536844.75, 188019.25, 536844.75, 187993.75, 536844.75, 188016.25, 536844.75, 187968.75, - 536844.75, 187916.25, 536844.75, 188056.75, 536844.75, 187994.75, 536844.75, 188039.25, - 536844.75, 188079.25, 536844.75, 187926.75, 536844.75, 187995.75, 536844.75, 188039.75, - 536844.75, 187910.75, 536844.75, 188080.25, 536844.75, 188012.25, 536844.75, 187915.75, - 536844.75, 188128.25, 536844.75, 188016.75, 536844.75, 188041.25, 536844.75, 188031.75, - 536844.75, 187998.25, 536844.75, 187919.75, 536844.75, 188031.25, 536844.75, 187999.25, - 536844.75, 187983.75, 536844.75, 188145.25, 536844.75, 187914.75, 536844.75, 187983.25, - 536844.75, 188111.25, 536844.75, 187982.75, 536844.75, 187931.75, 536844.75, 188030.75, - 536844.75, 188000.25, 536844.75, 187914.25, 536844.75, 188148.25, 536844.75, 187980.25, - 536844.75, 188029.75, 536844.75, 187921.25, 536844.75, 188021.75, 536844.75, 188017.75, - 536844.75, 187962.25, 536844.75, 187979.25, 536844.75, 188149.75, 536844.75, 187967.25, - 536844.75, 187978.25, 536844.75, 188028.75, 536844.75, 188119.25, 536844.75, 187965.25, - 536844.75, 188028.25, 536844.75, 188063.25, 536844.75, 187963.25, 536844.75, 187922.25, - 536844.75, 188026.75, 536844.75, 188048.75, 536844.75, 188107.75, 536844.75, 188115.25, - 536844.75, 187967.75, 536844.75, 188008.25, 536844.75, 188050.25, 536844.75, 187966.25, - 536844.75, 188022.75, 536844.75, 187928.75, 536844.75, 188142.25, 536844.75, 188096.25, - 536844.75, 187928.25, 536844.75, 188113.25, 536844.75, 188009.25, 536845.25, 188023.25, - 536845.25, 187981.75, 536845.25, 188013.75, 536845.25, 187992.25, 536845.25, 188056.25, - 536845.25, 187965.75, 536845.25, 188076.75, 536845.25, 188113.25, 536845.25, 187968.75, - 536845.25, 188034.75, 536845.25, 188015.75, 536845.25, 188077.75, 536845.25, 188038.75, - 536845.25, 187918.25, 536845.25, 187988.25, 536845.25, 188039.25, 536845.25, 188140.75, - 536845.25, 187987.75, 536845.25, 187918.75, 536845.25, 188080.75, 536845.25, 188069.75, - 536845.25, 188110.75, 536845.25, 187969.75, 536845.25, 187920.25, 536845.25, 188111.25, - 536845.25, 187911.25, 536845.25, 187999.75, 536845.25, 188008.75, 536845.25, 188146.25, - 536845.25, 188009.75, 536845.25, 187982.25, 536845.25, 187979.25, 536845.25, 188015.25, - 536845.25, 188043.25, 536845.25, 188147.25, 536845.25, 188030.25, 536845.25, 188050.25, - 536845.25, 188017.25, 536845.25, 187921.25, 536845.25, 188112.25, 536845.25, 188103.25, - 536845.25, 188029.25, 536845.25, 187978.75, 536845.25, 187967.25, 536845.25, 188022.25, - 536845.25, 187927.75, 536845.25, 187965.25, 536845.25, 188028.25, 536845.25, 188089.75, - 536845.25, 188027.75, 536845.25, 187929.75, 536845.25, 187929.25, 536845.25, 188026.75, - 536845.75, 187998.75, 536845.75, 188136.75, 536845.75, 188037.25, 536845.75, 187990.75, - 536845.75, 188009.25, 536845.75, 188026.25, 536845.75, 187990.25, 536845.75, 188014.75, - 536845.75, 188013.25, 536845.75, 187993.25, 536845.75, 187965.75, 536845.75, 188138.75, - 536845.75, 188035.25, 536845.75, 187963.75, 536845.75, 188051.25, 536845.75, 188077.25, - 536845.75, 187988.75, 536845.75, 187964.75, 536845.75, 188038.75, 536845.75, 187974.25, - 536845.75, 188139.75, 536845.75, 187929.25, 536845.75, 188078.25, 536845.75, 188010.25, - 536845.75, 187923.25, 536845.75, 187987.75, 536845.75, 188023.75, 536845.75, 188027.25, - 536845.75, 187969.25, 536845.75, 188080.25, 536845.75, 188040.25, 536845.75, 188040.75, - 536845.75, 187986.25, 536845.75, 188081.25, 536845.75, 187930.25, 536845.75, 188025.75, - 536845.75, 188089.75, 536845.75, 188143.75, 536845.75, 187998.25, 536845.75, 188004.25, - 536845.75, 188151.75, 536845.75, 187919.75, 536845.75, 188011.75, 536845.75, 188068.75, - 536845.75, 187967.75, 536845.75, 187912.25, 536845.75, 187999.25, 536845.75, 188111.75, - 536845.75, 188000.25, 536845.75, 188123.25, 536845.75, 188022.75, 536845.75, 188028.75, - 536845.75, 188112.75, 536845.75, 188000.75, 536845.75, 187920.75, 536845.75, 188099.25, - 536845.75, 188122.25, 536845.75, 187979.75, 536845.75, 188017.25, 536845.75, 187978.75, - 536845.75, 187970.25, 536845.75, 188018.25, 536846.25, 188049.25, 536846.25, 187992.75, - 536846.25, 188065.25, 536846.25, 188026.25, 536846.25, 188010.25, 536846.25, 188073.75, - 536846.25, 187979.25, 536846.25, 188116.75, 536846.25, 187990.25, 536846.25, 188112.25, - 536846.25, 187964.25, 536846.25, 188037.75, 536846.25, 188158.75, 536846.25, 187993.25, - 536846.25, 188092.25, 536846.25, 187991.25, 536846.25, 187979.75, 536846.25, 188013.25, - 536846.25, 188029.75, 536846.25, 187970.25, 536846.25, 188133.75, 536846.25, 188009.25, - 536846.25, 187928.25, 536846.25, 187965.75, 536846.25, 187968.75, 536846.25, 188105.75, - 536846.25, 188016.25, 536846.25, 188122.25, 536846.25, 187967.25, 536846.25, 188026.75, - 536846.25, 188077.25, 536846.25, 187974.25, 536846.25, 187980.75, 536846.25, 188104.25, - 536846.25, 188139.75, 536846.25, 188022.75, 536846.25, 188024.75, 536846.25, 188147.25, - 536846.25, 188014.25, 536846.25, 187916.25, 536846.25, 188101.75, 536846.25, 188050.75, - 536846.25, 187988.25, 536846.25, 188023.75, 536846.25, 188071.25, 536846.25, 188028.75, - 536846.25, 187969.25, 536846.25, 187966.25, 536846.25, 188146.75, 536846.25, 187918.75, - 536846.25, 187987.25, 536846.25, 188008.75, 536846.25, 188080.25, 536846.25, 187921.75, - 536846.25, 188000.25, 536846.25, 187922.25, 536846.25, 188151.25, 536846.25, 188040.25, - 536846.25, 188114.25, 536846.25, 187911.75, 536846.25, 188090.25, 536846.25, 187961.25, - 536846.25, 187983.25, 536846.25, 187924.75, 536846.25, 188095.25, 536846.25, 188081.25, - 536846.25, 187920.25, 536846.25, 187929.25, 536846.25, 188143.25, 536846.25, 187915.25, - 536846.25, 188041.25, 536846.25, 188151.75, 536846.25, 188028.25, 536846.25, 188025.75, - 536846.25, 187998.75, 536846.75, 187965.25, 536846.75, 187929.75, 536846.75, 187999.25, - 536846.75, 187919.75, 536846.75, 188108.75, 536846.75, 188136.25, 536846.75, 188010.75, - 536846.75, 188037.25, 536846.75, 187970.75, 536846.75, 188110.75, 536846.75, 187992.25, - 536846.75, 188023.25, 536846.75, 187990.75, 536846.75, 187925.25, 536846.75, 188036.25, - 536846.75, 187992.75, 536846.75, 187969.75, 536846.75, 188087.25, 536846.75, 188121.25, - 536846.75, 188025.25, 536846.75, 187924.75, 536846.75, 188081.25, 536846.75, 188111.25, - 536846.75, 187986.25, 536846.75, 187999.75, 536846.75, 188004.75, 536846.75, 187940.25, - 536846.75, 188080.75, 536846.75, 187921.25, 536846.75, 188057.25, 536846.75, 187967.25, - 536846.75, 187986.75, 536846.75, 187945.75, 536846.75, 187922.25, 536846.75, 187980.25, - 536846.75, 188012.25, 536846.75, 188092.25, 536846.75, 188000.25, 536846.75, 187970.25, - 536846.75, 187931.25, 536846.75, 188026.75, 536846.75, 187922.75, 536846.75, 188027.25, - 536846.75, 187966.25, 536846.75, 187918.75, 536846.75, 187943.75, 536846.75, 187988.75, - 536846.75, 188043.25, 536846.75, 188077.75, 536846.75, 188079.25, 536846.75, 187987.75, - 536846.75, 188009.75, 536846.75, 187980.75, 536846.75, 187981.25, 536846.75, 188159.25, - 536846.75, 188101.75, 536846.75, 187912.75, 536846.75, 188039.25, 536846.75, 188098.75, - 536846.75, 188000.75, 536847.25, 188005.25, 536847.25, 188000.75, 536847.25, 187923.25, - 536847.25, 188078.25, 536847.25, 187920.75, 536847.25, 188010.75, 536847.25, 188131.75, - 536847.25, 188078.75, 536847.25, 188023.75, 536847.25, 187929.25, 536847.25, 188024.75, - 536847.25, 188027.25, 536847.25, 188110.25, 536847.25, 187964.75, 536847.25, 188077.75, - 536847.25, 188061.25, 536847.25, 188066.75, 536847.25, 187970.75, 536847.25, 187943.25, - 536847.25, 187921.75, 536847.25, 187980.75, 536847.25, 188085.75, 536847.25, 188122.25, - 536847.25, 187970.25, 536847.25, 188039.75, 536847.25, 187989.25, 536847.25, 188118.25, - 536847.25, 187993.75, 536847.25, 187944.75, 536847.25, 188026.75, 536847.25, 188001.25, - 536847.25, 188011.25, 536847.25, 187910.75, 536847.25, 187989.75, 536847.25, 188099.75, - 536847.25, 187980.25, 536847.25, 187986.75, 536847.25, 188017.25, 536847.25, 188138.25, - 536847.25, 188087.75, 536847.25, 188010.25, 536847.25, 188080.75, 536847.25, 188025.25, - 536847.25, 188160.25, 536847.25, 188024.25, 536847.25, 188037.75, 536847.25, 188111.25, - 536847.25, 188115.25, 536847.25, 188109.25, 536847.25, 187919.25, 536847.25, 188087.25, - 536847.25, 187924.75, 536847.25, 187911.25, 536847.25, 188036.25, 536847.25, 188081.75, - 536847.25, 188107.75, 536847.25, 187925.25, 536847.25, 187990.75, 536847.25, 188110.75, - 536847.25, 188026.25, 536847.25, 188126.25, 536847.25, 188118.75, 536847.25, 188082.25, - 536847.25, 188017.75, 536847.25, 188037.25, 536847.25, 188036.75, 536847.25, 187966.25, - 536847.25, 188136.75, 536847.25, 187991.75, 536847.25, 188155.75, 536847.25, 187942.75, - 536847.25, 187919.75, 536847.25, 187969.75, 536847.75, 187991.25, 536847.75, 188024.75, - 536847.75, 188137.75, 536847.75, 188153.25, 536847.75, 188087.75, 536847.75, 188001.75, - 536847.75, 187912.75, 536847.75, 188152.75, 536847.75, 188010.25, 536847.75, 188079.75, - 536847.75, 188078.75, 536847.75, 188112.75, 536847.75, 188000.25, 536847.75, 188098.25, - 536847.75, 188136.75, 536847.75, 187923.25, 536847.75, 188022.25, 536847.75, 187918.25, - 536847.75, 188087.25, 536847.75, 188049.25, 536847.75, 188110.25, 536847.75, 188078.25, - 536847.75, 188012.25, 536847.75, 188025.25, 536847.75, 187989.75, 536847.75, 188104.75, - 536847.75, 188080.75, 536847.75, 188023.75, 536847.75, 187994.25, 536847.75, 187913.25, - 536847.75, 188093.75, 536847.75, 188089.75, 536847.75, 188110.75, 536847.75, 187999.25, - 536847.75, 187989.25, 536847.75, 188010.75, 536847.75, 187911.25, 536847.75, 187991.75, - 536847.75, 188024.25, 536847.75, 188081.25, 536847.75, 188036.75, 536847.75, 187969.75, - 536847.75, 187939.75, 536847.75, 188026.25, 536847.75, 188001.25, 536847.75, 187967.25, - 536847.75, 188108.25, 536847.75, 187923.75, 536847.75, 187992.25, 536847.75, 187941.75, - 536847.75, 187986.75, 536847.75, 188142.25, 536847.75, 187970.25, 536847.75, 188134.75, - 536847.75, 188111.25, 536847.75, 187979.75, 536847.75, 188086.25, 536847.75, 187943.75, - 536847.75, 187970.75, 536847.75, 187980.25, 536847.75, 187980.75, 536847.75, 188082.25, - 536847.75, 188066.25, 536847.75, 187921.75, 536847.75, 188072.75, 536847.75, 187998.25, - 536847.75, 187919.75, 536847.75, 188040.25, 536847.75, 188120.75, 536847.75, 188036.25, - 536848.25, 187966.25, 536848.25, 188039.75, 536848.25, 188058.25, 536848.25, 188088.75, - 536848.25, 187988.75, 536848.25, 187981.25, 536848.25, 188023.25, 536848.25, 187980.25, - 536848.25, 187992.75, 536848.25, 188058.75, 536848.25, 188017.75, 536848.25, 188148.75, - 536848.25, 188081.75, 536848.25, 188038.75, 536848.25, 187971.25, 536848.25, 188082.75, - 536848.25, 187924.75, 536848.25, 188107.75, 536848.25, 188011.25, 536848.25, 188024.25, - 536848.25, 188045.25, 536848.25, 187942.25, 536848.25, 188006.25, 536848.25, 188018.25, - 536848.25, 188015.75, 536848.25, 188021.75, 536848.25, 187944.75, 536848.25, 187991.75, - 536848.25, 188132.75, 536848.25, 187971.75, 536848.25, 188091.75, 536848.25, 187925.25, - 536848.25, 187986.25, 536848.25, 187964.25, 536848.25, 188104.75, 536848.25, 188023.75, - 536848.25, 187989.75, 536848.25, 188117.25, 536848.25, 188144.75, 536848.25, 187912.25, - 536848.25, 187967.75, 536848.25, 188153.75, 536848.25, 187987.75, 536848.25, 187920.75, - 536848.25, 188090.25, 536848.25, 187975.25, 536848.25, 188056.25, 536848.25, 187940.75, - 536848.25, 188000.75, 536848.25, 188079.75, 536848.25, 188079.25, 536848.25, 188010.25, - 536848.25, 187922.25, 536848.25, 188118.25, 536848.25, 188105.25, 536848.75, 188104.25, - 536848.75, 188022.75, 536848.75, 187995.75, 536848.75, 188153.25, 536848.75, 187946.75, - 536848.75, 187940.25, 536848.75, 188001.75, 536848.75, 188129.25, 536848.75, 187990.25, - 536848.75, 188142.75, 536848.75, 188152.75, 536848.75, 188018.75, 536848.75, 188039.25, - 536848.75, 187975.75, 536848.75, 188152.25, 536848.75, 188080.25, 536848.75, 187994.75, - 536848.75, 187926.25, 536848.75, 188096.25, 536848.75, 187994.25, 536848.75, 187949.25, - 536848.75, 188112.75, 536848.75, 188154.75, 536848.75, 187990.75, 536848.75, 187925.25, - 536848.75, 188118.75, 536848.75, 188100.75, 536848.75, 187951.25, 536848.75, 187971.75, - 536848.75, 187993.75, 536848.75, 188011.75, 536848.75, 187911.75, 536848.75, 188002.25, - 536848.75, 188037.25, 536848.75, 187967.25, 536848.75, 187971.25, 536848.75, 188044.75, - 536848.75, 188100.25, 536848.75, 188108.25, 536848.75, 188037.75, 536848.75, 188081.75, - 536848.75, 188149.25, 536848.75, 188020.75, 536848.75, 187987.25, 536848.75, 188148.75, - 536848.75, 188017.75, 536848.75, 187980.25, 536848.75, 188103.75, 536848.75, 187988.75, - 536848.75, 188105.75, 536848.75, 188148.25, 536848.75, 187965.25, 536848.75, 188039.75, - 536848.75, 188125.75, 536848.75, 187921.75, 536848.75, 188122.75, 536848.75, 187943.75, - 536848.75, 187923.75, 536848.75, 188082.75, 536848.75, 188001.25, 536848.75, 187981.75, - 536848.75, 188024.25, 536848.75, 187925.75, 536848.75, 187942.25, 536848.75, 187982.75, - 536848.75, 187991.75, 536848.75, 188010.75, 536848.75, 187948.75, 536848.75, 187986.25, - 536848.75, 187989.75, 536848.75, 188022.25, 536848.75, 188030.75, 536848.75, 188145.25, - 536849.25, 188146.75, 536849.25, 188022.25, 536849.25, 188148.75, 536849.25, 188048.25, - 536849.25, 187965.75, 536849.25, 188144.75, 536849.25, 187995.75, 536849.25, 187992.75, - 536849.25, 188153.25, 536849.25, 188123.25, 536849.25, 187963.75, 536849.25, 187990.25, - 536849.25, 187988.75, 536849.25, 187944.25, 536849.25, 188037.25, 536849.25, 188103.75, - 536849.25, 188028.25, 536849.25, 187967.25, 536849.25, 187970.75, 536849.25, 188105.75, - 536849.25, 188041.25, 536849.25, 188105.25, 536849.25, 187922.75, 536849.25, 187948.75, - 536849.25, 188006.25, 536849.25, 188011.75, 536849.25, 187965.25, 536849.25, 188082.25, - 536849.25, 188036.25, 536849.25, 187949.75, 536849.25, 188104.75, 536849.25, 187944.75, - 536849.25, 188125.75, 536849.25, 188136.25, 536849.25, 187980.75, 536849.25, 187971.75, - 536849.25, 188152.75, 536849.25, 188103.25, 536849.25, 188023.25, 536849.25, 188093.75, - 536849.25, 188010.75, 536849.25, 187925.25, 536849.25, 187992.25, 536849.25, 187999.25, - 536849.25, 187986.75, 536849.25, 187923.75, 536849.25, 187994.25, 536849.25, 188117.75, - 536849.25, 188104.25, 536849.25, 187985.75, 536849.25, 187984.25, 536849.25, 188000.75, - 536849.25, 187924.75, 536849.25, 188039.25, 536849.25, 187981.75, 536849.25, 188001.75, - 536849.25, 188023.75, 536849.25, 188152.25, 536849.25, 188080.25, 536849.25, 188021.75, - 536849.25, 188154.25, 536849.25, 187925.75, 536849.25, 187942.25, 536849.25, 188153.75, - 536849.25, 188012.25, 536849.25, 188083.25, 536849.25, 188078.25, 536849.25, 187982.25, - 536849.25, 187926.25, 536849.25, 187994.75, 536849.25, 188047.25, 536849.75, 187993.25, - 536849.75, 188037.25, 536849.75, 188062.75, 536849.75, 188036.75, 536849.75, 188020.75, - 536849.75, 187942.75, 536849.75, 187995.75, 536849.75, 188144.25, 536849.75, 188083.25, - 536849.75, 187982.25, 536849.75, 188126.25, 536849.75, 188121.25, 536849.75, 187996.75, - 536849.75, 188067.25, 536849.75, 187923.25, 536849.75, 188012.25, 536849.75, 187944.25, - 536849.75, 188153.75, 536849.75, 187971.25, 536849.75, 187983.75, 536849.75, 187936.75, - 536849.75, 188143.75, 536849.75, 187912.25, 536849.75, 188019.25, 536849.75, 187938.25, - 536849.75, 187922.75, 536849.75, 187948.75, 536849.75, 188099.75, 536849.75, 188079.75, - 536849.75, 188080.75, 536849.75, 188011.25, 536849.75, 188106.75, 536849.75, 187940.25, - 536849.75, 187991.25, 536849.75, 188039.75, 536849.75, 188070.25, 536849.75, 188001.25, - 536849.75, 187998.25, 536849.75, 187924.75, 536849.75, 187944.75, 536849.75, 187938.75, - 536849.75, 188104.75, 536849.75, 188040.75, 536849.75, 187925.25, 536849.75, 187946.75, - 536849.75, 188082.75, 536849.75, 187952.25, 536849.75, 188160.25, 536849.75, 187977.25, - 536849.75, 187910.75, 536849.75, 187949.25, 536849.75, 187971.75, 536849.75, 188075.75, - 536849.75, 188083.75, 536849.75, 187921.75, 536849.75, 188136.75, 536849.75, 187984.25, - 536849.75, 187990.75, 536849.75, 188105.25, 536849.75, 188037.75, 536849.75, 188100.75, - 536849.75, 187957.75, 536849.75, 187981.25, 536849.75, 188021.25, 536850.25, 187951.75, - 536850.25, 187958.25, 536850.25, 188042.75, 536850.25, 188021.25, 536850.25, 188001.75, - 536850.25, 188103.25, 536850.25, 188012.75, 536850.25, 188025.75, 536850.25, 188152.75, - 536850.25, 187999.25, 536850.25, 187994.25, 536850.25, 188083.75, 536850.25, 187949.25, - 536850.25, 188127.75, 536850.25, 188054.25, 536850.25, 188042.25, 536850.25, 187993.75, - 536850.25, 187940.75, 536850.25, 187991.75, 536850.25, 187972.25, 536850.25, 188040.25, - 536850.25, 188013.75, 536850.25, 188131.75, 536850.25, 187981.75, 536850.25, 188018.25, - 536850.25, 188018.75, 536850.25, 188122.75, 536850.25, 188114.25, 536850.25, 188106.75, - 536850.25, 188081.25, 536850.25, 188002.25, 536850.25, 188020.25, 536850.25, 187991.25, - 536850.25, 188041.25, 536850.25, 188087.25, 536850.25, 188011.75, 536850.25, 187990.75, - 536850.25, 188099.75, 536850.25, 187972.75, 536850.25, 187937.25, 536850.25, 188075.25, - 536850.25, 188099.25, 536850.25, 187939.75, 536850.25, 188109.75, 536850.25, 187948.75, - 536850.25, 188101.25, 536850.25, 188019.25, 536850.25, 188020.75, 536850.25, 188107.25, - 536850.25, 188153.75, 536850.25, 188103.75, 536850.25, 187946.25, 536850.25, 187942.25, - 536850.25, 188012.25, 536850.25, 187951.25, 536850.25, 187971.25, 536850.25, 188084.25, - 536850.25, 187992.75, 536850.25, 188102.25, 536850.25, 187945.25, 536850.25, 188100.25, - 536850.25, 187957.25, 536850.25, 187982.25, 536850.25, 187953.75, 536850.25, 188106.25, - 536850.25, 187952.75, 536850.25, 187945.75, 536850.25, 187982.75, 536850.25, 188017.75, - 536850.25, 188037.75, 536850.25, 188156.25, 536850.75, 187991.75, 536850.75, 187972.75, - 536850.75, 188037.25, 536850.75, 188001.25, 536850.75, 188001.75, 536850.75, 187995.75, - 536850.75, 187982.25, 536850.75, 187945.25, 536850.75, 188158.75, 536850.75, 187990.25, - 536850.75, 187999.75, 536850.75, 188108.25, 536850.75, 187965.75, 536850.75, 188084.25, - 536850.75, 187994.75, 536850.75, 187923.25, 536850.75, 188099.25, 536850.75, 188083.25, - 536850.75, 188100.25, 536850.75, 188080.75, 536850.75, 187936.75, 536850.75, 188102.75, - 536850.75, 188017.25, 536850.75, 187971.25, 536850.75, 188131.75, 536850.75, 187968.75, - 536850.75, 188079.25, 536850.75, 187946.25, 536850.75, 187956.25, 536850.75, 188128.25, - 536850.75, 188106.75, 536850.75, 187998.75, 536850.75, 188126.75, 536850.75, 187997.75, - 536850.75, 188037.75, 536850.75, 188003.25, 536850.75, 188104.25, 536850.75, 187938.25, - 536850.75, 188041.25, 536850.75, 187981.75, 536850.75, 187922.75, 536850.75, 188099.75, - 536850.75, 188011.75, 536850.75, 188077.75, 536850.75, 188114.25, 536850.75, 187965.25, - 536850.75, 187991.25, 536850.75, 187940.25, 536850.75, 188105.75, 536850.75, 188132.25, - 536850.75, 188081.25, 536850.75, 188020.25, 536850.75, 188018.75, 536850.75, 188042.75, - 536850.75, 187952.25, 536850.75, 188101.75, 536850.75, 188039.25, 536850.75, 188040.25, - 536850.75, 188052.75, 536850.75, 188052.25, 536850.75, 188134.75, 536850.75, 187993.75, - 536850.75, 188012.75, 536850.75, 187968.25, 536850.75, 187927.75, 536850.75, 187971.75, - 536850.75, 187943.75, 536850.75, 188042.25, 536850.75, 187958.25, 536850.75, 187939.25, - 536850.75, 188021.25, 536850.75, 188103.25, 536850.75, 187951.75, 536851.25, 187935.25, - 536851.25, 188125.75, 536851.25, 187993.75, 536851.25, 188064.25, 536851.25, 188120.25, - 536851.25, 188004.75, 536851.25, 188083.75, 536851.25, 188002.25, 536851.25, 188142.25, - 536851.25, 188110.75, 536851.25, 188097.75, 536851.25, 188157.25, 536851.25, 188020.25, - 536851.25, 188121.75, 536851.25, 187986.25, 536851.25, 187983.25, 536851.25, 188099.75, - 536851.25, 187992.25, 536851.25, 187935.75, 536851.25, 188079.75, 536851.25, 187997.75, - 536851.25, 188104.25, 536851.25, 188041.75, 536851.25, 187972.25, 536851.25, 188157.75, - 536851.25, 188057.75, 536851.25, 188080.25, 536851.25, 188019.25, 536851.25, 188106.75, - 536851.25, 187950.25, 536851.25, 188017.25, 536851.25, 188095.75, 536851.25, 187937.75, - 536851.25, 188020.75, 536851.25, 188084.75, 536851.25, 188079.25, 536851.25, 187951.25, - 536851.25, 187976.75, 536851.25, 188043.25, 536851.25, 188101.25, 536851.25, 187992.75, - 536851.25, 187957.25, 536851.25, 188135.75, 536851.25, 187973.25, 536851.25, 188111.25, - 536851.25, 188080.75, 536851.25, 188049.75, 536851.25, 187944.25, 536851.25, 188159.25, - 536851.25, 187953.75, 536851.25, 187952.75, 536851.25, 188012.25, 536851.25, 187956.25, - 536851.25, 188049.25, 536851.25, 188016.25, 536851.25, 188102.25, 536851.25, 188118.25, - 536851.25, 188019.75, 536851.25, 188038.75, 536851.25, 188039.25, 536851.25, 188106.25, - 536851.25, 187945.75, 536851.25, 188096.25, 536851.25, 188021.25, 536851.75, 188036.75, - 536851.75, 188146.25, 536851.75, 188083.25, 536851.75, 188078.25, 536851.75, 188107.25, - 536851.75, 188019.75, 536851.75, 187982.75, 536851.75, 188144.25, 536851.75, 187956.25, - 536851.75, 188016.25, 536851.75, 188136.75, 536851.75, 188156.75, 536851.75, 187953.25, - 536851.75, 187973.25, 536851.75, 187937.25, 536851.75, 188125.25, 536851.75, 188106.25, - 536851.75, 188086.75, 536851.75, 187950.25, 536851.75, 188095.75, 536851.75, 188013.75, - 536851.75, 187998.75, 536851.75, 188151.25, 536851.75, 187947.75, 536851.75, 188021.75, - 536851.75, 188015.75, 536851.75, 188003.25, 536851.75, 188080.25, 536851.75, 188007.25, - 536851.75, 188032.75, 536851.75, 187992.25, 536851.75, 187990.75, 536851.75, 188106.75, - 536851.75, 188157.25, 536851.75, 188018.75, 536851.75, 187981.75, 536851.75, 187994.25, - 536851.75, 187972.25, 536851.75, 188085.75, 536851.75, 188091.75, 536851.75, 188002.75, - 536851.75, 187943.25, 536851.75, 188095.25, 536851.75, 188100.75, 536851.75, 188075.75, - 536851.75, 188158.75, 536851.75, 188002.25, 536851.75, 187949.75, 536851.75, 187933.25, - 536851.75, 188018.25, 536851.75, 188104.75, 536851.75, 188082.25, 536851.75, 187938.75, - 536851.75, 187952.25, 536851.75, 188158.25, 536851.75, 187965.25, 536851.75, 187951.75, - 536851.75, 188139.75, 536851.75, 187965.75, 536851.75, 188061.75, 536851.75, 188079.25, - 536851.75, 188064.75, 536851.75, 188084.75, 536851.75, 188013.25, 536851.75, 188007.75, - 536851.75, 188028.25, 536851.75, 188041.75, 536851.75, 188103.75, 536851.75, 187936.75, - 536851.75, 188096.75, 536851.75, 187983.75, 536851.75, 188100.25, 536851.75, 187973.75, - 536851.75, 187954.25, 536851.75, 188074.25, 536851.75, 187947.25, 536851.75, 187993.25, - 536851.75, 188022.75, 536851.75, 188068.25, 536851.75, 188081.75, 536851.75, 187958.75, - 536851.75, 188138.25, 536851.75, 188061.25, 536851.75, 188022.25, 536851.75, 188017.75, - 536851.75, 188053.25, 536851.75, 187942.75, 536851.75, 188085.25, 536851.75, 188157.75, - 536852.25, 187937.75, 536852.25, 188018.25, 536852.25, 188081.75, 536852.25, 187941.25, - 536852.25, 188160.25, 536852.25, 188017.75, 536852.25, 188035.75, 536852.25, 188054.75, - 536852.25, 188033.25, 536852.25, 188155.75, 536852.25, 187992.75, 536852.25, 188077.25, - 536852.25, 187951.25, 536852.25, 188103.75, 536852.25, 188116.75, 536852.25, 187972.25, - 536852.25, 188095.75, 536852.25, 188002.25, 536852.25, 188106.25, 536852.25, 188082.25, - 536852.25, 188099.75, 536852.25, 187994.25, 536852.25, 188096.75, 536852.25, 187949.75, - 536852.25, 188159.25, 536852.25, 187992.25, 536852.25, 188019.25, 536852.25, 188013.75, - 536852.25, 188146.75, 536852.25, 188036.75, 536852.25, 187982.25, 536852.25, 188107.25, - 536852.25, 188079.25, 536852.25, 187954.25, 536852.25, 187976.75, 536852.25, 188095.25, - 536852.25, 188086.25, 536852.25, 188117.25, 536852.25, 188083.25, 536852.25, 188003.25, - 536852.25, 188101.25, 536852.25, 188012.25, 536852.25, 188021.75, 536852.25, 187991.75, - 536852.25, 188113.25, 536852.25, 188124.25, 536852.25, 188104.75, 536852.25, 188015.75, - 536852.25, 187955.25, 536852.25, 188085.75, 536852.25, 188078.25, 536852.25, 187948.75, - 536852.25, 188022.25, 536852.25, 187935.25, 536852.25, 188019.75, 536852.25, 188157.75, - 536852.25, 188042.25, 536852.25, 188136.75, 536852.25, 187958.75, 536852.25, 187910.75, - 536852.25, 187950.25, 536852.25, 187953.25, 536852.25, 188022.75, 536852.25, 188106.75, - 536852.25, 187952.25, 536852.25, 188060.75, 536852.25, 187942.75, 536852.25, 188094.25, - 536852.25, 188085.25, 536852.25, 188037.25, 536852.25, 187958.25, 536852.25, 188002.75, - 536852.25, 188018.75, 536852.25, 188041.25, 536852.75, 187983.25, 536852.75, 187990.75, - 536852.75, 187997.75, 536852.75, 188018.25, 536852.75, 187950.75, 536852.75, 188071.75, - 536852.75, 188011.75, 536852.75, 188002.75, 536852.75, 187977.75, 536852.75, 188069.25, - 536852.75, 188045.25, 536852.75, 188158.25, 536852.75, 188116.75, 536852.75, 188123.25, - 536852.75, 187956.75, 536852.75, 188133.25, 536852.75, 188105.25, 536852.75, 187933.75, - 536852.75, 187953.75, 536852.75, 188133.75, 536852.75, 188080.25, 536852.75, 187993.75, - 536852.75, 188078.75, 536852.75, 188098.25, 536852.75, 188108.25, 536852.75, 188084.75, - 536852.75, 188016.75, 536852.75, 188012.75, 536852.75, 187973.25, 536852.75, 188023.75, - 536852.75, 187993.25, 536852.75, 188149.25, 536852.75, 187936.25, 536852.75, 188085.75, - 536852.75, 188035.75, 536852.75, 188091.25, 536852.75, 187941.25, 536852.75, 187941.75, - 536852.75, 188155.75, 536852.75, 188077.25, 536852.75, 188100.75, 536852.75, 188087.25, - 536852.75, 188022.25, 536852.75, 187944.25, 536852.75, 188144.75, 536852.75, 188003.75, - 536852.75, 188096.25, 536852.75, 188084.25, 536852.75, 187992.75, 536852.75, 187983.75, - 536852.75, 188091.75, 536852.75, 187948.75, 536852.75, 187934.75, 536852.75, 188148.25, - 536852.75, 188072.25, 536852.75, 187994.25, 536852.75, 188036.25, 536852.75, 187936.75, - 536852.75, 188075.75, 536852.75, 188125.75, 536852.75, 187955.25, 536852.75, 187949.25, - 536852.75, 187932.25, 536852.75, 188001.25, 536852.75, 188127.75, 536852.75, 188016.25, - 536852.75, 188052.25, 536852.75, 188159.25, 536852.75, 188112.25, 536852.75, 187991.75, - 536852.75, 188024.25, 536852.75, 188151.75, 536852.75, 188083.75, 536852.75, 188151.25, - 536852.75, 188104.25, 536852.75, 188013.25, 536852.75, 188156.75, 536852.75, 188099.25, - 536852.75, 187944.75, 536852.75, 188107.25, 536852.75, 187972.75, 536852.75, 188095.25, - 536852.75, 188017.25, 536853.25, 187982.75, 536853.25, 188003.25, 536853.25, 188095.25, - 536853.25, 188028.75, 536853.25, 187995.25, 536853.25, 188023.25, 536853.25, 188117.25, - 536853.25, 188080.75, 536853.25, 187946.75, 536853.25, 188109.25, 536853.25, 188105.75, - 536853.25, 188017.25, 536853.25, 187947.75, 536853.25, 188012.25, 536853.25, 188135.25, - 536853.25, 188011.25, 536853.25, 188142.25, 536853.25, 188107.75, 536853.25, 188159.25, - 536853.25, 188154.25, 536853.25, 188024.25, 536853.25, 188151.25, 536853.25, 188093.75, - 536853.25, 188082.75, 536853.25, 188111.75, 536853.25, 188066.75, 536853.25, 188052.75, - 536853.25, 187957.75, 536853.25, 188104.75, 536853.25, 188052.25, 536853.25, 187989.25, - 536853.25, 188098.75, 536853.25, 187949.25, 536853.25, 187955.25, 536853.25, 188075.75, - 536853.25, 188077.75, 536853.25, 187991.25, 536853.25, 188156.25, 536853.25, 188043.75, - 536853.25, 188137.75, 536853.25, 187998.25, 536853.25, 188151.75, 536853.25, 188036.25, - 536853.25, 188118.75, 536853.25, 187943.75, 536853.25, 188074.75, 536853.25, 188099.75, - 536853.25, 187938.25, 536853.25, 187973.75, 536853.25, 188082.25, 536853.25, 188138.75, - 536853.25, 187995.75, 536853.25, 188109.75, 536853.25, 187959.75, 536853.25, 188115.25, - 536853.25, 188084.25, 536853.25, 188004.25, 536853.25, 188086.75, 536853.25, 187945.75, - 536853.25, 188096.25, 536853.25, 187931.75, 536853.25, 187932.75, 536853.25, 188008.75, - 536853.25, 187974.25, 536853.25, 188073.25, 536853.25, 188077.25, 536853.25, 188087.25, - 536853.25, 187940.25, 536853.25, 188155.75, 536853.25, 187994.75, 536853.25, 187953.25, - 536853.25, 188121.25, 536853.25, 187941.75, 536853.25, 188091.25, 536853.25, 188035.75, - 536853.25, 187936.25, 536853.25, 187971.75, 536853.25, 188150.75, 536853.25, 187984.25, - 536853.25, 187954.75, 536853.25, 188015.25, 536853.25, 188158.75, 536853.25, 187968.75, - 536853.25, 188152.25, 536853.25, 188153.75, 536853.25, 188152.75, 536853.25, 187971.25, - 536853.25, 187957.25, 536853.25, 188022.75, 536853.25, 187933.75, 536853.25, 187939.75, - 536853.25, 188000.25, 536853.25, 188076.75, 536853.25, 188105.25, 536853.25, 188143.25, - 536853.25, 188112.75, 536853.25, 187997.25, 536853.25, 187944.75, 536853.25, 188011.75, - 536853.25, 188002.75, 536853.25, 188087.75, 536853.25, 188117.75, 536853.25, 188130.75, - 536853.25, 188079.75, 536853.75, 187946.25, 536853.75, 187991.25, 536853.75, 187983.25, - 536853.75, 188155.25, 536853.75, 187996.75, 536853.75, 187955.25, 536853.75, 188118.25, - 536853.75, 187945.25, 536853.75, 188022.25, 536853.75, 187994.75, 536853.75, 187984.25, - 536853.75, 188023.75, 536853.75, 188157.25, 536853.75, 188015.25, 536853.75, 188144.25, - 536853.75, 188012.25, 536853.75, 188087.25, 536853.75, 187947.75, 536853.75, 188003.25, - 536853.75, 187974.25, 536853.75, 188076.75, 536853.75, 187982.75, 536853.75, 187947.25, - 536853.75, 188016.75, 536853.75, 187930.75, 536853.75, 187939.25, 536853.75, 188000.25, - 536853.75, 187972.75, 536853.75, 187997.25, 536853.75, 188152.25, 536853.75, 187988.25, - 536853.75, 187959.25, 536853.75, 188036.75, 536853.75, 188083.25, 536853.75, 187957.25, - 536853.75, 187934.75, 536853.75, 188120.25, 536853.75, 188086.75, 536853.75, 188018.75, - 536853.75, 188117.75, 536853.75, 188014.75, 536853.75, 188010.25, 536853.75, 187940.75, - 536853.75, 187990.75, 536853.75, 188097.75, 536853.75, 188011.25, 536853.75, 188105.25, - 536853.75, 188107.75, 536853.75, 188108.75, 536853.75, 188143.25, 536853.75, 188082.75, - 536853.75, 188073.75, 536853.75, 187993.25, 536853.75, 188094.75, 536853.75, 188153.75, - 536853.75, 187957.75, 536853.75, 188158.75, 536853.75, 188095.75, 536853.75, 188142.75, - 536853.75, 188004.75, 536853.75, 188075.75, 536853.75, 188118.75, 536853.75, 188035.75, - 536853.75, 188150.75, 536853.75, 188103.25, 536853.75, 188154.75, 536853.75, 187943.75, - 536853.75, 188036.25, 536853.75, 188097.25, 536853.75, 188099.75, 536853.75, 188079.75, - 536853.75, 188013.25, 536853.75, 188091.75, 536853.75, 188159.25, 536853.75, 188082.25, - 536853.75, 188024.25, 536853.75, 187970.75, 536853.75, 188141.75, 536853.75, 188077.25, - 536853.75, 187972.25, 536853.75, 187949.25, 536853.75, 188086.25, 536853.75, 187944.75, - 536853.75, 187954.25, 536853.75, 188142.25, 536853.75, 188130.25, 536853.75, 188051.25, - 536853.75, 187946.75, 536854.25, 188122.75, 536854.25, 187946.25, 536854.25, 188119.25, - 536854.25, 188110.25, 536854.25, 187983.25, 536854.25, 188150.25, 536854.25, 188054.25, - 536854.25, 188003.75, 536854.25, 188142.25, 536854.25, 187997.75, 536854.25, 188126.25, - 536854.25, 187995.25, 536854.25, 188100.75, 536854.25, 188086.25, 536854.25, 187938.25, - 536854.25, 188078.25, 536854.25, 187955.25, 536854.25, 187983.75, 536854.25, 188010.75, - 536854.25, 188046.75, 536854.25, 188057.25, 536854.25, 188024.25, 536854.25, 188081.25, - 536854.25, 188105.75, 536854.25, 188112.25, 536854.25, 187944.25, 536854.25, 188022.25, - 536854.25, 188011.75, 536854.25, 188116.25, 536854.25, 188016.25, 536854.25, 187998.25, - 536854.25, 188023.75, 536854.25, 187933.25, 536854.25, 187911.75, 536854.25, 188144.25, - 536854.25, 188106.75, 536854.25, 188070.75, 536854.25, 188073.25, 536854.25, 188097.25, - 536854.25, 188035.25, 536854.25, 188036.25, 536854.25, 188080.75, 536854.25, 188124.75, - 536854.25, 188012.25, 536854.25, 188154.75, 536854.25, 188140.75, 536854.25, 187954.75, - 536854.25, 188152.25, 536854.25, 188055.75, 536854.25, 187947.75, 536854.25, 188153.25, - 536854.25, 188077.75, 536854.25, 187945.75, 536854.25, 188159.75, 536854.25, 187939.75, - 536854.25, 187942.75, 536854.25, 188143.75, 536854.25, 187969.75, 536854.25, 187973.75, - 536854.25, 188004.75, 536854.25, 188118.25, 536854.25, 187971.75, 536854.25, 187958.25, - 536854.25, 188118.75, 536854.25, 188075.25, 536854.25, 187932.25, 536854.25, 188158.75, - 536854.25, 188112.75, 536854.25, 187971.25, 536854.25, 187955.75, 536854.25, 187979.25, - 536854.25, 188081.75, 536854.25, 188010.25, 536854.25, 188022.75, 536854.25, 187995.75, - 536854.25, 188014.25, 536854.25, 188097.75, 536854.25, 188073.75, 536854.25, 188111.75, - 536854.25, 187943.25, 536854.25, 188082.75, 536854.25, 187993.75, 536854.25, 188026.75, - 536854.25, 187924.75, 536854.25, 187985.25, 536854.25, 188151.25, 536854.75, 187985.25, - 536854.75, 188141.25, 536854.75, 188009.25, 536854.75, 188005.25, 536854.75, 188151.25, - 536854.75, 187946.25, 536854.75, 188013.75, 536854.75, 187992.25, 536854.75, 188130.25, - 536854.75, 188150.25, 536854.75, 188133.75, 536854.75, 187995.75, 536854.75, 188078.75, - 536854.75, 187993.25, 536854.75, 187928.25, 536854.75, 188022.75, 536854.75, 188093.25, - 536854.75, 188085.25, 536854.75, 187970.25, 536854.75, 188152.75, 536854.75, 188128.25, - 536854.75, 187925.25, 536854.75, 188012.25, 536854.75, 188158.75, 536854.75, 187985.75, - 536854.75, 187975.25, 536854.75, 187968.25, 536854.75, 187960.25, 536854.75, 187993.75, - 536854.75, 188014.75, 536854.75, 187959.25, 536854.75, 188106.25, 536854.75, 188075.75, - 536854.75, 187969.75, 536854.75, 188075.25, 536854.75, 188143.75, 536854.75, 187910.75, - 536854.75, 187984.75, 536854.75, 188133.25, 536854.75, 188080.25, 536854.75, 188067.25, - 536854.75, 187943.75, 536854.75, 187942.75, 536854.75, 188035.75, 536854.75, 188098.25, - 536854.75, 188041.75, 536854.75, 188063.25, 536854.75, 188159.75, 536854.75, 188046.25, - 536854.75, 188146.25, 536854.75, 187966.75, 536854.75, 188153.25, 536854.75, 188119.25, - 536854.75, 188077.75, 536854.75, 188116.75, 536854.75, 188009.75, 536854.75, 187954.75, - 536854.75, 187927.75, 536854.75, 187945.75, 536854.75, 188140.75, 536854.75, 188160.25, - 536854.75, 187955.75, 536854.75, 187973.75, 536854.75, 188008.75, 536854.75, 188136.75, - 536854.75, 188080.75, 536854.75, 188091.75, 536854.75, 188081.25, 536854.75, 187974.25, - 536854.75, 188015.25, 536854.75, 187941.75, 536854.75, 187936.75, 536854.75, 187934.25, - 536854.75, 188030.75, 536854.75, 187930.25, 536854.75, 188113.25, 536854.75, 188023.75, - 536854.75, 188109.25, 536854.75, 188070.25, 536854.75, 188110.25, 536854.75, 187998.25, - 536854.75, 188148.25, 536854.75, 188144.75, 536854.75, 188046.75, 536854.75, 187986.75, - 536854.75, 188110.75, 536854.75, 187969.25, 536854.75, 187931.25, 536854.75, 188010.75, - 536854.75, 187994.75, 536854.75, 188105.75, 536854.75, 188148.75, 536854.75, 188072.75, - 536854.75, 188086.25, 536854.75, 188074.75, 536854.75, 187992.75, 536854.75, 187997.75, - 536854.75, 188151.75, 536854.75, 187974.75, 536854.75, 188004.25, 536854.75, 188023.25, - 536854.75, 188078.25, 536855.25, 188150.25, 536855.25, 188151.75, 536855.25, 188111.75, - 536855.25, 188151.25, 536855.25, 188067.75, 536855.25, 188105.75, 536855.25, 188078.25, - 536855.25, 188073.75, 536855.25, 188023.75, 536855.25, 187997.75, 536855.25, 188048.25, - 536855.25, 188002.25, 536855.25, 188104.75, 536855.25, 188011.75, 536855.25, 188119.25, - 536855.25, 188152.75, 536855.25, 188005.25, 536855.25, 188077.25, 536855.25, 188074.75, - 536855.25, 187974.25, 536855.25, 187955.25, 536855.25, 188145.25, 536855.25, 187974.75, - 536855.25, 188004.25, 536855.25, 188023.25, 536855.25, 187969.25, 536855.25, 187993.25, - 536855.25, 188084.25, 536855.25, 188009.25, 536855.25, 187937.75, 536855.25, 188046.75, - 536855.25, 187992.25, 536855.25, 188024.25, 536855.25, 188097.75, 536855.25, 187932.75, - 536855.25, 187931.75, 536855.25, 188013.75, 536855.25, 188078.75, 536855.25, 188093.75, - 536855.25, 187992.75, 536855.25, 187944.75, 536855.25, 188112.25, 536855.25, 188158.75, - 536855.25, 188106.25, 536855.25, 187932.25, 536855.25, 188085.25, 536855.25, 188014.75, - 536855.25, 188021.25, 536855.25, 187970.75, 536855.25, 187945.25, 536855.25, 188080.75, - 536855.25, 187930.75, 536855.25, 188053.75, 536855.25, 188075.75, 536855.25, 188147.75, - 536855.25, 188091.25, 536855.25, 188112.75, 536855.25, 187984.25, 536855.25, 188148.25, - 536855.25, 188152.25, 536855.25, 188137.25, 536855.25, 188015.25, 536855.25, 187959.25, - 536855.25, 187968.25, 536855.25, 188106.75, 536855.25, 188140.75, 536855.25, 188083.75, - 536855.25, 187987.75, 536855.25, 187993.75, 536855.25, 188116.75, 536855.25, 188009.75, - 536855.25, 188072.25, 536855.25, 187973.75, 536855.25, 188143.75, 536855.25, 188075.25, - 536855.25, 188096.75, 536855.25, 187986.25, 536855.25, 188071.25, 536855.25, 187939.25, - 536855.25, 187954.75, 536855.25, 188085.75, 536855.25, 188109.75, 536855.25, 188117.25, - 536855.25, 188035.75, 536855.25, 188153.25, 536855.25, 188064.75, 536855.25, 188109.25, - 536855.25, 188098.25, 536855.25, 188036.25, 536855.25, 187994.25, 536855.25, 188159.75, - 536855.25, 187969.75, 536855.25, 187968.75, 536855.25, 188008.75, 536855.25, 187936.25, - 536855.75, 187975.25, 536855.75, 188067.25, 536855.75, 188098.25, 536855.75, 187996.25, - 536855.75, 187942.75, 536855.75, 187978.75, 536855.75, 188035.75, 536855.75, 187959.75, - 536855.75, 188084.75, 536855.75, 187968.75, 536855.75, 188077.75, 536855.75, 188070.75, - 536855.75, 188116.75, 536855.75, 188008.75, 536855.75, 187943.75, 536855.75, 188075.25, - 536855.75, 188144.25, 536855.75, 188034.75, 536855.75, 187927.75, 536855.75, 188083.25, - 536855.75, 188114.25, 536855.75, 188118.25, 536855.75, 188070.25, 536855.75, 188113.25, - 536855.75, 188130.75, 536855.75, 187961.25, 536855.75, 188157.25, 536855.75, 188015.25, - 536855.75, 188008.25, 536855.75, 187958.75, 536855.75, 188007.25, 536855.75, 188113.75, - 536855.75, 187967.75, 536855.75, 187995.25, 536855.75, 187998.25, 536855.75, 188099.25, - 536855.75, 188024.25, 536855.75, 187956.25, 536855.75, 187971.25, 536855.75, 188072.75, - 536855.75, 187991.75, 536855.75, 188118.75, 536855.75, 188141.75, 536855.75, 188014.25, - 536855.75, 187944.75, 536855.75, 188112.25, 536855.75, 187972.25, 536855.75, 187998.75, - 536855.75, 188105.25, 536855.75, 187931.75, 536855.75, 188009.25, 536855.75, 188157.75, - 536855.75, 187990.75, 536855.75, 188010.75, 536855.75, 188074.75, 536855.75, 187994.75, - 536855.75, 187994.25, 536855.75, 187971.75, 536855.75, 187985.25, 536855.75, 188104.25, - 536855.75, 187928.25, 536855.75, 187974.25, 536855.75, 188148.75, 536855.75, 188005.25, - 536855.75, 188054.25, 536855.75, 188078.25, 536855.75, 188159.25, 536855.75, 188023.75, - 536856.25, 188141.25, 536856.25, 187997.25, 536856.25, 187985.75, 536856.25, 188024.75, - 536856.25, 187923.75, 536856.25, 188100.25, 536856.25, 187943.25, 536856.25, 187970.25, - 536856.25, 188151.25, 536856.25, 187913.25, 536856.25, 187967.25, 536856.25, 188105.25, - 536856.25, 188125.25, 536856.25, 188114.75, 536856.25, 187993.25, 536856.25, 188156.75, - 536856.25, 187960.25, 536856.25, 188037.75, 536856.25, 188007.25, 536856.25, 188153.75, - 536856.25, 187950.75, 536856.25, 188081.75, 536856.25, 188014.75, 536856.25, 188004.75, - 536856.25, 188099.25, 536856.25, 188056.25, 536856.25, 188069.75, 536856.25, 187995.75, - 536856.25, 188043.75, 536856.25, 187929.25, 536856.25, 188072.25, 536856.25, 188119.75, - 536856.25, 187942.25, 536856.25, 188071.25, 536856.25, 188120.25, 536856.25, 187956.75, - 536856.25, 188034.25, 536856.25, 187968.75, 536856.25, 187957.25, 536856.25, 187984.75, - 536856.25, 188037.25, 536856.25, 187975.75, 536856.25, 188036.25, 536856.25, 187955.75, - 536856.25, 187952.25, 536856.25, 188068.75, 536856.25, 188035.25, 536856.25, 188159.75, - 536856.25, 188117.25, 536856.25, 187972.75, 536856.25, 188005.75, 536856.25, 188109.75, - 536856.25, 188116.75, 536856.25, 188144.25, 536856.25, 187929.75, 536856.25, 188015.75, - 536856.25, 188110.75, 536856.25, 188083.75, 536856.25, 187947.25, 536856.25, 187995.25, - 536856.25, 187973.25, 536856.25, 187941.75, 536856.25, 188157.25, 536856.25, 188148.25, - 536856.25, 187911.25, 536856.25, 188061.75, 536856.25, 187927.25, 536856.25, 188016.25, - 536856.25, 188015.25, 536856.25, 188113.75, 536856.25, 188025.25, 536856.25, 187941.25, - 536856.25, 188053.25, 536856.25, 188103.75, 536856.25, 187979.75, 536856.25, 188110.25, - 536856.25, 187991.75, 536856.25, 188144.75, 536856.25, 188151.75, 536856.25, 188142.25, - 536856.25, 188157.75, 536856.25, 188115.25, 536856.25, 187911.75, 536856.25, 187926.25, - 536856.25, 188084.25, 536856.25, 188007.75, 536856.25, 187974.75, 536856.25, 188039.25, - 536856.25, 187996.75, 536856.25, 188006.25, 536856.25, 188054.25, 536856.25, 188042.75, - 536856.25, 188098.75, 536856.25, 188067.75, 536856.25, 188103.25, 536856.75, 187955.75, - 536856.75, 188111.25, 536856.75, 187974.75, 536856.75, 188148.75, 536856.75, 187992.75, - 536856.75, 187979.75, 536856.75, 187941.25, 536856.75, 188155.75, 536856.75, 188044.25, - 536856.75, 187998.25, 536856.75, 188038.25, 536856.75, 188035.25, 536856.75, 188036.25, - 536856.75, 187941.75, 536856.75, 188005.25, 536856.75, 188109.75, 536856.75, 188040.75, - 536856.75, 188070.75, 536856.75, 188015.75, 536856.75, 188099.75, 536856.75, 187935.25, - 536856.75, 188109.25, 536856.75, 188132.25, 536856.75, 188008.75, 536856.75, 188076.25, - 536856.75, 188051.75, 536856.75, 188156.25, 536856.75, 188014.75, 536856.75, 188006.75, - 536856.75, 188082.75, 536856.75, 188118.75, 536856.75, 188151.25, 536856.75, 187970.25, - 536856.75, 188065.25, 536856.75, 187967.25, 536856.75, 188158.75, 536856.75, 188152.75, - 536856.75, 187971.75, 536856.75, 188159.75, 536856.75, 187985.75, 536856.75, 188024.75, - 536856.75, 188141.25, 536856.75, 188104.25, 536856.75, 187985.25, 536856.75, 188069.25, - 536856.75, 187992.25, 536856.75, 188114.75, 536856.75, 187972.75, 536856.75, 188034.25, - 536856.75, 188137.25, 536856.75, 188050.75, 536856.75, 187942.25, 536856.75, 187956.75, - 536856.75, 188143.75, 536856.75, 187968.75, 536856.75, 187975.75, 536856.75, 188036.75, - 536856.75, 187959.75, 536856.75, 187984.75, 536856.75, 188064.25, 536856.75, 188037.25, - 536856.75, 188068.75, 536856.75, 188117.25, 536856.75, 188004.75, 536856.75, 188110.25, - 536856.75, 188035.75, 536856.75, 188005.75, 536856.75, 188144.25, 536856.75, 188102.75, - 536856.75, 187974.25, 536856.75, 187973.25, 536856.75, 188045.25, 536856.75, 188076.75, - 536856.75, 187911.75, 536856.75, 188157.25, 536856.75, 187911.25, 536856.75, 188015.25, - 536856.75, 188053.25, 536856.75, 188144.75, 536856.75, 187994.75, 536856.75, 188007.75, - 536856.75, 187948.75, 536856.75, 188039.25, 536856.75, 188113.75, 536856.75, 187996.75, - 536856.75, 187969.25, 536856.75, 187926.75, 536856.75, 188006.25, 536856.75, 187935.75, - 536856.75, 187930.25, 536856.75, 188098.75, 536856.75, 188023.75, 536857.25, 188143.25, - 536857.25, 188023.75, 536857.25, 188021.75, 536857.25, 187950.25, 536857.25, 188160.25, - 536857.25, 188054.75, 536857.25, 188145.75, 536857.25, 188112.25, 536857.25, 187991.75, - 536857.25, 188106.25, 536857.25, 188159.25, 536857.25, 188121.75, 536857.25, 188036.75, - 536857.25, 188099.25, 536857.25, 188016.25, 536857.25, 188135.75, 536857.25, 188075.75, - 536857.25, 187992.75, 536857.25, 188068.25, 536857.25, 188076.25, 536857.25, 187967.75, - 536857.25, 187910.75, 536857.25, 188158.75, 536857.25, 188100.25, 536857.25, 187941.75, - 536857.25, 188020.25, 536857.25, 187988.25, 536857.25, 187968.25, 536857.25, 188006.25, - 536857.25, 188071.25, 536857.25, 187927.75, 536857.25, 188144.25, 536857.25, 187984.75, - 536857.25, 188016.75, 536857.25, 188015.25, 536857.25, 187959.25, 536857.25, 187941.25, - 536857.25, 188110.75, 536857.25, 188112.75, 536857.25, 188114.75, 536857.25, 188009.25, - 536857.25, 188151.25, 536857.25, 188012.25, 536857.25, 187990.75, 536857.25, 188005.75, - 536857.25, 187985.25, 536857.25, 188034.75, 536857.25, 188151.75, 536857.25, 187976.25, - 536857.25, 187969.75, 536857.25, 188094.75, 536857.25, 188038.75, 536857.25, 187960.25, - 536857.25, 187970.25, 536857.25, 187956.75, 536857.25, 188142.75, 536857.25, 188156.25, - 536857.25, 188101.75, 536857.25, 187940.75, 536857.25, 187995.25, 536857.25, 188082.25, - 536857.25, 187975.25, 536857.25, 188103.75, 536857.25, 187928.75, 536857.25, 188126.25, - 536857.25, 188155.75, 536857.25, 188033.75, 536857.25, 188153.25, 536857.25, 187935.25, - 536857.25, 188081.75, 536857.25, 188070.75, 536857.25, 188061.25, 536857.25, 188102.25, - 536857.25, 187939.75, 536857.25, 188155.25, 536857.25, 187973.75, 536857.25, 187996.25, - 536857.25, 188114.25, 536857.25, 188128.75, 536857.25, 188024.25, 536857.25, 188039.75, - 536857.25, 188038.25, 536857.25, 187997.25, 536857.25, 188141.75, 536857.25, 187956.25, - 536857.25, 188070.25, 536857.25, 188139.25, 536857.25, 187926.25, 536857.25, 187986.75, - 536857.25, 188080.75, 536857.25, 187972.25, 536857.25, 188142.25, 536857.25, 188032.75, - 536857.75, 188154.75, 536857.75, 188059.75, 536857.75, 187961.25, 536857.75, 187937.25, - 536857.75, 188154.25, 536857.75, 188115.75, 536857.75, 188142.25, 536857.75, 188032.75, - 536857.75, 188023.25, 536857.75, 188145.75, 536857.75, 188038.25, 536857.75, 188080.75, - 536857.75, 188112.25, 536857.75, 188004.25, 536857.75, 187925.25, 536857.75, 188146.25, - 536857.75, 188067.25, 536857.75, 188015.75, 536857.75, 188040.25, 536857.75, 187992.25, - 536857.75, 187997.25, 536857.75, 188042.75, 536857.75, 188102.75, 536857.75, 188024.25, - 536857.75, 187971.75, 536857.75, 188146.75, 536857.75, 187923.75, 536857.75, 188080.25, - 536857.75, 188153.75, 536857.75, 188025.75, 536857.75, 187957.75, 536857.75, 187914.25, - 536857.75, 187940.25, 536857.75, 188099.75, 536857.75, 187997.75, 536857.75, 187974.25, - 536857.75, 188145.25, 536857.75, 188061.25, 536857.75, 188070.75, 536857.75, 188055.75, - 536857.75, 187935.25, 536857.75, 187971.25, 536857.75, 187939.75, 536857.75, 187995.75, - 536857.75, 188115.25, 536857.75, 187989.75, 536857.75, 188033.75, 536857.75, 188111.25, - 536857.75, 187936.25, 536857.75, 187962.25, 536857.75, 188068.25, 536857.75, 187986.25, - 536857.75, 187923.25, 536857.75, 188158.75, 536857.75, 187970.75, 536857.75, 188044.75, - 536857.75, 187995.25, 536857.75, 188020.75, 536857.75, 188022.25, 536857.75, 188005.25, - 536857.75, 187957.25, 536857.75, 188058.25, 536857.75, 188064.75, 536857.75, 187941.75, - 536857.75, 187934.25, 536857.75, 188092.25, 536857.75, 187987.25, 536857.75, 187970.25, - 536857.75, 188150.25, 536857.75, 187968.25, 536857.75, 188022.75, 536857.75, 187925.75, - 536857.75, 188094.75, 536857.75, 187927.75, 536857.75, 187975.75, 536857.75, 188076.75, - 536857.75, 188152.25, 536857.75, 188062.75, 536857.75, 187993.75, 536857.75, 187994.75, - 536857.75, 188045.75, 536857.75, 187976.25, 536857.75, 188094.25, 536857.75, 187969.75, - 536857.75, 188150.75, 536857.75, 188151.75, 536857.75, 188077.25, 536857.75, 188037.25, - 536857.75, 188101.25, 536857.75, 187984.75, 536857.75, 187939.25, 536857.75, 188016.75, - 536857.75, 187960.75, 536857.75, 188100.75, 536857.75, 188063.25, 536857.75, 188143.75, - 536857.75, 187990.75, 536857.75, 188157.75, 536857.75, 188077.75, 536857.75, 188046.25, - 536857.75, 188112.75, 536857.75, 188041.25, 536857.75, 188151.25, 536857.75, 188124.25, - 536858.25, 187943.25, 536858.25, 188046.75, 536858.25, 187938.25, 536858.25, 187969.25, - 536858.25, 188112.75, 536858.25, 188151.25, 536858.25, 187985.25, 536858.25, 188046.25, - 536858.25, 188137.25, 536858.25, 188117.25, 536858.25, 188157.75, 536858.25, 187941.25, - 536858.25, 188143.75, 536858.25, 187994.25, 536858.25, 188052.75, 536858.25, 187990.75, - 536858.25, 188083.75, 536858.25, 188100.75, 536858.25, 187960.75, 536858.25, 187939.25, - 536858.25, 188101.25, 536858.25, 188034.75, 536858.25, 188005.75, 536858.25, 188151.75, - 536858.25, 187969.75, 536858.25, 188150.75, 536858.25, 187985.75, 536858.25, 187976.25, - 536858.25, 188045.75, 536858.25, 188152.25, 536858.25, 187993.75, 536858.25, 187957.25, - 536858.25, 188110.25, 536858.25, 188076.75, 536858.25, 188144.25, 536858.25, 188016.75, - 536858.25, 188120.25, 536858.25, 188094.75, 536858.25, 187959.75, 536858.25, 188020.25, - 536858.25, 187975.75, 536858.25, 188037.75, 536858.25, 187987.25, 536858.25, 187956.75, - 536858.25, 187934.25, 536858.25, 188037.25, 536858.25, 188011.75, 536858.25, 188150.25, - 536858.25, 188101.75, 536858.25, 188056.25, 536858.25, 188156.25, 536858.25, 188109.75, - 536858.25, 188005.25, 536858.25, 187995.25, 536858.25, 187970.75, 536858.25, 188061.75, - 536858.25, 188149.25, 536858.25, 187993.25, 536858.25, 188079.25, 536858.25, 187967.75, - 536858.25, 187939.75, 536858.25, 188068.25, 536858.25, 188076.25, 536858.25, 187936.75, - 536858.25, 187962.25, 536858.25, 187995.75, 536858.25, 188155.75, 536858.25, 188115.25, - 536858.25, 188033.75, 536858.25, 187935.25, 536858.25, 187927.25, 536858.25, 188145.25, - 536858.25, 188081.75, 536858.25, 188079.75, 536858.25, 188099.75, 536858.25, 188043.75, - 536858.25, 187940.25, 536858.25, 188021.25, 536858.25, 188015.75, 536858.25, 188134.75, - 536858.25, 188040.75, 536858.25, 188067.75, 536858.25, 187989.25, 536858.25, 187997.75, - 536858.25, 187923.75, 536858.25, 188102.75, 536858.25, 188042.75, 536858.25, 187973.25, - 536858.25, 188070.25, 536858.25, 187992.25, 536858.25, 187956.25, 536858.25, 188039.25, - 536858.25, 188113.75, 536858.25, 188067.25, 536858.25, 188032.75, 536858.25, 187996.75, - 536858.25, 188146.25, 536858.25, 188159.75, 536858.25, 187926.25, 536858.25, 188080.75, - 536858.25, 187925.25, 536858.25, 188023.25, 536858.25, 188121.25, 536858.25, 188154.25, - 536858.25, 187972.75, 536858.25, 187961.25, 536858.75, 187961.25, 536858.75, 188024.25, - 536858.75, 187971.75, 536858.75, 188157.75, 536858.75, 188115.75, 536858.75, 188056.75, - 536858.75, 187921.25, 536858.75, 188032.75, 536858.75, 187960.75, 536858.75, 187958.25, - 536858.75, 188143.75, 536858.75, 188127.25, 536858.75, 187991.75, 536858.75, 187938.25, - 536858.75, 188110.75, 536858.75, 187997.75, 536858.75, 187938.75, 536858.75, 188077.75, - 536858.75, 188036.75, 536858.75, 188087.25, 536858.75, 188016.75, 536858.75, 187972.75, - 536858.75, 188057.25, 536858.75, 188037.25, 536858.75, 188150.25, 536858.75, 187989.25, - 536858.75, 188054.75, 536858.75, 188029.25, 536858.75, 187976.75, 536858.75, 187968.75, - 536858.75, 187926.25, 536858.75, 188063.25, 536858.75, 187996.75, 536858.75, 187928.25, - 536858.75, 188101.25, 536858.75, 187971.25, 536858.75, 187929.75, 536858.75, 188043.25, - 536858.75, 187926.75, 536858.75, 187994.75, 536858.75, 187973.25, 536858.75, 187955.75, - 536858.75, 188003.25, 536858.75, 188004.75, 536858.75, 187976.25, 536858.75, 188002.75, - 536858.75, 188039.75, 536858.75, 188022.75, 536858.75, 188119.25, 536858.75, 188062.75, - 536858.75, 188020.75, 536858.75, 188066.75, 536858.75, 188060.75, 536858.75, 188040.75, - 536858.75, 188067.75, 536858.75, 188156.75, 536858.75, 187923.25, 536858.75, 188053.75, - 536858.75, 188158.75, 536858.75, 188100.25, 536858.75, 188131.25, 536858.75, 188055.75, - 536858.75, 187954.75, 536858.75, 187975.75, 536858.75, 187998.25, 536858.75, 188149.25, - 536858.75, 188022.25, 536858.75, 188079.75, 536858.75, 187956.75, 536858.75, 187946.75, - 536858.75, 187924.75, 536858.75, 188078.75, 536858.75, 188111.25, 536858.75, 188152.75, - 536858.75, 188066.25, 536858.75, 188038.75, 536858.75, 188115.25, 536858.75, 188153.25, - 536858.75, 188148.75, 536858.75, 187989.75, 536858.75, 187987.25, 536858.75, 187936.75, - 536858.75, 188036.25, 536858.75, 188019.25, 536858.75, 188140.75, 536858.75, 187986.25, - 536858.75, 188079.25, 536858.75, 188052.25, 536858.75, 187992.75, 536858.75, 188044.25, - 536858.75, 188148.25, 536858.75, 188016.25, 536859.25, 188061.75, 536859.25, 188116.25, - 536859.25, 187922.75, 536859.25, 187986.25, 536859.25, 187932.25, 536859.25, 187974.75, - 536859.25, 188027.25, 536859.25, 188016.25, 536859.25, 187928.75, 536859.25, 187987.75, - 536859.25, 187921.75, 536859.25, 188038.75, 536859.25, 188153.25, 536859.25, 188065.75, - 536859.25, 187936.75, 536859.25, 187935.25, 536859.25, 188066.25, 536859.25, 187980.75, - 536859.25, 188061.25, 536859.25, 188111.25, 536859.25, 187970.25, 536859.25, 188058.25, - 536859.25, 187936.25, 536859.25, 188078.75, 536859.25, 188062.25, 536859.25, 188057.75, - 536859.25, 188033.25, 536859.25, 187946.25, 536859.25, 188079.75, 536859.25, 188076.25, - 536859.25, 188142.75, 536859.25, 188022.25, 536859.25, 187954.75, 536859.25, 187973.75, - 536859.25, 188017.75, 536859.25, 187998.25, 536859.25, 188129.25, 536859.25, 188003.75, - 536859.25, 187937.75, 536859.25, 187998.75, 536859.25, 188044.75, 536859.25, 188047.25, - 536859.25, 188159.25, 536859.25, 188153.75, 536859.25, 187991.25, 536859.25, 188018.75, - 536859.25, 188039.25, 536859.25, 187990.25, 536859.25, 188048.75, 536859.25, 188149.75, - 536859.25, 188002.25, 536859.25, 187996.25, 536859.25, 188039.75, 536859.25, 188019.75, - 536859.25, 188040.75, 536859.25, 188025.25, 536859.25, 188022.75, 536859.25, 188146.75, - 536859.25, 187955.75, 536859.25, 188003.25, 536859.25, 188155.75, 536859.25, 188017.25, - 536859.25, 187932.75, 536859.25, 188120.25, 536859.25, 188024.75, 536859.25, 187988.75, - 536859.25, 188116.75, 536859.25, 188034.75, 536859.25, 188143.25, 536859.25, 188158.25, - 536859.25, 188023.75, 536859.25, 187961.25, 536859.25, 187986.75, 536859.25, 188055.25, - 536859.25, 188060.25, 536859.25, 187930.25, 536859.25, 188150.25, 536859.25, 187942.25, - 536859.25, 187962.75, 536859.25, 187937.25, 536859.25, 188117.25, 536859.25, 188157.25, - 536859.25, 188032.25, 536859.25, 188059.75, 536859.25, 188112.75, 536859.25, 188006.25, - 536859.25, 188046.25, 536859.25, 188024.25, 536859.25, 187920.25, 536859.25, 188141.25, - 536859.25, 188144.25, 536859.25, 188063.75, 536859.25, 187969.25, 536859.25, 187938.75, - 536859.25, 188154.75, 536859.25, 187972.25, 536859.25, 188112.25, 536859.25, 187994.25, - 536859.25, 188064.25, 536859.25, 187958.25, 536859.25, 187957.25, 536859.25, 187960.75, - 536859.25, 188155.25, 536859.25, 187993.75, 536859.25, 188100.75, 536859.25, 187955.25, - 536859.25, 188077.25, 536859.25, 187997.25, 536859.25, 188035.25, 536859.25, 187977.25, - 536859.25, 188115.75, 536859.75, 188039.75, 536859.75, 188047.25, 536859.75, 188157.75, - 536859.75, 188115.75, 536859.75, 188159.25, 536859.75, 187977.25, 536859.75, 187924.25, - 536859.75, 187998.25, 536859.75, 188003.75, 536859.75, 188035.25, 536859.75, 187955.25, - 536859.75, 188054.25, 536859.75, 188077.25, 536859.75, 188064.25, 536859.75, 188139.25, - 536859.75, 188155.25, 536859.75, 188112.25, 536859.75, 187993.75, 536859.75, 188033.25, - 536859.75, 187972.25, 536859.75, 188123.75, 536859.75, 187991.25, 536859.75, 188144.25, - 536859.75, 188141.25, 536859.75, 187954.25, 536859.75, 188153.75, 536859.75, 187937.75, - 536859.75, 188159.75, 536859.75, 187977.75, 536859.75, 188061.25, 536859.75, 188063.75, - 536859.75, 188018.75, 536859.75, 188076.75, 536859.75, 188066.75, 536859.75, 187920.25, - 536859.75, 188046.25, 536859.75, 188089.75, 536859.75, 188048.25, 536859.75, 188051.25, - 536859.75, 188153.25, 536859.75, 187927.75, 536859.75, 188151.25, 536859.75, 188024.25, - 536859.75, 188156.25, 536859.75, 187973.75, 536859.75, 188038.75, 536859.75, 188016.75, - 536859.75, 188136.75, 536859.75, 187928.75, 536859.75, 187995.75, 536859.75, 188148.25, - 536859.75, 188117.25, 536859.75, 188160.25, 536859.75, 188032.25, 536859.75, 188019.25, - 536859.75, 188036.25, 536859.75, 188016.25, 536859.75, 187976.75, 536859.75, 188116.25, - 536859.75, 187990.75, 536859.75, 188140.75, 536859.75, 187968.75, 536859.75, 188002.25, - 536859.75, 187922.75, 536859.75, 187986.25, 536859.75, 188143.25, 536859.75, 188109.75, - 536859.75, 188116.75, 536859.75, 188001.25, 536859.75, 188040.75, 536859.75, 188034.75, - 536859.75, 188114.25, 536859.75, 188050.75, 536859.75, 188128.75, 536859.75, 188065.75, - 536859.75, 187936.75, 536859.75, 187944.75, 536859.75, 187974.75, 536859.75, 188078.25, - 536859.75, 188058.75, 536859.75, 188134.25, 536859.75, 188111.25, 536859.75, 188003.25, - 536859.75, 188056.25, 536859.75, 187970.25, 536859.75, 188113.25, 536859.75, 187986.75, - 536859.75, 188022.75, 536859.75, 187988.75, 536859.75, 188152.25, 536859.75, 188034.25, - 536859.75, 188026.25, 536859.75, 188039.25, 536859.75, 188043.25, 536859.75, 188076.25, - 536859.75, 188155.75, 536859.75, 188002.75, 536859.75, 187975.75, 536859.75, 187932.75, - 536859.75, 188149.75, 536859.75, 187998.75, 536859.75, 187971.25, 536859.75, 188135.75, - 536859.75, 187910.75, 536859.75, 187990.25, 536860.25, 188088.75, 536860.25, 187987.75, - 536860.25, 188009.75, 536860.25, 188053.75, 536860.25, 187998.75, 536860.25, 188062.75, - 536860.25, 188000.75, 536860.25, 188039.25, 536860.25, 187953.25, 536860.25, 187933.75, - 536860.25, 188057.75, 536860.25, 187973.25, 536860.25, 187969.75, 536860.25, 188064.75, - 536860.25, 187996.75, 536860.25, 188035.75, 536860.25, 188074.75, 536860.25, 187970.25, - 536860.25, 188001.75, 536860.25, 187988.75, 536860.25, 187954.25, 536860.25, 188143.25, - 536860.25, 188062.25, 536860.25, 187992.25, 536860.25, 188003.25, 536860.25, 188047.75, - 536860.25, 188152.75, 536860.25, 188023.25, 536860.25, 188085.75, 536860.25, 188060.25, - 536860.25, 187988.25, 536860.25, 187961.25, 536860.25, 188017.25, 536860.25, 187929.25, - 536860.25, 188095.25, 536860.25, 188001.25, 536860.25, 188116.75, 536860.25, 188050.75, - 536860.25, 188146.75, 536860.25, 187986.25, 536860.25, 187932.25, 536860.25, 188055.75, - 536860.25, 188120.25, 536860.25, 188052.25, 536860.25, 187973.75, 536860.25, 188158.25, - 536860.25, 188124.75, 536860.25, 187981.75, 536860.25, 188061.75, 536860.25, 187923.75, - 536860.25, 187976.75, 536860.25, 188079.25, 536860.25, 187989.25, 536860.25, 188141.75, - 536860.25, 187974.75, 536860.25, 188036.25, 536860.25, 188037.25, 536860.25, 187962.75, - 536860.25, 188117.25, 536860.25, 188016.25, 536860.25, 188142.25, 536860.25, 188067.25, - 536860.25, 187928.75, 536860.25, 188075.25, 536860.25, 188059.75, 536860.25, 188024.25, - 536860.25, 187989.75, 536860.25, 188153.25, 536860.25, 187991.75, 536860.25, 188113.75, - 536860.25, 188111.75, 536860.25, 188119.75, 536860.25, 187997.75, 536860.25, 188052.75, - 536860.25, 188156.25, 536860.25, 188066.25, 536860.25, 188050.25, 536860.25, 188063.75, - 536860.25, 188141.25, 536860.25, 187977.75, 536860.25, 188038.25, 536860.25, 188159.75, - 536860.25, 188043.75, 536860.25, 187931.75, 536860.25, 188151.25, 536860.25, 188048.75, - 536860.25, 188033.25, 536860.25, 187921.25, 536860.25, 188031.75, 536860.25, 187957.25, - 536860.25, 188054.25, 536860.25, 188077.25, 536860.25, 188018.25, 536860.25, 187955.25, - 536860.25, 188103.25, 536860.25, 187958.25, 536860.25, 188147.25, 536860.25, 187935.25, - 536860.25, 187935.75, 536860.75, 188017.75, 536860.75, 187935.75, 536860.75, 188138.75, - 536860.75, 187963.75, 536860.75, 187987.25, 536860.75, 188033.25, 536860.75, 187961.75, - 536860.75, 188043.75, 536860.75, 187974.25, 536860.75, 188038.75, 536860.75, 187957.75, - 536860.75, 188058.25, 536860.75, 188061.25, 536860.75, 188066.75, 536860.75, 187922.25, - 536860.75, 188054.25, 536860.75, 188051.75, 536860.75, 188060.75, 536860.75, 188118.25, - 536860.75, 188016.25, 536860.75, 188007.75, 536860.75, 188036.25, 536860.75, 188067.75, - 536860.75, 187996.25, 536860.75, 188150.75, 536860.75, 188052.25, 536860.75, 187951.75, - 536860.75, 187921.75, 536860.75, 187961.25, 536860.75, 187933.25, 536860.75, 187958.75, - 536860.75, 188148.75, 536860.75, 188114.25, 536860.75, 188015.75, 536860.75, 187952.75, - 536860.75, 188062.25, 536860.75, 187954.25, 536860.75, 188117.75, 536860.75, 187956.25, - 536860.75, 188074.75, 536860.75, 188142.75, 536860.75, 188076.25, 536860.75, 187954.75, - 536860.75, 188057.75, 536860.75, 187944.25, 536860.75, 188155.75, 536860.75, 188001.75, - 536860.75, 188096.25, 536860.75, 187918.25, 536860.75, 188156.75, 536860.75, 187933.75, - 536860.75, 187963.25, 536860.75, 187917.25, 536860.75, 188139.75, 536860.75, 188035.75, - 536860.75, 188043.25, 536860.75, 187953.75, 536860.75, 188055.25, 536860.75, 187939.25, - 536860.75, 187988.25, 536860.75, 188093.75, 536860.75, 188151.75, 536860.75, 188063.25, - 536860.75, 188017.25, 536860.75, 188024.75, 536860.75, 188025.25, 536860.75, 188032.25, - 536860.75, 188150.25, 536860.75, 187959.25, 536860.75, 188039.25, 536860.75, 188000.25, - 536860.75, 188157.25, 536860.75, 188131.75, 536860.75, 188024.25, 536860.75, 188059.25, - 536860.75, 188142.25, 536860.75, 188143.75, 536860.75, 188057.25, 536860.75, 188041.25, - 536860.75, 187999.25, 536860.75, 188118.75, 536860.75, 187934.25, 536860.75, 187991.75, - 536860.75, 188112.75, 536860.75, 187978.25, 536860.75, 188050.25, 536860.75, 187934.75, - 536860.75, 188146.25, 536860.75, 188076.75, 536860.75, 187969.25, 536860.75, 188053.25, - 536860.75, 187999.75, 536860.75, 188056.75, 536860.75, 188157.75, 536860.75, 187958.25, - 536860.75, 188112.25, 536860.75, 188032.75, 536860.75, 188045.75, 536860.75, 187977.25, - 536860.75, 187971.75, 536860.75, 187997.25, 536860.75, 188023.75, 536860.75, 188074.25, - 536860.75, 188121.25, 536861.25, 188153.75, 536861.25, 188040.25, 536861.25, 187997.25, - 536861.25, 187971.75, 536861.25, 188115.75, 536861.25, 188032.75, 536861.25, 188139.25, - 536861.25, 188023.75, 536861.25, 188146.25, 536861.25, 187919.25, 536861.25, 188075.25, - 536861.25, 188055.25, 536861.25, 187917.25, 536861.25, 188135.75, 536861.25, 188059.75, - 536861.25, 188067.75, 536861.25, 188111.75, 536861.25, 188066.75, 536861.25, 188059.25, - 536861.25, 188159.75, 536861.25, 187957.75, 536861.25, 188054.25, 536861.25, 188050.75, - 536861.25, 188148.25, 536861.25, 188055.75, 536861.25, 188148.75, 536861.25, 188032.25, - 536861.25, 187951.25, 536861.25, 188015.75, 536861.25, 187954.75, 536861.25, 188074.75, - 536861.25, 187928.25, 536861.25, 188149.25, 536861.25, 187979.25, 536861.25, 188044.75, - 536861.25, 187988.25, 536861.25, 187996.75, 536861.25, 188037.25, 536861.25, 188000.75, - 536861.25, 188056.25, 536861.25, 187959.75, 536861.25, 188053.75, 536861.25, 187973.25, - 536861.25, 188120.25, 536861.25, 188150.25, 536861.25, 188016.75, 536861.25, 188042.25, - 536861.25, 188114.25, 536861.25, 187927.75, 536861.25, 187955.75, 536861.25, 188058.75, - 536861.25, 187978.25, 536861.25, 187934.75, 536861.25, 188141.25, 536861.25, 187996.25, - 536861.25, 187917.75, 536861.25, 188060.75, 536861.25, 188056.75, 536861.25, 187999.75, - 536861.25, 188144.25, 536861.25, 188033.25, 536861.25, 188048.75, 536861.25, 188150.75, - 536861.25, 187977.25, 536861.25, 187998.25, 536861.25, 188074.25, 536861.25, 188100.75, - 536861.25, 187935.25, 536861.25, 188110.75, 536861.25, 188063.75, 536861.25, 188017.75, - 536861.25, 187987.25, 536861.25, 188046.25, 536861.25, 188132.25, 536861.25, 188095.75, - 536861.25, 187963.75, 536861.25, 188038.75, 536861.25, 187970.75, 536861.25, 187965.25, - 536861.25, 188112.75, 536861.25, 188057.25, 536861.25, 188061.25, 536861.25, 188041.25, - 536861.25, 188157.25, 536861.25, 188051.75, 536861.25, 188017.25, 536861.25, 188073.25, - 536861.25, 188063.25, 536861.25, 188024.75, 536861.25, 188143.25, 536861.25, 187963.25, - 536861.25, 188139.75, 536861.25, 187953.25, 536861.25, 188047.25, 536861.25, 188156.75, - 536861.25, 188153.25, 536861.25, 188057.75, 536861.25, 188061.75, 536861.25, 188117.75, - 536861.25, 187958.75, 536861.25, 188130.75, 536861.25, 187933.25, 536861.25, 187932.25, - 536861.25, 187921.75, 536861.75, 188112.25, 536861.75, 187972.25, 536861.75, 187995.25, - 536861.75, 187932.25, 536861.75, 187951.75, 536861.75, 187950.25, 536861.75, 188145.75, - 536861.75, 187919.25, 536861.75, 187982.25, 536861.75, 188052.25, 536861.75, 188142.75, - 536861.75, 187934.25, 536861.75, 188038.25, 536861.75, 188067.25, 536861.75, 188043.25, - 536861.75, 187956.75, 536861.75, 188093.25, 536861.75, 188014.75, 536861.75, 188067.75, - 536861.75, 188118.75, 536861.75, 187990.25, 536861.75, 188142.25, 536861.75, 188059.25, - 536861.75, 187995.75, 536861.75, 188047.25, 536861.75, 188159.75, 536861.75, 188054.75, - 536861.75, 188113.75, 536861.75, 187961.75, 536861.75, 188139.75, 536861.75, 188134.75, - 536861.75, 188033.75, 536861.75, 188118.25, 536861.75, 188043.75, 536861.75, 188073.75, - 536861.75, 187964.25, 536861.75, 188024.75, 536861.75, 188156.25, 536861.75, 188055.75, - 536861.75, 188016.25, 536861.75, 188148.25, 536861.75, 188121.75, 536861.75, 188036.25, - 536861.75, 187927.25, 536861.75, 188148.75, 536861.75, 188068.25, 536861.75, 188052.75, - 536861.75, 188003.25, 536861.75, 187954.25, 536861.75, 188097.75, 536861.75, 188060.25, - 536861.75, 187987.75, 536861.75, 188100.25, 536861.75, 187959.75, 536861.75, 188058.25, - 536861.75, 188073.25, 536861.75, 188008.25, 536861.75, 188037.25, 536861.75, 188154.25, - 536861.75, 188002.75, 536861.75, 188031.75, 536861.75, 187978.75, 536861.75, 188104.75, - 536861.75, 188109.25, 536861.75, 188035.75, 536861.75, 188112.75, 536861.75, 187932.75, - 536861.75, 187941.25, 536861.75, 188053.75, 536861.75, 188116.75, 536861.75, 187918.75, - 536861.75, 188000.75, 536861.75, 188045.25, 536861.75, 187956.25, 536861.75, 188144.25, - 536861.75, 188003.75, 536861.75, 188114.25, 536861.75, 187988.75, 536861.75, 188045.75, - 536861.75, 187952.25, 536861.75, 187999.75, 536861.75, 187930.75, 536861.75, 187933.75, - 536861.75, 188015.25, 536861.75, 187977.75, 536862.25, 188056.75, 536862.25, 188053.25, - 536862.25, 187996.25, 536862.25, 187977.75, 536862.25, 187931.75, 536862.25, 188015.25, - 536862.25, 187950.75, 536862.25, 187930.75, 536862.25, 188072.75, 536862.25, 188098.25, - 536862.25, 188119.25, 536862.25, 188141.75, 536862.25, 188058.75, 536862.25, 188004.75, - 536862.25, 187927.75, 536862.25, 188049.25, 536862.25, 187959.25, 536862.25, 187955.25, - 536862.25, 187998.25, 536862.25, 188045.25, 536862.25, 187941.75, 536862.25, 188035.25, - 536862.25, 187956.25, 536862.25, 188025.25, 536862.25, 187918.75, 536862.25, 188071.25, - 536862.25, 188157.75, 536862.25, 187949.25, 536862.25, 187932.75, 536862.25, 188116.75, - 536862.25, 188035.75, 536862.25, 188109.25, 536862.25, 188108.25, 536862.25, 187978.75, - 536862.25, 188138.75, 536862.25, 188031.75, 536862.25, 188154.25, 536862.25, 188144.75, - 536862.25, 187916.25, 536862.25, 188073.25, 536862.25, 188085.25, 536862.25, 188158.75, - 536862.25, 188037.25, 536862.25, 188087.75, 536862.25, 187926.25, 536862.25, 188105.25, - 536862.25, 187962.75, 536862.25, 187987.75, 536862.25, 188143.75, 536862.25, 187910.75, - 536862.25, 188054.25, 536862.25, 188117.25, 536862.25, 187930.25, 536862.25, 188044.75, - 536862.25, 187979.25, 536862.25, 188015.75, 536862.25, 188014.25, 536862.25, 187964.75, - 536862.25, 188024.25, 536862.25, 188058.25, 536862.25, 187954.25, 536862.25, 188083.75, - 536862.25, 187962.25, 536862.25, 188031.25, 536862.25, 187952.75, 536862.25, 188060.25, - 536862.25, 188032.25, 536862.25, 188114.25, 536862.25, 188124.75, 536862.25, 188122.25, - 536862.25, 188148.75, 536862.25, 188068.25, 536862.25, 188036.25, 536862.25, 188049.75, - 536862.25, 188097.75, 536862.25, 188145.25, 536862.25, 188116.25, 536862.25, 188052.75, - 536862.25, 187931.25, 536862.25, 187914.75, 536862.25, 187989.25, 536862.25, 187919.75, - 536862.25, 188034.75, 536862.25, 188156.25, 536862.25, 187994.75, 536862.25, 188097.25, - 536862.25, 188007.75, 536862.25, 188073.75, 536862.25, 187948.75, 536862.25, 188147.75, - 536862.25, 188159.25, 536862.25, 188019.75, 536862.25, 188139.75, 536862.25, 187911.75, - 536862.25, 187953.25, 536862.25, 188113.75, 536862.25, 187925.75, 536862.25, 187928.75, - 536862.25, 188014.75, 536862.25, 188108.75, 536862.25, 188025.75, 536862.25, 188110.25, - 536862.25, 188037.75, 536862.25, 187998.75, 536862.25, 188086.75, 536862.25, 188146.75, - 536862.25, 187960.25, 536862.25, 187925.25, 536862.25, 188154.75, 536862.25, 188038.25, - 536862.25, 188007.25, 536862.25, 188107.75, 536862.25, 188127.25, 536862.25, 188099.25, - 536862.25, 188067.25, 536862.25, 188160.25, 536862.25, 187956.75, 536862.25, 188052.25, - 536862.25, 188023.75, 536862.25, 187924.75, 536862.25, 188034.25, 536862.25, 187950.25, - 536862.25, 188047.75, 536862.25, 188012.75, 536862.25, 188008.75, 536862.25, 187995.25, - 536862.25, 188142.75, 536862.25, 188155.25, 536862.25, 187953.75, 536862.75, 187938.75, - 536862.75, 188071.25, 536862.75, 188107.75, 536862.75, 187924.75, 536862.75, 188035.75, - 536862.75, 188037.75, 536862.75, 188034.75, 536862.75, 187956.75, 536862.75, 188052.25, - 536862.75, 187948.75, 536862.75, 188024.25, 536862.75, 188000.25, 536862.75, 188156.75, - 536862.75, 188024.75, 536862.75, 187987.75, 536862.75, 188117.75, 536862.75, 188120.25, - 536862.75, 188141.25, 536862.75, 188009.25, 536862.75, 187962.25, 536862.75, 188034.25, - 536862.75, 188147.75, 536862.75, 188058.25, 536862.75, 187950.25, 536862.75, 188052.75, - 536862.75, 188110.75, 536862.75, 187949.25, 536862.75, 188111.25, 536862.75, 187990.75, - 536862.75, 188140.75, 536862.75, 187979.25, 536862.75, 188114.75, 536862.75, 188144.75, - 536862.75, 188058.75, 536862.75, 188065.25, 536862.75, 188155.75, 536862.75, 188067.75, - 536862.75, 188108.25, 536862.75, 187999.25, 536862.75, 187927.75, 536862.75, 187971.25, - 536862.75, 188071.75, 536862.75, 188014.25, 536862.75, 187915.75, 536862.75, 187964.75, - 536862.75, 188031.25, 536862.75, 188036.25, 536862.75, 188116.25, 536862.75, 188128.25, - 536862.75, 187978.75, 536862.75, 187925.25, 536862.75, 187962.75, 536862.75, 188025.25, - 536862.75, 187954.25, 536862.75, 187918.75, 536862.75, 188037.25, 536862.75, 188098.25, - 536862.75, 188083.25, 536862.75, 188113.25, 536862.75, 187995.25, 536862.75, 188072.25, - 536862.75, 188054.75, 536862.75, 188032.75, 536862.75, 188070.25, 536862.75, 188108.75, - 536862.75, 187988.25, 536862.75, 188007.75, 536862.75, 188146.75, 536862.75, 188073.25, - 536862.75, 188097.25, 536862.75, 187951.75, 536862.75, 188047.75, 536862.75, 188053.25, - 536862.75, 187960.25, 536862.75, 187977.25, 536862.75, 188142.75, 536862.75, 188015.25, - 536862.75, 188038.25, 536862.75, 188099.25, 536862.75, 187932.25, 536862.75, 188045.25, - 536862.75, 188159.25, 536862.75, 188095.75, 536862.75, 187952.75, 536862.75, 188049.25, - 536862.75, 187931.25, 536862.75, 188158.25, 536862.75, 188053.75, 536862.75, 187929.75, - 536862.75, 188035.25, 536862.75, 188056.25, 536862.75, 187929.25, 536862.75, 188119.25, - 536862.75, 188007.25, 536862.75, 187993.75, 536862.75, 188153.75, 536862.75, 188016.25, - 536862.75, 188086.25, 536862.75, 188013.25, 536862.75, 187963.75, 536862.75, 187959.25, - 536862.75, 187995.75, 536862.75, 188032.25, 536862.75, 188097.75, 536863.25, 188054.25, - 536863.25, 188145.75, 536863.25, 188049.25, 536863.25, 187959.75, 536863.25, 188041.25, - 536863.25, 188069.25, 536863.25, 188035.75, 536863.25, 187924.75, 536863.25, 188046.25, - 536863.25, 188141.25, 536863.25, 188026.25, 536863.25, 188052.25, 536863.25, 187956.75, - 536863.25, 187988.75, 536863.25, 188156.75, 536863.25, 187924.25, 536863.25, 188109.25, - 536863.25, 188089.25, 536863.25, 188000.25, 536863.25, 187955.75, 536863.25, 187925.75, - 536863.25, 188015.75, 536863.25, 187993.75, 536863.25, 188055.75, 536863.25, 188118.25, - 536863.25, 188063.25, 536863.25, 188110.75, 536863.25, 187976.75, 536863.25, 188137.75, - 536863.25, 187977.75, 536863.25, 187948.25, 536863.25, 188029.75, 536863.25, 188127.25, - 536863.25, 188107.25, 536863.25, 188060.75, 536863.25, 188058.25, 536863.25, 187999.75, - 536863.25, 188056.25, 536863.25, 188061.75, 536863.25, 188052.75, 536863.25, 188111.25, - 536863.25, 188140.75, 536863.25, 188068.25, 536863.25, 187928.25, 536863.25, 187979.25, - 536863.25, 187978.25, 536863.25, 188109.75, 536863.25, 188031.75, 536863.25, 187994.75, - 536863.25, 188058.75, 536863.25, 187917.25, 536863.25, 188057.75, 536863.25, 187952.75, - 536863.25, 187947.25, 536863.25, 187973.25, 536863.25, 188030.25, 536863.25, 187963.25, - 536863.25, 188070.75, 536863.25, 187919.75, 536863.25, 188098.75, 536863.25, 188140.25, - 536863.25, 187927.75, 536863.25, 188047.25, 536863.25, 188099.25, 536863.25, 188139.75, - 536863.25, 187926.25, 536863.25, 188006.75, 536863.25, 187918.25, 536863.25, 188016.75, - 536863.25, 188106.25, 536863.25, 188087.25, 536863.25, 188012.75, 536863.25, 187930.25, - 536863.25, 188008.75, 536863.25, 188129.25, 536863.25, 187951.75, 536863.25, 188050.75, - 536863.25, 187915.75, 536863.25, 187913.75, 536863.25, 188036.25, 536863.25, 188152.75, - 536863.25, 188025.25, 536863.25, 188155.25, 536863.25, 187997.25, 536863.25, 188118.75, - 536863.25, 187972.75, 536863.25, 188004.25, 536863.25, 188144.25, 536863.25, 188120.75, - 536863.25, 188009.25, 536863.25, 188013.75, 536863.75, 187957.75, 536863.75, 187964.25, - 536863.75, 187946.25, 536863.75, 188108.75, 536863.75, 188070.25, 536863.75, 188056.75, - 536863.75, 187972.75, 536863.75, 187998.75, 536863.75, 188013.75, 536863.75, 188009.75, - 536863.75, 187953.25, 536863.75, 187951.25, 536863.75, 188154.75, 536863.75, 188127.75, - 536863.75, 187945.25, 536863.75, 188110.25, 536863.75, 188111.75, 536863.75, 188124.75, - 536863.75, 188159.75, 536863.75, 187979.75, 536863.75, 188025.25, 536863.75, 187978.75, - 536863.75, 187925.25, 536863.75, 188059.25, 536863.75, 187989.75, 536863.75, 188009.25, - 536863.75, 187946.75, 536863.75, 187983.25, 536863.75, 188104.75, 536863.75, 188050.75, - 536863.75, 188047.75, 536863.75, 187992.75, 536863.75, 187928.75, 536863.75, 187947.25, - 536863.75, 188057.25, 536863.75, 187912.25, 536863.75, 187999.25, 536863.75, 188069.75, - 536863.75, 188129.25, 536863.75, 188106.25, 536863.75, 188105.75, 536863.75, 188003.25, - 536863.75, 188001.25, 536863.75, 188088.75, 536863.75, 187958.75, 536863.75, 188140.25, - 536863.75, 188070.75, 536863.75, 188144.75, 536863.75, 188088.25, 536863.75, 188154.25, - 536863.75, 188137.25, 536863.75, 188011.75, 536863.75, 187973.25, 536863.75, 188031.75, - 536863.75, 188058.75, 536863.75, 188036.75, 536863.75, 188008.25, 536863.75, 188005.75, - 536863.75, 187976.25, 536863.75, 187975.25, 536863.75, 188138.75, 536863.75, 188068.25, - 536863.75, 187927.25, 536863.75, 187993.25, 536863.75, 187994.75, 536863.75, 187990.75, - 536863.75, 188091.75, 536863.75, 187999.75, 536863.75, 188017.25, 536863.75, 187950.25, - 536863.75, 187998.25, 536863.75, 188052.75, 536863.75, 187950.75, 536863.75, 188121.25, - 536863.75, 187976.75, 536863.75, 187914.25, 536863.75, 188132.75, 536863.75, 188034.25, - 536863.75, 188107.25, 536863.75, 187929.25, 536863.75, 188099.75, 536863.75, 188029.75, - 536863.75, 187948.25, 536863.75, 188025.75, 536863.75, 187980.25, 536863.75, 188007.25, - 536863.75, 188128.75, 536863.75, 188145.25, 536863.75, 188000.75, 536863.75, 188052.25, - 536863.75, 188158.75, 536863.75, 187996.25, 536863.75, 188105.25, 536863.75, 188101.25, - 536863.75, 188000.25, 536863.75, 187995.75, 536863.75, 187988.75, 536863.75, 188048.25, - 536863.75, 188156.75, 536863.75, 188013.25, 536863.75, 187989.25, 536863.75, 188120.25, - 536863.75, 187992.25, 536863.75, 187997.75, 536863.75, 187953.75, 536863.75, 188102.25, - 536863.75, 188097.75, 536863.75, 188034.75, 536863.75, 187929.75, 536863.75, 188054.25, - 536863.75, 187914.75, 536863.75, 188126.75, 536863.75, 188107.75, 536863.75, 188030.75, - 536864.25, 187913.25, 536864.25, 188023.75, 536864.25, 188107.75, 536864.25, 188055.75, - 536864.25, 188015.75, 536864.25, 188037.75, 536864.25, 188025.75, 536864.25, 187992.25, - 536864.25, 188127.25, 536864.25, 188033.75, 536864.25, 187957.25, 536864.25, 188054.25, - 536864.25, 188069.25, 536864.25, 187980.75, 536864.25, 187953.75, 536864.25, 188097.75, - 536864.25, 188013.25, 536864.25, 187944.75, 536864.25, 187975.25, 536864.25, 187929.75, - 536864.25, 187923.25, 536864.25, 187995.75, 536864.25, 188005.75, 536864.25, 188086.25, - 536864.25, 187915.25, 536864.25, 188007.25, 536864.25, 188048.75, 536864.25, 188120.25, - 536864.25, 188105.25, 536864.25, 188029.75, 536864.25, 187977.25, 536864.25, 188034.75, - 536864.25, 188121.75, 536864.25, 187994.75, 536864.25, 187914.75, 536864.25, 188036.75, - 536864.25, 187998.25, 536864.25, 187934.75, 536864.25, 188024.75, 536864.25, 188003.75, - 536864.25, 187978.25, 536864.25, 188053.75, 536864.25, 188090.25, 536864.25, 187947.75, - 536864.25, 188006.25, 536864.25, 188031.75, 536864.25, 188047.75, 536864.25, 188101.25, - 536864.25, 187946.75, 536864.25, 188152.75, 536864.25, 187988.75, 536864.25, 188154.25, - 536864.25, 188000.25, 536864.25, 187916.75, 536864.25, 188072.25, 536864.25, 187957.75, - 536864.25, 188000.75, 536864.25, 187914.25, 536864.25, 188150.25, 536864.25, 188054.75, - 536864.25, 188125.75, 536864.25, 188088.75, 536864.25, 188045.25, 536864.25, 187925.75, - 536864.25, 188159.75, 536864.25, 188118.75, 536864.25, 188098.25, 536864.25, 187960.25, - 536864.25, 187990.25, 536864.25, 188097.25, 536864.25, 188049.75, 536864.25, 188110.25, - 536864.25, 187945.25, 536864.25, 188007.75, 536864.25, 188145.25, 536864.25, 188053.25, - 536864.25, 188058.25, 536864.25, 188107.25, 536864.25, 188128.25, 536864.25, 188056.75, - 536864.25, 187972.75, 536864.25, 187979.75, 536864.25, 187946.25, 536864.25, 188001.75, - 536864.25, 188108.75, 536864.25, 188123.75, 536864.25, 188005.25, 536864.25, 188070.25, - 536864.25, 187925.25, 536864.25, 187998.75, 536864.25, 187953.25, 536864.25, 188052.75, - 536864.25, 188017.25, 536864.25, 187999.75, 536864.25, 188009.75, 536864.25, 188154.75, - 536864.25, 187951.25, 536864.25, 188064.75, 536864.25, 188067.75, 536864.25, 188103.25, - 536864.25, 188110.75, 536864.25, 187927.75, 536864.25, 187978.75, 536864.25, 188059.25, - 536864.25, 187911.75, 536864.25, 188136.75, 536864.25, 188104.75, 536864.25, 187928.75, - 536864.25, 187976.75, 536864.25, 187990.75, 536864.25, 188111.25, 536864.25, 187950.25, - 536864.25, 187999.25, 536864.25, 188008.75, 536864.25, 188014.25, 536864.25, 187971.25, - 536864.25, 188157.25, 536864.25, 187958.75, 536864.25, 187956.25, 536864.25, 187927.25, - 536864.25, 188088.25, 536864.25, 187993.25, 536864.25, 187926.75, 536864.25, 188008.25, - 536864.25, 187928.25, 536864.25, 187979.25, 536864.25, 188030.25, 536864.25, 188058.75, - 536864.75, 187913.25, 536864.75, 188153.25, 536864.75, 188058.75, 536864.75, 188094.75, - 536864.75, 188025.75, 536864.75, 188057.75, 536864.75, 187992.25, 536864.75, 188008.25, - 536864.75, 188064.25, 536864.75, 187980.75, 536864.75, 188126.75, 536864.75, 187978.75, - 536864.75, 187924.75, 536864.75, 188054.25, 536864.75, 187979.25, 536864.75, 187974.25, - 536864.75, 187974.75, 536864.75, 188141.25, 536864.75, 187975.25, 536864.75, 187989.25, - 536864.75, 188023.75, 536864.75, 188034.75, 536864.75, 187910.75, 536864.75, 188150.75, - 536864.75, 188153.75, 536864.75, 188158.75, 536864.75, 188105.75, 536864.75, 188029.75, - 536864.75, 187949.25, 536864.75, 187971.25, 536864.75, 188121.75, 536864.75, 187950.75, - 536864.75, 187947.25, 536864.75, 188053.75, 536864.75, 187945.25, 536864.75, 188143.25, - 536864.75, 187947.75, 536864.75, 188024.25, 536864.75, 188003.25, 536864.75, 188005.75, - 536864.75, 188030.75, 536864.75, 187972.75, 536864.75, 188152.75, 536864.75, 188117.75, - 536864.75, 188000.75, 536864.75, 187919.75, 536864.75, 188140.25, 536864.75, 187999.25, - 536864.75, 188057.25, 536864.75, 188125.75, 536864.75, 188100.25, 536864.75, 187926.25, - 536864.75, 187921.75, 536864.75, 188016.75, 536864.75, 188147.25, 536864.75, 188160.25, - 536864.75, 188121.25, 536864.75, 188144.75, 536864.75, 188159.75, 536864.75, 187996.25, - 536864.75, 187928.75, 536864.75, 188098.75, 536864.75, 188127.75, 536864.75, 188002.25, - 536864.75, 187997.25, 536864.75, 187911.75, 536864.75, 188082.75, 536864.75, 188131.75, - 536864.75, 187943.75, 536864.75, 188033.25, 536864.75, 188034.25, 536864.75, 188115.25, - 536864.75, 188013.75, 536864.75, 188004.75, 536864.75, 188005.25, 536864.75, 188100.75, - 536864.75, 187992.75, 536864.75, 188031.25, 536864.75, 188111.25, 536864.75, 187949.75, - 536864.75, 187989.75, 536864.75, 188036.25, 536864.75, 187998.75, 536864.75, 187995.25, - 536864.75, 187927.75, 536864.75, 188103.75, 536864.75, 188025.25, 536864.75, 188064.75, - 536864.75, 188110.75, 536864.75, 188037.25, 536864.75, 188103.25, 536864.75, 187971.75, - 536864.75, 188155.25, 536864.75, 187944.75, 536864.75, 187954.25, 536865.25, 188058.75, - 536865.25, 187944.75, 536865.25, 188151.75, 536865.25, 188112.75, 536865.25, 188023.75, - 536865.25, 187997.75, 536865.25, 188023.25, 536865.25, 187954.75, 536865.25, 187980.25, - 536865.25, 187992.25, 536865.25, 187961.75, 536865.25, 188100.75, 536865.25, 188030.25, - 536865.25, 188145.75, 536865.25, 187978.75, 536865.25, 188029.75, 536865.25, 187922.25, - 536865.25, 188139.25, 536865.25, 188135.25, 536865.25, 188133.75, 536865.25, 188129.25, - 536865.25, 187935.75, 536865.25, 188102.25, 536865.25, 187974.75, 536865.25, 187974.25, - 536865.25, 188017.75, 536865.25, 188122.75, 536865.25, 187989.25, 536865.25, 188057.75, - 536865.25, 188014.75, 536865.25, 188125.25, 536865.25, 188063.75, 536865.25, 187928.25, - 536865.25, 188150.75, 536865.25, 187944.25, 536865.25, 187995.75, 536865.25, 187995.25, - 536865.25, 188061.75, 536865.25, 187955.75, 536865.25, 188134.75, 536865.25, 187958.25, - 536865.25, 187998.75, 536865.25, 187993.75, 536865.25, 188036.25, 536865.25, 187989.75, - 536865.25, 188110.75, 536865.25, 188155.75, 536865.25, 188120.25, 536865.25, 188105.25, - 536865.25, 188065.25, 536865.25, 188112.25, 536865.25, 188001.75, 536865.25, 188111.25, - 536865.25, 188126.25, 536865.25, 188006.75, 536865.25, 188121.75, 536865.25, 187929.25, - 536865.25, 188035.75, 536865.25, 188022.25, 536865.25, 187956.75, 536865.25, 188024.75, - 536865.25, 188084.75, 536865.25, 188034.25, 536865.25, 188035.25, 536865.25, 187949.25, - 536865.25, 187914.25, 536865.25, 188003.25, 536865.25, 188005.25, 536865.25, 188082.25, - 536865.25, 188115.25, 536865.25, 188066.25, 536865.25, 187973.25, 536865.25, 188110.25, - 536865.25, 188100.25, 536865.25, 188111.75, 536865.25, 188099.25, 536865.25, 188154.25, - 536865.25, 188140.25, 536865.25, 188141.75, 536865.25, 188002.75, 536865.25, 187984.25, - 536865.25, 188101.75, 536865.25, 188150.25, 536865.25, 188159.75, 536865.25, 188099.75, - 536865.25, 188125.75, 536865.25, 188001.25, 536865.25, 188097.25, 536865.25, 187948.25, - 536865.25, 187981.25, 536865.25, 188004.25, 536865.25, 188098.75, 536865.25, 187943.25, - 536865.25, 188103.75, 536865.25, 188086.75, 536865.75, 187997.25, 536865.75, 188062.75, - 536865.75, 187960.25, 536865.75, 188131.75, 536865.75, 187980.75, 536865.75, 187954.25, - 536865.75, 187913.25, 536865.75, 188151.75, 536865.75, 187997.75, 536865.75, 187988.75, - 536865.75, 188086.75, 536865.75, 187991.75, 536865.75, 188155.25, 536865.75, 188073.25, - 536865.75, 187943.25, 536865.75, 188089.75, 536865.75, 188017.75, 536865.75, 188031.75, - 536865.75, 188152.25, 536865.75, 187980.25, 536865.75, 188015.25, 536865.75, 188037.25, - 536865.75, 187942.75, 536865.75, 188004.25, 536865.75, 188023.25, 536865.75, 187978.75, - 536865.75, 187944.75, 536865.75, 187926.25, 536865.75, 187956.25, 536865.75, 188029.75, - 536865.75, 188030.25, 536865.75, 188001.25, 536865.75, 188097.25, 536865.75, 188126.75, - 536865.75, 188125.75, 536865.75, 188087.25, 536865.75, 188014.25, 536865.75, 187970.25, - 536865.75, 187982.75, 536865.75, 188112.75, 536865.75, 187922.25, 536865.75, 188145.75, - 536865.75, 188116.75, 536865.75, 187912.25, 536865.75, 188098.75, 536865.75, 188008.25, - 536865.75, 187919.75, 536865.75, 187948.75, 536865.75, 187923.75, 536865.75, 188102.25, - 536865.75, 188152.75, 536865.75, 188101.75, 536865.75, 187911.25, 536865.75, 187961.75, - 536865.75, 188132.25, 536865.75, 187954.75, 536865.75, 188140.25, 536865.75, 187990.75, - 536865.75, 187927.75, 536865.75, 188110.25, 536865.75, 187974.25, 536865.75, 188058.25, - 536865.75, 188065.75, 536865.75, 188083.75, 536865.75, 188150.75, 536865.75, 188006.25, - 536865.75, 187993.75, 536865.75, 188139.25, 536865.75, 188035.25, 536865.75, 187943.75, - 536865.75, 188066.25, 536865.75, 188022.25, 536865.75, 187929.75, 536865.75, 188158.25, - 536865.75, 188013.75, 536865.75, 188003.25, 536865.75, 188005.75, 536865.75, 188057.75, - 536865.75, 188125.25, 536865.75, 188100.25, 536865.75, 187995.25, 536865.75, 188109.25, - 536865.75, 188084.75, 536865.75, 187944.25, 536865.75, 187947.25, 536865.75, 187918.25, - 536865.75, 188043.75, 536865.75, 188095.25, 536865.75, 187996.75, 536865.75, 187972.75, - 536865.75, 188014.75, 536865.75, 188134.75, 536865.75, 187995.75, 536865.75, 188107.75, - 536865.75, 187955.75, 536865.75, 187949.25, 536865.75, 187973.75, 536865.75, 188110.75, - 536865.75, 188006.75, 536865.75, 187990.25, 536865.75, 188149.25, 536865.75, 188036.25, - 536865.75, 187979.75, 536865.75, 188073.75, 536865.75, 188123.25, 536865.75, 188112.25, - 536865.75, 188153.75, 536865.75, 188119.25, 536865.75, 187928.25, 536865.75, 188145.25, - 536865.75, 188063.75, 536866.25, 188031.25, 536866.25, 187918.25, 536866.25, 188148.25, - 536866.25, 188114.75, 536866.25, 187922.75, 536866.25, 188149.25, 536866.25, 187955.25, - 536866.25, 188120.25, 536866.25, 188123.25, 536866.25, 187988.25, 536866.25, 188006.25, - 536866.25, 188106.25, 536866.25, 188001.75, 536866.25, 188116.75, 536866.25, 188132.75, - 536866.25, 187925.25, 536866.25, 188029.75, 536866.25, 188017.25, 536866.25, 187989.75, - 536866.25, 188058.75, 536866.25, 188014.75, 536866.25, 188005.75, 536866.25, 188024.75, - 536866.25, 188106.75, 536866.25, 187987.75, 536866.25, 187928.75, 536866.25, 187994.75, - 536866.25, 188003.25, 536866.25, 187927.25, 536866.25, 187947.25, 536866.25, 188074.75, - 536866.25, 187917.25, 536866.25, 188097.75, 536866.25, 188065.75, 536866.25, 188133.75, - 536866.25, 188100.75, 536866.25, 188133.25, 536866.25, 188020.75, 536866.25, 188112.75, - 536866.25, 187941.25, 536866.25, 188062.25, 536866.25, 188059.25, 536866.25, 188096.75, - 536866.25, 187935.25, 536866.25, 188071.75, 536866.25, 187929.75, 536866.25, 188145.75, - 536866.25, 187919.25, 536866.25, 188141.75, 536866.25, 188063.25, 536866.25, 188150.25, - 536866.25, 188097.25, 536866.25, 188122.75, 536866.25, 188119.75, 536866.25, 187948.75, - 536866.25, 187962.25, 536866.25, 188111.75, 536866.25, 188093.25, 536866.25, 187942.75, - 536866.25, 188099.75, 536866.25, 188125.75, 536866.25, 187996.25, 536866.25, 188001.25, - 536866.25, 188021.75, 536866.25, 187949.75, 536866.25, 188036.75, 536866.25, 187943.25, - 536866.25, 187979.25, 536866.25, 187921.75, 536866.25, 187985.25, 536866.25, 187942.25, - 536866.25, 187941.75, 536866.25, 187992.25, 536866.25, 188031.75, 536866.25, 188139.75, - 536866.25, 188073.25, 536866.25, 188015.25, 536866.25, 187980.75, 536866.25, 187992.75, - 536866.25, 188066.75, 536866.25, 188023.75, 536866.25, 187962.75, 536866.25, 188018.25, - 536866.25, 188025.75, 536866.25, 188118.25, 536866.25, 188111.25, 536866.25, 188149.75, - 536866.75, 188025.75, 536866.75, 188118.25, 536866.75, 187973.25, 536866.75, 188015.75, - 536866.75, 188019.25, 536866.75, 187980.25, 536866.75, 188073.75, 536866.75, 187987.75, - 536866.75, 188035.75, 536866.75, 188120.25, 536866.75, 188032.25, 536866.75, 188156.75, - 536866.75, 187974.75, 536866.75, 188107.75, 536866.75, 187919.25, 536866.75, 188024.25, - 536866.75, 187933.75, 536866.75, 188026.25, 536866.75, 187989.25, 536866.75, 187993.75, - 536866.75, 187953.75, 536866.75, 187916.75, 536866.75, 188097.75, 536866.75, 188101.25, - 536866.75, 188030.75, 536866.75, 188112.75, 536866.75, 187930.75, 536866.75, 188156.25, - 536866.75, 188002.75, 536866.75, 187948.25, 536866.75, 188112.25, 536866.75, 188135.75, - 536866.75, 188109.75, 536866.75, 187943.25, 536866.75, 187940.25, 536866.75, 187924.25, - 536866.75, 188063.25, 536866.75, 188058.25, 536866.75, 187995.75, 536866.75, 188048.75, - 536866.75, 188153.75, 536866.75, 188105.25, 536866.75, 188034.25, 536866.75, 187916.25, - 536866.75, 188123.75, 536866.75, 188148.25, 536866.75, 188133.75, 536866.75, 188146.25, - 536866.75, 187929.25, 536866.75, 188132.25, 536866.75, 187950.75, 536866.75, 188005.75, - 536866.75, 188134.75, 536866.75, 188017.75, 536866.75, 188084.25, 536866.75, 188003.75, - 536866.75, 187981.25, 536866.75, 187947.75, 536866.75, 187980.75, 536866.75, 187950.25, - 536866.75, 188120.75, 536866.75, 188141.75, 536866.75, 188033.75, 536866.75, 188151.75, - 536866.75, 187917.25, 536866.75, 188072.25, 536866.75, 187939.75, 536866.75, 188124.25, - 536866.75, 188115.75, 536866.75, 187917.75, 536866.75, 187993.25, 536866.75, 187919.75, - 536866.75, 188131.25, 536866.75, 187920.25, 536866.75, 188100.25, 536866.75, 188068.75, - 536866.75, 188131.75, 536866.75, 188070.75, 536866.75, 188065.25, 536866.75, 188031.75, - 536866.75, 187927.25, 536866.75, 188142.75, 536866.75, 188006.25, 536866.75, 187991.75, - 536866.75, 188118.75, 536866.75, 188104.75, 536866.75, 187994.25, 536866.75, 188015.25, - 536866.75, 187952.25, 536866.75, 187911.75, 536866.75, 188062.75, 536866.75, 187986.25, - 536866.75, 188033.25, 536866.75, 187918.75, 536866.75, 188002.25, 536866.75, 188073.25, - 536866.75, 187915.75, 536866.75, 188082.75, 536866.75, 188020.75, 536866.75, 188031.25, - 536866.75, 188025.25, 536866.75, 188092.75, 536866.75, 188122.25, 536866.75, 187930.25, - 536866.75, 188100.75, 536866.75, 187942.75, 536866.75, 188115.25, 536866.75, 188124.75, - 536866.75, 188138.75, 536866.75, 188018.25, 536866.75, 187986.75, 536866.75, 188070.25, - 536866.75, 187946.25, 536866.75, 188157.75, 536866.75, 188028.75, 536866.75, 188108.75, - 536866.75, 188059.75, 536866.75, 187922.75, 536866.75, 188036.25, 536866.75, 187988.25, - 536866.75, 188080.75, 536866.75, 188148.75, 536866.75, 187925.25, 536867.25, 187988.25, - 536867.25, 188148.75, 536867.25, 188036.25, 536867.25, 188125.25, 536867.25, 188028.75, - 536867.25, 187979.75, 536867.25, 187986.75, 536867.25, 188087.25, 536867.25, 187917.75, - 536867.25, 188023.25, 536867.25, 188001.75, 536867.25, 188116.25, 536867.25, 188005.25, - 536867.25, 188066.75, 536867.25, 188160.25, 536867.25, 187954.25, 536867.25, 187989.75, - 536867.25, 188150.25, 536867.25, 188002.25, 536867.25, 188097.25, 536867.25, 188031.25, - 536867.25, 187940.75, 536867.25, 187915.75, 536867.25, 187946.25, 536867.25, 188059.25, - 536867.25, 187918.75, 536867.25, 188062.75, 536867.25, 187986.25, 536867.25, 187941.75, - 536867.25, 188033.25, 536867.25, 187994.25, 536867.25, 188019.75, 536867.25, 187951.75, - 536867.25, 188006.25, 536867.25, 187952.25, 536867.25, 187991.75, 536867.25, 188098.25, - 536867.25, 188003.25, 536867.25, 188142.75, 536867.25, 188031.75, 536867.25, 188021.25, - 536867.25, 188146.75, 536867.25, 187942.25, 536867.25, 188065.75, 536867.25, 188073.25, - 536867.25, 187962.75, 536867.25, 188119.75, 536867.25, 187993.25, 536867.25, 187919.75, - 536867.25, 187929.75, 536867.25, 187950.25, 536867.25, 188124.25, 536867.25, 188020.25, - 536867.25, 187939.75, 536867.25, 188131.25, 536867.25, 187980.75, 536867.25, 187973.25, - 536867.25, 188096.75, 536867.25, 188120.75, 536867.25, 187931.25, 536867.25, 188049.25, - 536867.25, 188100.25, 536867.25, 187948.25, 536867.25, 187947.75, 536867.25, 187981.25, - 536867.25, 187982.25, 536867.25, 187950.75, 536867.25, 187929.25, 536867.25, 188063.25, - 536867.25, 188017.75, 536867.25, 188100.75, 536867.25, 188133.75, 536867.25, 188132.25, - 536867.25, 188121.75, 536867.25, 188146.25, 536867.25, 188123.75, 536867.25, 187916.25, - 536867.25, 187927.25, 536867.25, 187943.25, 536867.25, 187952.75, 536867.25, 188029.75, - 536867.25, 187988.75, 536867.25, 188156.25, 536867.25, 187925.75, 536867.25, 187923.25, - 536867.25, 188098.75, 536867.25, 187948.75, 536867.25, 188135.75, 536867.25, 188097.75, - 536867.25, 188112.75, 536867.25, 188114.25, 536867.25, 188081.25, 536867.25, 188030.75, - 536867.25, 187910.75, 536867.25, 187916.75, 536867.25, 188026.25, 536867.25, 188145.75, - 536867.25, 188014.75, 536867.25, 188102.25, 536867.25, 187989.25, 536867.25, 188148.25, - 536867.25, 188032.25, 536867.25, 188156.75, 536867.25, 188024.25, 536867.25, 187993.75, - 536867.25, 187980.25, 536867.25, 188035.75, 536867.25, 187928.75, 536867.25, 188036.75, - 536867.25, 187987.75, 536867.25, 188057.75, 536867.25, 187924.75, 536867.25, 188141.25, - 536867.25, 188071.25, 536867.25, 188118.25, 536867.25, 188111.25, 536867.75, 187941.25, - 536867.75, 188104.25, 536867.75, 188120.25, 536867.75, 188024.75, 536867.75, 188035.75, - 536867.75, 187914.25, 536867.75, 187987.25, 536867.75, 188123.25, 536867.75, 188034.25, - 536867.75, 188141.75, 536867.75, 188132.25, 536867.75, 188017.75, 536867.75, 187981.25, - 536867.75, 188100.25, 536867.75, 187925.75, 536867.75, 187928.25, 536867.75, 188003.25, - 536867.75, 187938.75, 536867.75, 188140.75, 536867.75, 187979.25, 536867.75, 187915.75, - 536867.75, 188031.25, 536867.75, 188151.75, 536867.75, 187995.25, 536867.75, 188124.75, - 536867.75, 188111.75, 536867.75, 188144.75, 536867.75, 188006.25, 536867.75, 188018.25, - 536867.75, 187978.75, 536867.75, 188033.25, 536867.75, 188154.75, 536867.75, 188064.75, - 536867.75, 187951.25, 536867.75, 188134.25, 536867.75, 188108.75, 536867.75, 188115.25, - 536867.75, 187938.25, 536867.75, 187930.25, 536867.75, 187989.75, 536867.75, 187985.75, - 536867.75, 188125.75, 536867.75, 188036.25, 536867.75, 188119.75, 536867.75, 188121.25, - 536867.75, 188116.25, 536867.75, 188154.25, 536867.75, 188138.75, 536867.75, 187992.75, - 536867.75, 188122.25, 536867.75, 187950.25, 536867.75, 188118.75, 536867.75, 188032.75, - 536867.75, 188131.75, 536867.75, 187982.25, 536867.75, 188119.25, 536867.75, 188018.75, - 536867.75, 187915.25, 536867.75, 187940.25, 536867.75, 188097.75, 536867.75, 187989.25, - 536867.75, 187974.25, 536867.75, 187947.25, 536867.75, 187960.75, 536867.75, 187992.25, - 536867.75, 187921.25, 536867.75, 188033.75, 536867.75, 188135.25, 536867.75, 188016.25, - 536867.75, 188029.75, 536867.75, 188064.25, 536867.75, 188100.75, 536867.75, 187916.25, - 536867.75, 188025.75, 536867.75, 188139.75, 536867.75, 187962.75, 536867.75, 187919.25, - 536867.75, 188106.25, 536867.75, 188010.75, 536867.75, 188112.25, 536867.75, 187918.75, - 536867.75, 188112.75, 536868.25, 187973.75, 536868.25, 188064.75, 536868.25, 187946.75, - 536868.25, 187918.75, 536868.25, 188061.75, 536868.25, 188117.75, 536868.25, 188141.25, - 536868.25, 187945.75, 536868.25, 187919.25, 536868.25, 188014.75, 536868.25, 187930.75, - 536868.25, 187974.75, 536868.25, 188052.25, 536868.25, 188156.25, 536868.25, 188029.25, - 536868.25, 188025.75, 536868.25, 188016.25, 536868.25, 187987.25, 536868.25, 187950.25, - 536868.25, 187914.75, 536868.25, 188064.25, 536868.25, 187936.75, 536868.25, 187985.25, - 536868.25, 188141.75, 536868.25, 188101.25, 536868.25, 188006.75, 536868.25, 188015.75, - 536868.25, 187977.25, 536868.25, 188033.75, 536868.25, 188123.25, 536868.25, 188002.75, - 536868.25, 188127.75, 536868.25, 187992.25, 536868.25, 187990.75, 536868.25, 187982.75, - 536868.25, 188028.25, 536868.25, 187947.25, 536868.25, 187962.25, 536868.25, 187928.75, - 536868.25, 188100.25, 536868.25, 188133.25, 536868.25, 187999.75, 536868.25, 187937.75, - 536868.25, 188063.75, 536868.25, 187984.75, 536868.25, 187995.75, 536868.25, 187939.75, - 536868.25, 187994.75, 536868.25, 187940.25, 536868.25, 187920.25, 536868.25, 187983.25, - 536868.25, 188146.25, 536868.25, 188133.75, 536868.25, 187920.75, 536868.25, 188126.25, - 536868.25, 188121.75, 536868.25, 188026.75, 536868.25, 188074.25, 536868.25, 187983.75, - 536868.25, 187976.75, 536868.25, 188010.75, 536868.25, 187952.25, 536868.25, 188003.75, - 536868.25, 187979.25, 536868.25, 187978.25, 536868.25, 188030.25, 536868.25, 188066.25, - 536868.25, 187994.25, 536868.25, 187931.25, 536868.25, 188143.25, 536868.25, 188017.25, - 536868.25, 188035.25, 536868.25, 187938.75, 536868.25, 188101.75, 536868.25, 187913.75, - 536868.25, 188040.25, 536868.25, 188025.25, 536868.25, 188018.25, 536868.25, 188119.75, - 536868.25, 188121.25, 536868.25, 188036.25, 536868.25, 188157.75, 536868.25, 187926.25, - 536868.25, 187985.75, 536868.25, 188124.75, 536868.25, 188060.25, 536868.25, 188043.25, - 536868.25, 188148.25, 536868.25, 188117.25, 536868.25, 187941.75, 536868.25, 187963.25, - 536868.25, 188012.75, 536868.25, 187939.25, 536868.25, 188136.25, 536868.25, 188148.75, - 536868.25, 188097.25, 536868.25, 187988.25, 536868.25, 187981.75, 536868.25, 187984.25, - 536868.25, 188113.25, 536868.25, 187938.25, 536868.25, 187930.25, 536868.75, 188036.25, - 536868.75, 187981.75, 536868.75, 187930.25, 536868.75, 187986.75, 536868.75, 188062.75, - 536868.75, 188115.25, 536868.75, 188121.25, 536868.75, 188035.25, 536868.75, 187938.25, - 536868.75, 188076.25, 536868.75, 187928.75, 536868.75, 187939.25, 536868.75, 188028.75, - 536868.75, 187978.75, 536868.75, 187984.25, 536868.75, 188136.25, 536868.75, 188050.25, - 536868.75, 188117.25, 536868.75, 187991.75, 536868.75, 188111.75, 536868.75, 187926.25, - 536868.75, 188010.75, 536868.75, 188124.75, 536868.75, 187985.75, 536868.75, 187919.75, - 536868.75, 187938.75, 536868.75, 188101.75, 536868.75, 187994.25, 536868.75, 187913.75, - 536868.75, 188085.75, 536868.75, 187992.75, 536868.75, 187984.75, 536868.75, 187976.75, - 536868.75, 188030.25, 536868.75, 187950.75, 536868.75, 188065.75, 536868.75, 188003.75, - 536868.75, 187978.25, 536868.75, 187982.25, 536868.75, 187923.25, 536868.75, 187973.75, - 536868.75, 188112.75, 536868.75, 188122.75, 536868.75, 188063.25, 536868.75, 187977.75, - 536868.75, 188062.25, 536868.75, 188155.75, 536868.75, 187920.75, 536868.75, 187977.25, - 536868.75, 187969.75, 536868.75, 187995.75, 536868.75, 187939.75, 536868.75, 188133.75, - 536868.75, 187962.25, 536868.75, 188119.25, 536868.75, 188135.75, 536868.75, 188103.75, - 536868.75, 187999.75, 536868.75, 187994.75, 536868.75, 187948.75, 536868.75, 187947.25, - 536868.75, 187974.25, 536868.75, 188002.75, 536868.75, 188028.25, 536868.75, 187914.75, - 536868.75, 188017.75, 536868.75, 188015.75, 536868.75, 188139.75, 536868.75, 187936.75, - 536868.75, 188147.75, 536868.75, 188123.75, 536868.75, 188021.25, 536868.75, 188097.75, - 536868.75, 187949.25, 536868.75, 188034.25, 536868.75, 188026.25, 536868.75, 188064.25, - 536868.75, 188010.25, 536868.75, 188133.25, 536868.75, 188156.25, 536868.75, 188016.25, - 536868.75, 187974.75, 536868.75, 188014.75, 536868.75, 188139.25, 536868.75, 187924.25, - 536868.75, 188116.75, 536868.75, 187919.25, 536868.75, 187945.75, 536868.75, 187912.75, - 536868.75, 188106.25, 536868.75, 188117.75, 536868.75, 187914.25, 536868.75, 187991.25, - 536869.25, 187924.75, 536869.25, 188141.75, 536869.25, 187936.25, 536869.25, 188123.25, - 536869.25, 187990.75, 536869.25, 187970.75, 536869.25, 187981.25, 536869.25, 187937.75, - 536869.25, 188051.25, 536869.25, 188008.25, 536869.25, 187990.25, 536869.25, 187920.75, - 536869.25, 187920.25, 536869.25, 188003.25, 536869.25, 187948.25, 536869.25, 188157.25, - 536869.25, 187928.25, 536869.25, 187949.75, 536869.25, 188050.75, 536869.25, 188025.25, - 536869.25, 188136.75, 536869.25, 188031.25, 536869.25, 188017.25, 536869.25, 188050.25, - 536869.25, 188028.75, 536869.25, 187944.25, 536869.25, 188113.25, 536869.25, 187991.25, - 536869.25, 187913.25, 536869.25, 187925.75, 536869.25, 188097.25, 536869.25, 188064.75, - 536869.25, 188157.75, 536869.25, 187912.25, 536869.25, 187946.25, 536869.25, 187941.75, - 536869.25, 188125.75, 536869.25, 187929.75, 536869.25, 188077.25, 536869.25, 188154.25, - 536869.25, 188122.25, 536869.25, 188015.25, 536869.25, 188016.75, 536869.25, 188143.25, - 536869.25, 188131.75, 536869.25, 188120.75, 536869.25, 188049.25, 536869.25, 188097.75, - 536869.25, 187931.25, 536869.25, 188140.25, 536869.25, 187923.25, 536869.25, 187935.75, - 536869.25, 188060.75, 536869.25, 187995.75, 536869.25, 188109.25, 536869.25, 187994.75, - 536869.25, 188121.75, 536869.25, 187974.25, 536869.25, 187989.25, 536869.25, 187977.75, - 536869.25, 188126.75, 536869.25, 188135.25, 536869.25, 188102.25, 536869.25, 188112.25, - 536869.25, 188118.25, 536869.25, 188025.75, 536869.25, 188127.25, 536869.25, 188064.25, - 536869.25, 187975.25, 536869.25, 188112.75, 536869.25, 187985.25, 536869.25, 188159.75, - 536869.25, 187983.25, 536869.25, 188133.25, 536869.25, 187945.25, 536869.25, 188100.75, - 536869.25, 188134.75, 536869.25, 188127.75, 536869.25, 187997.25, 536869.25, 188118.75, - 536869.25, 187975.75, 536869.25, 187927.75, 536869.25, 188121.25, 536869.25, 187938.75, - 536869.25, 187976.25, 536869.25, 188068.25, 536869.25, 188151.75, 536869.25, 187983.75, - 536869.25, 188116.75, 536869.25, 188034.75, 536869.75, 187922.75, 536869.75, 188026.75, - 536869.75, 188018.25, 536869.75, 187925.75, 536869.75, 187927.25, 536869.75, 188124.75, - 536869.75, 188103.25, 536869.75, 187980.25, 536869.75, 188136.75, 536869.75, 188004.75, - 536869.75, 187911.75, 536869.75, 187948.75, 536869.75, 187996.25, 536869.75, 188101.25, - 536869.75, 188050.25, 536869.75, 188026.25, 536869.75, 188144.75, 536869.75, 187954.25, - 536869.75, 188048.75, 536869.75, 188025.25, 536869.75, 188012.25, 536869.75, 187963.75, - 536869.75, 188117.25, 536869.75, 188131.25, 536869.75, 188116.75, 536869.75, 187929.25, - 536869.75, 188028.25, 536869.75, 187984.25, 536869.75, 188009.75, 536869.75, 188042.25, - 536869.75, 187934.75, 536869.75, 187913.25, 536869.75, 188035.75, 536869.75, 187980.75, - 536869.75, 188135.25, 536869.75, 188134.25, 536869.75, 187928.25, 536869.75, 188017.25, - 536869.75, 187935.75, 536869.75, 188036.75, 536869.75, 187945.75, 536869.75, 187920.25, - 536869.75, 187996.75, 536869.75, 188008.25, 536869.75, 188124.25, 536869.75, 188043.75, - 536869.75, 188154.75, 536869.75, 188102.25, 536869.75, 188137.25, 536869.75, 188076.75, - 536869.75, 188143.75, 536869.75, 188158.25, 536869.75, 188140.75, 536869.75, 188029.25, - 536869.75, 188006.25, 536869.75, 188049.25, 536869.75, 188033.25, 536869.75, 187936.25, - 536869.75, 188157.25, 536869.75, 187910.75, 536869.75, 188051.25, 536869.75, 188114.75, - 536869.75, 187986.75, 536869.75, 188100.25, 536869.75, 187937.25, 536869.75, 188048.25, - 536869.75, 188129.25, 536869.75, 187937.75, 536869.75, 187995.25, 536869.75, 188160.25, - 536869.75, 187977.25, 536869.75, 188100.75, 536869.75, 187948.25, 536869.75, 188113.25, - 536869.75, 188113.75, 536869.75, 187989.25, 536869.75, 187990.75, 536869.75, 188016.25, - 536869.75, 187975.25, 536869.75, 188064.25, 536869.75, 187949.25, 536869.75, 188061.75, - 536869.75, 188156.75, 536869.75, 188118.75, 536869.75, 187912.25, 536869.75, 187982.75, - 536869.75, 188122.25, 536869.75, 187921.75, 536869.75, 187946.25, 536869.75, 188049.75, - 536869.75, 188119.75, 536869.75, 188051.75, 536869.75, 188004.25, 536869.75, 188064.75, - 536869.75, 187930.75, 536869.75, 187923.75, 536869.75, 188098.25, 536869.75, 187931.75, - 536869.75, 188052.25, 536869.75, 188132.75, 536869.75, 188141.25, 536869.75, 187988.75, - 536869.75, 188032.75, 536869.75, 187941.75, 536869.75, 187978.25, 536869.75, 187912.75, - 536869.75, 187943.75, 536869.75, 187936.75, 536869.75, 187942.25, 536869.75, 188011.75, - 536869.75, 187921.25, 536869.75, 187985.25, 536869.75, 188142.75, 536869.75, 188121.25, - 536870.25, 188004.25, 536870.25, 187981.25, 536870.25, 188134.75, 536870.25, 187947.75, - 536870.25, 188079.25, 536870.25, 187948.75, 536870.25, 187985.25, 536870.25, 188132.75, - 536870.25, 188142.75, 536870.25, 188077.25, 536870.25, 188011.75, 536870.25, 187983.75, - 536870.25, 188018.25, 536870.25, 187936.75, 536870.25, 188106.75, 536870.25, 188063.25, - 536870.25, 187941.75, 536870.25, 187926.25, 536870.25, 187927.25, 536870.25, 187982.25, - 536870.25, 187978.25, 536870.25, 188032.75, 536870.25, 188128.75, 536870.25, 188105.75, - 536870.25, 188000.25, 536870.25, 188141.25, 536870.25, 187931.75, 536870.25, 188112.75, - 536870.25, 188098.25, 536870.25, 187923.75, 536870.25, 188064.75, 536870.25, 187930.75, - 536870.25, 187912.75, 536870.25, 188157.75, 536870.25, 188026.75, 536870.25, 188136.75, - 536870.25, 188109.25, 536870.25, 188066.25, 536870.25, 188052.25, 536870.25, 187911.75, - 536870.25, 188049.75, 536870.25, 187995.75, 536870.25, 188135.75, 536870.25, 188035.25, - 536870.25, 187946.25, 536870.25, 187980.25, 536870.25, 187996.25, 536870.25, 188134.25, - 536870.25, 187982.75, 536870.25, 187989.25, 536870.25, 188120.75, 536870.25, 188005.25, - 536870.25, 188131.75, 536870.25, 188141.75, 536870.25, 188026.25, 536870.25, 188112.25, - 536870.25, 188156.75, 536870.25, 188118.75, 536870.25, 188002.75, 536870.25, 187989.75, - 536870.25, 188025.25, 536870.25, 188125.75, 536870.25, 187990.75, 536870.25, 188116.75, - 536870.25, 187933.75, 536870.25, 188121.75, 536870.25, 187935.25, 536870.25, 188145.75, - 536870.25, 188048.25, 536870.25, 188012.25, 536870.25, 188101.75, 536870.25, 188028.25, - 536870.25, 188126.75, 536870.25, 187983.25, 536870.25, 187991.25, 536870.25, 187920.75, - 536870.25, 188117.25, 536870.25, 188028.75, 536870.25, 187946.75, 536870.25, 188008.75, - 536870.25, 187947.25, 536870.25, 187928.25, 536870.25, 187948.25, 536870.25, 188017.25, - 536870.25, 187937.25, 536870.25, 188065.25, 536870.25, 187995.25, 536870.25, 187919.75, - 536870.25, 188158.25, 536870.25, 188003.75, 536870.25, 187976.75, 536870.25, 187945.75, - 536870.25, 188143.25, 536870.25, 188100.25, 536870.25, 188132.25, 536870.25, 188033.25, - 536870.25, 188062.75, 536870.25, 188049.25, 536870.25, 188036.75, 536870.25, 187929.25, - 536870.25, 187922.75, 536870.25, 188140.75, 536870.25, 188143.75, 536870.25, 188154.75, - 536870.25, 188151.25, 536870.25, 187984.75, 536870.25, 188102.25, 536870.25, 188137.25, - 536870.25, 188030.25, 536870.25, 188124.25, 536870.25, 187941.25, 536870.25, 188061.25, - 536870.25, 188088.25, 536870.25, 187936.25, 536870.75, 188028.75, 536870.75, 188049.25, - 536870.75, 188033.25, 536870.75, 188062.75, 536870.75, 188117.75, 536870.75, 187944.75, - 536870.75, 187935.75, 536870.75, 188025.75, 536870.75, 188007.75, 536870.75, 187947.25, - 536870.75, 187998.25, 536870.75, 187996.75, 536870.75, 188035.75, 536870.75, 187980.75, - 536870.75, 187931.25, 536870.75, 187944.25, 536870.75, 188094.25, 536870.75, 188100.75, - 536870.75, 188133.25, 536870.75, 188017.75, 536870.75, 188113.75, 536870.75, 188036.25, - 536870.75, 187975.75, 536870.75, 188061.75, 536870.75, 187933.75, 536870.75, 188025.25, - 536870.75, 188102.75, 536870.75, 188118.75, 536870.75, 188018.75, 536870.75, 187922.25, - 536870.75, 188007.25, 536870.75, 188033.75, 536870.75, 188118.25, 536870.75, 187921.75, - 536870.75, 188116.25, 536870.75, 187980.25, 536870.75, 187911.75, 536870.75, 188103.25, - 536870.75, 188009.25, 536870.75, 188123.25, 536870.75, 187977.75, 536870.75, 187956.75, - 536870.75, 188049.75, 536870.75, 188005.75, 536870.75, 187926.25, 536870.75, 188112.25, - 536870.75, 188112.75, 536870.75, 188031.25, 536870.75, 188133.75, 536870.75, 187927.25, - 536870.75, 188064.75, 536870.75, 188009.75, 536870.75, 188032.75, 536870.75, 188124.75, - 536870.75, 187924.25, 536870.75, 188020.25, 536870.75, 187916.75, 536870.75, 187988.75, - 536870.75, 188063.25, 536870.75, 188142.25, 536870.75, 188122.25, 536870.75, 187984.25, - 536870.75, 187987.25, 536870.75, 187947.75, 536870.75, 187934.75, 536870.75, 188120.25, - 536871.25, 188046.75, 536871.25, 187987.25, 536871.25, 187932.75, 536871.25, 188048.75, - 536871.25, 188157.75, 536871.25, 187926.75, 536871.25, 188142.25, 536871.25, 188018.25, - 536871.25, 188119.25, 536871.25, 187983.75, 536871.25, 187988.25, 536871.25, 187915.25, - 536871.25, 188106.75, 536871.25, 187976.25, 536871.25, 188024.25, 536871.25, 188155.25, - 536871.25, 188004.75, 536871.25, 187925.75, 536871.25, 187925.25, 536871.25, 188032.25, - 536871.25, 188026.25, 536871.25, 188101.25, 536871.25, 187938.75, 536871.25, 188019.75, - 536871.25, 187980.75, 536871.25, 188028.25, 536871.25, 188050.25, 536871.25, 187911.25, - 536871.25, 188042.25, 536871.25, 188121.75, 536871.25, 188050.75, 536871.25, 188138.25, - 536871.25, 187927.75, 536871.25, 187964.75, 536871.25, 188035.75, 536871.25, 187928.25, - 536871.25, 188008.25, 536871.25, 188044.75, 536871.25, 188034.25, 536871.25, 188063.75, - 536871.25, 188003.75, 536871.25, 187940.25, 536871.25, 188115.25, 536871.25, 187939.75, - 536871.25, 188029.25, 536871.25, 188122.75, 536871.25, 188106.25, 536871.25, 188100.25, - 536871.25, 188006.25, 536871.25, 188010.25, 536871.25, 188157.25, 536871.25, 188056.75, - 536871.25, 187944.75, 536871.25, 188054.25, 536871.25, 187937.75, 536871.25, 187995.25, - 536871.25, 188041.75, 536871.25, 187977.25, 536871.25, 187979.25, 536871.25, 188100.75, - 536871.25, 187985.75, 536871.25, 188019.25, 536871.25, 188147.25, 536871.25, 187912.25, - 536871.25, 188113.25, 536871.25, 187933.25, 536871.25, 188024.75, 536871.25, 187921.25, - 536871.25, 187975.75, 536871.25, 187932.25, 536871.25, 188121.25, 536871.25, 188064.25, - 536871.25, 188123.75, 536871.25, 188043.25, 536871.25, 187922.25, 536871.25, 187977.75, - 536871.25, 187942.25, 536871.25, 188118.25, 536871.25, 188104.25, 536871.25, 187923.25, - 536871.25, 188116.25, 536871.25, 188031.75, 536871.25, 187943.25, 536871.25, 187929.75, - 536871.25, 188051.75, 536871.25, 188110.25, 536871.25, 187995.75, 536871.25, 187982.25, - 536871.25, 187957.75, 536871.25, 188049.75, 536871.25, 188142.75, 536871.25, 188030.75, - 536871.25, 187997.25, 536871.25, 187934.25, 536871.25, 188112.25, 536871.25, 188152.75, - 536871.25, 188069.75, 536871.25, 187943.75, 536871.75, 187926.25, 536871.75, 187930.75, - 536871.75, 187934.25, 536871.75, 188112.25, 536871.75, 187997.25, 536871.75, 188049.75, - 536871.75, 187940.75, 536871.75, 187978.25, 536871.75, 187943.75, 536871.75, 188030.75, - 536871.75, 188062.25, 536871.75, 188011.75, 536871.75, 188084.75, 536871.75, 188112.75, - 536871.75, 188034.75, 536871.75, 188031.75, 536871.75, 188051.75, 536871.75, 188120.25, - 536871.75, 187934.75, 536871.75, 188045.25, 536871.75, 187931.75, 536871.75, 187924.75, - 536871.75, 188116.25, 536871.75, 187982.75, 536871.75, 188039.75, 536871.75, 188123.75, - 536871.75, 188004.25, 536871.75, 187932.25, 536871.75, 188043.25, 536871.75, 188118.75, - 536871.75, 187915.25, 536871.75, 188064.25, 536871.75, 187923.75, 536871.75, 188009.25, - 536871.75, 187975.75, 536871.75, 188100.75, 536871.75, 187989.25, 536871.75, 188109.75, - 536871.75, 187987.75, 536871.75, 187933.25, 536871.75, 188113.25, 536871.75, 188107.25, - 536871.75, 188053.25, 536871.75, 187912.25, 536871.75, 187922.25, 536871.75, 188019.25, - 536871.75, 188036.25, 536871.75, 187921.25, 536871.75, 187977.25, 536871.75, 187944.75, - 536871.75, 188103.75, 536871.75, 188073.25, 536871.75, 188025.75, 536871.75, 187981.25, - 536871.75, 188154.25, 536871.75, 188129.25, 536871.75, 187939.75, 536871.75, 188132.25, - 536871.75, 187964.25, 536871.75, 188108.75, 536871.75, 187940.25, 536871.75, 188115.25, - 536871.75, 188124.25, 536871.75, 188102.25, 536871.75, 188023.75, 536871.75, 187942.25, - 536871.75, 188122.75, 536871.75, 188034.25, 536871.75, 188063.75, 536871.75, 188121.75, - 536871.75, 188159.75, 536871.75, 187927.75, 536871.75, 188117.75, 536871.75, 187988.25, - 536871.75, 188050.25, 536871.75, 187951.25, 536871.75, 188008.75, 536871.75, 188050.75, - 536871.75, 188028.25, 536871.75, 187911.25, 536871.75, 187926.75, 536871.75, 187939.25, - 536871.75, 188019.75, 536871.75, 188025.25, 536871.75, 188026.25, 536871.75, 188032.25, - 536871.75, 188029.25, 536871.75, 187996.25, 536871.75, 187979.75, 536871.75, 188018.75, - 536871.75, 188128.75, 536871.75, 187938.25, 536871.75, 188018.25, 536871.75, 187980.25, - 536871.75, 187985.75, 536871.75, 187928.25, 536871.75, 187983.75, 536871.75, 187994.75, - 536871.75, 188004.75, 536871.75, 187932.75, 536871.75, 188048.75, 536871.75, 187987.25, - 536871.75, 188007.25, 536872.25, 188006.75, 536872.25, 187999.25, 536872.25, 188035.75, - 536872.25, 188070.75, 536872.25, 188008.25, 536872.25, 188050.75, 536872.25, 188110.75, - 536872.25, 188116.75, 536872.25, 187989.75, 536872.25, 188101.25, 536872.25, 188024.25, - 536872.25, 187980.25, 536872.25, 187996.25, 536872.25, 187911.75, 536872.25, 187983.75, - 536872.25, 188136.75, 536872.25, 188063.75, 536872.25, 188158.25, 536872.25, 188102.25, - 536872.25, 187940.25, 536872.25, 187938.75, 536872.25, 188051.25, 536872.25, 187926.75, - 536872.25, 187937.75, 536872.25, 188160.25, 536872.25, 188124.75, 536872.25, 188119.75, - 536872.25, 187910.75, 536872.25, 188122.75, 536872.25, 188022.25, 536872.25, 188009.75, - 536872.25, 188023.75, 536872.25, 187933.75, 536872.25, 187924.25, 536872.25, 188118.25, - 536872.25, 188034.25, 536872.25, 188023.25, 536872.25, 187943.25, 536872.25, 188156.25, - 536872.25, 187985.25, 536872.25, 188112.75, 536872.25, 188028.75, 536872.25, 188031.75, - 536872.25, 188122.25, 536872.25, 188157.25, 536872.25, 188144.25, 536872.25, 188068.75, - 536872.25, 188154.75, 536872.25, 188069.75, 536872.25, 187930.25, 536872.25, 187982.25, - 536872.25, 187922.75, 536872.25, 188019.75, 536872.25, 187990.25, 536872.25, 187926.25, - 536872.25, 187988.75, 536872.25, 188018.75, 536872.25, 188027.25, 536872.25, 188111.75, - 536872.25, 188073.75, 536872.25, 188113.75, 536872.25, 187942.75, 536872.25, 188041.75, - 536872.25, 187946.25, 536872.25, 188121.25, 536872.25, 187978.75, 536872.25, 188005.25, - 536872.25, 187987.75, 536872.25, 187986.75, 536872.25, 188024.75, 536872.25, 188035.25, - 536872.25, 188136.25, 536872.25, 187921.75, 536872.25, 188123.25, 536872.25, 187981.75, - 536872.25, 188118.75, 536872.75, 188125.75, 536872.75, 188029.75, 536872.75, 188123.25, - 536872.75, 188113.75, 536872.75, 188101.75, 536872.75, 187921.75, 536872.75, 188005.25, - 536872.75, 188136.25, 536872.75, 187975.75, 536872.75, 188034.75, 536872.75, 188071.25, - 536872.75, 188034.25, 536872.75, 188116.25, 536872.75, 188107.75, 536872.75, 187923.75, - 536872.75, 187970.25, 536872.75, 187937.25, 536872.75, 187986.25, 536872.75, 188019.75, - 536872.75, 187969.75, 536872.75, 187926.25, 536872.75, 188121.25, 536872.75, 188024.25, - 536872.75, 187929.75, 536872.75, 188070.25, 536872.75, 187934.25, 536872.75, 187922.75, - 536872.75, 187923.25, 536872.75, 187978.25, 536872.75, 187998.75, 536872.75, 187931.25, - 536872.75, 187930.25, 536872.75, 188068.75, 536872.75, 188137.75, 536872.75, 188031.75, - 536872.75, 188006.25, 536872.75, 187979.25, 536872.75, 188095.75, 536872.75, 187996.75, - 536872.75, 188020.25, 536872.75, 188122.25, 536872.75, 188130.75, 536872.75, 187995.75, - 536872.75, 187993.75, 536872.75, 188100.25, 536872.75, 188022.75, 536872.75, 188021.25, - 536872.75, 188116.75, 536872.75, 188139.75, 536872.75, 188152.25, 536872.75, 187990.75, - 536872.75, 187912.75, 536872.75, 187922.25, 536872.75, 188019.25, 536872.75, 188133.25, - 536872.75, 187942.25, 536872.75, 188138.25, 536872.75, 188044.75, 536872.75, 188022.25, - 536872.75, 188071.75, 536872.75, 188009.75, 536872.75, 188042.75, 536872.75, 187976.75, - 536872.75, 188103.75, 536872.75, 187987.25, 536872.75, 188009.25, 536872.75, 187997.75, - 536872.75, 188068.25, 536872.75, 188102.25, 536872.75, 187928.25, 536872.75, 188010.25, - 536872.75, 188033.25, 536872.75, 188098.75, 536872.75, 188133.75, 536872.75, 188117.25, - 536872.75, 188120.75, 536872.75, 188138.75, 536872.75, 187925.75, 536872.75, 187941.25, - 536872.75, 188027.75, 536872.75, 187994.75, 536872.75, 188148.75, 536872.75, 188114.25, - 536872.75, 188046.25, 536872.75, 188102.75, 536872.75, 187965.75, 536872.75, 188005.75, - 536872.75, 188126.25, 536872.75, 188126.75, 536872.75, 188108.25, 536872.75, 187928.75, - 536872.75, 188119.25, 536872.75, 188156.75, 536873.25, 188014.25, 536873.25, 188106.75, - 536873.25, 188035.75, 536873.25, 187913.25, 536873.25, 188083.75, 536873.25, 188120.75, - 536873.25, 188155.75, 536873.25, 188148.25, 536873.25, 188070.75, 536873.25, 187941.25, - 536873.25, 188126.25, 536873.25, 187928.75, 536873.25, 188046.75, 536873.25, 188119.25, - 536873.25, 188012.25, 536873.25, 188101.25, 536873.25, 187965.75, 536873.25, 188028.25, - 536873.25, 188031.25, 536873.25, 188098.75, 536873.25, 188128.75, 536873.25, 188029.25, - 536873.25, 187938.25, 536873.25, 188151.25, 536873.25, 188069.25, 536873.25, 188097.75, - 536873.25, 187928.25, 536873.25, 188117.25, 536873.25, 188008.75, 536873.25, 188129.25, - 536873.25, 187962.25, 536873.25, 187997.75, 536873.25, 188106.25, 536873.25, 188071.75, - 536873.25, 187988.25, 536873.25, 188102.25, 536873.25, 188022.25, 536873.25, 188138.25, - 536873.25, 187922.25, 536873.25, 188143.25, 536873.25, 187965.25, 536873.25, 187912.75, - 536873.25, 188023.75, 536873.25, 188152.25, 536873.25, 188009.25, 536873.25, 188034.25, - 536873.25, 187995.25, 536873.25, 188114.25, 536873.25, 188032.75, 536873.25, 187979.25, - 536873.25, 188122.25, 536873.25, 188121.25, 536873.25, 187940.75, 536873.25, 188023.25, - 536873.25, 187943.75, 536873.25, 187986.25, 536873.25, 187975.75, 536873.25, 187942.75, - 536873.25, 187996.75, 536873.25, 187995.75, 536873.25, 188125.25, 536873.25, 187916.25, - 536873.25, 188116.25, 536873.25, 188006.25, 536873.25, 187984.75, 536873.25, 187968.25, - 536873.25, 188112.25, 536873.25, 188123.25, 536873.25, 188037.75, 536873.25, 187978.25, - 536873.25, 188113.25, 536873.25, 188101.75, 536873.25, 188005.25, 536873.25, 187986.75, - 536873.25, 187912.25, 536873.25, 188011.25, 536873.25, 187937.25, 536873.25, 188018.75, - 536873.25, 188045.25, 536873.25, 187931.75, 536873.25, 188019.75, 536873.25, 188132.75, - 536873.25, 187941.75, 536873.75, 188006.25, 536873.75, 187970.25, 536873.75, 188120.25, - 536873.75, 188011.75, 536873.75, 188070.25, 536873.75, 188159.25, 536873.75, 187991.25, - 536873.75, 187922.75, 536873.75, 188036.25, 536873.75, 187966.25, 536873.75, 188101.75, - 536873.75, 188113.75, 536873.75, 187929.75, 536873.75, 187998.75, 536873.75, 187935.25, - 536873.75, 188118.75, 536873.75, 187978.25, 536873.75, 188112.25, 536873.75, 188123.25, - 536873.75, 187930.25, 536873.75, 187926.25, 536873.75, 188028.75, 536873.75, 187927.75, - 536873.75, 188076.25, 536873.75, 188000.75, 536873.75, 188118.25, 536873.75, 187996.75, - 536873.75, 188116.75, 536873.75, 187997.25, 536873.75, 187940.75, 536873.75, 187931.25, - 536873.75, 188051.75, 536873.75, 188020.75, 536873.75, 188114.25, 536873.75, 188123.75, - 536873.75, 188012.75, 536873.75, 187989.25, 536873.75, 187933.75, 536873.75, 187938.75, - 536873.75, 187985.75, 536873.75, 187990.75, 536873.75, 188022.75, 536873.75, 188155.25, - 536873.75, 187976.25, 536873.75, 187976.75, 536873.75, 188021.25, 536873.75, 188019.25, - 536873.75, 187968.75, 536873.75, 188043.75, 536873.75, 188124.75, 536873.75, 188119.75, - 536873.75, 187937.75, 536873.75, 187911.75, 536873.75, 188117.75, 536873.75, 188022.25, - 536873.75, 188009.75, 536873.75, 188030.25, 536873.75, 188122.75, 536873.75, 188158.75, - 536873.75, 187987.25, 536873.75, 187925.75, 536873.75, 187993.25, 536873.75, 188131.25, - 536873.75, 188139.25, 536873.75, 188068.25, 536873.75, 187994.75, 536873.75, 188010.25, - 536873.75, 188104.75, 536873.75, 188128.75, 536873.75, 188061.25, 536873.75, 188135.25, - 536873.75, 188124.25, 536873.75, 187998.25, 536873.75, 187983.75, 536873.75, 188027.75, - 536873.75, 188005.75, 536873.75, 187928.75, 536873.75, 188102.75, 536873.75, 187935.75, - 536873.75, 187913.25, 536873.75, 188034.75, 536873.75, 187952.25, 536874.25, 188085.75, - 536874.25, 187938.25, 536874.25, 187969.25, 536874.25, 187911.25, 536874.25, 188008.75, - 536874.25, 187948.25, 536874.25, 187990.25, 536874.25, 187987.75, 536874.25, 188113.75, - 536874.25, 188071.25, 536874.25, 187923.25, 536874.25, 188120.25, 536874.25, 188137.75, - 536874.25, 187930.75, 536874.25, 188123.75, 536874.25, 187970.75, 536874.25, 188009.75, - 536874.25, 187955.25, 536874.25, 187939.75, 536874.25, 187920.25, 536874.25, 187971.25, - 536874.25, 188031.25, 536874.25, 188103.25, 536874.25, 187998.75, 536874.25, 187926.25, - 536874.25, 187934.25, 536874.25, 187932.25, 536874.25, 187968.25, 536874.25, 188022.75, - 536874.25, 187940.25, 536874.25, 188075.25, 536874.25, 188105.25, 536874.25, 188109.25, - 536874.25, 187985.75, 536874.25, 188089.25, 536874.25, 188032.25, 536874.25, 187992.25, - 536874.25, 188028.25, 536874.25, 188069.25, 536874.25, 188121.75, 536874.25, 187997.75, - 536874.25, 188102.25, 536874.25, 188019.25, 536874.25, 188153.25, 536874.25, 188127.25, - 536874.25, 188109.75, 536874.25, 187912.75, 536874.25, 188006.75, 536874.25, 187936.75, - 536874.25, 188110.25, 536874.25, 187934.75, 536874.25, 188112.75, 536874.25, 188068.75, - 536874.25, 188152.75, 536874.25, 187966.25, 536874.25, 188116.25, 536874.25, 188128.25, - 536874.25, 188118.75, 536874.25, 188101.75, 536874.25, 188041.75, 536874.25, 187984.75, - 536874.25, 188133.75, 536874.25, 188072.25, 536874.25, 188042.75, 536874.25, 187913.25, - 536874.25, 187935.75, 536874.25, 187922.75, 536874.25, 188012.25, 536874.25, 188110.75, - 536874.25, 188076.75, 536874.25, 188033.25, 536874.25, 188129.25, 536874.25, 188067.75, - 536874.25, 187966.75, 536874.25, 188010.75, 536874.25, 187928.75, 536874.25, 188114.25, - 536874.25, 187977.25, 536874.25, 188133.25, 536874.25, 188129.75, 536874.25, 188033.75, - 536874.25, 188021.75, 536874.25, 187993.75, 536874.25, 187995.75, 536874.25, 188020.25, - 536874.25, 188130.25, 536874.25, 188099.25, 536874.25, 188079.25, 536874.25, 188011.75, - 536874.25, 188132.75, 536874.25, 188011.25, 536874.25, 187923.75, 536874.25, 187933.25, - 536874.25, 188027.25, 536874.25, 188111.75, 536874.25, 187938.75, 536874.25, 187995.25, - 536874.25, 188111.25, 536874.25, 187980.75, 536874.25, 188099.75, 536874.25, 187927.25, - 536874.25, 188005.75, 536874.25, 188118.25, 536874.75, 188024.25, 536874.75, 187985.75, - 536874.75, 188029.25, 536874.75, 188044.25, 536874.75, 188102.75, 536874.75, 188071.25, - 536874.75, 188109.75, 536874.75, 187927.25, 536874.75, 187930.75, 536874.75, 187912.75, - 536874.75, 188124.25, 536874.75, 188131.75, 536874.75, 188120.25, 536874.75, 188004.25, - 536874.75, 188138.25, 536874.75, 188019.75, 536874.75, 188017.75, 536874.75, 188131.25, - 536874.75, 187994.25, 536874.75, 188111.75, 536874.75, 187970.75, 536874.75, 187938.75, - 536874.75, 188034.25, 536874.75, 188149.25, 536874.75, 188107.75, 536874.75, 187923.75, - 536874.75, 188126.25, 536874.75, 188009.75, 536874.75, 188038.75, 536874.75, 188018.75, - 536874.75, 187990.75, 536874.75, 188160.25, 536874.75, 187988.75, 536874.75, 188132.75, - 536874.75, 188110.25, 536874.75, 188136.75, 536874.75, 188006.25, 536874.75, 188099.25, - 536874.75, 187987.25, 536874.75, 188128.25, 536874.75, 188067.25, 536874.75, 187931.25, - 536874.75, 188101.75, 536874.75, 188027.25, 536874.75, 187997.75, 536874.75, 188008.75, - 536874.75, 187910.75, 536874.75, 187993.75, 536874.75, 187940.25, 536874.75, 188021.75, - 536874.75, 187933.75, 536874.75, 188114.25, 536874.75, 187991.25, 536874.75, 188121.75, - 536874.75, 188028.25, 536874.75, 188005.25, 536874.75, 187998.75, 536874.75, 188072.25, - 536874.75, 187923.25, 536874.75, 188064.75, 536874.75, 187917.75, 536874.75, 188010.75, - 536874.75, 187976.75, 536874.75, 188067.75, 536874.75, 188022.75, 536874.75, 188109.25, - 536874.75, 188001.75, 536874.75, 187926.25, 536874.75, 187913.25, 536874.75, 187971.75, - 536874.75, 187966.75, 536874.75, 188006.75, 536874.75, 188089.25, 536874.75, 188030.25, - 536874.75, 187935.75, 536874.75, 188110.75, 536874.75, 188112.75, 536874.75, 188020.25, - 536874.75, 187934.75, 536874.75, 187938.25, 536874.75, 188118.25, 536874.75, 188068.25, - 536874.75, 188155.25, 536874.75, 187968.75, 536874.75, 187965.75, 536874.75, 188134.25, - 536874.75, 188116.75, 536874.75, 188129.75, 536874.75, 187927.75, 536874.75, 188019.25, - 536874.75, 188119.25, 536874.75, 188124.75, 536874.75, 188098.25, 536874.75, 188068.75, - 536875.25, 188124.75, 536875.25, 188116.25, 536875.25, 188129.25, 536875.25, 188033.25, - 536875.25, 187999.25, 536875.25, 188022.25, 536875.25, 188155.25, 536875.25, 188112.75, - 536875.25, 187938.25, 536875.25, 187939.25, 536875.25, 187971.25, 536875.25, 187989.25, - 536875.25, 187922.75, 536875.25, 188155.75, 536875.25, 188120.75, 536875.25, 187971.75, - 536875.25, 187911.25, 536875.25, 188009.25, 536875.25, 188108.25, 536875.25, 188053.75, - 536875.25, 187914.75, 536875.25, 187992.25, 536875.25, 188098.75, 536875.25, 188027.75, - 536875.25, 188128.75, 536875.25, 188124.25, 536875.25, 187926.75, 536875.25, 188067.75, - 536875.25, 187934.25, 536875.25, 187986.25, 536875.25, 188125.25, 536875.25, 187930.25, - 536875.25, 188113.25, 536875.25, 188072.25, 536875.25, 188062.75, 536875.25, 187956.75, - 536875.25, 188138.75, 536875.25, 188133.25, 536875.25, 188108.75, 536875.25, 188122.75, - 536875.25, 187978.75, 536875.25, 187933.25, 536875.25, 188054.25, 536875.25, 187986.75, - 536875.25, 188139.75, 536875.25, 188019.75, 536875.25, 188146.25, 536875.25, 187911.75, - 536875.25, 188071.75, 536875.25, 188102.25, 536875.25, 187913.75, 536875.25, 188107.25, - 536875.25, 188023.25, 536875.25, 188152.75, 536875.25, 187931.25, 536875.25, 188032.75, - 536875.25, 187982.25, 536875.25, 188006.25, 536875.25, 188130.75, 536875.25, 187936.75, - 536875.25, 188043.25, 536875.25, 188018.75, 536875.25, 187969.75, 536875.25, 187924.25, - 536875.25, 188011.25, 536875.25, 188106.25, 536875.25, 188065.75, 536875.25, 187998.25, - 536875.25, 188017.75, 536875.25, 188004.25, 536875.25, 188066.25, 536875.25, 188024.25, - 536875.25, 187980.25, 536875.25, 188023.75, 536875.25, 188109.75, 536875.25, 187912.25, - 536875.25, 188005.75, 536875.25, 188127.25, 536875.25, 187925.25, 536875.25, 187990.25, - 536875.25, 188154.25, 536875.25, 187945.25, 536875.25, 188031.25, 536875.75, 187937.25, - 536875.75, 188012.25, 536875.75, 188120.25, 536875.75, 188010.25, 536875.75, 188008.75, - 536875.75, 187988.75, 536875.75, 188077.25, 536875.75, 187931.75, 536875.75, 188003.25, - 536875.75, 188119.75, 536875.75, 188075.75, 536875.75, 188130.25, 536875.75, 188118.75, - 536875.75, 187967.25, 536875.75, 188115.25, 536875.75, 188123.75, 536875.75, 188134.75, - 536875.75, 187937.75, 536875.75, 187929.75, 536875.75, 188154.25, 536875.75, 187970.25, - 536875.75, 187979.25, 536875.75, 188107.25, 536875.75, 188013.25, 536875.75, 187993.25, - 536875.75, 188031.75, 536875.75, 188053.75, 536875.75, 188000.25, 536875.75, 187969.25, - 536875.75, 188033.75, 536875.75, 188011.75, 536875.75, 187971.25, 536875.75, 188152.75, - 536875.75, 187981.75, 536875.75, 187925.25, 536875.75, 188015.75, 536875.75, 188127.25, - 536875.75, 188099.75, 536875.75, 188022.25, 536875.75, 188027.25, 536875.75, 188066.75, - 536875.75, 187931.25, 536875.75, 188113.75, 536875.75, 188057.75, 536875.75, 188078.25, - 536875.75, 188030.25, 536875.75, 187972.25, 536875.75, 188112.25, 536875.75, 187998.25, - 536875.75, 188030.75, 536875.75, 188024.75, 536875.75, 188125.75, 536875.75, 187967.75, - 536875.75, 188026.75, 536875.75, 188149.25, 536875.75, 188140.25, 536875.75, 187987.25, - 536875.75, 188016.75, 536875.75, 187929.25, 536875.75, 188052.75, 536875.75, 187935.75, - 536875.75, 187912.25, 536875.75, 188011.25, 536875.75, 188059.75, 536875.75, 187914.75, - 536875.75, 187923.25, 536875.75, 188022.75, 536875.75, 188055.25, 536875.75, 188108.25, - 536875.75, 188104.75, 536875.75, 188157.25, 536875.75, 188103.25, 536875.75, 188150.25, - 536875.75, 188154.75, 536875.75, 188109.75, 536875.75, 188104.25, 536875.75, 188066.25, - 536875.75, 188115.75, 536875.75, 187914.25, 536875.75, 188002.75, 536875.75, 188076.75, - 536875.75, 188012.75, 536875.75, 188010.75, 536875.75, 188029.75, 536875.75, 187977.75, - 536875.75, 187966.25, 536875.75, 188004.75, 536875.75, 187986.25, 536875.75, 188127.75, - 536875.75, 187960.25, 536875.75, 187991.75, 536875.75, 188072.75, 536875.75, 187978.75, - 536875.75, 188064.75, 536875.75, 188072.25, 536875.75, 188004.25, 536875.75, 188153.75, - 536875.75, 188033.25, 536875.75, 187923.75, 536875.75, 187934.25, 536875.75, 187999.75, - 536875.75, 188055.75, 536875.75, 188065.75, 536875.75, 188106.25, 536875.75, 188133.25, - 536875.75, 188126.75, 536875.75, 188017.25, 536875.75, 187924.75, 536875.75, 188018.25, - 536876.25, 188017.25, 536876.25, 187979.75, 536876.25, 187983.25, 536876.25, 187932.75, - 536876.25, 187934.25, 536876.25, 188106.25, 536876.25, 188018.25, 536876.25, 188055.75, - 536876.25, 188103.75, 536876.25, 188065.75, 536876.25, 188003.75, 536876.25, 187923.75, - 536876.25, 188079.75, 536876.25, 187936.75, 536876.25, 188120.25, 536876.25, 188004.25, - 536876.25, 188072.25, 536876.25, 187978.75, 536876.25, 188153.75, 536876.25, 188004.75, - 536876.25, 187937.25, 536876.25, 188070.75, 536876.25, 187988.25, 536876.25, 188078.75, - 536876.25, 187999.75, 536876.25, 188106.75, 536876.25, 187912.75, 536876.25, 187931.25, - 536876.25, 188055.25, 536876.25, 187977.75, 536876.25, 188124.25, 536876.25, 188122.25, - 536876.25, 188105.25, 536876.25, 188012.75, 536876.25, 188066.25, 536876.25, 188157.75, - 536876.25, 188129.75, 536876.25, 188104.25, 536876.25, 187930.75, 536876.25, 188115.75, - 536876.25, 188002.75, 536876.25, 188029.75, 536876.25, 188113.25, 536876.25, 188098.75, - 536876.25, 188103.25, 536876.25, 188073.75, 536876.25, 188033.25, 536876.25, 188154.75, - 536876.25, 187957.25, 536876.25, 188128.75, 536876.25, 188022.75, 536876.25, 188131.75, - 536876.25, 187914.75, 536876.25, 188157.25, 536876.25, 188013.25, 536876.25, 187914.25, - 536876.25, 188134.25, 536876.25, 188064.25, 536876.25, 188072.75, 536876.25, 187929.25, - 536876.25, 188125.75, 536876.25, 188026.75, 536876.25, 187935.75, 536876.25, 188097.25, - 536876.25, 187967.75, 536876.25, 188016.75, 536876.25, 188027.75, 536876.25, 188011.75, - 536876.25, 188102.75, 536876.25, 188024.75, 536876.25, 188066.75, 536876.25, 188149.75, - 536876.25, 188117.75, 536876.25, 188110.75, 536876.25, 188127.25, 536876.25, 188152.75, - 536876.25, 188033.75, 536876.25, 188099.75, 536876.25, 188014.75, 536876.25, 188030.25, - 536876.25, 187971.25, 536876.25, 187998.75, 536876.25, 188010.25, 536876.25, 187987.75, - 536876.25, 188053.75, 536876.25, 188154.25, 536876.25, 187913.25, 536876.25, 187969.25, - 536876.25, 188100.25, 536876.25, 188119.75, 536876.25, 188054.25, 536876.25, 188126.75, - 536876.25, 187980.75, 536876.25, 188143.75, 536876.25, 187989.75, 536876.25, 187970.25, - 536876.25, 187937.75, 536876.25, 188115.25, 536876.25, 188016.25, 536876.25, 188102.25, - 536876.25, 187967.25, 536876.25, 188153.25, 536876.25, 187971.75, 536876.25, 188077.25, - 536876.25, 188027.25, 536876.25, 187966.75, 536876.25, 188111.75, 536876.25, 188003.25, - 536876.75, 188003.25, 536876.75, 187959.25, 536876.75, 187932.25, 536876.75, 187971.75, - 536876.75, 188054.75, 536876.75, 188130.25, 536876.75, 188130.75, 536876.75, 188115.25, - 536876.75, 188009.25, 536876.75, 187969.75, 536876.75, 188079.25, 536876.75, 188154.75, - 536876.75, 187979.25, 536876.75, 187980.75, 536876.75, 188031.75, 536876.75, 188023.25, - 536876.75, 187931.75, 536876.75, 188077.75, 536876.75, 188135.25, 536876.75, 188078.25, - 536876.75, 187925.25, 536876.75, 188154.25, 536876.75, 188015.75, 536876.75, 187954.25, - 536876.75, 188063.75, 536876.75, 188123.75, 536876.75, 187992.25, 536876.75, 187987.25, - 536876.75, 187999.25, 536876.75, 188144.25, 536876.75, 188030.75, 536876.75, 187936.25, - 536876.75, 188010.75, 536876.75, 188064.25, 536876.75, 187935.25, 536876.75, 188016.75, - 536876.75, 188082.75, 536876.75, 188052.75, 536876.75, 188026.75, 536876.75, 188126.25, - 536876.75, 188011.25, 536876.75, 188061.75, 536876.75, 188062.75, 536876.75, 187914.75, - 536876.75, 188024.25, 536876.75, 188141.25, 536876.75, 188073.25, 536876.75, 188159.25, - 536876.75, 188073.75, 536876.75, 188103.25, 536876.75, 188029.75, 536876.75, 188002.75, - 536876.75, 188115.75, 536876.75, 188151.25, 536876.75, 188152.25, 536876.75, 188015.25, - 536876.75, 188114.25, 536876.75, 188124.75, 536876.75, 188103.75, 536876.75, 187978.75, - 536876.75, 188116.25, 536876.75, 188151.75, 536876.75, 188108.75, 536876.75, 188078.75, - 536876.75, 188031.25, 536876.75, 188059.25, 536876.75, 188012.25, 536876.75, 187990.75, - 536876.75, 187932.75, 536876.75, 188064.75, 536876.75, 188110.25, 536876.75, 188014.75, - 536876.75, 188055.75, 536876.75, 187944.75, 536876.75, 187924.75, 536876.75, 188000.25, - 536877.25, 187988.25, 536877.25, 188114.75, 536877.25, 188079.75, 536877.25, 187932.75, - 536877.25, 187930.25, 536877.25, 188064.75, 536877.25, 187990.75, 536877.25, 188106.25, - 536877.25, 188055.75, 536877.25, 187925.75, 536877.25, 188012.75, 536877.25, 187999.75, - 536877.25, 187924.25, 536877.25, 188002.25, 536877.25, 188091.25, 536877.25, 187986.25, - 536877.25, 187931.25, 536877.25, 188108.75, 536877.25, 188138.25, 536877.25, 188053.25, - 536877.25, 188073.25, 536877.25, 188151.75, 536877.25, 188056.25, 536877.25, 188057.25, - 536877.25, 188109.25, 536877.25, 188125.25, 536877.25, 188008.75, 536877.25, 188004.75, - 536877.25, 188122.75, 536877.25, 187912.75, 536877.25, 188136.75, 536877.25, 188146.75, - 536877.25, 188015.25, 536877.25, 188078.75, 536877.25, 188151.25, 536877.25, 187933.75, - 536877.25, 188042.25, 536877.25, 188115.75, 536877.25, 188077.75, 536877.25, 188150.25, - 536877.25, 188076.75, 536877.25, 188103.25, 536877.25, 188055.25, 536877.25, 188029.75, - 536877.25, 188023.75, 536877.25, 188114.25, 536877.25, 188073.75, 536877.25, 187918.75, - 536877.25, 188131.25, 536877.25, 187929.25, 536877.25, 187972.75, 536877.25, 187933.25, - 536877.25, 187999.25, 536877.25, 188033.25, 536877.25, 188136.25, 536877.25, 188139.75, - 536877.25, 188001.25, 536877.25, 188109.75, 536877.25, 188024.25, 536877.25, 187911.25, - 536877.25, 188052.75, 536877.25, 188062.75, 536877.25, 188064.25, 536877.25, 188000.75, - 536877.25, 188028.25, 536877.25, 188113.75, 536877.25, 188155.75, 536877.25, 188061.25, - 536877.25, 187968.25, 536877.25, 188123.25, 536877.25, 187968.75, 536877.25, 188032.75, - 536877.25, 188011.25, 536877.25, 187972.25, 536877.25, 187916.25, 536877.25, 188026.25, - 536877.25, 187934.75, 536877.25, 188152.75, 536877.25, 188155.25, 536877.25, 188030.25, - 536877.25, 187987.75, 536877.25, 188030.75, 536877.25, 187910.75, 536877.25, 187979.25, - 536877.25, 187995.25, 536877.25, 188134.75, 536877.25, 188078.25, 536877.25, 188003.25, - 536877.25, 187929.75, 536877.25, 188014.75, 536877.25, 188160.25, 536877.25, 188107.75, - 536877.25, 188153.25, 536877.25, 187991.25, 536877.25, 188029.25, 536877.25, 187970.75, - 536877.25, 188074.75, 536877.25, 188130.25, 536877.25, 187915.25, 536877.25, 188009.75, - 536877.25, 188075.75, 536877.25, 188117.25, 536877.25, 188001.75, 536877.75, 188027.25, - 536877.75, 188153.25, 536877.75, 188156.25, 536877.75, 188077.25, 536877.75, 187929.75, - 536877.75, 187979.25, 536877.75, 188107.25, 536877.75, 188149.75, 536877.75, 187911.75, - 536877.75, 188011.25, 536877.75, 188052.75, 536877.75, 187915.25, 536877.75, 188023.75, - 536877.75, 188029.75, 536877.75, 188009.25, 536877.75, 187970.25, 536877.75, 188135.25, - 536877.75, 188073.75, 536877.75, 187985.25, 536877.75, 188030.75, 536877.75, 187973.25, - 536877.75, 188146.75, 536877.75, 188034.75, 536877.75, 187912.75, 536877.75, 188110.75, - 536877.75, 188138.25, 536877.75, 187978.75, 536877.75, 188134.75, 536877.75, 188058.25, - 536877.75, 187989.25, 536877.75, 188009.75, 536877.75, 188001.75, 536877.75, 188122.75, - 536877.75, 188055.75, 536877.75, 188121.25, 536877.75, 188000.25, 536877.75, 187972.25, - 536877.75, 188109.25, 536877.75, 188058.75, 536877.75, 187924.25, 536877.75, 188008.25, - 536877.75, 188064.75, 536877.75, 188124.25, 536877.75, 187952.25, 536877.75, 188136.75, - 536877.75, 188150.25, 536877.75, 188123.25, 536877.75, 188076.75, 536877.75, 188013.75, - 536877.75, 188078.75, 536877.75, 188108.25, 536877.75, 188062.25, 536877.75, 187914.75, - 536877.75, 188032.75, 536877.75, 188027.75, 536877.75, 187911.25, 536877.75, 187941.75, - 536877.75, 187967.75, 536877.75, 188155.75, 536877.75, 188131.25, 536877.75, 188063.25, - 536877.75, 188115.75, 536877.75, 188002.25, 536877.75, 188107.75, 536877.75, 187972.75, - 536877.75, 188010.25, 536877.75, 188115.25, 536877.75, 188026.25, 536877.75, 188128.25, - 536877.75, 188024.25, 536877.75, 188015.25, 536877.75, 188130.25, 536877.75, 188000.75, - 536877.75, 188070.25, 536877.75, 188074.75, 536877.75, 188053.25, 536877.75, 188001.25, - 536877.75, 188056.25, 536877.75, 188124.75, 536877.75, 187991.25, 536877.75, 188142.75, - 536877.75, 187989.75, 536877.75, 188054.25, 536877.75, 188040.75, 536877.75, 188033.75, - 536877.75, 188029.25, 536877.75, 188062.75, 536877.75, 187914.25, 536877.75, 187999.25, - 536877.75, 187932.75, 536877.75, 188061.25, 536877.75, 187949.75, 536877.75, 188073.25, - 536877.75, 188013.25, 536877.75, 188076.25, 536877.75, 188093.75, 536877.75, 188079.75, - 536877.75, 187924.75, 536877.75, 187925.75, 536877.75, 187984.75, 536877.75, 187930.25, - 536878.25, 188018.25, 536878.25, 188138.25, 536878.25, 188106.75, 536878.25, 187986.25, - 536878.25, 188031.25, 536878.25, 188027.25, 536878.25, 188080.25, 536878.25, 187988.75, - 536878.25, 188121.25, 536878.25, 188152.25, 536878.25, 187928.75, 536878.25, 188076.25, - 536878.25, 188015.25, 536878.25, 188009.75, 536878.25, 187996.75, 536878.25, 187999.75, - 536878.25, 187939.75, 536878.25, 187972.25, 536878.25, 188106.25, 536878.25, 187933.75, - 536878.25, 187998.25, 536878.25, 188073.25, 536878.25, 188016.25, 536878.25, 188156.25, - 536878.25, 188055.25, 536878.25, 188130.75, 536878.25, 188012.25, 536878.25, 188137.75, - 536878.25, 187935.25, 536878.25, 188053.75, 536878.25, 187970.75, 536878.25, 188014.25, - 536878.25, 188024.25, 536878.25, 187933.25, 536878.25, 187931.25, 536878.25, 187916.25, - 536878.25, 187968.75, 536878.25, 188154.25, 536878.25, 188057.25, 536878.25, 187971.25, - 536878.25, 188140.25, 536878.25, 188008.75, 536878.25, 188034.75, 536878.25, 188074.25, - 536878.25, 187915.75, 536878.25, 188033.25, 536878.25, 187968.25, 536878.25, 188076.75, - 536878.25, 188061.25, 536878.25, 187930.75, 536878.25, 188062.25, 536878.25, 187986.75, - 536878.25, 188026.75, 536878.25, 188056.25, 536878.25, 187963.75, 536878.25, 188131.75, - 536878.25, 187924.75, 536878.25, 188032.75, 536878.25, 188000.75, 536878.25, 188114.25, - 536878.25, 188117.25, 536878.25, 188082.25, 536878.25, 188023.75, 536878.25, 188135.75, - 536878.25, 187920.25, 536878.25, 187911.75, 536878.25, 188075.75, 536878.25, 188075.25, - 536878.25, 188087.25, 536878.25, 188155.75, 536878.25, 188011.25, 536878.25, 188079.25, - 536878.25, 188154.75, 536878.25, 187966.75, 536878.25, 188123.75, 536878.25, 187925.25, - 536878.25, 187935.75, 536878.25, 188151.25, 536878.25, 188122.25, 536878.25, 187998.75, - 536878.75, 187967.25, 536878.75, 188140.75, 536878.75, 188010.25, 536878.75, 188011.75, - 536878.75, 188048.25, 536878.75, 187935.75, 536878.75, 187997.25, 536878.75, 188023.25, - 536878.75, 188028.25, 536878.75, 187971.75, 536878.75, 188139.75, 536878.75, 188015.75, - 536878.75, 188120.75, 536878.75, 188102.75, 536878.75, 187916.75, 536878.75, 188080.75, - 536878.75, 187967.75, 536878.75, 187971.25, 536878.75, 188132.25, 536878.75, 188075.75, - 536878.75, 188155.25, 536878.75, 188016.75, 536878.75, 188120.25, 536878.75, 188101.75, - 536878.75, 188105.25, 536878.75, 188032.75, 536878.75, 188031.75, 536878.75, 188071.25, - 536878.75, 188131.75, 536878.75, 188119.75, 536878.75, 188003.75, 536878.75, 187996.25, - 536878.75, 187924.75, 536878.75, 188123.25, 536878.75, 187999.25, 536878.75, 188013.75, - 536878.75, 188054.25, 536878.75, 187987.75, 536878.75, 188014.75, 536878.75, 188121.25, - 536878.75, 187915.75, 536878.75, 188047.25, 536878.75, 187989.75, 536878.75, 188061.75, - 536878.75, 187926.75, 536878.75, 188074.25, 536878.75, 188008.75, 536878.75, 187926.25, - 536878.75, 188153.75, 536878.75, 188060.75, 536878.75, 187992.25, 536878.75, 188121.75, - 536878.75, 187966.25, 536878.75, 188024.75, 536878.75, 188059.25, 536878.75, 187916.25, - 536878.75, 187933.25, 536878.75, 187931.75, 536878.75, 187935.25, 536878.75, 188025.75, - 536878.75, 188033.25, 536878.75, 188012.25, 536878.75, 188114.75, 536878.75, 188137.75, - 536878.75, 187988.25, 536878.75, 188136.25, 536878.75, 188116.75, 536878.75, 188017.25, - 536878.75, 188150.75, 536878.75, 187934.75, 536878.75, 188060.25, 536878.75, 188053.75, - 536878.75, 188010.75, 536878.75, 187988.75, 536878.75, 188079.75, 536878.75, 188002.75, - 536878.75, 188152.25, 536878.75, 188156.25, 536878.75, 188138.25, 536878.75, 188004.25, - 536878.75, 188142.25, 536879.25, 188055.75, 536879.25, 187994.25, 536879.25, 188117.75, - 536879.25, 188138.25, 536879.25, 188009.75, 536879.25, 187972.25, 536879.25, 188017.25, - 536879.25, 188137.75, 536879.25, 188033.25, 536879.25, 187925.25, 536879.25, 187933.25, - 536879.25, 188127.75, 536879.25, 187928.75, 536879.25, 188140.25, 536879.25, 188008.25, - 536879.25, 187931.25, 536879.25, 188153.75, 536879.25, 188074.25, 536879.25, 188141.25, - 536879.25, 188120.75, 536879.25, 187920.75, 536879.25, 188014.75, 536879.25, 187915.75, - 536879.25, 187965.25, 536879.25, 188013.75, 536879.25, 188104.75, 536879.25, 188054.75, - 536879.25, 187967.75, 536879.25, 187955.75, 536879.25, 188132.25, 536879.25, 188105.75, - 536879.25, 187966.75, 536879.25, 188011.75, 536879.25, 188121.25, 536879.25, 188122.25, - 536879.25, 187997.25, 536879.25, 188031.75, 536879.25, 188023.25, 536879.25, 188060.75, - 536879.25, 188080.75, 536879.25, 187992.75, 536879.25, 188052.75, 536879.25, 188010.25, - 536879.25, 188023.75, 536879.25, 188026.25, 536879.25, 188120.25, 536879.25, 188149.75, - 536879.25, 188000.75, 536879.25, 188119.75, 536879.25, 188090.75, 536879.25, 188155.25, - 536879.25, 188037.75, 536879.25, 187926.75, 536879.25, 188121.75, 536879.25, 188022.25, - 536879.25, 188033.75, 536879.25, 188027.25, 536879.25, 187935.25, 536879.25, 188024.75, - 536879.25, 187990.25, 536879.25, 188012.25, 536879.25, 188059.25, 536879.25, 187934.25, - 536879.25, 188130.75, 536879.25, 188015.75, 536879.25, 188014.25, 536879.25, 188150.75, - 536879.25, 188060.25, 536879.25, 188010.75, 536879.25, 187988.75, 536879.25, 187930.25, - 536879.25, 187916.25, 536879.25, 187931.75, 536879.25, 187991.75, 536879.25, 188079.75, - 536879.25, 188156.25, 536879.75, 188016.75, 536879.75, 188063.25, 536879.75, 188024.25, - 536879.75, 187929.75, 536879.75, 188131.75, 536879.75, 188013.75, 536879.75, 188139.75, - 536879.75, 188126.25, 536879.75, 188138.25, 536879.75, 188160.25, 536879.75, 188003.75, - 536879.75, 188060.25, 536879.75, 188153.25, 536879.75, 187933.25, 536879.75, 187932.25, - 536879.75, 188113.75, 536879.75, 188049.25, 536879.75, 187916.75, 536879.75, 188098.75, - 536879.75, 188048.75, 536879.75, 188125.75, 536879.75, 188081.25, 536879.75, 188155.75, - 536879.75, 188137.75, 536879.75, 188118.25, 536879.75, 188026.25, 536879.75, 188030.25, - 536879.75, 188058.25, 536879.75, 188119.75, 536879.75, 188141.75, 536879.75, 187966.25, - 536879.75, 187998.75, 536879.75, 188022.25, 536879.75, 187965.75, 536879.75, 188032.75, - 536879.75, 187967.75, 536879.75, 187987.25, 536879.75, 188002.25, 536879.75, 187925.75, - 536879.75, 188010.75, 536879.75, 187967.25, 536879.75, 188023.25, 536879.75, 188102.25, - 536879.75, 188080.75, 536879.75, 187997.75, 536879.75, 188016.25, 536879.75, 188101.75, - 536879.75, 187968.75, 536879.75, 188033.25, 536879.75, 187910.75, 536879.75, 187989.25, - 536879.75, 188097.25, 536879.75, 188154.25, 536879.75, 188007.75, 536879.75, 187996.75, - 536879.75, 188117.75, 536879.75, 188028.75, 536879.75, 187991.75, 536879.75, 188012.25, - 536879.75, 187926.75, 536879.75, 188025.75, 536879.75, 188142.75, 536879.75, 188091.75, - 536879.75, 188009.25, 536879.75, 188065.75, 536879.75, 187928.75, 536879.75, 187926.25, - 536879.75, 188151.75, 536879.75, 188080.25, 536879.75, 187996.25, 536879.75, 188004.75, - 536879.75, 188010.25, 536879.75, 188022.75, 536879.75, 188132.25, 536879.75, 188156.25, - 536879.75, 188120.25, 536879.75, 188061.25, 536880.25, 187917.25, 536880.25, 188120.25, - 536880.25, 188103.25, 536880.25, 188104.25, 536880.25, 188125.25, 536880.25, 188032.25, - 536880.25, 188135.75, 536880.25, 188081.75, 536880.25, 187926.25, 536880.25, 188021.25, - 536880.25, 188022.75, 536880.25, 187930.25, 536880.25, 187965.25, 536880.25, 188111.75, - 536880.25, 188012.75, 536880.25, 188060.75, 536880.25, 187915.25, 536880.25, 187968.75, - 536880.25, 188028.75, 536880.25, 188110.75, 536880.25, 187960.75, 536880.25, 187929.25, - 536880.25, 188134.75, 536880.25, 188156.75, 536880.25, 188017.75, 536880.25, 188046.25, - 536880.25, 188047.25, 536880.25, 188121.75, 536880.25, 188101.75, 536880.25, 187936.25, - 536880.25, 188117.25, 536880.25, 187999.25, 536880.25, 188132.75, 536880.25, 187991.25, - 536880.25, 188119.25, 536880.25, 187968.25, 536880.25, 187963.75, 536880.25, 188154.75, - 536880.25, 187964.25, 536880.25, 188152.75, 536880.25, 187992.75, 536880.25, 188018.25, - 536880.25, 187964.75, 536880.25, 187999.75, 536880.25, 188100.25, 536880.25, 187926.75, - 536880.25, 188032.75, 536880.25, 188136.75, 536880.25, 188022.25, 536880.25, 187954.75, - 536880.25, 188110.25, 536880.25, 188127.75, 536880.25, 187990.75, 536880.25, 188153.75, - 536880.25, 188009.75, 536880.25, 188125.75, 536880.25, 188119.75, 536880.25, 187927.25, - 536880.25, 188155.75, 536880.25, 188081.25, 536880.25, 188061.75, 536880.25, 187935.75, - 536880.25, 188048.75, 536880.25, 188150.25, 536880.25, 188049.75, 536880.25, 188133.25, - 536880.25, 187988.25, 536880.25, 188008.75, 536880.25, 188139.25, 536880.25, 188026.75, - 536880.25, 188021.75, 536880.25, 188112.25, 536880.25, 188020.75, 536880.25, 188139.75, - 536880.25, 187945.25, 536880.25, 188126.25, 536880.25, 187998.25, 536880.25, 188157.25, - 536880.75, 188156.25, 536880.75, 187966.25, 536880.75, 188046.25, 536880.75, 188131.75, - 536880.75, 188033.25, 536880.75, 188129.25, 536880.75, 188112.75, 536880.75, 188060.75, - 536880.75, 188134.75, 536880.75, 188110.75, 536880.75, 187998.25, 536880.75, 188139.75, - 536880.75, 187968.75, 536880.75, 188016.75, 536880.75, 188111.75, 536880.75, 188025.75, - 536880.75, 188109.25, 536880.75, 187977.25, 536880.75, 188059.25, 536880.75, 188139.25, - 536880.75, 187945.75, 536880.75, 188022.75, 536880.75, 187926.25, 536880.75, 188015.25, - 536880.75, 188046.75, 536880.75, 188031.25, 536880.75, 188014.25, 536880.75, 187971.75, - 536880.75, 188125.25, 536880.75, 188135.75, 536880.75, 187917.25, 536880.75, 188000.25, - 536880.75, 187964.75, 536880.75, 188116.75, 536880.75, 188119.75, 536880.75, 188010.25, - 536880.75, 188056.25, 536880.75, 188117.25, 536880.75, 188153.75, 536880.75, 187927.25, - 536880.75, 188134.25, 536880.75, 187930.25, 536880.75, 187965.75, 536880.75, 188022.25, - 536880.75, 188013.25, 536880.75, 187993.25, 536880.75, 187954.75, 536880.75, 187996.75, - 536880.75, 187989.25, 536880.75, 187929.25, 536880.75, 187931.75, 536880.75, 187963.75, - 536880.75, 188155.75, 536880.75, 188021.25, 536880.75, 188009.25, 536880.75, 188119.25, - 536880.75, 188080.75, 536880.75, 187991.25, 536880.75, 187922.75, 536880.75, 187968.25, - 536880.75, 188154.75, 536880.75, 188152.75, 536880.75, 187964.25, 536880.75, 187987.25, - 536880.75, 188117.75, 536880.75, 188132.25, 536880.75, 187917.75, 536880.75, 187962.25, - 536880.75, 188032.25, 536880.75, 188017.25, 536880.75, 187965.25, 536880.75, 187999.25, - 536880.75, 187926.75, 536880.75, 188147.25, 536880.75, 188156.75, 536880.75, 187915.75, - 536880.75, 188021.75, 536880.75, 188112.25, 536880.75, 188120.25, 536880.75, 188020.75, - 536880.75, 188125.75, 536880.75, 188009.75, 536880.75, 188137.75, 536880.75, 187937.25, - 536880.75, 188157.25, 536880.75, 188028.25, 536880.75, 188004.25, 536880.75, 188048.25, - 536880.75, 188008.75, 536880.75, 188102.25, 536880.75, 187936.25, 536880.75, 188126.25, - 536881.25, 187936.25, 536881.25, 188144.25, 536881.25, 188112.75, 536881.25, 188131.75, - 536881.25, 188033.25, 536881.25, 188120.75, 536881.25, 187961.75, 536881.25, 187989.25, - 536881.25, 188012.25, 536881.25, 187968.75, 536881.25, 188155.25, 536881.25, 187946.75, - 536881.25, 188153.25, 536881.25, 188109.25, 536881.25, 188005.75, 536881.25, 188015.25, - 536881.25, 187913.25, 536881.25, 188034.75, 536881.25, 188014.25, 536881.25, 188036.75, - 536881.25, 187995.25, 536881.25, 188100.75, 536881.25, 188123.75, 536881.25, 187927.75, - 536881.25, 188127.25, 536881.25, 188115.75, 536881.25, 188150.75, 536881.25, 188048.25, - 536881.25, 188105.25, 536881.25, 188126.75, 536881.25, 188033.75, 536881.25, 188029.25, - 536881.25, 187963.25, 536881.25, 187986.25, 536881.25, 187916.75, 536881.25, 188020.25, - 536881.25, 188106.75, 536881.25, 188071.25, 536881.25, 187996.75, 536881.25, 188109.75, - 536881.25, 188015.75, 536881.25, 188132.75, 536881.25, 188133.75, 536881.25, 188118.25, - 536881.25, 188136.25, 536881.25, 187935.25, 536881.25, 188061.75, 536881.25, 188054.25, - 536881.25, 188141.25, 536881.25, 188081.25, 536881.25, 188070.25, 536881.25, 188080.75, - 536881.25, 188156.25, 536881.25, 187991.25, 536881.25, 187967.25, 536881.25, 188107.25, - 536881.25, 188045.25, 536881.25, 188043.75, 536881.25, 188118.75, 536881.25, 188081.75, - 536881.25, 188009.75, 536881.25, 188140.25, 536881.25, 188104.75, 536881.25, 188011.75, - 536881.25, 187911.75, 536881.25, 187997.25, 536881.25, 187990.75, 536881.25, 187932.75, - 536881.25, 188115.25, 536881.25, 188096.75, 536881.25, 188154.25, 536881.25, 187917.75, - 536881.25, 188061.25, 536881.25, 188032.75, 536881.25, 188047.75, 536881.25, 188018.75, - 536881.25, 188021.75, 536881.25, 188111.25, 536881.25, 188026.75, 536881.25, 188137.25, - 536881.25, 188138.75, 536881.25, 188110.25, 536881.75, 188070.75, 536881.75, 188112.75, - 536881.75, 188133.25, 536881.75, 188138.75, 536881.75, 187926.25, 536881.75, 188121.25, - 536881.75, 187919.75, 536881.75, 188034.25, 536881.75, 188013.75, 536881.75, 187920.75, - 536881.75, 188047.75, 536881.75, 188068.75, 536881.75, 188062.25, 536881.75, 187988.75, - 536881.75, 188136.75, 536881.75, 188032.75, 536881.75, 188124.75, 536881.75, 187928.25, - 536881.75, 187961.75, 536881.75, 188036.25, 536881.75, 188112.25, 536881.75, 188019.25, - 536881.75, 188138.25, 536881.75, 187964.25, 536881.75, 188120.25, 536881.75, 187917.75, - 536881.75, 188001.25, 536881.75, 188034.75, 536881.75, 188037.25, 536881.75, 188010.75, - 536881.75, 187999.75, 536881.75, 187990.25, 536881.75, 188103.75, 536881.75, 187962.75, - 536881.75, 188080.25, 536881.75, 188031.25, 536881.75, 188082.25, 536881.75, 188108.25, - 536881.75, 187911.75, 536881.75, 188035.25, 536881.75, 188018.25, 536881.75, 188000.75, - 536881.75, 187995.75, 536881.75, 188048.75, 536881.75, 188157.75, 536881.75, 188000.25, - 536881.75, 188008.75, 536881.75, 188107.25, 536881.75, 188118.75, 536881.75, 187917.25, - 536881.75, 188149.75, 536881.75, 188104.25, 536881.75, 188035.75, 536881.75, 188004.25, - 536881.75, 188115.75, 536881.75, 188089.25, 536881.75, 187969.25, 536881.75, 188070.25, - 536881.75, 187966.75, 536881.75, 187927.25, 536881.75, 188019.75, 536881.75, 188021.25, - 536881.75, 188141.25, 536881.75, 188126.75, 536881.75, 188012.75, 536881.75, 188014.75, - 536881.75, 188062.75, 536881.75, 188069.75, 536881.75, 188029.25, 536881.75, 188118.25, - 536881.75, 188011.25, 536881.75, 187960.25, 536881.75, 188136.25, 536881.75, 188071.75, - 536881.75, 188133.75, 536881.75, 188029.75, 536881.75, 188105.75, 536881.75, 188013.25, - 536881.75, 188109.75, 536881.75, 188026.25, 536881.75, 188016.25, 536881.75, 187996.75, - 536881.75, 188028.75, 536881.75, 188017.75, 536881.75, 188132.75, 536881.75, 187918.25, - 536881.75, 188027.25, 536881.75, 188020.25, 536881.75, 187991.75, 536882.25, 187991.75, - 536882.25, 188029.75, 536882.25, 188152.25, 536882.25, 188106.75, 536882.25, 188027.25, - 536882.25, 188020.25, 536882.25, 187963.25, 536882.25, 188014.75, 536882.25, 188026.25, - 536882.25, 188015.25, 536882.25, 188136.25, 536882.25, 187969.25, 536882.25, 188087.75, - 536882.25, 188061.75, 536882.25, 188117.75, 536882.25, 188118.25, 536882.25, 188012.75, - 536882.25, 188029.25, 536882.25, 188028.75, 536882.25, 188019.75, 536882.25, 188070.25, - 536882.25, 187951.75, 536882.25, 188085.25, 536882.25, 188010.25, 536882.25, 188071.75, - 536882.25, 188081.25, 536882.25, 188048.75, 536882.25, 188105.75, 536882.25, 188116.75, - 536882.25, 187937.25, 536882.25, 187917.25, 536882.25, 187918.25, 536882.25, 187987.75, - 536882.25, 188118.75, 536882.25, 188004.25, 536882.25, 188137.75, 536882.25, 187910.75, - 536882.25, 188135.75, 536882.25, 188018.25, 536882.25, 188055.75, 536882.25, 187936.25, - 536882.25, 187995.75, 536882.25, 187911.75, 536882.25, 188069.25, 536882.25, 188154.25, - 536882.25, 187966.75, 536882.25, 188108.25, 536882.25, 188031.25, 536882.25, 187989.75, - 536882.25, 188000.25, 536882.25, 188154.75, 536882.25, 187997.25, 536882.25, 188080.25, - 536882.25, 188085.75, 536882.25, 187999.75, 536882.25, 188046.75, 536882.25, 187990.75, - 536882.25, 188037.25, 536882.25, 188034.25, 536882.25, 188058.25, 536882.25, 188160.25, - 536882.25, 188139.25, 536882.25, 188120.25, 536882.25, 188010.75, 536882.25, 188016.75, - 536882.25, 188114.75, 536882.25, 188034.75, 536882.25, 188000.75, 536882.25, 188138.25, - 536882.25, 188111.75, 536882.25, 187917.75, 536882.25, 187968.75, 536882.25, 188036.25, - 536882.25, 187922.25, 536882.25, 188132.25, 536882.25, 187928.25, 536882.25, 188124.75, - 536882.25, 187962.25, 536882.25, 188138.75, 536882.25, 187931.25, 536882.25, 188110.75, - 536882.25, 188139.75, 536882.25, 188019.25, 536882.25, 187960.75, 536882.25, 187992.75, - 536882.25, 188040.25, 536882.25, 188068.75, 536882.25, 187943.25, 536882.25, 188060.75, - 536882.25, 187967.25, 536882.25, 188131.75, 536882.25, 188137.25, 536882.25, 188020.75, - 536882.25, 187961.25, 536882.25, 188046.25, 536882.25, 187926.75, 536882.25, 188133.25, - 536882.25, 188102.25, 536882.25, 188112.75, 536882.25, 188104.25, 536882.75, 187999.25, - 536882.75, 187935.75, 536882.75, 188084.75, 536882.75, 188102.25, 536882.75, 188112.75, - 536882.75, 187996.25, 536882.75, 188030.75, 536882.75, 188121.25, 536882.75, 187927.25, - 536882.75, 188101.75, 536882.75, 187930.75, 536882.75, 188014.75, 536882.75, 188019.75, - 536882.75, 188133.75, 536882.75, 188121.75, 536882.75, 188033.25, 536882.75, 187961.75, - 536882.75, 188131.75, 536882.75, 187914.75, 536882.75, 188068.75, 536882.75, 188103.75, - 536882.75, 188062.75, 536882.75, 188037.25, 536882.75, 188013.25, 536882.75, 188138.25, - 536882.75, 187935.25, 536882.75, 188130.25, 536882.75, 188012.25, 536882.75, 187960.25, - 536882.75, 187928.25, 536882.75, 188002.75, 536882.75, 188120.75, 536882.75, 187967.75, - 536882.75, 188013.75, 536882.75, 188010.75, 536882.75, 188015.75, 536882.75, 188035.25, - 536882.75, 187959.25, 536882.75, 188083.75, 536882.75, 187959.75, 536882.75, 188037.75, - 536882.75, 188135.25, 536882.75, 188058.75, 536882.75, 188031.75, 536882.75, 188016.75, - 536882.75, 188094.75, 536882.75, 188085.25, 536882.75, 188062.25, 536882.75, 188017.25, - 536882.75, 188029.75, 536882.75, 188085.75, 536882.75, 187940.25, 536882.75, 188047.75, - 536882.75, 188027.25, 536882.75, 187933.25, 536882.75, 188156.75, 536882.75, 188003.25, - 536882.75, 187969.75, 536882.75, 187918.25, 536882.75, 188133.25, 536882.75, 188071.25, - 536882.75, 188018.75, 536882.75, 188069.25, 536882.75, 188024.75, 536882.75, 188026.75, - 536882.75, 187936.75, 536882.75, 188112.25, 536882.75, 188141.75, 536882.75, 188142.75, - 536882.75, 188107.25, 536882.75, 187998.25, 536882.75, 187911.75, 536882.75, 188009.75, - 536882.75, 188131.25, 536882.75, 188007.25, 536882.75, 188137.75, 536882.75, 187967.25, - 536882.75, 188157.75, 536882.75, 187937.25, 536882.75, 188004.75, 536882.75, 188081.25, - 536882.75, 188067.25, 536882.75, 188105.25, 536883.25, 188123.75, 536883.25, 188067.25, - 536883.25, 188103.25, 536883.25, 187918.75, 536883.25, 188157.75, 536883.25, 188038.25, - 536883.25, 188010.25, 536883.25, 188063.25, 536883.25, 188143.25, 536883.25, 188086.75, - 536883.25, 187927.75, 536883.25, 187919.25, 536883.25, 188130.75, 536883.25, 188141.25, - 536883.25, 188055.75, 536883.25, 188004.75, 536883.25, 187970.25, 536883.25, 188007.25, - 536883.25, 188144.75, 536883.25, 187929.75, 536883.25, 188056.25, 536883.25, 188018.25, - 536883.25, 188134.25, 536883.25, 188011.25, 536883.25, 188135.75, 536883.25, 188142.75, - 536883.25, 188112.25, 536883.25, 188061.75, 536883.25, 188027.75, 536883.25, 188119.75, - 536883.25, 187912.25, 536883.25, 187936.75, 536883.25, 188081.75, 536883.25, 187966.75, - 536883.25, 187957.25, 536883.25, 188129.75, 536883.25, 188157.25, 536883.25, 188011.75, - 536883.25, 188052.25, 536883.25, 188001.75, 536883.25, 188002.25, 536883.25, 187939.75, - 536883.25, 188083.25, 536883.25, 188003.25, 536883.25, 188132.75, 536883.25, 188028.25, - 536883.25, 188066.75, 536883.25, 188009.25, 536883.25, 188068.25, 536883.25, 187998.75, - 536883.25, 188031.75, 536883.25, 187938.25, 536883.25, 188143.75, 536883.25, 188026.75, - 536883.25, 187959.75, 536883.25, 187937.75, 536883.25, 188032.25, 536883.25, 188015.75, - 536883.25, 188004.25, 536883.25, 187995.25, 536883.25, 187959.25, 536883.25, 187996.75, - 536883.25, 187990.25, 536883.25, 187968.75, 536883.25, 188142.25, 536883.25, 188056.75, - 536883.25, 188113.25, 536883.25, 187958.75, 536883.25, 187952.75, 536883.25, 188159.75, - 536883.25, 187928.75, 536883.25, 188012.25, 536883.25, 188067.75, 536883.25, 187968.25, - 536883.25, 188100.25, 536883.25, 188084.25, 536883.25, 188104.75, 536883.25, 188016.25, - 536883.25, 188151.25, 536883.25, 187997.25, 536883.25, 188134.75, 536883.25, 188002.75, - 536883.25, 188037.25, 536883.25, 188028.75, 536883.25, 188155.75, 536883.25, 187911.25, - 536883.25, 188080.75, 536883.25, 188035.25, 536883.25, 188121.75, 536883.25, 187997.75, - 536883.25, 188133.75, 536883.25, 188072.75, 536883.25, 188101.75, 536883.25, 188156.25, - 536883.25, 188014.75, 536883.25, 187944.25, 536883.25, 188017.75, 536883.25, 187912.75, - 536883.25, 188005.25, 536883.25, 188072.25, 536883.75, 187911.25, 536883.75, 188035.75, - 536883.75, 188002.75, 536883.75, 188032.75, 536883.75, 188086.75, 536883.75, 188071.75, - 536883.75, 188055.25, 536883.75, 188014.75, 536883.75, 188080.75, 536883.75, 188017.75, - 536883.75, 188028.75, 536883.75, 188112.75, 536883.75, 188035.25, 536883.75, 187959.25, - 536883.75, 188118.25, 536883.75, 188084.25, 536883.75, 187960.25, 536883.75, 188129.25, - 536883.75, 187997.75, 536883.75, 188155.75, 536883.75, 187928.75, 536883.75, 188062.75, - 536883.75, 188033.25, 536883.75, 188140.75, 536883.75, 188131.75, 536883.75, 188057.25, - 536883.75, 187917.75, 536883.75, 188016.25, 536883.75, 188056.75, 536883.75, 187969.25, - 536883.75, 187968.25, 536883.75, 187990.25, 536883.75, 187921.25, 536883.75, 188007.25, - 536883.75, 187918.25, 536883.75, 187932.75, 536883.75, 188156.25, 536883.75, 188142.25, - 536883.75, 188038.25, 536883.75, 188013.25, 536883.75, 188004.25, 536883.75, 188104.75, - 536883.75, 187996.75, 536883.75, 187937.75, 536883.75, 187958.25, 536883.75, 188032.25, - 536883.75, 187956.75, 536883.75, 188026.75, 536883.75, 188120.75, 536883.75, 188013.75, - 536883.75, 188068.25, 536883.75, 188009.25, 536883.75, 187961.25, 536883.75, 187924.75, - 536883.75, 187998.75, 536883.75, 188017.25, 536883.75, 188085.25, 536883.75, 187956.25, - 536883.75, 188083.75, 536883.75, 187949.25, 536883.75, 188065.75, 536883.75, 188104.25, - 536883.75, 188083.25, 536883.75, 188003.25, 536883.75, 188001.75, 536883.75, 188048.75, - 536883.75, 187913.25, 536883.75, 188069.75, 536883.75, 188031.25, 536883.75, 188008.25, - 536883.75, 188001.25, 536883.75, 188109.75, 536883.75, 188011.75, 536883.75, 187918.75, - 536883.75, 188012.75, 536883.75, 188134.25, 536883.75, 188034.75, 536883.75, 188029.25, - 536883.75, 188134.75, 536883.75, 188028.25, 536883.75, 188027.75, 536883.75, 188141.25, - 536883.75, 188132.25, 536883.75, 188156.75, 536883.75, 188141.75, 536883.75, 188142.75, - 536883.75, 188112.25, 536883.75, 188061.75, 536883.75, 188056.25, 536883.75, 188082.25, - 536883.75, 188118.75, 536883.75, 188123.75, 536883.75, 188004.75, 536883.75, 188105.25, - 536883.75, 188055.75, 536883.75, 188018.25, 536883.75, 187967.25, 536883.75, 188072.25, - 536883.75, 188128.75, 536883.75, 188157.75, 536883.75, 188067.25, 536883.75, 187919.25, - 536883.75, 188151.75, 536883.75, 188143.25, 536883.75, 187927.75, 536883.75, 188103.25, - 536883.75, 188061.25, 536883.75, 188010.25, 536883.75, 188011.25, 536884.25, 188159.25, - 536884.25, 188081.25, 536884.25, 187970.25, 536884.25, 187911.75, 536884.25, 188011.25, - 536884.25, 188073.75, 536884.25, 188009.75, 536884.25, 188130.75, 536884.25, 188018.25, - 536884.25, 188055.75, 536884.25, 188072.25, 536884.25, 188004.75, 536884.25, 188081.75, - 536884.25, 188061.75, 536884.25, 187937.25, 536884.25, 188005.75, 536884.25, 188132.25, - 536884.25, 188012.75, 536884.25, 188141.25, 536884.25, 187929.75, 536884.25, 188001.25, - 536884.25, 188086.25, 536884.25, 187936.75, 536884.25, 188014.25, 536884.25, 187918.75, - 536884.25, 188145.75, 536884.25, 188133.25, 536884.25, 188008.25, 536884.25, 188000.25, - 536884.25, 187913.25, 536884.25, 188140.25, 536884.25, 188066.75, 536884.25, 188113.75, - 536884.25, 188027.25, 536884.25, 188082.75, 536884.25, 188048.75, 536884.25, 188001.75, - 536884.25, 188049.75, 536884.25, 188111.75, 536884.25, 188016.75, 536884.25, 188047.75, - 536884.25, 187956.25, 536884.25, 187937.75, 536884.25, 188143.75, 536884.25, 187989.25, - 536884.25, 188030.25, 536884.25, 188129.75, 536884.25, 188004.25, 536884.25, 187958.25, - 536884.25, 188156.25, 536884.25, 188026.25, 536884.25, 187957.25, 536884.25, 188135.25, - 536884.25, 188060.25, 536884.25, 188130.25, 536884.25, 187935.25, 536884.25, 187969.25, - 536884.25, 187928.25, 536884.25, 188016.25, 536884.25, 188038.25, 536884.25, 187938.75, - 536884.25, 188053.75, 536884.25, 188057.25, 536884.25, 187997.75, 536884.25, 188099.75, - 536884.25, 188155.75, 536884.25, 188059.75, 536884.25, 188028.75, 536884.25, 188091.25, - 536884.25, 188112.75, 536884.25, 188054.75, 536884.25, 187960.25, 536884.25, 188037.25, - 536884.25, 187957.75, 536884.25, 188128.25, 536884.25, 188133.75, 536884.25, 188035.25, - 536884.25, 188121.25, 536884.25, 188121.75, 536884.25, 187919.75, 536884.25, 187935.75, - 536884.25, 188055.25, 536884.25, 188071.75, 536884.75, 187988.25, 536884.75, 187912.75, - 536884.75, 188102.25, 536884.75, 188140.75, 536884.75, 187961.75, 536884.75, 188057.75, - 536884.75, 188000.75, 536884.75, 188153.25, 536884.75, 188027.25, 536884.75, 187910.75, - 536884.75, 188120.25, 536884.75, 188082.75, 536884.75, 188113.75, 536884.75, 188132.75, - 536884.75, 188006.25, 536884.75, 187912.25, 536884.75, 188073.25, 536884.75, 188067.25, - 536884.75, 188009.75, 536884.75, 188081.25, 536884.75, 187919.25, 536884.75, 188130.75, - 536884.75, 187990.75, 536884.75, 188112.25, 536884.75, 188127.75, 536884.75, 187955.25, - 536884.75, 187936.75, 536884.75, 188132.25, 536884.75, 188070.75, 536884.75, 188051.25, - 536884.75, 187967.75, 536884.75, 188063.75, 536884.75, 187998.75, 536884.75, 187931.75, - 536884.75, 188040.25, 536884.75, 188099.75, 536884.75, 187956.75, 536884.75, 188026.75, - 536884.75, 187958.25, 536884.75, 188067.75, 536884.75, 188057.25, 536884.75, 188103.75, - 536884.75, 188098.75, 536884.75, 187991.25, 536884.75, 188005.25, 536884.75, 188107.25, - 536884.75, 188133.75, 536884.75, 188070.25, 536884.75, 188054.25, 536884.75, 188059.75, - 536884.75, 187929.25, 536884.75, 188038.25, 536884.75, 188012.25, 536884.75, 187918.25, - 536884.75, 188113.25, 536884.75, 188130.25, 536884.75, 187948.75, 536884.75, 188015.75, - 536884.75, 187956.25, 536884.75, 187991.75, 536884.75, 188148.75, 536884.75, 188015.25, - 536884.75, 188033.75, 536884.75, 188001.25, 536884.75, 188134.25, 536884.75, 188005.75, - 536884.75, 187976.75, 536884.75, 188086.25, 536884.75, 188114.25, 536884.75, 188029.25, - 536884.75, 187930.25, 536884.75, 188082.25, 536884.75, 188160.25, 536884.75, 188058.25, - 536884.75, 188115.75, 536884.75, 188144.75, 536884.75, 188010.25, 536884.75, 188150.75, - 536884.75, 188119.75, 536884.75, 188143.25, 536884.75, 187998.25, 536884.75, 188100.75, - 536884.75, 188105.25, 536884.75, 188014.25, 536884.75, 187913.25, 536884.75, 187962.75, - 536884.75, 188079.75, 536884.75, 188092.75, 536884.75, 188000.25, 536884.75, 188001.75, - 536884.75, 188059.25, 536884.75, 188131.75, 536884.75, 188038.75, 536884.75, 188010.75, - 536884.75, 187922.25, 536884.75, 188087.25, 536884.75, 188056.75, 536884.75, 188116.25, - 536884.75, 188053.75, 536884.75, 188122.25, 536884.75, 188060.75, 536884.75, 188112.75, - 536884.75, 187928.75, 536884.75, 188126.25, 536884.75, 188129.25, 536884.75, 188072.75, - 536884.75, 188046.25, 536884.75, 187999.25, 536884.75, 188144.25, 536884.75, 188016.75, - 536885.25, 187928.75, 536885.25, 188126.25, 536885.25, 187954.75, 536885.25, 188001.25, - 536885.25, 188144.75, 536885.25, 188026.25, 536885.25, 188133.75, 536885.25, 187922.75, - 536885.25, 188092.25, 536885.25, 188057.25, 536885.25, 188067.75, 536885.25, 188010.75, - 536885.25, 188119.75, 536885.25, 188112.75, 536885.25, 188133.25, 536885.25, 188112.25, - 536885.25, 188067.25, 536885.25, 188132.75, 536885.25, 188121.25, 536885.25, 187957.75, - 536885.25, 187957.25, 536885.25, 188053.75, 536885.25, 188057.75, 536885.25, 188030.75, - 536885.25, 188066.75, 536885.25, 188016.75, 536885.25, 188072.75, 536885.25, 188105.25, - 536885.25, 188032.25, 536885.25, 188132.25, 536885.25, 188158.75, 536885.25, 188052.25, - 536885.25, 188148.25, 536885.25, 188000.25, 536885.25, 188131.75, 536885.25, 188115.75, - 536885.25, 188086.25, 536885.25, 187991.75, 536885.25, 188106.75, 536885.25, 188015.75, - 536885.25, 187962.25, 536885.25, 187960.25, 536885.25, 188027.25, 536885.25, 187999.75, - 536885.25, 188054.25, 536885.25, 187955.25, 536885.25, 188087.25, 536885.25, 188070.25, - 536885.25, 188081.75, 536885.25, 187991.25, 536885.25, 188115.25, 536885.25, 187933.25, - 536885.25, 188058.75, 536885.25, 187935.25, 536885.25, 187956.75, 536885.25, 187969.25, - 536885.25, 188103.75, 536885.25, 188108.25, 536885.25, 187919.75, 536885.25, 187912.75, - 536885.25, 188079.25, 536885.25, 188005.25, 536885.25, 187958.25, 536885.25, 187918.75, - 536885.25, 188141.75, 536885.25, 187990.75, 536885.25, 188016.25, 536885.25, 188009.75, - 536885.25, 188059.25, 536885.25, 188151.25, 536885.25, 188159.25, 536885.25, 188033.25, - 536885.25, 188060.25, 536885.25, 188071.25, 536885.25, 188113.75, 536885.25, 188038.75, - 536885.25, 188080.25, 536885.25, 187913.25, 536885.25, 188014.25, 536885.25, 188027.75, - 536885.25, 188048.25, 536885.25, 188128.75, 536885.25, 188063.25, 536885.25, 188012.75, - 536885.25, 187990.25, 536885.25, 188140.75, 536885.25, 187930.25, 536885.25, 187996.75, - 536885.25, 187988.25, 536885.25, 188059.75, 536885.25, 187989.25, 536885.25, 188072.25, - 536885.25, 188121.75, 536885.25, 188080.75, 536885.25, 188047.75, 536885.25, 187998.75, - 536885.25, 187936.75, 536885.25, 188125.75, 536885.25, 188081.25, 536885.25, 187912.25, - 536885.75, 188052.75, 536885.75, 188114.25, 536885.75, 188102.25, 536885.75, 187918.75, - 536885.75, 188098.75, 536885.75, 187956.75, 536885.75, 188112.25, 536885.75, 188120.75, - 536885.75, 187990.75, 536885.75, 188026.75, 536885.75, 187937.25, 536885.75, 188067.25, - 536885.75, 187982.25, 536885.75, 187955.25, 536885.75, 188038.25, 536885.75, 187919.25, - 536885.75, 188067.75, 536885.75, 187911.75, 536885.75, 187986.75, 536885.75, 188079.75, - 536885.75, 188125.75, 536885.75, 188104.75, 536885.75, 188087.75, 536885.75, 188059.25, - 536885.75, 188127.75, 536885.75, 188053.75, 536885.75, 188078.75, 536885.75, 188015.25, - 536885.75, 188034.25, 536885.75, 188116.75, 536885.75, 188014.75, 536885.75, 188159.25, - 536885.75, 188129.25, 536885.75, 188113.25, 536885.75, 188010.75, 536885.75, 188047.75, - 536885.75, 188127.25, 536885.75, 188131.25, 536885.75, 188046.25, 536885.75, 187916.25, - 536885.75, 188153.25, 536885.75, 188144.75, 536885.75, 188008.75, 536885.75, 188102.75, - 536885.75, 188073.75, 536885.75, 187998.25, 536885.75, 187961.75, 536885.75, 188123.25, - 536885.75, 188141.25, 536885.75, 188126.75, 536885.75, 188121.75, 536885.75, 187999.25, - 536885.75, 187986.25, 536885.75, 188037.75, 536885.75, 188005.75, 536885.75, 188006.25, - 536885.75, 188143.75, 536885.75, 188058.25, 536885.75, 187954.75, 536885.75, 188101.25, - 536885.75, 188072.75, 536885.75, 188053.25, 536885.75, 187980.25, 536885.75, 188156.25, - 536885.75, 188105.25, 536885.75, 188027.75, 536885.75, 187914.25, 536885.75, 188132.25, - 536885.75, 188013.75, 536885.75, 188086.75, 536885.75, 188034.75, 536885.75, 188052.25, - 536885.75, 188010.25, 536885.75, 188012.75, 536885.75, 187963.25, 536885.75, 188036.75, - 536885.75, 187980.75, 536885.75, 188048.25, 536885.75, 188117.25, 536885.75, 188099.75, - 536886.25, 187946.75, 536886.25, 188049.75, 536886.25, 188117.25, 536886.25, 188050.25, - 536886.25, 187992.25, 536886.25, 188048.25, 536886.25, 187980.75, 536886.25, 187987.75, - 536886.25, 188109.25, 536886.25, 187931.75, 536886.25, 188068.75, 536886.25, 188104.25, - 536886.25, 188031.75, 536886.25, 188132.25, 536886.25, 187988.75, 536886.25, 188012.75, - 536886.25, 187961.25, 536886.25, 188029.25, 536886.25, 188068.25, 536886.25, 188122.75, - 536886.25, 187955.75, 536886.25, 188048.75, 536886.25, 188039.25, 536886.25, 188147.75, - 536886.25, 187981.25, 536886.25, 187980.25, 536886.25, 188014.25, 536886.25, 188142.75, - 536886.25, 188122.25, 536886.25, 188051.75, 536886.25, 188006.75, 536886.25, 188143.75, - 536886.25, 188030.75, 536886.25, 188005.75, 536886.25, 188152.75, 536886.25, 188029.75, - 536886.25, 187954.75, 536886.25, 187982.75, 536886.25, 187953.25, 536886.25, 187997.25, - 536886.25, 188038.75, 536886.25, 187963.75, 536886.25, 188028.75, 536886.25, 188071.75, - 536886.25, 188015.25, 536886.25, 188057.75, 536886.25, 188113.25, 536886.25, 187936.75, - 536886.25, 188158.25, 536886.25, 188073.25, 536886.25, 188046.25, 536886.25, 188007.25, - 536886.25, 188047.75, 536886.25, 187938.75, 536886.25, 188131.25, 536886.25, 188030.25, - 536886.25, 188123.25, 536886.25, 187930.75, 536886.25, 187981.75, 536886.25, 187998.75, - 536886.25, 188044.75, 536886.25, 188075.75, 536886.25, 187929.25, 536886.25, 187953.75, - 536886.25, 187989.75, 536886.25, 188011.75, 536886.25, 188100.25, 536886.25, 187985.25, - 536886.25, 187920.75, 536886.25, 188013.25, 536886.25, 188105.75, 536886.25, 188078.75, - 536886.25, 187993.25, 536886.25, 187997.75, 536886.25, 188144.25, 536886.25, 188125.75, - 536886.25, 187986.75, 536886.25, 188129.75, 536886.25, 188146.75, 536886.25, 188079.75, - 536886.25, 188043.25, 536886.25, 187962.75, 536886.25, 188157.25, 536886.25, 188067.75, - 536886.25, 187929.75, 536886.25, 188126.25, 536886.25, 188116.75, 536886.25, 188120.25, - 536886.25, 188074.75, 536886.25, 188100.75, 536886.25, 188051.25, 536886.25, 187937.25, - 536886.25, 187939.75, 536886.25, 187954.25, 536886.25, 188011.25, 536886.25, 188020.75, - 536886.25, 188141.75, 536886.25, 188124.75, 536886.25, 188023.25, 536886.25, 188058.75, - 536886.25, 187940.25, 536886.25, 188064.75, 536886.25, 187914.75, 536886.25, 188045.75, - 536886.25, 188150.25, 536886.25, 188109.75, 536886.25, 188088.25, 536886.25, 187956.75, - 536886.25, 187995.75, 536886.25, 187920.25, 536886.25, 188064.25, 536886.25, 188114.25, - 536886.25, 188052.75, 536886.25, 188079.25, 536886.25, 188035.75, 536886.25, 188028.25, - 536886.25, 188102.25, 536886.25, 188012.25, 536886.25, 188130.25, 536886.25, 187978.25, - 536886.75, 187912.75, 536886.75, 188114.25, 536886.75, 188011.25, 536886.75, 187937.25, - 536886.75, 187940.25, 536886.75, 187952.25, 536886.75, 188012.25, 536886.75, 188102.25, - 536886.75, 187982.25, 536886.75, 188038.25, 536886.75, 188150.75, 536886.75, 188028.75, - 536886.75, 188079.25, 536886.75, 187929.75, 536886.75, 188146.25, 536886.75, 188098.75, - 536886.75, 188088.75, 536886.75, 187920.75, 536886.75, 188144.25, 536886.75, 188073.25, - 536886.75, 187981.75, 536886.75, 188123.25, 536886.75, 188047.75, 536886.75, 188057.75, - 536886.75, 188154.75, 536886.75, 187997.25, 536886.75, 187919.75, 536886.75, 188014.75, - 536886.75, 187954.75, 536886.75, 188030.75, 536886.75, 188015.25, 536886.75, 187998.25, - 536886.75, 187955.75, 536886.75, 188045.75, 536886.75, 188006.25, 536886.75, 187914.75, - 536886.75, 188143.75, 536886.75, 188036.75, 536886.75, 188039.25, 536886.75, 188069.25, - 536886.75, 188032.25, 536886.75, 188030.25, 536886.75, 188068.25, 536886.75, 188104.25, - 536886.75, 188099.75, 536886.75, 187992.25, 536886.75, 188038.75, 536886.75, 188126.25, - 536886.75, 188117.25, 536886.75, 188124.75, 536886.75, 188020.75, 536886.75, 188050.25, - 536886.75, 187954.25, 536886.75, 187985.75, 536886.75, 187980.75, 536886.75, 188026.75, - 536886.75, 188029.75, 536886.75, 187939.75, 536886.75, 188109.25, 536886.75, 188148.25, - 536886.75, 187953.75, 536886.75, 188052.25, 536886.75, 188051.25, 536886.75, 188100.75, - 536886.75, 188116.75, 536886.75, 188013.25, 536886.75, 188120.25, 536886.75, 188013.75, - 536886.75, 188157.75, 536886.75, 188087.25, 536886.75, 188029.25, 536886.75, 188125.25, - 536886.75, 188012.75, 536886.75, 187951.75, 536886.75, 187913.75, 536886.75, 188048.75, - 536886.75, 188027.75, 536886.75, 188122.75, 536886.75, 188006.75, 536886.75, 187962.75, - 536886.75, 188079.75, 536886.75, 188129.75, 536886.75, 187986.75, 536886.75, 188090.25, - 536886.75, 188067.75, 536886.75, 188105.75, 536886.75, 188014.25, 536886.75, 187980.25, - 536886.75, 187989.25, 536886.75, 188078.75, 536886.75, 188101.25, 536886.75, 188051.75, - 536886.75, 188142.75, 536886.75, 187961.25, 536886.75, 187963.75, 536886.75, 188005.75, - 536886.75, 188100.25, 536886.75, 187929.25, 536886.75, 187930.25, 536886.75, 188011.75, - 536886.75, 188141.25, 536886.75, 187953.25, 536886.75, 188113.75, 536886.75, 187936.25, - 536886.75, 188071.25, 536886.75, 188159.25, 536886.75, 187938.75, 536886.75, 188110.75, - 536886.75, 187995.25, 536886.75, 187997.75, 536886.75, 188044.75, 536886.75, 188046.25, - 536886.75, 187996.25, 536886.75, 187930.75, 536887.25, 188160.25, 536887.25, 187991.75, - 536887.25, 188028.25, 536887.25, 187996.25, 536887.25, 187915.75, 536887.25, 188114.25, - 536887.25, 188007.75, 536887.25, 188113.25, 536887.25, 188061.75, 536887.25, 188109.75, - 536887.25, 187958.25, 536887.25, 187952.25, 536887.25, 187936.25, 536887.25, 188113.75, - 536887.25, 187939.25, 536887.25, 187922.25, 536887.25, 188041.75, 536887.25, 187983.25, - 536887.25, 188148.75, 536887.25, 188011.75, 536887.25, 187930.25, 536887.25, 187988.75, - 536887.25, 188157.25, 536887.25, 187962.25, 536887.25, 188079.25, 536887.25, 188125.75, - 536887.25, 187920.75, 536887.25, 188116.25, 536887.25, 188093.75, 536887.25, 187957.75, - 536887.25, 187920.25, 536887.25, 188034.25, 536887.25, 187983.75, 536887.25, 187929.25, - 536887.25, 188104.75, 536887.25, 188028.75, 536887.25, 188129.75, 536887.25, 188123.75, - 536887.25, 188122.75, 536887.25, 187937.75, 536887.25, 187986.75, 536887.25, 187989.75, - 536887.25, 188130.75, 536887.25, 188049.25, 536887.25, 188121.25, 536887.25, 187962.75, - 536887.25, 188072.25, 536887.25, 187952.75, 536887.25, 187914.25, 536887.25, 187930.75, - 536887.25, 188070.75, 536887.25, 188044.25, 536887.25, 188109.25, 536887.25, 187995.75, - 536887.25, 188071.75, 536887.25, 188010.25, 536887.25, 188035.25, 536887.25, 188013.25, - 536887.25, 188051.25, 536887.25, 188121.75, 536887.25, 188013.75, 536887.25, 188060.75, - 536887.25, 187939.75, 536887.25, 188045.75, 536887.25, 187919.75, 536887.25, 188143.25, - 536887.25, 188030.75, 536887.25, 188049.75, 536887.25, 187938.25, 536887.25, 187910.75, - 536887.25, 187925.25, 536887.25, 188029.75, 536887.25, 188107.25, 536887.25, 188142.25, - 536887.25, 187994.25, 536887.25, 187997.25, 536887.25, 187991.25, 536887.25, 188006.25, - 536887.25, 188030.25, 536887.25, 188068.75, 536887.25, 188069.25, 536887.25, 188086.75, - 536887.25, 187914.75, 536887.25, 188048.25, 536887.25, 188105.25, 536887.25, 187988.25, - 536887.25, 187992.75, 536887.75, 187912.75, 536887.75, 188043.75, 536887.75, 188031.75, - 536887.75, 187915.75, 536887.75, 187931.75, 536887.75, 188062.75, 536887.75, 188114.75, - 536887.75, 188109.25, 536887.75, 187956.25, 536887.75, 188124.25, 536887.75, 188080.75, - 536887.75, 187976.25, 536887.75, 188042.75, 536887.75, 188088.75, 536887.75, 188064.75, - 536887.75, 187990.25, 536887.75, 188039.25, 536887.75, 188068.75, 536887.75, 187949.75, - 536887.75, 187947.75, 536887.75, 188088.25, 536887.75, 187935.75, 536887.75, 187994.25, - 536887.75, 188076.75, 536887.75, 188038.75, 536887.75, 187992.25, 536887.75, 187990.75, - 536887.75, 188037.25, 536887.75, 188116.75, 536887.75, 187992.75, 536887.75, 188041.25, - 536887.75, 187950.75, 536887.75, 187987.75, 536887.75, 188070.25, 536887.75, 188049.75, - 536887.75, 187940.75, 536887.75, 187936.75, 536887.75, 187995.75, 536887.75, 187958.75, - 536887.75, 188031.25, 536887.75, 188109.75, 536887.75, 187930.75, 536887.75, 188007.25, - 536887.75, 187962.75, 536887.75, 187941.75, 536887.75, 187913.75, 536887.75, 188064.25, - 536887.75, 188126.25, 536887.75, 187960.75, 536887.75, 188130.75, 536887.75, 188007.75, - 536887.75, 188049.25, 536887.75, 188129.75, 536887.75, 187939.25, 536887.75, 188127.75, - 536887.75, 187920.25, 536887.75, 188069.75, 536887.75, 188129.25, 536887.75, 188132.75, - 536887.75, 188045.25, 536887.75, 187921.25, 536887.75, 188087.75, 536887.75, 187962.25, - 536887.75, 188070.75, 536887.75, 187993.25, 536887.75, 188043.25, 536887.75, 188113.75, - 536887.75, 188080.25, 536887.75, 188036.25, 536887.75, 188117.75, 536887.75, 188065.75, - 536887.75, 188122.75, 536887.75, 188120.75, 536887.75, 188025.25, 536887.75, 188130.25, - 536887.75, 188119.75, 536887.75, 187951.25, 536887.75, 188131.25, 536887.75, 187986.25, - 536888.25, 187992.75, 536888.25, 188043.25, 536888.25, 188087.75, 536888.25, 187929.75, - 536888.25, 187940.25, 536888.25, 187920.75, 536888.25, 188132.75, 536888.25, 188072.75, - 536888.25, 187957.25, 536888.25, 188135.25, 536888.25, 187994.25, 536888.25, 188122.25, - 536888.25, 188036.75, 536888.25, 188043.75, 536888.25, 188104.25, 536888.25, 188099.75, - 536888.25, 188117.25, 536888.25, 187950.75, 536888.25, 188068.75, 536888.25, 188148.25, - 536888.25, 188044.25, 536888.25, 187914.25, 536888.25, 188007.75, 536888.25, 188123.75, - 536888.25, 188038.75, 536888.25, 188069.75, 536888.25, 187986.25, 536888.25, 188126.75, - 536888.25, 187927.75, 536888.25, 188113.25, 536888.25, 188117.75, 536888.25, 188065.75, - 536888.25, 188122.75, 536888.25, 188131.25, 536888.25, 187951.25, 536888.25, 187938.75, - 536888.25, 187960.25, 536888.25, 187986.75, 536888.25, 188149.75, 536888.25, 188130.75, - 536888.25, 187913.75, 536888.25, 188070.25, 536888.25, 188006.75, 536888.25, 187939.75, - 536888.25, 188037.25, 536888.25, 187950.25, 536888.25, 187912.75, 536888.25, 188124.25, - 536888.25, 188064.75, 536888.25, 188150.25, 536888.25, 187991.25, 536888.25, 188092.25, - 536888.25, 187995.75, 536888.25, 188102.75, 536888.25, 187920.25, 536888.25, 188142.25, - 536888.25, 187915.75, 536888.25, 188120.75, 536888.25, 188035.75, 536888.25, 187952.25, - 536888.25, 187931.25, 536888.25, 187949.75, 536888.25, 188042.75, 536888.25, 188088.75, - 536888.25, 188116.75, 536888.25, 187990.75, 536888.25, 188133.75, 536888.25, 188100.75, - 536888.25, 188079.75, 536888.25, 188105.75, 536888.25, 188129.75, 536888.25, 188060.75, - 536888.25, 187930.25, 536888.25, 188129.25, 536888.25, 188033.25, 536888.25, 188153.25, - 536888.25, 187913.25, 536888.25, 187939.25, 536888.25, 187987.75, 536888.25, 188109.75, - 536888.25, 188063.25, 536888.25, 188157.75, 536888.25, 187938.25, 536888.25, 187930.75, - 536888.25, 188029.75, 536888.25, 187956.25, 536888.25, 188059.75, 536888.25, 188031.75, - 536888.25, 188048.25, 536888.25, 188030.25, 536888.25, 187975.75, 536888.25, 187993.25, - 536888.25, 188039.25, 536888.25, 188152.75, 536888.25, 187936.75, 536888.25, 187989.75, - 536888.25, 187988.75, 536888.25, 188127.75, 536888.25, 188114.25, 536888.25, 187935.25, - 536888.75, 188043.75, 536888.75, 188150.25, 536888.75, 188049.25, 536888.75, 188038.75, - 536888.75, 188087.25, 536888.75, 188134.25, 536888.75, 188060.25, 536888.75, 188157.75, - 536888.75, 187938.25, 536888.75, 187921.25, 536888.75, 188061.75, 536888.75, 187924.25, - 536888.75, 188042.25, 536888.75, 188032.75, 536888.75, 188125.75, 536888.75, 187958.75, - 536888.75, 188039.25, 536888.75, 188062.75, 536888.75, 188133.75, 536888.75, 188059.75, - 536888.75, 188080.75, 536888.75, 187988.25, 536888.75, 187914.75, 536888.75, 188116.75, - 536888.75, 187990.25, 536888.75, 187948.25, 536888.75, 188103.25, 536888.75, 187984.75, - 536888.75, 187930.75, 536888.75, 188063.25, 536888.75, 188033.25, 536888.75, 188155.25, - 536888.75, 188031.25, 536888.75, 188104.75, 536888.75, 188064.25, 536888.75, 188008.25, - 536888.75, 188130.25, 536888.75, 188041.75, 536888.75, 187949.25, 536888.75, 188088.25, - 536888.75, 188130.75, 536888.75, 188065.25, 536888.75, 187936.25, 536888.75, 188058.25, - 536888.75, 188086.25, 536888.75, 188156.25, 536888.75, 187914.25, 536888.75, 188111.75, - 536888.75, 187992.25, 536888.75, 188066.25, 536888.75, 187931.75, 536888.75, 188122.25, - 536888.75, 188105.25, 536888.75, 188117.25, 536888.75, 188006.25, 536888.75, 188030.75, - 536888.75, 187985.25, 536888.75, 188132.75, 536889.25, 188085.25, 536889.25, 188134.25, - 536889.25, 188032.25, 536889.25, 187959.25, 536889.25, 188038.75, 536889.25, 187938.75, - 536889.25, 188087.25, 536889.25, 187957.25, 536889.25, 187984.25, 536889.25, 188154.25, - 536889.25, 188153.25, 536889.25, 187985.25, 536889.25, 187974.75, 536889.25, 187938.25, - 536889.25, 187921.25, 536889.25, 187994.25, 536889.25, 188031.75, 536889.25, 188007.25, - 536889.25, 188123.25, 536889.25, 187921.75, 536889.25, 188135.25, 536889.25, 187975.25, - 536889.25, 188035.25, 536889.25, 187937.25, 536889.25, 188081.25, 536889.25, 188114.25, - 536889.25, 188041.25, 536889.25, 188156.75, 536889.25, 188038.25, 536889.25, 187947.25, - 536889.25, 187934.75, 536889.25, 188032.75, 536889.25, 188042.25, 536889.25, 187948.75, - 536889.25, 187993.75, 536889.25, 187932.25, 536889.25, 188145.25, 536889.25, 187975.75, - 536889.25, 188062.75, 536889.25, 188152.25, 536889.25, 188086.75, 536889.25, 187911.25, - 536889.25, 187948.25, 536889.25, 188132.25, 536889.25, 187984.75, 536889.25, 188014.25, - 536889.25, 188151.75, 536889.25, 187999.25, 536889.25, 188021.75, 536889.25, 188066.25, - 536889.25, 188080.25, 536889.25, 187922.25, 536889.25, 188033.25, 536889.25, 187917.75, - 536889.25, 188063.75, 536889.25, 188133.25, 536889.25, 188131.75, 536889.25, 188007.75, - 536889.25, 187933.75, 536889.25, 188151.25, 536889.25, 188059.25, 536889.25, 187977.75, - 536889.25, 187980.25, 536889.25, 188051.75, 536889.25, 188105.75, 536889.25, 188145.75, - 536889.25, 188156.25, 536889.25, 188142.75, 536889.25, 188100.75, 536889.25, 188031.25, - 536889.25, 188114.75, 536889.25, 187931.25, 536889.25, 188058.25, 536889.25, 188124.75, - 536889.25, 188122.75, 536889.25, 188005.75, 536889.25, 188033.75, 536889.25, 188104.75, - 536889.25, 188015.75, 536889.25, 188130.25, 536889.25, 188065.75, 536889.25, 188155.75, - 536889.25, 188118.25, 536889.25, 187958.25, 536889.25, 187941.75, 536889.25, 187936.25, - 536889.25, 187949.25, 536889.25, 188100.25, 536889.25, 188041.75, 536889.25, 188040.75, - 536889.25, 188020.75, 536889.25, 188106.25, 536889.25, 188150.25, 536889.25, 187937.75, - 536889.25, 187913.75, 536889.25, 187911.75, 536889.25, 188149.75, 536889.75, 188149.75, - 536889.75, 188065.25, 536889.75, 187983.25, 536889.75, 188041.75, 536889.75, 187940.25, - 536889.75, 188150.25, 536889.75, 188085.25, 536889.75, 188032.25, 536889.75, 188132.75, - 536889.75, 188144.25, 536889.75, 188040.75, 536889.75, 188034.25, 536889.75, 188058.75, - 536889.75, 187959.25, 536889.75, 188124.25, 536889.75, 188126.75, 536889.75, 187937.25, - 536889.75, 188056.75, 536889.75, 187936.25, 536889.75, 187958.25, 536889.75, 187973.25, - 536889.75, 188118.25, 536889.75, 188131.25, 536889.75, 188134.75, 536889.75, 188087.25, - 536889.75, 188104.75, 536889.75, 188117.75, 536889.75, 188130.25, 536889.75, 187957.25, - 536889.75, 188004.25, 536889.75, 188106.25, 536889.75, 188005.75, 536889.75, 187912.75, - 536889.75, 188124.75, 536889.75, 188088.75, 536889.75, 188008.75, 536889.75, 187985.25, - 536889.75, 188058.25, 536889.75, 187949.75, 536889.75, 188013.25, 536889.75, 188114.75, - 536889.75, 187975.25, 536889.75, 188160.25, 536889.75, 188057.75, 536889.75, 187912.25, - 536889.75, 188156.25, 536889.75, 188036.25, 536889.75, 187992.75, 536889.75, 187931.25, - 536889.75, 187971.75, 536889.75, 187947.25, 536889.75, 188156.75, 536889.75, 188038.25, - 536889.75, 187948.75, 536889.75, 187934.25, 536889.75, 187977.25, 536889.75, 188129.75, - 536889.75, 187988.75, 536889.75, 188159.25, 536889.75, 188151.25, 536889.75, 188114.25, - 536889.75, 187934.75, 536889.75, 188032.75, 536889.75, 188117.25, 536889.75, 188034.75, - 536889.75, 188133.25, 536889.75, 188033.25, 536889.75, 188125.75, 536889.75, 188148.25, - 536889.75, 188062.25, 536889.75, 188080.25, 536889.75, 187932.75, 536889.75, 187987.75, - 536889.75, 187921.25, 536889.75, 188006.75, 536889.75, 188063.25, 536889.75, 188071.75, - 536889.75, 188039.25, 536889.75, 187910.75, 536889.75, 187930.75, 536889.75, 187993.75, - 536889.75, 188152.75, 536889.75, 187925.75, 536889.75, 187911.25, 536889.75, 188108.75, - 536889.75, 188132.25, 536889.75, 187931.75, 536889.75, 187938.25, 536889.75, 187984.75, - 536889.75, 188086.75, 536889.75, 187947.75, 536890.25, 187988.25, 536890.25, 188004.75, - 536890.25, 187948.25, 536890.25, 188099.75, 536890.25, 188080.75, 536890.25, 188084.75, - 536890.25, 188133.75, 536890.25, 188085.75, 536890.25, 188122.25, 536890.25, 188062.75, - 536890.25, 188105.25, 536890.25, 187946.75, 536890.25, 188147.75, 536890.25, 188116.75, - 536890.25, 188154.75, 536890.25, 187932.25, 536890.25, 188145.25, 536890.25, 188151.75, - 536890.25, 188016.75, 536890.25, 187940.75, 536890.25, 187972.75, 536890.25, 188066.25, - 536890.25, 187922.25, 536890.25, 187945.75, 536890.25, 188122.75, 536890.25, 188117.25, - 536890.25, 188006.25, 536890.25, 188110.75, 536890.25, 188143.75, 536890.25, 188034.75, - 536890.25, 188009.25, 536890.25, 188131.75, 536890.25, 188151.25, 536890.25, 188056.25, - 536890.25, 188011.25, 536890.25, 188086.25, 536890.25, 188113.75, 536890.25, 188114.75, - 536890.25, 188081.25, 536890.25, 188069.75, 536890.25, 188030.75, 536890.25, 188035.25, - 536890.25, 188031.25, 536890.25, 187984.25, 536890.25, 188039.75, 536890.25, 188100.75, - 536890.25, 188018.25, 536890.25, 188057.75, 536890.25, 188031.75, 536890.25, 188123.25, - 536890.25, 188049.75, 536890.25, 188156.25, 536890.25, 187915.25, 536890.25, 187994.25, - 536890.25, 187957.75, 536890.25, 188145.75, 536890.25, 188157.75, 536890.25, 188008.75, - 536890.25, 188148.75, 536890.25, 188083.75, 536890.25, 188004.25, 536890.25, 187985.25, - 536890.25, 188154.25, 536890.25, 188130.25, 536890.25, 188132.75, 536890.25, 187978.25, - 536890.25, 188065.75, 536890.25, 188131.25, 536890.25, 187958.25, 536890.25, 187937.25, - 536890.25, 187983.25, 536890.25, 188030.25, 536890.25, 188144.25, 536890.25, 188038.75, - 536890.25, 187933.25, 536890.25, 188040.75, 536890.25, 188034.25, 536890.25, 188037.25, - 536890.25, 187939.75, 536890.25, 188130.75, 536890.25, 187993.25, 536890.75, 188113.75, - 536890.75, 187970.25, 536890.75, 187945.25, 536890.75, 188120.25, 536890.75, 188101.75, - 536890.75, 188046.25, 536890.75, 187974.25, 536890.75, 187937.75, 536890.75, 188010.75, - 536890.75, 188148.25, 536890.75, 188157.75, 536890.75, 187993.75, 536890.75, 188029.75, - 536890.75, 187912.75, 536890.75, 188154.75, 536890.75, 188100.75, 536890.75, 187982.75, - 536890.75, 188063.75, 536890.75, 188033.75, 536890.75, 188003.25, 536890.75, 187986.25, - 536890.75, 187941.25, 536890.75, 187921.75, 536890.75, 188102.25, 536890.75, 188142.75, - 536890.75, 188009.75, 536890.75, 188132.25, 536890.75, 188085.75, 536890.75, 188056.25, - 536890.75, 188055.25, 536890.75, 188035.75, 536890.75, 188003.75, 536890.75, 188009.25, - 536890.75, 188155.25, 536890.75, 187971.75, 536890.75, 188027.25, 536890.75, 188146.25, - 536890.75, 188148.75, 536890.75, 187932.75, 536890.75, 188020.25, 536890.75, 187973.25, - 536890.75, 188050.25, 536890.75, 188093.25, 536890.75, 188143.25, 536890.75, 187985.75, - 536890.75, 187913.25, 536890.75, 188008.75, 536890.75, 188121.25, 536890.75, 187917.25, - 536890.75, 188008.25, 536890.75, 188004.25, 536890.75, 188056.75, 536890.75, 187941.75, - 536890.75, 188052.25, 536890.75, 187982.25, 536890.75, 188081.25, 536890.75, 187934.25, - 536890.75, 188085.25, 536890.75, 188081.75, 536890.75, 188103.75, 536890.75, 188115.25, - 536890.75, 188144.25, 536890.75, 187995.25, 536890.75, 188004.75, 536890.75, 187944.25, - 536890.75, 188067.75, 536890.75, 187983.75, 536890.75, 188030.75, 536890.75, 187940.25, - 536890.75, 187979.25, 536890.75, 188151.75, 536890.75, 188157.25, 536890.75, 188083.75, - 536890.75, 188154.25, 536890.75, 188105.75, 536890.75, 187940.75, 536890.75, 188007.25, - 536890.75, 187936.75, 536890.75, 187978.75, 536890.75, 188066.25, 536890.75, 188057.25, - 536890.75, 188146.75, 536890.75, 188082.25, 536890.75, 188117.25, 536890.75, 188116.25, - 536890.75, 188006.75, 536890.75, 187994.75, 536890.75, 188131.75, 536890.75, 188049.25, - 536890.75, 188031.75, 536890.75, 187942.25, 536890.75, 188106.75, 536890.75, 187981.75, - 536890.75, 188153.75, 536890.75, 188122.75, 536890.75, 187973.75, 536890.75, 188066.75, - 536890.75, 188155.75, 536890.75, 188152.25, 536890.75, 187932.25, 536890.75, 187983.25, - 536890.75, 188000.25, 536890.75, 188055.75, 536890.75, 187922.75, 536891.25, 188152.25, - 536891.25, 188055.75, 536891.25, 187932.25, 536891.25, 187983.25, 536891.25, 188015.75, - 536891.25, 188066.75, 536891.25, 187973.75, 536891.25, 187937.25, 536891.25, 187981.75, - 536891.25, 187946.25, 536891.25, 188122.75, 536891.25, 188153.75, 536891.25, 188006.75, - 536891.25, 187950.25, 536891.25, 187969.75, 536891.25, 188145.25, 536891.25, 187994.75, - 536891.25, 187943.75, 536891.25, 187927.75, 536891.25, 188116.25, 536891.25, 188062.75, - 536891.25, 188082.25, 536891.25, 188066.25, 536891.25, 187978.75, 536891.25, 188099.75, - 536891.25, 187936.75, 536891.25, 188007.25, 536891.25, 188115.75, 536891.25, 187940.75, - 536891.25, 188154.25, 536891.25, 188083.75, 536891.25, 188157.25, 536891.25, 188084.25, - 536891.25, 188038.75, 536891.25, 188005.25, 536891.25, 188049.75, 536891.25, 188151.75, - 536891.25, 187940.25, 536891.25, 187936.25, 536891.25, 188147.25, 536891.25, 187978.25, - 536891.25, 188039.25, 536891.25, 188125.75, 536891.25, 187922.25, 536891.25, 188007.75, - 536891.25, 188115.25, 536891.25, 188103.75, 536891.25, 188081.75, 536891.25, 187982.25, - 536891.25, 188081.25, 536891.25, 187974.75, 536891.25, 187941.75, 536891.25, 188121.75, - 536891.25, 188004.25, 536891.25, 188008.75, 536891.25, 187973.25, 536891.25, 187985.75, - 536891.25, 188151.25, 536891.25, 188036.25, 536891.25, 187932.75, 536891.25, 188029.25, - 536891.25, 187971.75, 536891.25, 188146.25, 536891.25, 188113.75, 536891.25, 188055.25, - 536891.25, 188003.75, 536891.25, 188085.75, 536891.25, 188035.75, 536891.25, 188009.75, - 536891.25, 188142.75, 536891.25, 187941.25, 536891.25, 187986.75, 536891.25, 187921.75, - 536891.25, 188033.75, 536891.25, 188063.75, 536891.25, 188154.75, 536891.25, 188120.75, - 536891.25, 188010.75, 536891.25, 187993.75, 536891.25, 188157.75, 536891.25, 187945.25, - 536891.25, 188101.75, 536891.25, 188026.75, 536891.25, 188002.75, 536891.25, 188068.75, - 536891.25, 187972.25, 536891.25, 187970.25, 536891.75, 187968.25, 536891.75, 188063.25, - 536891.75, 187970.25, 536891.75, 187942.75, 536891.75, 188147.25, 536891.75, 188002.75, - 536891.75, 188152.75, 536891.75, 188144.25, 536891.75, 188113.25, 536891.75, 188156.25, - 536891.75, 188007.75, 536891.75, 187968.75, 536891.75, 187916.75, 536891.75, 188053.75, - 536891.75, 188112.25, 536891.75, 187920.25, 536891.75, 188034.25, 536891.75, 187992.25, - 536891.75, 187944.25, 536891.75, 188003.25, 536891.75, 187974.25, 536891.75, 188086.25, - 536891.75, 188095.25, 536891.75, 188034.75, 536891.75, 187986.75, 536891.75, 188081.75, - 536891.75, 188106.75, 536891.75, 187988.25, 536891.75, 188149.75, 536891.75, 188153.25, - 536891.75, 187992.75, 536891.75, 187980.75, 536891.75, 188082.75, 536891.75, 188145.75, - 536891.75, 188056.25, 536891.75, 188055.75, 536891.75, 188011.75, 536891.75, 188150.75, - 536891.75, 187932.25, 536891.75, 187971.25, 536891.75, 187972.75, 536891.75, 188028.25, - 536891.75, 188102.75, 536891.75, 188103.25, 536891.75, 187953.75, 536891.75, 188066.75, - 536891.75, 188123.25, 536891.75, 188121.25, 536891.75, 187974.75, 536891.75, 187943.25, - 536891.75, 188006.25, 536891.75, 187981.25, 536891.75, 188106.25, 536891.75, 188042.25, - 536891.75, 187923.25, 536891.75, 187994.75, 536891.75, 188114.25, 536891.75, 187986.25, - 536891.75, 187932.75, 536891.75, 188036.25, 536891.75, 187982.25, 536891.75, 188054.75, - 536891.75, 188155.25, 536891.75, 187936.75, 536891.75, 188085.25, 536891.75, 188113.75, - 536891.75, 187980.25, 536891.75, 187990.25, 536891.75, 187970.75, 536891.75, 187933.75, - 536891.75, 188105.75, 536891.75, 188103.75, 536891.75, 188001.75, 536891.75, 187944.75, - 536891.75, 188076.75, 536891.75, 188088.25, 536891.75, 188067.75, 536891.75, 188105.25, - 536891.75, 188143.75, 536891.75, 188076.25, 536891.75, 188005.25, 536891.75, 188009.75, - 536891.75, 188001.25, 536891.75, 188064.25, 536892.25, 187967.25, 536892.25, 188109.75, - 536892.25, 187968.25, 536892.25, 188035.75, 536892.25, 188001.25, 536892.25, 188055.25, - 536892.25, 188101.25, 536892.25, 187995.75, 536892.25, 188155.25, 536892.25, 188076.75, - 536892.25, 188150.25, 536892.25, 188067.25, 536892.25, 188076.25, 536892.25, 188028.75, - 536892.25, 187945.75, 536892.25, 188105.25, 536892.25, 188118.25, 536892.25, 187941.25, - 536892.25, 188004.75, 536892.25, 187933.75, 536892.25, 188085.25, 536892.25, 187978.75, - 536892.25, 188009.25, 536892.25, 188012.25, 536892.25, 188147.75, 536892.25, 188148.75, - 536892.25, 188005.75, 536892.25, 187987.25, 536892.25, 188054.75, 536892.25, 188053.25, - 536892.25, 188146.75, 536892.25, 187969.25, 536892.25, 188100.25, 536892.25, 188068.25, - 536892.25, 188056.75, 536892.25, 187986.25, 536892.25, 188054.25, 536892.25, 188025.75, - 536892.25, 188114.75, 536892.25, 187967.75, 536892.25, 187974.75, 536892.25, 188075.75, - 536892.25, 188006.25, 536892.25, 188004.25, 536892.25, 188010.25, 536892.25, 187943.25, - 536892.25, 187956.25, 536892.25, 187951.25, 536892.25, 187922.75, 536892.25, 188102.75, - 536892.25, 188112.75, 536892.25, 188008.25, 536892.25, 187971.25, 536892.25, 188119.25, - 536892.25, 188159.25, 536892.25, 187932.25, 536892.25, 187933.25, 536892.25, 188011.75, - 536892.25, 188028.25, 536892.25, 188085.75, 536892.25, 187910.75, 536892.25, 188000.25, - 536892.25, 188036.75, 536892.25, 187980.75, 536892.25, 187913.75, 536892.25, 188002.25, - 536892.25, 188149.75, 536892.25, 188075.25, 536892.25, 187992.75, 536892.25, 188160.25, - 536892.25, 188106.75, 536892.25, 188102.25, 536892.25, 188074.75, 536892.25, 187942.25, - 536892.25, 188108.25, 536892.25, 188115.25, 536892.25, 187974.25, 536892.25, 188064.75, - 536892.25, 187947.25, 536892.25, 188025.25, 536892.25, 187995.25, 536892.25, 188082.25, - 536892.25, 188155.75, 536892.25, 188107.25, 536892.25, 188034.75, 536892.25, 187923.75, - 536892.25, 187992.25, 536892.25, 188034.25, 536892.25, 188156.25, 536892.25, 188026.75, - 536892.25, 188144.25, 536892.25, 187994.25, 536892.25, 188051.25, 536892.25, 188111.75, - 536892.25, 188158.25, 536892.25, 188037.25, 536892.25, 188011.25, 536892.25, 187911.25, - 536892.25, 187979.25, 536892.75, 188101.25, 536892.75, 188037.25, 536892.75, 188149.25, - 536892.75, 188158.25, 536892.75, 188125.25, 536892.75, 188014.75, 536892.75, 188011.25, - 536892.75, 187994.25, 536892.75, 188091.75, 536892.75, 187946.75, 536892.75, 187979.25, - 536892.75, 188053.75, 536892.75, 187969.75, 536892.75, 188025.25, 536892.75, 188112.25, - 536892.75, 188156.25, 536892.75, 187939.75, 536892.75, 187923.75, 536892.75, 188081.75, - 536892.75, 187999.75, 536892.75, 188115.25, 536892.75, 188086.25, 536892.75, 188074.75, - 536892.75, 188102.25, 536892.75, 187942.25, 536892.75, 188157.75, 536892.75, 188006.75, - 536892.75, 187980.75, 536892.75, 188075.25, 536892.75, 188149.75, 536892.75, 188037.75, - 536892.75, 188003.75, 536892.75, 188064.75, 536892.75, 188036.75, 536892.75, 188002.25, - 536892.75, 187973.75, 536892.75, 187932.25, 536892.75, 187942.75, 536892.75, 188063.75, - 536892.75, 188052.25, 536892.75, 187971.25, 536892.75, 188079.25, 536892.75, 187922.75, - 536892.75, 188102.75, 536892.75, 188075.75, 536892.75, 187943.25, 536892.75, 188151.25, - 536892.75, 187987.25, 536892.75, 188121.75, 536892.75, 188008.75, 536892.75, 187974.75, - 536892.75, 187941.75, 536892.75, 188106.25, 536892.75, 188114.75, 536892.75, 187986.25, - 536892.75, 188025.75, 536892.75, 188056.75, 536892.75, 188068.25, 536892.75, 187947.75, - 536892.75, 188054.25, 536892.75, 188118.75, 536892.75, 188147.75, 536892.75, 188012.25, - 536892.75, 188047.75, 536892.75, 188085.25, 536892.75, 188067.25, 536892.75, 188057.25, - 536892.75, 187971.75, 536892.75, 187933.75, 536892.75, 187970.75, 536892.75, 188005.75, - 536892.75, 188148.75, 536892.75, 188004.75, 536892.75, 188001.75, 536892.75, 188143.75, - 536892.75, 188009.25, 536892.75, 188099.75, 536892.75, 188110.25, 536892.75, 187995.75, - 536892.75, 187978.75, 536892.75, 188076.75, 536892.75, 188105.75, 536892.75, 188028.75, - 536892.75, 187945.75, 536892.75, 188154.25, 536892.75, 188105.25, 536892.75, 188001.25, - 536892.75, 188109.25, 536892.75, 188146.75, 536892.75, 188155.25, 536892.75, 187967.25, - 536892.75, 188109.75, 536892.75, 188055.25, 536892.75, 188009.75, 536892.75, 187968.25, - 536893.25, 188005.25, 536893.25, 188067.75, 536893.25, 187991.25, 536893.25, 188076.75, - 536893.25, 188109.75, 536893.25, 188151.75, 536893.25, 188140.75, 536893.25, 187940.75, - 536893.25, 188158.75, 536893.25, 188001.75, 536893.25, 187995.75, 536893.25, 188064.25, - 536893.25, 188026.25, 536893.25, 188051.75, 536893.25, 188148.75, 536893.25, 188027.25, - 536893.25, 188057.25, 536893.25, 187969.25, 536893.25, 188050.75, 536893.25, 188067.25, - 536893.25, 187994.75, 536893.25, 188012.25, 536893.25, 187947.75, 536893.25, 187970.75, - 536893.25, 188117.25, 536893.25, 187923.25, 536893.25, 188106.25, 536893.25, 187941.75, - 536893.25, 188108.75, 536893.25, 188010.25, 536893.25, 188008.75, 536893.25, 188004.25, - 536893.25, 188122.75, 536893.25, 188123.25, 536893.25, 188052.75, 536893.25, 188112.75, - 536893.25, 187933.25, 536893.25, 188121.25, 536893.25, 188073.25, 536893.25, 187977.75, - 536893.25, 188064.75, 536893.25, 188056.25, 536893.25, 188159.25, 536893.25, 188008.25, - 536893.25, 187966.75, 536893.25, 187934.25, 536893.25, 188000.25, 536893.25, 187974.25, - 536893.25, 188108.25, 536893.25, 188086.25, 536893.25, 188115.25, 536893.25, 188034.75, - 536893.25, 187923.75, 536893.25, 188107.25, 536893.25, 187986.75, 536893.25, 187947.25, - 536893.25, 187967.75, 536893.25, 188156.25, 536893.25, 187998.25, 536893.25, 187977.25, - 536893.25, 188087.25, 536893.25, 187999.75, 536893.25, 187945.25, 536893.25, 187979.25, - 536893.25, 188073.75, 536893.25, 188007.25, 536893.25, 187916.25, 536893.25, 187944.25, - 536893.25, 188011.25, 536893.25, 188147.25, 536893.25, 188115.75, 536893.25, 188076.25, - 536893.75, 188121.25, 536893.75, 188048.25, 536893.75, 187993.75, 536893.75, 188011.25, - 536893.75, 188098.75, 536893.75, 187948.75, 536893.75, 187918.25, 536893.75, 188015.75, - 536893.75, 187937.25, 536893.75, 187972.25, 536893.75, 188067.25, 536893.75, 188102.25, - 536893.75, 187946.25, 536893.75, 187996.25, 536893.75, 188037.75, 536893.75, 187992.75, - 536893.75, 188157.75, 536893.75, 188006.75, 536893.75, 188153.25, 536893.75, 188106.75, - 536893.75, 187945.25, 536893.75, 188052.75, 536893.75, 188122.75, 536893.75, 188116.25, - 536893.75, 188000.75, 536893.75, 188155.75, 536893.75, 188038.25, 536893.75, 187941.25, - 536893.75, 188072.75, 536893.75, 188007.25, 536893.75, 188003.25, 536893.75, 188123.25, - 536893.75, 187987.75, 536893.75, 187939.75, 536893.75, 187976.75, 536893.75, 188074.25, - 536893.75, 188106.25, 536893.75, 188037.25, 536893.75, 188120.25, 536893.75, 188101.75, - 536893.75, 188002.75, 536893.75, 187943.75, 536893.75, 188148.25, 536893.75, 187914.25, - 536893.75, 188010.75, 536893.75, 187975.75, 536893.75, 188107.75, 536893.75, 188122.25, - 536893.75, 188007.75, 536893.75, 188123.75, 536893.75, 187914.75, 536893.75, 187997.25, - 536893.75, 187965.75, 536893.75, 187965.25, 536893.75, 188077.75, 536893.75, 188057.75, - 536893.75, 188156.75, 536893.75, 188068.75, 536893.75, 188038.75, 536893.75, 187977.75, - 536893.75, 188108.25, 536893.75, 187924.75, 536893.75, 188146.75, 536893.75, 188115.25, - 536893.75, 188075.25, 536893.75, 187928.25, 536893.75, 187948.25, 536893.75, 188120.75, - 536893.75, 188052.25, 536893.75, 188010.25, 536893.75, 187972.75, 536893.75, 188124.25, - 536893.75, 188013.75, 536893.75, 188086.75, 536893.75, 188087.75, 536893.75, 188121.75, - 536893.75, 187968.75, 536893.75, 188077.25, 536893.75, 188159.25, 536893.75, 187941.75, - 536893.75, 187959.25, 536893.75, 187999.25, 536893.75, 187923.25, 536893.75, 188050.25, - 536893.75, 187939.25, 536893.75, 187995.25, 536893.75, 187970.25, 536893.75, 188116.75, - 536893.75, 188148.75, 536893.75, 188157.25, 536893.75, 187934.75, 536893.75, 187998.75, - 536893.75, 187911.25, 536893.75, 187967.25, 536893.75, 187933.75, 536893.75, 188013.25, - 536893.75, 187988.25, 536893.75, 188100.75, 536893.75, 187998.25, 536893.75, 187977.25, - 536893.75, 188065.25, 536893.75, 188012.75, 536893.75, 188056.75, 536893.75, 187924.25, - 536894.25, 188119.25, 536894.25, 188011.25, 536894.25, 188076.75, 536894.25, 188012.75, - 536894.25, 188087.25, 536894.25, 188065.25, 536894.25, 188063.75, 536894.25, 188051.75, - 536894.25, 187948.75, 536894.25, 188026.75, 536894.25, 188015.75, 536894.25, 187993.75, - 536894.25, 187988.25, 536894.25, 188102.25, 536894.25, 187911.75, 536894.25, 188067.25, - 536894.25, 187945.75, 536894.25, 187942.75, 536894.25, 188037.75, 536894.25, 187946.25, - 536894.25, 187911.25, 536894.25, 188106.75, 536894.25, 188158.25, 536894.25, 188121.25, - 536894.25, 187972.25, 536894.25, 188027.75, 536894.25, 188118.25, 536894.25, 187944.75, - 536894.25, 188122.75, 536894.25, 188006.75, 536894.25, 188113.75, 536894.25, 188157.75, - 536894.25, 188153.25, 536894.25, 187945.25, 536894.25, 188071.75, 536894.25, 187998.25, - 536894.25, 187934.75, 536894.25, 188050.75, 536894.25, 187938.75, 536894.25, 188056.25, - 536894.25, 188038.25, 536894.25, 188112.25, 536894.25, 187987.25, 536894.25, 188000.75, - 536894.25, 187966.25, 536894.25, 188148.25, 536894.25, 187995.25, 536894.25, 188080.75, - 536894.25, 188073.75, 536894.25, 188125.25, 536894.25, 187939.25, 536894.25, 188114.25, - 536894.25, 187973.25, 536894.25, 187968.25, 536894.25, 188123.25, 536894.25, 188064.75, - 536894.25, 188050.25, 536894.25, 188007.25, 536894.25, 188003.25, 536894.25, 188069.25, - 536894.25, 187976.75, 536894.25, 187939.75, 536894.25, 188101.25, 536894.25, 188159.25, - 536894.25, 188154.25, 536894.25, 188035.25, 536894.25, 188120.25, 536894.25, 187946.75, - 536894.25, 188066.75, 536894.25, 188101.75, 536894.25, 188159.75, 536894.25, 188013.75, - 536894.25, 188049.25, 536894.25, 188068.25, 536894.25, 188008.75, 536894.25, 188100.25, - 536894.25, 187923.75, 536894.25, 188010.75, 536894.25, 188146.75, 536894.25, 187964.75, - 536894.25, 187943.75, 536894.25, 188010.25, 536894.25, 187919.25, 536894.25, 187942.25, - 536894.25, 188008.25, 536894.25, 188067.75, 536894.25, 188124.25, 536894.25, 188003.75, - 536894.25, 188123.75, 536894.25, 187944.25, 536894.25, 188145.25, 536894.25, 187969.75, - 536894.25, 187933.25, 536894.25, 187977.75, 536894.25, 187999.75, 536894.25, 188077.75, - 536894.25, 188032.25, 536894.25, 188072.25, 536894.25, 188120.75, 536894.25, 188011.75, - 536894.25, 187928.25, 536894.25, 188086.75, 536894.25, 187995.75, 536894.25, 188156.75, - 536894.75, 187995.75, 536894.75, 187924.75, 536894.75, 187934.25, 536894.75, 187947.25, - 536894.75, 188150.75, 536894.75, 188115.25, 536894.75, 188057.75, 536894.75, 187992.25, - 536894.75, 188057.25, 536894.75, 187924.25, 536894.75, 188120.75, 536894.75, 188119.25, - 536894.75, 187948.25, 536894.75, 188072.25, 536894.75, 188008.25, 536894.75, 188067.75, - 536894.75, 188122.25, 536894.75, 188002.75, 536894.75, 187942.25, 536894.75, 188010.75, - 536894.75, 188147.25, 536894.75, 187943.75, 536894.75, 187910.75, 536894.75, 188107.75, - 536894.75, 187972.75, 536894.75, 188000.25, 536894.75, 188146.75, 536894.75, 187996.75, - 536894.75, 188010.25, 536894.75, 187997.75, 536894.75, 188087.75, 536894.75, 187941.75, - 536894.75, 187925.25, 536894.75, 187968.75, 536894.75, 187937.75, 536894.75, 188115.75, - 536894.75, 187987.75, 536894.75, 188077.25, 536894.75, 188144.25, 536894.75, 187974.75, - 536894.75, 188113.25, 536894.75, 188159.25, 536894.75, 188050.25, 536894.75, 188007.25, - 536894.75, 187976.75, 536894.75, 188005.25, 536894.75, 188123.25, 536894.75, 187941.25, - 536894.75, 188158.75, 536894.75, 187963.75, 536894.75, 188004.25, 536894.75, 187966.25, - 536894.75, 188160.25, 536894.75, 187998.25, 536894.75, 188112.25, 536894.75, 188148.75, - 536894.75, 187936.75, 536894.75, 188071.75, 536894.75, 187970.25, 536894.75, 187998.75, - 536894.75, 188118.25, 536894.75, 188037.75, 536894.75, 187944.75, 536894.75, 187992.75, - 536894.75, 188065.75, 536894.75, 188056.75, 536894.75, 187933.75, 536894.75, 187967.25, - 536894.75, 187974.25, 536894.75, 188156.25, 536894.75, 188078.25, 536894.75, 188013.25, - 536894.75, 188002.25, 536894.75, 187988.25, 536894.75, 187913.75, 536894.75, 187975.25, - 536894.75, 188070.75, 536894.75, 188048.75, 536894.75, 188067.25, 536894.75, 188145.25, - 536894.75, 188118.75, 536894.75, 187964.25, 536894.75, 187949.25, 536895.25, 188111.75, - 536895.25, 187989.25, 536895.25, 188048.25, 536895.25, 187996.25, 536895.25, 187911.75, - 536895.25, 188078.25, 536895.25, 187967.75, 536895.25, 187937.75, 536895.25, 187939.75, - 536895.25, 188069.25, 536895.25, 187921.75, 536895.25, 187936.75, 536895.25, 188058.25, - 536895.25, 188107.25, 536895.25, 188006.25, 536895.25, 187941.25, 536895.25, 188119.75, - 536895.25, 188043.25, 536895.25, 188070.25, 536895.25, 188123.25, 536895.25, 187935.25, - 536895.25, 188010.75, 536895.25, 187997.25, 536895.25, 187987.75, 536895.25, 188058.75, - 536895.25, 187965.75, 536895.25, 188049.25, 536895.25, 187965.25, 536895.25, 187940.75, - 536895.25, 188077.75, 536895.25, 188151.75, 536895.25, 187973.75, 536895.25, 188049.75, - 536895.25, 188147.25, 536895.25, 188086.75, 536895.25, 187963.75, 536895.25, 188150.75, - 536895.25, 188112.75, 536895.25, 188007.75, 536895.25, 187935.75, 536895.25, 187938.25, - 536895.25, 187947.25, 536895.25, 187919.25, 536895.25, 188005.75, 536895.25, 187947.75, - 536895.25, 187943.25, 536895.25, 188004.25, 536895.25, 188147.75, 536895.25, 188038.75, - 536895.25, 187966.75, 536895.25, 188108.25, 536895.25, 188158.75, 536895.25, 188088.25, - 536895.25, 187924.75, 536895.25, 187933.75, 536895.25, 188066.25, 536895.25, 188072.25, - 536895.25, 187972.75, 536895.25, 187994.25, 536895.25, 187988.75, 536895.25, 188087.25, - 536895.25, 187920.25, 536895.25, 188013.75, 536895.25, 187919.75, 536895.25, 187975.25, - 536895.25, 187968.75, 536895.25, 188121.75, 536895.25, 188009.75, 536895.25, 187948.25, - 536895.25, 188159.25, 536895.25, 188013.25, 536895.25, 187925.75, 536895.25, 188044.25, - 536895.25, 188114.25, 536895.25, 188071.25, 536895.25, 188121.25, 536895.25, 187949.75, - 536895.25, 187915.25, 536895.25, 188157.25, 536895.25, 188009.25, 536895.25, 188148.75, - 536895.25, 187964.25, 536895.25, 187942.75, 536895.25, 188039.25, 536895.25, 188065.75, - 536895.25, 188118.25, 536895.25, 188090.25, 536895.25, 187998.75, 536895.75, 188118.25, - 536895.75, 188065.75, 536895.75, 187942.75, 536895.75, 188039.25, 536895.75, 188005.25, - 536895.75, 187911.25, 536895.75, 187964.25, 536895.75, 188152.75, 536895.75, 188148.75, - 536895.75, 187988.25, 536895.75, 188157.25, 536895.75, 187949.75, 536895.75, 187995.25, - 536895.75, 188121.25, 536895.75, 188121.75, 536895.75, 188071.25, 536895.75, 188002.25, - 536895.75, 188159.25, 536895.75, 188013.25, 536895.75, 187962.25, 536895.75, 188009.75, - 536895.75, 187925.75, 536895.75, 188013.75, 536895.75, 188118.75, 536895.75, 188033.25, - 536895.75, 187968.75, 536895.75, 188076.75, 536895.75, 188008.75, 536895.75, 188088.25, - 536895.75, 187972.75, 536895.75, 188110.25, 536895.75, 188051.75, 536895.75, 188070.75, - 536895.75, 187994.25, 536895.75, 187934.25, 536895.75, 187933.75, 536895.75, 188156.75, - 536895.75, 188158.75, 536895.75, 188108.25, 536895.75, 187928.25, 536895.75, 188042.75, - 536895.75, 188004.25, 536895.75, 187973.25, 536895.75, 187966.75, 536895.75, 187974.75, - 536895.75, 187935.75, 536895.75, 188005.75, 536895.75, 187943.25, 536895.75, 187947.75, - 536895.75, 188057.25, 536895.75, 188119.25, 536895.75, 187919.25, 536895.75, 188007.75, - 536895.75, 188122.25, 536895.75, 188112.75, 536895.75, 187963.75, 536895.75, 187947.25, - 536895.75, 188068.75, 536895.75, 187965.75, 536895.75, 187942.25, 536895.75, 187940.75, - 536895.75, 188049.25, 536895.75, 188088.75, 536895.75, 188010.75, 536895.75, 188147.25, - 536895.75, 188120.75, 536895.75, 187977.75, 536895.75, 188074.25, 536895.75, 187973.75, - 536895.75, 187939.75, 536895.75, 187935.25, 536895.75, 188007.25, 536895.75, 188006.25, - 536895.75, 188070.25, 536895.75, 187996.75, 536895.75, 187923.75, 536895.75, 188015.25, - 536895.75, 188038.25, 536895.75, 188107.25, 536895.75, 187922.75, 536895.75, 187921.75, - 536895.75, 188069.25, 536895.75, 187936.75, 536895.75, 188142.25, 536895.75, 188006.75, - 536895.75, 188082.75, 536895.75, 188003.25, 536895.75, 188078.25, 536895.75, 187937.25, - 536895.75, 187911.75, 536895.75, 188048.25, 536895.75, 187996.25, 536895.75, 188111.75, - 536895.75, 188122.75, 536895.75, 187987.75, 536896.25, 188140.25, 536896.25, 188069.75, - 536896.25, 188111.75, 536896.25, 187962.75, 536896.25, 188111.25, 536896.25, 188157.75, - 536896.25, 187916.75, 536896.25, 188148.25, 536896.25, 188153.25, 536896.25, 187941.25, - 536896.25, 188058.75, 536896.25, 188120.25, 536896.25, 188010.75, 536896.25, 188119.75, - 536896.25, 188077.75, 536896.25, 188010.25, 536896.25, 187941.75, 536896.25, 188077.25, - 536896.25, 188141.25, 536896.25, 188012.25, 536896.25, 188002.75, 536896.25, 188110.75, - 536896.25, 187933.75, 536896.25, 188145.25, 536896.25, 188094.75, 536896.25, 187936.25, - 536896.25, 188148.75, 536896.25, 187966.25, 536896.25, 188157.25, 536896.25, 188068.75, - 536896.25, 188146.25, 536896.25, 188044.25, 536896.25, 187948.25, 536896.25, 188114.75, - 536896.25, 188013.75, 536896.25, 188023.75, 536896.25, 188008.25, 536896.25, 187924.75, - 536896.25, 188108.25, 536896.25, 188057.75, 536896.25, 187947.25, 536896.25, 188107.75, - 536896.25, 188053.25, 536896.25, 188007.25, 536896.25, 188043.25, 536896.25, 187973.25, - 536896.25, 188048.75, 536896.25, 188116.25, 536896.25, 187992.75, 536896.25, 187911.75, - 536896.25, 187918.75, 536896.25, 188088.75, 536896.25, 187922.75, 536896.25, 187925.25, - 536896.25, 187927.25, 536896.25, 187913.25, 536896.25, 188041.75, 536896.25, 188038.75, - 536896.25, 188068.25, 536896.25, 187967.25, 536896.25, 188087.75, 536896.25, 187921.25, - 536896.25, 187940.25, 536896.25, 187939.25, 536896.25, 188145.75, 536896.25, 187949.25, - 536896.25, 187988.25, 536896.25, 187934.75, 536896.75, 188107.75, 536896.75, 187939.25, - 536896.75, 188011.25, 536896.75, 188158.25, 536896.75, 187962.75, 536896.75, 188078.25, - 536896.75, 188039.25, 536896.75, 187912.75, 536896.75, 187972.25, 536896.75, 187922.25, - 536896.75, 187921.25, 536896.75, 188042.25, 536896.75, 188111.25, 536896.75, 187935.75, - 536896.75, 187940.25, 536896.75, 188148.25, 536896.75, 187931.75, 536896.75, 188117.75, - 536896.75, 188004.75, 536896.75, 187931.25, 536896.75, 188069.25, 536896.75, 187925.75, - 536896.75, 188001.75, 536896.75, 187915.75, 536896.75, 187967.75, 536896.75, 188058.25, - 536896.75, 187954.75, 536896.75, 188038.75, 536896.75, 187939.75, 536896.75, 187938.25, - 536896.75, 188120.25, 536896.75, 188010.75, 536896.75, 188119.75, 536896.75, 188077.75, - 536896.75, 187938.75, 536896.75, 188067.75, 536896.75, 188011.75, 536896.75, 188117.25, - 536896.75, 187995.75, 536896.75, 188010.25, 536896.75, 188151.75, 536896.75, 187950.25, - 536896.75, 188041.75, 536896.75, 187941.75, 536896.75, 188086.75, 536896.75, 187998.25, - 536896.75, 188012.25, 536896.75, 188003.75, 536896.75, 188147.75, 536896.75, 188002.75, - 536896.75, 188021.25, 536896.75, 188072.75, 536896.75, 187925.25, 536896.75, 188142.75, - 536896.75, 188109.75, 536896.75, 187930.25, 536896.75, 188085.75, 536896.75, 188044.75, - 536896.75, 187962.25, 536896.75, 187937.25, 536896.75, 188059.25, 536896.75, 188116.75, - 536896.75, 188073.25, 536896.75, 188040.25, 536896.75, 188009.25, 536896.75, 188157.25, - 536896.75, 187989.25, 536896.75, 187948.75, 536896.75, 187971.75, 536896.75, 187932.75, - 536896.75, 187923.25, 536896.75, 187948.25, 536896.75, 188015.25, 536896.75, 188143.25, - 536896.75, 187920.25, 536896.75, 187926.25, 536896.75, 187920.75, 536896.75, 187968.75, - 536896.75, 188108.75, 536896.75, 187934.25, 536896.75, 187924.75, 536896.75, 188043.75, - 536896.75, 188115.25, 536896.75, 188007.25, 536896.75, 188039.75, 536896.75, 188154.25, - 536896.75, 187963.25, 536896.75, 188087.25, 536896.75, 187989.75, 536896.75, 187912.25, - 536896.75, 187970.25, 536896.75, 188014.75, 536896.75, 188066.75, 536896.75, 187988.75, - 536896.75, 188007.75, 536896.75, 188149.25, 536896.75, 187947.25, 536896.75, 188153.75, - 536896.75, 188049.75, 536897.25, 188000.25, 536897.25, 188153.75, 536897.25, 188049.75, - 536897.25, 188070.75, 536897.25, 188037.25, 536897.25, 188158.25, 536897.25, 188149.25, - 536897.25, 187987.75, 536897.25, 187939.25, 536897.25, 188014.75, 536897.25, 188011.25, - 536897.25, 188115.75, 536897.25, 188107.75, 536897.25, 187912.25, 536897.25, 187989.75, - 536897.25, 188039.25, 536897.25, 188154.25, 536897.25, 188043.75, 536897.25, 188155.75, - 536897.25, 188087.25, 536897.25, 188078.25, 536897.25, 187969.75, 536897.25, 188015.25, - 536897.25, 187934.25, 536897.25, 187924.75, 536897.25, 187910.75, 536897.25, 188056.75, - 536897.25, 188108.75, 536897.25, 187988.25, 536897.25, 188118.75, 536897.25, 187931.25, - 536897.25, 187920.75, 536897.25, 187923.25, 536897.25, 187963.25, 536897.25, 187940.25, - 536897.25, 188088.25, 536897.25, 188117.75, 536897.25, 188022.25, 536897.25, 187937.75, - 536897.25, 188004.25, 536897.25, 187925.75, 536897.25, 187920.25, 536897.25, 187973.25, - 536897.25, 187967.75, 536897.25, 188004.75, 536897.25, 187932.75, 536897.25, 188114.25, - 536897.25, 187948.25, 536897.25, 188157.25, 536897.25, 188069.25, 536897.25, 187971.75, - 536897.25, 188067.25, 536897.25, 187989.25, 536897.25, 188058.25, 536897.25, 187930.75, - 536897.25, 188009.25, 536897.25, 187971.25, 536897.25, 188086.25, 536897.25, 188152.75, - 536897.25, 187932.25, 536897.25, 188148.75, 536897.25, 187938.25, 536897.25, 188063.25, - 536897.25, 188113.75, 536897.25, 188077.75, 536897.25, 187950.25, 536897.25, 187965.25, - 536897.25, 188059.25, 536897.25, 187938.75, 536897.25, 188011.75, 536897.25, 188067.75, - 536897.25, 188117.25, 536897.25, 188076.25, 536897.25, 188012.25, 536897.25, 187955.75, - 536897.25, 187937.25, 536897.25, 187913.25, 536897.25, 188010.25, 536897.25, 187911.75, - 536897.25, 188077.25, 536897.25, 187949.75, 536897.25, 187936.75, 536897.25, 188109.75, - 536897.25, 187935.25, 536897.25, 188002.25, 536897.25, 187966.75, 536897.25, 188160.25, - 536897.25, 188142.75, 536897.25, 188002.75, 536897.25, 188072.75, 536897.25, 188147.75, - 536897.25, 187998.25, 536897.25, 188049.25, 536897.25, 188041.75, 536897.75, 187913.25, - 536897.75, 188002.25, 536897.75, 188133.25, 536897.75, 187925.25, 536897.75, 188077.25, - 536897.75, 188095.25, 536897.75, 187937.25, 536897.75, 188044.75, 536897.75, 188086.75, - 536897.75, 187962.25, 536897.75, 188117.25, 536897.75, 187921.75, 536897.75, 188009.75, - 536897.75, 188045.25, 536897.75, 188109.25, 536897.75, 188012.25, 536897.75, 187986.25, - 536897.75, 187933.25, 536897.75, 188076.25, 536897.75, 188148.25, 536897.75, 187950.75, - 536897.75, 187963.75, 536897.75, 188059.25, 536897.75, 187998.75, 536897.75, 187994.75, - 536897.75, 188148.75, 536897.75, 188151.75, 536897.75, 188010.75, 536897.75, 187930.75, - 536897.75, 188152.75, 536897.75, 188040.25, 536897.75, 188038.75, 536897.75, 188146.25, - 536897.75, 188157.75, 536897.75, 188067.25, 536897.75, 187988.75, 536897.75, 188057.25, - 536897.75, 188044.25, 536897.75, 187970.75, 536897.75, 188114.75, 536897.75, 188013.75, - 536897.75, 188040.75, 536897.75, 187987.25, 536897.75, 188133.75, 536897.75, 187948.75, - 536897.75, 187968.75, 536897.75, 187922.25, 536897.75, 187949.25, 536897.75, 188056.75, - 536897.75, 187912.75, 536897.75, 187970.25, 536897.75, 187931.75, 536897.75, 187936.75, - 536897.75, 188057.75, 536897.75, 187926.75, 536897.75, 188049.75, 536897.75, 188085.25, - 536898.25, 188091.75, 536898.25, 187983.25, 536898.25, 187950.75, 536898.25, 187929.75, - 536898.25, 188013.25, 536898.25, 187969.75, 536898.25, 188013.75, 536898.25, 188108.75, - 536898.25, 187972.75, 536898.25, 188012.75, 536898.25, 188014.25, 536898.25, 187980.25, - 536898.25, 188012.25, 536898.25, 188148.25, 536898.25, 188051.25, 536898.25, 188131.75, - 536898.25, 187994.75, 536898.25, 188010.75, 536898.25, 188067.75, 536898.25, 188010.25, - 536898.25, 188082.25, 536898.25, 188158.75, 536898.25, 187933.75, 536898.25, 188149.75, - 536898.25, 187912.75, 536898.25, 187936.25, 536898.25, 188113.25, 536898.25, 188039.75, - 536898.25, 188133.25, 536898.25, 188050.75, 536898.25, 188015.75, 536898.25, 187913.75, - 536898.25, 188076.75, 536898.25, 188153.25, 536898.25, 188076.25, 536898.25, 188068.25, - 536898.25, 187915.75, 536898.25, 187935.75, 536898.25, 187938.75, 536898.25, 188057.25, - 536898.25, 187935.25, 536898.25, 187921.25, 536898.25, 188145.25, 536898.25, 188036.25, - 536898.25, 187922.25, 536898.25, 188114.25, 536898.25, 188143.25, 536898.25, 188050.25, - 536898.25, 187985.75, 536898.25, 188084.75, 536898.25, 187998.25, 536898.25, 188054.75, - 536898.25, 187917.25, 536898.25, 188005.25, 536898.25, 188085.25, 536898.25, 188075.75, - 536898.25, 188141.25, 536898.25, 187929.25, 536898.25, 187941.75, 536898.25, 187926.25, - 536898.25, 188145.75, 536898.25, 187936.75, 536898.25, 188085.75, 536898.25, 187968.25, - 536898.25, 187931.25, 536898.25, 188059.75, 536898.25, 188074.75, 536898.25, 187962.75, - 536898.25, 188135.25, 536898.25, 187965.25, 536898.25, 187926.75, 536898.25, 188132.25, - 536898.25, 187930.25, 536898.25, 188117.75, 536898.25, 188053.75, 536898.25, 187986.75, - 536898.25, 187970.25, 536898.25, 188152.75, 536898.25, 188143.75, 536898.25, 188056.25, - 536898.25, 188134.75, 536898.25, 187988.25, 536898.25, 187949.25, 536898.25, 188068.75, - 536898.25, 188002.75, 536898.25, 188003.25, 536898.25, 188005.75, 536898.25, 188134.25, - 536898.25, 187927.25, 536898.25, 188116.75, 536898.25, 187937.25, 536898.25, 188088.75, - 536898.25, 188142.25, 536898.25, 188049.25, 536898.25, 188045.75, 536898.25, 187948.75, - 536898.25, 188055.75, 536898.25, 188132.75, 536898.25, 188038.25, 536898.25, 187987.75, - 536898.75, 187950.75, 536898.75, 188013.75, 536898.75, 187936.75, 536898.75, 188014.25, - 536898.75, 188012.25, 536898.75, 188072.75, 536898.75, 187968.75, 536898.75, 188144.25, - 536898.75, 187920.25, 536898.75, 187916.75, 536898.75, 188006.25, 536898.75, 188014.75, - 536898.75, 187912.25, 536898.75, 188038.25, 536898.75, 187987.75, 536898.75, 187948.75, - 536898.75, 188055.75, 536898.75, 188067.25, 536898.75, 188045.75, 536898.75, 188131.75, - 536898.75, 188044.25, 536898.75, 188011.25, 536898.75, 187922.75, 536898.75, 188154.25, - 536898.75, 188142.25, 536898.75, 187967.75, 536898.75, 188067.75, 536898.75, 188015.25, - 536898.75, 188010.25, 536898.75, 188158.75, 536898.75, 187998.75, 536898.75, 187917.75, - 536898.75, 188136.75, 536898.75, 187937.25, 536898.75, 188117.25, 536898.75, 188060.25, - 536898.75, 188149.75, 536898.75, 188113.25, 536898.75, 188156.75, 536898.75, 188116.75, - 536898.75, 188050.75, 536898.75, 188015.75, 536898.75, 188132.75, 536898.75, 187966.75, - 536898.75, 187913.75, 536898.75, 188076.75, 536898.75, 188153.25, 536898.75, 188076.25, - 536898.75, 188003.25, 536898.75, 188059.25, 536898.75, 188055.25, 536898.75, 187935.75, - 536898.75, 187963.75, 536898.75, 188083.75, 536898.75, 188145.25, 536898.75, 188143.25, - 536898.75, 188084.75, 536898.75, 187984.75, 536898.75, 187952.75, 536898.75, 188039.25, - 536898.75, 188104.25, 536898.75, 187949.75, 536898.75, 187923.25, 536898.75, 187930.75, - 536898.75, 188005.25, 536898.75, 187998.25, 536898.75, 188054.75, 536898.75, 187988.25, - 536898.75, 187985.75, 536898.75, 188085.25, 536898.75, 188145.75, 536898.75, 187926.25, - 536898.75, 188134.75, 536898.75, 188038.75, 536898.75, 187929.25, 536898.75, 188085.75, - 536898.75, 188075.25, 536898.75, 187961.75, 536898.75, 188115.25, 536898.75, 188056.25, - 536898.75, 188143.75, 536898.75, 187931.25, 536898.75, 188059.75, 536898.75, 188074.75, - 536898.75, 187986.75, 536898.75, 187926.75, 536898.75, 188135.25, 536898.75, 188037.25, - 536898.75, 188002.25, 536898.75, 188049.75, 536898.75, 188132.25, 536899.25, 187964.75, - 536899.25, 188146.25, 536899.25, 188147.25, 536899.25, 188054.25, 536899.25, 187930.25, - 536899.25, 188053.75, 536899.25, 188015.25, 536899.25, 188011.25, 536899.25, 187912.75, - 536899.25, 187927.75, 536899.25, 188045.25, 536899.25, 188010.25, 536899.25, 188037.25, - 536899.25, 187937.25, 536899.25, 188159.25, 536899.25, 188135.25, 536899.25, 187932.75, - 536899.25, 188114.25, 536899.25, 188115.75, 536899.25, 187987.25, 536899.25, 187992.25, - 536899.25, 187933.75, 536899.25, 187985.25, 536899.25, 187962.75, 536899.25, 188060.25, - 536899.25, 188149.25, 536899.25, 188130.25, 536899.25, 187936.25, 536899.25, 188074.25, - 536899.25, 188144.75, 536899.25, 188136.75, 536899.25, 188059.75, 536899.25, 188065.75, - 536899.25, 188003.25, 536899.25, 188115.25, 536899.25, 188075.25, 536899.25, 188089.25, - 536899.25, 187932.25, 536899.25, 188133.25, 536899.25, 188073.25, 536899.25, 188011.75, - 536899.25, 188014.75, 536899.25, 188158.25, 536899.25, 187962.25, 536899.25, 188006.75, - 536899.25, 187929.25, 536899.25, 187913.75, 536899.25, 187995.75, 536899.25, 187915.75, - 536899.25, 188134.75, 536899.25, 188136.25, 536899.25, 188008.75, 536899.25, 188155.25, - 536899.25, 188053.25, 536899.25, 187983.75, 536899.25, 188032.75, 536899.25, 188141.75, - 536899.25, 188037.75, 536899.25, 187949.25, 536899.25, 187916.75, 536899.25, 187917.25, - 536899.25, 188130.75, 536899.25, 188131.25, 536899.25, 187950.75, 536899.25, 188026.75, - 536899.25, 187968.75, 536899.25, 188068.75, 536899.25, 188002.75, 536899.25, 187931.75, - 536899.25, 188074.75, 536899.25, 188071.25, 536899.25, 188109.75, 536899.25, 188066.75, - 536899.25, 188060.75, 536899.25, 187984.75, 536899.25, 188050.25, 536899.25, 188012.75, - 536899.25, 188084.75, 536899.75, 188129.25, 536899.75, 188128.75, 536899.75, 188084.25, - 536899.75, 188012.75, 536899.75, 188150.25, 536899.75, 188050.25, 536899.75, 188014.25, - 536899.75, 188073.75, 536899.75, 187955.25, 536899.75, 188060.75, 536899.75, 188037.75, - 536899.75, 188143.25, 536899.75, 187985.25, 536899.75, 188053.75, 536899.75, 188070.25, - 536899.75, 187983.25, 536899.75, 188002.75, 536899.75, 188064.75, 536899.75, 187917.25, - 536899.75, 188083.75, 536899.75, 188051.75, 536899.75, 188036.25, 536899.75, 187980.25, - 536899.75, 188007.25, 536899.75, 188130.75, 536899.75, 188114.25, 536899.75, 187930.75, - 536899.75, 188134.75, 536899.75, 188069.25, 536899.75, 187910.75, 536899.75, 188072.75, - 536899.75, 188009.25, 536899.75, 187988.25, 536899.75, 188151.75, 536899.75, 188005.75, - 536899.75, 187950.25, 536899.75, 187951.25, 536899.75, 187927.25, 536899.75, 188113.75, - 536899.75, 188071.25, 536899.75, 188068.25, 536899.75, 188052.75, 536899.75, 187933.25, - 536899.75, 188061.25, 536899.75, 187913.25, 536899.75, 188083.25, 536899.75, 188135.75, - 536899.75, 187920.25, 536899.75, 187934.75, 536899.75, 188136.25, 536899.75, 187929.75, - 536899.75, 188006.25, 536899.75, 188009.75, 536899.75, 188064.25, 536899.75, 187926.25, - 536899.75, 187962.25, 536899.75, 187969.75, 536899.75, 187942.25, 536899.75, 187999.25, - 536899.75, 188008.25, 536899.75, 188003.75, 536899.75, 187936.75, 536899.75, 188073.25, - 536899.75, 187984.25, 536899.75, 187914.25, 536899.75, 187932.25, 536899.75, 188160.25, - 536899.75, 188139.25, 536899.75, 187961.75, 536899.75, 188147.75, 536899.75, 188013.25, - 536899.75, 187920.75, 536899.75, 187937.75, 536899.75, 187969.25, 536899.75, 188046.75, - 536899.75, 188129.75, 536899.75, 188046.25, 536899.75, 188060.25, 536899.75, 187951.75, - 536899.75, 187917.75, 536899.75, 188130.25, 536899.75, 188149.25, 536899.75, 188080.25, - 536899.75, 187962.75, 536899.75, 187987.25, 536899.75, 188051.25, 536899.75, 187928.75, - 536899.75, 187933.75, 536899.75, 187968.25, 536899.75, 187943.25, 536899.75, 188159.25, - 536899.75, 188045.25, 536899.75, 188147.25, 536899.75, 187922.75, 536899.75, 188148.75, - 536899.75, 187914.75, 536899.75, 188148.25, 536899.75, 187990.75, 536899.75, 187997.75, - 536899.75, 187974.25, 536899.75, 188054.25, 536899.75, 188137.25, 536899.75, 188126.75, - 536899.75, 188010.75, 536899.75, 188144.75, 536899.75, 188001.25, 536900.25, 188157.25, - 536900.25, 188010.75, 536900.25, 188098.75, 536900.25, 188148.25, 536900.25, 187976.25, - 536900.25, 188082.25, 536900.25, 187933.75, 536900.25, 187975.75, 536900.25, 187937.25, - 536900.25, 188045.75, 536900.25, 187981.75, 536900.25, 187915.75, 536900.25, 187943.75, - 536900.25, 188063.75, 536900.25, 187951.75, 536900.25, 187987.25, 536900.25, 188065.75, - 536900.25, 188136.75, 536900.25, 187920.75, 536900.25, 188147.75, 536900.25, 187932.25, - 536900.25, 188053.75, 536900.25, 187914.25, 536900.25, 188072.75, 536900.25, 187999.25, - 536900.25, 188052.75, 536900.25, 187913.25, 536900.25, 188009.75, 536900.25, 187920.25, - 536900.25, 187983.75, 536900.25, 187983.25, 536900.25, 188068.25, 536900.25, 187933.25, - 536900.25, 188136.25, 536900.25, 187984.25, 536900.25, 187935.75, 536900.25, 188009.25, - 536900.25, 188006.25, 536900.25, 188151.75, 536900.25, 187996.25, 536900.25, 187919.75, - 536900.25, 188036.25, 536900.25, 188051.75, 536900.25, 188004.25, 536900.25, 188065.25, - 536900.25, 188083.75, 536900.25, 188012.75, 536900.25, 188145.25, 536900.25, 188129.25, - 536900.25, 188060.75, 536900.25, 188128.25, 536900.25, 188150.25, 536900.25, 188084.25, - 536900.25, 187917.25, 536900.25, 188066.25, 536900.25, 188073.75, 536900.25, 187984.75, - 536900.25, 188005.75, 536900.25, 188159.75, 536900.25, 187950.75, 536900.25, 187949.75, - 536900.25, 187929.75, 536900.25, 187927.25, 536900.25, 187962.25, 536900.25, 187985.75, - 536900.25, 188145.75, 536900.25, 188143.75, 536900.25, 187969.75, 536900.25, 187929.25, - 536900.25, 188129.75, 536900.25, 188158.25, 536900.25, 187934.75, 536900.25, 187936.75, - 536900.25, 187961.75, 536900.25, 188008.25, 536900.25, 188074.25, 536900.25, 188130.25, - 536900.25, 187928.75, 536900.25, 188013.75, 536900.25, 188148.75, 536900.25, 187962.75, - 536900.25, 188025.25, 536900.25, 187930.25, 536900.25, 188147.25, 536900.25, 188135.25, - 536900.25, 188037.25, 536900.25, 188002.25, 536900.25, 187968.25, 536900.25, 188050.75, - 536900.75, 188062.75, 536900.75, 188003.25, 536900.75, 187929.75, 536900.75, 188069.75, - 536900.75, 188144.75, 536900.75, 187914.75, 536900.75, 188128.25, 536900.75, 188085.75, - 536900.75, 187928.25, 536900.75, 188061.25, 536900.75, 187994.75, 536900.75, 188036.75, - 536900.75, 187952.25, 536900.75, 188059.75, 536900.75, 188008.75, 536900.75, 188159.25, - 536900.75, 187932.75, 536900.75, 187969.25, 536900.75, 188082.25, 536900.75, 187926.25, - 536900.75, 188013.75, 536900.75, 188063.25, 536900.75, 188143.75, 536900.75, 187964.25, - 536900.75, 188091.25, 536900.75, 187912.75, 536900.75, 188146.25, 536900.75, 187962.75, - 536900.75, 188158.75, 536900.75, 188051.25, 536900.75, 188013.25, 536900.75, 187968.25, - 536900.75, 188149.25, 536900.75, 187936.75, 536900.75, 188149.75, 536900.75, 187927.75, - 536900.75, 188007.75, 536900.75, 187937.75, 536900.75, 188060.25, 536900.75, 187962.25, - 536900.75, 188145.25, 536900.75, 187950.75, 536900.75, 188072.25, 536900.75, 187982.75, - 536900.75, 188146.75, 536900.75, 188021.25, 536900.75, 188046.25, 536900.75, 188000.25, - 536900.75, 188082.75, 536900.75, 187950.25, 536900.75, 188081.75, 536900.75, 188136.75, - 536900.75, 188071.75, 536900.75, 188006.75, 536900.75, 188047.25, 536900.75, 188064.75, - 536900.75, 188093.25, 536900.75, 187932.25, 536900.75, 188068.75, 536900.75, 188005.25, - 536900.75, 187970.75, 536900.75, 188128.75, 536900.75, 188145.75, 536900.75, 187913.75, - 536900.75, 188046.75, 536900.75, 188004.75, 536900.75, 188037.75, 536900.75, 187983.75, - 536900.75, 188147.75, 536900.75, 188052.25, 536901.25, 188004.75, 536901.25, 187968.75, - 536901.25, 188147.75, 536901.25, 188037.75, 536901.25, 187963.75, 536901.25, 188081.25, - 536901.25, 188035.75, 536901.25, 187913.75, 536901.25, 187925.25, 536901.25, 187938.75, - 536901.25, 187935.25, 536901.25, 188060.75, 536901.25, 188052.75, 536901.25, 187951.25, - 536901.25, 187924.75, 536901.25, 187933.25, 536901.25, 187952.75, 536901.25, 188062.25, - 536901.25, 188127.75, 536901.25, 187920.25, 536901.25, 188014.25, 536901.25, 187938.25, - 536901.25, 188145.75, 536901.25, 188007.25, 536901.25, 188064.25, 536901.25, 188071.75, - 536901.25, 188127.25, 536901.25, 188136.25, 536901.25, 187970.25, 536901.25, 187966.75, - 536901.25, 188046.25, 536901.25, 188082.75, 536901.25, 188070.75, 536901.25, 187930.25, - 536901.25, 187921.25, 536901.25, 188037.25, 536901.25, 188145.25, 536901.25, 188007.75, - 536901.25, 188063.75, 536901.25, 188142.25, 536901.25, 187967.75, 536901.25, 188137.75, - 536901.25, 188140.25, 536901.25, 188142.75, 536901.25, 187926.75, 536901.25, 188013.25, - 536901.25, 187937.25, 536901.25, 188152.75, 536901.25, 187992.25, 536901.25, 187982.25, - 536901.25, 188143.75, 536901.25, 187931.25, 536901.25, 188138.25, 536901.25, 187963.25, - 536901.25, 188157.25, 536901.25, 188150.75, 536901.25, 188080.75, 536901.25, 188137.25, - 536901.25, 188069.25, 536901.25, 187914.75, 536901.25, 188157.75, 536901.25, 188125.25, - 536901.25, 188004.25, 536901.25, 187993.75, 536901.25, 187980.75, 536901.25, 187928.25, - 536901.25, 188159.25, 536901.25, 188072.75, 536901.25, 187981.75, 536901.25, 188097.25, - 536901.25, 188061.75, 536901.25, 188055.75, 536901.75, 187943.75, 536901.75, 188143.75, - 536901.75, 188059.75, 536901.75, 187981.75, 536901.75, 188072.75, 536901.75, 188069.75, - 536901.75, 188159.25, 536901.75, 188080.75, 536901.75, 188036.75, 536901.75, 188005.75, - 536901.75, 187914.75, 536901.75, 188150.75, 536901.75, 188069.25, 536901.75, 187932.25, - 536901.75, 188158.25, 536901.75, 188129.25, 536901.75, 188006.25, 536901.75, 187979.75, - 536901.75, 187932.75, 536901.75, 188013.75, 536901.75, 187963.25, 536901.75, 188158.75, - 536901.75, 188063.75, 536901.75, 188038.25, 536901.75, 187926.75, 536901.75, 187937.25, - 536901.75, 187968.25, 536901.75, 187949.75, 536901.75, 188013.25, 536901.75, 188137.75, - 536901.75, 188045.75, 536901.75, 187956.75, 536901.75, 187937.75, 536901.75, 187925.75, - 536901.75, 187951.75, 536901.75, 188088.75, 536901.75, 187915.75, 536901.75, 188149.25, - 536901.75, 188150.25, 536901.75, 188060.25, 536901.75, 187920.75, 536901.75, 187930.25, - 536901.75, 187969.75, 536901.75, 187929.25, 536901.75, 188037.25, 536901.75, 188156.75, - 536901.75, 188145.25, 536901.75, 188006.75, 536901.75, 188139.25, 536901.75, 187966.75, - 536901.75, 188071.75, 536901.75, 187962.25, 536901.75, 188126.75, 536901.75, 188145.75, - 536901.75, 188070.75, 536901.75, 187998.75, 536901.75, 188147.25, 536901.75, 188058.25, - 536901.75, 188060.75, 536901.75, 187951.25, 536901.75, 187938.75, 536901.75, 188047.25, - 536901.75, 187930.75, 536901.75, 187924.75, 536901.75, 188007.25, 536901.75, 188142.75, - 536901.75, 187913.75, 536901.75, 187983.75, 536901.75, 187938.25, 536901.75, 188051.75, - 536901.75, 188147.75, 536901.75, 187980.25, 536901.75, 188037.75, 536901.75, 187982.25, - 536901.75, 187952.75, 536901.75, 188061.75, 536901.75, 187925.25, 536901.75, 188155.75, - 536901.75, 188127.75, 536901.75, 188081.25, 536902.25, 188071.25, 536902.25, 187980.25, - 536902.25, 187930.75, 536902.25, 188037.75, 536902.25, 187970.75, 536902.25, 188142.75, - 536902.25, 188003.75, 536902.25, 188070.25, 536902.25, 187950.75, 536902.25, 188046.75, - 536902.25, 187910.75, 536902.25, 188014.75, 536902.25, 188136.25, 536902.25, 188151.25, - 536902.25, 188044.75, 536902.25, 188058.25, 536902.25, 188046.25, 536902.25, 187914.25, - 536902.25, 187982.75, 536902.25, 187938.75, 536902.25, 188070.75, 536902.25, 187960.75, - 536902.25, 188145.75, 536902.25, 188126.75, 536902.25, 188049.75, 536902.25, 188045.25, - 536902.25, 187924.25, 536902.25, 188028.75, 536902.25, 188154.75, 536902.25, 188006.75, - 536902.25, 187971.25, 536902.25, 188037.25, 536902.25, 187979.75, 536902.25, 188160.25, - 536902.25, 187965.75, 536902.25, 187916.25, 536902.25, 187925.75, 536902.25, 187951.75, - 536902.25, 187936.75, 536902.25, 187937.75, 536902.25, 188137.75, 536902.25, 188149.75, - 536902.25, 188038.25, 536902.25, 187962.75, 536902.25, 187963.25, 536902.25, 187979.25, - 536902.25, 187964.25, 536902.25, 187926.75, 536902.25, 187931.25, 536902.25, 188138.25, - 536902.25, 188095.75, 536902.25, 188148.25, 536902.25, 188159.25, 536902.25, 188061.25, - 536902.25, 187977.75, 536902.25, 188006.25, 536902.25, 188005.75, 536902.25, 187952.25, - 536902.25, 188125.25, 536902.25, 188015.25, 536902.25, 188157.25, 536902.25, 188154.25, - 536902.25, 188144.75, 536902.25, 187914.75, 536902.25, 187981.25, 536902.25, 188061.75, - 536902.25, 188157.75, 536902.25, 188058.75, 536902.25, 187925.25, 536902.75, 188144.25, - 536902.75, 187953.75, 536902.75, 187981.25, 536902.75, 187914.75, 536902.75, 188080.75, - 536902.75, 188138.25, 536902.75, 187964.75, 536902.75, 188146.25, 536902.75, 187939.25, - 536902.75, 187924.25, 536902.75, 188000.25, 536902.75, 188039.75, 536902.75, 188058.25, - 536902.75, 188014.25, 536902.75, 188115.25, 536902.75, 188062.75, 536902.75, 187982.25, - 536902.75, 187923.25, 536902.75, 187963.75, 536902.75, 188004.75, 536902.75, 187924.75, - 536902.75, 188029.75, 536902.75, 187915.25, 536902.75, 187951.25, 536902.75, 188039.25, - 536902.75, 187914.25, 536902.75, 188081.75, 536902.75, 188057.75, 536902.75, 188002.25, - 536902.75, 188156.25, 536902.75, 187939.75, 536902.75, 187953.25, 536902.75, 188138.75, - 536902.75, 187925.75, 536902.75, 188152.75, 536902.75, 188044.25, 536902.75, 188145.25, - 536902.75, 187979.25, 536902.75, 187990.75, 536902.75, 188045.25, 536902.75, 187993.75, - 536902.75, 187923.75, 536902.75, 188157.75, 536902.75, 188058.75, 536902.75, 188126.75, - 536902.75, 188134.25, 536902.75, 188153.75, 536902.75, 188042.25, 536902.75, 187978.75, - 536902.75, 188003.25, 536902.75, 188143.75, 536902.75, 188154.25, 536902.75, 187980.75, - 536902.75, 188015.25, 536902.75, 188151.25, 536902.75, 188038.25, 536902.75, 188149.75, - 536902.75, 187977.25, 536902.75, 187921.75, 536902.75, 187915.75, 536902.75, 188113.25, - 536902.75, 188136.75, 536902.75, 187965.75, 536902.75, 188145.75, 536902.75, 187935.75, - 536902.75, 188151.75, 536902.75, 188002.75, 536902.75, 187927.25, 536902.75, 188044.75, - 536902.75, 188155.25, 536902.75, 188116.25, 536902.75, 188155.75, 536902.75, 187938.25, - 536902.75, 188125.75, 536903.25, 188061.75, 536903.25, 187952.75, 536903.25, 188151.75, - 536903.25, 187938.25, 536903.25, 188137.25, 536903.25, 187999.75, 536903.25, 188116.25, - 536903.25, 188127.75, 536903.25, 188113.75, 536903.25, 188155.75, 536903.25, 187914.75, - 536903.25, 188138.25, 536903.25, 188043.75, 536903.25, 188044.75, 536903.25, 188033.25, - 536903.25, 188155.25, 536903.25, 187939.25, 536903.25, 187924.25, 536903.25, 188146.25, - 536903.25, 188002.75, 536903.25, 188150.75, 536903.25, 187962.25, 536903.25, 188058.25, - 536903.25, 187981.25, 536903.25, 188014.25, 536903.25, 188145.75, 536903.25, 188003.75, - 536903.25, 188136.75, 536903.25, 188081.25, 536903.25, 188062.75, 536903.25, 187935.25, - 536903.25, 187971.25, 536903.25, 187980.25, 536903.25, 188004.75, 536903.25, 187926.25, - 536903.25, 187924.75, 536903.25, 187977.25, 536903.25, 187966.25, 536903.25, 187963.75, - 536903.25, 187915.25, 536903.25, 188056.75, 536903.25, 187951.25, 536903.25, 187927.75, - 536903.25, 188043.25, 536903.25, 188135.75, 536903.25, 188085.25, 536903.25, 188154.75, - 536903.25, 187922.75, 536903.25, 187998.25, 536903.25, 187965.25, 536903.25, 188156.25, - 536903.25, 187978.25, 536903.25, 187938.75, 536903.25, 187963.25, 536903.25, 188057.75, - 536903.25, 188149.75, 536903.25, 188095.25, 536903.25, 188038.25, 536903.25, 188138.75, - 536903.25, 188045.25, 536903.25, 188037.25, 536903.25, 188145.25, 536903.25, 188061.25, - 536903.25, 187918.25, 536903.25, 187994.75, 536903.25, 187979.25, 536903.25, 187945.25, - 536903.25, 187916.25, 536903.25, 187923.75, 536903.25, 188126.75, 536903.25, 187928.25, - 536903.25, 188132.25, 536903.25, 188003.25, 536903.25, 188151.25, 536903.25, 188067.75, - 536903.25, 188015.25, 536903.25, 188143.75, 536903.25, 187980.75, 536903.25, 187981.75, - 536903.25, 188154.25, 536903.25, 188077.75, 536903.75, 188154.75, 536903.75, 188154.25, - 536903.75, 188062.25, 536903.75, 187975.75, 536903.75, 188057.25, 536903.75, 188117.25, - 536903.75, 188145.25, 536903.75, 188114.25, 536903.75, 187916.25, 536903.75, 188003.25, - 536903.75, 188113.75, 536903.75, 188043.75, 536903.75, 188001.25, 536903.75, 188082.25, - 536903.75, 187932.25, 536903.75, 187917.75, 536903.75, 188042.25, 536903.75, 188002.75, - 536903.75, 188128.25, 536903.75, 187919.25, 536903.75, 187923.75, 536903.75, 187995.75, - 536903.75, 188006.25, 536903.75, 188048.75, 536903.75, 188127.25, 536903.75, 187993.75, - 536903.75, 188041.75, 536903.75, 188137.25, 536903.75, 187970.75, 536903.75, 188152.25, - 536903.75, 188056.25, 536903.75, 187978.75, 536903.75, 187953.75, 536903.75, 187923.25, - 536903.75, 188063.25, 536903.75, 187977.75, 536903.75, 188139.25, 536903.75, 187989.75, - 536903.75, 187935.25, 536903.75, 187933.75, 536903.75, 188150.25, 536903.75, 188015.75, - 536903.75, 187953.25, 536903.75, 187964.25, 536903.75, 188009.25, 536903.75, 188136.25, - 536903.75, 188038.25, 536903.75, 187915.75, 536903.75, 188056.75, 536903.75, 188146.75, - 536903.75, 187963.75, 536903.75, 187921.75, 536903.75, 187927.75, 536903.75, 187918.25, - 536903.75, 187940.25, 536903.75, 187951.75, 536903.75, 188002.25, 536903.75, 187939.75, - 536903.75, 188014.75, 536903.75, 188039.25, 536903.75, 187976.25, 536903.75, 187922.75, - 536904.25, 187951.75, 536904.25, 188015.25, 536904.25, 188154.75, 536904.25, 188081.75, - 536904.25, 187974.75, 536904.25, 188000.75, 536904.25, 187985.75, 536904.25, 187939.75, - 536904.25, 188014.75, 536904.25, 188148.25, 536904.25, 187940.25, 536904.25, 187963.75, - 536904.25, 187921.75, 536904.25, 187971.75, 536904.25, 187922.25, 536904.25, 187976.75, - 536904.25, 187964.25, 536904.25, 187986.75, 536904.25, 188041.25, 536904.25, 188015.75, - 536904.25, 188126.25, 536904.25, 187915.75, 536904.25, 188137.75, 536904.25, 188150.75, - 536904.25, 187953.25, 536904.25, 188062.75, 536904.25, 188082.75, 536904.25, 188152.75, - 536904.25, 188153.25, 536904.25, 188042.75, 536904.25, 188040.75, 536904.25, 188158.25, - 536904.25, 188038.75, 536904.25, 187984.25, 536904.25, 188115.25, 536904.25, 187940.75, - 536904.25, 188145.75, 536904.25, 188056.25, 536904.25, 188042.25, 536904.25, 187952.75, - 536904.25, 188126.75, 536904.25, 187919.25, 536904.25, 188039.75, 536904.25, 187923.75, - 536904.25, 188001.25, 536904.25, 187952.25, 536904.25, 188112.75, 536904.25, 188000.25, - 536904.25, 188153.75, 536904.25, 188001.75, 536904.25, 187916.75, 536904.25, 187921.25, - 536904.25, 188031.25, 536904.25, 188063.75, 536904.25, 188057.25, 536904.25, 188148.75, - 536904.25, 187964.75, 536904.25, 188138.25, 536904.25, 188063.25, 536904.25, 187975.75, - 536904.25, 187954.25, 536904.25, 188116.25, 536904.25, 188144.25, 536904.25, 187918.75, - 536904.25, 188127.75, 536904.75, 187918.75, 536904.75, 187986.75, 536904.75, 187977.75, - 536904.75, 187939.25, 536904.75, 188145.25, 536904.75, 187952.75, 536904.75, 188116.25, - 536904.75, 188151.25, 536904.75, 187952.25, 536904.75, 188073.75, 536904.75, 188056.25, - 536904.75, 188062.75, 536904.75, 188059.75, 536904.75, 187967.25, 536904.75, 188114.75, - 536904.75, 187971.75, 536904.75, 187919.25, 536904.75, 187911.25, 536904.75, 188042.25, - 536904.75, 187971.25, 536904.75, 188026.75, 536904.75, 188000.25, 536904.75, 187915.75, - 536904.75, 187938.25, 536904.75, 188041.25, 536904.75, 187976.75, 536904.75, 188136.25, - 536904.75, 188123.25, 536904.75, 187932.25, 536904.75, 188089.25, 536904.75, 188139.25, - 536904.75, 187921.25, 536904.75, 188015.75, 536904.75, 187964.25, 536904.75, 187986.25, - 536904.75, 188001.75, 536904.75, 187954.25, 536904.75, 188082.75, 536904.75, 187974.25, - 536904.75, 188049.25, 536904.75, 187960.25, 536904.75, 188063.25, 536904.75, 188015.25, - 536904.75, 188145.75, 536904.75, 187975.75, 536904.75, 188154.25, 536904.75, 188038.75, - 536904.75, 188040.75, 536904.75, 188153.75, 536904.75, 188112.75, 536904.75, 188057.75, - 536904.75, 188081.75, 536904.75, 188146.75, 536904.75, 188160.25, 536904.75, 188014.75, - 536904.75, 188149.25, 536904.75, 187940.75, 536904.75, 187975.25, 536904.75, 188039.75, - 536904.75, 188001.25, 536904.75, 187916.75, 536904.75, 187910.75, 536904.75, 187923.75, - 536904.75, 188060.75, 536904.75, 187945.25, 536904.75, 187994.75, 536904.75, 187936.75, - 536904.75, 187922.25, 536904.75, 188137.75, 536904.75, 188153.25, 536904.75, 188122.75, - 536904.75, 187999.75, 536904.75, 188144.25, 536904.75, 188154.75, 536905.25, 188126.75, - 536905.25, 187926.75, 536905.25, 188154.75, 536905.25, 188137.25, 536905.25, 188040.75, - 536905.25, 188063.75, 536905.25, 188042.75, 536905.25, 187977.75, 536905.25, 188138.75, - 536905.25, 188151.25, 536905.25, 187993.75, 536905.25, 187995.25, 536905.25, 187933.25, - 536905.25, 188154.25, 536905.25, 188074.75, 536905.25, 187953.75, 536905.25, 187918.25, - 536905.25, 187926.25, 536905.25, 187999.25, 536905.25, 187980.75, 536905.25, 187918.75, - 536905.25, 188097.25, 536905.25, 188056.75, 536905.25, 188014.75, 536905.25, 188082.25, - 536905.25, 188149.75, 536905.25, 188075.25, 536905.25, 187973.25, 536905.25, 188127.25, - 536905.25, 187940.25, 536905.25, 188144.75, 536905.25, 188059.75, 536905.25, 188040.25, - 536905.25, 187920.75, 536905.25, 187921.25, 536905.25, 187965.25, 536905.25, 188092.75, - 536905.25, 188119.75, 536905.25, 188013.25, 536905.25, 188039.75, 536905.25, 187946.25, - 536905.25, 187974.75, 536905.25, 187937.25, 536905.25, 188013.75, 536905.25, 187985.75, - 536905.25, 188120.25, 536905.25, 187917.25, 536905.25, 187923.75, 536905.25, 187976.25, - 536905.25, 188138.25, 536905.25, 188122.75, 536905.25, 188113.75, 536905.25, 187972.25, - 536905.25, 188151.75, 536905.25, 187922.75, 536905.25, 188137.75, 536905.25, 188083.25, - 536905.25, 187953.25, 536905.25, 188127.75, 536905.25, 187938.75, 536905.25, 188014.25, - 536905.25, 188057.25, 536905.25, 188039.25, 536905.25, 187919.75, 536905.25, 188114.25, - 536905.25, 188042.25, 536905.25, 188016.25, 536905.25, 187924.25, 536905.25, 187936.75, - 536905.25, 188000.25, 536905.75, 188064.25, 536905.75, 187915.75, 536905.75, 188014.25, - 536905.75, 187965.75, 536905.75, 187972.75, 536905.75, 188130.25, 536905.75, 188058.25, - 536905.75, 188130.75, 536905.75, 187919.25, 536905.75, 188043.75, 536905.75, 187938.25, - 536905.75, 187935.75, 536905.75, 187955.25, 536905.75, 187925.25, 536905.75, 188137.75, - 536905.75, 188118.25, 536905.75, 188154.75, 536905.75, 187983.75, 536905.75, 188081.25, - 536905.75, 188138.25, 536905.75, 187927.75, 536905.75, 187924.75, 536905.75, 188016.75, - 536905.75, 188113.75, 536905.75, 187921.75, 536905.75, 188114.75, 536905.75, 188131.75, - 536905.75, 187976.25, 536905.75, 188121.75, 536905.75, 188120.25, 536905.75, 188075.75, - 536905.75, 187937.25, 536905.75, 188039.75, 536905.75, 187916.75, 536905.75, 187998.75, - 536905.75, 188158.75, 536905.75, 187984.25, 536905.75, 188123.25, 536905.75, 188012.25, - 536905.75, 188058.75, 536905.75, 188159.75, 536905.75, 188119.75, 536905.75, 188064.75, - 536905.75, 187999.75, 536905.75, 187974.75, 536905.75, 187937.75, 536905.75, 187923.25, - 536905.75, 187988.25, 536905.75, 188131.25, 536905.75, 187973.75, 536905.75, 187964.75, - 536905.75, 187980.25, 536905.75, 187987.75, 536905.75, 188012.75, 536905.75, 188082.75, - 536905.75, 188080.75, 536905.75, 188149.75, 536905.75, 187974.25, 536905.75, 188079.25, - 536905.75, 188073.75, 536905.75, 188075.25, 536905.75, 188063.25, 536905.75, 188013.25, - 536905.75, 187939.75, 536905.75, 188043.25, 536905.75, 188015.25, 536905.75, 187926.25, - 536905.75, 188152.75, 536905.75, 187918.75, 536905.75, 187953.75, 536905.75, 188074.75, - 536905.75, 188003.25, 536905.75, 187954.75, 536905.75, 187997.75, 536905.75, 188150.75, - 536905.75, 187952.75, 536905.75, 187994.75, 536905.75, 188119.25, 536905.75, 188123.75, - 536905.75, 188115.75, 536905.75, 188057.75, 536905.75, 187941.25, 536905.75, 187916.25, - 536905.75, 188122.25, 536905.75, 188159.25, 536905.75, 188153.75, 536905.75, 187985.25, - 536906.25, 188057.75, 536906.25, 188153.75, 536906.25, 188159.25, 536906.25, 188074.25, - 536906.25, 187974.25, 536906.25, 187926.75, 536906.25, 188109.25, 536906.25, 188123.25, - 536906.25, 187917.75, 536906.25, 187916.25, 536906.25, 187955.75, 536906.25, 187918.75, - 536906.25, 188138.75, 536906.25, 187939.25, 536906.25, 188062.75, 536906.25, 188087.25, - 536906.25, 188150.75, 536906.25, 187939.75, 536906.25, 188074.75, 536906.25, 187997.75, - 536906.25, 187926.25, 536906.25, 187952.25, 536906.25, 188080.75, 536906.25, 187995.25, - 536906.25, 188075.25, 536906.25, 188145.75, 536906.25, 187983.25, 536906.25, 188011.75, - 536906.25, 188012.75, 536906.25, 187954.75, 536906.25, 188081.75, 536906.25, 188148.25, - 536906.25, 188073.75, 536906.25, 188127.25, 536906.25, 188157.25, 536906.25, 188152.75, - 536906.25, 187918.25, 536906.25, 187987.75, 536906.25, 187985.25, 536906.25, 188013.25, - 536906.25, 188118.75, 536906.25, 187964.75, 536906.25, 187996.75, 536906.25, 187923.25, - 536906.25, 188055.75, 536906.25, 187941.25, 536906.25, 188097.25, 536906.25, 187999.75, - 536906.25, 188013.75, 536906.25, 187920.75, 536906.25, 188130.75, 536906.25, 188131.25, - 536906.25, 188082.25, 536906.25, 188014.75, 536906.25, 187919.75, 536906.25, 188127.75, - 536906.25, 187940.75, 536906.25, 187953.25, 536906.25, 187922.25, 536906.25, 188149.75, - 536906.25, 188154.75, 536906.25, 188130.25, 536906.25, 187911.75, 536906.25, 188042.25, - 536906.25, 187924.25, 536906.25, 187965.75, 536906.25, 188144.75, 536906.25, 188060.25, - 536906.25, 187915.75, 536906.25, 187972.75, 536906.25, 188073.25, 536906.25, 188063.75, - 536906.25, 188064.25, 536906.25, 188114.25, 536906.25, 187937.75, 536906.25, 187975.25, - 536906.25, 188138.25, 536906.25, 187976.75, 536906.25, 187917.25, 536906.25, 187938.25, - 536906.25, 188136.25, 536906.25, 187971.25, 536906.25, 187935.75, 536906.25, 187924.75, - 536906.25, 187922.75, 536906.25, 188081.25, 536906.25, 188015.75, 536906.25, 188012.25, - 536906.25, 187983.75, 536906.25, 188137.75, 536906.25, 188113.75, 536906.25, 188054.25, - 536906.25, 187914.25, 536906.25, 187923.75, 536906.25, 187916.75, 536906.25, 187928.75, - 536906.25, 187998.75, 536906.25, 187937.25, 536906.25, 188158.75, 536906.75, 187914.25, - 536906.75, 188080.25, 536906.75, 188120.25, 536906.75, 188159.25, 536906.75, 187917.75, - 536906.75, 188076.25, 536906.75, 187998.75, 536906.75, 188158.25, 536906.75, 187932.25, - 536906.75, 187923.75, 536906.75, 188010.25, 536906.75, 187955.75, 536906.75, 187996.25, - 536906.75, 188137.75, 536906.75, 188157.25, 536906.75, 188157.75, 536906.75, 187997.25, - 536906.75, 187939.75, 536906.75, 187928.25, 536906.75, 188124.25, 536906.75, 187941.75, - 536906.75, 188001.25, 536906.75, 188012.75, 536906.75, 187965.25, 536906.75, 188080.75, - 536906.75, 188118.25, 536906.75, 188081.25, 536906.75, 187927.75, 536906.75, 188129.75, - 536906.75, 187987.25, 536906.75, 187955.25, 536906.75, 187936.25, 536906.75, 187966.25, - 536906.75, 187995.25, 536906.75, 188058.25, 536906.75, 188043.25, 536906.75, 188073.75, - 536906.75, 188128.75, 536906.75, 188152.75, 536906.75, 187995.75, 536906.75, 187935.25, - 536906.75, 187973.75, 536906.75, 187996.75, 536906.75, 188099.75, 536906.75, 187923.25, - 536906.75, 187915.25, 536906.75, 188153.25, 536906.75, 187930.25, 536906.75, 188013.75, - 536906.75, 188016.25, 536906.75, 188048.25, 536906.75, 188119.75, 536906.75, 188073.25, - 536906.75, 187954.25, 536906.75, 188043.75, 536906.75, 187972.75, 536906.75, 187937.75, - 536906.75, 188121.75, 536906.75, 187927.25, 536906.75, 188071.75, 536906.75, 188079.75, - 536906.75, 187988.25, 536906.75, 188011.25, 536906.75, 187940.25, 536906.75, 188131.75, - 536906.75, 188079.25, 536906.75, 188154.75, 536906.75, 187917.25, 536906.75, 188063.25, - 536906.75, 187925.75, 536906.75, 188122.75, 536906.75, 188062.75, 536906.75, 187953.25, - 536907.25, 187929.25, 536907.25, 187989.25, 536907.25, 188062.75, 536907.25, 188154.25, - 536907.25, 188137.25, 536907.25, 188010.75, 536907.25, 188078.25, 536907.25, 187919.25, - 536907.25, 188153.25, 536907.25, 188127.75, 536907.25, 188117.75, 536907.25, 188009.75, - 536907.25, 187988.25, 536907.25, 188011.25, 536907.25, 187955.25, 536907.25, 188131.75, - 536907.25, 187992.75, 536907.25, 187937.75, 536907.25, 188156.25, 536907.25, 187941.25, - 536907.25, 188075.75, 536907.25, 188044.75, 536907.25, 187966.75, 536907.25, 188030.75, - 536907.25, 188116.75, 536907.25, 188063.25, 536907.25, 188035.75, 536907.25, 188154.75, - 536907.25, 187920.75, 536907.25, 187965.25, 536907.25, 188160.25, 536907.25, 188058.25, - 536907.25, 187973.75, 536907.25, 187935.25, 536907.25, 188071.25, 536907.25, 187954.75, - 536907.25, 187913.25, 536907.25, 188127.25, 536907.25, 187914.75, 536907.25, 188139.75, - 536907.25, 187973.25, 536907.25, 188128.75, 536907.25, 188061.75, 536907.25, 187936.25, - 536907.25, 187938.25, 536907.25, 188136.25, 536907.25, 188011.75, 536907.25, 188072.25, - 536907.25, 188134.25, 536907.25, 187912.25, 536907.25, 188152.25, 536907.25, 188077.25, - 536907.25, 187925.25, 536907.25, 188061.25, 536907.25, 187963.75, 536907.25, 187995.25, - 536907.25, 187981.75, 536907.25, 187953.75, 536907.25, 188046.75, 536907.25, 188062.25, - 536907.25, 187988.75, 536907.25, 188013.75, 536907.25, 188129.25, 536907.25, 187938.75, - 536907.25, 188080.25, 536907.25, 188157.75, 536907.25, 188006.25, 536907.25, 187941.75, - 536907.25, 187946.75, 536907.25, 187997.25, 536907.25, 188159.25, 536907.25, 188058.75, - 536907.25, 188139.25, 536907.25, 188012.75, 536907.25, 188119.25, 536907.25, 187996.25, - 536907.25, 188157.25, 536907.25, 187934.75, 536907.25, 188086.25, 536907.25, 188078.75, - 536907.25, 188132.25, 536907.25, 187955.75, 536907.25, 188059.25, 536907.25, 188010.25, - 536907.25, 188123.75, 536907.25, 187926.75, 536907.25, 187916.75, 536907.25, 187910.75, - 536907.25, 187994.75, 536907.25, 188124.75, 536907.25, 187993.25, 536907.25, 187994.25, - 536907.25, 188120.25, 536907.75, 188012.75, 536907.75, 187954.75, 536907.75, 187920.75, - 536907.75, 188046.75, 536907.75, 187994.25, 536907.75, 187913.75, 536907.75, 188079.75, - 536907.75, 187927.75, 536907.75, 187987.25, 536907.75, 187916.25, 536907.75, 187926.75, - 536907.75, 187938.25, 536907.75, 188062.75, 536907.75, 188058.25, 536907.75, 188158.75, - 536907.75, 187912.75, 536907.75, 188012.25, 536907.75, 187983.75, 536907.75, 188062.25, - 536907.75, 187935.75, 536907.75, 188157.25, 536907.75, 188076.25, 536907.75, 187955.75, - 536907.75, 188043.25, 536907.75, 188059.25, 536907.75, 188131.25, 536907.75, 188155.25, - 536907.75, 187981.75, 536907.75, 187974.25, 536907.75, 187917.75, 536907.75, 188009.75, - 536907.75, 188013.25, 536907.75, 187973.75, 536907.75, 188053.75, 536907.75, 188046.25, - 536907.75, 188072.75, 536907.75, 188031.75, 536907.75, 188079.25, 536907.75, 188082.75, - 536907.75, 187965.75, 536907.75, 187989.25, 536907.75, 187928.25, 536907.75, 188127.75, - 536907.75, 187914.25, 536907.75, 188138.25, 536907.75, 188150.25, 536907.75, 188154.75, - 536907.75, 187933.75, 536907.75, 187927.25, 536907.75, 188002.75, 536907.75, 188010.25, - 536907.75, 188078.75, 536907.75, 187996.25, 536907.75, 187994.75, 536907.75, 188130.75, - 536907.75, 187934.75, 536907.75, 188008.75, 536907.75, 187941.75, 536907.75, 188129.25, - 536907.75, 187953.75, 536907.75, 187920.25, 536907.75, 188132.25, 536907.75, 187988.75, - 536907.75, 187992.25, 536907.75, 187992.75, 536907.75, 188010.75, 536907.75, 187995.75, - 536907.75, 188011.75, 536907.75, 187973.25, 536907.75, 188077.75, 536907.75, 188074.75, - 536907.75, 187915.25, 536907.75, 188128.75, 536907.75, 187940.75, 536907.75, 188156.25, - 536907.75, 188131.75, 536907.75, 188135.75, 536907.75, 187923.75, 536907.75, 187993.25, - 536907.75, 188043.75, 536907.75, 188116.25, 536907.75, 188070.25, 536907.75, 188127.25, - 536907.75, 188153.25, 536907.75, 188124.75, 536907.75, 188137.75, 536907.75, 188036.75, - 536907.75, 187938.75, 536907.75, 188078.25, 536907.75, 188139.75, 536907.75, 188095.25, - 536907.75, 188060.75, 536907.75, 188061.75, 536907.75, 188071.75, 536907.75, 188011.25, - 536907.75, 188119.75, 536907.75, 187972.75, 536907.75, 187926.25, 536908.25, 188044.25, - 536908.25, 188045.25, 536908.25, 188155.75, 536908.25, 187994.25, 536908.25, 187941.25, - 536908.25, 187955.25, 536908.25, 188120.75, 536908.25, 187916.25, 536908.25, 188127.25, - 536908.25, 188012.25, 536908.25, 187936.75, 536908.25, 188134.75, 536908.25, 188060.75, - 536908.25, 188070.75, 536908.25, 188118.25, 536908.25, 187937.25, 536908.25, 187972.25, - 536908.25, 188138.25, 536908.25, 187913.25, 536908.25, 188124.25, 536908.25, 188078.25, - 536908.25, 188009.25, 536908.25, 187966.25, 536908.25, 188125.75, 536908.25, 187973.75, - 536908.25, 187914.75, 536908.25, 187969.75, 536908.25, 188122.75, 536908.25, 188140.25, - 536908.25, 187922.25, 536908.25, 187936.25, 536908.25, 188156.25, 536908.25, 188008.25, - 536908.25, 188044.75, 536908.25, 187966.75, 536908.25, 188135.75, 536908.25, 188061.75, - 536908.25, 188070.25, 536908.25, 188043.75, 536908.25, 188059.75, 536908.25, 188128.25, - 536908.25, 188116.75, 536908.25, 187954.25, 536908.25, 188058.75, 536908.25, 188028.25, - 536908.25, 188131.75, 536908.25, 188036.25, 536908.25, 187937.75, 536908.25, 187942.25, - 536908.25, 187911.75, 536908.25, 187998.25, 536908.25, 188151.75, 536908.25, 188077.75, - 536908.25, 188014.75, 536908.25, 187928.25, 536908.25, 188015.25, 536908.25, 188136.75, - 536908.25, 187982.25, 536908.25, 187939.25, 536908.25, 187980.75, 536908.25, 187967.25, - 536908.25, 188069.75, 536908.25, 188077.25, 536908.25, 187992.25, 536908.25, 188152.75, - 536908.25, 187912.25, 536908.25, 187988.75, 536908.25, 188132.25, 536908.25, 188061.25, - 536908.25, 188125.25, 536908.25, 187993.75, 536908.25, 187935.25, 536908.25, 188032.25, - 536908.25, 188068.75, 536908.25, 187933.75, 536908.25, 187927.25, 536908.25, 188135.25, - 536908.25, 188085.25, 536908.25, 187918.75, 536908.25, 188153.75, 536908.25, 188118.75, - 536908.25, 187939.75, 536908.25, 187948.25, 536908.25, 187919.75, 536908.75, 188137.25, - 536908.75, 188013.75, 536908.75, 188125.25, 536908.75, 187926.25, 536908.75, 187941.75, - 536908.75, 188133.25, 536908.75, 187989.75, 536908.75, 187933.75, 536908.75, 188126.25, - 536908.75, 188008.75, 536908.75, 188007.25, 536908.75, 188122.25, 536908.75, 188007.75, - 536908.75, 187920.25, 536908.75, 187927.25, 536908.75, 188149.75, 536908.75, 188152.75, - 536908.75, 187940.25, 536908.75, 188154.25, 536908.75, 188006.75, 536908.75, 188016.75, - 536908.75, 187992.75, 536908.75, 188090.25, 536908.75, 188117.25, 536908.75, 187973.25, - 536908.75, 187939.25, 536908.75, 188105.75, 536908.75, 188011.75, 536908.75, 187996.75, - 536908.75, 187971.75, 536908.75, 187956.75, 536908.75, 188150.75, 536908.75, 187991.25, - 536908.75, 187928.25, 536908.75, 188076.75, 536908.75, 187936.75, 536908.75, 187911.75, - 536908.75, 187914.25, 536908.75, 188127.75, 536908.75, 187954.25, 536908.75, 188060.25, - 536908.75, 188132.75, 536908.75, 188131.75, 536908.75, 188117.75, 536908.75, 188036.25, - 536908.75, 188093.25, 536908.75, 187916.75, 536908.75, 188046.25, 536908.75, 188035.75, - 536908.75, 188116.25, 536908.75, 187928.75, 536908.75, 187967.75, 536908.75, 187942.75, - 536908.75, 188141.75, 536908.75, 188156.25, 536908.75, 187914.75, 536908.75, 188139.75, - 536908.75, 188123.25, 536908.75, 187937.25, 536908.75, 188009.25, 536908.75, 187970.25, - 536908.75, 187990.75, 536908.75, 187972.25, 536908.75, 188015.75, 536908.75, 188049.75, - 536908.75, 188159.75, 536908.75, 188059.25, 536908.75, 188136.25, 536908.75, 187955.75, - 536908.75, 188118.25, 536908.75, 188115.25, 536908.75, 188076.25, 536908.75, 188078.25, - 536908.75, 188069.25, 536908.75, 188045.75, 536908.75, 188101.75, 536908.75, 187991.75, - 536908.75, 188122.75, 536908.75, 188120.75, 536908.75, 188113.75, 536908.75, 188046.75, - 536908.75, 188119.75, 536908.75, 187972.75, 536908.75, 188126.75, 536908.75, 187941.25, - 536908.75, 187932.25, 536908.75, 188155.75, 536908.75, 187921.75, 536908.75, 187922.75, - 536908.75, 188068.25, 536909.25, 188069.25, 536909.25, 188012.75, 536909.25, 188126.75, - 536909.25, 187922.75, 536909.25, 188068.25, 536909.25, 187932.25, 536909.25, 188115.75, - 536909.25, 188158.75, 536909.25, 187926.75, 536909.25, 188113.75, 536909.25, 188154.75, - 536909.25, 188045.75, 536909.25, 187991.75, 536909.25, 187976.25, 536909.25, 187955.75, - 536909.25, 188123.25, 536909.25, 187942.25, 536909.25, 188076.25, 536909.25, 187914.25, - 536909.25, 187971.25, 536909.25, 188007.75, 536909.25, 188007.25, 536909.25, 188120.25, - 536909.25, 187996.25, 536909.25, 188136.25, 536909.25, 188059.25, 536909.25, 188151.25, - 536909.25, 187915.25, 536909.25, 187939.75, 536909.25, 187992.25, 536909.25, 188133.25, - 536909.25, 188131.75, 536909.25, 188116.25, 536909.25, 187967.75, 536909.25, 188159.75, - 536909.25, 188154.25, 536909.25, 188128.75, 536909.25, 187922.25, 536909.25, 188115.25, - 536909.25, 187955.25, 536909.25, 188122.75, 536909.25, 187913.25, 536909.25, 188029.25, - 536909.25, 187966.25, 536909.25, 188112.25, 536909.25, 188118.25, 536909.25, 187941.25, - 536909.25, 188046.75, 536909.25, 188018.25, 536909.25, 187972.25, 536909.25, 188044.75, - 536909.25, 187990.75, 536909.25, 187956.75, 536909.25, 188008.25, 536909.25, 187942.75, - 536909.25, 188034.75, 536909.25, 187916.75, 536909.25, 187938.75, 536909.25, 188117.75, - 536909.25, 187953.25, 536909.25, 188014.75, 536909.25, 187981.25, 536909.25, 187973.25, - 536909.25, 188042.25, 536909.25, 187912.25, 536909.25, 188008.75, 536909.25, 188049.25, - 536909.25, 187920.25, 536909.25, 188132.25, 536909.25, 188155.25, 536909.25, 188138.75, - 536909.25, 188121.75, 536909.25, 187928.25, 536909.25, 187954.25, 536909.25, 188126.25, - 536909.25, 188005.75, 536909.25, 188077.25, 536909.25, 188156.75, 536909.25, 188117.25, - 536909.25, 188015.25, 536909.25, 187971.75, 536909.75, 188140.25, 536909.75, 188119.75, - 536909.75, 187991.25, 536909.75, 188008.25, 536909.75, 188092.25, 536909.75, 187922.25, - 536909.75, 188136.75, 536909.75, 188135.25, 536909.75, 187990.25, 536909.75, 187948.75, - 536909.75, 188059.25, 536909.75, 188015.25, 536909.75, 188156.75, 536909.75, 187918.75, - 536909.75, 187989.25, 536909.75, 187941.75, 536909.75, 188068.75, 536909.75, 188046.25, - 536909.75, 188139.25, 536909.75, 188131.75, 536909.75, 187954.75, 536909.75, 188069.25, - 536909.75, 187967.75, 536909.75, 188013.25, 536909.75, 187966.75, 536909.75, 188159.75, - 536909.75, 187971.25, 536909.75, 187955.75, 536909.75, 188060.25, 536909.75, 188006.25, - 536909.75, 187911.25, 536909.75, 187913.25, 536909.75, 188130.25, 536909.75, 188121.25, - 536909.75, 188067.25, 536909.75, 188016.75, 536909.75, 187972.75, 536909.75, 187969.75, - 536909.75, 187957.25, 536909.75, 187981.75, 536909.75, 187997.75, 536909.75, 188133.25, - 536909.75, 188120.75, 536909.75, 188124.25, 536909.75, 188012.25, 536909.75, 188137.75, - 536909.75, 188124.75, 536909.75, 188005.25, 536909.75, 188154.75, 536909.75, 188126.25, - 536909.75, 187989.75, 536909.75, 187920.75, 536909.75, 188116.75, 536909.75, 188076.75, - 536909.75, 187910.75, 536909.75, 187949.25, 536909.75, 188059.75, 536909.75, 188121.75, - 536909.75, 187928.75, 536909.75, 188058.75, 536909.75, 188004.25, 536909.75, 188038.75, - 536909.75, 187915.75, 536909.75, 188058.25, 536909.75, 187981.25, 536909.75, 188077.75, - 536909.75, 188117.75, 536909.75, 187943.25, 536909.75, 187980.75, 536909.75, 188160.25, - 536909.75, 187912.75, 536909.75, 188110.75, 536909.75, 187927.25, 536909.75, 188130.75, - 536909.75, 188008.75, 536909.75, 187920.25, 536909.75, 188153.75, 536910.25, 187968.25, - 536910.25, 187935.75, 536910.25, 187969.25, 536910.25, 187922.25, 536910.25, 187914.25, - 536910.25, 188057.75, 536910.25, 188119.25, 536910.25, 187970.75, 536910.25, 188003.75, - 536910.25, 188158.25, 536910.25, 188111.25, 536910.25, 188152.75, 536910.25, 188110.75, - 536910.25, 188112.75, 536910.25, 188123.75, 536910.25, 187921.75, 536910.25, 187957.75, - 536910.25, 187915.75, 536910.25, 188060.25, 536910.25, 187929.75, 536910.25, 187954.75, - 536910.25, 188138.75, 536910.25, 188046.25, 536910.25, 187988.75, 536910.25, 187927.25, - 536910.25, 188005.75, 536910.25, 188069.25, 536910.25, 187982.25, 536910.25, 187943.25, - 536910.25, 187957.25, 536910.25, 187967.25, 536910.25, 187919.75, 536910.25, 187987.75, - 536910.25, 188034.25, 536910.25, 188136.25, 536910.25, 188004.75, 536910.25, 188113.25, - 536910.25, 188159.75, 536910.25, 188153.25, 536910.25, 188069.75, 536910.25, 187921.25, - 536910.25, 188120.25, 536910.25, 188134.25, 536910.25, 188030.25, 536910.25, 188047.25, - 536910.25, 188006.75, 536910.25, 188137.75, 536910.25, 187912.25, 536910.25, 188051.25, - 536910.25, 187929.25, 536910.25, 187970.25, 536910.25, 188154.25, 536910.25, 188027.75, - 536910.25, 188078.25, 536910.25, 188141.25, 536910.25, 188085.25, 536910.25, 188115.25, - 536910.25, 188077.25, 536910.25, 188011.25, 536910.25, 187938.25, 536910.25, 188132.75, - 536910.25, 188119.75, 536910.25, 188014.25, 536910.25, 188131.25, 536910.25, 187926.25, - 536910.25, 187942.75, 536910.25, 187928.75, 536910.25, 187956.25, 536910.25, 188106.75, - 536910.25, 187972.25, 536910.25, 188140.25, 536910.25, 188132.25, 536910.25, 188114.75, - 536910.25, 188114.25, 536910.25, 188058.75, 536910.25, 188020.25, 536910.25, 188157.25, - 536910.25, 188118.25, 536910.25, 188004.25, 536910.25, 188008.25, 536910.25, 188122.25, - 536910.25, 188156.25, 536910.75, 188030.25, 536910.75, 188122.25, 536910.75, 188046.25, - 536910.75, 187941.25, 536910.75, 188123.25, 536910.75, 187968.75, 536910.75, 187989.75, - 536910.75, 188132.75, 536910.75, 188005.25, 536910.75, 188007.75, 536910.75, 187943.25, - 536910.75, 187970.75, 536910.75, 188058.75, 536910.75, 188132.25, 536910.75, 188114.25, - 536910.75, 188058.25, 536910.75, 188124.25, 536910.75, 187987.75, 536910.75, 188111.25, - 536910.75, 188059.75, 536910.75, 188110.75, 536910.75, 188112.75, 536910.75, 188159.75, - 536910.75, 187914.25, 536910.75, 187971.75, 536910.75, 187990.25, 536910.75, 188137.25, - 536910.75, 188059.25, 536910.75, 188029.75, 536910.75, 188102.25, 536910.75, 188069.25, - 536910.75, 187988.75, 536910.75, 188049.75, 536910.75, 187969.25, 536910.75, 188004.25, - 536910.75, 187957.75, 536910.75, 187912.25, 536910.75, 188046.75, 536910.75, 188140.25, - 536910.75, 188138.25, 536910.75, 188125.25, 536910.75, 188014.25, 536910.75, 187968.25, - 536910.75, 187916.25, 536910.75, 187942.75, 536910.75, 188119.75, 536910.75, 187927.25, - 536910.75, 187957.25, 536910.75, 187928.75, 536910.75, 188026.75, 536910.75, 188115.25, - 536910.75, 188002.75, 536910.75, 188011.75, 536910.75, 188027.25, 536910.75, 188061.75, - 536910.75, 187929.25, 536910.75, 188131.25, 536910.75, 188078.25, 536910.75, 188006.75, - 536910.75, 187967.25, 536910.75, 187970.25, 536910.75, 187949.75, 536910.75, 187997.25, - 536910.75, 188077.25, 536910.75, 188041.75, 536910.75, 187972.75, 536910.75, 188013.25, - 536910.75, 188004.75, 536910.75, 188157.25, 536910.75, 188115.75, 536910.75, 187955.75, - 536910.75, 188155.25, 536910.75, 188141.25, 536910.75, 188015.25, 536910.75, 188153.25, - 536910.75, 188157.75, 536910.75, 188133.75, 536910.75, 187981.25, 536910.75, 187914.75, - 536910.75, 187911.25, 536910.75, 188121.25, 536911.25, 188069.75, 536911.25, 188121.25, - 536911.25, 187920.75, 536911.25, 188133.75, 536911.25, 188030.25, 536911.25, 188156.25, - 536911.25, 188077.75, 536911.25, 188113.25, 536911.25, 187921.25, 536911.25, 187996.75, - 536911.25, 188121.75, 536911.25, 188154.25, 536911.25, 188046.75, 536911.25, 187922.75, - 536911.25, 188028.75, 536911.25, 188010.25, 536911.25, 187929.75, 536911.25, 188004.75, - 536911.25, 188133.25, 536911.25, 187981.75, 536911.25, 187916.25, 536911.25, 188027.75, - 536911.25, 188078.25, 536911.25, 188108.75, 536911.25, 188025.25, 536911.25, 188115.75, - 536911.25, 188013.25, 536911.25, 187915.75, 536911.25, 188070.25, 536911.25, 187927.75, - 536911.25, 187981.25, 536911.25, 187918.25, 536911.25, 187943.75, 536911.25, 188014.25, - 536911.25, 188137.25, 536911.25, 188056.75, 536911.25, 188140.25, 536911.25, 187986.25, - 536911.25, 187956.25, 536911.25, 188114.75, 536911.25, 188070.75, 536911.25, 187936.75, - 536911.25, 187928.25, 536911.25, 188060.75, 536911.25, 188057.25, 536911.25, 187942.25, - 536911.25, 187956.75, 536911.25, 187919.25, 536911.25, 188003.75, 536911.25, 187937.25, - 536911.25, 188118.75, 536911.25, 187920.25, 536911.25, 188159.75, 536911.25, 187977.25, - 536911.25, 188139.25, 536911.25, 188111.25, 536911.25, 188153.75, 536911.25, 188002.75, - 536911.25, 188154.75, 536911.25, 188110.75, 536911.25, 188057.75, 536911.25, 188136.75, - 536911.25, 188118.25, 536911.25, 187987.25, 536911.25, 187966.75, 536911.25, 187977.75, - 536911.25, 187988.25, 536911.25, 187958.25, 536911.25, 188113.75, 536911.25, 188092.25, - 536911.75, 188133.25, 536911.75, 187929.75, 536911.75, 188060.25, 536911.75, 187922.25, - 536911.75, 188046.25, 536911.75, 188118.75, 536911.75, 187939.75, 536911.75, 187921.75, - 536911.75, 188078.75, 536911.75, 187944.25, 536911.75, 188002.25, 536911.75, 188027.25, - 536911.75, 187986.75, 536911.75, 188071.25, 536911.75, 188116.25, 536911.75, 188154.25, - 536911.75, 188136.25, 536911.75, 188093.25, 536911.75, 188056.75, 536911.75, 188111.75, - 536911.75, 188025.75, 536911.75, 187986.25, 536911.75, 188051.25, 536911.75, 187930.25, - 536911.75, 187950.75, 536911.75, 188055.75, 536911.75, 188155.75, 536911.75, 187990.75, - 536911.75, 187935.75, 536911.75, 187956.25, 536911.75, 187985.25, 536911.75, 187956.75, - 536911.75, 187985.75, 536911.75, 188008.25, 536911.75, 187998.25, 536911.75, 188001.25, - 536911.75, 187930.75, 536911.75, 188031.25, 536911.75, 188154.75, 536911.75, 188134.75, - 536911.75, 188091.25, 536911.75, 188109.75, 536911.75, 188058.75, 536911.75, 188056.25, - 536911.75, 187923.75, 536911.75, 187980.75, 536911.75, 188070.25, 536911.75, 188026.75, - 536911.75, 187928.75, 536911.75, 187941.25, 536911.75, 187916.75, 536911.75, 188001.75, - 536911.75, 188087.75, 536911.75, 188077.75, 536911.75, 188141.25, 536911.75, 188010.75, - 536911.75, 187923.25, 536911.75, 188061.25, 536911.75, 188028.25, 536911.75, 187934.75, - 536911.75, 188158.25, 536911.75, 188002.75, 536911.75, 188057.75, 536911.75, 188138.75, - 536911.75, 187919.75, 536911.75, 188047.75, 536911.75, 187968.25, 536911.75, 188120.25, - 536911.75, 188010.25, 536911.75, 188158.75, 536911.75, 188038.75, 536911.75, 188155.25, - 536911.75, 188140.75, 536911.75, 188159.25, 536911.75, 188047.25, 536911.75, 188134.25, - 536911.75, 188003.25, 536911.75, 188136.75, 536911.75, 188156.75, 536911.75, 188133.75, - 536911.75, 188091.75, 536911.75, 188119.25, 536911.75, 188117.25, 536911.75, 187958.25, - 536911.75, 187922.75, 536912.25, 188133.75, 536912.25, 187944.25, 536912.25, 188158.25, - 536912.25, 187920.25, 536912.25, 188112.75, 536912.25, 188114.75, 536912.25, 188134.25, - 536912.25, 187919.75, 536912.25, 188119.25, 536912.25, 188010.25, 536912.25, 188143.75, - 536912.25, 188047.75, 536912.25, 188025.75, 536912.25, 188141.25, 536912.25, 188160.25, - 536912.25, 188003.25, 536912.25, 187984.75, 536912.25, 188057.25, 536912.25, 188077.75, - 536912.25, 188137.75, 536912.25, 187980.75, 536912.25, 188047.25, 536912.25, 188002.75, - 536912.25, 188089.75, 536912.25, 188037.75, 536912.25, 188055.75, 536912.25, 187910.75, - 536912.25, 188130.25, 536912.25, 188001.25, 536912.25, 188139.25, 536912.25, 188120.25, - 536912.25, 187928.25, 536912.25, 188028.25, 536912.25, 188036.75, 536912.25, 188056.25, - 536912.25, 188114.25, 536912.25, 187921.25, 536912.25, 187934.75, 536912.25, 188156.75, - 536912.25, 187940.25, 536912.25, 187985.75, 536912.25, 188050.75, 536912.25, 187956.75, - 536912.25, 188011.25, 536912.25, 188118.25, 536912.25, 187943.25, 536912.25, 187921.75, - 536912.25, 188026.25, 536912.25, 188048.25, 536912.25, 188155.75, 536912.25, 188113.75, - 536912.25, 188026.75, 536912.25, 187918.75, 536912.25, 188118.75, 536912.25, 188060.75, - 536912.25, 187915.25, 536912.25, 188155.25, 536912.25, 188051.25, 536912.25, 188134.75, - 536912.25, 188013.25, 536912.25, 188154.25, 536912.25, 187933.25, 536912.25, 187986.25, - 536912.25, 188111.75, 536912.25, 188069.25, 536912.25, 188002.25, 536912.25, 187922.75, - 536912.25, 188055.25, 536912.25, 188133.25, 536912.25, 187958.25, 536912.25, 187929.75, - 536912.25, 188131.25, 536912.25, 187941.75, 536912.25, 187986.75, 536912.25, 188001.75, - 536912.25, 188092.25, 536912.25, 188126.75, 536912.25, 188078.75, 536912.25, 188135.25, - 536912.25, 188115.75, 536912.25, 188039.75, 536912.25, 188060.25, 536912.25, 188068.75, - 536912.25, 188061.75, 536912.25, 187956.25, 536912.25, 187939.75, 536912.25, 188076.25, - 536912.25, 188070.75, 536912.25, 188140.25, 536912.25, 187985.25, 536912.75, 188008.25, - 536912.75, 187923.75, 536912.75, 188140.75, 536912.75, 188028.75, 536912.75, 188137.25, - 536912.75, 188054.25, 536912.75, 188047.75, 536912.75, 188050.25, 536912.75, 188109.25, - 536912.75, 188090.75, 536912.75, 187931.25, 536912.75, 188070.75, 536912.75, 187930.75, - 536912.75, 187972.75, 536912.75, 188076.25, 536912.75, 188156.25, 536912.75, 188037.25, - 536912.75, 188000.25, 536912.75, 188141.75, 536912.75, 188138.75, 536912.75, 188135.25, - 536912.75, 187975.75, 536912.75, 188068.75, 536912.75, 187980.25, 536912.75, 187917.25, - 536912.75, 188009.75, 536912.75, 187940.25, 536912.75, 187912.25, 536912.75, 188070.25, - 536912.75, 187941.25, 536912.75, 187986.75, 536912.75, 188000.75, 536912.75, 188011.75, - 536912.75, 188003.25, 536912.75, 188093.75, 536912.75, 187956.25, 536912.75, 187922.25, - 536912.75, 187942.25, 536912.75, 187940.75, 536912.75, 188133.25, 536912.75, 188076.75, - 536912.75, 188119.75, 536912.75, 187999.75, 536912.75, 188159.25, 536912.75, 188136.75, - 536912.75, 188027.75, 536912.75, 188055.75, 536912.75, 188134.75, 536912.75, 188037.75, - 536912.75, 187918.75, 536912.75, 187973.25, 536912.75, 188069.25, 536912.75, 187936.75, - 536912.75, 187943.75, 536912.75, 187984.25, 536912.75, 187939.75, 536912.75, 188110.75, - 536912.75, 187929.25, 536912.75, 188092.75, 536912.75, 188154.25, 536912.75, 188054.75, - 536912.75, 187933.25, 536912.75, 188142.25, 536912.75, 187944.75, 536912.75, 188026.75, - 536912.75, 188051.25, 536912.75, 188077.25, 536912.75, 187942.75, 536912.75, 188036.75, - 536912.75, 187998.25, 536912.75, 188048.25, 536912.75, 188155.25, 536912.75, 187985.75, - 536912.75, 188053.75, 536912.75, 188035.75, 536912.75, 187919.25, 536912.75, 187958.75, - 536912.75, 188118.25, 536912.75, 187950.75, 536912.75, 188001.75, 536912.75, 188027.25, - 536912.75, 187956.75, 536912.75, 188120.75, 536913.25, 188113.75, 536913.25, 187916.25, - 536913.25, 187957.25, 536913.25, 187982.25, 536913.25, 188078.25, 536913.25, 188129.25, - 536913.25, 188117.75, 536913.25, 188075.25, 536913.25, 188029.25, 536913.25, 188061.25, - 536913.25, 187944.75, 536913.25, 187936.25, 536913.25, 187958.75, 536913.25, 188071.25, - 536913.25, 188053.25, 536913.25, 188018.25, 536913.25, 187945.25, 536913.25, 187957.75, - 536913.25, 188002.75, 536913.25, 188114.25, 536913.25, 188062.75, 536913.25, 187968.75, - 536913.25, 188069.25, 536913.25, 187998.25, 536913.25, 188048.25, 536913.25, 187918.25, - 536913.25, 188138.25, 536913.25, 188121.25, 536913.25, 188051.75, 536913.25, 188051.25, - 536913.25, 187924.75, 536913.25, 187930.25, 536913.25, 188054.75, 536913.25, 188061.75, - 536913.25, 188112.25, 536913.25, 188019.75, 536913.25, 188035.75, 536913.25, 188139.75, - 536913.25, 188052.25, 536913.25, 188049.25, 536913.25, 187936.75, 536913.25, 188003.25, - 536913.25, 188086.75, 536913.25, 188102.75, 536913.25, 188036.25, 536913.25, 188048.75, - 536913.25, 188037.75, 536913.25, 187981.75, 536913.25, 188034.75, 536913.25, 187973.25, - 536913.25, 187944.25, 536913.25, 188159.25, 536913.25, 187923.25, 536913.25, 188158.75, - 536913.25, 187995.25, 536913.25, 188110.25, 536913.25, 188117.25, 536913.25, 188089.25, - 536913.25, 187937.75, 536913.25, 188135.25, 536913.25, 187999.75, 536913.25, 188055.75, - 536913.25, 187959.25, 536913.25, 188034.25, 536913.25, 187983.75, 536913.25, 188015.75, - 536913.25, 188128.75, 536913.25, 188027.75, 536913.25, 188038.25, 536913.25, 188074.25, - 536913.25, 187931.75, 536913.25, 188119.75, 536913.25, 187984.75, 536913.25, 187919.25, - 536913.25, 188076.25, 536913.25, 187928.75, 536913.25, 187999.25, 536913.25, 187971.75, - 536913.25, 188105.75, 536913.25, 188076.75, 536913.25, 187915.75, 536913.25, 188091.25, - 536913.25, 188092.25, 536913.25, 188137.75, 536913.25, 188068.75, 536913.25, 187996.75, - 536913.25, 188006.75, 536913.25, 188049.75, 536913.25, 188075.75, 536913.25, 188071.75, - 536913.25, 187917.25, 536913.25, 188032.25, 536913.25, 188121.75, 536913.25, 188000.25, - 536913.25, 187931.25, 536913.25, 187998.75, 536913.25, 188109.25, 536913.25, 188038.75, - 536913.25, 188068.25, 536913.25, 188116.75, 536913.25, 187917.75, 536913.25, 188141.25, - 536913.25, 187997.25, 536913.25, 187985.25, 536913.25, 188016.75, 536913.75, 188114.75, - 536913.75, 188016.75, 536913.75, 188141.75, 536913.75, 188105.25, 536913.75, 188075.75, - 536913.75, 188137.75, 536913.75, 188010.25, 536913.75, 187918.25, 536913.75, 188008.75, - 536913.75, 187971.75, 536913.75, 187916.75, 536913.75, 188119.75, 536913.75, 188134.25, - 536913.75, 187999.25, 536913.75, 187940.75, 536913.75, 187959.25, 536913.75, 188010.75, - 536913.75, 188054.75, 536913.75, 187937.75, 536913.75, 188117.25, 536913.75, 188004.75, - 536913.75, 187973.25, 536913.75, 187923.25, 536913.75, 187918.75, 536913.75, 188103.75, - 536913.75, 187943.75, 536913.75, 188049.25, 536913.75, 187972.25, 536913.75, 188120.25, - 536913.75, 187924.75, 536913.75, 188036.25, 536913.75, 188062.25, 536913.75, 188135.75, - 536913.75, 187945.25, 536913.75, 188071.75, 536913.75, 188052.25, 536913.75, 187916.25, - 536913.75, 187998.25, 536913.75, 188071.25, 536913.75, 188051.25, 536913.75, 188112.25, - 536913.75, 187996.75, 536913.75, 188061.25, 536913.75, 188075.25, 536913.75, 187944.75, - 536913.75, 188001.75, 536913.75, 187935.25, 536913.75, 187930.25, 536913.75, 188118.75, - 536913.75, 187958.75, 536913.75, 188048.25, 536913.75, 188103.25, 536913.75, 187915.25, - 536913.75, 187932.75, 536913.75, 187999.75, 536913.75, 188034.25, 536913.75, 187983.75, - 536913.75, 188048.75, 536913.75, 188052.75, 536913.75, 188068.75, 536913.75, 188019.25, - 536913.75, 188000.75, 536913.75, 187985.25, 536913.75, 187998.75, 536913.75, 187931.25, - 536913.75, 187917.75, 536913.75, 188000.25, 536913.75, 188068.25, 536913.75, 187981.75, - 536913.75, 188070.75, 536913.75, 188049.75, 536913.75, 187922.75, 536913.75, 187942.25, - 536913.75, 188074.25, 536913.75, 187936.75, 536913.75, 188035.75, 536913.75, 188019.75, - 536913.75, 188007.25, 536913.75, 187957.25, 536913.75, 188138.25, 536913.75, 187971.25, - 536913.75, 188109.75, 536913.75, 188002.75, 536913.75, 187936.25, 536913.75, 188142.75, - 536913.75, 188051.75, 536913.75, 188113.75, 536913.75, 188127.75, 536913.75, 188087.75, - 536913.75, 188047.75, 536913.75, 188037.75, 536913.75, 188134.75, 536913.75, 188106.75, - 536913.75, 188073.25, 536913.75, 188119.25, 536913.75, 188120.75, 536913.75, 187915.75, - 536913.75, 188015.75, 536913.75, 188132.75, 536913.75, 188091.75, 536913.75, 187928.75, - 536913.75, 188116.75, 536913.75, 187938.75, 536914.25, 188106.25, 536914.25, 187970.25, - 536914.25, 187945.75, 536914.25, 188159.75, 536914.25, 188140.75, 536914.25, 187930.75, - 536914.25, 188079.75, 536914.25, 188118.25, 536914.25, 188134.75, 536914.25, 187992.75, - 536914.25, 188073.25, 536914.25, 188139.25, 536914.25, 188110.75, 536914.25, 188069.25, - 536914.25, 187957.75, 536914.25, 188033.75, 536914.25, 188127.25, 536914.25, 187970.75, - 536914.25, 187997.75, 536914.25, 188116.25, 536914.25, 187936.75, 536914.25, 188101.75, - 536914.25, 188061.75, 536914.25, 188019.75, 536914.25, 187927.75, 536914.25, 187958.25, - 536914.25, 188135.25, 536914.25, 187914.25, 536914.25, 188049.75, 536914.25, 188115.75, - 536914.25, 187997.25, 536914.25, 188140.25, 536914.25, 187931.25, 536914.25, 187917.75, - 536914.25, 188039.25, 536914.25, 187998.75, 536914.25, 187917.25, 536914.25, 188048.75, - 536914.25, 187985.25, 536914.25, 188142.75, 536914.25, 188052.75, 536914.25, 188068.75, - 536914.25, 187974.25, 536914.25, 188034.25, 536914.25, 187996.25, 536914.25, 187984.25, - 536914.25, 188102.75, 536914.25, 188111.75, 536914.25, 188074.75, 536914.25, 188018.75, - 536914.25, 187914.75, 536914.25, 188142.25, 536914.25, 188103.25, 536914.25, 188032.75, - 536914.25, 188118.75, 536914.25, 187952.25, 536914.25, 188053.25, 536914.25, 188117.75, - 536914.25, 188052.25, 536914.25, 188090.25, 536914.25, 187945.25, 536914.25, 188028.25, - 536914.25, 187972.25, 536914.25, 188001.25, 536914.25, 187943.75, 536914.25, 187925.25, - 536914.25, 187923.25, 536914.25, 188034.75, 536914.25, 188017.75, 536914.25, 187996.75, - 536914.25, 188104.25, 536914.25, 187981.25, 536914.25, 188093.25, 536914.25, 188008.75, - 536914.25, 187916.75, 536914.25, 188017.25, 536914.25, 188121.75, 536914.25, 188038.75, - 536914.25, 188112.75, 536914.25, 187923.75, 536914.25, 188035.25, 536914.25, 188089.75, - 536914.25, 188114.25, 536914.25, 187995.25, 536914.25, 188136.25, 536914.25, 188016.25, - 536914.25, 188071.75, 536914.75, 188015.75, 536914.75, 188031.25, 536914.75, 187916.25, - 536914.75, 187945.75, 536914.75, 188159.75, 536914.75, 187934.75, 536914.75, 188116.75, - 536914.75, 188153.75, 536914.75, 187940.25, 536914.75, 188132.75, 536914.75, 188071.75, - 536914.75, 187924.25, 536914.75, 187915.75, 536914.75, 188110.75, 536914.75, 188087.75, - 536914.75, 188021.25, 536914.75, 188020.75, 536914.75, 188062.25, 536914.75, 188069.25, - 536914.75, 188136.25, 536914.75, 187943.25, 536914.75, 188062.75, 536914.75, 187957.75, - 536914.75, 188020.25, 536914.75, 188113.75, 536914.75, 188073.75, 536914.75, 188072.25, - 536914.75, 188139.25, 536914.75, 187970.75, 536914.75, 188100.75, 536914.75, 187951.25, - 536914.75, 188033.25, 536914.75, 188160.25, 536914.75, 188010.25, 536914.75, 188101.75, - 536914.75, 187939.75, 536914.75, 188068.25, 536914.75, 188019.75, 536914.75, 187994.25, - 536914.75, 188135.25, 536914.75, 187914.25, 536914.75, 188063.75, 536914.75, 188088.75, - 536914.75, 188141.25, 536914.75, 187942.25, 536914.75, 188040.25, 536914.75, 187922.75, - 536914.75, 188052.75, 536914.75, 187959.75, 536914.75, 188115.75, 536914.75, 188111.25, - 536914.75, 187997.25, 536914.75, 188102.25, 536914.75, 187982.75, 536914.75, 188107.25, - 536914.75, 188140.25, 536914.75, 188039.25, 536914.75, 188123.25, 536914.75, 187972.75, - 536914.75, 188086.25, 536914.75, 187939.25, 536914.75, 188142.75, 536914.75, 188038.25, - 536914.75, 187925.75, 536914.75, 188039.75, 536914.75, 187944.25, 536914.75, 188136.75, - 536914.75, 187967.75, 536914.75, 188111.75, 536914.75, 187992.25, 536914.75, 188032.25, - 536914.75, 187985.75, 536914.75, 188138.75, 536914.75, 187975.75, 536914.75, 188067.25, - 536914.75, 187937.25, 536914.75, 187984.75, 536914.75, 188032.75, 536914.75, 187958.75, - 536914.75, 187932.25, 536914.75, 188143.75, 536914.75, 188115.25, 536914.75, 187970.25, - 536914.75, 188017.25, 536914.75, 187982.25, 536914.75, 187934.25, 536914.75, 187935.75, - 536914.75, 188018.25, 536914.75, 188052.25, 536914.75, 187995.25, 536914.75, 188090.25, - 536914.75, 188085.25, 536914.75, 187923.25, 536914.75, 187931.75, 536914.75, 188034.75, - 536914.75, 187969.75, 536914.75, 187910.75, 536914.75, 187973.25, 536914.75, 187996.75, - 536914.75, 188104.75, 536914.75, 187930.25, 536914.75, 188064.75, 536914.75, 188117.25, - 536915.25, 187980.75, 536915.25, 188031.25, 536915.25, 188104.75, 536915.25, 187940.25, - 536915.25, 188028.75, 536915.25, 188066.75, 536915.25, 188120.25, 536915.25, 188117.25, - 536915.25, 188125.75, 536915.25, 188116.75, 536915.25, 187950.25, 536915.25, 187930.75, - 536915.25, 188006.75, 536915.25, 187924.25, 536915.25, 188071.75, 536915.25, 187915.75, - 536915.25, 188088.25, 536915.25, 188119.25, 536915.25, 188110.75, 536915.25, 188113.75, - 536915.25, 187943.25, 536915.25, 188020.75, 536915.25, 187972.25, 536915.25, 187996.75, - 536915.25, 188063.25, 536915.25, 187969.75, 536915.25, 188073.25, 536915.25, 187957.75, - 536915.25, 187946.25, 536915.25, 188062.75, 536915.25, 188020.25, 536915.25, 188033.75, - 536915.25, 188138.25, 536915.25, 188100.75, 536915.25, 187923.25, 536915.25, 187997.75, - 536915.25, 188088.75, 536915.25, 188033.25, 536915.25, 187914.25, 536915.25, 188068.25, - 536915.25, 188028.25, 536915.25, 187939.75, 536915.25, 188083.75, 536915.25, 188019.75, - 536915.25, 188039.25, 536915.25, 187994.25, 536915.25, 188085.25, 536915.25, 188001.75, - 536915.25, 188062.25, 536915.25, 188135.25, 536915.25, 187945.25, 536915.25, 188086.75, - 536915.25, 188045.25, 536915.25, 187994.75, 536915.25, 188040.25, 536915.25, 188143.75, - 536915.25, 188016.75, 536915.25, 188141.75, 536915.25, 187937.25, 536915.25, 187982.75, - 536915.25, 188111.25, 536915.25, 187959.75, 536915.25, 188015.75, 536915.25, 188114.25, - 536915.25, 188105.25, 536915.25, 187931.25, 536915.25, 187934.25, 536915.25, 188072.75, - 536915.25, 187938.25, 536915.25, 187997.25, 536915.25, 187935.75, 536915.25, 188076.25, - 536915.25, 187998.75, 536915.25, 187985.25, 536915.25, 188019.25, 536915.25, 188014.25, - 536915.25, 187926.25, 536915.25, 188142.75, 536915.25, 187970.25, 536915.25, 188038.25, - 536915.25, 188136.75, 536915.25, 188039.75, 536915.25, 188068.75, 536915.25, 187944.25, - 536915.25, 187932.75, 536915.25, 188038.75, 536915.25, 188111.75, 536915.25, 187993.75, - 536915.25, 188032.25, 536915.25, 188118.25, 536915.25, 188067.75, 536915.25, 187984.75, - 536915.25, 188072.25, 536915.25, 188138.75, 536915.25, 188158.25, 536915.25, 187958.75, - 536915.25, 187914.75, 536915.25, 187942.75, 536915.75, 188105.25, 536915.75, 188031.75, - 536915.75, 187913.25, 536915.75, 188101.75, 536915.75, 188065.75, 536915.75, 188107.75, - 536915.75, 187939.75, 536915.75, 187914.75, 536915.75, 187993.75, 536915.75, 187930.25, - 536915.75, 188018.75, 536915.75, 187971.25, 536915.75, 187959.25, 536915.75, 187945.75, - 536915.75, 187992.25, 536915.75, 188032.75, 536915.75, 187958.25, 536915.75, 187931.25, - 536915.75, 188085.25, 536915.75, 188124.25, 536915.75, 188030.75, 536915.75, 187995.75, - 536915.75, 187960.25, 536915.75, 188028.75, 536915.75, 188020.25, 536915.75, 188126.25, - 536915.75, 187932.75, 536915.75, 188063.25, 536915.75, 188086.75, 536915.75, 188066.25, - 536915.75, 187925.25, 536915.75, 187983.25, 536915.75, 188040.25, 536915.75, 187913.75, - 536915.75, 188141.75, 536915.75, 188023.75, 536915.75, 187995.25, 536915.75, 188027.75, - 536915.75, 187941.75, 536915.75, 188016.75, 536915.75, 188115.25, 536915.75, 187996.25, - 536915.75, 188134.75, 536915.75, 188017.75, 536915.75, 188136.25, 536915.75, 188017.25, - 536915.75, 188088.25, 536915.75, 188113.25, 536915.75, 187923.75, 536915.75, 188142.75, - 536915.75, 188115.75, 536915.75, 188103.75, 536915.75, 188016.25, 536915.75, 187972.25, - 536915.75, 187982.75, 536915.75, 188072.75, 536915.75, 188114.75, 536915.75, 188112.25, - 536915.75, 188067.75, 536915.75, 187973.25, 536915.75, 188112.75, 536915.75, 187986.25, - 536915.75, 187959.75, 536915.75, 188021.25, 536915.75, 188040.75, 536915.75, 187941.25, - 536915.75, 187960.75, 536915.75, 188140.25, 536915.75, 187912.75, 536916.25, 188098.75, - 536916.25, 187912.75, 536916.25, 188135.75, 536916.25, 188110.25, 536916.25, 188129.75, - 536916.25, 187939.25, 536916.25, 188084.75, 536916.25, 188016.25, 536916.25, 187991.25, - 536916.25, 187947.25, 536916.25, 188018.25, 536916.25, 187992.75, 536916.25, 188102.25, - 536916.25, 187993.75, 536916.25, 188027.75, 536916.25, 188112.25, 536916.25, 187940.75, - 536916.25, 188019.25, 536916.25, 188029.75, 536916.25, 188022.25, 536916.25, 188054.25, - 536916.25, 188107.25, 536916.25, 187993.25, 536916.25, 187941.75, 536916.25, 187932.25, - 536916.25, 187995.75, 536916.25, 188127.75, 536916.25, 188138.75, 536916.25, 187912.25, - 536916.25, 188145.75, 536916.25, 187946.25, 536916.25, 188112.75, 536916.25, 187943.75, - 536916.25, 188017.25, 536916.25, 188085.75, 536916.25, 188117.25, 536916.25, 187986.75, - 536916.25, 188091.75, 536916.25, 188063.75, 536916.25, 187960.25, 536916.25, 188064.25, - 536916.25, 188104.25, 536916.25, 188065.75, 536916.25, 188066.25, 536916.25, 188106.25, - 536916.25, 188065.25, 536916.25, 187930.75, 536916.25, 187931.75, 536916.25, 187932.75, - 536916.25, 187974.75, 536916.25, 187945.75, 536916.25, 188020.25, 536916.25, 188041.25, - 536916.25, 188121.75, 536916.25, 187985.75, 536916.25, 187931.25, 536916.25, 187925.25, - 536916.25, 187971.25, 536916.25, 188031.25, 536916.25, 188104.75, 536916.25, 187911.75, - 536916.25, 188062.75, 536916.25, 187924.75, 536916.25, 188083.75, 536916.25, 188090.25, - 536916.25, 187944.75, 536916.25, 188022.75, 536916.25, 188082.25, 536916.25, 188134.25, - 536916.25, 188018.75, 536916.25, 187969.75, 536916.25, 187913.25, 536916.25, 188026.75, - 536916.25, 187982.25, 536916.25, 187994.25, 536916.25, 188101.25, 536916.25, 188031.75, - 536916.25, 187940.25, 536916.25, 187961.25, 536916.25, 187958.75, 536916.25, 188141.75, - 536916.25, 188087.25, 536916.25, 188021.75, 536916.25, 188139.75, 536916.25, 187969.25, - 536916.75, 188087.25, 536916.75, 188116.25, 536916.75, 188039.25, 536916.75, 188021.75, - 536916.75, 187961.25, 536916.75, 188062.75, 536916.75, 188134.25, 536916.75, 187952.75, - 536916.75, 188033.25, 536916.75, 188101.25, 536916.75, 188105.75, 536916.75, 187913.25, - 536916.75, 188083.75, 536916.75, 187925.25, 536916.75, 188107.75, 536916.75, 188065.25, - 536916.75, 188085.25, 536916.75, 187974.75, 536916.75, 188041.25, 536916.75, 187931.25, - 536916.75, 187924.75, 536916.75, 188026.75, 536916.75, 188063.75, 536916.75, 187969.75, - 536916.75, 188086.75, 536916.75, 188065.75, 536916.75, 188107.25, 536916.75, 188099.75, - 536916.75, 188042.25, 536916.75, 188136.25, 536916.75, 188117.75, 536916.75, 187982.75, - 536916.75, 188053.25, 536916.75, 187991.25, 536916.75, 188111.25, 536916.75, 188114.75, - 536916.75, 187946.25, 536916.75, 187992.75, 536916.75, 188109.25, 536916.75, 188020.75, - 536916.75, 187911.75, 536916.75, 187937.25, 536916.75, 188000.25, 536916.75, 188063.25, - 536916.75, 188029.75, 536916.75, 188142.25, 536916.75, 188018.25, 536916.75, 187990.75, - 536916.75, 188123.25, 536916.75, 187940.75, 536916.75, 188098.75, 536916.75, 187912.75, - 536916.75, 188135.75, 536916.75, 187959.75, 536916.75, 187939.25, 536916.75, 188022.25, - 536916.75, 188019.25, 536916.75, 188114.25, 536916.75, 187941.75, 536916.75, 188027.75, - 536916.75, 188021.25, 536916.75, 188142.75, 536916.75, 187993.75, 536916.75, 188133.25, - 536916.75, 187925.75, 536916.75, 188145.25, 536916.75, 188110.75, 536916.75, 188017.75, - 536916.75, 188016.25, 536916.75, 187943.75, 536916.75, 188085.75, 536916.75, 187924.25, - 536916.75, 187986.75, 536916.75, 187974.25, 536916.75, 187945.75, 536916.75, 188104.25, - 536916.75, 188066.75, 536916.75, 187993.25, 536916.75, 188064.25, 536916.75, 187963.75, - 536916.75, 188138.75, 536916.75, 187932.75, 536916.75, 188064.75, 536916.75, 188112.75, - 536916.75, 187983.75, 536916.75, 187999.75, 536916.75, 188134.75, 536916.75, 188104.75, - 536916.75, 187992.25, 536916.75, 188140.75, 536916.75, 188031.25, 536916.75, 187944.75, - 536916.75, 187985.75, 536916.75, 187958.75, 536916.75, 187980.75, 536916.75, 188018.75, - 536916.75, 187940.25, 536917.25, 188098.75, 536917.25, 187940.25, 536917.25, 187925.75, - 536917.25, 187947.25, 536917.25, 188132.25, 536917.25, 187930.75, 536917.25, 187941.75, - 536917.25, 187959.25, 536917.25, 187943.25, 536917.25, 187931.75, 536917.25, 188109.75, - 536917.25, 188069.25, 536917.25, 188141.25, 536917.25, 188030.75, 536917.25, 188160.25, - 536917.25, 188104.75, 536917.25, 188040.75, 536917.25, 188040.25, 536917.25, 188139.75, - 536917.25, 188063.75, 536917.25, 187983.25, 536917.25, 188111.25, 536917.25, 187942.25, - 536917.25, 188017.75, 536917.25, 187939.75, 536917.25, 188020.25, 536917.25, 188103.75, - 536917.25, 188016.25, 536917.25, 187991.75, 536917.25, 188109.25, 536917.25, 187972.75, - 536917.25, 188064.75, 536917.25, 187942.75, 536917.25, 187912.25, 536917.25, 188133.75, - 536917.25, 187974.25, 536917.25, 187932.25, 536917.25, 188131.75, 536917.25, 188021.75, - 536917.25, 187932.75, 536917.25, 187917.75, 536917.25, 188061.25, 536917.25, 187998.75, - 536917.25, 188101.75, 536917.25, 187924.75, 536917.25, 187999.75, 536917.25, 188015.75, - 536917.25, 188106.75, 536917.25, 187960.25, 536917.25, 187935.25, 536917.25, 187953.75, - 536917.25, 187983.75, 536917.25, 187960.75, 536917.25, 188025.25, 536917.25, 188113.25, - 536917.25, 188112.25, 536917.25, 187986.25, 536917.25, 188122.25, 536917.25, 187990.75, - 536917.25, 187945.25, 536917.25, 188029.75, 536917.25, 188064.25, 536917.25, 188102.25, - 536917.25, 187974.75, 536917.25, 188041.75, 536917.25, 187910.75, 536917.25, 188112.75, - 536917.25, 188133.25, 536917.25, 188014.75, 536917.25, 187911.25, 536917.25, 188086.25, - 536917.25, 188025.75, 536917.25, 187984.25, 536917.75, 187999.25, 536917.75, 188138.75, - 536917.75, 188119.75, 536917.75, 187997.25, 536917.75, 188014.75, 536917.75, 188098.25, - 536917.75, 188001.25, 536917.75, 187933.75, 536917.75, 187989.75, 536917.75, 187946.75, - 536917.75, 187937.25, 536917.75, 187945.25, 536917.75, 187947.75, 536917.75, 188015.25, - 536917.75, 188122.25, 536917.75, 188128.75, 536917.75, 188112.25, 536917.75, 188126.75, - 536917.75, 188011.25, 536917.75, 188026.25, 536917.75, 187936.25, 536917.75, 188139.25, - 536917.75, 188022.75, 536917.75, 188103.25, 536917.75, 188108.75, 536917.75, 188106.75, - 536917.75, 187911.75, 536917.75, 188019.75, 536917.75, 188030.25, 536917.75, 187916.25, - 536917.75, 188113.75, 536917.75, 187917.75, 536917.75, 188018.25, 536917.75, 187958.25, - 536917.75, 188111.75, 536917.75, 187974.25, 536917.75, 187932.25, 536917.75, 188131.75, - 536917.75, 187953.25, 536917.75, 188085.25, 536917.75, 187990.25, 536917.75, 187970.25, - 536917.75, 187925.25, 536917.75, 188146.75, 536917.75, 187991.75, 536917.75, 188024.25, - 536917.75, 188099.25, 536917.75, 188041.25, 536917.75, 187923.25, 536917.75, 188120.25, - 536917.75, 188044.75, 536917.75, 187939.75, 536917.75, 188103.75, 536917.75, 188020.25, - 536917.75, 187942.25, 536917.75, 188042.25, 536917.75, 188063.75, 536917.75, 188023.25, - 536917.75, 188132.75, 536917.75, 188073.75, 536917.75, 188021.25, 536917.75, 188079.25, - 536917.75, 187989.25, 536917.75, 188016.75, 536917.75, 187933.25, 536917.75, 187987.25, - 536917.75, 188114.75, 536917.75, 188017.25, 536917.75, 188105.25, 536917.75, 188110.25, - 536917.75, 187959.25, 536917.75, 187975.75, 536917.75, 187959.75, 536917.75, 188133.75, - 536917.75, 187940.25, 536917.75, 187947.25, 536917.75, 187924.25, 536918.25, 187944.75, - 536918.25, 187947.25, 536918.25, 187924.25, 536918.25, 187987.25, 536918.25, 188079.75, - 536918.25, 188116.75, 536918.25, 188110.25, 536918.25, 188120.75, 536918.25, 188131.75, - 536918.25, 187959.75, 536918.25, 187975.75, 536918.25, 187933.25, 536918.25, 188105.25, - 536918.25, 188017.25, 536918.25, 187959.25, 536918.25, 188040.25, 536918.25, 188096.25, - 536918.25, 187931.75, 536918.25, 188020.75, 536918.25, 188023.75, 536918.25, 188079.25, - 536918.25, 188111.25, 536918.25, 188139.75, 536918.25, 187957.75, 536918.25, 188100.75, - 536918.25, 188109.25, 536918.25, 188105.75, 536918.25, 188000.25, 536918.25, 188099.25, - 536918.25, 188127.25, 536918.25, 187978.25, 536918.25, 188021.75, 536918.25, 188103.75, - 536918.25, 188132.75, 536918.25, 187958.75, 536918.25, 188019.75, 536918.25, 188031.25, - 536918.25, 188108.75, 536918.25, 188135.25, 536918.25, 188027.25, 536918.25, 188112.25, - 536918.25, 188114.25, 536918.25, 187923.25, 536918.25, 188024.25, 536918.25, 187926.75, - 536918.25, 188014.25, 536918.25, 187947.75, 536918.25, 187986.25, 536918.25, 187991.75, - 536918.25, 187945.25, 536918.25, 187983.75, 536918.25, 187972.25, 536918.25, 188117.75, - 536918.25, 187937.75, 536918.25, 187925.25, 536918.25, 187984.75, 536918.25, 188025.75, - 536918.25, 187986.75, 536918.25, 187916.75, 536918.25, 187934.25, 536918.25, 187933.75, - 536918.25, 187988.75, 536918.25, 188107.75, 536918.25, 187998.75, 536918.25, 187979.25, - 536918.25, 187944.25, 536918.25, 188015.25, 536918.25, 188030.25, 536918.25, 187946.75, - 536918.25, 187973.75, 536918.25, 188102.75, 536918.25, 188025.25, 536918.25, 188155.25, - 536918.25, 187989.75, 536918.25, 188018.75, 536918.25, 187936.75, 536918.25, 187960.25, - 536918.25, 188139.25, 536918.25, 188022.75, 536918.75, 187923.75, 536918.75, 188132.25, - 536918.75, 188031.75, 536918.75, 187956.25, 536918.75, 187996.75, 536918.75, 188079.75, - 536918.75, 187925.75, 536918.75, 188047.25, 536918.75, 187936.25, 536918.75, 188107.25, - 536918.75, 188129.75, 536918.75, 188139.25, 536918.75, 187987.75, 536918.75, 187993.25, - 536918.75, 188156.25, 536918.75, 188103.25, 536918.75, 188151.75, 536918.75, 187959.75, - 536918.75, 187991.25, 536918.75, 188012.75, 536918.75, 188154.75, 536918.75, 188131.75, - 536918.75, 187985.75, 536918.75, 188105.25, 536918.75, 188100.25, 536918.75, 188026.75, - 536918.75, 187927.25, 536918.75, 188113.75, 536918.75, 188064.25, 536918.75, 188139.75, - 536918.75, 188016.75, 536918.75, 187989.25, 536918.75, 188109.75, 536918.75, 187926.25, - 536918.75, 188030.75, 536918.75, 188107.75, 536918.75, 188020.25, 536918.75, 187976.75, - 536918.75, 188080.25, 536918.75, 188128.25, 536918.75, 187962.75, 536918.75, 187988.75, - 536918.75, 188104.75, 536918.75, 188000.25, 536918.75, 187911.25, 536918.75, 187990.25, - 536918.75, 187934.25, 536918.75, 188145.25, 536918.75, 187921.75, 536918.75, 188042.25, - 536918.75, 187958.75, 536918.75, 187984.75, 536918.75, 187997.25, 536918.75, 188040.75, - 536918.75, 188077.75, 536918.75, 187923.25, 536918.75, 188016.25, 536918.75, 188098.75, - 536918.75, 187957.25, 536918.75, 188108.25, 536918.75, 187985.25, 536918.75, 188151.25, - 536918.75, 188146.25, 536918.75, 188078.25, 536918.75, 187971.25, 536918.75, 187974.75, - 536918.75, 187961.25, 536918.75, 188103.75, 536918.75, 187928.25, 536918.75, 188029.75, - 536918.75, 188147.25, 536918.75, 187922.75, 536918.75, 187947.75, 536919.25, 188125.75, - 536919.25, 188147.25, 536919.25, 187947.75, 536919.25, 187963.75, 536919.25, 187926.75, - 536919.25, 187928.25, 536919.25, 187947.25, 536919.25, 188102.25, 536919.25, 188106.25, - 536919.25, 188103.75, 536919.25, 187960.75, 536919.25, 187958.25, 536919.25, 188041.75, - 536919.25, 188019.75, 536919.25, 187935.75, 536919.25, 187934.75, 536919.25, 187944.75, - 536919.25, 187927.75, 536919.25, 187913.25, 536919.25, 187924.75, 536919.25, 188031.25, - 536919.25, 188101.75, 536919.25, 188144.75, 536919.25, 187972.25, 536919.25, 187932.75, - 536919.25, 187993.75, 536919.25, 188140.25, 536919.25, 188019.25, 536919.25, 188131.25, - 536919.25, 187953.25, 536919.25, 187974.25, 536919.25, 188155.75, 536919.25, 187997.75, - 536919.25, 187932.25, 536919.25, 188011.75, 536919.25, 188025.75, 536919.25, 188080.75, - 536919.25, 188013.75, 536919.25, 188078.75, 536919.25, 187990.25, 536919.25, 188032.25, - 536919.25, 187948.25, 536919.25, 188000.75, 536919.25, 188041.25, 536919.25, 187920.25, - 536919.25, 187922.25, 536919.25, 187956.25, 536919.25, 187923.75, 536919.25, 188076.25, - 536919.25, 188042.25, 536919.25, 188118.75, 536919.25, 187998.75, 536919.25, 188099.75, - 536919.25, 187942.25, 536919.25, 188042.75, 536919.25, 188016.75, 536919.25, 187956.75, - 536919.25, 187957.75, 536919.25, 188149.75, 536919.25, 187992.75, 536919.25, 187937.25, - 536919.25, 187948.75, 536919.25, 187927.25, 536919.25, 188015.75, 536919.25, 188130.75, - 536919.25, 188102.75, 536919.25, 188021.25, 536919.25, 188077.25, 536919.25, 188009.75, - 536919.25, 188043.25, 536919.25, 188002.25, 536919.25, 188106.75, 536919.25, 187921.75, - 536919.25, 187911.75, 536919.25, 188051.75, 536919.25, 187992.25, 536919.25, 187993.25, - 536919.25, 187987.75, 536919.25, 187962.25, 536919.25, 188110.25, 536919.25, 188152.25, - 536919.25, 187988.25, 536919.25, 187925.75, 536919.25, 188159.75, 536919.25, 188025.25, - 536919.25, 188022.75, 536919.25, 188035.75, 536919.25, 188031.75, 536919.25, 188140.75, - 536919.25, 188132.25, 536919.25, 188012.75, 536919.25, 187955.75, 536919.75, 188076.25, - 536919.75, 187968.25, 536919.75, 187992.75, 536919.75, 188042.25, 536919.75, 187993.25, - 536919.75, 188078.25, 536919.75, 187996.25, 536919.75, 187923.75, 536919.75, 187962.25, - 536919.75, 188145.75, 536919.75, 187999.25, 536919.75, 187958.25, 536919.75, 187987.25, - 536919.75, 188038.75, 536919.75, 187928.25, 536919.75, 188046.25, 536919.75, 188099.75, - 536919.75, 187937.25, 536919.75, 187935.75, 536919.75, 187926.25, 536919.75, 187920.25, - 536919.75, 187933.75, 536919.75, 187991.25, 536919.75, 187956.75, 536919.75, 187932.25, - 536919.75, 188140.25, 536919.75, 188126.25, 536919.75, 188031.75, 536919.75, 188117.25, - 536919.75, 187986.25, 536919.75, 187992.25, 536919.75, 188026.75, 536919.75, 188016.25, - 536919.75, 188058.75, 536919.75, 188008.75, 536919.75, 188077.25, 536919.75, 188000.25, - 536919.75, 187927.25, 536919.75, 188058.25, 536919.75, 188041.75, 536919.75, 188160.25, - 536919.75, 187934.75, 536919.75, 188108.75, 536919.75, 188131.25, 536919.75, 188107.25, - 536919.75, 188019.25, 536919.75, 188036.75, 536919.75, 188031.25, 536919.75, 187954.75, - 536919.75, 187922.25, 536919.75, 187986.75, 536919.75, 187963.75, 536919.75, 188152.75, - 536919.75, 188104.75, 536919.75, 187948.25, 536919.75, 188112.25, 536919.75, 187993.75, - 536919.75, 188051.25, 536919.75, 188147.25, 536919.75, 187957.25, 536919.75, 188140.75, - 536919.75, 187998.25, 536919.75, 188132.25, 536919.75, 188012.25, 536919.75, 187927.75, - 536919.75, 188153.25, 536919.75, 187956.25, 536919.75, 188110.75, 536919.75, 188144.25, - 536919.75, 187990.75, 536919.75, 188102.25, 536919.75, 188017.25, 536919.75, 188108.25, - 536919.75, 187920.75, 536919.75, 187981.75, 536919.75, 188011.75, 536919.75, 187947.25, - 536919.75, 187936.75, 536919.75, 187911.75, 536919.75, 188143.75, 536919.75, 187922.75, - 536919.75, 188041.25, 536919.75, 188015.25, 536919.75, 188081.25, 536919.75, 187987.75, - 536919.75, 188013.75, 536919.75, 188105.75, 536919.75, 188102.75, 536919.75, 187929.75, - 536919.75, 187994.25, 536919.75, 187972.25, 536919.75, 187960.75, 536919.75, 188101.75, - 536919.75, 188024.75, 536919.75, 187983.25, 536919.75, 188019.75, 536919.75, 187932.75, - 536919.75, 188023.25, 536919.75, 188025.75, 536919.75, 188099.25, 536919.75, 188001.75, - 536919.75, 188080.75, 536919.75, 187910.75, 536919.75, 188130.25, 536920.25, 188130.75, - 536920.25, 188113.75, 536920.25, 188116.25, 536920.25, 188094.75, 536920.25, 188025.75, - 536920.25, 188130.25, 536920.25, 188157.25, 536920.25, 188076.75, 536920.25, 188023.25, - 536920.25, 188080.75, 536920.25, 187990.75, 536920.25, 188102.75, 536920.25, 187921.75, - 536920.25, 188025.25, 536920.25, 188139.25, 536920.25, 188013.25, 536920.25, 187949.25, - 536920.25, 187920.25, 536920.25, 188143.75, 536920.25, 188152.25, 536920.25, 187991.75, - 536920.25, 187919.25, 536920.25, 187918.75, 536920.25, 188155.75, 536920.25, 188153.25, - 536920.25, 187928.75, 536920.25, 187954.75, 536920.25, 188140.75, 536920.25, 187948.75, - 536920.25, 187924.75, 536920.25, 188115.25, 536920.25, 188020.75, 536920.25, 188128.75, - 536920.25, 187925.75, 536920.25, 188141.25, 536920.25, 187955.75, 536920.25, 188001.25, - 536920.25, 187947.75, 536920.25, 188075.75, 536920.25, 188021.75, 536920.25, 188145.25, - 536920.25, 188104.25, 536920.25, 188107.25, 536920.25, 187990.25, 536920.25, 187921.25, - 536920.25, 187938.75, 536920.25, 187934.75, 536920.25, 188105.25, 536920.25, 187997.75, - 536920.25, 187962.75, 536920.25, 188093.75, 536920.25, 187933.25, 536920.25, 188109.25, - 536920.25, 187924.25, 536920.25, 188079.75, 536920.25, 187923.25, 536920.25, 187960.25, - 536920.25, 187959.25, 536920.25, 188010.25, 536920.25, 188151.25, 536920.25, 187955.25, - 536920.25, 187956.75, 536920.25, 187992.75, 536920.25, 188145.75, 536920.25, 188079.25, - 536920.25, 187962.25, 536920.25, 187925.25, 536920.25, 187999.25, 536920.25, 188032.25, - 536920.75, 188079.25, 536920.75, 187991.25, 536920.75, 188156.75, 536920.75, 187943.75, - 536920.75, 188031.75, 536920.75, 187953.25, 536920.75, 187963.25, 536920.75, 187919.75, - 536920.75, 188016.25, 536920.75, 187957.75, 536920.75, 187915.75, 536920.75, 188128.25, - 536920.75, 187925.25, 536920.75, 188144.75, 536920.75, 188104.25, 536920.75, 188042.25, - 536920.75, 188124.25, 536920.75, 187917.75, 536920.75, 188148.25, 536920.75, 188078.75, - 536920.75, 188140.75, 536920.75, 188157.75, 536920.75, 187961.25, 536920.75, 188106.75, - 536920.75, 187948.25, 536920.75, 188093.25, 536920.75, 188151.75, 536920.75, 187947.25, - 536920.75, 188022.75, 536920.75, 188139.25, 536920.75, 187954.25, 536920.75, 187994.25, - 536920.75, 187954.75, 536920.75, 188010.75, 536920.75, 188032.75, 536920.75, 188146.25, - 536920.75, 188155.25, 536920.75, 187935.25, 536920.75, 188149.75, 536920.75, 188094.75, - 536920.75, 188043.25, 536920.75, 188130.75, 536920.75, 188076.25, 536920.75, 187990.75, - 536920.75, 188069.25, 536920.75, 187995.25, 536920.75, 188023.25, 536920.75, 188024.75, - 536920.75, 187929.75, 536920.75, 187952.75, 536920.75, 188152.25, 536920.75, 188150.75, - 536920.75, 187921.75, 536920.75, 188009.25, 536920.75, 188154.25, 536920.75, 187930.25, - 536920.75, 187918.75, 536920.75, 187927.75, 536920.75, 187964.25, 536920.75, 188155.75, - 536920.75, 188144.25, 536920.75, 187973.75, 536920.75, 188043.75, 536920.75, 187953.75, - 536920.75, 187941.75, 536920.75, 188127.75, 536920.75, 188002.75, 536920.75, 188128.75, - 536920.75, 188074.75, 536920.75, 188152.75, 536920.75, 188075.25, 536920.75, 187934.25, - 536920.75, 187998.25, 536920.75, 188129.75, 536920.75, 188041.75, 536920.75, 188042.75, - 536920.75, 188143.25, 536920.75, 187989.25, 536920.75, 188106.25, 536920.75, 188080.25, - 536920.75, 188008.75, 536920.75, 188016.75, 536920.75, 187949.75, 536920.75, 188093.75, - 536920.75, 187918.25, 536920.75, 188011.25, 536920.75, 187943.25, 536920.75, 187924.25, - 536920.75, 188129.25, 536920.75, 187993.75, 536920.75, 187923.25, 536920.75, 188151.25, - 536920.75, 187959.25, 536920.75, 187955.25, 536920.75, 188153.75, 536920.75, 187929.25, - 536920.75, 188024.25, 536920.75, 188020.25, 536920.75, 187912.75, 536920.75, 188103.25, - 536920.75, 187942.75, 536920.75, 188022.25, 536920.75, 188100.75, 536920.75, 188137.75, - 536920.75, 187912.25, 536920.75, 187998.75, 536921.25, 187953.75, 536921.25, 188078.25, - 536921.25, 188042.25, 536921.25, 187993.75, 536921.25, 188032.25, 536921.25, 187942.75, - 536921.25, 188129.25, 536921.25, 187943.25, 536921.25, 187955.25, 536921.25, 188093.75, - 536921.25, 188080.25, 536921.25, 188022.25, 536921.25, 187958.25, 536921.25, 187989.25, - 536921.25, 188042.75, 536921.25, 188106.25, 536921.25, 188103.25, 536921.25, 188129.75, - 536921.25, 187962.25, 536921.25, 188001.25, 536921.25, 188033.25, 536921.25, 188103.75, - 536921.25, 188153.75, 536921.25, 188011.75, 536921.25, 187928.25, 536921.25, 187935.75, - 536921.25, 187923.25, 536921.25, 187930.25, 536921.25, 188151.25, 536921.25, 188008.75, - 536921.25, 188013.75, 536921.25, 188025.25, 536921.25, 188102.75, 536921.25, 187924.25, - 536921.25, 188130.25, 536921.25, 188071.75, 536921.25, 188149.25, 536921.25, 188010.75, - 536921.25, 187942.25, 536921.25, 187938.25, 536921.25, 188043.75, 536921.25, 188041.75, - 536921.25, 187911.75, 536921.25, 188139.25, 536921.25, 188151.75, 536921.25, 188012.75, - 536921.25, 188157.75, 536921.25, 188075.75, 536921.25, 187934.25, 536921.25, 188154.25, - 536921.25, 188141.25, 536921.25, 188031.25, 536921.25, 187990.75, 536921.25, 188146.75, - 536921.25, 187917.25, 536921.25, 188128.25, 536921.25, 188152.75, 536921.25, 187934.75, - 536921.25, 188127.75, 536921.25, 188147.25, 536921.25, 188132.25, 536921.25, 188100.25, - 536921.25, 188074.25, 536921.25, 188114.25, 536921.25, 188079.25, 536921.25, 187944.25, - 536921.25, 188009.25, 536921.25, 188101.75, 536921.25, 188031.75, 536921.25, 187949.25, - 536921.25, 187921.75, 536921.25, 187993.25, 536921.25, 188138.75, 536921.25, 187933.25, - 536921.25, 187973.75, 536921.25, 187956.25, 536921.25, 187919.75, 536921.25, 188107.25, - 536921.25, 188019.25, 536921.25, 187987.75, 536921.25, 187952.75, 536921.25, 187957.75, - 536921.25, 187960.75, 536921.25, 187947.75, 536921.25, 187963.75, 536921.25, 187917.75, - 536921.25, 188023.25, 536921.25, 188152.25, 536921.25, 188154.75, 536921.25, 188156.75, - 536921.25, 187994.25, 536921.25, 187948.25, 536921.25, 187989.75, 536921.25, 187922.75, - 536921.25, 187913.25, 536921.25, 188109.75, 536921.25, 187954.25, 536921.25, 188001.75, - 536921.75, 188102.25, 536921.75, 188001.75, 536921.75, 188064.75, 536921.75, 188022.75, - 536921.75, 188017.25, 536921.75, 188009.75, 536921.75, 188124.25, 536921.75, 188149.75, - 536921.75, 188043.25, 536921.75, 187999.75, 536921.75, 188020.75, 536921.75, 188154.75, - 536921.75, 188140.75, 536921.75, 187995.25, 536921.75, 187997.25, 536921.75, 188024.75, - 536921.75, 188045.75, 536921.75, 187951.75, 536921.75, 187987.75, 536921.75, 188003.25, - 536921.75, 187953.25, 536921.75, 187921.75, 536921.75, 188124.75, 536921.75, 187960.75, - 536921.75, 188101.75, 536921.75, 188143.75, 536921.75, 187969.75, 536921.75, 188092.75, - 536921.75, 187995.75, 536921.75, 187933.75, 536921.75, 188100.25, 536921.75, 188147.25, - 536921.75, 187963.25, 536921.75, 188156.25, 536921.75, 187930.75, 536921.75, 188132.25, - 536921.75, 188150.25, 536921.75, 188127.75, 536921.75, 187917.25, 536921.75, 188152.75, - 536921.75, 188013.25, 536921.75, 188128.25, 536921.75, 188112.75, 536921.75, 188131.25, - 536921.75, 188146.75, 536921.75, 187957.25, 536921.75, 187998.25, 536921.75, 188078.75, - 536921.75, 188012.75, 536921.75, 187961.25, 536921.75, 188127.25, 536921.75, 188032.75, - 536921.75, 187990.25, 536921.75, 187928.75, 536921.75, 187954.75, 536921.75, 188077.75, - 536921.75, 187938.75, 536921.75, 188000.25, 536921.75, 187988.75, 536921.75, 187918.25, - 536921.75, 188150.75, 536921.75, 188062.25, 536921.75, 188023.75, 536921.75, 187930.25, - 536921.75, 188054.75, 536921.75, 188125.25, 536921.75, 188153.25, 536921.75, 187948.75, - 536921.75, 187964.75, 536921.75, 187940.25, 536921.75, 188033.25, 536921.75, 188024.25, - 536921.75, 188145.25, 536921.75, 187935.75, 536921.75, 188131.75, 536921.75, 188001.25, - 536921.75, 187922.25, 536921.75, 188042.75, 536921.75, 188027.75, 536921.75, 188093.75, - 536921.75, 187912.75, 536921.75, 187949.75, 536921.75, 188021.25, 536921.75, 187955.25, - 536921.75, 187959.25, 536921.75, 187994.75, 536921.75, 188145.75, 536921.75, 188088.75, - 536922.25, 188050.75, 536922.25, 187962.25, 536922.25, 187952.25, 536922.25, 187987.25, - 536922.25, 188024.25, 536922.25, 188055.25, 536922.25, 187940.25, 536922.25, 188033.25, - 536922.25, 188141.75, 536922.25, 187918.25, 536922.25, 188016.75, 536922.25, 188002.25, - 536922.25, 188123.75, 536922.25, 188150.25, 536922.25, 188043.75, 536922.25, 187942.25, - 536922.25, 188160.25, 536922.25, 188144.25, 536922.25, 188127.75, 536922.25, 188142.75, - 536922.25, 187940.75, 536922.25, 188002.75, 536922.25, 187930.75, 536922.25, 188143.75, - 536922.25, 187920.75, 536922.25, 188009.25, 536922.25, 188156.75, 536922.25, 188094.75, - 536922.25, 188017.25, 536922.25, 188101.75, 536922.25, 188023.25, 536922.25, 187929.75, - 536922.25, 187916.75, 536922.25, 188033.75, 536922.25, 188147.75, 536922.25, 188076.25, - 536922.25, 188012.25, 536922.25, 188037.75, 536922.25, 188073.75, 536922.25, 188043.25, - 536922.25, 187963.75, 536922.25, 188130.75, 536922.25, 188076.75, 536922.25, 188155.25, - 536922.25, 187937.25, 536922.25, 187983.25, 536922.25, 188126.25, 536922.25, 187916.25, - 536922.25, 188124.25, 536922.25, 187994.25, 536922.25, 187947.25, 536922.25, 188102.25, - 536922.25, 188148.75, 536922.25, 188031.25, 536922.25, 188144.75, 536922.25, 188020.75, - 536922.25, 188157.75, 536922.25, 188148.25, 536922.25, 187951.75, 536922.25, 187953.25, - 536922.25, 188146.25, 536922.25, 188099.25, 536922.25, 188124.75, 536922.25, 187930.25, - 536922.25, 188091.75, 536922.25, 187915.25, 536922.25, 187988.25, 536922.25, 187921.25, - 536922.25, 188010.25, 536922.25, 187955.75, 536922.25, 187935.25, 536922.25, 187991.25, - 536922.25, 188092.75, 536922.25, 187950.75, 536922.25, 187995.75, 536922.25, 187999.25, - 536922.25, 187996.25, 536922.25, 188078.25, 536922.25, 187993.75, 536922.25, 188108.75, - 536922.25, 187929.25, 536922.25, 187910.75, 536922.25, 188093.75, 536922.25, 188154.25, - 536922.25, 188122.25, 536922.25, 187974.75, 536922.25, 188021.25, 536922.25, 188011.25, - 536922.25, 188112.75, 536922.25, 187922.25, 536922.25, 188112.25, 536922.25, 187949.75, - 536922.25, 187939.25, 536922.25, 188139.75, 536922.25, 187948.75, 536922.25, 187986.75, - 536922.25, 187953.75, 536922.25, 187964.25, 536922.25, 187918.75, 536922.25, 187936.75, - 536922.25, 188150.75, 536922.25, 188090.75, 536922.25, 188133.25, 536922.25, 188130.25, - 536922.25, 188025.75, 536922.25, 188145.75, 536922.25, 188032.75, 536922.25, 188132.75, - 536922.25, 187920.25, 536922.75, 187920.25, 536922.75, 188132.75, 536922.75, 187932.75, - 536922.75, 188039.25, 536922.75, 188145.75, 536922.75, 188013.75, 536922.75, 188151.75, - 536922.75, 188031.75, 536922.75, 187949.75, 536922.75, 187918.75, 536922.75, 187961.25, - 536922.75, 187948.75, 536922.75, 188032.75, 536922.75, 188139.75, 536922.75, 188129.75, - 536922.75, 188100.25, 536922.75, 188042.75, 536922.75, 188093.75, 536922.75, 187929.25, - 536922.75, 188153.25, 536922.75, 188109.25, 536922.75, 188135.75, 536922.75, 188122.75, - 536922.75, 188158.75, 536922.75, 187950.75, 536922.75, 188133.75, 536922.75, 188092.75, - 536922.75, 187962.75, 536922.75, 187957.25, 536922.75, 187936.75, 536922.75, 188010.25, - 536922.75, 188000.75, 536922.75, 187915.25, 536922.75, 187988.25, 536922.75, 188011.75, - 536922.75, 188025.25, 536922.75, 188124.75, 536922.75, 188146.25, 536922.75, 187996.75, - 536922.75, 188096.75, 536922.75, 188077.25, 536922.75, 187994.25, 536922.75, 188139.25, - 536922.75, 188144.75, 536922.75, 188111.25, 536922.75, 188029.75, 536922.75, 188148.75, - 536922.75, 187947.25, 536922.75, 188094.25, 536922.75, 187950.25, 536922.75, 188126.25, - 536922.75, 187916.25, 536922.75, 187937.25, 536922.75, 187960.25, 536922.75, 187914.25, - 536922.75, 187951.25, 536922.75, 187999.75, 536922.75, 188104.25, 536922.75, 188021.75, - 536922.75, 188142.25, 536922.75, 188012.25, 536922.75, 188030.75, 536922.75, 187919.75, - 536922.75, 188147.75, 536922.75, 188055.75, 536922.75, 187929.75, 536922.75, 188001.75, - 536922.75, 188033.75, 536922.75, 187949.25, 536922.75, 187954.25, 536922.75, 188101.75, - 536922.75, 188017.25, 536922.75, 188154.75, 536922.75, 188009.25, 536922.75, 187920.75, - 536922.75, 188074.25, 536922.75, 188142.75, 536922.75, 188132.25, 536922.75, 188131.25, - 536922.75, 188098.75, 536922.75, 187975.25, 536922.75, 187925.75, 536922.75, 187998.25, - 536922.75, 188043.75, 536922.75, 188068.25, 536922.75, 188123.75, 536922.75, 188075.75, - 536922.75, 188144.25, 536922.75, 188151.25, 536922.75, 188016.75, 536922.75, 188045.25, - 536922.75, 188054.75, 536922.75, 188024.25, 536922.75, 187964.75, 536922.75, 187940.25, - 536922.75, 187987.25, 536922.75, 187912.75, 536922.75, 188100.75, 536922.75, 187952.25, - 536922.75, 187962.25, 536922.75, 187955.25, 536923.25, 187994.75, 536923.25, 188091.75, - 536923.25, 187955.25, 536923.25, 188012.75, 536923.25, 188100.75, 536923.25, 187958.25, - 536923.25, 188158.25, 536923.25, 188034.75, 536923.25, 188127.25, 536923.25, 188098.75, - 536923.25, 187965.25, 536923.25, 188127.75, 536923.25, 188133.75, 536923.25, 188143.25, - 536923.25, 187936.75, 536923.25, 188121.25, 536923.25, 188138.25, 536923.25, 187934.25, - 536923.25, 188002.75, 536923.25, 188043.75, 536923.25, 188075.75, 536923.25, 187942.25, - 536923.25, 188091.25, 536923.25, 187917.25, 536923.25, 188141.25, 536923.25, 188025.25, - 536923.25, 188074.75, 536923.25, 188023.25, 536923.25, 188142.75, 536923.25, 188152.25, - 536923.25, 188099.25, 536923.25, 188147.25, 536923.25, 187986.75, 536923.25, 188145.25, - 536923.25, 188043.25, 536923.25, 187999.75, 536923.25, 188151.25, 536923.25, 188085.75, - 536923.25, 188146.75, 536923.25, 187950.25, 536923.25, 188129.25, 536923.25, 188017.75, - 536923.25, 187941.25, 536923.25, 188149.75, 536923.25, 188133.25, 536923.25, 188022.25, - 536923.25, 188100.25, 536923.25, 187942.75, 536923.25, 187987.25, 536923.25, 187919.75, - 536923.25, 188033.25, 536923.25, 188140.25, 536923.25, 188094.25, 536923.25, 187952.75, - 536923.25, 188130.25, 536923.25, 188123.25, 536923.25, 188110.75, 536923.25, 188096.75, - 536923.25, 188099.75, 536923.25, 188013.25, 536923.25, 187934.75, 536923.25, 187929.75, - 536923.25, 188154.25, 536923.25, 187923.75, 536923.25, 187957.75, 536923.25, 188089.75, - 536923.25, 188000.75, 536923.25, 187995.75, 536923.25, 187914.25, 536923.25, 187950.75, - 536923.25, 187986.25, 536923.25, 188122.75, 536923.25, 188090.75, 536923.25, 187963.75, - 536923.25, 187915.75, 536923.25, 188003.25, 536923.25, 187915.25, 536923.25, 188019.25, - 536923.25, 187929.25, 536923.25, 187984.75, 536923.25, 188142.25, 536923.25, 188021.75, - 536923.25, 188095.75, 536923.25, 187943.25, 536923.25, 187916.75, 536923.25, 188021.25, - 536923.25, 188135.25, 536923.25, 187954.75, 536923.25, 187937.75, 536923.25, 188013.75, - 536923.25, 187998.75, 536923.25, 188030.75, 536923.25, 188151.75, 536923.25, 187917.75, - 536923.25, 187936.25, 536923.25, 188061.25, 536923.25, 188009.75, 536923.25, 188155.25, - 536923.25, 188130.75, 536923.25, 187932.25, 536923.25, 187921.25, 536923.25, 188026.25, - 536923.25, 188122.25, 536923.75, 188155.25, 536923.75, 187985.75, 536923.75, 188130.75, - 536923.75, 187916.25, 536923.75, 188044.25, 536923.75, 188001.25, 536923.75, 188020.75, - 536923.75, 188012.25, 536923.75, 187917.75, 536923.75, 188151.75, 536923.75, 188013.75, - 536923.75, 187989.75, 536923.75, 187984.75, 536923.75, 187953.75, 536923.75, 187922.25, - 536923.75, 188137.25, 536923.75, 188159.25, 536923.75, 188003.25, 536923.75, 188095.75, - 536923.75, 187963.25, 536923.75, 187913.75, 536923.75, 188096.25, 536923.75, 187929.25, - 536923.75, 188090.75, 536923.75, 188135.75, 536923.75, 188098.25, 536923.75, 187954.75, - 536923.75, 187922.75, 536923.75, 188154.75, 536923.75, 187951.25, 536923.75, 187995.75, - 536923.75, 188130.25, 536923.75, 187929.75, 536923.75, 187919.25, 536923.75, 188089.75, - 536923.75, 187995.25, 536923.75, 188014.25, 536923.75, 187996.25, 536923.75, 187948.25, - 536923.75, 188120.25, 536923.75, 187985.25, 536923.75, 187921.75, 536923.75, 188107.25, - 536923.75, 188128.25, 536923.75, 187914.75, 536923.75, 188022.75, 536923.75, 187965.75, - 536923.75, 188150.25, 536923.75, 187958.75, 536923.75, 187983.25, 536923.75, 188120.75, - 536923.75, 188094.25, 536923.75, 188121.75, 536923.75, 187952.75, 536923.75, 188018.25, - 536923.75, 187987.75, 536923.75, 188119.75, 536923.75, 188034.25, 536923.75, 188043.25, - 536923.75, 188097.75, 536923.75, 188156.25, 536923.75, 188099.25, 536923.75, 188151.25, - 536923.75, 187935.75, 536923.75, 188115.75, 536923.75, 188142.75, 536923.75, 187930.75, - 536923.75, 188136.25, 536923.75, 188146.75, 536923.75, 188157.25, 536923.75, 187930.25, - 536923.75, 188088.25, 536923.75, 188026.75, 536923.75, 188149.25, 536923.75, 188134.75, - 536923.75, 188121.25, 536923.75, 188141.75, 536923.75, 187964.75, 536923.75, 188002.75, - 536923.75, 187935.25, 536923.75, 188010.75, 536923.75, 188002.25, 536923.75, 188025.75, - 536923.75, 188127.75, 536923.75, 188034.75, 536923.75, 188127.25, 536923.75, 188128.75, - 536923.75, 188097.25, 536923.75, 187962.25, 536924.25, 187965.75, 536924.25, 188004.75, - 536924.25, 188127.25, 536924.25, 188127.75, 536924.25, 188105.25, 536924.25, 188010.75, - 536924.25, 188095.25, 536924.25, 188121.25, 536924.25, 187986.75, 536924.25, 188069.25, - 536924.25, 188045.25, 536924.25, 188133.25, 536924.25, 187930.75, 536924.25, 187918.75, - 536924.25, 188145.25, 536924.25, 188142.75, 536924.25, 187941.25, 536924.25, 188034.75, - 536924.25, 187913.75, 536924.25, 188022.25, 536924.25, 188121.75, 536924.25, 188120.75, - 536924.25, 187955.25, 536924.25, 187958.75, 536924.25, 188013.25, 536924.25, 187921.75, - 536924.25, 188088.25, 536924.25, 188089.75, 536924.25, 188017.25, 536924.25, 187922.75, - 536924.25, 188154.75, 536924.25, 187995.75, 536924.25, 188024.75, 536924.25, 187960.75, - 536924.25, 188010.25, 536924.25, 188033.75, 536924.25, 188095.75, 536924.25, 188140.75, - 536924.25, 187937.75, 536924.25, 187984.75, 536924.25, 188027.25, 536924.25, 188109.25, - 536924.25, 188148.25, 536924.25, 188090.75, 536924.25, 188150.75, 536924.25, 187948.75, - 536924.25, 187997.25, 536924.25, 187949.75, 536924.25, 188044.25, 536924.25, 188013.75, - 536924.25, 187954.25, 536924.25, 187926.75, 536924.25, 187920.25, 536924.25, 188011.25, - 536924.25, 188137.25, 536924.25, 187984.25, 536924.25, 188159.25, 536924.25, 188031.75, - 536924.25, 188145.75, 536924.25, 188154.25, 536924.25, 187915.25, 536924.25, 187931.25, - 536924.25, 187963.75, 536924.25, 188135.75, 536924.25, 187929.75, 536924.25, 187950.75, - 536924.25, 187996.25, 536924.25, 188050.25, 536924.25, 187995.25, 536924.25, 187985.25, - 536924.25, 188107.25, 536924.25, 188134.25, 536924.25, 188123.25, 536924.25, 188128.25, - 536924.25, 188136.75, 536924.25, 187983.25, 536924.25, 188092.25, 536924.25, 187947.25, - 536924.25, 188094.25, 536924.25, 188081.25, 536924.25, 188043.25, 536924.25, 188119.75, - 536924.25, 188097.75, 536924.25, 188157.75, 536924.25, 188018.25, 536924.25, 188156.25, - 536924.25, 188149.75, 536924.25, 188129.25, 536924.25, 187987.75, 536924.25, 187935.25, - 536924.25, 188099.25, 536924.25, 188066.25, 536924.25, 188152.25, 536924.25, 188133.75, - 536924.25, 188131.25, 536924.25, 188043.75, 536924.25, 187936.75, 536924.25, 187934.25, - 536924.25, 188003.75, 536924.25, 188141.75, 536924.25, 188000.25, 536924.25, 188128.75, - 536924.25, 188097.25, 536924.25, 187962.25, 536924.25, 187964.75, 536924.25, 188150.25, - 536924.75, 188034.25, 536924.75, 188048.75, 536924.75, 188091.75, 536924.75, 188158.25, - 536924.75, 188020.25, 536924.75, 188131.75, 536924.75, 188123.75, 536924.75, 188025.25, - 536924.75, 188133.75, 536924.75, 187918.25, 536924.75, 188107.75, 536924.75, 187942.25, - 536924.75, 188129.25, 536924.75, 187996.75, 536924.75, 188160.25, 536924.75, 187920.75, - 536924.75, 188139.25, 536924.75, 188141.25, 536924.75, 188156.25, 536924.75, 188132.25, - 536924.75, 188094.25, 536924.75, 187926.25, 536924.75, 188134.25, 536924.75, 188136.25, - 536924.75, 187914.75, 536924.75, 188131.25, 536924.75, 187999.75, 536924.75, 188120.25, - 536924.75, 188155.75, 536924.75, 188119.25, 536924.75, 187987.75, 536924.75, 188128.25, - 536924.75, 187952.75, 536924.75, 187913.75, 536924.75, 188022.75, 536924.75, 187995.25, - 536924.75, 187910.75, 536924.75, 188003.25, 536924.75, 187983.25, 536924.75, 188014.25, - 536924.75, 187997.25, 536924.75, 188129.75, 536924.75, 188011.25, 536924.75, 187922.25, - 536924.75, 187950.75, 536924.75, 187931.25, 536924.75, 188122.75, 536924.75, 188046.75, - 536924.75, 187917.75, 536924.75, 188154.25, 536924.75, 187955.25, 536924.75, 188096.25, - 536924.75, 188034.75, 536924.75, 188150.75, 536924.75, 188142.25, 536924.75, 188104.75, - 536924.75, 188018.75, 536924.75, 187920.25, 536924.75, 188001.25, 536924.75, 187983.75, - 536924.75, 187963.25, 536924.75, 188094.75, 536924.75, 187930.25, 536924.75, 188130.75, - 536924.75, 188122.25, 536924.75, 188026.25, 536924.75, 188142.75, 536924.75, 188148.25, - 536924.75, 187930.75, 536924.75, 188002.75, 536924.75, 188140.75, 536924.75, 188044.75, - 536924.75, 187988.25, 536924.75, 188148.75, 536924.75, 187945.75, 536924.75, 188118.75, - 536924.75, 188098.25, 536924.75, 187954.75, 536924.75, 188089.75, 536924.75, 187957.75, - 536924.75, 187939.75, 536924.75, 187935.75, 536924.75, 187940.25, 536924.75, 187948.25, - 536924.75, 188118.25, 536924.75, 188022.25, 536924.75, 187918.75, 536924.75, 187946.75, - 536924.75, 188045.25, 536924.75, 188126.75, 536924.75, 187950.25, 536925.25, 187950.25, - 536925.25, 188126.75, 536925.25, 188146.75, 536925.25, 188022.25, 536925.25, 188118.25, - 536925.25, 188090.25, 536925.25, 188140.25, 536925.25, 187974.75, 536925.25, 187998.25, - 536925.25, 188051.25, 536925.25, 188156.75, 536925.25, 188093.25, 536925.25, 188095.25, - 536925.25, 187923.75, 536925.25, 187997.75, 536925.25, 188089.75, 536925.25, 188068.25, - 536925.25, 187988.75, 536925.25, 188126.25, 536925.25, 188134.75, 536925.25, 188035.25, - 536925.25, 188004.75, 536925.25, 188102.75, 536925.25, 187982.25, 536925.25, 188044.75, - 536925.25, 187951.75, 536925.25, 187982.75, 536925.25, 188135.25, 536925.25, 187947.75, - 536925.25, 187937.75, 536925.25, 188027.25, 536925.25, 187985.75, 536925.25, 187936.25, - 536925.25, 188084.25, 536925.25, 188038.25, 536925.25, 188110.75, 536925.25, 188154.75, - 536925.25, 188130.25, 536925.25, 188094.75, 536925.25, 187981.75, 536925.25, 188155.25, - 536925.25, 187913.25, 536925.25, 187983.75, 536925.25, 187919.25, 536925.25, 188001.25, - 536925.25, 188013.75, 536925.25, 187946.25, 536925.25, 187964.25, 536925.25, 187931.75, - 536925.25, 188096.25, 536925.25, 188045.75, 536925.25, 187953.75, 536925.25, 188012.25, - 536925.25, 188122.75, 536925.25, 188061.25, 536925.25, 187954.25, 536925.25, 188147.75, - 536925.25, 188139.75, 536925.25, 187945.25, 536925.25, 187931.25, 536925.25, 187966.25, - 536925.25, 187914.25, 536925.25, 187997.25, 536925.25, 188093.75, 536925.25, 187959.25, - 536925.25, 187995.25, 536925.25, 188123.25, 536925.25, 187949.25, 536925.25, 188022.75, - 536925.25, 188021.75, 536925.25, 187947.25, 536925.25, 188069.75, 536925.25, 188015.25, - 536925.25, 188124.25, 536925.25, 187912.25, 536925.25, 187914.75, 536925.25, 188147.25, - 536925.25, 188151.25, 536925.25, 187961.25, 536925.25, 188120.25, 536925.25, 188142.25, - 536925.25, 188131.25, 536925.25, 188046.25, 536925.25, 188070.25, 536925.25, 188157.25, - 536925.25, 187959.75, 536925.25, 188023.25, 536925.25, 188119.75, 536925.25, 188132.25, - 536925.25, 188066.75, 536925.25, 188139.25, 536925.25, 187917.25, 536925.25, 188078.75, - 536925.25, 188158.75, 536925.25, 187935.25, 536925.25, 187996.75, 536925.25, 187918.25, - 536925.25, 188085.25, 536925.25, 188026.75, 536925.25, 188149.25, 536925.25, 188014.75, - 536925.25, 187912.75, 536925.25, 187923.25, 536925.25, 188143.25, 536925.25, 187937.25, - 536925.25, 188128.75, 536925.25, 187987.25, 536925.25, 188159.75, 536925.25, 188123.75, - 536925.25, 188158.25, 536925.25, 187989.25, 536925.25, 188000.25, 536925.25, 187958.25, - 536925.25, 187955.25, 536925.25, 187952.25, 536925.25, 188034.25, 536925.25, 187951.25, - 536925.75, 187994.75, 536925.75, 188095.25, 536925.75, 187996.75, 536925.75, 188099.25, - 536925.75, 188144.75, 536925.75, 188158.25, 536925.75, 187952.25, 536925.75, 188134.25, - 536925.75, 188088.75, 536925.75, 188141.75, 536925.75, 187956.25, 536925.75, 188021.75, - 536925.75, 187997.25, 536925.75, 187964.75, 536925.75, 188084.75, 536925.75, 187913.75, - 536925.75, 188026.75, 536925.75, 187930.75, 536925.75, 188127.75, 536925.75, 187913.25, - 536925.75, 188083.75, 536925.75, 188126.75, 536925.75, 188022.25, 536925.75, 187998.25, - 536925.75, 187976.25, 536925.75, 188016.25, 536925.75, 188125.75, 536925.75, 187998.75, - 536925.75, 188046.25, 536925.75, 187959.75, 536925.75, 188106.25, 536925.75, 187985.25, - 536925.75, 187936.25, 536925.75, 187946.25, 536925.75, 187966.25, 536925.75, 188142.25, - 536925.75, 188044.25, 536925.75, 188129.75, 536925.75, 188022.75, 536925.75, 188124.25, - 536925.75, 188155.75, 536925.75, 188143.25, 536925.75, 187947.75, 536925.75, 187958.25, - 536925.75, 188000.25, 536925.75, 188014.75, 536925.75, 188149.25, 536925.75, 188066.75, - 536925.75, 187944.25, 536925.75, 188023.25, 536925.75, 187947.25, 536925.75, 188123.25, - 536925.75, 187950.75, 536925.75, 188147.75, 536925.75, 187932.75, 536925.75, 188023.75, - 536925.75, 188001.25, 536925.75, 188067.75, 536925.75, 188122.25, 536925.75, 188137.75, - 536925.75, 188156.75, 536925.75, 188090.25, 536925.75, 187918.75, 536925.75, 188138.25, - 536925.75, 187935.75, 536925.75, 187977.75, 536925.75, 188116.75, 536925.75, 188002.25, - 536925.75, 188155.25, 536925.75, 188068.75, 536925.75, 187982.75, 536925.75, 188101.75, - 536925.75, 188154.75, 536925.75, 188094.75, 536925.75, 188006.25, 536925.75, 188012.25, - 536925.75, 187949.25, 536925.75, 187954.25, 536925.75, 188140.75, 536925.75, 188019.25, - 536925.75, 187951.75, 536925.75, 187914.25, 536925.75, 188003.25, 536925.75, 187951.25, - 536925.75, 187963.75, 536925.75, 188069.75, 536925.75, 188086.25, 536925.75, 188070.25, - 536925.75, 187931.25, 536925.75, 187988.25, 536925.75, 188034.25, 536925.75, 188035.25, - 536925.75, 187912.25, 536925.75, 188130.75, 536925.75, 187959.25, 536925.75, 188093.75, - 536925.75, 188156.25, 536925.75, 188139.75, 536925.75, 187922.75, 536925.75, 188092.75, - 536925.75, 187945.25, 536925.75, 187930.25, 536925.75, 187967.25, 536925.75, 188117.75, - 536925.75, 188146.75, 536925.75, 187982.25, 536925.75, 188118.75, 536925.75, 188046.75, - 536925.75, 187986.75, 536926.25, 188093.25, 536926.25, 188131.25, 536926.25, 188046.75, - 536926.25, 187936.75, 536926.25, 188091.75, 536926.25, 188005.25, 536926.25, 188144.75, - 536926.25, 187988.75, 536926.25, 188071.75, 536926.25, 188134.25, 536926.25, 187952.25, - 536926.25, 187967.25, 536926.25, 187980.75, 536926.25, 187966.75, 536926.25, 188117.75, - 536926.25, 188128.25, 536926.25, 188034.75, 536926.25, 187953.75, 536926.25, 187923.75, - 536926.25, 188092.75, 536926.25, 188104.25, 536926.25, 187923.25, 536926.25, 188128.75, - 536926.25, 187931.75, 536926.25, 187912.75, 536926.25, 188084.75, 536926.25, 187930.75, - 536926.25, 187962.75, 536926.25, 188134.75, 536926.25, 187913.25, 536926.25, 188127.25, - 536926.25, 188158.75, 536926.25, 188126.75, 536926.25, 188145.25, 536926.25, 188029.75, - 536926.25, 188119.25, 536926.25, 187998.25, 536926.25, 188046.25, 536926.25, 188044.75, - 536926.25, 188040.25, 536926.25, 188115.25, 536926.25, 187962.25, 536926.25, 187998.75, - 536926.25, 188056.25, 536926.25, 188141.25, 536926.25, 188011.75, 536926.25, 188034.25, - 536926.25, 188036.25, 536926.25, 188087.25, 536926.25, 187964.25, 536926.25, 188146.25, - 536926.25, 187993.75, 536926.25, 188107.25, 536926.25, 188124.75, 536926.25, 188094.25, - 536926.25, 188155.75, 536926.25, 188015.25, 536926.25, 188120.25, 536926.25, 187960.25, - 536926.25, 188117.25, 536926.25, 187918.25, 536926.25, 188144.25, 536926.25, 187949.75, - 536926.25, 188123.75, 536926.25, 187987.75, 536926.25, 188145.75, 536926.25, 188014.25, - 536926.25, 188147.75, 536926.25, 187951.75, 536926.25, 188140.75, 536926.25, 188122.75, - 536926.25, 188159.25, 536926.25, 188130.25, 536926.25, 188048.25, 536926.25, 187932.75, - 536926.25, 188094.75, 536926.25, 187944.75, 536926.25, 188138.75, 536926.25, 188133.25, - 536926.25, 188151.25, 536926.25, 188137.75, 536926.25, 188116.25, 536926.25, 188142.75, - 536926.25, 187980.25, 536926.25, 188001.75, 536926.25, 187960.75, 536926.25, 188156.75, - 536926.25, 188085.75, 536926.25, 187921.75, 536926.25, 188027.75, 536926.25, 188035.75, - 536926.25, 188081.25, 536926.75, 187996.75, 536926.75, 187911.75, 536926.75, 187924.25, - 536926.75, 188068.75, 536926.75, 188116.75, 536926.75, 188100.75, 536926.75, 188121.25, - 536926.75, 188157.75, 536926.75, 188144.75, 536926.75, 188138.25, 536926.75, 188118.75, - 536926.75, 188100.25, 536926.75, 188027.75, 536926.75, 187918.75, 536926.75, 187940.75, - 536926.75, 187981.25, 536926.75, 187923.25, 536926.75, 187917.75, 536926.75, 188026.25, - 536926.75, 188045.75, 536926.75, 188121.75, 536926.75, 188139.75, 536926.75, 188113.75, - 536926.75, 188013.25, 536926.75, 187967.75, 536926.75, 187937.25, 536926.75, 188002.75, - 536926.75, 187948.25, 536926.75, 187931.75, 536926.75, 188093.75, 536926.75, 187937.75, - 536926.75, 187943.75, 536926.75, 187964.75, 536926.75, 187921.25, 536926.75, 188127.75, - 536926.75, 187965.75, 536926.75, 188116.25, 536926.75, 187938.75, 536926.75, 187997.75, - 536926.75, 188138.75, 536926.75, 188001.25, 536926.75, 188019.75, 536926.75, 187913.25, - 536926.75, 188094.75, 536926.75, 188085.25, 536926.75, 187932.75, 536926.75, 188127.25, - 536926.75, 188027.25, 536926.75, 188129.25, 536926.75, 188159.25, 536926.75, 188035.25, - 536926.75, 188091.25, 536926.75, 188045.25, 536926.75, 187950.25, 536926.75, 188022.25, - 536926.75, 188014.25, 536926.75, 187953.25, 536926.75, 188083.75, 536926.75, 188136.75, - 536926.75, 188130.75, 536926.75, 188157.25, 536926.75, 187944.25, 536926.75, 188046.25, - 536926.75, 187957.75, 536926.75, 187950.75, 536926.75, 188115.25, 536926.75, 187917.25, - 536926.75, 187959.25, 536926.75, 187989.25, 536926.75, 188003.75, 536926.75, 188066.75, - 536926.75, 188141.25, 536926.75, 188145.75, 536926.75, 188092.25, 536926.75, 188063.75, - 536926.75, 188049.75, 536926.75, 188036.25, 536926.75, 187932.25, 536926.75, 188083.25, - 536926.75, 187948.75, 536926.75, 187988.25, 536926.75, 188143.25, 536926.75, 187933.25, - 536926.75, 188117.25, 536926.75, 188028.25, 536926.75, 187991.75, 536926.75, 188015.75, - 536926.75, 187920.25, 536926.75, 188124.25, 536926.75, 187999.25, 536926.75, 188015.25, - 536926.75, 188082.75, 536926.75, 188119.75, 536926.75, 188022.75, 536926.75, 188155.75, - 536926.75, 188124.75, 536927.25, 188124.75, 536927.25, 188082.25, 536927.25, 188094.25, - 536927.25, 187931.25, 536927.25, 188082.75, 536927.25, 188120.25, 536927.25, 188086.25, - 536927.25, 187987.75, 536927.25, 188036.25, 536927.25, 187938.25, 536927.25, 188124.25, - 536927.25, 188015.75, 536927.25, 187961.25, 536927.25, 188025.25, 536927.25, 188102.25, - 536927.25, 187948.75, 536927.25, 188032.25, 536927.25, 187992.25, 536927.25, 187966.25, - 536927.25, 188083.25, 536927.25, 187988.25, 536927.25, 187952.75, 536927.25, 188092.25, - 536927.25, 188065.75, 536927.25, 187911.25, 536927.25, 188014.75, 536927.25, 188034.25, - 536927.25, 188142.25, 536927.25, 187918.75, 536927.25, 188132.25, 536927.25, 188150.75, - 536927.25, 187998.75, 536927.25, 188049.75, 536927.25, 187989.25, 536927.25, 187920.75, - 536927.25, 187950.75, 536927.25, 188115.25, 536927.25, 188108.25, 536927.25, 188160.25, - 536927.25, 188130.75, 536927.25, 187917.25, 536927.25, 187944.25, 536927.25, 187992.75, - 536927.25, 187959.75, 536927.25, 188062.75, 536927.25, 188028.75, 536927.25, 188003.25, - 536927.25, 188119.25, 536927.25, 188004.25, 536927.25, 188091.25, 536927.25, 188045.25, - 536927.25, 187953.25, 536927.25, 188016.75, 536927.25, 187913.25, 536927.25, 188122.75, - 536927.25, 188159.25, 536927.25, 188127.25, 536927.25, 188012.25, 536927.25, 188129.25, - 536927.25, 187932.75, 536927.25, 187912.25, 536927.25, 187969.25, 536927.25, 188094.75, - 536927.25, 188085.25, 536927.25, 187938.75, 536927.25, 188026.25, 536927.25, 188116.25, - 536927.25, 188138.75, 536927.25, 188035.25, 536927.25, 187997.75, 536927.25, 188137.75, - 536927.25, 187910.75, 536927.25, 187962.75, 536927.25, 188127.75, 536927.25, 188038.25, - 536927.25, 188142.75, 536927.25, 188098.75, 536927.25, 187985.25, 536927.25, 188026.75, - 536927.25, 187994.75, 536927.25, 188084.25, 536927.25, 187912.75, 536927.25, 188068.25, - 536927.25, 188093.75, 536927.25, 188139.75, 536927.25, 188089.75, 536927.25, 187948.25, - 536927.25, 187982.75, 536927.25, 187923.25, 536927.25, 187942.75, 536927.25, 187917.75, - 536927.25, 188138.25, 536927.25, 188113.75, 536927.25, 188092.75, 536927.25, 188012.75, - 536927.25, 188156.25, 536927.25, 188140.25, 536927.25, 188146.75, 536927.25, 188093.25, - 536927.25, 188027.75, 536927.25, 187978.25, 536927.25, 188091.75, 536927.25, 188005.25, - 536927.25, 188027.25, 536927.25, 188116.75, 536927.25, 187911.75, 536927.25, 188121.25, - 536927.25, 187924.25, 536927.25, 187936.75, 536927.25, 187965.25, 536927.75, 188084.25, - 536927.75, 187999.25, 536927.75, 188090.75, 536927.75, 187950.75, 536927.75, 187947.25, - 536927.75, 188099.25, 536927.75, 188069.25, 536927.75, 188025.75, 536927.75, 188046.75, - 536927.75, 188091.75, 536927.75, 188139.75, 536927.75, 188028.75, 536927.75, 188157.75, - 536927.75, 187931.75, 536927.75, 188059.25, 536927.75, 187988.75, 536927.75, 188028.25, - 536927.75, 187911.75, 536927.75, 188143.25, 536927.75, 188146.75, 536927.75, 188063.25, - 536927.75, 188067.25, 536927.75, 187961.25, 536927.75, 187933.75, 536927.75, 188130.75, - 536927.75, 188124.25, 536927.75, 187923.75, 536927.75, 188015.25, 536927.75, 187959.25, - 536927.75, 188130.25, 536927.75, 187982.75, 536927.75, 188129.75, 536927.75, 188001.25, - 536927.75, 187943.75, 536927.75, 187932.75, 536927.75, 188035.25, 536927.75, 188080.75, - 536927.75, 188023.75, 536927.75, 188156.75, 536927.75, 188013.75, 536927.75, 188133.25, - 536927.75, 188057.25, 536927.75, 188015.75, 536927.75, 188137.75, 536927.75, 188113.25, - 536927.75, 188025.25, 536927.75, 187983.75, 536927.75, 187918.25, 536927.75, 188139.25, - 536927.75, 188089.75, 536927.75, 187981.75, 536927.75, 187990.75, 536927.75, 188157.25, - 536927.75, 188119.75, 536927.75, 188094.25, 536927.75, 187998.75, 536927.75, 188135.25, - 536927.75, 188125.75, 536927.75, 188001.75, 536927.75, 188116.25, 536927.75, 187944.75, - 536927.75, 188024.75, 536927.75, 188046.25, 536927.75, 188062.75, 536927.75, 187998.25, - 536927.75, 187942.75, 536927.75, 187960.25, 536927.75, 188083.75, 536927.75, 188022.25, - 536927.75, 187952.75, 536927.75, 187940.25, 536927.75, 188045.75, 536927.75, 188128.75, - 536927.75, 187947.75, 536927.75, 188144.25, 536927.75, 188085.75, 536927.75, 188134.75, - 536927.75, 187965.75, 536927.75, 188114.25, 536927.75, 187951.25, 536927.75, 188147.25, - 536927.75, 187930.75, 536927.75, 188036.25, 536927.75, 188141.25, 536927.75, 187916.75, - 536927.75, 188114.75, 536927.75, 187989.75, 536927.75, 188131.75, 536927.75, 188095.25, - 536928.25, 187921.75, 536928.25, 187962.25, 536928.25, 188146.25, 536928.25, 187937.25, - 536928.25, 188158.25, 536928.25, 188097.75, 536928.25, 188103.75, 536928.25, 188135.25, - 536928.25, 188084.75, 536928.25, 187924.75, 536928.25, 187990.25, 536928.25, 187917.25, - 536928.25, 188031.75, 536928.25, 187953.75, 536928.25, 188032.75, 536928.25, 188064.25, - 536928.25, 187925.25, 536928.25, 188035.75, 536928.25, 187964.75, 536928.25, 188023.25, - 536928.25, 188073.25, 536928.25, 187948.25, 536928.25, 187946.25, 536928.25, 188089.75, - 536928.25, 188142.75, 536928.25, 188106.75, 536928.25, 188031.25, 536928.25, 187959.25, - 536928.25, 187941.75, 536928.25, 187961.25, 536928.25, 188096.25, 536928.25, 188119.75, - 536928.25, 188119.25, 536928.25, 188120.25, 536928.25, 188006.75, 536928.25, 188021.25, - 536928.25, 188005.75, 536928.25, 188089.25, 536928.25, 188142.25, 536928.25, 188136.75, - 536928.25, 188113.75, 536928.25, 187939.75, 536928.25, 187999.75, 536928.25, 188130.25, - 536928.25, 187959.75, 536928.25, 188083.75, 536928.25, 188159.75, 536928.25, 188112.25, - 536928.25, 188112.75, 536928.25, 187958.75, 536928.25, 187918.25, 536928.25, 188046.75, - 536928.25, 188141.25, 536928.25, 188145.75, 536928.25, 188130.75, 536928.25, 188025.75, - 536928.25, 188023.75, 536928.25, 187963.75, 536928.25, 187981.75, 536928.25, 188079.25, - 536928.25, 187919.25, 536928.25, 187983.25, 536928.25, 188062.75, 536928.25, 188029.25, - 536928.25, 188015.75, 536928.25, 187998.25, 536928.25, 187939.25, 536928.25, 187960.25, - 536928.25, 187961.75, 536928.25, 188124.75, 536928.25, 188137.75, 536928.25, 188114.25, - 536928.25, 188147.75, 536928.25, 188087.75, 536928.25, 188036.75, 536928.25, 188046.25, - 536928.25, 188088.25, 536928.25, 187937.75, 536928.25, 187941.25, 536928.25, 188061.25, - 536928.25, 188123.75, 536928.25, 188090.25, 536928.25, 188020.75, 536928.25, 187945.75, - 536928.25, 188062.25, 536928.25, 187932.25, 536928.25, 188157.25, 536928.25, 188055.75, - 536928.25, 187922.25, 536928.25, 188113.25, 536928.25, 188127.25, 536928.25, 188063.75, - 536928.25, 187952.25, 536928.25, 188047.75, 536928.25, 188028.25, 536928.25, 188143.25, - 536928.25, 188145.25, 536928.25, 188024.25, 536928.25, 188138.25, 536928.25, 188158.75, - 536928.25, 187943.25, 536928.25, 188125.25, 536928.25, 187943.75, 536928.25, 187981.25, - 536928.25, 187983.75, 536928.25, 188088.75, 536928.25, 188146.75, 536928.25, 187933.25, - 536928.25, 187940.25, 536928.75, 187921.75, 536928.75, 188138.25, 536928.75, 188016.75, - 536928.75, 188156.75, 536928.75, 188019.75, 536928.75, 188092.75, 536928.75, 188157.25, - 536928.75, 187989.25, 536928.75, 188024.25, 536928.75, 188006.25, 536928.75, 188143.25, - 536928.75, 188145.25, 536928.75, 187947.75, 536928.75, 187933.25, 536928.75, 187943.75, - 536928.75, 188028.25, 536928.75, 188022.25, 536928.75, 188082.75, 536928.75, 188146.75, - 536928.75, 188025.25, 536928.75, 187950.25, 536928.75, 188113.25, 536928.75, 188152.75, - 536928.75, 188000.75, 536928.75, 187932.25, 536928.75, 187938.25, 536928.75, 188046.25, - 536928.75, 188036.75, 536928.75, 188014.25, 536928.75, 187922.75, 536928.75, 188129.25, - 536928.75, 188103.75, 536928.75, 188090.25, 536928.75, 187945.25, 536928.75, 188123.75, - 536928.75, 188029.25, 536928.75, 187918.25, 536928.75, 188088.25, 536928.75, 188129.75, - 536928.75, 188134.75, 536928.75, 188147.75, 536928.75, 188114.25, 536928.75, 188012.75, - 536928.75, 188063.75, 536928.75, 187934.25, 536928.75, 187998.25, 536928.75, 188147.25, - 536928.75, 188137.75, 536928.75, 188023.75, 536928.75, 188124.75, 536928.75, 188024.75, - 536928.75, 187987.75, 536928.75, 187943.25, 536928.75, 187959.25, 536928.75, 188039.75, - 536928.75, 188145.75, 536928.75, 188003.75, 536928.75, 188112.25, 536928.75, 188141.75, - 536928.75, 187958.75, 536928.75, 187960.25, 536928.75, 187963.75, 536928.75, 188060.75, - 536928.75, 188083.75, 536928.75, 188119.25, 536928.75, 188036.25, 536928.75, 187957.75, - 536928.75, 187969.75, 536928.75, 188046.75, 536928.75, 188059.75, 536928.75, 188033.25, - 536928.75, 188052.75, 536928.75, 188140.25, 536928.75, 188079.75, 536928.75, 187999.25, - 536928.75, 188150.25, 536928.75, 187939.25, 536928.75, 188136.75, 536928.75, 188005.75, - 536928.75, 187953.25, 536928.75, 187981.25, 536928.75, 188106.25, 536928.75, 188103.25, - 536928.75, 188089.25, 536928.75, 188019.25, 536928.75, 187961.25, 536928.75, 188089.75, - 536928.75, 187925.25, 536928.75, 188142.75, 536928.75, 187946.25, 536928.75, 187924.25, - 536928.75, 188023.25, 536928.75, 188032.75, 536928.75, 188002.25, 536928.75, 187951.75, - 536928.75, 188049.25, 536928.75, 188114.75, 536928.75, 188096.25, 536928.75, 188062.75, - 536928.75, 188125.75, 536928.75, 188035.75, 536928.75, 188084.75, 536928.75, 187917.25, - 536928.75, 187923.75, 536928.75, 188095.25, 536928.75, 188047.25, 536928.75, 187937.25, - 536928.75, 188157.75, 536928.75, 187953.75, 536928.75, 188136.25, 536928.75, 188146.25, - 536929.25, 188111.25, 536929.25, 187981.75, 536929.25, 187924.75, 536929.25, 188158.25, - 536929.25, 188021.25, 536929.25, 187998.75, 536929.25, 188149.75, 536929.25, 188044.75, - 536929.25, 187946.75, 536929.25, 188136.25, 536929.25, 188124.25, 536929.25, 187948.25, - 536929.25, 188031.25, 536929.25, 187934.75, 536929.25, 188006.75, 536929.25, 188120.25, - 536929.25, 188033.25, 536929.25, 188140.25, 536929.25, 188064.75, 536929.25, 188112.75, - 536929.25, 188073.25, 536929.25, 188030.75, 536929.25, 187990.75, 536929.25, 188021.75, - 536929.25, 188110.75, 536929.25, 187991.25, 536929.25, 187938.75, 536929.25, 188101.75, - 536929.25, 187998.25, 536929.25, 187945.25, 536929.25, 188129.75, 536929.25, 187942.75, - 536929.25, 188111.75, 536929.25, 188086.75, 536929.25, 187932.25, 536929.25, 188157.25, - 536929.25, 187974.25, 536929.25, 188020.25, 536929.25, 188020.75, 536929.25, 188103.75, - 536929.25, 187950.25, 536929.25, 188032.25, 536929.25, 188137.25, 536929.25, 188132.75, - 536929.25, 188028.25, 536929.25, 188022.75, 536929.25, 188024.25, 536929.25, 188030.25, - 536929.25, 188061.75, 536929.25, 188086.25, 536929.25, 188138.25, 536929.25, 187983.75, - 536929.25, 187932.75, 536929.25, 188005.25, 536929.25, 188006.25, 536929.25, 188016.75, - 536929.25, 187922.25, 536929.25, 187988.75, 536929.25, 187913.25, 536929.25, 188125.25, - 536929.25, 187918.25, 536929.25, 188158.75, 536929.25, 188045.75, 536929.25, 188130.75, - 536929.25, 187964.25, 536929.25, 188102.75, 536929.25, 187937.75, 536929.25, 187958.25, - 536929.25, 188146.75, 536929.25, 188093.75, 536929.25, 188028.75, 536929.25, 187918.75, - 536929.25, 188014.75, 536929.25, 187941.25, 536929.25, 188063.75, 536929.25, 188147.25, - 536929.25, 187919.25, 536929.25, 188015.75, 536929.25, 187962.75, 536929.25, 187983.25, - 536929.25, 188115.75, 536929.25, 187925.75, 536929.25, 188004.75, 536929.25, 187957.25, - 536929.25, 188150.75, 536929.25, 187982.25, 536929.25, 187920.75, 536929.25, 188142.25, - 536929.25, 188088.75, 536929.25, 188037.25, 536929.25, 187986.25, 536929.25, 187980.75, - 536929.25, 188046.75, 536929.25, 187947.25, 536929.25, 187950.75, 536929.25, 187941.75, - 536929.25, 187939.75, 536929.25, 188019.25, 536929.25, 187953.75, 536929.25, 187962.25, - 536929.25, 187925.25, 536929.25, 187936.75, 536929.25, 188017.25, 536929.25, 188114.75, - 536929.25, 188031.75, 536929.25, 188088.25, 536929.25, 187989.75, 536929.25, 188061.25, - 536929.75, 188125.25, 536929.75, 188060.25, 536929.75, 188080.75, 536929.75, 188115.25, - 536929.75, 188041.75, 536929.75, 188104.75, 536929.75, 188140.75, 536929.75, 187949.25, - 536929.75, 188157.75, 536929.75, 187910.75, 536929.75, 188044.25, 536929.75, 188043.25, - 536929.75, 188136.75, 536929.75, 188019.25, 536929.75, 187999.25, 536929.75, 188088.75, - 536929.75, 188067.75, 536929.75, 187988.25, 536929.75, 188133.25, 536929.75, 188135.75, - 536929.75, 188078.75, 536929.75, 187920.25, 536929.75, 188059.75, 536929.75, 187990.25, - 536929.75, 188160.25, 536929.75, 188003.75, 536929.75, 188100.75, 536929.75, 187954.25, - 536929.75, 188064.25, 536929.75, 188071.25, 536929.75, 187921.25, 536929.75, 187915.75, - 536929.75, 187948.75, 536929.75, 188046.75, 536929.75, 188037.25, 536929.75, 188087.25, - 536929.75, 188084.25, 536929.75, 188102.25, 536929.75, 188003.25, 536929.75, 188121.25, - 536929.75, 187983.75, 536929.75, 188107.25, 536929.75, 188019.75, 536929.75, 188138.75, - 536929.75, 188110.25, 536929.75, 188030.25, 536929.75, 188022.75, 536929.75, 187925.75, - 536929.75, 188109.25, 536929.75, 188104.25, 536929.75, 188058.75, 536929.75, 188096.75, - 536929.75, 188059.25, 536929.75, 188128.75, 536929.75, 187942.25, 536929.75, 188139.25, - 536929.75, 188101.75, 536929.75, 187956.75, 536929.75, 188082.25, 536929.75, 188021.75, - 536929.75, 188052.25, 536929.75, 187987.75, 536929.75, 187962.75, 536929.75, 188014.25, - 536929.75, 188062.75, 536929.75, 187916.25, 536929.75, 187945.75, 536929.75, 188005.75, - 536929.75, 188087.75, 536929.75, 188000.25, 536929.75, 188133.75, 536929.75, 187961.75, - 536929.75, 188136.25, 536929.75, 187933.25, 536929.75, 187982.75, 536929.75, 188121.75, - 536929.75, 187955.75, 536929.75, 188015.25, 536929.75, 188045.75, 536929.75, 187946.25, - 536929.75, 187924.75, 536929.75, 187913.25, 536929.75, 188085.75, 536929.75, 187917.75, - 536929.75, 187940.25, 536929.75, 188083.75, 536929.75, 188158.25, 536929.75, 188109.75, - 536929.75, 188111.25, 536929.75, 188044.75, 536929.75, 187938.25, 536929.75, 187958.25, - 536929.75, 188103.75, 536929.75, 188018.25, 536929.75, 188153.25, 536929.75, 188016.25, - 536929.75, 188022.25, 536929.75, 187981.75, 536929.75, 188029.75, 536929.75, 187933.75, - 536929.75, 188017.75, 536929.75, 188135.25, 536929.75, 188132.25, 536929.75, 188086.75, - 536929.75, 187944.25, 536929.75, 188045.25, 536929.75, 188126.25, 536929.75, 187949.75, - 536929.75, 188157.25, 536929.75, 188159.25, 536929.75, 187999.75, 536929.75, 187984.25, - 536929.75, 188141.25, 536929.75, 187938.75, 536929.75, 188037.75, 536929.75, 187957.75, - 536929.75, 187991.25, 536929.75, 187991.75, 536929.75, 188043.75, 536930.25, 188112.75, - 536930.25, 187957.75, 536930.25, 187991.25, 536930.25, 187938.75, 536930.25, 188130.75, - 536930.25, 188072.25, 536930.25, 188141.25, 536930.25, 188085.75, 536930.25, 187967.25, - 536930.25, 188088.75, 536930.25, 188107.75, 536930.25, 188054.25, 536930.25, 187961.75, - 536930.25, 188063.25, 536930.25, 188002.75, 536930.25, 187944.25, 536930.25, 188157.75, - 536930.25, 187942.75, 536930.25, 188135.25, 536930.25, 187949.75, 536930.25, 188045.25, - 536930.25, 188006.75, 536930.25, 188111.25, 536930.25, 188036.75, 536930.25, 188062.25, - 536930.25, 188091.75, 536930.25, 188046.25, 536930.25, 188017.75, 536930.25, 188032.25, - 536930.25, 187981.75, 536930.25, 187933.75, 536930.25, 188132.25, 536930.25, 187939.25, - 536930.25, 188022.25, 536930.25, 188016.25, 536930.25, 188154.75, 536930.25, 187946.75, - 536930.25, 187955.25, 536930.25, 187982.75, 536930.25, 187940.25, 536930.25, 188109.75, - 536930.25, 188152.25, 536930.25, 188125.75, 536930.25, 187988.75, 536930.25, 188103.75, - 536930.25, 188044.75, 536930.25, 187924.75, 536930.25, 187955.75, 536930.25, 188154.25, - 536930.25, 188121.75, 536930.25, 188139.25, 536930.25, 188086.75, 536930.25, 188045.75, - 536930.25, 187916.25, 536930.25, 188159.25, 536930.25, 188000.25, 536930.25, 188136.25, - 536930.25, 188085.25, 536930.25, 188124.75, 536930.25, 188130.25, 536930.25, 187933.25, - 536930.25, 188105.25, 536930.25, 188100.25, 536930.25, 188121.25, 536930.25, 188029.25, - 536930.25, 187983.25, 536930.25, 188148.75, 536930.25, 187962.75, 536930.25, 187942.25, - 536930.25, 188101.75, 536930.25, 188100.75, 536930.25, 187985.75, 536930.25, 188028.75, - 536930.25, 188021.75, 536930.25, 188058.75, 536930.25, 188059.25, 536930.25, 187932.25, - 536930.25, 188110.25, 536930.25, 187925.75, 536930.25, 188109.25, 536930.25, 188115.75, - 536930.25, 187932.75, 536930.25, 187941.25, 536930.25, 188020.75, 536930.25, 188087.75, - 536930.25, 188030.25, 536930.25, 187990.25, 536930.25, 188043.25, 536930.25, 187918.25, - 536930.25, 188020.25, 536930.25, 187989.25, 536930.25, 187954.25, 536930.25, 188102.25, - 536930.25, 187948.75, 536930.25, 188138.75, 536930.25, 188018.75, 536930.25, 188133.25, - 536930.25, 187981.25, 536930.25, 187950.75, 536930.25, 187920.25, 536930.25, 187953.25, - 536930.25, 187999.25, 536930.25, 188128.75, 536930.25, 188044.25, 536930.25, 187934.25, - 536930.25, 188080.75, 536930.25, 188114.75, 536930.25, 188140.75, 536930.25, 188091.25, - 536930.25, 187925.25, 536930.25, 187949.25, 536930.25, 188088.25, 536930.25, 188037.75, - 536930.75, 188021.25, 536930.75, 188058.75, 536930.75, 187931.75, 536930.75, 188090.75, - 536930.75, 188120.75, 536930.75, 187982.75, 536930.75, 188100.75, 536930.75, 188136.75, - 536930.75, 187987.25, 536930.75, 187956.75, 536930.75, 188128.75, 536930.75, 188158.25, - 536930.75, 188062.75, 536930.75, 188104.25, 536930.75, 188081.25, 536930.75, 187956.25, - 536930.75, 188019.25, 536930.75, 188041.75, 536930.75, 187937.25, 536930.75, 188043.25, - 536930.75, 188084.75, 536930.75, 187941.75, 536930.75, 188037.25, 536930.75, 188096.75, - 536930.75, 188115.75, 536930.75, 188087.25, 536930.75, 188147.25, 536930.75, 188114.25, - 536930.75, 188100.25, 536930.75, 187930.25, 536930.75, 188085.25, 536930.75, 188127.25, - 536930.75, 187947.75, 536930.75, 188016.75, 536930.75, 188086.25, 536930.75, 188045.25, - 536930.75, 188131.25, 536930.75, 188079.25, 536930.75, 188113.75, 536930.75, 188139.25, - 536930.75, 188158.75, 536930.75, 187948.25, 536930.75, 187940.75, 536930.75, 188097.25, - 536930.75, 188146.75, 536930.75, 188159.25, 536930.75, 188000.25, 536930.75, 188109.75, - 536930.75, 187926.25, 536930.75, 188099.75, 536930.75, 187954.75, 536930.75, 187990.75, - 536930.75, 188061.25, 536930.75, 188038.25, 536930.75, 187929.25, 536930.75, 187932.25, - 536930.75, 187963.25, 536930.75, 188083.25, 536930.75, 187983.75, 536930.75, 188130.25, - 536930.75, 188107.75, 536930.75, 188089.25, 536930.75, 188030.25, 536930.75, 188122.25, - 536930.75, 188015.75, 536930.75, 188102.25, 536930.75, 187953.25, 536930.75, 188029.75, - 536930.75, 188004.25, 536930.75, 187949.25, 536930.75, 187991.25, 536930.75, 187946.75, - 536930.75, 188013.75, 536930.75, 188140.25, 536930.75, 187999.75, 536930.75, 188108.75, - 536930.75, 188135.75, 536930.75, 187962.25, 536930.75, 188044.25, 536930.75, 188056.25, - 536930.75, 187939.25, 536930.75, 188124.25, 536930.75, 187915.75, 536930.75, 187932.75, - 536930.75, 188019.75, 536930.75, 188111.75, 536930.75, 187924.75, 536930.75, 187946.25, - 536930.75, 188005.75, 536931.25, 188097.75, 536931.25, 188096.25, 536931.25, 188015.25, - 536931.25, 188018.75, 536931.25, 187914.75, 536931.25, 187984.75, 536931.25, 188099.25, - 536931.25, 188017.75, 536931.25, 188038.75, 536931.25, 188136.75, 536931.25, 188108.25, - 536931.25, 188142.75, 536931.25, 188141.75, 536931.25, 188040.25, 536931.25, 188134.25, - 536931.25, 188082.25, 536931.25, 188156.75, 536931.25, 188001.25, 536931.25, 188019.75, - 536931.25, 187950.75, 536931.25, 188128.25, 536931.25, 188111.75, 536931.25, 187953.75, - 536931.25, 187926.75, 536931.25, 187932.75, 536931.25, 188075.75, 536931.25, 187984.25, - 536931.25, 188107.25, 536931.25, 188041.75, 536931.25, 187919.25, 536931.25, 188104.75, - 536931.25, 188030.75, 536931.25, 187962.25, 536931.25, 188082.75, 536931.25, 188010.25, - 536931.25, 187973.75, 536931.25, 188059.75, 536931.25, 188150.75, 536931.25, 188131.75, - 536931.25, 187946.75, 536931.25, 188017.25, 536931.25, 187916.75, 536931.25, 187939.75, - 536931.25, 187941.75, 536931.25, 188037.25, 536931.25, 188135.75, 536931.25, 187954.25, - 536931.25, 188084.25, 536931.25, 187951.75, 536931.25, 187963.75, 536931.25, 187930.75, - 536931.25, 188098.75, 536931.25, 188158.75, 536931.25, 188080.75, 536931.25, 188112.25, - 536931.25, 187986.25, 536931.25, 188029.75, 536931.25, 187953.25, 536931.25, 188153.75, - 536931.25, 188078.75, 536931.25, 188058.25, 536931.25, 187992.25, 536931.25, 188114.25, - 536931.25, 188105.25, 536931.25, 188061.25, 536931.25, 188014.75, 536931.25, 188011.75, - 536931.25, 188042.25, 536931.25, 187991.75, 536931.25, 187913.25, 536931.25, 188018.25, - 536931.25, 188043.75, 536931.25, 188159.75, 536931.25, 188113.25, 536931.25, 188126.75, - 536931.25, 187952.75, 536931.25, 187940.25, 536931.25, 187919.75, 536931.25, 187992.75, - 536931.25, 188000.75, 536931.25, 188061.75, 536931.25, 188105.75, 536931.25, 188126.25, - 536931.25, 188111.25, 536931.25, 188093.25, 536931.25, 187986.75, 536931.25, 188116.75, - 536931.25, 187963.25, 536931.25, 188083.75, 536931.25, 188125.75, 536931.25, 187926.25, - 536931.25, 187955.25, 536931.25, 187917.25, 536931.25, 187932.25, 536931.25, 188106.25, - 536931.25, 187954.75, 536931.25, 187911.75, 536931.25, 187990.75, 536931.75, 188027.25, - 536931.75, 187984.75, 536931.75, 188060.25, 536931.75, 188099.25, 536931.75, 188145.75, - 536931.75, 188038.75, 536931.75, 188108.25, 536931.75, 188017.75, 536931.75, 187954.75, - 536931.75, 187932.25, 536931.75, 187986.75, 536931.75, 187940.25, 536931.75, 188134.25, - 536931.75, 187934.25, 536931.75, 188082.25, 536931.75, 187972.25, 536931.75, 187963.25, - 536931.75, 188000.25, 536931.75, 188129.75, 536931.75, 188035.75, 536931.75, 187946.25, - 536931.75, 187939.25, 536931.75, 188001.75, 536931.75, 188097.25, 536931.75, 188076.75, - 536931.75, 188111.75, 536931.75, 188152.75, 536931.75, 188116.75, 536931.75, 187930.25, - 536931.75, 187948.25, 536931.75, 188128.25, 536931.75, 188083.25, 536931.75, 188111.25, - 536931.75, 188159.25, 536931.75, 188008.75, 536931.75, 187953.75, 536931.75, 187926.75, - 536931.75, 188113.75, 536931.75, 188052.25, 536931.75, 187929.25, 536931.75, 188136.25, - 536931.75, 188105.75, 536931.75, 188037.75, 536931.75, 188043.75, 536931.75, 188116.25, - 536931.75, 188000.75, 536931.75, 187964.25, 536931.75, 188121.25, 536931.75, 188030.25, - 536931.75, 187919.75, 536931.75, 187919.25, 536931.75, 187918.75, 536931.75, 188159.75, - 536931.75, 188133.25, 536931.75, 188041.75, 536931.75, 188107.25, 536931.75, 188018.25, - 536931.75, 187952.75, 536931.75, 188019.25, 536931.75, 187990.25, 536931.75, 188104.75, - 536931.75, 188029.75, 536931.75, 188042.25, 536931.75, 187970.75, 536931.75, 188091.25, - 536931.75, 188158.75, 536931.75, 188145.25, 536931.75, 187983.25, 536931.75, 187939.75, - 536931.75, 188014.75, 536931.75, 188121.75, 536931.75, 188059.75, 536931.75, 187920.75, - 536931.75, 188097.75, 536931.75, 188088.75, 536931.75, 187933.25, 536931.75, 188017.25, - 536931.75, 188114.25, 536931.75, 188100.25, 536931.75, 187915.25, 536931.75, 187920.25, - 536931.75, 188105.25, 536931.75, 188086.25, 536931.75, 187916.75, 536931.75, 187953.25, - 536931.75, 188131.75, 536931.75, 188112.25, 536931.75, 187999.75, 536931.75, 187992.25, - 536931.75, 188078.75, 536931.75, 188153.75, 536931.75, 187951.25, 536931.75, 187995.25, - 536931.75, 187925.75, 536931.75, 188004.25, 536931.75, 188112.75, 536931.75, 187962.75, - 536931.75, 188130.75, 536931.75, 188031.75, 536931.75, 188059.25, 536931.75, 188084.25, - 536931.75, 187954.25, 536931.75, 187991.25, 536932.25, 187962.75, 536932.25, 188106.75, - 536932.25, 188127.75, 536932.25, 187913.75, 536932.25, 188004.75, 536932.25, 187951.75, - 536932.25, 187949.25, 536932.25, 188112.25, 536932.25, 188143.75, 536932.25, 188105.25, - 536932.25, 187927.75, 536932.25, 187988.25, 536932.25, 188129.25, 536932.25, 188097.75, - 536932.25, 188097.25, 536932.25, 188133.75, 536932.25, 188155.75, 536932.25, 187917.75, - 536932.25, 188121.75, 536932.25, 188127.25, 536932.25, 187939.75, 536932.25, 188082.75, - 536932.25, 188030.75, 536932.25, 188160.25, 536932.25, 188015.75, 536932.25, 187953.75, - 536932.25, 188016.75, 536932.25, 187953.25, 536932.25, 187915.25, 536932.25, 188139.75, - 536932.25, 188104.75, 536932.25, 188059.75, 536932.25, 188006.25, 536932.25, 188030.25, - 536932.25, 187919.75, 536932.25, 188000.75, 536932.25, 188121.25, 536932.25, 188041.25, - 536932.25, 187984.25, 536932.25, 188112.75, 536932.25, 188032.75, 536932.25, 188040.75, - 536932.25, 187932.75, 536932.25, 188135.25, 536932.25, 188083.25, 536932.25, 187981.75, - 536932.25, 188126.25, 536932.25, 188001.75, 536932.25, 187926.25, 536932.25, 188159.75, - 536932.25, 188125.75, 536932.25, 187940.75, 536932.25, 188137.25, 536932.25, 188000.25, - 536932.25, 188039.25, 536932.25, 187934.25, 536932.25, 188132.75, 536932.25, 188082.25, - 536932.25, 187916.25, 536932.25, 187952.25, 536932.25, 187982.75, 536932.25, 188017.75, - 536932.25, 187928.75, 536932.25, 188038.25, 536932.25, 187910.75, 536932.25, 188096.25, - 536932.25, 188018.75, 536932.25, 188158.25, 536932.25, 187914.25, 536932.25, 187963.25, - 536932.25, 188159.25, 536932.75, 188040.25, 536932.75, 187941.25, 536932.75, 188137.75, - 536932.75, 188156.75, 536932.75, 188127.75, 536932.75, 188080.25, 536932.75, 188038.75, - 536932.75, 188158.25, 536932.75, 188127.25, 536932.75, 188068.25, 536932.75, 187975.25, - 536932.75, 188002.75, 536932.75, 188098.75, 536932.75, 188019.75, 536932.75, 188017.75, - 536932.75, 187952.75, 536932.75, 187934.75, 536932.75, 188001.25, 536932.75, 188082.75, - 536932.75, 187915.75, 536932.75, 188129.25, 536932.75, 188122.75, 536932.75, 187933.75, - 536932.75, 187934.25, 536932.75, 188092.75, 536932.75, 188097.75, 536932.75, 188157.75, - 536932.75, 188117.25, 536932.75, 187949.25, 536932.75, 187925.25, 536932.75, 187947.25, - 536932.75, 188135.75, 536932.75, 187991.75, 536932.75, 188031.75, 536932.75, 188131.75, - 536932.75, 187942.25, 536932.75, 187912.75, 536932.75, 187992.75, 536932.75, 187929.75, - 536932.75, 188040.75, 536932.75, 187993.25, 536932.75, 187912.25, 536932.75, 188157.25, - 536932.75, 188030.75, 536932.75, 187928.25, 536932.75, 188031.25, 536932.75, 188081.75, - 536932.75, 188098.25, 536932.75, 188093.75, 536932.75, 187984.25, 536932.75, 188096.75, - 536932.75, 188112.25, 536932.75, 188138.25, 536932.75, 187940.75, 536932.75, 188042.25, - 536932.75, 187964.25, 536932.75, 187916.25, 536932.75, 188039.75, 536932.75, 188081.25, - 536932.75, 187926.25, 536932.75, 187923.25, 536932.75, 188159.25, 536932.75, 188136.75, - 536932.75, 187950.75, 536932.75, 188018.75, 536932.75, 187951.25, 536932.75, 188003.25, - 536932.75, 188106.25, 536932.75, 187927.25, 536932.75, 187963.75, 536932.75, 187917.25, - 536932.75, 188144.25, 536933.25, 187917.25, 536933.25, 188019.75, 536933.25, 188136.75, - 536933.25, 187951.25, 536933.25, 188060.25, 536933.25, 187950.75, 536933.25, 188079.75, - 536933.25, 187932.75, 536933.25, 187920.75, 536933.25, 187948.25, 536933.25, 188039.75, - 536933.25, 187964.25, 536933.25, 188043.25, 536933.25, 188081.25, 536933.25, 187963.75, - 536933.25, 187940.75, 536933.25, 188125.25, 536933.25, 187915.75, 536933.25, 187924.25, - 536933.25, 188039.25, 536933.25, 188000.75, 536933.25, 188138.25, 536933.25, 188081.75, - 536933.25, 187926.25, 536933.25, 187914.25, 536933.25, 187933.25, 536933.25, 188015.75, - 536933.25, 188030.75, 536933.25, 187912.25, 536933.25, 188106.75, 536933.25, 188157.25, - 536933.25, 188073.75, 536933.25, 188135.75, 536933.25, 188134.75, 536933.25, 187927.25, - 536933.25, 187992.75, 536933.25, 188041.25, 536933.25, 187991.75, 536933.25, 188031.75, - 536933.25, 187967.25, 536933.25, 188131.75, 536933.25, 187914.75, 536933.25, 188117.75, - 536933.25, 188059.75, 536933.25, 188017.75, 536933.25, 188040.25, 536933.25, 188137.25, - 536933.25, 188001.25, 536933.25, 187950.25, 536933.25, 187980.25, 536933.25, 188126.75, - 536933.25, 188018.25, 536933.25, 188002.75, 536933.25, 188088.75, 536933.25, 188038.75, - 536933.25, 187952.75, 536933.25, 188158.25, 536933.25, 188098.75, 536933.25, 188096.25, - 536933.25, 187962.75, 536933.25, 187928.75, 536933.25, 187984.75, 536933.25, 188080.25, - 536933.25, 188099.25, 536933.25, 188105.25, 536933.25, 187976.75, 536933.25, 188127.75, - 536933.25, 188052.75, 536933.25, 188156.75, 536933.25, 188137.75, 536933.25, 188133.25, - 536933.25, 187934.75, 536933.25, 188094.25, 536933.75, 187982.25, 536933.75, 187981.75, - 536933.75, 188097.25, 536933.75, 187948.75, 536933.75, 187933.75, 536933.75, 188137.75, - 536933.75, 188038.25, 536933.75, 188144.25, 536933.75, 188099.25, 536933.75, 188130.75, - 536933.75, 187982.75, 536933.75, 188150.75, 536933.75, 188155.75, 536933.75, 188039.25, - 536933.75, 188127.75, 536933.75, 188036.75, 536933.75, 188081.75, 536933.75, 188026.75, - 536933.75, 187950.75, 536933.75, 187993.25, 536933.75, 187923.75, 536933.75, 187964.75, - 536933.75, 188108.25, 536933.75, 188003.25, 536933.75, 188129.75, 536933.75, 187917.75, - 536933.75, 187920.25, 536933.75, 187992.25, 536933.75, 187935.25, 536933.75, 188107.25, - 536933.75, 187941.75, 536933.75, 188106.75, 536933.75, 188111.75, 536933.75, 188132.25, - 536933.75, 187950.25, 536933.75, 188094.75, 536933.75, 188084.25, 536933.75, 187918.25, - 536933.75, 188061.75, 536933.75, 188156.25, 536933.75, 187925.75, 536933.75, 187926.75, - 536933.75, 188019.25, 536933.75, 187923.25, 536933.75, 188123.75, 536933.75, 188134.25, - 536933.75, 187940.25, 536933.75, 188031.75, 536933.75, 187963.75, 536933.75, 188159.75, - 536933.75, 188157.75, 536933.75, 187916.25, 536933.75, 188098.25, 536933.75, 187914.25, - 536933.75, 188112.75, 536933.75, 188020.75, 536933.75, 187918.75, 536933.75, 188013.25, - 536933.75, 187944.75, 536933.75, 188031.25, 536933.75, 187943.25, 536933.75, 188116.25, - 536933.75, 188138.75, 536933.75, 188037.75, 536934.25, 188097.75, 536934.25, 188064.75, - 536934.25, 188117.75, 536934.25, 187926.25, 536934.25, 188033.25, 536934.25, 188037.25, - 536934.25, 187921.75, 536934.25, 188063.25, 536934.25, 187965.25, 536934.25, 187943.25, - 536934.25, 187949.25, 536934.25, 188031.25, 536934.25, 188085.75, 536934.25, 188006.75, - 536934.25, 187913.25, 536934.25, 187925.25, 536934.25, 187921.25, 536934.25, 188129.75, - 536934.25, 188050.75, 536934.25, 188122.25, 536934.25, 188007.75, 536934.25, 188141.75, - 536934.25, 188128.75, 536934.25, 188009.75, 536934.25, 187963.75, 536934.25, 187947.25, - 536934.25, 187916.25, 536934.25, 188157.75, 536934.25, 187942.25, 536934.25, 188032.75, - 536934.25, 187914.75, 536934.25, 187983.25, 536934.25, 188080.25, 536934.25, 187981.25, - 536934.25, 187913.75, 536934.25, 188139.25, 536934.25, 187970.25, 536934.25, 188131.75, - 536934.25, 188031.75, 536934.25, 188098.25, 536934.25, 188129.25, 536934.25, 188087.25, - 536934.25, 187948.25, 536934.25, 187926.75, 536934.25, 187934.25, 536934.25, 188001.25, - 536934.25, 188156.25, 536934.25, 187966.75, 536934.25, 188027.75, 536934.25, 187979.75, - 536934.25, 188146.25, 536934.25, 188001.75, 536934.25, 188086.75, 536934.25, 188053.25, - 536934.25, 188051.25, 536934.25, 188099.75, 536934.25, 187917.75, 536934.25, 188035.25, - 536934.25, 188106.25, 536934.25, 188032.25, 536934.25, 187947.75, 536934.25, 188154.25, - 536934.25, 188155.25, 536934.25, 188113.25, 536934.25, 188038.25, 536934.25, 188018.75, - 536934.25, 188019.75, 536934.25, 187949.75, 536934.25, 188136.25, 536934.25, 188047.75, - 536934.25, 188082.75, 536934.25, 187950.75, 536934.25, 188133.75, 536934.25, 188158.75, - 536934.25, 188002.75, 536934.25, 187980.75, 536934.25, 188134.25, 536934.25, 188036.75, - 536934.25, 188155.75, 536934.25, 187924.25, 536934.25, 188002.25, 536934.25, 187916.75, - 536934.25, 188125.25, 536934.25, 188052.75, 536934.25, 188137.75, 536934.25, 188159.25, - 536934.25, 187932.25, 536934.25, 188082.25, 536934.25, 187941.25, 536934.25, 187933.75, - 536934.25, 187993.75, 536934.25, 188036.25, 536934.25, 187983.75, 536934.25, 187975.25, - 536934.25, 188097.25, 536934.75, 187982.25, 536934.75, 188085.75, 536934.75, 187997.25, - 536934.75, 188081.75, 536934.75, 187948.75, 536934.75, 187984.25, 536934.75, 187933.75, - 536934.75, 188118.75, 536934.75, 188097.25, 536934.75, 187936.25, 536934.75, 188036.75, - 536934.75, 187993.75, 536934.75, 187980.75, 536934.75, 187950.75, 536934.75, 187919.25, - 536934.75, 187949.75, 536934.75, 188158.75, 536934.75, 188018.75, 536934.75, 187971.25, - 536934.75, 188113.25, 536934.75, 188006.25, 536934.75, 188148.25, 536934.75, 188094.75, - 536934.75, 188003.25, 536934.75, 188154.25, 536934.75, 188160.25, 536934.75, 187964.75, - 536934.75, 187917.75, 536934.75, 187910.75, 536934.75, 187992.25, 536934.75, 188106.75, - 536934.75, 188027.75, 536934.75, 188035.75, 536934.75, 188134.25, 536934.75, 187916.75, - 536934.75, 187915.75, 536934.75, 187926.75, 536934.75, 188031.75, 536934.75, 188134.75, - 536934.75, 188028.75, 536934.75, 188121.25, 536934.75, 188123.25, 536934.75, 188024.25, - 536934.75, 188054.25, 536934.75, 187963.75, 536934.75, 188064.25, 536934.75, 188093.25, - 536934.75, 188037.25, 536934.75, 188128.75, 536934.75, 187940.75, 536934.75, 187942.75, - 536934.75, 187981.75, 536934.75, 187913.25, 536934.75, 187983.25, 536934.75, 187925.25, - 536934.75, 188159.25, 536934.75, 187978.25, 536934.75, 187975.75, 536934.75, 188135.25, - 536934.75, 187965.25, 536934.75, 187934.75, 536934.75, 188079.25, 536934.75, 188007.75, - 536934.75, 187924.25, 536934.75, 188157.75, 536934.75, 187949.25, 536934.75, 188064.75, - 536934.75, 187947.25, 536934.75, 188129.75, 536934.75, 188019.75, 536934.75, 188139.25, - 536934.75, 187925.75, 536934.75, 187975.25, 536934.75, 188109.75, 536934.75, 188001.75, - 536934.75, 188066.25, 536934.75, 188018.25, 536934.75, 188124.25, 536934.75, 188009.25, - 536934.75, 187982.75, 536934.75, 188098.75, 536934.75, 187947.75, 536934.75, 188002.75, - 536934.75, 188051.25, 536934.75, 188133.75, 536934.75, 188155.75, 536934.75, 188109.25, - 536934.75, 188005.75, 536934.75, 188052.75, 536934.75, 188099.25, 536934.75, 188137.75, - 536934.75, 188036.25, 536934.75, 188133.25, 536934.75, 188131.25, 536935.25, 188082.25, - 536935.25, 188032.75, 536935.25, 188153.25, 536935.25, 188152.25, 536935.25, 187945.75, - 536935.25, 188005.75, 536935.25, 188082.75, 536935.25, 188099.25, 536935.25, 187914.75, - 536935.25, 188050.75, 536935.25, 188099.75, 536935.25, 187992.75, 536935.25, 188035.25, - 536935.25, 188066.25, 536935.25, 187935.25, 536935.25, 188158.75, 536935.25, 188004.25, - 536935.25, 188064.75, 536935.25, 187964.25, 536935.25, 187946.75, 536935.25, 188092.75, - 536935.25, 187926.25, 536935.25, 188127.25, 536935.25, 188113.75, 536935.25, 187986.25, - 536935.25, 188114.25, 536935.25, 187983.25, 536935.25, 188098.75, 536935.25, 188137.75, - 536935.25, 187962.75, 536935.25, 188109.25, 536935.25, 188128.25, 536935.25, 187934.75, - 536935.25, 188097.75, 536935.25, 188020.25, 536935.25, 187914.25, 536935.25, 188064.25, - 536935.25, 188148.75, 536935.25, 188139.75, 536935.25, 188107.75, 536935.25, 187942.25, - 536935.25, 187961.75, 536935.25, 188123.25, 536935.25, 188098.25, 536935.25, 188019.25, - 536935.25, 188118.25, 536935.25, 188129.25, 536935.25, 188033.25, 536935.25, 187948.25, - 536935.25, 188032.25, 536935.25, 188138.25, 536935.25, 188088.25, 536935.25, 187941.25, - 536935.25, 188154.25, 536935.25, 187981.25, 536935.25, 188036.75, 536935.25, 187993.75, - 536935.25, 187986.75, 536935.25, 187983.75, 536935.25, 188159.75, 536935.25, 187920.75, - 536935.25, 188006.25, 536935.25, 188066.75, 536935.25, 188091.25, 536935.25, 188108.25, - 536935.25, 187923.25, 536935.25, 188002.25, 536935.25, 187933.75, 536935.25, 188008.25, - 536935.25, 187937.25, 536935.25, 188049.25, 536935.25, 188148.25, 536935.25, 188155.25, - 536935.25, 188097.25, 536935.75, 188118.75, 536935.75, 188049.25, 536935.75, 188117.25, - 536935.75, 188110.25, 536935.75, 188083.25, 536935.75, 187994.25, 536935.75, 187927.75, - 536935.75, 188148.25, 536935.75, 188003.25, 536935.75, 187936.25, 536935.75, 187963.25, - 536935.75, 188004.75, 536935.75, 188100.25, 536935.75, 187993.25, 536935.75, 188079.75, - 536935.75, 188005.25, 536935.75, 188038.25, 536935.75, 187986.75, 536935.75, 188108.25, - 536935.75, 188145.75, 536935.75, 187988.75, 536935.75, 188051.75, 536935.75, 188101.75, - 536935.75, 188033.75, 536935.75, 188034.75, 536935.75, 187911.75, 536935.75, 188151.75, - 536935.75, 188048.75, 536935.75, 187915.25, 536935.75, 188033.25, 536935.75, 188083.75, - 536935.75, 187990.25, 536935.75, 188086.75, 536935.75, 187945.25, 536935.75, 187954.75, - 536935.75, 187926.75, 536935.75, 188062.75, 536935.75, 188107.75, 536935.75, 188008.75, - 536935.75, 188064.25, 536935.75, 187922.25, 536935.75, 188152.75, 536935.75, 188009.75, - 536935.75, 188019.25, 536935.75, 188128.75, 536935.75, 188034.25, 536935.75, 188139.75, - 536935.75, 188003.75, 536935.75, 188130.75, 536935.75, 188063.25, 536935.75, 188067.75, - 536935.75, 188072.25, 536935.75, 188006.75, 536935.75, 187994.75, 536935.75, 188020.75, - 536935.75, 188098.75, 536935.75, 188137.75, 536935.75, 188010.25, 536935.75, 187921.75, - 536935.75, 187986.25, 536935.75, 187946.25, 536935.75, 187960.75, 536935.75, 187947.75, - 536935.75, 187942.25, 536935.75, 188063.75, 536935.75, 188131.25, 536935.75, 188145.25, - 536935.75, 188050.25, 536935.75, 188067.25, 536935.75, 188132.25, 536935.75, 187961.25, - 536935.75, 188154.75, 536935.75, 188064.75, 536935.75, 188007.25, 536935.75, 188107.25, - 536935.75, 187934.25, 536935.75, 187937.75, 536935.75, 188004.25, 536935.75, 188143.75, - 536935.75, 188138.75, 536935.75, 188021.25, 536935.75, 188153.25, 536935.75, 187924.75, - 536935.75, 187927.25, 536935.75, 187943.25, 536935.75, 188022.75, 536935.75, 188110.75, - 536935.75, 187926.25, 536935.75, 187945.75, 536935.75, 188082.25, 536935.75, 188032.75, - 536936.25, 187927.25, 536936.25, 188151.75, 536936.25, 188082.25, 536936.25, 187962.25, - 536936.25, 187944.25, 536936.25, 188082.75, 536936.25, 188122.75, 536936.25, 188110.75, - 536936.25, 187974.25, 536936.25, 188004.25, 536936.25, 188138.75, 536936.25, 188021.25, - 536936.25, 187937.75, 536936.25, 188151.25, 536936.25, 188128.75, 536936.25, 187989.25, - 536936.25, 187935.25, 536936.25, 188143.75, 536936.25, 188099.25, 536936.25, 188107.25, - 536936.25, 188002.75, 536936.25, 188050.75, 536936.25, 187946.75, 536936.25, 188067.25, - 536936.25, 188145.25, 536936.25, 188131.25, 536936.25, 187946.25, 536936.25, 188127.25, - 536936.25, 188089.75, 536936.25, 188152.25, 536936.25, 187960.75, 536936.25, 188112.25, - 536936.25, 187986.25, 536936.25, 188113.75, 536936.25, 188063.25, 536936.25, 188064.25, - 536936.25, 187921.75, 536936.25, 188114.25, 536936.25, 188019.75, 536936.25, 187926.25, - 536936.25, 187912.25, 536936.25, 188048.75, 536936.25, 188098.75, 536936.25, 188129.75, - 536936.25, 188067.75, 536936.25, 187947.75, 536936.25, 188006.75, 536936.25, 188020.75, - 536936.25, 187986.75, 536936.25, 188139.75, 536936.25, 188062.75, 536936.25, 188107.75, - 536936.25, 188003.75, 536936.25, 187990.25, 536936.25, 187962.75, 536936.25, 188016.25, - 536936.25, 187945.25, 536936.25, 188009.75, 536936.25, 187922.25, 536936.25, 187991.75, - 536936.25, 187914.25, 536936.25, 188154.75, 536936.25, 188132.75, 536936.25, 188033.75, - 536936.25, 188032.25, 536936.25, 188146.25, 536936.25, 188131.75, 536936.25, 188033.25, - 536936.25, 188086.75, 536936.25, 188159.75, 536936.25, 188154.25, 536936.25, 188101.75, - 536936.25, 188130.75, 536936.25, 187934.25, 536936.25, 187920.25, 536936.25, 188049.75, - 536936.25, 188034.75, 536936.25, 188007.75, 536936.25, 187933.25, 536936.25, 188052.25, - 536936.25, 188065.75, 536936.25, 188006.25, 536936.25, 187993.25, 536936.25, 188100.25, - 536936.25, 188004.75, 536936.25, 188003.25, 536936.25, 187963.25, 536936.25, 187935.75, - 536936.25, 188134.75, 536936.25, 188110.25, 536936.25, 188005.25, 536936.25, 188125.25, - 536936.25, 188010.75, 536936.25, 188117.25, 536936.25, 188002.25, 536936.25, 188118.75, - 536936.25, 188063.75, 536936.75, 188063.75, 536936.75, 187994.75, 536936.75, 188002.25, - 536936.75, 188112.75, 536936.75, 188008.25, 536936.75, 187933.75, 536936.75, 187930.25, - 536936.75, 187927.75, 536936.75, 187932.25, 536936.75, 188114.75, 536936.75, 188090.25, - 536936.75, 188150.75, 536936.75, 187959.75, 536936.75, 188151.75, 536936.75, 187993.75, - 536936.75, 187934.75, 536936.75, 188079.75, 536936.75, 187960.25, 536936.75, 188139.25, - 536936.75, 188129.75, 536936.75, 187941.25, 536936.75, 188083.75, 536936.75, 188154.75, - 536936.75, 188156.25, 536936.75, 188033.25, 536936.75, 188098.25, 536936.75, 187936.75, - 536936.75, 188154.25, 536936.75, 188095.75, 536936.75, 188003.75, 536936.75, 187926.75, - 536936.75, 187922.25, 536936.75, 187962.75, 536936.75, 188021.25, 536936.75, 188031.25, - 536936.75, 188020.25, 536936.75, 188140.25, 536936.75, 187965.25, 536936.75, 187921.75, - 536936.75, 188067.25, 536936.75, 188114.25, 536936.75, 188078.75, 536936.75, 187960.75, - 536936.75, 187986.25, 536936.75, 188009.25, 536936.75, 187942.25, 536936.75, 188151.25, - 536936.75, 188007.25, 536936.75, 187961.25, 536936.75, 188064.75, 536936.75, 188126.75, - 536936.75, 187959.25, 536936.75, 188099.75, 536936.75, 188149.75, 536936.75, 187923.75, - 536936.75, 188001.25, 536936.75, 187944.25, 536936.75, 187944.75, 536936.75, 187945.75, - 536936.75, 187926.25, 536936.75, 188032.75, 536937.25, 188063.75, 536937.25, 187994.25, - 536937.25, 188139.25, 536937.25, 188130.25, 536937.25, 187922.25, 536937.25, 187940.75, - 536937.25, 188098.25, 536937.25, 188148.75, 536937.25, 188087.75, 536937.25, 187927.75, - 536937.25, 188140.75, 536937.25, 188150.25, 536937.25, 188031.25, 536937.25, 188152.75, - 536937.25, 188042.75, 536937.25, 188156.25, 536937.25, 187987.75, 536937.25, 187975.25, - 536937.25, 188073.25, 536937.25, 188033.25, 536937.25, 187979.25, 536937.25, 187971.25, - 536937.25, 187960.25, 536937.25, 188157.75, 536937.25, 187988.25, 536937.25, 188137.75, - 536937.25, 187928.25, 536937.25, 188080.75, 536937.25, 188001.25, 536937.25, 187944.75, - 536937.25, 188126.75, 536937.25, 187962.75, 536937.25, 188155.25, 536937.25, 188159.25, - 536937.25, 188049.75, 536937.25, 187960.75, 536937.25, 188065.75, 536937.25, 188072.25, - 536937.25, 187936.25, 536937.25, 187934.25, 536937.25, 188007.25, 536937.25, 188009.25, - 536937.25, 188127.25, 536937.25, 188083.25, 536937.25, 187937.75, 536937.25, 187934.75, - 536937.25, 187910.75, 536937.25, 188153.25, 536937.25, 188041.75, 536937.25, 187958.25, - 536937.25, 188032.75, 536937.25, 187921.75, 536937.25, 188112.75, 536937.25, 188097.25, - 536937.25, 187943.75, 536937.25, 188108.25, 536937.25, 188021.25, 536937.25, 188127.75, - 536937.25, 188062.75, 536937.25, 188020.25, 536937.25, 188084.25, 536937.25, 188081.75, - 536937.25, 188002.75, 536937.25, 187943.25, 536937.25, 188099.75, 536937.25, 187920.25, - 536937.25, 188066.25, 536937.25, 187941.75, 536937.25, 187992.25, 536937.25, 187931.75, - 536937.25, 187983.25, 536937.25, 187958.75, 536937.25, 188115.25, 536937.25, 188125.25, - 536937.25, 188022.25, 536937.25, 188071.75, 536937.25, 188115.75, 536937.25, 188045.75, - 536937.25, 188139.75, 536937.25, 188111.25, 536937.25, 188000.75, 536937.25, 187961.25, - 536937.25, 188142.75, 536937.25, 188110.75, 536937.25, 188031.75, 536937.25, 187923.75, - 536937.25, 187933.75, 536937.25, 188030.75, 536937.25, 188021.75, 536937.25, 188007.75, - 536937.25, 187932.75, 536937.25, 188160.25, 536937.25, 187995.25, 536937.25, 187911.75, - 536937.25, 187919.25, 536937.25, 187920.75, 536937.25, 187961.75, 536937.25, 188120.25, - 536937.25, 188130.75, 536937.25, 188003.25, 536937.25, 188066.75, 536937.75, 187978.25, - 536937.75, 188029.75, 536937.75, 187994.25, 536937.75, 188064.75, 536937.75, 188091.75, - 536937.75, 188073.75, 536937.75, 188151.25, 536937.75, 187942.25, 536937.75, 188020.75, - 536937.75, 188113.75, 536937.75, 188099.25, 536937.75, 188065.25, 536937.75, 188128.25, - 536937.75, 187919.25, 536937.75, 188130.75, 536937.75, 188063.25, 536937.75, 188076.75, - 536937.75, 188033.75, 536937.75, 188139.25, 536937.75, 187937.25, 536937.75, 188010.75, - 536937.75, 187932.75, 536937.75, 188148.75, 536937.75, 188107.75, 536937.75, 188066.75, - 536937.75, 188151.75, 536937.75, 188021.75, 536937.75, 188095.75, 536937.75, 187995.25, - 536937.75, 188140.75, 536937.75, 188152.75, 536937.75, 188072.25, 536937.75, 188030.75, - 536937.75, 187987.75, 536937.75, 188081.25, 536937.75, 187971.75, 536937.75, 188111.25, - 536937.75, 188152.25, 536937.75, 188125.75, 536937.75, 187933.75, 536937.75, 188156.25, - 536937.75, 188031.75, 536937.75, 187968.75, 536937.75, 187955.75, 536937.75, 187961.25, - 536937.75, 187960.25, 536937.75, 188109.25, 536937.75, 188000.75, 536937.75, 187926.25, - 536937.75, 188033.25, 536937.75, 187928.25, 536937.75, 188067.75, 536937.75, 188139.75, - 536937.75, 187911.25, 536937.75, 188044.75, 536937.75, 187944.25, 536937.75, 187945.75, - 536937.75, 187927.25, 536937.75, 188071.75, 536937.75, 188115.25, 536937.75, 187958.75, - 536937.75, 188083.25, 536937.75, 188042.25, 536937.75, 188063.75, 536937.75, 187992.25, - 536937.75, 187979.75, 536937.75, 188099.75, 536937.75, 188066.25, 536937.75, 187931.75, - 536937.75, 188148.25, 536937.75, 187920.25, 536937.75, 188098.75, 536937.75, 187999.75, - 536937.75, 187922.75, 536937.75, 188119.75, 536937.75, 188084.25, 536937.75, 187957.75, - 536937.75, 188020.25, 536937.75, 188155.25, 536937.75, 188096.25, 536937.75, 188124.25, - 536937.75, 188110.25, 536937.75, 187993.75, 536937.75, 187984.75, 536937.75, 188145.25, - 536937.75, 188065.75, 536937.75, 187980.75, 536937.75, 188008.25, 536937.75, 188032.75, - 536937.75, 187921.75, 536937.75, 187959.25, 536937.75, 188007.25, 536937.75, 188046.25, - 536937.75, 187934.25, 536937.75, 188127.25, 536937.75, 188141.25, 536937.75, 188153.25, - 536937.75, 187985.75, 536937.75, 188009.25, 536937.75, 187995.75, 536937.75, 188159.25, - 536937.75, 188002.25, 536937.75, 188088.75, 536938.25, 188079.75, 536938.25, 187995.75, - 536938.25, 188047.75, 536938.25, 188159.25, 536938.25, 188009.25, 536938.25, 187938.75, - 536938.25, 187934.25, 536938.25, 187958.25, 536938.25, 187936.25, 536938.25, 187957.75, - 536938.25, 188108.75, 536938.25, 187938.25, 536938.25, 188158.75, 536938.25, 188029.25, - 536938.25, 188127.75, 536938.25, 188088.75, 536938.25, 187932.25, 536938.25, 188071.25, - 536938.25, 187984.75, 536938.25, 188129.25, 536938.25, 188147.25, 536938.25, 188083.75, - 536938.25, 188124.25, 536938.25, 187986.75, 536938.25, 187941.25, 536938.25, 187986.25, - 536938.25, 188119.75, 536938.25, 188140.25, 536938.25, 187999.75, 536938.25, 188016.75, - 536938.25, 187931.75, 536938.25, 188098.25, 536938.25, 187930.75, 536938.25, 187919.75, - 536938.25, 187980.25, 536938.25, 188032.25, 536938.25, 187943.25, 536938.25, 188066.25, - 536938.25, 187983.25, 536938.25, 187989.25, 536938.25, 187977.75, 536938.25, 188115.25, - 536938.25, 188050.75, 536938.25, 188080.25, 536938.25, 188084.75, 536938.25, 188070.75, - 536938.25, 188014.75, 536938.25, 188008.75, 536938.25, 188115.75, 536938.25, 187942.75, - 536938.25, 188149.25, 536938.25, 188043.25, 536938.25, 188079.25, 536938.25, 188033.25, - 536938.25, 188001.75, 536938.25, 188000.75, 536938.25, 187923.75, 536938.25, 188049.25, - 536938.25, 188146.75, 536938.25, 187984.25, 536938.25, 187976.75, 536938.25, 188072.25, - 536938.25, 188150.75, 536938.25, 187995.25, 536938.25, 188007.75, 536938.25, 187927.75, - 536938.25, 188126.25, 536938.25, 188009.75, 536938.25, 188150.25, 536938.25, 188094.25, - 536938.25, 188151.75, 536938.25, 188070.25, 536938.25, 187956.25, 536938.25, 187981.25, - 536938.25, 188030.75, 536938.25, 187990.25, 536938.25, 188043.75, 536938.25, 188095.25, - 536938.25, 187922.25, 536938.25, 187932.75, 536938.25, 188020.75, 536938.25, 188064.25, - 536938.25, 188099.25, 536938.25, 187931.25, 536938.25, 188124.75, 536938.25, 188073.75, - 536938.25, 188120.25, 536938.25, 188151.25, 536938.25, 188096.75, 536938.25, 188110.75, - 536938.75, 188072.75, 536938.75, 187934.75, 536938.75, 188073.75, 536938.75, 188043.75, - 536938.75, 188159.75, 536938.75, 188109.25, 536938.75, 188140.75, 536938.75, 187976.75, - 536938.75, 188007.75, 536938.75, 188020.75, 536938.75, 188107.75, 536938.75, 188065.25, - 536938.75, 187928.25, 536938.75, 187975.75, 536938.75, 187956.25, 536938.75, 187981.75, - 536938.75, 188123.75, 536938.75, 188070.75, 536938.75, 187981.25, 536938.75, 187931.25, - 536938.75, 187982.75, 536938.75, 188094.75, 536938.75, 188034.75, 536938.75, 188093.75, - 536938.75, 188120.75, 536938.75, 188115.75, 536938.75, 188032.25, 536938.75, 188094.25, - 536938.75, 188069.25, 536938.75, 187920.75, 536938.75, 188098.75, 536938.75, 188027.25, - 536938.75, 187983.75, 536938.75, 187928.75, 536938.75, 188125.25, 536938.75, 188126.25, - 536938.75, 187957.25, 536938.75, 188143.25, 536938.75, 188095.75, 536938.75, 187987.25, - 536938.75, 188064.25, 536938.75, 188029.75, 536938.75, 187987.75, 536938.75, 188096.75, - 536938.75, 187930.25, 536938.75, 187980.75, 536938.75, 188073.25, 536938.75, 187922.75, - 536938.75, 187978.25, 536938.75, 188119.25, 536938.75, 187955.75, 536938.75, 188069.75, - 536938.75, 188109.75, 536938.75, 188074.25, 536938.75, 187921.25, 536938.75, 188116.25, - 536938.75, 188084.25, 536938.75, 187979.25, 536938.75, 188067.25, 536938.75, 188030.25, - 536938.75, 187993.75, 536938.75, 187943.75, 536938.75, 188147.25, 536938.75, 187958.25, - 536938.75, 187924.25, 536938.75, 188127.75, 536938.75, 188010.25, 536938.75, 188147.75, - 536938.75, 187956.75, 536938.75, 188070.25, 536938.75, 188082.25, 536938.75, 188080.75, - 536938.75, 187996.25, 536938.75, 188124.75, 536938.75, 188146.25, 536938.75, 188046.25, - 536938.75, 187929.25, 536938.75, 188150.75, 536938.75, 188136.25, 536938.75, 188085.25, - 536938.75, 187997.75, 536938.75, 188097.25, 536938.75, 187924.75, 536938.75, 188137.25, - 536938.75, 188096.25, 536938.75, 188108.25, 536938.75, 188022.75, 536938.75, 188119.75, - 536938.75, 187998.75, 536938.75, 188149.75, 536938.75, 188086.25, 536938.75, 188141.25, - 536938.75, 187935.75, 536938.75, 187935.25, 536938.75, 187982.25, 536938.75, 188000.25, - 536938.75, 188021.25, 536938.75, 187994.75, 536938.75, 188106.25, 536938.75, 188083.75, - 536938.75, 188153.25, 536938.75, 187985.75, 536938.75, 188158.75, 536938.75, 188068.75, - 536938.75, 188022.25, 536938.75, 188115.25, 536938.75, 187943.25, 536938.75, 188028.75, - 536938.75, 188122.75, 536939.25, 188122.75, 536939.25, 187943.25, 536939.25, 188082.25, - 536939.25, 188073.75, 536939.25, 188026.75, 536939.25, 187924.75, 536939.25, 188009.25, - 536939.25, 187936.25, 536939.25, 188068.75, 536939.25, 188149.25, 536939.25, 188081.75, - 536939.25, 188022.25, 536939.25, 187933.75, 536939.25, 187968.25, 536939.25, 188145.25, - 536939.25, 188097.75, 536939.25, 188140.25, 536939.25, 188146.75, 536939.25, 188021.25, - 536939.25, 188027.75, 536939.25, 187986.25, 536939.25, 187929.25, 536939.25, 187993.25, - 536939.25, 187971.25, 536939.25, 188119.75, 536939.25, 188154.75, 536939.25, 187998.75, - 536939.25, 188022.75, 536939.25, 188096.25, 536939.25, 188124.75, 536939.25, 187936.75, - 536939.25, 188008.25, 536939.25, 188150.75, 536939.25, 188045.25, 536939.25, 188141.25, - 536939.25, 188148.25, 536939.25, 188136.75, 536939.25, 187921.75, 536939.25, 187957.75, - 536939.25, 187996.25, 536939.25, 188144.75, 536939.25, 187998.25, 536939.25, 188010.25, - 536939.25, 187956.75, 536939.25, 188127.75, 536939.25, 188080.75, 536939.25, 188147.25, - 536939.25, 188080.25, 536939.25, 188092.25, 536939.25, 188085.75, 536939.25, 187924.25, - 536939.25, 188044.75, 536939.25, 187979.25, 536939.25, 188084.25, 536939.25, 188070.25, - 536939.25, 187955.75, 536939.25, 188033.25, 536939.25, 188092.75, 536939.25, 188069.75, - 536939.25, 187987.25, 536939.25, 188118.25, 536939.25, 187930.25, 536939.25, 187920.25, - 536939.25, 188073.25, 536939.25, 187922.75, 536939.25, 188125.75, 536939.25, 188119.25, - 536939.25, 187987.75, 536939.25, 188029.75, 536939.25, 188154.25, 536939.25, 188096.75, - 536939.25, 187980.75, 536939.25, 187983.25, 536939.25, 187920.75, 536939.25, 188126.25, - 536939.25, 188125.25, 536939.25, 188009.75, 536939.25, 188108.25, 536939.25, 188156.75, - 536939.25, 188027.25, 536939.25, 188094.25, 536939.25, 188069.25, 536939.25, 187999.75, - 536939.25, 188003.25, 536939.25, 188052.75, 536939.25, 187954.75, 536939.25, 188115.75, - 536939.25, 187957.25, 536939.25, 188120.75, 536939.25, 187938.25, 536939.25, 187942.25, - 536939.25, 188151.75, 536939.25, 187943.75, 536939.25, 187977.75, 536939.25, 188094.75, - 536939.25, 187928.75, 536939.25, 188123.75, 536939.25, 188031.75, 536939.25, 187982.75, - 536939.25, 188138.25, 536939.25, 187984.25, 536939.25, 188030.75, 536939.25, 187931.25, - 536939.25, 188042.75, 536939.25, 187935.25, 536939.25, 187956.25, 536939.25, 188107.75, - 536939.25, 187981.25, 536939.25, 187928.25, 536939.25, 187994.25, 536939.25, 187976.75, - 536939.25, 187995.25, 536939.25, 187999.25, 536939.25, 187927.75, 536939.25, 188072.25, - 536939.75, 187995.25, 536939.75, 188043.75, 536939.75, 188141.75, 536939.75, 188087.75, - 536939.75, 188102.75, 536939.75, 187929.25, 536939.75, 188041.25, 536939.75, 188106.75, - 536939.75, 187994.25, 536939.75, 187992.75, 536939.75, 188065.25, 536939.75, 188159.75, - 536939.75, 187968.75, 536939.75, 188008.75, 536939.75, 188109.25, 536939.75, 187923.75, - 536939.75, 187928.75, 536939.75, 188123.75, 536939.75, 188000.75, 536939.75, 187957.25, - 536939.75, 188093.75, 536939.75, 188140.75, 536939.75, 187983.75, 536939.75, 187954.75, - 536939.75, 187980.75, 536939.75, 188028.25, 536939.75, 188101.25, 536939.75, 187941.25, - 536939.75, 188027.25, 536939.75, 188142.25, 536939.75, 188069.25, 536939.75, 188151.25, - 536939.75, 187974.25, 536939.75, 188104.75, 536939.75, 187992.25, 536939.75, 187983.25, - 536939.75, 187977.75, 536939.75, 187955.25, 536939.75, 187944.25, 536939.75, 188029.75, - 536939.75, 188084.75, 536939.75, 188095.75, 536939.75, 188073.25, 536939.75, 187934.25, - 536939.75, 187980.25, 536939.75, 188155.75, 536939.75, 187977.25, 536939.75, 188092.75, - 536939.75, 188118.25, 536939.75, 188143.75, 536939.75, 188109.75, 536939.75, 187942.75, - 536939.75, 187910.75, 536939.75, 188030.25, 536939.75, 188026.25, 536939.75, 188092.25, - 536939.75, 187923.25, 536939.75, 188067.25, 536939.75, 187936.25, 536939.75, 187986.75, - 536939.75, 188145.75, 536939.75, 188042.25, 536939.75, 188147.25, 536939.75, 188108.75, - 536939.75, 188120.25, 536939.75, 187944.75, 536939.75, 187997.75, 536939.75, 187996.75, - 536939.75, 188040.25, 536939.75, 188010.75, 536939.75, 187998.75, 536939.75, 188144.75, - 536939.75, 187957.75, 536939.75, 188022.75, 536939.75, 188093.25, 536939.75, 188146.25, - 536939.75, 188118.75, 536939.75, 188160.25, 536939.75, 188097.25, 536939.75, 187929.75, - 536939.75, 188074.25, 536939.75, 187985.25, 536939.75, 188021.75, 536939.75, 187974.75, - 536939.75, 188027.75, 536939.75, 188154.25, 536939.75, 188154.75, 536939.75, 188124.75, - 536939.75, 187982.25, 536939.75, 188106.25, 536939.75, 188140.25, 536939.75, 188149.25, - 536939.75, 188009.25, 536939.75, 188028.75, 536939.75, 188068.75, 536940.25, 187933.75, - 536940.25, 187985.75, 536940.25, 188066.25, 536940.25, 188153.25, 536940.25, 187973.25, - 536940.25, 188043.75, 536940.25, 187934.75, 536940.25, 188144.25, 536940.25, 187994.75, - 536940.25, 188127.25, 536940.25, 188145.25, 536940.25, 188022.25, 536940.25, 188028.75, - 536940.25, 188110.25, 536940.25, 188100.75, 536940.25, 187953.25, 536940.25, 187952.75, - 536940.25, 188039.25, 536940.25, 188121.25, 536940.25, 187935.75, 536940.25, 187929.75, - 536940.25, 188106.25, 536940.25, 188105.25, 536940.25, 188093.25, 536940.25, 188023.25, - 536940.25, 188141.25, 536940.25, 187985.25, 536940.25, 188096.25, 536940.25, 188118.75, - 536940.25, 188066.75, 536940.25, 188074.75, 536940.25, 187996.75, 536940.25, 188085.25, - 536940.25, 187944.75, 536940.25, 188055.75, 536940.25, 188010.75, 536940.25, 188120.25, - 536940.25, 187979.75, 536940.25, 188148.25, 536940.25, 188085.75, 536940.25, 188045.25, - 536940.25, 188147.75, 536940.25, 188090.25, 536940.25, 188073.75, 536940.25, 187963.75, - 536940.25, 188010.25, 536940.25, 188080.75, 536940.25, 188067.25, 536940.25, 188095.75, - 536940.25, 187980.25, 536940.25, 187984.75, 536940.25, 187979.25, 536940.25, 188143.75, - 536940.25, 188067.75, 536940.25, 188024.75, 536940.25, 187930.25, 536940.25, 188118.25, - 536940.25, 188073.25, 536940.25, 187995.75, 536940.25, 187934.25, 536940.25, 188082.75, - 536940.25, 188155.75, 536940.25, 188046.75, 536940.25, 188025.75, 536940.25, 188156.25, - 536940.25, 187987.75, 536940.25, 187944.25, 536940.25, 187955.25, 536940.25, 187983.25, - 536940.25, 188064.25, 536940.25, 188143.25, 536940.25, 188101.25, 536940.25, 188027.25, - 536940.25, 188116.75, 536940.25, 188068.25, 536940.25, 188142.75, 536940.25, 187953.75, - 536940.25, 188099.25, 536940.25, 187997.25, 536940.25, 187954.25, 536940.25, 188123.75, - 536940.25, 187992.75, 536940.25, 187957.25, 536940.25, 188104.25, 536940.25, 187988.25, - 536940.25, 187974.25, 536940.25, 188109.25, 536940.25, 187984.25, 536940.25, 187981.75, - 536940.25, 188159.75, 536940.25, 187946.25, 536940.25, 188153.75, 536940.25, 187976.75, - 536940.25, 188025.25, 536940.25, 188135.25, 536940.25, 188106.75, 536940.25, 188081.25, - 536940.25, 188090.75, 536940.25, 187929.25, 536940.25, 188091.75, 536940.25, 187935.25, - 536940.25, 188041.25, 536940.25, 187975.75, 536940.25, 188011.25, 536940.25, 188134.75, - 536940.25, 187991.75, 536940.75, 187980.25, 536940.75, 187934.75, 536940.75, 187984.25, - 536940.75, 188091.75, 536940.75, 188041.25, 536940.75, 187991.75, 536940.75, 188148.25, - 536940.75, 188153.75, 536940.75, 187923.75, 536940.75, 188008.75, 536940.75, 188026.25, - 536940.75, 188147.75, 536940.75, 188120.25, 536940.75, 188092.75, 536940.75, 188010.75, - 536940.75, 187975.75, 536940.75, 188092.25, 536940.75, 187955.25, 536940.75, 187934.25, - 536940.75, 188055.75, 536940.75, 188152.75, 536940.75, 187987.75, 536940.75, 188096.25, - 536940.75, 187979.25, 536940.75, 187995.25, 536940.75, 188144.75, 536940.75, 188146.25, - 536940.75, 188022.25, 536940.75, 188075.25, 536940.75, 188155.25, 536940.75, 187997.25, - 536940.75, 188027.75, 536940.75, 188000.25, 536940.75, 188068.25, 536940.75, 188025.75, - 536940.75, 187973.25, 536940.75, 188081.75, 536940.75, 188115.25, 536940.75, 188066.25, - 536940.75, 187968.25, 536940.75, 187988.25, 536940.75, 187935.75, 536940.75, 188054.75, - 536940.75, 188087.25, 536940.75, 187956.25, 536940.75, 188038.75, 536940.75, 188110.25, - 536940.75, 188139.75, 536940.75, 187929.75, 536940.75, 188066.75, 536940.75, 188148.75, - 536940.75, 188074.75, 536940.75, 188028.25, 536940.75, 188104.75, 536940.75, 188021.75, - 536940.75, 187923.25, 536940.75, 187992.25, 536940.75, 187981.75, 536940.75, 188025.25, - 536940.75, 188143.25, 536940.75, 187977.75, 536940.75, 188071.25, 536940.75, 188090.25, - 536940.75, 187954.25, 536940.75, 188051.25, 536940.75, 188073.75, 536940.75, 187995.75, - 536940.75, 187933.75, 536940.75, 188042.75, 536940.75, 187943.25, 536940.75, 187985.75, - 536940.75, 188022.75, 536940.75, 187944.25, 536940.75, 187982.75, 536940.75, 188159.25, - 536940.75, 187942.25, 536940.75, 187960.25, 536940.75, 188144.25, 536940.75, 187955.75, - 536940.75, 187921.75, 536940.75, 188080.75, 536940.75, 187976.75, 536940.75, 187986.75, - 536940.75, 188094.75, 536940.75, 188044.25, 536940.75, 188085.25, 536940.75, 187986.25, - 536940.75, 188106.75, 536940.75, 187956.75, 536940.75, 188067.75, 536940.75, 187992.75, - 536940.75, 188142.75, 536940.75, 187930.25, 536940.75, 188085.75, 536940.75, 188118.25, - 536940.75, 188105.25, 536940.75, 188030.75, 536940.75, 187979.75, 536940.75, 188027.25, - 536940.75, 188141.25, 536940.75, 187944.75, 536940.75, 187981.25, 536940.75, 188099.75, - 536940.75, 187952.75, 536940.75, 188065.75, 536940.75, 187953.25, 536940.75, 188009.25, - 536940.75, 187951.75, 536940.75, 188118.75, 536940.75, 188122.75, 536940.75, 188036.25, - 536940.75, 187920.25, 536940.75, 188026.75, 536940.75, 188108.75, 536941.25, 188147.25, - 536941.25, 188074.25, 536941.25, 188121.25, 536941.25, 188023.25, 536941.25, 188118.75, - 536941.25, 188086.25, 536941.25, 188122.75, 536941.25, 188067.25, 536941.25, 188091.25, - 536941.25, 188064.25, 536941.25, 187953.25, 536941.25, 187932.25, 536941.25, 188155.75, - 536941.25, 187945.25, 536941.25, 187951.25, 536941.25, 187951.75, 536941.25, 187979.75, - 536941.25, 187992.75, 536941.25, 187985.25, 536941.25, 188118.25, 536941.25, 188105.25, - 536941.25, 188100.75, 536941.25, 187977.75, 536941.25, 188050.25, 536941.25, 187996.25, - 536941.25, 188103.75, 536941.25, 188104.25, 536941.25, 188085.25, 536941.25, 187932.75, - 536941.25, 187984.75, 536941.25, 187933.75, 536941.25, 187982.25, 536941.25, 188010.25, - 536941.25, 188143.25, 536941.25, 188140.25, 536941.25, 187933.25, 536941.25, 188103.25, - 536941.25, 187918.75, 536941.25, 188022.75, 536941.25, 187935.75, 536941.25, 188142.25, - 536941.25, 188099.25, 536941.25, 188089.75, 536941.25, 188023.75, 536941.25, 188139.25, - 536941.25, 188109.25, 536941.25, 188098.75, 536941.25, 187977.25, 536941.25, 188156.25, - 536941.25, 187920.75, 536941.25, 188025.25, 536941.25, 188027.25, 536941.25, 187981.75, - 536941.25, 188024.75, 536941.25, 188009.75, 536941.25, 188111.25, 536941.25, 188145.25, - 536941.25, 188104.75, 536941.25, 187953.75, 536941.25, 188065.25, 536941.25, 188101.25, - 536941.25, 187973.75, 536941.25, 188040.75, 536941.25, 188119.25, 536941.25, 188025.75, - 536941.25, 188075.25, 536941.25, 188131.25, 536941.25, 188116.75, 536941.25, 188109.75, - 536941.25, 188145.75, 536941.25, 187987.75, 536941.25, 188022.25, 536941.25, 187995.25, - 536941.25, 187935.25, 536941.25, 188090.75, 536941.25, 188152.75, 536941.25, 187925.75, - 536941.25, 188056.25, 536941.25, 187930.75, 536941.25, 188121.75, 536941.25, 188010.75, - 536941.25, 188057.25, 536941.25, 188040.25, 536941.25, 188011.25, 536941.25, 188153.25, - 536941.25, 187923.75, 536941.25, 187991.25, 536941.75, 188064.75, 536941.75, 187996.75, - 536941.75, 188094.25, 536941.75, 187919.75, 536941.75, 187950.25, 536941.75, 188130.75, - 536941.75, 188026.25, 536941.75, 188065.25, 536941.75, 187971.25, 536941.75, 188151.75, - 536941.75, 188086.75, 536941.75, 187936.75, 536941.75, 188102.25, 536941.75, 188132.25, - 536941.75, 187932.25, 536941.75, 188136.25, 536941.75, 188148.75, 536941.75, 188111.25, - 536941.75, 188068.75, 536941.75, 188139.25, 536941.75, 188037.75, 536941.75, 187933.25, - 536941.75, 187944.25, 536941.75, 187918.75, 536941.75, 188140.25, 536941.75, 187921.25, - 536941.75, 188003.75, 536941.75, 187994.75, 536941.75, 188061.75, 536941.75, 188011.75, - 536941.75, 187990.75, 536941.75, 187985.25, 536941.75, 187974.75, 536941.75, 187951.25, - 536941.75, 188088.75, 536941.75, 187983.25, 536941.75, 188142.25, 536941.75, 188121.25, - 536941.75, 187993.75, 536941.75, 188064.25, 536941.75, 188157.25, 536941.75, 187931.75, - 536941.75, 188158.25, 536941.75, 188039.75, 536941.75, 188125.25, 536941.75, 187997.75, - 536941.75, 187983.75, 536941.75, 188142.75, 536941.75, 188085.75, 536941.75, 187925.25, - 536941.75, 187971.75, 536941.75, 187937.25, 536941.75, 187984.75, 536941.75, 188010.25, - 536941.75, 188024.25, 536941.75, 188057.75, 536941.75, 187966.25, 536941.75, 188089.25, - 536941.75, 188098.75, 536941.75, 188099.25, 536941.75, 188089.75, 536941.75, 188103.25, - 536941.75, 188090.25, 536941.75, 187922.75, 536941.75, 187923.25, 536941.75, 187941.75, - 536941.75, 187974.25, 536941.75, 188103.75, 536941.75, 187945.75, 536941.75, 188156.75, - 536941.75, 188074.75, 536941.75, 188138.75, 536941.75, 188066.75, 536941.75, 188069.25, - 536941.75, 188056.75, 536941.75, 187973.75, 536941.75, 187931.25, 536941.75, 188038.75, - 536941.75, 187993.25, 536941.75, 187980.75, 536941.75, 188063.75, 536941.75, 188119.25, - 536941.75, 188055.25, 536941.75, 188075.25, 536941.75, 188102.75, 536941.75, 187936.25, - 536941.75, 187946.75, 536941.75, 187995.25, 536941.75, 187935.25, 536941.75, 188110.75, - 536941.75, 187930.75, 536941.75, 188091.75, 536941.75, 187975.25, 536941.75, 187991.75, - 536941.75, 188153.75, 536941.75, 187952.25, 536941.75, 188101.75, 536942.25, 187978.75, - 536942.25, 187973.75, 536942.25, 188143.25, 536942.25, 187974.75, 536942.25, 188135.75, - 536942.25, 187995.25, 536942.25, 187944.75, 536942.25, 188086.75, 536942.25, 188075.25, - 536942.25, 187983.25, 536942.25, 188011.75, 536942.25, 187985.25, 536942.25, 188007.25, - 536942.25, 188055.25, 536942.25, 187923.75, 536942.25, 187982.25, 536942.25, 188119.75, - 536942.25, 188088.25, 536942.25, 188074.25, 536942.25, 188122.25, 536942.25, 187993.25, - 536942.25, 188025.75, 536942.25, 187985.75, 536942.25, 188109.25, 536942.25, 187994.25, - 536942.25, 187929.25, 536942.25, 187981.75, 536942.25, 188110.75, 536942.25, 188067.25, - 536942.25, 188025.25, 536942.25, 188157.25, 536942.25, 188009.75, 536942.25, 187931.25, - 536942.25, 188039.25, 536942.25, 188101.25, 536942.25, 188061.25, 536942.25, 188004.25, - 536942.25, 188065.25, 536942.25, 188140.75, 536942.25, 188160.25, 536942.25, 187952.25, - 536942.25, 188116.75, 536942.25, 187923.25, 536942.25, 188146.25, 536942.25, 188012.25, - 536942.25, 188063.75, 536942.25, 188144.75, 536942.25, 188156.75, 536942.25, 187981.25, - 536942.25, 188151.75, 536942.25, 187996.75, 536942.25, 188153.75, 536942.25, 188103.25, - 536942.25, 187945.75, 536942.25, 187992.75, 536942.25, 188125.25, 536942.25, 187942.75, - 536942.25, 187941.75, 536942.25, 188157.75, 536942.25, 188148.75, 536942.25, 188099.25, - 536942.25, 187983.75, 536942.25, 188136.75, 536942.25, 188057.25, 536942.25, 188064.75, - 536942.25, 188120.25, 536942.25, 188085.75, 536942.25, 187954.25, 536942.25, 188147.75, - 536942.25, 188055.75, 536942.25, 188026.25, 536942.25, 187980.25, 536942.25, 188111.25, - 536942.25, 187950.25, 536942.25, 188062.75, 536942.25, 188091.25, 536942.25, 188089.75, - 536942.25, 187919.25, 536942.25, 188117.25, 536942.25, 187935.75, 536942.25, 188040.75, - 536942.25, 187971.25, 536942.25, 187910.75, 536942.25, 188141.25, 536942.25, 188130.25, - 536942.25, 188102.25, 536942.25, 187937.25, 536942.25, 187932.25, 536942.25, 188066.25, - 536942.25, 188024.25, 536942.25, 188113.25, 536942.25, 188023.75, 536942.25, 188069.75, - 536942.25, 188022.75, 536942.25, 188156.25, 536942.25, 188100.75, 536942.25, 187971.75, - 536942.25, 187930.25, 536942.25, 187951.25, 536942.25, 188037.25, 536942.25, 188098.75, - 536942.25, 188159.25, 536942.25, 187984.75, 536942.25, 187932.75, 536942.25, 187997.75, - 536942.25, 188104.25, 536942.25, 188155.75, 536942.25, 187935.25, 536942.25, 187951.75, - 536942.75, 187920.75, 536942.75, 188155.75, 536942.75, 188093.75, 536942.75, 187991.25, - 536942.75, 187998.75, 536942.75, 188102.75, 536942.75, 188058.25, 536942.75, 187945.25, - 536942.75, 188064.25, 536942.75, 188066.75, 536942.75, 187985.25, 536942.75, 188111.75, - 536942.75, 187921.25, 536942.75, 188090.75, 536942.75, 188140.25, 536942.75, 187969.25, - 536942.75, 187918.75, 536942.75, 188157.25, 536942.75, 188154.25, 536942.75, 188119.25, - 536942.75, 188139.25, 536942.75, 187994.25, 536942.75, 188074.75, 536942.75, 188120.75, - 536942.75, 188118.75, 536942.75, 188092.75, 536942.75, 188042.75, 536942.75, 188087.25, - 536942.75, 187993.75, 536942.75, 188110.75, 536942.75, 187984.25, 536942.75, 188060.75, - 536942.75, 188146.75, 536942.75, 188086.25, 536942.75, 187967.25, 536942.75, 188117.75, - 536942.75, 188093.25, 536942.75, 188010.25, 536942.75, 187978.25, 536942.75, 188024.75, - 536942.75, 188144.75, 536942.75, 187946.25, 536942.75, 188139.75, 536942.75, 188051.25, - 536942.75, 188116.75, 536942.75, 187982.75, 536942.75, 187952.25, 536942.75, 188063.25, - 536942.75, 187931.75, 536942.75, 188099.75, 536942.75, 187929.75, 536942.75, 187930.75, - 536942.75, 188152.75, 536942.75, 187970.75, 536942.75, 188123.25, 536942.75, 187949.25, - 536942.75, 188089.75, 536942.75, 188158.25, 536942.75, 187974.25, 536942.75, 188090.25, - 536942.75, 188038.25, 536942.75, 187943.75, 536942.75, 188062.75, 536942.75, 187998.25, - 536942.75, 188010.75, 536942.75, 187948.75, 536942.75, 187936.75, 536942.75, 187950.75, - 536942.75, 187919.25, 536942.75, 188075.75, 536943.25, 188156.25, 536943.25, 187960.75, - 536943.25, 188105.25, 536943.25, 188154.75, 536943.25, 188074.75, 536943.25, 188102.75, - 536943.25, 187986.25, 536943.25, 188078.75, 536943.25, 187936.75, 536943.25, 187937.25, - 536943.25, 187998.75, 536943.25, 187919.75, 536943.25, 187947.25, 536943.25, 188145.75, - 536943.25, 188115.25, 536943.25, 187980.25, 536943.25, 188088.75, 536943.25, 187990.75, - 536943.25, 187950.75, 536943.25, 187949.75, 536943.25, 188010.75, 536943.25, 188011.25, - 536943.25, 188148.25, 536943.25, 188110.25, 536943.25, 188153.25, 536943.25, 187948.75, - 536943.25, 187991.75, 536943.25, 188112.25, 536943.25, 188056.75, 536943.25, 187946.75, - 536943.25, 188111.75, 536943.25, 188158.75, 536943.25, 188062.25, 536943.25, 187945.75, - 536943.25, 187922.75, 536943.25, 188086.75, 536943.25, 188061.75, 536943.25, 188141.75, - 536943.25, 187983.75, 536943.25, 188075.25, 536943.25, 187936.25, 536943.25, 188103.75, - 536943.25, 188148.75, 536943.25, 187975.75, 536943.25, 187975.25, 536943.25, 188115.75, - 536943.25, 187979.25, 536943.25, 188090.25, 536943.25, 188060.25, 536943.25, 188100.25, - 536943.25, 187992.25, 536943.25, 188004.75, 536943.25, 187928.25, 536943.25, 187947.75, - 536943.25, 188076.25, 536943.25, 187931.25, 536943.25, 187949.25, 536943.25, 187992.75, - 536943.25, 188152.25, 536943.25, 187969.25, 536943.25, 188094.25, 536943.25, 187996.75, - 536943.25, 187986.75, 536943.25, 187997.25, 536943.25, 188118.75, 536943.25, 188098.75, - 536943.25, 188139.25, 536943.25, 188154.25, 536943.25, 187981.75, 536943.25, 188099.75, - 536943.25, 188012.25, 536943.25, 187920.25, 536943.25, 188071.75, 536943.25, 188145.25, - 536943.25, 187918.25, 536943.25, 188107.75, 536943.25, 187946.25, 536943.25, 188140.75, - 536943.25, 187988.75, 536943.25, 187929.25, 536943.25, 187928.75, 536943.25, 188087.75, - 536943.25, 187982.75, 536943.25, 188116.75, 536943.25, 188094.75, 536943.25, 188117.75, - 536943.25, 188100.75, 536943.25, 187937.75, 536943.25, 187930.25, 536943.25, 188159.25, - 536943.25, 188039.25, 536943.25, 188063.25, 536943.25, 188010.25, 536943.25, 187979.75, - 536943.75, 188039.25, 536943.75, 187982.75, 536943.75, 187979.75, 536943.75, 187937.75, - 536943.75, 188153.25, 536943.75, 188002.25, 536943.75, 188061.25, 536943.75, 188076.75, - 536943.75, 188140.25, 536943.75, 187984.25, 536943.75, 188094.75, 536943.75, 187938.75, - 536943.75, 187928.75, 536943.75, 188057.75, 536943.75, 188099.25, 536943.75, 187927.75, - 536943.75, 187991.75, 536943.75, 188145.25, 536943.75, 188127.75, 536943.75, 188154.25, - 536943.75, 188156.75, 536943.75, 187936.25, 536943.75, 187978.25, 536943.75, 187980.75, - 536943.75, 188059.75, 536943.75, 188087.25, 536943.75, 187920.25, 536943.75, 187943.25, - 536943.75, 187958.75, 536943.75, 187975.25, 536943.75, 188101.25, 536943.75, 187946.25, - 536943.75, 188151.75, 536943.75, 187930.25, 536943.75, 188147.25, 536943.75, 188119.75, - 536943.75, 188090.75, 536943.75, 188142.25, 536943.75, 187918.75, 536943.75, 187992.75, - 536943.75, 188102.25, 536943.75, 188055.75, 536943.75, 188060.25, 536943.75, 187949.75, - 536943.75, 187947.75, 536943.75, 188076.25, 536943.75, 187982.25, 536943.75, 188118.75, - 536943.75, 188133.75, 536943.75, 187947.25, 536943.75, 187969.25, 536943.75, 187968.25, - 536943.75, 187921.25, 536943.75, 188026.75, 536943.75, 188086.25, 536943.75, 187948.75, - 536943.75, 187979.25, 536943.75, 187948.25, 536943.75, 188115.75, 536943.75, 188067.75, - 536943.75, 188158.25, 536943.75, 188103.75, 536943.75, 187986.25, 536943.75, 188089.25, - 536943.75, 187922.75, 536943.75, 188120.25, 536943.75, 188062.25, 536943.75, 188056.75, - 536943.75, 187946.75, 536943.75, 187983.75, 536943.75, 187950.75, 536943.75, 188145.75, - 536943.75, 188110.25, 536943.75, 188010.75, 536943.75, 187945.75, 536943.75, 188067.25, - 536943.75, 188075.25, 536943.75, 187974.25, 536943.75, 187997.25, 536943.75, 187990.75, - 536943.75, 188083.75, 536943.75, 188111.25, 536943.75, 188151.25, 536943.75, 188088.75, - 536943.75, 187937.25, 536943.75, 187951.75, 536943.75, 188064.75, 536943.75, 188098.75, - 536943.75, 187949.25, 536943.75, 188084.25, 536943.75, 187930.75, 536943.75, 188117.25, - 536943.75, 188093.75, 536943.75, 188154.75, 536944.25, 187976.25, 536944.25, 187945.75, - 536944.25, 188088.75, 536944.25, 188131.25, 536944.25, 187998.75, 536944.25, 187990.75, - 536944.25, 188112.25, 536944.25, 188087.25, 536944.25, 188158.25, 536944.25, 188060.75, - 536944.25, 188011.75, 536944.25, 188110.75, 536944.25, 187983.25, 536944.25, 188155.25, - 536944.25, 188072.25, 536944.25, 188139.75, 536944.25, 188149.25, 536944.25, 188061.75, - 536944.25, 188103.25, 536944.25, 187920.75, 536944.25, 188101.25, 536944.25, 188050.75, - 536944.25, 188118.75, 536944.25, 187923.25, 536944.25, 188012.25, 536944.25, 187922.75, - 536944.25, 187928.25, 536944.25, 188150.25, 536944.25, 187995.75, 536944.25, 188139.25, - 536944.25, 187938.25, 536944.25, 188056.75, 536944.25, 188057.75, 536944.25, 188157.25, - 536944.25, 187985.75, 536944.25, 187918.75, 536944.25, 187919.25, 536944.25, 187991.75, - 536944.25, 188059.25, 536944.25, 187986.75, 536944.25, 188104.25, 536944.25, 188076.75, - 536944.25, 188059.75, 536944.25, 187997.75, 536944.25, 187966.25, 536944.25, 188112.75, - 536944.25, 188084.25, 536944.25, 188075.75, 536944.25, 187946.75, 536944.25, 188012.75, - 536944.25, 188118.25, 536944.25, 187918.25, 536944.25, 187937.75, 536944.25, 188154.25, - 536944.25, 187949.75, 536944.25, 187959.25, 536944.25, 187989.75, 536944.25, 187987.75, - 536944.25, 187927.75, 536944.25, 188115.25, 536944.25, 187958.75, 536944.25, 187996.75, - 536944.25, 188099.75, 536944.25, 188159.25, 536944.25, 188070.25, 536944.25, 187947.75, - 536944.25, 187958.25, 536944.25, 188157.75, 536944.25, 188151.75, 536944.25, 188106.75, - 536944.25, 188087.75, 536944.25, 187936.75, 536944.25, 188098.75, 536944.25, 188011.25, - 536944.25, 187983.75, 536944.25, 187989.25, 536944.25, 188115.75, 536944.75, 187998.25, - 536944.75, 187925.75, 536944.75, 187927.25, 536944.75, 188121.75, 536944.75, 188099.25, - 536944.75, 187919.75, 536944.75, 188087.75, 536944.75, 188052.25, 536944.75, 188148.75, - 536944.75, 188005.25, 536944.75, 187942.75, 536944.75, 187966.75, 536944.75, 188098.25, - 536944.75, 188049.75, 536944.75, 188159.25, 536944.75, 188160.25, 536944.75, 188013.25, - 536944.75, 188152.75, 536944.75, 188157.75, 536944.75, 187999.25, 536944.75, 188083.25, - 536944.75, 187988.75, 536944.75, 187989.75, 536944.75, 187958.75, 536944.75, 188115.25, - 536944.75, 187999.75, 536944.75, 188060.25, 536944.75, 187987.75, 536944.75, 188100.75, - 536944.75, 188108.25, 536944.75, 188147.25, 536944.75, 187918.25, 536944.75, 187984.75, - 536944.75, 188112.75, 536944.75, 188137.25, 536944.75, 188077.25, 536944.75, 188143.25, - 536944.75, 188098.75, 536944.75, 187967.25, 536944.75, 188159.75, 536944.75, 188153.25, - 536944.75, 187997.75, 536944.75, 188155.75, 536944.75, 188102.75, 536944.75, 187986.75, - 536944.75, 188113.75, 536944.75, 187918.75, 536944.75, 187947.75, 536944.75, 187990.25, - 536944.75, 188058.75, 536944.75, 188141.25, 536944.75, 188097.25, 536944.75, 187980.25, - 536944.75, 187965.25, 536944.75, 187913.75, 536944.75, 187910.75, 536944.75, 188084.75, - 536944.75, 187938.25, 536944.75, 188139.25, 536944.75, 187987.25, 536944.75, 188076.25, - 536944.75, 188116.25, 536944.75, 188085.25, 536944.75, 188100.25, 536944.75, 187929.25, - 536944.75, 188156.75, 536944.75, 188104.75, 536944.75, 188056.25, 536944.75, 188125.75, - 536944.75, 188103.25, 536944.75, 188139.75, 536944.75, 187960.75, 536944.75, 188072.25, - 536944.75, 187985.25, 536944.75, 188013.75, 536944.75, 187983.25, 536944.75, 188111.75, - 536944.75, 188050.75, 536944.75, 188011.75, 536944.75, 188103.75, 536944.75, 188083.75, - 536944.75, 188058.25, 536944.75, 188114.75, 536944.75, 187975.75, 536944.75, 187946.75, - 536944.75, 188124.25, 536944.75, 188055.25, 536945.25, 188114.75, 536945.25, 188123.75, - 536945.25, 188112.25, 536945.25, 187941.25, 536945.25, 188091.75, 536945.25, 187938.25, - 536945.25, 187920.75, 536945.25, 188138.25, 536945.25, 188094.75, 536945.25, 187989.75, - 536945.25, 187925.25, 536945.25, 188141.75, 536945.25, 188159.25, 536945.25, 188102.75, - 536945.25, 187937.25, 536945.25, 188083.25, 536945.25, 188112.75, 536945.25, 187967.25, - 536945.25, 188115.25, 536945.25, 188058.75, 536945.25, 188097.25, 536945.25, 188119.25, - 536945.25, 187912.75, 536945.25, 187983.25, 536945.25, 188111.75, 536945.25, 188083.75, - 536945.25, 187924.75, 536945.25, 188158.25, 536945.25, 187928.25, 536945.25, 188157.25, - 536945.25, 188058.25, 536945.25, 188091.25, 536945.25, 187998.75, 536945.25, 187964.75, - 536945.25, 188056.25, 536945.25, 188114.25, 536945.25, 188125.75, 536945.25, 187987.25, - 536945.25, 187929.25, 536945.25, 188100.25, 536945.25, 188116.25, 536945.25, 188085.25, - 536945.25, 188076.25, 536945.25, 187972.75, 536945.25, 187968.75, 536945.25, 188071.75, - 536945.25, 187994.25, 536945.25, 187918.75, 536945.25, 188113.75, 536945.25, 188143.25, - 536945.25, 188126.25, 536945.25, 187987.75, 536945.25, 188016.25, 536945.25, 188073.25, - 536945.25, 188152.75, 536945.25, 188148.75, 536945.25, 188087.75, 536945.25, 188099.25, - 536945.25, 187998.25, 536945.25, 188148.25, 536945.25, 188137.75, 536945.25, 187919.75, - 536945.25, 187927.25, 536945.25, 187966.75, 536945.25, 188098.25, 536945.25, 188011.25, - 536945.25, 187936.75, 536945.25, 187988.75, 536945.25, 187986.75, 536945.25, 188060.25, - 536945.25, 187926.75, 536945.25, 188077.25, 536945.25, 188050.25, 536945.25, 188151.25, - 536945.25, 187997.75, 536945.25, 187965.75, 536945.25, 187986.25, 536945.25, 187990.25, - 536945.25, 187984.25, 536945.25, 188089.25, 536945.25, 188084.75, 536945.25, 188012.25, - 536945.25, 187952.25, 536945.25, 188101.25, 536945.25, 188104.75, 536945.25, 188139.75, - 536945.25, 188005.75, 536945.25, 187947.75, 536945.75, 188138.75, 536945.75, 188144.25, - 536945.75, 187920.25, 536945.75, 187967.75, 536945.75, 187983.25, 536945.75, 187917.75, - 536945.75, 188055.25, 536945.75, 187964.75, 536945.75, 188157.25, 536945.75, 187998.75, - 536945.75, 188155.75, 536945.75, 188013.75, 536945.75, 187921.25, 536945.75, 188091.75, - 536945.75, 188051.25, 536945.75, 188007.75, 536945.75, 187928.75, 536945.75, 188157.75, - 536945.75, 188115.75, 536945.75, 188099.75, 536945.75, 187992.75, 536945.75, 188094.25, - 536945.75, 188013.25, 536945.75, 187998.25, 536945.75, 188137.75, 536945.75, 188142.75, - 536945.75, 187983.75, 536945.75, 187925.75, 536945.75, 188088.75, 536945.75, 188091.25, - 536945.75, 187989.25, 536945.75, 188114.25, 536945.75, 187999.75, 536945.75, 187985.25, - 536945.75, 188154.75, 536945.75, 187937.75, 536945.75, 188012.75, 536945.75, 188055.75, - 536945.75, 188088.25, 536945.75, 188058.25, 536945.75, 188105.25, 536945.75, 187989.75, - 536945.75, 187965.75, 536945.75, 187921.75, 536945.75, 188076.75, 536945.75, 187924.25, - 536945.75, 187913.75, 536945.75, 188116.75, 536945.75, 188012.25, 536945.75, 188087.75, - 536945.75, 188104.25, 536945.75, 188096.75, 536945.75, 188089.75, 536945.75, 188154.25, - 536945.75, 187929.75, 536945.75, 188124.25, 536945.75, 188094.75, 536945.75, 187912.75, - 536945.75, 187969.75, 536945.75, 187938.75, 536945.75, 188159.75, 536945.75, 188150.75, - 536945.75, 188062.75, 536945.75, 187914.75, 536945.75, 187977.25, 536945.75, 188149.75, - 536945.75, 188140.75, 536945.75, 188112.25, 536945.75, 188063.75, 536945.75, 188081.75, - 536945.75, 188155.25, 536945.75, 188101.75, 536945.75, 188117.75, 536945.75, 187922.25, - 536945.75, 188151.25, 536945.75, 187980.75, 536945.75, 188102.25, 536945.75, 188066.75, - 536945.75, 188124.75, 536945.75, 188059.75, 536945.75, 187961.25, 536945.75, 188112.75, - 536945.75, 187913.25, 536945.75, 187988.25, 536946.25, 187988.25, 536946.25, 188086.25, - 536946.25, 187956.75, 536946.25, 188149.25, 536946.25, 188056.25, 536946.25, 188077.75, - 536946.25, 188046.75, 536946.25, 187963.75, 536946.25, 187980.75, 536946.25, 187951.75, - 536946.25, 187968.75, 536946.25, 188000.25, 536946.25, 188112.25, 536946.25, 188101.25, - 536946.25, 188140.75, 536946.25, 188103.25, 536946.25, 187984.75, 536946.25, 187958.25, - 536946.25, 188141.25, 536946.25, 187929.75, 536946.25, 187967.25, 536946.25, 188078.75, - 536946.25, 187932.75, 536946.25, 188103.75, 536946.25, 187938.75, 536946.25, 187930.25, - 536946.25, 188144.25, 536946.25, 188138.25, 536946.25, 188136.75, 536946.25, 187936.75, - 536946.25, 187912.75, 536946.25, 188100.75, 536946.25, 188089.75, 536946.25, 188113.25, - 536946.25, 188090.25, 536946.25, 188051.75, 536946.25, 188154.25, 536946.25, 188117.25, - 536946.25, 187919.25, 536946.25, 188128.25, 536946.25, 188148.25, 536946.25, 188056.75, - 536946.25, 188092.25, 536946.25, 187911.75, 536946.25, 187999.25, 536946.25, 187991.25, - 536946.25, 188090.75, 536946.25, 188050.75, 536946.25, 188156.75, 536946.25, 187918.25, - 536946.25, 187976.25, 536946.25, 187980.25, 536946.25, 188135.25, 536946.25, 188105.25, - 536946.25, 187981.75, 536946.25, 188088.25, 536946.25, 187985.75, 536946.25, 188137.25, - 536946.25, 187925.25, 536946.25, 187989.75, 536946.25, 188012.75, 536946.25, 188116.25, - 536946.25, 187937.75, 536946.25, 188100.25, 536946.25, 188145.25, 536946.25, 187986.75, - 536946.25, 188064.75, 536946.25, 188055.75, 536946.25, 188154.75, 536946.25, 187962.75, - 536946.25, 188096.25, 536946.25, 188052.25, 536946.25, 188048.25, 536946.25, 188158.75, - 536946.25, 187925.75, 536946.25, 188049.75, 536946.25, 188046.25, 536946.25, 188014.25, - 536946.25, 188142.25, 536946.25, 188143.75, 536946.25, 188057.25, 536946.25, 187964.25, - 536946.25, 188098.75, 536946.25, 187981.25, 536946.25, 188141.75, 536946.25, 188074.75, - 536946.25, 188031.25, 536946.25, 187976.75, 536946.25, 188139.25, 536946.25, 188150.25, - 536946.25, 187923.25, 536946.25, 188095.75, 536946.25, 187929.25, 536946.25, 188060.75, - 536946.25, 187964.75, 536946.25, 188153.75, 536946.25, 187924.75, 536946.25, 187966.75, - 536946.25, 188122.75, 536946.25, 188108.75, 536946.25, 187947.25, 536946.25, 188134.75, - 536946.75, 188095.25, 536946.75, 187963.75, 536946.75, 187966.75, 536946.75, 187917.75, - 536946.75, 187963.25, 536946.75, 188104.25, 536946.75, 187999.25, 536946.75, 187991.25, - 536946.75, 188055.25, 536946.75, 187919.25, 536946.75, 188051.75, 536946.75, 187988.75, - 536946.75, 187912.75, 536946.75, 188092.25, 536946.75, 187936.75, 536946.75, 187940.25, - 536946.75, 187968.25, 536946.75, 188054.75, 536946.75, 188104.75, 536946.75, 188136.75, - 536946.75, 188153.75, 536946.75, 187924.25, 536946.75, 187984.75, 536946.75, 188084.75, - 536946.75, 187939.25, 536946.75, 188083.75, 536946.75, 187937.75, 536946.75, 188060.75, - 536946.75, 187990.25, 536946.75, 188114.75, 536946.75, 188085.75, 536946.75, 187967.25, - 536946.75, 187962.25, 536946.75, 188095.75, 536946.75, 188091.75, 536946.75, 187980.25, - 536946.75, 187976.75, 536946.75, 188090.75, 536946.75, 187996.25, 536946.75, 188141.75, - 536946.75, 188103.25, 536946.75, 187921.75, 536946.75, 187984.25, 536946.75, 188078.25, - 536946.75, 188105.25, 536946.75, 188115.75, 536946.75, 188044.25, 536946.75, 188063.75, - 536946.75, 188099.75, 536946.75, 187911.25, 536946.75, 187935.25, 536946.75, 188056.25, - 536946.75, 187981.25, 536946.75, 187998.75, 536946.75, 188124.75, 536946.75, 187925.25, - 536946.75, 188012.75, 536946.75, 188071.75, 536946.75, 188146.75, 536946.75, 188077.75, - 536946.75, 187986.75, 536946.75, 188159.25, 536946.75, 187962.75, 536946.75, 188072.25, - 536946.75, 188087.25, 536946.75, 188143.75, 536946.75, 187956.25, 536946.75, 188098.75, - 536946.75, 188155.25, 536946.75, 187929.25, 536946.75, 188142.25, 536946.75, 187925.75, - 536946.75, 187968.75, 536946.75, 188000.25, 536946.75, 188014.25, 536946.75, 188101.25, - 536946.75, 188057.25, 536946.75, 188133.25, 536946.75, 187938.75, 536946.75, 188052.25, - 536946.75, 188047.25, 536946.75, 187922.75, 536946.75, 188055.75, 536946.75, 188149.75, - 536946.75, 187985.25, 536946.75, 188077.25, 536946.75, 188158.75, 536946.75, 187929.75, - 536946.75, 188139.25, 536946.75, 188105.75, 536946.75, 188088.75, 536946.75, 187964.25, - 536946.75, 188100.75, 536946.75, 188123.25, 536946.75, 188094.25, 536946.75, 188060.25, - 536946.75, 188144.25, 536946.75, 188154.25, 536946.75, 187971.25, 536946.75, 188117.25, - 536946.75, 188116.75, 536946.75, 188116.25, 536946.75, 188052.75, 536946.75, 187947.75, - 536946.75, 187981.75, 536946.75, 188135.25, 536946.75, 187976.25, 536946.75, 188076.75, - 536946.75, 187914.25, 536947.25, 187913.75, 536947.25, 188141.75, 536947.25, 188070.75, - 536947.25, 187925.25, 536947.25, 187922.25, 536947.25, 188076.25, 536947.25, 188105.25, - 536947.25, 187912.25, 536947.25, 188116.75, 536947.25, 188137.25, 536947.25, 188149.25, - 536947.25, 187910.75, 536947.25, 188148.25, 536947.25, 188117.25, 536947.25, 187963.25, - 536947.25, 188121.25, 536947.25, 187990.75, 536947.25, 188050.75, 536947.25, 188103.25, - 536947.25, 188055.25, 536947.25, 187969.25, 536947.25, 188012.75, 536947.25, 188157.75, - 536947.25, 187921.75, 536947.25, 188144.25, 536947.25, 187937.25, 536947.25, 187985.75, - 536947.25, 188100.75, 536947.25, 188122.25, 536947.25, 188100.25, 536947.25, 188013.25, - 536947.25, 188070.25, 536947.25, 188006.25, 536947.25, 188088.75, 536947.25, 188147.25, - 536947.25, 187991.25, 536947.25, 188105.75, 536947.25, 188160.25, 536947.25, 187987.25, - 536947.25, 188000.25, 536947.25, 188053.75, 536947.25, 187929.75, 536947.25, 187964.75, - 536947.25, 188077.25, 536947.25, 188092.25, 536947.25, 188097.75, 536947.25, 188039.25, - 536947.25, 187999.75, 536947.25, 188055.75, 536947.25, 188077.75, 536947.25, 187962.25, - 536947.25, 188066.25, 536947.25, 188096.25, 536947.25, 187965.75, 536947.25, 188143.75, - 536947.25, 188094.25, 536947.25, 188091.75, 536947.25, 188054.75, 536947.25, 187929.25, - 536947.25, 188095.75, 536947.25, 187924.75, 536947.25, 187930.25, 536947.25, 188137.75, - 536947.25, 188048.25, 536947.25, 188078.75, 536947.25, 188156.75, 536947.25, 187936.75, - 536947.25, 188079.25, 536947.25, 187981.25, 536947.25, 187962.75, 536947.25, 187983.25, - 536947.25, 188013.75, 536947.25, 187925.75, 536947.25, 188154.75, 536947.25, 187984.75, - 536947.25, 187973.75, 536947.25, 188038.75, 536947.25, 188098.75, 536947.25, 187938.25, - 536947.25, 188103.75, 536947.25, 188046.25, 536947.75, 188155.25, 536947.75, 188131.25, - 536947.75, 187924.25, 536947.75, 188005.75, 536947.75, 188090.25, 536947.75, 188051.75, - 536947.75, 188117.75, 536947.75, 187981.25, 536947.75, 188000.75, 536947.75, 188155.75, - 536947.75, 187970.25, 536947.75, 187931.25, 536947.75, 188128.75, 536947.75, 187964.75, - 536947.75, 188142.75, 536947.75, 187961.75, 536947.75, 188054.25, 536947.75, 188049.75, - 536947.75, 188045.25, 536947.75, 188143.25, 536947.75, 187959.75, 536947.75, 188047.25, - 536947.75, 187915.25, 536947.75, 187973.75, 536947.75, 187921.25, 536947.75, 188045.75, - 536947.75, 188159.25, 536947.75, 188138.25, 536947.75, 188131.75, 536947.75, 187992.25, - 536947.75, 188106.75, 536947.75, 187963.75, 536947.75, 188118.25, 536947.75, 188104.75, - 536947.75, 187952.75, 536947.75, 188010.75, 536947.75, 188077.75, 536947.75, 188068.75, - 536947.75, 187935.75, 536947.75, 188120.75, 536947.75, 188145.25, 536947.75, 188048.75, - 536947.75, 187930.75, 536947.75, 187965.75, 536947.75, 187996.25, 536947.75, 187922.25, - 536947.75, 187978.25, 536947.75, 188053.75, 536947.75, 187961.25, 536947.75, 188079.75, - 536947.75, 188158.75, 536947.75, 188089.25, 536947.75, 187977.75, 536947.75, 187974.25, - 536947.75, 187985.25, 536947.75, 188157.25, 536947.75, 187934.75, 536947.75, 187988.25, - 536947.75, 187929.25, 536947.75, 188096.75, 536947.75, 187937.25, 536947.75, 188098.25, - 536947.75, 187969.25, 536947.75, 187984.25, 536947.75, 188050.75, 536947.75, 188093.75, - 536947.75, 188140.75, 536947.75, 187999.75, 536947.75, 188121.25, 536947.75, 187920.75, - 536947.75, 188112.25, 536947.75, 188092.75, 536947.75, 188001.25, 536947.75, 188141.75, - 536947.75, 187925.25, 536947.75, 187954.25, 536947.75, 188012.25, 536947.75, 188109.75, - 536947.75, 188106.25, 536947.75, 188130.25, 536947.75, 188078.25, 536947.75, 188116.75, - 536947.75, 188146.25, 536947.75, 187987.75, 536947.75, 187914.25, 536947.75, 187936.25, - 536947.75, 188119.25, 536947.75, 188053.25, 536947.75, 188065.25, 536947.75, 187989.75, - 536948.25, 187936.25, 536948.25, 188078.25, 536948.25, 187937.25, 536948.25, 188146.25, - 536948.25, 188130.25, 536948.25, 188137.25, 536948.25, 188011.25, 536948.25, 187920.75, - 536948.25, 188092.75, 536948.25, 188121.25, 536948.25, 187990.75, 536948.25, 188103.25, - 536948.25, 188097.75, 536948.25, 187969.25, 536948.25, 188012.75, 536948.25, 187987.75, - 536948.25, 187941.25, 536948.25, 187961.25, 536948.25, 188079.75, 536948.25, 187933.75, - 536948.25, 188053.75, 536948.25, 188142.25, 536948.25, 187922.25, 536948.25, 187965.75, - 536948.25, 188105.25, 536948.25, 188145.25, 536948.25, 187959.25, 536948.25, 187935.75, - 536948.25, 187973.75, 536948.25, 187914.75, 536948.25, 188077.75, 536948.25, 188050.25, - 536948.25, 188064.75, 536948.25, 188106.75, 536948.25, 188159.25, 536948.25, 188085.75, - 536948.25, 188084.75, 536948.25, 188060.75, 536948.25, 187959.75, 536948.25, 188095.75, - 536948.25, 187961.75, 536948.25, 187962.75, 536948.25, 187970.25, 536948.25, 187931.25, - 536948.25, 187984.75, 536948.25, 188117.75, 536948.25, 188155.25, 536948.25, 188155.75, - 536948.25, 188013.75, 536948.25, 187924.25, 536948.25, 187923.75, 536948.25, 187989.25, - 536948.25, 187913.75, 536948.25, 188054.25, 536948.25, 187975.75, 536948.25, 187930.25, - 536948.25, 188079.25, 536948.25, 187916.75, 536948.25, 188045.25, 536948.25, 187992.25, - 536948.25, 188144.75, 536948.25, 188047.25, 536948.25, 188040.75, 536948.25, 188052.25, - 536948.25, 188143.25, 536948.25, 188054.75, 536948.25, 188045.75, 536948.25, 188131.75, - 536948.25, 187998.25, 536948.25, 188142.75, 536948.25, 188096.25, 536948.25, 188091.25, - 536948.25, 188120.25, 536948.25, 188138.25, 536948.25, 187965.25, 536948.25, 187966.25, - 536948.25, 188076.25, 536948.25, 188089.75, 536948.25, 188077.25, 536948.25, 188000.25, - 536948.25, 188158.75, 536948.25, 188120.75, 536948.25, 188013.25, 536948.25, 187934.75, - 536948.25, 187919.25, 536948.25, 188049.25, 536948.25, 188132.25, 536948.25, 188099.25, - 536948.25, 187985.25, 536948.25, 188151.75, 536948.25, 188096.75, 536948.25, 187928.75, - 536948.25, 188093.75, 536948.25, 188104.25, 536948.25, 188116.25, 536948.25, 188148.25, - 536948.25, 188154.25, 536948.25, 188012.25, 536948.25, 187999.75, 536948.25, 188089.25, - 536948.25, 188053.25, 536948.25, 188052.75, 536948.25, 187911.75, 536948.25, 188131.25, - 536948.75, 188062.25, 536948.75, 187969.25, 536948.75, 188089.75, 536948.75, 187973.25, - 536948.75, 187988.25, 536948.75, 188156.25, 536948.75, 188011.25, 536948.75, 188130.25, - 536948.75, 187963.25, 536948.75, 188099.25, 536948.75, 188092.25, 536948.75, 187934.25, - 536948.75, 188059.75, 536948.75, 188130.75, 536948.75, 187957.75, 536948.75, 188010.75, - 536948.75, 187949.75, 536948.75, 188102.25, 536948.75, 188077.75, 536948.75, 187925.25, - 536948.75, 187921.75, 536948.75, 187958.75, 536948.75, 187986.25, 536948.75, 188118.25, - 536948.75, 187986.75, 536948.75, 188110.25, 536948.75, 188140.75, 536948.75, 188159.25, - 536948.75, 188154.75, 536948.75, 188101.75, 536948.75, 188121.75, 536948.75, 188094.25, - 536948.75, 187931.25, 536948.75, 187938.75, 536948.75, 188106.75, 536948.75, 188012.25, - 536948.75, 188147.25, 536948.75, 187922.75, 536948.75, 187990.75, 536948.75, 188010.25, - 536948.75, 188048.75, 536948.75, 187937.75, 536948.75, 188105.75, 536948.75, 188000.25, - 536948.75, 188047.75, 536948.75, 188090.25, 536948.75, 188078.75, 536948.75, 188142.75, - 536948.75, 188129.25, 536948.75, 187936.75, 536948.75, 188001.75, 536948.75, 188051.75, - 536948.75, 188001.25, 536948.75, 188141.75, 536948.75, 188119.75, 536948.75, 188061.25, - 536948.75, 187932.75, 536948.75, 188111.75, 536948.75, 187991.25, 536948.75, 188103.75, - 536948.75, 188035.75, 536948.75, 187913.75, 536948.75, 188116.75, 536948.75, 187930.25, - 536948.75, 188052.75, 536948.75, 187988.75, 536948.75, 188098.75, 536948.75, 187978.25, - 536948.75, 187994.25, 536948.75, 188093.25, 536948.75, 188153.75, 536948.75, 188144.75, - 536948.75, 188109.25, 536948.75, 188049.75, 536948.75, 188067.75, 536948.75, 188158.75, - 536948.75, 188076.25, 536948.75, 188052.25, 536948.75, 188120.25, 536949.25, 187989.25, - 536949.25, 188009.25, 536949.25, 188095.25, 536949.25, 188092.75, 536949.25, 187939.75, - 536949.25, 188091.25, 536949.25, 187989.75, 536949.25, 188067.25, 536949.25, 187960.75, - 536949.25, 188057.25, 536949.25, 188075.75, 536949.25, 187985.75, 536949.25, 187956.75, - 536949.25, 187974.25, 536949.25, 188061.75, 536949.25, 188074.25, 536949.25, 187977.75, - 536949.25, 188008.75, 536949.25, 188139.75, 536949.25, 187933.25, 536949.25, 188153.75, - 536949.25, 187930.75, 536949.25, 188093.25, 536949.25, 187957.25, 536949.25, 187958.75, - 536949.25, 188041.75, 536949.25, 188052.75, 536949.25, 188019.25, 536949.25, 188157.25, - 536949.25, 188148.75, 536949.25, 187924.25, 536949.25, 188113.75, 536949.25, 187982.25, - 536949.25, 188051.25, 536949.25, 187981.25, 536949.25, 188006.75, 536949.25, 188158.75, - 536949.25, 187982.75, 536949.25, 188010.75, 536949.25, 188009.75, 536949.25, 188119.25, - 536949.25, 187979.25, 536949.25, 187959.25, 536949.25, 187965.75, 536949.25, 187991.25, - 536949.25, 188120.75, 536949.25, 187957.75, 536949.25, 188154.25, 536949.25, 188077.75, - 536949.25, 188062.25, 536949.25, 188046.25, 536949.25, 188094.75, 536949.25, 188097.25, - 536949.25, 187926.75, 536949.25, 187986.25, 536949.25, 187959.75, 536949.25, 188145.75, - 536949.25, 188041.25, 536949.25, 188117.25, 536949.25, 188104.25, 536949.25, 187984.75, - 536949.25, 188099.75, 536949.25, 187986.75, 536949.25, 188001.75, 536949.25, 188107.25, - 536949.25, 188014.75, 536949.25, 187974.75, 536949.25, 188000.75, 536949.25, 188106.25, - 536949.25, 187921.25, 536949.25, 188124.25, 536949.25, 187962.75, 536949.25, 188144.25, - 536949.25, 187936.75, 536949.25, 188114.75, 536949.25, 188078.75, 536949.25, 187963.25, - 536949.25, 187931.75, 536949.25, 187977.25, 536949.25, 187958.25, 536949.25, 188074.75, - 536949.25, 188040.25, 536949.25, 187990.25, 536949.25, 188048.75, 536949.25, 187964.25, - 536949.25, 188159.25, 536949.25, 188155.25, 536949.25, 188050.75, 536949.25, 187937.75, - 536949.25, 188047.25, 536949.25, 187938.75, 536949.25, 187923.25, 536949.25, 187980.25, - 536949.25, 188035.25, 536949.25, 187922.75, 536949.25, 188141.25, 536949.25, 187990.75, - 536949.25, 187962.25, 536949.25, 187978.75, 536949.75, 188141.25, 536949.75, 187967.25, - 536949.75, 188035.25, 536949.75, 188091.75, 536949.75, 187921.25, 536949.75, 188107.75, - 536949.75, 187923.25, 536949.75, 188010.25, 536949.75, 188096.25, 536949.75, 187938.75, - 536949.75, 188077.25, 536949.75, 188047.25, 536949.75, 187980.25, 536949.75, 187963.25, - 536949.75, 187923.75, 536949.75, 187989.25, 536949.75, 188096.75, 536949.75, 188105.75, - 536949.75, 188155.25, 536949.75, 188050.75, 536949.75, 188090.25, 536949.75, 187958.25, - 536949.75, 187970.25, 536949.75, 188129.75, 536949.75, 188078.75, 536949.75, 187962.25, - 536949.75, 187962.75, 536949.75, 188140.75, 536949.75, 187990.25, 536949.75, 188104.25, - 536949.75, 188144.25, 536949.75, 187937.25, 536949.75, 188000.75, 536949.75, 188098.25, - 536949.75, 187986.75, 536949.75, 188099.75, 536949.75, 188103.25, 536949.75, 187979.25, - 536949.75, 188007.25, 536949.75, 188117.25, 536949.75, 187986.25, 536949.75, 188142.75, - 536949.75, 187936.75, 536949.75, 188076.25, 536949.75, 188041.25, 536949.75, 187915.75, - 536949.75, 187971.75, 536949.75, 187932.25, 536949.75, 188078.25, 536949.75, 187959.75, - 536949.75, 188142.25, 536949.75, 188001.75, 536949.75, 188093.75, 536949.75, 188073.25, - 536949.75, 187991.25, 536949.75, 187933.25, 536949.75, 188010.75, 536949.75, 188058.25, - 536949.75, 188119.25, 536949.75, 187982.75, 536949.75, 188009.75, 536949.75, 188051.25, - 536949.75, 188008.25, 536949.75, 188113.75, 536949.75, 188118.75, 536949.75, 187978.25, - 536949.75, 188154.25, 536949.75, 187957.25, 536949.75, 187930.75, 536949.75, 187999.75, - 536949.75, 188079.75, 536949.75, 188160.25, 536949.75, 188144.75, 536949.75, 188008.75, - 536949.75, 187985.25, 536949.75, 187989.75, 536949.75, 187988.75, 536949.75, 187956.75, - 536949.75, 188156.25, 536949.75, 188039.75, 536949.75, 188074.25, 536949.75, 188139.25, - 536949.75, 188066.75, 536949.75, 188009.25, 536949.75, 187910.75, 536949.75, 187974.25, - 536949.75, 187995.75, 536949.75, 187988.25, 536949.75, 188158.25, 536949.75, 187979.75, - 536949.75, 188094.75, 536949.75, 188048.25, 536949.75, 188092.75, 536949.75, 188086.25, - 536949.75, 188061.75, 536949.75, 187956.25, 536949.75, 188089.75, 536949.75, 187984.75, - 536950.25, 187949.75, 536950.25, 187956.25, 536950.25, 188106.25, 536950.25, 188074.75, - 536950.25, 188102.75, 536950.25, 188154.75, 536950.25, 188075.75, 536950.25, 188007.25, - 536950.25, 188073.25, 536950.25, 187924.25, 536950.25, 187966.75, 536950.25, 188144.25, - 536950.25, 187938.75, 536950.25, 188095.25, 536950.25, 187986.75, 536950.25, 187999.75, - 536950.25, 188048.25, 536950.25, 188056.75, 536950.25, 188111.25, 536950.25, 188153.75, - 536950.25, 188008.75, 536950.25, 188091.75, 536950.25, 187988.75, 536950.25, 188159.25, - 536950.25, 188001.25, 536950.25, 188054.25, 536950.25, 187938.25, 536950.25, 188108.25, - 536950.25, 187985.25, 536950.25, 188095.75, 536950.25, 187941.25, 536950.25, 188117.75, - 536950.25, 188039.75, 536950.25, 188091.25, 536950.25, 187916.25, 536950.25, 188009.25, - 536950.25, 187956.75, 536950.25, 188156.75, 536950.25, 188049.75, 536950.25, 187931.25, - 536950.25, 188140.75, 536950.25, 187963.75, 536950.25, 187923.25, 536950.25, 187990.25, - 536950.25, 187996.25, 536950.25, 188049.25, 536950.25, 188097.25, 536950.25, 188076.25, - 536950.25, 188158.75, 536950.25, 188078.25, 536950.25, 187930.75, 536950.25, 187960.75, - 536950.25, 188002.25, 536950.25, 188104.25, 536950.25, 187978.75, 536950.25, 187931.75, - 536950.25, 188118.75, 536950.25, 187978.25, 536950.25, 188061.25, 536950.25, 187983.25, - 536950.25, 187975.75, 536950.25, 188042.25, 536950.25, 187959.25, 536950.25, 188106.75, - 536950.25, 188077.75, 536950.25, 187965.25, 536950.25, 187984.75, 536950.25, 188102.25, - 536950.25, 187925.25, 536950.25, 188076.75, 536950.25, 188046.75, 536950.25, 188143.75, - 536950.25, 187966.25, 536950.25, 188062.75, 536950.25, 188046.25, 536950.25, 188073.75, - 536950.25, 187941.75, 536950.75, 187955.75, 536950.75, 188075.25, 536950.75, 188058.75, - 536950.75, 187992.75, 536950.75, 188138.25, 536950.75, 188062.25, 536950.75, 188119.75, - 536950.75, 188125.75, 536950.75, 188041.75, 536950.75, 187940.25, 536950.75, 188076.75, - 536950.75, 188135.75, 536950.75, 188139.25, 536950.75, 188146.75, 536950.75, 188042.25, - 536950.75, 188104.75, 536950.75, 188106.75, 536950.75, 187930.75, 536950.75, 188155.75, - 536950.75, 187930.25, 536950.75, 188152.75, 536950.75, 188006.75, 536950.75, 187916.75, - 536950.75, 188118.25, 536950.75, 187929.75, 536950.75, 187981.75, 536950.75, 188145.75, - 536950.75, 187957.75, 536950.75, 187983.25, 536950.75, 187982.75, 536950.75, 187991.75, - 536950.75, 187987.25, 536950.75, 188002.75, 536950.75, 187945.75, 536950.75, 187915.25, - 536950.75, 187914.25, 536950.75, 188072.75, 536950.75, 188049.25, 536950.75, 187984.25, - 536950.75, 187926.25, 536950.75, 187967.75, 536950.75, 188122.25, 536950.75, 187960.25, - 536950.75, 187987.75, 536950.75, 187976.25, 536950.75, 188072.25, 536950.75, 187955.25, - 536950.75, 187931.25, 536950.75, 188063.25, 536950.75, 188146.25, 536950.75, 187967.25, - 536950.75, 188147.75, 536950.75, 188141.75, 536950.75, 187916.25, 536950.75, 187963.75, - 536950.75, 187975.25, 536950.75, 188003.25, 536950.75, 187925.75, 536950.75, 187990.75, - 536950.75, 187922.25, 536950.75, 188000.25, 536950.75, 188137.75, 536950.75, 188047.75, - 536950.75, 187985.25, 536950.75, 188021.25, 536950.75, 187950.75, 536950.75, 187988.25, - 536950.75, 188126.25, 536950.75, 188153.75, 536950.75, 188159.25, 536950.75, 187999.75, - 536950.75, 188007.75, 536950.75, 188071.25, 536950.75, 187979.25, 536950.75, 187961.25, - 536950.75, 188106.25, 536950.75, 187925.25, 536950.75, 187952.75, 536950.75, 188005.75, - 536950.75, 187939.25, 536950.75, 188109.75, 536950.75, 187983.75, 536950.75, 188040.75, - 536950.75, 188007.25, 536950.75, 187937.75, 536950.75, 188064.25, 536950.75, 187929.25, - 536950.75, 188157.25, 536950.75, 187924.75, 536950.75, 188153.25, 536950.75, 188045.75, - 536950.75, 188074.75, 536950.75, 187923.75, 536951.25, 187924.75, 536951.25, 188001.75, - 536951.25, 187960.25, 536951.25, 187930.75, 536951.25, 187925.25, 536951.25, 187999.25, - 536951.25, 188005.75, 536951.25, 187963.75, 536951.25, 188007.75, 536951.25, 188001.25, - 536951.25, 188155.25, 536951.25, 188047.25, 536951.25, 188148.75, 536951.25, 188075.75, - 536951.25, 188117.75, 536951.25, 187925.75, 536951.25, 188126.25, 536951.25, 187990.75, - 536951.25, 187967.25, 536951.25, 188106.25, 536951.25, 187937.25, 536951.25, 187923.25, - 536951.25, 187914.75, 536951.25, 188063.25, 536951.25, 187964.75, 536951.25, 188158.75, - 536951.25, 187983.75, 536951.25, 187946.25, 536951.25, 187984.25, 536951.25, 187915.25, - 536951.25, 187975.75, 536951.25, 187978.75, 536951.25, 187929.25, 536951.25, 188103.25, - 536951.25, 188061.25, 536951.25, 187983.25, 536951.25, 188048.25, 536951.25, 188118.25, - 536951.25, 188141.25, 536951.25, 187926.75, 536951.25, 188155.75, 536951.25, 187993.25, - 536951.25, 188139.25, 536951.25, 187987.25, 536951.25, 188032.75, 536951.25, 188119.25, - 536951.25, 188062.75, 536951.25, 187943.25, 536951.25, 188045.75, 536951.25, 187938.75, - 536951.25, 188075.25, 536951.25, 188138.25, 536951.25, 188096.75, 536951.25, 188156.75, - 536951.25, 188136.25, 536951.25, 187990.25, 536951.25, 188106.75, 536951.25, 188145.25, - 536951.25, 188066.25, 536951.25, 187984.75, 536951.25, 188076.75, 536951.25, 188115.25, - 536951.25, 188145.75, 536951.25, 188105.75, 536951.25, 188031.25, 536951.25, 187953.25, - 536951.25, 188139.75, 536951.25, 188143.25, 536951.25, 188098.75, 536951.25, 188002.75, - 536951.25, 187982.25, 536951.25, 188093.75, 536951.25, 187991.75, 536951.25, 187981.75, - 536951.25, 187994.25, 536951.25, 187982.75, 536951.25, 188072.75, 536951.25, 188137.25, - 536951.25, 188147.75, 536951.25, 187956.75, 536951.25, 188146.25, 536951.25, 188053.25, - 536951.25, 188095.25, 536951.25, 187974.25, 536951.25, 188006.25, 536951.25, 188078.75, - 536951.25, 188000.25, 536951.25, 188042.75, 536951.25, 188033.25, 536951.25, 188150.75, - 536951.25, 188040.75, 536951.25, 188081.25, 536951.25, 188071.25, 536951.25, 188074.25, - 536951.25, 188125.25, 536951.25, 188104.75, 536951.25, 188119.75, 536951.25, 187911.75, - 536951.25, 187955.75, 536951.25, 187961.25, 536951.25, 188007.25, 536951.25, 187953.75, - 536951.25, 188157.75, 536951.25, 188116.25, 536951.25, 188134.75, 536951.25, 188153.25, - 536951.25, 188120.25, 536951.75, 187976.25, 536951.75, 188103.75, 536951.75, 187960.25, - 536951.75, 187939.25, 536951.75, 187963.75, 536951.75, 187932.75, 536951.75, 187971.25, - 536951.75, 188120.25, 536951.75, 188033.25, 536951.75, 188078.75, 536951.75, 187961.25, - 536951.75, 188139.75, 536951.75, 187994.75, 536951.75, 188036.25, 536951.75, 187991.25, - 536951.75, 187981.25, 536951.75, 187913.25, 536951.75, 188002.75, 536951.75, 187916.75, - 536951.75, 187979.75, 536951.75, 188138.25, 536951.75, 188062.75, 536951.75, 188070.25, - 536951.75, 187983.75, 536951.75, 188046.25, 536951.75, 188147.25, 536951.75, 187925.75, - 536951.75, 188080.75, 536951.75, 188134.75, 536951.75, 188148.25, 536951.75, 188069.75, - 536951.75, 188154.75, 536951.75, 188038.75, 536951.75, 187917.25, 536951.75, 187980.25, - 536951.75, 188040.25, 536951.75, 187915.75, 536951.75, 187938.25, 536951.75, 188137.75, - 536951.75, 188101.75, 536951.75, 188159.25, 536951.75, 187975.75, 536951.75, 187976.75, - 536951.75, 188004.25, 536951.75, 187940.75, 536951.75, 188012.25, 536951.75, 187962.75, - 536951.75, 188106.25, 536951.75, 188072.25, 536951.75, 187930.25, 536951.75, 188112.25, - 536951.75, 188158.75, 536951.75, 187924.25, 536951.75, 188054.75, 536951.75, 187972.75, - 536951.75, 188006.75, 536951.75, 188118.25, 536951.75, 187912.25, 536951.75, 187929.25, - 536951.75, 188063.75, 536951.75, 187993.25, 536951.75, 188119.25, 536951.75, 188060.75, - 536951.75, 187989.75, 536951.75, 188106.75, 536951.75, 188128.75, 536951.75, 188046.75, - 536951.75, 188145.25, 536951.75, 188146.25, 536951.75, 187957.75, 536951.75, 188124.25, - 536951.75, 188150.25, 536951.75, 188150.75, 536951.75, 188093.25, 536951.75, 188149.25, - 536951.75, 188079.75, 536951.75, 188154.25, 536951.75, 188135.25, 536951.75, 187955.25, - 536951.75, 187964.25, 536951.75, 187954.75, 536951.75, 187958.75, 536951.75, 188032.75, - 536951.75, 187982.75, 536951.75, 187957.25, 536951.75, 188078.25, 536951.75, 188112.75, - 536951.75, 187987.75, 536951.75, 187917.75, 536951.75, 187988.25, 536951.75, 187927.75, - 536951.75, 188004.75, 536951.75, 188071.25, 536951.75, 188034.75, 536951.75, 187952.25, - 536951.75, 187937.75, 536951.75, 187922.25, 536952.25, 188073.25, 536952.25, 188144.75, - 536952.25, 187939.75, 536952.25, 187961.25, 536952.25, 187987.75, 536952.25, 188092.75, - 536952.25, 187926.25, 536952.25, 187957.25, 536952.25, 188034.75, 536952.25, 188135.25, - 536952.25, 187955.25, 536952.25, 187952.25, 536952.25, 187953.75, 536952.25, 187911.75, - 536952.25, 187926.75, 536952.25, 188150.25, 536952.25, 187910.75, 536952.25, 188153.75, - 536952.25, 188073.75, 536952.25, 188079.25, 536952.25, 187941.25, 536952.25, 188156.25, - 536952.25, 187956.25, 536952.25, 188048.25, 536952.25, 188020.75, 536952.25, 188147.75, - 536952.25, 187938.25, 536952.25, 188032.75, 536952.25, 188033.75, 536952.25, 187940.75, - 536952.25, 188055.75, 536952.25, 188003.75, 536952.25, 187980.75, 536952.25, 188034.25, - 536952.25, 187930.25, 536952.25, 187920.25, 536952.25, 188160.25, 536952.25, 188059.75, - 536952.25, 188091.25, 536952.25, 188049.25, 536952.25, 188038.25, 536952.25, 188062.25, - 536952.25, 188120.25, 536952.25, 187917.75, 536952.25, 188137.25, 536952.25, 188031.25, - 536952.25, 188150.75, 536952.25, 187981.75, 536952.25, 188002.25, 536952.25, 188151.75, - 536952.25, 188118.75, 536952.25, 188146.75, 536952.25, 188032.25, 536952.25, 187982.25, - 536952.25, 187957.75, 536952.25, 188071.75, 536952.25, 187975.25, 536952.25, 187976.25, - 536952.25, 188039.25, 536952.25, 187971.75, 536952.25, 188068.75, 536952.25, 187912.75, - 536952.25, 188113.25, 536952.25, 188005.25, 536952.25, 188041.75, 536952.25, 187988.75, - 536952.25, 187977.25, 536952.25, 187958.75, 536952.25, 188104.75, 536952.25, 188006.25, - 536952.25, 188070.75, 536952.25, 187993.25, 536952.25, 187959.75, 536952.25, 188122.75, - 536952.25, 187929.25, 536952.25, 188060.25, 536952.25, 188044.25, 536952.25, 188080.25, - 536952.25, 188082.75, 536952.25, 188036.25, 536952.25, 188103.25, 536952.25, 187990.25, - 536952.25, 188105.75, 536952.25, 187993.75, 536952.25, 188044.75, 536952.25, 188047.75, - 536952.25, 187924.25, 536952.25, 188107.25, 536952.25, 187913.25, 536952.25, 188085.75, - 536952.25, 188063.25, 536952.25, 187923.25, 536952.25, 188035.25, 536952.25, 187968.75, - 536952.25, 188003.25, 536952.25, 188031.75, 536952.25, 188149.75, 536952.25, 188134.25, - 536952.25, 187929.75, 536952.25, 187950.25, 536952.25, 188061.25, 536952.25, 187958.25, - 536952.25, 187916.25, 536952.25, 187916.75, 536952.25, 188058.25, 536952.25, 187978.75, - 536952.25, 188107.75, 536952.25, 188037.25, 536952.25, 188094.25, 536952.25, 187980.25, - 536952.25, 188005.75, 536952.25, 188053.75, 536952.25, 188133.75, 536952.25, 188069.75, - 536952.25, 188045.25, 536952.25, 188154.75, 536952.25, 187951.25, 536952.25, 188152.25, - 536952.25, 188081.75, 536952.25, 187992.25, 536952.25, 188148.75, 536952.25, 188101.75, - 536952.25, 188137.75, 536952.25, 188064.25, 536952.25, 187989.25, 536952.75, 188040.25, - 536952.75, 188115.75, 536952.75, 187992.25, 536952.75, 188148.75, 536952.75, 188064.25, - 536952.75, 187924.75, 536952.75, 187930.75, 536952.75, 188082.25, 536952.75, 188133.75, - 536952.75, 187997.25, 536952.75, 188107.25, 536952.75, 188147.75, 536952.75, 188091.75, - 536952.75, 188063.25, 536952.75, 188154.75, 536952.75, 188107.75, 536952.75, 188043.25, - 536952.75, 188037.25, 536952.75, 187980.25, 536952.75, 188105.25, 536952.75, 187916.25, - 536952.75, 187950.75, 536952.75, 188061.25, 536952.75, 187929.75, 536952.75, 188134.25, - 536952.75, 188070.25, 536952.75, 188137.75, 536952.75, 188149.75, 536952.75, 188035.25, - 536952.75, 187923.25, 536952.75, 188002.75, 536952.75, 188044.75, 536952.75, 187951.75, - 536952.75, 188060.25, 536952.75, 188047.75, 536952.75, 187924.25, 536952.75, 188104.25, - 536952.75, 187989.75, 536952.75, 187975.75, 536952.75, 187915.25, 536952.75, 187958.25, - 536952.75, 188064.75, 536952.75, 187913.25, 536952.75, 187917.25, 536952.75, 188080.25, - 536952.75, 188152.25, 536952.75, 188070.75, 536952.75, 188078.75, 536952.75, 187921.75, - 536952.75, 188041.75, 536952.75, 188122.75, 536952.75, 188072.75, 536952.75, 188003.25, - 536952.75, 188049.75, 536952.75, 188102.25, 536952.75, 188006.25, 536952.75, 187993.25, - 536952.75, 188036.25, 536952.75, 187939.75, 536952.75, 188137.25, 536952.75, 188068.75, - 536952.75, 188060.75, 536952.75, 188113.25, 536952.75, 188146.75, 536952.75, 188130.75, - 536952.75, 187960.25, 536952.75, 188110.75, 536952.75, 188136.25, 536952.75, 187976.25, - 536952.75, 188002.25, 536952.75, 188061.75, 536952.75, 188115.25, 536952.75, 188071.75, - 536952.75, 187957.75, 536952.75, 188059.25, 536952.75, 188157.75, 536952.75, 187971.25, - 536952.75, 188118.75, 536952.75, 187954.25, 536952.75, 188151.75, 536952.75, 187981.75, - 536952.75, 188031.25, 536952.75, 188138.75, 536952.75, 187912.75, 536952.75, 187952.75, - 536952.75, 188133.25, 536952.75, 188145.25, 536952.75, 188153.25, 536952.75, 188095.25, - 536952.75, 187941.75, 536952.75, 188120.25, 536952.75, 188156.25, 536952.75, 187940.75, - 536952.75, 188033.75, 536952.75, 187988.75, 536952.75, 188032.75, 536952.75, 188034.25, - 536952.75, 188048.25, 536952.75, 188045.75, 536952.75, 188136.75, 536952.75, 188150.25, - 536952.75, 187929.25, 536952.75, 187938.25, 536952.75, 187911.75, 536952.75, 187928.25, - 536952.75, 188004.75, 536952.75, 187994.25, 536952.75, 187926.75, 536952.75, 187955.25, - 536952.75, 187960.75, 536952.75, 188123.25, 536952.75, 188122.25, 536952.75, 187956.25, - 536952.75, 187926.25, 536952.75, 187987.75, 536952.75, 188071.25, 536952.75, 187949.75, - 536953.25, 187948.75, 536953.25, 188134.75, 536953.25, 188119.25, 536953.25, 187938.75, - 536953.25, 187980.75, 536953.25, 187952.25, 536953.25, 188043.75, 536953.25, 188145.75, - 536953.25, 188107.75, 536953.25, 188151.25, 536953.25, 188058.25, 536953.25, 188053.75, - 536953.25, 188049.25, 536953.25, 188046.75, 536953.25, 188052.25, 536953.25, 188059.75, - 536953.25, 187941.25, 536953.25, 187957.75, 536953.25, 188108.25, 536953.25, 188119.75, - 536953.25, 187931.25, 536953.25, 188036.75, 536953.25, 188044.25, 536953.25, 187963.75, - 536953.25, 187930.25, 536953.25, 188000.25, 536953.25, 188031.75, 536953.25, 188093.25, - 536953.25, 188040.75, 536953.25, 187912.25, 536953.25, 187988.25, 536953.25, 187945.75, - 536953.25, 188125.25, 536953.25, 188069.75, 536953.25, 188083.25, 536953.25, 187976.75, - 536953.25, 188063.75, 536953.25, 187958.75, 536953.25, 188091.75, 536953.25, 187950.75, - 536953.25, 188003.25, 536953.25, 187954.25, 536953.25, 188039.25, 536953.25, 187913.25, - 536953.25, 188067.25, 536953.25, 188060.25, 536953.25, 188135.75, 536953.25, 188120.75, - 536953.25, 187990.75, 536953.25, 187977.25, 536953.25, 188046.25, 536953.25, 187955.75, - 536953.25, 188144.75, 536953.25, 188014.25, 536953.25, 188043.25, 536953.25, 187981.25, - 536953.25, 187980.25, 536953.25, 188094.75, 536953.25, 187916.75, 536953.25, 188157.75, - 536953.25, 188090.75, 536953.25, 188105.75, 536953.25, 188152.75, 536953.25, 188030.75, - 536953.25, 187979.75, 536953.25, 187978.75, 536953.25, 188132.25, 536953.25, 188155.25, - 536953.25, 187925.75, 536953.25, 188038.75, 536953.25, 188037.75, 536953.25, 187927.25, - 536953.25, 188122.75, 536953.25, 188073.75, 536953.25, 188104.25, 536953.25, 188067.75, - 536953.25, 188153.75, 536953.25, 187922.75, 536953.25, 188073.25, 536953.25, 188150.75, - 536953.25, 188079.75, 536953.25, 187953.25, 536953.25, 188153.25, 536953.25, 188091.25, - 536953.25, 188154.25, 536953.25, 188146.25, 536953.25, 188157.25, 536953.25, 187923.75, - 536953.25, 187991.25, 536953.25, 188145.25, 536953.25, 188154.75, 536953.25, 188033.25, - 536953.25, 187960.25, 536953.25, 188137.25, 536953.25, 188048.25, 536953.25, 188159.25, - 536953.75, 188001.75, 536953.75, 187969.25, 536953.75, 187949.25, 536953.75, 188094.25, - 536953.75, 187913.75, 536953.75, 187957.25, 536953.75, 188145.25, 536953.75, 188134.75, - 536953.75, 188104.75, 536953.75, 187989.25, 536953.75, 188157.25, 536953.75, 188068.75, - 536953.75, 188117.25, 536953.75, 188152.75, 536953.75, 188038.25, 536953.75, 188042.75, - 536953.75, 188121.25, 536953.75, 188064.75, 536953.75, 187956.25, 536953.75, 187972.75, - 536953.75, 188080.75, 536953.75, 188073.75, 536953.75, 188045.25, 536953.75, 187947.75, - 536953.75, 188159.25, 536953.75, 188054.25, 536953.75, 188153.75, 536953.75, 187998.25, - 536953.75, 188096.25, 536953.75, 188031.25, 536953.75, 188065.25, 536953.75, 187964.75, - 536953.75, 187978.25, 536953.75, 188139.75, 536953.75, 188136.75, 536953.75, 188106.25, - 536953.75, 187961.75, 536953.75, 187989.75, 536953.75, 188081.25, 536953.75, 188069.25, - 536953.75, 187914.25, 536953.75, 188059.25, 536953.75, 187924.25, 536953.75, 187959.75, - 536953.75, 188033.75, 536953.75, 188041.25, 536953.75, 188074.75, 536953.75, 187931.75, - 536953.75, 188093.75, 536953.75, 187937.25, 536953.75, 188106.75, 536953.75, 188058.75, - 536953.75, 188057.75, 536953.75, 187954.25, 536953.75, 187967.75, 536953.75, 188056.75, - 536953.75, 188103.25, 536953.75, 188066.25, 536953.75, 188069.75, 536953.75, 188081.75, - 536953.75, 187968.75, 536953.75, 187923.25, 536953.75, 188020.25, 536953.75, 188155.75, - 536953.75, 188031.75, 536953.75, 187993.25, 536953.75, 188158.25, 536953.75, 187940.25, - 536953.75, 188079.25, 536953.75, 188115.25, 536953.75, 187931.25, 536953.75, 188138.25, - 536953.75, 188092.25, 536953.75, 188119.75, 536953.75, 188108.25, 536953.75, 188032.25, - 536953.75, 188034.75, 536953.75, 187977.75, 536953.75, 187939.25, 536953.75, 187948.75, - 536953.75, 188046.75, 536953.75, 188082.75, 536953.75, 187979.25, 536953.75, 188040.25, - 536953.75, 188136.25, 536953.75, 187980.75, 536953.75, 188151.25, 536953.75, 187966.75, - 536953.75, 188043.75, 536953.75, 187914.75, 536953.75, 188145.75, 536953.75, 188095.25, - 536953.75, 187930.75, 536953.75, 188068.25, 536954.25, 188095.25, 536954.25, 188105.25, - 536954.25, 187930.75, 536954.25, 187998.75, 536954.25, 188065.25, 536954.25, 188146.75, - 536954.25, 187979.75, 536954.25, 188154.75, 536954.25, 188096.25, 536954.25, 188065.75, - 536954.25, 187995.25, 536954.25, 187947.75, 536954.25, 188035.75, 536954.25, 188001.25, - 536954.25, 187947.25, 536954.25, 187914.75, 536954.25, 188080.75, 536954.25, 188073.75, - 536954.25, 188016.75, 536954.25, 187948.25, 536954.25, 187972.75, 536954.25, 188133.75, - 536954.25, 188029.75, 536954.25, 188042.75, 536954.25, 187948.75, 536954.25, 187912.75, - 536954.25, 188058.75, 536954.25, 188159.75, 536954.25, 188043.75, 536954.25, 188136.25, - 536954.25, 188057.75, 536954.25, 187949.25, 536954.25, 188107.75, 536954.25, 188133.25, - 536954.25, 188072.75, 536954.25, 187936.75, 536954.25, 187940.25, 536954.25, 188115.75, - 536954.25, 187975.75, 536954.25, 187939.25, 536954.25, 188154.25, 536954.25, 188046.75, - 536954.25, 188033.25, 536954.25, 188080.25, 536954.25, 188045.75, 536954.25, 187977.75, - 536954.25, 188034.75, 536954.25, 187957.25, 536954.25, 188066.25, 536954.25, 187939.75, - 536954.25, 188131.25, 536954.25, 187976.75, 536954.25, 187930.25, 536954.25, 188031.75, - 536954.25, 188068.75, 536954.25, 187995.75, 536954.25, 187931.25, 536954.25, 188092.25, - 536954.25, 187979.25, 536954.25, 188135.25, 536954.25, 187937.75, 536954.25, 188146.25, - 536954.25, 188079.25, 536954.25, 187953.25, 536954.25, 188079.75, 536954.25, 187968.25, - 536954.25, 188038.75, 536954.25, 187993.25, 536954.25, 188032.25, 536954.25, 188158.25, - 536954.25, 188155.75, 536954.25, 188064.25, 536954.25, 188019.25, 536954.25, 188051.75, - 536954.25, 188030.75, 536954.25, 188041.75, 536954.25, 188115.25, 536954.25, 187988.75, - 536954.25, 188106.25, 536954.25, 188120.25, 536954.25, 188097.25, 536954.25, 188062.75, - 536954.25, 187978.25, 536954.25, 187968.75, 536954.25, 187988.25, 536954.25, 188069.75, - 536954.25, 188082.75, 536954.25, 187955.25, 536954.25, 187924.25, 536954.25, 188056.75, - 536954.25, 188138.25, 536954.25, 188103.25, 536954.25, 188036.75, 536954.25, 187926.25, - 536954.25, 188144.75, 536954.25, 188112.75, 536954.25, 188069.25, 536954.25, 187961.75, - 536954.25, 187938.25, 536954.25, 188120.75, 536954.25, 187913.25, 536954.25, 187969.75, - 536954.25, 187959.75, 536954.25, 188156.75, 536954.25, 188093.75, 536954.25, 188039.25, - 536954.25, 188103.75, 536954.25, 188049.25, 536954.25, 188041.25, 536954.75, 188081.25, - 536954.75, 187989.75, 536954.75, 188142.25, 536954.75, 187994.75, 536954.75, 187978.25, - 536954.75, 188108.75, 536954.75, 188094.75, 536954.75, 188033.75, 536954.75, 187996.25, - 536954.75, 188077.75, 536954.75, 188160.25, 536954.75, 187913.25, 536954.75, 188142.75, - 536954.75, 188157.75, 536954.75, 187938.25, 536954.75, 188031.25, 536954.75, 188120.75, - 536954.75, 187938.75, 536954.75, 188022.75, 536954.75, 188156.25, 536954.75, 188134.75, - 536954.75, 188065.75, 536954.75, 187977.25, 536954.75, 188069.25, 536954.75, 188145.75, - 536954.75, 187914.75, 536954.75, 188083.75, 536954.75, 188021.25, 536954.75, 188039.75, - 536954.75, 188107.25, 536954.75, 188067.25, 536954.75, 188064.75, 536954.75, 187910.75, - 536954.75, 187955.25, 536954.75, 187935.25, 536954.75, 187948.75, 536954.75, 188042.75, - 536954.75, 187991.75, 536954.75, 188131.25, 536954.75, 188120.25, 536954.75, 187977.75, - 536954.75, 187923.75, 536954.75, 188082.25, 536954.75, 187975.75, 536954.75, 188130.25, - 536954.75, 188064.25, 536954.75, 188040.75, 536954.75, 188155.25, 536954.75, 187946.75, - 536954.75, 188032.25, 536954.75, 188091.25, 536954.75, 188145.25, 536954.75, 188057.25, - 536954.75, 187969.25, 536954.75, 188104.25, 536954.75, 188068.25, 536954.75, 188038.75, - 536954.75, 188154.25, 536954.75, 188121.25, 536954.75, 187936.75, 536954.75, 187930.75, - 536954.75, 188033.25, 536954.75, 187973.75, 536954.75, 188140.25, 536954.75, 188090.25, - 536954.75, 187931.25, 536954.75, 188080.25, 536954.75, 188132.75, 536954.75, 188119.75, - 536954.75, 187937.75, 536954.75, 187995.75, 536954.75, 188135.25, 536954.75, 187999.75, - 536954.75, 187957.25, 536954.75, 187976.75, 536954.75, 187953.75, 536954.75, 187989.25, - 536954.75, 187953.25, 536954.75, 188121.75, 536955.25, 188121.75, 536955.25, 187956.75, - 536955.25, 187970.25, 536955.25, 187992.25, 536955.25, 188066.25, 536955.25, 187959.25, - 536955.25, 188007.75, 536955.25, 188094.25, 536955.25, 188034.25, 536955.25, 188066.75, - 536955.25, 187913.75, 536955.25, 188119.75, 536955.25, 188105.25, 536955.25, 187923.25, - 536955.25, 187960.75, 536955.25, 188058.25, 536955.25, 188079.75, 536955.25, 187990.25, - 536955.25, 187930.75, 536955.25, 187973.75, 536955.25, 188020.75, 536955.25, 188092.75, - 536955.25, 188035.25, 536955.25, 188140.25, 536955.25, 188048.25, 536955.25, 188102.75, - 536955.25, 188104.25, 536955.25, 187915.25, 536955.25, 187946.25, 536955.25, 187919.25, - 536955.25, 187952.25, 536955.25, 188077.25, 536955.25, 187997.75, 536955.25, 187935.25, - 536955.25, 188067.25, 536955.25, 188057.25, 536955.25, 188132.25, 536955.25, 187975.75, - 536955.25, 188130.75, 536955.25, 188152.75, 536955.25, 188155.25, 536955.25, 188120.25, - 536955.25, 188042.75, 536955.25, 187980.25, 536955.25, 187976.25, 536955.25, 187945.75, - 536955.25, 188029.75, 536955.25, 188038.25, 536955.25, 188106.75, 536955.25, 187932.25, - 536955.25, 188109.25, 536955.25, 188124.75, 536955.25, 187951.75, 536955.25, 188140.75, - 536955.25, 187947.25, 536955.25, 187918.75, 536955.25, 187996.75, 536955.25, 187974.25, - 536955.25, 188144.25, 536955.25, 188028.75, 536955.25, 188067.75, 536955.25, 188044.25, - 536955.25, 187924.75, 536955.25, 188030.25, 536955.25, 188145.75, 536955.25, 188116.75, - 536955.25, 188069.25, 536955.25, 187925.75, 536955.25, 187995.25, 536955.25, 188159.25, - 536955.25, 188032.75, 536955.25, 187947.75, 536955.25, 188129.75, 536955.25, 188133.75, - 536955.25, 188148.75, 536955.25, 187954.25, 536955.25, 187914.25, 536955.25, 188154.25, - 536955.25, 188156.25, 536955.25, 188074.75, 536955.25, 188023.25, 536955.25, 187990.75, - 536955.25, 188074.25, 536955.25, 188075.75, 536955.25, 188157.75, 536955.25, 188142.75, - 536955.25, 187938.25, 536955.25, 188036.25, 536955.25, 187928.75, 536955.25, 188076.25, - 536955.25, 188022.25, 536955.25, 187993.75, 536955.25, 187938.75, 536955.25, 188141.75, - 536955.25, 188065.25, 536955.25, 188078.25, 536955.25, 187965.75, 536955.25, 188039.25, - 536955.25, 188142.25, 536955.25, 187941.25, 536955.25, 187998.75, 536955.25, 187931.75, - 536955.25, 188108.25, 536955.25, 187925.25, 536955.75, 188142.25, 536955.75, 188074.75, - 536955.75, 188141.75, 536955.75, 188044.75, 536955.75, 188081.25, 536955.75, 188106.25, - 536955.75, 187998.75, 536955.75, 187989.75, 536955.75, 188032.75, 536955.75, 187993.75, - 536955.75, 188123.25, 536955.75, 188051.25, 536955.75, 188065.75, 536955.75, 188065.25, - 536955.75, 188154.25, 536955.75, 188142.75, 536955.75, 188074.25, 536955.75, 187914.25, - 536955.75, 188096.25, 536955.75, 188036.25, 536955.75, 187952.75, 536955.75, 187925.75, - 536955.75, 187924.75, 536955.75, 188080.75, 536955.75, 188038.25, 536955.75, 188106.75, - 536955.75, 187972.75, 536955.75, 187932.25, 536955.75, 187949.25, 536955.75, 188042.75, - 536955.75, 188058.75, 536955.75, 187975.75, 536955.75, 188077.25, 536955.75, 188067.25, - 536955.75, 188057.75, 536955.75, 187973.25, 536955.75, 188033.25, 536955.75, 187986.25, - 536955.75, 187932.75, 536955.75, 187938.75, 536955.75, 188080.25, 536955.75, 188094.25, - 536955.75, 188066.75, 536955.75, 188066.25, 536955.75, 188132.75, 536955.75, 187953.25, - 536955.75, 188048.75, 536955.75, 187989.25, 536955.75, 187960.25, 536955.75, 188031.75, - 536955.75, 188068.75, 536955.75, 187965.25, 536955.75, 187913.75, 536955.75, 188035.25, - 536955.75, 188050.75, 536955.75, 188057.25, 536955.75, 188090.75, 536955.75, 188041.75, - 536955.75, 187961.25, 536955.75, 188155.25, 536955.75, 187955.25, 536955.75, 187935.75, - 536955.75, 187934.25, 536955.75, 188139.75, 536955.75, 188144.25, 536955.75, 187996.75, - 536955.75, 187926.25, 536955.75, 188118.25, 536955.75, 188023.25, 536955.75, 188120.75, - 536955.75, 187969.75, 536955.75, 187976.25, 536955.75, 187957.75, 536955.75, 188039.25, - 536955.75, 187931.75, 536955.75, 187911.75, 536955.75, 188022.25, 536955.75, 188103.25, - 536955.75, 188115.25, 536955.75, 188069.75, 536955.75, 188082.75, 536955.75, 187924.25, - 536955.75, 188130.25, 536955.75, 187953.75, 536955.75, 187931.25, 536955.75, 187979.25, - 536955.75, 187937.75, 536955.75, 188003.75, 536955.75, 188047.25, 536955.75, 187956.75, - 536955.75, 188032.25, 536955.75, 187952.25, 536955.75, 188019.25, 536955.75, 188092.75, - 536955.75, 188119.75, 536955.75, 188043.75, 536955.75, 188107.75, 536955.75, 188034.75, - 536955.75, 188078.25, 536955.75, 188130.75, 536955.75, 188029.75, 536955.75, 187958.25, - 536955.75, 188075.75, 536955.75, 188134.75, 536955.75, 188095.25, 536955.75, 188145.75, - 536955.75, 187914.75, 536955.75, 188019.75, 536955.75, 187995.25, 536955.75, 188028.25, - 536956.25, 187938.25, 536956.25, 188148.25, 536956.25, 188028.25, 536956.25, 188144.75, - 536956.25, 187931.75, 536956.25, 188021.25, 536956.25, 188035.75, 536956.25, 187946.25, - 536956.25, 187917.75, 536956.25, 188030.75, 536956.25, 188128.75, 536956.25, 188041.75, - 536956.25, 187919.25, 536956.25, 188143.75, 536956.25, 188117.25, 536956.25, 188121.25, - 536956.25, 187956.25, 536956.25, 188037.75, 536956.25, 188079.75, 536956.25, 187996.25, - 536956.25, 188129.75, 536956.25, 187991.25, 536956.25, 188107.25, 536956.25, 188103.25, - 536956.25, 188029.25, 536956.25, 187944.25, 536956.25, 188104.75, 536956.25, 187970.25, - 536956.25, 187957.75, 536956.25, 188133.25, 536956.25, 188120.25, 536956.25, 188145.25, - 536956.25, 188109.75, 536956.25, 188056.75, 536956.25, 187954.25, 536956.25, 187924.75, - 536956.25, 188079.25, 536956.25, 188034.25, 536956.25, 187925.25, 536956.25, 187955.25, - 536956.25, 187972.75, 536956.25, 188038.75, 536956.25, 187975.25, 536956.25, 187961.25, - 536956.25, 188122.25, 536956.25, 187926.75, 536956.25, 188154.25, 536956.25, 187962.75, - 536956.25, 187974.75, 536956.25, 188066.75, 536956.25, 188019.25, 536956.25, 187939.25, - 536956.25, 187992.25, 536956.25, 188053.75, 536956.25, 188040.25, 536956.25, 188020.75, - 536956.25, 187992.75, 536956.25, 187951.75, 536956.25, 188123.25, 536956.25, 187973.75, - 536956.25, 188054.25, 536956.25, 188037.25, 536956.25, 187934.25, 536956.25, 188032.75, - 536956.25, 188112.25, 536956.25, 187918.75, 536956.25, 187945.25, 536956.25, 187958.25, - 536956.25, 188132.25, 536956.25, 187914.75, 536956.25, 187932.75, 536956.25, 187967.75, - 536956.25, 188108.75, 536956.25, 187990.75, 536956.25, 187914.25, 536956.25, 188039.75, - 536956.25, 188131.25, 536956.25, 188075.25, 536956.25, 188154.75, 536956.25, 188077.75, - 536956.25, 188058.75, 536956.25, 187995.25, 536956.75, 188067.75, 536956.75, 188021.25, - 536956.75, 188022.75, 536956.75, 188120.75, 536956.75, 188154.75, 536956.75, 187943.25, - 536956.75, 187914.75, 536956.75, 187914.25, 536956.75, 187963.75, 536956.75, 188110.75, - 536956.75, 187990.75, 536956.75, 187948.75, 536956.75, 187920.25, 536956.75, 188078.25, - 536956.75, 187965.75, 536956.75, 188039.25, 536956.75, 188046.25, 536956.75, 188027.25, - 536956.75, 188124.25, 536956.75, 188041.25, 536956.75, 187950.75, 536956.75, 188016.25, - 536956.75, 188034.75, 536956.75, 188032.75, 536956.75, 188028.75, 536956.75, 188049.75, - 536956.75, 188151.75, 536956.75, 188054.25, 536956.75, 188058.25, 536956.75, 188025.75, - 536956.75, 187949.25, 536956.75, 188017.75, 536956.75, 187919.25, 536956.75, 187990.25, - 536956.75, 187940.25, 536956.75, 188123.25, 536956.75, 188149.25, 536956.75, 188076.25, - 536956.75, 188143.75, 536956.75, 187947.25, 536956.75, 187974.75, 536956.75, 187939.75, - 536956.75, 188074.75, 536956.75, 187987.25, 536956.75, 188150.75, 536956.75, 188130.75, - 536956.75, 188142.25, 536956.75, 188123.75, 536956.75, 187959.75, 536956.75, 188122.75, - 536956.75, 188037.75, 536956.75, 188078.75, 536956.75, 188119.75, 536956.75, 187972.25, - 536956.75, 187997.25, 536956.75, 187933.25, 536956.75, 187952.25, 536956.75, 188104.75, - 536956.75, 187966.25, 536956.75, 188112.75, 536956.75, 188111.75, 536956.75, 187993.75, - 536956.75, 187962.75, 536956.75, 188030.25, 536956.75, 188139.25, 536956.75, 187944.25, - 536956.75, 188108.25, 536956.75, 187933.75, 536956.75, 188121.75, 536956.75, 187945.75, - 536956.75, 188109.25, 536956.75, 188153.75, 536956.75, 188049.25, 536956.75, 188080.25, - 536956.75, 188011.75, 536956.75, 188000.25, 536956.75, 188105.25, 536956.75, 188077.25, - 536956.75, 187955.25, 536956.75, 187925.25, 536956.75, 187932.25, 536956.75, 188034.25, - 536956.75, 187991.75, 536956.75, 188036.25, 536956.75, 188059.25, 536956.75, 188130.25, - 536956.75, 187973.25, 536956.75, 188145.25, 536956.75, 187938.25, 536956.75, 187965.25, - 536956.75, 187972.75, 536956.75, 187939.25, 536956.75, 187944.75, 536956.75, 188036.75, - 536956.75, 187954.75, 536956.75, 187971.25, 536957.25, 188109.75, 536957.25, 187971.25, - 536957.25, 187954.75, 536957.25, 187985.25, 536957.25, 187965.25, 536957.25, 187910.75, - 536957.25, 187972.75, 536957.25, 188145.75, 536957.25, 187936.75, 536957.25, 188033.25, - 536957.25, 188153.75, 536957.25, 187946.75, 536957.25, 188068.25, 536957.25, 187984.25, - 536957.25, 188120.25, 536957.25, 187942.75, 536957.25, 187925.25, 536957.25, 188059.25, - 536957.25, 187973.25, 536957.25, 188038.75, 536957.25, 187994.75, 536957.25, 188028.75, - 536957.25, 187949.75, 536957.25, 188074.25, 536957.25, 188105.25, 536957.25, 188116.25, - 536957.25, 188122.25, 536957.25, 188080.25, 536957.25, 188017.25, 536957.25, 187945.75, - 536957.25, 188109.25, 536957.25, 188011.75, 536957.25, 188077.25, 536957.25, 188030.25, - 536957.25, 188036.75, 536957.25, 188035.25, 536957.25, 188108.25, 536957.25, 187972.25, - 536957.25, 188139.25, 536957.25, 187991.25, 536957.25, 187944.25, 536957.25, 188103.25, - 536957.25, 188154.75, 536957.25, 188019.25, 536957.25, 187914.75, 536957.25, 188104.75, - 536957.25, 188067.75, 536957.25, 188143.75, 536957.25, 187996.25, 536957.25, 187933.25, - 536957.25, 187993.75, 536957.25, 187966.25, 536957.25, 188101.75, 536957.25, 188002.25, - 536957.25, 187997.25, 536957.25, 188078.75, 536957.25, 187913.75, 536957.25, 188156.25, - 536957.25, 187922.25, 536957.25, 188123.75, 536957.25, 188040.25, 536957.25, 188020.75, - 536957.25, 188121.25, 536957.25, 188107.75, 536957.25, 187927.25, 536957.25, 187990.25, - 536957.25, 187912.75, 536957.25, 188024.75, 536957.25, 187919.25, 536957.25, 188126.25, - 536957.25, 187962.25, 536957.25, 188149.25, 536957.25, 188128.75, 536957.25, 188043.25, - 536957.25, 188160.25, 536957.25, 187916.25, 536957.25, 187946.25, 536957.25, 188058.25, - 536957.25, 187940.25, 536957.25, 188139.75, 536957.25, 187931.75, 536957.25, 187926.25, - 536957.25, 188041.25, 536957.25, 187950.75, 536957.25, 188037.25, 536957.25, 188039.25, - 536957.25, 187934.25, 536957.25, 188044.75, 536957.25, 188021.75, 536957.25, 188144.75, - 536957.25, 187990.75, 536957.25, 188124.25, 536957.25, 188028.25, 536957.25, 187938.75, - 536957.25, 188038.25, 536957.25, 188075.25, 536957.25, 187955.25, 536957.25, 188073.25, - 536957.25, 188129.25, 536957.75, 188129.25, 536957.75, 188047.75, 536957.75, 188060.25, - 536957.75, 188156.25, 536957.75, 187939.75, 536957.75, 187947.25, 536957.75, 188027.75, - 536957.75, 188053.25, 536957.75, 187948.25, 536957.75, 187969.75, 536957.75, 187957.75, - 536957.75, 188049.75, 536957.75, 188031.75, 536957.75, 188128.75, 536957.75, 188049.25, - 536957.75, 188154.75, 536957.75, 188121.25, 536957.75, 188113.75, 536957.75, 188037.75, - 536957.75, 188104.75, 536957.75, 187996.25, 536957.75, 188138.75, 536957.75, 188066.25, - 536957.75, 187944.25, 536957.75, 187958.75, 536957.75, 188123.75, 536957.75, 188024.75, - 536957.75, 187914.25, 536957.75, 188143.75, 536957.75, 187920.75, 536957.75, 188144.25, - 536957.75, 187932.75, 536957.75, 187940.25, 536957.75, 187920.25, 536957.75, 187991.75, - 536957.75, 188039.75, 536957.75, 187971.75, 536957.75, 187970.25, 536957.75, 188131.25, - 536957.75, 187945.25, 536957.75, 188058.75, 536957.75, 187993.25, 536957.75, 187955.25, - 536957.75, 187990.75, 536957.75, 188065.75, 536957.75, 188037.25, 536957.75, 188072.75, - 536957.75, 188114.25, 536957.75, 188055.75, 536957.75, 187918.75, 536957.75, 187953.25, - 536957.75, 188106.25, 536957.75, 188076.25, 536957.75, 187954.25, 536957.75, 187954.75, - 536957.75, 187970.75, 536957.75, 188109.75, 536957.75, 187927.25, 536957.75, 187928.75, - 536957.75, 187967.25, 536957.75, 187994.25, 536957.75, 187912.75, 536957.75, 188079.25, - 536957.75, 187973.25, 536957.75, 188034.25, 536957.75, 187932.25, 536957.75, 188026.75, - 536957.75, 188031.25, 536957.75, 188130.75, 536957.75, 187925.75, 536957.75, 188122.75, - 536957.75, 188109.25, 536957.75, 188154.25, 536957.75, 187983.25, 536957.75, 187914.75, - 536957.75, 188074.75, 536957.75, 188035.25, 536957.75, 187950.25, 536957.75, 187930.75, - 536957.75, 188137.75, 536958.25, 187930.75, 536958.25, 188137.75, 536958.25, 187940.75, - 536958.25, 187995.75, 536958.25, 187993.75, 536958.25, 187960.25, 536958.25, 188054.75, - 536958.25, 187919.75, 536958.25, 188122.25, 536958.25, 188028.75, 536958.25, 188153.25, - 536958.25, 187913.25, 536958.25, 188023.75, 536958.25, 188036.25, 536958.25, 187928.75, - 536958.25, 188025.25, 536958.25, 187967.25, 536958.25, 187944.75, 536958.25, 188033.25, - 536958.25, 188140.25, 536958.25, 187969.25, 536958.25, 187927.25, 536958.25, 187930.25, - 536958.25, 188050.25, 536958.25, 188076.25, 536958.25, 188157.75, 536958.25, 188140.75, - 536958.25, 188048.75, 536958.25, 188112.25, 536958.25, 188032.75, 536958.25, 188135.25, - 536958.25, 188040.75, 536958.25, 188127.75, 536958.25, 187963.25, 536958.25, 188059.25, - 536958.25, 188042.25, 536958.25, 187968.25, 536958.25, 188130.25, 536958.25, 188114.25, - 536958.25, 188106.75, 536958.25, 188072.25, 536958.25, 187970.25, 536958.25, 188111.25, - 536958.25, 188027.25, 536958.25, 188113.25, 536958.25, 188076.75, 536958.25, 187948.75, - 536958.25, 187971.75, 536958.25, 188143.25, 536958.25, 188070.25, 536958.25, 187940.25, - 536958.25, 188121.75, 536958.25, 188143.75, 536958.25, 188078.25, 536958.25, 187932.75, - 536958.25, 187967.75, 536958.25, 187947.75, 536958.25, 188034.75, 536958.25, 187991.25, - 536958.25, 187911.25, 536958.25, 188110.25, 536958.25, 188024.75, 536958.25, 187951.25, - 536958.25, 187992.25, 536958.25, 188068.75, 536958.25, 188129.75, 536958.25, 187959.25, - 536958.25, 187931.25, 536958.25, 188104.25, 536958.25, 187951.75, 536958.25, 187912.25, - 536958.25, 188049.75, 536958.25, 188118.25, 536958.25, 188020.25, 536958.25, 187994.75, - 536958.25, 188025.75, 536958.25, 188156.75, 536958.25, 187943.75, 536958.25, 187969.75, - 536958.25, 187926.25, 536958.25, 187939.25, 536958.25, 187976.25, 536958.25, 187949.25, - 536958.25, 188115.25, 536958.25, 187942.25, 536958.25, 188029.25, 536958.25, 188155.75, - 536958.25, 188035.75, 536958.25, 188110.75, 536958.25, 188046.25, 536958.25, 188026.25, - 536958.25, 188144.75, 536958.25, 188032.25, 536958.25, 187927.75, 536958.25, 188156.25, - 536958.25, 188058.25, 536958.25, 188134.75, 536958.25, 188071.75, 536958.25, 188060.25, - 536958.25, 188073.75, 536958.25, 188105.75, 536958.75, 187913.25, 536958.75, 188071.75, - 536958.75, 187920.75, 536958.75, 187943.75, 536958.75, 188060.25, 536958.75, 187959.75, - 536958.75, 188026.25, 536958.75, 188134.75, 536958.75, 187939.25, 536958.75, 187952.25, - 536958.75, 187968.75, 536958.75, 187994.75, 536958.75, 188058.25, 536958.75, 188115.25, - 536958.75, 188022.25, 536958.75, 187942.25, 536958.75, 187931.25, 536958.75, 187992.25, - 536958.75, 187925.25, 536958.75, 187969.75, 536958.75, 188078.25, 536958.75, 187940.25, - 536958.75, 188027.25, 536958.75, 188138.25, 536958.75, 188144.25, 536958.75, 187995.25, - 536958.75, 188154.75, 536958.75, 188049.25, 536958.75, 188058.75, 536958.75, 188050.25, - 536958.75, 188140.75, 536958.75, 188075.25, 536958.75, 188032.75, 536958.75, 187970.75, - 536958.75, 188157.75, 536958.75, 188048.75, 536958.75, 188040.25, 536958.75, 188153.25, - 536958.75, 188130.75, 536958.75, 187914.75, 536958.75, 188123.25, 536958.75, 188147.25, - 536958.75, 187912.75, 536958.75, 187995.75, 536958.75, 187993.75, 536958.75, 187940.75, - 536958.75, 187919.75, 536958.75, 188137.75, 536958.75, 187949.75, 536958.75, 187960.25, - 536958.75, 187926.75, 536958.75, 187930.75, 536958.75, 187954.25, 536958.75, 187962.75, - 536958.75, 187981.25, 536958.75, 188072.75, 536958.75, 188113.25, 536958.75, 187994.25, - 536958.75, 187928.25, 536958.75, 188109.25, 536958.75, 188054.75, 536958.75, 187943.25, - 536958.75, 187946.75, 536958.75, 188130.25, 536958.75, 188111.25, 536958.75, 188122.25, - 536958.75, 188143.75, 536958.75, 188074.25, 536958.75, 187991.75, 536958.75, 188030.25, - 536958.75, 187911.25, 536958.75, 187996.25, 536958.75, 188069.75, 536958.75, 188023.75, - 536958.75, 187911.75, 536958.75, 187968.25, 536958.75, 188156.75, 536958.75, 188025.25, - 536958.75, 188028.25, 536958.75, 188038.25, 536958.75, 188036.25, 536958.75, 188073.25, - 536958.75, 187947.75, 536958.75, 188129.25, 536958.75, 187969.25, 536958.75, 188035.75, - 536958.75, 188114.25, 536958.75, 188144.75, 536958.75, 188105.25, 536958.75, 188110.75, - 536958.75, 187951.25, 536958.75, 188076.75, 536958.75, 188143.25, 536958.75, 188121.75, - 536958.75, 187991.25, 536958.75, 188128.25, 536958.75, 188049.75, 536958.75, 187966.25, - 536958.75, 187997.25, 536958.75, 188104.75, 536958.75, 188110.25, 536958.75, 187959.25, - 536959.25, 187944.25, 536959.25, 188049.75, 536959.25, 188079.75, 536959.25, 188128.75, - 536959.25, 187991.25, 536959.25, 188159.25, 536959.25, 188041.75, 536959.25, 187926.25, - 536959.25, 188139.75, 536959.25, 188069.25, 536959.25, 188073.75, 536959.25, 187970.25, - 536959.25, 187917.25, 536959.25, 188129.25, 536959.25, 188033.75, 536959.25, 187947.75, - 536959.25, 187954.75, 536959.25, 188033.25, 536959.25, 188073.25, 536959.25, 188041.25, - 536959.25, 187911.75, 536959.25, 187964.25, 536959.25, 187932.25, 536959.25, 188026.75, - 536959.25, 187931.75, 536959.25, 187945.75, 536959.25, 188122.25, 536959.25, 188143.75, - 536959.25, 188135.25, 536959.25, 188127.25, 536959.25, 188029.25, 536959.25, 187919.75, - 536959.25, 187913.75, 536959.25, 187926.75, 536959.25, 188074.75, 536959.25, 187950.25, - 536959.25, 188079.25, 536959.25, 187940.75, 536959.25, 188067.75, 536959.25, 188141.25, - 536959.25, 188111.75, 536959.25, 187929.25, 536959.25, 188031.25, 536959.25, 188142.75, - 536959.25, 188154.25, 536959.25, 187995.75, 536959.25, 187928.75, 536959.25, 187992.75, - 536959.25, 188123.25, 536959.25, 187914.75, 536959.25, 187929.75, 536959.25, 188106.25, - 536959.25, 188115.75, 536959.25, 188126.25, 536959.25, 188043.25, 536959.25, 188076.25, - 536959.25, 187970.75, 536959.25, 187967.25, 536959.25, 188157.75, 536959.25, 187955.75, - 536959.25, 187977.75, 536959.25, 188032.75, 536959.25, 188044.75, 536959.25, 188114.75, - 536959.25, 187946.25, 536959.25, 187990.75, 536959.25, 188112.25, 536959.25, 188159.75, - 536959.25, 187958.25, 536959.25, 188067.25, 536959.25, 188057.75, 536959.25, 188049.25, - 536959.25, 188144.25, 536959.25, 187932.75, 536959.25, 187950.75, 536959.25, 188070.75, - 536959.25, 187967.75, 536959.25, 188131.25, 536959.25, 188034.75, 536959.25, 188071.25, - 536959.25, 188132.25, 536959.25, 187994.75, 536959.25, 188108.25, 536959.25, 187951.75, - 536959.25, 187947.25, 536959.25, 188036.75, 536959.25, 188112.75, 536959.25, 188155.75, - 536959.25, 187968.75, 536959.25, 188149.75, 536959.25, 187939.75, 536959.25, 188107.75, - 536959.25, 188032.25, 536959.25, 188153.75, 536959.25, 188156.25, 536959.25, 188145.75, - 536959.75, 187966.75, 536959.75, 188099.25, 536959.75, 187926.25, 536959.75, 188033.25, - 536959.75, 187944.25, 536959.75, 188074.25, 536959.75, 188093.25, 536959.75, 188141.75, - 536959.75, 188025.75, 536959.75, 188066.75, 536959.75, 188110.25, 536959.75, 188020.75, - 536959.75, 188135.25, 536959.75, 187978.25, 536959.75, 188152.75, 536959.75, 187967.75, - 536959.75, 187917.75, 536959.75, 188032.75, 536959.75, 188104.75, 536959.75, 188157.25, - 536959.75, 188135.75, 536959.75, 187992.25, 536959.75, 187951.25, 536959.75, 188003.75, - 536959.75, 187949.25, 536959.75, 187939.75, 536959.75, 188068.25, 536959.75, 187964.75, - 536959.75, 188122.25, 536959.75, 187969.75, 536959.75, 188074.75, 536959.75, 188058.25, - 536959.75, 187930.75, 536959.75, 188027.75, 536959.75, 188059.25, 536959.75, 188030.75, - 536959.75, 188110.75, 536959.75, 187991.75, 536959.75, 187942.75, 536959.75, 187929.25, - 536959.75, 187927.25, 536959.75, 188059.75, 536959.75, 188042.25, 536959.75, 187970.25, - 536959.75, 188111.75, 536959.75, 187933.25, 536959.75, 188153.25, 536959.75, 188014.75, - 536959.75, 188108.25, 536959.75, 188141.25, 536959.75, 188144.25, 536959.75, 187932.25, - 536959.75, 187965.25, 536959.75, 188065.25, 536959.75, 188057.75, 536959.75, 187928.25, - 536959.75, 187914.25, 536959.75, 188155.25, 536959.75, 188159.75, 536959.75, 187966.25, - 536959.75, 188112.75, 536959.75, 188028.75, 536959.75, 188072.25, 536959.75, 187916.25, - 536959.75, 188123.75, 536959.75, 188033.75, 536959.75, 187915.25, 536959.75, 187956.75, - 536959.75, 187990.75, 536959.75, 187920.75, 536959.75, 187968.25, 536959.75, 187948.25, - 536959.75, 188068.75, 536959.75, 188118.75, 536959.75, 188156.25, 536959.75, 188057.25, - 536959.75, 188060.75, 536959.75, 188031.25, 536959.75, 188083.75, 536959.75, 187990.25, - 536959.75, 188022.25, 536959.75, 188005.25, 536959.75, 188160.25, 536959.75, 188061.25, - 536959.75, 188018.75, 536959.75, 188140.25, 536959.75, 188061.75, 536959.75, 187952.25, - 536959.75, 188079.25, 536959.75, 188115.25, 536959.75, 188098.25, 536959.75, 188071.25, - 536959.75, 187956.25, 536959.75, 188035.25, 536959.75, 188077.25, 536959.75, 188041.25, - 536959.75, 188030.25, 536959.75, 188053.25, 536959.75, 188080.25, 536959.75, 188142.75, - 536959.75, 188115.75, 536959.75, 188070.75, 536959.75, 188106.75, 536959.75, 187944.75, - 536959.75, 188031.75, 536959.75, 187961.25, 536959.75, 188024.25, 536959.75, 187970.75, - 536959.75, 187952.75, 536959.75, 188106.25, 536959.75, 187948.75, 536959.75, 188022.75, - 536959.75, 188150.25, 536959.75, 188125.25, 536959.75, 187941.25, 536959.75, 188139.25, - 536959.75, 188069.75, 536959.75, 187963.75, 536959.75, 187910.75, 536959.75, 188056.25, - 536959.75, 187989.25, 536959.75, 188158.25, 536960.25, 188056.25, 536960.25, 188158.25, - 536960.25, 187940.75, 536960.25, 188074.25, 536960.25, 188139.25, 536960.25, 188143.75, - 536960.25, 188070.25, 536960.25, 188152.75, 536960.25, 187944.25, 536960.25, 187989.25, - 536960.25, 188110.25, 536960.25, 187941.25, 536960.25, 188066.75, 536960.25, 187926.75, - 536960.25, 188022.75, 536960.25, 188020.75, 536960.25, 188126.75, 536960.25, 187921.75, - 536960.25, 187917.75, 536960.25, 188041.25, 536960.25, 188097.25, 536960.25, 187967.75, - 536960.25, 188040.25, 536960.25, 187978.25, 536960.25, 187961.25, 536960.25, 188078.75, - 536960.25, 188134.75, 536960.25, 188077.25, 536960.25, 188157.25, 536960.25, 188070.75, - 536960.25, 188034.75, 536960.25, 188030.25, 536960.25, 187944.75, 536960.25, 188139.75, - 536960.25, 188105.75, 536960.25, 188115.75, 536960.25, 187992.25, 536960.25, 188124.75, - 536960.25, 188098.25, 536960.25, 187951.25, 536960.25, 188120.25, 536960.25, 187956.25, - 536960.25, 188056.75, 536960.25, 187939.75, 536960.25, 188053.25, 536960.25, 188074.75, - 536960.25, 188071.25, 536960.25, 187949.25, 536960.25, 187930.75, 536960.25, 188026.75, - 536960.25, 188032.75, 536960.25, 188077.75, 536960.25, 188035.25, 536960.25, 188059.25, - 536960.25, 187960.25, 536960.25, 188064.25, 536960.25, 188029.75, 536960.25, 188110.75, - 536960.25, 187952.25, 536960.25, 187947.75, 536960.25, 188114.75, 536960.25, 187932.75, - 536960.25, 187941.75, 536960.25, 187929.25, 536960.25, 188061.25, 536960.25, 188027.25, - 536960.25, 188059.75, 536960.25, 188075.25, 536960.25, 188036.75, 536960.25, 188031.25, - 536960.25, 188057.25, 536960.25, 188118.75, 536960.25, 188122.75, 536960.25, 188060.75, - 536960.25, 187931.75, 536960.25, 188030.75, 536960.25, 187915.25, 536960.25, 188111.75, - 536960.25, 188042.25, 536960.25, 187927.25, 536960.25, 187956.75, 536960.25, 187964.25, - 536960.25, 187990.75, 536960.25, 188023.75, 536960.25, 188072.25, 536960.25, 187968.25, - 536960.25, 187991.25, 536960.25, 188107.75, 536960.25, 188153.25, 536960.25, 187927.75, - 536960.25, 187940.25, 536960.25, 187932.25, 536960.25, 188130.75, 536960.25, 188108.25, - 536960.25, 188033.75, 536960.25, 187916.25, 536960.25, 188038.75, 536960.25, 188092.75, - 536960.25, 188079.75, 536960.25, 188021.75, 536960.25, 188123.75, 536960.25, 188112.75, - 536960.25, 187966.25, 536960.25, 188155.75, 536960.25, 188144.25, 536960.25, 187955.25, - 536960.25, 188141.25, 536960.25, 188159.75, 536960.25, 187914.25, 536960.25, 188065.25, - 536960.25, 188057.75, 536960.25, 187994.75, 536960.25, 188060.25, 536960.25, 188132.25, - 536960.75, 188154.25, 536960.75, 188079.75, 536960.75, 188112.75, 536960.75, 188155.25, - 536960.75, 188042.25, 536960.75, 188026.25, 536960.75, 188112.25, 536960.75, 187914.25, - 536960.75, 188055.75, 536960.75, 188144.25, 536960.75, 187916.25, 536960.75, 187930.25, - 536960.75, 188099.25, 536960.75, 187987.75, 536960.75, 188045.25, 536960.75, 187950.25, - 536960.75, 187957.25, 536960.75, 188159.25, 536960.75, 187951.75, 536960.75, 188064.75, - 536960.75, 188068.75, 536960.75, 188123.25, 536960.75, 188072.25, 536960.75, 188096.25, - 536960.75, 188052.25, 536960.75, 188060.75, 536960.75, 188156.25, 536960.75, 188052.75, - 536960.75, 188036.75, 536960.75, 188029.75, 536960.75, 188071.75, 536960.75, 188005.25, - 536960.75, 188057.25, 536960.75, 188122.75, 536960.75, 188140.25, 536960.75, 187991.75, - 536960.75, 187922.25, 536960.75, 188081.25, 536960.75, 187965.75, 536960.75, 187941.75, - 536960.75, 188032.25, 536960.75, 188115.25, 536960.75, 188076.25, 536960.75, 188158.75, - 536960.75, 187921.25, 536960.75, 188028.25, 536960.75, 187989.75, 536960.75, 188066.25, - 536960.75, 188020.25, 536960.75, 187933.25, 536960.75, 187966.75, 536960.75, 188055.25, - 536960.75, 188064.25, 536960.75, 187988.75, 536960.75, 188142.25, 536960.75, 187932.25, - 536960.75, 187940.75, 536960.75, 188124.75, 536960.75, 188142.75, 536960.75, 188106.75, - 536960.75, 188030.25, 536960.75, 188095.75, 536960.75, 187964.75, 536960.75, 188073.75, - 536960.75, 188116.25, 536960.75, 188106.25, 536960.75, 187952.75, 536960.75, 188041.25, - 536960.75, 188104.25, 536960.75, 188135.25, 536960.75, 187949.75, 536960.75, 188150.25, - 536960.75, 188006.25, 536960.75, 187959.25, 536960.75, 188002.25, 536960.75, 188058.75, - 536960.75, 188080.25, 536960.75, 188067.25, 536960.75, 188126.25, 536960.75, 187933.75, - 536960.75, 187955.75, 536960.75, 188152.75, 536960.75, 187914.75, 536960.75, 188069.75, - 536960.75, 187963.75, 536961.25, 188143.75, 536961.25, 188106.75, 536961.25, 188043.25, - 536961.25, 188067.25, 536961.25, 188141.75, 536961.25, 187960.75, 536961.25, 188097.25, - 536961.25, 187944.25, 536961.25, 188067.75, 536961.25, 188157.25, 536961.25, 187942.25, - 536961.25, 188058.75, 536961.25, 188142.25, 536961.25, 188051.25, 536961.25, 187954.75, - 536961.25, 188068.25, 536961.25, 188025.75, 536961.25, 188055.25, 536961.25, 188054.75, - 536961.25, 188020.75, 536961.25, 187922.25, 536961.25, 188135.25, 536961.25, 187965.75, - 536961.25, 188089.75, 536961.25, 187942.75, 536961.25, 187987.75, 536961.25, 187975.75, - 536961.25, 188073.75, 536961.25, 187916.25, 536961.25, 187962.75, 536961.25, 188135.75, - 536961.25, 188064.75, 536961.25, 188068.75, 536961.25, 188145.75, 536961.25, 187988.25, - 536961.25, 188051.75, 536961.25, 188140.75, 536961.25, 188018.75, 536961.25, 188058.25, - 536961.25, 188140.25, 536961.25, 188069.25, 536961.25, 188105.75, 536961.25, 188139.75, - 536961.25, 188063.75, 536961.25, 188020.25, 536961.25, 187963.75, 536961.25, 188125.25, - 536961.25, 187989.25, 536961.25, 187920.25, 536961.25, 188134.25, 536961.25, 187986.75, - 536961.25, 188056.25, 536961.25, 188110.75, 536961.25, 188014.25, 536961.25, 188139.25, - 536961.25, 187914.75, 536961.25, 188125.75, 536961.25, 187922.75, 536961.25, 187953.25, - 536961.25, 187948.75, 536961.25, 188126.25, 536961.25, 188021.25, 536961.25, 187959.25, - 536961.25, 187941.25, 536961.25, 188053.75, 536961.25, 188116.75, 536961.25, 188006.75, - 536961.25, 188025.25, 536961.25, 187952.75, 536961.25, 188062.75, 536961.25, 187949.75, - 536961.25, 187915.75, 536961.25, 188133.25, 536961.25, 187968.75, 536961.25, 188024.25, - 536961.25, 187946.25, 536961.25, 187991.75, 536961.25, 188111.75, 536961.25, 188031.75, - 536961.25, 187950.75, 536961.25, 188082.25, 536961.25, 188040.25, 536961.25, 188152.75, - 536961.25, 188052.25, 536961.25, 188071.25, 536961.25, 187932.75, 536961.25, 188053.25, - 536961.25, 188050.25, 536961.25, 188032.25, 536961.25, 188158.75, 536961.25, 187927.75, - 536961.25, 188076.25, 536961.25, 188079.25, 536961.25, 188030.25, 536961.25, 188153.25, - 536961.25, 188098.75, 536961.25, 188152.25, 536961.25, 188114.25, 536961.25, 188144.75, - 536961.25, 188138.25, 536961.25, 188052.75, 536961.25, 188148.25, 536961.25, 188029.25, - 536961.25, 187956.75, 536961.25, 187918.25, 536961.25, 188143.25, 536961.25, 188154.75, - 536961.25, 187934.25, 536961.25, 187948.25, 536961.25, 188112.25, 536961.25, 188027.75, - 536961.25, 187945.75, 536961.25, 188159.25, 536961.25, 188099.25, 536961.25, 188153.75, - 536961.25, 188026.25, 536961.25, 188028.75, 536961.25, 188094.75, 536961.25, 187965.25, - 536961.25, 188112.75, 536961.25, 188131.75, 536961.75, 188143.75, 536961.75, 188154.25, - 536961.75, 188103.75, 536961.75, 188067.25, 536961.75, 187960.75, 536961.75, 188066.75, - 536961.75, 188043.25, 536961.75, 188055.25, 536961.75, 188097.25, 536961.75, 188068.25, - 536961.75, 188051.25, 536961.75, 188079.75, 536961.75, 187965.25, 536961.75, 188057.75, - 536961.75, 187945.25, 536961.75, 187942.75, 536961.75, 187964.25, 536961.75, 187922.25, - 536961.75, 187986.25, 536961.75, 188135.25, 536961.75, 188155.75, 536961.75, 188054.75, - 536961.75, 188036.75, 536961.75, 188033.75, 536961.75, 187916.25, 536961.75, 187987.75, - 536961.75, 188141.25, 536961.75, 188153.75, 536961.75, 188016.75, 536961.75, 188068.75, - 536961.75, 188029.25, 536961.75, 187953.75, 536961.75, 188026.25, 536961.75, 187955.25, - 536961.75, 188025.75, 536961.75, 187968.25, 536961.75, 188027.75, 536961.75, 188137.75, - 536961.75, 187948.25, 536961.75, 188112.25, 536961.75, 187990.75, 536961.75, 188023.75, - 536961.75, 188135.75, 536961.75, 187934.25, 536961.75, 187950.25, 536961.75, 187992.75, - 536961.75, 188134.75, 536961.75, 188064.75, 536961.75, 187962.75, 536961.75, 188077.75, - 536961.75, 188041.75, 536961.75, 187988.25, 536961.75, 188051.75, 536961.75, 188145.75, - 536961.75, 187982.25, 536961.75, 188124.25, 536961.75, 188148.25, 536961.75, 188118.25, - 536961.75, 188069.25, 536961.75, 188140.25, 536961.75, 188026.75, 536961.75, 188064.25, - 536961.75, 188052.75, 536961.75, 187915.25, 536961.75, 187988.75, 536961.75, 187932.75, - 536961.75, 187999.25, 536961.75, 187945.75, 536961.75, 188028.25, 536961.75, 188139.75, - 536961.75, 188106.25, 536961.75, 188016.25, 536961.75, 188097.75, 536961.75, 188059.25, - 536961.75, 187989.25, 536961.75, 188020.25, 536961.75, 188125.25, 536961.75, 188144.75, - 536961.75, 187962.25, 536961.75, 188114.25, 536961.75, 188050.75, 536961.75, 188057.25, - 536961.75, 188005.75, 536961.75, 188056.25, 536961.75, 188012.25, 536961.75, 188152.25, - 536961.75, 187914.75, 536961.75, 188139.25, 536961.75, 188125.75, 536961.75, 188126.25, - 536961.75, 188021.25, 536961.75, 188149.75, 536961.75, 187952.25, 536961.75, 187941.25, - 536961.75, 188053.25, 536961.75, 187976.75, 536961.75, 187943.25, 536961.75, 188031.75, - 536961.75, 188070.75, 536961.75, 188053.75, 536961.75, 187940.75, 536961.75, 188025.25, - 536961.75, 187952.75, 536961.75, 188111.25, 536961.75, 187946.25, 536961.75, 188076.25, - 536961.75, 188050.25, 536961.75, 187991.75, 536961.75, 188056.75, 536961.75, 188052.25, - 536961.75, 188095.75, 536961.75, 188032.25, 536961.75, 188079.25, 536961.75, 188132.75, - 536961.75, 188142.75, 536961.75, 188107.25, 536961.75, 188058.25, 536961.75, 187956.25, - 536962.25, 188154.75, 536962.25, 187953.25, 536962.25, 187921.75, 536962.25, 187987.25, - 536962.25, 188136.75, 536962.25, 188055.25, 536962.25, 188094.75, 536962.25, 188043.75, - 536962.25, 187915.75, 536962.25, 188015.25, 536962.25, 188027.75, 536962.25, 187944.75, - 536962.25, 187989.75, 536962.25, 188082.25, 536962.25, 188042.75, 536962.25, 188020.75, - 536962.25, 187954.25, 536962.25, 188142.25, 536962.25, 187964.25, 536962.25, 187985.75, - 536962.25, 187942.75, 536962.25, 188056.75, 536962.25, 188135.25, 536962.25, 188138.75, - 536962.25, 188066.25, 536962.25, 187945.25, 536962.25, 188116.25, 536962.25, 188133.25, - 536962.25, 188115.25, 536962.25, 188011.25, 536962.25, 188024.75, 536962.25, 188096.75, - 536962.25, 187933.25, 536962.25, 188065.75, 536962.25, 188051.25, 536962.25, 187916.25, - 536962.25, 188050.25, 536962.25, 188004.25, 536962.25, 188053.75, 536962.25, 187961.25, - 536962.25, 188098.75, 536962.25, 187950.25, 536962.25, 188070.75, 536962.25, 188155.25, - 536962.25, 188068.75, 536962.25, 187957.25, 536962.25, 188153.25, 536962.25, 188075.75, - 536962.25, 187946.75, 536962.25, 188143.25, 536962.25, 187959.75, 536962.25, 188049.25, - 536962.25, 188027.25, 536962.25, 188099.25, 536962.25, 187928.25, 536962.25, 188140.75, - 536962.25, 188018.75, 536962.25, 187979.75, 536962.25, 187974.25, 536962.25, 188136.25, - 536962.25, 188160.25, 536962.25, 188073.25, 536962.25, 187943.25, 536962.25, 188095.25, - 536962.25, 188064.25, 536962.25, 188114.75, 536962.25, 187915.25, 536962.25, 188126.25, - 536962.25, 188026.75, 536962.25, 187934.25, 536962.25, 188038.25, 536962.25, 187963.75, - 536962.25, 187910.75, 536962.25, 187989.25, 536962.25, 188133.75, 536962.25, 188069.75, - 536962.25, 187962.25, 536962.25, 188125.25, 536962.25, 188110.75, 536962.25, 187986.75, - 536962.25, 188152.25, 536962.25, 188057.25, 536962.75, 188070.25, 536962.75, 188048.25, - 536962.75, 188136.25, 536962.75, 187933.75, 536962.75, 187960.75, 536962.75, 188154.75, - 536962.75, 187916.75, 536962.75, 187986.75, 536962.75, 187922.75, 536962.75, 188153.25, - 536962.75, 188134.25, 536962.75, 188022.75, 536962.75, 188125.75, 536962.75, 188050.75, - 536962.75, 187915.75, 536962.75, 187990.25, 536962.75, 188141.75, 536962.75, 188071.25, - 536962.75, 188117.75, 536962.75, 188071.75, 536962.75, 188019.25, 536962.75, 188120.75, - 536962.75, 188095.75, 536962.75, 188063.75, 536962.75, 188151.75, 536962.75, 188139.25, - 536962.75, 188142.75, 536962.75, 187919.25, 536962.75, 188046.25, 536962.75, 188017.25, - 536962.75, 187985.25, 536962.75, 187956.25, 536962.75, 188048.75, 536962.75, 188142.25, - 536962.75, 188152.75, 536962.75, 187945.75, 536962.75, 188047.75, 536962.75, 187942.25, - 536962.75, 188126.25, 536962.75, 187949.25, 536962.75, 187984.25, 536962.75, 188122.25, - 536962.75, 187961.75, 536962.75, 187986.25, 536962.75, 188133.25, 536962.75, 187949.75, - 536962.75, 188052.75, 536962.75, 188066.25, 536962.75, 187946.25, 536962.75, 187957.75, - 536962.75, 188021.75, 536962.75, 188054.75, 536962.75, 188115.25, 536962.75, 188034.75, - 536962.75, 187941.75, 536962.75, 188016.25, 536962.75, 188099.75, 536962.75, 188024.25, - 536962.75, 187941.25, 536962.75, 187957.25, 536962.75, 188018.25, 536962.75, 188098.75, - 536962.75, 187935.75, 536962.75, 187970.25, 536962.75, 188126.75, 536962.75, 187991.25, - 536962.75, 187918.75, 536962.75, 187923.75, 536962.75, 188065.25, 536962.75, 187988.25, - 536962.75, 188070.75, 536962.75, 187934.75, 536962.75, 188096.25, 536962.75, 188055.75, - 536962.75, 188023.75, 536962.75, 187920.75, 536962.75, 187962.75, 536962.75, 188049.25, - 536962.75, 187992.25, 536962.75, 188116.75, 536962.75, 187953.75, 536962.75, 187918.25, - 536962.75, 187943.75, 536963.25, 187953.75, 536963.25, 187934.75, 536963.25, 188117.25, - 536963.25, 188052.75, 536963.25, 188094.25, 536963.25, 187918.25, 536963.25, 188019.75, - 536963.25, 187919.75, 536963.25, 188065.25, 536963.25, 187962.75, 536963.25, 188116.75, - 536963.25, 188075.75, 536963.25, 188049.25, 536963.25, 188024.25, 536963.25, 188150.25, - 536963.25, 188023.75, 536963.25, 188099.25, 536963.25, 188016.75, 536963.25, 188149.75, - 536963.25, 188034.75, 536963.25, 187923.75, 536963.25, 188135.75, 536963.25, 187918.75, - 536963.25, 188155.25, 536963.25, 188055.75, 536963.25, 188025.75, 536963.25, 188037.25, - 536963.25, 188072.25, 536963.25, 187959.25, 536963.25, 187971.75, 536963.25, 187947.75, - 536963.25, 187916.25, 536963.25, 188018.25, 536963.25, 188047.25, 536963.25, 187991.25, - 536963.25, 187941.75, 536963.25, 188095.25, 536963.25, 188062.75, 536963.25, 188096.75, - 536963.25, 187981.75, 536963.25, 188101.25, 536963.25, 187943.25, 536963.25, 187961.75, - 536963.25, 187984.75, 536963.25, 187922.25, 536963.25, 188148.25, 536963.25, 188139.25, - 536963.25, 188116.25, 536963.25, 188053.75, 536963.25, 188064.25, 536963.25, 187985.25, - 536963.25, 187950.75, 536963.25, 187984.25, 536963.25, 187986.25, 536963.25, 187988.75, - 536963.25, 188141.75, 536963.25, 187932.25, 536963.25, 187985.75, 536963.25, 187938.25, - 536963.25, 188013.75, 536963.25, 188114.75, 536963.25, 188021.75, 536963.25, 187942.25, - 536963.25, 188126.25, 536963.25, 188151.75, 536963.25, 187962.25, 536963.25, 188152.75, - 536963.25, 187953.25, 536963.25, 188077.25, 536963.25, 188048.75, 536963.25, 187933.75, - 536963.25, 188097.75, 536963.25, 187945.75, 536963.25, 188020.75, 536963.25, 188067.75, - 536963.25, 188120.75, 536963.25, 188083.75, 536963.25, 188153.25, 536963.25, 188063.75, - 536963.25, 188019.25, 536963.25, 188050.75, 536963.25, 188043.25, 536963.25, 188071.25, - 536963.25, 188154.75, 536963.25, 188032.75, 536963.25, 187987.25, 536963.25, 188125.25, - 536963.25, 188048.25, 536963.25, 187990.25, 536963.25, 188152.25, 536963.25, 188134.25, - 536963.25, 188026.75, 536963.25, 188055.25, 536963.25, 187960.75, 536963.25, 187915.75, - 536963.25, 188070.25, 536963.25, 187956.25, 536963.75, 188100.25, 536963.75, 187921.75, - 536963.75, 188136.25, 536963.75, 188014.25, 536963.75, 187991.75, 536963.75, 187939.75, - 536963.75, 187985.75, 536963.75, 188013.75, 536963.75, 187950.75, 536963.75, 188043.75, - 536963.75, 188097.25, 536963.75, 188033.25, 536963.75, 188052.25, 536963.75, 188013.25, - 536963.75, 188136.75, 536963.75, 188143.25, 536963.75, 188073.75, 536963.75, 187974.75, - 536963.75, 187992.75, 536963.75, 188134.75, 536963.75, 187930.25, 536963.75, 188038.25, - 536963.75, 187946.25, 536963.75, 188151.25, 536963.75, 188153.75, 536963.75, 187969.75, - 536963.75, 187916.75, 536963.75, 188129.25, 536963.75, 188072.25, 536963.75, 188142.75, - 536963.75, 187932.75, 536963.75, 188153.25, 536963.75, 188022.25, 536963.75, 188048.25, - 536963.75, 188128.75, 536963.75, 187923.25, 536963.75, 187959.25, 536963.75, 188095.75, - 536963.75, 187935.25, 536963.75, 188062.25, 536963.75, 188047.75, 536963.75, 188119.75, - 536963.75, 187961.25, 536963.75, 188024.25, 536963.75, 188116.75, 536963.75, 188070.75, - 536963.75, 187943.25, 536963.75, 188126.25, 536963.75, 188018.75, 536963.75, 187942.75, - 536963.75, 187988.25, 536963.75, 188125.75, 536963.75, 188017.25, 536963.75, 188023.25, - 536963.75, 187959.75, 536963.75, 188117.75, 536963.75, 188063.75, 536963.75, 187983.25, - 536963.75, 188069.75, 536963.75, 187983.75, 536963.75, 188046.25, 536963.75, 188097.75, - 536963.75, 188141.25, 536963.75, 187931.75, 536963.75, 188031.25, 536963.75, 188142.25, - 536963.75, 187950.25, 536964.25, 187946.75, 536964.25, 188123.25, 536964.25, 188056.75, - 536964.25, 188023.75, 536964.25, 187949.75, 536964.25, 188017.75, 536964.25, 188136.25, - 536964.25, 188061.75, 536964.25, 188095.75, 536964.25, 187960.25, 536964.25, 187952.25, - 536964.25, 188020.25, 536964.25, 188076.75, 536964.25, 187955.25, 536964.25, 187958.25, - 536964.25, 188115.75, 536964.25, 188152.25, 536964.25, 187981.25, 536964.25, 187991.75, - 536964.25, 187985.75, 536964.25, 188114.25, 536964.25, 187950.75, 536964.25, 187932.75, - 536964.25, 187923.25, 536964.25, 188071.75, 536964.25, 188074.25, 536964.25, 188075.25, - 536964.25, 188009.75, 536964.25, 188062.25, 536964.25, 188098.25, 536964.25, 188142.25, - 536964.25, 188127.75, 536964.25, 187936.25, 536964.25, 187935.75, 536964.25, 188022.25, - 536964.25, 187982.25, 536964.25, 188013.25, 536964.25, 188135.25, 536964.25, 188015.75, - 536964.25, 188016.25, 536964.25, 188142.75, 536964.25, 187989.25, 536964.25, 188121.75, - 536964.25, 187943.75, 536964.25, 187923.75, 536964.25, 188097.75, 536964.25, 187917.75, - 536964.25, 188140.25, 536964.25, 188099.25, 536964.25, 188113.25, 536964.25, 188118.25, - 536964.25, 188062.75, 536964.25, 187987.25, 536964.25, 188127.25, 536964.25, 188045.75, - 536964.25, 187961.25, 536964.25, 187951.25, 536964.25, 187916.75, 536964.25, 187954.75, - 536964.25, 188031.75, 536964.25, 188046.25, 536964.25, 188138.75, 536964.25, 188134.75, - 536964.25, 187983.75, 536964.25, 187917.25, 536964.25, 188096.75, 536964.25, 188154.75, - 536964.25, 188049.75, 536964.25, 188154.25, 536964.25, 187993.25, 536964.25, 187945.75, - 536964.25, 187957.25, 536964.25, 188117.25, 536964.25, 188022.75, 536964.25, 188073.25, - 536964.25, 188138.25, 536964.25, 188126.75, 536964.25, 187929.25, 536964.25, 188072.75, - 536964.25, 188125.75, 536964.25, 188111.25, 536964.25, 187969.75, 536964.25, 187990.75, - 536964.25, 187927.75, 536964.25, 187958.75, 536964.25, 188046.75, 536964.25, 188063.25, - 536964.25, 188147.25, 536964.25, 187942.75, 536964.25, 187934.25, 536964.25, 188133.25, - 536964.75, 188072.75, 536964.75, 187921.75, 536964.75, 187922.75, 536964.75, 187958.75, - 536964.75, 188046.75, 536964.75, 188138.25, 536964.75, 188063.25, 536964.75, 188132.75, - 536964.75, 188160.25, 536964.75, 187990.75, 536964.75, 187942.75, 536964.75, 187985.25, - 536964.75, 187934.25, 536964.75, 188022.75, 536964.75, 188154.25, 536964.75, 188126.75, - 536964.75, 187929.75, 536964.75, 187924.25, 536964.75, 187920.25, 536964.75, 188117.25, - 536964.75, 188057.25, 536964.75, 188155.75, 536964.75, 187957.25, 536964.75, 188134.25, - 536964.75, 188024.25, 536964.75, 188125.25, 536964.75, 187986.25, 536964.75, 188142.25, - 536964.75, 187983.25, 536964.75, 188138.75, 536964.75, 188122.75, 536964.75, 188046.25, - 536964.75, 188157.25, 536964.75, 188047.25, 536964.75, 188031.75, 536964.75, 188159.25, - 536964.75, 188044.75, 536964.75, 187931.25, 536964.75, 187916.75, 536964.75, 188016.75, - 536964.75, 187961.25, 536964.75, 188045.75, 536964.75, 188113.25, 536964.75, 188118.25, - 536964.75, 187954.75, 536964.75, 188073.75, 536964.75, 187992.75, 536964.75, 188139.75, - 536964.75, 188019.25, 536964.75, 187933.75, 536964.75, 188097.75, 536964.75, 187984.25, - 536964.75, 188099.25, 536964.75, 187917.75, 536964.75, 187910.75, 536964.75, 187943.75, - 536964.75, 188014.75, 536964.75, 188095.25, 536964.75, 188023.25, 536964.75, 188152.75, - 536964.75, 188020.75, 536964.75, 187967.25, 536964.75, 188135.25, 536964.75, 188098.25, - 536964.75, 187935.75, 536964.75, 188022.25, 536964.75, 188067.75, 536964.75, 187970.25, - 536964.75, 188127.75, 536964.75, 187960.75, 536964.75, 188058.75, 536964.75, 188055.75, - 536964.75, 187991.75, 536964.75, 188062.25, 536964.75, 188009.75, 536964.75, 187946.75, - 536964.75, 187950.75, 536964.75, 188016.25, 536964.75, 188074.75, 536964.75, 188078.75, - 536964.75, 188114.25, 536964.75, 188096.25, 536964.75, 188153.25, 536964.75, 187981.25, - 536964.75, 188149.25, 536964.75, 188071.75, 536964.75, 187953.75, 536964.75, 187959.25, - 536964.75, 187933.25, 536964.75, 187955.25, 536964.75, 188136.25, 536964.75, 188061.75, - 536964.75, 188157.75, 536964.75, 187960.25, 536964.75, 188108.75, 536964.75, 188035.75, - 536964.75, 187949.75, 536964.75, 188114.75, 536964.75, 188048.25, 536964.75, 188023.75, - 536965.25, 188029.75, 536965.25, 188141.75, 536965.25, 188150.75, 536965.25, 188014.25, - 536965.25, 188018.25, 536965.25, 188030.25, 536965.25, 188095.75, 536965.25, 188020.25, - 536965.25, 188056.75, 536965.25, 187952.25, 536965.25, 188043.75, 536965.25, 187947.75, - 536965.25, 187958.25, 536965.25, 188064.75, 536965.25, 188043.25, 536965.25, 188153.75, - 536965.25, 187920.75, 536965.25, 187919.25, 536965.25, 187950.25, 536965.25, 188147.75, - 536965.25, 188074.25, 536965.25, 188033.25, 536965.25, 188055.25, 536965.25, 188106.75, - 536965.25, 187982.25, 536965.25, 187935.75, 536965.25, 188020.75, 536965.25, 187980.25, - 536965.25, 188141.25, 536965.25, 187954.75, 536965.25, 188027.75, 536965.25, 188045.75, - 536965.25, 187983.75, 536965.25, 188096.75, 536965.25, 187957.75, 536965.25, 187917.25, - 536965.25, 188148.75, 536965.25, 188142.75, 536965.25, 188021.25, 536965.25, 188107.75, - 536965.25, 187950.75, 536965.25, 187935.25, 536965.25, 188152.75, 536965.25, 188070.25, - 536965.25, 187946.25, 536965.25, 188022.75, 536965.25, 188056.25, 536965.25, 187971.25, - 536965.25, 187955.75, 536965.25, 188032.25, 536965.25, 188063.25, 536965.25, 188127.75, - 536965.25, 187918.25, 536965.25, 188024.25, 536965.25, 188070.75, 536965.25, 188021.75, - 536965.25, 188132.25, 536965.25, 187943.75, 536965.25, 187989.25, 536965.25, 188060.25, - 536965.25, 188131.75, 536965.25, 187982.75, 536965.25, 188036.25, 536965.25, 188116.25, - 536965.25, 187989.75, 536965.25, 187995.75, 536965.25, 188127.25, 536965.25, 187981.75, - 536965.75, 187988.25, 536965.75, 188108.75, 536965.75, 188062.75, 536965.75, 188127.25, - 536965.75, 188153.25, 536965.75, 188067.25, 536965.75, 187947.75, 536965.75, 187987.25, - 536965.75, 187936.25, 536965.75, 188015.25, 536965.75, 187918.75, 536965.75, 187988.75, - 536965.75, 187954.25, 536965.75, 188014.25, 536965.75, 188146.75, 536965.75, 188128.75, - 536965.75, 187979.75, 536965.75, 188024.75, 536965.75, 187916.75, 536965.75, 187952.25, - 536965.75, 188131.75, 536965.75, 188115.25, 536965.75, 188056.75, 536965.75, 187942.25, - 536965.75, 188116.75, 536965.75, 188102.75, 536965.75, 187958.25, 536965.75, 187943.75, - 536965.75, 188051.75, 536965.75, 188045.25, 536965.75, 187957.25, 536965.75, 187950.25, - 536965.75, 187919.25, 536965.75, 188019.25, 536965.75, 188152.25, 536965.75, 188144.25, - 536965.75, 187980.75, 536965.75, 188043.25, 536965.75, 187978.75, 536965.75, 188071.75, - 536965.75, 188096.25, 536965.75, 188151.75, 536965.75, 188143.75, 536965.75, 188093.25, - 536965.75, 187979.25, 536965.75, 187981.25, 536965.75, 188109.25, 536965.75, 188024.25, - 536965.75, 188145.75, 536965.75, 188044.25, 536965.75, 188118.75, 536965.75, 187943.25, - 536965.75, 187991.75, 536965.75, 188155.25, 536965.75, 188033.25, 536965.75, 188132.75, - 536965.75, 188159.25, 536965.75, 188142.25, 536965.75, 188109.75, 536965.75, 188133.25, - 536965.75, 188158.75, 536965.75, 188154.75, 536965.75, 188013.25, 536965.75, 188140.75, - 536965.75, 187982.25, 536965.75, 188128.25, 536965.75, 188046.75, 536965.75, 187944.25, - 536965.75, 188135.25, 536965.75, 188042.75, 536965.75, 188072.25, 536965.75, 188137.75, - 536965.75, 188019.75, 536965.75, 188143.25, 536965.75, 188108.25, 536965.75, 187917.75, - 536965.75, 187935.25, 536965.75, 188097.75, 536965.75, 188144.75, 536965.75, 187956.25, - 536965.75, 187936.75, 536965.75, 187929.75, 536965.75, 188092.75, 536965.75, 188159.75, - 536965.75, 188133.75, 536965.75, 188142.75, 536965.75, 188156.25, 536965.75, 188021.25, - 536965.75, 187951.25, 536965.75, 188057.75, 536965.75, 188016.75, 536965.75, 188071.25, - 536965.75, 188033.75, 536965.75, 188036.75, 536965.75, 188063.75, 536965.75, 188032.75, - 536965.75, 188059.25, 536965.75, 187932.25, 536965.75, 188117.75, 536965.75, 187947.25, - 536965.75, 187972.25, 536966.25, 188060.75, 536966.25, 187917.25, 536966.25, 188103.75, - 536966.25, 188157.25, 536966.25, 188071.25, 536966.25, 188153.25, 536966.25, 188032.75, - 536966.25, 188025.75, 536966.25, 187956.25, 536966.25, 188063.75, 536966.25, 188118.25, - 536966.25, 188057.75, 536966.25, 187951.25, 536966.25, 187912.25, 536966.25, 188056.25, - 536966.25, 188144.75, 536966.25, 188133.75, 536966.25, 188141.25, 536966.25, 188024.25, - 536966.25, 187935.25, 536966.25, 188107.75, 536966.25, 188051.25, 536966.25, 188069.25, - 536966.25, 188137.75, 536966.25, 187950.75, 536966.25, 188142.25, 536966.25, 188019.25, - 536966.25, 187917.75, 536966.25, 188143.25, 536966.25, 188072.25, 536966.25, 187944.75, - 536966.25, 187935.75, 536966.25, 188011.75, 536966.25, 187987.75, 536966.25, 188142.75, - 536966.25, 187944.25, 536966.25, 188154.75, 536966.25, 187936.25, 536966.25, 188119.75, - 536966.25, 188020.75, 536966.25, 188033.25, 536966.25, 187954.75, 536966.25, 188013.25, - 536966.25, 187943.25, 536966.25, 188140.75, 536966.25, 188042.75, 536966.25, 187955.75, - 536966.25, 188055.25, 536966.25, 187971.25, 536966.25, 187981.25, 536966.25, 188132.75, - 536966.25, 188155.25, 536966.25, 188145.75, 536966.25, 188103.25, 536966.25, 187994.25, - 536966.25, 187978.75, 536966.25, 188120.25, 536966.25, 188095.25, 536966.25, 188096.25, - 536966.25, 187979.25, 536966.25, 188021.75, 536966.25, 188152.75, 536966.25, 188093.25, - 536966.25, 188041.75, 536966.25, 188112.25, 536966.25, 188144.25, 536966.25, 187919.75, - 536966.25, 188017.75, 536966.25, 187980.75, 536966.25, 188127.75, 536966.25, 188044.25, - 536966.25, 187943.75, 536966.25, 187933.25, 536966.25, 187957.25, 536966.25, 187941.25, - 536966.25, 188106.25, 536966.25, 187923.75, 536966.25, 188112.75, 536966.25, 188138.75, - 536966.25, 188043.75, 536966.25, 188116.75, 536966.25, 187955.25, 536966.25, 188108.75, - 536966.25, 187966.25, 536966.25, 187979.75, 536966.25, 188024.75, 536966.25, 187982.75, - 536966.25, 188014.25, 536966.25, 187988.75, 536966.25, 187942.25, 536966.25, 188127.25, - 536966.25, 188062.75, 536966.25, 187956.75, 536966.25, 187947.25, 536966.75, 187980.75, - 536966.75, 188071.75, 536966.75, 188146.25, 536966.75, 188017.75, 536966.75, 188020.25, - 536966.75, 187977.25, 536966.75, 187954.75, 536966.75, 188109.25, 536966.75, 188157.25, - 536966.75, 188151.75, 536966.75, 188143.75, 536966.75, 187924.75, 536966.75, 187947.75, - 536966.75, 187978.25, 536966.75, 188103.75, 536966.75, 188109.75, 536966.75, 187954.25, - 536966.75, 188042.75, 536966.75, 188014.75, 536966.75, 187921.25, 536966.75, 188146.75, - 536966.75, 188110.25, 536966.75, 188054.75, 536966.75, 187980.25, 536966.75, 187955.25, - 536966.75, 188073.75, 536966.75, 187953.75, 536966.75, 188033.25, 536966.75, 188159.75, - 536966.75, 188041.75, 536966.75, 188145.75, 536966.75, 187931.75, 536966.75, 188059.25, - 536966.75, 187936.75, 536966.75, 187941.75, 536966.75, 188012.25, 536966.75, 188033.75, - 536966.75, 187947.25, 536966.75, 188148.75, 536966.75, 188018.75, 536966.75, 188073.25, - 536966.75, 188091.25, 536966.75, 188133.75, 536966.75, 188027.25, 536966.75, 188117.75, - 536966.75, 188091.75, 536966.75, 188052.75, 536966.75, 188137.75, 536966.75, 188040.75, - 536966.75, 188032.75, 536966.75, 187948.75, 536966.75, 188094.25, 536966.75, 187943.25, - 536966.75, 188147.25, 536966.75, 187953.25, 536966.75, 188111.25, 536966.75, 188025.25, - 536966.75, 188011.75, 536966.75, 188103.25, 536966.75, 187978.75, 536966.75, 188063.25, - 536966.75, 187941.25, 536966.75, 188133.25, 536966.75, 188116.75, 536966.75, 188127.25, - 536966.75, 188151.25, 536966.75, 188062.75, 536966.75, 188145.25, 536966.75, 188139.75, - 536966.75, 188040.25, 536966.75, 188158.75, 536966.75, 188011.25, 536966.75, 188112.75, - 536966.75, 188128.25, 536966.75, 188138.75, 536966.75, 188131.75, 536966.75, 187919.25, - 536966.75, 188115.25, 536966.75, 188153.75, 536966.75, 187918.75, 536966.75, 187940.75, - 536966.75, 188128.75, 536966.75, 188015.25, 536966.75, 188152.25, 536966.75, 188159.25, - 536966.75, 187951.75, 536966.75, 188148.25, 536966.75, 187956.75, 536966.75, 187925.25, - 536966.75, 188129.25, 536967.25, 188129.25, 536967.25, 187925.25, 536967.25, 188113.25, - 536967.25, 188102.25, 536967.25, 188148.25, 536967.25, 187951.75, 536967.25, 188015.75, - 536967.25, 188022.25, 536967.25, 188159.25, 536967.25, 188113.75, 536967.25, 187931.25, - 536967.25, 187937.25, 536967.25, 188019.25, 536967.25, 188108.75, 536967.25, 187952.25, - 536967.25, 188114.75, 536967.25, 188008.75, 536967.25, 187977.75, 536967.25, 188034.25, - 536967.25, 188115.25, 536967.25, 187918.75, 536967.25, 188038.75, 536967.25, 188150.25, - 536967.25, 187919.25, 536967.25, 188153.75, 536967.25, 187929.25, 536967.25, 188147.75, - 536967.25, 188138.75, 536967.25, 188016.25, 536967.25, 188143.75, 536967.25, 187976.25, - 536967.25, 187952.75, 536967.25, 188032.25, 536967.25, 188127.75, 536967.25, 188040.25, - 536967.25, 188139.75, 536967.25, 187980.75, 536967.25, 188145.25, 536967.25, 187979.25, - 536967.25, 187940.25, 536967.25, 187910.75, 536967.25, 188072.75, 536967.25, 187918.25, - 536967.25, 188112.25, 536967.25, 188160.25, 536967.25, 188111.75, 536967.25, 188117.25, - 536967.25, 188154.25, 536967.25, 188059.75, 536967.25, 187978.75, 536967.25, 188011.75, - 536967.25, 187953.25, 536967.25, 188019.75, 536967.25, 188111.25, 536967.25, 187937.75, - 536967.25, 188094.25, 536967.25, 188031.75, 536967.25, 188099.75, 536967.25, 188046.75, - 536967.25, 187911.25, 536967.25, 188052.75, 536967.25, 188091.75, 536967.25, 188133.75, - 536967.25, 188149.75, 536967.25, 188073.25, 536967.25, 188141.25, 536967.25, 188148.75, - 536967.25, 188018.75, 536967.25, 188085.75, 536967.25, 188064.25, 536967.25, 188134.25, - 536967.25, 188110.75, 536967.25, 188034.75, 536967.25, 187936.75, 536967.25, 187931.75, - 536967.25, 188033.75, 536967.25, 187930.75, 536967.25, 188118.75, 536967.25, 188041.75, - 536967.25, 188033.25, 536967.25, 188073.75, 536967.25, 188055.75, 536967.25, 188123.75, - 536967.25, 188108.25, 536967.25, 188018.25, 536967.25, 187917.75, 536967.25, 188042.25, - 536967.25, 188157.75, 536967.25, 188110.25, 536967.25, 188146.75, 536967.25, 188119.25, - 536967.25, 188030.75, 536967.25, 187922.25, 536967.25, 188135.25, 536967.25, 187942.25, - 536967.25, 188152.75, 536967.25, 188104.75, 536967.25, 187972.25, 536967.25, 188013.25, - 536967.25, 188058.25, 536967.25, 188052.25, 536967.25, 188155.75, 536967.25, 188058.75, - 536967.25, 188074.25, 536967.25, 188157.25, 536967.25, 188013.75, 536967.25, 188097.25, - 536967.25, 188109.25, 536967.25, 187954.75, 536967.25, 188017.75, 536967.25, 188100.75, - 536967.25, 188067.75, 536967.25, 187939.75, 536967.25, 188055.25, 536967.25, 187947.75, - 536967.25, 187926.25, 536967.75, 187926.25, 536967.75, 188128.25, 536967.75, 188055.25, - 536967.75, 188127.75, 536967.75, 187919.25, 536967.75, 188063.25, 536967.75, 188063.75, - 536967.75, 188158.25, 536967.75, 187940.75, 536967.75, 187937.25, 536967.75, 188159.25, - 536967.75, 188064.75, 536967.75, 188017.25, 536967.75, 188123.75, 536967.75, 187975.75, - 536967.75, 188141.25, 536967.75, 188129.25, 536967.75, 188030.75, 536967.75, 188018.25, - 536967.75, 187942.25, 536967.75, 187936.25, 536967.75, 187954.75, 536967.75, 187950.25, - 536967.75, 188066.75, 536967.75, 187931.25, 536967.75, 187947.75, 536967.75, 187921.75, - 536967.75, 187918.75, 536967.75, 188152.75, 536967.75, 188119.75, 536967.75, 187942.75, - 536967.75, 188146.75, 536967.75, 188119.25, 536967.75, 187978.75, 536967.75, 188034.75, - 536967.75, 188118.75, 536967.75, 187953.75, 536967.75, 188041.25, 536967.75, 188091.75, - 536967.75, 187918.25, 536967.75, 188117.75, 536967.75, 188031.75, 536967.75, 188040.75, - 536967.75, 187953.25, 536967.75, 187940.25, 536967.75, 188116.75, 536967.75, 188040.25, - 536967.75, 188032.25, 536967.75, 187976.25, 536967.75, 187952.75, 536967.75, 188018.75, - 536967.75, 188150.25, 536967.75, 188147.75, 536967.75, 187939.25, 536967.75, 188115.25, - 536967.75, 188133.25, 536967.75, 188153.75, 536967.75, 188140.25, 536967.75, 188154.25, - 536967.75, 188019.25, 536967.75, 188114.75, 536967.75, 188015.75, 536967.75, 187925.25, - 536967.75, 188071.75, 536967.75, 187952.25, 536967.75, 188152.25, 536967.75, 188138.75, - 536967.75, 188102.25, 536967.75, 188113.75, 536967.75, 187977.75, 536967.75, 188148.25, - 536967.75, 188113.25, 536967.75, 188038.75, 536967.75, 188010.75, 536967.75, 187963.25, - 536967.75, 188133.75, 536967.75, 188094.25, 536967.75, 188072.75, 536967.75, 188059.25, - 536967.75, 188052.75, 536967.75, 188111.75, 536967.75, 188011.75, 536967.75, 187924.25, - 536967.75, 188073.25, 536967.75, 188148.75, 536967.75, 188012.25, 536967.75, 187934.25, - 536967.75, 188051.75, 536967.75, 188033.25, 536967.75, 188093.25, 536967.75, 188100.25, - 536967.75, 188019.75, 536967.75, 188090.75, 536967.75, 187950.75, 536967.75, 188073.75, - 536967.75, 187915.75, 536967.75, 188149.75, 536967.75, 188110.25, 536967.75, 188109.25, - 536967.75, 188052.25, 536967.75, 188143.25, 536967.75, 188100.75, 536967.75, 187979.75, - 536967.75, 188108.75, 536967.75, 188108.25, 536967.75, 188033.75, 536967.75, 188026.25, - 536968.25, 187973.75, 536968.25, 188150.25, 536968.25, 188017.75, 536968.25, 188014.75, - 536968.25, 188030.25, 536968.25, 188047.25, 536968.25, 187919.75, 536968.25, 188108.75, - 536968.25, 187911.25, 536968.25, 188128.75, 536968.25, 188101.25, 536968.25, 188046.25, - 536968.25, 188064.25, 536968.25, 188155.75, 536968.25, 188153.25, 536968.25, 187936.75, - 536968.25, 188103.75, 536968.25, 187977.25, 536968.25, 188144.75, 536968.25, 188064.75, - 536968.25, 187938.25, 536968.25, 188017.25, 536968.25, 188092.75, 536968.25, 188029.75, - 536968.25, 187975.75, 536968.25, 187947.75, 536968.25, 188129.25, 536968.25, 188091.25, - 536968.25, 188151.75, 536968.25, 188018.25, 536968.25, 188090.25, 536968.25, 187921.25, - 536968.25, 187950.25, 536968.25, 188074.25, 536968.25, 188105.25, 536968.25, 188016.75, - 536968.25, 188120.25, 536968.25, 188042.75, 536968.25, 187918.75, 536968.25, 187978.75, - 536968.25, 187994.75, 536968.25, 188034.75, 536968.25, 188031.25, 536968.25, 188118.75, - 536968.25, 188110.25, 536968.25, 188149.75, 536968.25, 188118.25, 536968.25, 188031.75, - 536968.25, 188102.75, 536968.25, 188078.25, 536968.25, 188056.25, 536968.25, 188100.25, - 536968.25, 187933.75, 536968.25, 188040.75, 536968.25, 187940.25, 536968.25, 188116.25, - 536968.25, 188016.25, 536968.25, 188039.75, 536968.25, 187935.25, 536968.25, 188133.25, - 536968.25, 188098.75, 536968.25, 187938.75, 536968.25, 188135.25, 536968.25, 188059.75, - 536968.25, 188052.75, 536968.25, 188134.75, 536968.25, 187952.25, 536968.25, 188114.25, - 536968.25, 188156.25, 536968.25, 188038.25, 536968.25, 187979.25, 536968.25, 188039.25, - 536968.25, 188148.25, 536968.25, 187951.75, 536968.25, 188099.75, 536968.25, 188025.75, - 536968.25, 187930.75, 536968.25, 188057.25, 536968.25, 188112.75, 536968.25, 187971.75, - 536968.25, 188011.75, 536968.25, 188059.25, 536968.25, 188034.25, 536968.25, 187965.25, - 536968.25, 188072.75, 536968.25, 188112.25, 536968.75, 187927.75, 536968.75, 188141.25, - 536968.75, 188112.25, 536968.75, 188134.25, 536968.75, 187976.75, 536968.75, 187997.25, - 536968.75, 187973.75, 536968.75, 187912.25, 536968.75, 188036.25, 536968.75, 187934.25, - 536968.75, 187919.25, 536968.75, 188128.75, 536968.75, 188034.25, 536968.75, 188112.75, - 536968.75, 188014.75, 536968.75, 188059.25, 536968.75, 188142.25, 536968.75, 188038.75, - 536968.75, 187934.75, 536968.75, 188155.25, 536968.75, 188014.25, 536968.75, 188064.25, - 536968.75, 188124.75, 536968.75, 188153.25, 536968.75, 187931.75, 536968.75, 188099.25, - 536968.75, 188100.75, 536968.75, 187977.75, 536968.75, 188145.75, 536968.75, 188039.25, - 536968.75, 187924.25, 536968.75, 187937.75, 536968.75, 188156.25, 536968.75, 187974.75, - 536968.75, 188015.25, 536968.75, 188058.25, 536968.75, 187938.25, 536968.75, 187932.75, - 536968.75, 187920.75, 536968.75, 188104.75, 536968.75, 188109.25, 536968.75, 188151.25, - 536968.75, 188056.75, 536968.75, 187933.25, 536968.75, 188026.75, 536968.75, 188110.75, - 536968.75, 188013.75, 536968.75, 188065.25, 536968.75, 188129.25, 536968.75, 187949.25, - 536968.75, 188098.75, 536968.75, 188151.75, 536968.75, 188030.75, 536968.75, 188122.75, - 536968.75, 187974.25, 536968.75, 188079.75, 536968.75, 188129.75, 536968.75, 188130.25, - 536968.75, 187948.25, 536968.75, 188077.25, 536968.75, 187952.75, 536968.75, 188098.25, - 536968.75, 187975.25, 536968.75, 187926.75, 536968.75, 188074.75, 536968.75, 187950.25, - 536968.75, 188132.75, 536968.75, 188029.25, 536968.75, 188073.75, 536968.75, 187951.25, - 536968.75, 188078.75, 536968.75, 187940.25, 536968.75, 188116.25, 536968.75, 188105.25, - 536968.75, 188146.25, 536968.75, 188091.25, 536968.75, 187939.25, 536968.75, 188028.25, - 536968.75, 188157.25, 536968.75, 188057.75, 536968.75, 188016.75, 536968.75, 188109.75, - 536968.75, 188022.75, 536968.75, 187973.25, 536968.75, 188070.25, 536968.75, 188035.25, - 536968.75, 188107.75, 536968.75, 188037.75, 536968.75, 188091.75, 536968.75, 187925.75, - 536968.75, 187911.75, 536968.75, 187918.75, 536968.75, 188131.25, 536968.75, 188012.75, - 536968.75, 188013.25, 536968.75, 188094.75, 536968.75, 187935.75, 536968.75, 187953.75, - 536968.75, 187922.75, 536968.75, 188118.75, 536968.75, 187948.75, 536968.75, 188093.25, - 536968.75, 188068.75, 536969.25, 188135.75, 536969.25, 188037.75, 536969.25, 187948.75, - 536969.25, 188060.25, 536969.25, 187972.75, 536969.25, 187925.75, 536969.25, 188146.75, - 536969.25, 188132.25, 536969.25, 187922.25, 536969.25, 187918.75, 536969.25, 187911.75, - 536969.25, 188012.75, 536969.25, 188117.75, 536969.25, 188143.75, 536969.25, 187918.25, - 536969.25, 188152.75, 536969.25, 188035.25, 536969.25, 188022.75, 536969.25, 188079.75, - 536969.25, 188087.75, 536969.25, 188157.25, 536969.25, 188109.75, 536969.25, 187951.25, - 536969.25, 188052.25, 536969.25, 187939.25, 536969.25, 187948.25, 536969.25, 188107.75, - 536969.25, 188057.75, 536969.25, 188039.75, 536969.25, 187936.25, 536969.25, 188028.25, - 536969.25, 187976.25, 536969.25, 187950.25, 536969.25, 187926.75, 536969.25, 187975.25, - 536969.25, 188098.25, 536969.25, 188115.75, 536969.25, 188073.75, 536969.25, 187935.25, - 536969.25, 187932.75, 536969.25, 188129.75, 536969.25, 188029.75, 536969.25, 188013.75, - 536969.25, 188110.75, 536969.25, 188030.75, 536969.25, 188098.75, 536969.25, 188123.25, - 536969.25, 188151.75, 536969.25, 188157.75, 536969.25, 187974.25, 536969.25, 187949.25, - 536969.25, 188065.25, 536969.25, 188154.25, 536969.25, 187933.25, 536969.25, 188129.25, - 536969.25, 187925.25, 536969.25, 187952.25, 536969.25, 188021.25, 536969.25, 188036.25, - 536969.25, 187920.75, 536969.25, 188114.25, 536969.25, 188055.75, 536969.25, 187937.75, - 536969.25, 188151.25, 536969.25, 187974.75, 536969.25, 187924.25, 536969.25, 188104.75, - 536969.25, 188099.25, 536969.25, 188133.75, 536969.25, 187931.75, 536969.25, 188142.25, - 536969.25, 188026.25, 536969.25, 188102.25, 536969.25, 188113.25, 536969.25, 188064.25, - 536969.25, 188014.25, 536969.25, 188059.25, 536969.25, 188101.25, 536969.25, 187951.75, - 536969.25, 188155.25, 536969.25, 188015.25, 536969.25, 188108.75, 536969.25, 187919.75, - 536969.25, 188014.75, 536969.25, 188111.75, 536969.25, 188034.25, 536969.25, 188128.75, - 536969.25, 188038.75, 536969.25, 188079.25, 536969.25, 187914.25, 536969.25, 187976.75, - 536969.25, 187938.25, 536969.75, 187937.25, 536969.75, 188145.25, 536969.75, 187912.25, - 536969.75, 188141.75, 536969.75, 188103.75, 536969.75, 188127.25, 536969.75, 188125.25, - 536969.75, 187950.25, 536969.75, 188027.25, 536969.75, 188034.75, 536969.75, 188145.75, - 536969.75, 187925.75, 536969.75, 187936.75, 536969.75, 188078.75, 536969.75, 188048.75, - 536969.75, 188064.75, 536969.75, 188045.25, 536969.75, 187975.75, 536969.75, 188077.25, - 536969.75, 188157.75, 536969.75, 187949.75, 536969.75, 188095.25, 536969.75, 188160.25, - 536969.75, 188060.75, 536969.75, 187910.75, 536969.75, 188035.75, 536969.75, 188130.25, - 536969.75, 188026.75, 536969.75, 188066.25, 536969.75, 187921.25, 536969.75, 187932.25, - 536969.75, 188036.25, 536969.75, 187936.25, 536969.75, 188057.25, 536969.75, 188029.25, - 536969.75, 188130.75, 536969.75, 187921.75, 536969.75, 188157.25, 536969.75, 188102.25, - 536969.75, 187934.25, 536969.75, 188107.75, 536969.75, 187922.25, 536969.75, 187917.25, - 536969.75, 188028.75, 536969.75, 187918.75, 536969.75, 187950.75, 536969.75, 187948.75, - 536969.75, 188027.75, 536969.75, 188101.75, 536969.75, 188036.75, 536969.75, 188108.25, - 536969.75, 188075.25, 536969.75, 188058.25, 536969.75, 188100.75, 536969.75, 188117.25, - 536969.75, 188109.25, 536969.75, 188013.75, 536969.75, 188116.25, 536969.75, 187976.25, - 536969.75, 188098.75, 536969.75, 188115.25, 536969.75, 187993.75, 536969.75, 188028.25, - 536969.75, 187935.25, 536969.75, 188074.75, 536969.75, 187972.75, 536969.75, 188156.25, - 536969.75, 188013.25, 536969.75, 188037.75, 536969.75, 188112.75, 536969.75, 187949.25, - 536969.75, 187917.75, 536969.75, 188059.25, 536969.75, 188099.75, 536969.75, 187973.75, - 536969.75, 187934.75, 536969.75, 188111.25, 536969.75, 187947.25, 536969.75, 187971.25, - 536969.75, 188134.25, 536970.25, 187927.75, 536970.25, 188134.25, 536970.25, 188011.75, - 536970.25, 188112.25, 536970.25, 187971.25, 536970.25, 187973.75, 536970.25, 187934.75, - 536970.25, 188012.25, 536970.25, 187912.75, 536970.25, 188094.25, 536970.25, 187917.75, - 536970.25, 188112.75, 536970.25, 188058.75, 536970.25, 188080.75, 536970.25, 188100.25, - 536970.25, 187923.75, 536970.25, 188133.75, 536970.25, 188114.25, 536970.25, 188109.75, - 536970.25, 188074.25, 536970.25, 188071.75, 536970.25, 188115.25, 536970.25, 188116.75, - 536970.25, 188100.75, 536970.25, 187994.25, 536970.25, 188037.25, 536970.25, 188075.25, - 536970.25, 188145.25, 536970.25, 187974.75, 536970.25, 187922.75, 536970.25, 188058.25, - 536970.25, 188060.25, 536970.25, 187911.75, 536970.25, 188108.25, 536970.25, 188155.75, - 536970.25, 188069.25, 536970.25, 187915.75, 536970.25, 188075.75, 536970.25, 188028.75, - 536970.25, 187991.25, 536970.25, 187935.75, 536970.25, 187970.25, 536970.25, 187913.25, - 536970.25, 187917.25, 536970.25, 187950.75, 536970.25, 187973.25, 536970.25, 187971.75, - 536970.25, 188049.75, 536970.25, 188157.25, 536970.25, 187921.75, 536970.25, 188107.25, - 536970.25, 188142.75, 536970.25, 187916.75, 536970.25, 188130.75, 536970.25, 188026.75, - 536970.25, 188066.25, 536970.25, 188106.75, 536970.25, 188122.75, 536970.25, 187949.75, - 536970.25, 188065.75, 536970.25, 188157.75, 536970.25, 188123.25, 536970.25, 188035.75, - 536970.25, 188077.25, 536970.25, 187955.25, 536970.25, 187913.75, 536970.25, 188048.75, - 536970.25, 187933.75, 536970.25, 188106.25, 536970.25, 187959.75, 536970.25, 188096.25, - 536970.25, 188078.25, 536970.25, 187996.75, 536970.25, 188145.75, 536970.25, 188027.25, - 536970.25, 188018.25, 536970.25, 188085.75, 536970.25, 188017.25, 536970.25, 187961.25, - 536970.25, 188047.75, 536970.25, 188095.75, 536970.25, 187972.25, 536970.25, 187926.25, - 536970.75, 188142.25, 536970.75, 188128.25, 536970.75, 187949.25, 536970.75, 188080.75, - 536970.75, 188081.25, 536970.75, 188100.25, 536970.75, 188027.25, 536970.75, 187972.75, - 536970.75, 187915.75, 536970.75, 188100.75, 536970.75, 187917.25, 536970.75, 188057.75, - 536970.75, 188123.25, 536970.75, 188154.75, 536970.75, 188124.75, 536970.75, 187991.75, - 536970.75, 188034.25, 536970.75, 188065.75, 536970.75, 187932.75, 536970.75, 187976.25, - 536970.75, 187933.75, 536970.75, 188103.25, 536970.75, 188026.75, 536970.75, 188098.25, - 536970.75, 188078.25, 536970.75, 188066.25, 536970.75, 188082.75, 536970.75, 187969.75, - 536970.75, 187930.25, 536970.75, 188058.75, 536970.75, 188001.25, 536970.75, 188135.25, - 536970.75, 188103.75, 536970.75, 188022.75, 536970.75, 188043.75, 536970.75, 187972.25, - 536970.75, 188002.25, 536970.75, 188121.25, 536970.75, 187950.25, 536970.75, 187921.75, - 536970.75, 188016.75, 536970.75, 188134.25, 536970.75, 187973.25, 536970.75, 188106.25, - 536970.75, 188092.75, 536970.75, 188077.25, 536970.75, 188035.75, 536970.75, 188003.25, - 536970.75, 188133.25, 536970.75, 188084.25, 536970.75, 188106.75, 536970.75, 188107.25, - 536970.75, 188142.75, 536970.75, 188015.25, 536970.75, 187934.25, 536970.75, 187959.25, - 536970.75, 187971.75, 536970.75, 188108.25, 536970.75, 188075.25, 536970.75, 188037.25, - 536970.75, 188004.75, 536970.75, 188047.75, 536970.75, 188049.75, 536970.75, 188130.75, - 536970.75, 187935.75, 536970.75, 188037.75, 536970.75, 188012.75, 536970.75, 188073.75, - 536970.75, 187911.75, 536970.75, 188110.75, 536970.75, 187934.75, 536970.75, 188011.75, - 536970.75, 188112.25, 536970.75, 187922.75, 536970.75, 187971.25, 536970.75, 188129.75, - 536970.75, 188112.75, 536970.75, 187923.75, 536970.75, 188094.25, 536970.75, 187937.25, - 536970.75, 188060.75, 536970.75, 187973.75, 536970.75, 188116.25, 536970.75, 188048.75, - 536970.75, 188144.75, 536970.75, 188115.75, 536970.75, 188114.25, 536970.75, 188114.75, - 536970.75, 188071.75, 536971.25, 187935.25, 536971.25, 187969.25, 536971.25, 188080.75, - 536971.25, 188114.25, 536971.25, 187970.75, 536971.25, 188113.75, 536971.25, 187915.25, - 536971.25, 188027.25, 536971.25, 188148.25, 536971.25, 188058.25, 536971.25, 187912.75, - 536971.25, 187915.75, 536971.25, 188080.25, 536971.25, 188113.25, 536971.25, 188091.25, - 536971.25, 188101.25, 536971.25, 188052.75, 536971.25, 188049.25, 536971.25, 188065.75, - 536971.25, 188064.25, 536971.25, 187949.75, 536971.25, 187926.75, 536971.25, 188094.75, - 536971.25, 187976.25, 536971.25, 188103.25, 536971.25, 188092.25, 536971.25, 187969.75, - 536971.25, 188041.25, 536971.25, 187996.75, 536971.25, 188001.25, 536971.25, 188073.25, - 536971.25, 188130.25, 536971.25, 188137.75, 536971.25, 188103.75, 536971.25, 188121.75, - 536971.25, 188002.25, 536971.25, 188104.25, 536971.25, 188012.75, 536971.25, 188059.25, - 536971.25, 187975.25, 536971.25, 188134.75, 536971.25, 188105.25, 536971.25, 188074.75, - 536971.25, 188013.75, 536971.25, 187993.25, 536971.25, 188027.75, 536971.25, 188049.75, - 536971.25, 188145.25, 536971.25, 187973.25, 536971.25, 188105.75, 536971.25, 187974.75, - 536971.25, 187914.25, 536971.25, 187916.25, 536971.25, 188075.75, 536971.25, 188149.75, - 536971.25, 188127.25, 536971.25, 187950.75, 536971.25, 188106.75, 536971.25, 188131.25, - 536971.25, 188096.75, 536971.25, 187971.75, 536971.25, 188042.25, 536971.25, 188060.25, - 536971.25, 188076.75, 536971.25, 187970.25, 536971.25, 187998.25, 536971.25, 187998.75, - 536971.25, 187922.25, 536971.25, 187994.25, 536971.75, 188096.25, 536971.75, 188119.75, - 536971.75, 188076.25, 536971.75, 188036.25, 536971.75, 188050.25, 536971.75, 188046.75, - 536971.75, 188056.75, 536971.75, 187994.75, 536971.75, 187950.75, 536971.75, 188090.25, - 536971.75, 187914.25, 536971.75, 187997.75, 536971.75, 188003.25, 536971.75, 188150.25, - 536971.75, 188092.75, 536971.75, 188075.25, 536971.75, 188120.75, 536971.75, 187968.75, - 536971.75, 188095.25, 536971.75, 188028.25, 536971.75, 187993.25, 536971.75, 188077.75, - 536971.75, 188002.75, 536971.75, 188013.25, 536971.75, 188105.25, 536971.75, 187913.25, - 536971.75, 188054.75, 536971.75, 187950.25, 536971.75, 188104.75, 536971.75, 187928.25, - 536971.75, 187997.25, 536971.75, 188118.25, 536971.75, 187990.25, 536971.75, 187926.25, - 536971.75, 187951.25, 536971.75, 187972.25, 536971.75, 188145.25, 536971.75, 187968.25, - 536971.75, 188001.75, 536971.75, 188128.75, 536971.75, 188148.75, 536971.75, 188046.25, - 536971.75, 188012.25, 536971.75, 188011.75, 536971.75, 188066.25, 536971.75, 188055.25, - 536971.75, 188112.25, 536971.75, 188082.25, 536971.75, 187922.75, 536971.75, 188102.75, - 536971.75, 188092.25, 536971.75, 187926.75, 536971.75, 187913.75, 536971.75, 187996.75, - 536971.75, 188064.25, 536971.75, 188028.75, 536971.75, 188094.75, 536971.75, 188102.25, - 536971.75, 188070.25, 536971.75, 188129.75, 536971.75, 188079.25, 536971.75, 188049.25, - 536971.75, 188101.75, 536971.75, 188112.75, 536971.75, 188101.25, 536971.75, 187999.25, - 536971.75, 188061.75, 536971.75, 188000.75, 536971.75, 187991.75, 536971.75, 187927.25, - 536971.75, 187999.75, 536971.75, 187977.25, 536971.75, 188091.75, 536971.75, 188100.75, - 536971.75, 188065.25, 536971.75, 187927.75, 536971.75, 187933.25, 536971.75, 187914.75, - 536971.75, 188145.75, 536971.75, 187923.75, 536971.75, 188147.25, 536971.75, 188020.75, - 536971.75, 187970.75, 536971.75, 188000.25, 536971.75, 188100.25, 536971.75, 188080.75, - 536971.75, 188144.75, 536971.75, 187923.25, 536971.75, 188064.75, 536972.25, 187971.75, - 536972.25, 188061.75, 536972.25, 188096.25, 536972.25, 188076.25, 536972.25, 188100.25, - 536972.25, 188027.25, 536972.25, 188123.75, 536972.25, 187934.25, 536972.25, 188080.75, - 536972.25, 187969.25, 536972.25, 188065.25, 536972.25, 187950.75, 536972.25, 187944.75, - 536972.25, 187993.75, 536972.25, 188035.75, 536972.25, 188000.75, 536972.25, 188036.75, - 536972.25, 187999.25, 536972.25, 188092.25, 536972.25, 188014.75, 536972.25, 188075.25, - 536972.25, 188066.25, 536972.25, 188077.25, 536972.25, 188151.75, 536972.25, 188130.75, - 536972.25, 187933.25, 536972.25, 187927.75, 536972.25, 187969.75, 536972.25, 188100.75, - 536972.25, 188021.75, 536972.25, 187991.25, 536972.25, 187977.25, 536972.25, 188095.25, - 536972.25, 188046.25, 536972.25, 187973.25, 536972.25, 188013.25, 536972.25, 188001.75, - 536972.25, 188090.75, 536972.25, 187968.25, 536972.25, 187921.75, 536972.25, 188054.75, - 536972.25, 188002.75, 536972.25, 188067.75, 536972.25, 188027.75, 536972.25, 188049.75, - 536972.25, 188012.25, 536972.25, 187910.75, 536972.25, 188003.25, 536972.25, 188063.75, - 536972.25, 188046.75, 536972.25, 187913.25, 536972.25, 187998.25, 536972.25, 188105.25, - 536972.25, 187970.25, 536972.25, 188049.25, 536972.25, 188011.25, 536972.25, 187950.25, - 536972.25, 188150.75, 536972.25, 187912.75, 536972.25, 187968.75, 536972.25, 187913.75, - 536972.25, 187992.75, 536972.25, 188028.75, 536972.25, 187926.25, 536972.25, 188129.75, - 536972.25, 188094.25, 536972.25, 188145.25, 536972.25, 188128.75, 536972.25, 188104.25, - 536972.25, 187990.75, 536972.25, 188093.25, 536972.25, 187976.25, 536972.25, 187922.75, - 536972.25, 188103.75, 536972.25, 187996.75, 536972.25, 187966.75, 536972.25, 187914.75, - 536972.25, 187926.75, 536972.25, 188147.75, 536972.25, 188102.75, 536972.25, 188160.25, - 536972.25, 188050.25, 536972.25, 187923.25, 536972.25, 188082.25, 536972.25, 188129.25, - 536972.25, 188061.25, 536972.25, 187970.75, 536972.75, 188061.25, 536972.75, 188129.25, - 536972.75, 187923.25, 536972.75, 187919.25, 536972.75, 188048.75, 536972.75, 188082.25, - 536972.75, 188144.75, 536972.75, 188102.75, 536972.75, 187967.75, 536972.75, 188078.75, - 536972.75, 188093.25, 536972.75, 188022.75, 536972.75, 187911.75, 536972.75, 188127.75, - 536972.75, 188113.75, 536972.75, 188028.25, 536972.75, 188028.75, 536972.75, 188060.75, - 536972.75, 188118.75, 536972.75, 188148.25, 536972.75, 188062.75, 536972.75, 187923.75, - 536972.75, 188152.25, 536972.75, 188041.75, 536972.75, 188010.25, 536972.75, 188025.25, - 536972.75, 187997.75, 536972.75, 187950.25, 536972.75, 188127.25, 536972.75, 188151.25, - 536972.75, 188042.25, 536972.75, 187970.25, 536972.75, 188090.25, 536972.75, 188022.25, - 536972.75, 187988.75, 536972.75, 188111.25, 536972.75, 188003.25, 536972.75, 188092.75, - 536972.75, 188148.75, 536972.75, 188090.75, 536972.75, 187951.25, 536972.75, 188012.75, - 536972.75, 187975.25, 536972.75, 187993.25, 536972.75, 188057.25, 536972.75, 188095.25, - 536972.75, 187913.25, 536972.75, 188001.75, 536972.75, 187927.25, 536972.75, 188001.25, - 536972.75, 188050.75, 536972.75, 188109.75, 536972.75, 187969.75, 536972.75, 188097.25, - 536972.75, 188013.75, 536972.75, 188056.75, 536972.75, 188142.25, 536972.75, 188064.25, - 536972.75, 187991.75, 536972.75, 187966.25, 536972.75, 188143.25, 536972.75, 188000.75, - 536972.75, 188075.75, 536972.75, 188045.75, 536972.75, 187999.75, 536972.75, 188095.75, - 536972.75, 188055.25, 536972.75, 187967.25, 536972.75, 187928.75, 536972.75, 188099.75, - 536972.75, 188000.25, 536972.75, 188064.75, 536972.75, 187994.25, 536972.75, 188100.25, - 536973.25, 187923.75, 536973.25, 188056.25, 536973.25, 188144.75, 536973.25, 188071.75, - 536973.25, 187988.75, 536973.25, 188064.75, 536973.25, 188078.25, 536973.25, 188082.75, - 536973.25, 187975.75, 536973.25, 188048.75, 536973.25, 188144.25, 536973.25, 188045.25, - 536973.25, 188018.75, 536973.25, 188076.25, 536973.25, 188028.75, 536973.25, 187976.25, - 536973.25, 188060.25, 536973.25, 188091.75, 536973.25, 188145.75, 536973.25, 188006.25, - 536973.25, 188089.25, 536973.25, 188143.25, 536973.25, 188076.75, 536973.25, 187999.75, - 536973.25, 188017.75, 536973.25, 188096.75, 536973.25, 188148.25, 536973.25, 188020.75, - 536973.25, 188091.25, 536973.25, 188040.75, 536973.25, 187950.75, 536973.25, 188072.25, - 536973.25, 188044.75, 536973.25, 187990.25, 536973.25, 188092.25, 536973.25, 187965.75, - 536973.25, 187912.25, 536973.25, 187967.25, 536973.25, 187996.75, 536973.25, 187928.25, - 536973.25, 187966.75, 536973.25, 188036.75, 536973.25, 188100.75, 536973.25, 188149.75, - 536973.25, 187951.75, 536973.25, 188059.75, 536973.25, 188102.25, 536973.25, 188142.25, - 536973.25, 188134.75, 536973.25, 188093.25, 536973.25, 187914.25, 536973.25, 188118.25, - 536973.25, 188062.25, 536973.25, 188127.75, 536973.25, 188141.25, 536973.25, 188001.25, - 536973.25, 188028.25, 536973.25, 188014.25, 536973.25, 188047.75, 536973.25, 188041.75, - 536973.25, 188153.25, 536973.25, 188047.25, 536973.25, 188101.25, 536973.25, 187954.75, - 536973.25, 187924.25, 536973.25, 188002.25, 536973.25, 188088.25, 536973.25, 188057.75, - 536973.25, 188150.25, 536973.25, 188013.75, 536973.25, 188081.75, 536973.25, 188063.25, - 536973.25, 188042.25, 536973.25, 187987.75, 536973.25, 188148.75, 536973.25, 188126.75, - 536973.25, 188119.25, 536973.25, 188146.75, 536973.25, 187922.25, 536973.25, 188068.25, - 536973.25, 188003.75, 536973.25, 188013.25, 536973.25, 188077.75, 536973.25, 188029.25, - 536973.25, 188037.75, 536973.25, 188125.75, 536973.25, 188046.75, 536973.25, 188101.75, - 536973.25, 187929.75, 536973.25, 188079.75, 536973.25, 188063.75, 536973.75, 188012.75, - 536973.75, 188003.25, 536973.75, 188079.75, 536973.75, 188077.75, 536973.75, 188037.75, - 536973.75, 188013.25, 536973.75, 187925.75, 536973.75, 188029.25, 536973.75, 188152.75, - 536973.75, 188126.75, 536973.75, 188125.75, 536973.75, 187968.25, 536973.75, 188130.75, - 536973.75, 188043.25, 536973.75, 188057.75, 536973.75, 188002.75, 536973.75, 188127.25, - 536973.75, 188088.25, 536973.75, 188013.75, 536973.75, 188146.25, 536973.75, 188056.75, - 536973.75, 187924.25, 536973.75, 188049.75, 536973.75, 188063.25, 536973.75, 188101.25, - 536973.75, 188151.25, 536973.75, 187997.75, 536973.75, 188028.25, 536973.75, 188024.75, - 536973.75, 188086.25, 536973.75, 188062.75, 536973.75, 187929.25, 536973.75, 187992.25, - 536973.75, 188001.75, 536973.75, 188092.75, 536973.75, 188127.75, 536973.75, 188142.25, - 536973.75, 188049.25, 536973.75, 188059.75, 536973.75, 187927.75, 536973.75, 187965.25, - 536973.75, 188062.25, 536973.75, 188093.25, 536973.75, 187967.25, 536973.75, 187966.75, - 536973.75, 187969.75, 536973.75, 187914.25, 536973.75, 187966.25, 536973.75, 188089.75, - 536973.75, 187940.75, 536973.75, 187951.75, 536973.75, 188149.75, 536973.75, 188069.75, - 536973.75, 187990.25, 536973.75, 188100.75, 536973.75, 187912.75, 536973.75, 187965.75, - 536973.75, 188056.25, 536973.75, 188025.75, 536973.75, 187923.75, 536973.75, 188030.25, - 536973.75, 187996.75, 536973.75, 188095.75, 536973.75, 188044.75, 536973.75, 188091.25, - 536973.75, 188082.25, 536973.75, 187950.75, 536973.75, 188100.25, 536973.75, 187999.75, - 536973.75, 187928.25, 536973.75, 188045.75, 536973.75, 187953.25, 536973.75, 188055.25, - 536973.75, 188060.25, 536973.75, 188076.25, 536973.75, 188045.25, 536973.75, 188116.75, - 536973.75, 188140.75, 536973.75, 188144.25, 536973.75, 187923.25, 536973.75, 188000.25, - 536973.75, 188039.75, 536973.75, 188091.75, 536973.75, 188144.75, 536973.75, 188096.75, - 536973.75, 187989.75, 536973.75, 188078.25, 536973.75, 188064.75, 536974.25, 188064.75, - 536974.25, 188063.75, 536974.25, 187989.75, 536974.25, 188000.25, 536974.25, 188080.75, - 536974.25, 188076.75, 536974.25, 187925.25, 536974.25, 188078.25, 536974.25, 188124.25, - 536974.25, 188099.75, 536974.25, 188139.25, 536974.25, 188092.25, 536974.25, 187963.75, - 536974.25, 187965.75, 536974.25, 188135.25, 536974.25, 187952.25, 536974.25, 188064.25, - 536974.25, 188036.75, 536974.25, 188151.75, 536974.25, 187986.25, 536974.25, 188141.75, - 536974.25, 188048.75, 536974.25, 188122.25, 536974.25, 187999.25, 536974.25, 188125.25, - 536974.25, 188014.25, 536974.25, 188093.75, 536974.25, 187927.25, 536974.25, 188077.25, - 536974.25, 188095.75, 536974.25, 188061.25, 536974.25, 188028.75, 536974.25, 188125.75, - 536974.25, 188090.75, 536974.25, 187921.75, 536974.25, 188002.75, 536974.25, 188059.75, - 536974.25, 187988.25, 536974.25, 188067.75, 536974.25, 188101.75, 536974.25, 188110.25, - 536974.25, 188147.25, 536974.25, 188019.75, 536974.25, 187951.25, 536974.25, 188090.25, - 536974.25, 187914.75, 536974.25, 187998.75, 536974.25, 188126.25, 536974.25, 188143.75, - 536974.25, 187987.75, 536974.25, 187923.75, 536974.25, 187998.25, 536974.25, 187967.75, - 536974.25, 188146.75, 536974.25, 187912.25, 536974.25, 188139.75, 536974.25, 188047.25, - 536974.25, 188151.25, 536974.25, 188041.25, 536974.25, 188089.75, 536974.25, 188028.25, - 536974.25, 187922.75, 536974.25, 187913.75, 536974.25, 187964.25, 536974.25, 188098.75, - 536974.25, 188093.25, 536974.25, 187965.25, 536974.25, 188060.75, 536974.25, 188102.25, - 536974.25, 188038.75, 536974.25, 188062.25, 536974.75, 188112.75, 536974.75, 188049.25, - 536974.75, 188050.25, 536974.75, 188115.25, 536974.75, 188098.75, 536974.75, 188102.25, - 536974.75, 188081.25, 536974.75, 188023.25, 536974.75, 188139.25, 536974.75, 187910.75, - 536974.75, 188137.75, 536974.75, 187920.75, 536974.75, 188047.75, 536974.75, 188064.75, - 536974.75, 188094.75, 536974.75, 188055.25, 536974.75, 188098.25, 536974.75, 188015.25, - 536974.75, 188143.25, 536974.75, 187964.25, 536974.75, 188076.75, 536974.75, 188088.75, - 536974.75, 188004.75, 536974.75, 188160.25, 536974.75, 188140.25, 536974.75, 187951.75, - 536974.75, 188028.25, 536974.75, 188096.25, 536974.75, 188134.75, 536974.75, 188124.25, - 536974.75, 188065.25, 536974.75, 188115.75, 536974.75, 188123.75, 536974.75, 187962.75, - 536974.75, 188032.75, 536974.75, 188071.25, 536974.75, 187925.25, 536974.75, 188000.75, - 536974.75, 188099.75, 536974.75, 188092.25, 536974.75, 188028.75, 536974.75, 188138.75, - 536974.75, 188124.75, 536974.75, 187998.25, 536974.75, 187963.75, 536974.75, 187923.75, - 536974.75, 187988.25, 536974.75, 188053.25, 536974.75, 188143.75, 536974.75, 188091.25, - 536974.75, 188123.25, 536974.75, 188044.75, 536974.75, 187927.75, 536974.75, 187922.25, - 536974.75, 188122.75, 536974.75, 187998.75, 536974.75, 188138.25, 536974.75, 187991.75, - 536974.75, 188090.25, 536974.75, 187952.75, 536974.75, 188003.75, 536974.75, 187965.75, - 536974.75, 187915.25, 536974.75, 187993.75, 536974.75, 187966.25, 536974.75, 187921.25, - 536974.75, 188064.25, 536974.75, 187967.25, 536974.75, 187923.25, 536974.75, 188147.75, - 536974.75, 188077.75, 536974.75, 188095.25, 536974.75, 188014.75, 536974.75, 188055.75, - 536974.75, 187987.25, 536974.75, 187996.25, 536974.75, 188013.25, 536974.75, 188003.25, - 536974.75, 188141.75, 536974.75, 188048.75, 536974.75, 188057.25, 536974.75, 188046.25, - 536974.75, 188120.75, 536974.75, 187963.25, 536974.75, 188101.75, 536974.75, 187995.25, - 536974.75, 188061.75, 536974.75, 188109.75, 536974.75, 188043.25, 536974.75, 188103.25, - 536974.75, 188122.25, 536974.75, 188013.75, 536974.75, 187984.75, 536974.75, 188140.75, - 536974.75, 188103.75, 536974.75, 187928.25, 536974.75, 187985.75, 536974.75, 188061.25, - 536974.75, 188121.75, 536974.75, 188067.25, 536974.75, 187920.25, 536974.75, 188090.75, - 536974.75, 188125.75, 536974.75, 188135.75, 536974.75, 188002.25, 536974.75, 188146.25, - 536974.75, 188029.75, 536975.25, 188138.25, 536975.25, 188002.25, 536975.25, 188043.75, - 536975.25, 188109.25, 536975.25, 188125.75, 536975.25, 187920.25, 536975.25, 188097.25, - 536975.25, 188090.75, 536975.25, 188141.75, 536975.25, 188137.25, 536975.25, 188121.25, - 536975.25, 187984.75, 536975.25, 188029.75, 536975.25, 188056.75, 536975.25, 188048.75, - 536975.25, 188002.75, 536975.25, 188122.25, 536975.25, 188013.75, 536975.25, 188101.75, - 536975.25, 187923.75, 536975.25, 188120.75, 536975.25, 187962.75, 536975.25, 188003.25, - 536975.25, 188094.25, 536975.25, 187923.25, 536975.25, 188014.75, 536975.25, 188039.25, - 536975.25, 188077.75, 536975.25, 188063.75, 536975.25, 188046.75, 536975.25, 187966.25, - 536975.25, 188001.25, 536975.25, 188046.25, 536975.25, 188157.25, 536975.25, 187951.25, - 536975.25, 187921.25, 536975.25, 188147.25, 536975.25, 188143.75, 536975.25, 188091.75, - 536975.25, 187915.25, 536975.25, 188100.75, 536975.25, 187965.75, 536975.25, 188003.75, - 536975.25, 188110.75, 536975.25, 188057.25, 536975.25, 187918.75, 536975.25, 188119.75, - 536975.25, 188122.75, 536975.25, 187922.25, 536975.25, 187932.25, 536975.25, 188091.25, - 536975.25, 188073.75, 536975.25, 188044.75, 536975.25, 188090.25, 536975.25, 188106.75, - 536975.25, 187952.75, 536975.25, 187939.25, 536975.25, 187987.75, 536975.25, 188019.75, - 536975.25, 188098.25, 536975.25, 188029.25, 536975.25, 188124.75, 536975.25, 188095.25, - 536975.25, 188139.75, 536975.25, 187963.75, 536975.25, 187964.25, 536975.25, 187986.75, - 536975.25, 188140.75, 536975.25, 187994.75, 536975.25, 187925.25, 536975.25, 188102.25, - 536975.25, 188089.75, 536975.25, 188042.25, 536975.25, 187988.75, 536975.25, 188123.75, - 536975.25, 188134.75, 536975.25, 188049.75, 536975.25, 188080.75, 536975.25, 188113.25, - 536975.25, 188065.25, 536975.25, 188060.75, 536975.25, 188028.25, 536975.25, 188082.25, - 536975.25, 188028.75, 536975.25, 188045.25, 536975.25, 187913.75, 536975.25, 188076.75, - 536975.25, 188041.75, 536975.25, 188100.25, 536975.25, 188081.25, 536975.25, 187951.75, - 536975.25, 188079.25, 536975.25, 187962.25, 536975.25, 188064.75, 536975.25, 188047.75, - 536975.25, 188094.75, 536975.25, 187920.75, 536975.25, 188098.75, 536975.25, 187965.25, - 536975.25, 187911.75, 536975.25, 188050.25, 536975.25, 188138.75, 536975.75, 188103.25, - 536975.75, 188055.25, 536975.75, 188026.75, 536975.75, 187952.25, 536975.75, 188045.25, - 536975.75, 187923.75, 536975.75, 188142.25, 536975.75, 188156.25, 536975.75, 188071.25, - 536975.75, 188092.75, 536975.75, 187951.75, 536975.75, 188049.25, 536975.75, 188027.75, - 536975.75, 188072.75, 536975.75, 187962.25, 536975.75, 188000.75, 536975.75, 188055.75, - 536975.75, 187956.75, 536975.75, 188111.25, 536975.75, 187999.75, 536975.75, 188049.75, - 536975.75, 188110.75, 536975.75, 188014.25, 536975.75, 187914.75, 536975.75, 188157.75, - 536975.75, 188155.75, 536975.75, 187947.25, 536975.75, 187996.75, 536975.75, 188044.75, - 536975.75, 188123.25, 536975.75, 188028.75, 536975.75, 188015.25, 536975.75, 188094.25, - 536975.75, 187983.25, 536975.75, 188001.25, 536975.75, 187994.25, 536975.75, 188094.75, - 536975.75, 188088.75, 536975.75, 187922.75, 536975.75, 188077.25, 536975.75, 187962.75, - 536975.75, 187964.75, 536975.75, 187983.75, 536975.75, 187992.75, 536975.75, 187960.75, - 536975.75, 187953.75, 536975.75, 188078.25, 536975.75, 188001.75, 536975.75, 188121.75, - 536975.75, 188051.75, 536975.75, 188041.75, 536975.75, 188142.75, 536975.75, 187989.75, - 536975.75, 188004.75, 536975.75, 188066.75, 536975.75, 188096.75, 536975.75, 187992.25, - 536975.75, 188097.25, 536975.75, 188138.75, 536975.75, 188136.25, 536975.75, 188120.25, - 536975.75, 188033.75, 536975.75, 188097.75, 536975.75, 188100.75, 536975.75, 188042.25, - 536975.75, 188137.75, 536975.75, 187919.75, 536975.75, 188119.25, 536975.75, 188052.75, - 536975.75, 188146.75, 536975.75, 188004.25, 536975.75, 187986.25, 536975.75, 188099.25, - 536976.25, 187963.25, 536976.25, 188057.75, 536976.25, 188004.25, 536976.25, 188052.75, - 536976.25, 187927.75, 536976.25, 187998.75, 536976.25, 188119.75, 536976.25, 188152.25, - 536976.25, 188083.25, 536976.25, 187915.75, 536976.25, 188058.25, 536976.25, 188136.75, - 536976.25, 188157.25, 536976.25, 188120.25, 536976.25, 188052.25, 536976.25, 187961.25, - 536976.25, 188097.75, 536976.25, 188136.25, 536976.25, 187992.25, 536976.25, 188053.25, - 536976.25, 188004.75, 536976.25, 188078.75, 536976.25, 188158.25, 536976.25, 188142.75, - 536976.25, 188135.75, 536976.25, 187916.75, 536976.25, 188051.75, 536976.25, 188118.75, - 536976.25, 187982.25, 536976.25, 188125.25, 536976.25, 188023.75, 536976.25, 187953.75, - 536976.25, 188096.25, 536976.25, 188069.25, 536976.25, 187999.25, 536976.25, 188059.25, - 536976.25, 187997.25, 536976.25, 187926.25, 536976.25, 187961.75, 536976.25, 187983.75, - 536976.25, 187993.25, 536976.25, 188095.75, 536976.25, 188050.75, 536976.25, 188156.75, - 536976.25, 188133.75, 536976.25, 188016.25, 536976.25, 187989.25, 536976.25, 188077.25, - 536976.25, 188001.75, 536976.25, 188044.25, 536976.25, 188015.75, 536976.25, 188117.75, - 536976.25, 188155.75, 536976.25, 188094.25, 536976.25, 188028.75, 536976.25, 187918.25, - 536976.25, 187925.25, 536976.25, 188093.75, 536976.25, 187959.75, 536976.25, 187953.25, - 536976.25, 188056.25, 536976.25, 188014.25, 536976.25, 187924.75, 536976.25, 187919.25, - 536976.25, 188093.25, 536976.25, 187995.75, 536976.25, 187924.25, 536976.25, 187999.75, - 536976.25, 188065.75, 536976.25, 188028.25, 536976.25, 187981.75, 536976.25, 188055.75, - 536976.25, 188054.75, 536976.25, 188027.75, 536976.25, 187923.25, 536976.25, 188124.25, - 536976.25, 188092.75, 536976.25, 188148.25, 536976.25, 187987.25, 536976.25, 188026.75, - 536976.25, 188147.75, 536976.25, 188000.25, 536976.75, 187915.25, 536976.75, 187982.75, - 536976.75, 187952.25, 536976.75, 187964.25, 536976.75, 187923.75, 536976.75, 188147.75, - 536976.75, 188055.25, 536976.75, 188000.25, 536976.75, 188120.75, 536976.75, 188027.25, - 536976.75, 187952.75, 536976.75, 187923.25, 536976.75, 188112.75, 536976.75, 188157.25, - 536976.75, 188098.25, 536976.75, 188098.75, 536976.75, 188003.75, 536976.75, 187962.25, - 536976.75, 188119.75, 536976.75, 188064.75, 536976.75, 188158.25, 536976.75, 187920.75, - 536976.75, 188052.75, 536976.75, 188057.25, 536976.75, 188022.25, 536976.75, 188154.75, - 536976.75, 187963.25, 536976.75, 187995.75, 536976.75, 188073.75, 536976.75, 187919.25, - 536976.75, 188092.75, 536976.75, 188004.25, 536976.75, 188142.75, 536976.75, 188014.25, - 536976.75, 187953.25, 536976.75, 188124.25, 536976.75, 188027.75, 536976.75, 188120.25, - 536976.75, 187914.25, 536976.75, 188065.25, 536976.75, 187959.25, 536976.75, 188096.25, - 536976.75, 188108.25, 536976.75, 188058.25, 536976.75, 187963.75, 536976.75, 187925.25, - 536976.75, 187994.75, 536976.75, 188055.75, 536976.75, 188000.75, 536976.75, 188093.25, - 536976.75, 187934.25, 536976.75, 188076.25, 536976.75, 188090.25, 536976.75, 187927.75, - 536976.75, 188015.25, 536976.75, 188100.25, 536976.75, 188119.25, 536976.75, 188107.25, - 536976.75, 188136.75, 536976.75, 188117.75, 536976.75, 188100.75, 536976.75, 187999.75, - 536976.75, 188141.25, 536976.75, 187985.25, 536976.75, 188056.25, 536976.75, 187918.25, - 536976.75, 188095.75, 536976.75, 188016.25, 536976.75, 188089.75, 536976.75, 188025.75, - 536976.75, 187916.75, 536976.75, 188145.25, 536976.75, 187959.75, 536976.75, 188133.75, - 536976.75, 188095.25, 536976.75, 187961.25, 536976.75, 188050.75, 536976.75, 188044.25, - 536976.75, 188004.75, 536976.75, 188078.75, 536976.75, 188093.75, 536976.75, 188025.25, - 536976.75, 188077.75, 536976.75, 187997.25, 536976.75, 188157.75, 536976.75, 188127.75, - 536976.75, 188154.25, 536976.75, 188103.75, 536976.75, 188066.25, 536976.75, 188118.25, - 536976.75, 188051.75, 536976.75, 188058.75, 536976.75, 187953.75, 536976.75, 187992.75, - 536976.75, 188028.75, 536977.25, 188122.75, 536977.25, 187953.75, 536977.25, 188140.75, - 536977.25, 187917.75, 536977.25, 188135.25, 536977.25, 188160.25, 536977.25, 188078.25, - 536977.25, 187961.75, 536977.25, 187960.75, 536977.25, 188066.25, 536977.25, 187982.25, - 536977.25, 187998.25, 536977.25, 187926.25, 536977.25, 188016.75, 536977.25, 188041.75, - 536977.25, 188157.75, 536977.25, 188134.75, 536977.25, 187957.75, 536977.25, 188077.75, - 536977.25, 187925.75, 536977.25, 187910.75, 536977.25, 188079.25, 536977.25, 188106.25, - 536977.25, 188004.75, 536977.25, 188093.75, 536977.25, 188095.25, 536977.25, 188088.25, - 536977.25, 188025.75, 536977.25, 188102.25, 536977.25, 188024.75, 536977.25, 188000.25, - 536977.25, 188079.75, 536977.25, 188124.75, 536977.25, 188016.25, 536977.25, 188119.25, - 536977.25, 188065.75, 536977.25, 188136.75, 536977.25, 188028.25, 536977.25, 188117.75, - 536977.25, 187983.75, 536977.25, 188086.25, 536977.25, 187996.75, 536977.25, 188015.25, - 536977.25, 187925.25, 536977.25, 188054.75, 536977.25, 187995.25, 536977.25, 187999.25, - 536977.25, 187915.75, 536977.25, 188042.25, 536977.25, 187955.25, 536977.25, 187959.25, - 536977.25, 188065.25, 536977.25, 187991.25, 536977.25, 188053.75, 536977.25, 187953.25, - 536977.25, 188142.25, 536977.25, 188004.25, 536977.25, 187917.25, 536977.25, 188137.25, - 536977.25, 188158.25, 536977.25, 188023.75, 536977.25, 188148.75, 536977.25, 188124.25, - 536977.25, 187989.75, 536977.25, 188057.25, 536977.25, 188092.75, 536977.25, 188026.75, - 536977.25, 188116.75, 536977.25, 187981.75, 536977.25, 187962.25, 536977.25, 188085.25, - 536977.25, 188157.25, 536977.25, 187923.25, 536977.25, 188092.25, 536977.25, 188098.25, - 536977.25, 187990.75, 536977.25, 187958.75, 536977.25, 188002.25, 536977.25, 188138.25, - 536977.25, 188153.75, 536977.25, 188097.25, 536977.25, 188053.25, 536977.25, 188097.75, - 536977.25, 187952.75, 536977.25, 187923.75, 536977.25, 188155.25, 536977.75, 188023.25, - 536977.75, 187990.25, 536977.75, 188152.75, 536977.75, 187948.75, 536977.75, 187982.75, - 536977.75, 188043.25, 536977.75, 187954.25, 536977.75, 188138.25, 536977.75, 188096.75, - 536977.75, 188137.75, 536977.75, 187998.75, 536977.75, 188052.75, 536977.75, 188057.75, - 536977.75, 188126.25, 536977.75, 188099.25, 536977.75, 188004.25, 536977.75, 188066.75, - 536977.75, 187991.25, 536977.75, 187963.25, 536977.75, 187954.75, 536977.75, 188139.25, - 536977.75, 188125.25, 536977.75, 188081.75, 536977.75, 188115.25, 536977.75, 187915.75, - 536977.75, 188143.25, 536977.75, 188024.25, 536977.75, 188042.25, 536977.75, 188153.25, - 536977.75, 188086.25, 536977.75, 188091.75, 536977.75, 188020.75, 536977.75, 188033.75, - 536977.75, 188087.25, 536977.75, 188056.75, 536977.75, 188119.25, 536977.75, 187916.75, - 536977.75, 188139.75, 536977.75, 188079.75, 536977.75, 187986.75, 536977.75, 188004.75, - 536977.75, 187983.75, 536977.75, 187961.25, 536977.75, 188044.25, 536977.75, 188136.25, - 536977.75, 187958.25, 536977.75, 188025.25, 536977.75, 187997.75, 536977.75, 188018.75, - 536977.75, 188135.75, 536977.75, 188041.75, 536977.75, 187960.75, 536977.75, 188078.25, - 536977.75, 188051.25, 536977.75, 188157.75, 536977.75, 188059.25, 536977.75, 187988.75, - 536977.75, 188140.75, 536977.75, 188005.25, 536977.75, 188016.75, 536977.75, 188094.25, - 536977.75, 187957.75, 536977.75, 187997.25, 536977.75, 188156.75, 536977.75, 188050.75, - 536977.75, 187993.75, 536977.75, 187911.75, 536977.75, 188118.25, 536977.75, 188077.25, - 536977.75, 187999.75, 536977.75, 187994.25, 536977.75, 188054.25, 536977.75, 188041.25, - 536977.75, 188005.75, 536977.75, 188155.75, 536977.75, 188015.75, 536977.75, 188060.25, - 536977.75, 187996.75, 536977.75, 188026.25, 536977.75, 188065.75, 536977.75, 187957.25, - 536977.75, 187994.75, 536977.75, 188054.75, 536977.75, 187925.25, 536977.75, 188149.75, - 536977.75, 188123.75, 536977.75, 188117.75, 536977.75, 187916.25, 536977.75, 188141.75, - 536977.75, 188014.75, 536977.75, 187960.25, 536977.75, 188061.75, 536977.75, 188013.75, - 536977.75, 188045.25, 536977.75, 187924.75, 536977.75, 188070.75, 536977.75, 188148.75, - 536977.75, 188117.25, 536977.75, 187924.25, 536977.75, 187953.25, 536977.75, 188116.75, - 536977.75, 188072.75, 536977.75, 188038.75, 536977.75, 188039.25, 536977.75, 188115.75, - 536977.75, 188148.25, 536977.75, 188055.25, 536978.25, 188098.25, 536978.25, 187916.25, - 536978.25, 188140.75, 536978.25, 188041.25, 536978.25, 187992.25, 536978.25, 188033.75, - 536978.25, 187992.75, 536978.25, 188051.25, 536978.25, 188058.75, 536978.25, 188039.25, - 536978.25, 188155.75, 536978.25, 187928.25, 536978.25, 188023.75, 536978.25, 188101.25, - 536978.25, 187911.75, 536978.25, 188095.25, 536978.25, 188025.75, 536978.25, 187958.25, - 536978.25, 188057.75, 536978.25, 188118.75, 536978.25, 188013.25, 536978.25, 188087.25, - 536978.25, 188076.25, 536978.25, 188057.25, 536978.25, 188123.75, 536978.25, 188070.75, - 536978.25, 188045.25, 536978.25, 188066.75, 536978.25, 188139.25, 536978.25, 188141.75, - 536978.25, 188086.25, 536978.25, 188156.75, 536978.25, 188056.75, 536978.25, 188014.75, - 536978.25, 188143.75, 536978.25, 188103.75, 536978.25, 188138.75, 536978.25, 187993.75, - 536978.25, 188085.75, 536978.25, 188115.25, 536978.25, 187954.75, 536978.25, 187962.75, - 536978.25, 188117.75, 536978.25, 188022.75, 536978.25, 188015.25, 536978.25, 188137.75, - 536978.25, 188125.25, 536978.25, 188037.25, 536978.25, 188015.75, 536978.25, 187925.25, - 536978.25, 187958.75, 536978.25, 188153.75, 536978.25, 187960.25, 536978.25, 188077.75, - 536978.25, 188024.25, 536978.25, 188148.25, 536978.25, 188157.75, 536978.25, 188044.25, - 536978.25, 188078.25, 536978.25, 187998.75, 536978.25, 187990.25, 536978.25, 187957.25, - 536978.25, 188085.25, 536978.25, 188055.25, 536978.25, 188016.75, 536978.25, 188060.25, - 536978.25, 188091.25, 536978.25, 188096.25, 536978.25, 188002.25, 536978.25, 188115.75, - 536978.25, 188066.25, 536978.25, 188054.75, 536978.25, 188136.75, 536978.25, 188091.75, - 536978.25, 188148.75, 536978.25, 187997.75, 536978.25, 188099.75, 536978.25, 188054.25, - 536978.25, 187959.25, 536978.25, 188022.25, 536978.25, 188064.25, 536978.25, 188042.75, - 536978.25, 187921.25, 536978.25, 187981.75, 536978.25, 188136.25, 536978.25, 187915.75, - 536978.25, 188092.75, 536978.25, 187988.75, 536978.25, 188006.25, 536978.25, 188004.75, - 536978.25, 188065.75, 536978.25, 188024.75, 536978.25, 188048.25, 536978.25, 187995.75, - 536978.25, 187953.25, 536978.25, 187982.75, 536978.25, 188116.75, 536978.25, 188025.25, - 536978.25, 188038.25, 536978.25, 187914.25, 536978.25, 187927.25, 536978.25, 188153.25, - 536978.25, 188135.75, 536978.25, 188080.25, 536978.25, 188093.25, 536978.25, 187956.25, - 536978.25, 188052.75, 536978.25, 187924.25, 536978.25, 187997.25, 536978.25, 188026.25, - 536978.25, 187915.25, 536978.75, 188135.25, 536978.75, 188156.25, 536978.75, 188149.75, - 536978.75, 188113.75, 536978.75, 187996.25, 536978.75, 187997.25, 536978.75, 188023.25, - 536978.75, 188058.75, 536978.75, 188052.75, 536978.75, 187992.75, 536978.75, 187956.25, - 536978.75, 188039.25, 536978.75, 188155.75, 536978.75, 188154.25, 536978.75, 187914.75, - 536978.75, 187928.25, 536978.75, 187927.25, 536978.75, 188042.25, 536978.75, 187986.25, - 536978.75, 188139.75, 536978.75, 188114.25, 536978.75, 188074.25, 536978.75, 188057.25, - 536978.75, 188021.75, 536978.75, 188043.25, 536978.75, 188045.25, 536978.75, 188146.75, - 536978.75, 187924.75, 536978.75, 188134.75, 536978.75, 188126.75, 536978.75, 187991.25, - 536978.75, 188133.25, 536978.75, 188043.75, 536978.75, 188139.25, 536978.75, 188086.25, - 536978.75, 188105.25, 536978.75, 187996.75, 536978.75, 188014.75, 536978.75, 188005.75, - 536978.75, 187954.25, 536978.75, 188083.75, 536978.75, 188090.25, 536978.75, 188056.75, - 536978.75, 187995.25, 536978.75, 188076.75, 536978.75, 188143.75, 536978.75, 187953.25, - 536978.75, 188079.75, 536978.75, 188085.75, 536978.75, 188115.25, 536978.75, 188096.75, - 536978.75, 188152.25, 536978.75, 187947.75, 536978.75, 187986.75, 536978.75, 187954.75, - 536978.75, 187925.25, 536978.75, 187958.75, 536978.75, 188030.25, 536978.75, 187929.75, - 536978.75, 188006.25, 536978.75, 188077.75, 536978.75, 188041.75, 536978.75, 188024.25, - 536978.75, 188144.25, 536978.75, 187913.75, 536978.75, 188016.25, 536978.75, 188115.75, - 536978.75, 188016.75, 536978.75, 188152.75, 536978.75, 188044.75, 536978.75, 187989.75, - 536978.75, 187917.25, 536978.75, 188091.25, 536978.75, 187956.75, 536978.75, 188038.75, - 536978.75, 187950.25, 536978.75, 188154.75, 536978.75, 187953.75, 536978.75, 188078.75, - 536978.75, 188124.75, 536978.75, 188052.25, 536978.75, 188102.75, 536978.75, 188117.25, - 536978.75, 188084.75, 536978.75, 187917.75, 536978.75, 188092.25, 536979.25, 188112.75, - 536979.25, 188058.25, 536979.25, 188071.75, 536979.25, 188088.25, 536979.25, 187917.75, - 536979.25, 188113.75, 536979.25, 188133.75, 536979.25, 187994.75, 536979.25, 188042.75, - 536979.25, 188075.75, 536979.25, 187989.25, 536979.25, 188046.25, 536979.25, 188017.25, - 536979.25, 188144.75, 536979.25, 187987.75, 536979.25, 188023.25, 536979.25, 188117.25, - 536979.25, 187992.25, 536979.25, 187955.25, 536979.25, 187928.25, 536979.25, 187946.25, - 536979.25, 188147.25, 536979.25, 187914.75, 536979.25, 188140.25, 536979.25, 188096.25, - 536979.25, 187914.25, 536979.25, 188091.75, 536979.25, 188062.75, 536979.25, 188059.25, - 536979.25, 188095.75, 536979.25, 188078.75, 536979.25, 187911.75, 536979.25, 188017.75, - 536979.25, 188113.25, 536979.25, 188027.25, 536979.25, 188005.25, 536979.25, 188022.25, - 536979.25, 188076.25, 536979.25, 187926.75, 536979.25, 188139.75, 536979.25, 187985.75, - 536979.25, 187991.75, 536979.25, 187925.75, 536979.25, 188127.25, 536979.25, 187926.25, - 536979.25, 188040.25, 536979.25, 188067.25, 536979.25, 188150.25, 536979.25, 187924.75, - 536979.25, 188086.75, 536979.25, 188125.75, 536979.25, 188089.75, 536979.25, 188073.75, - 536979.25, 188128.25, 536979.25, 188048.25, 536979.25, 188019.75, 536979.25, 187995.75, - 536979.25, 187916.75, 536979.25, 187927.75, 536979.25, 188045.75, 536979.25, 188119.75, - 536979.25, 188047.75, 536979.25, 188155.25, 536979.25, 188006.75, 536979.25, 188038.25, - 536979.25, 188040.75, 536979.25, 188114.75, 536979.25, 187954.25, 536979.25, 188016.25, - 536979.25, 188090.25, 536979.25, 188149.25, 536979.25, 187957.25, 536979.25, 188076.75, - 536979.25, 187955.75, 536979.25, 187995.25, 536979.25, 188028.75, 536979.25, 188118.25, - 536979.25, 188032.25, 536979.25, 188146.75, 536979.25, 187994.25, 536979.25, 187990.75, - 536979.25, 187993.75, 536979.25, 187949.25, 536979.25, 188143.75, 536979.25, 188039.75, - 536979.25, 187928.75, 536979.25, 188037.25, 536979.25, 188061.75, 536979.25, 187948.25, - 536979.25, 188034.75, 536979.25, 187929.75, 536979.25, 188006.25, 536979.25, 188126.25, - 536979.75, 188126.25, 536979.75, 188144.25, 536979.75, 187915.75, 536979.75, 188100.25, - 536979.75, 188058.25, 536979.75, 188071.75, 536979.75, 188125.25, 536979.75, 188019.25, - 536979.75, 187945.75, 536979.75, 188063.75, 536979.75, 188142.25, 536979.75, 187954.75, - 536979.75, 187948.25, 536979.75, 187928.75, 536979.75, 187925.25, 536979.75, 188033.25, - 536979.75, 188075.75, 536979.75, 188022.75, 536979.75, 188020.25, 536979.75, 188088.25, - 536979.75, 188117.75, 536979.75, 187962.75, 536979.75, 187986.75, 536979.75, 188042.75, - 536979.75, 188047.75, 536979.75, 188067.75, 536979.75, 187955.25, 536979.75, 188039.75, - 536979.75, 187987.25, 536979.75, 188085.75, 536979.75, 188017.25, 536979.75, 187989.25, - 536979.75, 187947.25, 536979.75, 188152.25, 536979.75, 188117.25, 536979.75, 188012.25, - 536979.75, 188058.75, 536979.75, 187994.25, 536979.75, 187993.75, 536979.75, 187949.25, - 536979.75, 188135.25, 536979.75, 188052.75, 536979.75, 188112.75, 536979.75, 188134.25, - 536979.75, 188062.25, 536979.75, 188101.75, 536979.75, 188146.75, 536979.75, 187910.75, - 536979.75, 188001.75, 536979.75, 187928.25, 536979.75, 187995.25, 536979.75, 187955.75, - 536979.75, 188160.25, 536979.75, 188102.25, 536979.75, 188147.25, 536979.75, 187973.75, - 536979.75, 188016.25, 536979.75, 188090.25, 536979.75, 188022.25, 536979.75, 187954.25, - 536979.75, 188038.25, 536979.75, 188048.25, 536979.75, 188114.75, 536979.75, 187914.75, - 536979.75, 188040.75, 536979.75, 188085.25, 536979.75, 188042.25, 536979.75, 188128.75, - 536979.75, 188155.25, 536979.75, 188148.75, 536979.75, 188139.25, 536979.75, 188096.25, - 536979.75, 188153.25, 536979.75, 187927.75, 536979.75, 188122.75, 536979.75, 187944.25, - 536979.75, 187957.75, 536979.75, 188046.25, 536979.75, 188116.75, 536979.75, 188066.75, - 536979.75, 187916.75, 536979.75, 188112.25, 536979.75, 188006.75, 536979.75, 188120.25, - 536979.75, 188129.25, 536979.75, 188076.25, 536979.75, 188125.75, 536979.75, 187917.25, - 536979.75, 187989.75, 536979.75, 188045.25, 536979.75, 188089.75, 536979.75, 188060.25, - 536979.75, 187912.75, 536979.75, 188043.75, 536979.75, 188150.25, 536979.75, 188036.75, - 536979.75, 188057.75, 536979.75, 188091.25, 536979.75, 187924.75, 536979.75, 188052.25, - 536979.75, 187953.75, 536979.75, 187985.75, 536979.75, 187926.75, 536979.75, 187991.75, - 536979.75, 187925.75, 536979.75, 187926.25, 536979.75, 188113.25, 536979.75, 187956.75, - 536979.75, 188005.25, 536979.75, 188139.75, 536980.25, 187929.25, 536980.25, 188136.25, - 536980.25, 188127.25, 536980.25, 188146.25, 536980.25, 188006.25, 536980.25, 188021.25, - 536980.25, 188049.75, 536980.25, 188049.25, 536980.25, 188036.75, 536980.25, 188038.75, - 536980.25, 188060.25, 536980.25, 187924.75, 536980.25, 188125.75, 536980.25, 188076.75, - 536980.25, 188007.75, 536980.25, 188016.75, 536980.25, 188028.25, 536980.25, 188126.75, - 536980.25, 188136.75, 536980.25, 188017.75, 536980.25, 188067.75, 536980.25, 188153.25, - 536980.25, 188039.25, 536980.25, 188132.75, 536980.25, 188035.75, 536980.25, 188098.75, - 536980.25, 188043.75, 536980.25, 188140.25, 536980.25, 188023.75, 536980.25, 188040.25, - 536980.25, 188085.25, 536980.25, 188005.75, 536980.25, 188090.25, 536980.25, 188016.25, - 536980.25, 188129.75, 536980.25, 187918.25, 536980.25, 188111.75, 536980.25, 188086.25, - 536980.25, 188111.25, 536980.25, 188145.75, 536980.25, 187913.25, 536980.25, 187992.25, - 536980.25, 187948.25, 536980.25, 187990.75, 536980.25, 188118.25, 536980.25, 188089.25, - 536980.25, 187993.75, 536980.25, 187994.25, 536980.25, 188058.75, 536980.25, 188148.25, - 536980.25, 188127.75, 536980.25, 188042.75, 536980.25, 187912.25, 536980.25, 187933.75, - 536980.25, 188079.75, 536980.25, 188149.75, 536980.25, 188112.75, 536980.25, 188032.75, - 536980.25, 188024.75, 536980.25, 187946.75, 536980.25, 187955.25, 536980.25, 188028.75, - 536980.25, 188088.25, 536980.25, 188018.25, 536980.25, 187925.25, 536980.25, 188110.75, - 536980.25, 188078.25, 536980.25, 187929.75, 536980.25, 188141.25, 536980.25, 188131.25, - 536980.25, 187945.75, 536980.25, 187954.75, 536980.25, 187956.75, 536980.75, 188033.75, - 536980.75, 188078.75, 536980.75, 188081.25, 536980.75, 187923.25, 536980.75, 188150.75, - 536980.75, 188131.25, 536980.75, 188147.25, 536980.75, 188129.25, 536980.75, 188007.75, - 536980.75, 188041.75, 536980.75, 188112.25, 536980.75, 188136.75, 536980.75, 188058.25, - 536980.75, 187918.25, 536980.75, 187955.25, 536980.75, 188039.25, 536980.75, 188130.25, - 536980.75, 188048.75, 536980.75, 187911.25, 536980.75, 187923.75, 536980.75, 188017.25, - 536980.75, 188084.75, 536980.75, 188037.75, 536980.75, 187944.75, 536980.75, 188021.25, - 536980.75, 188078.25, 536980.75, 188126.25, 536980.75, 188136.25, 536980.75, 188044.75, - 536980.75, 188077.75, 536980.75, 188140.75, 536980.75, 188100.25, 536980.75, 188025.75, - 536980.75, 187930.25, 536980.75, 188088.25, 536980.75, 188072.75, 536980.75, 188128.75, - 536980.75, 188007.25, 536980.75, 188088.75, 536980.75, 188005.75, 536980.75, 187949.25, - 536980.75, 187925.25, 536980.75, 188037.25, 536980.75, 188110.75, 536980.75, 188045.75, - 536980.75, 188087.75, 536980.75, 188085.75, 536980.75, 188023.25, 536980.75, 188117.75, - 536980.75, 188018.25, 536980.75, 188024.25, 536980.75, 187988.25, 536980.75, 187912.25, - 536980.75, 188145.25, 536980.75, 188148.25, 536980.75, 188061.25, 536980.75, 188146.75, - 536980.75, 188031.25, 536980.75, 188149.25, 536980.75, 188068.75, 536980.75, 187948.75, - 536980.75, 188038.25, 536980.75, 188110.25, 536980.75, 187933.25, 536980.75, 188056.75, - 536980.75, 188125.75, 536980.75, 188076.25, 536980.75, 188046.75, 536980.75, 188139.25, - 536980.75, 187929.25, 536980.75, 187917.75, 536980.75, 187993.25, 536980.75, 187927.75, - 536980.75, 187991.25, 536980.75, 188020.25, 536980.75, 188043.25, 536980.75, 188109.75, - 536980.75, 188006.75, 536980.75, 188032.75, 536980.75, 188038.75, 536980.75, 188067.25, - 536980.75, 188059.25, 536980.75, 188159.75, 536980.75, 188087.25, 536980.75, 187918.75, - 536980.75, 187987.75, 536980.75, 188019.25, 536980.75, 188019.75, 536980.75, 188118.75, - 536980.75, 188100.75, 536981.25, 188043.25, 536981.25, 188024.25, 536981.25, 188081.25, - 536981.25, 188041.75, 536981.25, 187928.75, 536981.25, 188019.75, 536981.25, 188048.75, - 536981.25, 187936.75, 536981.25, 188019.25, 536981.25, 187987.75, 536981.25, 187918.25, - 536981.25, 187917.75, 536981.25, 188111.25, 536981.25, 188148.75, 536981.25, 188058.25, - 536981.25, 188136.75, 536981.25, 187917.25, 536981.25, 188087.25, 536981.25, 188016.75, - 536981.25, 188115.75, 536981.25, 188068.25, 536981.25, 188017.25, 536981.25, 187913.25, - 536981.25, 188038.75, 536981.25, 188067.25, 536981.25, 187924.75, 536981.25, 188150.25, - 536981.25, 188074.25, 536981.25, 188147.75, 536981.25, 188123.75, 536981.25, 187923.75, - 536981.25, 188113.25, 536981.25, 187996.75, 536981.25, 188037.75, 536981.25, 187944.75, - 536981.25, 188086.75, 536981.25, 188109.75, 536981.25, 188006.25, 536981.25, 187947.75, - 536981.25, 188032.75, 536981.25, 188098.75, 536981.25, 188078.25, 536981.25, 188126.75, - 536981.25, 188032.25, 536981.25, 188141.25, 536981.25, 188125.75, 536981.25, 188044.75, - 536981.25, 188136.25, 536981.25, 188140.25, 536981.25, 188156.25, 536981.25, 187991.25, - 536981.25, 187993.25, 536981.25, 188110.25, 536981.25, 188140.75, 536981.25, 188109.25, - 536981.25, 188018.25, 536981.25, 188077.75, 536981.25, 188088.25, 536981.25, 187915.75, - 536981.25, 188047.25, 536981.25, 188018.75, 536981.25, 188155.75, 536981.25, 187988.75, - 536981.25, 188088.75, 536981.25, 188007.25, 536981.25, 188022.75, 536981.25, 187922.75, - 536981.25, 188033.25, 536981.25, 187947.25, 536981.25, 188110.75, 536981.25, 187929.75, - 536981.25, 188146.75, 536981.25, 188144.25, 536981.25, 188145.25, 536981.25, 188148.25, - 536981.25, 187992.25, 536981.25, 188037.25, 536981.25, 187990.75, 536981.25, 188061.25, - 536981.25, 187912.25, 536981.25, 188058.75, 536981.25, 188085.75, 536981.25, 188087.75, - 536981.25, 188038.25, 536981.75, 187945.75, 536981.75, 188044.75, 536981.75, 188130.75, - 536981.75, 188136.25, 536981.75, 188023.25, 536981.75, 188151.25, 536981.75, 188138.25, - 536981.75, 188085.75, 536981.75, 187988.75, 536981.75, 188061.75, 536981.75, 187951.75, - 536981.75, 188007.25, 536981.75, 188031.25, 536981.75, 187929.25, 536981.75, 187930.75, - 536981.75, 188077.25, 536981.75, 188001.75, 536981.75, 187937.25, 536981.75, 188068.75, - 536981.75, 188111.75, 536981.75, 187946.75, 536981.75, 188022.25, 536981.75, 188132.25, - 536981.75, 188129.75, 536981.75, 188046.75, 536981.75, 188018.25, 536981.75, 188046.25, - 536981.75, 188128.25, 536981.75, 188126.75, 536981.75, 188097.25, 536981.75, 188036.25, - 536981.75, 188125.75, 536981.75, 188141.25, 536981.75, 188069.25, 536981.75, 188032.25, - 536981.75, 188035.75, 536981.75, 188123.75, 536981.75, 188019.75, 536981.75, 188079.25, - 536981.75, 187919.25, 536981.75, 188142.75, 536981.75, 188112.25, 536981.75, 188145.75, - 536981.75, 188030.75, 536981.75, 188060.75, 536981.75, 188017.75, 536981.75, 188067.75, - 536981.75, 188130.25, 536981.75, 187990.25, 536981.75, 188037.75, 536981.75, 187980.75, - 536981.75, 188047.75, 536981.75, 188033.75, 536981.75, 188113.25, 536981.75, 188108.25, - 536981.75, 187999.75, 536981.75, 187911.25, 536981.75, 187923.75, 536981.75, 188036.75, - 536981.75, 188109.75, 536981.75, 188147.25, 536981.75, 188001.25, 536981.75, 187921.75, - 536981.75, 188085.25, 536981.75, 188087.25, 536981.75, 188131.25, 536981.75, 187911.75, - 536981.75, 187991.75, 536981.75, 187987.25, 536981.75, 188114.25, 536981.75, 187918.75, - 536981.75, 187989.75, 536981.75, 188068.25, 536981.75, 188139.75, 536981.75, 188129.25, - 536981.75, 188007.75, 536981.75, 188151.75, 536981.75, 188058.25, 536981.75, 187980.25, - 536981.75, 188080.25, 536981.75, 188029.75, 536981.75, 187923.25, 536982.25, 188146.25, - 536982.25, 188084.75, 536982.25, 188134.25, 536982.25, 188068.25, 536982.25, 188150.75, - 536982.25, 188021.75, 536982.25, 188156.25, 536982.25, 188050.75, 536982.25, 187919.25, - 536982.25, 188035.25, 536982.25, 188007.75, 536982.25, 188107.25, 536982.25, 188021.25, - 536982.25, 187985.75, 536982.25, 188078.75, 536982.25, 188106.25, 536982.25, 188121.75, - 536982.25, 188054.75, 536982.25, 187989.75, 536982.25, 188141.25, 536982.25, 188113.75, - 536982.25, 187986.75, 536982.25, 187979.75, 536982.25, 188036.25, 536982.25, 188030.25, - 536982.25, 188029.75, 536982.25, 188137.25, 536982.25, 187946.25, 536982.25, 187910.75, - 536982.25, 188151.25, 536982.25, 187945.75, 536982.25, 187936.25, 536982.25, 188046.25, - 536982.25, 188031.25, 536982.25, 187980.75, 536982.25, 187929.25, 536982.25, 188061.75, - 536982.25, 188154.75, 536982.25, 188043.75, 536982.25, 188047.75, 536982.25, 187990.25, - 536982.25, 188044.25, 536982.25, 188020.75, 536982.25, 188048.25, 536982.25, 188008.25, - 536982.25, 188160.25, 536982.25, 188155.75, 536982.25, 188076.25, 536982.25, 188017.75, - 536982.25, 188123.25, 536982.25, 187933.75, 536982.25, 188094.75, 536982.25, 187989.25, - 536982.25, 187938.25, 536982.25, 188097.75, 536982.25, 188020.25, 536982.25, 188082.25, - 536982.25, 188059.25, 536982.25, 188150.25, 536982.25, 188109.75, 536982.25, 188126.25, - 536982.25, 188112.25, 536982.25, 187921.25, 536982.25, 188114.25, 536982.25, 188069.25, - 536982.25, 188124.75, 536982.25, 187947.75, 536982.25, 188022.75, 536982.25, 188151.75, - 536982.25, 188132.75, 536982.25, 187997.25, 536982.25, 188080.25, 536982.25, 187981.75, - 536982.25, 187922.25, 536982.25, 187964.25, 536982.25, 187918.75, 536982.25, 188141.75, - 536982.25, 188135.75, 536982.25, 187930.25, 536982.25, 187921.75, 536982.25, 188036.75, - 536982.25, 187949.75, 536982.25, 188057.25, 536982.25, 188149.25, 536982.25, 188123.75, - 536982.25, 188137.75, 536982.25, 188112.75, 536982.25, 188124.25, 536982.25, 188006.75, - 536982.25, 188034.25, 536982.25, 188034.75, 536982.25, 187919.75, 536982.25, 188043.25, - 536982.25, 187991.25, 536982.25, 188156.75, 536982.25, 187952.25, 536982.25, 188026.75, - 536982.25, 188069.75, 536982.25, 188045.75, 536982.25, 188136.25, 536982.25, 188086.25, - 536982.25, 188131.75, 536982.25, 188047.25, 536982.25, 188045.25, 536982.25, 188111.75, - 536982.25, 188079.75, 536982.25, 188073.25, 536982.25, 187929.75, 536982.25, 188003.25, - 536982.25, 188018.75, 536982.25, 188031.75, 536982.25, 188046.75, 536982.25, 188109.25, - 536982.25, 188152.25, 536982.75, 187932.25, 536982.75, 188099.25, 536982.75, 187920.25, - 536982.75, 188061.25, 536982.75, 188149.75, 536982.75, 188152.25, 536982.75, 188145.25, - 536982.75, 187929.75, 536982.75, 188046.75, 536982.75, 188138.25, 536982.75, 188109.25, - 536982.75, 188044.75, 536982.75, 187989.75, 536982.75, 188095.75, 536982.75, 188058.25, - 536982.75, 187919.25, 536982.75, 187986.25, 536982.75, 188021.75, 536982.75, 188079.75, - 536982.75, 188111.75, 536982.75, 188136.25, 536982.75, 188045.75, 536982.75, 188131.75, - 536982.75, 188150.75, 536982.75, 188068.25, 536982.75, 188112.75, 536982.75, 188035.25, - 536982.75, 188045.25, 536982.75, 188141.25, 536982.75, 188007.75, 536982.75, 188146.25, - 536982.75, 188078.75, 536982.75, 188035.75, 536982.75, 188137.25, 536982.75, 188113.75, - 536982.75, 188034.75, 536982.75, 188106.25, 536982.75, 188125.75, 536982.75, 187986.75, - 536982.75, 187999.75, 536982.75, 188124.25, 536982.75, 188006.75, 536982.75, 187980.75, - 536982.75, 188030.25, 536982.75, 188085.75, 536982.75, 188036.25, 536982.75, 188031.25, - 536982.75, 188034.25, 536982.75, 187979.75, 536982.75, 187932.75, 536982.75, 188058.75, - 536982.75, 188041.25, 536982.75, 188107.75, 536982.75, 188127.75, 536982.75, 188140.75, - 536982.75, 188129.25, 536982.75, 187930.25, 536982.75, 188046.25, 536982.75, 188135.75, - 536982.75, 188136.75, 536982.75, 187929.25, 536982.75, 188019.25, 536982.75, 187990.25, - 536982.75, 188084.75, 536982.75, 188061.75, 536982.75, 187918.75, 536982.75, 188042.25, - 536982.75, 188028.75, 536982.75, 188132.75, 536982.75, 187935.75, 536982.75, 188057.75, - 536982.75, 188072.75, 536982.75, 188048.25, 536982.75, 188020.75, 536982.75, 188151.25, - 536982.75, 187921.25, 536982.75, 188122.75, 536982.75, 187936.75, 536982.75, 187921.75, - 536982.75, 188069.25, 536982.75, 188096.25, 536982.75, 188047.25, 536982.75, 187934.25, - 536982.75, 187938.25, 536982.75, 188126.25, 536982.75, 187911.75, 536982.75, 188150.25, - 536982.75, 188123.25, 536982.75, 188055.75, 536982.75, 187989.25, 536982.75, 188028.25, - 536982.75, 188123.75, 536982.75, 188082.25, 536983.25, 188059.25, 536983.25, 188028.25, - 536983.25, 187994.25, 536983.25, 188145.75, 536983.25, 188070.25, 536983.25, 188150.25, - 536983.25, 187988.25, 536983.25, 188142.75, 536983.25, 188020.25, 536983.25, 187917.75, - 536983.25, 188000.25, 536983.25, 187911.75, 536983.25, 187933.75, 536983.25, 188008.25, - 536983.25, 188114.25, 536983.25, 188151.75, 536983.25, 188026.25, 536983.25, 187931.25, - 536983.25, 188048.25, 536983.25, 188019.75, 536983.25, 187981.75, 536983.25, 188154.75, - 536983.25, 188125.25, 536983.25, 188080.25, 536983.25, 188139.75, 536983.25, 188047.75, - 536983.25, 188155.25, 536983.25, 188004.25, 536983.25, 187952.75, 536983.25, 188108.25, - 536983.25, 188136.75, 536983.25, 187930.25, 536983.25, 187992.75, 536983.25, 188009.25, - 536983.25, 188029.75, 536983.25, 188082.75, 536983.25, 188085.75, 536983.25, 188153.25, - 536983.25, 187920.75, 536983.25, 187932.75, 536983.25, 188125.75, 536983.25, 188034.25, - 536983.25, 187949.75, 536983.25, 187962.25, 536983.25, 188121.25, 536983.25, 188026.75, - 536983.25, 188039.75, 536983.25, 188106.25, 536983.25, 187937.75, 536983.25, 188085.25, - 536983.25, 188045.25, 536983.25, 187986.75, 536983.25, 188121.75, 536983.25, 187920.25, - 536983.25, 187999.75, 536983.25, 188132.25, 536983.25, 188148.75, 536983.25, 187916.75, - 536983.25, 188032.75, 536983.25, 188131.25, 536983.25, 188070.75, 536983.25, 188034.75, - 536983.25, 188126.75, 536983.25, 188128.25, 536983.25, 188007.25, 536983.25, 188141.25, - 536983.25, 187988.75, 536983.25, 188113.75, 536983.25, 188106.75, 536983.25, 187938.75, - 536983.25, 188136.25, 536983.25, 187982.25, 536983.25, 187986.25, 536983.25, 188018.75, - 536983.25, 188069.75, 536983.25, 188044.75, 536983.25, 188030.75, 536983.25, 188124.25, - 536983.25, 187990.75, 536983.25, 187980.25, 536983.25, 188156.75, 536983.75, 188062.25, - 536983.75, 188157.25, 536983.75, 188136.25, 536983.75, 187939.25, 536983.75, 188122.25, - 536983.75, 188068.75, 536983.75, 188053.75, 536983.75, 188105.25, 536983.75, 188060.75, - 536983.75, 188018.25, 536983.75, 187912.75, 536983.75, 188081.25, 536983.75, 188121.25, - 536983.75, 188149.75, 536983.75, 187919.75, 536983.75, 188115.25, 536983.75, 188112.25, - 536983.75, 187916.75, 536983.75, 188070.25, 536983.75, 187918.25, 536983.75, 188078.75, - 536983.75, 187985.75, 536983.75, 188124.75, 536983.75, 188017.75, 536983.75, 188074.25, - 536983.75, 188142.75, 536983.75, 188147.75, 536983.75, 188118.75, 536983.75, 188085.25, - 536983.75, 187934.75, 536983.75, 188105.75, 536983.75, 188114.25, 536983.75, 188028.25, - 536983.75, 188005.75, 536983.75, 188047.75, 536983.75, 188152.75, 536983.75, 188060.25, - 536983.75, 188049.75, 536983.75, 187951.25, 536983.75, 188127.75, 536983.75, 188070.75, - 536983.75, 188138.25, 536983.75, 188129.25, 536983.75, 188007.25, 536983.75, 188108.25, - 536983.75, 188034.75, 536983.75, 188008.25, 536983.75, 188151.25, 536983.75, 187930.75, - 536983.75, 187931.75, 536983.75, 188029.25, 536983.75, 188078.25, 536983.75, 188122.75, - 536983.75, 187978.75, 536983.75, 188125.75, 536983.75, 188061.25, 536983.75, 188088.75, - 536983.75, 188156.25, 536983.75, 188008.75, 536983.75, 188058.25, 536983.75, 188120.75, - 536983.75, 188104.75, 536983.75, 188077.75, 536983.75, 187988.25, 536983.75, 187982.75, - 536983.75, 187946.75, 536983.75, 188146.75, 536983.75, 188033.25, 536983.75, 188136.75, - 536983.75, 188027.75, 536983.75, 187913.75, 536983.75, 187911.25, 536983.75, 188087.75, - 536983.75, 188019.75, 536983.75, 187987.25, 536983.75, 187990.75, 536983.75, 188155.75, - 536983.75, 188130.75, 536983.75, 187933.25, 536983.75, 187934.25, 536983.75, 187914.75, - 536983.75, 187936.75, 536983.75, 188043.25, 536983.75, 187949.25, 536983.75, 187912.25, - 536983.75, 188091.75, 536983.75, 188091.25, 536983.75, 188032.75, 536983.75, 188054.75, - 536983.75, 187995.75, 536983.75, 188094.25, 536983.75, 188113.25, 536983.75, 187998.25, - 536983.75, 188009.75, 536983.75, 188086.25, 536983.75, 188082.75, 536983.75, 188094.75, - 536983.75, 187991.25, 536983.75, 187931.25, 536983.75, 188086.75, 536983.75, 188127.25, - 536983.75, 188141.75, 536983.75, 188009.25, 536983.75, 188049.25, 536983.75, 188107.25, - 536983.75, 188153.25, 536983.75, 188048.75, 536983.75, 187950.25, 536983.75, 188066.25, - 536984.25, 187961.25, 536984.25, 188001.25, 536984.25, 188027.25, 536984.25, 188009.25, - 536984.25, 188119.75, 536984.25, 188153.25, 536984.25, 187929.25, 536984.25, 188003.75, - 536984.25, 188127.25, 536984.25, 188151.75, 536984.25, 188026.75, 536984.25, 187931.25, - 536984.25, 188009.75, 536984.25, 188034.25, 536984.25, 187983.75, 536984.25, 188080.25, - 536984.25, 188038.75, 536984.25, 188082.75, 536984.25, 187935.25, 536984.25, 187917.75, - 536984.25, 188148.75, 536984.25, 188107.75, 536984.25, 187918.25, 536984.25, 188059.25, - 536984.25, 188032.75, 536984.25, 188113.25, 536984.25, 187917.25, 536984.25, 188124.75, - 536984.25, 188158.25, 536984.25, 187978.25, 536984.25, 187983.25, 536984.25, 187912.25, - 536984.25, 187934.25, 536984.25, 187936.75, 536984.25, 187933.25, 536984.25, 188016.25, - 536984.25, 188155.75, 536984.25, 187911.25, 536984.25, 187987.25, 536984.25, 187990.75, - 536984.25, 188120.75, 536984.25, 188106.25, 536984.25, 188113.75, 536984.25, 188022.75, - 536984.25, 188146.75, 536984.25, 188028.75, 536984.25, 188054.25, 536984.25, 188077.75, - 536984.25, 187988.25, 536984.25, 188141.25, 536984.25, 188104.75, 536984.25, 188156.25, - 536984.25, 187930.25, 536984.25, 188061.25, 536984.25, 188008.75, 536984.25, 187954.75, - 536984.25, 188085.75, 536984.25, 188137.75, 536984.25, 187978.75, 536984.25, 187992.75, - 536984.25, 188122.75, 536984.25, 188041.25, 536984.25, 188060.25, 536984.25, 187931.75, - 536984.25, 188121.75, 536984.25, 187948.25, 536984.25, 188151.25, 536984.25, 188061.75, - 536984.25, 188008.25, 536984.25, 188065.75, 536984.25, 187938.25, 536984.25, 188007.25, - 536984.25, 187938.75, 536984.25, 188105.75, 536984.25, 188103.25, 536984.25, 188129.25, - 536984.25, 187985.25, 536984.25, 188070.75, 536984.25, 187930.75, 536984.25, 187996.75, - 536984.25, 188152.75, 536984.25, 188114.25, 536984.25, 188045.75, 536984.25, 188036.75, - 536984.25, 188068.75, 536984.25, 188074.25, 536984.25, 188122.25, 536984.25, 187985.75, - 536984.25, 188070.25, 536984.25, 188123.25, 536984.25, 188022.25, 536984.25, 188048.25, - 536984.25, 188149.75, 536984.25, 188018.25, 536984.25, 188121.25, 536984.25, 187981.25, - 536984.25, 188081.25, 536984.25, 188138.75, 536984.25, 188053.75, 536984.25, 188114.75, - 536984.25, 188060.75, 536984.25, 188056.75, 536984.25, 188157.25, 536984.25, 187919.25, - 536984.25, 187939.25, 536984.25, 188148.25, 536984.25, 188092.75, 536984.25, 188154.75, - 536984.25, 188066.25, 536984.25, 187929.75, 536984.25, 188048.75, 536984.75, 187929.75, - 536984.75, 188083.75, 536984.75, 188026.25, 536984.75, 188062.75, 536984.75, 187914.75, - 536984.75, 188030.25, 536984.75, 187910.75, 536984.75, 187981.25, 536984.75, 188010.75, - 536984.75, 188033.25, 536984.75, 187925.25, 536984.75, 188025.25, 536984.75, 188113.75, - 536984.75, 188080.25, 536984.75, 188007.75, 536984.75, 187935.25, 536984.75, 188078.75, - 536984.75, 187958.25, 536984.75, 188119.25, 536984.75, 188143.25, 536984.75, 187916.25, - 536984.75, 188082.25, 536984.75, 188123.25, 536984.75, 187963.25, 536984.75, 188160.25, - 536984.75, 188052.25, 536984.75, 188122.25, 536984.75, 188130.25, 536984.75, 188125.25, - 536984.75, 188049.25, 536984.75, 188105.25, 536984.75, 188126.25, 536984.75, 188120.25, - 536984.75, 188086.75, 536984.75, 187984.75, 536984.75, 187935.75, 536984.75, 188114.25, - 536984.75, 188152.75, 536984.75, 187914.25, 536984.75, 188106.75, 536984.75, 187912.75, - 536984.75, 188026.75, 536984.75, 188127.75, 536984.75, 188086.25, 536984.75, 188131.25, - 536984.75, 188103.75, 536984.75, 188131.75, 536984.75, 188070.25, 536984.75, 188028.75, - 536984.75, 188064.25, 536984.75, 187933.75, 536984.75, 187979.25, 536984.75, 188007.25, - 536984.75, 187917.75, 536984.75, 188145.25, 536984.75, 187920.25, 536984.75, 188034.75, - 536984.75, 188023.25, 536984.75, 188121.75, 536984.75, 188128.25, 536984.75, 188091.25, - 536984.75, 188043.75, 536984.75, 187990.75, 536984.75, 188060.25, 536984.75, 188147.75, - 536984.75, 188139.75, 536984.75, 187982.75, 536984.75, 187985.25, 536984.75, 188061.25, - 536984.75, 187986.75, 536984.75, 188021.75, 536984.75, 188028.25, 536984.75, 187938.75, - 536984.75, 187946.75, 536984.75, 188008.75, 536984.75, 188146.75, 536984.75, 187978.75, - 536984.75, 188153.75, 536985.25, 188142.25, 536985.25, 188034.75, 536985.25, 188028.25, - 536985.25, 188125.75, 536985.25, 188144.25, 536985.25, 187945.75, 536985.25, 188121.75, - 536985.25, 187982.25, 536985.25, 187982.75, 536985.25, 188143.75, 536985.25, 187986.75, - 536985.25, 188079.75, 536985.25, 188037.25, 536985.25, 188111.25, 536985.25, 188029.25, - 536985.25, 188083.75, 536985.25, 188123.75, 536985.25, 187938.25, 536985.25, 188070.25, - 536985.25, 188007.25, 536985.25, 187978.25, 536985.25, 187954.75, 536985.25, 188152.25, - 536985.25, 188105.75, 536985.25, 187942.25, 536985.25, 188083.25, 536985.25, 188118.75, - 536985.25, 188025.75, 536985.25, 188145.25, 536985.25, 188063.25, 536985.25, 187933.75, - 536985.25, 188049.75, 536985.25, 188086.25, 536985.25, 188006.25, 536985.25, 188120.25, - 536985.25, 188008.25, 536985.25, 188103.75, 536985.25, 187919.75, 536985.25, 187977.75, - 536985.25, 188101.75, 536985.25, 187959.75, 536985.25, 187983.75, 536985.25, 188022.25, - 536985.25, 187922.25, 536985.25, 188034.25, 536985.25, 188156.25, 536985.25, 187913.25, - 536985.25, 187927.75, 536985.25, 187977.25, 536985.25, 188024.75, 536985.25, 187937.75, - 536985.25, 188132.75, 536985.25, 188085.25, 536985.25, 188051.25, 536985.25, 188150.75, - 536985.25, 188049.25, 536985.25, 188142.75, 536985.25, 188093.25, 536985.25, 188123.25, - 536985.25, 188103.25, 536985.25, 187920.75, 536985.25, 187984.75, 536985.25, 188050.75, - 536985.25, 188087.25, 536985.25, 188075.25, 536985.25, 188062.25, 536985.25, 188020.75, - 536985.25, 188119.75, 536985.25, 187935.75, 536985.25, 187929.25, 536985.25, 188144.75, - 536985.25, 187971.25, 536985.25, 187980.25, 536985.25, 188147.25, 536985.25, 188071.25, - 536985.25, 188035.25, 536985.25, 188071.75, 536985.25, 188022.75, 536985.25, 188079.25, - 536985.25, 188146.25, 536985.25, 188118.25, 536985.25, 187986.25, 536985.25, 187950.75, - 536985.25, 188019.25, 536985.25, 188025.25, 536985.25, 188124.25, 536985.25, 188102.25, - 536985.25, 187980.75, 536985.25, 188115.75, 536985.25, 188027.75, 536985.25, 188154.25, - 536985.25, 188102.75, 536985.25, 188042.75, 536985.25, 187981.25, 536985.25, 188116.75, - 536985.25, 187914.75, 536985.25, 187953.25, 536985.25, 188010.25, 536985.25, 187916.25, - 536985.25, 188010.75, 536985.25, 188030.25, 536985.25, 187934.75, 536985.25, 187984.25, - 536985.25, 188023.75, 536985.75, 188010.75, 536985.75, 188155.75, 536985.75, 187914.75, - 536985.75, 188022.75, 536985.75, 188027.75, 536985.75, 187934.25, 536985.75, 188010.25, - 536985.75, 188048.25, 536985.75, 188030.25, 536985.75, 188154.25, 536985.75, 187913.75, - 536985.75, 188126.25, 536985.75, 188033.25, 536985.75, 188102.25, 536985.75, 188025.25, - 536985.75, 188144.75, 536985.75, 187935.25, 536985.75, 188127.25, 536985.75, 188082.25, - 536985.75, 188048.75, 536985.75, 187929.25, 536985.75, 188115.75, 536985.75, 188050.75, - 536985.75, 187920.75, 536985.75, 188080.75, 536985.75, 187984.75, 536985.75, 188102.75, - 536985.75, 188049.75, 536985.75, 188087.25, 536985.75, 188009.25, 536985.75, 188026.75, - 536985.75, 188086.75, 536985.75, 187937.75, 536985.75, 187991.25, 536985.75, 187977.75, - 536985.75, 188101.75, 536985.75, 188006.75, 536985.75, 188083.25, 536985.75, 188086.25, - 536985.75, 188006.25, 536985.75, 188024.25, 536985.75, 188059.75, 536985.75, 188041.25, - 536985.75, 188152.25, 536985.75, 188051.75, 536985.75, 187978.25, 536985.75, 187983.25, - 536985.75, 188128.25, 536985.75, 187954.25, 536985.75, 187945.75, 536985.75, 188021.25, - 536985.75, 188125.75, 536985.75, 187985.25, 536985.75, 187927.75, 536985.75, 187952.25, - 536985.75, 187978.75, 536985.75, 188146.75, 536985.75, 188034.75, 536985.75, 188070.75, - 536985.75, 188142.25, 536985.75, 188109.25, 536985.75, 188008.75, 536985.75, 187982.25, - 536985.75, 188005.75, 536985.75, 188085.75, 536985.75, 188156.75, 536985.75, 188150.75, - 536985.75, 187938.75, 536985.75, 188073.25, 536985.75, 188061.25, 536985.75, 188024.75, - 536985.75, 187986.75, 536985.75, 188118.25, 536985.75, 188029.25, 536985.75, 188123.75, - 536985.75, 188129.25, 536985.75, 188089.75, 536985.75, 188065.75, 536985.75, 188131.75, - 536985.75, 188122.75, 536985.75, 188118.75, 536985.75, 188062.25, 536985.75, 187912.75, - 536985.75, 188138.75, 536985.75, 187919.75, 536985.75, 187915.75, 536985.75, 187913.25, - 536985.75, 187996.25, 536985.75, 188092.25, 536985.75, 188142.75, 536985.75, 188103.25, - 536985.75, 188146.25, 536985.75, 188079.25, 536985.75, 188116.25, 536985.75, 187986.25, - 536985.75, 188019.25, 536985.75, 188051.25, 536985.75, 188145.75, 536985.75, 187947.75, - 536985.75, 187929.75, 536985.75, 188085.25, 536986.25, 188110.75, 536986.25, 187946.25, - 536986.25, 188124.25, 536986.25, 188101.25, 536986.25, 188090.25, 536986.25, 188114.75, - 536986.25, 188105.25, 536986.25, 188081.75, 536986.25, 188021.75, 536986.25, 188081.25, - 536986.25, 187973.25, 536986.25, 188033.75, 536986.25, 188028.25, 536986.25, 188122.75, - 536986.25, 188143.75, 536986.25, 187971.75, 536986.25, 188039.25, 536986.25, 188153.75, - 536986.25, 188144.25, 536986.25, 188115.75, 536986.25, 188021.25, 536986.25, 188023.25, - 536986.25, 188061.75, 536986.25, 187974.25, 536986.25, 188082.25, 536986.25, 188071.25, - 536986.25, 188080.75, 536986.25, 188104.75, 536986.25, 187935.75, 536986.25, 187920.25, - 536986.25, 188049.75, 536986.25, 188004.75, 536986.25, 187923.75, 536986.25, 187984.25, - 536986.25, 188082.75, 536986.25, 188080.25, 536986.25, 187913.75, 536986.25, 188113.75, - 536986.25, 187935.25, 536986.25, 188029.75, 536986.25, 188119.75, 536986.25, 188034.25, - 536986.25, 188129.75, 536986.25, 188111.25, 536986.25, 188006.75, 536986.25, 188055.25, - 536986.25, 187920.75, 536986.25, 188153.25, 536986.25, 188064.75, 536986.25, 187926.75, - 536986.25, 187983.75, 536986.25, 187925.75, 536986.25, 188145.25, 536986.25, 188135.25, - 536986.25, 188124.75, 536986.25, 188132.75, 536986.25, 187982.75, 536986.25, 188049.25, - 536986.25, 187988.25, 536986.25, 188100.25, 536986.25, 188061.25, 536986.25, 188112.25, - 536986.25, 188145.75, 536986.25, 188120.25, 536986.25, 188152.75, 536986.25, 188002.75, - 536986.25, 188024.25, 536986.25, 188059.75, 536986.25, 187990.75, 536986.25, 188084.25, - 536986.25, 188142.25, 536986.25, 188154.75, 536986.25, 188085.75, 536986.25, 188060.25, - 536986.25, 188017.75, 536986.25, 188084.75, 536986.25, 188122.25, 536986.25, 188008.25, - 536986.25, 187979.75, 536986.25, 187980.75, 536986.25, 187980.25, 536986.25, 188035.25, - 536986.25, 188121.25, 536986.75, 188099.75, 536986.75, 188007.75, 536986.75, 187980.75, - 536986.75, 188071.75, 536986.75, 188142.75, 536986.75, 187962.25, 536986.75, 188120.25, - 536986.75, 188105.75, 536986.75, 188133.75, 536986.75, 188154.75, 536986.75, 188142.25, - 536986.75, 188002.75, 536986.75, 188113.25, 536986.75, 188152.75, 536986.75, 188001.75, - 536986.75, 188084.25, 536986.75, 187981.25, 536986.75, 188148.75, 536986.75, 188103.75, - 536986.75, 187921.25, 536986.75, 188035.75, 536986.75, 188100.25, 536986.75, 188131.25, - 536986.75, 188128.25, 536986.75, 188007.25, 536986.75, 188003.25, 536986.75, 188079.75, - 536986.75, 188022.25, 536986.75, 187982.25, 536986.75, 188124.25, 536986.75, 188104.25, - 536986.75, 188027.25, 536986.75, 188123.25, 536986.75, 188135.75, 536986.75, 188072.25, - 536986.75, 188083.75, 536986.75, 188043.25, 536986.75, 187991.75, 536986.75, 188083.25, - 536986.75, 187983.75, 536986.75, 188020.25, 536986.75, 188124.75, 536986.75, 188038.75, - 536986.75, 188141.75, 536986.75, 188117.25, 536986.75, 187926.25, 536986.75, 187920.25, - 536986.75, 188137.25, 536986.75, 188098.75, 536986.75, 188020.75, 536986.75, 188010.25, - 536986.75, 188000.75, 536986.75, 188119.25, 536986.75, 188034.25, 536986.75, 188004.25, - 536986.75, 188098.25, 536986.75, 187914.75, 536986.75, 188143.25, 536986.75, 187913.75, - 536986.75, 188104.75, 536986.75, 188117.75, 536986.75, 188102.25, 536986.75, 187922.75, - 536986.75, 188100.75, 536986.75, 187927.25, 536986.75, 188075.75, 536986.75, 187971.25, - 536986.75, 187935.75, 536986.75, 188154.25, 536986.75, 188011.75, 536986.75, 188088.75, - 536986.75, 188156.25, 536986.75, 188039.75, 536986.75, 187992.75, 536986.75, 188091.25, - 536986.75, 188063.75, 536986.75, 188115.75, 536986.75, 188144.25, 536986.75, 188138.25, - 536986.75, 187971.75, 536986.75, 188028.25, 536986.75, 188005.75, 536986.75, 188025.75, - 536986.75, 188023.25, 536986.75, 188063.25, 536986.75, 188121.75, 536986.75, 188005.25, - 536986.75, 188036.75, 536986.75, 187973.25, 536986.75, 188105.25, 536986.75, 188081.75, - 536986.75, 188050.25, 536986.75, 188051.25, 536986.75, 187934.75, 536987.25, 188021.75, - 536987.25, 188104.25, 536987.25, 188143.75, 536987.25, 188062.25, 536987.25, 188025.75, - 536987.25, 187985.25, 536987.25, 188005.75, 536987.25, 188082.25, 536987.25, 188138.25, - 536987.25, 188006.25, 536987.25, 188062.75, 536987.25, 187971.75, 536987.25, 188063.25, - 536987.25, 188037.25, 536987.25, 188136.25, 536987.25, 188005.25, 536987.25, 188051.25, - 536987.25, 188063.75, 536987.25, 188082.75, 536987.25, 188019.25, 536987.25, 188143.25, - 536987.25, 188034.25, 536987.25, 188111.25, 536987.25, 188100.75, 536987.25, 188080.75, - 536987.25, 188123.25, 536987.25, 188115.25, 536987.25, 188083.75, 536987.25, 187982.25, - 536987.25, 188029.75, 536987.25, 188022.25, 536987.25, 188128.25, 536987.25, 188004.25, - 536987.25, 188084.25, 536987.25, 188119.75, 536987.25, 188154.75, 536987.25, 187981.25, - 536987.25, 187945.25, 536987.25, 187980.75, 536987.25, 188153.25, 536987.25, 188003.75, - 536987.25, 188115.75, 536987.25, 187924.75, 536987.25, 188042.75, 536987.25, 188099.75, - 536987.25, 187926.75, 536987.25, 188035.25, 536987.25, 187980.25, 536987.25, 187921.25, - 536987.25, 188142.75, 536987.25, 188079.75, 536987.25, 188123.75, 536987.25, 187989.25, - 536987.25, 188152.75, 536987.25, 188002.75, 536987.25, 188142.25, 536987.25, 188059.75, - 536987.25, 188024.25, 536987.25, 187971.25, 536987.25, 188038.75, 536987.25, 188137.25, - 536987.25, 188049.25, 536987.25, 188120.25, 536987.25, 188020.25, 536987.25, 188141.75, - 536987.25, 188001.75, 536987.25, 188103.75, 536987.25, 187931.25, 536987.25, 188010.75, - 536987.25, 188027.25, 536987.25, 187991.75, 536987.25, 187995.25, 536987.25, 187920.75, - 536987.25, 188119.25, 536987.25, 188020.75, 536987.25, 188160.25, 536987.25, 188126.75, - 536987.25, 188098.25, 536987.25, 188117.75, 536987.25, 188071.75, 536987.25, 188000.75, - 536987.25, 188088.25, 536987.25, 188120.75, 536987.25, 188027.75, 536987.25, 188124.75, - 536987.25, 188133.25, 536987.25, 188104.75, 536987.25, 188075.75, 536987.25, 187918.75, - 536987.25, 188022.75, 536987.25, 188049.75, 536987.25, 187910.75, 536987.25, 187975.25, - 536987.25, 187925.25, 536987.25, 188121.75, 536987.25, 188105.25, 536987.25, 188140.75, - 536987.25, 187999.75, 536987.25, 187934.75, 536987.25, 188039.75, 536987.25, 188130.25, - 536987.25, 188134.75, 536987.25, 187935.75, 536987.25, 188121.25, 536987.25, 188072.25, - 536987.75, 188110.75, 536987.75, 187914.75, 536987.75, 187962.75, 536987.75, 187978.75, - 536987.75, 188039.25, 536987.75, 188142.25, 536987.75, 188129.25, 536987.75, 188128.75, - 536987.75, 188038.75, 536987.75, 188035.75, 536987.75, 187913.25, 536987.75, 188003.25, - 536987.75, 188099.25, 536987.75, 188133.75, 536987.75, 188142.75, 536987.75, 187980.25, - 536987.75, 188035.25, 536987.75, 188118.25, 536987.75, 188127.25, 536987.75, 188090.25, - 536987.75, 187976.25, 536987.75, 188124.25, 536987.75, 188121.25, 536987.75, 188022.75, - 536987.75, 188080.25, 536987.75, 188001.75, 536987.75, 188064.75, 536987.75, 188098.75, - 536987.75, 187987.75, 536987.75, 187935.75, 536987.75, 187969.25, 536987.75, 188021.75, - 536987.75, 188010.25, 536987.75, 187980.75, 536987.75, 187962.25, 536987.75, 188097.75, - 536987.75, 188006.25, 536987.75, 188138.75, 536987.75, 188027.25, 536987.75, 188001.25, - 536987.75, 188113.75, 536987.75, 188154.75, 536987.75, 188119.75, 536987.75, 188134.25, - 536987.75, 188154.25, 536987.75, 187995.25, 536987.75, 188139.25, 536987.75, 187956.75, - 536987.75, 188081.25, 536987.75, 188125.75, 536987.75, 188121.75, 536987.75, 188097.25, - 536987.75, 188012.75, 536987.75, 187915.25, 536987.75, 188140.25, 536987.75, 188053.75, - 536987.75, 187999.25, 536987.75, 187992.25, 536987.75, 188104.75, 536987.75, 188052.25, - 536987.75, 188114.25, 536987.75, 188063.75, 536987.75, 187921.25, 536987.75, 188082.75, - 536987.75, 188011.25, 536987.75, 187992.75, 536987.75, 187982.25, 536987.75, 188089.75, - 536987.75, 188037.25, 536987.75, 187924.25, 536987.75, 187935.25, 536987.75, 187922.75, - 536987.75, 187975.25, 536987.75, 187925.25, 536987.75, 187983.25, 536987.75, 188050.75, - 536987.75, 188004.75, 536987.75, 188011.75, 536987.75, 188030.25, 536988.25, 188133.75, - 536988.25, 188079.25, 536988.25, 188038.25, 536988.25, 187969.25, 536988.25, 188097.25, - 536988.25, 188064.25, 536988.25, 188050.25, 536988.25, 188111.75, 536988.25, 188155.25, - 536988.25, 188149.75, 536988.25, 187968.25, 536988.25, 188006.75, 536988.25, 187974.75, - 536988.25, 187983.75, 536988.25, 188037.75, 536988.25, 187978.25, 536988.25, 188023.25, - 536988.25, 188004.75, 536988.25, 187924.25, 536988.25, 188035.75, 536988.25, 187989.75, - 536988.25, 188000.25, 536988.25, 187999.75, 536988.25, 187975.25, 536988.25, 188002.25, - 536988.25, 188105.75, 536988.25, 188044.25, 536988.25, 187979.25, 536988.25, 188106.75, - 536988.25, 188113.25, 536988.25, 188132.75, 536988.25, 188153.75, 536988.25, 188028.25, - 536988.25, 187936.25, 536988.25, 187992.75, 536988.25, 188028.75, 536988.25, 187982.25, - 536988.25, 188101.25, 536988.25, 187925.75, 536988.25, 187922.25, 536988.25, 187979.75, - 536988.25, 188139.75, 536988.25, 188011.25, 536988.25, 187973.25, 536988.25, 188007.25, - 536988.25, 187964.25, 536988.25, 187997.75, 536988.25, 187935.25, 536988.25, 188056.25, - 536988.25, 188141.25, 536988.25, 188126.75, 536988.25, 187963.25, 536988.25, 187935.75, - 536988.25, 187961.75, 536988.25, 187959.75, 536988.25, 187993.75, 536988.25, 187923.25, - 536988.25, 188124.75, 536988.25, 187921.75, 536988.25, 188036.75, 536988.25, 187972.75, - 536988.25, 188081.75, 536988.25, 187976.25, 536988.25, 188125.25, 536988.25, 187911.25, - 536988.25, 188098.25, 536988.25, 188096.75, 536988.25, 188114.75, 536988.25, 188051.75, - 536988.25, 187955.75, 536988.25, 188036.25, 536988.25, 188118.25, 536988.25, 188117.25, - 536988.25, 187980.75, 536988.25, 188140.25, 536988.25, 188026.75, 536988.25, 188121.25, - 536988.25, 188091.75, 536988.25, 188076.75, 536988.25, 187926.25, 536988.25, 187986.25, - 536988.25, 188115.25, 536988.25, 188122.25, 536988.25, 188004.25, 536988.25, 188155.75, - 536988.25, 188020.75, 536988.25, 188117.75, 536988.25, 188096.25, 536988.25, 188104.25, - 536988.25, 188139.25, 536988.25, 188112.25, 536988.25, 188071.75, 536988.25, 188156.75, - 536988.25, 187998.75, 536988.25, 188126.25, 536988.25, 188072.75, 536988.25, 188123.25, - 536988.75, 187975.75, 536988.75, 187911.75, 536988.75, 188113.75, 536988.75, 188114.75, - 536988.75, 188071.75, 536988.75, 188117.75, 536988.75, 188126.25, 536988.75, 187998.75, - 536988.75, 188140.25, 536988.75, 188097.75, 536988.75, 188155.75, 536988.75, 188119.25, - 536988.75, 188027.25, 536988.75, 188096.25, 536988.75, 188110.75, 536988.75, 188006.25, - 536988.75, 188121.25, 536988.75, 188010.25, 536988.75, 187911.25, 536988.75, 188125.75, - 536988.75, 188115.25, 536988.75, 188026.75, 536988.75, 188036.25, 536988.75, 188134.25, - 536988.75, 187921.75, 536988.75, 187980.75, 536988.75, 188121.75, 536988.75, 188036.75, - 536988.75, 187992.25, 536988.75, 188000.75, 536988.75, 188072.75, 536988.75, 188081.25, - 536988.75, 187922.25, 536988.75, 187972.75, 536988.75, 188073.25, 536988.75, 188034.25, - 536988.75, 188124.75, 536988.75, 188133.25, 536988.75, 188035.25, 536988.75, 188157.75, - 536988.75, 187961.75, 536988.75, 187935.75, 536988.75, 187939.75, 536988.75, 187926.75, - 536988.75, 187969.25, 536988.75, 188056.75, 536988.75, 187993.75, 536988.75, 188141.25, - 536988.75, 188126.75, 536988.75, 188095.25, 536988.75, 188087.25, 536988.75, 188125.25, - 536988.75, 187923.75, 536988.75, 187935.25, 536988.75, 188011.25, 536988.75, 188044.75, - 536988.75, 187922.75, 536988.75, 188105.75, 536988.75, 188007.25, 536988.75, 188118.25, - 536988.75, 188097.25, 536988.75, 187936.25, 536988.75, 187982.25, 536988.75, 188028.25, - 536988.75, 187977.25, 536988.75, 187977.75, 536988.75, 187992.75, 536988.75, 188153.75, - 536988.75, 188003.25, 536988.75, 187973.75, 536988.75, 188023.25, 536988.75, 188002.25, - 536988.75, 187967.25, 536988.75, 188004.75, 536988.75, 187979.25, 536988.75, 188139.25, - 536988.75, 188149.75, 536988.75, 188103.25, 536988.75, 188129.25, 536988.75, 187975.25, - 536988.75, 188128.75, 536988.75, 188050.25, 536988.75, 187978.25, 536988.75, 188123.75, - 536988.75, 187983.75, 536988.75, 188073.75, 536988.75, 188100.75, 536988.75, 188037.75, - 536988.75, 187998.25, 536988.75, 188080.75, 536988.75, 187978.75, 536988.75, 187928.25, - 536988.75, 188111.75, 536988.75, 188116.25, 536988.75, 188029.25, 536988.75, 187996.75, - 536988.75, 188051.25, 536988.75, 187960.75, 536988.75, 187925.75, 536988.75, 188099.25, - 536989.25, 188116.75, 536989.25, 187962.75, 536989.25, 188138.25, 536989.25, 188139.75, - 536989.25, 188002.75, 536989.25, 187998.25, 536989.25, 187985.25, 536989.25, 187978.75, - 536989.25, 188072.25, 536989.25, 188101.25, 536989.25, 188107.25, 536989.25, 187935.75, - 536989.25, 188095.25, 536989.25, 187959.25, 536989.25, 187994.25, 536989.25, 188038.75, - 536989.25, 188021.75, 536989.25, 188113.25, 536989.25, 188123.25, 536989.25, 188137.25, - 536989.25, 188130.25, 536989.25, 188134.75, 536989.25, 187999.25, 536989.25, 188063.75, - 536989.25, 188086.75, 536989.25, 187922.75, 536989.25, 188114.25, 536989.25, 188054.25, - 536989.25, 188135.25, 536989.25, 187933.75, 536989.25, 187971.25, 536989.25, 188144.25, - 536989.25, 187980.25, 536989.25, 187934.75, 536989.25, 188020.25, 536989.25, 187976.75, - 536989.25, 187960.25, 536989.25, 187973.75, 536989.25, 187999.75, 536989.25, 187996.75, - 536989.25, 188012.25, 536989.25, 188064.25, 536989.25, 188057.25, 536989.25, 187926.75, - 536989.25, 188050.75, 536989.25, 188124.25, 536989.25, 188094.25, 536989.25, 188045.25, - 536989.25, 188105.25, 536989.25, 187990.75, 536989.25, 188077.25, 536989.25, 188106.25, - 536989.25, 188038.25, 536989.25, 187976.25, 536989.25, 187974.75, 536989.25, 187980.75, - 536989.25, 188156.25, 536989.25, 188011.75, 536989.25, 187968.75, 536989.25, 188071.75, - 536989.25, 188003.75, 536989.25, 188138.75, 536989.25, 187992.75, 536989.25, 187920.25, - 536989.25, 187991.25, 536989.25, 188124.75, 536989.25, 187997.75, 536989.25, 187972.75, - 536989.25, 188119.25, 536989.25, 188130.75, 536989.25, 188128.25, 536989.25, 188096.25, - 536989.25, 188154.75, 536989.25, 188150.25, 536989.25, 188036.25, 536989.25, 188004.25, - 536989.75, 187991.75, 536989.75, 188084.25, 536989.75, 187975.75, 536989.75, 187920.75, - 536989.75, 188004.25, 536989.75, 188093.75, 536989.75, 187995.25, 536989.75, 188129.75, - 536989.75, 188154.75, 536989.75, 188160.25, 536989.75, 188118.75, 536989.75, 187926.25, - 536989.75, 187995.75, 536989.75, 187934.25, 536989.75, 188022.25, 536989.75, 187916.25, - 536989.75, 188113.75, 536989.75, 187914.75, 536989.75, 188094.75, 536989.75, 188064.75, - 536989.75, 188075.25, 536989.75, 188133.25, 536989.75, 187992.75, 536989.75, 188028.25, - 536989.75, 187991.25, 536989.75, 187911.75, 536989.75, 188115.75, 536989.75, 188018.25, - 536989.75, 188156.25, 536989.75, 188071.75, 536989.75, 188093.25, 536989.75, 187910.75, - 536989.75, 188037.25, 536989.75, 187993.25, 536989.75, 188000.25, 536989.75, 188011.75, - 536989.75, 187957.75, 536989.75, 187918.25, 536989.75, 188117.25, 536989.75, 187976.25, - 536989.75, 187997.25, 536989.75, 188124.25, 536989.75, 188105.25, 536989.75, 188080.25, - 536989.75, 187990.75, 536989.75, 188137.75, 536989.75, 188101.75, 536989.75, 187958.75, - 536989.75, 188111.75, 536989.75, 187961.25, 536989.75, 187926.75, 536989.75, 187963.25, - 536989.75, 187966.75, 536989.75, 188051.25, 536989.75, 188125.25, 536989.75, 188094.25, - 536989.75, 188050.75, 536989.75, 188034.25, 536989.75, 188134.75, 536989.75, 187970.75, - 536989.75, 187996.75, 536989.75, 188065.25, 536989.75, 187960.25, 536989.75, 188120.25, - 536989.75, 187933.25, 536989.75, 188148.75, 536989.75, 188114.25, 536989.75, 187990.25, - 536989.75, 188112.75, 536989.75, 188028.75, 536989.75, 187962.75, 536989.75, 188148.25, - 536989.75, 188135.25, 536989.75, 188039.25, 536989.75, 187927.25, 536989.75, 188033.75, - 536989.75, 188012.75, 536989.75, 188130.75, 536989.75, 187964.75, 536989.75, 187970.25, - 536989.75, 188130.25, 536989.75, 188105.75, 536989.75, 188070.25, 536989.75, 188051.75, - 536989.75, 187933.75, 536989.75, 187986.25, 536989.75, 188024.25, 536989.75, 187971.75, - 536989.75, 188113.25, 536989.75, 187998.75, 536989.75, 188022.75, 536989.75, 187994.25, - 536989.75, 188035.75, 536989.75, 188139.75, 536989.75, 187985.25, 536989.75, 188013.25, - 536989.75, 188066.25, 536989.75, 188136.75, 536989.75, 188065.75, 536989.75, 188101.25, - 536989.75, 187927.75, 536989.75, 188131.25, 536989.75, 188072.25, 536989.75, 187988.75, - 536989.75, 188155.25, 536989.75, 187998.25, 536989.75, 188152.75, 536989.75, 187968.25, - 536989.75, 188138.25, 536989.75, 187996.25, 536989.75, 187973.25, 536990.25, 187958.25, - 536990.25, 188101.25, 536990.25, 187996.25, 536990.25, 187971.75, 536990.25, 188065.75, - 536990.25, 187970.25, 536990.25, 188050.75, 536990.25, 188085.75, 536990.25, 188133.75, - 536990.25, 188136.25, 536990.25, 187968.25, 536990.25, 187926.75, 536990.25, 188136.75, - 536990.25, 187996.75, 536990.25, 187989.25, 536990.25, 188070.25, 536990.25, 188052.75, - 536990.25, 188142.75, 536990.25, 188044.75, 536990.25, 187980.25, 536990.25, 188115.25, - 536990.25, 188094.25, 536990.25, 187997.25, 536990.25, 187933.25, 536990.25, 188032.75, - 536990.25, 188137.25, 536990.25, 188146.75, 536990.25, 187980.75, 536990.25, 188099.25, - 536990.25, 187990.25, 536990.25, 188139.25, 536990.25, 187984.25, 536990.25, 188106.75, - 536990.25, 188022.25, 536990.25, 187970.75, 536990.25, 188153.25, 536990.25, 187963.25, - 536990.25, 188071.75, 536990.25, 187981.25, 536990.25, 187995.25, 536990.25, 188141.75, - 536990.25, 188033.75, 536990.25, 187997.75, 536990.25, 188133.25, 536990.25, 187976.25, - 536990.25, 187991.25, 536990.25, 188084.25, 536990.25, 187986.75, 536990.25, 188139.75, - 536990.25, 188107.25, 536990.25, 187960.25, 536990.25, 188094.75, 536990.25, 188113.75, - 536990.25, 188114.75, 536990.25, 187991.75, 536990.25, 188093.75, 536990.25, 187998.25, - 536990.25, 188118.75, 536990.25, 187964.25, 536990.25, 187975.75, 536990.25, 187915.25, - 536990.25, 188013.25, 536990.25, 187961.25, 536990.25, 188101.75, 536990.25, 188111.75, - 536990.25, 187969.75, 536990.25, 188072.75, 536990.25, 187994.25, 536990.25, 188097.75, - 536990.25, 187934.25, 536990.25, 187992.25, 536990.25, 188051.75, 536990.25, 188130.25, - 536990.25, 188012.75, 536990.25, 188093.25, 536990.25, 188075.25, 536990.25, 188154.75, - 536990.25, 188096.25, 536990.25, 188004.75, 536990.25, 188114.25, 536990.25, 188156.25, - 536990.25, 187921.25, 536990.25, 187992.75, 536990.25, 188124.75, 536990.25, 188092.75, - 536990.25, 188022.75, 536990.25, 187974.25, 536990.25, 188051.25, 536990.25, 188105.25, - 536990.25, 188034.75, 536990.25, 188124.25, 536990.25, 188038.75, 536990.25, 188074.75, - 536990.25, 187932.25, 536990.25, 187993.25, 536990.25, 188118.25, 536990.25, 188000.25, - 536990.75, 187957.75, 536990.75, 188109.75, 536990.75, 187932.25, 536990.75, 187982.75, - 536990.75, 188053.75, 536990.75, 188156.75, 536990.75, 188119.25, 536990.75, 188083.75, - 536990.75, 187973.75, 536990.75, 188092.75, 536990.75, 187993.75, 536990.75, 188156.25, - 536990.75, 187930.75, 536990.75, 188052.25, 536990.75, 188147.25, 536990.75, 187998.75, - 536990.75, 188093.25, 536990.75, 188132.25, 536990.75, 187968.75, 536990.75, 187967.75, - 536990.75, 187964.25, 536990.75, 188067.75, 536990.75, 188129.75, 536990.75, 188064.25, - 536990.75, 188135.75, 536990.75, 187935.75, 536990.75, 188023.75, 536990.75, 188131.25, - 536990.75, 187973.25, 536990.75, 188076.75, 536990.75, 187924.25, 536990.75, 188155.75, - 536990.75, 188096.75, 536990.75, 188072.25, 536990.75, 188025.25, 536990.75, 187918.25, - 536990.75, 188134.75, 536990.75, 187966.25, 536990.75, 187994.75, 536990.75, 187958.75, - 536990.75, 187922.25, 536990.75, 187990.75, 536990.75, 188071.75, 536990.75, 187963.25, - 536990.75, 187987.75, 536990.75, 188121.75, 536990.75, 187927.25, 536990.75, 188112.75, - 536990.75, 187976.75, 536990.75, 187971.25, 536990.75, 188139.25, 536990.75, 187935.25, - 536990.75, 188137.75, 536990.75, 188080.25, 536990.75, 187986.25, 536990.75, 188131.75, - 536990.75, 187921.75, 536990.75, 188095.75, 536990.75, 188024.25, 536990.75, 188065.25, - 536990.75, 188157.25, 536990.75, 188101.25, 536990.75, 188116.75, 536990.75, 188113.25, - 536990.75, 188096.25, 536990.75, 188037.25, 536990.75, 187995.75, 536990.75, 188035.75, - 536990.75, 187927.75, 536990.75, 188106.25, 536990.75, 187989.25, 536990.75, 187919.25, - 536990.75, 187971.75, 536990.75, 188130.75, 536990.75, 187962.75, 536990.75, 188109.25, - 536990.75, 187960.75, 536990.75, 188090.75, 536990.75, 187932.75, 536990.75, 188024.75, - 536990.75, 188037.75, 536990.75, 187988.75, 536990.75, 187985.75, 536990.75, 187974.75, - 536991.25, 188155.75, 536991.25, 188107.25, 536991.25, 188128.75, 536991.25, 188153.75, - 536991.25, 188135.25, 536991.25, 187935.75, 536991.25, 188060.25, 536991.25, 187964.25, - 536991.25, 188039.75, 536991.25, 188155.25, 536991.25, 188129.25, 536991.25, 188108.75, - 536991.25, 188093.25, 536991.25, 188121.25, 536991.25, 188038.25, 536991.25, 188046.25, - 536991.25, 187932.75, 536991.25, 188140.25, 536991.25, 188073.25, 536991.25, 187930.75, - 536991.25, 187993.75, 536991.25, 187934.75, 536991.25, 187987.25, 536991.25, 188132.75, - 536991.25, 188136.75, 536991.25, 187988.25, 536991.25, 187994.75, 536991.25, 188134.25, - 536991.25, 188068.75, 536991.25, 187974.25, 536991.25, 188069.25, 536991.25, 188035.75, - 536991.25, 187927.75, 536991.25, 188012.25, 536991.25, 188066.25, 536991.25, 188089.25, - 536991.25, 187971.25, 536991.25, 187959.25, 536991.25, 187964.75, 536991.25, 187937.25, - 536991.25, 187974.75, 536991.25, 188058.25, 536991.25, 188088.75, 536991.25, 188109.75, - 536991.25, 187989.75, 536991.25, 187965.25, 536991.25, 188005.25, 536991.25, 188149.25, - 536991.25, 188024.25, 536991.25, 188052.75, 536991.25, 187922.25, 536991.25, 188145.25, - 536991.25, 187917.25, 536991.25, 187921.25, 536991.25, 188052.25, 536991.25, 187932.25, - 536991.25, 188156.25, 536991.25, 187928.75, 536991.25, 188090.25, 536991.25, 188104.75, - 536991.25, 187963.75, 536991.25, 188133.75, 536991.25, 187995.75, 536991.25, 188000.75, - 536991.25, 187969.75, 536991.25, 188039.25, 536991.25, 187972.25, 536991.25, 188117.75, - 536991.25, 188120.25, 536991.25, 188115.25, 536991.25, 187969.25, 536991.25, 188064.75, - 536991.25, 188091.75, 536991.25, 187987.75, 536991.25, 188023.75, 536991.25, 188077.75, - 536991.25, 188154.25, 536991.25, 188158.25, 536991.25, 188110.75, 536991.25, 188062.75, - 536991.25, 187930.25, 536991.25, 188001.25, 536991.25, 188092.25, 536991.25, 188112.25, - 536991.25, 188091.25, 536991.25, 188010.25, 536991.25, 188108.25, 536991.25, 188119.75, - 536991.75, 188039.25, 536991.75, 188088.75, 536991.75, 187920.25, 536991.75, 188138.25, - 536991.75, 187918.25, 536991.75, 188013.75, 536991.75, 188119.75, 536991.75, 188077.25, - 536991.75, 188158.25, 536991.75, 188025.25, 536991.75, 187973.25, 536991.75, 188110.25, - 536991.75, 187935.75, 536991.75, 187996.25, 536991.75, 188134.75, 536991.75, 187927.25, - 536991.75, 188064.25, 536991.75, 188096.75, 536991.75, 188112.25, 536991.75, 187916.25, - 536991.75, 188072.75, 536991.75, 188129.75, 536991.75, 187961.25, 536991.75, 188132.25, - 536991.75, 188155.75, 536991.75, 188021.75, 536991.75, 187987.75, 536991.75, 188023.75, - 536991.75, 188108.75, 536991.75, 188126.25, 536991.75, 188134.25, 536991.75, 188053.25, - 536991.75, 187930.75, 536991.75, 188046.75, 536991.75, 188006.25, 536991.75, 187972.25, - 536991.75, 187966.75, 536991.75, 187969.25, 536991.75, 188118.75, 536991.75, 188102.25, - 536991.75, 188120.75, 536991.75, 188112.75, 536991.75, 188082.75, 536991.75, 187929.75, - 536991.75, 187967.75, 536991.75, 188133.75, 536991.75, 188035.75, 536991.75, 188088.25, - 536991.75, 188153.25, 536991.75, 188000.75, 536991.75, 188038.25, 536991.75, 187929.25, - 536991.75, 187999.25, 536991.75, 187922.25, 536991.75, 188092.25, 536991.75, 188037.25, - 536991.75, 187973.75, 536991.75, 187936.25, 536991.75, 187932.25, 536991.75, 187983.75, - 536991.75, 188156.25, 536991.75, 187986.25, 536991.75, 188145.25, 536991.75, 188130.75, - 536991.75, 188117.25, 536991.75, 188082.25, 536991.75, 187993.75, 536991.75, 188132.75, - 536991.75, 187917.25, 536991.75, 187934.75, 536991.75, 188045.75, 536991.75, 188052.75, - 536991.75, 188069.75, 536991.75, 188040.25, 536991.75, 187979.75, 536991.75, 188064.75, - 536991.75, 188034.25, 536991.75, 188080.25, 536991.75, 187971.25, 536991.75, 188051.75, - 536991.75, 187965.25, 536991.75, 187989.25, 536991.75, 188011.75, 536991.75, 187930.25, - 536991.75, 188044.75, 536991.75, 188090.25, 536991.75, 187921.25, 536991.75, 188128.75, - 536991.75, 188130.25, 536991.75, 188135.25, 536991.75, 188154.75, 536991.75, 187960.75, - 536991.75, 188066.25, 536991.75, 188012.25, 536991.75, 187995.25, 536991.75, 188116.75, - 536991.75, 187964.75, 536991.75, 187912.25, 536991.75, 188089.25, 536992.25, 188135.25, - 536992.25, 187937.25, 536992.25, 187974.75, 536992.25, 188012.25, 536992.25, 188039.75, - 536992.25, 187988.25, 536992.25, 188154.75, 536992.25, 187972.75, 536992.25, 188130.25, - 536992.25, 187960.75, 536992.25, 187949.25, 536992.25, 187976.25, 536992.25, 188152.75, - 536992.25, 187932.75, 536992.25, 187967.25, 536992.25, 188011.75, 536992.25, 188073.75, - 536992.25, 188128.75, 536992.25, 188106.25, 536992.25, 188012.75, 536992.25, 187910.75, - 536992.25, 188040.75, 536992.25, 188052.25, 536992.25, 188127.75, 536992.25, 188068.25, - 536992.25, 188014.25, 536992.25, 188066.75, 536992.25, 187982.25, 536992.25, 187971.25, - 536992.25, 187969.75, 536992.25, 187987.25, 536992.25, 188145.75, 536992.25, 187929.25, - 536992.25, 188000.75, 536992.25, 188088.25, 536992.25, 187994.75, 536992.25, 188091.25, - 536992.25, 188091.75, 536992.25, 188108.75, 536992.25, 188133.25, 536992.25, 188106.75, - 536992.25, 188160.25, 536992.25, 188130.75, 536992.25, 187963.25, 536992.25, 188132.25, - 536992.25, 188008.25, 536992.25, 188053.25, 536992.25, 188153.75, 536992.25, 188036.75, - 536992.25, 188115.25, 536992.25, 188125.75, 536992.25, 187995.75, 536992.25, 188122.25, - 536992.25, 188072.75, 536992.25, 188065.75, 536992.25, 187964.25, 536992.25, 188037.75, - 536992.25, 187961.25, 536992.25, 188113.75, 536992.25, 188084.25, 536992.25, 188110.75, - 536992.25, 187966.75, 536992.25, 188064.25, 536992.25, 187986.75, 536992.25, 187928.75, - 536992.25, 188101.75, 536992.25, 188089.75, 536992.25, 188129.75, 536992.25, 188108.25, - 536992.25, 187927.75, 536992.25, 188133.75, 536992.25, 188001.75, 536992.25, 188111.25, - 536992.75, 188093.25, 536992.75, 188131.25, 536992.75, 188064.25, 536992.75, 188048.75, - 536992.75, 188046.75, 536992.75, 188140.25, 536992.75, 188132.25, 536992.75, 188069.25, - 536992.75, 188073.25, 536992.75, 188004.75, 536992.75, 188040.75, 536992.75, 188073.75, - 536992.75, 188055.25, 536992.75, 188134.25, 536992.75, 187965.75, 536992.75, 187928.25, - 536992.75, 188034.75, 536992.75, 188068.75, 536992.75, 188121.25, 536992.75, 188089.25, - 536992.75, 188038.75, 536992.75, 188000.25, 536992.75, 188053.75, 536992.75, 188105.25, - 536992.75, 188007.25, 536992.75, 187969.75, 536992.75, 187963.75, 536992.75, 188151.75, - 536992.75, 187961.75, 536992.75, 188034.25, 536992.75, 188087.75, 536992.75, 187920.75, - 536992.75, 187936.75, 536992.75, 188129.25, 536992.75, 188107.75, 536992.75, 188128.25, - 536992.75, 188010.75, 536992.75, 187981.75, 536992.75, 188001.25, 536992.75, 188106.75, - 536992.75, 188106.25, 536992.75, 188095.25, 536992.75, 188067.25, 536992.75, 188098.75, - 536992.75, 188154.25, 536992.75, 187929.75, 536992.75, 188119.75, 536992.75, 188108.25, - 536992.75, 188109.75, 536992.75, 187987.75, 536992.75, 188157.25, 536992.75, 188152.25, - 536992.75, 188009.75, 536992.75, 187997.25, 536992.75, 188127.25, 536992.75, 188152.75, - 536992.75, 188087.25, 536992.75, 188009.25, 536992.75, 188120.25, 536992.75, 188090.75, - 536992.75, 188007.75, 536992.75, 188131.75, 536992.75, 188052.75, 536992.75, 187986.25, - 536992.75, 188065.25, 536992.75, 188002.25, 536992.75, 187971.75, 536992.75, 187938.75, - 536992.75, 187989.75, 536992.75, 188078.75, 536992.75, 188092.25, 536992.75, 187964.75, - 536992.75, 187959.25, 536992.75, 187988.25, 536992.75, 188142.25, 536992.75, 187968.25, - 536992.75, 187970.25, 536992.75, 188115.75, 536992.75, 188008.75, 536992.75, 187970.75, - 536992.75, 188155.25, 536992.75, 188062.25, 536992.75, 187996.25, 536992.75, 188085.75, - 536992.75, 188117.25, 536992.75, 187967.25, 536993.25, 188115.75, 536993.25, 187964.75, - 536993.25, 187996.25, 536993.25, 188039.75, 536993.25, 187997.25, 536993.25, 187971.75, - 536993.25, 187995.75, 536993.25, 187956.25, 536993.25, 188095.25, 536993.25, 188106.25, - 536993.25, 187995.25, 536993.25, 188072.25, 536993.25, 187950.75, 536993.25, 188046.75, - 536993.25, 188073.25, 536993.25, 188073.75, 536993.25, 188151.25, 536993.25, 187967.25, - 536993.25, 188000.25, 536993.25, 188157.25, 536993.25, 188031.25, 536993.25, 188151.75, - 536993.25, 188120.75, 536993.25, 188067.75, 536993.25, 188107.75, 536993.25, 188013.75, - 536993.25, 188001.25, 536993.25, 188067.25, 536993.25, 188001.75, 536993.25, 188152.25, - 536993.25, 188036.75, 536993.25, 188152.75, 536993.25, 188131.75, 536993.25, 188040.75, - 536993.25, 188052.75, 536993.25, 188156.75, 536993.25, 187913.25, 536993.25, 187928.25, - 536993.25, 187974.25, 536993.25, 188012.25, 536993.25, 188130.75, 536993.25, 188011.75, - 536993.25, 188088.75, 536993.25, 188120.25, 536993.25, 187989.75, 536993.25, 187959.25, - 536993.25, 188102.75, 536993.25, 187968.25, 536993.25, 187971.25, 536993.25, 187989.25, - 536993.25, 188109.25, 536993.25, 188038.75, 536993.25, 188127.25, 536993.25, 187926.75, - 536993.25, 188065.25, 536993.25, 188087.75, 536993.25, 187959.75, 536993.25, 187975.75, - 536993.25, 188010.75, 536993.25, 188153.25, 536993.25, 188109.75, 536993.25, 188010.25, - 536993.25, 187928.75, 536993.25, 188004.25, 536993.25, 187987.75, 536993.25, 188132.25, - 536993.25, 187968.75, 536993.25, 188129.25, 536993.25, 188119.75, 536993.25, 188080.75, - 536993.25, 188153.75, 536993.25, 187960.25, 536993.25, 187986.75, 536993.25, 188154.25, - 536993.25, 188086.25, 536993.25, 188034.25, 536993.25, 187922.25, 536993.25, 188048.75, - 536993.25, 188008.75, 536993.25, 187970.75, 536993.25, 188132.75, 536993.25, 188038.25, - 536993.25, 188155.25, 536993.25, 188034.75, 536993.25, 188154.75, 536993.25, 188007.25, - 536993.25, 187982.25, 536993.25, 187981.75, 536993.25, 188111.25, 536993.25, 188127.75, - 536993.25, 188099.75, 536993.25, 188142.75, 536993.25, 188092.25, 536993.75, 187970.25, - 536993.75, 188149.75, 536993.75, 188130.75, 536993.75, 188046.25, 536993.75, 187938.75, - 536993.75, 187980.25, 536993.75, 188090.75, 536993.75, 188085.25, 536993.75, 187995.75, - 536993.75, 187971.75, 536993.75, 188106.75, 536993.75, 188091.25, 536993.75, 188106.25, - 536993.75, 188092.75, 536993.75, 187915.75, 536993.75, 188039.25, 536993.75, 187997.75, - 536993.75, 187932.25, 536993.75, 188069.25, 536993.75, 187950.75, 536993.75, 187942.75, - 536993.75, 188007.25, 536993.75, 188097.25, 536993.75, 188151.25, 536993.75, 188130.25, - 536993.75, 187967.25, 536993.75, 187957.75, 536993.75, 188074.75, 536993.75, 187925.25, - 536993.75, 188068.25, 536993.75, 188008.75, 536993.75, 188035.75, 536993.75, 187965.75, - 536993.75, 188031.25, 536993.75, 188151.75, 536993.75, 187962.75, 536993.75, 187937.75, - 536993.75, 187929.75, 536993.75, 188006.25, 536993.75, 187930.25, 536993.75, 188067.75, - 536993.75, 188128.75, 536993.75, 187958.25, 536993.75, 188001.25, 536993.75, 188101.25, - 536993.75, 187912.75, 536993.75, 188063.25, 536993.75, 188081.25, 536993.75, 187969.25, - 536993.75, 187964.25, 536993.75, 188086.75, 536993.75, 188099.25, 536993.75, 188108.25, - 536993.75, 188087.25, 536993.75, 188031.75, 536993.75, 187987.25, 536993.75, 188048.25, - 536993.75, 188001.75, 536993.75, 188129.75, 536993.75, 188064.75, 536993.75, 188053.75, - 536993.75, 188125.75, 536993.75, 188097.75, 536993.75, 188012.75, 536993.75, 187933.75, - 536993.75, 188009.75, 536993.75, 187968.75, 536993.75, 188041.25, 536993.75, 188144.75, - 536993.75, 188047.75, 536993.75, 188155.75, 536993.75, 187918.25, 536993.75, 187913.25, - 536993.75, 188010.25, 536993.75, 188078.75, 536993.75, 188011.25, 536993.75, 188053.25, - 536993.75, 187950.25, 536993.75, 188066.25, 536993.75, 188156.25, 536993.75, 187988.75, - 536993.75, 187920.75, 536993.75, 187943.25, 536993.75, 188127.25, 536994.25, 188022.25, - 536994.25, 188079.75, 536994.25, 188038.75, 536994.25, 188003.25, 536994.25, 187988.25, - 536994.25, 187988.75, 536994.25, 188044.75, 536994.25, 188102.75, 536994.25, 188098.25, - 536994.25, 188002.75, 536994.25, 188141.25, 536994.25, 188091.75, 536994.25, 188049.75, - 536994.25, 187924.75, 536994.25, 187950.25, 536994.25, 188041.75, 536994.25, 187936.75, - 536994.25, 187987.75, 536994.25, 188127.25, 536994.25, 187965.25, 536994.25, 187923.25, - 536994.25, 188040.75, 536994.25, 187963.25, 536994.25, 188129.25, 536994.25, 187951.25, - 536994.25, 188032.25, 536994.25, 188045.25, 536994.25, 188102.25, 536994.25, 188053.75, - 536994.25, 188125.75, 536994.25, 187966.25, 536994.25, 187921.25, 536994.25, 188103.75, - 536994.25, 188013.25, 536994.25, 188009.25, 536994.25, 188001.75, 536994.25, 187920.25, - 536994.25, 188054.75, 536994.25, 188101.75, 536994.25, 188108.25, 536994.25, 188093.25, - 536994.25, 188097.75, 536994.25, 187932.75, 536994.25, 188101.25, 536994.25, 187958.25, - 536994.25, 188089.75, 536994.25, 188047.25, 536994.25, 188096.25, 536994.25, 188154.25, - 536994.25, 188014.25, 536994.25, 187911.75, 536994.25, 187967.75, 536994.25, 187962.75, - 536994.25, 188151.75, 536994.25, 188090.25, 536994.25, 188061.75, 536994.25, 188031.25, - 536994.25, 188045.75, 536994.25, 188006.75, 536994.25, 188075.25, 536994.25, 188121.25, - 536994.25, 188105.25, 536994.25, 187925.25, 536994.25, 188100.75, 536994.25, 187983.75, - 536994.25, 188055.75, 536994.25, 188159.25, 536994.25, 188066.75, 536994.25, 188126.25, - 536994.25, 187957.75, 536994.25, 188040.25, 536994.25, 188068.75, 536994.25, 188014.75, - 536994.25, 188085.75, 536994.25, 188074.25, 536994.25, 188139.25, 536994.25, 188028.75, - 536994.25, 188148.25, 536994.25, 187931.75, 536994.25, 188073.25, 536994.25, 188097.25, - 536994.25, 188069.25, 536994.25, 187955.75, 536994.25, 188107.25, 536994.25, 188148.75, - 536994.25, 187948.25, 536994.25, 187925.75, 536994.25, 187994.75, 536994.25, 187969.75, - 536994.25, 187932.25, 536994.25, 188150.75, 536994.25, 187950.75, 536994.25, 187961.75, - 536994.25, 188100.25, 536994.25, 187914.25, 536994.25, 188128.25, 536994.25, 188123.75, - 536994.25, 188127.75, 536994.25, 188121.75, 536994.25, 187935.25, 536994.25, 188037.25, - 536994.25, 188007.75, 536994.25, 187966.75, 536994.25, 188085.25, 536994.25, 188092.25, - 536994.25, 188150.25, 536994.25, 188030.25, 536994.25, 187996.75, 536994.25, 187964.75, - 536994.25, 188054.25, 536994.25, 188142.75, 536994.25, 188056.25, 536994.25, 187970.25, - 536994.25, 188084.25, 536994.75, 187914.25, 536994.75, 188089.75, 536994.75, 188040.75, - 536994.75, 188084.75, 536994.75, 187965.25, 536994.75, 188102.25, 536994.75, 188039.75, - 536994.75, 188080.75, 536994.75, 188091.75, 536994.75, 188001.25, 536994.75, 188067.25, - 536994.75, 188129.25, 536994.75, 187962.25, 536994.75, 188068.25, 536994.75, 187949.25, - 536994.75, 188108.25, 536994.75, 188001.75, 536994.75, 187954.75, 536994.75, 188053.25, - 536994.75, 188084.25, 536994.75, 188127.25, 536994.75, 188121.25, 536994.75, 188028.25, - 536994.75, 187930.25, 536994.75, 187980.75, 536994.75, 188044.25, 536994.75, 187925.25, - 536994.75, 188092.25, 536994.75, 188128.25, 536994.75, 187947.75, 536994.75, 187987.75, - 536994.75, 188054.25, 536994.75, 188003.25, 536994.75, 188158.75, 536994.75, 188155.75, - 536994.75, 188032.75, 536994.75, 188148.25, 536994.75, 187936.75, 536994.75, 187969.75, - 536994.75, 188045.75, 536994.75, 187978.75, 536994.75, 187964.75, 536994.75, 188119.75, - 536994.75, 188075.25, 536994.75, 187932.75, 536994.75, 188101.25, 536994.75, 187962.75, - 536994.75, 188105.25, 536994.75, 188005.75, 536994.75, 188062.25, 536994.75, 188159.25, - 536994.75, 188055.75, 536994.75, 187988.25, 536994.75, 188006.25, 536994.75, 188074.25, - 536994.75, 188042.25, 536994.75, 188148.75, 536994.75, 188107.25, 536994.75, 187967.25, - 536994.75, 188061.75, 536994.75, 188030.75, 536994.75, 188079.25, 536994.75, 187924.25, - 536994.75, 187910.75, 536994.75, 187931.75, 536994.75, 187950.75, 536994.75, 188045.25, - 536994.75, 188139.25, 536994.75, 188097.25, 536994.75, 188014.75, 536994.75, 188105.75, - 536994.75, 187929.25, 536994.75, 187967.75, 536994.75, 187994.25, 536994.75, 187937.25, - 536994.75, 188014.25, 536994.75, 188090.25, 536994.75, 187932.25, 536994.75, 188085.75, - 536994.75, 187925.75, 536994.75, 188061.25, 536994.75, 187997.25, 536994.75, 188154.75, - 536994.75, 188097.75, 536994.75, 188013.25, 536994.75, 187966.25, 536994.75, 188083.75, - 536994.75, 187979.25, 536994.75, 188029.75, 536994.75, 188149.75, 536994.75, 187951.25, - 536994.75, 187968.75, 536994.75, 188049.25, 536994.75, 187996.75, 536994.75, 188008.75, - 536994.75, 188125.25, 536994.75, 188140.75, 536994.75, 188160.25, 536994.75, 188121.75, - 536994.75, 188100.75, 536994.75, 188150.25, 536994.75, 188127.75, 536994.75, 188099.75, - 536994.75, 187921.75, 536994.75, 188010.75, 536994.75, 187913.25, 536995.25, 187995.75, - 536995.25, 187956.75, 536995.25, 188103.25, 536995.25, 187951.75, 536995.25, 187965.25, - 536995.25, 188011.75, 536995.25, 188125.75, 536995.25, 188036.75, 536995.25, 188121.75, - 536995.25, 187914.75, 536995.25, 188012.25, 536995.25, 188150.25, 536995.25, 187962.25, - 536995.25, 187949.25, 536995.25, 188118.25, 536995.25, 188031.75, 536995.25, 187954.75, - 536995.25, 188009.25, 536995.25, 188106.75, 536995.25, 188127.75, 536995.25, 188126.25, - 536995.25, 188053.75, 536995.25, 188028.25, 536995.25, 188093.75, 536995.25, 188095.25, - 536995.25, 188146.75, 536995.25, 187960.25, 536995.25, 188059.75, 536995.25, 187987.75, - 536995.25, 188120.25, 536995.25, 188092.25, 536995.25, 187925.25, 536995.25, 187963.75, - 536995.25, 188151.75, 536995.25, 188119.75, 536995.25, 188123.75, 536995.25, 188106.25, - 536995.25, 187947.75, 536995.25, 188091.25, 536995.25, 188060.25, 536995.25, 188068.75, - 536995.25, 188101.75, 536995.25, 188154.25, 536995.25, 188099.25, 536995.25, 188082.25, - 536995.25, 188154.75, 536995.25, 188008.25, 536995.25, 188031.25, 536995.25, 188147.75, - 536995.25, 188028.75, 536995.25, 187997.25, 536995.25, 187912.75, 536995.25, 188148.25, - 536995.25, 188054.75, 536995.25, 187956.25, 536995.25, 188044.75, 536995.25, 187947.25, - 536995.25, 188045.75, 536995.25, 188086.25, 536995.25, 188007.25, 536995.25, 188046.75, - 536995.25, 187913.75, 536995.25, 188090.75, 536995.25, 188041.25, 536995.25, 188103.75, - 536995.25, 188006.75, 536995.25, 188037.25, 536995.25, 188149.25, 536995.25, 188075.25, - 536995.25, 187932.75, 536995.25, 188069.75, 536995.25, 188005.75, 536995.25, 188096.25, - 536995.25, 188097.25, 536995.25, 188074.75, 536995.25, 187948.75, 536995.25, 188102.75, - 536995.25, 188038.25, 536995.25, 187932.25, 536995.25, 187965.75, 536995.25, 187988.75, - 536995.25, 188015.25, 536995.25, 187934.75, 536995.25, 188042.25, 536995.75, 187998.25, - 536995.75, 188050.75, 536995.75, 187961.75, 536995.75, 188006.25, 536995.75, 188137.75, - 536995.75, 188074.75, 536995.75, 188061.75, 536995.75, 187962.75, 536995.75, 188016.25, - 536995.75, 188143.25, 536995.75, 187988.25, 536995.75, 188038.25, 536995.75, 188039.25, - 536995.75, 188037.25, 536995.75, 188101.25, 536995.75, 188055.25, 536995.75, 187953.75, - 536995.75, 188030.75, 536995.75, 187950.75, 536995.75, 188004.75, 536995.75, 188043.75, - 536995.75, 188105.75, 536995.75, 188126.75, 536995.75, 188032.25, 536995.75, 188069.25, - 536995.75, 188100.25, 536995.75, 187915.25, 536995.75, 187950.25, 536995.75, 188004.25, - 536995.75, 187960.75, 536995.75, 187933.25, 536995.75, 188098.25, 536995.75, 187956.25, - 536995.75, 188152.25, 536995.75, 187947.25, 536995.75, 188057.25, 536995.75, 188061.25, - 536995.75, 188093.25, 536995.75, 188060.75, 536995.75, 187940.25, 536995.75, 188007.75, - 536995.75, 188026.75, 536995.75, 188003.75, 536995.75, 188028.75, 536995.75, 188031.25, - 536995.75, 187923.25, 536995.75, 187999.75, 536995.75, 187972.75, 536995.75, 187927.25, - 536995.75, 188150.75, 536995.75, 188119.25, 536995.75, 187954.25, 536995.75, 188075.75, - 536995.75, 188068.75, 536995.75, 187986.75, 536995.75, 188060.25, 536995.75, 188122.75, - 536995.75, 187959.75, 536995.75, 188054.25, 536995.75, 188151.75, 536995.75, 188149.75, - 536995.75, 187947.75, 536995.75, 188012.75, 536995.75, 188000.25, 536995.75, 188147.75, - 536995.75, 188146.25, 536995.75, 188042.75, 536995.75, 188043.25, 536995.75, 188104.75, - 536995.75, 187938.25, 536995.75, 188123.75, 536995.75, 187996.75, 536995.75, 188118.25, - 536995.75, 188059.75, 536995.75, 188127.25, 536995.75, 188127.75, 536995.75, 188142.25, - 536995.75, 188125.25, 536995.75, 187966.25, 536995.75, 187964.25, 536995.75, 188121.25, - 536995.75, 187946.25, 536995.75, 188076.25, 536995.75, 188135.25, 536995.75, 188001.75, - 536995.75, 188096.75, 536995.75, 187960.25, 536995.75, 188009.75, 536995.75, 188094.25, - 536995.75, 188046.25, 536995.75, 188027.25, 536995.75, 188031.75, 536995.75, 187914.75, - 536995.75, 188150.25, 536995.75, 188085.25, 536995.75, 187962.25, 536995.75, 187976.75, - 536995.75, 188104.25, 536995.75, 187928.25, 536995.75, 188047.25, 536995.75, 188027.75, - 536995.75, 188122.25, 536995.75, 188083.75, 536995.75, 188102.25, 536995.75, 188041.75, - 536995.75, 187963.25, 536995.75, 188002.75, 536996.25, 188147.25, 536996.25, 188041.75, - 536996.25, 188104.25, 536996.25, 187963.25, 536996.25, 188047.25, 536996.25, 187965.25, - 536996.25, 188125.75, 536996.25, 188001.25, 536996.25, 188122.25, 536996.25, 188031.75, - 536996.25, 188096.75, 536996.25, 188027.25, 536996.25, 188099.25, 536996.25, 187962.25, - 536996.25, 188001.75, 536996.25, 187987.75, 536996.25, 187949.25, 536996.25, 188126.25, - 536996.25, 188052.25, 536996.25, 188053.75, 536996.25, 188037.75, 536996.25, 188146.75, - 536996.25, 187975.25, 536996.25, 188044.25, 536996.25, 188127.25, 536996.25, 188158.25, - 536996.25, 188146.25, 536996.25, 188122.75, 536996.25, 188104.75, 536996.25, 188118.25, - 536996.25, 188116.75, 536996.25, 188017.75, 536996.25, 188054.25, 536996.25, 188126.75, - 536996.25, 188136.75, 536996.25, 188120.25, 536996.25, 188145.25, 536996.25, 188127.75, - 536996.25, 187986.25, 536996.25, 188152.25, 536996.25, 187933.25, 536996.25, 188031.25, - 536996.25, 188095.25, 536996.25, 188028.75, 536996.25, 187950.25, 536996.25, 187932.25, - 536996.25, 187912.75, 536996.25, 187977.75, 536996.25, 188042.75, 536996.25, 188092.75, - 536996.25, 188109.75, 536996.25, 188055.25, 536996.25, 187960.75, 536996.25, 188075.25, - 536996.25, 188105.25, 536996.25, 188151.25, 536996.25, 187988.25, 536996.25, 188159.25, - 536996.25, 188026.25, 536996.25, 187961.75, 536996.25, 188040.25, 536996.25, 187967.25, - 536996.25, 187998.75, 536996.25, 188125.25, 536996.25, 187948.75, 536996.25, 188030.75, - 536996.25, 188006.25, 536996.25, 188098.25, 536996.25, 188097.25, 536996.25, 188139.25, - 536996.25, 187953.25, 536996.25, 187913.75, 536996.25, 187945.75, 536996.25, 188118.75, - 536996.25, 188102.75, 536996.25, 187965.75, 536996.25, 188014.75, 536996.25, 188061.75, - 536996.25, 188045.25, 536996.25, 187962.75, 536996.25, 188042.25, 536996.25, 187927.75, - 536996.25, 188057.25, 536996.25, 188006.75, 536996.25, 188043.75, 536996.25, 188036.25, - 536996.25, 188085.25, 536996.25, 187915.75, 536996.25, 188043.25, 536996.25, 188093.25, - 536996.25, 188061.25, 536996.25, 188060.75, 536996.25, 188007.75, 536996.25, 188090.25, - 536996.25, 188101.25, 536996.25, 188012.75, 536996.25, 188085.75, 536996.25, 188121.75, - 536996.25, 188089.75, 536996.25, 187959.25, 536996.25, 188011.25, 536996.25, 187933.75, - 536996.25, 188149.75, 536996.25, 188060.25, 536996.25, 187923.75, 536996.25, 188083.75, - 536996.25, 188123.75, 536996.25, 188100.75, 536996.25, 188010.25, 536996.25, 187961.25, - 536996.25, 188078.75, 536996.25, 187946.25, 536996.25, 187930.75, 536996.25, 188030.25, - 536996.25, 188059.25, 536996.25, 188046.25, 536996.75, 187959.25, 536996.75, 188094.25, - 536996.75, 188088.25, 536996.75, 187964.25, 536996.75, 188150.25, 536996.75, 188059.25, - 536996.75, 187961.25, 536996.75, 188038.75, 536996.75, 187946.25, 536996.75, 188100.75, - 536996.75, 187974.25, 536996.75, 188103.25, 536996.75, 188083.25, 536996.75, 188093.75, - 536996.75, 188058.75, 536996.75, 187963.75, 536996.75, 188060.25, 536996.75, 187914.25, - 536996.75, 188124.75, 536996.75, 187948.25, 536996.75, 187966.25, 536996.75, 188012.25, - 536996.75, 188097.75, 536996.75, 188007.25, 536996.75, 187995.25, 536996.75, 187915.75, - 536996.75, 188149.25, 536996.75, 187982.25, 536996.75, 188014.25, 536996.75, 188094.75, - 536996.75, 187916.75, 536996.75, 188045.25, 536996.75, 187945.75, 536996.75, 187997.75, - 536996.75, 187998.25, 536996.75, 187953.25, 536996.75, 187965.75, 536996.75, 188143.75, - 536996.75, 188030.75, 536996.75, 187998.75, 536996.75, 188005.75, 536996.75, 187950.75, - 536996.75, 188004.75, 536996.75, 188046.75, 536996.75, 188144.75, 536996.75, 188124.25, - 536996.75, 187944.75, 536996.75, 187957.75, 536996.75, 188055.75, 536996.75, 188042.75, - 536996.75, 188039.25, 536996.75, 188097.25, 536996.75, 187931.25, 536996.75, 187936.75, - 536996.75, 187999.25, 536996.75, 188026.75, 536996.75, 188003.75, 536996.75, 188100.25, - 536996.75, 188028.75, 536996.75, 188044.75, 536996.75, 188054.75, 536996.75, 188116.25, - 536996.75, 187986.25, 536996.75, 187986.75, 536996.75, 187959.75, 536996.75, 188065.75, - 536996.75, 188145.75, 536996.75, 188000.25, 536996.75, 188002.25, 536996.75, 188092.25, - 536996.75, 187949.75, 536996.75, 188126.25, 536996.75, 188076.25, 536996.75, 188117.25, - 536996.75, 187930.25, 536996.75, 187954.75, 536996.75, 188027.25, 536996.75, 187914.75, - 536996.75, 187960.25, 536996.75, 188122.75, 536996.75, 188102.25, 536996.75, 188118.25, - 536996.75, 188159.75, 536997.25, 187964.75, 536997.25, 188076.75, 536997.25, 188088.75, - 536997.25, 188084.75, 536997.25, 187958.25, 536997.25, 188118.25, 536997.25, 187945.25, - 536997.25, 187949.25, 536997.25, 188075.75, 536997.25, 188045.75, 536997.25, 188051.25, - 536997.25, 187944.75, 536997.25, 187957.75, 536997.25, 188095.75, 536997.25, 187913.75, - 536997.25, 187974.75, 536997.25, 188136.25, 536997.25, 188095.25, 536997.25, 188098.25, - 536997.25, 187990.75, 536997.25, 188055.25, 536997.25, 187935.25, 536997.25, 188055.75, - 536997.25, 187967.25, 536997.25, 187995.75, 536997.25, 187956.75, 536997.25, 187910.75, - 536997.25, 187963.75, 536997.25, 188150.25, 536997.25, 188014.25, 536997.25, 188088.25, - 536997.25, 188094.75, 536997.25, 187964.25, 536997.25, 187996.25, 536997.25, 188084.25, - 536997.25, 188087.75, 536997.25, 188119.25, 536997.25, 188029.25, 536997.25, 187989.25, - 536997.25, 188069.75, 536997.25, 188043.25, 536997.25, 187997.75, 536997.25, 188013.25, - 536997.25, 188102.75, 536997.25, 187966.25, 536997.25, 188148.75, 536997.25, 188083.75, - 536997.25, 188099.75, 536997.25, 187988.75, 536997.25, 187951.75, 536997.25, 188083.25, - 536997.25, 188098.75, 536997.25, 187998.75, 536997.25, 188037.25, 536997.25, 188010.75, - 536997.25, 188096.25, 536997.25, 188160.25, 536997.25, 187947.25, 536997.25, 188009.25, - 536997.25, 187961.25, 536997.25, 188148.25, 536997.25, 188094.25, 536997.25, 187933.25, - 536997.25, 188059.75, 536997.25, 187984.25, 536997.25, 187959.75, 536997.25, 188091.25, - 536997.25, 188158.25, 536997.25, 188000.25, 536997.25, 187955.25, 536997.25, 187952.25, - 536997.25, 188068.25, 536997.25, 187984.75, 536997.25, 187965.25, 536997.25, 188027.75, - 536997.25, 188123.25, 536997.25, 188147.25, 536997.25, 188120.75, 536997.25, 188067.75, - 536997.25, 188060.25, 536997.25, 188122.75, 536997.25, 188142.75, 536997.25, 188087.25, - 536997.25, 187948.25, 536997.25, 188082.25, 536997.25, 188085.75, 536997.25, 188008.25, - 536997.25, 188086.75, 536997.25, 188043.75, 536997.25, 188132.75, 536997.25, 188143.25, - 536997.25, 188047.75, 536997.25, 188143.75, 536997.25, 187970.25, 536997.25, 188145.75, - 536997.25, 187945.75, 536997.25, 188003.25, 536997.25, 187986.75, 536997.25, 187954.25, - 536997.25, 188101.75, 536997.25, 188092.75, 536997.25, 187953.25, 536997.25, 188081.25, - 536997.25, 188125.25, 536997.25, 188003.75, 536997.25, 187986.25, 536997.25, 188144.75, - 536997.25, 188159.25, 536997.25, 188026.75, 536997.25, 187969.75, 536997.25, 187960.75, - 536997.75, 188004.25, 536997.75, 188145.25, 536997.75, 188026.75, 536997.75, 188081.75, - 536997.75, 187915.25, 536997.75, 187986.25, 536997.75, 188144.75, 536997.75, 187932.75, - 536997.75, 187953.75, 536997.75, 188003.75, 536997.75, 188005.25, 536997.75, 188086.75, - 536997.75, 188159.75, 536997.75, 188003.25, 536997.75, 188158.75, 536997.75, 188143.75, - 536997.75, 188146.75, 536997.75, 188006.75, 536997.75, 188092.25, 536997.75, 187928.75, - 536997.75, 188147.25, 536997.75, 188043.75, 536997.75, 188093.25, 536997.75, 188008.25, - 536997.75, 188101.25, 536997.75, 188087.25, 536997.75, 187948.25, 536997.75, 188096.75, - 536997.75, 187971.25, 536997.75, 188080.75, 536997.75, 188067.75, 536997.75, 188142.75, - 536997.75, 188122.75, 536997.75, 188027.75, 536997.75, 188068.25, 536997.75, 187984.75, - 536997.75, 188121.25, 536997.75, 187959.75, 536997.75, 187984.25, 536997.75, 187952.25, - 536997.75, 187971.75, 536997.75, 188148.25, 536997.75, 188028.75, 536997.75, 187999.25, - 536997.75, 187947.25, 536997.75, 188010.25, 536997.75, 187988.25, 536997.75, 188010.75, - 536997.75, 188083.25, 536997.75, 188076.75, 536997.75, 188099.75, 536997.75, 187926.75, - 536997.75, 188098.75, 536997.75, 188100.75, 536997.75, 187998.75, 536997.75, 188148.75, - 536997.75, 187966.25, 536997.75, 188011.25, 536997.75, 187983.25, 536997.75, 188102.75, - 536997.75, 188012.25, 536997.75, 188012.75, 536997.75, 187998.25, 536997.75, 187997.75, - 536997.75, 188043.25, 536997.75, 188070.25, 536997.75, 188119.25, 536997.75, 188084.25, - 536997.75, 187980.75, 536997.75, 187973.25, 536997.75, 188057.75, 536997.75, 188013.75, - 536997.75, 188035.25, 536997.75, 188123.75, 536997.75, 187964.25, 536997.75, 188042.75, - 536997.75, 188070.75, 536997.75, 187956.75, 536997.75, 188089.25, 536997.75, 187967.25, - 536997.75, 187995.75, 536997.75, 188098.25, 536997.75, 188055.25, 536997.75, 188095.25, - 536997.75, 188045.25, 536997.75, 188054.25, 536997.75, 188116.75, 536997.75, 187994.25, - 536997.75, 187913.75, 536997.75, 188075.75, 536997.75, 187944.75, 536997.75, 188045.75, - 536997.75, 187945.25, 536997.75, 188095.75, 536997.75, 188134.75, 536997.75, 187958.25, - 536997.75, 188084.75, 536997.75, 188122.25, 536998.25, 187991.25, 536998.25, 188087.75, - 536998.25, 188118.25, 536998.25, 187966.75, 536998.25, 188046.75, 536998.25, 188100.25, - 536998.25, 188069.25, 536998.25, 187947.25, 536998.25, 187950.25, 536998.25, 188091.25, - 536998.25, 188068.75, 536998.25, 188157.25, 536998.25, 187956.25, 536998.25, 187967.25, - 536998.25, 187997.25, 536998.25, 188090.25, 536998.25, 188056.25, 536998.25, 187980.25, - 536998.25, 188157.75, 536998.25, 187983.25, 536998.25, 188100.75, 536998.25, 188158.25, - 536998.25, 188097.75, 536998.25, 187950.75, 536998.25, 187983.75, 536998.25, 188147.75, - 536998.25, 188070.25, 536998.25, 188082.75, 536998.25, 188096.25, 536998.25, 188089.75, - 536998.25, 187965.25, 536998.25, 187996.25, 536998.25, 188082.25, 536998.25, 188070.75, - 536998.25, 188000.75, 536998.25, 188094.75, 536998.25, 188046.25, 536998.25, 188091.75, - 536998.25, 187945.75, 536998.25, 187985.25, 536998.25, 187957.25, 536998.25, 188010.75, - 536998.25, 188059.25, 536998.25, 187957.75, 536998.25, 187954.75, 536998.25, 188009.25, - 536998.25, 188076.25, 536998.25, 188086.75, 536998.25, 188076.75, 536998.25, 188038.75, - 536998.25, 187947.75, 536998.25, 188094.25, 536998.25, 187989.75, 536998.25, 188080.75, - 536998.25, 188048.25, 536998.25, 188122.75, 536998.25, 187959.25, 536998.25, 188144.25, - 536998.25, 187987.75, 536998.25, 188143.25, 536998.25, 188119.75, 536998.25, 187959.75, - 536998.75, 188143.25, 536998.75, 188080.25, 536998.75, 188099.25, 536998.75, 188048.75, - 536998.75, 188079.75, 536998.75, 188061.75, 536998.75, 188159.75, 536998.75, 188079.25, - 536998.75, 187965.75, 536998.75, 188006.25, 536998.75, 188051.75, 536998.75, 188144.25, - 536998.75, 187946.25, 536998.75, 188093.75, 536998.75, 188088.25, 536998.75, 188080.75, - 536998.75, 188004.75, 536998.75, 188155.75, 536998.75, 188142.25, 536998.75, 188078.25, - 536998.75, 188159.25, 536998.75, 187958.75, 536998.75, 188077.75, 536998.75, 187969.75, - 536998.75, 188077.25, 536998.75, 188003.75, 536998.75, 188092.75, 536998.75, 187954.25, - 536998.75, 187960.25, 536998.75, 188088.75, 536998.75, 188123.75, 536998.75, 188081.25, - 536998.75, 188002.25, 536998.75, 188047.75, 536998.75, 188009.25, 536998.75, 188009.75, - 536998.75, 188092.25, 536998.75, 188124.25, 536998.75, 188086.25, 536998.75, 188001.25, - 536998.75, 187966.25, 536998.75, 187945.75, 536998.75, 188096.75, 536998.75, 188047.25, - 536998.75, 187956.75, 536998.75, 188012.25, 536998.75, 188133.25, 536998.75, 188000.75, - 536998.75, 188128.75, 536998.75, 188070.75, 536998.75, 188057.25, 536998.75, 188085.75, - 536998.75, 188121.25, 536998.75, 187996.75, 536998.75, 187955.25, 536998.75, 188123.25, - 536998.75, 188096.25, 536998.75, 188070.25, 536998.75, 187961.25, 536998.75, 188000.25, - 536998.75, 188115.25, 536998.75, 188097.75, 536998.75, 187983.75, 536998.75, 187997.25, - 536998.75, 188015.25, 536998.75, 188043.25, 536998.75, 188085.25, 536998.75, 188055.75, - 536998.75, 188157.75, 536998.75, 187982.75, 536998.75, 187956.25, 536998.75, 188068.75, - 536998.75, 188055.25, 536998.75, 187982.25, 536998.75, 187999.75, 536998.75, 188097.25, - 536998.75, 188090.75, 536998.75, 187955.75, 536998.75, 187949.75, 536998.75, 188095.75, - 536998.75, 187981.25, 536998.75, 187964.75, 536999.25, 187964.75, 536999.25, 188069.25, - 536999.25, 188123.75, 536999.25, 187955.75, 536999.25, 188090.75, 536999.25, 188095.75, - 536999.25, 188051.75, 536999.25, 187998.75, 536999.25, 187981.25, 536999.25, 188070.25, - 536999.25, 187956.25, 536999.25, 187949.25, 536999.25, 187982.25, 536999.25, 188157.75, - 536999.25, 188157.25, 536999.25, 187972.75, 536999.25, 187982.75, 536999.25, 187997.25, - 536999.25, 188095.25, 536999.25, 188055.75, 536999.25, 188034.75, 536999.25, 187996.75, - 536999.25, 188124.75, 536999.25, 188068.25, 536999.25, 187967.25, 536999.25, 187965.25, - 536999.25, 188070.75, 536999.25, 188000.75, 536999.25, 187983.25, 536999.25, 188099.75, - 536999.25, 188120.75, 536999.25, 188047.25, 536999.25, 187948.75, 536999.25, 188057.25, - 536999.25, 188001.25, 536999.25, 188089.25, 536999.25, 188096.75, 536999.25, 187961.25, - 536999.25, 187957.25, 536999.25, 187994.25, 536999.25, 188092.25, 536999.25, 188076.25, - 536999.25, 188001.75, 536999.25, 188045.75, 536999.25, 187954.75, 536999.25, 188131.75, - 536999.25, 188123.25, 536999.25, 188002.25, 536999.25, 188076.75, 536999.25, 188043.75, - 536999.25, 188119.25, 536999.25, 188146.25, 536999.25, 188088.75, 536999.25, 187985.25, - 536999.25, 188010.25, 536999.25, 188086.25, 536999.25, 187968.25, 536999.25, 187960.75, - 536999.25, 188086.75, 536999.25, 188081.25, 536999.25, 187960.25, 536999.25, 188094.25, - 536999.25, 188078.75, 536999.25, 188009.25, 536999.25, 188142.25, 536999.25, 188098.75, - 536999.25, 188079.25, 536999.25, 188144.25, 536999.25, 188008.75, 536999.25, 188087.75, - 536999.25, 187965.75, 536999.25, 188080.75, 536999.25, 188093.75, 536999.25, 187953.25, - 536999.25, 188099.25, 536999.25, 188159.75, 536999.25, 188143.25, 536999.25, 188079.75, - 536999.75, 188080.25, 536999.75, 187931.25, 536999.75, 188099.25, 536999.75, 188079.75, - 536999.75, 188143.25, 536999.75, 188142.75, 536999.75, 188046.75, 536999.75, 187922.25, - 536999.75, 188087.75, 536999.75, 188006.25, 536999.75, 187960.25, 536999.75, 187959.25, - 536999.75, 188004.75, 536999.75, 188078.25, 536999.75, 188159.25, 536999.75, 188077.75, - 536999.75, 188048.25, 536999.75, 187960.75, 536999.75, 188004.25, 536999.75, 188141.75, - 536999.75, 188160.25, 536999.75, 188145.25, 536999.75, 188156.25, 536999.75, 188077.25, - 536999.75, 188086.25, 536999.75, 188094.75, 536999.75, 187966.25, 536999.75, 187985.75, - 536999.75, 187951.75, 536999.75, 188011.75, 536999.75, 188088.75, 536999.75, 188140.75, - 536999.75, 188124.25, 536999.75, 187968.25, 536999.75, 187985.25, 536999.75, 188158.75, - 536999.75, 187954.75, 536999.75, 188034.25, 536999.75, 188091.75, 536999.75, 188001.25, - 536999.75, 187967.75, 536999.75, 188057.25, 536999.75, 187946.75, 536999.75, 188085.75, - 536999.75, 188156.75, 536999.75, 187980.25, 536999.75, 187956.75, 536999.75, 188056.25, - 536999.75, 188085.25, 536999.75, 187965.25, 536999.75, 188096.25, 536999.75, 187955.25, - 536999.75, 187973.25, 536999.75, 188095.25, 536999.75, 187997.25, 536999.75, 188097.75, - 536999.75, 188133.75, 536999.75, 188124.75, 536999.75, 187910.75, 536999.75, 187982.25, - 536999.75, 188053.75, 536999.75, 188068.75, 536999.75, 187981.75, 536999.75, 188069.75, - 536999.75, 188157.75, 536999.75, 187981.25, 536999.75, 188091.25, 536999.75, 188095.75, - 536999.75, 187953.25, 537000.25, 187946.75, 537000.25, 187992.75, 537000.25, 188089.25, - 537000.25, 188001.75, 537000.25, 188058.75, 537000.25, 188047.75, 537000.25, 188141.25, - 537000.25, 187958.25, 537000.25, 187991.25, 537000.25, 187952.25, 537000.25, 188098.25, - 537000.25, 188140.75, 537000.25, 188088.75, 537000.25, 187966.75, 537000.25, 188093.25, - 537000.25, 188140.25, 537000.25, 188077.75, 537000.25, 188088.25, 537000.25, 187995.25, - 537000.25, 188071.75, 537000.25, 187958.75, 537000.25, 188090.25, 537000.25, 187928.75, - 537000.25, 188057.25, 537000.25, 188007.25, 537000.25, 188157.25, 537000.25, 187947.25, - 537000.25, 188003.25, 537000.25, 188056.75, 537000.25, 188048.75, 537000.25, 188125.25, - 537000.25, 188078.75, 537000.25, 187955.25, 537000.25, 187954.25, 537000.25, 187942.25, - 537000.25, 187959.25, 537000.25, 187972.25, 537000.25, 188015.25, 537000.25, 188049.25, - 537000.25, 188049.75, 537000.25, 188106.25, 537000.25, 188159.25, 537000.25, 187956.75, - 537000.25, 187987.75, 537000.25, 188097.25, 537000.25, 188000.25, 537000.25, 188092.75, - 537000.25, 187996.25, 537000.25, 188095.25, 537000.25, 187960.25, 537000.25, 188046.25, - 537000.25, 187999.25, 537000.25, 188143.75, 537000.25, 188124.25, 537000.25, 188099.75, - 537000.25, 188018.75, 537000.25, 187932.75, 537000.25, 188154.25, 537000.25, 187979.25, - 537000.25, 188085.75, 537000.25, 187967.75, 537000.25, 187984.25, 537000.25, 188091.25, - 537000.25, 188130.25, 537000.25, 187979.75, 537000.25, 188070.25, 537000.25, 188053.25, - 537000.25, 188100.75, 537000.25, 188019.75, 537000.25, 187951.75, 537000.25, 187980.25, - 537000.25, 188158.25, 537000.25, 187953.75, 537000.25, 188085.25, 537000.25, 187965.25, - 537000.25, 188144.25, 537000.25, 187980.75, 537000.25, 188005.25, 537000.25, 187911.25, - 537000.25, 188100.25, 537000.25, 188124.75, 537000.25, 188091.75, 537000.25, 187997.75, - 537000.25, 188084.25, 537000.25, 188107.25, 537000.75, 188154.75, 537000.75, 188052.25, - 537000.75, 188091.75, 537000.75, 188124.75, 537000.75, 187997.75, 537000.75, 188096.25, - 537000.75, 188135.25, 537000.75, 188100.25, 537000.75, 188100.75, 537000.75, 188085.25, - 537000.75, 188144.75, 537000.75, 187980.25, 537000.75, 187944.25, 537000.75, 187971.75, - 537000.75, 188070.25, 537000.75, 188157.75, 537000.75, 188005.75, 537000.75, 188091.25, - 537000.75, 187967.75, 537000.75, 188085.75, 537000.75, 187984.75, 537000.75, 187921.75, - 537000.75, 188092.25, 537000.75, 188158.75, 537000.75, 187946.75, 537000.75, 188006.25, - 537000.75, 188106.75, 537000.75, 188069.25, 537000.75, 188018.75, 537000.75, 188017.75, - 537000.75, 188099.75, 537000.75, 188124.25, 537000.75, 187999.25, 537000.75, 187978.75, - 537000.75, 188070.75, 537000.75, 188097.25, 537000.75, 187950.25, 537000.75, 188092.75, - 537000.75, 188000.25, 537000.75, 187964.75, 537000.75, 187959.75, 537000.75, 187956.75, - 537000.75, 188068.75, 537000.75, 188145.25, 537000.75, 187918.25, 537000.75, 188099.25, - 537000.75, 187976.25, 537000.75, 187954.25, 537000.75, 187955.25, 537000.75, 187965.75, - 537000.75, 188056.75, 537000.75, 187947.25, 537000.75, 188048.75, 537000.75, 188057.25, - 537000.75, 188003.25, 537000.75, 188145.75, 537000.75, 188078.25, 537000.75, 187990.75, - 537000.75, 188090.25, 537000.75, 187958.75, 537000.75, 188098.75, 537000.75, 188143.25, - 537000.75, 188088.25, 537000.75, 188097.75, 537000.75, 188077.75, 537000.75, 188140.25, - 537000.75, 188048.25, 537000.75, 188093.25, 537000.75, 188088.75, 537000.75, 188008.25, - 537000.75, 188077.25, 537000.75, 188140.75, 537000.75, 188108.25, 537000.75, 187994.25, - 537000.75, 188002.25, 537000.75, 188095.75, 537000.75, 187952.25, 537000.75, 188128.75, - 537000.75, 187991.75, 537000.75, 188047.25, 537000.75, 187958.25, 537000.75, 188141.25, - 537000.75, 188098.25, 537000.75, 188089.25, 537000.75, 187951.75, 537000.75, 188151.75, - 537000.75, 188156.75, 537000.75, 188141.75, 537000.75, 188151.25, 537001.25, 187957.75, - 537001.25, 188151.25, 537001.25, 187944.25, 537001.25, 188144.75, 537001.25, 188151.75, - 537001.25, 187953.75, 537001.25, 188095.25, 537001.25, 188039.75, 537001.25, 188096.75, - 537001.25, 188084.75, 537001.25, 187979.25, 537001.25, 188058.75, 537001.25, 188045.75, - 537001.25, 188100.75, 537001.25, 188104.75, 537001.25, 188088.75, 537001.25, 187999.25, - 537001.25, 187967.25, 537001.25, 187958.25, 537001.25, 188005.25, 537001.25, 188020.25, - 537001.25, 187952.25, 537001.25, 187968.75, 537001.25, 188094.25, 537001.25, 188058.25, - 537001.25, 188083.75, 537001.25, 187993.75, 537001.25, 188086.25, 537001.25, 188070.25, - 537001.25, 187991.25, 537001.25, 187978.25, 537001.25, 187911.75, 537001.25, 187951.25, - 537001.25, 188072.75, 537001.25, 188157.75, 537001.25, 187956.25, 537001.25, 187997.25, - 537001.25, 188019.25, 537001.25, 188125.25, 537001.25, 188150.75, 537001.25, 188066.25, - 537001.25, 188049.75, 537001.25, 188070.75, 537001.25, 188088.25, 537001.25, 187985.75, - 537001.25, 188090.75, 537001.25, 188097.75, 537001.25, 187976.75, 537001.25, 187966.25, - 537001.25, 188084.25, 537001.25, 187945.75, 537001.25, 188153.75, 537001.25, 188044.75, - 537001.25, 188087.75, 537001.25, 188139.75, 537001.25, 187950.25, 537001.25, 187996.25, - 537001.25, 188155.75, 537001.25, 188003.75, 537001.25, 188102.25, 537001.25, 188107.75, - 537001.25, 188057.25, 537001.25, 188092.75, 537001.25, 188157.25, 537001.25, 188007.25, - 537001.25, 188049.25, 537001.25, 188124.25, 537001.25, 188099.25, 537001.25, 187948.25, - 537001.25, 188006.75, 537001.25, 188138.75, 537001.25, 188046.75, 537001.25, 188106.25, - 537001.25, 188137.75, 537001.25, 188122.75, 537001.25, 188000.75, 537001.75, 188015.25, - 537001.75, 187968.25, 537001.75, 188138.25, 537001.75, 187969.75, 537001.75, 187976.25, - 537001.75, 188102.75, 537001.75, 188138.75, 537001.75, 188137.75, 537001.75, 188106.25, - 537001.75, 187950.75, 537001.75, 187955.25, 537001.75, 188107.75, 537001.75, 188071.25, - 537001.75, 188139.25, 537001.75, 187952.75, 537001.75, 188108.75, 537001.75, 187987.25, - 537001.75, 187969.25, 537001.75, 188048.75, 537001.75, 188139.75, 537001.75, 188044.75, - 537001.75, 188033.75, 537001.75, 188088.25, 537001.75, 187944.75, 537001.75, 188137.25, - 537001.75, 187986.75, 537001.75, 188155.75, 537001.75, 188101.75, 537001.75, 188094.75, - 537001.75, 188086.75, 537001.75, 188017.75, 537001.75, 188057.75, 537001.75, 188071.75, - 537001.75, 187939.25, 537001.75, 187942.75, 537001.75, 188061.75, 537001.75, 187995.25, - 537001.75, 187994.75, 537001.75, 188125.25, 537001.75, 188002.75, 537001.75, 187977.25, - 537001.75, 188101.25, 537001.75, 187977.75, 537001.75, 188053.75, 537001.75, 188126.25, - 537001.75, 188000.25, 537001.75, 188154.25, 537001.75, 188001.25, 537001.75, 188152.25, - 537001.75, 188132.25, 537001.75, 188045.25, 537001.75, 188127.25, 537001.75, 187957.25, - 537001.75, 188156.25, 537001.75, 188070.25, 537001.75, 188036.75, 537001.75, 188034.25, - 537001.75, 188083.75, 537001.75, 188130.75, 537001.75, 188020.25, 537001.75, 187978.75, - 537001.75, 187991.75, 537001.75, 187968.75, 537001.75, 187952.25, 537001.75, 188155.25, - 537001.75, 188050.25, 537001.75, 187929.25, 537001.75, 188141.25, 537001.75, 188088.75, - 537001.75, 188107.25, 537001.75, 187966.75, 537001.75, 187943.25, 537001.75, 187948.75, - 537001.75, 187946.75, 537001.75, 188058.75, 537001.75, 188094.25, 537001.75, 187998.25, - 537001.75, 188096.25, 537001.75, 187949.25, 537001.75, 188100.25, 537001.75, 188108.25, - 537001.75, 188021.25, 537001.75, 187998.75, 537001.75, 187980.75, 537001.75, 188091.25, - 537001.75, 188125.75, 537001.75, 188039.75, 537001.75, 188085.25, 537001.75, 188095.25, - 537001.75, 187953.75, 537001.75, 188047.75, 537001.75, 187992.75, 537001.75, 188040.75, - 537001.75, 187979.75, 537001.75, 188151.25, 537002.25, 188004.75, 537002.25, 187998.75, - 537002.25, 188095.25, 537002.25, 188037.75, 537002.25, 188064.25, 537002.25, 188085.25, - 537002.25, 187980.75, 537002.25, 188091.25, 537002.25, 187979.75, 537002.25, 188096.25, - 537002.25, 187955.75, 537002.25, 188004.25, 537002.25, 188124.75, 537002.25, 187931.75, - 537002.25, 187998.25, 537002.25, 188020.75, 537002.25, 187943.25, 537002.25, 188100.75, - 537002.25, 187999.25, 537002.25, 188091.75, 537002.25, 188099.75, 537002.25, 188155.25, - 537002.25, 188107.25, 537002.25, 188050.25, 537002.25, 187999.75, 537002.25, 188154.75, - 537002.25, 188000.25, 537002.25, 188052.75, 537002.25, 187978.75, 537002.25, 188129.75, - 537002.25, 188083.75, 537002.25, 187967.75, 537002.25, 188045.25, 537002.25, 188154.25, - 537002.25, 187996.75, 537002.25, 188041.75, 537002.25, 188126.25, 537002.25, 187964.75, - 537002.25, 187949.75, 537002.25, 187977.25, 537002.25, 188019.25, 537002.25, 188006.25, - 537002.25, 188136.25, 537002.25, 187944.75, 537002.25, 187986.25, 537002.25, 188081.25, - 537002.25, 188155.75, 537002.25, 188137.25, 537002.25, 188017.25, 537002.25, 188102.25, - 537002.25, 188042.25, 537002.25, 187910.75, 537002.25, 188000.75, 537002.25, 188032.75, - 537002.25, 187956.75, 537002.25, 187948.25, 537002.25, 188046.75, 537002.25, 188095.75, - 537002.25, 188138.25, 537002.25, 187969.75, 537002.25, 187976.25, 537002.25, 188106.25, - 537002.25, 187947.25, 537002.25, 187955.25, 537002.25, 188107.75, 537002.25, 188007.25, - 537002.25, 188139.25, 537002.25, 188127.75, 537002.25, 187966.75, 537002.25, 188139.75, - 537002.25, 187952.75, 537002.25, 188033.75, 537002.25, 187975.75, 537002.25, 188108.75, - 537002.25, 188088.25, 537002.25, 188071.75, 537002.25, 188057.75, 537002.25, 188043.75, - 537002.25, 188140.25, 537002.25, 187994.75, 537002.25, 188094.75, 537002.25, 188152.25, - 537002.25, 187963.75, 537002.25, 188108.25, 537002.25, 188156.25, 537002.25, 187911.75, - 537002.25, 187957.25, 537002.25, 188160.25, 537002.25, 188088.75, 537002.25, 187952.25, - 537002.25, 187993.75, 537002.25, 188058.75, 537002.25, 188034.75, 537002.25, 187992.25, - 537002.25, 187951.75, 537002.25, 188094.25, 537002.25, 188039.75, 537002.25, 188151.25, - 537002.25, 188001.75, 537002.25, 187954.75, 537002.25, 187990.75, 537002.75, 187992.75, - 537002.75, 187937.25, 537002.75, 188038.25, 537002.75, 187921.75, 537002.75, 187996.75, - 537002.75, 187979.75, 537002.75, 188034.75, 537002.75, 188005.75, 537002.75, 188006.25, - 537002.75, 187967.25, 537002.75, 188093.75, 537002.75, 188058.25, 537002.75, 187974.25, - 537002.75, 188070.75, 537002.75, 188039.25, 537002.75, 188089.25, 537002.75, 188071.25, - 537002.75, 188034.25, 537002.75, 187955.25, 537002.75, 187991.25, 537002.75, 187956.75, - 537002.75, 188047.75, 537002.75, 187999.25, 537002.75, 187954.25, 537002.75, 188036.75, - 537002.75, 188040.75, 537002.75, 188154.75, 537002.75, 188093.25, 537002.75, 187967.75, - 537002.75, 187935.25, 537002.75, 187947.75, 537002.75, 188151.25, 537002.75, 187990.75, - 537002.75, 188083.75, 537002.75, 188001.25, 537002.75, 188126.25, 537002.75, 188038.75, - 537002.75, 187961.25, 537002.75, 188152.75, 537002.75, 187975.25, 537002.75, 188086.75, - 537002.75, 188045.25, 537002.75, 188101.25, 537002.75, 187997.75, 537002.75, 188001.75, - 537002.75, 187970.25, 537002.75, 187952.25, 537002.75, 188049.25, 537002.75, 188136.25, - 537002.75, 187976.75, 537002.75, 188014.75, 537002.75, 187969.75, 537002.75, 188136.75, - 537002.75, 187994.25, 537002.75, 188150.75, 537002.75, 188003.75, 537002.75, 187950.75, - 537002.75, 187942.25, 537002.75, 187935.75, 537002.75, 187950.25, 537002.75, 187989.25, - 537002.75, 188060.75, 537002.75, 187947.25, 537002.75, 188138.25, 537002.75, 188102.25, - 537002.75, 188142.75, 537002.75, 188094.75, 537002.75, 188090.25, 537002.75, 188048.75, - 537002.75, 188153.75, 537002.75, 188088.25, 537002.75, 188137.75, 537002.75, 188016.25, - 537002.75, 188092.75, 537002.75, 188125.25, 537002.75, 187966.75, 537002.75, 187975.75, - 537002.75, 188153.25, 537003.25, 188153.25, 537003.25, 187988.25, 537003.25, 188087.75, - 537003.25, 188016.75, 537003.25, 187953.75, 537003.25, 187987.25, 537003.25, 187936.25, - 537003.25, 188048.75, 537003.25, 188072.25, 537003.25, 188015.75, 537003.25, 188102.75, - 537003.25, 188033.25, 537003.25, 187947.25, 537003.25, 188060.75, 537003.25, 188072.75, - 537003.25, 188044.75, 537003.25, 187911.75, 537003.25, 187940.75, 537003.25, 188102.25, - 537003.25, 187948.25, 537003.25, 188032.75, 537003.25, 188054.75, 537003.25, 187995.25, - 537003.25, 188092.75, 537003.25, 188103.25, 537003.25, 188136.75, 537003.25, 188101.75, - 537003.25, 188018.25, 537003.25, 187970.25, 537003.25, 188037.75, 537003.25, 188042.75, - 537003.25, 188014.75, 537003.25, 188001.25, 537003.25, 188088.75, 537003.25, 187952.75, - 537003.25, 188126.75, 537003.25, 188035.75, 537003.25, 187933.75, 537003.25, 188004.75, - 537003.25, 188092.25, 537003.25, 187968.25, 537003.25, 187993.75, 537003.25, 188032.25, - 537003.25, 188003.25, 537003.25, 188086.75, 537003.25, 187935.25, 537003.25, 188135.75, - 537003.25, 187998.75, 537003.25, 188142.25, 537003.25, 188019.75, 537003.25, 187974.75, - 537003.25, 188040.75, 537003.25, 188049.75, 537003.25, 187947.75, 537003.25, 188093.25, - 537003.25, 188013.25, 537003.25, 187954.25, 537003.25, 188091.75, 537003.25, 187964.75, - 537003.25, 187995.75, 537003.25, 188084.25, 537003.25, 188108.25, 537003.25, 188047.75, - 537003.25, 187912.25, 537003.25, 188042.25, 537003.25, 188070.25, 537003.25, 188040.25, - 537003.25, 188086.25, 537003.25, 187961.75, 537003.25, 187996.25, 537003.25, 188059.25, - 537003.25, 188143.75, 537003.25, 187981.75, 537003.25, 187991.75, 537003.25, 187949.25, - 537003.25, 188125.75, 537003.25, 188002.25, 537003.25, 188134.75, 537003.25, 188030.25, - 537003.25, 187962.75, 537003.25, 188070.75, 537003.25, 188084.75, 537003.25, 188131.75, - 537003.25, 188106.75, 537003.25, 188151.75, 537003.25, 187971.25, 537003.25, 187996.75, - 537003.25, 188050.25, 537003.25, 187951.75, 537003.25, 188089.75, 537003.25, 188091.25, - 537003.25, 187968.75, 537003.25, 187948.75, 537003.25, 188041.75, 537003.25, 188050.75, - 537003.25, 187946.75, 537003.25, 187931.75, 537003.25, 187973.75, 537003.25, 187997.25, - 537003.75, 188041.75, 537003.75, 187997.25, 537003.75, 188038.25, 537003.75, 187948.25, - 537003.75, 187987.25, 537003.75, 187973.75, 537003.75, 188004.25, 537003.75, 187968.75, - 537003.75, 188060.75, 537003.75, 187946.75, 537003.75, 187995.25, 537003.75, 187992.25, - 537003.75, 188087.75, 537003.75, 187959.75, 537003.75, 188151.75, 537003.75, 187948.75, - 537003.75, 187979.75, 537003.75, 188092.75, 537003.75, 188050.25, 537003.75, 187996.75, - 537003.75, 188007.75, 537003.75, 187974.25, 537003.75, 188012.25, 537003.75, 187980.75, - 537003.75, 188006.25, 537003.75, 188051.25, 537003.75, 188136.75, 537003.75, 188072.25, - 537003.75, 187988.25, 537003.75, 188076.75, 537003.75, 188042.75, 537003.75, 188101.75, - 537003.75, 187951.25, 537003.75, 188058.25, 537003.75, 187953.25, 537003.75, 187953.75, - 537003.75, 188141.75, 537003.75, 187986.25, 537003.75, 188130.75, 537003.75, 187993.25, - 537003.75, 188089.25, 537003.75, 188005.75, 537003.75, 188084.75, 537003.75, 188153.25, - 537003.75, 188152.25, 537003.75, 188134.75, 537003.75, 187970.25, 537003.75, 188002.25, - 537003.75, 188133.25, 537003.75, 188018.75, 537003.75, 188071.75, 537003.75, 187949.25, - 537003.75, 187954.25, 537003.75, 188001.25, 537003.75, 187972.75, 537003.75, 187936.25, - 537003.75, 187947.75, 537003.75, 187952.75, 537003.75, 188047.25, 537003.75, 188040.75, - 537003.75, 187945.75, 537003.75, 188036.25, 537003.75, 187974.75, 537003.75, 188142.75, - 537003.75, 188151.25, 537003.75, 188126.75, 537003.75, 188035.75, 537003.75, 188013.75, - 537003.75, 188033.25, 537003.75, 188072.75, 537003.75, 187996.25, 537003.75, 187939.75, - 537003.75, 188071.25, 537003.75, 188125.75, 537003.75, 188079.75, 537003.75, 187967.25, - 537003.75, 188124.25, 537003.75, 187967.75, 537003.75, 188090.75, 537003.75, 187984.25, - 537003.75, 187935.25, 537003.75, 187973.25, 537003.75, 187933.75, 537003.75, 188084.25, - 537003.75, 188094.75, 537003.75, 187952.25, 537003.75, 188135.75, 537003.75, 188091.75, - 537003.75, 188032.25, 537003.75, 187995.75, 537003.75, 187983.25, 537003.75, 187911.75, - 537003.75, 188058.75, 537003.75, 188014.75, 537003.75, 188017.25, 537003.75, 188067.25, - 537003.75, 187977.25, 537003.75, 187940.75, 537003.75, 187965.75, 537003.75, 188035.25, - 537003.75, 187994.25, 537003.75, 188099.75, 537003.75, 188092.25, 537003.75, 187964.75, - 537003.75, 188049.75, 537004.25, 188103.25, 537004.25, 187969.75, 537004.25, 187994.25, - 537004.25, 188003.75, 537004.25, 187944.25, 537004.25, 187968.25, 537004.25, 187940.75, - 537004.25, 187995.75, 537004.25, 187959.25, 537004.25, 188107.25, 537004.25, 187961.25, - 537004.25, 188088.75, 537004.25, 187989.25, 537004.25, 188135.75, 537004.25, 188091.75, - 537004.25, 187933.75, 537004.25, 188086.75, 537004.25, 188003.25, 537004.25, 188059.75, - 537004.25, 188039.75, 537004.25, 187963.75, 537004.25, 187993.75, 537004.25, 188087.25, - 537004.25, 188150.25, 537004.25, 188036.75, 537004.25, 188015.25, 537004.25, 187975.25, - 537004.25, 188125.75, 537004.25, 188090.75, 537004.25, 188039.25, 537004.25, 188001.75, - 537004.25, 187935.75, 537004.25, 188013.75, 537004.25, 187969.25, 537004.25, 187990.75, - 537004.25, 187946.25, 537004.25, 187945.75, 537004.25, 187944.75, 537004.25, 187947.75, - 537004.25, 188126.25, 537004.25, 188043.75, 537004.25, 188071.75, 537004.25, 188103.75, - 537004.25, 187968.75, 537004.25, 188088.25, 537004.25, 188133.25, 537004.25, 188030.25, - 537004.25, 188153.25, 537004.25, 188035.75, 537004.25, 188001.25, 537004.25, 188016.25, - 537004.25, 188098.75, 537004.25, 188074.75, 537004.25, 187952.75, 537004.25, 187970.25, - 537004.25, 188042.75, 537004.25, 187991.25, 537004.25, 187941.75, 537004.25, 188101.75, - 537004.25, 188047.75, 537004.25, 187972.25, 537004.25, 188085.25, 537004.25, 187973.75, - 537004.25, 188150.75, 537004.25, 187988.25, 537004.25, 187991.75, 537004.25, 188050.25, - 537004.25, 188072.25, 537004.25, 188151.75, 537004.25, 188091.25, 537004.25, 188148.75, - 537004.25, 187986.75, 537004.25, 187951.75, 537004.25, 187953.75, 537004.25, 188032.75, - 537004.25, 187934.25, 537004.25, 187946.75, 537004.25, 188133.75, 537004.25, 187976.25, - 537004.25, 188041.75, 537004.25, 188048.75, 537004.25, 187931.75, 537004.25, 187970.75, - 537004.75, 187994.75, 537004.75, 188087.75, 537004.75, 188127.25, 537004.75, 187947.25, - 537004.75, 188132.75, 537004.75, 188157.25, 537004.75, 188102.25, 537004.75, 188001.75, - 537004.75, 187992.25, 537004.75, 188040.75, 537004.75, 188133.75, 537004.75, 188043.25, - 537004.75, 188089.75, 537004.75, 187943.75, 537004.75, 188096.25, 537004.75, 188055.25, - 537004.75, 187946.75, 537004.75, 188155.25, 537004.75, 187960.25, 537004.75, 187987.75, - 537004.75, 187934.25, 537004.75, 188090.25, 537004.75, 188007.75, 537004.75, 188128.25, - 537004.75, 188034.75, 537004.75, 188085.75, 537004.75, 188108.25, 537004.75, 187945.25, - 537004.75, 188011.75, 537004.75, 187999.25, 537004.75, 187971.75, 537004.75, 188151.75, - 537004.75, 188101.75, 537004.75, 188012.25, 537004.75, 188042.75, 537004.75, 187912.75, - 537004.75, 188006.25, 537004.75, 187976.75, 537004.75, 188159.25, 537004.75, 187971.25, - 537004.75, 188049.25, 537004.75, 188153.25, 537004.75, 188136.25, 537004.75, 188040.25, - 537004.75, 187972.25, 537004.75, 188102.75, 537004.75, 188059.25, 537004.75, 188050.25, - 537004.75, 188142.75, 537004.75, 188034.25, 537004.75, 188047.75, 537004.75, 188085.25, - 537004.75, 187992.75, 537004.75, 188033.25, 537004.75, 188105.25, 537004.75, 188039.75, - 537004.75, 187988.75, 537004.75, 188009.75, 537004.75, 188061.75, 537004.75, 188084.75, - 537004.75, 187962.75, 537004.75, 187969.25, 537004.75, 188001.25, 537004.75, 187981.75, - 537004.75, 187989.25, 537004.75, 187938.75, 537004.75, 188086.75, 537004.75, 188002.75, - 537004.75, 188005.75, 537004.75, 188133.25, 537004.75, 188043.75, 537004.75, 188008.75, - 537004.75, 188060.25, 537004.75, 188037.75, 537004.75, 188031.25, 537004.75, 188086.25, - 537004.75, 188143.75, 537004.75, 187913.25, 537004.75, 188036.25, 537004.75, 187937.25, - 537004.75, 188103.75, 537004.75, 188151.25, 537004.75, 187910.75, 537004.75, 188132.25, - 537004.75, 187932.25, 537004.75, 188160.25, 537004.75, 187944.25, 537004.75, 187920.25, - 537004.75, 187993.75, 537004.75, 188056.75, 537004.75, 188027.75, 537004.75, 188031.75, - 537004.75, 188152.75, 537004.75, 188047.25, 537004.75, 187969.75, 537004.75, 188044.25, - 537004.75, 187990.25, 537004.75, 188052.75, 537004.75, 188006.75, 537004.75, 187989.75, - 537004.75, 187995.75, 537004.75, 187973.25, 537004.75, 188135.25, 537004.75, 188107.25, - 537004.75, 187968.25, 537004.75, 187933.75, 537005.25, 187933.75, 537005.25, 187968.25, - 537005.25, 187989.75, 537005.25, 188107.25, 537005.25, 187924.75, 537005.25, 188149.75, - 537005.25, 188048.25, 537005.25, 188059.75, 537005.25, 188047.25, 537005.25, 188031.75, - 537005.25, 188135.25, 537005.25, 188003.25, 537005.25, 187912.25, 537005.25, 188132.25, - 537005.25, 187970.75, 537005.25, 187993.75, 537005.25, 188103.25, 537005.25, 188062.75, - 537005.25, 187982.25, 537005.25, 188041.25, 537005.25, 188013.75, 537005.25, 187932.25, - 537005.25, 188032.25, 537005.25, 188151.25, 537005.25, 188078.75, 537005.25, 188036.75, - 537005.25, 188103.75, 537005.25, 187977.25, 537005.25, 188052.25, 537005.25, 188117.25, - 537005.25, 187913.25, 537005.25, 188133.25, 537005.25, 187945.75, 537005.25, 188060.25, - 537005.25, 188005.75, 537005.25, 188001.75, 537005.25, 187964.25, 537005.25, 188094.25, - 537005.25, 187959.25, 537005.25, 188086.75, 537005.25, 188008.75, 537005.25, 188043.75, - 537005.25, 188002.75, 537005.25, 187989.25, 537005.25, 187935.25, 537005.25, 187969.25, - 537005.25, 188109.75, 537005.25, 188015.25, 537005.25, 188107.75, 537005.25, 188053.75, - 537005.25, 188156.25, 537005.25, 187944.75, 537005.25, 188127.75, 537005.25, 188050.25, - 537005.25, 188136.25, 537005.25, 187962.25, 537005.25, 188002.25, 537005.25, 188085.25, - 537005.25, 187945.25, 537005.25, 188033.25, 537005.25, 188038.25, 537005.25, 188034.25, - 537005.25, 187938.25, 537005.25, 188040.75, 537005.25, 188145.75, 537005.25, 187957.25, - 537005.25, 188047.75, 537005.25, 187999.25, 537005.25, 187972.25, 537005.25, 187971.25, - 537005.25, 187935.75, 537005.25, 188059.25, 537005.25, 187946.25, 537005.25, 188105.25, - 537005.25, 188025.75, 537005.25, 188039.75, 537005.25, 187939.25, 537005.25, 187976.75, - 537005.25, 188151.75, 537005.25, 187975.75, 537005.25, 188143.25, 537005.25, 188006.25, - 537005.25, 188085.75, 537005.25, 188035.75, 537005.25, 188131.75, 537005.25, 187988.25, - 537005.25, 187943.75, 537005.25, 188126.75, 537005.25, 188089.75, 537005.25, 188090.25, - 537005.25, 188099.25, 537005.25, 187942.75, 537005.25, 188011.25, 537005.25, 188087.75, - 537005.25, 188072.25, 537005.25, 187994.75, 537005.25, 188132.75, 537005.25, 188007.75, - 537005.25, 188148.75, 537005.25, 187992.25, 537005.25, 188102.25, 537005.25, 187987.25, - 537005.25, 187947.25, 537005.25, 188133.75, 537005.25, 188043.25, 537005.25, 187944.25, - 537005.75, 187969.75, 537005.75, 187943.25, 537005.75, 188089.25, 537005.75, 187992.25, - 537005.75, 188132.25, 537005.75, 188048.25, 537005.75, 188037.75, 537005.75, 188034.75, - 537005.75, 187935.75, 537005.75, 187976.25, 537005.75, 188046.75, 537005.75, 188024.25, - 537005.75, 188090.75, 537005.75, 188005.25, 537005.75, 188131.25, 537005.75, 188107.25, - 537005.75, 188157.75, 537005.75, 188127.25, 537005.75, 188012.25, 537005.75, 188040.25, - 537005.75, 188040.75, 537005.75, 187971.75, 537005.75, 187944.75, 537005.75, 188104.25, - 537005.75, 188061.75, 537005.75, 188134.75, 537005.75, 188031.25, 537005.75, 188034.25, - 537005.75, 187932.25, 537005.75, 187992.75, 537005.75, 188036.25, 537005.75, 188135.25, - 537005.75, 187911.25, 537005.75, 188058.25, 537005.75, 187935.25, 537005.75, 188106.25, - 537005.75, 188007.25, 537005.75, 187993.25, 537005.75, 188127.75, 537005.75, 187932.75, - 537005.75, 187939.25, 537005.75, 188108.75, 537005.75, 187970.25, 537005.75, 188152.25, - 537005.75, 188032.75, 537005.75, 187942.75, 537005.75, 187968.75, 537005.75, 187987.75, - 537005.75, 188153.25, 537005.75, 187988.75, 537005.75, 188003.25, 537005.75, 188103.25, - 537005.75, 188147.75, 537005.75, 188044.25, 537005.75, 187993.75, 537005.75, 188151.25, - 537006.25, 188151.25, 537006.25, 188130.75, 537006.25, 187934.75, 537006.25, 187946.75, - 537006.25, 188085.75, 537006.25, 187936.75, 537006.25, 188030.75, 537006.25, 188152.75, - 537006.25, 187991.75, 537006.25, 187965.25, 537006.25, 188043.25, 537006.25, 188059.75, - 537006.25, 188103.75, 537006.25, 188134.25, 537006.25, 188013.75, 537006.25, 187933.75, - 537006.25, 188091.25, 537006.25, 188035.25, 537006.25, 188134.75, 537006.25, 187989.75, - 537006.25, 188096.75, 537006.25, 188127.25, 537006.25, 187982.25, 537006.25, 187992.75, - 537006.25, 188004.75, 537006.25, 188029.75, 537006.25, 188038.75, 537006.25, 188003.75, - 537006.25, 188012.75, 537006.25, 188070.25, 537006.25, 187958.25, 537006.25, 187939.75, - 537006.25, 188045.75, 537006.25, 187940.75, 537006.25, 188135.25, 537006.25, 188039.75, - 537006.25, 187942.25, 537006.25, 187936.25, 537006.25, 188036.25, 537006.25, 188001.25, - 537006.25, 188006.75, 537006.25, 187978.25, 537006.25, 188149.75, 537006.25, 188056.25, - 537006.25, 188153.25, 537006.25, 188102.75, 537006.25, 188037.75, 537006.25, 188008.25, - 537006.25, 188043.75, 537006.25, 187941.25, 537006.25, 187988.25, 537006.25, 187983.25, - 537006.25, 188034.25, 537006.25, 188031.75, 537006.25, 188129.25, 537006.25, 188131.25, - 537006.25, 187943.75, 537006.25, 188154.75, 537006.25, 188153.75, 537006.25, 188002.75, - 537006.25, 188128.25, 537006.25, 187984.75, 537006.25, 187945.25, 537006.25, 188060.75, - 537006.25, 188127.75, 537006.25, 187991.25, 537006.25, 188044.75, 537006.25, 187942.75, - 537006.25, 187957.75, 537006.25, 187950.25, 537006.25, 188054.75, 537006.25, 188129.75, - 537006.25, 187985.25, 537006.25, 188046.75, 537006.25, 188061.25, 537006.25, 187970.25, - 537006.25, 187969.25, 537006.25, 188034.75, 537006.25, 188106.25, 537006.25, 187998.25, - 537006.75, 188087.75, 537006.75, 187912.75, 537006.75, 187946.25, 537006.75, 187985.75, - 537006.75, 188009.25, 537006.75, 187970.25, 537006.75, 188148.25, 537006.75, 188129.75, - 537006.75, 188148.75, 537006.75, 187985.25, 537006.75, 188043.75, 537006.75, 187991.25, - 537006.75, 188155.75, 537006.75, 188044.75, 537006.75, 188007.25, 537006.75, 188058.25, - 537006.75, 188128.25, 537006.75, 188127.75, 537006.75, 188099.75, 537006.75, 188045.25, - 537006.75, 188060.75, 537006.75, 187925.75, 537006.75, 187984.25, 537006.75, 188034.75, - 537006.75, 188007.75, 537006.75, 188002.75, 537006.75, 187937.25, 537006.75, 187934.25, - 537006.75, 187987.75, 537006.75, 187975.75, 537006.75, 187977.75, 537006.75, 188129.25, - 537006.75, 187959.75, 537006.75, 188090.25, 537006.75, 188153.25, 537006.75, 188100.75, - 537006.75, 187969.25, 537006.75, 188036.25, 537006.75, 188038.25, 537006.75, 187941.25, - 537006.75, 188027.25, 537006.75, 188058.75, 537006.75, 188003.25, 537006.75, 187956.75, - 537006.75, 188060.25, 537006.75, 188013.25, 537006.75, 187943.75, 537006.75, 187956.25, - 537006.75, 188035.75, 537006.75, 187936.25, 537006.75, 188029.75, 537006.75, 188103.25, - 537006.75, 188047.25, 537006.75, 188026.75, 537006.75, 188133.25, 537006.75, 187992.25, - 537006.75, 187968.25, 537006.75, 187982.25, 537006.75, 188151.25, 537006.75, 188091.25, - 537006.75, 187962.75, 537006.75, 188096.75, 537006.75, 188047.75, 537006.75, 188089.75, - 537006.75, 188106.75, 537006.75, 188134.75, 537006.75, 187991.75, 537006.75, 187941.75, - 537006.75, 187944.75, 537006.75, 187933.75, 537006.75, 187990.25, 537006.75, 188035.25, - 537006.75, 188044.25, 537006.75, 188130.25, 537006.75, 187996.75, 537006.75, 188152.75, - 537006.75, 187946.75, 537006.75, 188105.25, 537006.75, 188033.75, 537006.75, 188103.75, - 537006.75, 187942.25, 537006.75, 188062.25, 537006.75, 188130.75, 537006.75, 188039.75, - 537007.25, 188002.25, 537007.25, 188133.75, 537007.25, 187968.25, 537007.25, 187910.75, - 537007.25, 188076.75, 537007.25, 187978.75, 537007.25, 188128.75, 537007.25, 188152.25, - 537007.25, 188036.75, 537007.25, 187932.25, 537007.25, 188052.25, 537007.25, 188091.75, - 537007.25, 188135.25, 537007.25, 187939.75, 537007.25, 188103.75, 537007.25, 188100.75, - 537007.25, 187983.25, 537007.25, 188149.25, 537007.25, 187969.25, 537007.25, 188023.25, - 537007.25, 188052.75, 537007.25, 188131.25, 537007.25, 187967.25, 537007.25, 187984.25, - 537007.25, 188127.75, 537007.25, 187977.25, 537007.25, 188045.25, 537007.25, 187947.25, - 537007.25, 187945.25, 537007.25, 188061.25, 537007.25, 188128.25, 537007.25, 188037.25, - 537007.25, 187934.25, 537007.25, 187991.25, 537007.25, 188090.75, 537007.25, 188046.75, - 537007.25, 187985.75, 537007.25, 187970.25, 537007.25, 188032.75, 537007.25, 188044.75, - 537007.25, 187942.75, 537007.25, 188153.75, 537007.25, 188132.75, 537007.25, 187968.75, - 537007.25, 187988.25, 537007.25, 188033.25, 537007.25, 188102.75, 537007.25, 187923.75, - 537007.25, 187965.75, 537007.25, 188001.25, 537007.25, 187940.75, 537007.25, 187998.75, - 537007.25, 188129.25, 537007.25, 188035.75, 537007.25, 188103.25, 537007.25, 187989.75, - 537007.25, 187994.25, 537007.25, 188105.75, 537007.25, 188151.25, 537007.25, 188004.75, - 537007.25, 188132.25, 537007.25, 188076.25, 537007.25, 187943.25, 537007.25, 187930.75, - 537007.25, 188160.25, 537007.25, 187933.75, 537007.25, 188059.75, 537007.25, 188131.75, - 537007.25, 188004.25, 537007.25, 187969.75, 537007.25, 188108.25, 537007.75, 188148.75, - 537007.75, 187943.25, 537007.75, 188004.75, 537007.75, 188037.75, 537007.75, 187935.75, - 537007.75, 188037.25, 537007.75, 187967.75, 537007.75, 187997.75, 537007.75, 188006.25, - 537007.75, 188106.75, 537007.75, 188150.25, 537007.75, 188006.75, 537007.75, 187995.75, - 537007.75, 187937.25, 537007.75, 188112.75, 537007.75, 188008.25, 537007.75, 188060.25, - 537007.75, 187966.25, 537007.75, 188035.75, 537007.75, 188003.75, 537007.75, 188068.75, - 537007.75, 187952.25, 537007.75, 187934.75, 537007.75, 187937.75, 537007.75, 187968.75, - 537007.75, 188009.25, 537007.75, 187993.25, 537007.75, 187992.75, 537007.75, 188010.25, - 537007.75, 188059.25, 537007.75, 188151.75, 537007.75, 188104.75, 537007.75, 188076.25, - 537007.75, 188076.75, 537007.75, 188109.25, 537007.75, 188104.25, 537007.75, 187955.25, - 537007.75, 187991.25, 537007.75, 188038.75, 537007.75, 187945.75, 537007.75, 188033.75, - 537007.75, 187990.75, 537007.75, 188027.25, 537007.75, 187990.25, 537007.75, 187989.75, - 537007.75, 188078.75, 537007.75, 187913.25, 537007.75, 188103.25, 537007.75, 187938.75, - 537007.75, 187989.25, 537007.75, 188153.25, 537007.75, 188055.75, 537007.75, 188044.75, - 537007.75, 188136.75, 537007.75, 187986.25, 537007.75, 188108.75, 537007.75, 187939.25, - 537007.75, 187946.25, 537007.75, 187932.75, 537007.75, 188082.25, 537007.75, 188158.75, - 537007.75, 187984.25, 537007.75, 188147.75, 537007.75, 188083.25, 537007.75, 188154.75, - 537007.75, 188032.25, 537007.75, 187970.75, 537007.75, 188031.75, 537007.75, 188108.25, - 537007.75, 188117.75, 537007.75, 188045.75, 537007.75, 187939.75, 537007.75, 187961.75, - 537007.75, 187932.25, 537007.75, 188001.75, 537007.75, 188091.75, 537007.75, 187981.25, - 537007.75, 187971.25, 537007.75, 188084.75, 537007.75, 187941.75, 537007.75, 187931.75, - 537007.75, 187927.75, 537007.75, 188133.25, 537007.75, 188025.75, 537007.75, 188097.75, - 537007.75, 187941.25, 537007.75, 188027.75, 537007.75, 188120.75, 537007.75, 188026.75, - 537007.75, 187930.75, 537007.75, 188131.75, 537007.75, 187954.75, 537008.25, 187984.25, - 537008.25, 187941.75, 537008.25, 188032.75, 537008.25, 188027.25, 537008.25, 188073.75, - 537008.25, 188010.25, 537008.25, 188059.25, 537008.25, 188116.25, 537008.25, 187939.75, - 537008.25, 187931.25, 537008.25, 188151.75, 537008.25, 188044.25, 537008.25, 188076.25, - 537008.25, 188073.25, 537008.25, 188135.25, 537008.25, 188045.25, 537008.25, 188011.25, - 537008.25, 188108.75, 537008.25, 188060.25, 537008.25, 188131.75, 537008.25, 187934.25, - 537008.25, 187970.75, 537008.25, 187930.75, 537008.25, 187932.25, 537008.25, 188132.75, - 537008.25, 188008.25, 537008.25, 188133.75, 537008.25, 188147.25, 537008.25, 187945.75, - 537008.25, 188060.75, 537008.25, 188045.75, 537008.25, 188038.75, 537008.25, 188091.75, - 537008.25, 188034.25, 537008.25, 187969.25, 537008.25, 188150.75, 537008.25, 188076.75, - 537008.25, 187991.75, 537008.25, 188001.25, 537008.25, 188112.25, 537008.25, 188083.25, - 537008.25, 187938.25, 537008.25, 188096.75, 537008.25, 188106.25, 537008.25, 188034.75, - 537008.25, 188107.75, 537008.25, 187995.75, 537008.25, 188031.25, 537008.25, 188077.75, - 537008.25, 188025.75, 537008.25, 187990.75, 537008.25, 187944.25, 537008.25, 188152.75, - 537008.25, 188103.75, 537008.25, 188134.75, 537008.25, 187953.25, 537008.25, 188134.25, - 537008.25, 188006.25, 537008.25, 187933.75, 537008.25, 187987.75, 537008.25, 187966.25, - 537008.25, 188051.25, 537008.25, 187980.75, 537008.25, 187941.25, 537008.25, 188091.25, - 537008.25, 187997.75, 537008.25, 187977.75, 537008.25, 187989.75, 537008.25, 187985.25, - 537008.25, 188037.75, 537008.25, 188003.75, 537008.25, 187977.25, 537008.25, 188103.25, - 537008.25, 187985.75, 537008.25, 187939.25, 537008.25, 188109.75, 537008.25, 188049.75, - 537008.25, 187968.25, 537008.25, 187979.75, 537008.25, 188090.75, 537008.25, 188028.25, - 537008.25, 187938.75, 537008.25, 187989.25, 537008.25, 188026.75, 537008.25, 188037.25, - 537008.25, 188004.75, 537008.25, 188148.75, 537008.25, 187988.75, 537008.25, 188153.25, - 537008.25, 187967.75, 537008.75, 187979.25, 537008.75, 188117.25, 537008.75, 188159.25, - 537008.75, 188081.75, 537008.75, 187962.75, 537008.75, 188033.25, 537008.75, 188128.75, - 537008.75, 188038.25, 537008.75, 187938.25, 537008.75, 188104.25, 537008.75, 188037.25, - 537008.75, 188058.25, 537008.75, 187993.25, 537008.75, 188004.75, 537008.75, 188004.25, - 537008.75, 188064.75, 537008.75, 188080.25, 537008.75, 188048.25, 537008.75, 187967.25, - 537008.75, 187937.75, 537008.75, 188026.25, 537008.75, 187999.75, 537008.75, 187994.75, - 537008.75, 187953.75, 537008.75, 188034.75, 537008.75, 187935.75, 537008.75, 188153.75, - 537008.75, 188031.75, 537008.75, 187945.25, 537008.75, 187938.75, 537008.75, 187940.25, - 537008.75, 188114.25, 537008.75, 187983.25, 537008.75, 188104.75, 537008.75, 188092.25, - 537008.75, 187934.25, 537008.75, 188136.25, 537008.75, 187937.25, 537008.75, 188036.25, - 537008.75, 188103.25, 537008.75, 187966.75, 537008.75, 188031.25, 537008.75, 188008.75, - 537008.75, 188073.75, 537008.75, 188060.25, 537008.75, 188145.25, 537008.75, 187977.25, - 537008.75, 188084.25, 537008.75, 188067.25, 537008.75, 187977.75, 537008.75, 187961.25, - 537008.75, 187965.25, 537008.75, 187992.25, 537008.75, 188137.25, 537008.75, 187970.25, - 537008.75, 187988.25, 537008.75, 188149.25, 537008.75, 188108.75, 537008.75, 187980.75, - 537008.75, 188083.75, 537008.75, 188110.75, 537008.75, 188059.75, 537008.75, 187960.75, - 537008.75, 187942.75, 537008.75, 188135.75, 537008.75, 188009.25, 537008.75, 188106.75, - 537008.75, 188113.75, 537008.75, 188027.75, 537008.75, 187971.75, 537008.75, 187987.75, - 537008.75, 187943.25, 537008.75, 187933.75, 537008.75, 188130.25, 537008.75, 187984.75, - 537009.25, 187966.25, 537009.25, 187931.25, 537009.25, 188046.25, 537009.25, 188062.25, - 537009.25, 188105.75, 537009.25, 188054.75, 537009.25, 188039.25, 537009.25, 188113.75, - 537009.25, 187971.75, 537009.25, 188109.25, 537009.25, 188117.25, 537009.25, 188035.75, - 537009.25, 187942.75, 537009.25, 187975.25, 537009.25, 188056.75, 537009.25, 187951.75, - 537009.25, 188116.25, 537009.25, 188106.75, 537009.25, 187965.75, 537009.25, 187947.75, - 537009.25, 187942.25, 537009.25, 188134.75, 537009.25, 188098.25, 537009.25, 188057.25, - 537009.25, 188154.25, 537009.25, 188129.25, 537009.25, 188103.75, 537009.25, 188058.75, - 537009.25, 187952.25, 537009.25, 188035.25, 537009.25, 188020.75, 537009.25, 188113.25, - 537009.25, 188076.25, 537009.25, 188068.25, 537009.25, 188114.75, 537009.25, 188151.25, - 537009.25, 187960.25, 537009.25, 187961.75, 537009.25, 187993.75, 537009.25, 187988.25, - 537009.25, 187930.25, 537009.25, 187961.25, 537009.25, 188135.25, 537009.25, 188084.75, - 537009.25, 188057.75, 537009.25, 187992.75, 537009.25, 187977.25, 537009.25, 188150.25, - 537009.25, 188006.75, 537009.25, 187965.25, 537009.25, 188133.25, 537009.25, 187943.75, - 537009.25, 188024.25, 537009.25, 188091.25, 537009.25, 188111.75, 537009.25, 187913.25, - 537009.25, 188032.25, 537009.25, 187941.75, 537009.25, 187959.25, 537009.25, 188036.25, - 537009.25, 188005.25, 537009.25, 187959.75, 537009.25, 187944.75, 537009.25, 188033.75, - 537009.25, 187936.25, 537009.25, 188092.75, 537009.25, 187981.75, 537009.25, 187935.25, - 537009.25, 187964.75, 537009.25, 188028.25, 537009.25, 187983.25, 537009.25, 188107.75, - 537009.25, 187971.25, 537009.25, 188128.25, 537009.25, 188023.75, 537009.25, 188055.75, - 537009.25, 188032.75, 537009.25, 188064.25, 537009.25, 187937.75, 537009.25, 188007.25, - 537009.25, 188031.75, 537009.25, 188112.75, 537009.25, 187998.75, 537009.25, 188136.75, - 537009.25, 187976.75, 537009.25, 188080.25, 537009.25, 188044.75, 537009.25, 187950.25, - 537009.25, 188132.25, 537009.25, 188049.75, 537009.25, 187979.25, 537009.25, 188152.25, - 537009.25, 187963.25, 537009.25, 187987.25, 537009.25, 188046.75, 537009.25, 187983.75, - 537009.25, 188091.75, 537009.25, 188076.75, 537009.25, 188118.75, 537009.25, 188028.75, - 537009.25, 187982.25, 537009.75, 188034.75, 537009.75, 188091.75, 537009.75, 187962.75, - 537009.75, 188152.25, 537009.75, 187914.75, 537009.75, 187938.25, 537009.75, 187987.25, - 537009.75, 187983.75, 537009.75, 188021.25, 537009.75, 188007.75, 537009.75, 188133.25, - 537009.75, 188098.25, 537009.75, 187910.75, 537009.75, 187976.75, 537009.75, 188093.25, - 537009.75, 188045.75, 537009.75, 187944.25, 537009.75, 188031.75, 537009.75, 188061.25, - 537009.75, 188133.75, 537009.75, 188007.25, 537009.75, 187971.25, 537009.75, 188108.25, - 537009.75, 188128.25, 537009.75, 188032.25, 537009.75, 188104.75, 537009.75, 187935.25, - 537009.75, 188131.75, 537009.75, 187981.75, 537009.75, 187968.75, 537009.75, 188107.75, - 537009.75, 188033.75, 537009.75, 187937.25, 537009.75, 187963.25, 537009.75, 188039.25, - 537009.75, 188031.25, 537009.75, 187981.25, 537009.75, 188151.25, 537009.75, 187929.75, - 537009.75, 188153.75, 537009.75, 187941.75, 537009.75, 188150.25, 537009.75, 188135.25, - 537009.75, 188006.75, 537009.75, 188057.75, 537009.75, 188024.25, 537009.75, 187961.25, - 537009.75, 187960.25, 537009.75, 187978.75, 537009.75, 188114.75, 537009.75, 188068.25, - 537009.75, 187961.75, 537009.75, 188078.25, 537009.75, 187996.25, 537009.75, 188113.25, - 537009.75, 187922.25, 537009.75, 188035.25, 537009.75, 188058.75, 537009.75, 187973.25, - 537009.75, 188118.75, 537009.75, 188103.75, 537009.75, 188142.25, 537009.75, 188160.25, - 537009.75, 187990.25, 537009.75, 188035.75, 537009.75, 188048.75, 537009.75, 188134.75, - 537009.75, 187966.25, 537009.75, 187941.25, 537009.75, 187931.25, 537009.75, 188005.75, - 537009.75, 187977.25, 537009.75, 188105.75, 537009.75, 188075.75, 537009.75, 187942.75, - 537009.75, 187992.75, 537009.75, 188056.75, 537009.75, 188042.75, 537009.75, 188149.75, - 537009.75, 188115.25, 537009.75, 187939.25, 537009.75, 188020.75, 537009.75, 187950.75, - 537009.75, 187959.25, 537009.75, 188036.25, 537009.75, 187959.75, 537009.75, 187942.25, - 537009.75, 188084.25, 537009.75, 187968.25, 537009.75, 188134.25, 537009.75, 188148.25, - 537009.75, 188090.75, 537009.75, 187964.75, 537009.75, 187983.25, 537009.75, 187998.75, - 537009.75, 188115.75, 537009.75, 188004.75, 537009.75, 187979.25, 537009.75, 188046.75, - 537009.75, 187936.75, 537009.75, 188057.25, 537010.25, 187957.75, 537010.25, 188154.25, - 537010.25, 188033.25, 537010.25, 188089.75, 537010.25, 188081.25, 537010.25, 187936.25, - 537010.25, 188025.25, 537010.25, 188066.75, 537010.25, 187950.25, 537010.25, 187930.75, - 537010.25, 188068.25, 537010.25, 188153.75, 537010.25, 187942.25, 537010.25, 188151.75, - 537010.25, 187937.75, 537010.25, 187912.25, 537010.25, 187959.75, 537010.25, 188148.25, - 537010.25, 188054.25, 537010.25, 188055.75, 537010.25, 187979.25, 537010.25, 188069.25, - 537010.25, 188022.75, 537010.25, 188010.25, 537010.25, 188056.25, 537010.25, 188004.75, - 537010.25, 187988.75, 537010.25, 188105.25, 537010.25, 188148.75, 537010.25, 187993.75, - 537010.25, 188115.75, 537010.25, 187992.75, 537010.25, 187963.75, 537010.25, 188023.75, - 537010.25, 187935.75, 537010.25, 187968.25, 537010.25, 187965.75, 537010.25, 188131.25, - 537010.25, 187931.25, 537010.25, 188029.75, 537010.25, 187985.25, 537010.25, 187980.75, - 537010.25, 188115.25, 537010.25, 188110.75, 537010.25, 188030.25, 537010.25, 188010.75, - 537010.25, 187934.75, 537010.25, 188053.75, 537010.25, 187971.75, 537010.25, 188117.25, - 537010.25, 188106.75, 537010.25, 188057.25, 537010.25, 188111.25, 537010.25, 187962.25, - 537010.25, 188113.25, 537010.25, 187984.25, 537010.25, 187965.25, 537010.25, 188150.25, - 537010.25, 187958.75, 537010.25, 188032.75, 537010.25, 188100.25, 537010.25, 188021.25, - 537010.25, 187982.25, 537010.25, 188076.75, 537010.25, 187969.25, 537010.25, 188043.75, - 537010.25, 188019.75, 537010.25, 188007.75, 537010.25, 188132.75, 537010.25, 188104.75, - 537010.25, 188092.25, 537010.25, 187934.25, 537010.75, 187957.75, 537010.75, 188110.75, - 537010.75, 188052.25, 537010.75, 187957.25, 537010.75, 187933.25, 537010.75, 188075.25, - 537010.75, 188037.75, 537010.75, 188011.25, 537010.75, 187970.75, 537010.75, 187931.75, - 537010.75, 187972.75, 537010.75, 187999.75, 537010.75, 188092.75, 537010.75, 188104.75, - 537010.75, 187975.25, 537010.75, 188093.25, 537010.75, 188015.75, 537010.75, 187932.75, - 537010.75, 187994.75, 537010.75, 188008.25, 537010.75, 188028.75, 537010.75, 188010.25, - 537010.75, 187958.25, 537010.75, 188056.25, 537010.75, 188117.75, 537010.75, 188105.25, - 537010.75, 187974.25, 537010.75, 188023.25, 537010.75, 188024.75, 537010.75, 187988.25, - 537010.75, 188046.75, 537010.75, 187972.25, 537010.75, 187989.25, 537010.75, 187937.75, - 537010.75, 187992.25, 537010.75, 187963.75, 537010.75, 187969.75, 537010.75, 188114.25, - 537010.75, 187982.25, 537010.75, 188105.75, 537010.75, 188116.75, 537010.75, 187935.75, - 537010.75, 188110.25, 537010.75, 188152.25, 537010.75, 188112.25, 537010.75, 188074.75, - 537010.75, 188022.25, 537010.75, 187911.75, 537010.75, 188136.25, 537010.75, 188009.25, - 537010.75, 188093.75, 537010.75, 188149.25, 537010.75, 188027.75, 537010.75, 187955.25, - 537010.75, 188083.25, 537010.75, 188106.25, 537010.75, 187973.25, 537010.75, 188029.75, - 537010.75, 188154.75, 537010.75, 187978.25, 537010.75, 188107.25, 537010.75, 188042.75, - 537010.75, 187934.75, 537010.75, 188025.75, 537010.75, 187968.75, 537010.75, 188153.75, - 537010.75, 187978.75, 537010.75, 188108.75, 537010.75, 187993.25, 537010.75, 188053.25, - 537010.75, 187973.75, 537010.75, 187946.25, 537010.75, 188111.75, 537010.75, 187976.25, - 537010.75, 187941.75, 537010.75, 188055.25, 537010.75, 187994.25, 537010.75, 187967.25, - 537010.75, 188084.75, 537010.75, 188053.75, 537010.75, 187966.75, 537010.75, 188150.25, - 537010.75, 188073.25, 537010.75, 188089.25, 537010.75, 188080.75, 537010.75, 188116.25, - 537010.75, 188030.75, 537010.75, 188005.75, 537010.75, 188106.75, 537010.75, 187933.75, - 537010.75, 187914.25, 537010.75, 188130.25, 537010.75, 188031.25, 537010.75, 188020.75, - 537010.75, 187964.25, 537010.75, 188006.25, 537010.75, 188152.75, 537010.75, 187962.25, - 537010.75, 187966.25, 537010.75, 188076.25, 537010.75, 188155.75, 537010.75, 188129.25, - 537010.75, 188099.25, 537010.75, 187916.75, 537010.75, 188109.75, 537011.25, 188067.75, - 537011.25, 188038.25, 537011.25, 187930.75, 537011.25, 188081.75, 537011.25, 187976.25, - 537011.25, 188111.25, 537011.25, 188019.75, 537011.25, 188057.25, 537011.25, 188053.25, - 537011.25, 188117.25, 537011.25, 188076.25, 537011.25, 187994.25, 537011.25, 188152.75, - 537011.25, 188035.25, 537011.25, 187962.25, 537011.25, 187981.25, 537011.25, 188006.25, - 537011.25, 188116.25, 537011.25, 187933.75, 537011.25, 187977.25, 537011.25, 188106.75, - 537011.25, 188114.75, 537011.25, 188030.75, 537011.25, 188156.25, 537011.25, 188005.75, - 537011.25, 188053.75, 537011.25, 188066.25, 537011.25, 187966.75, 537011.25, 187970.25, - 537011.25, 187956.25, 537011.25, 188084.75, 537011.25, 187973.75, 537011.25, 187956.75, - 537011.25, 188039.25, 537011.25, 187981.75, 537011.25, 188153.75, 537011.25, 188052.75, - 537011.25, 187935.25, 537011.25, 187995.75, 537011.25, 188099.25, 537011.25, 188107.25, - 537011.25, 188025.75, 537011.25, 188154.75, 537011.25, 188110.75, 537011.25, 187982.75, - 537011.25, 187949.25, 537011.25, 187967.25, 537011.25, 188054.75, 537011.25, 188029.75, - 537011.25, 188106.25, 537011.25, 187978.75, 537011.25, 188149.25, 537011.25, 188103.25, - 537011.25, 188109.25, 537011.25, 188146.75, 537011.25, 187957.75, 537011.25, 188023.25, - 537011.25, 188024.75, 537011.25, 188083.75, 537011.25, 187963.75, 537011.25, 187975.75, - 537011.25, 187911.75, 537011.25, 187947.75, 537011.25, 188116.75, 537011.25, 188075.75, - 537011.25, 188074.75, 537011.25, 188076.75, 537011.25, 187992.25, 537011.25, 187989.25, - 537011.25, 188105.75, 537011.25, 188134.25, 537011.25, 188041.75, 537011.25, 188127.25, - 537011.25, 187988.25, 537011.25, 188089.75, 537011.25, 188079.75, 537011.25, 188114.25, - 537011.25, 188130.25, 537011.25, 188153.25, 537011.25, 187936.25, 537011.25, 187958.25, - 537011.25, 188045.75, 537011.25, 188092.75, 537011.25, 188133.25, 537011.25, 188148.75, - 537011.25, 187999.25, 537011.25, 187993.75, 537011.25, 187983.75, 537011.25, 188152.25, - 537011.25, 188031.75, 537011.25, 188008.25, 537011.25, 188028.75, 537011.25, 188011.75, - 537011.25, 188015.75, 537011.25, 187932.25, 537011.25, 188019.25, 537011.25, 188010.25, - 537011.25, 188131.75, 537011.25, 188104.75, 537011.25, 187969.75, 537011.25, 188093.25, - 537011.25, 187972.75, 537011.25, 188052.25, 537011.25, 187979.25, 537011.25, 188129.25, - 537011.25, 188055.75, 537011.25, 187937.75, 537011.25, 187957.25, 537011.25, 188154.25, - 537011.25, 188090.25, 537011.25, 188075.25, 537011.25, 188109.75, 537011.25, 187976.75, - 537011.25, 187964.25, 537011.75, 187933.25, 537011.75, 188050.75, 537011.75, 188028.25, - 537011.75, 188084.25, 537011.75, 187975.25, 537011.75, 187954.75, 537011.75, 187911.75, - 537011.75, 187988.75, 537011.75, 187955.75, 537011.75, 187932.75, 537011.75, 187972.25, - 537011.75, 188110.25, 537011.75, 187965.75, 537011.75, 187974.75, 537011.75, 187998.25, - 537011.75, 188107.75, 537011.75, 187938.75, 537011.75, 188040.75, 537011.75, 188155.25, - 537011.75, 188118.75, 537011.75, 188029.25, 537011.75, 187963.75, 537011.75, 188022.25, - 537011.75, 187973.25, 537011.75, 188036.25, 537011.75, 188151.25, 537011.75, 187916.25, - 537011.75, 188010.75, 537011.75, 187993.25, 537011.75, 188051.25, 537011.75, 188109.25, - 537011.75, 188056.75, 537011.75, 188055.25, 537011.75, 187956.25, 537011.75, 188139.25, - 537011.75, 188115.25, 537011.75, 188145.75, 537011.75, 188031.25, 537011.75, 188155.75, - 537011.75, 187970.25, 537011.75, 188035.75, 537011.75, 188116.25, 537011.75, 188111.25, - 537011.75, 187971.75, 537011.75, 188094.25, 537011.75, 188082.75, 537011.75, 188118.25, - 537011.75, 187965.25, 537011.75, 188009.25, 537011.75, 188150.25, 537011.75, 188057.75, - 537011.75, 187956.75, 537011.75, 187963.25, 537011.75, 188152.75, 537011.75, 188053.25, - 537011.75, 187968.75, 537011.75, 188083.25, 537011.75, 188058.25, 537011.75, 188106.25, - 537011.75, 188093.75, 537011.75, 188071.75, 537011.75, 187938.25, 537011.75, 188027.25, - 537011.75, 188112.25, 537011.75, 188081.75, 537011.75, 188132.75, 537011.75, 188021.25, - 537011.75, 187982.25, 537011.75, 187969.25, 537011.75, 187992.25, 537011.75, 188007.75, - 537011.75, 187932.25, 537011.75, 188154.25, 537011.75, 187934.25, 537011.75, 188021.75, - 537012.25, 187974.25, 537012.25, 188033.75, 537012.25, 187954.75, 537012.25, 188039.75, - 537012.25, 188108.75, 537012.25, 188050.25, 537012.25, 187910.75, 537012.25, 188108.25, - 537012.25, 187947.75, 537012.25, 188156.75, 537012.25, 188027.25, 537012.25, 188146.25, - 537012.25, 188145.75, 537012.25, 187955.25, 537012.25, 188118.75, 537012.25, 188027.75, - 537012.25, 187973.25, 537012.25, 187917.25, 537012.25, 187927.75, 537012.25, 188016.75, - 537012.25, 187974.75, 537012.25, 188107.75, 537012.25, 187943.25, 537012.25, 188028.25, - 537012.25, 187954.25, 537012.25, 188071.75, 537012.25, 188147.75, 537012.25, 188145.25, - 537012.25, 188000.25, 537012.25, 187912.75, 537012.25, 188050.75, 537012.25, 188028.75, - 537012.25, 187936.75, 537012.25, 187967.75, 537012.25, 188022.75, 537012.25, 188155.25, - 537012.25, 188153.25, 537012.25, 187953.75, 537012.25, 188026.75, 537012.25, 188110.75, - 537012.25, 187980.25, 537012.25, 188051.25, 537012.25, 188149.75, 537012.25, 187956.25, - 537012.25, 187964.75, 537012.25, 187947.25, 537012.25, 187966.25, 537012.25, 188155.75, - 537012.25, 188070.75, 537012.25, 187963.75, 537012.25, 188150.25, 537012.25, 188094.25, - 537012.25, 188024.25, 537012.25, 188135.25, 537012.25, 187989.75, 537012.25, 188026.25, - 537012.25, 188006.75, 537012.25, 188056.75, 537012.25, 188111.75, 537012.25, 188115.25, - 537012.25, 188130.75, 537012.25, 188100.25, 537012.25, 187981.75, 537012.25, 188156.25, - 537012.25, 187937.25, 537012.25, 188007.25, 537012.25, 188057.25, 537012.25, 188093.75, - 537012.25, 188160.25, 537012.25, 187971.75, 537012.25, 187932.25, 537012.25, 188158.25, - 537012.25, 187990.75, 537012.25, 188082.75, 537012.25, 187994.75, 537012.25, 188132.75, - 537012.25, 188052.25, 537012.25, 187965.25, 537012.25, 187969.75, 537012.25, 188113.25, - 537012.25, 188140.25, 537012.25, 187932.75, 537012.25, 188073.25, 537012.25, 188119.75, - 537012.25, 188077.25, 537012.25, 187934.75, 537012.25, 188073.75, 537012.25, 187937.75, - 537012.25, 188020.75, 537012.25, 187971.25, 537012.25, 188159.25, 537012.25, 187938.25, - 537012.25, 188117.75, 537012.25, 187991.75, 537012.25, 188151.75, 537012.25, 188075.25, - 537012.25, 187992.75, 537012.25, 188092.75, 537012.25, 188052.75, 537012.25, 188032.25, - 537012.25, 187916.25, 537012.25, 187970.75, 537012.75, 188050.25, 537012.75, 187976.25, - 537012.75, 187970.75, 537012.75, 188119.25, 537012.75, 188156.75, 537012.75, 188092.75, - 537012.75, 188020.25, 537012.75, 187978.75, 537012.75, 188108.75, 537012.75, 188116.75, - 537012.75, 188133.75, 537012.75, 187992.75, 537012.75, 188031.75, 537012.75, 188027.25, - 537012.75, 187937.25, 537012.75, 188108.25, 537012.75, 187938.25, 537012.75, 187983.25, - 537012.75, 187991.75, 537012.75, 187964.25, 537012.75, 187955.25, 537012.75, 188009.25, - 537012.75, 188027.75, 537012.75, 188084.25, 537012.75, 188077.25, 537012.75, 187937.75, - 537012.75, 188023.25, 537012.75, 188073.75, 537012.75, 188145.75, 537012.75, 187965.75, - 537012.75, 187928.25, 537012.75, 188105.75, 537012.75, 188028.25, 537012.75, 187934.75, - 537012.75, 187985.75, 537012.75, 188147.75, 537012.75, 188033.75, 537012.75, 188120.25, - 537012.75, 187954.25, 537012.75, 187994.25, 537012.75, 187991.25, 537012.75, 187933.25, - 537012.75, 188113.25, 537012.75, 188028.75, 537012.75, 188000.25, 537012.75, 188037.75, - 537012.75, 187936.75, 537012.75, 187911.75, 537012.75, 187915.25, 537012.75, 188016.25, - 537012.75, 188072.25, 537012.75, 187971.75, 537012.75, 187932.25, 537012.75, 187926.75, - 537012.75, 187945.75, 537012.75, 188049.25, 537012.75, 188052.25, 537012.75, 188128.75, - 537012.75, 187990.25, 537012.75, 188150.75, 537012.75, 188093.75, 537012.75, 188155.25, - 537012.75, 188022.75, 537012.75, 188110.25, 537012.75, 188023.75, 537012.75, 188071.75, - 537012.75, 188057.25, 537012.75, 188007.25, 537012.75, 188035.25, 537012.75, 188156.25, - 537012.75, 187968.25, 537012.75, 187979.75, 537012.75, 187968.75, 537012.75, 187953.75, - 537012.75, 188110.75, 537012.75, 188022.25, 537012.75, 188026.75, 537012.75, 188144.25, - 537012.75, 188111.75, 537012.75, 188056.75, 537012.75, 188107.25, 537012.75, 188051.25, - 537012.75, 187956.25, 537012.75, 187989.25, 537012.75, 188118.25, 537012.75, 188106.75, - 537012.75, 188094.25, 537012.75, 187981.25, 537012.75, 188094.75, 537012.75, 188024.25, - 537012.75, 188006.25, 537012.75, 188111.25, 537012.75, 188155.75, 537012.75, 187963.75, - 537012.75, 188100.25, 537012.75, 188143.75, 537012.75, 188131.25, 537012.75, 188070.75, - 537012.75, 187938.75, 537012.75, 187953.25, 537013.25, 187953.25, 537013.25, 188143.75, - 537013.25, 188021.75, 537013.25, 187913.25, 537013.25, 188091.25, 537013.25, 187962.25, - 537013.25, 187981.25, 537013.25, 188082.25, 537013.25, 188106.75, 537013.25, 188144.25, - 537013.25, 187989.25, 537013.25, 188069.75, 537013.25, 188153.25, 537013.25, 187963.75, - 537013.25, 188048.25, 537013.25, 187980.25, 537013.25, 188006.75, 537013.25, 188139.25, - 537013.25, 188117.25, 537013.25, 188094.25, 537013.25, 187963.25, 537013.25, 187953.75, - 537013.25, 187915.75, 537013.25, 187972.25, 537013.25, 187937.25, 537013.25, 187935.75, - 537013.25, 187933.75, 537013.25, 188112.25, 537013.25, 187952.75, 537013.25, 188049.75, - 537013.25, 188037.25, 537013.25, 188022.75, 537013.25, 187982.25, 537013.25, 187990.25, - 537013.25, 188112.75, 537013.25, 188078.25, 537013.25, 187994.75, 537013.25, 187965.25, - 537013.25, 187972.75, 537013.25, 188151.25, 537013.25, 187936.75, 537013.25, 188008.75, - 537013.25, 188057.75, 537013.25, 187912.75, 537013.25, 188050.75, 537013.25, 188119.75, - 537013.25, 188140.25, 537013.25, 187931.75, 537013.25, 187917.75, 537013.25, 188156.25, - 537013.25, 188025.75, 537013.25, 187982.75, 537013.25, 187934.75, 537013.25, 188016.75, - 537013.25, 187974.75, 537013.25, 188105.75, 537013.25, 188145.75, 537013.25, 187993.75, - 537013.25, 188154.75, 537013.25, 188025.25, 537013.25, 188077.25, 537013.25, 188001.25, - 537013.25, 188055.25, 537013.25, 188109.25, 537013.25, 188058.25, 537013.25, 188130.25, - 537013.25, 188075.75, 537013.25, 187983.75, 537013.25, 188027.25, 537013.25, 188047.75, - 537013.25, 187916.25, 537013.25, 188152.25, 537013.25, 188116.75, 537013.25, 188141.25, - 537013.25, 187970.25, 537013.25, 188058.75, 537013.25, 187974.25, 537013.75, 188113.75, - 537013.75, 188139.25, 537013.75, 188115.25, 537013.75, 188046.25, 537013.75, 187962.75, - 537013.75, 187913.25, 537013.75, 188031.25, 537013.75, 188118.75, 537013.75, 188138.75, - 537013.75, 187971.75, 537013.75, 188001.75, 537013.75, 188046.75, 537013.75, 188056.25, - 537013.75, 188015.75, 537013.75, 188080.25, 537013.75, 188137.75, 537013.75, 188065.75, - 537013.75, 187944.25, 537013.75, 188057.75, 537013.75, 187941.75, 537013.75, 188077.75, - 537013.75, 187917.25, 537013.75, 188140.75, 537013.75, 188049.75, 537013.75, 188095.25, - 537013.75, 188023.75, 537013.75, 188016.75, 537013.75, 187987.75, 537013.75, 187951.25, - 537013.75, 187971.25, 537013.75, 187973.25, 537013.75, 188153.75, 537013.75, 188012.25, - 537013.75, 188055.25, 537013.75, 187973.75, 537013.75, 187977.25, 537013.75, 188041.25, - 537013.75, 187911.25, 537013.75, 188104.75, 537013.75, 187934.25, 537013.75, 188021.75, - 537013.75, 188144.75, 537013.75, 188011.25, 537013.75, 187946.25, 537013.75, 187953.75, - 537013.75, 188017.75, 537013.75, 187951.75, 537013.75, 187974.75, 537013.75, 188110.75, - 537013.75, 188047.75, 537013.75, 187916.25, 537013.75, 188105.75, 537013.75, 187952.25, - 537013.75, 188144.25, 537013.75, 188059.75, 537013.75, 187975.25, 537013.75, 188094.75, - 537013.75, 187912.75, 537013.75, 187932.75, 537013.75, 188048.25, 537013.75, 187969.75, - 537013.75, 188072.25, 537013.75, 187961.75, 537013.75, 188101.25, 537013.75, 187995.25, - 537013.75, 188007.75, 537013.75, 188117.25, 537013.75, 187983.25, 537013.75, 188143.25, - 537013.75, 188026.25, 537013.75, 188150.75, 537013.75, 188098.75, 537013.75, 188025.25, - 537013.75, 188150.25, 537013.75, 188020.75, 537013.75, 188154.75, 537013.75, 188071.75, - 537013.75, 187975.75, 537013.75, 187995.75, 537013.75, 187931.25, 537013.75, 187983.75, - 537013.75, 188007.25, 537013.75, 188094.25, 537013.75, 188048.75, 537014.25, 188020.25, - 537014.25, 187915.75, 537014.25, 188029.75, 537014.25, 187978.75, 537014.25, 188007.25, - 537014.25, 188048.75, 537014.25, 188143.75, 537014.25, 188046.25, 537014.25, 188115.25, - 537014.25, 188070.75, 537014.25, 187995.75, 537014.25, 188025.75, 537014.25, 188053.25, - 537014.25, 187953.25, 537014.25, 187975.75, 537014.25, 188112.25, 537014.25, 188108.75, - 537014.25, 187913.25, 537014.25, 188117.75, 537014.25, 188154.75, 537014.25, 188150.25, - 537014.25, 188118.75, 537014.25, 188150.75, 537014.25, 188138.75, 537014.25, 188014.75, - 537014.25, 188139.75, 537014.25, 188026.25, 537014.25, 187976.75, 537014.25, 187971.75, - 537014.25, 188025.25, 537014.25, 187916.75, 537014.25, 188015.75, 537014.25, 187983.25, - 537014.25, 187982.75, 537014.25, 187961.75, 537014.25, 188034.25, 537014.25, 188112.75, - 537014.25, 187931.75, 537014.25, 188111.25, 537014.25, 188147.25, 537014.25, 188080.25, - 537014.25, 188057.75, 537014.25, 187969.75, 537014.25, 187912.75, 537014.25, 187942.75, - 537014.25, 188055.75, 537014.25, 188048.25, 537014.25, 188145.75, 537014.25, 188095.75, - 537014.25, 188026.75, 537014.25, 187932.75, 537014.25, 188065.25, 537014.25, 187933.25, - 537014.25, 188113.25, 537014.25, 187994.25, 537014.25, 188022.75, 537014.25, 188094.75, - 537014.25, 188144.25, 537014.25, 187975.25, 537014.25, 188021.25, 537014.25, 188107.25, - 537014.25, 187952.25, 537014.25, 188016.75, 537014.25, 188095.25, 537014.25, 187960.75, - 537014.25, 187951.25, 537014.25, 187979.75, 537014.25, 187934.75, 537014.25, 188036.25, - 537014.25, 187993.75, 537014.25, 187938.25, 537014.25, 187973.25, 537014.25, 188113.75, - 537014.25, 187963.25, 537014.25, 188114.25, 537014.25, 188047.75, 537014.25, 188068.75, - 537014.25, 187999.75, 537014.25, 188152.25, 537014.25, 188092.75, 537014.25, 187971.25, - 537014.25, 187951.75, 537014.25, 188069.25, 537014.25, 187962.25, 537014.25, 188154.25, - 537014.25, 188104.75, 537014.25, 188116.25, 537014.25, 188032.75, 537014.25, 187946.25, - 537014.25, 187935.75, 537014.25, 187934.25, 537014.25, 188141.25, 537014.25, 188027.25, - 537014.25, 188144.75, 537014.75, 188011.25, 537014.75, 187986.75, 537014.75, 188017.75, - 537014.75, 188081.25, 537014.75, 187970.75, 537014.75, 187960.25, 537014.75, 188155.75, - 537014.75, 188129.75, 537014.75, 188092.25, 537014.75, 187934.25, 537014.75, 187950.25, - 537014.75, 187944.75, 537014.75, 187951.75, 537014.75, 187930.75, 537014.75, 188154.25, - 537014.75, 188064.75, 537014.75, 187947.75, 537014.75, 187973.75, 537014.75, 188058.75, - 537014.75, 188118.25, 537014.75, 188017.25, 537014.75, 187974.75, 537014.75, 188045.75, - 537014.75, 188080.75, 537014.75, 188037.75, 537014.75, 188110.75, 537014.75, 188153.75, - 537014.75, 188114.25, 537014.75, 188063.25, 537014.75, 188022.25, 537014.75, 188044.75, - 537014.75, 187986.25, 537014.75, 188096.25, 537014.75, 187960.75, 537014.75, 187941.25, - 537014.75, 188095.25, 537014.75, 188027.25, 537014.75, 188136.75, 537014.75, 187988.25, - 537014.75, 188142.25, 537014.75, 187918.75, 537014.75, 187943.25, 537014.75, 188022.75, - 537014.75, 187913.75, 537014.75, 187933.25, 537014.75, 188009.25, 537014.75, 188094.75, - 537014.75, 187917.25, 537014.75, 188048.25, 537014.75, 187932.25, 537014.75, 188093.25, - 537014.75, 188066.25, 537014.75, 187912.25, 537014.75, 187972.75, 537014.75, 188078.25, - 537014.75, 188151.25, 537014.75, 188080.25, 537014.75, 187994.75, 537014.75, 188056.25, - 537014.75, 188024.75, 537014.75, 188007.75, 537014.75, 188160.25, 537014.75, 188015.25, - 537014.75, 187931.75, 537014.75, 188082.75, 537014.75, 188118.75, 537014.75, 187976.75, - 537014.75, 188014.75, 537014.75, 187961.25, 537014.75, 187984.25, 537014.75, 188156.25, - 537014.75, 187995.75, 537014.75, 188046.75, 537014.75, 188020.75, 537014.75, 188079.25, - 537014.75, 187947.25, 537014.75, 188035.75, 537014.75, 187990.25, 537014.75, 187983.75, - 537014.75, 187978.25, 537014.75, 188103.25, 537014.75, 187910.75, 537014.75, 187976.25, - 537014.75, 187950.75, 537014.75, 188007.25, 537014.75, 188026.75, 537015.25, 187936.25, - 537015.25, 188008.75, 537015.25, 187950.75, 537015.25, 187959.25, 537015.25, 188095.75, - 537015.25, 188056.75, 537015.25, 188066.75, 537015.25, 188108.75, 537015.25, 188001.75, - 537015.25, 187946.75, 537015.25, 188079.25, 537015.25, 188147.25, 537015.25, 187977.75, - 537015.25, 187933.75, 537015.25, 187947.25, 537015.25, 188046.75, 537015.25, 188065.75, - 537015.25, 187972.25, 537015.25, 188014.75, 537015.25, 188057.25, 537015.25, 187918.25, - 537015.25, 188145.75, 537015.25, 188103.75, 537015.25, 188118.75, 537015.25, 188079.75, - 537015.25, 188023.75, 537015.25, 188138.25, 537015.25, 188085.75, 537015.25, 188096.25, - 537015.25, 188155.25, 537015.25, 188114.75, 537015.25, 188145.25, 537015.25, 188137.75, - 537015.25, 188022.25, 537015.25, 188140.25, 537015.25, 187958.75, 537015.25, 187941.75, - 537015.25, 187959.75, 537015.25, 188148.75, 537015.25, 187977.25, 537015.25, 188037.25, - 537015.25, 188085.25, 537015.25, 188024.25, 537015.25, 187920.75, 537015.25, 188102.75, - 537015.25, 188005.25, 537015.25, 188077.25, 537015.25, 187949.25, 537015.25, 188058.25, - 537015.25, 187981.75, 537015.25, 188119.75, 537015.25, 188076.75, 537015.25, 188021.25, - 537015.25, 188062.75, 537015.25, 188111.25, 537015.25, 188084.25, 537015.25, 188020.75, - 537015.25, 187931.25, 537015.25, 188027.75, 537015.25, 188006.75, 537015.25, 187996.25, - 537015.25, 188094.25, 537015.25, 187971.25, 537015.25, 187937.25, 537015.25, 187935.25, - 537015.25, 188019.75, 537015.25, 187975.75, 537015.25, 187911.25, 537015.25, 188141.25, - 537015.25, 187930.75, 537015.25, 187987.25, 537015.25, 188093.75, 537015.25, 187961.25, - 537015.25, 187995.25, 537015.25, 187950.25, 537015.25, 188060.75, 537015.25, 188101.25, - 537015.25, 187986.75, 537015.25, 188045.25, 537015.25, 187949.75, 537015.25, 187912.75, - 537015.25, 187947.75, 537015.25, 188142.75, 537015.25, 188117.25, 537015.25, 187985.75, - 537015.25, 187986.25, 537015.25, 188154.25, 537015.25, 188074.25, 537015.25, 188059.75, - 537015.25, 188044.75, 537015.25, 188081.75, 537015.25, 187974.25, 537015.25, 188113.75, - 537015.25, 188116.75, 537015.25, 188076.25, 537015.25, 188059.25, 537015.25, 188156.75, - 537015.75, 188156.75, 537015.75, 188080.75, 537015.75, 188076.25, 537015.75, 188010.25, - 537015.75, 188101.75, 537015.75, 188081.75, 537015.75, 188056.75, 537015.75, 188113.75, - 537015.75, 187974.25, 537015.75, 187972.25, 537015.75, 188044.75, 537015.75, 187938.75, - 537015.75, 188059.75, 537015.75, 187946.25, 537015.75, 187957.75, 537015.75, 188089.75, - 537015.75, 188141.75, 537015.75, 187986.25, 537015.75, 187948.75, 537015.75, 188067.25, - 537015.75, 187931.75, 537015.75, 188018.25, 537015.75, 187947.25, 537015.75, 187985.75, - 537015.75, 188001.75, 537015.75, 187975.25, 537015.75, 188147.25, 537015.75, 188096.25, - 537015.75, 188044.25, 537015.75, 188103.75, 537015.75, 188119.25, 537015.75, 188045.25, - 537015.75, 187933.75, 537015.75, 188067.75, 537015.75, 187940.75, 537015.75, 187959.25, - 537015.75, 187918.25, 537015.75, 188138.75, 537015.75, 187986.75, 537015.75, 187912.75, - 537015.75, 188014.75, 537015.75, 187949.75, 537015.75, 188065.75, 537015.75, 187960.25, - 537015.75, 187995.25, 537015.75, 188023.75, 537015.75, 188034.25, 537015.75, 188101.25, - 537015.75, 188015.25, 537015.75, 188136.25, 537015.75, 187985.25, 537015.75, 187984.75, - 537015.75, 188007.75, 537015.75, 188143.25, 537015.75, 188079.75, 537015.75, 187971.75, - 537015.75, 188027.75, 537015.75, 188093.75, 537015.75, 187934.25, 537015.75, 188154.75, - 537015.75, 188085.75, 537015.75, 187975.75, 537015.75, 188106.25, 537015.75, 188024.25, - 537015.75, 188112.25, 537015.75, 188043.25, 537015.75, 188155.25, 537015.75, 188025.75, - 537015.75, 188141.25, 537015.75, 187992.25, 537015.75, 188137.75, 537015.75, 188022.25, - 537015.75, 188148.75, 537015.75, 187971.25, 537015.75, 187958.75, 537015.75, 187977.25, - 537015.75, 188140.75, 537015.75, 188021.75, 537015.75, 188110.75, 537015.75, 187996.25, - 537015.75, 188016.75, 537015.75, 188084.75, 537015.75, 188006.75, 537015.75, 187931.25, - 537015.75, 188077.25, 537015.75, 187968.75, 537015.75, 188020.75, 537015.75, 188070.75, - 537015.75, 188107.25, 537015.75, 188114.25, 537015.75, 188102.75, 537015.75, 188005.75, - 537015.75, 188153.75, 537015.75, 188094.75, 537015.75, 187987.75, 537015.75, 188076.75, - 537016.25, 188006.25, 537016.25, 187932.25, 537016.25, 187973.25, 537016.25, 188119.75, - 537016.25, 188021.25, 537016.25, 188005.75, 537016.25, 188100.75, 537016.25, 187976.75, - 537016.25, 188114.25, 537016.25, 188059.25, 537016.25, 187949.25, 537016.25, 188024.75, - 537016.25, 188141.25, 537016.25, 188118.25, 537016.25, 188058.25, 537016.25, 188017.25, - 537016.25, 188144.75, 537016.25, 188116.25, 537016.25, 187996.25, 537016.25, 188100.25, - 537016.25, 188020.75, 537016.25, 188020.25, 537016.25, 188155.75, 537016.25, 187973.75, - 537016.25, 188090.25, 537016.25, 188013.25, 537016.25, 188007.25, 537016.25, 188083.75, - 537016.25, 188156.25, 537016.25, 187967.75, 537016.25, 187936.75, 537016.25, 188048.75, - 537016.25, 188043.25, 537016.25, 188004.25, 537016.25, 188013.75, 537016.25, 187972.75, - 537016.25, 187930.75, 537016.25, 187965.25, 537016.25, 187975.75, 537016.25, 187916.75, - 537016.25, 187922.25, 537016.25, 188086.75, 537016.25, 187984.75, 537016.25, 188102.25, - 537016.25, 188043.75, 537016.25, 187914.75, 537016.25, 188081.25, 537016.25, 187958.25, - 537016.25, 187957.25, 537016.25, 188008.75, 537016.25, 188066.25, 537016.25, 187912.25, - 537016.25, 187932.75, 537016.25, 188146.75, 537016.25, 188060.25, 537016.25, 188120.25, - 537016.25, 188045.25, 537016.25, 188096.25, 537016.25, 188019.25, 537016.25, 187919.25, - 537016.25, 187986.75, 537016.25, 188142.25, 537016.25, 187986.25, 537016.25, 187934.75, - 537016.25, 188113.75, 537016.25, 187948.75, 537016.25, 188032.75, 537016.25, 188095.75, - 537016.25, 188047.75, 537016.25, 188157.75, 537016.25, 187978.75, 537016.75, 188095.75, - 537016.75, 187935.25, 537016.75, 187935.75, 537016.75, 187925.25, 537016.75, 188108.75, - 537016.75, 188066.25, 537016.75, 188064.75, 537016.75, 188110.25, 537016.75, 188076.75, - 537016.75, 188064.25, 537016.75, 188061.75, 537016.75, 188112.25, 537016.75, 188060.75, - 537016.75, 188078.25, 537016.75, 188112.75, 537016.75, 187911.25, 537016.75, 188113.25, - 537016.75, 188059.75, 537016.75, 188058.75, 537016.75, 188114.25, 537016.75, 188157.75, - 537016.75, 187938.25, 537016.75, 188057.75, 537016.75, 188157.25, 537016.75, 188114.75, - 537016.75, 188115.25, 537016.75, 188116.75, 537016.75, 187939.25, 537016.75, 188118.25, - 537016.75, 188118.75, 537016.75, 187911.75, 537016.75, 187940.25, 537016.75, 187972.75, - 537016.75, 188049.75, 537016.75, 188119.75, 537016.75, 188049.25, 537016.75, 187933.25, - 537016.75, 188120.25, 537016.75, 188102.75, 537016.75, 187973.25, 537016.75, 188120.75, - 537016.75, 188121.25, 537016.75, 188046.75, 537016.75, 188046.25, 537016.75, 188121.75, - 537016.75, 187975.75, 537016.75, 188080.75, 537016.75, 188043.75, 537016.75, 188102.25, - 537016.75, 187976.25, 537016.75, 188042.75, 537016.75, 188042.25, 537016.75, 188041.25, - 537016.75, 188031.25, 537016.75, 187932.75, 537016.75, 188155.75, 537016.75, 187947.25, - 537016.75, 188028.25, 537016.75, 187912.25, 537016.75, 188082.25, 537016.75, 187947.75, - 537016.75, 188026.25, 537016.75, 187948.25, 537016.75, 187918.25, 537016.75, 188023.25, - 537016.75, 187948.75, 537016.75, 187984.25, 537016.75, 188022.75, 537016.75, 187949.25, - 537016.75, 188021.25, 537016.75, 188084.25, 537016.75, 187932.25, 537016.75, 188100.75, - 537016.75, 188097.25, 537016.75, 188019.75, 537016.75, 187949.75, 537016.75, 188019.25, - 537016.75, 188018.75, 537016.75, 187986.25, 537016.75, 188018.25, 537016.75, 187950.25, - 537016.75, 188085.75, 537016.75, 188015.75, 537016.75, 188015.25, 537016.75, 188153.75, - 537016.75, 188139.25, 537016.75, 188014.75, 537016.75, 188139.75, 537016.75, 188099.75, - 537016.75, 188141.25, 537016.75, 188009.25, 537016.75, 188142.75, 537016.75, 188008.25, - 537016.75, 188152.25, 537016.75, 188099.25, 537016.75, 188006.25, 537016.75, 188005.25, - 537016.75, 187958.25, 537016.75, 187993.25, 537016.75, 187957.75, 537016.75, 188004.75, - 537016.75, 188004.25, 537016.75, 188098.75, 537016.75, 188145.25, 537016.75, 188145.75, - 537016.75, 188003.25, 537016.75, 187995.75, 537016.75, 187956.75, 537016.75, 188088.25, - 537016.75, 188147.25, 537016.75, 188001.25, 537016.75, 187955.75, 537016.75, 187914.25, - 537016.75, 187930.75, 537016.75, 187996.75, 537017.25, 187996.75, 537017.25, 188115.75, - 537017.25, 187930.75, 537017.25, 188118.25, 537017.25, 187956.25, 537017.25, 188057.25, - 537017.25, 188118.75, 537017.25, 187940.25, 537017.25, 188119.75, 537017.25, 188157.25, - 537017.25, 188076.25, 537017.25, 188049.25, 537017.25, 188080.25, 537017.25, 187933.25, - 537017.25, 188114.75, 537017.25, 188120.25, 537017.25, 187973.25, 537017.25, 188102.75, - 537017.25, 188147.25, 537017.25, 188157.75, 537017.25, 188156.75, 537017.25, 187935.25, - 537017.25, 187975.25, 537017.25, 187956.75, 537017.25, 188002.75, 537017.25, 188095.75, - 537017.25, 188046.25, 537017.25, 188003.25, 537017.25, 187995.75, 537017.25, 188107.25, - 537017.25, 188145.75, 537017.25, 187975.75, 537017.25, 188058.75, 537017.25, 188003.75, - 537017.25, 188044.25, 537017.25, 188096.75, 537017.25, 188102.25, 537017.25, 188043.75, - 537017.25, 188098.75, 537017.25, 188043.25, 537017.25, 188004.25, 537017.25, 187935.75, - 537017.25, 188059.75, 537017.25, 188042.75, 537017.25, 188042.25, 537017.25, 187957.75, - 537017.25, 188041.25, 537017.25, 188144.75, 537017.25, 188067.75, 537017.25, 188005.25, - 537017.25, 188081.25, 537017.25, 187992.25, 537017.25, 188040.25, 537017.25, 187919.25, - 537017.25, 188060.25, 537017.25, 188031.25, 537017.25, 187977.25, 537017.25, 187932.75, - 537017.25, 187911.25, 537017.25, 187910.75, 537017.25, 188112.75, 537017.25, 188160.25, - 537017.25, 188096.25, 537017.25, 188007.25, 537017.25, 187947.25, 537017.25, 188008.25, - 537017.25, 188066.25, 537017.25, 188008.75, 537017.25, 188082.25, 537017.25, 188152.75, - 537017.25, 187912.25, 537017.25, 188061.25, 537017.25, 188027.75, 537017.25, 188141.75, - 537017.25, 187947.75, 537017.25, 187979.25, 537017.25, 188155.25, 537017.25, 188026.25, - 537017.25, 187948.25, 537017.25, 188024.25, 537017.25, 188023.25, 537017.25, 188140.25, - 537017.25, 188065.75, 537017.25, 187948.75, 537017.25, 188065.25, 537017.25, 187984.25, - 537017.25, 188022.75, 537017.25, 187949.25, 537017.25, 188014.75, 537017.25, 188077.25, - 537017.25, 188015.25, 537017.25, 187950.75, 537017.25, 187985.25, 537017.25, 188139.25, - 537017.25, 188097.25, 537017.25, 188100.75, 537017.25, 188159.75, 537017.25, 188020.75, - 537017.25, 187932.25, 537017.25, 188111.25, 537017.25, 188015.75, 537017.25, 188019.75, - 537017.25, 188137.75, 537017.25, 187931.75, 537017.25, 188110.25, 537017.25, 187949.75, - 537017.25, 188019.25, 537017.25, 188084.75, 537017.25, 188018.25, 537017.25, 188100.25, - 537017.25, 188017.75, 537017.25, 187950.25, 537017.75, 188064.25, 537017.75, 188017.25, - 537017.75, 187950.25, 537017.75, 188103.25, 537017.75, 188063.75, 537017.75, 188017.75, - 537017.75, 188115.75, 537017.75, 188157.25, 537017.75, 188118.25, 537017.75, 188085.25, - 537017.75, 188159.75, 537017.75, 187986.75, 537017.75, 188018.75, 537017.75, 188062.25, - 537017.75, 188016.75, 537017.75, 187985.75, 537017.75, 188079.25, 537017.75, 188085.75, - 537017.75, 187997.25, 537017.75, 188015.75, 537017.75, 188050.75, 537017.75, 188118.75, - 537017.75, 188064.75, 537017.75, 188061.75, 537017.75, 188020.25, 537017.75, 188079.75, - 537017.75, 187911.75, 537017.75, 187996.25, 537017.75, 187950.75, 537017.75, 187972.75, - 537017.75, 188077.25, 537017.75, 188021.25, 537017.75, 188153.75, 537017.75, 187955.75, - 537017.75, 188083.75, 537017.75, 187955.25, 537017.75, 188098.25, 537017.75, 188048.25, - 537017.75, 187934.75, 537017.75, 188013.75, 537017.75, 187973.25, 537017.75, 187948.75, - 537017.75, 188047.25, 537017.75, 187956.75, 537017.75, 188120.75, 537017.75, 188002.75, - 537017.75, 188046.75, 537017.75, 187975.75, 537017.75, 188109.25, 537017.75, 188155.25, - 537017.75, 188140.75, 537017.75, 188121.75, 537017.75, 188145.75, 537017.75, 188141.25, - 537017.75, 188066.25, 537017.75, 188114.25, 537017.75, 188003.75, 537017.75, 187930.25, - 537017.75, 188096.25, 537017.75, 187918.75, 537017.75, 188080.75, 537017.75, 188087.25, - 537017.75, 188045.25, 537017.75, 188061.25, 537017.75, 188007.75, 537017.75, 188059.25, - 537017.75, 188029.75, 537017.75, 187954.25, 537017.75, 187994.75, 537017.75, 188099.25, - 537017.75, 187976.25, 537017.75, 187936.25, 537017.75, 188097.75, 537017.75, 188006.25, - 537017.75, 188145.25, 537017.75, 187933.75, 537017.75, 188098.75, 537017.75, 187915.25, - 537017.75, 188095.75, 537017.75, 188103.75, 537017.75, 188004.75, 537017.75, 187920.25, - 537017.75, 188042.25, 537017.75, 188041.75, 537017.75, 188113.25, 537017.75, 187963.25, - 537017.75, 187971.25, 537017.75, 188040.75, 537017.75, 188040.25, 537017.75, 188081.25, - 537017.75, 188158.25, 537017.75, 187931.25, 537018.25, 188005.75, 537018.25, 188040.75, - 537018.25, 188040.25, 537018.25, 187953.75, 537018.25, 188039.75, 537018.25, 188039.25, - 537018.25, 187920.75, 537018.25, 188103.75, 537018.25, 188038.75, 537018.25, 187976.75, - 537018.25, 188037.25, 537018.25, 187919.75, 537018.25, 188059.75, 537018.25, 188043.25, - 537018.25, 187994.25, 537018.25, 188113.75, 537018.25, 188043.75, 537018.25, 188006.25, - 537018.25, 188060.25, 537018.25, 188099.25, 537018.25, 188087.75, 537018.25, 187946.75, - 537018.25, 187915.75, 537018.25, 188152.75, 537018.25, 188122.25, 537018.25, 188158.25, - 537018.25, 187952.25, 537018.25, 187951.75, 537018.25, 188086.75, 537018.25, 187951.25, - 537018.25, 188025.75, 537018.25, 188046.25, 537018.25, 188003.25, 537018.25, 188112.25, - 537018.25, 188046.75, 537018.25, 188155.25, 537018.25, 187918.25, 537018.25, 187954.75, - 537018.25, 188121.25, 537018.25, 188001.75, 537018.25, 187941.25, 537018.25, 188058.25, - 537018.25, 187983.25, 537018.25, 188013.25, 537018.25, 187996.25, 537018.25, 187937.25, - 537018.25, 188153.25, 537018.25, 187984.75, 537018.25, 188075.75, 537018.25, 188014.25, - 537018.25, 188049.25, 537018.25, 187933.25, 537018.25, 187955.25, 537018.25, 187973.25, - 537018.25, 188021.75, 537018.25, 188098.25, 537018.25, 187929.75, 537018.25, 187988.75, - 537018.25, 187936.75, 537018.25, 188078.75, 537018.25, 188050.25, 537018.25, 188097.25, - 537018.25, 187950.75, 537018.25, 188061.75, 537018.25, 187997.75, 537018.25, 187987.75, - 537018.25, 187932.25, 537018.25, 188158.75, 537018.25, 187934.25, 537018.25, 188115.25, - 537018.25, 187987.25, 537018.25, 187912.75, 537018.25, 188018.25, 537018.25, 188117.75, - 537018.25, 188159.75, 537018.25, 188017.25, 537018.25, 187950.25, 537018.25, 188157.25, - 537018.25, 188116.75, 537018.25, 188103.25, 537018.25, 188116.25, 537018.25, 187919.25, - 537018.75, 188103.25, 537018.75, 188116.75, 537018.75, 187939.25, 537018.75, 188157.25, - 537018.75, 188117.25, 537018.75, 187972.75, 537018.75, 188115.25, 537018.75, 188051.25, - 537018.75, 187973.25, 537018.75, 187929.75, 537018.75, 188048.25, 537018.75, 188157.75, - 537018.75, 188058.25, 537018.75, 187974.75, 537018.75, 188121.25, 537018.75, 187938.25, - 537018.75, 188158.25, 537018.75, 188122.25, 537018.75, 188080.75, 537018.75, 187933.75, - 537018.75, 187976.25, 537018.75, 188045.25, 537018.75, 188043.75, 537018.75, 188113.75, - 537018.75, 188043.25, 537018.75, 187976.75, 537018.75, 188040.75, 537018.75, 188040.25, - 537018.75, 188039.75, 537018.75, 188113.25, 537018.75, 188103.75, 537018.75, 188039.25, - 537018.75, 188038.25, 537018.75, 187996.75, 537018.75, 187919.25, 537018.75, 187977.25, - 537018.75, 187932.75, 537018.75, 187946.75, 537018.75, 188158.75, 537018.75, 188060.75, - 537018.75, 188029.25, 537018.75, 187912.25, 537018.75, 188028.25, 537018.75, 187918.75, - 537018.75, 188024.25, 537018.75, 187948.75, 537018.75, 187985.25, 537018.75, 188097.25, - 537018.75, 188021.25, 537018.75, 188020.25, 537018.75, 187932.25, 537018.75, 187912.75, - 537018.75, 187960.75, 537018.75, 188062.75, 537018.75, 188063.75, 537018.75, 187950.25, - 537018.75, 188110.75, 537018.75, 188154.25, 537018.75, 188159.25, 537018.75, 188085.25, - 537018.75, 188017.25, 537018.75, 187987.25, 537018.75, 188015.75, 537018.75, 187950.75, - 537018.75, 187988.75, 537018.75, 188086.75, 537018.75, 188013.75, 537018.75, 188013.25, - 537018.75, 187989.75, 537018.75, 188152.75, 537018.75, 188006.75, 537018.75, 188097.75, - 537018.75, 187953.25, 537018.75, 187953.75, 537018.75, 188095.75, 537018.75, 188004.75, - 537018.75, 187994.25, 537018.75, 187935.75, 537018.75, 187995.75, 537018.75, 188146.25, - 537018.75, 187954.75, 537018.75, 188001.25, 537018.75, 188074.25, 537018.75, 187955.25, - 537018.75, 188076.25, 537018.75, 188098.25, 537018.75, 187997.75, 537018.75, 187934.25, - 537019.25, 188037.25, 537019.25, 187998.25, 537019.25, 187988.25, 537019.25, 187984.75, - 537019.25, 188046.25, 537019.25, 188111.25, 537019.25, 188061.75, 537019.25, 188013.25, - 537019.25, 188054.25, 537019.25, 188081.25, 537019.25, 188040.75, 537019.25, 187951.25, - 537019.25, 188156.25, 537019.25, 188006.25, 537019.25, 188121.75, 537019.25, 188116.75, - 537019.25, 188041.25, 537019.25, 188014.25, 537019.25, 187985.25, 537019.25, 188057.25, - 537019.25, 188061.25, 537019.25, 188058.75, 537019.25, 187941.75, 537019.25, 187972.25, - 537019.25, 187919.25, 537019.25, 187953.25, 537019.25, 188117.25, 537019.25, 187987.75, - 537019.25, 188053.75, 537019.25, 188022.75, 537019.25, 188104.25, 537019.25, 187971.75, - 537019.25, 187932.25, 537019.25, 187911.75, 537019.25, 188080.75, 537019.25, 188042.25, - 537019.25, 188033.25, 537019.25, 187937.25, 537019.25, 188076.75, 537019.25, 188159.75, - 537019.25, 188087.75, 537019.25, 188086.25, 537019.25, 187950.25, 537019.25, 187913.25, - 537019.25, 187952.75, 537019.25, 188042.75, 537019.25, 187942.75, 537019.25, 187954.25, - 537019.25, 188007.75, 537019.25, 188066.75, 537019.25, 187951.75, 537019.25, 188039.25, - 537019.25, 187930.25, 537019.25, 187936.75, 537019.25, 188078.75, 537019.25, 188073.25, - 537019.25, 187916.25, 537019.25, 187950.75, 537019.25, 188158.75, 537019.25, 188085.25, - 537019.25, 187935.25, 537019.25, 187933.25, 537019.25, 187921.25, 537019.25, 187997.25, - 537019.25, 188043.25, 537019.25, 188038.75, 537019.25, 188037.75, 537019.25, 188015.75, - 537019.25, 188005.25, 537019.25, 188050.75, 537019.25, 187970.75, 537019.25, 188155.75, - 537019.75, 187931.75, 537019.75, 188079.75, 537019.75, 188155.75, 537019.75, 188154.25, - 537019.75, 188043.75, 537019.75, 187968.25, 537019.75, 188102.25, 537019.75, 187971.25, - 537019.75, 187986.75, 537019.75, 187947.25, 537019.75, 188082.25, 537019.75, 188037.75, - 537019.75, 187952.25, 537019.75, 188057.75, 537019.75, 188009.75, 537019.75, 188116.25, - 537019.75, 187986.25, 537019.75, 188002.25, 537019.75, 188043.25, 537019.75, 187915.75, - 537019.75, 188007.75, 537019.75, 187934.25, 537019.75, 188037.25, 537019.75, 188084.25, - 537019.75, 188051.75, 537019.75, 187950.75, 537019.75, 188078.75, 537019.75, 187997.75, - 537019.75, 188160.25, 537019.75, 188122.75, 537019.75, 187918.75, 537019.75, 187937.25, - 537019.75, 188039.25, 537019.75, 188104.75, 537019.75, 187985.75, 537019.75, 187930.25, - 537019.75, 187919.75, 537019.75, 188079.25, 537019.75, 188064.75, 537019.75, 188026.25, - 537019.75, 187974.25, 537019.75, 187969.75, 537019.75, 188086.25, 537019.75, 187978.75, - 537019.75, 188110.25, 537019.75, 187949.75, 537019.75, 188141.75, 537019.75, 187933.25, - 537019.75, 188142.75, 537019.75, 188159.75, 537019.75, 187912.75, 537019.75, 188036.75, - 537019.75, 188006.75, 537019.75, 187936.25, 537019.75, 188053.25, 537019.75, 187975.25, - 537019.75, 187932.25, 537019.75, 188053.75, 537019.75, 187971.75, 537019.75, 188115.75, - 537019.75, 188077.75, 537019.75, 188042.25, 537019.75, 188117.25, 537019.75, 188008.25, - 537019.75, 187929.25, 537019.75, 187930.75, 537019.75, 188014.75, 537019.75, 188041.75, - 537019.75, 187988.75, 537019.75, 188116.75, 537019.75, 187994.75, 537019.75, 188157.75, - 537019.75, 187910.75, 537019.75, 187931.25, 537019.75, 187947.75, 537019.75, 188086.75, - 537019.75, 188112.75, 537019.75, 188156.75, 537019.75, 188035.75, 537019.75, 188023.25, - 537019.75, 187913.75, 537019.75, 188013.75, 537019.75, 187984.25, 537019.75, 188054.25, - 537019.75, 188159.25, 537019.75, 188005.75, 537019.75, 188059.25, 537019.75, 188115.25, - 537019.75, 187993.75, 537019.75, 187998.75, 537019.75, 188076.25, 537020.25, 187984.75, - 537020.25, 188077.25, 537020.25, 187951.25, 537020.25, 188084.75, 537020.25, 188156.25, - 537020.25, 188022.25, 537020.25, 188078.25, 537020.25, 187972.75, 537020.25, 187988.25, - 537020.25, 188159.25, 537020.25, 188005.75, 537020.25, 188081.25, 537020.25, 188013.75, - 537020.25, 187921.75, 537020.25, 188000.75, 537020.25, 187935.75, 537020.25, 187983.75, - 537020.25, 188121.25, 537020.25, 188041.25, 537020.25, 188035.75, 537020.25, 188008.25, - 537020.25, 188057.25, 537020.25, 188042.25, 537020.25, 188117.25, 537020.25, 188116.75, - 537020.25, 188022.75, 537020.25, 188019.25, 537020.25, 188083.25, 537020.25, 188053.75, - 537020.25, 187931.25, 537020.25, 188102.75, 537020.25, 188036.25, 537020.25, 188101.75, - 537020.25, 188056.75, 537020.25, 187930.75, 537020.25, 188052.75, 537020.25, 188014.75, - 537020.25, 188069.75, 537020.25, 187941.75, 537020.25, 188060.75, 537020.25, 188047.75, - 537020.25, 187919.25, 537020.25, 187932.25, 537020.25, 187986.75, 537020.25, 188122.25, - 537020.25, 187912.75, 537020.25, 188006.75, 537020.25, 188103.25, 537020.25, 188036.75, - 537020.25, 188110.25, 537020.25, 188159.75, 537020.25, 188079.25, 537020.25, 187933.25, - 537020.25, 188141.75, 537020.25, 187951.75, 537020.25, 187974.75, 537020.25, 187919.75, - 537020.25, 187969.25, 537020.25, 188045.25, 537020.25, 187985.75, 537020.25, 188086.25, - 537020.25, 187950.25, 537020.25, 188122.75, 537020.25, 187937.25, 537020.25, 188037.25, - 537020.25, 187913.25, 537020.25, 187950.75, 537020.25, 187930.25, 537020.25, 187948.75, - 537020.25, 187912.25, 537020.25, 187949.75, 537020.25, 187996.75, 537020.25, 188058.25, - 537020.25, 187934.75, 537020.25, 188103.75, 537020.25, 187997.75, 537020.25, 188116.25, - 537020.25, 187952.25, 537020.25, 188007.75, 537020.25, 187986.25, 537020.25, 188114.75, - 537020.25, 188065.75, 537020.25, 188037.75, 537020.25, 187947.25, 537020.25, 188078.75, - 537020.25, 188079.75, 537020.25, 188054.75, 537020.25, 187931.75, 537020.25, 188025.25, - 537020.25, 188038.25, 537020.25, 188155.75, 537020.25, 188154.25, 537020.25, 187971.25, - 537020.25, 188050.75, 537020.75, 187958.75, 537020.75, 188123.25, 537020.75, 187997.75, - 537020.75, 187930.75, 537020.75, 188038.25, 537020.75, 187973.75, 537020.75, 188102.25, - 537020.75, 187940.25, 537020.75, 188060.25, 537020.75, 187947.25, 537020.75, 188119.25, - 537020.75, 187934.25, 537020.75, 188082.25, 537020.75, 188109.25, 537020.75, 188051.75, - 537020.75, 187949.25, 537020.75, 187931.25, 537020.75, 187975.75, 537020.75, 188039.25, - 537020.75, 188058.25, 537020.75, 187936.75, 537020.75, 187991.25, 537020.75, 187937.25, - 537020.75, 187996.75, 537020.75, 187939.75, 537020.75, 187948.75, 537020.75, 187960.25, - 537020.75, 187950.75, 537020.75, 187998.25, 537020.75, 188104.75, 537020.75, 187976.75, - 537020.75, 188122.75, 537020.75, 188015.25, 537020.75, 188159.75, 537020.75, 188142.75, - 537020.75, 188011.25, 537020.75, 188101.75, 537020.75, 188117.75, 537020.75, 187912.75, - 537020.75, 188052.75, 537020.75, 188014.75, 537020.75, 188155.25, 537020.75, 188036.25, - 537020.75, 187987.75, 537020.75, 188116.75, 537020.75, 188083.25, 537020.75, 188080.75, - 537020.75, 187966.75, 537020.75, 187920.75, 537020.75, 188104.25, 537020.75, 187916.75, - 537020.75, 188034.25, 537020.75, 187972.25, 537020.75, 187948.25, 537020.75, 188040.25, - 537020.75, 188058.75, 537020.75, 188082.75, 537020.75, 188034.75, 537020.75, 188117.25, - 537020.75, 187933.75, 537020.75, 187985.25, 537020.75, 188157.75, 537020.75, 188121.25, - 537020.75, 188041.25, 537020.75, 188054.25, 537020.75, 188157.25, 537020.75, 188059.25, - 537020.75, 188006.25, 537020.75, 187998.75, 537020.75, 188156.75, 537020.75, 188013.25, - 537020.75, 188076.25, 537020.75, 188144.25, 537020.75, 187984.75, 537020.75, 188077.25, - 537020.75, 187913.75, 537021.25, 188156.25, 537021.25, 188002.75, 537021.25, 188111.25, - 537021.25, 188157.75, 537021.25, 187947.75, 537021.25, 188117.25, 537021.25, 188063.25, - 537021.25, 188079.25, 537021.25, 187971.75, 537021.25, 188054.75, 537021.25, 187976.25, - 537021.25, 188076.75, 537021.25, 188149.25, 537021.25, 188052.25, 537021.25, 187917.25, - 537021.25, 188119.25, 537021.25, 187972.75, 537021.25, 188091.75, 537021.25, 187999.75, - 537021.25, 188015.75, 537021.25, 187914.25, 537021.25, 187946.75, 537021.25, 188055.25, - 537021.25, 188080.25, 537021.25, 188148.25, 537021.25, 187997.25, 537021.25, 187996.75, - 537021.25, 188144.75, 537021.25, 187936.25, 537021.25, 188032.75, 537021.25, 187996.25, - 537021.25, 188015.25, 537021.25, 188120.25, 537021.25, 187933.25, 537021.25, 188115.75, - 537021.25, 187970.25, 537021.25, 187975.25, 537021.25, 188033.75, 537021.25, 188120.75, - 537021.25, 188061.25, 537021.25, 187938.75, 537021.25, 188014.25, 537021.25, 188024.25, - 537021.25, 187962.25, 537021.25, 187994.75, 537021.25, 187984.25, 537021.25, 188154.75, - 537021.25, 188035.25, 537021.25, 188140.75, 537021.25, 188159.25, 537021.25, 188012.75, - 537021.25, 187985.25, 537021.25, 188121.75, 537021.25, 188097.25, 537021.25, 187912.75, - 537021.25, 187958.25, 537021.25, 187969.75, 537021.25, 188057.75, 537021.25, 188037.25, - 537021.25, 188104.75, 537021.25, 187935.25, 537021.25, 188090.75, 537021.25, 188037.75, - 537021.25, 188007.25, 537021.25, 187958.75, 537021.25, 188060.25, 537021.25, 188154.25, - 537021.25, 187989.75, 537021.25, 187959.25, 537021.25, 188123.75, 537021.25, 187949.25, - 537021.25, 187934.75, 537021.25, 187987.25, 537021.25, 187942.75, 537021.25, 187913.25, - 537021.25, 187966.75, 537021.25, 188008.75, 537021.25, 188074.75, 537021.25, 187967.25, - 537021.25, 188040.25, 537021.25, 188153.75, 537021.25, 188105.25, 537021.25, 188081.25, - 537021.25, 187937.75, 537021.25, 188041.25, 537021.25, 188040.75, 537021.25, 187988.25, - 537021.25, 188059.75, 537021.25, 188076.25, 537021.25, 187955.25, 537021.25, 187973.25, - 537021.75, 188059.75, 537021.75, 188149.25, 537021.75, 187934.25, 537021.75, 188122.75, - 537021.75, 188022.25, 537021.75, 187922.25, 537021.75, 187996.75, 537021.75, 187967.25, - 537021.75, 188123.75, 537021.75, 187934.75, 537021.75, 188158.75, 537021.75, 188141.75, - 537021.75, 188014.75, 537021.75, 188052.25, 537021.75, 188080.25, 537021.75, 187988.25, - 537021.75, 188058.75, 537021.75, 187976.25, 537021.75, 187947.75, 537021.75, 188121.75, - 537021.75, 187920.25, 537021.75, 188119.75, 537021.75, 188091.25, 537021.75, 188075.75, - 537021.75, 187995.75, 537021.75, 188150.25, 537021.75, 188034.25, 537021.75, 187959.25, - 537021.75, 188023.25, 537021.75, 188006.75, 537021.75, 187958.25, 537021.75, 188104.25, - 537021.75, 188063.75, 537021.75, 188000.25, 537021.75, 187933.75, 537021.75, 188003.25, - 537021.75, 188040.75, 537021.75, 187942.75, 537021.75, 188105.75, 537021.75, 187938.25, - 537021.75, 188144.25, 537021.75, 188117.25, 537021.75, 187960.25, 537021.75, 187953.75, - 537021.75, 188009.25, 537021.75, 188120.25, 537021.75, 188087.25, 537021.75, 187970.75, - 537021.75, 187946.75, 537021.75, 187973.75, 537021.75, 188038.75, 537021.75, 188111.25, - 537021.75, 188051.75, 537021.75, 188033.75, 537021.75, 187955.25, 537021.75, 188123.25, - 537021.75, 187984.75, 537021.75, 188036.25, 537021.75, 188057.75, 537021.75, 188081.25, - 537021.75, 187986.25, 537021.75, 188060.75, 537021.75, 188015.75, 537021.75, 188105.25, - 537021.75, 188034.75, 537021.75, 188081.75, 537021.75, 188057.25, 537021.75, 188104.75, - 537021.75, 188153.75, 537021.75, 187917.75, 537021.75, 188119.25, 537021.75, 188054.75, - 537021.75, 187921.25, 537021.75, 188032.75, 537021.75, 188040.25, 537021.75, 187913.75, - 537021.75, 187932.25, 537021.75, 187917.25, 537021.75, 188008.75, 537021.75, 188046.75, - 537021.75, 187997.75, 537021.75, 188074.75, 537021.75, 188002.25, 537021.75, 187972.75, - 537021.75, 188143.25, 537021.75, 188154.75, 537021.75, 187913.25, 537021.75, 187938.75, - 537021.75, 188061.25, 537021.75, 188154.25, 537021.75, 188056.75, 537021.75, 187975.25, - 537021.75, 188013.75, 537021.75, 188115.75, 537021.75, 187999.75, 537021.75, 188055.25, - 537021.75, 188079.25, 537021.75, 187930.25, 537021.75, 187986.75, 537021.75, 188159.25, - 537021.75, 188035.25, 537021.75, 188125.75, 537021.75, 187958.75, 537021.75, 188102.25, - 537021.75, 187984.25, 537021.75, 188045.25, 537021.75, 187994.75, 537022.25, 188050.75, - 537022.25, 187975.75, 537022.25, 187948.25, 537022.25, 187987.75, 537022.25, 187984.25, - 537022.25, 188019.75, 537022.25, 188103.25, 537022.25, 188054.25, 537022.25, 188055.25, - 537022.25, 187912.75, 537022.25, 187967.75, 537022.25, 188094.25, 537022.25, 188118.75, - 537022.25, 188121.25, 537022.25, 188007.25, 537022.25, 187938.75, 537022.25, 187992.75, - 537022.25, 188037.75, 537022.25, 187920.75, 537022.25, 188156.75, 537022.25, 188078.25, - 537022.25, 187924.75, 537022.25, 187947.25, 537022.25, 187990.75, 537022.25, 188033.25, - 537022.25, 188148.75, 537022.25, 188123.25, 537022.25, 188099.25, 537022.25, 188081.25, - 537022.25, 188015.75, 537022.25, 188036.25, 537022.25, 188047.25, 537022.25, 188051.75, - 537022.25, 188061.75, 537022.25, 187935.25, 537022.25, 187964.75, 537022.25, 187930.25, - 537022.25, 187974.25, 537022.25, 188154.25, 537022.25, 187998.75, 537022.25, 188083.75, - 537022.25, 188058.25, 537022.25, 187936.75, 537022.25, 188103.75, 537022.25, 188060.25, - 537022.25, 187914.25, 537022.25, 187948.75, 537022.25, 187910.75, 537022.25, 188105.75, - 537022.25, 187938.25, 537022.25, 188080.75, 537022.25, 187933.75, 537022.25, 188075.75, - 537022.25, 188035.75, 537022.25, 188122.25, 537022.25, 187965.75, 537022.25, 187973.75, - 537022.25, 188145.75, 537022.25, 188053.75, 537022.25, 187970.25, 537022.25, 187976.25, - 537022.25, 187949.25, 537022.25, 188118.25, 537022.25, 188147.75, 537022.25, 188155.25, - 537022.25, 187991.75, 537022.25, 187988.25, 537022.25, 188031.25, 537022.25, 188014.75, - 537022.25, 188160.25, 537022.25, 188058.75, 537022.25, 188032.25, 537022.25, 187947.75, - 537022.25, 187943.25, 537022.25, 187985.25, 537022.25, 188089.75, 537022.25, 187934.75, - 537022.25, 188158.25, 537022.25, 188012.75, 537022.25, 188059.25, 537022.25, 187931.75, - 537022.25, 188159.75, 537022.25, 188077.75, 537022.75, 188003.75, 537022.75, 188117.75, - 537022.75, 188064.75, 537022.75, 188144.75, 537022.75, 188076.75, 537022.75, 187989.75, - 537022.75, 188145.75, 537022.75, 188036.75, 537022.75, 188052.75, 537022.75, 188053.25, - 537022.75, 187945.75, 537022.75, 187971.75, 537022.75, 188066.75, 537022.75, 187943.75, - 537022.75, 187918.75, 537022.75, 188157.75, 537022.75, 188120.25, 537022.75, 188014.25, - 537022.75, 187922.75, 537022.75, 187990.25, 537022.75, 188107.25, 537022.75, 187939.25, - 537022.75, 188070.75, 537022.75, 188042.75, 537022.75, 188109.75, 537022.75, 188007.75, - 537022.75, 188077.25, 537022.75, 188151.25, 537022.75, 188051.75, 537022.75, 188142.25, - 537022.75, 188103.25, 537022.75, 188015.25, 537022.75, 188098.75, 537022.75, 188061.75, - 537022.75, 187957.25, 537022.75, 187990.75, 537022.75, 188142.75, 537022.75, 187999.25, - 537022.75, 188099.75, 537022.75, 188054.75, 537022.75, 187972.75, 537022.75, 188033.25, - 537022.75, 187967.75, 537022.75, 187966.75, 537022.75, 188121.25, 537022.75, 188118.75, - 537022.75, 188124.25, 537022.75, 188111.75, 537022.75, 187912.75, 537022.75, 188090.75, - 537022.75, 187937.25, 537022.75, 188148.25, 537022.75, 188159.25, 537022.75, 187968.25, - 537022.75, 187936.25, 537022.75, 188056.25, 537022.75, 188016.25, 537022.75, 188010.75, - 537022.75, 188155.75, 537022.75, 188106.25, 537022.75, 187962.75, 537022.75, 188056.75, - 537022.75, 188009.75, 537022.75, 188078.25, 537022.75, 188081.25, 537022.75, 188050.25, - 537022.75, 188075.25, 537022.75, 187946.25, 537022.75, 188030.25, 537022.75, 188011.75, - 537022.75, 188087.75, 537022.75, 188000.25, 537022.75, 187985.75, 537022.75, 188048.25, - 537022.75, 188149.75, 537022.75, 188125.25, 537022.75, 188065.75, 537022.75, 188105.25, - 537022.75, 188060.75, 537022.75, 187912.25, 537022.75, 188008.25, 537022.75, 187932.75, - 537022.75, 188078.75, 537022.75, 188069.25, 537022.75, 187970.75, 537022.75, 188058.25, - 537022.75, 188030.75, 537022.75, 187948.75, 537022.75, 187914.25, 537022.75, 187949.25, - 537022.75, 188031.25, 537022.75, 188108.75, 537022.75, 187921.75, 537022.75, 187935.75, - 537022.75, 187964.25, 537022.75, 188058.75, 537022.75, 188121.75, 537022.75, 187916.25, - 537022.75, 187937.75, 537022.75, 188158.75, 537022.75, 188098.25, 537022.75, 188076.25, - 537022.75, 187914.75, 537022.75, 187950.75, 537022.75, 188032.25, 537022.75, 188096.25, - 537022.75, 187993.25, 537022.75, 188036.25, 537022.75, 187973.25, 537022.75, 188037.25, - 537022.75, 188031.75, 537023.25, 188031.75, 537023.25, 188032.25, 537023.25, 188071.25, - 537023.25, 188066.25, 537023.25, 188158.75, 537023.25, 188119.75, 537023.25, 187916.25, - 537023.25, 188031.25, 537023.25, 188032.75, 537023.25, 188030.75, 537023.25, 187946.75, - 537023.25, 187991.25, 537023.25, 188005.25, 537023.25, 188030.25, 537023.25, 187946.25, - 537023.25, 188050.25, 537023.25, 188029.75, 537023.25, 188016.25, 537023.25, 188007.75, - 537023.25, 187936.25, 537023.25, 188050.75, 537023.25, 187917.25, 537023.25, 188145.25, - 537023.25, 188098.75, 537023.25, 187967.75, 537023.25, 187990.75, 537023.25, 188120.25, - 537023.25, 187990.25, 537023.25, 188052.25, 537023.25, 188015.25, 537023.25, 187970.75, - 537023.25, 188070.25, 537023.25, 187919.25, 537023.25, 188089.25, 537023.25, 188009.25, - 537023.25, 187939.75, 537023.25, 188047.75, 537023.25, 188123.75, 537023.25, 188073.25, - 537023.25, 188149.25, 537023.25, 188117.75, 537023.25, 187947.75, 537023.25, 187934.75, - 537023.25, 188052.75, 537023.25, 188014.75, 537023.25, 187971.75, 537023.25, 188077.25, - 537023.25, 188034.25, 537023.25, 188053.25, 537023.25, 188064.25, 537023.25, 188053.75, - 537023.25, 188120.75, 537023.25, 187972.25, 537023.25, 187976.25, 537023.25, 188036.75, - 537023.25, 188100.25, 537023.25, 188157.75, 537023.25, 188143.75, 537023.25, 188156.25, - 537023.25, 187941.25, 537023.25, 187999.25, 537023.25, 188042.75, 537023.25, 188061.75, - 537023.25, 188019.25, 537023.25, 187932.25, 537023.25, 187983.75, 537023.25, 188054.75, - 537023.25, 188073.75, 537023.25, 188111.75, 537023.25, 187965.75, 537023.25, 188055.25, - 537023.25, 187913.25, 537023.25, 188019.75, 537023.25, 187937.25, 537023.25, 187987.75, - 537023.25, 188056.25, 537023.25, 188081.25, 537023.25, 188056.75, 537023.25, 188078.25, - 537023.25, 187912.75, 537023.25, 187938.75, 537023.25, 188148.25, 537023.25, 188151.75, - 537023.25, 187975.25, 537023.25, 187989.25, 537023.25, 188000.25, 537023.25, 188153.75, - 537023.25, 188105.25, 537023.25, 188021.25, 537023.25, 188008.25, 537023.25, 188058.25, - 537023.25, 187933.75, 537023.25, 187993.75, 537023.25, 188035.75, 537023.25, 188080.75, - 537023.25, 188041.25, 537023.25, 188012.25, 537023.25, 187911.75, 537023.25, 187973.75, - 537023.25, 187949.25, 537023.25, 187921.75, 537023.25, 187964.25, 537023.25, 188058.75, - 537023.25, 187937.75, 537023.25, 188076.25, 537023.25, 188059.25, 537023.25, 188121.75, - 537023.25, 187914.75, 537023.25, 187973.25, 537023.25, 188036.25, 537023.75, 188151.75, - 537023.75, 188142.25, 537023.75, 187985.25, 537023.75, 187914.75, 537023.75, 187949.25, - 537023.75, 188012.25, 537023.75, 187937.75, 537023.75, 187965.75, 537023.75, 188069.25, - 537023.75, 187923.75, 537023.75, 188141.25, 537023.75, 187934.25, 537023.75, 187911.75, - 537023.75, 188060.25, 537023.75, 188011.75, 537023.75, 188013.25, 537023.75, 188068.75, - 537023.75, 187933.75, 537023.75, 188159.25, 537023.75, 188100.75, 537023.75, 188060.75, - 537023.75, 188014.25, 537023.75, 188151.25, 537023.75, 187962.25, 537023.75, 188057.75, - 537023.75, 188086.75, 537023.75, 187988.75, 537023.75, 187948.75, 537023.75, 188014.75, - 537023.75, 187945.75, 537023.75, 188125.25, 537023.75, 188144.75, 537023.75, 188075.75, - 537023.75, 188057.25, 537023.75, 187919.25, 537023.75, 188070.75, 537023.75, 188120.25, - 537023.75, 188008.75, 537023.75, 188079.25, 537023.75, 187962.75, 537023.75, 188000.25, - 537023.75, 188147.25, 537023.75, 187918.25, 537023.75, 188061.25, 537023.75, 188056.75, - 537023.75, 188074.25, 537023.75, 187913.25, 537023.75, 188059.75, 537023.75, 188146.75, - 537023.75, 187999.75, 537023.75, 188031.75, 537023.75, 188124.25, 537023.75, 187963.75, - 537023.75, 188119.75, 537023.75, 188148.75, 537023.75, 188142.75, 537023.75, 188100.25, - 537023.75, 187935.25, 537023.75, 188030.75, 537023.75, 188104.25, 537023.75, 188065.75, - 537023.75, 188052.75, 537023.75, 188037.75, 537023.75, 188119.25, 537023.75, 187987.25, - 537023.75, 187921.25, 537023.75, 187971.75, 537023.75, 187968.75, 537023.75, 188009.25, - 537023.75, 188028.25, 537023.75, 188076.75, 537023.75, 188118.25, 537023.75, 188016.25, - 537023.75, 188155.75, 537023.75, 188106.25, 537023.75, 187918.75, 537023.75, 188029.75, - 537023.75, 187936.75, 537023.75, 188029.25, 537023.75, 188072.25, 537023.75, 187922.75, - 537023.75, 188050.75, 537023.75, 187911.25, 537023.75, 187930.25, 537023.75, 188051.25, - 537023.75, 188016.75, 537023.75, 188118.75, 537024.25, 188065.25, 537024.25, 187917.25, - 537024.25, 188142.25, 537024.25, 188051.25, 537024.25, 187968.25, 537024.25, 188079.75, - 537024.25, 187965.25, 537024.25, 188012.75, 537024.25, 188028.75, 537024.25, 188017.25, - 537024.25, 188038.25, 537024.25, 188101.25, 537024.25, 187922.75, 537024.25, 188072.25, - 537024.25, 188050.75, 537024.25, 187966.25, 537024.25, 188004.25, 537024.25, 188087.75, - 537024.25, 187944.25, 537024.25, 188076.75, 537024.25, 188071.75, 537024.25, 188118.25, - 537024.25, 187967.25, 537024.25, 187966.75, 537024.25, 188149.75, 537024.25, 188028.25, - 537024.25, 187968.75, 537024.25, 187963.25, 537024.25, 188030.25, 537024.25, 188119.25, - 537024.25, 187950.25, 537024.25, 187989.75, 537024.25, 187991.25, 537024.25, 187942.75, - 537024.25, 187929.25, 537024.25, 187935.25, 537024.25, 187912.25, 537024.25, 188104.25, - 537024.25, 188018.25, 537024.25, 188105.75, 537024.25, 188146.25, 537024.25, 188103.25, - 537024.25, 187986.25, 537024.25, 187931.25, 537024.25, 187949.75, 537024.25, 187999.75, - 537024.25, 188073.75, 537024.25, 187914.25, 537024.25, 188158.75, 537024.25, 188066.75, - 537024.25, 188010.25, 537024.25, 188037.25, 537024.25, 187937.25, 537024.25, 187987.75, - 537024.25, 187948.25, 537024.25, 188094.75, 537024.25, 188150.25, 537024.25, 188125.75, - 537024.25, 187915.75, 537024.25, 188010.75, 537024.25, 188148.25, 537024.25, 188048.25, - 537024.25, 187985.75, 537024.25, 188097.75, 537024.25, 188057.25, 537024.25, 188033.25, - 537024.25, 188075.25, 537024.25, 187917.75, 537024.25, 188106.75, 537024.25, 188075.75, - 537024.25, 188112.75, 537024.25, 188015.25, 537024.25, 188047.75, 537024.25, 188001.25, - 537024.25, 188021.25, 537024.25, 187948.75, 537024.25, 187930.75, 537024.25, 188125.25, - 537024.25, 188011.25, 537024.25, 188014.75, 537024.25, 187992.75, 537024.25, 188068.25, - 537024.25, 188159.25, 537024.25, 188078.75, 537024.25, 188068.75, 537024.25, 188008.25, - 537024.25, 187913.75, 537024.25, 187988.25, 537024.25, 188060.25, 537024.25, 188097.25, - 537024.25, 188124.75, 537024.25, 188000.75, 537024.25, 188069.25, 537024.25, 188143.25, - 537024.25, 187961.25, 537024.25, 188144.25, 537024.25, 188046.25, 537024.25, 188059.25, - 537024.25, 187935.75, 537024.25, 187915.25, 537024.75, 188028.25, 537024.75, 187910.75, - 537024.75, 188075.75, 537024.75, 188032.75, 537024.75, 188008.75, 537024.75, 188075.25, - 537024.75, 188124.75, 537024.75, 187946.25, 537024.75, 187914.25, 537024.75, 187988.25, - 537024.75, 188050.25, 537024.75, 188119.25, 537024.75, 188073.75, 537024.75, 188029.75, - 537024.75, 188047.75, 537024.75, 188125.25, 537024.75, 188051.25, 537024.75, 188028.75, - 537024.75, 188105.75, 537024.75, 187922.75, 537024.75, 187930.75, 537024.75, 188101.25, - 537024.75, 188009.25, 537024.75, 188073.25, 537024.75, 188079.75, 537024.75, 188072.75, - 537024.75, 188090.25, 537024.75, 187963.25, 537024.75, 187966.75, 537024.75, 188143.25, - 537024.75, 187967.75, 537024.75, 188072.25, 537024.75, 188052.75, 537024.75, 187968.25, - 537024.75, 188103.25, 537024.75, 187913.25, 537024.75, 188142.25, 537024.75, 188026.75, - 537024.75, 187957.25, 537024.75, 188125.75, 537024.75, 188071.75, 537024.75, 187999.75, - 537024.75, 187968.75, 537024.75, 188047.25, 537024.75, 188124.25, 537024.75, 188055.25, - 537024.75, 187948.25, 537024.75, 188160.25, 537024.75, 188148.25, 537024.75, 188046.75, - 537024.75, 188010.75, 537024.75, 188106.75, 537024.75, 188087.25, 537024.75, 187969.25, - 537024.75, 187913.75, 537024.75, 188046.25, 537024.75, 188159.75, 537024.75, 187948.75, - 537024.75, 187993.75, 537024.75, 187933.75, 537024.75, 188000.75, 537024.75, 187964.25, - 537024.75, 187923.75, 537024.75, 188151.75, 537024.75, 188059.75, 537024.75, 187949.25, - 537024.75, 187965.75, 537024.75, 188012.75, 537024.75, 187992.75, 537024.75, 187935.75, - 537024.75, 188144.25, 537024.75, 188078.75, 537024.75, 188013.25, 537024.75, 187917.75, - 537024.75, 188061.25, 537024.75, 188104.25, 537024.75, 188005.75, 537024.75, 188013.75, - 537024.75, 187926.25, 537024.75, 188068.25, 537024.75, 187985.75, 537024.75, 188150.25, - 537024.75, 188145.75, 537024.75, 188037.25, 537024.75, 188137.25, 537024.75, 187916.75, - 537024.75, 188017.25, 537024.75, 188065.25, 537024.75, 187915.25, 537024.75, 188016.25, - 537024.75, 188004.75, 537024.75, 187921.25, 537024.75, 188126.25, 537024.75, 188158.75, - 537024.75, 188038.25, 537024.75, 188139.25, 537024.75, 188066.25, 537024.75, 187944.25, - 537024.75, 187958.75, 537025.25, 188104.75, 537025.25, 187931.75, 537025.25, 188097.75, - 537025.25, 187950.75, 537025.25, 188008.75, 537025.25, 187986.75, 537025.25, 187940.75, - 537025.25, 188150.25, 537025.25, 188048.75, 537025.25, 188037.75, 537025.25, 187931.25, - 537025.25, 187934.25, 537025.25, 187936.25, 537025.25, 187911.25, 537025.25, 187988.75, - 537025.25, 188080.25, 537025.25, 188119.75, 537025.25, 188016.75, 537025.25, 188033.75, - 537025.25, 188067.25, 537025.25, 188067.75, 537025.25, 188120.25, 537025.25, 188044.75, - 537025.25, 188149.75, 537025.25, 188029.25, 537025.25, 187916.75, 537025.25, 188051.25, - 537025.25, 188125.25, 537025.25, 187934.75, 537025.25, 188159.25, 537025.25, 187991.75, - 537025.25, 188068.25, 537025.25, 188009.25, 537025.25, 188072.75, 537025.25, 187930.25, - 537025.25, 188157.75, 537025.25, 188002.75, 537025.25, 188146.75, 537025.25, 188091.75, - 537025.25, 188034.25, 537025.25, 187949.75, 537025.25, 188096.75, 537025.25, 188027.25, - 537025.25, 187913.25, 537025.25, 187962.25, 537025.25, 187937.25, 537025.25, 188026.75, - 537025.25, 188088.75, 537025.25, 188106.25, 537025.25, 188045.75, 537025.25, 187999.75, - 537025.25, 188071.75, 537025.25, 188001.25, 537025.25, 188034.75, 537025.25, 187990.25, - 537025.25, 187961.75, 537025.25, 187912.75, 537025.25, 188047.25, 537025.25, 188101.25, - 537025.25, 188113.25, 537025.25, 188012.25, 537025.25, 187949.25, 537025.25, 188148.25, - 537025.25, 188156.75, 537025.25, 188036.25, 537025.25, 187914.75, 537025.25, 188099.25, - 537025.25, 188079.25, 537025.25, 187948.75, 537025.25, 188011.25, 537025.25, 187920.25, - 537025.25, 188107.25, 537025.75, 187920.25, 537025.75, 188000.75, 537025.75, 187938.25, - 537025.75, 188147.75, 537025.75, 187933.75, 537025.75, 188069.75, 537025.75, 188092.25, - 537025.75, 188011.25, 537025.75, 188070.75, 537025.75, 188080.75, 537025.75, 188092.75, - 537025.75, 187948.75, 537025.75, 188079.25, 537025.75, 187929.75, 537025.75, 187913.75, - 537025.75, 187987.25, 537025.75, 188154.25, 537025.75, 187915.75, 537025.75, 188156.75, - 537025.75, 188121.75, 537025.75, 187945.25, 537025.75, 188071.25, 537025.75, 188101.25, - 537025.75, 187911.75, 537025.75, 187938.75, 537025.75, 187916.25, 537025.75, 188124.25, - 537025.75, 187963.75, 537025.75, 187912.75, 537025.75, 188025.25, 537025.75, 188084.25, - 537025.75, 187923.25, 537025.75, 188010.25, 537025.75, 188107.75, 537025.75, 188068.75, - 537025.75, 188001.75, 537025.75, 188045.75, 537025.75, 188026.25, 537025.75, 188102.25, - 537025.75, 187966.25, 537025.75, 188019.75, 537025.75, 188091.25, 537025.75, 188027.25, - 537025.75, 188120.75, 537025.75, 187937.25, 537025.75, 188072.25, 537025.75, 188088.75, - 537025.75, 187964.75, 537025.75, 187932.25, 537025.75, 187967.75, 537025.75, 188149.25, - 537025.75, 188099.75, 537025.75, 187990.75, 537025.75, 187989.25, 537025.75, 188052.25, - 537025.75, 188017.75, 537025.75, 188159.25, 537025.75, 188040.75, 537025.75, 188028.75, - 537025.75, 188142.75, 537025.75, 188051.75, 537025.75, 188105.75, 537025.75, 187950.25, - 537025.75, 188158.25, 537025.75, 188118.75, 537025.75, 187936.75, 537025.75, 188125.25, - 537025.75, 187965.25, 537025.75, 188044.75, 537025.75, 187917.25, 537025.75, 187912.25, - 537025.75, 188120.25, 537025.75, 188090.25, 537025.75, 187988.25, 537025.75, 188050.25, - 537025.75, 188049.75, 537025.75, 187971.25, 537025.75, 188144.75, 537025.75, 187991.25, - 537025.75, 188049.25, 537025.75, 188089.75, 537025.75, 188066.75, 537025.75, 188065.75, - 537025.75, 188126.25, 537025.75, 188090.75, 537025.75, 187950.75, 537025.75, 188032.75, - 537025.75, 187986.25, 537026.25, 188101.25, 537026.25, 188090.25, 537026.25, 187964.75, - 537026.25, 187937.25, 537026.25, 188091.25, 537026.25, 188088.25, 537026.25, 188158.25, - 537026.25, 188112.25, 537026.25, 188008.25, 537026.25, 187959.75, 537026.25, 188095.75, - 537026.25, 188048.75, 537026.25, 188145.75, 537026.25, 187917.75, 537026.25, 187929.25, - 537026.25, 188049.25, 537026.25, 188122.75, 537026.25, 188001.75, 537026.25, 188098.75, - 537026.25, 187936.75, 537026.25, 188017.25, 537026.25, 188125.25, 537026.25, 188105.75, - 537026.25, 187988.25, 537026.25, 188100.75, 537026.25, 187992.75, 537026.25, 187911.75, - 537026.25, 188044.75, 537026.25, 187917.25, 537026.25, 187949.25, 537026.25, 188093.25, - 537026.25, 187913.25, 537026.25, 187914.75, 537026.25, 187991.25, 537026.25, 188033.25, - 537026.25, 188142.25, 537026.25, 188089.25, 537026.25, 188065.75, 537026.25, 188158.75, - 537026.25, 187923.75, 537026.25, 187950.75, 537026.25, 187942.25, 537026.25, 188120.25, - 537026.25, 188066.25, 537026.25, 188081.25, 537026.25, 188000.75, 537026.25, 187931.75, - 537026.25, 187987.75, 537026.25, 187957.75, 537026.25, 188149.75, 537026.25, 188126.25, - 537026.25, 188080.75, 537026.25, 188159.25, 537026.25, 188108.25, 537026.25, 188010.25, - 537026.25, 187945.25, 537026.25, 188050.75, 537026.25, 187916.25, 537026.25, 188023.75, - 537026.25, 188118.75, 537026.25, 188024.25, 537026.25, 188092.25, 537026.25, 188047.75, - 537026.25, 187934.25, 537026.25, 188068.25, 537026.25, 188051.75, 537026.25, 187990.75, - 537026.25, 188034.75, 537026.25, 188071.25, 537026.25, 188102.25, 537026.25, 188148.75, - 537026.25, 187930.75, 537026.25, 188026.75, 537026.25, 187962.25, 537026.25, 188052.25, - 537026.25, 188042.75, 537026.25, 188010.75, 537026.25, 187965.75, 537026.25, 188079.75, - 537026.25, 188106.75, 537026.25, 188120.75, 537026.25, 188103.25, 537026.25, 188090.75, - 537026.25, 188070.25, 537026.25, 188099.25, 537026.25, 188156.25, 537026.25, 188123.75, - 537026.25, 188011.25, 537026.25, 187920.25, 537026.25, 187998.25, 537026.25, 188107.25, - 537026.75, 188034.25, 537026.75, 188120.25, 537026.75, 188048.25, 537026.75, 187992.25, - 537026.75, 187949.75, 537026.75, 188150.25, 537026.75, 187963.25, 537026.75, 188090.75, - 537026.75, 188087.75, 537026.75, 188061.25, 537026.75, 187989.75, 537026.75, 188122.75, - 537026.75, 187935.75, 537026.75, 187917.75, 537026.75, 187951.25, 537026.75, 188107.75, - 537026.75, 188043.25, 537026.75, 188089.75, 537026.75, 188069.25, 537026.75, 188075.75, - 537026.75, 187992.75, 537026.75, 188001.25, 537026.75, 188124.75, 537026.75, 187924.75, - 537026.75, 188119.75, 537026.75, 187989.25, 537026.75, 187912.75, 537026.75, 188038.75, - 537026.75, 188044.75, 537026.75, 188034.75, 537026.75, 188025.75, 537026.75, 187925.25, - 537026.75, 187987.75, 537026.75, 187962.25, 537026.75, 188103.75, 537026.75, 188025.25, - 537026.75, 188046.25, 537026.75, 187929.75, 537026.75, 188121.75, 537026.75, 188055.25, - 537026.75, 188051.75, 537026.75, 188049.75, 537026.75, 188124.25, 537026.75, 188061.75, - 537026.75, 187916.75, 537026.75, 188043.75, 537026.75, 187979.25, 537026.75, 187911.25, - 537026.75, 188035.25, 537026.75, 188123.25, 537026.75, 187978.75, 537026.75, 187991.25, - 537026.75, 188093.25, 537026.75, 188065.75, 537026.75, 187986.75, 537026.75, 187964.25, - 537026.75, 188023.75, 537026.75, 188125.75, 537026.75, 188067.75, 537026.75, 188023.25, - 537026.75, 188144.75, 537026.75, 188119.25, 537026.75, 188081.25, 537026.75, 188108.25, - 537026.75, 187935.25, 537026.75, 188131.25, 537026.75, 188086.75, 537026.75, 188080.25, - 537026.75, 188046.75, 537026.75, 188149.75, 537026.75, 188010.25, 537026.75, 188067.25, - 537026.75, 187938.25, 537026.75, 187912.25, 537026.75, 188126.25, 537027.25, 188159.25, - 537027.25, 187934.25, 537027.25, 188067.25, 537027.25, 188080.25, 537027.25, 188066.75, - 537027.25, 188086.75, 537027.25, 188114.25, 537027.25, 188080.75, 537027.25, 188030.25, - 537027.25, 188108.25, 537027.25, 187918.25, 537027.25, 188081.25, 537027.25, 188067.75, - 537027.25, 187987.25, 537027.25, 188023.75, 537027.25, 187979.25, 537027.25, 188036.25, - 537027.25, 188066.25, 537027.25, 188125.75, 537027.25, 188022.75, 537027.25, 188024.25, - 537027.25, 188104.75, 537027.25, 187932.75, 537027.25, 188050.25, 537027.25, 188051.25, - 537027.25, 188092.75, 537027.25, 187993.25, 537027.25, 188123.25, 537027.25, 188022.25, - 537027.25, 188016.25, 537027.25, 188089.75, 537027.25, 187938.75, 537027.25, 188047.25, - 537027.25, 188021.75, 537027.25, 188081.75, 537027.25, 188049.75, 537027.25, 188095.25, - 537027.25, 188005.75, 537027.25, 187994.75, 537027.25, 187925.75, 537027.25, 187989.75, - 537027.25, 188047.75, 537027.25, 188046.25, 537027.25, 188126.75, 537027.25, 187937.75, - 537027.25, 188044.75, 537027.25, 188088.25, 537027.25, 188121.25, 537027.25, 187920.75, - 537027.25, 188013.75, 537027.25, 188068.75, 537027.25, 187955.25, 537027.25, 188099.75, - 537027.25, 188119.75, 537027.25, 188065.25, 537027.25, 188060.75, 537027.25, 188034.75, - 537027.25, 187963.75, 537027.25, 187924.75, 537027.25, 187989.25, 537027.25, 188028.75, - 537027.25, 187991.75, 537027.25, 188001.25, 537027.25, 187980.25, 537027.25, 188069.25, - 537027.25, 188041.25, 537027.25, 188064.75, 537027.25, 187977.25, 537027.25, 188098.75, - 537027.25, 188160.25, 537027.25, 187965.25, 537027.25, 187946.25, 537027.25, 187988.75, - 537027.25, 188087.75, 537027.25, 188107.75, 537027.25, 187935.75, 537027.25, 188122.25, - 537027.25, 187939.25, 537027.25, 188045.75, 537027.25, 187950.25, 537027.25, 188002.25, - 537027.25, 188105.25, 537027.25, 188094.25, 537027.25, 187910.75, 537027.25, 187922.25, - 537027.25, 188062.25, 537027.25, 188003.25, 537027.25, 187978.75, 537027.25, 188127.25, - 537027.25, 188043.25, 537027.25, 187954.75, 537027.25, 187951.75, 537027.25, 187992.25, - 537027.25, 187949.75, 537027.25, 188034.25, 537027.25, 188090.25, 537027.25, 187937.25, - 537027.25, 188061.75, 537027.25, 188069.75, 537027.25, 188123.75, 537027.25, 187916.75, - 537027.75, 188061.75, 537027.75, 187964.75, 537027.75, 187937.25, 537027.75, 187940.75, - 537027.75, 187949.75, 537027.75, 187932.25, 537027.75, 187978.25, 537027.75, 188105.25, - 537027.75, 187992.25, 537027.75, 188048.25, 537027.75, 188087.75, 537027.75, 188041.25, - 537027.75, 187946.25, 537027.75, 187914.25, 537027.75, 187989.25, 537027.75, 188119.75, - 537027.75, 188081.75, 537027.75, 187920.75, 537027.75, 188049.75, 537027.75, 188125.75, - 537027.75, 188120.25, 537027.75, 188007.25, 537027.75, 188050.75, 537027.75, 188042.75, - 537027.75, 187935.25, 537027.75, 187992.75, 537027.75, 187916.25, 537027.75, 187950.25, - 537027.75, 188095.75, 537027.75, 188122.75, 537027.75, 188047.75, 537027.75, 187979.75, - 537027.75, 188061.25, 537027.75, 187977.25, 537027.75, 188034.25, 537027.75, 188159.75, - 537027.75, 188001.75, 537027.75, 187998.25, 537027.75, 187930.25, 537027.75, 187920.25, - 537027.75, 188012.25, 537027.75, 187987.25, 537027.75, 187965.75, 537027.75, 188001.25, - 537027.75, 187990.25, 537027.75, 187955.75, 537027.75, 187924.75, 537027.75, 187955.25, - 537027.75, 188145.25, 537027.75, 188039.25, 537027.75, 188096.25, 537027.75, 188065.25, - 537027.75, 188107.75, 537027.75, 187951.25, 537027.75, 188034.75, 537027.75, 188046.25, - 537027.75, 188069.25, 537027.75, 187963.75, 537027.75, 188088.25, 537027.75, 188099.75, - 537027.75, 188026.25, 537027.75, 188126.75, 537027.75, 188121.75, 537027.75, 188068.75, - 537027.75, 187999.75, 537027.75, 188158.75, 537027.75, 187990.75, 537027.75, 188022.25, - 537027.75, 188114.25, 537027.75, 187994.75, 537027.75, 187931.25, 537027.75, 188068.25, - 537027.75, 188043.75, 537027.75, 187916.75, 537027.75, 188092.75, 537027.75, 188047.25, - 537027.75, 187938.75, 537027.75, 187918.25, 537027.75, 188080.75, 537027.75, 188067.75, - 537027.75, 188023.75, 537027.75, 188022.75, 537027.75, 188123.25, 537027.75, 188086.75, - 537027.75, 187936.25, 537027.75, 188023.25, 537027.75, 188079.25, 537027.75, 188108.75, - 537027.75, 187934.25, 537027.75, 188066.75, 537028.25, 187977.75, 537028.25, 188081.25, - 537028.25, 188041.25, 537028.25, 188049.25, 537028.25, 188105.75, 537028.25, 188097.75, - 537028.25, 188121.75, 537028.25, 188041.75, 537028.25, 187988.25, 537028.25, 188062.25, - 537028.25, 188097.25, 537028.25, 187964.25, 537028.25, 188036.25, 537028.25, 188003.25, - 537028.25, 188045.75, 537028.25, 187992.75, 537028.25, 188067.25, 537028.25, 188035.75, - 537028.25, 188126.25, 537028.25, 187950.75, 537028.25, 188040.25, 537028.25, 188119.75, - 537028.25, 187989.75, 537028.25, 188046.75, 537028.25, 188067.75, 537028.25, 187952.25, - 537028.25, 188022.75, 537028.25, 188148.25, 537028.25, 188049.75, 537028.25, 188127.75, - 537028.25, 188014.75, 537028.25, 187925.75, 537028.25, 188108.25, 537028.25, 187992.25, - 537028.25, 187938.75, 537028.25, 188044.75, 537028.25, 187996.25, 537028.25, 188094.75, - 537028.25, 187975.75, 537028.25, 187997.75, 537028.25, 187950.25, 537028.25, 187979.25, - 537028.25, 187953.75, 537028.25, 188138.25, 537028.25, 188000.25, 537028.25, 187917.75, - 537028.25, 188094.25, 537028.25, 188004.75, 537028.25, 188043.75, 537028.25, 188080.75, - 537028.25, 187977.25, 537028.25, 188089.25, 537028.25, 188064.75, 537028.25, 188043.25, - 537028.25, 187993.25, 537028.25, 188038.75, 537028.25, 188095.75, 537028.25, 187999.75, - 537028.25, 188026.25, 537028.25, 188016.75, 537028.25, 188103.75, 537028.25, 187937.75, - 537028.25, 187995.25, 537028.25, 187963.75, 537028.25, 188020.25, 537028.25, 188001.75, - 537028.25, 188113.25, 537028.25, 188107.25, 537028.25, 187980.75, 537028.25, 188120.75, - 537028.25, 188027.25, 537028.25, 187954.25, 537028.25, 188069.75, 537028.25, 188045.25, - 537028.25, 188095.25, 537028.25, 187936.75, 537028.25, 188021.25, 537028.75, 187926.25, - 537028.75, 188098.25, 537028.75, 188020.75, 537028.75, 188045.25, 537028.75, 188099.25, - 537028.75, 187939.25, 537028.75, 187990.25, 537028.75, 188102.75, 537028.75, 188069.75, - 537028.75, 187998.75, 537028.75, 188078.75, 537028.75, 188039.25, 537028.75, 188006.75, - 537028.75, 187911.75, 537028.75, 187976.25, 537028.75, 188132.25, 537028.75, 188122.25, - 537028.75, 188120.75, 537028.75, 188096.75, 537028.75, 188107.25, 537028.75, 188013.25, - 537028.75, 188102.25, 537028.75, 188027.75, 537028.75, 188143.75, 537028.75, 188098.75, - 537028.75, 187998.25, 537028.75, 188070.25, 537028.75, 187951.75, 537028.75, 187995.25, - 537028.75, 188094.25, 537028.75, 188095.75, 537028.75, 188021.75, 537028.75, 188070.75, - 537028.75, 188038.75, 537028.75, 188068.75, 537028.75, 188101.75, 537028.75, 188025.75, - 537028.75, 187939.75, 537028.75, 187918.75, 537028.75, 187995.75, 537028.75, 188025.25, - 537028.75, 187991.25, 537028.75, 188036.75, 537028.75, 187987.75, 537028.75, 188065.75, - 537028.75, 188002.25, 537028.75, 188051.75, 537028.75, 188055.75, 537028.75, 188037.75, - 537028.75, 187994.75, 537028.75, 188037.25, 537028.75, 187975.75, 537028.75, 187956.75, - 537028.75, 188064.25, 537028.75, 188003.75, 537028.75, 188042.75, 537028.75, 187996.25, - 537028.75, 188127.75, 537028.75, 188030.75, 537028.75, 188106.25, 537028.75, 188063.25, - 537028.75, 188050.25, 537028.75, 188082.75, 537028.75, 188062.75, 537028.75, 187925.75, - 537028.75, 187938.75, 537028.75, 187946.75, 537028.75, 188066.25, 537028.75, 187952.25, - 537028.75, 188109.25, 537028.75, 187923.75, 537028.75, 188115.25, 537028.75, 188035.75, - 537028.75, 188015.25, 537028.75, 188090.75, 537028.75, 187921.75, 537028.75, 187936.25, - 537028.75, 188120.25, 537028.75, 187938.25, 537028.75, 188009.25, 537028.75, 188040.75, - 537028.75, 188044.25, 537028.75, 187993.75, 537028.75, 187926.75, 537028.75, 188082.25, - 537028.75, 187931.75, 537028.75, 187979.25, 537028.75, 187952.75, 537028.75, 188048.25, - 537028.75, 188087.75, 537028.75, 188074.75, 537028.75, 188003.25, 537028.75, 188127.25, - 537028.75, 188000.75, 537028.75, 188062.25, 537028.75, 188019.75, 537028.75, 188049.25, - 537028.75, 188036.25, 537028.75, 187988.75, 537028.75, 188018.75, 537028.75, 188048.75, - 537028.75, 188076.75, 537028.75, 188002.75, 537028.75, 187978.75, 537028.75, 187996.75, - 537028.75, 188055.25, 537029.25, 187926.75, 537029.25, 188120.25, 537029.25, 187920.75, - 537029.25, 187979.25, 537029.25, 188048.25, 537029.25, 188128.25, 537029.25, 188035.25, - 537029.25, 188035.75, 537029.25, 188009.25, 537029.25, 187922.25, 537029.25, 187952.25, - 537029.25, 187978.75, 537029.25, 188142.25, 537029.25, 187994.75, 537029.25, 187979.75, - 537029.25, 187978.25, 537029.25, 188048.75, 537029.25, 188049.25, 537029.25, 188050.25, - 537029.25, 187995.25, 537029.25, 187993.75, 537029.25, 187925.75, 537029.25, 188010.75, - 537029.25, 188047.75, 537029.25, 187996.25, 537029.25, 188036.25, 537029.25, 187996.75, - 537029.25, 188031.75, 537029.25, 187976.25, 537029.25, 188102.75, 537029.25, 188036.75, - 537029.25, 187939.25, 537029.25, 187988.25, 537029.25, 188082.25, 537029.25, 188096.75, - 537029.25, 188106.25, 537029.25, 187956.25, 537029.25, 187975.75, 537029.25, 188041.75, - 537029.25, 187932.75, 537029.25, 187938.75, 537029.25, 188097.25, 537029.25, 188037.25, - 537029.25, 188127.25, 537029.25, 187998.25, 537029.25, 187974.25, 537029.25, 188027.75, - 537029.25, 187938.25, 537029.25, 188132.25, 537029.25, 188126.75, 537029.25, 188099.75, - 537029.25, 187951.25, 537029.25, 188070.75, 537029.25, 187991.25, 537029.25, 188025.25, - 537029.25, 188113.75, 537029.25, 188094.25, 537029.25, 188038.25, 537029.25, 188000.75, - 537029.25, 188038.75, 537029.25, 188122.25, 537029.25, 187924.25, 537029.25, 188107.25, - 537029.25, 188069.75, 537029.25, 188021.25, 537029.25, 187955.25, 537029.25, 188081.25, - 537029.25, 188062.75, 537029.25, 187985.75, 537029.25, 187943.25, 537029.25, 188020.75, - 537029.25, 188001.75, 537029.25, 188043.25, 537029.25, 188020.25, 537029.25, 187917.75, - 537029.25, 188123.25, 537029.25, 188064.25, 537029.25, 188045.25, 537029.25, 188005.25, - 537029.25, 187920.25, 537029.25, 188107.75, 537029.25, 188002.25, 537029.25, 188077.25, - 537029.25, 188019.75, 537029.25, 188064.75, 537029.25, 188019.25, 537029.25, 188002.75, - 537029.25, 188018.75, 537029.25, 188068.25, 537029.25, 188067.25, 537029.25, 188003.25, - 537029.25, 188109.75, 537029.25, 188039.75, 537029.25, 187942.25, 537029.25, 188081.75, - 537029.25, 187936.25, 537029.25, 188098.75, 537029.25, 187917.25, 537029.25, 188108.75, - 537029.25, 188145.25, 537029.25, 188065.75, 537029.25, 188044.25, 537029.75, 187974.75, - 537029.75, 188062.25, 537029.75, 187910.75, 537029.75, 187979.25, 537029.75, 187920.75, - 537029.75, 188048.25, 537029.75, 187952.75, 537029.75, 188087.75, 537029.75, 188076.25, - 537029.75, 187913.25, 537029.75, 187954.25, 537029.75, 187994.25, 537029.75, 187952.25, - 537029.75, 188109.25, 537029.75, 187978.75, 537029.75, 188035.25, 537029.75, 188048.75, - 537029.75, 187940.25, 537029.75, 187995.75, 537029.75, 187977.25, 537029.75, 187956.75, - 537029.75, 188072.25, 537029.75, 188127.75, 537029.75, 187988.25, 537029.75, 188129.75, - 537029.75, 187993.25, 537029.75, 188120.75, 537029.75, 188081.75, 537029.75, 188052.75, - 537029.75, 187951.75, 537029.75, 188109.75, 537029.75, 188017.75, 537029.75, 187939.25, - 537029.75, 188018.25, 537029.75, 188106.25, 537029.75, 188089.75, 537029.75, 188003.25, - 537029.75, 187935.25, 537029.75, 188055.75, 537029.75, 188042.25, 537029.75, 187919.75, - 537029.75, 188115.75, 537029.75, 188097.25, 537029.75, 187947.25, 537029.75, 187918.75, - 537029.75, 188012.25, 537029.75, 187998.25, 537029.75, 188160.25, 537029.75, 188002.75, - 537029.75, 188071.25, 537029.75, 187974.25, 537029.75, 187998.75, 537029.75, 188127.25, - 537029.75, 188046.75, 537029.75, 188095.25, 537029.75, 188041.25, 537029.75, 187999.25, - 537029.75, 188026.75, 537029.75, 188019.75, 537029.75, 188123.25, 537029.75, 188064.75, - 537029.75, 187999.75, 537029.75, 188068.75, 537029.75, 188037.75, 537029.75, 187989.25, - 537029.75, 188082.75, 537029.75, 188099.25, 537029.75, 188095.75, 537029.75, 187917.75, - 537029.75, 187926.25, 537029.75, 188063.75, 537029.75, 188103.75, 537029.75, 188020.25, - 537029.75, 188000.25, 537029.75, 188063.25, 537029.75, 188121.75, 537029.75, 187918.25, - 537029.75, 188046.25, 537029.75, 188097.75, 537029.75, 187942.75, 537029.75, 187990.75, - 537029.75, 188107.25, 537029.75, 187914.75, 537029.75, 188021.75, 537029.75, 188069.75, - 537029.75, 187943.25, 537030.25, 188017.25, 537030.25, 187988.75, 537030.25, 187955.25, - 537030.25, 188004.25, 537030.25, 188035.75, 537030.25, 188076.75, 537030.25, 187989.75, - 537030.25, 187943.25, 537030.25, 188109.25, 537030.25, 188045.75, 537030.25, 188021.75, - 537030.25, 188001.25, 537030.25, 188104.75, 537030.25, 188020.75, 537030.25, 187994.75, - 537030.25, 187937.25, 537030.25, 188007.75, 537030.25, 188038.75, 537030.25, 188040.25, - 537030.25, 188061.75, 537030.25, 187920.75, 537030.25, 187977.75, 537030.25, 188105.25, - 537030.25, 188022.75, 537030.25, 188042.75, 537030.25, 187957.25, 537030.25, 188083.25, - 537030.25, 187945.75, 537030.25, 188100.75, 537030.25, 188105.75, 537030.25, 188070.25, - 537030.25, 188085.75, 537030.25, 187993.75, 537030.25, 188060.75, 537030.25, 188046.25, - 537030.25, 187990.25, 537030.25, 188052.25, 537030.25, 188063.25, 537030.25, 187939.75, - 537030.25, 188121.75, 537030.25, 188036.25, 537030.25, 187948.25, 537030.25, 188124.25, - 537030.25, 188090.25, 537030.25, 188043.75, 537030.25, 188103.75, 537030.25, 188082.25, - 537030.25, 187919.25, 537030.25, 188122.75, 537030.25, 187991.25, 537030.25, 187956.75, - 537030.25, 188070.75, 537030.25, 187977.25, 537030.25, 188098.75, 537030.25, 188129.75, - 537030.25, 188017.75, 537030.25, 188003.75, 537030.25, 188068.75, 537030.25, 188052.75, - 537030.25, 188046.75, 537030.25, 188110.25, 537030.25, 187976.75, 537030.25, 188117.75, - 537030.25, 188125.75, 537030.25, 188098.25, 537030.25, 187941.25, 537030.25, 187942.25, - 537030.25, 188071.25, 537030.25, 188130.25, 537030.25, 187951.75, 537030.25, 187998.75, - 537030.25, 187914.25, 537030.25, 188097.25, 537030.25, 187992.75, 537030.25, 188121.25, - 537030.25, 188016.25, 537030.25, 188106.75, 537030.25, 187924.75, 537030.25, 187998.25, - 537030.25, 188123.25, 537030.25, 188102.25, 537030.25, 188011.75, 537030.25, 187918.75, - 537030.25, 188003.25, 537030.25, 188102.75, 537030.25, 187975.75, 537030.25, 188018.75, - 537030.25, 187927.25, 537030.25, 188115.75, 537030.25, 187936.75, 537030.25, 187953.25, - 537030.25, 187997.75, 537030.75, 187975.25, 537030.75, 188018.75, 537030.75, 187953.25, - 537030.75, 187927.25, 537030.75, 188104.75, 537030.75, 187971.25, 537030.75, 187919.75, - 537030.75, 188102.75, 537030.75, 188057.25, 537030.75, 187942.25, 537030.75, 188003.25, - 537030.75, 188115.25, 537030.75, 187956.25, 537030.75, 187998.25, 537030.75, 188002.75, - 537030.75, 188044.25, 537030.75, 188016.75, 537030.75, 187992.75, 537030.75, 187924.75, - 537030.75, 187939.25, 537030.75, 187974.25, 537030.75, 188106.25, 537030.75, 188081.75, - 537030.75, 187951.75, 537030.75, 188027.25, 537030.75, 188016.25, 537030.75, 188121.25, - 537030.75, 187921.25, 537030.75, 187981.75, 537030.75, 188109.75, 537030.75, 188130.25, - 537030.75, 187976.25, 537030.75, 188087.25, 537030.75, 187938.25, 537030.75, 187971.75, - 537030.75, 188127.25, 537030.75, 188007.25, 537030.75, 187943.75, 537030.75, 187999.25, - 537030.75, 188046.75, 537030.75, 187916.75, 537030.75, 188041.25, 537030.75, 188121.75, - 537030.75, 188129.75, 537030.75, 188098.75, 537030.75, 187996.75, 537030.75, 187930.25, - 537030.75, 188098.25, 537030.75, 188097.25, 537030.75, 188101.75, 537030.75, 187939.75, - 537030.75, 188108.75, 537030.75, 187925.25, 537030.75, 187989.25, 537030.75, 188017.75, - 537030.75, 188103.75, 537030.75, 187990.25, 537030.75, 188082.25, 537030.75, 188123.75, - 537030.75, 187948.25, 537030.75, 188070.75, 537030.75, 188125.75, 537030.75, 187942.75, - 537030.75, 187918.25, 537030.75, 188052.25, 537030.75, 187915.75, 537030.75, 187993.75, - 537030.75, 188046.25, 537030.75, 188034.25, 537030.75, 188038.25, 537030.75, 188070.25, - 537030.75, 187940.25, 537030.75, 188036.25, 537030.75, 187977.75, 537030.75, 188074.75, - 537030.75, 187995.25, 537030.75, 187950.25, 537030.75, 188010.25, 537030.75, 188083.25, - 537030.75, 187957.25, 537030.75, 188061.25, 537030.75, 188126.25, 537030.75, 188061.75, - 537030.75, 188128.75, 537030.75, 188100.25, 537030.75, 188022.75, 537030.75, 188038.75, - 537030.75, 188105.25, 537030.75, 188035.25, 537030.75, 188022.25, 537030.75, 188122.75, - 537030.75, 188020.75, 537030.75, 188069.75, 537030.75, 187937.25, 537030.75, 188042.75, - 537030.75, 188109.25, 537030.75, 188040.25, 537030.75, 188062.25, 537030.75, 188017.25, - 537030.75, 188063.25, 537030.75, 187989.75, 537030.75, 188004.25, 537030.75, 187953.75, - 537030.75, 188095.75, 537030.75, 188037.75, 537031.25, 187920.25, 537031.25, 188022.75, - 537031.25, 188128.25, 537031.25, 187994.25, 537031.25, 188009.25, 537031.25, 187952.75, - 537031.25, 188105.25, 537031.25, 187952.25, 537031.25, 188075.25, 537031.25, 188072.25, - 537031.25, 187922.75, 537031.25, 188071.75, 537031.25, 188124.75, 537031.25, 188070.25, - 537031.25, 188090.25, 537031.25, 187943.25, 537031.25, 187919.25, 537031.25, 187939.75, - 537031.25, 187953.75, 537031.25, 188014.75, 537031.25, 188031.75, 537031.25, 187941.25, - 537031.25, 187926.25, 537031.25, 188015.75, 537031.25, 187993.25, 537031.25, 188121.25, - 537031.25, 188004.75, 537031.25, 187915.25, 537031.25, 187997.25, 537031.25, 188103.25, - 537031.25, 188067.25, 537031.25, 187970.75, 537031.25, 188017.25, 537031.25, 187976.25, - 537031.25, 188116.75, 537031.25, 188089.75, 537031.25, 187989.75, 537031.25, 187975.75, - 537031.25, 188004.25, 537031.25, 188056.25, 537031.25, 188047.25, 537031.25, 188057.25, - 537031.25, 188109.25, 537031.25, 188037.25, 537031.25, 188100.25, 537031.25, 188131.75, - 537031.25, 188109.75, 537031.25, 187992.25, 537031.25, 188039.75, 537031.25, 188132.25, - 537031.25, 187971.75, 537031.25, 188020.25, 537031.25, 188046.75, 537031.25, 188101.75, - 537031.25, 188037.75, 537031.25, 188002.25, 537031.25, 187972.25, 537031.25, 188126.75, - 537031.25, 188020.75, 537031.25, 188059.75, 537031.25, 188122.25, 537031.25, 188103.75, - 537031.25, 188022.25, 537031.25, 188042.75, 537031.25, 187941.75, 537031.25, 188060.25, - 537031.25, 188046.25, 537031.25, 188061.75, 537031.25, 188061.25, 537031.25, 188083.25, - 537031.75, 187948.75, 537031.75, 188133.75, 537031.75, 188060.75, 537031.75, 188126.25, - 537031.75, 188133.25, 537031.75, 187944.25, 537031.75, 188101.25, 537031.75, 187991.25, - 537031.75, 188083.75, 537031.75, 187972.75, 537031.75, 188026.25, 537031.75, 187914.75, - 537031.75, 188021.75, 537031.75, 188111.25, 537031.75, 188001.25, 537031.75, 188122.75, - 537031.75, 187999.75, 537031.75, 188089.25, 537031.75, 188082.75, 537031.75, 188091.25, - 537031.75, 188110.75, 537031.75, 187920.25, 537031.75, 188002.25, 537031.75, 188103.75, - 537031.75, 188037.75, 537031.75, 188059.25, 537031.75, 188110.25, 537031.75, 188058.75, - 537031.75, 187971.25, 537031.75, 187923.75, 537031.75, 188018.25, 537031.75, 188098.75, - 537031.75, 188058.25, 537031.75, 188003.75, 537031.75, 187911.25, 537031.75, 188131.75, - 537031.75, 187954.25, 537031.75, 188040.25, 537031.75, 187994.25, 537031.75, 188109.25, - 537031.75, 187997.75, 537031.75, 187956.25, 537031.75, 188031.25, 537031.75, 187983.25, - 537031.75, 187914.25, 537031.75, 187944.75, 537031.75, 188016.75, 537031.75, 188123.25, - 537031.75, 188036.75, 537031.75, 188016.25, 537031.75, 188005.25, 537031.75, 188107.75, - 537031.75, 188054.25, 537031.75, 188125.25, 537031.75, 188031.75, 537031.75, 187970.25, - 537031.75, 188015.25, 537031.75, 188069.75, 537031.75, 188032.75, 537031.75, 187916.75, - 537031.75, 187939.75, 537031.75, 188014.25, 537031.75, 188082.25, 537031.75, 188090.25, - 537031.75, 188071.25, 537031.75, 188099.75, 537031.75, 187996.25, 537031.75, 188047.75, - 537031.75, 188041.75, 537031.75, 187953.25, 537031.75, 187969.25, 537031.75, 188072.25, - 537031.75, 187993.75, 537031.75, 188102.25, 537031.75, 187915.75, 537031.75, 187940.25, - 537031.75, 187920.75, 537031.75, 188034.25, 537031.75, 187995.75, 537031.75, 188129.25, - 537031.75, 188035.25, 537031.75, 187940.75, 537032.25, 188008.25, 537032.25, 187914.75, - 537032.25, 188083.75, 537032.25, 187972.75, 537032.25, 187910.75, 537032.25, 188124.25, - 537032.25, 187952.75, 537032.25, 188009.75, 537032.25, 187911.75, 537032.25, 188041.75, - 537032.25, 187948.75, 537032.25, 188060.75, 537032.25, 188101.25, 537032.25, 187916.25, - 537032.25, 188073.25, 537032.25, 188060.25, 537032.25, 188021.75, 537032.25, 187937.25, - 537032.25, 188125.25, 537032.25, 188133.25, 537032.25, 188040.75, 537032.25, 188111.25, - 537032.25, 188059.75, 537032.25, 188082.75, 537032.25, 188027.25, 537032.25, 188103.75, - 537032.25, 188040.25, 537032.25, 188058.75, 537032.25, 187915.75, 537032.25, 187938.25, - 537032.25, 188058.25, 537032.25, 188002.25, 537032.25, 187943.75, 537032.25, 188088.75, - 537032.25, 188019.75, 537032.25, 188110.25, 537032.25, 188091.25, 537032.25, 187997.75, - 537032.25, 188056.25, 537032.25, 187968.25, 537032.25, 188130.75, 537032.25, 187923.25, - 537032.25, 188072.25, 537032.25, 188116.75, 537032.25, 188031.25, 537032.25, 188031.75, - 537032.25, 187997.25, 537032.25, 188098.75, 537032.25, 188032.75, 537032.25, 188085.25, - 537032.25, 187996.25, 537032.25, 188038.75, 537032.25, 187954.25, 537032.25, 188004.25, - 537032.25, 188066.75, 537032.25, 187940.25, 537032.25, 188034.25, 537032.25, 188088.25, - 537032.25, 188004.75, 537032.25, 187969.25, 537032.25, 187953.25, 537032.25, 187926.75, - 537032.25, 187991.25, 537032.25, 188015.75, 537032.25, 187970.25, 537032.25, 188035.25, - 537032.25, 187994.75, 537032.25, 188046.75, 537032.25, 187991.75, 537032.25, 187940.75, - 537032.25, 188090.25, 537032.25, 188015.25, 537032.25, 187953.75, 537032.25, 187913.75, - 537032.25, 188070.25, 537032.25, 188037.25, 537032.25, 188014.25, 537032.25, 188047.25, - 537032.25, 188127.75, 537032.25, 188102.75, 537032.25, 188099.75, 537032.25, 188013.25, - 537032.25, 188071.25, 537032.25, 187992.75, 537032.25, 187944.75, 537032.25, 188160.25, - 537032.25, 187919.75, 537032.75, 187919.75, 537032.75, 187983.25, 537032.75, 187928.25, - 537032.75, 188023.25, 537032.75, 187944.75, 537032.75, 188000.75, 537032.75, 187983.75, - 537032.75, 187920.75, 537032.75, 187911.75, 537032.75, 187943.25, 537032.75, 188083.25, - 537032.75, 187992.75, 537032.75, 188127.75, 537032.75, 188123.75, 537032.75, 188013.25, - 537032.75, 188025.25, 537032.75, 188025.75, 537032.75, 188070.75, 537032.75, 188082.25, - 537032.75, 188097.25, 537032.75, 188153.25, 537032.75, 188010.75, 537032.75, 188111.25, - 537032.75, 188058.75, 537032.75, 188036.25, 537032.75, 188039.75, 537032.75, 188048.25, - 537032.75, 188095.25, 537032.75, 188089.25, 537032.75, 187994.25, 537032.75, 188058.25, - 537032.75, 188099.25, 537032.75, 187953.75, 537032.75, 188057.75, 537032.75, 188014.75, - 537032.75, 188128.25, 537032.75, 187992.25, 537032.75, 188127.25, 537032.75, 188110.75, - 537032.75, 188090.25, 537032.75, 187915.75, 537032.75, 187940.75, 537032.75, 188071.75, - 537032.75, 187971.75, 537032.75, 188056.75, 537032.75, 188030.75, 537032.75, 187968.25, - 537032.75, 188034.75, 537032.75, 187997.75, 537032.75, 188002.75, 537032.75, 188088.75, - 537032.75, 188005.25, 537032.75, 188055.25, 537032.75, 188122.75, 537032.75, 188003.25, - 537032.75, 188072.25, 537032.75, 188152.75, 537032.75, 187953.25, 537032.75, 187995.75, - 537032.75, 188130.75, 537032.75, 188031.75, 537032.75, 188085.25, 537032.75, 188039.25, - 537032.75, 187968.75, 537032.75, 188085.75, 537032.75, 188034.25, 537032.75, 188130.25, - 537032.75, 187941.75, 537032.75, 188117.25, 537032.75, 187990.75, 537032.75, 187956.75, - 537032.75, 188098.75, 537032.75, 188101.75, 537032.75, 187996.75, 537032.75, 188100.25, - 537033.25, 187990.75, 537033.25, 188098.25, 537033.25, 187968.75, 537033.25, 187971.25, - 537033.25, 187911.25, 537033.25, 188003.75, 537033.25, 188117.75, 537033.25, 188033.25, - 537033.25, 188033.75, 537033.25, 188053.75, 537033.25, 188054.25, 537033.25, 187996.25, - 537033.25, 188130.25, 537033.25, 187941.75, 537033.25, 188095.75, 537033.25, 188080.25, - 537033.25, 188004.75, 537033.25, 187953.25, 537033.25, 187935.25, 537033.25, 188011.25, - 537033.25, 188130.75, 537033.25, 188126.25, 537033.25, 188129.25, 537033.25, 187939.25, - 537033.25, 188122.75, 537033.25, 187912.25, 537033.25, 188098.75, 537033.25, 188088.25, - 537033.25, 187944.25, 537033.25, 187927.75, 537033.25, 188126.75, 537033.25, 188056.25, - 537033.25, 187920.25, 537033.25, 187924.75, 537033.25, 188049.25, 537033.25, 188086.25, - 537033.25, 188035.25, 537033.25, 188048.75, 537033.25, 188030.25, 537033.25, 188121.75, - 537033.25, 187949.75, 537033.25, 188097.75, 537033.25, 187975.25, 537033.25, 187929.25, - 537033.25, 187954.75, 537033.25, 187968.25, 537033.25, 187921.75, 537033.25, 187998.25, - 537033.25, 188110.75, 537033.25, 188071.75, 537033.25, 187921.25, 537033.25, 188057.75, - 537033.25, 188131.75, 537033.25, 188154.75, 537033.25, 188099.75, 537033.25, 187972.25, - 537033.25, 187917.75, 537033.25, 188089.25, 537033.25, 187942.25, 537033.25, 188047.25, - 537033.25, 188082.75, 537033.25, 187994.25, 537033.25, 188048.25, 537033.25, 187993.75, - 537033.25, 188132.25, 537033.25, 188040.25, 537033.25, 188005.75, 537033.25, 188153.25, - 537033.25, 188037.25, 537033.25, 188123.25, 537033.25, 188013.75, 537033.25, 187966.75, - 537033.25, 188151.75, 537033.25, 187984.25, 537033.25, 187955.25, 537033.25, 188084.25, - 537033.25, 188021.75, 537033.25, 188072.75, 537033.25, 188123.75, 537033.25, 187941.25, - 537033.25, 188125.25, 537033.25, 187942.75, 537033.25, 188081.75, 537033.25, 188036.75, - 537033.25, 187993.25, 537033.25, 187916.25, 537033.25, 188006.25, 537033.25, 187981.75, - 537033.25, 187982.25, 537033.25, 188012.75, 537033.25, 188090.75, 537033.25, 187983.75, - 537033.25, 188111.75, 537033.75, 188102.25, 537033.75, 187920.75, 537033.75, 188153.75, - 537033.75, 188111.75, 537033.75, 187914.75, 537033.75, 188097.75, 537033.75, 187967.75, - 537033.75, 188072.75, 537033.75, 188123.25, 537033.75, 187920.25, 537033.75, 187953.25, - 537033.75, 188122.75, 537033.75, 187985.75, 537033.75, 188011.75, 537033.75, 188025.25, - 537033.75, 188081.25, 537033.75, 187941.75, 537033.75, 188046.25, 537033.75, 187955.25, - 537033.75, 188132.25, 537033.75, 187944.25, 537033.75, 188082.75, 537033.75, 188100.75, - 537033.75, 188012.25, 537033.75, 188089.25, 537033.75, 188071.75, 537033.75, 187983.25, - 537033.75, 187969.75, 537033.75, 187981.75, 537033.75, 187941.25, 537033.75, 188110.75, - 537033.75, 188013.75, 537033.75, 188097.25, 537033.75, 188080.75, 537033.75, 188029.25, - 537033.75, 188057.25, 537033.75, 187945.25, 537033.75, 187954.75, 537033.75, 187922.25, - 537033.75, 187978.25, 537033.75, 188131.25, 537033.75, 188034.75, 537033.75, 187971.75, - 537033.75, 187927.75, 537033.75, 188068.25, 537033.75, 187997.75, 537033.75, 188155.75, - 537033.75, 188084.75, 537033.75, 188055.75, 537033.75, 188004.75, 537033.75, 188055.25, - 537033.75, 188034.25, 537033.75, 188004.25, 537033.75, 187914.25, 537033.75, 188156.25, - 537033.75, 187996.25, 537033.75, 187939.75, 537033.75, 188100.25, 537033.75, 188065.75, - 537033.75, 187971.25, 537034.25, 188150.25, 537034.25, 187930.25, 537034.25, 188017.75, - 537034.25, 187950.25, 537034.25, 188052.75, 537034.25, 188032.75, 537034.25, 188100.25, - 537034.25, 188117.75, 537034.25, 188130.25, 537034.25, 188055.25, 537034.25, 188085.25, - 537034.25, 187922.75, 537034.25, 188080.25, 537034.25, 188145.25, 537034.25, 188137.75, - 537034.25, 188065.25, 537034.25, 187940.25, 537034.25, 187915.25, 537034.25, 187997.75, - 537034.25, 188067.75, 537034.25, 188110.25, 537034.25, 187977.75, 537034.25, 187995.25, - 537034.25, 187927.75, 537034.25, 187925.25, 537034.25, 188005.25, 537034.25, 188090.25, - 537034.25, 187965.25, 537034.25, 188107.75, 537034.25, 188050.25, 537034.25, 188030.25, - 537034.25, 188035.25, 537034.25, 188002.75, 537034.25, 187970.25, 537034.25, 187932.75, - 537034.25, 188015.25, 537034.25, 187975.25, 537034.25, 188120.25, 537034.25, 188070.25, - 537034.25, 187962.75, 537034.25, 187945.25, 537034.25, 188077.75, 537034.25, 187980.25, - 537034.25, 187957.75, 537034.25, 188020.25, 537034.25, 188047.75, 537034.25, 188140.25, - 537034.25, 187917.75, 537034.25, 188155.25, 537034.25, 188115.25, 537034.25, 188127.75, - 537034.25, 188057.75, 537034.25, 188092.75, 537034.25, 187982.75, 537034.25, 188012.75, - 537034.25, 188160.25, 537034.25, 188082.75, 537034.25, 187992.75, 537034.25, 188102.75, - 537034.25, 188027.75, 537034.25, 188037.75, 537034.25, 187985.25, 537034.25, 187947.75, - 537034.25, 187955.25, 537034.25, 188152.75, 537034.25, 187912.75, 537034.25, 188062.75, - 537034.25, 187935.25, 537034.25, 187952.75, 537034.25, 188132.75, 537034.25, 188122.75, - 537034.25, 188025.25, 537034.25, 188157.75, 537034.25, 187920.25, 537034.25, 188135.25, - 537034.25, 188000.25, 537034.25, 187937.75, 537034.25, 187990.25, 537034.25, 188042.75, - 537034.25, 188045.25, 537034.25, 188040.25, 537034.25, 188060.25, 537034.25, 188072.75, - 537034.25, 187972.75, 537034.25, 188112.75, 537034.25, 187967.75, 537034.25, 188147.75, - 537034.25, 188097.75, 537034.25, 188125.25, 537034.25, 187942.75, 537034.25, 187960.25, - 537034.25, 188075.25, 537034.25, 188010.25, 537034.25, 188022.75, 537034.25, 188007.75, - 537034.25, 188087.75, 537034.25, 188105.25, 537034.25, 188142.75, 537034.25, 187987.75, - 537034.25, 188095.25, 537034.25, 187910.75 - }; - } - -} // namespace unittests -} // namespace tntn diff --git a/unittests/tntn/vertex_points.h b/unittests/tntn/vertex_points.h deleted file mode 100644 index 78fe068..0000000 --- a/unittests/tntn/vertex_points.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -namespace tntn { -namespace unittests { - void init_vertex_list(std::vector& data); -} -} // namespace tntn From c524262a3545ccfece72268480bbd94da6b61086 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 11:51:41 +0200 Subject: [PATCH 019/122] further clean up --- src/terrainlib/Dataset.cpp | 4 +- src/terrainlib/Image.cpp | 2 +- src/terrainlib/Image.h | 7 -- src/terrainlib/algorithms/primitives.h | 103 ------------------ .../algorithms/raster_triangle_scanline.h | 101 ----------------- src/terrainlib/init.cpp | 3 - src/terrainlib/init.h | 4 - src/terrainlib/srs.h | 21 ---- unittests/CMakeLists.txt | 1 - unittests/srs_test.cpp | 93 ---------------- 10 files changed, 3 insertions(+), 336 deletions(-) delete mode 100644 src/terrainlib/algorithms/primitives.h delete mode 100644 src/terrainlib/algorithms/raster_triangle_scanline.h delete mode 100644 unittests/srs_test.cpp diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index f8de08a..989847d 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -35,7 +35,7 @@ Dataset::Dataset(const std::string& path) { - tntn::initialize_gdal_once(); + initialize_gdal_once(); m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); if (!m_gdal_dataset) { LOG_ERROR("Couldn't open dataset {}.\n", path); @@ -47,7 +47,7 @@ Dataset::Dataset(const std::string& path) Dataset::Dataset(GDALDataset* dataset) { - tntn::initialize_gdal_once(); + initialize_gdal_once(); m_gdal_dataset.reset(dataset); if (!m_gdal_dataset) { LOG_ERROR("Dataset is null.\n"); diff --git a/src/terrainlib/Image.cpp b/src/terrainlib/Image.cpp index e718d70..3f1f668 100644 --- a/src/terrainlib/Image.cpp +++ b/src/terrainlib/Image.cpp @@ -24,7 +24,7 @@ void image::saveImageAsPng(const Image& image, const std::string& path) { - tntn::initialize_freeimage_once(); + initialize_freeimage_once(); FIBITMAP* free_bitmap = FreeImage_Allocate(int(image.width()), int(image.height()), 24); // free image has line 0 at the bottom diff --git a/src/terrainlib/Image.h b/src/terrainlib/Image.h index 9bc4b8e..814d1f1 100644 --- a/src/terrainlib/Image.h +++ b/src/terrainlib/Image.h @@ -29,11 +29,6 @@ #include -namespace tntn { -template -class Raster; -} - template class Image { public: @@ -68,8 +63,6 @@ class Image { unsigned m_width = 0; unsigned m_height = 0; std::vector m_data; - - friend class tntn::Raster; }; using HeightData = Image; diff --git a/src/terrainlib/algorithms/primitives.h b/src/terrainlib/algorithms/primitives.h deleted file mode 100644 index a610136..0000000 --- a/src/terrainlib/algorithms/primitives.h +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include -#include - -#ifndef ALGORITHMS_PRIMITIVES_H -#define ALGORITHMS_PRIMITIVES_H - -namespace primitives { - -// two times the area of the ccw triangle with vertices a, b, and c. -// negative, if the triangle is cw -template -inline T triAreaX2(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) -{ - // doesn't work for unsigned types. if you need that, come up with something :) - static_assert(std::is_signed_v); - return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); -} - -enum class Winding : char { - CW = -1, - Undefined = 0, - CCW = 1 -}; - -template -inline Winding winding(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) -{ - constexpr bool is_integral = std::is_integral_v; - if constexpr (is_integral) { - using Signed = typename std::conditional::type, T>::type; - auto v = (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) - (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); - if (v == 0) - return Winding::Undefined; - if (v < 0) - return Winding::CW; - return Winding::CCW; - } else { - auto v = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); - if (std::abs(v) < 0.0000000000000001) - return Winding::Undefined; - if (v < 0) - return Winding::CW; - return Winding::CCW; - } -} - -template -inline bool ccw(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) -{ - constexpr bool is_integral = std::is_integral_v; - if constexpr (is_integral) { - using Signed = typename std::conditional::type, T>::type; - if constexpr (include_border) - return (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) >= (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); - return (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) > (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); - } - if constexpr (include_border) - return (b.x - a.x) * (c.y - a.y) >= (b.y - a.y) * (c.x - a.x); - return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x); -} - -template -inline bool rightOf(const glm::tvec2& x, const glm::tvec2& org, const glm::tvec2& dest) -{ - return ccw(x, dest, org); -} - -template -inline bool leftOf(const glm::tvec2& x, const glm::tvec2& org, const glm::tvec2& dest) -{ - return ccw(x, org, dest); -} - -// https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage -// the bottom edge of the raster is not included! -template -inline bool inside(const glm::tvec2& x, const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) -{ - constexpr bool is_integral = std::is_integral_v; - using Signed = typename std::conditional::type, T>::type; - using sVec = glm::tvec2; - // return leftOf(x, a, b) && leftOf(x, b, c) && leftOf(x, c, a); - const auto ccw = [](Winding w) { return w == Winding::CCW; }; - const auto undef = [](Winding w) { return w == Winding::Undefined; }; - const auto topleftedge = [](const sVec& edge) { return (edge.y == 0 && edge.x < 0) || edge.y < 0; }; - - const auto w_ab = winding(x, a, b); - const auto w_bc = winding(x, b, c); - const auto w_ca = winding(x, c, a); - const auto e_ab = sVec(b) - sVec(a); - const auto e_bc = sVec(c) - sVec(b); - const auto e_ca = sVec(a) - sVec(c); - - bool overlap = true; - overlap &= ccw(w_ab) || (undef(w_ab) && topleftedge(e_ab)); - overlap &= ccw(w_bc) || (undef(w_bc) && topleftedge(e_bc)); - overlap &= ccw(w_ca) || (undef(w_ca) && topleftedge(e_ca)); - return overlap; -} -} - -#endif diff --git a/src/terrainlib/algorithms/raster_triangle_scanline.h b/src/terrainlib/algorithms/raster_triangle_scanline.h deleted file mode 100644 index 7e22fdc..0000000 --- a/src/terrainlib/algorithms/raster_triangle_scanline.h +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef ALGORITHMS_RASTER_TRIANGLE_SCANLINE_H -#define ALGORITHMS_RASTER_TRIANGLE_SCANLINE_H - -#include "primitives.h" -#include "tntn/Raster.h" -#include -#include -#include - -namespace raster { - -template -void triangle_scanline(const tntn::Raster& raster, const glm::uvec2& a, const glm::uvec2& b, const glm::uvec2& c, const Lambda& fun) -{ - assert(primitives::winding(a, b, c) == primitives::Winding::CCW); - - const auto min = glm::min(glm::min(a, b), c); - const auto max = glm::max(glm::max(a, b), c); - for (auto y = min.y; y <= max.y; ++y) { - for (auto x = min.x; x <= max.x; ++x) { - const auto coord = glm::uvec2(x, y); - if (primitives::inside(coord, a, b, c)) - fun(coord, raster.value(coord.y, coord.x)); // raster is row / column - } - } - if (min.y == 0) { - // bottom row of raster is not included in primitives::inside, so check for it and make an extrawurscht. - const auto walk_bottom = [&](const glm::uvec2& a, const glm::uvec2& b) { - if ((b - a).y == 0 && a.y == 0) { - const auto end_x = std::max(a.x, b.x); - for (auto x = std::min(a.x, b.x); x < end_x; ++x) { - const auto coord = glm::uvec2(x, 0); - fun(coord, raster.value(coord.y, coord.x)); // raster is row / column - } - } - }; - walk_bottom(a, b); - walk_bottom(b, c); - walk_bottom(c, a); - } - const auto last_x = raster.get_width() - 1; - if (max.x == last_x) { - // similar with the rightmost column - const auto walk_right = [&](const glm::uvec2& a, const glm::uvec2& b) { - if ((b - a).x == 0 && a.x == last_x) { - const auto end_y = std::max(a.y, b.y); - for (auto y = std::min(a.y, b.y); y < end_y; ++y) { - const auto coord = glm::uvec2(last_x, y); - fun(coord, raster.value(coord.y, coord.x)); // raster is row / column - } - } - }; - walk_right(a, b); - walk_right(b, c); - walk_right(c, a); - } - // if (max.x == last_x && min.y == 0) { - // const auto check_br = [&](const glm::uvec2& a, const glm::uvec2& b) { - // if ((b - a).y == 0 && a.y == 0 && b.x == last_x) { - // const auto coord = glm::uvec2(last_x, 0); - // fun(coord, raster.value(coord.y, coord.x)); // raster is row / column - // } - // }; - // check_br(a, b); - // check_br(b, c); - // check_br(c, a); - // } - const auto last_y = raster.get_height() - 1; - if (max.x == last_x && max.y == last_y) { - const auto check_tr = [&](const glm::uvec2& a, const glm::uvec2& b) { - if ((b - a).x == 0 && b.y == last_y && b.x == last_x) { - const auto coord = glm::uvec2(last_x, last_y); - fun(coord, raster.value(coord.y, coord.x)); // raster is row / column - } - }; - check_tr(a, b); - check_tr(b, c); - check_tr(c, a); - } -} -} -#endif diff --git a/src/terrainlib/init.cpp b/src/terrainlib/init.cpp index c44918d..73e8ac2 100644 --- a/src/terrainlib/init.cpp +++ b/src/terrainlib/init.cpp @@ -5,8 +5,6 @@ #include -namespace tntn { - std::once_flag g_gdal_initialized_once_flag; void initialize_gdal_once() @@ -36,4 +34,3 @@ void initialize_freeimage_once() }); static FreeImageDeinitialiserHandler deinitialiser; } -} // namespace tntn diff --git a/src/terrainlib/init.h b/src/terrainlib/init.h index afd2817..1d84902 100644 --- a/src/terrainlib/init.h +++ b/src/terrainlib/init.h @@ -1,8 +1,4 @@ #pragma once -namespace tntn { - void initialize_gdal_once(); void initialize_freeimage_once(); - -} // namespace tntn diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index 833cc6a..8a2d36e 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -303,25 +303,4 @@ inline OGRSpatialReference mgi() { return from_epsg(4312); } -// only for tntn -template -inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) { - return transform_point(source_srs, ecef(), p); -} - -template -inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) { - return transform_points(source_srs, ecef(), points); -} - -template -inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) { - return transform_points(source_srs, ecef(), points); -} - -template -inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) { - return toECEF(source_srs, { p1, p2 }); -} - } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 5ca7460..26ebb61 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -23,7 +23,6 @@ add_executable(unittests_terrainlib parallel_tile_generator.cpp parallel_tiler.cpp progress_indicator_test.cpp - srs_test.cpp tile_heights_generator.cpp top_down_tiler.cpp ) diff --git a/unittests/srs_test.cpp b/unittests/srs_test.cpp deleted file mode 100644 index 83cd0dc..0000000 --- a/unittests/srs_test.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * Copyright (C) 2022 alpinemaps.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "srs.h" -#include -#include -#include -#include -#include -#include - -using namespace radix; -using Catch::Approx; - -TEST_CASE("ECEF conversinos") -{ - OGRSpatialReference webmercator; - webmercator.importFromEPSG(3857); - webmercator.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - OGRSpatialReference wgs84; - wgs84.importFromEPSG(4326); - wgs84.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - SECTION("single point") - { - // comparison against https://www.oc.nps.edu/oc2902w/coord/llhxyz.htm - const auto steffl_wgs84 = glm::dvec3(16.372489, 48.208814, 171.28); - const auto steffl_webmercator = srs::transform_point(wgs84, webmercator, steffl_wgs84); - { - const auto steffl_ecef = srs::toECEF(wgs84, steffl_wgs84); - CHECK(steffl_ecef.x == Approx(4085862.0)); - CHECK(steffl_ecef.y == Approx(1200403.0)); - CHECK(steffl_ecef.z == Approx(4732509.0)); - } - { - const auto steffl_ecef = srs::toECEF(webmercator, steffl_webmercator); - CHECK(steffl_ecef.x == Approx(4085862.0)); - CHECK(steffl_ecef.y == Approx(1200403.0)); - CHECK(steffl_ecef.z == Approx(4732509.0)); - } - } - - SECTION("multiple points") - { - // comparison against https://www.oc.nps.edu/oc2902w/coord/llhxyz.htm - const auto steffl_wgs84 = glm::dvec3(16.372489, 48.208814, 171.28); - const auto grossglockner_wgs84 = glm::dvec3(12.694504, 47.073913, 3798.0); - - const auto [steffl_ecef, grossglockner_ecef] = srs::toECEF(wgs84, steffl_wgs84, grossglockner_wgs84); - { - CHECK(steffl_ecef.x == Approx(4085862.0)); - CHECK(steffl_ecef.y == Approx(1200403.0)); - CHECK(steffl_ecef.z == Approx(4732509.0)); - } - { - CHECK(grossglockner_ecef.x == Approx(4247824.0)); - CHECK(grossglockner_ecef.y == Approx(956860.0)); - CHECK(grossglockner_ecef.z == Approx(4650146.0)); - } - } - - SECTION("point array") - { - // comparison against https://www.oc.nps.edu/oc2902w/coord/llhxyz.htm - const std::vector points = { glm::dvec3(16.372489, 48.208814, 171.28), - glm::dvec3(12.694504, 47.073913, 3798.0) }; - const auto ecef_points = srs::toECEF(wgs84, points); - CHECK(ecef_points[0].x == Approx(4085862.0)); - CHECK(ecef_points[0].y == Approx(1200403.0)); - CHECK(ecef_points[0].z == Approx(4732509.0)); - - CHECK(ecef_points[1].x == Approx(4247824.0)); - CHECK(ecef_points[1].y == Approx(956860.0)); - CHECK(ecef_points[1].z == Approx(4650146.0)); - } -} From 3af29b7d86e9253ea12b9815528f80bea3b6af1b Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 15:10:27 +0200 Subject: [PATCH 020/122] include cgal from the repo --- cmake/AddRepo.cmake | 2 +- cmake/SetupCGAL.cmake | 62 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 15 +++++--- src/terrainmerger/simplify.cpp | 2 +- unittests/CMakeLists.txt | 2 +- 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 cmake/SetupCGAL.cmake diff --git a/cmake/AddRepo.cmake b/cmake/AddRepo.cmake index 772f876..ec28ca1 100644 --- a/cmake/AddRepo.cmake +++ b/cmake/AddRepo.cmake @@ -47,13 +47,13 @@ function(alp_add_git_repository name) set(ALP_EXTERN_DIR extern) endif() - file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/${ALP_EXTERN_DIR} ) set(repo_dir ${CMAKE_SOURCE_DIR}/${ALP_EXTERN_DIR}/${name}) set(short_repo_dir ${ALP_EXTERN_DIR}/${name}) if (DEFINED PARAM_DESTINATION_PATH AND NOT PARAM_DESTINATION_PATH STREQUAL "") set(repo_dir ${CMAKE_SOURCE_DIR}/${PARAM_DESTINATION_PATH}) set(short_repo_dir ${PARAM_DESTINATION_PATH}) endif() + file(MAKE_DIRECTORY ${repo_dir}) set(${name}_SOURCE_DIR "${repo_dir}" PARENT_SCOPE) set(ALP_EXTERN_${name} "${repo_dir}" CACHE PATH "Path to an external repository within the project. Note that this is read only (it'll be overwritten).") diff --git a/cmake/SetupCGAL.cmake b/cmake/SetupCGAL.cmake new file mode 100644 index 0000000..4d2f7bb --- /dev/null +++ b/cmake/SetupCGAL.cmake @@ -0,0 +1,62 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2025 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +if(NOT COMMAND alp_add_git_repository) + include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) +endif() + + +include(ExternalProject) + +function(alp_setup_cgal cgal_version) + alp_add_git_repository(cgal URL https://github.com/CGAL/cgal.git COMMITISH ${cgal_version} DO_NOT_ADD_SUBPROJECT) + + set(cgal_destination_path "${CMAKE_BINARY_DIR}/alp_external/cgal") + + # If CGAL is already there, just import it and return + if(EXISTS "${cgal_destination_path}/lib/cmake/CGAL/CGALConfig.cmake") + list(PREPEND CMAKE_PREFIX_PATH + "${cgal_destination_path}/lib/cmake/CGAL") + find_package(CGAL CONFIG REQUIRED) # gives CGAL::CGAL etc. + return() + endif() + + # First run? Build + install CGAL once + ExternalProject_Add(CGAL + PREFIX "${cgal_destination_path}" + SOURCE_DIR "${cgal_SOURCE_DIR}" + + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCGAL_HEADER_ONLY=ON + -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF + + BUILD_COMMAND "${CMAKE_COMMAND}" --build --target install + UPDATE_COMMAND "" # updates handled by git + STEP_TARGETS install # creates CGAL-install + ) + + # Provide an imported interface target right + file(MAKE_DIRECTORY "${cgal_destination_path}/include") + add_library(CGAL::CGAL INTERFACE IMPORTED GLOBAL) + set_target_properties(CGAL::CGAL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${cgal_destination_path}/include") + + # make sure headers are installed *before* anything that includes them + add_dependencies(CGAL::CGAL CGAL-install) +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c9c4a8..aaabccc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,15 +39,18 @@ alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH v3.1 find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) find_package(OpenCV REQUIRED) -find_package(CGAL REQUIRED) -find_package(Eigen3 REQUIRED NO_MODULE) find_package(CURL REQUIRED) - -alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH bbed8f3607c2d5fa97e309b119d0520fbebca983 NOT_SYSTEM) alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH 20de8b73bbbabaf2f94dd07c4ece8ff3590af531) +alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH 3.4.0 DO_NOT_ADD_SUBPROJECT) +add_library(Eigen3 INTERFACE) +target_include_directories(Eigen3 INTERFACE ${eigen_SOURCE_DIR}) + +include(../cmake/SetupCGAL.cmake) +alp_setup_cgal("v6.0.1") + alp_add_git_repository(cgltf URL https://github.com/jkuhlmann/cgltf COMMITISH 7331a5adf4b0fde15f0e682a5803e4f17137e0ad DO_NOT_ADD_SUBPROJECT) add_library(cgltf INTERFACE) target_include_directories(cgltf INTERFACE ${cgltf_SOURCE_DIR}) @@ -73,6 +76,8 @@ alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COM add_library(zpp_bits INTERFACE) target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH 5d56bcefbb8f13ebedebdf30bc24c92708566a70 NOT_SYSTEM) + add_library(terrainlib terrainlib/alpine_raster.h terrainlib/alpine_raster.cpp @@ -147,7 +152,7 @@ add_library(terrainmergerlib ) target_precompile_headers(terrainmergerlib PRIVATE terrainmerger/pch.h) target_include_directories(terrainmergerlib PUBLIC terrainmerger terrainlib) -target_link_libraries(terrainmergerlib PUBLIC terrainlib radix CLI11::CLI11 Eigen3::Eigen CGAL::CGAL) +target_link_libraries(terrainmergerlib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) add_executable(terrainmerger terrainmerger/main.cpp ) diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index d49e36f..65efe05 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -290,7 +290,7 @@ struct UvMapUpdateEdgeCollapseVisitor : CGAL::Surface_mesh_simplification::Edge_ // Called during the processing phase for each edge being collapsed. // If placement is absent the edge is left uncollapsed. - void OnCollapsing(const Profile &profile, std::optional placement) { + void OnCollapsing(const Profile &profile, boost::optional placement) { if (!placement) { return; } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 26ebb61..0862af8 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -62,5 +62,5 @@ add_executable(unittests_terrainbuilder # terrainbuilder/texture.cpp ) -target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain CGAL::CGAL) +target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain) target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") From acdcc765e1daad9223060504ef77a826b4eda009 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 18:36:10 +0200 Subject: [PATCH 021/122] build gdal and proj in the config step --- cmake/SetupGDAL.cmake | 109 +++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 29 +-------- src/terrainmerger/simplify.cpp | 2 +- 3 files changed, 112 insertions(+), 28 deletions(-) create mode 100644 cmake/SetupGDAL.cmake diff --git a/cmake/SetupGDAL.cmake b/cmake/SetupGDAL.cmake new file mode 100644 index 0000000..87cd120 --- /dev/null +++ b/cmake/SetupGDAL.cmake @@ -0,0 +1,109 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2025 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +if(NOT COMMAND alp_add_git_repository) + include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) +endif() + +function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) + if(NOT EXISTS "${INSTALL_DIR}/lib" AND + NOT EXISTS "${INSTALL_DIR}/lib64") + message(STATUS "[alp] Configuring ${NAME}") + # file(MAKE_DIRECTORY "${BUILD_DIR}") + + message(STATUS "CMake generator: ${CMAKE_GENERATOR}") + + execute_process( + COMMAND ${CMAKE_COMMAND} + -G "${CMAKE_GENERATOR}" + -S ${SRC_DIR} + -B ${BUILD_DIR} + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + ${ARGN} + RESULT_VARIABLE _cfg_res) + + if(_cfg_res) + message(FATAL_ERROR "[alp] Configuring ${NAME} failed!") + endif() + + message(STATUS "[alp] Building + installing ${NAME}") + execute_process( + COMMAND ${CMAKE_COMMAND} + --build ${BUILD_DIR} + --config ${CMAKE_BUILD_TYPE} + --target install + RESULT_VARIABLE _bld_res) + + if(_bld_res) + message(FATAL_ERROR "[alp] Building ${NAME} failed!") + endif() + else() + message(STATUS "[alp] Re‑using existing ${NAME} install at ${INSTALL_DIR}") + endif() +endfunction() + +function(alp_setup_proj proj_version) + alp_add_git_repository(proj URL https://github.com/OSGeo/PROJ.git COMMITISH ${proj_version} DO_NOT_ADD_SUBPROJECT) + + set(_proj_src "${proj_SOURCE_DIR}") + set(_proj_build "${CMAKE_BINARY_DIR}/alp_external/proj_build") + set(_proj_install "${CMAKE_BINARY_DIR}/alp_external/proj_install") + + _alp_build_and_install(PROJ ${_proj_src} ${_proj_build} ${_proj_install} -DBUILD_TESTING=OFF -DBUILD_APPS=OFF) + + set(ALP_PROJ_INSTALL_DIR ${_proj_install} CACHE PATH "Local PROJ install" FORCE) + + list(PREPEND CMAKE_PREFIX_PATH "${_proj_install}") + find_package(PROJ CONFIG REQUIRED) +endfunction() + +function(alp_setup_gdal) + set(oneValueArgs GDAL_VERSION PROJ_VERSION) + cmake_parse_arguments(ARG "" "${oneValueArgs}" "" ${ARGN}) + + if(NOT ARG_GDAL_VERSION OR NOT ARG_PROJ_VERSION) + message(FATAL_ERROR "alp_setup_gdal() needs: GDAL_VERSION PROJ_VERSION ") + endif() + + alp_setup_proj(${ARG_PROJ_VERSION}) + set(_proj_install "${ALP_PROJ_INSTALL_DIR}") + + alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH ${ARG_GDAL_VERSION} DO_NOT_ADD_SUBPROJECT) + + set(_gdal_src "${gdal_SOURCE_DIR}") + set(_gdal_build "${CMAKE_BINARY_DIR}/alp_external/gdal_build") + set(_gdal_install "${CMAKE_BINARY_DIR}/alp_external/gdal_install") + + _alp_build_and_install(GDAL + "${_gdal_src}" "${_gdal_build}" "${_gdal_install}" + -DCMAKE_PREFIX_PATH="${_proj_install}" + -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF + -DOGR_BUILD_OPTIONAL_DRIVERS=OFF + -DBUILD_APPS=OFF + -DBUILD_TESTING=OFF + -DBUILD_PYTHON_BINDINGS=OFF + -DBUILD_JAVA_BINDINGS=OFF + -DBUILD_CSHARP_BINDINGS=OFF + -DGDAL_USE_JPEG=OFF + -DGDAL_USE_ICONV=OFF) + + list(PREPEND CMAKE_PREFIX_PATH "${_gdal_install}") + find_package(GDAL CONFIG REQUIRED) +endfunction() + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aaabccc..3984e9a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,33 +8,8 @@ message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) - - -# alp_add_git_repository(PROJ URL https://github.com/OSGeo/PROJ.git COMMITISH 9.6.0) -# # set(CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}/alp_external/PROJ" ${CMAKE_PREFIX_PATH}) - -# set(PROJ_ROOT ${CMAKE_BINARY_DIR}/alp_external/PROJ CACHE INTERNAL "unsure this is correct") -# set(PROJ_DIR ${CMAKE_BINARY_DIR}/alp_external/PROJ CACHE INTERNAL "unsure this is correct") -# set(PROJ_INCLUDE_DIR ${CMAKE_BINARY_DIR}/alp_external/PROJ/include CACHE INTERNAL "this should be correct") -# set(PROJ_LIBRARY PROJ::proj CACHE INTERNAL "hope this works") - -# can't include proj via repo, gdals find script doesn't play well with it. -# todo: clone cgal, clean up - -set(GDAL_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) -set(OGR_BUILD_OPTIONAL_DRIVERS OFF CACHE BOOL "" FORCE) -set(BUILD_APPS OFF CACHE BOOL "don't build gdal apps" FORCE) -set(BUILD_TESTING OFF CACHE BOOL "don't build gdal apps" FORCE) -set(BUILD_PYTHON_BINDINGS OFF CACHE BOOL "" FORCE) -set(BUILD_JAVA_BINDINGS OFF CACHE BOOL "" FORCE) -set(BUILD_CSHARP_BINDINGS OFF CACHE BOOL "" FORCE) -set(GDAL_USE_JPEG OFF CACHE BOOL "not targetting jpeg for now and it builds an additonal executable" FORCE) - -# The Iconv library is used to convert text from one encoding to another encoding. It is generally available as a system library for Unix-like systems. -# On Windows, GDAL can leverage the API of the operating system for a few base conversions, but using Iconv will provide additional capabilities. -# gdal supports vector layers, we won't need it here for now, and an unnecessary target will be produced. -set(GDAL_USE_ICONV OFF CACHE BOOL "i don't think we need this one" FORCE) -alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH v3.10.3) +include(../cmake/SetupGDAL.cmake) +alp_setup_gdal(GDAL_VERSION v3.10.3 PROJ_VERSION 9.6.0) find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index 65efe05..d49e36f 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -290,7 +290,7 @@ struct UvMapUpdateEdgeCollapseVisitor : CGAL::Surface_mesh_simplification::Edge_ // Called during the processing phase for each edge being collapsed. // If placement is absent the edge is left uncollapsed. - void OnCollapsing(const Profile &profile, boost::optional placement) { + void OnCollapsing(const Profile &profile, std::optional placement) { if (!placement) { return; } From 1f9175cfad262776c4f73748b965b59fa6d1dfd9 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 18:40:45 +0200 Subject: [PATCH 022/122] i'm confused about the quoting. chatgpt and gemini tell to quote, but quoting -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} breaks the build. igonre for now --- cmake/SetupGDAL.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/SetupGDAL.cmake b/cmake/SetupGDAL.cmake index 87cd120..fb3188d 100644 --- a/cmake/SetupGDAL.cmake +++ b/cmake/SetupGDAL.cmake @@ -26,11 +26,9 @@ function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) message(STATUS "[alp] Configuring ${NAME}") # file(MAKE_DIRECTORY "${BUILD_DIR}") - message(STATUS "CMake generator: ${CMAKE_GENERATOR}") - execute_process( COMMAND ${CMAKE_COMMAND} - -G "${CMAKE_GENERATOR}" + -G ${CMAKE_GENERATOR} -S ${SRC_DIR} -B ${BUILD_DIR} -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} From b90b0decbc83b29cf159758fc170b795face400b Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Mon, 5 May 2025 19:01:45 +0200 Subject: [PATCH 023/122] update cmake scripts --- cmake/CheckForScriptUpdates.cmake | 2 +- src/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/CheckForScriptUpdates.cmake b/cmake/CheckForScriptUpdates.cmake index 224e681..cb48df7 100644 --- a/cmake/CheckForScriptUpdates.cmake +++ b/cmake/CheckForScriptUpdates.cmake @@ -42,7 +42,7 @@ function(alp_check_for_script_updates script_path) get_property(cmake_scripts_SOURCE_DIR GLOBAL PROPERTY _alp_check_for_script_updates_script_repo) else() alp_add_git_repository(cmake_scripts - URL "git@github.com:AlpineMapsOrg/cmake_scripts.git" + URL "https://github.com/AlpineMapsOrg/cmake_scripts.git" COMMITISH origin/main DO_NOT_ADD_SUBPROJECT PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) set_property(GLOBAL PROPERTY _alp_check_for_script_updates_repo_flag TRUE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3984e9a..9d477af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,7 +51,7 @@ alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COM add_library(zpp_bits INTERFACE) target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) -alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH 5d56bcefbb8f13ebedebdf30bc24c92708566a70 NOT_SYSTEM) +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH abc5efb32c7c7a8295fcad3077c3100a35a4baab NOT_SYSTEM) add_library(terrainlib terrainlib/alpine_raster.h terrainlib/alpine_raster.cpp From 3425896b7acf7e2560e7b6950260f8d6daf31f93 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Tue, 6 May 2025 17:21:39 +0200 Subject: [PATCH 024/122] create alp_setup_cmake_project and use it for gdal, cgal, boost and opencv alp_setup_cmake_project clones a repo via url + version, builds and installs it into the cmake binary dir. there is caching based on the version (rerun the build only if the version changes). --- CMakeLists.txt | 1 + cmake/AddRepo.cmake | 170 ++++++++++++++-------------------- cmake/SetupCGAL.cmake | 62 ------------- cmake/SetupCMakeProject.cmake | 89 ++++++++++++++++++ cmake/SetupGDAL.cmake | 93 ++++--------------- src/CMakeLists.txt | 28 +++--- 6 files changed, 192 insertions(+), 251 deletions(-) delete mode 100644 cmake/SetupCGAL.cmake create mode 100644 cmake/SetupCMakeProject.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2273a..2488212 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(alpine-terrain-builder) option(ALP_UNITTESTS "include unit test targets in the buildsystem" ON) include(cmake/AddRepo.cmake) +include(cmake/SetupCMakeProject.cmake) add_subdirectory(src) diff --git a/cmake/AddRepo.cmake b/cmake/AddRepo.cmake index ec28ca1..5bbb712 100644 --- a/cmake/AddRepo.cmake +++ b/cmake/AddRepo.cmake @@ -28,6 +28,33 @@ if(NOT DEFINED _alp_add_repo_check_flag) set_property(GLOBAL PROPERTY _alp_add_repo_check_flag FALSE) endif() +function(_alp_git_checkout_branch repo repo_dir commitish) + message(STATUS "[alp/git] In ${repo}, checking out ${commitish}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} checkout --quiet ${commitish} + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_CHECKOUT_RESULT + ) + if (NOT GIT_CHECKOUT_RESULT) + message(STATUS "[alp/git] In ${repo}, checking out branch ${commitish} was successfull.") + else() + message(FATAL_ERROR "[alp/git] In ${repo}, checking out branch ${commitish} was NOT successfull!") + endif() + + if (EXISTS "${repo_dir}/.gitmodules") + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_SUBMODULE_RESULT + ) + if(GIT_SUBMODULE_RESULT EQUAL 0) + message(STATUS "[alp/git] In ${repo}, submodules updated to match ${commitish}.") + else() + message(WARNING "[alp/git] In ${repo}, submodule update failed after checking out ${commitish}.") + endif() + endif() +endfunction() + function(alp_add_git_repository name) set(options DO_NOT_ADD_SUBPROJECT NOT_SYSTEM PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) set(oneValueArgs URL COMMITISH DESTINATION_PATH) @@ -56,21 +83,11 @@ function(alp_add_git_repository name) file(MAKE_DIRECTORY ${repo_dir}) set(${name}_SOURCE_DIR "${repo_dir}" PARENT_SCOPE) - set(ALP_EXTERN_${name} "${repo_dir}" CACHE PATH "Path to an external repository within the project. Note that this is read only (it'll be overwritten).") - - if(EXISTS "${repo_dir}/.git") - message(STATUS "Updating git repo in ${short_repo_dir}") - # Check internet connection - execute_process( - COMMAND ${GIT_EXECUTABLE} ls-remote ${PARAM_URL} - OUTPUT_QUIET - ERROR_QUIET - RESULT_VARIABLE GIT_LSREMOTE_RESULT - ) - string(REGEX MATCH "^[^/]+/.+" commitish_is_remote_branch "${PARAM_COMMITISH}") + string(REGEX MATCH "^[^/]+/.+" commitish_is_remote_branch "${PARAM_COMMITISH}") - # First, see if PARAM_COMMITISH is a valid local ref at all: + if(EXISTS "${repo_dir}/.git") + # First, see if PARAM_COMMITISH is a valid local ref: execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH} WORKING_DIRECTORY ${repo_dir} @@ -79,15 +96,11 @@ function(alp_add_git_repository name) RESULT_VARIABLE GIT_COMMIT_RESULT ) - if (NOT GIT_COMMIT_RESULT) - # - # At this point, PARAM_COMMITISH is recognized by Git + if (GIT_COMMIT_RESULT EQUAL 0 AND NOT commitish_is_remote_branch) + # PARAM_COMMITISH is recognized by Git => no need to fetch # (could be a tag (lightweight or annotated) or a direct commit SHA). - # The problem: if it's an *annotated* tag, rev-parse gives us - # the tag object's hash, not the commit hash. - # + # if it's an *annotated* tag, rev-parse gives us the tag object's hash, not the commit hash. # => Force resolve the actual commit object with ^{commit}: - # execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH}^{commit} WORKING_DIRECTORY ${repo_dir} @@ -112,106 +125,57 @@ function(alp_add_git_repository name) OUTPUT_STRIP_TRAILING_WHITESPACE ) - if (GIT_HEAD_OUTPUT STREQUAL CHECK_COMMITISH AND NOT commitish_is_remote_branch) - message(STATUS "Repo in ${short_repo_dir} is already at ${PARAM_COMMITISH}. Skipping checkout.") + if (GIT_HEAD_OUTPUT STREQUAL CHECK_COMMITISH) + message(STATUS "[alp/git] ${short_repo_dir} is already at ${PARAM_COMMITISH}. Skipping checkout.") else() - if (GIT_LSREMOTE_RESULT) - message(WARNING "No internet connection or remote unavailable. Leaving ${name} as is.") - else() - message(STATUS "Fetching updates for ${name}.") - execute_process( - COMMAND ${GIT_EXECUTABLE} fetch - WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_FETCH_RESULT - ) - endif() - - message(STATUS "Checking out ${PARAM_COMMITISH} in ${name}.") - execute_process( - COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} - WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_CHECKOUT_RESULT - ) - if (NOT GIT_CHECKOUT_RESULT) - message(STATUS "Checking out ${PARAM_COMMITISH} was successfull.") - else() - message(FATAL_ERROR "In ${name}, checking out ${PARAM_COMMITISH} was NOT successfull!") - endif() + _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) endif() else() - # - # If rev-parse --verify failed, - # we assume it's a branch name that doesn't exist as a direct ref locally - # - message(STATUS "COMMITISH ${PARAM_COMMITISH} might be a branch, checking for internet connection.") - - if (GIT_LSREMOTE_RESULT) - message(WARNING "No internet connection or remote unavailable. Leaving branch ${PARAM_COMMITISH} as-is.") - else() - message(STATUS "Fetching updates for branch ${PARAM_COMMITISH}.") + # either remote branch or commitish not recognised + message(STATUS "[alp/git] Fetching updates for ${short_repo_dir}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} fetch + WORKING_DIRECTORY ${repo_dir} + RESULT_VARIABLE GIT_FETCH_RESULT + ) + if (GIT_FETCH_RESULT EQUAL 0) + message(STATUS "[alp/git] Fetch successful for ${short_repo_dir}.") execute_process( - COMMAND ${GIT_EXECUTABLE} fetch + COMMAND ${GIT_EXECUTABLE} branch --show-current WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_FETCH_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE GIT_BRANCH_OUTPUT + RESULT_VARIABLE GIT_BRANCH_RESULT ) - if (NOT GIT_FETCH_RESULT) - message(STATUS "Fetch successfull.") - - execute_process( - COMMAND ${GIT_EXECUTABLE} branch --show-current - WORKING_DIRECTORY ${repo_dir} - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE GIT_BRANCH_OUTPUT - RESULT_VARIABLE GIT_BRANCH_RESULT - ) - if (GIT_BRANCH_RESULT) - message(FATAL_ERROR "${repo_dir}: git branch --show-current not successfull") - endif() - - if (GIT_BRANCH_OUTPUT STREQUAL "") - # Currently detached; let's checkout the branch - execute_process( - COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} - WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_CHECKOUT_RESULT - ) - if (NOT GIT_CHECKOUT_RESULT) - message(STATUS "In ${name}, checking out branch ${PARAM_COMMITISH} was successfull.") - else() - message(FATAL_ERROR "In ${name}, checking out branch ${PARAM_COMMITISH} was NOT successfull!") - endif() - else() - message(WARNING - "${short_repo_dir} is on branch ${GIT_BRANCH_OUTPUT}, leaving it there. " - "NOT checking out ${PARAM_COMMITISH}! Use origin/main or similar if you " - "want to stay up-to-date with upstream." - ) - endif() + if (NOT GIT_BRANCH_RESULT EQUAL 0) + message(FATAL_ERROR "[alp/git] In ${short_repo_dir}, git branch --show-current not successfull") + endif() + + if (GIT_BRANCH_OUTPUT STREQUAL "") + # Currently detached; let's checkout the branch + _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) else() - message(WARNING "Fetching ${name} was NOT successfull!") + message(WARNING + "[alp/git] ${short_repo_dir} on branch ${GIT_BRANCH_OUTPUT}, leaving it there. " + "NOT checking out ${PARAM_COMMITISH}! Use origin/main or similar if you " + "want to stay up-to-date with upstream." + ) endif() + else () + message(WARNING "[alp/git] Not able to fetch updates for ${short_repo_dir} and ${PARAM_COMMITISH} was not found locally or is a remote branch.") endif() endif() else() # If the repo doesn't exist, do a fresh clone - message(STATUS "Cloning ${PARAM_URL} to ${short_repo_dir}.") + message(STATUS "[alp/git] Cloning ${PARAM_URL} to ${repo_dir}.") execute_process( COMMAND ${GIT_EXECUTABLE} clone --recurse-submodules ${PARAM_URL} ${repo_dir} RESULT_VARIABLE GIT_CLONE_RESULT ) - if (NOT GIT_CLONE_RESULT) - execute_process( - COMMAND ${GIT_EXECUTABLE} checkout --quiet ${PARAM_COMMITISH} - WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_CHECKOUT_RESULT - ) - if (NOT GIT_CHECKOUT_RESULT) - message(STATUS "Checking out ${PARAM_COMMITISH} was successfull.") - else() - message(FATAL_ERROR "In ${name}, checking out ${PARAM_COMMITISH} was NOT successfull!") - endif() + if (GIT_CLONE_RESULT EQUAL 0) + _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) else() - message(FATAL_ERROR "Cloning ${name} was NOT successfull!") + message(FATAL_ERROR "[alp/git] Cloning ${short_repo_dir} was NOT successfull!") endif() endif() diff --git a/cmake/SetupCGAL.cmake b/cmake/SetupCGAL.cmake deleted file mode 100644 index 4d2f7bb..0000000 --- a/cmake/SetupCGAL.cmake +++ /dev/null @@ -1,62 +0,0 @@ -############################################################################# -# AlpineMaps.org -# Copyright (C) 2025 Adam Celarek -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -############################################################################# - -if(NOT COMMAND alp_add_git_repository) - include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) -endif() - - -include(ExternalProject) - -function(alp_setup_cgal cgal_version) - alp_add_git_repository(cgal URL https://github.com/CGAL/cgal.git COMMITISH ${cgal_version} DO_NOT_ADD_SUBPROJECT) - - set(cgal_destination_path "${CMAKE_BINARY_DIR}/alp_external/cgal") - - # If CGAL is already there, just import it and return - if(EXISTS "${cgal_destination_path}/lib/cmake/CGAL/CGALConfig.cmake") - list(PREPEND CMAKE_PREFIX_PATH - "${cgal_destination_path}/lib/cmake/CGAL") - find_package(CGAL CONFIG REQUIRED) # gives CGAL::CGAL etc. - return() - endif() - - # First run? Build + install CGAL once - ExternalProject_Add(CGAL - PREFIX "${cgal_destination_path}" - SOURCE_DIR "${cgal_SOURCE_DIR}" - - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX= - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCGAL_HEADER_ONLY=ON - -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF - - BUILD_COMMAND "${CMAKE_COMMAND}" --build --target install - UPDATE_COMMAND "" # updates handled by git - STEP_TARGETS install # creates CGAL-install - ) - - # Provide an imported interface target right - file(MAKE_DIRECTORY "${cgal_destination_path}/include") - add_library(CGAL::CGAL INTERFACE IMPORTED GLOBAL) - set_target_properties(CGAL::CGAL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${cgal_destination_path}/include") - - # make sure headers are installed *before* anything that includes them - add_dependencies(CGAL::CGAL CGAL-install) -endfunction() diff --git a/cmake/SetupCMakeProject.cmake b/cmake/SetupCMakeProject.cmake new file mode 100644 index 0000000..1fde788 --- /dev/null +++ b/cmake/SetupCMakeProject.cmake @@ -0,0 +1,89 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2025 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +if(NOT COMMAND alp_add_git_repository) + include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) +endif() + +function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) + message(STATUS "[alp] Configuring ${NAME}") + + execute_process( + COMMAND ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} + -S ${SRC_DIR} + -B ${BUILD_DIR} + -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + ${ARGN} + RESULT_VARIABLE _cfg_res) + + if(_cfg_res) + message(FATAL_ERROR "[alp] Configuring ${NAME} failed!") + endif() + + message(STATUS "[alp] Building + installing ${NAME}") + execute_process( + COMMAND ${CMAKE_COMMAND} + --build ${BUILD_DIR} + --config ${CMAKE_BUILD_TYPE} + --target install + RESULT_VARIABLE _bld_res) + + if(_bld_res) + message(FATAL_ERROR "[alp] Building ${NAME} failed!") + endif() +endfunction() + +function(alp_setup_cmake_project arg_NAME) + set(options) + set(oneValueArgs URL COMMITISH) + set(multiValueArgs CMAKE_ARGUMENTS) + cmake_parse_arguments(PARSE_ARGV 1 arg "${options}" "${oneValueArgs}" "${multiValueArgs}") + + if(NOT arg_NAME OR NOT arg_URL OR NOT arg_COMMITISH) + message(FATAL_ERROR "[alp] alp_setup_cmake_project() needs: URL COMMITISH ") + endif() + + set(version_var "ALP_INSTALLED_${arg_NAME}_VERSION") + set(path_var "ALP_INSTALLED_${arg_NAME}_PATH") + + if(DEFINED ${version_var} AND "${${version_var}}" STREQUAL "${arg_COMMITISH}" AND DEFINED ${path_var} AND EXISTS "${${path_var}}") + list(PREPEND CMAKE_PREFIX_PATH "${${path_var}}") + set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE) + return() + endif() + + alp_add_git_repository(${arg_NAME} URL ${arg_URL} COMMITISH ${arg_COMMITISH} DO_NOT_ADD_SUBPROJECT) + set(src_dir "${${arg_NAME}_SOURCE_DIR}") + set(build_dir "${CMAKE_BINARY_DIR}/alp_external/${arg_NAME}_build") + set(install_dir "${CMAKE_BINARY_DIR}/alp_external/${arg_NAME}") + + file(REMOVE_RECURSE "${install_dir}") + _alp_build_and_install(${arg_NAME} ${src_dir} ${build_dir} ${install_dir} ${arg_CMAKE_ARGUMENTS}) + + list(PREPEND CMAKE_PREFIX_PATH "${install_dir}") + set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE) + + + set(${path_var} "${install_dir}" CACHE PATH "Install path for ${arg_NAME}" FORCE) + set(${version_var} "${arg_COMMITISH}" CACHE STRING "Installed commit/tag for ${arg_NAME}" FORCE) +endfunction() + + diff --git a/cmake/SetupGDAL.cmake b/cmake/SetupGDAL.cmake index fb3188d..9d19258 100644 --- a/cmake/SetupGDAL.cmake +++ b/cmake/SetupGDAL.cmake @@ -16,61 +16,10 @@ # along with this program. If not, see . ############################################################################# -if(NOT COMMAND alp_add_git_repository) - include(${CMAKE_CURRENT_LIST_DIR}/AddRepo.cmake) +if(NOT COMMAND alp_setup_cmake_project) + include(${CMAKE_CURRENT_LIST_DIR}/SetupCMakeProject.cmake) endif() -function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) - if(NOT EXISTS "${INSTALL_DIR}/lib" AND - NOT EXISTS "${INSTALL_DIR}/lib64") - message(STATUS "[alp] Configuring ${NAME}") - # file(MAKE_DIRECTORY "${BUILD_DIR}") - - execute_process( - COMMAND ${CMAKE_COMMAND} - -G ${CMAKE_GENERATOR} - -S ${SRC_DIR} - -B ${BUILD_DIR} - -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - ${ARGN} - RESULT_VARIABLE _cfg_res) - - if(_cfg_res) - message(FATAL_ERROR "[alp] Configuring ${NAME} failed!") - endif() - - message(STATUS "[alp] Building + installing ${NAME}") - execute_process( - COMMAND ${CMAKE_COMMAND} - --build ${BUILD_DIR} - --config ${CMAKE_BUILD_TYPE} - --target install - RESULT_VARIABLE _bld_res) - - if(_bld_res) - message(FATAL_ERROR "[alp] Building ${NAME} failed!") - endif() - else() - message(STATUS "[alp] Re‑using existing ${NAME} install at ${INSTALL_DIR}") - endif() -endfunction() - -function(alp_setup_proj proj_version) - alp_add_git_repository(proj URL https://github.com/OSGeo/PROJ.git COMMITISH ${proj_version} DO_NOT_ADD_SUBPROJECT) - - set(_proj_src "${proj_SOURCE_DIR}") - set(_proj_build "${CMAKE_BINARY_DIR}/alp_external/proj_build") - set(_proj_install "${CMAKE_BINARY_DIR}/alp_external/proj_install") - - _alp_build_and_install(PROJ ${_proj_src} ${_proj_build} ${_proj_install} -DBUILD_TESTING=OFF -DBUILD_APPS=OFF) - - set(ALP_PROJ_INSTALL_DIR ${_proj_install} CACHE PATH "Local PROJ install" FORCE) - - list(PREPEND CMAKE_PREFIX_PATH "${_proj_install}") - find_package(PROJ CONFIG REQUIRED) -endfunction() - function(alp_setup_gdal) set(oneValueArgs GDAL_VERSION PROJ_VERSION) cmake_parse_arguments(ARG "" "${oneValueArgs}" "" ${ARGN}) @@ -79,29 +28,27 @@ function(alp_setup_gdal) message(FATAL_ERROR "alp_setup_gdal() needs: GDAL_VERSION PROJ_VERSION ") endif() - alp_setup_proj(${ARG_PROJ_VERSION}) - set(_proj_install "${ALP_PROJ_INSTALL_DIR}") - - alp_add_git_repository(gdal URL https://github.com/OSGeo/gdal.git COMMITISH ${ARG_GDAL_VERSION} DO_NOT_ADD_SUBPROJECT) + alp_setup_cmake_project(proj URL https://github.com/OSGeo/PROJ.git COMMITISH ${ARG_PROJ_VERSION} CMAKE_ARGUMENTS -DBUILD_TESTING=OFF -DBUILD_APPS=OFF) + find_package(PROJ CONFIG REQUIRED) - set(_gdal_src "${gdal_SOURCE_DIR}") - set(_gdal_build "${CMAKE_BINARY_DIR}/alp_external/gdal_build") - set(_gdal_install "${CMAKE_BINARY_DIR}/alp_external/gdal_install") + set(_proj_install "${ALP_PROJ_INSTALL_DIR}") - _alp_build_and_install(GDAL - "${_gdal_src}" "${_gdal_build}" "${_gdal_install}" - -DCMAKE_PREFIX_PATH="${_proj_install}" - -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF - -DOGR_BUILD_OPTIONAL_DRIVERS=OFF - -DBUILD_APPS=OFF - -DBUILD_TESTING=OFF - -DBUILD_PYTHON_BINDINGS=OFF - -DBUILD_JAVA_BINDINGS=OFF - -DBUILD_CSHARP_BINDINGS=OFF - -DGDAL_USE_JPEG=OFF - -DGDAL_USE_ICONV=OFF) + alp_setup_cmake_project(gdal + URL https://github.com/OSGeo/gdal.git + COMMITISH ${ARG_GDAL_VERSION} + CMAKE_ARGUMENTS + -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF + -DOGR_BUILD_OPTIONAL_DRIVERS=OFF + -DBUILD_APPS=OFF + -DBUILD_TESTING=OFF + -DBUILD_PYTHON_BINDINGS=OFF + -DBUILD_JAVA_BINDINGS=OFF + -DBUILD_CSHARP_BINDINGS=OFF + -DGDAL_USE_JPEG=OFF + -DGDAL_USE_ICONV=OFF + ) - list(PREPEND CMAKE_PREFIX_PATH "${_gdal_install}") find_package(GDAL CONFIG REQUIRED) + set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE) endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d477af..9d17371 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,12 +8,8 @@ message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) -include(../cmake/SetupGDAL.cmake) -alp_setup_gdal(GDAL_VERSION v3.10.3 PROJ_VERSION 9.6.0) - find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) -find_package(OpenCV REQUIRED) find_package(CURL REQUIRED) alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) @@ -23,8 +19,17 @@ alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH add_library(Eigen3 INTERFACE) target_include_directories(Eigen3 INTERFACE ${eigen_SOURCE_DIR}) -include(../cmake/SetupCGAL.cmake) -alp_setup_cgal("v6.0.1") +alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF) +find_package(Boost CONFIG REQUIRED) + +include(../cmake/SetupGDAL.cmake) +alp_setup_gdal(GDAL_VERSION v3.10.3 PROJ_VERSION 9.6.0) + +alp_setup_cmake_project(cgal URL https://github.com/CGAL/cgal.git COMMITISH "v6.0.1" CMAKE_ARGUMENTS -DCGAL_HEADER_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF) +find_package(CGAL REQUIRED) + +alp_setup_cmake_project(opencv URL https://github.com/opencv/opencv.git COMMITISH 4.11.0 CMAKE_ARGUMENTS -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_opencv_apps=OFF) +find_package(OpenCV REQUIRED) alp_add_git_repository(cgltf URL https://github.com/jkuhlmann/cgltf COMMITISH 7331a5adf4b0fde15f0e682a5803e4f17137e0ad DO_NOT_ADD_SUBPROJECT) add_library(cgltf INTERFACE) @@ -83,8 +88,9 @@ add_library(terrainlib terrainlib/ctb/types.hpp terrainlib/init.h terrainlib/init.cpp ) +target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected ${OpenCV_LIBS}) -target_include_directories(terrainlib PUBLIC terrainlib ${OpenCV_INCLUDE_DIRS}) + if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) endif() @@ -103,12 +109,11 @@ add_library(terrainbuilderlib terrainbuilder/octree/storage.h terrainbuilder/octree/space.h ) -target_include_directories(terrainbuilderlib PUBLIC terrainbuilder terrainlib) +target_include_directories(terrainbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainbuilder) target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) add_executable(terrainbuilder terrainbuilder/main.cpp ) -target_include_directories(terrainbuilder PUBLIC terrainbuilder) target_link_libraries(terrainbuilder PUBLIC terrainbuilderlib) add_library(terrainmergerlib @@ -125,25 +130,22 @@ add_library(terrainmergerlib terrainmerger/convert.cpp terrainmerger/validate.h ) +target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) target_precompile_headers(terrainmergerlib PRIVATE terrainmerger/pch.h) -target_include_directories(terrainmergerlib PUBLIC terrainmerger terrainlib) target_link_libraries(terrainmergerlib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) add_executable(terrainmerger terrainmerger/main.cpp ) -target_include_directories(terrainmerger PUBLIC terrainmerger) target_link_libraries(terrainmerger PUBLIC terrainmergerlib) add_executable(tile-downloader tile_downloader/main.cpp ) target_link_libraries(tile-downloader PUBLIC terrainlib ${CURL_LIBRARIES}) -target_include_directories(tile-downloader PUBLIC ${CURL_INCLUDE_DIR}) add_executable(terrainconvert terrainconvert/cli.h terrainconvert/cli.cpp terrainconvert/main.cpp ) -target_include_directories(terrainconvert PUBLIC terrainlib) target_link_libraries(terrainconvert PUBLIC terrainlib CLI11::CLI11) From e01efae842d835dd6b64efda754053c5d1cca0d5 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 13:46:58 +0200 Subject: [PATCH 025/122] Remove out of bounds node access --- src/terrainbuilder/octree/id.h | 103 ++++++++++++++++--------- unittests/terrainbuilder/octree_id.cpp | 13 ++-- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/terrainbuilder/octree/id.h b/src/terrainbuilder/octree/id.h index 00c35cc..50c2f34 100644 --- a/src/terrainbuilder/octree/id.h +++ b/src/terrainbuilder/octree/id.h @@ -1,51 +1,70 @@ #pragma once +#include #include #include -#include -#include -#include #include #include +#include + namespace octree { +using Level = uint32_t; +using Coord = uint32_t; +using Coords = glm::tvec3; +using Index = uint64_t; + class Id { public: - constexpr Id(uint32_t level, glm::uvec3 coords) - : _level(level), _index(interleave3(coords)) {} - constexpr Id(uint32_t level, uint64_t index) - : _level(level), _index(index) {} + [[nodiscard]] static constexpr Level max_level() { + return (sizeof(Index) * 8) / 3; + } + [[nodiscard]] static constexpr Coord max_coord_on_level(Level level) { + return (1ull << level) - 1; + } + [[nodiscard]] static constexpr Index max_index_on_level(Level level) { + return (1ull << (3 * level)) - 1; + } - constexpr uint32_t level() const { + constexpr Id(Level level, Coords coords) + : Id(level, interleave3(coords)) { + } + constexpr Id(Level level, Index index) + : _level(level), _index(index) { + assert(this->_level <= Id::max_level()); + assert(this->_index <= Id::max_index_on_level(this->_level)); + } + + [[nodiscard]] constexpr Level level() const { return this->_level; } - constexpr uint64_t index_on_level() const { + [[nodiscard]] constexpr Index index_on_level() const { return this->_index; } - constexpr glm::uvec3 coords() const { + [[nodiscard]] constexpr Coords coords() const { return deinterleave3(this->index_on_level()); } - constexpr uint32_t x() const { + [[nodiscard]] constexpr Coord x() const { return this->coords().x; } - constexpr uint32_t y() const { + [[nodiscard]] constexpr Coord y() const { return this->coords().y; } - constexpr uint32_t z() const { + [[nodiscard]] constexpr Coord z() const { return this->coords().z; } - constexpr std::optional neighbour(const glm::ivec3& d) const { - const auto new_coords = glm::ivec3(this->coords()) + d; - if (new_coords.x < 0 || new_coords.y < 0 || new_coords.z < 0) { - // throw std::out_of_range("Neighbour coordinates cannot be negative"); + [[nodiscard]] constexpr std::optional neighbour(const glm::ivec3& d) const { + const Coord max_coord = Id::max_coord_on_level(this->level()); + const glm::ivec3 new_coords = glm::ivec3(this->coords()) + d; + if (glm::any(glm::lessThan(new_coords, glm::ivec3(0))) || glm::any(glm::greaterThan(new_coords, glm::ivec3(max_coord)))) { return std::nullopt; } - return Id(this->level(), glm::uvec3(new_coords)); + return Id(this->level(), Coords(new_coords)); } - constexpr std::vector neighbours() const { + [[nodiscard]] std::vector neighbours() const { std::vector result; result.reserve(26); for (int dx = -1; dx <= 1; dx++) { @@ -67,30 +86,35 @@ class Id { return result; } - constexpr std::optional parent() const { + [[nodiscard]] constexpr std::optional parent() const { if (this->level() == 0) { return std::nullopt; } - const auto parent_coords = this->coords() / glm::uvec3(2); + const auto parent_coords = this->coords() / Coords(2); return Id(this->level() - 1, parent_coords); } - constexpr Id child(uint32_t child_index) const { + // TODO: make this return std::optional and check against max level? + [[nodiscard]] constexpr Id child(uint32_t child_index) const { if (child_index > 7) { throw std::invalid_argument("Invalid child index (must be 0-7)"); } return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); } - constexpr std::array children() const { + [[nodiscard]] constexpr std::array children() const { return { this->child(0), this->child(1), this->child(2), this->child(3), this->child(4), this->child(5), this->child(6), this->child(7) }; } - static constexpr Id root() { + [[nodiscard]] constexpr bool is_root() const { + return this->level() == 0; + } + + [[nodiscard]] static constexpr Id root() { return Id(0, 0); } @@ -99,16 +123,18 @@ class Id { } private: - uint32_t _level; - uint64_t _index; + Level _level; + Index _index; - static constexpr uint64_t interleave3(const glm::uvec3 &coords) { - const uint64_t x = coords.x; - const uint64_t y = coords.y; - const uint64_t z = coords.z; + [[nodiscard]] static constexpr Index interleave3(const Coords &coords) { + assert(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); - uint64_t result = 0; - for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + const Index x = coords.x; + const Index y = coords.y; + const Index z = coords.z; + + Index result = 0; + for (Level i = 0; i < Id::max_level(); i++) { result |= ((x >> i) & 1) << (3 * i); result |= ((y >> i) & 1) << (3 * i + 1); result |= ((z >> i) & 1) << (3 * i + 2); @@ -116,11 +142,11 @@ class Id { return result; } - static constexpr glm::uvec3 deinterleave3(uint64_t index) { - uint32_t x = 0; - uint32_t y = 0; - uint32_t z = 0; - for (uint32_t i = 0; i < (sizeof(uint64_t) * 8) / 3; i++) { + [[nodiscard]] static constexpr Coords deinterleave3(Index index) { + Coord x = 0; + Coord y = 0; + Coord z = 0; + for (Level i = 0; i < Id::max_level(); i++) { x |= ((index >> (3 * i)) & 1) << i; y |= ((index >> (3 * i + 1)) & 1) << i; z |= ((index >> (3 * i + 2)) & 1) << i; @@ -131,6 +157,8 @@ class Id { } // namespace octree +#include +#include template <> struct fmt::formatter { // Parses format specifications; here we ignore them. @@ -148,6 +176,7 @@ struct fmt::formatter { id.level(), id.x(), id.y(), id.z(), id.index_on_level()); } }; + #include #include namespace octree{ diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainbuilder/octree_id.cpp index 482f40b..966f56e 100644 --- a/unittests/terrainbuilder/octree_id.cpp +++ b/unittests/terrainbuilder/octree_id.cpp @@ -7,12 +7,12 @@ using namespace octree; TEST_CASE("Id basic construction and accessors", "[octree::Id]") { - Id id(2, glm::uvec3(3, 1, 4)); + Id id(2, glm::uvec3(3, 1, 2)); CHECK(id.level() == 2); - CHECK(id.coords() == glm::uvec3(3, 1, 4)); + CHECK(id.coords() == glm::uvec3(3, 1, 2)); CHECK(id.x() == 3); CHECK(id.y() == 1); - CHECK(id.z() == 4); + CHECK(id.z() == 2); } TEST_CASE("Id interleave and deinterleave roundtrip", "[octree::Id]") { @@ -33,6 +33,9 @@ TEST_CASE("Id neighbour out of bounds returns nullopt", "[octree::Id]") { CHECK_FALSE(id.neighbour(glm::ivec3(-1, 0, 0)).has_value()); CHECK_FALSE(id.neighbour(glm::ivec3(0, -1, 0)).has_value()); CHECK_FALSE(id.neighbour(glm::ivec3(0, 0, -1)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(100, 0, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, Id::max_coord_on_level(id.level()), 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(Id::max_coord_on_level(id.level()))).has_value()); } TEST_CASE("Id parent returns nullopt at root level", "[octree::Id]") { @@ -41,10 +44,10 @@ TEST_CASE("Id parent returns nullopt at root level", "[octree::Id]") { } TEST_CASE("Id parent returns correct parent", "[octree::Id]") { - Id id(2, glm::uvec3(6, 4, 2)); + Id id(5, glm::uvec3(6, 4, 2)); auto parent = id.parent(); REQUIRE(parent.has_value()); - CHECK(parent->level() == 1); + CHECK(parent->level() == 4); CHECK(parent->coords() == glm::uvec3(3, 2, 1)); } From 5bac07d197d1118b7317c4aa6432b8c7055492e5 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 14:13:56 +0200 Subject: [PATCH 026/122] Make child and children return std::optional --- src/terrainbuilder/octree/id.h | 41 +++++++++++++++-------- src/terrainbuilder/octree/space.h | 8 +++-- src/terrainbuilder/octree/storage.h | 2 +- unittests/terrainbuilder/octree_id.cpp | 2 +- unittests/terrainbuilder/octree_space.cpp | 2 +- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/terrainbuilder/octree/id.h b/src/terrainbuilder/octree/id.h index 50c2f34..9961e0b 100644 --- a/src/terrainbuilder/octree/id.h +++ b/src/terrainbuilder/octree/id.h @@ -20,20 +20,20 @@ class Id { [[nodiscard]] static constexpr Level max_level() { return (sizeof(Index) * 8) / 3; } - [[nodiscard]] static constexpr Coord max_coord_on_level(Level level) { + [[nodiscard]] static constexpr Coord max_coord_on_level(const Level level) { return (1ull << level) - 1; } - [[nodiscard]] static constexpr Index max_index_on_level(Level level) { + [[nodiscard]] static constexpr Index max_index_on_level(const Level level) { return (1ull << (3 * level)) - 1; } - constexpr Id(Level level, Coords coords) + constexpr Id(const Level level, const Coords coords) : Id(level, interleave3(coords)) { } - constexpr Id(Level level, Index index) + constexpr Id(const Level level, const Index index) : _level(level), _index(index) { - assert(this->_level <= Id::max_level()); - assert(this->_index <= Id::max_index_on_level(this->_level)); + assert(level <= Id::max_level()); + assert(index <= Id::max_index_on_level(this->_level)); } [[nodiscard]] constexpr Level level() const { @@ -95,19 +95,27 @@ class Id { return Id(this->level() - 1, parent_coords); } - // TODO: make this return std::optional and check against max level? - [[nodiscard]] constexpr Id child(uint32_t child_index) const { + [[nodiscard]] constexpr std::optional child(uint32_t child_index) const { if (child_index > 7) { throw std::invalid_argument("Invalid child index (must be 0-7)"); } - return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); + if (!this->has_children()) { + return std::nullopt; + } + return this->_child(child_index); + } + + [[nodiscard]] constexpr std::optional> children() const { + if (!this->has_children()) { + return std::nullopt; + } + return std::array{ + this->_child(0), this->_child(1), this->_child(2), this->_child(3), + this->_child(4), this->_child(5), this->_child(6), this->_child(7)}; } - [[nodiscard]] constexpr std::array children() const { - return { - this->child(0), this->child(1), this->child(2), this->child(3), - this->child(4), this->child(5), this->child(6), this->child(7) - }; + [[nodiscard]] constexpr bool has_children() const { + return this->level() < Id::max_level(); } [[nodiscard]] constexpr bool is_root() const { @@ -126,6 +134,11 @@ class Id { Level _level; Index _index; + [[nodiscard]] constexpr Id _child(const uint32_t child_index) const { + assert(child_index <= 7); + return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); + } + [[nodiscard]] static constexpr Index interleave3(const Coords &coords) { assert(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); diff --git a/src/terrainbuilder/octree/space.h b/src/terrainbuilder/octree/space.h index d1ae7d2..9ec70d1 100644 --- a/src/terrainbuilder/octree/space.h +++ b/src/terrainbuilder/octree/space.h @@ -43,7 +43,7 @@ class Space { Id current_smallest_encompassing_node = root; while (true) { - const std::array children = current_smallest_encompassing_node.children(); + const std::array children = current_smallest_encompassing_node.children().value(); std::optional next_smallest; for (const auto &child : children) { @@ -73,14 +73,18 @@ class Space { } std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { + assert(target_level <= Id::max_level()); + Id current = root; const Bounds root_bounds = this->get_node_bounds(current); if (!root_bounds.contains_exclusive(point)) { return std::nullopt; } + // TODO: this could be much more efficient while (current.level() < target_level) { - for (const auto& child : current.children()) { + const auto children = current.children().value(); + for (const auto& child : children) { const Bounds child_bounds = this->get_node_bounds(child); if (child_bounds.contains_exclusive(point)) { current = child; diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainbuilder/octree/storage.h index bb8831b..f444c75 100644 --- a/src/terrainbuilder/octree/storage.h +++ b/src/terrainbuilder/octree/storage.h @@ -13,7 +13,7 @@ using Node = TerrainMesh; class Storage { public: - Storage(const std::filesystem::path &basePath) : base_path(basePath) {} + Storage(const std::filesystem::path &base_path) : base_path(base_path) {} std::optional load_node(const Id &id) const { const auto node_path = this->get_node_path(id); diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainbuilder/octree_id.cpp index 966f56e..bcaf784 100644 --- a/unittests/terrainbuilder/octree_id.cpp +++ b/unittests/terrainbuilder/octree_id.cpp @@ -53,7 +53,7 @@ TEST_CASE("Id parent returns correct parent", "[octree::Id]") { TEST_CASE("Id child returns correct child", "[octree::Id]") { Id parent(1, glm::uvec3(1, 1, 1)); - Id child = parent.child(5); + Id child = parent.child(5).value(); CHECK(child.level() == 2); CHECK((child.index_on_level() >> 3) == parent.index_on_level()); CHECK((child.index_on_level() & 7) == 5); diff --git a/unittests/terrainbuilder/octree_space.cpp b/unittests/terrainbuilder/octree_space.cpp index 6202c51..4ac8ffd 100644 --- a/unittests/terrainbuilder/octree_space.cpp +++ b/unittests/terrainbuilder/octree_space.cpp @@ -75,7 +75,7 @@ TEST_CASE("find_smallest_node_encompassing_bounds returns smallest valid node", } // Now check that no child of this node fully contains the target - for (const auto &child_id : id.children()) { + for (const auto &child_id : id.children().value()) { Bounds child_bounds = space.get_node_bounds(child_id); bool all_corners_inside = true; for (const auto &corner : radix::geometry::corners(target)) { From 3d19a299216f38e5b463732223552a3991333215 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Wed, 7 May 2025 15:01:21 +0200 Subject: [PATCH 027/122] Add WIP octree. Needs refactoring. --- src/CMakeLists.txt | 25 +- src/core/Application.cpp | 320 ++++++++++++------ src/core/Application.h | 12 +- src/core/Camera.cpp | 67 +++- src/core/Camera.h | 27 +- src/core/geometry/UnitCube.h | 34 ++ src/core/octree/id.h | 203 +++++++++++ src/core/octree/space.h | 278 +++++++++++++++ src/core/octree/storage.h | 46 +++ src/core/{ => shader}/GLUniformAbstractions.h | 0 src/core/{ => shader}/Shader.cpp | 0 src/core/{ => shader}/Shader.h | 0 src/core/{ => shader}/ShaderProgram.cpp | 5 + src/core/{ => shader}/ShaderProgram.h | 0 src/core/{ => shader}/Uniform.h | 0 src/core/{ => window}/Window.cpp | 116 +++++-- src/core/{ => window}/Window.h | 27 +- src/res/CMakeLists.txt | 4 +- src/res/shaders/basic.vert | 17 - .../shaders/{basic.frag => octree_lines.frag} | 3 +- src/res/shaders/octree_lines.vert | 27 ++ 21 files changed, 1038 insertions(+), 173 deletions(-) create mode 100644 src/core/geometry/UnitCube.h create mode 100644 src/core/octree/id.h create mode 100644 src/core/octree/space.h create mode 100644 src/core/octree/storage.h rename src/core/{ => shader}/GLUniformAbstractions.h (100%) rename src/core/{ => shader}/Shader.cpp (100%) rename src/core/{ => shader}/Shader.h (100%) rename src/core/{ => shader}/ShaderProgram.cpp (95%) rename src/core/{ => shader}/ShaderProgram.h (100%) rename src/core/{ => shader}/Uniform.h (100%) rename src/core/{ => window}/Window.cpp (58%) rename src/core/{ => window}/Window.h (59%) delete mode 100644 src/res/shaders/basic.vert rename src/res/shaders/{basic.frag => octree_lines.frag} (68%) create mode 100644 src/res/shaders/octree_lines.vert diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4c0c2f..7ce7e6b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,18 +79,35 @@ if(NOT TARGET spdlog) FetchContent_MakeAvailable(spdlog) endif() +if(NOT TARGET radix) + FetchContent_Declare(radix + GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git + GIT_TAG origin/main + SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix + SOURCE_SUBDIR src + ) + message(STATUS "Including radix") + FetchContent_MakeAvailable(radix) +endif() + add_executable(alpenite-browser main.cpp core/Application.cpp - core/Window.cpp - core/Shader.cpp - core/ShaderProgram.cpp + core/window/Window.cpp + core/shader/Shader.cpp + core/shader/ShaderProgram.cpp + core/shader/Uniform.h + core/shader/GLUniformAbstractions.h core/Buffer.cpp core/Camera.cpp utils/log/Log.cpp + core/geometry/UnitCube.h + + core/octree/id.h + core/octree/space.h ) -target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog) +target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog radix) target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/core/Application.cpp b/src/core/Application.cpp index 091d8b7..a88e1e5 100644 --- a/src/core/Application.cpp +++ b/src/core/Application.cpp @@ -5,21 +5,27 @@ // CMRC Resource Compiler #include -#include "Shader.h" -#include "ShaderProgram.h" + +#include "shader/Shader.h" +#include "shader/ShaderProgram.h" #include "Buffer.h" #include "Camera.h" +#include "geometry/UnitCube.h" +#include "octree/space.h" CMRC_DECLARE(res); Application::Application(std::string title, int width, int height) : m_title(title), m_width(width), m_height(height) { + m_nav_mode = false; + WindowConfig c = { .width = 1280, .height = 720, .title = "Alpenite Browser", - .resizeable = true, + .resizeable = false, + .msaa_samples = 4, .opengl_version = {4, 6}, .opengl_core_profile = true }; @@ -28,6 +34,14 @@ Application::Application(std::string title, int width, int height) init_glad(); init_gl(); + + if (c.msaa_samples > 0) { + glEnable(GL_MULTISAMPLE); + } + + m_movement_speed = 100000.0f; + m_roll_speed = 0.02f; + m_mouse_sensitivity = 50.0f; } void Application::run() { @@ -35,66 +49,80 @@ void Application::run() { double last_frame_time = glfwGetTime(); + LOG_INFO("Setting up key event callbacks"); + m_window->register_key_event(GLFW_PRESS, GLFW_KEY_TAB, [this]() { + toggle_nav_mode(); + + if (m_nav_mode) { + LOG_DEBUG("Entering Nav Mode"); + m_window->set_capture_mouse(true); + m_window->clear_accumulated_cursor_delta(); + } else { + LOG_DEBUG("Exiting Nav Mode"); + m_window->set_capture_mouse(false); + } + }); + + m_window->register_key_event(GLFW_PRESS, GLFW_KEY_ESCAPE, [this]() { + m_window->set_should_close(true); + }); + + m_window->register_scroll_event([this](glm::dvec2 scroll) { + float old_speed = m_movement_speed; + + double factor = 1.0f; + + if (scroll.y > 0) { + factor = 1.2f; + } else if (scroll.y < 0) { + factor = 0.8f; + } + + m_movement_speed = glm::max(1.0f, m_movement_speed * (float)factor); + LOG_DEBUG("Movement Speed: {} >> {}", old_speed, m_movement_speed); + }); + LOG_INFO("Setting up shaders"); - auto vertex_shader_code = RES.open("shaders/basic.vert"); - Shader vertex_shader(GL_VERTEX_SHADER); - vertex_shader.compile(std::string_view(vertex_shader_code.begin(), vertex_shader_code.end())); + auto vsc_octree_lines = RES.open("shaders/octree_lines.vert"); + Shader vs_octree_lines(GL_VERTEX_SHADER); + vs_octree_lines.compile(std::string_view(vsc_octree_lines.begin(), vsc_octree_lines.end())); - auto fragment_shader_code = RES.open("shaders/basic.frag"); - Shader fragment_shader(GL_FRAGMENT_SHADER); - fragment_shader.compile(std::string_view(fragment_shader_code.begin(), fragment_shader_code.end())); + auto fsc_octree_lines = RES.open("shaders/octree_lines.frag"); + Shader fs_octree_lines(GL_FRAGMENT_SHADER); + fs_octree_lines.compile(std::string_view(fsc_octree_lines.begin(), fsc_octree_lines.end())); - ShaderProgram shader_program; + ShaderProgram sp_octree_lines; - shader_program.attach(vertex_shader); - shader_program.attach(fragment_shader); - shader_program.link(); - shader_program.use(); + sp_octree_lines.attach(vs_octree_lines); + sp_octree_lines.attach(fs_octree_lines); + sp_octree_lines.link(); + sp_octree_lines.use(); - Uniform U_projection = shader_program.get_uniform("projection"); - Uniform U_view = shader_program.get_uniform("view"); + Uniform U_projection = sp_octree_lines.get_uniform("projection"); + Uniform U_view = sp_octree_lines.get_uniform("view"); LOG_INFO("Setting up camera"); CameraConfig camera_config = { - .fov_deg = 60.0f, + .fov_deg = 90.0f, .aspect_ratio = m_window->getAspectRatio(), - .near_plane = 0.1f, - .far_plane = 100.0f, + .near_plane = 1000.0f, + .far_plane = 200000000.0f, - .position = glm::vec3(0.0f, 0.0f, 5.0f), + .position = glm::vec3(0.0f, 0.0f, 10000000.0f), .target = glm::vec3(0.0f), .up = glm::vec3(0.0f, 1.0f, 0.0f), }; - Camera camera(camera_config); + m_camera = std::make_unique(camera_config); - U_projection.set(camera.projection_matrix()); - U_view.set(camera.view_matrix()); + U_projection.set(m_camera->projection_matrix()); + U_view.set(m_camera->view_matrix()); LOG_INFO("Setting up lines"); - std::vector vertices = { - glm::vec3(-1.0, -1.0, -1.0), //000 //#0 - glm::vec3(-1.0, 1.0, -1.0), //010 //#1 - glm::vec3( 1.0, 1.0, -1.0), //110 //#2 - glm::vec3( 1.0, -1.0, -1.0), //100 //#3 + std::vector vertices = UnitCube::vertices(); + std::vector indices = UnitCube::line_indices(); - glm::vec3(-1.0, -1.0, 1.0), //001 //#4 - glm::vec3(-1.0, 1.0, 1.0), //011 //#5 - glm::vec3( 1.0, 1.0, 1.0), //111 //#6 - glm::vec3( 1.0, -1.0, 1.0), //101 //#7 - }; - - std::vector indices = { - //Bottom Loop - 0, 1, 1, 2, 2, 3, 3, 0, - //Top Loop - 4, 5, 5, 6, 6, 7, 7, 4, - //Connecting Top and Bottom - 0, 4, - 1, 5, - 2, 6, - 3, 7 - }; + octree::Space space = octree::Space::earth(); unsigned int VAO; glGenVertexArrays(1, &VAO); @@ -102,100 +130,200 @@ void Application::run() { Buffer cube_ibo(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW); Buffer cube_vbo; + Buffer cube_instance_active_buffer; + Buffer cube_instance_model_buffer; cube_vbo.set_data(vertices); cube_ibo.set_data(indices); + // VERTICES cube_vbo.bind(); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL); glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL); + + // INSTANCE ACTIVE + cube_instance_active_buffer.bind(); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(float), NULL); + glVertexAttribDivisor(1, 1); + // INSTANCE MODEL MATRICES + cube_instance_model_buffer.bind(); + + size_t vec4_size = sizeof(glm::vec4); + + // LOC 2: COLUMN 0 + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void*)0); + glVertexAttribDivisor(2, 1); + + // LOC 3: COLUMN 1 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void*)(1 * vec4_size)); + glVertexAttribDivisor(3, 1); + + // LOC 4: COLUMN 2 + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void*)(2 * vec4_size)); + glVertexAttribDivisor(4, 1); + + // LOC 5: COLUMN 3 + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void*)(3 * vec4_size)); + glVertexAttribDivisor(5, 1); + + // INDICES cube_ibo.bind(); - //glEnable(GL_CULL_FACE); - //glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor(0.f, 0.f, 0.f, 1.f); - glm::dvec2 last_cursor_position = m_window->get_cursor_position() / m_window->get_window_size(); - - float default_movement_speed = 5.0f; - float mouse_sensitivity = 100.0f; - while (!m_window->should_close()) { const double current_frame_time = glfwGetTime(); const double frame_delta_time = current_frame_time - last_frame_time; last_frame_time = current_frame_time; m_window->poll_events(); + update_camera(frame_delta_time, U_view); - glm::dvec2 current_cursor_position = m_window->get_cursor_position(); - - if (m_window->is_mouse_button_pressed(GLFW_MOUSE_BUTTON_LEFT)) { - m_window->set_capture_mouse(true); + octree::OctreeRenderIntent rendering_intent = space.generate_octree_render_intent(octree::Id::root(), m_camera->get_position(), false); - const glm::dvec2 cursor_position_delta = (current_cursor_position - last_cursor_position) / m_window->get_window_size(); - glm::vec3 camera_rotation_delta = glm::vec3(cursor_position_delta.y, cursor_position_delta.x, 0.0f) * (float)frame_delta_time * mouse_sensitivity; + cube_instance_active_buffer.set_data(rendering_intent.instances_active); + cube_instance_model_buffer.set_data(rendering_intent.instances_model_mats); - camera.rotate(camera_rotation_delta); - } else { - m_window->set_capture_mouse(false); + if (rendering_intent.min_scene_distance.has_value() && m_camera->get_near() != rendering_intent.min_scene_distance.value()) { + m_camera->set_near(rendering_intent.min_scene_distance.value() * 0.5f); } - - - glm::vec3 local_movement_delta(0.0f); - float movement_speed = default_movement_speed; - - if (m_window->is_key_pressed(GLFW_KEY_LEFT_SHIFT)) { - movement_speed *= 2.0f; + if (rendering_intent.max_scene_distance.has_value() && m_camera->get_far() != rendering_intent.max_scene_distance.value()) { + m_camera->set_far(rendering_intent.max_scene_distance.value() * 1.5f); } - if (m_window->is_key_pressed(GLFW_KEY_W) || m_window->is_key_pressed(GLFW_KEY_UP)) { - local_movement_delta.z += 1.0f; - } - if (m_window->is_key_pressed(GLFW_KEY_S) || m_window->is_key_pressed(GLFW_KEY_DOWN)) { - local_movement_delta.z -= 1.0f; + if (m_camera->is_projection_matrix_outdated()) { + U_projection.set(m_camera->projection_matrix()); } - if (m_window->is_key_pressed(GLFW_KEY_D) || m_window->is_key_pressed(GLFW_KEY_RIGHT)) { - local_movement_delta.x += 1.0f; - } - if (m_window->is_key_pressed(GLFW_KEY_A) || m_window->is_key_pressed(GLFW_KEY_LEFT)) { - local_movement_delta.x -= 1.0f; - } + glm::dvec3 cam_pos = m_camera->get_position(); + float near = m_camera->get_near(); + float far = m_camera->get_far(); - if (m_window->is_key_pressed(GLFW_KEY_SPACE)) { - local_movement_delta.y += 1.0f; - } - if (m_window->is_key_pressed(GLFW_KEY_LEFT_CONTROL)) { - local_movement_delta.y -= 1.0f; - } - - if (glm::abs(local_movement_delta.x) + glm::abs(local_movement_delta.y) + glm::abs(local_movement_delta.z) != 0.0f) { - camera.move_local(local_movement_delta * (float)frame_delta_time * movement_speed); - } + std::string id_string; + + if (rendering_intent.closest_node.has_value()) { + auto id = rendering_intent.closest_node.value(); + + uint32_t level = id.level(); + uint32_t id_x = id.coords().x; + uint32_t id_y = id.coords().y; + uint32_t id_z = id.coords().z; - if (camera.is_view_matrix_outdated()) { - LOG_DEBUG("Camera view outdated"); - U_view.set(camera.view_matrix()); + id_string = std::vformat(" | CLOSEST ID: L{} {} {} {}", + std::make_format_args( + level, id_x, id_y, id_z + ) + ); } + octree::Coords coords = rendering_intent.closest_node.value().coords(); - last_cursor_position = current_cursor_position; + m_window->set_title_suffix(std::vformat(" | CAM POS: {:.2f}, {:.2f}, {:.2f} | Z-NEAR: {:.2f}, Z-FAR: {:.2f}{}", + std::make_format_args( + cam_pos.x, cam_pos.y, cam_pos.z, near, far, id_string + ) + )); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glPointSize(10.0f); - glDrawElements(GL_LINES, indices.size(), GL_UNSIGNED_INT, 0); + glLineWidth(2.0f); + glDrawElementsInstanced(GL_LINES, indices.size(), GL_UNSIGNED_INT, 0, rendering_intent.instance_count); m_window->swapBuffers(); } } +void Application::update_camera(float frame_delta_time, Uniform U_view) { + if (!m_camera) { + LOG_WARN("Trying to update non-initialized camera!"); + return; + } + + if (!m_nav_mode) { + return; + } + + /*glm::dvec2 scroll_delta = m_window->get_accumulated_scroll_delta(); + m_movement_speed = glm::max(m_movement_speed + glm::sign((float)scroll_delta.y), 0.0f);*/ + + + + float movement_speed = m_movement_speed; + float roll_speed = m_roll_speed; + float mouse_sensitivity = m_mouse_sensitivity; + + if (m_window->is_key_pressed(GLFW_KEY_LEFT_SHIFT)) { + movement_speed *= 5.0f; + roll_speed *= 1.5f; + } + + float roll = 0.0f; + if (m_window->is_key_pressed(GLFW_KEY_Q)) { + roll -= 1.00f; + } + if (m_window->is_key_pressed(GLFW_KEY_E)) { + roll += 1.00f; + } + + const glm::dvec2 cursor_position_delta = m_window->get_accumulated_cursor_delta(); + glm::vec3 camera_rotation_delta = glm::vec3(-cursor_position_delta.x, -cursor_position_delta.y, roll * roll_speed) * (float)frame_delta_time * mouse_sensitivity; + + if (glm::abs(camera_rotation_delta.x) + glm::abs(camera_rotation_delta.y) + glm::abs(camera_rotation_delta.z) != 0.0f) { + m_camera->rotate(camera_rotation_delta.x, camera_rotation_delta.y, camera_rotation_delta.z); + } + + glm::vec3 local_movement_delta(0.0f); + + if (m_window->is_key_pressed(GLFW_KEY_W) || m_window->is_key_pressed(GLFW_KEY_UP)) { + local_movement_delta.z += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_S) || m_window->is_key_pressed(GLFW_KEY_DOWN)) { + local_movement_delta.z -= 1.0f; + } + + if (m_window->is_key_pressed(GLFW_KEY_D) || m_window->is_key_pressed(GLFW_KEY_RIGHT)) { + local_movement_delta.x += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_A) || m_window->is_key_pressed(GLFW_KEY_LEFT)) { + local_movement_delta.x -= 1.0f; + } + + if (m_window->is_key_pressed(GLFW_KEY_SPACE)) { + local_movement_delta.y += 1.0f; + } + if (m_window->is_key_pressed(GLFW_KEY_LEFT_CONTROL)) { + local_movement_delta.y -= 1.0f; + } + + float movement_magnitude = glm::length(local_movement_delta); + local_movement_delta /= movement_magnitude; + + if (movement_magnitude != 0.0f) { + m_camera->move_local(local_movement_delta * (float)frame_delta_time * movement_speed); + } + + if (m_camera->is_view_matrix_outdated()) { + U_view.set(m_camera->view_matrix()); + } +} + Application::~Application() { LOG_INFO("Exiting"); } +void Application::toggle_nav_mode() { + m_nav_mode = !m_nav_mode; +} + void Application::init_glad() { // Load OpenGL functions, gladLoadGL returns the loaded version, 0 on error. int version = gladLoadGL(glfwGetProcAddress); diff --git a/src/core/Application.h b/src/core/Application.h index 314a72a..311f136 100644 --- a/src/core/Application.h +++ b/src/core/Application.h @@ -5,13 +5,16 @@ #include #include -#include "Window.h" +#include "window/Window.h" +#include "Camera.h" +#include "shader/Uniform.h" class Application { public: Application(std::string title, int width, int height); void run(); + void update_camera(float frame_delta_time, Uniform U_view); ~Application(); @@ -20,6 +23,13 @@ class Application { int m_width, m_height; std::unique_ptr m_window; + std::unique_ptr m_camera; + + float m_movement_speed, m_roll_speed, m_mouse_sensitivity; + + bool m_nav_mode; + + void toggle_nav_mode(); void init_glad(); void init_gl(); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 5f22b24..c54e5c1 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -9,40 +9,73 @@ Camera::Camera(CameraConfig config) : m_position(config.position), m_up(glm::normalize(config.up)){ - glm::vec3 forward = glm::normalize(config.target - m_position); + glm::dvec3 forward = glm::normalize(config.target - m_position); m_rotation = glm::quatLookAt(forward, m_up); update_projection_matrix(); update_view_matrix(); } -void Camera::rotate(glm::vec3 euler_radians_delta) { +void Camera::rotate(double delta_yaw, double delta_pitch, double delta_roll) { m_view_matrix_cache.reset(); - glm::vec3 euler_rot = glm::eulerAngles(m_rotation); - glm::vec3 new_euler_rot = euler_rot + euler_radians_delta; + glm::dquat pitch = glm::angleAxis(delta_pitch, get_local_right_dir()); + glm::dquat yaw = glm::angleAxis(delta_yaw, get_local_up_dir()); + glm::dquat roll = glm::angleAxis(delta_roll, get_local_forward_dir()); - new_euler_rot.x = glm::mod(new_euler_rot.x, glm::two_pi()); - new_euler_rot.y = glm::mod(new_euler_rot.y, glm::two_pi()); - new_euler_rot.z = glm::mod(new_euler_rot.z, glm::two_pi()); + glm::dquat rotation = yaw * pitch * roll; - LOG_DEBUG("{} / {} / {} => {} / {} / {}", euler_rot.x, euler_rot.y, euler_rot.z, new_euler_rot.x, new_euler_rot.y, new_euler_rot.z); - - m_rotation = glm::quat(new_euler_rot); + m_rotation = rotation * m_rotation; } -void Camera::move_local(glm::vec3 local_movement_delta) { +void Camera::move_local(glm::dvec3 local_movement_delta) { m_view_matrix_cache.reset(); - glm::vec3 right_dir = local_movement_delta.x * glm::normalize(m_rotation * glm::vec3(1.0f, 0.0f, 0.0f)); - glm::vec3 up_dir = local_movement_delta.y * glm::normalize(m_rotation * m_up); - glm::vec3 forward_dir = local_movement_delta.z * glm::normalize(m_rotation * glm::vec3(0.0f, 0.0f, -1.0f)); - - auto copy = glm::vec3(m_position); + glm::dvec3 right_dir = local_movement_delta.x * get_local_right_dir(); + glm::dvec3 up_dir = local_movement_delta.y * get_local_up_dir(); + glm::dvec3 forward_dir = local_movement_delta.z * get_local_forward_dir(); m_position += right_dir + up_dir + forward_dir; } +void Camera::set_near(float near) { + LOG_TRACE("SETTING NEAR: {}", near); + m_projection_matrix_cache.reset(); + + m_near_plane = near; +} + +void Camera::set_far(float far) { + LOG_TRACE("SETTING FAR: {}", far); + m_projection_matrix_cache.reset(); + + m_far_plane = far; +} + +float Camera::get_near() { + return m_near_plane; +} + +float Camera::get_far() { + return m_far_plane; +} + +glm::dvec3 Camera::get_position() { + return m_position; +} + +glm::dvec3 Camera::get_local_right_dir() { + return glm::normalize(m_rotation * glm::dvec3(1.0f, 0.0f, 0.0f)); +} + +glm::dvec3 Camera::get_local_up_dir() { + return glm::normalize(m_rotation * m_up); +} + +glm::dvec3 Camera::get_local_forward_dir() { + return glm::normalize(m_rotation * glm::dvec3(0.0f, 0.0f, -1.0f)); +} + bool Camera::is_view_matrix_outdated() { return !m_view_matrix_cache.has_value(); } @@ -66,7 +99,7 @@ glm::mat4 Camera::view_matrix() { void Camera::update_view_matrix() { if (!m_view_matrix_cache.has_value()) { glm::mat4 rotation = glm::mat4_cast(m_rotation); - glm::mat4 translation = glm::translate(glm::mat4(1.0f), m_position); + glm::mat4 translation = glm::translate(glm::dmat4(1.0f), m_position); //TODO: Use camera re-centering to mitigate precision losses at large values m_view_matrix_cache.emplace(glm::inverse(translation * rotation)); } } diff --git a/src/core/Camera.h b/src/core/Camera.h index 46b7200..6a56fee 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -9,17 +9,28 @@ struct CameraConfig { float near_plane = 0.1f; float far_plane = 100.0f; - glm::vec3 position = glm::vec3(0.0f, 0.0f, 5.0f); - glm::vec3 target = glm::vec3(0.0f); - glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); + glm::dvec3 position = glm::dvec3(0.0f, 0.0f, 5.0f); + glm::dvec3 target = glm::dvec3(0.0f); + glm::dvec3 up = glm::dvec3(0.0f, 1.0f, 0.0f); }; class Camera { public: Camera(CameraConfig config); - void rotate(glm::vec3 euler_delta); - void move_local(glm::vec3 local_movement_delta); + void rotate(double delta_yaw, double delta_pitch, double delta_roll); + void move_local(glm::dvec3 local_movement_delta); + void set_near(float near); + void set_far(float far); + + float get_near(); + float get_far(); + + glm::dvec3 get_position(); + + glm::dvec3 get_local_right_dir(); + glm::dvec3 get_local_up_dir(); + glm::dvec3 get_local_forward_dir(); bool is_view_matrix_outdated(); bool is_projection_matrix_outdated(); @@ -33,9 +44,9 @@ class Camera { float m_near_plane; float m_far_plane; - glm::vec3 m_up; - glm::vec3 m_position; - glm::quat m_rotation; + glm::dvec3 m_up; + glm::dvec3 m_position; + glm::dquat m_rotation; std::optional m_view_matrix_cache; std::optional m_projection_matrix_cache; diff --git a/src/core/geometry/UnitCube.h b/src/core/geometry/UnitCube.h new file mode 100644 index 0000000..891c8f5 --- /dev/null +++ b/src/core/geometry/UnitCube.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include + +class UnitCube { +public: + static constexpr std::vector vertices() { + return { + glm::vec3(-0.5, -0.5, -0.5), //000 //#0 + glm::vec3(-0.5, 0.5, -0.5), //010 //#1 + glm::vec3( 0.5, 0.5, -0.5), //110 //#2 + glm::vec3( 0.5, -0.5, -0.5), //100 //#3 + + glm::vec3(-0.5, -0.5, 0.5), //001 //#4 + glm::vec3(-0.5, 0.5, 0.5), //011 //#5 + glm::vec3( 0.5, 0.5, 0.5), //111 //#6 + glm::vec3( 0.5, -0.5, 0.5), //101 //#7 + }; + } + + static constexpr std::vector line_indices() { + return { + //Bottom Loop + 0, 1, 1, 2, 2, 3, 3, 0, + //Top Loop + 4, 5, 5, 6, 6, 7, 7, 4, + //Connecting Top and Bottom + 0, 4, + 1, 5, + 2, 6, + 3, 7 + }; + } +}; \ No newline at end of file diff --git a/src/core/octree/id.h b/src/core/octree/id.h new file mode 100644 index 0000000..0c8b454 --- /dev/null +++ b/src/core/octree/id.h @@ -0,0 +1,203 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace octree { + +using Level = uint32_t; +using Coord = uint32_t; +using Coords = glm::tvec3; +using Index = uint64_t; + +class Id { +public: + [[nodiscard]] static constexpr Level max_level() { + return (sizeof(Index) * 8) / 3; + } + [[nodiscard]] static constexpr Coord max_coord_on_level(const Level level) { + return (1ull << level) - 1; + } + [[nodiscard]] static constexpr Index max_index_on_level(const Level level) { + return (1ull << (3 * level)) - 1; + } + + constexpr Id(const Level level, const Coords coords) + : Id(level, interleave3(coords)) { + } + constexpr Id(const Level level, const Index index) + : _level(level), _index(index) { + assert(level <= Id::max_level()); + assert(index <= Id::max_index_on_level(this->_level)); + } + + [[nodiscard]] constexpr Level level() const { + return this->_level; + } + [[nodiscard]] constexpr Index index_on_level() const { + return this->_index; + } + [[nodiscard]] constexpr Coords coords() const { + return deinterleave3(this->index_on_level()); + } + [[nodiscard]] constexpr Coord x() const { + return this->coords().x; + } + [[nodiscard]] constexpr Coord y() const { + return this->coords().y; + } + [[nodiscard]] constexpr Coord z() const { + return this->coords().z; + } + + [[nodiscard]] constexpr std::optional neighbour(const glm::ivec3& d) const { + const Coord max_coord = Id::max_coord_on_level(this->level()); + const glm::ivec3 new_coords = glm::ivec3(this->coords()) + d; + if (glm::any(glm::lessThan(new_coords, glm::ivec3(0))) || glm::any(glm::greaterThan(new_coords, glm::ivec3(max_coord)))) { + return std::nullopt; + } + return Id(this->level(), Coords(new_coords)); + } + + [[nodiscard]] std::vector neighbours() const { + std::vector result; + result.reserve(26); + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + for (int dz = -1; dz <= 1; dz++) { + if (dx == 0 && dy == 0 && dz == 0) { + continue; // Skip the center itself + } + + const glm::ivec3 offset(dx, dy, dz); + const auto neighbour = this->neighbour({dx, dy, dz}); + if (!neighbour.has_value()) { + continue; + } + result.push_back(neighbour.value()); + } + } + } + return result; + } + + [[nodiscard]] constexpr std::optional parent() const { + if (this->level() == 0) { + return std::nullopt; + } + + const auto parent_coords = this->coords() / Coords(2); + return Id(this->level() - 1, parent_coords); + } + + [[nodiscard]] constexpr std::optional child(uint32_t child_index) const { + if (child_index > 7) { + throw std::invalid_argument("Invalid child index (must be 0-7)"); + } + if (!this->has_children()) { + return std::nullopt; + } + return this->_child(child_index); + } + + [[nodiscard]] constexpr std::optional> children() const { + if (!this->has_children()) { + return std::nullopt; + } + return std::array{ + this->_child(0), this->_child(1), this->_child(2), this->_child(3), + this->_child(4), this->_child(5), this->_child(6), this->_child(7)}; + } + + [[nodiscard]] constexpr bool has_children() const { + return this->level() < Id::max_level(); + } + + [[nodiscard]] constexpr bool is_root() const { + return this->level() == 0; + } + + [[nodiscard]] static constexpr Id root() { + return Id(0, 0); + } + + bool operator==(const Id &other) const { + return this->_level == other._level && this->_index == other._index; + } + +private: + Level _level; + Index _index; + + [[nodiscard]] constexpr Id _child(const uint32_t child_index) const { + assert(child_index <= 7); + return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); + } + + [[nodiscard]] static constexpr Index interleave3(const Coords &coords) { + assert(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); + + const Index x = coords.x; + const Index y = coords.y; + const Index z = coords.z; + + Index result = 0; + for (Level i = 0; i < Id::max_level(); i++) { + result |= ((x >> i) & 1) << (3 * i); + result |= ((y >> i) & 1) << (3 * i + 1); + result |= ((z >> i) & 1) << (3 * i + 2); + } + return result; + } + + [[nodiscard]] static constexpr Coords deinterleave3(Index index) { + Coord x = 0; + Coord y = 0; + Coord z = 0; + for (Level i = 0; i < Id::max_level(); i++) { + x |= ((index >> (3 * i)) & 1) << i; + y |= ((index >> (3 * i + 1)) & 1) << i; + z |= ((index >> (3 * i + 2)) & 1) << i; + } + return {x, y, z}; + } +}; + +} // namespace octree + +//#include +//#include +//template <> +//struct fmt::formatter { +// // Parses format specifications; here we ignore them. +// template +// constexpr auto parse(ParseContext &ctx) { +// return ctx.begin(); +// } +// +// // Format the Id object. +// template +// auto format(const octree::Id &id, FormatContext &ctx) { +// return fmt::format_to( +// ctx.out(), +// "Id(level={}, coords=({}, {}, {}), index={})", +// id.level(), id.x(), id.y(), id.z(), id.index_on_level()); +// } +//}; +// +//#include +//#include +//namespace octree{ +//inline std::string to_string(const octree::Id &id) { +// return fmt::format("{}", id); +//} +//inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { +// fmt::print(os, "{}", id); +// return os; +//} +//} diff --git a/src/core/octree/space.h b/src/core/octree/space.h new file mode 100644 index 0000000..aa7d068 --- /dev/null +++ b/src/core/octree/space.h @@ -0,0 +1,278 @@ +#pragma once + +#include + +#include "id.h" +#include +#include +#include + +namespace octree { +using Bounds = radix::geometry::Aabb3d; + +struct OctreeRenderIntent { + std::vector instances_active; + std::vector instances_model_mats; + size_t instance_count; + + std::optional min_scene_distance; + std::optional max_scene_distance; + + std::optional closest_node; +}; + +class Space { +public: + const Bounds bounds; + + static constexpr Space earth() { + const double max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) + const double extends = max_radius * 1.1; // TODO: how much padding do we want here + return Space(Bounds( + {-extends, -extends, -extends}, {extends, extends, extends})); + } + + std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { + // We don't want to recurse indefinitely if the bounds are empty. + const glm::dvec3 target_size = target_bounds.size(); + if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { + throw std::invalid_argument("target bounds cannot be empty"); + } + + const std::array corners = radix::geometry::corners(target_bounds); + + const Bounds root_bounds = get_node_bounds(root); + // Check if all points of the target bounds are inside the root bounds. + bool all_corners_inside_root = true; + for (const auto &corner : corners) { + if (!root_bounds.contains_inclusive(corner)) { + all_corners_inside_root = false; + break; + } + } + + if (!all_corners_inside_root) { + return std::nullopt; // Target bounds are outside the defined space. + } + + Id current_smallest_encompassing_node = root; + while (current_smallest_encompassing_node.has_children()) { + const std::array children = current_smallest_encompassing_node.children().value(); + std::optional next_smallest; + + for (const auto &child : children) { + const Bounds child_bounds = get_node_bounds(child); + bool all_corners_inside_child = true; + for (const auto &corner : corners) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside_child = false; + break; + } + } + + if (all_corners_inside_child) { + next_smallest = child; + break; // Found a child that fully contains the bounds, go deeper. + } + } + + if (next_smallest.has_value()) { + current_smallest_encompassing_node = next_smallest.value(); + } else { + break; // No child fully contains the bounds, so the current node is the smallest. + } + } + + return current_smallest_encompassing_node; + } + + std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { + assert(target_level <= Id::max_level()); + + Id current = root; + const Bounds root_bounds = this->get_node_bounds(current); + if (!root_bounds.contains_exclusive(point)) { + return std::nullopt; + } + + while (current.level() < target_level && current.has_children()) { + for (const auto& child : current.children().value()) { + const Bounds child_bounds = this->get_node_bounds(child); + if (child_bounds.contains_exclusive(point)) { + current = child; + break; + } + } + } + + return current; + } + + Bounds get_node_bounds(const Id &id) const { + const auto coords = id.coords(); + const uint32_t level = id.level(); + const uint32_t resolution = 1 << level; + + // Calculate the size of a node at this level + const glm::dvec3 bounds_size = bounds.size(); + const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); + + // Calculate the minimum point of the node + const glm::dvec3 min_bound = bounds.min; + const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; + + // Calculate the maximum point of the node + const glm::dvec3 node_max = node_min + node_size; + + Bounds node_bounds; + node_bounds.min = node_min; + node_bounds.max = node_max; + return node_bounds; + } + + OctreeRenderIntent generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only) { + // Defines under which ratio between dist(cam, node_bbox_centre) / node_bbox_size the node is split + // I.e.: dist = 2000 and node_bbox_size = 4000 -> ratio = 0.5 -> node would get refined + double refining_ratio = 0.5f; + + std::vector refining_ids; + refining_ids.push_back(root); + + std::vector instance_active; + std::vector instance_models; + + double closest_distance = std::numeric_limits::infinity(); + double farthest_distance = 0; + std::optional closest_index; + + std::optional closest; + std::optional farthest; + + + while (!refining_ids.empty()) { + Id current = refining_ids.back(); + refining_ids.pop_back(); + + Bounds current_bounds = get_node_bounds(current); + + double current_distance = glm::distance(current_bounds.centre(), cam_pos); + double current_ratio = current_distance / glm::length(current_bounds.size()); + + //LOG_DEBUG("DIST: {}, RATIO: {}", distance, current_ratio); + + if (current_ratio <= refining_ratio && current.has_children()) { + // Split node into 8 children, and add them to the refining list + for (Id child : current.children().value()) { + refining_ids.push_back(child); + } + } else { + // Don't split. Check whether to render this node + bool is_current_closest = false; + bool is_current_farthest = false; + + if (current_distance < closest_distance) { + closest_distance = current_distance; + is_current_closest = true; + closest = current; + } + if (current_distance > farthest_distance) { + farthest_distance = current_distance; + is_current_farthest = true; + farthest = current; + } + + if (!draw_neighbours_only) { + glm::dmat4 model_scale = glm::scale(glm::dmat4(1.0f), current_bounds.size()); + glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre()); + glm::mat4 model = model_translate * model_scale; + + instance_active.push_back(0.0f); + instance_models.push_back(glm::mat4(model)); + + if (is_current_closest) { + // The current node, is the closest to this point. Mark it as active and mark the previous closest (if any) as inactive + if (closest_index.has_value()) { + instance_active[closest_index.value()] = 0.0f; + } + closest_index = instance_active.size() - 1; + instance_active[closest_index.value()] = 1.0f; + } + } else { + if (is_current_closest) { + // The current node, is the closest to this point. Delete all nodes in the list + + instance_active.clear(); + instance_models.clear(); + + farthest_distance = current_distance; + farthest = current; + + // Add the current active node to the render list + glm::dmat4 model_scale = glm::scale(glm::dmat4(1.0f), current_bounds.size()); + glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre()); + glm::mat4 model = model_translate * model_scale; + + instance_active.push_back(1.0f); + instance_models.push_back(glm::mat4(model)); + + for (auto neighbour : current.neighbours()) { + Bounds neighbour_bounds = get_node_bounds(neighbour); + + double neighbour_distance = glm::distance(neighbour_bounds.centre(), cam_pos); + + glm::dmat4 neighbour_model_scale = glm::scale(glm::dmat4(1.0f), neighbour_bounds.size()); + glm::dmat4 neighbour_model_translate = glm::translate(glm::dmat4(1.0f), neighbour_bounds.centre()); + glm::mat4 neighbour_model = neighbour_model_translate * neighbour_model_scale; + + instance_active.push_back(0.0f); + instance_models.push_back(glm::mat4(neighbour_model)); + + if (neighbour_distance < closest_distance) { + closest_distance = current_distance; + closest = neighbour; + } + if (neighbour_distance > farthest_distance) { + farthest_distance = current_distance; + farthest = neighbour; + } + } + } + } + } + } + + OctreeRenderIntent rendering_intent{ + .instances_active = instance_active, + .instances_model_mats = instance_models, + .instance_count = instance_models.size(), + }; + + if (closest.has_value()) { + rendering_intent.closest_node = closest; + rendering_intent.min_scene_distance = std::numeric_limits::infinity(); + for (glm::dvec3 closest_corner : radix::geometry::corners(get_node_bounds(closest.value()))) { + double dist = glm::distance(closest_corner, cam_pos); + + if (dist < rendering_intent.min_scene_distance) { + rendering_intent.min_scene_distance = dist; + } + } + } + if (farthest.has_value()) { + rendering_intent.max_scene_distance = 0; + for (glm::dvec3 farthest_corner : radix::geometry::corners(get_node_bounds(farthest.value()))) { + double dist = glm::distance(farthest_corner, cam_pos); + + if (dist > rendering_intent.max_scene_distance) { + rendering_intent.max_scene_distance = dist; + } + } + } + + return rendering_intent; + } + +private: +}; + +} // namespace octree diff --git a/src/core/octree/storage.h b/src/core/octree/storage.h new file mode 100644 index 0000000..bb8831b --- /dev/null +++ b/src/core/octree/storage.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include + +#include "id.h" +#include "mesh/io.h" +#include "mesh/terrain_mesh.h" + +namespace octree { +using Node = TerrainMesh; + +class Storage { + public: + Storage(const std::filesystem::path &basePath) : base_path(basePath) {} + + std::optional load_node(const Id &id) const { + const auto node_path = this->get_node_path(id); + const auto result = io::load_mesh_from_path(node_path); + if (result.has_value()) { + return result.value(); + } else { + return std::nullopt; + } + } + + bool save_node(const Id &id, const Node &node) const { + const auto node_path = this->get_node_path(id); + const auto result = io::save_mesh_to_path(node_path, node); + return result.has_value(); + } + + bool has_node(const Id &id) const { + return std::filesystem::exists(this->get_node_path(id)); + } + + private: + std::filesystem::path get_node_path(const Id &id) const { + return base_path / std::to_string(id.level()) / std::to_string(id.x()) / (std::to_string(id.y()) + ".gltf"); + } + + private: + const std::filesystem::path base_path; +}; +} diff --git a/src/core/GLUniformAbstractions.h b/src/core/shader/GLUniformAbstractions.h similarity index 100% rename from src/core/GLUniformAbstractions.h rename to src/core/shader/GLUniformAbstractions.h diff --git a/src/core/Shader.cpp b/src/core/shader/Shader.cpp similarity index 100% rename from src/core/Shader.cpp rename to src/core/shader/Shader.cpp diff --git a/src/core/Shader.h b/src/core/shader/Shader.h similarity index 100% rename from src/core/Shader.h rename to src/core/shader/Shader.h diff --git a/src/core/ShaderProgram.cpp b/src/core/shader/ShaderProgram.cpp similarity index 95% rename from src/core/ShaderProgram.cpp rename to src/core/shader/ShaderProgram.cpp index 48a8788..888e2b8 100644 --- a/src/core/ShaderProgram.cpp +++ b/src/core/shader/ShaderProgram.cpp @@ -61,6 +61,11 @@ void ShaderProgram::link() { m_uniform_locations.insert(std::make_pair(name.substr(0, length), location)); LOG_DEBUG("Uniform #{} Name: {}", i, name.substr(0, length)); } + + // load all attribute locations + + GLint attribute_count; + glGetProgramiv(m_handle, GL_ACTIVE_ATTRIBUTES, &attribute_count); } GLuint ShaderProgram::handle() { diff --git a/src/core/ShaderProgram.h b/src/core/shader/ShaderProgram.h similarity index 100% rename from src/core/ShaderProgram.h rename to src/core/shader/ShaderProgram.h diff --git a/src/core/Uniform.h b/src/core/shader/Uniform.h similarity index 100% rename from src/core/Uniform.h rename to src/core/shader/Uniform.h diff --git a/src/core/Window.cpp b/src/core/window/Window.cpp similarity index 58% rename from src/core/Window.cpp rename to src/core/window/Window.cpp index 155fdd6..496ecac 100644 --- a/src/core/Window.cpp +++ b/src/core/window/Window.cpp @@ -4,51 +4,67 @@ std::atomic Window::glfw_initialized(false); std::atomic Window::window_instances(0); -Window::Window(WindowConfig config) : m_width(config.width), m_height(config.height), m_title(config.title) { +Window::Window(WindowConfig config) : m_width(config.width), m_height(config.height), m_title(config.title), m_msaa_samples(config.msaa_samples) { update_window_count(1); const auto [gl_major_version, gl_minor_version] = config.opengl_version; - LOG_GL_INFO("Creating window with context: OpenGL {}.{}{}", gl_major_version, gl_minor_version, config.opengl_core_profile ? " CORE" : ""); + LOG_GL_INFO("Creating window \"{}\" with context: OpenGL {}.{}{}", m_title, gl_major_version, gl_minor_version, config.opengl_core_profile ? " CORE" : ""); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, gl_major_version); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, gl_minor_version); glfwWindowHint(GLFW_OPENGL_PROFILE, config.opengl_core_profile ? GLFW_OPENGL_CORE_PROFILE : GLFW_OPENGL_ANY_PROFILE); glfwWindowHint(GLFW_RESIZABLE, config.resizeable ? GLFW_TRUE : GLFW_FALSE); + glfwWindowHint(GLFW_SAMPLES, config.msaa_samples); #ifdef _DEBUG // enable debug mode LOG_GL_DEBUG("Setting OpenGL Debug Context"); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_FALSE); - // doesnt work: glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); #endif // _DEBUG - m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), NULL, NULL); - if (m_window == NULL) { + m_handle = glfwCreateWindow(m_width, m_height, m_title.c_str(), NULL, NULL); + if (m_handle == NULL) { update_window_count(-1); LOG_GL_FATAL_AND_EXIT("Failed to create GLFW window"); } - glfwMakeContextCurrent(m_window); + glfwMakeContextCurrent(m_handle); // Set the required callback functions - glfwSetKeyCallback(m_window, key_callback); - glfwSetMouseButtonCallback(m_window, mouse_button_callback); - glfwSetCursorPosCallback(m_window, cursor_position_callback); + glfwSetKeyCallback(m_handle, key_callback); + glfwSetMouseButtonCallback(m_handle, mouse_button_callback); + glfwSetCursorPosCallback(m_handle, cursor_position_callback); + glfwSetScrollCallback(m_handle, scroll_callback); + + // Initialize current and last cursor positions + glfwGetCursorPos(m_handle, &m_current_unfetched_cursor_pos.x, &m_current_unfetched_cursor_pos.y); + clear_accumulated_cursor_delta(); + + m_min_dimension = glm::min(m_width, m_height); + m_max_dimension = glm::max(m_width, m_height); // Link a pointer to this class with the window handle, to be able to access this class from the callbacks - glfwSetWindowUserPointer(m_window, (void*)this); + glfwSetWindowUserPointer(m_handle, (void*)this); } Window::~Window() { LOG_GL_INFO("Destroying Window \"{}\"", m_title); - glfwDestroyWindow(m_window); + glfwDestroyWindow(m_handle); update_window_count(-1); } bool Window::should_close() { - return glfwWindowShouldClose(m_window); + return glfwWindowShouldClose(m_handle); +} + +void Window::set_should_close(bool should_close) { + glfwSetWindowShouldClose(m_handle, should_close ? GL_TRUE : GL_FALSE); +} + +void Window::set_title_suffix(std::string suffix) { + glfwSetWindowTitle(m_handle, (m_title + suffix).c_str()); } void Window::poll_events() { @@ -56,20 +72,46 @@ void Window::poll_events() { } void Window::swapBuffers() { - glfwSwapBuffers(m_window); + glfwSwapBuffers(m_handle); +} + +bool Window::is_mouse_captured() { + return glfwGetInputMode(m_handle, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; +} + +void Window::toggle_capture_mouse() { + if (is_mouse_captured()) { + set_capture_mouse(false); + } else { + set_capture_mouse(true); + } } void Window::set_capture_mouse(bool captured) { if (captured) { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(m_handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(m_handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); } else { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetInputMode(m_handle, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); + glfwSetInputMode(m_handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } } +glm::dvec2 Window::get_accumulated_cursor_delta() { + glm::dvec2 delta = (m_current_unfetched_cursor_pos - m_last_fetched_cursor_pos) / (double)m_max_dimension; + + clear_accumulated_cursor_delta(); + + return delta; +} + +void Window::clear_accumulated_cursor_delta() { + m_last_fetched_cursor_pos = m_current_unfetched_cursor_pos;; +} + glm::dvec2 Window::get_cursor_position() { glm::dvec2 cursor_position; - glfwGetCursorPos(m_window, &cursor_position.x, &cursor_position.y); + glfwGetCursorPos(m_handle, &cursor_position.x, &cursor_position.y); return cursor_position; } @@ -97,6 +139,20 @@ bool Window::is_mouse_button_pressed(int button) { return result->second; } +void Window::register_key_event(int action, int key, std::function callback) { + m_key_callbacks.try_emplace({ action, key }, std::vector>(0)); + + auto callbacks = m_key_callbacks.find({ action, key }); + + if (callbacks != m_key_callbacks.end()) { + callbacks->second.push_back(callback); + } +} + +void Window::register_scroll_event(std::function callback) { + m_scroll_callbacks.push_back(callback); +} + float Window::getAspectRatio() { return (float)m_width / (float)m_height; } @@ -108,21 +164,25 @@ void Window::glfw_error_callback(int error, const char* description) { void Window::key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { Window* w = (Window*)glfwGetWindowUserPointer(window); - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GL_TRUE); - } - if (!w->m_key_states.contains(key)) { w->m_key_states.emplace(key, false); } if (action == GLFW_PRESS) { - LOG_DEBUG("KEY {} PRESS", key); w->m_key_states[key] = true; } else if (action == GLFW_RELEASE) { - LOG_DEBUG("KEY {} RELEASE", key); w->m_key_states[key] = false; } + + w->m_key_callbacks.try_emplace({action, key}, std::vector>(0)); + + auto callbacks = w->m_key_callbacks.find({ action, key }); + + if (callbacks != w->m_key_callbacks.end()) { + for (auto callback : callbacks->second) { + callback(); + } + } } void Window::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { @@ -142,8 +202,16 @@ void Window::mouse_button_callback(GLFWwindow* window, int button, int action, i void Window::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { Window* w = (Window*)glfwGetWindowUserPointer(window); - w->m_current_cursor_pos.x = xpos; - w->m_current_cursor_pos.y = ypos; + w->m_current_unfetched_cursor_pos.x = xpos; + w->m_current_unfetched_cursor_pos.y = ypos; +} + +void Window::scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { + Window* w = (Window*)glfwGetWindowUserPointer(window); + + for (auto callback : w->m_scroll_callbacks) { + callback(glm::dvec2(xoffset, yoffset)); + } } void Window::update_window_count(int delta) { diff --git a/src/core/Window.h b/src/core/window/Window.h similarity index 59% rename from src/core/Window.h rename to src/core/window/Window.h index f3c7241..14d763b 100644 --- a/src/core/Window.h +++ b/src/core/window/Window.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include #include @@ -10,6 +11,7 @@ struct WindowConfig { int height = 720; std::string title = "Window Title"; bool resizeable = true; + int msaa_samples = 4; std::tuple opengl_version = { 4, 6 }; bool opengl_core_profile = true; @@ -21,35 +23,54 @@ class Window { ~Window(); bool should_close(); + void set_should_close(bool should_close); + + void set_title_suffix(std::string suffix); + void poll_events(); void swapBuffers(); + bool is_mouse_captured(); + void toggle_capture_mouse(); void set_capture_mouse(bool captured); + + glm::dvec2 get_accumulated_cursor_delta(); + void clear_accumulated_cursor_delta(); glm::dvec2 get_cursor_position(); glm::dvec2 get_window_size(); bool is_key_pressed(int key); bool is_mouse_button_pressed(int key); + void register_key_event(int action, int key, std::function callback); + void register_scroll_event(std::function callback); + float getAspectRatio(); private: static std::atomic window_instances; static std::atomic glfw_initialized; - int m_width, m_height; + int m_width, m_height, m_max_dimension, m_min_dimension; std::string m_title; + int m_msaa_samples; - GLFWwindow* m_window; + GLFWwindow* m_handle; std::map m_mouse_button_states; std::map m_key_states; - glm::dvec2 m_current_cursor_pos; + + glm::dvec2 m_last_fetched_cursor_pos; + glm::dvec2 m_current_unfetched_cursor_pos; + + std::map, std::vector>> m_key_callbacks; + std::vector> m_scroll_callbacks; static void glfw_error_callback(int error, const char* description); static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos); + static void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); static void update_window_count(int delta); }; diff --git a/src/res/CMakeLists.txt b/src/res/CMakeLists.txt index 4f92c69..47c7430 100644 --- a/src/res/CMakeLists.txt +++ b/src/res/CMakeLists.txt @@ -12,7 +12,7 @@ cmrc_add_resource_library( NAMESPACE res # ADD NEW RESOURCES AFTER HERE - shaders/basic.vert - shaders/basic.frag + shaders/octree_lines.vert + shaders/octree_lines.frag # shaders/select.csh ) diff --git a/src/res/shaders/basic.vert b/src/res/shaders/basic.vert deleted file mode 100644 index b356d89..0000000 --- a/src/res/shaders/basic.vert +++ /dev/null @@ -1,17 +0,0 @@ -#version 460 core - -layout (location = 0) in vec3 pos; - -uniform mat4 view; -uniform mat4 projection; - -out VS_OUT { - vec4 world_pos; -} vs_out; - -void main() -{ - vs_out.world_pos = projection * view * vec4(pos, 1.0); - - gl_Position = vs_out.world_pos; -} diff --git a/src/res/shaders/basic.frag b/src/res/shaders/octree_lines.frag similarity index 68% rename from src/res/shaders/basic.frag rename to src/res/shaders/octree_lines.frag index beac6d6..b15c84d 100644 --- a/src/res/shaders/basic.frag +++ b/src/res/shaders/octree_lines.frag @@ -2,10 +2,11 @@ in VS_OUT { vec4 world_pos; + vec4 color; } fs_in; out vec4 FragColor; void main() { - FragColor = vec4(1.0f); + FragColor = fs_in.color; } diff --git a/src/res/shaders/octree_lines.vert b/src/res/shaders/octree_lines.vert new file mode 100644 index 0000000..d2ebb5e --- /dev/null +++ b/src/res/shaders/octree_lines.vert @@ -0,0 +1,27 @@ +#version 460 core + +layout (location = 0) in vec3 pos; +layout (location = 1) in float instance_active; // 0: false, 1: true +layout (location = 2) in mat4 model; //loc 2: column 0 + //loc 3: column 1 + //loc 4: column 2 + //loc 5: column 3 + +uniform mat4 view; +uniform mat4 projection; + +out VS_OUT { + vec4 world_pos; + vec4 color; +} vs_out; + +void main() +{ + vs_out.world_pos = model * vec4(pos, 1.0); + vs_out.color = mix(vec4(0.1f, 0.1f, 0.1f, 0.5f), vec4(1.0f, 1.0f, 0.0f, 1.0f), instance_active); + + vec4 view_space = view * vs_out.world_pos; + view_space.z += 0.001f * instance_active; + + gl_Position = projection * view_space; +} From dcaf9f4433357fc887f05a06b1cfa24f319ee66a Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Wed, 7 May 2025 16:16:06 +0200 Subject: [PATCH 028/122] add cmake params to the cache version --- cmake/SetupCMakeProject.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/SetupCMakeProject.cmake b/cmake/SetupCMakeProject.cmake index 1fde788..2a35653 100644 --- a/cmake/SetupCMakeProject.cmake +++ b/cmake/SetupCMakeProject.cmake @@ -64,7 +64,7 @@ function(alp_setup_cmake_project arg_NAME) set(version_var "ALP_INSTALLED_${arg_NAME}_VERSION") set(path_var "ALP_INSTALLED_${arg_NAME}_PATH") - if(DEFINED ${version_var} AND "${${version_var}}" STREQUAL "${arg_COMMITISH}" AND DEFINED ${path_var} AND EXISTS "${${path_var}}") + if(DEFINED ${version_var} AND "${${version_var}}" STREQUAL "${arg_COMMITISH}${arg_CMAKE_ARGUMENTS}" AND DEFINED ${path_var} AND EXISTS "${${path_var}}") list(PREPEND CMAKE_PREFIX_PATH "${${path_var}}") set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE) return() @@ -83,7 +83,7 @@ function(alp_setup_cmake_project arg_NAME) set(${path_var} "${install_dir}" CACHE PATH "Install path for ${arg_NAME}" FORCE) - set(${version_var} "${arg_COMMITISH}" CACHE STRING "Installed commit/tag for ${arg_NAME}" FORCE) + set(${version_var} "${arg_COMMITISH}${arg_CMAKE_ARGUMENTS}" CACHE STRING "Installed commit/tag for $ + build flags" FORCE) endfunction() From 543c666fb5b7e5974025618f9708b382773c5d9c Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Wed, 7 May 2025 16:16:37 +0200 Subject: [PATCH 029/122] thin down opencv --- cmake/SetupGDAL.cmake | 1 - cmake/SetupOpenCV.cmake | 44 +++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 6 +++--- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 cmake/SetupOpenCV.cmake diff --git a/cmake/SetupGDAL.cmake b/cmake/SetupGDAL.cmake index 9d19258..93f8564 100644 --- a/cmake/SetupGDAL.cmake +++ b/cmake/SetupGDAL.cmake @@ -44,7 +44,6 @@ function(alp_setup_gdal) -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=OFF - -DGDAL_USE_JPEG=OFF -DGDAL_USE_ICONV=OFF ) diff --git a/cmake/SetupOpenCV.cmake b/cmake/SetupOpenCV.cmake new file mode 100644 index 0000000..71a069b --- /dev/null +++ b/cmake/SetupOpenCV.cmake @@ -0,0 +1,44 @@ +############################################################################# +# AlpineMaps.org +# Copyright (C) 2025 Adam Celarek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +############################################################################# + +if(NOT COMMAND alp_setup_cmake_project) + include(${CMAKE_CURRENT_LIST_DIR}/SetupCMakeProject.cmake) +endif() + +function(alp_setup_opencv version) + alp_setup_cmake_project(opencv + URL https://github.com/opencv/opencv.git COMMITISH ${version} + CMAKE_ARGUMENTS + -DBUILD_TESTS=OFF + -DBUILD_PERF_TESTS=OFF + -DBUILD_EXAMPLES=OFF + -DBUILD_opencv_apps=OFF + -DBUILD_opencv_apps=OFF + -DBUILD_opencv_python3=OFF + -DBUILD_opencv_java=OFF + -DBUILD_opencv_world=OFF + -DWITH_OPENGL=OFF + -DWITH_GSTREAMER=OFF + -DWITH_FFMPEG=OFF + -DWITH_JPEG=OFF -DWITH_PNG=OFF -DWITH_TIFF=OFF + -DWITH_GTK=OFF -DWITH_QT=OFF + -DBUILD_LIST=core,imgproc + ) + find_package(OpenCV REQUIRED) +endfunction() + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d17371..89361cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH add_library(Eigen3 INTERFACE) target_include_directories(Eigen3 INTERFACE ${eigen_SOURCE_DIR}) -alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF) +alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF "-DBOOST_INCLUDE_LIBRARIES='graph'") find_package(Boost CONFIG REQUIRED) include(../cmake/SetupGDAL.cmake) @@ -28,8 +28,8 @@ alp_setup_gdal(GDAL_VERSION v3.10.3 PROJ_VERSION 9.6.0) alp_setup_cmake_project(cgal URL https://github.com/CGAL/cgal.git COMMITISH "v6.0.1" CMAKE_ARGUMENTS -DCGAL_HEADER_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF) find_package(CGAL REQUIRED) -alp_setup_cmake_project(opencv URL https://github.com/opencv/opencv.git COMMITISH 4.11.0 CMAKE_ARGUMENTS -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_opencv_apps=OFF) -find_package(OpenCV REQUIRED) +include(../cmake/SetupOpenCV.cmake) +alp_setup_opencv(4.11.0) alp_add_git_repository(cgltf URL https://github.com/jkuhlmann/cgltf COMMITISH 7331a5adf4b0fde15f0e682a5803e4f17137e0ad DO_NOT_ADD_SUBPROJECT) add_library(cgltf INTERFACE) From eded55f4d7fc772ce13062ffed2967f7c65394d5 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 18:44:08 +0200 Subject: [PATCH 030/122] Fix holes between node meshes --- src/terrainbuilder/mesh_builder.cpp | 39 ++++++++++++----------- src/terrainlib/mesh/terrain_mesh.cpp | 20 ++++++++++++ src/terrainlib/mesh/terrain_mesh.h | 1 + unittests/terrainbuilder/mesh2.cpp | 47 ++++++++++++++++++---------- 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index 2aac57a..fe740e8 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -7,16 +7,15 @@ #include #include #include +#include #include "Dataset.h" #include "mesh/terrain_mesh.h" #include "srs.h" #include "raster.h" - #include "log.h" #include "mesh_builder.h" #include "raw_dataset_reader.h" -#include namespace terrainbuilder::mesh { @@ -172,19 +171,21 @@ TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bo } // Calculate epsilon to merge newly created vertices + const double max_edge_length = calculate_max_edge_length(mesh).value(); const double average_edge_length = estimate_average_edge_length(mesh).value(); const double epsilon = average_edge_length / 1000; std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); // Construct 6 axis-aligned clipping planes from the bounding box - const std::array, 6> planes = { - radix::geometry::Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left - radix::geometry::Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right - radix::geometry::Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom - radix::geometry::Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top - radix::geometry::Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near - radix::geometry::Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far + using Plane = radix::geometry::Plane; + const std::array planes = { + Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left + Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right + Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom + Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top + Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near + Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far }; std::vector new_positions = mesh.positions; @@ -201,14 +202,16 @@ TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bo mesh.positions[source_triangle.y], mesh.positions[source_triangle.z]}; - uint16_t inside_count = 0; - for (const auto &vertex : triangle) { - if (bounds.contains_inclusive(vertex)) { - inside_count += 1; - } - } + const uint8_t inside_count = std::count_if(triangle.begin(), triangle.end(), [&](const auto &vertex) { + return bounds.contains_inclusive(vertex); + }); if (inside_count == 0) { - continue; + // Triangle vertices are not inside the bounds, however there can still be intersection + if (std::any_of(triangle.begin(), triangle.end(), [&](const auto &vertex) { + return radix::geometry::distance_sq(bounds, vertex) > max_edge_length * max_edge_length; + })) { + continue; + } } if (inside_count == source_triangle.length()) { new_triangles.push_back(source_triangle); @@ -218,8 +221,6 @@ TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bo // Start with the original triangle // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); - assert(!clipped_triangles.empty()); - for (const auto &clipped_triangle : clipped_triangles) { glm::uvec3 decomposed_triangle; for (size_t i = 0; i < clipped_triangle.size(); i++) { @@ -241,7 +242,7 @@ TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bo if (it != seen_vertices.cend()) { vertex_index = it->second; } - + } // Add a new vertex diff --git a/src/terrainlib/mesh/terrain_mesh.cpp b/src/terrainlib/mesh/terrain_mesh.cpp index f71ea7b..ace0553 100644 --- a/src/terrainlib/mesh/terrain_mesh.cpp +++ b/src/terrainlib/mesh/terrain_mesh.cpp @@ -64,6 +64,26 @@ std::optional estimate_average_edge_length(const TerrainMesh &mesh, cons return total_length / edge_count; } +std::optional calculate_max_edge_length(const TerrainMesh &mesh) { + if (mesh.face_count() == 0) { + return std::nullopt; + } + + double max_length = 0.0; + for (const auto &tri : mesh.triangles) { + const glm::dvec3 &a = mesh.positions[tri.x]; + const glm::dvec3 &b = mesh.positions[tri.y]; + const glm::dvec3 &c = mesh.positions[tri.z]; + + const double ab = glm::distance(a, b); + const double bc = glm::distance(b, c); + const double ca = glm::distance(c, a); + + max_length = std::max({ab, bc, ca, max_length}); + } + return max_length; +} + std::vector find_isolated_vertices(const TerrainMesh& mesh) { std::vector connected; connected.resize(mesh.vertex_count()); diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index 627196f..d68d8df 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -59,6 +59,7 @@ radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes); std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size = 1000); +std::optional calculate_max_edge_length(const TerrainMesh &mesh); std::vector find_isolated_vertices(const TerrainMesh& mesh); size_t remove_isolated_vertices(TerrainMesh& mesh); diff --git a/unittests/terrainbuilder/mesh2.cpp b/unittests/terrainbuilder/mesh2.cpp index 362b29a..006c6aa 100644 --- a/unittests/terrainbuilder/mesh2.cpp +++ b/unittests/terrainbuilder/mesh2.cpp @@ -24,8 +24,10 @@ #include #include +#include #include #include +#include #include "../catch2_helpers.h" #include "Dataset.h" @@ -38,15 +40,17 @@ #include "mesh/io.h" -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point3; -typedef CGAL::Surface_mesh SurfaceMesh; -typedef SurfaceMesh::Vertex_index VertexIndex; -typedef SurfaceMesh::Edge_index EdgeIndex; -typedef SurfaceMesh::Halfedge_index HalfEdgeIndex; -typedef SurfaceMesh::Face_index FaceIndex; -typedef boost::graph_traits::vertex_descriptor VertexDescriptor; -typedef boost::graph_traits::halfedge_descriptor HalfedgeDescriptor; +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point3 = Kernel::Point_3; +using SurfaceMesh = CGAL::Surface_mesh; + +using VertexIndex = SurfaceMesh::Vertex_index; +using EdgeIndex = SurfaceMesh::Edge_index; +using HalfEdgeIndex = SurfaceMesh::Halfedge_index; +using FaceIndex = SurfaceMesh::Face_index; + +using VertexDescriptor = boost::graph_traits::vertex_descriptor; +using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; Point3 glm2cgal(glm::dvec3 point) { return Point3(point[0], point[1], point[2]); @@ -72,7 +76,7 @@ SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { return cgal_mesh; } -void check_mesh(const TerrainMesh &mesh) { +void check_mesh_basics(const TerrainMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); CHECK(cgal_mesh.is_valid(true)); CHECK(CGAL::is_triangle_mesh(cgal_mesh)); @@ -84,10 +88,21 @@ void check_no_holes(const TerrainMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); std::vector border_cycles; CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); - const size_t nb_holes = border_cycles.size(); + const size_t nb_holes = border_cycles.size() - 1; // outer edge is a boundary cycle CHECK(nb_holes == 0); } +size_t count_connected_components(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + using CcMap = CGAL::Unique_hash_map; + using CcPropertyMap = boost::associative_property_map; + + CcMap cc_map; + CcPropertyMap cc_pmap(cc_map); + const size_t num = CGAL::Polygon_mesh_processing::connected_components(cgal_mesh, cc_pmap); + return num; +} + void check_uvs(const TerrainMesh &mesh) { REQUIRE(mesh.uvs.size() == mesh.positions.size()); @@ -219,7 +234,7 @@ TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuil check_uvs(mesh); check_duplicate_vertices(mesh.positions); check_duplicate_triangles(mesh.triangles); - check_mesh(mesh); + check_mesh_basics(mesh); } const std::vector positions_in_target_srs = srs::transform_points(mesh_srs, target_srs, mesh.positions); @@ -287,7 +302,7 @@ TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); const octree::Space space = octree::Space::earth(); - const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 16).value(); + const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 17).value(); std::vector nodes = summit_node.neighbours(); nodes.push_back(summit_node); @@ -312,9 +327,9 @@ TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { } CHECK(node_meshes.size() >= 3); - const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-8); - const std::filesystem::path mesh_path = "/mnt/e/Code/TU/2023S/Project/terrain-builder/build/unittests/mesh.glb"; - io::save_mesh_to_path(mesh_path, merged_mesh, io::SaveOptions{.texture_format = ".png"}); + const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-6); + check_mesh_basics(merged_mesh); check_non_empty(merged_mesh); check_no_holes(merged_mesh); + CHECK(count_connected_components(merged_mesh) == 1); } \ No newline at end of file From ad87ed1736a414fa0b50bd4f6b5429222bf98227 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 18:44:15 +0200 Subject: [PATCH 031/122] Fix octree id tests --- unittests/terrainbuilder/octree_id.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainbuilder/octree_id.cpp index bcaf784..1a5ecd8 100644 --- a/unittests/terrainbuilder/octree_id.cpp +++ b/unittests/terrainbuilder/octree_id.cpp @@ -34,8 +34,8 @@ TEST_CASE("Id neighbour out of bounds returns nullopt", "[octree::Id]") { CHECK_FALSE(id.neighbour(glm::ivec3(0, -1, 0)).has_value()); CHECK_FALSE(id.neighbour(glm::ivec3(0, 0, -1)).has_value()); CHECK_FALSE(id.neighbour(glm::ivec3(100, 0, 0)).has_value()); - CHECK_FALSE(id.neighbour(glm::ivec3(0, Id::max_coord_on_level(id.level()), 0)).has_value()); - CHECK_FALSE(id.neighbour(glm::ivec3(Id::max_coord_on_level(id.level()))).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(0, Id::max_coord_on_level(id.level()) + 1, 0)).has_value()); + CHECK_FALSE(id.neighbour(glm::ivec3(Id::max_coord_on_level(id.level()) + 1)).has_value()); } TEST_CASE("Id parent returns nullopt at root level", "[octree::Id]") { From 1208dc49b934f952d8b923d40debe5159be4f963 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 18:46:31 +0200 Subject: [PATCH 032/122] Minor refactoring --- src/terrainbuilder/main.cpp | 10 +- src/terrainbuilder/octree/utils.cpp | 2 - src/terrainbuilder/octree/utils.h | 10 - src/terrainbuilder/tile_provider.h | 1 - src/terrainlib/mesh/terrain_mesh.h | 16 +- src/terrainlib/srs.h | 6 + unittests/CMakeLists.txt | 8 +- unittests/terrainbuilder/mesh.cpp | 416 ++++++++++++++++------------ unittests/terrainbuilder/mesh2.cpp | 335 ---------------------- 9 files changed, 261 insertions(+), 543 deletions(-) delete mode 100644 src/terrainbuilder/octree/utils.cpp delete mode 100644 src/terrainbuilder/octree/utils.h delete mode 100644 unittests/terrainbuilder/mesh2.cpp diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index 9263bfb..c116b50 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -95,14 +95,8 @@ int run(std::span args) { Dataset dataset(dataset_path); - OGRSpatialReference target_bounds_srs; - target_bounds_srs.SetFromUserInput(target_srs_input.c_str()); - target_bounds_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - OGRSpatialReference mesh_srs; - mesh_srs.SetFromUserInput(mesh_srs_input.c_str()); - mesh_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - + OGRSpatialReference target_bounds_srs = srs::from_user_input(target_srs_input); + OGRSpatialReference mesh_srs = srs::from_user_input(mesh_srs_input); OGRSpatialReference texture_srs = srs::webmercator(); radix::geometry::Aabb3d target_bounds; diff --git a/src/terrainbuilder/octree/utils.cpp b/src/terrainbuilder/octree/utils.cpp deleted file mode 100644 index 2916c30..0000000 --- a/src/terrainbuilder/octree/utils.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "utils.h" - diff --git a/src/terrainbuilder/octree/utils.h b/src/terrainbuilder/octree/utils.h deleted file mode 100644 index 6eb734b..0000000 --- a/src/terrainbuilder/octree/utils.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "id.h" - -#include -#include - -namespace octree { - -} // namespace octree diff --git a/src/terrainbuilder/tile_provider.h b/src/terrainbuilder/tile_provider.h index 76fbd56..5a8b238 100644 --- a/src/terrainbuilder/tile_provider.h +++ b/src/terrainbuilder/tile_provider.h @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index d68d8df..d441dda 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -61,9 +61,9 @@ radix::geometry::Aabb<3, double> calculate_bounds(std::span m std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size = 1000); std::optional calculate_max_edge_length(const TerrainMesh &mesh); -std::vector find_isolated_vertices(const TerrainMesh& mesh); -size_t remove_isolated_vertices(TerrainMesh& mesh); -size_t remove_triangles_of_negligible_size(TerrainMesh& mesh, const double threshold_percentage_of_average = 0.001); +std::vector find_isolated_vertices(const TerrainMesh &mesh); +size_t remove_isolated_vertices(TerrainMesh & mesh); +size_t remove_triangles_of_negligible_size(TerrainMesh & mesh, const double threshold_percentage_of_average = 0.001); bool compare_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2); bool compare_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2); @@ -76,20 +76,20 @@ inline auto find_duplicate_triangles(Triangles& triangles, bool ignore_orientati return std::unique(std::begin(triangles), std::end(triangles), ignore_orientation ? compare_equality_triangles_ignore_orientation : compare_equality_triangles); } template <> -inline auto find_duplicate_triangles(TerrainMesh &mesh, bool ignore_orientation) { +inline auto find_duplicate_triangles(TerrainMesh& mesh, bool ignore_orientation) { return find_duplicate_triangles(mesh.triangles, ignore_orientation); } void remove_duplicate_triangles(TerrainMesh& mesh, bool ignore_orientation = true); -void remove_duplicate_triangles(std::vector &triangles, bool ignore_orientation = true); +void remove_duplicate_triangles(std::vector& triangles, bool ignore_orientation = true); std::unordered_map> create_edge_to_triangle_index_mapping(const TerrainMesh &mesh); -std::vector count_vertex_adjacent_triangles(const TerrainMesh& mesh); +std::vector count_vertex_adjacent_triangles(const TerrainMesh &mesh); -std::vector find_non_manifold_edges(const TerrainMesh& mesh); +std::vector find_non_manifold_edges(const TerrainMesh &mesh); std::vector find_single_non_manifold_triangle_indices(const TerrainMesh &mesh); void remove_single_non_manifold_triangles(TerrainMesh& mesh); -void sort_and_normalize_triangles(TerrainMesh &mesh); +void sort_and_normalize_triangles(TerrainMesh& mesh); void sort_and_normalize_triangles(std::span triangles); void validate_mesh(const TerrainMesh &mesh); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index ea6c608..c6fe994 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -295,6 +295,12 @@ inline OGRSpatialReference from_epsg(uint32_t epsg) { srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); return srs; } +inline OGRSpatialReference from_user_input(const std::string& user_input) { + OGRSpatialReference srs; + srs.SetFromUserInput(user_input.c_str()); + srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + return srs; +} inline OGRSpatialReference ecef() { return from_epsg(4978); } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 2af3f18..4fae74b 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -84,11 +84,9 @@ add_executable(unittests_terrainbuilder catch2_helpers.h terrainbuilder/octree_id.cpp terrainbuilder/octree_space.cpp - terrainbuilder/mesh2.cpp - # TODO: - # terrainbuilder/mesh_io.cpp - # terrainbuilder/mesh.cpp - # terrainbuilder/texture.cpp + terrainbuilder/mesh.cpp + terrainbuilder/mesh_io.cpp + terrainbuilder/texture.cpp ) target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain CGAL::CGAL) diff --git a/unittests/terrainbuilder/mesh.cpp b/unittests/terrainbuilder/mesh.cpp index 296091f..72f4eb4 100644 --- a/unittests/terrainbuilder/mesh.cpp +++ b/unittests/terrainbuilder/mesh.cpp @@ -18,35 +18,39 @@ *****************************************************************************/ #include +#include -#include #include #include +#include #include #include -#include #include #include #include "../catch2_helpers.h" #include "Dataset.h" -#include "ctb/GlobalMercator.hpp" -#include "ctb/GlobalGeodetic.hpp" -#include "ctb/Grid.hpp" +#include "merge.h" +#include "mesh/terrain_mesh.h" +#include "mesh_builder.h" +#include "octree/id.h" +#include "octree/space.h" #include "srs.h" #include "mesh/io.h" -#include "mesh_builder.h" -#include "mesh/terrain_mesh.h" -#include "merge.h" -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point3; -typedef CGAL::Surface_mesh SurfaceMesh; -typedef boost::graph_traits::vertex_descriptor VertexDescriptor; -typedef boost::graph_traits::edge_descriptor EdgeDescriptor; -typedef boost::graph_traits::face_descriptor FaceDescriptor; +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point3 = Kernel::Point_3; +using SurfaceMesh = CGAL::Surface_mesh; + +using VertexIndex = SurfaceMesh::Vertex_index; +using EdgeIndex = SurfaceMesh::Edge_index; +using HalfEdgeIndex = SurfaceMesh::Halfedge_index; +using FaceIndex = SurfaceMesh::Face_index; + +using VertexDescriptor = boost::graph_traits::vertex_descriptor; +using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; Point3 glm2cgal(glm::dvec3 point) { return Point3(point[0], point[1], point[2]); @@ -61,10 +65,10 @@ SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { } for (const glm::uvec3 &triangle : mesh.triangles) { - const CGAL::SM_Face_index face = cgal_mesh.add_face( - CGAL::SM_Vertex_index(triangle.x), - CGAL::SM_Vertex_index(triangle.y), - CGAL::SM_Vertex_index(triangle.z)); + const FaceIndex face = cgal_mesh.add_face( + VertexIndex(triangle.x), + VertexIndex(triangle.y), + VertexIndex(triangle.z)); REQUIRE(face != SurfaceMesh::null_face()); } @@ -72,29 +76,31 @@ SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { return cgal_mesh; } -size_t count_connected_components(const SurfaceMesh &mesh) { - typedef CGAL::Unique_hash_map CcMap; - typedef boost::associative_property_map CcPropertyMap; - - CcMap cc_map; - CcPropertyMap cc_pmap(cc_map); - const size_t num = CGAL::Polygon_mesh_processing::connected_components(mesh, cc_pmap); - return num; +void check_mesh_basics(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + CHECK(cgal_mesh.is_valid(true)); + CHECK(CGAL::is_triangle_mesh(cgal_mesh)); + CHECK(CGAL::is_valid_polygon_mesh(cgal_mesh, true)); + CHECK_FALSE(CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); } -glm::dvec3 apply_transform(OGRCoordinateTransformation *transform, const glm::dvec3 &v) { - glm::dvec3 result(v); - REQUIRE(transform->Transform(1, &result.x, &result.y, &result.z)); - return result; +void check_no_holes(const TerrainMesh &mesh) { + const SurfaceMesh cgal_mesh = mesh2cgal(mesh); + std::vector border_cycles; + CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); + const size_t nb_holes = border_cycles.size() - 1; // outer edge is a boundary cycle + CHECK(nb_holes == 0); } -void check_mesh_is_plane(const TerrainMesh &mesh) { +size_t count_connected_components(const TerrainMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); - REQUIRE(cgal_mesh.is_valid(true)); - REQUIRE(CGAL::is_triangle_mesh(cgal_mesh)); - REQUIRE(CGAL::is_valid_polygon_mesh(cgal_mesh, true)); - REQUIRE(count_connected_components(cgal_mesh) == 1); - REQUIRE(!CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); + using CcMap = CGAL::Unique_hash_map; + using CcPropertyMap = boost::associative_property_map; + + CcMap cc_map; + CcPropertyMap cc_pmap(cc_map); + const size_t num = CGAL::Polygon_mesh_processing::connected_components(cgal_mesh, cc_pmap); + return num; } void check_uvs(const TerrainMesh &mesh) { @@ -111,157 +117,219 @@ void check_non_empty(const TerrainMesh &mesh) { REQUIRE(mesh.triangles.size() > 0); } -TEST_CASE("can build reference mesh tiles", "[terrainbuilder]") { - const std::vector> tile_test_cases = { - {"tiny tile", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::Id(23, glm::uvec2(4430412, 2955980), radix::tile::Scheme::SlippyMap)}, - {"small tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap)}, - {"tile on the border", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(18, glm::uvec2(138457, 169781), radix::tile::Scheme::Tms)} -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED - {"tile slightly larger than dataset", "/austria/pizbuin_1m_mgi.tif", radix::tile::Id(11, glm::uvec2(1081, 721), radix::tile::Scheme::SlippyMap)}, - {"huge tile", "/austria/pizbuin_1m_epsg3857.tif", radix::tile::Id(6, glm::uvec2(33, 41), radix::tile::Scheme::Tms)}, - {"giant tile", "/austria/at_mgi.tif", radix::tile::Id(1, glm::uvec2(1, 0), radix::tile::Scheme::SlippyMap)}, -#endif - }; - - - - const ctb::Grid grid = ctb::GlobalMercator(); - std::vector> test_cases = { - {"custom bounds", "/austria/pizbuin_1m_epsg4326.tif", radix::tile::SrsBounds(glm::dvec2(1127962, 5915858), glm::dvec2(1127966, 5915882))}}; - for (const auto &test : tile_test_cases) { - const auto [test_name, dataset_suffix, target_tile] = test; - const radix::tile::SrsBounds tile_bounds = grid.srsBounds(target_tile, false); - test_cases.push_back({test_name, dataset_suffix, tile_bounds}); +struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); } +}; - for (const auto &test : test_cases) { - const auto [test_name, dataset_suffix, target_bounds] = test; - - DYNAMIC_SECTION(test_name) { - const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); - Dataset dataset(dataset_path); - - OGRSpatialReference webmercator_srs; - webmercator_srs.importFromEPSG(3857); - webmercator_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - radix::tile::SrsBounds output_tile_bounds; - radix::tile::SrsBounds output_texture_bounds; - - output_tile_bounds = target_bounds; - output_texture_bounds = target_bounds; - const TerrainMesh mesh = terrainbuilder::mesh::build_reference_mesh_tile( - dataset, - ecef_srs, - grid.getSRS(), output_tile_bounds, - webmercator_srs, output_texture_bounds, - terrainbuilder::Border(0), - false) - .value(); - - check_non_empty(mesh); - check_uvs(mesh); - check_mesh_is_plane(mesh); - - // check all vertices inside bounds - const std::unique_ptr transform_ecef_webmercator = srs::transformation(ecef_srs, webmercator_srs); - for (const glm::dvec3 ecef_position : mesh.positions) { - const glm::dvec3 webmercator_position = apply_transform(transform_ecef_webmercator.get(), ecef_position); - REQUIRE(target_bounds.contains_inclusive(webmercator_position)); - } +struct DVec3Equal { + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } +}; - // TODO: also test inclusive bounds (but this requires reconstructing the quads of the mesh) +void check_duplicate_vertices(const std::vector &positions) { + std::unordered_set seen; + for (const auto &pos : positions) { + REQUIRE(seen.insert(pos).second); + } +} +/* +void check_duplicate_vertices(const std::vector &positions, double epsilon=1e-8) { + for (size_t i = 0; i < positions.size(); i++) { + for (size_t j = i + 1; j < positions.size(); j++) { + REQUIRE(glm::distance(positions[i], positions[j]) > epsilon); } } } +*/ -TEST_CASE("neighbouring tiles fit together", "[terrainbuilder]") { - const ctb::Grid grid = ctb::GlobalMercator(); - const std::string dataset_suffix = "/austria/pizbuin_1m_epsg3857.tif"; - const std::array tiles = radix::tile::Id(20, glm::uvec2(553801, 369497), radix::tile::Scheme::SlippyMap).children(); - - std::vector tile_meshes; - for (const radix::tile::Id &tile : tiles) { - const radix::tile::SrsBounds tile_bounds = grid.srsBounds(tile, false); - DYNAMIC_SECTION(tile) { - const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); - Dataset dataset(dataset_path); - - OGRSpatialReference webmercator_srs; - webmercator_srs.importFromEPSG(3857); - webmercator_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - radix::tile::SrsBounds output_tile_bounds; - radix::tile::SrsBounds output_texture_bounds; - - output_tile_bounds = tile_bounds; - output_texture_bounds = tile_bounds; - const TerrainMesh mesh = terrainbuilder::mesh::build_reference_mesh_tile( - dataset, - ecef_srs, - grid.getSRS(), output_tile_bounds, - webmercator_srs, output_texture_bounds, - terrainbuilder::Border(0, 1, 1, 0), - true).value(); +void check_duplicate_triangles(std::vector triangles) { + const auto duplicate_triangles = find_duplicate_triangles(triangles, true); + CHECK(duplicate_triangles == triangles.end()); +} - tile_meshes.push_back(mesh); - } - } +template +radix::geometry::Aabb bounds_around_point(const glm::vec centre, const T margin) { + radix::geometry::Aabb bounds; + bounds.min = centre - glm::vec(margin); + bounds.max = centre + glm::vec(margin); + return bounds; +} - const TerrainMesh merged_mesh = merge::merge_meshes(tile_meshes, 0.1); - check_non_empty(merged_mesh); - check_mesh_is_plane(merged_mesh); +radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { + const double infinity = std::numeric_limits::infinity(); + const glm::dvec3 min(bounds2d.min, -infinity); + const glm::dvec3 max(bounds2d.max, infinity); + return radix::geometry::Aabb3d(min, max); } -TEST_CASE("neighbouring tiles fit together repeatedly", "[terrainbuilder]") { - const ctb::Grid grid = ctb::GlobalMercator(); - const std::string dataset_suffix = "/austria/innenstadt_gs_1m_mgi.tif"; - - const radix::tile::Id root_tile_id(16, glm::uvec2(35748, 22724), radix::tile::Scheme::SlippyMap); - std::vector child_meshes; - for (const radix::tile::Id child_tile_id : root_tile_id.children()) { - std::vector grand_child_meshes; - for (const radix::tile::Id grand_child_tile_id : child_tile_id.children()) { - const radix::tile::SrsBounds grand_child_tile_bounds = grid.srsBounds(grand_child_tile_id, false); - DYNAMIC_SECTION(grand_child_tile_id) { - const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); - Dataset dataset(dataset_path); - - OGRSpatialReference webmercator_srs; - webmercator_srs.importFromEPSG(3857); - webmercator_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - OGRSpatialReference ecef_srs; - ecef_srs.importFromEPSG(4978); - ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - - radix::tile::SrsBounds output_tile_bounds; - radix::tile::SrsBounds output_texture_bounds; - - output_tile_bounds = grand_child_tile_bounds; - output_texture_bounds = grand_child_tile_bounds; - const TerrainMesh grand_child_mesh = terrainbuilder::mesh::build_reference_mesh_tile( - dataset, - ecef_srs, - grid.getSRS(), output_tile_bounds, - webmercator_srs, output_texture_bounds, - terrainbuilder::Border(0, 1, 1, 0), - true).value(); - - grand_child_meshes.push_back(grand_child_mesh); +TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuilder]") { + struct TestData { + std::string path_suffix; + radix::geometry::Aabb3d target_bounds; + OGRSpatialReference target_srs; + OGRSpatialReference mesh_srs; + double resolution; // in m + }; + + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const glm::dvec3 steffl_wgs84(16.3735655, 48.2083264, 204); + const glm::dvec3 steffl_ecef = srs::transform_point(wgs84_srs, ecef_srs, steffl_wgs84); + + const std::vector test_data{ + {"/austria/pizbuin_1m_epsg4326.tif", + extend_bounds_to_3d(bounds_around_point(glm::dvec2(pizbuin_summit_wgs84), 0.0001)), + wgs84_srs, + wgs84_srs, + 1}, + {"/austria/pizbuin_1m_mgi.tif", + bounds_around_point(pizbuin_summit_ecef, 50 * 1.), + ecef_srs, + ecef_srs, + 1}, + {"/austria/vienna_20m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 20.), + ecef_srs, + ecef_srs, + 20}, + {"/austria/at_100m_mgi.tif", + bounds_around_point(steffl_ecef, 50 * 100.), + ecef_srs, + ecef_srs, + 100}}; + + for (const auto &data : test_data) { + DYNAMIC_SECTION(data.path_suffix) { + Dataset dataset(std::filesystem::path(ATB_TEST_DATA_DIR).concat(data.path_suffix)); + const auto source_srs = dataset.srs(); + const auto &mesh_srs = data.mesh_srs; + const auto &target_srs = data.target_srs; + const auto &target_bounds = data.target_bounds; + const auto resolution = data.resolution; + + radix::tile::SrsBounds texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + mesh_srs, + target_srs, target_bounds, + source_srs, texture_bounds); + if (!result) { + FAIL("Failed to build mesh: " << result.error()); + } + const TerrainMesh mesh = result.value(); + + SECTION("Basic mesh properties") { + check_non_empty(mesh); + check_uvs(mesh); + check_duplicate_vertices(mesh.positions); + check_duplicate_triangles(mesh.triangles); + check_mesh_basics(mesh); + } + + const std::vector positions_in_target_srs = srs::transform_points(mesh_srs, target_srs, mesh.positions); + SECTION("Vertices within target bounds") { + for (const auto &position : positions_in_target_srs) { + REQUIRE(radix::geometry::Aabb2d(target_bounds).contains_inclusive(glm::dvec2(position))); + REQUIRE(target_bounds.contains_inclusive(position)); + } + } + + SECTION("Some vertices on bounds (clipping check)") { + std::vector vertices_on_bounds; + for (const glm::dvec3 position : positions_in_target_srs) { + if (!target_bounds.contains_exclusive(position)) { + vertices_on_bounds.push_back(position); + } + } + CHECK(vertices_on_bounds.size() > 10); + } + + SECTION("Matches dataset resolution") { + const auto positions_in_source_srs = srs::transform_points(mesh_srs, source_srs, mesh.positions); + auto flat_positions_in_source_srs = positions_in_source_srs; + for (auto &pos : flat_positions_in_source_srs) { + pos.z = 0.0; + } + const auto flat_positions_in_ecef_srs = srs::transform_points(source_srs, ecef_srs, flat_positions_in_source_srs); + + const auto target_bounds_2d = radix::geometry::Aabb2d(target_bounds); + const auto padding = target_bounds_2d.size() * 0.1; + const auto inner_min = target_bounds_2d.min + padding; + const auto inner_max = target_bounds_2d.max - padding; + const radix::geometry::Aabb2d inner_bounds_2d{inner_min, inner_max}; + + std::vector filtered_triangles; + for (const auto &tri : mesh.triangles) { + const glm::dvec3 &a = positions_in_target_srs[tri.x]; + const glm::dvec3 &b = positions_in_target_srs[tri.y]; + const glm::dvec3 &c = positions_in_target_srs[tri.z]; + if (inner_bounds_2d.contains_inclusive(a) && + inner_bounds_2d.contains_inclusive(b) && + inner_bounds_2d.contains_inclusive(c)) { + filtered_triangles.push_back(tri); + } + } + TerrainMesh inside_flat_mesh; + inside_flat_mesh.positions = flat_positions_in_ecef_srs; + inside_flat_mesh.triangles = filtered_triangles; + + const auto avg_edge_length = estimate_average_edge_length(inside_flat_mesh); + REQUIRE(avg_edge_length.has_value()); + const auto expected_avg_edge_length = ((1 + 1 + std::sqrt(3)) / 3) * resolution; + CHECK(avg_edge_length.value() == Catch::Approx(expected_avg_edge_length).margin(expected_avg_edge_length * 0.2)); } } + } +} - const TerrainMesh child_mesh = merge::merge_meshes(grand_child_meshes, 0.1); - child_meshes.push_back(child_mesh); +TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { + const auto mgi_srs = srs::mgi(); + const auto ecef_srs = srs::ecef(); + const auto wgs84_srs = srs::wgs84(); + const auto webmercator_srs = srs::webmercator(); + + const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); + const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); + const octree::Space space = octree::Space::earth(); + const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 17).value(); + std::vector nodes = summit_node.neighbours(); + nodes.push_back(summit_node); + + const std::string dataset_suffix = "/austria/pizbuin_1m_mgi.tif"; + const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); + Dataset dataset(dataset_path); + + std::vector node_meshes; + for (const octree::Id &node : nodes) { + const octree::Bounds node_bounds = space.get_node_bounds(node); + radix::tile::SrsBounds output_texture_bounds; + const auto result = terrainbuilder::mesh::build_reference_mesh_patch( + dataset, + ecef_srs, + ecef_srs, node_bounds, + webmercator_srs, output_texture_bounds); + if (!result.has_value()) { + continue; + } + const TerrainMesh mesh = result.value(); + node_meshes.push_back(mesh); } + CHECK(node_meshes.size() >= 3); - const TerrainMesh mesh = merge::merge_meshes(child_meshes, 0.1); - check_non_empty(mesh); - check_mesh_is_plane(mesh); -} + const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-6); + check_mesh_basics(merged_mesh); + check_non_empty(merged_mesh); + check_no_holes(merged_mesh); + CHECK(count_connected_components(merged_mesh) == 1); +} \ No newline at end of file diff --git a/unittests/terrainbuilder/mesh2.cpp b/unittests/terrainbuilder/mesh2.cpp deleted file mode 100644 index 006c6aa..0000000 --- a/unittests/terrainbuilder/mesh2.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * Copyright (C) 2022 alpinemaps.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "../catch2_helpers.h" -#include "Dataset.h" -#include "merge.h" -#include "mesh/terrain_mesh.h" -#include "mesh_builder.h" -#include "octree/id.h" -#include "octree/space.h" -#include "srs.h" - -#include "mesh/io.h" - -using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using Point3 = Kernel::Point_3; -using SurfaceMesh = CGAL::Surface_mesh; - -using VertexIndex = SurfaceMesh::Vertex_index; -using EdgeIndex = SurfaceMesh::Edge_index; -using HalfEdgeIndex = SurfaceMesh::Halfedge_index; -using FaceIndex = SurfaceMesh::Face_index; - -using VertexDescriptor = boost::graph_traits::vertex_descriptor; -using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; - -Point3 glm2cgal(glm::dvec3 point) { - return Point3(point[0], point[1], point[2]); -} - -SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { - SurfaceMesh cgal_mesh; - - for (const glm::dvec3 &position : mesh.positions) { - const CGAL::SM_Vertex_index vertex = cgal_mesh.add_vertex(glm2cgal(position)); - REQUIRE(vertex != SurfaceMesh::null_vertex()); - } - - for (const glm::uvec3 &triangle : mesh.triangles) { - const FaceIndex face = cgal_mesh.add_face( - VertexIndex(triangle.x), - VertexIndex(triangle.y), - VertexIndex(triangle.z)); - - REQUIRE(face != SurfaceMesh::null_face()); - } - - return cgal_mesh; -} - -void check_mesh_basics(const TerrainMesh &mesh) { - const SurfaceMesh cgal_mesh = mesh2cgal(mesh); - CHECK(cgal_mesh.is_valid(true)); - CHECK(CGAL::is_triangle_mesh(cgal_mesh)); - CHECK(CGAL::is_valid_polygon_mesh(cgal_mesh, true)); - CHECK_FALSE(CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); -} - -void check_no_holes(const TerrainMesh &mesh) { - const SurfaceMesh cgal_mesh = mesh2cgal(mesh); - std::vector border_cycles; - CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); - const size_t nb_holes = border_cycles.size() - 1; // outer edge is a boundary cycle - CHECK(nb_holes == 0); -} - -size_t count_connected_components(const TerrainMesh &mesh) { - const SurfaceMesh cgal_mesh = mesh2cgal(mesh); - using CcMap = CGAL::Unique_hash_map; - using CcPropertyMap = boost::associative_property_map; - - CcMap cc_map; - CcPropertyMap cc_pmap(cc_map); - const size_t num = CGAL::Polygon_mesh_processing::connected_components(cgal_mesh, cc_pmap); - return num; -} - -void check_uvs(const TerrainMesh &mesh) { - REQUIRE(mesh.uvs.size() == mesh.positions.size()); - - for (const glm::dvec2 uv : mesh.uvs) { - REQUIRE(glm::all(glm::greaterThanEqual(uv, glm::dvec2(0)))); - REQUIRE(glm::all(glm::lessThanEqual(uv, glm::dvec2(1)))); - } -} - -void check_non_empty(const TerrainMesh &mesh) { - REQUIRE(mesh.positions.size() > 0); - REQUIRE(mesh.triangles.size() > 0); -} - -struct DVec3Hash { - std::size_t operator()(const glm::dvec3 &v) const { - std::size_t h1 = std::hash{}(v.x); - std::size_t h2 = std::hash{}(v.y); - std::size_t h3 = std::hash{}(v.z); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } -}; - -struct DVec3Equal { - bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { - return glm::all(glm::epsilonEqual(a, b, 1e-8)); - } -}; - -void check_duplicate_vertices(const std::vector &positions) { - std::unordered_set seen; - for (const auto &pos : positions) { - REQUIRE(seen.insert(pos).second); - } -} -/* -void check_duplicate_vertices(const std::vector &positions, double epsilon=1e-8) { - for (size_t i = 0; i < positions.size(); i++) { - for (size_t j = i + 1; j < positions.size(); j++) { - REQUIRE(glm::distance(positions[i], positions[j]) > epsilon); - } - } -} -*/ - -void check_duplicate_triangles(std::vector triangles) { - const auto duplicate_triangles = find_duplicate_triangles(triangles, true); - CHECK(duplicate_triangles == triangles.end()); -} - -template -radix::geometry::Aabb bounds_around_point(const glm::vec centre, const T margin) { - radix::geometry::Aabb bounds; - bounds.min = centre - glm::vec(margin); - bounds.max = centre + glm::vec(margin); - return bounds; -} - -radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { - const double infinity = std::numeric_limits::infinity(); - const glm::dvec3 min(bounds2d.min, -infinity); - const glm::dvec3 max(bounds2d.max, infinity); - return radix::geometry::Aabb3d(min, max); -} - -TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuilder]") { - struct TestData { - std::string path_suffix; - radix::geometry::Aabb3d target_bounds; - OGRSpatialReference target_srs; - OGRSpatialReference mesh_srs; - double resolution; // in m - }; - - const auto mgi_srs = srs::mgi(); - const auto ecef_srs = srs::ecef(); - const auto wgs84_srs = srs::wgs84(); - const auto webmercator_srs = srs::webmercator(); - - const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); - const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); - const glm::dvec3 steffl_wgs84(16.3735655, 48.2083264, 204); - const glm::dvec3 steffl_ecef = srs::transform_point(wgs84_srs, ecef_srs, steffl_wgs84); - - const std::vector test_data{ - {"/austria/pizbuin_1m_epsg4326.tif", - extend_bounds_to_3d(bounds_around_point(glm::dvec2(pizbuin_summit_wgs84), 0.0001)), - wgs84_srs, - wgs84_srs, - 1}, - {"/austria/pizbuin_1m_mgi.tif", - bounds_around_point(pizbuin_summit_ecef, 50 * 1.), - ecef_srs, - ecef_srs, - 1}, - {"/austria/vienna_20m_mgi.tif", - bounds_around_point(steffl_ecef, 50 * 20.), - ecef_srs, - ecef_srs, - 20}, - {"/austria/at_100m_mgi.tif", - bounds_around_point(steffl_ecef, 50 * 100.), - ecef_srs, - ecef_srs, - 100}}; - - for (const auto &data : test_data) { - DYNAMIC_SECTION(data.path_suffix) { - Dataset dataset(std::filesystem::path(ATB_TEST_DATA_DIR).concat(data.path_suffix)); - const auto source_srs = dataset.srs(); - const auto &mesh_srs = data.mesh_srs; - const auto &target_srs = data.target_srs; - const auto &target_bounds = data.target_bounds; - const auto resolution = data.resolution; - - radix::tile::SrsBounds texture_bounds; - const auto result = terrainbuilder::mesh::build_reference_mesh_patch( - dataset, - mesh_srs, - target_srs, target_bounds, - source_srs, texture_bounds); - if (!result) { - FAIL("Failed to build mesh: " << result.error()); - } - const TerrainMesh mesh = result.value(); - - SECTION("Basic mesh properties") { - check_non_empty(mesh); - check_uvs(mesh); - check_duplicate_vertices(mesh.positions); - check_duplicate_triangles(mesh.triangles); - check_mesh_basics(mesh); - } - - const std::vector positions_in_target_srs = srs::transform_points(mesh_srs, target_srs, mesh.positions); - SECTION("Vertices within target bounds") { - for (const auto &position : positions_in_target_srs) { - REQUIRE(radix::geometry::Aabb2d(target_bounds).contains_inclusive(glm::dvec2(position))); - REQUIRE(target_bounds.contains_inclusive(position)); - } - } - - SECTION("Some vertices on bounds (clipping check)") { - std::vector vertices_on_bounds; - for (const glm::dvec3 position : positions_in_target_srs) { - if (!target_bounds.contains_exclusive(position)) { - vertices_on_bounds.push_back(position); - } - } - CHECK(vertices_on_bounds.size() > 10); - } - - SECTION("Matches dataset resolution") { - const auto positions_in_source_srs = srs::transform_points(mesh_srs, source_srs, mesh.positions); - auto flat_positions_in_source_srs = positions_in_source_srs; - for (auto &pos : flat_positions_in_source_srs) { - pos.z = 0.0; - } - const auto flat_positions_in_ecef_srs = srs::transform_points(source_srs, ecef_srs, flat_positions_in_source_srs); - - const auto target_bounds_2d = radix::geometry::Aabb2d(target_bounds); - const auto padding = target_bounds_2d.size() * 0.1; - const auto inner_min = target_bounds_2d.min + padding; - const auto inner_max = target_bounds_2d.max - padding; - const radix::geometry::Aabb2d inner_bounds_2d{inner_min, inner_max}; - - std::vector filtered_triangles; - for (const auto &tri : mesh.triangles) { - const glm::dvec3 &a = positions_in_target_srs[tri.x]; - const glm::dvec3 &b = positions_in_target_srs[tri.y]; - const glm::dvec3 &c = positions_in_target_srs[tri.z]; - if (inner_bounds_2d.contains_inclusive(a) && - inner_bounds_2d.contains_inclusive(b) && - inner_bounds_2d.contains_inclusive(c)) { - filtered_triangles.push_back(tri); - } - } - TerrainMesh inside_flat_mesh; - inside_flat_mesh.positions = flat_positions_in_ecef_srs; - inside_flat_mesh.triangles = filtered_triangles; - - const auto avg_edge_length = estimate_average_edge_length(inside_flat_mesh); - REQUIRE(avg_edge_length.has_value()); - const auto expected_avg_edge_length = ((1 + 1 + std::sqrt(3)) / 3) * resolution; - CHECK(avg_edge_length.value() == Catch::Approx(expected_avg_edge_length).margin(expected_avg_edge_length * 0.2)); - } - } - } -} - -TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { - const auto mgi_srs = srs::mgi(); - const auto ecef_srs = srs::ecef(); - const auto wgs84_srs = srs::wgs84(); - const auto webmercator_srs = srs::webmercator(); - - const glm::dvec3 pizbuin_summit_wgs84(10.118333, 46.844167, 3312); - const glm::dvec3 pizbuin_summit_ecef = srs::transform_point(wgs84_srs, ecef_srs, pizbuin_summit_wgs84); - const octree::Space space = octree::Space::earth(); - const octree::Id summit_node = space.find_node_at_level_containing_point(pizbuin_summit_ecef, 17).value(); - std::vector nodes = summit_node.neighbours(); - nodes.push_back(summit_node); - - const std::string dataset_suffix = "/austria/pizbuin_1m_mgi.tif"; - const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); - Dataset dataset(dataset_path); - - std::vector node_meshes; - for (const octree::Id &node : nodes) { - const octree::Bounds node_bounds = space.get_node_bounds(node); - radix::tile::SrsBounds output_texture_bounds; - const auto result = terrainbuilder::mesh::build_reference_mesh_patch( - dataset, - ecef_srs, - ecef_srs, node_bounds, - webmercator_srs, output_texture_bounds); - if (!result.has_value()) { - continue; - } - const TerrainMesh mesh = result.value(); - node_meshes.push_back(mesh); - } - CHECK(node_meshes.size() >= 3); - - const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-6); - check_mesh_basics(merged_mesh); - check_non_empty(merged_mesh); - check_no_holes(merged_mesh); - CHECK(count_connected_components(merged_mesh) == 1); -} \ No newline at end of file From 18d18b62c5635e6b098fb22f0b4763afafb5e109 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 7 May 2025 18:55:27 +0200 Subject: [PATCH 033/122] Fix mesh io tests --- unittests/terrainbuilder/mesh_io.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/unittests/terrainbuilder/mesh_io.cpp b/unittests/terrainbuilder/mesh_io.cpp index bf3ffb8..928d4d2 100644 --- a/unittests/terrainbuilder/mesh_io.cpp +++ b/unittests/terrainbuilder/mesh_io.cpp @@ -17,8 +17,6 @@ * along with this program. If not, see . *****************************************************************************/ -#include - #include #include "../catch2_helpers.h" From 12534a88c396c81e4d229af3393b4577392e32a3 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 16:23:15 +0200 Subject: [PATCH 034/122] update cmake scripts --- cmake/AddRepo.cmake | 215 +++++++++++++++++++++++++++----------------- src/CMakeLists.txt | 2 +- 2 files changed, 135 insertions(+), 82 deletions(-) diff --git a/cmake/AddRepo.cmake b/cmake/AddRepo.cmake index 5bbb712..b3e669e 100644 --- a/cmake/AddRepo.cmake +++ b/cmake/AddRepo.cmake @@ -28,39 +28,55 @@ if(NOT DEFINED _alp_add_repo_check_flag) set_property(GLOBAL PROPERTY _alp_add_repo_check_flag FALSE) endif() -function(_alp_git_checkout_branch repo repo_dir commitish) - message(STATUS "[alp/git] In ${repo}, checking out ${commitish}.") +function(_alp_git_checkout repo repo_dir commitish) + message(STATUS "[alp/git] ${repo}: Checking out ${commitish}.") execute_process( COMMAND ${GIT_EXECUTABLE} checkout --quiet ${commitish} WORKING_DIRECTORY ${repo_dir} RESULT_VARIABLE GIT_CHECKOUT_RESULT + ERROR_VARIABLE checkout_output + OUTPUT_VARIABLE checkout_output ) if (NOT GIT_CHECKOUT_RESULT) - message(STATUS "[alp/git] In ${repo}, checking out branch ${commitish} was successfull.") + # message(STATUS "[alp/git] In ${repo}, checking out ${commitish} succeeded.") else() - message(FATAL_ERROR "[alp/git] In ${repo}, checking out branch ${commitish} was NOT successfull!") + message(WARNING "[alp/git] ${repo}: Checking out ${commitish} was NOT successful: ${checkout_output}") endif() if (EXISTS "${repo_dir}/.gitmodules") + # init/update submodules; for shallow clones this will still be shallow because the super‑project is. execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${_ALP_SUBMODULE_UPDATE_ARGS} WORKING_DIRECTORY ${repo_dir} RESULT_VARIABLE GIT_SUBMODULE_RESULT + ERROR_VARIABLE checkout_output + OUTPUT_VARIABLE checkout_output ) if(GIT_SUBMODULE_RESULT EQUAL 0) - message(STATUS "[alp/git] In ${repo}, submodules updated to match ${commitish}.") + # message(STATUS "[alp/git] ${repo}: Submodules updated to match ${commitish}.") else() - message(WARNING "[alp/git] In ${repo}, submodule update failed after checking out ${commitish}.") + message(WARNING "[alp/git] ${repo}: Submodule update failed after checking out ${commitish}: ${checkout_output}") endif() endif() endfunction() function(alp_add_git_repository name) - set(options DO_NOT_ADD_SUBPROJECT NOT_SYSTEM PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) + set(options DO_NOT_ADD_SUBPROJECT NOT_SYSTEM DEEP_CLONE PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES) set(oneValueArgs URL COMMITISH DESTINATION_PATH) set(multiValueArgs ) cmake_parse_arguments(PARSE_ARGV 1 PARAM "${options}" "${oneValueArgs}" "${multiValueArgs}") + # Determine whether we should do a shallow or deep clone/fetch. + if(PARAM_DEEP_CLONE) + # message(STATUS "[alp/git] Cloning ${PARAM_URL} DEEPLY to ${repo_dir}.") + set(_ALP_GIT_CLONE_ARGS) + set(_ALP_SUBMODULE_UPDATE_ARGS) + else() + # message(STATUS "[alp/git] Cloning ${PARAM_URL} SHALLOWY to ${repo_dir}.") + set(_ALP_GIT_CLONE_ARGS --no-checkout --depth 1 --shallow-submodules) + set(_ALP_SUBMODULE_UPDATE_ARGS --depth 1 --recommend-shallow) + endif() + get_property(_check_ran GLOBAL PROPERTY _alp_add_repo_check_flag) if(NOT PARAM_PRIVATE_DO_NOT_CHECK_FOR_SCRIPT_UPDATES AND NOT _check_ran) if(NOT COMMAND alp_check_for_script_updates) @@ -84,103 +100,140 @@ function(alp_add_git_repository name) set(${name}_SOURCE_DIR "${repo_dir}" PARENT_SCOPE) - string(REGEX MATCH "^[^/]+/.+" commitish_is_remote_branch "${PARAM_COMMITISH}") + # Detect if the requested ref looks like a remote branch (e.g. origin/main) + string(REGEX MATCH "^[^/]+/.+" force_fetch "${PARAM_COMMITISH}") + + set(force_checkout FALSE) + if(NOT EXISTS "${repo_dir}/.git") + # Do a fresh clone + message(STATUS "[alp/git] ${short_repo_dir}: Cloning ${PARAM_URL} to ${repo_dir}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} clone ${_ALP_GIT_CLONE_ARGS} --recurse-submodules ${PARAM_URL} ${repo_dir} + RESULT_VARIABLE GIT_CLONE_RESULT + ERROR_VARIABLE clone_output + OUTPUT_VARIABLE clone_output + ) + if (NOT GIT_CLONE_RESULT EQUAL 0) + message(SEND_ERROR "[alp/git] ${short_repo_dir}: Cloning was NOT successful: ${clone_output}") + endif() + if (NOT PARAM_DEEP_CLONE) + # shallow clone, fetch ref and checkout + set(force_fetch TRUE) + endif() + set(force_checkout TRUE) + endif() - if(EXISTS "${repo_dir}/.git") - # First, see if PARAM_COMMITISH is a valid local ref: + # Check out the correct branch: + # First, see if PARAM_COMMITISH is a valid local ref: + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH} + WORKING_DIRECTORY ${repo_dir} + OUTPUT_VARIABLE GIT_COMMIT_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE commit_present_result + ERROR_QUIET + ) + if (commit_present_result EQUAL 0 AND NOT force_fetch) + # PARAM_COMMITISH is recognized by Git => no need to fetch + # (could be a tag (lightweight or annotated) or a direct commit SHA). + # if it's an *annotated* tag, rev-parse gives us the tag object's hash, not the commit hash. + # => Force resolve the actual commit object with ^{commit}: execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH} + COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH}^{commit} WORKING_DIRECTORY ${repo_dir} - OUTPUT_VARIABLE GIT_COMMIT_OUTPUT + OUTPUT_VARIABLE GIT_COMMIT_OBJECT OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE GIT_COMMIT_RESULT + RESULT_VARIABLE commit_object_result ) - if (GIT_COMMIT_RESULT EQUAL 0 AND NOT commitish_is_remote_branch) - # PARAM_COMMITISH is recognized by Git => no need to fetch - # (could be a tag (lightweight or annotated) or a direct commit SHA). - # if it's an *annotated* tag, rev-parse gives us the tag object's hash, not the commit hash. - # => Force resolve the actual commit object with ^{commit}: - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --verify ${PARAM_COMMITISH}^{commit} - WORKING_DIRECTORY ${repo_dir} - OUTPUT_VARIABLE GIT_COMMIT_OBJECT - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE GIT_COMMIT_OBJECT_RESULT - ) + if (commit_object_result EQUAL 0) + # Successfully resolved a commit object + set(commitish_hash "${GIT_COMMIT_OBJECT}") + else() + # Fallback if that fails (should rarely happen if it's a proper commit/tag) + set(commitish_hash "${GIT_COMMIT_OUTPUT}") + endif() - if (GIT_COMMIT_OBJECT_RESULT EQUAL 0) - # Successfully resolved a commit object - set(CHECK_COMMITISH "${GIT_COMMIT_OBJECT}") - else() - # Fallback if that fails (should rarely happen if it's a proper commit/tag) - set(CHECK_COMMITISH "${GIT_COMMIT_OUTPUT}") - endif() + # Grab HEAD commit + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify HEAD + WORKING_DIRECTORY ${repo_dir} + OUTPUT_VARIABLE git_head_hash + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (git_head_hash STREQUAL commitish_hash AND NOT force_checkout) + message(STATUS "[alp/git] ${short_repo_dir}: Already at ${PARAM_COMMITISH}. Skipping checkout.") + else() + _alp_git_checkout(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) + endif() + else() + # either remote branch or commitish not recognised + message(STATUS "[alp/git] ${short_repo_dir}: Fetching updates.") - # Grab HEAD commit + if(PARAM_DEEP_CLONE) + # Original deep‑clone logic: fetch everything (incl. all tags) deeply. + # message(STATUS "[alp/git] Deep clone, fetching all.") execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --verify HEAD + COMMAND ${GIT_EXECUTABLE} fetch origin --tags WORKING_DIRECTORY ${repo_dir} - OUTPUT_VARIABLE GIT_HEAD_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE fetch_result + OUTPUT_QUIET + ERROR_QUIET ) - - if (GIT_HEAD_OUTPUT STREQUAL CHECK_COMMITISH) - message(STATUS "[alp/git] ${short_repo_dir} is already at ${PARAM_COMMITISH}. Skipping checkout.") - else() - _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) - endif() else() - # either remote branch or commitish not recognised - message(STATUS "[alp/git] Fetching updates for ${short_repo_dir}.") + # ── Shallow path ───────────────────────── + # 1. Try to fetch COMMITISH as a tag + # message(STATUS "[alp/git] Shallow clone, trying to fetch tag ${PARAM_COMMITISH}.") execute_process( - COMMAND ${GIT_EXECUTABLE} fetch + COMMAND ${GIT_EXECUTABLE} fetch origin tag ${PARAM_COMMITISH} --depth 1 WORKING_DIRECTORY ${repo_dir} - RESULT_VARIABLE GIT_FETCH_RESULT + RESULT_VARIABLE fetch_result + OUTPUT_QUIET + ERROR_QUIET ) - if (GIT_FETCH_RESULT EQUAL 0) - message(STATUS "[alp/git] Fetch successful for ${short_repo_dir}.") + + # 2. If that failed, try it as branch‑name or raw hash + if(NOT fetch_result EQUAL 0) + # message(STATUS "[alp/git] Shallow clone, failed to fetch tag ${PARAM_COMMITISH}. Probably it is a branch or hash. Trying again..") + set(_FETCH_REF "${PARAM_COMMITISH}") + string(REGEX REPLACE "^origin/(.+)" "\\1" _FETCH_REF "${_FETCH_REF}") execute_process( - COMMAND ${GIT_EXECUTABLE} branch --show-current + COMMAND ${GIT_EXECUTABLE} fetch origin ${_FETCH_REF} --depth 1 WORKING_DIRECTORY ${repo_dir} - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE GIT_BRANCH_OUTPUT - RESULT_VARIABLE GIT_BRANCH_RESULT + RESULT_VARIABLE fetch_result + OUTPUT_QUIET + ERROR_QUIET ) - if (NOT GIT_BRANCH_RESULT EQUAL 0) - message(FATAL_ERROR "[alp/git] In ${short_repo_dir}, git branch --show-current not successfull") - endif() - - if (GIT_BRANCH_OUTPUT STREQUAL "") - # Currently detached; let's checkout the branch - _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) - else() - message(WARNING - "[alp/git] ${short_repo_dir} on branch ${GIT_BRANCH_OUTPUT}, leaving it there. " - "NOT checking out ${PARAM_COMMITISH}! Use origin/main or similar if you " - "want to stay up-to-date with upstream." - ) - endif() - else () - message(WARNING "[alp/git] Not able to fetch updates for ${short_repo_dir} and ${PARAM_COMMITISH} was not found locally or is a remote branch.") endif() endif() - else() - # If the repo doesn't exist, do a fresh clone - message(STATUS "[alp/git] Cloning ${PARAM_URL} to ${repo_dir}.") - execute_process( - COMMAND ${GIT_EXECUTABLE} clone --recurse-submodules ${PARAM_URL} ${repo_dir} - RESULT_VARIABLE GIT_CLONE_RESULT - ) - if (GIT_CLONE_RESULT EQUAL 0) - _alp_git_checkout_branch(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) + + if (fetch_result EQUAL 0) + # message(STATUS "[alp/git] Fetch successful for ${short_repo_dir}.") + execute_process( + COMMAND ${GIT_EXECUTABLE} branch --show-current + WORKING_DIRECTORY ${repo_dir} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE current_branch + RESULT_VARIABLE branch_result + ) + if (NOT branch_result EQUAL 0) + message(FATAL_ERROR "[alp/git] ${short_repo_dir}: git branch --show-current failed") + endif() + + if (current_branch STREQUAL "" OR force_checkout) + # not on a branch. that's what we usually have (detached head state) + _alp_git_checkout(${short_repo_dir} ${repo_dir} ${PARAM_COMMITISH}) + else() + message(WARNING "[alp/git] ${short_repo_dir}: On branch ${current_branch}, leaving it there. NOT checking out ${PARAM_COMMITISH}! Use origin/main or similar if you want to stay up‑to‑date with upstream.") + endif() else() - message(FATAL_ERROR "[alp/git] Cloning ${short_repo_dir} was NOT successfull!") + message(WARNING "[alp/git] ${short_repo_dir}: Unable to fetch updates for; ${PARAM_COMMITISH} not found locally or is a remote branch.") endif() endif() - if (NOT ${PARAM_DO_NOT_ADD_SUBPROJECT}) - if (NOT ${PARAM_NOT_SYSTEM}) + if (NOT PARAM_DO_NOT_ADD_SUBPROJECT) + if (NOT PARAM_NOT_SYSTEM) add_subdirectory(${repo_dir} ${CMAKE_BINARY_DIR}/alp_external/${name} SYSTEM) else() add_subdirectory(${repo_dir} ${CMAKE_BINARY_DIR}/alp_external/${name}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 89361cb..910bda3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,7 +56,7 @@ alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COM add_library(zpp_bits INTERFACE) target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) -alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH abc5efb32c7c7a8295fcad3077c3100a35a4baab NOT_SYSTEM) +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) add_library(terrainlib terrainlib/alpine_raster.h terrainlib/alpine_raster.cpp From 2dcacd0d6b818f2a56da98eb947cdef9a66f6313 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 16:23:27 +0200 Subject: [PATCH 035/122] fix opencv linking --- cmake/SetupOpenCV.cmake | 2 +- src/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/SetupOpenCV.cmake b/cmake/SetupOpenCV.cmake index 71a069b..9596635 100644 --- a/cmake/SetupOpenCV.cmake +++ b/cmake/SetupOpenCV.cmake @@ -37,7 +37,7 @@ function(alp_setup_opencv version) -DWITH_FFMPEG=OFF -DWITH_JPEG=OFF -DWITH_PNG=OFF -DWITH_TIFF=OFF -DWITH_GTK=OFF -DWITH_QT=OFF - -DBUILD_LIST=core,imgproc + -DBUILD_LIST=core,imgproc,imgcodecs ) find_package(OpenCV REQUIRED) endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 910bda3..e24f56c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -89,7 +89,7 @@ add_library(terrainlib terrainlib/init.h terrainlib/init.cpp ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected ${OpenCV_LIBS}) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) From 0e711c4b32ac68304244b1c7afff4167871989d7 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 16:23:44 +0200 Subject: [PATCH 036/122] code style for cgal header --- src/terrainmerger/cgal.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/terrainmerger/cgal.h b/src/terrainmerger/cgal.h index 75f7611..d66bcc0 100644 --- a/src/terrainmerger/cgal.h +++ b/src/terrainmerger/cgal.h @@ -1,5 +1,4 @@ -#ifndef CGAL_H -#define CGAL_H +#pragma once #include #include @@ -32,4 +31,4 @@ namespace simple { DEFINE_KERNEL(CGAL::Exact_predicates_inexact_constructions_kernel) -#endif +#undef DEFINE_KERNEL From 690f8269474bc77ea7397681d0081e6c97c9ce46 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 17:03:09 +0200 Subject: [PATCH 037/122] try fix gdal for martin --- cmake/SetupCMakeProject.cmake | 4 ++-- cmake/SetupGDAL.cmake | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/SetupCMakeProject.cmake b/cmake/SetupCMakeProject.cmake index 2a35653..fbfc52f 100644 --- a/cmake/SetupCMakeProject.cmake +++ b/cmake/SetupCMakeProject.cmake @@ -28,7 +28,7 @@ function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) -G ${CMAKE_GENERATOR} -S ${SRC_DIR} -B ${BUILD_DIR} - -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${ARGN} @@ -66,7 +66,7 @@ function(alp_setup_cmake_project arg_NAME) if(DEFINED ${version_var} AND "${${version_var}}" STREQUAL "${arg_COMMITISH}${arg_CMAKE_ARGUMENTS}" AND DEFINED ${path_var} AND EXISTS "${${path_var}}") list(PREPEND CMAKE_PREFIX_PATH "${${path_var}}") - set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) return() endif() diff --git a/cmake/SetupGDAL.cmake b/cmake/SetupGDAL.cmake index 93f8564..b16081b 100644 --- a/cmake/SetupGDAL.cmake +++ b/cmake/SetupGDAL.cmake @@ -45,6 +45,7 @@ function(alp_setup_gdal) -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=OFF -DGDAL_USE_ICONV=OFF + -DGDAL_USE_EXTERNAL_LIBS=OFF ) find_package(GDAL CONFIG REQUIRED) From 15dca6ad6f39f13f9ded87079d6a62aef9217a95 Mon Sep 17 00:00:00 2001 From: Adam Ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 21:39:46 +0200 Subject: [PATCH 038/122] fix opencv setup (build with jpeg and png) --- cmake/SetupOpenCV.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/SetupOpenCV.cmake b/cmake/SetupOpenCV.cmake index 9596635..50afb1f 100644 --- a/cmake/SetupOpenCV.cmake +++ b/cmake/SetupOpenCV.cmake @@ -35,7 +35,7 @@ function(alp_setup_opencv version) -DWITH_OPENGL=OFF -DWITH_GSTREAMER=OFF -DWITH_FFMPEG=OFF - -DWITH_JPEG=OFF -DWITH_PNG=OFF -DWITH_TIFF=OFF + -DWITH_JPEG=ON -DWITH_PNG=ON -DWITH_TIFF=ON -DWITH_GTK=OFF -DWITH_QT=OFF -DBUILD_LIST=core,imgproc,imgcodecs ) From 414a46898b5d9e05ac381d0a0839026386f82564 Mon Sep 17 00:00:00 2001 From: Adam Celarek <5292991+adam-ce@users.noreply.github.com> Date: Thu, 8 May 2025 22:25:25 +0200 Subject: [PATCH 039/122] build in parallel even with make (hopefully) --- cmake/SetupCMakeProject.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/SetupCMakeProject.cmake b/cmake/SetupCMakeProject.cmake index fbfc52f..ad72db1 100644 --- a/cmake/SetupCMakeProject.cmake +++ b/cmake/SetupCMakeProject.cmake @@ -43,6 +43,7 @@ function(_alp_build_and_install NAME SRC_DIR BUILD_DIR INSTALL_DIR) COMMAND ${CMAKE_COMMAND} --build ${BUILD_DIR} --config ${CMAKE_BUILD_TYPE} + --parallel --target install RESULT_VARIABLE _bld_res) From dd7f3ed428cb07e58e5b014b237197bccf57a82e Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 9 May 2025 16:04:42 +0200 Subject: [PATCH 040/122] Add batch building --- src/terrainbuilder/main.cpp | 396 ++++++++++++++++++------ src/terrainbuilder/mesh_builder.cpp | 6 +- src/terrainbuilder/octree/space.h | 3 +- src/terrainbuilder/octree/storage.h | 12 +- src/terrainbuilder/octree/utils.h | 41 +++ src/terrainbuilder/raw_dataset_reader.h | 10 +- src/terrainbuilder/terrainbuilder.cpp | 34 +- src/terrainbuilder/terrainbuilder.h | 11 +- src/terrainlib/Dataset.cpp | 24 +- src/terrainlib/Dataset.h | 1 + src/terrainlib/log.h | 24 ++ src/terrainlib/mesh/terrain_mesh.h | 3 + src/terrainlib/srs.h | 25 +- unittests/terrainbuilder/texture.cpp | 3 +- 14 files changed, 470 insertions(+), 123 deletions(-) create mode 100644 src/terrainbuilder/octree/utils.h diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index c116b50..57eddb4 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -1,23 +1,44 @@ -#include +#include +#include #include -#include #include +#include #include #include #include #include -#include "Dataset.h" -#include "ctb/GlobalMercator.hpp" -#include "ctb/Grid.hpp" #include "srs.h" - +#include "Dataset.h" #include "terrainbuilder.h" #include "log.h" +#include "ctb/GlobalMercator.hpp" +#include "ctb/GlobalGeodetic.hpp" +#include "ctb/Grid.hpp" + +#include "octree/id.h" #include "octree/storage.h" #include "octree/space.h" +#include "octree/utils.h" + +OGRSpatialReference parse_srs(const std::string &user_input) { + const auto result = srs::from_user_input(user_input); + if (!result.has_value()) { + LOG_ERROR(result.error()); + exit(1); + } + return result.value(); +} + +int srs_dimension(const OGRSpatialReference &srs) { + if (srs.IsCompound()) + return 3; + if (srs.IsGeographic() || srs.IsProjected()) + return 2; + return 2; // fallback +} radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { const double infinity = std::numeric_limits::infinity(); @@ -26,135 +47,316 @@ radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { return radix::geometry::Aabb3d(min, max); } -int run(std::span args) { +radix::geometry::Aabb3d parse_bounds_from_values(const std::vector &data, const OGRSpatialReference &srs) { + const int dim = srs_dimension(srs); + const size_t expected = (dim == 3) ? 6 : 4; + + if (data.size() != expected) { + LOG_ERROR_AND_EXIT("Target bounds expects {} values for {}D SRS.", expected, dim); + } + + if (data.size() == 4) { + const glm::dvec2 min(data[0], data[2]); + const glm::dvec2 max(data[0] + data[1], data[2] + data[3]); + return extend_bounds_to_3d(radix::geometry::Aabb2d(min, max)); + } else if (data.size() == 6) { + const glm::dvec3 min(data[0], data[2], data[4]); + const glm::dvec3 max(data[0] + data[1], data[2] + data[3], data[4] + data[5]); + return radix::geometry::Aabb3d(min, max); + } else { + LOG_ERROR_AND_EXIT("Invalid number of elements for --bounds. Expected 4 or 6."); + } +} + +radix::geometry::Aabb3d parse_bounds_from_tile( + const std::vector &data, + radix::tile::Scheme scheme, + const OGRSpatialReference &srs) { + + // Determine the correct Grid type based on SRS + std::optional grid; + const OGRSpatialReference &webmercator_srs = srs::webmercator(); + const OGRSpatialReference &wgs84_srs = srs::wgs84(); + if (srs.IsSame(&webmercator_srs)) { + grid = ctb::GlobalMercator(); + } else if (srs.IsSame(&wgs84_srs)) { + grid = ctb::GlobalGeodetic(); + } else { + LOG_ERROR_AND_EXIT("Only WebMercator (EPSG:3857) or WGS84 (EPSG:4326) supported for --tile."); + } + + const unsigned int zoom_level = data[0]; + const glm::uvec2 tile_coords(data[1], data[2]); + const radix::tile::Id target_tile(zoom_level, tile_coords, scheme); + + return extend_bounds_to_3d(grid->srsBounds(target_tile, false)); +} + +radix::geometry::Aabb3d parse_bounds_from_node(const std::vector &data, const OGRSpatialReference &srs) { + // Validate node SRS (only ECEF) + const OGRSpatialReference &ecef_srs = srs::ecef(); + if (!srs.IsSame(&ecef_srs)) { + LOG_ERROR_AND_EXIT("Only ECEF (EPSG:4978) supported for --node."); + } + + const uint32_t zoom_level = data[0]; + octree::Id target_node = octree::Id::root(); + + if (data.size() == 2) { + target_node = {zoom_level, data[1]}; + } else if (data.size() == 4) { + const glm::uvec3 coords(data[1], data[2], data[3]); + target_node = {zoom_level, coords}; + } else { + LOG_ERROR_AND_EXIT("Invalid number of args for --node. Expected 2 or 4."); + } + + return octree::Space::earth().get_node_bounds(target_node); +} + +radix::geometry::Aabb3d parse_target_bounds( + const std::vector &bounds_data, + const std::vector &node_data, + const std::vector &tile_data, + radix::tile::Scheme tile_scheme, + OGRSpatialReference &srs) { + + if (!bounds_data.empty()) { + return parse_bounds_from_values(bounds_data, srs); + } + + if (!tile_data.empty()) { + return parse_bounds_from_tile(tile_data, tile_scheme, srs); + } + + if (!node_data.empty()) { + return parse_bounds_from_node(node_data, srs); + } + + UNREACHABLE(); +} + +void update_progress_bar(std::atomic &completed_tasks, uint32_t total_tasks) { + const uint32_t progress = static_cast((static_cast(completed_tasks) / total_tasks) * 100); + + std::cout << "\rProgress: ["; + uint32_t bar_width = 50; + uint32_t pos = bar_width * progress / 100; + for (uint32_t i = 0; i < bar_width; ++i) { + if (i < pos) { + std::cout << "="; + } else if (i == pos) { + std::cout << ">"; + } else { + std::cout << " "; + } + } + std::cout << "] " << progress << "% (" << completed_tasks.load() << "/" << total_tasks << ")"; + std::cout.flush(); +} + +template +T expect(const std::optional &opt, const std::string &msg) { + if (!opt) { + LOG_ERROR_AND_EXIT(msg); + } + return *opt; +} + +void batch_build( + Dataset &dataset, + const octree::Level target_level, + const OGRSpatialReference &texture_srs, + const std::optional &texture_base_path, + const OGRSpatialReference &mesh_srs, + const std::filesystem::path &output_base_path, + const std::string &output_format) { + const octree::Storage storage(output_base_path); + + const auto dataset_srs = dataset.srs(); + const auto dataset_bounds = dataset.bounds3d(); + + const auto ecef_srs = srs::ecef(); + const auto ecef_bounds = srs::encompassing_bounds_transfer( + dataset_srs, ecef_srs, dataset_bounds); + const auto space = octree::Space::earth(); + const auto root_node = expect( + space.find_smallest_node_encompassing_bounds(ecef_bounds), + "Dataset is outside the octree root node."); + + std::vector stack = {root_node}; + std::vector target_nodes; + while (!stack.empty()) { + const octree::Id node = stack.back(); + stack.pop_back(); + + const auto node_bounds = space.get_node_bounds(node); + const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer(ecef_srs, dataset_srs, node_bounds); + fmt::println("{}", node); + if (!radix::geometry::intersect(node_bounds_dataset_srs, dataset_bounds)) { + continue; + } + + if (node.level() < target_level) { + const auto children = node.children(); + if (children.has_value()) { + std::copy(children->begin(), children->end(), std::back_inserter(stack)); + } + } else if (node.level() == target_level) { + fmt::println("{}", target_nodes.size()); + target_nodes.push_back(node); + } + } + + std::atomic nodes_built(0); + std::for_each(std::execution::par, target_nodes.begin(), target_nodes.end(), [&](const auto &node) { + const auto node_bounds = space.get_node_bounds(node); + const TerrainMesh mesh = terrainbuilder::build( + dataset, + ecef_srs, + node_bounds, + texture_srs, + texture_base_path, + mesh_srs); + if (!mesh.is_empty()) { + storage.save_node(node, mesh); + } + + nodes_built++; + update_progress_bar(nodes_built, target_nodes.size()); + }); +} + +int run(std::span args) { int argc = args.size(); - char ** argv = args.data(); + char **argv = args.data(); CLI::App app{"Terrain Builder"}; app.allow_windows_style_options(); argv = app.ensure_utf8(argv); + // === COMMON OPTIONS === std::filesystem::path dataset_path; + std::optional texture_base_path; + std::string mesh_srs_input = "EPSG:4978"; + std::filesystem::path output_path; + spdlog::level::level_enum log_level = spdlog::level::level_enum::trace; + + const std::map log_level_names{ + {"off", spdlog::level::level_enum::off}, + {"critical", spdlog::level::level_enum::critical}, + {"error", spdlog::level::level_enum::err}, + {"warn", spdlog::level::level_enum::warn}, + {"info", spdlog::level::level_enum::info}, + {"debug", spdlog::level::level_enum::debug}, + {"trace", spdlog::level::level_enum::trace}}; + app.add_option("--dataset", dataset_path, "Path to a heightmap dataset file") ->required() ->check(CLI::ExistingFile); - - std::optional texture_base_path; app.add_option("--textures", texture_base_path, "Path to a folder containing texture tiles in the format of {zoom}/{col}/{row}.jpeg") ->check(CLI::ExistingDirectory); - - std::string mesh_srs_input; app.add_option("--mesh-srs", mesh_srs_input, "EPSG code of the target srs of the mesh positions") - ->default_val("EPSG:4978"); // ECEF + ->default_val("EPSG:4978"); + app.add_option("--verbosity", log_level, "Verbosity level of logging") + ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)); - std::string target_srs_input; - app.add_option("--target-srs", target_srs_input, "EPSG code of the srs of the target bounds or id") - ->default_val("EPSG:4978"); // ECEF + // === SINGLE COMMAND === + auto *single = app.add_subcommand("single", "Build a single reference mesh") + ->fallthrough(); - auto *target = app.add_option_group("target"); std::vector target_bounds_data; + std::vector target_tile_data; + std::vector target_node_data; + std::string target_srs_input; + radix::tile::Scheme target_tile_scheme; + + auto *target = single->add_option_group("target"); target->add_option("--bounds", target_bounds_data, "Target bounds for the reference mesh as \"{xmin} {width} {ymin} {height} [{zmin} {depth}]\"") ->expected(4, 6); - std::vector target_tile_data; target->add_option("--tile", target_tile_data, "Target tile id for the reference tile as \"{zoom} {x} {y}\"") - ->expected(3) - ->excludes("--bounds"); - std::vector target_node_data; + ->expected(3); target->add_option("--node", target_node_data, "Target node id for the reference node as \"{zoom} {index}\" or \"{zoom} {x} {y} {z}\"") - ->expected(2, 4) - ->excludes("--tile") - ->excludes("--bounds"); + ->expected(2, 4); target->require_option(1); - radix::tile::Scheme target_tile_scheme; - std::map scheme_str_map{{"slippymap", radix::tile::Scheme::SlippyMap}, {"google", radix::tile::Scheme::SlippyMap}, {"tms", radix::tile::Scheme::Tms}}; - app.add_option("--scheme", target_tile_scheme, "Target scheme for the tile id") + single->add_option("--output", output_path, "Output path were the mesh is written to (.tile, .gltf or .glb)") + ->required(); + + std::map scheme_str_map{ + {"slippymap", radix::tile::Scheme::SlippyMap}, + {"google", radix::tile::Scheme::SlippyMap}, + {"tms", radix::tile::Scheme::Tms}}; + single->add_option("--scheme", target_tile_scheme, "Tile scheme") ->default_val(radix::tile::Scheme::SlippyMap) ->needs("--tile") ->transform(CLI::CheckedTransformer(scheme_str_map, CLI::ignore_case)); - std::filesystem::path output_path; - app.add_option("--output", output_path, "Path to which the reference mesh will be written to (extension can be .tile, .gltf or .glb)") - ->required(); + single->add_option("--srs", target_srs_input, "EPSG code of the srs of the target bounds or id"); + single->callback([&]() { + if (target_srs_input.empty()) { + if (!target_bounds_data.empty()) { + target_srs_input = "EPSG:4978"; + } else if (!target_tile_data.empty()) { + target_srs_input = "EPSG:3857"; + } else if (!target_node_data.empty()) { + target_srs_input = "EPSG:4978"; + } + } + }); - spdlog::level::level_enum log_level = spdlog::level::level_enum::trace; - const std::map log_level_names{ - {"off", spdlog::level::level_enum::off}, - {"critical", spdlog::level::level_enum::critical}, - {"error", spdlog::level::level_enum::err}, - {"warn", spdlog::level::level_enum::warn}, - {"info", spdlog::level::level_enum::info}, - {"debug", spdlog::level::level_enum::debug}, - {"trace", spdlog::level::level_enum::trace}}; - app.add_option("--verbosity", log_level, "Verbosity level of logging") - ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)); + // === BATCH COMMAND === + auto *batch = app.add_subcommand("batch", "Build all nodes for a dataset at a given level") + ->fallthrough(); + + octree::Level target_level; + batch->add_option("--target-level", target_level, "Level of detail for batch generation") + ->required(); + std::filesystem::path output_base_path; + batch->add_option("--output", output_base_path, "Output path were the meshes are written to.") + ->required(); + std::string output_format; + batch->add_option("--format", output_format, "Output mesh format") + ->check(CLI::IsMember({"glb", "gltf", "tile"})) + ->default_val("glb"); CLI11_PARSE(app, argc, argv); Log::init(log_level); Dataset dataset(dataset_path); - - OGRSpatialReference target_bounds_srs = srs::from_user_input(target_srs_input); - OGRSpatialReference mesh_srs = srs::from_user_input(mesh_srs_input); + OGRSpatialReference mesh_srs = parse_srs(mesh_srs_input); OGRSpatialReference texture_srs = srs::webmercator(); - radix::geometry::Aabb3d target_bounds; - if (!target_bounds_data.empty()) { - // Target bounds are given directly - if (target_bounds_data.size() == 4) { - const glm::dvec2 min(target_bounds_data[0], target_bounds_data[2]); - const glm::dvec2 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3]); - target_bounds = extend_bounds_to_3d(radix::geometry::Aabb2d(min, max)); - } else if (target_bounds_data.size() == 6) { - const glm::dvec3 min(target_bounds_data[0], target_bounds_data[2], target_bounds_data[4]); - const glm::dvec3 max(target_bounds_data[0] + target_bounds_data[1], target_bounds_data[2] + target_bounds_data[3], target_bounds_data[4] + target_bounds_data[5]); - target_bounds = radix::geometry::Aabb3d(min, max); - } else { - LOG_ERROR("Invalid number of elements for --bounds. Expected 4 or 6 ({xmin} {width} {ymin} {height} [{zmin} {depth}])."); - return 1; - } - } else if (!target_tile_data.empty()) { - // Target bounds are based on a webmercator tile id - const ctb::Grid grid = ctb::GlobalMercator(); - - const unsigned int zoom_level = target_tile_data[0]; - const glm::uvec2 tile_coords(target_tile_data[1], target_tile_data[2]); - const radix::tile::Id target_tile(zoom_level, tile_coords, target_tile_scheme); - if (!target_bounds_srs.IsSame(&grid.getSRS())) { - LOG_ERROR("Target tile id is only supported for the webmercator reference system"); - exit(1); - } + if (*single) { + OGRSpatialReference target_srs = parse_srs(target_srs_input); + const radix::geometry::Aabb3d target_bounds = parse_target_bounds( + target_bounds_data, + target_node_data, + target_tile_data, + target_tile_scheme, + target_srs); - target_bounds = extend_bounds_to_3d(grid.srsBounds(target_tile, false)); - } else { - // Target bounds are based on an octree node id - const uint32_t zoom_level = target_node_data[0]; - octree::Id target_node = octree::Id::root(); - if (target_node_data.size() == 2) { - const uint64_t node_index = target_node_data[1]; - target_node = {zoom_level, node_index}; - } else if (target_node_data.size() == 4) { - const glm::uvec3 coords(target_node_data[1], target_node_data[2], target_node_data[3]); - target_node = { zoom_level, coords }; - } else { - LOG_ERROR("Invalid number of args for --node. Expected 2 or 4."); - return 1; - } - - const octree::Space world = octree::Space::earth(); - target_bounds = world.get_node_bounds(target_node); + terrainbuilder::build_and_save( + dataset, + target_srs, + target_bounds, + texture_srs, + texture_base_path, + mesh_srs, + output_path); } - - terrainbuilder::build( - dataset, - target_bounds_srs, - target_bounds, - texture_srs, - texture_base_path, - mesh_srs, - output_path); + if (*batch) { + batch_build( + dataset, + target_level, + texture_srs, + texture_base_path, + mesh_srs, + output_base_path, + output_format); + } return 0; } diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index fe740e8..d83127d 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -316,7 +316,11 @@ tl::expected build_reference_mesh_patch( const raster::HeightMap height_map = read_result.value(); LOG_TRACE("Finding valid pixels"); - const raster::Mask valid_mask = raster::transform(height_map, is_valid); + const float no_data_value = reader.get_no_data_value(); + const raster::Mask valid_mask = raster::transform(height_map, [=](const float height) { + return height != no_data_value; + }); + // const raster::Mask valid_mask = raster::transform(height_map, is_valid); LOG_TRACE("Transforming pixels to vertices"); const raster::Raster source_points = raster::transform(height_map, valid_mask, [&](const float height, const raster::Coords& coords) { diff --git a/src/terrainbuilder/octree/space.h b/src/terrainbuilder/octree/space.h index 9ec70d1..8fd881f 100644 --- a/src/terrainbuilder/octree/space.h +++ b/src/terrainbuilder/octree/space.h @@ -7,6 +7,7 @@ namespace octree { using Bounds = radix::geometry::Aabb3d; +// TODO: add srs to this? class Space { public: const Bounds bounds; @@ -42,7 +43,7 @@ class Space { } Id current_smallest_encompassing_node = root; - while (true) { + while (current_smallest_encompassing_node.has_children()) { const std::array children = current_smallest_encompassing_node.children().value(); std::optional next_smallest; diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainbuilder/octree/storage.h index f444c75..17d2076 100644 --- a/src/terrainbuilder/octree/storage.h +++ b/src/terrainbuilder/octree/storage.h @@ -36,8 +36,16 @@ class Storage { } private: - std::filesystem::path get_node_path(const Id &id) const { - return base_path / std::to_string(id.level()) / std::to_string(id.x()) / (std::to_string(id.y()) + ".gltf"); + std::filesystem::path get_node_path(const Id &id, std::string_view ext = "glb") const { + if (!ext.empty() && ext.front() == '.') { + ext = ext.substr(1); // Remove leading dot + } + + return base_path + / std::to_string(id.level()) + / std::to_string(id.x()) + / std::to_string(id.y()) + / fmt::format("{}.{}", id.z(), ext); } private: diff --git a/src/terrainbuilder/octree/utils.h b/src/terrainbuilder/octree/utils.h new file mode 100644 index 0000000..4ce9706 --- /dev/null +++ b/src/terrainbuilder/octree/utils.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#include "octree/id.h" + +namespace octree { + +void for_each_descendant_at_level(const Id &node, const Level target_level, const std::function &callback) { + if (target_level <= node.level()) { + return; + } + + const Level level_diff = target_level - node.level(); + const Index start = node.index_on_level() << (3 * level_diff); + const Index count = Index(1) << (3 * level_diff); + + for (Index i = 0; i < count; ++i) { + callback(Id(target_level, start + i)); + } +} + +std::vector list_descendant_at_level(const Id &node, const Level target_level) { + if (target_level <= node.level()) { + return {}; + } + + const Level level_diff = target_level - node.level(); + const Index start = node.index_on_level() << (3 * level_diff); + const Index count = Index(1) << (3 * level_diff); + + std::vector nodes; + nodes.reserve(count); + for (Index i = 0; i < count; ++i) { + nodes.emplace_back(target_level, start + i); + } + return nodes; +} + +} diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/terrainbuilder/raw_dataset_reader.h index 49026db..fb20f8a 100644 --- a/src/terrainbuilder/raw_dataset_reader.h +++ b/src/terrainbuilder/raw_dataset_reader.h @@ -35,6 +35,12 @@ class RawDatasetReader { return this->dataset; } + double get_no_data_value() { + assert(this->dataset->GetRasterCount() >= 1); + GDALRasterBand *height_band = this->dataset->GetRasterBand(1); + return height_band->GetNoDataValue(); + } + glm::uvec2 dataset_size() { GDALRasterBand *heights_band = this->dataset->GetRasterBand(1); // non-owning pointer return glm::uvec2(heights_band->GetXSize(), heights_band->GetYSize()); @@ -54,7 +60,7 @@ class RawDatasetReader { assert(glm::all(glm::lessThan(bounds.max, glm::ivec2(this->dataset_size())))); assert(this->dataset->GetRasterCount() >= 1); - GDALRasterBand *heights_band = this->dataset->GetRasterBand(1); // non-owning pointer + GDALRasterBand *height_band = this->dataset->GetRasterBand(1); // non-owning pointer // Initialize the HeightData for reading raster::HeightMap height_data(bounds.width(), bounds.height()); @@ -68,7 +74,7 @@ class RawDatasetReader { } // Read data from the heights band into heights_data - const int read_result = heights_band->RasterIO( + const int read_result = height_band->RasterIO( GF_Read, bounds.min.x, bounds.min.y, bounds.width(), bounds.height(), static_cast(height_data.data()), bounds.width(), bounds.height(), GDT_Float32, 0, 0); diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 203e54c..21014f3 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -43,14 +43,13 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { std::filesystem::path base_path; }; -void build( +TerrainMesh build( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, const OGRSpatialReference &texture_srs, const std::optional texture_base_path, - const OGRSpatialReference &mesh_srs, - const std::filesystem::path &output_path) { + const OGRSpatialReference &mesh_srs) { const ctb::Grid grid = ctb::GlobalMercator(); radix::tile::SrsBounds texture_bounds; @@ -79,10 +78,12 @@ void build( "}}", dataset_bounds.min.x, dataset_bounds.min.y, dataset_bounds.width(), dataset_bounds.height(), target_bounds.min.x, target_bounds.min.y, target_bounds.size().x, target_bounds.size().y); - exit(1); + // TODO: exit(1); + return {}; } else if (error == mesh::BuildError::EmptyRegion) { LOG_WARN("Target bounds are inside dataset, but the region is empty"); - exit(0); + // TODO: exit(0); + return {}; } } TerrainMesh mesh = mesh_result.value(); @@ -101,12 +102,32 @@ void build( mesh.texture = texture; LOG_DEBUG("Assembling mesh texture took {}s", format_secs_since(start)); LOG_INFO("Finished assembling mesh texture"); - } else { LOG_INFO("Skipped assembling texture"); } + + return mesh; +} + +void build_and_save( + Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, + const std::optional texture_base_path, + const OGRSpatialReference &mesh_srs, + const std::filesystem::path &output_path) { + const TerrainMesh mesh = build( + dataset, + target_bounds_srs, + target_bounds, + texture_srs, + texture_base_path, + mesh_srs); LOG_INFO("Writing mesh to output path {}", output_path.string()); + + std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); // TODO: use a JSON libary instead std::unordered_map metadata; @@ -129,4 +150,5 @@ void build( LOG_DEBUG("Writing mesh took {}s", format_secs_since(start)); LOG_INFO("Done", output_path.string()); } + } diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index e77a58d..2db979f 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -6,11 +6,12 @@ #include #include "Dataset.h" +#include "mesh/terrain_mesh.h" #include "srs.h" namespace terrainbuilder { -void build( +void build_and_save( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -18,6 +19,14 @@ void build( const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_path); + +TerrainMesh build( + Dataset &dataset, + const OGRSpatialReference &target_bounds_srs, + const radix::geometry::Aabb3d &target_bounds, + const OGRSpatialReference &texture_srs, + const std::optional texture_base_path, + const OGRSpatialReference &mesh_srs); } #endif diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 989847d..781a5c6 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -33,10 +33,13 @@ #include "init.h" #include "log.h" -Dataset::Dataset(const std::string& path) -{ +Dataset::Dataset(const std::string &path) { initialize_gdal_once(); - m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); + const auto gdal_dataset = GDALOpenEx( + path.c_str(), + GDAL_OF_READONLY | GDAL_OF_THREAD_SAFE | GDAL_OF_RASTER | GDAL_OF_INTERNAL, + nullptr, nullptr, nullptr); + m_gdal_dataset.reset(static_cast(gdal_dataset)); if (!m_gdal_dataset) { LOG_ERROR("Couldn't open dataset {}.\n", path); throw Exception(""); @@ -89,6 +92,21 @@ radix::tile::SrsBounds Dataset::bounds() const { return { {westX, southY}, {eastX, northY} }; } +radix::tile::SrsAndHeightBounds Dataset::bounds3d() const { + const auto band = this->m_gdal_dataset->GetRasterBand(1); + + glm::dvec2 height_range; + if (!band->GetStatistics(1, 0, &height_range.x, &height_range.y, nullptr, nullptr)) { + throw std::runtime_error("Could not determine dataset height bounds"); + } + + const auto bounds2d = this->bounds(); + radix::tile::SrsAndHeightBounds bounds3d; + bounds3d.min = glm::dvec3(bounds2d.min, height_range[0]); + bounds3d.max = glm::dvec3(bounds2d.max, height_range[1]); + return bounds3d; +} + radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) const { const auto l_bounds = bounds(); const auto west = l_bounds.min.x; diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index ef62bcf..ac64264 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -46,6 +46,7 @@ class Dataset { [[nodiscard]] std::string name() const; [[nodiscard]] radix::tile::SrsBounds bounds() const; + [[nodiscard]] radix::tile::SrsAndHeightBounds bounds3d() const; [[nodiscard]] radix::tile::SrsBounds bounds(const OGRSpatialReference &targetSrs) const; [[nodiscard]] OGRSpatialReference srs() const; [[nodiscard]] unsigned widthInPixels() const; diff --git a/src/terrainlib/log.h b/src/terrainlib/log.h index 5753fb1..358dde4 100644 --- a/src/terrainlib/log.h +++ b/src/terrainlib/log.h @@ -27,5 +27,29 @@ class Log { #define LOG_INFO(...) SPDLOG_LOGGER_INFO (::Log::get_logger(), __VA_ARGS__) #define LOG_WARN(...) SPDLOG_LOGGER_WARN (::Log::get_logger(), __VA_ARGS__) #define LOG_ERROR(...) SPDLOG_LOGGER_ERROR(::Log::get_logger(), __VA_ARGS__) +#define LOG_ERROR_AND_EXIT(...) \ + do { \ + LOG_ERROR(__VA_ARGS__); \ + exit(1); \ + } while (false) +#if defined(__GNUC__) || defined(__clang__) +#define UNREACHABLE() \ + do { \ + LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define UNREACHABLE() \ + do { \ + LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ + __assume(false); \ + } while (0) +#else +#define UNREACHABLE() \ + do { \ + LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ + std::abort(); \ + } while (0) +#endif #endif diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h index 7d926ae..1a3ccb8 100644 --- a/src/terrainlib/mesh/terrain_mesh.h +++ b/src/terrainlib/mesh/terrain_mesh.h @@ -45,6 +45,9 @@ class TerrainMesh { size_t face_count() const { return this->triangles.size(); } + bool is_empty() const { + return this->vertex_count() == 0 && this->face_count() == 0; + } bool has_uvs() const { return this->positions.size() == this->uvs.size(); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index 45b7c7a..9b22ae0 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -20,11 +20,14 @@ #include "Exception.h" #include +#include #include #include #include #include #include +#include +#include #include namespace srs { @@ -284,29 +287,35 @@ inline radix::geometry::Aabb3d encompassing_bounds_transfer( return target_bounds; } -inline OGRSpatialReference from_epsg(uint32_t epsg) { +inline tl::expected from_epsg(const uint32_t epsg) { OGRSpatialReference srs; - srs.importFromEPSG(epsg); + if (srs.importFromEPSG(epsg) != OGRERR_NONE) { + return tl::unexpected(fmt::format("Failed to import spatial reference from EPSG code: {}", epsg)); + } srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); return srs; } -inline OGRSpatialReference from_user_input(const std::string& user_input) { + +inline tl::expected from_user_input(const std::string &user_input) { OGRSpatialReference srs; - srs.SetFromUserInput(user_input.c_str()); + if (srs.SetFromUserInput(user_input.c_str()) != OGRERR_NONE) { + return tl::unexpected(fmt::format("Failed to set spatial reference from user input: {}", user_input)); + } srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); return srs; } + inline OGRSpatialReference ecef() { - return from_epsg(4978); + return from_epsg(4978).value(); } inline OGRSpatialReference webmercator() { - return from_epsg(3857); + return from_epsg(3857).value(); } inline OGRSpatialReference wgs84() { - return from_epsg(4326); + return from_epsg(4326).value(); } inline OGRSpatialReference mgi() { - return from_epsg(4312); + return from_epsg(4312).value(); } } diff --git a/unittests/terrainbuilder/texture.cpp b/unittests/terrainbuilder/texture.cpp index a1903a7..f4bc25d 100644 --- a/unittests/terrainbuilder/texture.cpp +++ b/unittests/terrainbuilder/texture.cpp @@ -21,8 +21,7 @@ #include #include #include - -#include +#include #include "../catch2_helpers.h" #include "Dataset.h" From 2dcc5566be1d104ab9924b84906ff0cabb1d56ae Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Sat, 10 May 2025 00:36:40 +0200 Subject: [PATCH 041/122] Handle Window resize. --- src/core/Application.cpp | 10 +++++++++- src/core/Camera.cpp | 6 ++++++ src/core/Camera.h | 1 + src/core/window/Window.cpp | 16 ++++++++++++++++ src/core/window/Window.h | 3 +++ src/main.cpp | 4 ++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/core/Application.cpp b/src/core/Application.cpp index a88e1e5..5f22d32 100644 --- a/src/core/Application.cpp +++ b/src/core/Application.cpp @@ -24,7 +24,7 @@ Application::Application(std::string title, int width, int height) .width = 1280, .height = 720, .title = "Alpenite Browser", - .resizeable = false, + .resizeable = true, .msaa_samples = 4, .opengl_version = {4, 6}, .opengl_core_profile = true @@ -117,6 +117,14 @@ void Application::run() { U_projection.set(m_camera->projection_matrix()); U_view.set(m_camera->view_matrix()); + m_window->register_framebuffer_resize_event([this, &U_projection](glm::ivec2 new_size) { + m_camera->set_aspect_ratio((float)new_size.x / (float)new_size.y); + + glViewport(0, 0, new_size.x, new_size.y); + + U_projection.set(m_camera->projection_matrix()); + }); + LOG_INFO("Setting up lines"); std::vector vertices = UnitCube::vertices(); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index c54e5c1..6880613 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -52,6 +52,12 @@ void Camera::set_far(float far) { m_far_plane = far; } +void Camera::set_aspect_ratio(float new_aspect_ratio) { + m_projection_matrix_cache.reset(); + + m_aspect_ratio = new_aspect_ratio; +} + float Camera::get_near() { return m_near_plane; } diff --git a/src/core/Camera.h b/src/core/Camera.h index 6a56fee..524aabd 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -22,6 +22,7 @@ class Camera { void move_local(glm::dvec3 local_movement_delta); void set_near(float near); void set_far(float far); + void set_aspect_ratio(float new_aspect_ratio); float get_near(); float get_far(); diff --git a/src/core/window/Window.cpp b/src/core/window/Window.cpp index 496ecac..0d01068 100644 --- a/src/core/window/Window.cpp +++ b/src/core/window/Window.cpp @@ -36,6 +36,7 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei glfwSetMouseButtonCallback(m_handle, mouse_button_callback); glfwSetCursorPosCallback(m_handle, cursor_position_callback); glfwSetScrollCallback(m_handle, scroll_callback); + glfwSetFramebufferSizeCallback(m_handle, framebuffer_size_callback); // Initialize current and last cursor positions glfwGetCursorPos(m_handle, &m_current_unfetched_cursor_pos.x, &m_current_unfetched_cursor_pos.y); @@ -153,6 +154,10 @@ void Window::register_scroll_event(std::function callback) { m_scroll_callbacks.push_back(callback); } +void Window::register_framebuffer_resize_event(std::function callback) { + m_framebuffer_resize_callbacks.push_back(callback); +} + float Window::getAspectRatio() { return (float)m_width / (float)m_height; } @@ -214,6 +219,17 @@ void Window::scroll_callback(GLFWwindow* window, double xoffset, double yoffset) } } +void Window::framebuffer_size_callback(GLFWwindow* window, int width, int height) { + Window* w = (Window*)glfwGetWindowUserPointer(window); + + w->m_width = width; + w->m_height = height; + + for (auto callback : w->m_framebuffer_resize_callbacks) { + callback(glm::dvec2(width, height)); + } +} + void Window::update_window_count(int delta) { if (delta == 0) { return; diff --git a/src/core/window/Window.h b/src/core/window/Window.h index 14d763b..c8107d7 100644 --- a/src/core/window/Window.h +++ b/src/core/window/Window.h @@ -44,6 +44,7 @@ class Window { void register_key_event(int action, int key, std::function callback); void register_scroll_event(std::function callback); + void register_framebuffer_resize_event(std::function callback); float getAspectRatio(); @@ -65,12 +66,14 @@ class Window { std::map, std::vector>> m_key_callbacks; std::vector> m_scroll_callbacks; + std::vector> m_framebuffer_resize_callbacks; static void glfw_error_callback(int error, const char* description); static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos); static void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); + static void framebuffer_size_callback(GLFWwindow* window, int width, int height); static void update_window_count(int delta); }; diff --git a/src/main.cpp b/src/main.cpp index e4edc83..a26a424 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,11 @@ #include "utils/log/Log.h" int main() { +#ifdef DEBUG Log::Init(spdlog::level::trace); +#else + Log::Init(spdlog::level::info); +#endif Application app("Alpenite Browser", 1280, 720); From a2f0acf298f2f67218472a43f078c4da42367492 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Sat, 10 May 2025 00:38:12 +0200 Subject: [PATCH 042/122] Add imgui. Add Camera Settings Window. --- src/CMakeLists.txt | 28 ++++- src/core/Application.cpp | 211 ++++++++++++++++++++++++++++++------- src/core/Application.h | 2 + src/core/Camera.cpp | 40 +++++++ src/core/Camera.h | 12 +++ src/core/octree/space.h | 2 +- src/core/window/Window.cpp | 4 + src/core/window/Window.h | 3 + 8 files changed, 263 insertions(+), 39 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ce7e6b..611b6c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -90,6 +90,32 @@ if(NOT TARGET radix) FetchContent_MakeAvailable(radix) endif() +if(NOT TARGET imgui) + SET(IMGUI_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/imgui) + FetchContent_Declare(imgui + GIT_REPOSITORY https://github.com/ocornut/imgui.git + GIT_TAG origin/master + SOURCE_DIR ${IMGUI_SOURCE_DIR} + ) + message(STATUS "Including imgui") + #FetchContent_MakeAvailable(imgui) + + add_library(imgui STATIC + ${IMGUI_SOURCE_DIR}/imgui.cpp + ${IMGUI_SOURCE_DIR}/imgui_draw.cpp + ${IMGUI_SOURCE_DIR}/imgui_demo.cpp # TODO: Remove after use + ${IMGUI_SOURCE_DIR}/imgui_tables.cpp + ${IMGUI_SOURCE_DIR}/imgui_widgets.cpp + ${IMGUI_SOURCE_DIR}/backends/imgui_impl_glfw.cpp + ${IMGUI_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp + ) + target_include_directories(imgui PUBLIC + ${IMGUI_SOURCE_DIR} + ${IMGUI_SOURCE_DIR}/backends + ) + target_link_libraries(imgui PUBLIC glfw) +endif() + add_executable(alpenite-browser main.cpp @@ -109,5 +135,5 @@ add_executable(alpenite-browser core/octree/id.h core/octree/space.h ) -target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog radix) +target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog radix imgui) target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/core/Application.cpp b/src/core/Application.cpp index 5f22d32..9e0fb75 100644 --- a/src/core/Application.cpp +++ b/src/core/Application.cpp @@ -6,6 +6,10 @@ // CMRC Resource Compiler #include +#include +#include +#include + #include "shader/Shader.h" #include "shader/ShaderProgram.h" #include "Buffer.h" @@ -35,6 +39,16 @@ Application::Application(std::string title, int width, int height) init_glad(); init_gl(); + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(m_window->handle(), true); // Second param install_callback=true will install GLFW callbacks and chain to existing ones. + ImGui_ImplOpenGL3_Init(); + if (c.msaa_samples > 0) { glEnable(GL_MULTISAMPLE); } @@ -52,13 +66,23 @@ void Application::run() { LOG_INFO("Setting up key event callbacks"); m_window->register_key_event(GLFW_PRESS, GLFW_KEY_TAB, [this]() { toggle_nav_mode(); + + ImGuiIO& io = ImGui::GetIO(); if (m_nav_mode) { LOG_DEBUG("Entering Nav Mode"); + + io.ConfigFlags |= ImGuiConfigFlags_NoMouse; + io.ConfigFlags |= ImGuiConfigFlags_NoKeyboard; + m_window->set_capture_mouse(true); m_window->clear_accumulated_cursor_delta(); } else { LOG_DEBUG("Exiting Nav Mode"); + + io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; + io.ConfigFlags &= ~ImGuiConfigFlags_NoKeyboard; + m_window->set_capture_mouse(false); } }); @@ -108,7 +132,7 @@ void Application::run() { .near_plane = 1000.0f, .far_plane = 200000000.0f, - .position = glm::vec3(0.0f, 0.0f, 10000000.0f), + .position = glm::vec3(10000000.0f), .target = glm::vec3(0.0f), .up = glm::vec3(0.0f, 1.0f, 0.0f), }; @@ -191,11 +215,20 @@ void Application::run() { glClearColor(0.f, 0.f, 0.f, 1.f); while (!m_window->should_close()) { + + m_window->poll_events(); + const double current_frame_time = glfwGetTime(); const double frame_delta_time = current_frame_time - last_frame_time; last_frame_time = current_frame_time; + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + draw_camera_settings_window(); - m_window->poll_events(); update_camera(frame_delta_time, U_view); octree::OctreeRenderIntent rendering_intent = space.generate_octree_render_intent(octree::Id::root(), m_camera->get_position(), false); @@ -203,49 +236,28 @@ void Application::run() { cube_instance_active_buffer.set_data(rendering_intent.instances_active); cube_instance_model_buffer.set_data(rendering_intent.instances_model_mats); - if (rendering_intent.min_scene_distance.has_value() && m_camera->get_near() != rendering_intent.min_scene_distance.value()) { + if (rendering_intent.min_scene_distance.has_value() && m_camera->get_near() != (float)rendering_intent.min_scene_distance.value() * 0.5f) { m_camera->set_near(rendering_intent.min_scene_distance.value() * 0.5f); } - if (rendering_intent.max_scene_distance.has_value() && m_camera->get_far() != rendering_intent.max_scene_distance.value()) { + if (rendering_intent.max_scene_distance.has_value() && m_camera->get_far() != (float)rendering_intent.max_scene_distance.value() * 1.5f) { m_camera->set_far(rendering_intent.max_scene_distance.value() * 1.5f); } + if (m_camera->is_view_matrix_outdated()) { + U_view.set(m_camera->view_matrix()); + } if (m_camera->is_projection_matrix_outdated()) { U_projection.set(m_camera->projection_matrix()); } - glm::dvec3 cam_pos = m_camera->get_position(); - float near = m_camera->get_near(); - float far = m_camera->get_far(); - - std::string id_string; - - if (rendering_intent.closest_node.has_value()) { - auto id = rendering_intent.closest_node.value(); - - uint32_t level = id.level(); - uint32_t id_x = id.coords().x; - uint32_t id_y = id.coords().y; - uint32_t id_z = id.coords().z; - - id_string = std::vformat(" | CLOSEST ID: L{} {} {} {}", - std::make_format_args( - level, id_x, id_y, id_z - ) - ); - } - octree::Coords coords = rendering_intent.closest_node.value().coords(); - - m_window->set_title_suffix(std::vformat(" | CAM POS: {:.2f}, {:.2f}, {:.2f} | Z-NEAR: {:.2f}, Z-FAR: {:.2f}{}", - std::make_format_args( - cam_pos.x, cam_pos.y, cam_pos.z, near, far, id_string - ) - )); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glLineWidth(2.0f); + //glLineWidth(2.0f); glDrawElementsInstanced(GL_LINES, indices.size(), GL_UNSIGNED_INT, 0, rendering_intent.instance_count); + // RENDER IMGUI AFTER OUR RENDERS + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + m_window->swapBuffers(); } } @@ -318,14 +330,13 @@ void Application::update_camera(float frame_delta_time, Uniform U_vie if (movement_magnitude != 0.0f) { m_camera->move_local(local_movement_delta * (float)frame_delta_time * movement_speed); } - - if (m_camera->is_view_matrix_outdated()) { - U_view.set(m_camera->view_matrix()); - } } Application::~Application() { LOG_INFO("Exiting"); + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); } void Application::toggle_nav_mode() { @@ -353,6 +364,132 @@ void Application::init_gl() { glViewport(0, 0, m_width, m_height); } +void Application::draw_camera_settings_window() { + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200, 400), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin("Camera Settings")) { + ImGui::End(); + return; + } + + if (ImGui::CollapsingHeader("Position")) { + bool cam_pos_edited = false; + glm::dvec3 cam_pos = m_camera->get_position(); + + + float double_input_width = ImGui::CalcTextSize("#########.#########").x; + + ImGui::SetNextItemWidth(double_input_width); + ImGui::InputDouble("X", &cam_pos.x); + + if (ImGui::IsItemEdited()) { + cam_pos_edited = true; + } + + ImGui::SetNextItemWidth(double_input_width); + ImGui::InputDouble("Y", &cam_pos.y); + + if (ImGui::IsItemEdited()) { + cam_pos_edited = true; + } + + ImGui::SetNextItemWidth(double_input_width); + ImGui::InputDouble("Z", &cam_pos.z); + + if (ImGui::IsItemEdited() || cam_pos_edited) { + cam_pos_edited = true; + + m_camera->set_position(cam_pos); + } + } + + if (ImGui::CollapsingHeader("Orientation")) { + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Euler Angles")) { + bool euler_edited = false; + glm::vec3 euler = glm::degrees(m_camera->get_rotation_euler()); + + ImGui::SliderFloat("Pitch (X)", &euler.x, -180.0f, 180.0f); + if (ImGui::IsItemEdited()) { + euler_edited = true; + } + + ImGui::SliderFloat("Yaw (Y)", &euler.y, -90.0f, 90.0f); + if (ImGui::IsItemEdited()) { + euler_edited = true; + } + + ImGui::SliderFloat("Roll (Z)", &euler.z, -180.0f, 180.0f); + if (ImGui::IsItemEdited() || euler_edited) { + euler_edited = true; + + m_camera->set_rotation_euler(glm::radians(euler)); + } + + ImGui::TreePop(); + } + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Quaternion")) { + bool quat_edited = false; + glm::quat quat = m_camera->get_rotation_quat(); + + ImGui::SliderFloat("X", &quat.x, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } + + ImGui::SliderFloat("Y", &quat.y, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } + + ImGui::SliderFloat("Z", &quat.z, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } + + ImGui::SliderFloat("W", &quat.w, -1.0, 1.0); + if (ImGui::IsItemEdited() || quat_edited) { + quat_edited = true; + + m_camera->set_rotation_quat(glm::normalize(quat)); + } + + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Projection")) { + float fov = m_camera->get_fov(); + + ImGui::SliderFloat("FOV", &fov, 0.1f, 120.0f); + if (ImGui::IsItemEdited()) { + m_camera->set_fov(fov); + } + + ImGui::Separator(); + + float near = m_camera->get_near(); + ImGui::InputFloat("Near Plane", &near); + if (ImGui::IsItemEdited()) { + m_camera->set_near(near); + } + + float far = m_camera->get_far(); + ImGui::InputFloat("Far Plane", &far); + if (ImGui::IsItemEdited()) { + m_camera->set_far(far); + } + + ImGui::Separator(); + } + + ImGui::End(); +} + void Application::gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, diff --git a/src/core/Application.h b/src/core/Application.h index 311f136..7e9b200 100644 --- a/src/core/Application.h +++ b/src/core/Application.h @@ -34,6 +34,8 @@ class Application { void init_glad(); void init_gl(); + void draw_camera_settings_window(); + static void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 6880613..4992e90 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -52,12 +52,26 @@ void Camera::set_far(float far) { m_far_plane = far; } +float Camera::get_aspect_ratio() { + return m_aspect_ratio; +} + void Camera::set_aspect_ratio(float new_aspect_ratio) { m_projection_matrix_cache.reset(); m_aspect_ratio = new_aspect_ratio; } +float Camera::get_fov() { + return m_fov_deg; +} + +void Camera::set_fov(float new_fov_deg) { + m_projection_matrix_cache.reset(); + + m_fov_deg = new_fov_deg; +} + float Camera::get_near() { return m_near_plane; } @@ -70,6 +84,32 @@ glm::dvec3 Camera::get_position() { return m_position; } +void Camera::set_position(glm::dvec3 new_position) { + m_view_matrix_cache.reset(); + + m_position = new_position; +} + +glm::quat Camera::get_rotation_quat() { + return m_rotation; +} + +void Camera::set_rotation_quat(glm::quat new_rotation_quat) { + m_view_matrix_cache.reset(); + + m_rotation = new_rotation_quat; +} + +glm::vec3 Camera::get_rotation_euler() { + return glm::eulerAngles(m_rotation); +} + +void Camera::set_rotation_euler(glm::vec3 new_rotation_euler_radians) { + m_view_matrix_cache.reset(); + + m_rotation = glm::quat(new_rotation_euler_radians); +} + glm::dvec3 Camera::get_local_right_dir() { return glm::normalize(m_rotation * glm::dvec3(1.0f, 0.0f, 0.0f)); } diff --git a/src/core/Camera.h b/src/core/Camera.h index 524aabd..37dd491 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -22,12 +22,24 @@ class Camera { void move_local(glm::dvec3 local_movement_delta); void set_near(float near); void set_far(float far); + + float get_aspect_ratio(); void set_aspect_ratio(float new_aspect_ratio); + float get_fov(); + void set_fov(float new_fov_deg); + float get_near(); float get_far(); glm::dvec3 get_position(); + void set_position(glm::dvec3 new_position); + + glm::quat get_rotation_quat(); + void set_rotation_quat(glm::quat new_rotation_quat); + + glm::vec3 get_rotation_euler(); + void set_rotation_euler(glm::vec3 new_rotation_euler_radians); glm::dvec3 get_local_right_dir(); glm::dvec3 get_local_up_dir(); diff --git a/src/core/octree/space.h b/src/core/octree/space.h index aa7d068..5a2a94d 100644 --- a/src/core/octree/space.h +++ b/src/core/octree/space.h @@ -133,7 +133,7 @@ class Space { OctreeRenderIntent generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only) { // Defines under which ratio between dist(cam, node_bbox_centre) / node_bbox_size the node is split // I.e.: dist = 2000 and node_bbox_size = 4000 -> ratio = 0.5 -> node would get refined - double refining_ratio = 0.5f; + double refining_ratio = 1.0f; std::vector refining_ids; refining_ids.push_back(root); diff --git a/src/core/window/Window.cpp b/src/core/window/Window.cpp index 0d01068..2f7a59d 100644 --- a/src/core/window/Window.cpp +++ b/src/core/window/Window.cpp @@ -120,6 +120,10 @@ glm::dvec2 Window::get_window_size() { return glm::dvec2(m_width, m_height); } +GLFWwindow* Window::handle() { + return m_handle; +} + bool Window::is_key_pressed(int key) { auto result = m_key_states.find(key); diff --git a/src/core/window/Window.h b/src/core/window/Window.h index c8107d7..e868bec 100644 --- a/src/core/window/Window.h +++ b/src/core/window/Window.h @@ -39,6 +39,9 @@ class Window { glm::dvec2 get_cursor_position(); glm::dvec2 get_window_size(); + + GLFWwindow* handle(); + bool is_key_pressed(int key); bool is_mouse_button_pressed(int key); From 43ffa4b5f94a97ead123bb60839d8b38dbe6ef27 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Mon, 12 May 2025 12:25:36 +0200 Subject: [PATCH 043/122] Refactoring --- .gitignore | 3 +- src/CMakeLists.txt | 39 +- src/terrainbuilder/main.cpp | 68 +- src/terrainbuilder/mesh_builder.cpp | 37 +- src/terrainbuilder/mesh_builder.h | 4 +- src/terrainbuilder/octree/storage.h | 8 +- src/terrainbuilder/terrainbuilder.cpp | 14 +- src/terrainbuilder/terrainbuilder.h | 6 +- src/terrainconvert/main.cpp | 4 +- src/terrainlib/Dataset.cpp | 72 +- src/terrainlib/Dataset.h | 24 +- src/terrainlib/DatasetReader.cpp | 217 ----- src/terrainlib/DatasetReader.h | 56 -- src/terrainlib/Exception.h | 35 - src/terrainlib/Image.cpp | 45 - src/terrainlib/Image.h | 99 -- src/terrainlib/ParallelTileGenerator.cpp | 109 --- src/terrainlib/ParallelTileGenerator.h | 74 -- src/terrainlib/ParallelTiler.cpp | 72 -- src/terrainlib/ParallelTiler.h | 33 - src/terrainlib/ProgressIndicator.cpp | 42 +- src/terrainlib/ProgressIndicator.h | 10 +- src/terrainlib/TileHeightsGenerator.cpp | 84 -- src/terrainlib/TileHeightsGenerator.h | 39 - src/terrainlib/Tiler.cpp | 68 -- src/terrainlib/Tiler.h | 48 - src/terrainlib/TopDownTiler.cpp | 36 - src/terrainlib/TopDownTiler.h | 30 - src/terrainlib/alpine_raster.cpp | 40 - src/terrainlib/alpine_raster.h | 51 -- src/terrainlib/depth_first_tile_traverser.h | 40 - src/terrainlib/init.cpp | 31 +- src/terrainlib/init.h | 1 - src/terrainlib/log.cpp | 4 +- src/terrainlib/log.h | 28 +- src/terrainlib/mesh/SimpleMesh.h | 54 ++ src/terrainlib/mesh/io.cpp | 854 +----------------- src/terrainlib/mesh/io.h | 154 +--- src/terrainlib/mesh/io/error.h | 102 +++ src/terrainlib/mesh/io/gltf.cpp | 702 ++++++++++++++ src/terrainlib/mesh/io/gltf.h | 37 + src/terrainlib/mesh/io/options.h | 19 + src/terrainlib/mesh/io/terrain.cpp | 147 +++ src/terrainlib/mesh/io/terrain.h | 59 ++ src/terrainlib/mesh/io/texture.cpp | 27 + src/terrainlib/mesh/io/texture.h | 19 + src/terrainlib/mesh/io/utils.cpp | 15 + src/terrainlib/mesh/io/utils.h | 13 + src/terrainlib/mesh/non_copyable.h | 16 - src/terrainlib/mesh/raw_gltf.cpp | 20 - src/terrainlib/mesh/raw_gltf.h | 47 - src/terrainlib/mesh/terrain_mesh.h | 97 -- .../mesh/{terrain_mesh.cpp => utils.cpp} | 43 +- src/terrainlib/mesh/utils.h | 47 + src/terrainlib/srs.h | 31 +- src/terrainmerger/convert.cpp | 6 +- src/terrainmerger/convert.h | 4 +- src/terrainmerger/main.cpp | 22 +- src/terrainmerger/merge.cpp | 67 +- src/terrainmerger/merge.h | 14 +- src/terrainmerger/pch.h | 2 +- src/terrainmerger/simplify.cpp | 13 +- src/terrainmerger/simplify.h | 8 +- src/terrainmerger/uv_map.cpp | 10 +- src/terrainmerger/uv_map.h | 6 +- unittests/terrainbuilder/mesh.cpp | 27 +- unittests/terrainbuilder/mesh_io.cpp | 47 +- unittests/terrainbuilder/texture.cpp | 2 +- unittests/terrainmerger/convert.cpp | 4 +- unittests/terrainmerger/merge.cpp | 30 +- 70 files changed, 1622 insertions(+), 2714 deletions(-) delete mode 100644 src/terrainlib/DatasetReader.cpp delete mode 100644 src/terrainlib/DatasetReader.h delete mode 100644 src/terrainlib/Exception.h delete mode 100644 src/terrainlib/Image.cpp delete mode 100644 src/terrainlib/Image.h delete mode 100644 src/terrainlib/ParallelTileGenerator.cpp delete mode 100644 src/terrainlib/ParallelTileGenerator.h delete mode 100644 src/terrainlib/ParallelTiler.cpp delete mode 100644 src/terrainlib/ParallelTiler.h delete mode 100644 src/terrainlib/TileHeightsGenerator.cpp delete mode 100644 src/terrainlib/TileHeightsGenerator.h delete mode 100644 src/terrainlib/Tiler.cpp delete mode 100644 src/terrainlib/Tiler.h delete mode 100644 src/terrainlib/TopDownTiler.cpp delete mode 100644 src/terrainlib/TopDownTiler.h delete mode 100644 src/terrainlib/alpine_raster.cpp delete mode 100644 src/terrainlib/alpine_raster.h delete mode 100644 src/terrainlib/depth_first_tile_traverser.h create mode 100644 src/terrainlib/mesh/SimpleMesh.h create mode 100644 src/terrainlib/mesh/io/error.h create mode 100644 src/terrainlib/mesh/io/gltf.cpp create mode 100644 src/terrainlib/mesh/io/gltf.h create mode 100644 src/terrainlib/mesh/io/options.h create mode 100644 src/terrainlib/mesh/io/terrain.cpp create mode 100644 src/terrainlib/mesh/io/terrain.h create mode 100644 src/terrainlib/mesh/io/texture.cpp create mode 100644 src/terrainlib/mesh/io/texture.h create mode 100644 src/terrainlib/mesh/io/utils.cpp create mode 100644 src/terrainlib/mesh/io/utils.h delete mode 100644 src/terrainlib/mesh/non_copyable.h delete mode 100644 src/terrainlib/mesh/raw_gltf.cpp delete mode 100644 src/terrainlib/mesh/raw_gltf.h delete mode 100644 src/terrainlib/mesh/terrain_mesh.h rename src/terrainlib/mesh/{terrain_mesh.cpp => utils.cpp} (90%) create mode 100644 src/terrainlib/mesh/utils.h diff --git a/.gitignore b/.gitignore index eeace7f..4cfb18f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ *.tif *.tif.aux.xml /CMakeLists.txt.user -/3rdparty/* build/ .vscode -unittest_tiles +/unittests/output .vs /extern/* diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e24f56c..c0e86db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,37 +59,32 @@ target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) add_library(terrainlib - terrainlib/alpine_raster.h terrainlib/alpine_raster.cpp - - terrainlib/mesh/io.h terrainlib/mesh/io.cpp - terrainlib/mesh/raw_gltf.h terrainlib/mesh/raw_gltf.cpp - terrainlib/mesh/terrain_mesh.h terrainlib/mesh/terrain_mesh.cpp - terrainlib/mesh/non_copyable.h - terrainlib/log.h - terrainlib/log.cpp - - terrainlib/Dataset.h terrainlib/Dataset.cpp - terrainlib/DatasetReader.h terrainlib/DatasetReader.cpp - terrainlib/depth_first_tile_traverser.h - terrainlib/Exception.h - terrainlib/Image.h terrainlib/Image.cpp - terrainlib/ParallelTileGenerator.h terrainlib/ParallelTileGenerator.cpp - terrainlib/ParallelTiler.h terrainlib/ParallelTiler.cpp - terrainlib/ProgressIndicator.h terrainlib/ProgressIndicator.cpp - terrainlib/srs.h - terrainlib/TileHeightsGenerator.h terrainlib/TileHeightsGenerator.cpp - terrainlib/Tiler.h terrainlib/Tiler.cpp - terrainlib/TopDownTiler.h terrainlib/TopDownTiler.cpp terrainlib/ctb/CTBException.hpp terrainlib/ctb/GlobalGeodetic.hpp terrainlib/ctb/GlobalGeodetic.cpp terrainlib/ctb/GlobalMercator.hpp terrainlib/ctb/GlobalMercator.cpp terrainlib/ctb/Grid.hpp terrainlib/ctb/TileCoordinate.hpp terrainlib/ctb/types.hpp + + terrainlib/mesh/io/error.h + terrainlib/mesh/io/gltf.h terrainlib/mesh/io/gltf.cpp + terrainlib/mesh/io/options.h + terrainlib/mesh/io/terrain.h terrainlib/mesh/io/terrain.cpp + terrainlib/mesh/io/texture.h terrainlib/mesh/io/texture.cpp + terrainlib/mesh/io/utils.h terrainlib/mesh/io/utils.cpp + + terrainlib/mesh/io.h terrainlib/mesh/io.cpp + terrainlib/mesh/SimpleMesh.h + terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp + + terrainlib/Dataset.h terrainlib/Dataset.cpp terrainlib/init.h terrainlib/init.cpp + terrainlib/log.h terrainlib/log.cpp + terrainlib/ProgressIndicator.h terrainlib/ProgressIndicator.cpp + terrainlib/srs.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits freeimage cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index 57eddb4..c1db8ab 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -8,11 +8,14 @@ #include #include #include +#include +#include #include "srs.h" #include "Dataset.h" #include "terrainbuilder.h" #include "log.h" +#include "ProgressIndicator.h" #include "ctb/GlobalMercator.hpp" #include "ctb/GlobalGeodetic.hpp" @@ -136,25 +139,6 @@ radix::geometry::Aabb3d parse_target_bounds( UNREACHABLE(); } -void update_progress_bar(std::atomic &completed_tasks, uint32_t total_tasks) { - const uint32_t progress = static_cast((static_cast(completed_tasks) / total_tasks) * 100); - - std::cout << "\rProgress: ["; - uint32_t bar_width = 50; - uint32_t pos = bar_width * progress / 100; - for (uint32_t i = 0; i < bar_width; ++i) { - if (i < pos) { - std::cout << "="; - } else if (i == pos) { - std::cout << ">"; - } else { - std::cout << " "; - } - } - std::cout << "] " << progress << "% (" << completed_tasks.load() << "/" << total_tasks << ")"; - std::cout.flush(); -} - template T expect(const std::optional &opt, const std::string &msg) { if (!opt) { @@ -163,6 +147,7 @@ T expect(const std::optional &opt, const std::string &msg) { return *opt; } + void batch_build( Dataset &dataset, const octree::Level target_level, @@ -184,46 +169,55 @@ void batch_build( space.find_smallest_node_encompassing_bounds(ecef_bounds), "Dataset is outside the octree root node."); - std::vector stack = {root_node}; - std::vector target_nodes; - while (!stack.empty()) { - const octree::Id node = stack.back(); - stack.pop_back(); + tbb::concurrent_vector concurrent_targets; + tbb::task_group tg; + std::function process_node; + + process_node = [&](octree::Id node) { const auto node_bounds = space.get_node_bounds(node); const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer(ecef_srs, dataset_srs, node_bounds); - fmt::println("{}", node); + if (!radix::geometry::intersect(node_bounds_dataset_srs, dataset_bounds)) { - continue; + return; } if (node.level() < target_level) { - const auto children = node.children(); - if (children.has_value()) { - std::copy(children->begin(), children->end(), std::back_inserter(stack)); + if (auto children = node.children(); children.has_value()) { + for (const auto &child : *children) { + tg.run([=] { process_node(child); }); + } } } else if (node.level() == target_level) { - fmt::println("{}", target_nodes.size()); - target_nodes.push_back(node); + concurrent_targets.push_back(node); } - } + }; + + tg.run([&] { process_node(root_node); }); + tg.wait(); // Wait for all tasks + + std::vector target_nodes; + target_nodes.assign(concurrent_targets.begin(), concurrent_targets.end()); + + ProgressIndicator progress(target_nodes.size()); + std::jthread progress_thread = progress.start_monitoring(); - std::atomic nodes_built(0); std::for_each(std::execution::par, target_nodes.begin(), target_nodes.end(), [&](const auto &node) { const auto node_bounds = space.get_node_bounds(node); - const TerrainMesh mesh = terrainbuilder::build( - dataset, + auto local_dataset = dataset.clone(); + const SimpleMesh mesh = terrainbuilder::build( + local_dataset, ecef_srs, node_bounds, texture_srs, texture_base_path, mesh_srs); + if (!mesh.is_empty()) { storage.save_node(node, mesh); } - nodes_built++; - update_progress_bar(nodes_built, target_nodes.size()); + progress.task_finished(); }); } diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index d83127d..25e89ef 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -10,12 +10,13 @@ #include #include "Dataset.h" -#include "mesh/terrain_mesh.h" -#include "srs.h" -#include "raster.h" #include "log.h" +#include "mesh/SimpleMesh.h" #include "mesh_builder.h" +#include "raster.h" #include "raw_dataset_reader.h" +#include "srs.h" +#include "mesh/utils.h" namespace terrainbuilder::mesh { @@ -59,12 +60,12 @@ glm::dvec3 convert_pixel_to_vertex(const float height, const raster::Coords pixe return coords_source; } -TerrainMesh meshify(const raster::Raster& source_points, const raster::Mask& mask) { +SimpleMesh meshify(const raster::Raster& source_points, const raster::Mask& mask) { // Compact the vertex grid into a list of valid ones. const size_t valid_vertex_count = std::reduce(mask.begin(), mask.end(), 0); // Check if we even have any valid vertices. Can happen if all of the region is padding. if (valid_vertex_count == 0) { - return TerrainMesh(); + return SimpleMesh(); } std::vector positions; @@ -105,11 +106,11 @@ TerrainMesh meshify(const raster::Raster& source_points, const raste } assert(triangles.size() <= max_triangle_count); - return TerrainMesh(triangles, positions); + return SimpleMesh(triangles, positions); } -TerrainMesh transform_mesh(const TerrainMesh &source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs) { - TerrainMesh target_mesh; +SimpleMesh transform_mesh(const SimpleMesh &source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs) { + SimpleMesh target_mesh; target_mesh.positions = srs::transform_points(source_srs, target_srs, source_mesh.positions); target_mesh.triangles = source_mesh.triangles; target_mesh.uvs = source_mesh.uvs; @@ -117,7 +118,7 @@ TerrainMesh transform_mesh(const TerrainMesh &source_mesh, const OGRSpatialRefer return target_mesh; } -TerrainMesh reindex_mesh(const TerrainMesh &mesh) { +SimpleMesh reindex_mesh(const SimpleMesh &mesh) { std::vector new_positions; new_positions.reserve(mesh.vertex_count()); std::vector new_triangles; @@ -143,7 +144,7 @@ TerrainMesh reindex_mesh(const TerrainMesh &mesh) { new_triangles.push_back(new_triangle_indices); } - return TerrainMesh(new_triangles, new_positions); + return SimpleMesh(new_triangles, new_positions); } namespace { @@ -165,7 +166,7 @@ namespace { }; } -TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bounds) { +SimpleMesh clip_mesh(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { return {}; } @@ -259,7 +260,7 @@ TerrainMesh clip_mesh(const TerrainMesh &mesh, const radix::geometry::Aabb3d &bo } // TODO: derive new_positions from seen_vertices - return reindex_mesh(TerrainMesh(new_triangles, new_positions)); + return reindex_mesh(SimpleMesh(new_triangles, new_positions)); } std::vector generate_uv_space(const std::vector& positions, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds& texture_bounds) { @@ -280,7 +281,7 @@ radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { return radix::geometry::Aabb3d(min, max); } -tl::expected build_reference_mesh_tile( +tl::expected build_reference_mesh_tile( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &tile_srs, const radix::tile::SrsBounds &tile_bounds, @@ -288,7 +289,7 @@ tl::expected build_reference_mesh_tile( return build_reference_mesh_patch(dataset, mesh_srs, tile_srs, extend_bounds_to_3d(tile_bounds), texture_srs, texture_bounds); } -tl::expected build_reference_mesh_patch( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, @@ -328,15 +329,15 @@ tl::expected build_reference_mesh_patch( }); LOG_TRACE("Generating triangles"); - const TerrainMesh mesh_in_source_srs = meshify(source_points, valid_mask); + const SimpleMesh mesh_in_source_srs = meshify(source_points, valid_mask); // Check if we even have any valid vertices. Can happen if all of the region is padding. if (mesh_in_source_srs.vertex_count() == 0 || mesh_in_source_srs.face_count() == 0) { return tl::unexpected(BuildError::EmptyRegion); } LOG_TRACE("Clipping mesh based on target bounds"); - const TerrainMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); - TerrainMesh clipped_mesh = clip_mesh(mesh_in_clip_srs, clip_bounds); + const SimpleMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); + SimpleMesh clipped_mesh = clip_mesh(mesh_in_clip_srs, clip_bounds); // Check if there are any vertices left if (clipped_mesh.vertex_count() == 0 || clipped_mesh.face_count() == 0) { return tl::unexpected(BuildError::EmptyRegion); @@ -347,7 +348,7 @@ tl::expected build_reference_mesh_patch( clipped_mesh.uvs = generate_uv_space(clipped_mesh.positions, clip_srs, texture_srs, texture_bounds); LOG_TRACE("Transforming mesh into output srs"); - TerrainMesh target_mesh = transform_mesh(clipped_mesh, clip_srs, mesh_srs); + SimpleMesh target_mesh = transform_mesh(clipped_mesh, clip_srs, mesh_srs); remove_isolated_vertices(target_mesh); // TODO: is this still required? validate_mesh(target_mesh); diff --git a/src/terrainbuilder/mesh_builder.h b/src/terrainbuilder/mesh_builder.h index feadc3c..5e68ce5 100644 --- a/src/terrainbuilder/mesh_builder.h +++ b/src/terrainbuilder/mesh_builder.h @@ -6,7 +6,7 @@ #include "Dataset.h" #include "srs.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" #include "border.h" namespace terrainbuilder::mesh { @@ -18,7 +18,7 @@ enum class BuildError { std::ostream &operator<<(std::ostream &os, BuildError error); /// Builds a mesh from the given height dataset. -tl::expected build_reference_mesh_patch( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainbuilder/octree/storage.h index 17d2076..fc20eae 100644 --- a/src/terrainbuilder/octree/storage.h +++ b/src/terrainbuilder/octree/storage.h @@ -6,10 +6,10 @@ #include "id.h" #include "mesh/io.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" namespace octree { -using Node = TerrainMesh; +using Node = SimpleMesh; class Storage { public: @@ -17,7 +17,7 @@ class Storage { std::optional load_node(const Id &id) const { const auto node_path = this->get_node_path(id); - const auto result = io::load_mesh_from_path(node_path); + const auto result = mesh::io::load_from_path(node_path); if (result.has_value()) { return result.value(); } else { @@ -27,7 +27,7 @@ class Storage { bool save_node(const Id &id, const Node &node) const { const auto node_path = this->get_node_path(id); - const auto result = io::save_mesh_to_path(node_path, node); + const auto result = mesh::io::save_to_path(node, node_path); return result.has_value(); } diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 21014f3..6fb27ab 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -12,7 +12,7 @@ #include "log.h" #include "mesh/io.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" #include "mesh_builder.h" #include "terrainbuilder.h" #include "texture_assembler.h" @@ -22,6 +22,7 @@ namespace terrainbuilder { +namespace { std::string format_secs_since(const std::chrono::high_resolution_clock::time_point &start) { const auto duration = std::chrono::high_resolution_clock::now() - start; const double seconds = std::chrono::duration(duration).count(); @@ -29,6 +30,7 @@ std::string format_secs_since(const std::chrono::high_resolution_clock::time_poi ss << std::fixed << std::setprecision(2) << seconds; return ss.str(); } +} class BasemapSchemeTilePathProvider : public TilePathProvider { public: @@ -43,7 +45,7 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { std::filesystem::path base_path; }; -TerrainMesh build( +SimpleMesh build( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -56,7 +58,7 @@ TerrainMesh build( std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); LOG_INFO("Building mesh..."); - tl::expected mesh_result = mesh::build_reference_mesh_patch( + tl::expected mesh_result = mesh::build_reference_mesh_patch( dataset, mesh_srs, target_bounds_srs, target_bounds, @@ -86,7 +88,7 @@ TerrainMesh build( return {}; } } - TerrainMesh mesh = mesh_result.value(); + SimpleMesh mesh = mesh_result.value(); LOG_DEBUG("Mesh building took {}s", format_secs_since(start)); LOG_INFO("Finished building mesh geometry"); @@ -117,7 +119,7 @@ void build_and_save( const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_path) { - const TerrainMesh mesh = build( + const SimpleMesh mesh = build( dataset, target_bounds_srs, target_bounds, @@ -143,7 +145,7 @@ void build_and_save( "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); */ - if (!io::save_mesh_to_path(output_path, mesh, io::SaveOptions{.metadata = metadata}).has_value()) { + if (!::mesh::io::save_to_path(mesh, output_path, ::mesh::io::SaveOptions{.metadata = metadata}).has_value()) { LOG_ERROR("Failed to save mesh to file {}", output_path.string()); exit(2); } diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index 2db979f..59c9e53 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -6,8 +6,7 @@ #include #include "Dataset.h" -#include "mesh/terrain_mesh.h" -#include "srs.h" +#include "mesh/SimpleMesh.h" namespace terrainbuilder { @@ -20,13 +19,14 @@ void build_and_save( const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_path); -TerrainMesh build( +SimpleMesh build( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, const OGRSpatialReference &texture_srs, const std::optional texture_base_path, const OGRSpatialReference &mesh_srs); + } #endif diff --git a/src/terrainconvert/main.cpp b/src/terrainconvert/main.cpp index b8d2f66..62d0b06 100644 --- a/src/terrainconvert/main.cpp +++ b/src/terrainconvert/main.cpp @@ -11,12 +11,12 @@ void run(const cli::Args& args) { LOG_INFO("Loading input mesh..."); - const tl::expected load_result = io::load_mesh_from_path(args.input_path); + const tl::expected load_result = io::load_mesh_from_path(args.input_path); if (!load_result.has_value()) { LOG_ERROR("Failed to load mesh: {}", load_result.error().description()); return; } - TerrainMesh mesh = load_result.value(); + SimpleMesh mesh = load_result.value(); if (args.texture_resolution.has_value()) { if (mesh.texture.has_value()) { diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 781a5c6..0823541 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -27,44 +27,45 @@ #include -#include "Exception.h" #include "ctb/Grid.hpp" -#include "srs.h" #include "init.h" #include "log.h" +#include "srs.h" Dataset::Dataset(const std::string &path) { initialize_gdal_once(); - const auto gdal_dataset = GDALOpenEx( - path.c_str(), - GDAL_OF_READONLY | GDAL_OF_THREAD_SAFE | GDAL_OF_RASTER | GDAL_OF_INTERNAL, - nullptr, nullptr, nullptr); - m_gdal_dataset.reset(static_cast(gdal_dataset)); + m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); if (!m_gdal_dataset) { LOG_ERROR("Couldn't open dataset {}.\n", path); - throw Exception(""); + throw std::runtime_error(""); } + m_path = path; m_name = std::regex_replace(path, std::regex("^.*/"), ""); m_name = std::regex_replace(m_name, std::regex(R"(\.\w+$)"), ""); } -Dataset::Dataset(GDALDataset* dataset) -{ +Dataset::Dataset(GDALDataset *dataset) { initialize_gdal_once(); m_gdal_dataset.reset(dataset); if (!m_gdal_dataset) { LOG_ERROR("Dataset is null.\n"); - throw Exception("Dataset is null."); + throw std::runtime_error("Dataset is null."); } } -DatasetPtr Dataset::make_shared(const std::string& path) -{ +DatasetPtr Dataset::make_shared(const std::string &path) { return std::make_shared(path); } -std::string Dataset::name() const -{ +Dataset Dataset::clone() { + if (!m_path.has_value()) { + LOG_ERROR("Cannot clone dataset.\n"); + throw std::runtime_error("Cannot clone dataset."); + } + return Dataset(this->m_path.value()); +} + +std::string Dataset::name() const { return m_name; } @@ -73,7 +74,7 @@ Dataset::~Dataset() = default; radix::tile::SrsBounds Dataset::bounds() const { std::array adfGeoTransform = {}; if (m_gdal_dataset->GetGeoTransform(adfGeoTransform.data()) != CE_None) - throw Exception("Could not get transformation information from source dataset"); + throw std::runtime_error("Could not get transformation information from source dataset"); // https://gdal.org/user/raster_data_model.html // gdal has a row/column raster format, where row 0 is the top most row. @@ -82,14 +83,14 @@ radix::tile::SrsBounds Dataset::bounds() const { // we don't support sheering or rotation for now if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) - throw Exception("Dataset geo transform contains sheering or rotation. This is not supported!"); + throw std::runtime_error("Dataset geo transform contains sheering or rotation. This is not supported!"); const double westX = adfGeoTransform[0]; const double southY = adfGeoTransform[3] + (heightInPixels() * adfGeoTransform[5]); const double eastX = adfGeoTransform[0] + (widthInPixels() * adfGeoTransform[1]); const double northY = adfGeoTransform[3]; - return { {westX, southY}, {eastX, northY} }; + return {{westX, southY}, {eastX, northY}}; } radix::tile::SrsAndHeightBounds Dataset::bounds3d() const { @@ -114,7 +115,6 @@ radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) con const auto north = l_bounds.max.y; const auto south = l_bounds.min.y; - const auto data_srs = srs(); if (targetSrs.IsSame(&data_srs)) return l_bounds; @@ -131,14 +131,14 @@ radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) con const auto deltaX = l_bounds.width() / 2000.0; if (deltaX <= 0.0) - throw Exception("west coordinate > east coordinate. This is not supported."); + throw std::runtime_error("west coordinate > east coordinate. This is not supported."); for (double s = west; s < east; s += deltaX) { addCoordinate(s, south); addCoordinate(s, north); } const auto deltaY = (north - south) / 2000.0; if (deltaY <= 0.0) - throw Exception("south coordinate > north coordinate. This is not supported."); + throw std::runtime_error("south coordinate > north coordinate. This is not supported."); for (double s = south; s < north; s += deltaY) { addCoordinate(west, s); addCoordinate(east, s); @@ -157,26 +157,23 @@ radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) con const double target_maxX = *std::max_element(x.begin(), x.end()); const double target_minY = *std::min_element(y.begin(), y.end()); const double target_maxY = *std::max_element(y.begin(), y.end()); - return { {target_minX, target_minY}, {target_maxX, target_maxY} }; + return {{target_minX, target_minY}, {target_maxX, target_maxY}}; } -OGRSpatialReference Dataset::srs() const -{ - const char* srcWKT = m_gdal_dataset->GetProjectionRef(); +OGRSpatialReference Dataset::srs() const { + const char *srcWKT = m_gdal_dataset->GetProjectionRef(); if (!strlen(srcWKT)) - throw Exception("The source dataset does not have a spatial reference system assigned"); + throw std::runtime_error("The source dataset does not have a spatial reference system assigned"); auto srs = OGRSpatialReference(srcWKT); srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); return srs; } -unsigned Dataset::widthInPixels() const -{ +unsigned Dataset::widthInPixels() const { return ctb::i_pixel(m_gdal_dataset->GetRasterXSize()); } -unsigned Dataset::heightInPixels() const -{ +unsigned Dataset::heightInPixels() const { return ctb::i_pixel(m_gdal_dataset->GetRasterYSize()); } @@ -188,32 +185,27 @@ double Dataset::heightInPixels(const radix::tile::SrsBounds &bounds, const OGRSp return bounds.height() / pixelHeightIn(bounds_srs); } -unsigned Dataset::n_bands() const -{ +unsigned Dataset::n_bands() const { const auto n = m_gdal_dataset->GetRasterCount(); assert(n >= 0); return unsigned(n); } -GDALDataset* Dataset::gdalDataset() -{ +GDALDataset *Dataset::gdalDataset() { return m_gdal_dataset.get(); } -double Dataset::gridResolution(const OGRSpatialReference& target_srs) const -{ +double Dataset::gridResolution(const OGRSpatialReference &target_srs) const { return std::min(pixelWidthIn(target_srs), pixelHeightIn(target_srs)); } -double Dataset::pixelWidthIn(const OGRSpatialReference& target_srs) const -{ +double Dataset::pixelWidthIn(const OGRSpatialReference &target_srs) const { const auto b0 = bounds(); const auto b1 = srs::non_exact_bounds_transform(b0, srs(), target_srs); return b1.width() / widthInPixels(); } -double Dataset::pixelHeightIn(const OGRSpatialReference& target_srs) const -{ +double Dataset::pixelHeightIn(const OGRSpatialReference &target_srs) const { const auto b = srs::non_exact_bounds_transform(bounds(), srs(), target_srs); return b.height() / heightInPixels(); } diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index ac64264..622dc01 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -41,7 +41,8 @@ class Dataset { Dataset(const std::string& path); Dataset(GDALDataset* dataset); // takes over ownership ~Dataset(); - static DatasetPtr make_shared(const std::string& path); + static DatasetPtr make_shared(const std::string &path); + Dataset clone(); [[nodiscard]] std::string name() const; @@ -49,20 +50,21 @@ class Dataset { [[nodiscard]] radix::tile::SrsAndHeightBounds bounds3d() const; [[nodiscard]] radix::tile::SrsBounds bounds(const OGRSpatialReference &targetSrs) const; [[nodiscard]] OGRSpatialReference srs() const; - [[nodiscard]] unsigned widthInPixels() const; - [[nodiscard]] unsigned heightInPixels() const; - [[nodiscard]] double widthInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; - [[nodiscard]] double heightInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const; - [[nodiscard]] unsigned n_bands() const; - [[nodiscard]] GDALDataset* gdalDataset(); + [[nodiscard]] unsigned int widthInPixels() const; + [[nodiscard]] unsigned int heightInPixels() const; + [[nodiscard]] double widthInPixels(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &bounds_srs) const; + [[nodiscard]] double heightInPixels(const radix::tile::SrsBounds &bounds, const OGRSpatialReference &bounds_srs) const; + [[nodiscard]] unsigned int n_bands() const; + [[nodiscard]] GDALDataset *gdalDataset(); - [[nodiscard]] double gridResolution(const OGRSpatialReference& target_srs) const; - [[nodiscard]] double pixelWidthIn(const OGRSpatialReference& target_srs) const; - [[nodiscard]] double pixelHeightIn(const OGRSpatialReference& target_srs) const; + [[nodiscard]] double gridResolution(const OGRSpatialReference &target_srs) const; + [[nodiscard]] double pixelWidthIn(const OGRSpatialReference &target_srs) const; + [[nodiscard]] double pixelHeightIn(const OGRSpatialReference &target_srs) const; private: std::unique_ptr m_gdal_dataset; + std::optional m_path; std::string m_name; -}; + }; #endif diff --git a/src/terrainlib/DatasetReader.cpp b/src/terrainlib/DatasetReader.cpp deleted file mode 100644 index 351bfc8..0000000 --- a/src/terrainlib/DatasetReader.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/******************************************************************************* - * Copyright 2014 GeoData - * Copyright 2022 Adam Celarek - * - * Licensed 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 "DatasetReader.h" -#include "Dataset.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Dataset.h" -#include "Exception.h" -#include "Image.h" -#include "ctb/types.hpp" - -namespace { -std::string toWkt(const OGRSpatialReference& srs) -{ - char* wkt_char_string = nullptr; - srs.exportToWkt(&wkt_char_string); - std::string wkt_string(wkt_char_string); - CPLFree(wkt_char_string); - return wkt_string; -} - -std::array computeGeoTransform(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) -{ - return { bounds.min.x, bounds.width() / width, 0, - bounds.max.y, 0, -bounds.height() / height }; -} - -using GdalImageTransformArgsPtr = std::unique_ptr; -GdalImageTransformArgsPtr make_image_transform_args(const DatasetReader &reader, - Dataset *dataset, - const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) { - CPLStringList transformOptions; - if (reader.isReprojecting()) { - transformOptions.SetNameValue("SRC_SRS", reader.dataset_srs_wkt().c_str()); - transformOptions.SetNameValue("DST_SRS", reader.target_srs_wkt().c_str()); - } - auto args = GdalImageTransformArgsPtr(GDALCreateGenImgProjTransformer2(dataset->gdalDataset(), nullptr, transformOptions.List()), &GDALDestroyGenImgProjTransformer); - if (!args) { - throw Exception("GDALCreateGenImgProjTransformer2 failed."); - } - - const auto adfGeoTransform = computeGeoTransform(bounds, width, height); - GDALSetGenImgProjTransformerDstGeoTransform(args.get(), adfGeoTransform.data()); - - return args; -} - -using GdalWarpOptionsPtr = std::unique_ptr; -using WarpOptionData = std::pair; - -WarpOptionData makeWarpOptions(const DatasetReader& reader, Dataset* dataset, const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) -{ - auto options = GdalWarpOptionsPtr(GDALCreateWarpOptions(), &GDALDestroyWarpOptions); - options->hSrcDS = dataset->gdalDataset(); - options->nBandCount = 1; - options->eResampleAlg = GDALResampleAlg::GRA_Cubic; - options->panSrcBands = static_cast(CPLMalloc(sizeof(int) * 1)); - options->panDstBands = static_cast(CPLMalloc(sizeof(int) * 1)); - options->padfSrcNoDataReal = static_cast(CPLMalloc(sizeof(double) * 1)); - options->padfSrcNoDataImag = static_cast(CPLMalloc(sizeof(double) * 1)); - options->padfDstNoDataReal = static_cast(CPLMalloc(sizeof(double) * 1)); - options->padfDstNoDataImag = static_cast(CPLMalloc(sizeof(double) * 1)); - { - int bGotNoData = false; - double noDataValue = dataset->gdalDataset()->GetRasterBand(1)->GetNoDataValue(&bGotNoData); - if (!bGotNoData) - noDataValue = -32768; - - options->padfSrcNoDataReal[0] = noDataValue; - options->padfSrcNoDataImag[0] = 0; - options->padfDstNoDataReal[0] = noDataValue; - options->padfDstNoDataImag[0] = 0; - - options->panSrcBands[0] = int(reader.dataset_band()); - options->panDstBands[0] = 1; - } - constexpr auto use_approximation = true; - if (use_approximation) { - const auto error_threshold = 0.5; - auto image_transform_args = make_image_transform_args(reader, dataset, bounds, width, height); - options->pTransformerArg = GDALCreateApproxTransformer(GDALGenImgProjTransform, image_transform_args.get(), error_threshold); - options->pfnTransformer = GDALApproxTransform; - return { std::move(options), std::move(image_transform_args) }; - } - - options->pTransformerArg = make_image_transform_args(reader, dataset, bounds, width, height).release(); - options->pfnTransformer = GDALGenImgProjTransform; - - return { std::move(options), GdalImageTransformArgsPtr(nullptr, &GDALDestroyGenImgProjTransformer) }; -} - -#ifdef ATB_ENABLE_OVERVIEW_READING -std::shared_ptr getOverviewDataset(const std::shared_ptr& dataset, void* hTransformerArg, bool warn_on_missing_overviews) -{ - GDALDataset* poSrcDS = dataset->gdalDataset(); - int nOvLevel = -2; - int nOvCount = poSrcDS->GetRasterBand(1)->GetOverviewCount(); - - assert(nOvCount >= 0); - if (nOvCount == 0) { - if (warn_on_missing_overviews) - LOG_WARN("No dataset overviews found."); - return dataset; - } - - std::array adfSuggestedGeoTransform; - std::array adfExtent; - int nPixels; - int nLines; - /* Compute what the "natural" output resolution (in pixels) would be for this */ - /* input dataset */ - if (GDALSuggestedWarpOutput2(poSrcDS, GDALGenImgProjTransform, hTransformerArg, - adfSuggestedGeoTransform.data(), &nPixels, &nLines, - adfExtent.data(), 0) - == CE_Failure) { - LOG_WARN("GDALSuggestedWarpOutput2 failed. We won't use dataset overviews!"); - return dataset; - } - - double dfTargetRatio = 1.0 / adfSuggestedGeoTransform[1]; - // if( dfTargetRatio <= 1.0 ) { - // LOG_WARN(fmt::format("dfTargetRatio {} <= 1.0. We won't use dataset overviews!\n", dfTargetRatio)); - // LOG_WARN(fmt::format("Other values: nPixels={}, nLines={}, adfExtent={}/{}/{}/{}\n", - // nPixels, nLines, adfExtent[0], adfExtent[1], adfExtent[2], adfExtent[3])); - // LOG_WARN(fmt::format("Other values: adfSuggestedGeoTransform={}/{}/{}/{}/{}/{}\n", - // adfSuggestedGeoTransform[0], adfSuggestedGeoTransform[1], adfSuggestedGeoTransform[2], - // adfSuggestedGeoTransform[3], adfSuggestedGeoTransform[4], adfSuggestedGeoTransform[5])); - // return dataset; - // } - - int iOvr; - for (iOvr = -1; iOvr < nOvCount - 1; iOvr++) { - const auto dfOvrRatio = (iOvr < 0) ? 1.0 : double(poSrcDS->GetRasterXSize()) / poSrcDS->GetRasterBand(1)->GetOverview(iOvr)->GetXSize(); - const auto dfNextOvrRatio = double(poSrcDS->GetRasterXSize()) / poSrcDS->GetRasterBand(1)->GetOverview(iOvr + 1)->GetXSize(); - if (dfOvrRatio < dfTargetRatio && dfNextOvrRatio > dfTargetRatio) - break; - if (std::abs(dfOvrRatio - dfTargetRatio) < 1e-1) - break; - } - iOvr += nOvLevel + 2; - if (iOvr >= 0) { - LOG_DEBUG("WARPING: Selecting overview level {} for output dataset {}x{}\n", iOvr, nPixels, nLines); - return std::make_shared(static_cast(GDALCreateOverviewDataset(poSrcDS, iOvr, FALSE))); - } - return dataset; -} -#endif - -} - -DatasetReader::DatasetReader(const std::shared_ptr& dataset, const OGRSpatialReference& targetSRS, unsigned band, bool warn_on_missing_overviews) - : m_dataset(dataset) - , m_dataset_srs_wkt(toWkt(dataset->srs())) - , m_target_srs_wkt(toWkt(targetSRS)) - , m_requires_reprojection(!dataset->srs().IsSame(&targetSRS)) - , m_warn_on_missing_overviews(warn_on_missing_overviews) - , m_band(band) -{ - if (band > dataset->n_bands()) - throw Exception(fmt::format("Dataset does not contain band number {} (there are {} bands).", band, dataset->n_bands())); -} - -HeightData DatasetReader::read(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { - return readFrom(m_dataset, bounds, width, height); -} - -HeightData DatasetReader::readWithOverviews(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { -#ifdef ATB_ENABLE_OVERVIEW_READING - auto transformer_args = make_image_transform_args(*this, m_dataset.get(), bounds, width, height); - auto source_dataset = getOverviewDataset(m_dataset, transformer_args.get(), m_warn_on_missing_overviews); - - return readFrom(source_dataset, bounds, width, height); -#else - return read(bounds, width, height); -#endif -} - -HeightData DatasetReader::readFrom(const std::shared_ptr &source_dataset, const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const { - // if we have performance problems with the warping, it'd still be possible to approximate the warping operation with a linear transform (mostly when zoomed in / on higher zoom levels). - // CTB does this in GDALTiler.cpp around line 375 ("// Decide if we are doing an approximate or exact transformation"). - - auto warp_options = makeWarpOptions(*this, source_dataset.get(), bounds, width, height); - auto adfGeoTransform = computeGeoTransform(bounds, width, height); - auto warped_dataset = Dataset(static_cast(GDALCreateWarpedVRT(source_dataset->gdalDataset(), int(width), int(height), adfGeoTransform.data(), warp_options.first.get()))); - - auto* heights_band = warped_dataset.gdalDataset()->GetRasterBand(1); // non-owning pointer - auto heights_data = HeightData(width, height); - if (heights_band->RasterIO(GF_Read, 0, 0, int(width), int(height), - static_cast(heights_data.data()), int(width), int(height), GDT_Float32, 0, 0) - != CE_None) - throw Exception("couldn't read data"); - - return heights_data; -} diff --git a/src/terrainlib/DatasetReader.h b/src/terrainlib/DatasetReader.h deleted file mode 100644 index 62e161e..0000000 --- a/src/terrainlib/DatasetReader.h +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef DATASETREADER_H -#define DATASETREADER_H - -#include -#include - -#include "Image.h" -#include - -class Dataset; -class OGRSpatialReference; - -class DatasetReader { -public: - DatasetReader(const std::shared_ptr& dataset, const OGRSpatialReference& targetSRS, unsigned band, bool warn_on_missing_overviews = true); - - HeightData read(const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const; - HeightData readWithOverviews(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const; - - unsigned dataset_band() const { return m_band; } - bool isReprojecting() const { return m_requires_reprojection; } - std::string dataset_srs_wkt() const { return m_dataset_srs_wkt; } - std::string target_srs_wkt() const { return m_target_srs_wkt; } - -protected: - HeightData readFrom(const std::shared_ptr &dataset, const radix::tile::SrsBounds &bounds, unsigned width, unsigned height) const; - -private: - std::shared_ptr m_dataset; - std::string m_dataset_srs_wkt; - std::string m_target_srs_wkt; - bool m_requires_reprojection; - bool m_warn_on_missing_overviews; - unsigned m_band; -}; - -#endif // DATASETREADER_H diff --git a/src/terrainlib/Exception.h b/src/terrainlib/Exception.h deleted file mode 100644 index 6984a40..0000000 --- a/src/terrainlib/Exception.h +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef EXCEPTION_H -#define EXCEPTION_H - -#include - -/// This represents a CTB runtime error -class Exception : public std::runtime_error { -public: - Exception(const std::string& message) - : std::runtime_error(message) - { - while (false) { } - } -}; - -#endif // EXCEPTION_H diff --git a/src/terrainlib/Image.cpp b/src/terrainlib/Image.cpp deleted file mode 100644 index 3f1f668..0000000 --- a/src/terrainlib/Image.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "Image.h" -#include "init.h" -#include -#include - -void image::saveImageAsPng(const Image& image, const std::string& path) -{ - initialize_freeimage_once(); - - FIBITMAP* free_bitmap = FreeImage_Allocate(int(image.width()), int(image.height()), 24); - // free image has line 0 at the bottom - for (unsigned free_row = 0; free_row < image.height(); ++free_row) { - unsigned alpine_row = image.height() - free_row - 1; - assert(alpine_row < image.height()); - for (unsigned col = 0; col < image.width(); ++col) { - RGBQUAD colour; - colour.rgbRed = image.pixel(alpine_row, col).x; - colour.rgbGreen = image.pixel(alpine_row, col).y; - colour.rgbBlue = image.pixel(alpine_row, col).z; - FreeImage_SetPixelColor(free_bitmap, col, free_row, &colour); - } - } - FreeImage_Save(FIF_PNG, free_bitmap, path.c_str(), PNG_Z_BEST_COMPRESSION); - FreeImage_Unload(free_bitmap); - // FreeImage_DeInitialise(); -} diff --git a/src/terrainlib/Image.h b/src/terrainlib/Image.h deleted file mode 100644 index 814d1f1..0000000 --- a/src/terrainlib/Image.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef IMAGE_H -#define IMAGE_H - -#include -#include -#include -#include -#include -#include - -#include - -template -class Image { -public: - Image() = default; - Image(unsigned width, unsigned height) - : m_width(width) - , m_height(height) - , m_data(size_t(m_width * m_height)) - { - } - - [[nodiscard]] unsigned width() const { return m_width; } - [[nodiscard]] unsigned height() const { return m_height; } - [[nodiscard]] T pixel(unsigned row, unsigned column) const - { - assert(column < m_width); - assert(row < m_height); - assert(m_data.size() == size_t(m_width * m_height)); - return m_data[row * m_width + column]; - } - - [[nodiscard]] T* data() { return m_data.data(); } - [[nodiscard]] const T *data() const { return m_data.data(); } - - [[nodiscard]] auto size() const { return m_data.size(); } - [[nodiscard]] auto begin() { return m_data.begin(); } - [[nodiscard]] auto end() { return m_data.end(); } - [[nodiscard]] auto begin() const { return m_data.begin(); } - [[nodiscard]] auto end() const { return m_data.end(); } - -private: - unsigned m_width = 0; - unsigned m_height = 0; - std::vector m_data; -}; - -using HeightData = Image; -using RgbImage = Image; -using uchar = unsigned char; - -namespace image { -void saveImageAsPng(const Image& image, const std::string& path); - -template -[[nodiscard]] auto transformImage(const Image& i, Fun conversion_fun) -> Image -{ - using T2 = decltype(conversion_fun(*i.begin())); - Image i2(i.width(), i.height()); - std::transform(i.begin(), i.end(), i2.begin(), conversion_fun); - return i2; -} - -template -void debugOut(const Image& image, const std::string& path) -{ - auto [min, max] = std::ranges::minmax(image); - - // [min=min, ..] is required for cpp correctness. min/max from the capture are not variables, we need to copy them: - // https://stackoverflow.com/questions/50799719/reference-to-local-binding-declared-in-enclosing-function?noredirect=1&lq=1 - saveImageAsPng(transformImage(image, [min = min, max = max](auto v) { - const auto c = uchar(255.F * (float(v) - float(min)) / float(max - min)); - return glm::u8vec3(c, c, c); - }), - path); -} -} - -#endif // HEIGHTDATA_H diff --git a/src/terrainlib/ParallelTileGenerator.cpp b/src/terrainlib/ParallelTileGenerator.cpp deleted file mode 100644 index cd28ae2..0000000 --- a/src/terrainlib/ParallelTileGenerator.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "ParallelTileGenerator.h" -#include "ProgressIndicator.h" - -#include -#include - -#include - -#include "Dataset.h" -#include "ctb/GlobalGeodetic.hpp" -#include "ctb/GlobalMercator.hpp" - -#include -#include - -ParallelTileGenerator::ParallelTileGenerator(const std::string& input_data_path, const ctb::Grid& grid, const ParallelTiler& tiler, std::unique_ptr tile_writer, const std::string& output_data_path) - : m_output_data_path(output_data_path) - , m_input_data_path(input_data_path) - , m_grid(grid) - , m_tiler(tiler) - , m_tile_writer(std::move(tile_writer)) -{ -} - -ParallelTileGenerator ParallelTileGenerator::make(const std::string &input_data_path, - ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, - std::unique_ptr tile_writer, - const std::string &output_data_path, - unsigned grid_resolution) { - const auto dataset = Dataset::make_shared(input_data_path); - ctb::Grid grid = ctb::GlobalGeodetic(grid_resolution); - if (srs == ctb::Grid::Srs::SphericalMercator) - grid = ctb::GlobalMercator(grid_resolution); - const auto border = tile_writer->formatRequiresBorder(); - return { input_data_path, grid, ParallelTiler(grid, dataset->bounds(grid.getSRS()), border, tiling_scheme), std::move(tile_writer), output_data_path }; -} - -const ParallelTiler& ParallelTileGenerator::tiler() const -{ - return m_tiler; -} - -const ctb::Grid& ParallelTileGenerator::grid() const -{ - return m_grid; -} - -void ParallelTileGenerator::write(const radix::tile::Descriptor &tile, const HeightData &heights) const { - const auto dir_path = fmt::format("{}/{}/{}", m_output_data_path, tile.id.zoom_level, tile.id.coords.x); - const auto file_path = fmt::format("{}/{}.{}", dir_path, tile.id.coords.y, m_tile_writer->formatFileEnding()); - std::filesystem::create_directories(dir_path); - m_tile_writer->write(file_path, tile, heights); -} - -void ParallelTileGenerator::process(const std::pair& zoom_range, bool progress_bar_on_console, bool generate_world_wide_tiles) const -{ - auto tiler = m_tiler; - if (generate_world_wide_tiles) - tiler.setBounds(grid().getExtent()); - - const auto tiles = tiler.generateTiles(zoom_range); - - auto pi = ProgressIndicator(tiles.size()); - std::jthread monitoring_thread; - - if (progress_bar_on_console) - monitoring_thread = pi.startMonitoring(); // destructor will join. - - const auto fun = [&pi, progress_bar_on_console, this](const radix::tile::Descriptor &tile) { - // Recreating Dataset for every tile. This was the easiest fix for multithreading, - // and it takes only 0.5% of the time (half a percent). - // most of the cpu time is used in 'readWithOverviews' (specificly 'RasterIO', and - // 'VRTWarpedRasterBand::IReadBlock') and a bit in 'write' (specifically 'FreeImage_Save'). - const auto dataset = Dataset::make_shared(m_input_data_path); - DatasetReader reader(dataset, m_grid.getSRS(), 1, m_warn_on_missing_overviews); - const auto heights = reader.readWithOverviews(tile.srsBounds, tile.tileSize, tile.tileSize); - write(tile, heights); - if (progress_bar_on_console) - pi.taskFinished(); - }; - std::for_each(std::execution::par, tiles.begin(), tiles.end(), fun); -} - -radix::tile::Border ParallelTileWriterInterface::formatRequiresBorder() const { - return m_format_requires_border; -} - -const std::string& ParallelTileWriterInterface::formatFileEnding() const -{ - return m_file_ending; -} diff --git a/src/terrainlib/ParallelTileGenerator.h b/src/terrainlib/ParallelTileGenerator.h deleted file mode 100644 index 033334d..0000000 --- a/src/terrainlib/ParallelTileGenerator.h +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef PARALLELTILEGENERATOR_H -#define PARALLELTILEGENERATOR_H - -#include -#include - -#include "Image.h" -#include "ParallelTiler.h" -#include "ctb/Grid.hpp" -#include "ctb/types.hpp" -#include - -class ParallelTileWriterInterface; - -class ParallelTileGenerator { - std::string m_output_data_path; - std::string m_input_data_path; - ctb::Grid m_grid; - ParallelTiler m_tiler; - std::unique_ptr m_tile_writer; - bool m_warn_on_missing_overviews = true; - -public: - ParallelTileGenerator(const std::string& input_data_path, const ctb::Grid& grid, const ParallelTiler& tiler, std::unique_ptr tile_writer, const std::string& output_data_path); - [[nodiscard]] static ParallelTileGenerator make(const std::string &input_data_path, - ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, - std::unique_ptr tile_writer, - const std::string &output_data_path, - unsigned grid_resolution = 256); - - void setWarnOnMissingOverviews(bool flag) { m_warn_on_missing_overviews = flag; } - [[nodiscard]] const ParallelTiler& tiler() const; - [[nodiscard]] const ctb::Grid& grid() const; - void write(const radix::tile::Descriptor &tile, const HeightData &heights) const; - void process(const std::pair& zoom_range, bool progress_bar_on_console = false, bool generate_world_wide_tiles = false) const; -}; - -class ParallelTileWriterInterface { - radix::tile::Border m_format_requires_border; - std::string m_file_ending; - -public: - ParallelTileWriterInterface(radix::tile::Border format_requires_border, const std::string &file_ending) - : m_format_requires_border(format_requires_border), m_file_ending(file_ending) { - } - ParallelTileWriterInterface(const ParallelTileWriterInterface&) = default; - ParallelTileWriterInterface(ParallelTileWriterInterface&&) = default; - virtual ~ParallelTileWriterInterface() = default; - ParallelTileWriterInterface& operator=(const ParallelTileWriterInterface&) = default; - ParallelTileWriterInterface& operator=(ParallelTileWriterInterface&&) = default; - virtual void write(const std::string &file_path, const radix::tile::Descriptor &tile, const HeightData &heights) const = 0; - [[nodiscard]] radix::tile::Border formatRequiresBorder() const; - [[nodiscard]] const std::string& formatFileEnding() const; -}; - -#endif // PARALLELTILEGENERATOR_H diff --git a/src/terrainlib/ParallelTiler.cpp b/src/terrainlib/ParallelTiler.cpp deleted file mode 100644 index ca77293..0000000 --- a/src/terrainlib/ParallelTiler.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "ParallelTiler.h" - -#include "Exception.h" -#include - -ParallelTiler::ParallelTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) : Tiler(grid, bounds, border, scheme) -{ -} - -radix::tile::Id ParallelTiler::southWestTile(unsigned zoom_level) const { - return grid().crsToTile(bounds().min, zoom_level).to(scheme()); -} - -radix::tile::Id ParallelTiler::northEastTile(unsigned zoom_level) const -{ - const auto epsilon = grid().resolution(zoom_level) / 100; - return grid().crsToTile(bounds().max - epsilon, zoom_level).to(scheme()); -} - -std::vector ParallelTiler::generateTiles(unsigned zoom_level) const -{ - // in the tms scheme south west corresponds to the smaller numbers. hence we can iterate from sw to ne - const auto sw = southWestTile(zoom_level).to(radix::tile::Scheme::Tms).coords; - const auto ne = northEastTile(zoom_level).to(radix::tile::Scheme::Tms).coords; - - std::vector tiles; - tiles.reserve((ne.y - sw.y + 1) * (ne.x - sw.x + 1)); - for (auto ty = sw.y; ty <= ne.y; ++ty) { - for (auto tx = sw.x; tx <= ne.x; ++tx) { - const auto tile_id = radix::tile::Id{zoom_level, {tx, ty}, radix::tile::Scheme::Tms}.to(scheme()); - tiles.emplace_back(tile_for(tile_id)); - if (tiles.size() >= 1'000'000'000) - // think about creating an on the fly tile generator. storing so many tiles takes a lot of memory. - throw Exception("Setting the zoom level so higher is probably not a good idea. This would generate more than 1'000 million tiles. " - "I'm aborting. If you really need this, then that means that the future is bright. But you'll have to edit the code..\n" - " . . \n / \\_/ \\ \n | O O | \n | ~V~ | _\n ~_ _ / // \n / \\ // \n" - " | || |/ \n | / \\ | \n || || \n \n"); - } - } - - return tiles; -} - -std::vector ParallelTiler::generateTiles(const std::pair &zoom_range) const { - std::vector tiles; - assert(zoom_range.first <= zoom_range.second); - for (ctb::i_zoom i = zoom_range.first; i <= zoom_range.second; ++i) { - auto zoom_level_tiles = generateTiles(i); - tiles.reserve(tiles.size() + zoom_level_tiles.size()); - std::move(zoom_level_tiles.begin(), zoom_level_tiles.end(), std::back_inserter(tiles)); - } - return tiles; -} diff --git a/src/terrainlib/ParallelTiler.h b/src/terrainlib/ParallelTiler.h deleted file mode 100644 index 2ab9c5e..0000000 --- a/src/terrainlib/ParallelTiler.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#pragma once - -#include "Tiler.h" - -class ParallelTiler : public Tiler { -public: - ParallelTiler(const ctb::Grid &grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme); - - [[nodiscard]] std::vector generateTiles(unsigned zoom_level) const; - [[nodiscard]] std::vector generateTiles(const std::pair& zoom_range) const; - - [[nodiscard]] radix::tile::Id southWestTile(unsigned zoom_level) const; - [[nodiscard]] radix::tile::Id northEastTile(unsigned zoom_level) const; -}; diff --git a/src/terrainlib/ProgressIndicator.cpp b/src/terrainlib/ProgressIndicator.cpp index 4bc5c29..e81198b 100644 --- a/src/terrainlib/ProgressIndicator.cpp +++ b/src/terrainlib/ProgressIndicator.cpp @@ -28,22 +28,20 @@ using namespace std::literals; ProgressIndicator::ProgressIndicator(size_t n_steps) - : m_n_steps(n_steps) -{ + : m_n_steps(n_steps) { } -void ProgressIndicator::taskFinished() -{ +void ProgressIndicator::task_finished() { ++m_step; - if (m_step > m_n_steps) - throw Exception("Too many steps reported."); + if (m_step > m_n_steps) { + throw std::runtime_error("Too many steps reported."); + } } -std::jthread ProgressIndicator::startMonitoring() const -{ +std::jthread ProgressIndicator::start_monitoring() const { const auto print = [this](size_t delta_v, std::chrono::milliseconds delta_t) { const auto delta_t_in_secs = std::chrono::duration_cast>(delta_t).count(); - const auto print_out = fmt::format("{} {}, {} tiles per second", this->progressBar(), this->xOfYDoneMessagE(), float(delta_v) / delta_t_in_secs); + const auto print_out = fmt::format("{} {}, {}/s", this->progress_bar(), this->x_of_y_done_message(), float(delta_v) / delta_t_in_secs); std::cout << '\r' << print_out; std::cout.flush(); }; @@ -66,16 +64,26 @@ std::jthread ProgressIndicator::startMonitoring() const return thread; } -std::string ProgressIndicator::progressBar() const -{ - const auto progress = unsigned(100.0 * (double(m_step) / double(m_n_steps)) + 0.5); - assert(progress >= 0); - assert(progress <= 100); +std::string ProgressIndicator::progress_bar() const { + const auto bar_width = 50; + const auto progress = uint32_t(bar_width * (double(m_step) / double(m_n_steps)) + 0.5); + assert(progress <= bar_width); - return std::string(progress, '|') + std::string(100 - progress, '-'); + std::ostringstream oss; + oss << "["; + for (uint32_t i = 0; i < bar_width; ++i) { + if (i < progress) { + oss << "="; + } else if (i == progress) { + oss << ">"; + } else { + oss << " "; + } + } + oss << "]"; + return oss.str(); } -std::string ProgressIndicator::xOfYDoneMessagE() const -{ +std::string ProgressIndicator::x_of_y_done_message() const { return fmt::format("{}/{}", m_step.load(), m_n_steps); } diff --git a/src/terrainlib/ProgressIndicator.h b/src/terrainlib/ProgressIndicator.h index 714ddc0..754c3fd 100644 --- a/src/terrainlib/ProgressIndicator.h +++ b/src/terrainlib/ProgressIndicator.h @@ -25,8 +25,6 @@ #include #include -#include "Exception.h" - class ProgressIndicator { const size_t m_n_steps; std::atomic m_step = 0; @@ -34,10 +32,10 @@ class ProgressIndicator { public: ProgressIndicator(size_t n_steps); - void taskFinished(); - [[nodiscard]] std::jthread startMonitoring() const; // join on the returned thread after the work is done!! - [[nodiscard]] std::string progressBar() const; - [[nodiscard]] std::string xOfYDoneMessagE() const; + void task_finished(); + [[nodiscard]] std::jthread start_monitoring() const; // join on the returned thread after the work is done!! + [[nodiscard]] std::string progress_bar() const; + [[nodiscard]] std::string x_of_y_done_message() const; }; #endif // PROGRESSINDICATOR_H diff --git a/src/terrainlib/TileHeightsGenerator.cpp b/src/terrainlib/TileHeightsGenerator.cpp deleted file mode 100644 index 8b8e359..0000000 --- a/src/terrainlib/TileHeightsGenerator.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 madam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "TileHeightsGenerator.h" - -#include - -#include "Dataset.h" -#include "DatasetReader.h" -#include "TopDownTiler.h" -#include "ctb/GlobalGeodetic.hpp" -#include "ctb/GlobalMercator.hpp" -#include "depth_first_tile_traverser.h" -#include - -TileHeightsGenerator::TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path) - : m_input_data_path(std::move(input_data_path)) - , m_srs(srs) - , m_scheme(scheme) - , m_border(border) - , m_output_path(std::move(output_path)) -{ -} - -void TileHeightsGenerator::run(unsigned max_zoom_level) const -{ - struct MinMaxData { - radix::tile::Id tile_id; - std::pair min_max = std::make_pair(0, 9000); - }; - - const auto dataset = Dataset::make_shared(m_input_data_path); - - ctb::Grid grid = ctb::GlobalGeodetic(64); - if (m_srs == ctb::Grid::Srs::SphericalMercator) - grid = ctb::GlobalMercator(64); - const auto bounds = dataset->bounds(grid.getSRS()); - const auto tile_reader = DatasetReader(dataset, grid.getSRS(), 1, false); - const auto tiler = TopDownTiler(grid, bounds, m_border, m_scheme); - auto tile_heights = radix::TileHeights(); - - const auto read_function = [&](const radix::tile::Descriptor &tile) -> MinMaxData { - const auto tile_data = tile_reader.readWithOverviews(tile.srsBounds, tile.tileSize, tile.tileSize); - auto [min, max] = std::ranges::minmax(tile_data); - tile_heights.emplace(tile.id, std::make_pair(min, max)); - return { tile.id, std::make_pair(min, max) }; - }; - - std::vector>> aggregate_calls; - const auto aggregate_function = [&](const std::vector& data) -> MinMaxData { - const auto new_id = data.front().tile_id.parent(); - auto min_max = data.front().min_max; - for (const auto& d : data) { - min_max.first = std::min(min_max.first, d.min_max.first); - min_max.second = std::max(min_max.second, d.min_max.second); - } - tile_heights.emplace(new_id, min_max); - return { new_id, min_max }; - }; - - - traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 0, { 0, 0 }, m_scheme }, max_zoom_level); - if (m_srs == ctb::Grid::Srs::WGS84) { - // two root tiles - traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 0, { 1, 0 }, m_scheme }, max_zoom_level); - } - tile_heights.write_to(m_output_path); - -} diff --git a/src/terrainlib/TileHeightsGenerator.h b/src/terrainlib/TileHeightsGenerator.h deleted file mode 100644 index 00f63a7..0000000 --- a/src/terrainlib/TileHeightsGenerator.h +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 madam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#pragma once - -#include -#include - -#include "ctb/Grid.hpp" -#include - - -class TileHeightsGenerator -{ - std::string m_input_data_path; - ctb::Grid::Srs m_srs; - radix::tile::Scheme m_scheme; - radix::tile::Border m_border; - std::filesystem::path m_output_path; -public: - TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path); - void run(unsigned max_zoom_level) const; -}; - diff --git a/src/terrainlib/Tiler.cpp b/src/terrainlib/Tiler.cpp deleted file mode 100644 index eb0f703..0000000 --- a/src/terrainlib/Tiler.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 madam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "Tiler.h" - -#include - -Tiler::Tiler(ctb::Grid grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) - : m_grid(std::move(grid)) - , m_bounds(bounds) - , m_border_south_east(border) - , m_scheme(scheme) -{ - -} - -const ctb::Grid& Tiler::grid() const -{ - return m_grid; -} - -ctb::i_tile Tiler::grid_size() const -{ - return grid().tileSize(); -} - -ctb::i_tile Tiler::tile_size() const -{ - return grid_size() + unsigned(border_south_east()); -} - -radix::tile::Border Tiler::border_south_east() const -{ - return m_border_south_east; -} - -radix::tile::Descriptor Tiler::tile_for(const radix::tile::Id& tile_id) const -{ - radix::tile::SrsBounds srs_bounds = grid().srsBounds(tile_id, border_south_east() == radix::tile::Border::Yes); - return {tile_id, srs_bounds, grid().getEpsgCode(), grid_size(), tile_size()}; -} - -radix::tile::Scheme Tiler::scheme() const { - return m_scheme; -} - -const radix::tile::SrsBounds &Tiler::bounds() const { - return m_bounds; -} - -void Tiler::setBounds(const radix::tile::SrsBounds &newBounds) { - m_bounds = newBounds; -} diff --git a/src/terrainlib/Tiler.h b/src/terrainlib/Tiler.h deleted file mode 100644 index c9ffd8d..0000000 --- a/src/terrainlib/Tiler.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#pragma once - -#include "ctb/Grid.hpp" -#include "ctb/types.hpp" -#include - -class Tiler -{ -public: - Tiler(ctb::Grid grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme); - - [[nodiscard]] radix::tile::Scheme scheme() const; - [[nodiscard]] const radix::tile::SrsBounds &bounds() const; - void setBounds(const radix::tile::SrsBounds &newBounds); - [[nodiscard]] radix::tile::Descriptor tile_for(const radix::tile::Id &tile_id) const; - -protected: - [[nodiscard]] const ctb::Grid& grid() const; - [[nodiscard]] ctb::i_tile grid_size() const; - [[nodiscard]] ctb::i_tile tile_size() const; - [[nodiscard]] radix::tile::Border border_south_east() const; - -private: - - const ctb::Grid m_grid; - radix::tile::SrsBounds m_bounds; - const radix::tile::Border m_border_south_east; - const radix::tile::Scheme m_scheme; -}; - diff --git a/src/terrainlib/TopDownTiler.cpp b/src/terrainlib/TopDownTiler.cpp deleted file mode 100644 index 8030532..0000000 --- a/src/terrainlib/TopDownTiler.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "TopDownTiler.h" - -TopDownTiler::TopDownTiler(const ctb::Grid &grid, const radix::tile::SrsBounds &bounds, radix::tile::Border border, radix::tile::Scheme scheme) - : Tiler(grid, bounds, border, scheme) { -} - -std::vector TopDownTiler::generateTiles(const radix::tile::Id &parent_id) const { - assert(parent_id.scheme == scheme()); - const auto tile_ids = parent_id.to(scheme()).children(); - std::vector tiles; - for (const auto& tile_id : tile_ids) { - radix::tile::Descriptor t = tile_for(tile_id); - if (intersect(bounds(), t.srsBounds)) - tiles.push_back(std::move(t)); - } - - return tiles; -} diff --git a/src/terrainlib/TopDownTiler.h b/src/terrainlib/TopDownTiler.h deleted file mode 100644 index 0b7c533..0000000 --- a/src/terrainlib/TopDownTiler.h +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#pragma once -#include -#include "Tiler.h" -#include "ctb/Grid.hpp" -#include - -class TopDownTiler : public Tiler { -public: - TopDownTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme); - - [[nodiscard]] std::vector generateTiles(const radix::tile::Id &parent_id) const; -}; diff --git a/src/terrainlib/alpine_raster.cpp b/src/terrainlib/alpine_raster.cpp deleted file mode 100644 index 53c45d0..0000000 --- a/src/terrainlib/alpine_raster.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "alpine_raster.h" - -#include -#include -#include - -#include -#include - -#include "Image.h" -#include "ParallelTileGenerator.h" -#include "ctb/Grid.hpp" -#include - -ParallelTileGenerator alpine_raster::make_generator(const std::string &input_data_path, const std::string &output_data_path, ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, radix::tile::Border border, unsigned grid_resolution) { - return ParallelTileGenerator::make(input_data_path, srs, tiling_scheme, std::make_unique(border), output_data_path, grid_resolution); -} - -void alpine_raster::TileWriter::write(const std::string &file_path, const radix::tile::Descriptor &tile, const HeightData &heights) const { - image::saveImageAsPng(image::transformImage(heights, radix::height_encoding::to_rgb), - file_path); -} diff --git a/src/terrainlib/alpine_raster.h b/src/terrainlib/alpine_raster.h deleted file mode 100644 index b1ad459..0000000 --- a/src/terrainlib/alpine_raster.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#ifndef ALPINERASTERGENERATOR_H -#define ALPINERASTERGENERATOR_H - -#include - -#include -#include - -#include "Image.h" -#include "ParallelTileGenerator.h" -#include -#include "ctb/Grid.hpp" - -namespace alpine_raster { - -class TileWriter : public ParallelTileWriterInterface { -public: - TileWriter(radix::tile::Border border) - : ParallelTileWriterInterface(border, "png") { - } - void write(const std::string& base_path, const radix::tile::Descriptor& tile, const HeightData& heights) const override; -}; -[[nodiscard]] ParallelTileGenerator make_generator( - const std::string &input_data_path, - const std::string &output_data_path, - ctb::Grid::Srs srs, - radix::tile::Scheme tiling_scheme, - radix::tile::Border border, - unsigned grid_resolution = 256); -} - -#endif // ALPINERASTERGENERATOR_H diff --git a/src/terrainlib/depth_first_tile_traverser.h b/src/terrainlib/depth_first_tile_traverser.h deleted file mode 100644 index 68379de..0000000 --- a/src/terrainlib/depth_first_tile_traverser.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#pragma once - -#include "TopDownTiler.h" - -template -auto traverse_depth_first_and_aggregate(const TopDownTiler &tiler, ReadFunction read, AggregateFunction aggregate, const radix::tile::Id &root_tile_id, unsigned max_zoom_level) - -> decltype(read(tiler.tile_for(root_tile_id))) { - using DataType = decltype(read(tiler.tile_for(root_tile_id))); - const auto subtiles = tiler.generateTiles(root_tile_id); - // subtiles can be empty if the parent tile had an overlap with the dataset extent only on the border pixels. - if (root_tile_id.zoom_level == max_zoom_level || subtiles.empty()) { - return read(tiler.tile_for(root_tile_id)); - } - - std::vector unaggregated_data; - for (const auto& tile : subtiles) { - auto tile_data = traverse_depth_first_and_aggregate(tiler, read, aggregate, tile.id, max_zoom_level); - unaggregated_data.emplace_back(std::move(tile_data)); - } - - return aggregate(unaggregated_data); -} diff --git a/src/terrainlib/init.cpp b/src/terrainlib/init.cpp index 73e8ac2..1e835d7 100644 --- a/src/terrainlib/init.cpp +++ b/src/terrainlib/init.cpp @@ -1,36 +1,15 @@ -#include "init.h" -#include "log.h" -#include -#include //for call_once +#include #include +#include "init.h" +#include "log.h" + std::once_flag g_gdal_initialized_once_flag; -void initialize_gdal_once() -{ +void initialize_gdal_once() { std::call_once(g_gdal_initialized_once_flag, []() { LOG_DEBUG("calling GDALAllRegister..."); GDALAllRegister(); }); } - -std::once_flag g_freeimage_initialized_once_flag; - -namespace { - struct FreeImageDeinitialiserHandler { - ~FreeImageDeinitialiserHandler() - { - FreeImage_DeInitialise(); - } - }; -} - -void initialize_freeimage_once() -{ - std::call_once(g_freeimage_initialized_once_flag, []() { - LOG_DEBUG("calling GDALAllRegister..."); - FreeImage_Initialise(); - }); - static FreeImageDeinitialiserHandler deinitialiser; -} diff --git a/src/terrainlib/init.h b/src/terrainlib/init.h index 1d84902..960a324 100644 --- a/src/terrainlib/init.h +++ b/src/terrainlib/init.h @@ -1,4 +1,3 @@ #pragma once void initialize_gdal_once(); -void initialize_freeimage_once(); diff --git a/src/terrainlib/log.cpp b/src/terrainlib/log.cpp index 0837cea..ddf059c 100644 --- a/src/terrainlib/log.cpp +++ b/src/terrainlib/log.cpp @@ -1,8 +1,8 @@ -#include "log.h" - #include #include +#include "log.h" + std::shared_ptr Log::logger; void Log::init(spdlog::level::level_enum log_level) { diff --git a/src/terrainlib/log.h b/src/terrainlib/log.h index 358dde4..200a5db 100644 --- a/src/terrainlib/log.h +++ b/src/terrainlib/log.h @@ -1,5 +1,4 @@ -#ifndef LOG_H -#define LOG_H +#pragma once #ifndef SPDLOG_FMT_EXTERNAL #define SPDLOG_FMT_EXTERNAL @@ -32,24 +31,19 @@ class Log { LOG_ERROR(__VA_ARGS__); \ exit(1); \ } while (false) -#if defined(__GNUC__) || defined(__clang__) -#define UNREACHABLE() \ - do { \ - LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ - __builtin_unreachable(); \ - } while (0) + +#if __cplusplus >= 202302L +#define _UNREACHABLE() std::unreachable() +#elif defined(__GNUC__) || defined(__clang__) +#define _UNREACHABLE() __builtin_unreachable() #elif defined(_MSC_VER) -#define UNREACHABLE() \ - do { \ - LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ - __assume(false); \ - } while (0) +#define _UNREACHABLE() __assume(false) #else +#define _UNREACHABLE() std::abort() +#endif + #define UNREACHABLE() \ do { \ LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ - std::abort(); \ + _UNREACHABLE(); \ } while (0) -#endif - -#endif diff --git a/src/terrainlib/mesh/SimpleMesh.h b/src/terrainlib/mesh/SimpleMesh.h new file mode 100644 index 0000000..0a0eafb --- /dev/null +++ b/src/terrainlib/mesh/SimpleMesh.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include +#include +#include +#include + +class SimpleMesh { +public: + using Triangle = glm::uvec3; + using Edge = glm::uvec2; + using Position = glm::dvec3; + using Uv = glm::dvec2; + using Texture = cv::Mat; + using serialize = zpp::bits::members<4>; + + SimpleMesh(std::vector triangles, std::vector positions) + : SimpleMesh(triangles, positions, {}) {} + SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs) + : SimpleMesh(triangles, positions, uvs, std::nullopt) {} + SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) + : SimpleMesh(triangles, positions, uvs, std::optional(std::move(texture))) {} + SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) + : triangles(triangles), positions(positions), uvs(uvs), texture(std::move(texture)) {} + SimpleMesh() = default; + SimpleMesh(SimpleMesh &&) = default; + SimpleMesh &operator=(SimpleMesh &&) = default; + SimpleMesh(const SimpleMesh &) = default; + SimpleMesh &operator=(const SimpleMesh &) = default; + + std::vector triangles; + std::vector positions; + std::vector uvs; + std::optional texture; + + size_t vertex_count() const { + return this->positions.size(); + } + size_t face_count() const { + return this->triangles.size(); + } + bool is_empty() const { + return this->vertex_count() == 0 && this->face_count() == 0; + } + + bool has_uvs() const { + return this->positions.size() == this->uvs.size(); + } + bool has_texture() const { + return this->texture.has_value(); + } +}; diff --git a/src/terrainlib/mesh/io.cpp b/src/terrainlib/mesh/io.cpp index 522d280..04b3d04 100644 --- a/src/terrainlib/mesh/io.cpp +++ b/src/terrainlib/mesh/io.cpp @@ -1,853 +1,39 @@ -#include -#include - -#define CGLTF_IMPLEMENTATION -#define CGLTF_WRITE_IMPLEMENTATION -// #define CGLTF_VALIDATE_ENABLE_ASSERTS -#include -#undef CGLTF_IMPLEMENTATION -#undef CGLTF_WRITE_IMPLEMENTATION -#include -#include -#include -#include -#include - -#include "io.h" +#include "mesh/io.h" #include "log.h" +#include "mesh/io/gltf.h" +#include "mesh/io/terrain.h" -namespace { -const int GL_NEAREST = 0x2600; -const int GL_LINEAR = 0x2601; -const int GL_NEAREST_MIPMAP_NEAREST = 0x2700; -const int GL_LINEAR_MIPMAP_NEAREST = 0x2701; -const int GL_NEAREST_MIPMAP_LINEAR = 0x2702; -const int GL_LINEAR_MIPMAP_LINEAR = 0x2703; -const int GL_TEXTURE_MAG_FILTER = 0x2800; -const int GL_TEXTURE_MIN_FILTER = 0x2801; -const int GL_REPEAT = 0x2901; -const int GL_CLAMP_TO_EDGE = 0x812F; -const int GL_MIRRORED_REPEAT = 0x8370; -} // namespace - -using namespace io; - -static cgltf_attribute *find_attribute_with_type(cgltf_attribute *attributes, size_t attribute_count, cgltf_attribute_type type) { - for (unsigned int i = 0; i < attribute_count; i++) { - cgltf_attribute *attribute = &attributes[i]; - if (attribute->type == type) { - return attribute; - } - } - - return nullptr; -} - -cv::Mat io::read_texture_from_encoded_bytes(std::span buffer) { - cv::Mat raw_data = cv::Mat(1, buffer.size(), CV_8UC1, const_cast(buffer.data())); - cv::Mat mat = cv::imdecode(raw_data, cv::IMREAD_UNCHANGED); - mat.convertTo(mat, CV_8UC3); - return mat; -} -void io::write_texture_to_encoded_buffer(const cv::Mat &image, std::vector &buffer, const std::string extension) { - cv::Mat converted; - image.convertTo(converted, CV_8UC3); - cv::imencode(extension, image, buffer); -} -std::vector io::write_texture_to_encoded_buffer(const cv::Mat &image, const std::string extension) { - std::vector buffer; - io::write_texture_to_encoded_buffer(image, buffer, extension); - return buffer; -} - -static glm::mat4 get_node_transform_local(const cgltf_node &node) { - if (node.has_matrix) { - return glm::make_mat4(node.matrix); - } - - glm::mat4 transform(1); - - if (node.has_translation) { - const glm::vec3 translation(node.translation[0], node.translation[1], node.translation[2]); - transform = glm::translate(transform, translation); - } - - if (node.has_rotation) { - glm::quat rotation(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2]); - transform = transform * glm::toMat4(rotation); - } - - if (node.has_scale) { - glm::vec3 scaling(node.scale[0], node.scale[1], node.scale[2]); - transform = glm::scale(transform, scaling); - } - - return transform; -} - -static glm::dmat4 get_node_transform_world(const cgltf_node &node) { - glm::dmat4 transform = get_node_transform_local(node); - - const cgltf_node *parent = node.parent; - while (parent != nullptr) { - const glm::dmat4 parent_transform = get_node_transform_local(*parent); - transform *= parent_transform; - parent = parent->parent; - } - - return transform; -} - -static const cgltf_node *find_mesh_node_under_node(const cgltf_node &node, const cgltf_mesh &target_mesh) { - if (node.mesh != nullptr) { - if (std::addressof(target_mesh) == node.mesh) { - return &node; - } - } - - for (cgltf_size child_index = 0; child_index < node.children_count; child_index++) { - const cgltf_node &child = *node.children[child_index]; - const cgltf_node *child_result = find_mesh_node_under_node(child, target_mesh); - if (child_result != nullptr) { - return child_result; - } - } - - return nullptr; -} -static const cgltf_node *find_mesh_node_in_scene(const cgltf_scene &scene, const cgltf_mesh &mesh) { - for (cgltf_size i = 0; i < scene.nodes_count; i++) { - const cgltf_node &node = *scene.nodes[i]; - const cgltf_node *mesh_node = find_mesh_node_under_node(node, mesh); - if (mesh_node != nullptr) { - return mesh_node; - } - } - - return nullptr; -} -static const cgltf_node *find_mesh_node(const cgltf_data &data, const cgltf_mesh &mesh) { - if (data.scenes_count == 0) { - LOG_WARN("file contains no scenes"); - return nullptr; - } - - for (cgltf_size i = 0; i < data.scenes_count; i++) { - const cgltf_scene &scene = data.scenes[i]; - const cgltf_node *mesh_node = find_mesh_node_in_scene(scene, mesh); - if (mesh_node != nullptr) { - return mesh_node; - } - } - - return nullptr; -} - -static glm::dmat4 get_mesh_transform(const cgltf_data &data, const cgltf_mesh &mesh) { - const cgltf_node *mesh_node = find_mesh_node(data, mesh); - if (mesh_node == nullptr) { - return glm::dmat4(1); - } - return get_node_transform_world(*mesh_node); -} - -static std::optional load_texture_from_material(const cgltf_material &material) { - if (!material.has_pbr_metallic_roughness || material.pbr_metallic_roughness.base_color_texture.texture == nullptr) { - LOG_WARN("mesh material has no texture"); - return std::nullopt; - } - - cgltf_texture &albedo_texture = *material.pbr_metallic_roughness.base_color_texture.texture; - cgltf_image &albedo_image = *albedo_texture.image; - - const std::span raw_texture{cgltf_buffer_view_data(albedo_image.buffer_view), albedo_image.buffer_view->size}; - cv::Mat texture = read_texture_from_encoded_bytes(raw_texture); - return texture; -} - -#define GET_OR_INVALID_FORMAT(var, opt) \ - do { \ - if (!(opt).has_value()) { \ - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); \ - } else { \ - var = opt.value(); \ - } \ - } while (false) - -template -static std::optional> get_single_element(const char* name, cgltf_size count, T const* items) { - if (count == 0) { - LOG_ERROR("file contains no {}", name); - return std::nullopt; - } - if (count > 1) { - LOG_WARN("file contains more than one {}", name); - return std::nullopt; - } - - const T& ref = items[0]; - - return ref; -} - -tl::expected io::load_mesh_from_raw(const RawGltfMesh &raw, const LoadOptions _options) { - LOG_TRACE("Loading mesh from gltf data"); - - const cgltf_data &data = *raw.data; - - const auto mesh_opt = get_single_element("mesh", data.meshes_count, data.meshes); - if (!mesh_opt.has_value()) { - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); - } - const cgltf_mesh &mesh = mesh_opt.value(); - - const auto mesh_primitive_opt = get_single_element("mesh primitive", mesh.primitives_count, mesh.primitives); - if (!mesh_primitive_opt.has_value()) { - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); - } - const cgltf_primitive &mesh_primitive = mesh_primitive_opt.value(); - if (mesh_primitive.type != cgltf_primitive_type::cgltf_primitive_type_triangles) { - LOG_ERROR("mesh has invalid primitive type"); - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); - } - - // indices - cgltf_accessor &index_accessor = *mesh_primitive.indices; - std::vector indices; - indices.resize(index_accessor.count / 3); - cgltf_accessor_unpack_indices(&index_accessor, reinterpret_cast(indices.data()), cgltf_component_size(index_accessor.component_type), indices.size() * 3); - - // positions - cgltf_attribute *position_attr = find_attribute_with_type(mesh_primitive.attributes, mesh_primitive.attributes_count, cgltf_attribute_type_position); - if (position_attr == nullptr) { - LOG_ERROR("mesh has no position attribute"); - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); - } - - cgltf_accessor &position_accessor = *position_attr->data; - std::vector positions; - positions.resize(position_accessor.count); - cgltf_accessor_unpack_floats(&position_accessor, reinterpret_cast(positions.data()), positions.size() * 3); - - // uvs - cgltf_attribute *uv_attr = find_attribute_with_type(mesh_primitive.attributes, mesh_primitive.attributes_count, cgltf_attribute_type_texcoord); - std::vector uvs; - if (uv_attr == nullptr) { - LOG_WARN("mesh has no uv attribute"); - } else { - cgltf_accessor &uv_accessor = *uv_attr->data; - uvs.resize(uv_accessor.count); - cgltf_accessor_unpack_floats(&uv_accessor, reinterpret_cast(uvs.data()), uvs.size() * 2); - } - - glm::dmat4 transform = get_mesh_transform(data, mesh); - std::vector positionsd; - positionsd.resize(positions.size()); - for (unsigned int i = 0; i < positions.size(); i++) { - const glm::dvec4 positiond = glm::dvec4(positions[i], 1); - const glm::dvec4 transformed = transform * positiond; - positionsd[i] = glm::dvec3(transformed) / transformed.w; - } - - std::vector uvsd; - uvsd.resize(uvs.size()); - for (unsigned int i = 0; i < uvsd.size(); i++) { - uvsd[i] = glm::dvec2(uvs[i]); - } - - std::optional texture = load_texture_from_material(*mesh_primitive.material); - - return TerrainMesh(indices, positionsd, uvsd, texture); -} - -static LoadMeshError map_cgltf_error(cgltf_result result) { - switch (result) { - case cgltf_result::cgltf_result_data_too_short: - case cgltf_result::cgltf_result_unknown_format: - case cgltf_result::cgltf_result_invalid_json: - case cgltf_result::cgltf_result_invalid_gltf: - case cgltf_result::cgltf_result_legacy_gltf: - return LoadMeshErrorKind::InvalidFormat; - case cgltf_result::cgltf_result_file_not_found: - case cgltf_result::cgltf_result_io_error: - return LoadMeshErrorKind::FileNotFound; - case cgltf_result::cgltf_result_out_of_memory: - return LoadMeshErrorKind::OutOfMemory; - default: - assert(false); - break; - } -} - -/// Calculates the size of the data of a vector in bytes. -template -static size_t vectorsizeof(const typename std::vector &vec) { - return sizeof(T) * vec.size(); -} - -/// Encodes the data at the given pointer into base64. -// from https://github.com/syoyo/tinygltf/blob/5e8a7fd602af22aa9619ccd3baeaeeaff0ecb6f3/tiny_gltf.h#L2297 -static std::string base64_encode(unsigned char const *bytes_to_encode, - unsigned int in_len) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - const char *base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = - ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = - ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (i = 0; (i < 4); i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) { - for (j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = - ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = - ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while ((i++ < 3)) - ret += '='; - } - - return ret; -} - -/// Encodes the given data as a base64 data uri. -static std::string data_uri_encode(unsigned char const *bytes_to_encode, unsigned int in_len) { - return "data:application/octet-stream;base64," + base64_encode(bytes_to_encode, in_len); -} - -static size_t align(std::size_t alignment, size_t offset) noexcept { - const size_t aligned = (offset - 1u + alignment) & -alignment; - return aligned; -} - -static std::string image_ext_to_mime(std::string_view extension) { - if (extension.starts_with(".")) { - extension = extension.substr(1); - } - - return fmt::format("image/{}", extension); -} - -static std::filesystem::path create_parent_directories(const std::filesystem::path &path) { - const std::filesystem::path parent_path = std::filesystem::absolute(path).parent_path(); - std::filesystem::create_directories(parent_path); - return parent_path; -} - -/// Saves the mesh as a .gltf or .glb file at the given path. -static void save_mesh_as_gltf(const TerrainMesh &terrain_mesh, const std::filesystem::path &path, const SaveOptions options) { - LOG_TRACE("Saving mesh as gltf/glb"); - - // ********************* Preprocessing ********************* // - - // Calculate the average vertex position for later normalization. - const size_t vertex_count = terrain_mesh.positions.size(); - glm::dvec3 average_position(0, 0, 0); - for (size_t i = 0; i < vertex_count; i++) { - average_position += terrain_mesh.positions[i] / static_cast(vertex_count); - } - - // Create vertex data vector from positions and uvs. - // We also normalize vertex position by extracting their average position and storing the offsets. - // This is to preserve more of our double accuracy, as gltf cannot store them directly. - // This helps but does not fully preserve the accuracy. - std::vector vertices; - vertices.reserve((vectorsizeof(terrain_mesh.positions) + vectorsizeof(terrain_mesh.uvs)) / sizeof(float)); - glm::vec3 max_position(-std::numeric_limits::infinity()); - glm::vec3 min_position(std::numeric_limits::infinity()); - for (size_t i = 0; i < vertex_count; i++) { - const glm::vec3 normalized_position = terrain_mesh.positions[i] - average_position; - - vertices.push_back(normalized_position.x); - vertices.push_back(normalized_position.y); - vertices.push_back(normalized_position.z); - if (terrain_mesh.has_uvs()) { - vertices.push_back(terrain_mesh.uvs[i].x); - vertices.push_back(terrain_mesh.uvs[i].y); - } - - max_position = glm::max(max_position, normalized_position); - min_position = glm::min(min_position, normalized_position); - } - - // Encode the texture as jpeg data. - const bool has_texture = terrain_mesh.has_texture(); - std::vector texture_bytes; - if (has_texture) { - texture_bytes = write_texture_to_encoded_buffer(terrain_mesh.texture.value(), options.texture_format); - } - - // Create a single buffer that holds all binary data (indices, vertices, textures) - // We need to do this because only a single buffer can be written as a binary blob in .glb files. - const size_t index_data_offset = align(sizeof(glm::uvec3), 0); - const size_t index_data_byte_count = vectorsizeof(terrain_mesh.triangles); - const size_t index_data_end = index_data_offset + index_data_byte_count; - const size_t vertex_data_offset = align(sizeof(glm::vec3), index_data_end); - const size_t vertex_data_byte_count = vectorsizeof(vertices); - const size_t vertex_data_end = vertex_data_offset + vertex_data_byte_count; - const size_t texture_data_offset = align(sizeof(uint8_t), vertex_data_end); - const size_t texture_data_byte_count = vectorsizeof(texture_bytes); - const size_t texture_data_end = texture_data_offset + texture_data_byte_count; - - std::vector buffer_data; - buffer_data.resize(texture_data_end); - std::memcpy(buffer_data.data() + index_data_offset, terrain_mesh.triangles.data(), index_data_byte_count); - std::memcpy(buffer_data.data() + vertex_data_offset, vertices.data(), vertex_data_byte_count); - std::memcpy(buffer_data.data() + texture_data_offset, texture_bytes.data(), texture_data_byte_count); - - const bool binary_output = path.extension() == ".glb"; - - // ********************* Create GLTF data structure ********************* // - - // Initialize a GLTF data structure - cgltf_data data = {}; - std::string version = "2.0\0"; - data.asset.version = version.data(); - std::string generator = "alpinite\0"; - data.asset.generator = generator.data(); - - std::array buffers; - - // Create a gltf buffer to hold vertex data, index data and the texture. - cgltf_buffer &buffer = buffers[0] = {}; - buffer.size = buffer_data.size(); - buffer.data = buffer_data.data(); - std::string buffer_data_encoded; - if (binary_output) { - // The binary blob at the end of the file will be used as the contents of the first buffer if it does not have an uri defined. - data.bin = buffer_data.data(); - data.bin_size = buffer_data.size(); - } else { - buffer_data_encoded = data_uri_encode(buffer_data.data(), buffer_data.size()); - buffer.uri = buffer_data_encoded.data(); - } - - // Create buffer views for each of types of data in the buffer. - std::array buffer_views; - - cgltf_buffer_view &index_buffer_view = buffer_views[0] = {}; - index_buffer_view.buffer = &buffer; - index_buffer_view.offset = index_data_offset; - index_buffer_view.size = index_data_byte_count; - index_buffer_view.stride = 0; - index_buffer_view.type = cgltf_buffer_view_type_indices; - - cgltf_buffer_view &vertex_buffer_view = buffer_views[1] = {}; - vertex_buffer_view.buffer = &buffer; - vertex_buffer_view.offset = vertex_data_offset; - vertex_buffer_view.size = vertex_data_byte_count; - vertex_buffer_view.stride = (terrain_mesh.has_uvs() ? 5 : 3) * sizeof(float); - vertex_buffer_view.type = cgltf_buffer_view_type_vertices; - - cgltf_buffer_view &texture_buffer_view = buffer_views[2] = {}; - texture_buffer_view.buffer = &buffer; - texture_buffer_view.offset = texture_data_offset; - texture_buffer_view.size = texture_data_byte_count; - texture_buffer_view.stride = 0; - - // Create accessors describing the layout of data in the buffer views. - std::array accessors; - - // Create an accessor for indices. - cgltf_accessor &index_accessor = accessors[0] = {}; - index_accessor.buffer_view = &index_buffer_view; - index_accessor.type = cgltf_type_scalar; - index_accessor.component_type = cgltf_component_type_r_32u; - index_accessor.count = terrain_mesh.face_count() * 3; - index_accessor.has_min = true; - index_accessor.min[0] = static_cast(0.0); - index_accessor.has_max = true; - index_accessor.max[0] = static_cast(vertex_count - 1); - - // Create an accessor for vertex positions - cgltf_accessor &position_accessor = accessors[1] = {}; - position_accessor.buffer_view = &vertex_buffer_view; - position_accessor.component_type = cgltf_component_type_r_32f; - position_accessor.type = cgltf_type_vec3; - position_accessor.offset = 0 * sizeof(float); - position_accessor.count = vertex_count; - // We need the min and max as some viewers otherwise refuse to open the file. - position_accessor.has_min = true; - position_accessor.has_max = true; - std::copy(glm::value_ptr(min_position), glm::value_ptr(min_position) + min_position.length(), position_accessor.min); - std::copy(glm::value_ptr(max_position), glm::value_ptr(max_position) + max_position.length(), position_accessor.max); - - cgltf_accessor &uv_accessor = accessors[2] = {}; - if (terrain_mesh.has_uvs()) { - // Create an accessor for vertex uvs - uv_accessor.buffer_view = &vertex_buffer_view; - uv_accessor.component_type = cgltf_component_type_r_32f; - uv_accessor.type = cgltf_type_vec2; - uv_accessor.offset = 3 * sizeof(float); - uv_accessor.count = vertex_count; - uv_accessor.has_min = true; - uv_accessor.has_max = true; - std::fill(uv_accessor.min, uv_accessor.min + 2, 0); - std::fill(uv_accessor.max, uv_accessor.max + 2, 1); - } - - // Create a mesh primitive. - std::array primitive_attributes; - cgltf_attribute &position_attribute = primitive_attributes[0] = {}; - std::string position_attribute_name = "POSITION\0"; - position_attribute.name = position_attribute_name.data(); - position_attribute.type = cgltf_attribute_type::cgltf_attribute_type_position; - position_attribute.index = 0; - position_attribute.data = &position_accessor; - cgltf_attribute &uv_attribute = primitive_attributes[1] = {}; - std::string uv_attribute_name = "TEXCOORD_0\0"; - if (terrain_mesh.has_uvs()) { - uv_attribute.name = uv_attribute_name.data(); - uv_attribute.type = cgltf_attribute_type::cgltf_attribute_type_texcoord; - uv_attribute.index = 0; - uv_attribute.data = &uv_accessor; - } - - // Create a gltf texture - std::array images; - cgltf_image &image = images[0] = {}; - image.buffer_view = &texture_buffer_view; - std::string image_mime_type = image_ext_to_mime(options.texture_format); - image.mime_type = image_mime_type.data(); - - std::array samplers; - cgltf_sampler &sampler = samplers[0] = {}; - sampler.min_filter = GL_LINEAR_MIPMAP_LINEAR; - sampler.mag_filter = GL_LINEAR; - sampler.wrap_s = GL_CLAMP_TO_EDGE; - sampler.wrap_t = GL_CLAMP_TO_EDGE; - - std::array textures; - cgltf_texture &texture = textures[0] = {}; - texture.image = ℑ - texture.sampler = &sampler; - - // Create a material - std::array materials; - cgltf_material &material = materials[0] = {}; - material.has_pbr_metallic_roughness = true; - material.pbr_metallic_roughness.base_color_factor[0] = 1.0f; - material.pbr_metallic_roughness.base_color_factor[1] = 0.9f; - material.pbr_metallic_roughness.base_color_factor[2] = 0.9f; - material.pbr_metallic_roughness.base_color_factor[3] = 1.0f; - material.pbr_metallic_roughness.roughness_factor = 1; - if (has_texture) { - material.pbr_metallic_roughness.base_color_texture.texture = &texture; - } - material.double_sided = true; - - // Build the primitive for the mesh - std::array primitives; - cgltf_primitive &primitive = primitives[0] = {}; - primitive.type = cgltf_primitive_type_triangles; - primitive.indices = &index_accessor; - primitive.attributes_count = primitive_attributes.size(); - primitive.attributes = primitive_attributes.data(); - if (!terrain_mesh.has_uvs()) { - primitive.attributes_count -= 1; - } - primitive.material = &material; - - // Build the actual mesh - std::array meshes; - cgltf_mesh &mesh = meshes[0] = {}; - mesh.primitives_count = 1; - mesh.primitives = &primitive; - - // Create the node hierachy. - // We create parent nodes to offset the position by the average calculate above. - // We need multiple parents to ensure that we dont lose our double precision accurary. - char *node_name = const_cast(options.name.data()); - std::array nodes; - cgltf_node &mesh_node = nodes[2] = {}; - mesh_node.name = node_name; - mesh_node.has_translation = true; - mesh_node.mesh = &mesh; - - cgltf_node &parent_node = nodes[1] = {}; - parent_node.name = node_name; - std::array parent_node_children = {&mesh_node}; - parent_node.children_count = parent_node_children.size(); - parent_node.children = parent_node_children.data(); - parent_node.has_translation = true; - - cgltf_node &parent_parent_node = nodes[0] = {}; - parent_parent_node.name = node_name; - std::array parent_parent_node_children = {&parent_node}; - parent_parent_node.children_count = parent_parent_node_children.size(); - parent_parent_node.children = parent_parent_node_children.data(); - parent_parent_node.has_translation = true; - - const glm::vec3 parent_parent_offset(average_position); - const glm::dvec3 parent_parent_offset_error = glm::dvec3(parent_parent_offset) - average_position; - const glm::vec3 parent_offset(-parent_parent_offset_error); - const glm::dvec3 parent_offset_error = glm::dvec3(parent_offset) + glm::dvec3(parent_parent_offset) - average_position; - const glm::vec3 mesh_offset(-parent_offset_error); - std::copy(glm::value_ptr(parent_parent_offset), glm::value_ptr(parent_parent_offset) + parent_parent_offset.length(), parent_parent_node.translation); - std::copy(glm::value_ptr(parent_offset), glm::value_ptr(parent_offset) + parent_offset.length(), parent_node.translation); - std::copy(glm::value_ptr(mesh_offset), glm::value_ptr(mesh_offset) + mesh_offset.length(), mesh_node.translation); - const glm::dvec3 full_error = (glm::dvec3(parent_parent_offset) + glm::dvec3(parent_offset) + glm::dvec3(mesh_offset)) - average_position; - // assert(glm::length(full_error) == 0); - if (full_error != glm::dvec3(0)) { - LOG_ERROR("Float transform trick failed (error: {})", glm::length(full_error)); - } - - // Create a scene - std::array scenes; - cgltf_scene &scene = scenes[0] = {}; - std::array scene_nodes = {&parent_parent_node}; - scene.nodes_count = scene_nodes.size(); - scene.nodes = scene_nodes.data(); - - // Set up data references - data.meshes_count = meshes.size(); - data.meshes = meshes.data(); - data.nodes_count = nodes.size(); - data.nodes = nodes.data(); - data.scenes_count = scenes.size(); - data.scenes = scenes.data(); - data.buffers_count = buffers.size(); - data.buffers = buffers.data(); - data.buffer_views_count = buffer_views.size(); - data.buffer_views = buffer_views.data(); - data.accessors_count = accessors.size(); - data.accessors = accessors.data(); - if (!terrain_mesh.has_uvs()) { - data.accessors_count -= 1; - } - data.materials_count = materials.size(); - data.materials = materials.data(); - if (has_texture) { - data.textures_count = textures.size(); - data.textures = textures.data(); - data.images_count = images.size(); - data.images = images.data(); - data.samplers_count = samplers.size(); - data.samplers = samplers.data(); - } else { - data.textures_count = 0; - data.images_count = 0; - data.samplers_count = 0; - data.buffer_views_count -= 1; - } +namespace mesh { +namespace io { - // Set up extra metadata - std::string extras_str; - const auto &extra_metadata = options.metadata; - if (!extra_metadata.empty()) { - std::stringstream extras = {}; - extras << "{"; - for (auto const &[key, val] : extra_metadata) { - extras << "\n"; - extras << " "; - extras << "\"" << key << "\""; - extras << ": "; - extras << val; - extras << ","; - } - extras.seekp(-1, std::ios_base::end); // remove last "," - extras << "\n }"; - extras << "\0"; - extras_str = extras.str(); - data.extras.data = extras_str.data(); - } - - // ********************* Save the GLTF data to a file ********************* // - create_parent_directories(path); - cgltf_options gltf_options; - if (binary_output) { - gltf_options.type = cgltf_file_type_glb; - } - if (cgltf_write_file(&gltf_options, path.c_str(), &data) != cgltf_result_success) { - throw std::runtime_error("Failed to save GLTF file"); - } -} - -static tl::expected, SaveMeshError> write_mesh_to_buffer(const TerrainMesh &mesh) { - LOG_TRACE("Serializing mesh to buffer"); - - // TODO: this ignores the texture format in SaveOptions - std::vector data; - zpp::bits::out out(data); - auto result = out(mesh); - if (zpp::bits::failure(result)) { - std::error_code error_code = std::make_error_code(result); - LOG_ERROR("Error while writing tile: {}", error_code.message()); - - switch (result) { - case std::errc::no_buffer_space: - case std::errc::message_size: - case std::errc::result_out_of_range: - return tl::unexpected(SaveMeshErrorKind::OutOfMemory); - break; - default: - throw std::runtime_error("unreachable"); - break; - } - } - - return data; -} - -static tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path) { - LOG_TRACE("Writing bytes to path {}", path.string()); - - std::ofstream ofs(path, std::ios::out | std::ios::binary); - if (!ofs.is_open()) { - LOG_ERROR("Failed to open file {}", path.string()); - return tl::unexpected(SaveMeshErrorKind::OpenFile); - } - - const unsigned long data_size = bytes.size(); - // ofs.write(reinterpret_cast(&data_size), sizeof(unsigned long)); - ofs.write(reinterpret_cast(bytes.data()), data_size); - - if (!ofs.good()) { - LOG_ERROR("Failed to write to file {}", path.string()); - ofs.close(); - return tl::unexpected(SaveMeshErrorKind::WriteFile); - } - - ofs.close(); - - return {}; -} - -static tl::expected save_mesh_as_bin(const TerrainMesh &mesh, const std::filesystem::path &path, const SaveOptions _options) { - LOG_TRACE("Saving mesh as high precision tile"); - - const auto result = write_mesh_to_buffer(mesh); - if (!result.has_value()) { - return tl::unexpected(result.error()); - } - const std::vector bytes = result.value(); - - create_parent_directories(path); - - return write_bytes_to_path(bytes, path); -} - -static tl::expected, LoadMeshError> read_bytes_from_path(const std::filesystem::path &path) { - LOG_TRACE("Reading bytes from path {}", path.string()); - - std::ifstream ifs(path, std::ios::in | std::ios::binary); - if (!ifs.is_open()) { - LOG_ERROR("Failed to open file {}", path.string()); - return tl::unexpected(LoadMeshErrorKind::FileNotFound); - } - - std::vector data; - - // get length of file - ifs.seekg(0, ifs.end); - const size_t length = ifs.tellg(); - ifs.seekg(0, ifs.beg); - - // read file - if (length > 0) { - data.resize(length); - ifs.read(reinterpret_cast(data.data()), length); - } - ifs.close(); - - return data; -} - -static tl::expected read_mesh_from_buffer(const std::span bytes) { - LOG_TRACE("Deserializing mesh from buffer"); - - zpp::bits::in in(bytes); - TerrainMesh mesh; - auto result = in(mesh); - if (zpp::bits::failure(result)) { - std::error_code error_code = std::make_error_code(result); - LOG_ERROR("error while reading tile: {}", error_code.message()); - - switch (result) { - case std::errc::no_buffer_space: - case std::errc::message_size: - return tl::unexpected(LoadMeshErrorKind::OutOfMemory); - case std::errc::value_too_large: - case std::errc::bad_message: - case std::errc::protocol_error: - case std::errc::result_out_of_range: - return tl::unexpected(LoadMeshErrorKind::InvalidFormat); - case std::errc::not_supported: - case std::errc::invalid_argument: - throw std::runtime_error("unreachable"); - default: - throw std::runtime_error("unexpected error"); - } - } - - return mesh; -} - -static tl::expected load_mesh_from_bin(const std::filesystem::path &path, const LoadOptions _options) { - const auto result = read_bytes_from_path(path); - if (!result.has_value()) { - return tl::unexpected(result.error()); - } - const std::vector bytes = result.value(); - - return read_mesh_from_buffer(bytes); -} - -tl::expected io::load_mesh_from_path(const std::filesystem::path &path, const LoadOptions options) { +tl::expected load_from_path( + const std::filesystem::path &path, + const LoadOptions& options) { const std::filesystem::path extension = path.extension(); if (extension == ".glb" || extension == ".gltf") { - tl::expected raw_mesh = RawGltfMesh::load_from_path(path); - if (!raw_mesh) { - return tl::unexpected(map_cgltf_error(raw_mesh.error())); - } - return load_mesh_from_raw(*raw_mesh, options); - } else if (extension == ".tile") { - return load_mesh_from_bin(path, options); + return gltf::load_from_path(path, options); + } else if (extension == ".terrain") { + return terrain::load_from_path(path, options); } else { return tl::unexpected(LoadMeshErrorKind::UnsupportedFormat); } } -tl::expected io::save_mesh_to_path( +tl::expected save_to_path( + const SimpleMesh &mesh, const std::filesystem::path &path, - const TerrainMesh &mesh, - const SaveOptions options) { + const SaveOptions &options) { LOG_TRACE("Saving mesh to path {}", path.string()); const std::filesystem::path extension = path.extension(); if (extension == ".glb" || extension == ".gltf") { - // TODO: return errors - save_mesh_as_gltf(mesh, path, options); - } else if (extension == ".tile") { - save_mesh_as_bin(mesh, path, options); + return gltf::save_to_path(mesh, path, options); + } else if (extension == ".terrain") { + return terrain::save_to_path(mesh, path, options); } else { return tl::unexpected(SaveMeshErrorKind::UnsupportedFormat); } - return {}; +} + +} } diff --git a/src/terrainlib/mesh/io.h b/src/terrainlib/mesh/io.h index 78a3b62..82923c8 100644 --- a/src/terrainlib/mesh/io.h +++ b/src/terrainlib/mesh/io.h @@ -1,156 +1,24 @@ #pragma once #include -#include -#include -#include -#include -#include -#include #include -#include "terrain_mesh.h" -#include "log.h" -#include "raw_gltf.h" +#include "mesh/SimpleMesh.h" +#include "mesh/io/options.h" +#include "mesh/io/error.h" +namespace mesh { namespace io { -struct LoadOptions { -}; +tl::expected load_from_path( + const std::filesystem::path &path, + const LoadOptions& options = {}); -enum class LoadMeshErrorKind { - UnsupportedFormat, - FileNotFound, - InvalidFormat, - OutOfMemory -}; - -class LoadMeshError { -public: - LoadMeshError() = default; - constexpr LoadMeshError(LoadMeshErrorKind kind) - : kind(kind) {} - - operator LoadMeshErrorKind() const { - return this->kind; - } - constexpr bool operator==(LoadMeshError other) const { - return this->kind == other.kind; - } - constexpr bool operator!=(LoadMeshError other) const { - return this->kind != other.kind; - } - - std::string description() const { - switch (kind) { - case LoadMeshErrorKind::UnsupportedFormat: - return "format not supported"; - case LoadMeshErrorKind::FileNotFound: - return "file not found"; - case LoadMeshErrorKind::InvalidFormat: - return "invalid file format"; - case LoadMeshErrorKind::OutOfMemory: - return "out of memory"; - default: - return "undefined error"; - } - } - -private: - LoadMeshErrorKind kind; -}; - -tl::expected load_mesh_from_raw(const RawGltfMesh &raw, const LoadOptions = {}); -tl::expected load_mesh_from_path(const std::filesystem::path &path, const LoadOptions = {}); - -struct SaveOptions { - std::string texture_format = ".jpeg"; - std::string name = "Tile"; - std::unordered_map metadata = {}; -}; - -enum class SaveMeshErrorKind { - UnsupportedFormat, - OpenFile, - WriteFile, - OutOfMemory -}; - -class SaveMeshError { -public: - SaveMeshError() = default; - constexpr SaveMeshError(SaveMeshErrorKind kind) - : kind(kind) {} - - operator SaveMeshErrorKind() const { - return this->kind; - } - constexpr bool operator==(SaveMeshError other) const { - return this->kind == other.kind; - } - constexpr bool operator!=(SaveMeshError other) const { - return this->kind != other.kind; - } - - std::string description() const { - switch (kind) { - case SaveMeshErrorKind::UnsupportedFormat: - return "format not supported"; - case SaveMeshErrorKind::OpenFile: - return "failed to open output file"; - case SaveMeshErrorKind::WriteFile: - return "failed to write to output file"; - case SaveMeshErrorKind::OutOfMemory: - return "out of memory"; - default: - return "undefined error"; - } - } - -private: - SaveMeshErrorKind kind; -}; - -tl::expected save_mesh_to_path(const std::filesystem::path &path, const TerrainMesh &mesh, const SaveOptions options = {}); - -cv::Mat read_texture_from_encoded_bytes(std::span buffer); -void write_texture_to_encoded_buffer(const cv::Mat &image, std::vector &buffer, const std::string extension = ".png"); -std::vector write_texture_to_encoded_buffer(const cv::Mat &image, const std::string extension = ".png"); +tl::expected save_to_path( + const SimpleMesh &mesh, + const std::filesystem::path &path, + const SaveOptions& options = {}); } - -// custom serialization -namespace zpp::bits { -template -constexpr auto serialize(auto &archive, glm::tvec2 &v) { - return archive(v.x, v.y); -} - -template -constexpr auto serialize(auto &archive, const glm::tvec2 &v) { - return archive(v.x, v.y); -} - -template -constexpr auto serialize(auto &archive, glm::tvec3 &v) { - return archive(v.x, v.y, v.z); -} - -template -constexpr auto serialize(auto &archive, const glm::tvec3 &v) { - return archive(v.x, v.y, v.z); -} - -auto serialize(auto &archive, cv::Mat &v) { - std::vector buf; - auto result = archive(buf); - v = io::read_texture_from_encoded_bytes(buf); - return result; } - -auto serialize(auto &archive, const cv::Mat &v) { - return archive(io::write_texture_to_encoded_buffer(v)); -} -} // namespace zpp::bits - diff --git a/src/terrainlib/mesh/io/error.h b/src/terrainlib/mesh/io/error.h new file mode 100644 index 0000000..ba6d55d --- /dev/null +++ b/src/terrainlib/mesh/io/error.h @@ -0,0 +1,102 @@ +#pragma once + +#include + +namespace mesh { +namespace io { + +enum class LoadMeshErrorKind { + UnsupportedFormat, + FileNotFound, + InvalidFormat, + OutOfMemory +}; + +class LoadMeshError { +public: + LoadMeshError() = default; + constexpr LoadMeshError(LoadMeshErrorKind kind) + : kind(kind) {} + + operator LoadMeshErrorKind() const { + return this->kind; + } + constexpr bool operator==(LoadMeshError other) const { + return this->kind == other.kind; + } + constexpr bool operator!=(LoadMeshError other) const { + return this->kind != other.kind; + } + + std::string description() const { + switch (kind) { + case LoadMeshErrorKind::UnsupportedFormat: + return "format not supported"; + case LoadMeshErrorKind::FileNotFound: + return "file not found"; + case LoadMeshErrorKind::InvalidFormat: + return "invalid file format"; + case LoadMeshErrorKind::OutOfMemory: + return "out of memory"; + default: + return "undefined error"; + } + } + + friend std::ostream &operator<<(std::ostream &os, const LoadMeshError &err) { + return os << err.description(); + } + +private: + LoadMeshErrorKind kind; +}; + +enum class SaveMeshErrorKind { + UnsupportedFormat, + OpenFile, + WriteFile, + OutOfMemory +}; + +class SaveMeshError { +public: + SaveMeshError() = default; + constexpr SaveMeshError(SaveMeshErrorKind kind) + : kind(kind) {} + + operator SaveMeshErrorKind() const { + return this->kind; + } + constexpr bool operator==(SaveMeshError other) const { + return this->kind == other.kind; + } + constexpr bool operator!=(SaveMeshError other) const { + return this->kind != other.kind; + } + + std::string description() const { + switch (kind) { + case SaveMeshErrorKind::UnsupportedFormat: + return "format not supported"; + case SaveMeshErrorKind::OpenFile: + return "failed to open output file"; + case SaveMeshErrorKind::WriteFile: + return "failed to write to output file"; + case SaveMeshErrorKind::OutOfMemory: + return "out of memory"; + default: + return "undefined error"; + } + } + + friend std::ostream &operator<<(std::ostream &os, const SaveMeshError &error) { + os << error.description(); + return os; + } + +private: + SaveMeshErrorKind kind; +}; + +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/gltf.cpp b/src/terrainlib/mesh/io/gltf.cpp new file mode 100644 index 0000000..b6b867c --- /dev/null +++ b/src/terrainlib/mesh/io/gltf.cpp @@ -0,0 +1,702 @@ +#include +#include +#include + +#define CGLTF_IMPLEMENTATION +#define CGLTF_WRITE_IMPLEMENTATION +// #define CGLTF_VALIDATE_ENABLE_ASSERTS +#include +#undef CGLTF_IMPLEMENTATION +#undef CGLTF_WRITE_IMPLEMENTATION + +#include "log.h" +#include "mesh/io/utils.h" +#include "mesh/io/gltf.h" +#include "mesh/io/texture.h" + +using namespace mesh::io::utils; + +namespace mesh { +namespace io { +namespace gltf { + +namespace { +const int GL_NEAREST = 0x2600; +const int GL_LINEAR = 0x2601; +const int GL_NEAREST_MIPMAP_NEAREST = 0x2700; +const int GL_LINEAR_MIPMAP_NEAREST = 0x2701; +const int GL_NEAREST_MIPMAP_LINEAR = 0x2702; +const int GL_LINEAR_MIPMAP_LINEAR = 0x2703; +const int GL_TEXTURE_MAG_FILTER = 0x2800; +const int GL_TEXTURE_MIN_FILTER = 0x2801; +const int GL_REPEAT = 0x2901; +const int GL_CLAMP_TO_EDGE = 0x812F; +const int GL_MIRRORED_REPEAT = 0x8370; + +cgltf_attribute *find_attribute_with_type(cgltf_attribute *attributes, size_t attribute_count, cgltf_attribute_type type) { + for (unsigned int i = 0; i < attribute_count; i++) { + cgltf_attribute *attribute = &attributes[i]; + if (attribute->type == type) { + return attribute; + } + } + + return nullptr; +} + +glm::mat4 get_node_transform_local(const cgltf_node &node) { + if (node.has_matrix) { + return glm::make_mat4(node.matrix); + } + + glm::mat4 transform(1); + + if (node.has_translation) { + const glm::vec3 translation(node.translation[0], node.translation[1], node.translation[2]); + transform = glm::translate(transform, translation); + } + + if (node.has_rotation) { + glm::quat rotation(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2]); + transform = transform * glm::toMat4(rotation); + } + + if (node.has_scale) { + glm::vec3 scaling(node.scale[0], node.scale[1], node.scale[2]); + transform = glm::scale(transform, scaling); + } + + return transform; +} + +glm::dmat4 get_node_transform_world(const cgltf_node &node) { + glm::dmat4 transform = get_node_transform_local(node); + + const cgltf_node *parent = node.parent; + while (parent != nullptr) { + const glm::dmat4 parent_transform = get_node_transform_local(*parent); + transform *= parent_transform; + parent = parent->parent; + } + + return transform; +} + +const cgltf_node *find_mesh_node_under_node(const cgltf_node &node, const cgltf_mesh &target_mesh) { + if (node.mesh != nullptr) { + if (std::addressof(target_mesh) == node.mesh) { + return &node; + } + } + + for (cgltf_size child_index = 0; child_index < node.children_count; child_index++) { + const cgltf_node &child = *node.children[child_index]; + const cgltf_node *child_result = find_mesh_node_under_node(child, target_mesh); + if (child_result != nullptr) { + return child_result; + } + } + + return nullptr; +} +const cgltf_node *find_mesh_node_in_scene(const cgltf_scene &scene, const cgltf_mesh &mesh) { + for (cgltf_size i = 0; i < scene.nodes_count; i++) { + const cgltf_node &node = *scene.nodes[i]; + const cgltf_node *mesh_node = find_mesh_node_under_node(node, mesh); + if (mesh_node != nullptr) { + return mesh_node; + } + } + + return nullptr; +} +const cgltf_node *find_mesh_node(const cgltf_data &data, const cgltf_mesh &mesh) { + if (data.scenes_count == 0) { + LOG_WARN("file contains no scenes"); + return nullptr; + } + + for (cgltf_size i = 0; i < data.scenes_count; i++) { + const cgltf_scene &scene = data.scenes[i]; + const cgltf_node *mesh_node = find_mesh_node_in_scene(scene, mesh); + if (mesh_node != nullptr) { + return mesh_node; + } + } + + return nullptr; +} + +glm::dmat4 get_mesh_transform(const cgltf_data &data, const cgltf_mesh &mesh) { + const cgltf_node *mesh_node = find_mesh_node(data, mesh); + if (mesh_node == nullptr) { + return glm::dmat4(1); + } + return get_node_transform_world(*mesh_node); +} + +/// Encodes the data at the given pointer into base64. +// from https://github.com/syoyo/tinygltf/blob/5e8a7fd602af22aa9619ccd3baeaeeaff0ecb6f3/tiny_gltf.h#L2297 +std::string base64_encode(unsigned char const *bytes_to_encode, + unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + const char *base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = + ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = + ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (i = 0; (i < 4); i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = + ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = + ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while ((i++ < 3)) + ret += '='; + } + + return ret; +} + +/// Encodes the given data as a base64 data uri. +std::string data_uri_encode(unsigned char const *bytes_to_encode, unsigned int in_len) { + return "data:application/octet-stream;base64," + base64_encode(bytes_to_encode, in_len); +} + +std::optional load_texture_from_material(const cgltf_material &material) { + if (!material.has_pbr_metallic_roughness || material.pbr_metallic_roughness.base_color_texture.texture == nullptr) { + LOG_WARN("mesh material has no texture"); + return std::nullopt; + } + + cgltf_texture &albedo_texture = *material.pbr_metallic_roughness.base_color_texture.texture; + cgltf_image &albedo_image = *albedo_texture.image; + + const std::span raw_texture{cgltf_buffer_view_data(albedo_image.buffer_view), albedo_image.buffer_view->size}; + cv::Mat texture = mesh::io::texture::read_texture_from_encoded_bytes(raw_texture); + return texture; +} + +#define GET_OR_INVALID_FORMAT(var, opt) \ + do { \ + if (!(opt).has_value()) { \ + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); \ + } else { \ + var = opt.value(); \ + } \ + } while (false) + +template +static std::optional> get_single_element(const char *name, cgltf_size count, T const *items) { + if (count == 0) { + LOG_ERROR("file contains no {}", name); + return std::nullopt; + } + if (count > 1) { + LOG_WARN("file contains more than one {}", name); + return std::nullopt; + } + + const T &ref = items[0]; + + return ref; +} + +LoadMeshError map_cgltf_error(cgltf_result result) { + switch (result) { + case cgltf_result::cgltf_result_data_too_short: + case cgltf_result::cgltf_result_unknown_format: + case cgltf_result::cgltf_result_invalid_json: + case cgltf_result::cgltf_result_invalid_gltf: + case cgltf_result::cgltf_result_legacy_gltf: + return LoadMeshErrorKind::InvalidFormat; + case cgltf_result::cgltf_result_file_not_found: + case cgltf_result::cgltf_result_io_error: + return LoadMeshErrorKind::FileNotFound; + case cgltf_result::cgltf_result_out_of_memory: + return LoadMeshErrorKind::OutOfMemory; + default: + assert(false); + break; + } +} + +/// Calculates the size of the data of a vector in bytes. +template +static size_t vectorsizeof(const typename std::vector &vec) { + return sizeof(T) * vec.size(); +} + +static size_t align(std::size_t alignment, size_t offset) noexcept { + const size_t aligned = (offset - 1u + alignment) & -alignment; + return aligned; +} + +static std::string image_ext_to_mime(std::string_view extension) { + if (extension.starts_with(".")) { + extension = extension.substr(1); + } + + return fmt::format("image/{}", extension); +} +} + +tl::expected load_raw_from_path(const std::filesystem::path &path) { + cgltf_options options = {}; + cgltf_data *data = NULL; + const std::string path_str = path.string(); + const char *path_ptr = path_str.c_str(); + cgltf_result result = cgltf_parse_file(&options, path_ptr, &data); + if (result != cgltf_result::cgltf_result_success) { + return tl::unexpected(result); + } + result = cgltf_load_buffers(&options, data, path_ptr); + if (result != cgltf_result::cgltf_result_success) { + return tl::unexpected(result); + } + return RawMesh(data, cgltf_free); +} + +tl::expected load_mesh_from_raw(const RawMesh &raw, const LoadOptions& options) { + LOG_TRACE("Loading mesh from gltf data"); + + const cgltf_data &data = *raw; + + const auto mesh_opt = get_single_element("mesh", data.meshes_count, data.meshes); + if (!mesh_opt.has_value()) { + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); + } + const cgltf_mesh &mesh = mesh_opt.value(); + + const auto mesh_primitive_opt = get_single_element("mesh primitive", mesh.primitives_count, mesh.primitives); + if (!mesh_primitive_opt.has_value()) { + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); + } + const cgltf_primitive &mesh_primitive = mesh_primitive_opt.value(); + if (mesh_primitive.type != cgltf_primitive_type::cgltf_primitive_type_triangles) { + LOG_ERROR("mesh has invalid primitive type"); + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); + } + + // indices + cgltf_accessor &index_accessor = *mesh_primitive.indices; + std::vector indices; + indices.resize(index_accessor.count / 3); + cgltf_accessor_unpack_indices(&index_accessor, reinterpret_cast(indices.data()), cgltf_component_size(index_accessor.component_type), indices.size() * 3); + + // positions + cgltf_attribute *position_attr = find_attribute_with_type(mesh_primitive.attributes, mesh_primitive.attributes_count, cgltf_attribute_type_position); + if (position_attr == nullptr) { + LOG_ERROR("mesh has no position attribute"); + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); + } + + cgltf_accessor &position_accessor = *position_attr->data; + std::vector positions; + positions.resize(position_accessor.count); + cgltf_accessor_unpack_floats(&position_accessor, reinterpret_cast(positions.data()), positions.size() * 3); + + // uvs + cgltf_attribute *uv_attr = find_attribute_with_type(mesh_primitive.attributes, mesh_primitive.attributes_count, cgltf_attribute_type_texcoord); + std::vector uvs; + if (uv_attr == nullptr) { + LOG_WARN("mesh has no uv attribute"); + } else { + cgltf_accessor &uv_accessor = *uv_attr->data; + uvs.resize(uv_accessor.count); + cgltf_accessor_unpack_floats(&uv_accessor, reinterpret_cast(uvs.data()), uvs.size() * 2); + } + + glm::dmat4 transform = get_mesh_transform(data, mesh); + std::vector positionsd; + positionsd.resize(positions.size()); + for (unsigned int i = 0; i < positions.size(); i++) { + const glm::dvec4 positiond = glm::dvec4(positions[i], 1); + const glm::dvec4 transformed = transform * positiond; + positionsd[i] = glm::dvec3(transformed) / transformed.w; + } + + std::vector uvsd; + uvsd.resize(uvs.size()); + for (unsigned int i = 0; i < uvsd.size(); i++) { + uvsd[i] = glm::dvec2(uvs[i]); + } + + std::optional texture = load_texture_from_material(*mesh_primitive.material); + + return SimpleMesh(indices, positionsd, uvsd, texture); +} + +/// Saves the mesh as a .gltf or .glb file at the given path. +tl::expected save_to_path( + const SimpleMesh &terrain_mesh, + const std::filesystem::path &path, + const SaveOptions& options) { + LOG_TRACE("Saving mesh as gltf/glb"); + + // ********************* Preprocessing ********************* // + + // Calculate the average vertex position for later normalization. + const size_t vertex_count = terrain_mesh.positions.size(); + glm::dvec3 average_position(0, 0, 0); + for (size_t i = 0; i < vertex_count; i++) { + average_position += terrain_mesh.positions[i] / static_cast(vertex_count); + } + + // Create vertex data vector from positions and uvs. + // We also normalize vertex position by extracting their average position and storing the offsets. + // This is to preserve more of our double accuracy, as gltf cannot store them directly. + // This helps but does not fully preserve the accuracy. + std::vector vertices; + vertices.reserve((vectorsizeof(terrain_mesh.positions) + vectorsizeof(terrain_mesh.uvs)) / sizeof(float)); + glm::vec3 max_position(-std::numeric_limits::infinity()); + glm::vec3 min_position(std::numeric_limits::infinity()); + for (size_t i = 0; i < vertex_count; i++) { + const glm::vec3 normalized_position = terrain_mesh.positions[i] - average_position; + + vertices.push_back(normalized_position.x); + vertices.push_back(normalized_position.y); + vertices.push_back(normalized_position.z); + if (terrain_mesh.has_uvs()) { + vertices.push_back(terrain_mesh.uvs[i].x); + vertices.push_back(terrain_mesh.uvs[i].y); + } + + max_position = glm::max(max_position, normalized_position); + min_position = glm::min(min_position, normalized_position); + } + + // Encode the texture as jpeg data. + const bool has_texture = terrain_mesh.has_texture(); + std::vector texture_bytes; + if (has_texture) { + texture_bytes = mesh::io::texture::write_texture_to_encoded_buffer(terrain_mesh.texture.value(), options.texture_format); + } + + // Create a single buffer that holds all binary data (indices, vertices, textures) + // We need to do this because only a single buffer can be written as a binary blob in .glb files. + const size_t index_data_offset = align(sizeof(glm::uvec3), 0); + const size_t index_data_byte_count = vectorsizeof(terrain_mesh.triangles); + const size_t index_data_end = index_data_offset + index_data_byte_count; + const size_t vertex_data_offset = align(sizeof(glm::vec3), index_data_end); + const size_t vertex_data_byte_count = vectorsizeof(vertices); + const size_t vertex_data_end = vertex_data_offset + vertex_data_byte_count; + const size_t texture_data_offset = align(sizeof(uint8_t), vertex_data_end); + const size_t texture_data_byte_count = vectorsizeof(texture_bytes); + const size_t texture_data_end = texture_data_offset + texture_data_byte_count; + + std::vector buffer_data; + buffer_data.resize(texture_data_end); + std::memcpy(buffer_data.data() + index_data_offset, terrain_mesh.triangles.data(), index_data_byte_count); + std::memcpy(buffer_data.data() + vertex_data_offset, vertices.data(), vertex_data_byte_count); + std::memcpy(buffer_data.data() + texture_data_offset, texture_bytes.data(), texture_data_byte_count); + + const bool binary_output = path.extension() == ".glb"; + + // ********************* Create GLTF data structure ********************* // + + // Initialize a GLTF data structure + cgltf_data data = {}; + std::string version = "2.0\0"; + data.asset.version = version.data(); + std::string generator = "alpinite\0"; + data.asset.generator = generator.data(); + + std::array buffers; + + // Create a gltf buffer to hold vertex data, index data and the texture. + cgltf_buffer &buffer = buffers[0] = {}; + buffer.size = buffer_data.size(); + buffer.data = buffer_data.data(); + std::string buffer_data_encoded; + if (binary_output) { + // The binary blob at the end of the file will be used as the contents of the first buffer if it does not have an uri defined. + data.bin = buffer_data.data(); + data.bin_size = buffer_data.size(); + } else { + buffer_data_encoded = data_uri_encode(buffer_data.data(), buffer_data.size()); + buffer.uri = buffer_data_encoded.data(); + } + + // Create buffer views for each of types of data in the buffer. + std::array buffer_views; + + cgltf_buffer_view &index_buffer_view = buffer_views[0] = {}; + index_buffer_view.buffer = &buffer; + index_buffer_view.offset = index_data_offset; + index_buffer_view.size = index_data_byte_count; + index_buffer_view.stride = 0; + index_buffer_view.type = cgltf_buffer_view_type_indices; + + cgltf_buffer_view &vertex_buffer_view = buffer_views[1] = {}; + vertex_buffer_view.buffer = &buffer; + vertex_buffer_view.offset = vertex_data_offset; + vertex_buffer_view.size = vertex_data_byte_count; + vertex_buffer_view.stride = (terrain_mesh.has_uvs() ? 5 : 3) * sizeof(float); + vertex_buffer_view.type = cgltf_buffer_view_type_vertices; + + cgltf_buffer_view &texture_buffer_view = buffer_views[2] = {}; + texture_buffer_view.buffer = &buffer; + texture_buffer_view.offset = texture_data_offset; + texture_buffer_view.size = texture_data_byte_count; + texture_buffer_view.stride = 0; + + // Create accessors describing the layout of data in the buffer views. + std::array accessors; + + // Create an accessor for indices. + cgltf_accessor &index_accessor = accessors[0] = {}; + index_accessor.buffer_view = &index_buffer_view; + index_accessor.type = cgltf_type_scalar; + index_accessor.component_type = cgltf_component_type_r_32u; + index_accessor.count = terrain_mesh.face_count() * 3; + index_accessor.has_min = true; + index_accessor.min[0] = static_cast(0.0); + index_accessor.has_max = true; + index_accessor.max[0] = static_cast(vertex_count - 1); + + // Create an accessor for vertex positions + cgltf_accessor &position_accessor = accessors[1] = {}; + position_accessor.buffer_view = &vertex_buffer_view; + position_accessor.component_type = cgltf_component_type_r_32f; + position_accessor.type = cgltf_type_vec3; + position_accessor.offset = 0 * sizeof(float); + position_accessor.count = vertex_count; + // We need the min and max as some viewers otherwise refuse to open the file. + position_accessor.has_min = true; + position_accessor.has_max = true; + std::copy(glm::value_ptr(min_position), glm::value_ptr(min_position) + min_position.length(), position_accessor.min); + std::copy(glm::value_ptr(max_position), glm::value_ptr(max_position) + max_position.length(), position_accessor.max); + + cgltf_accessor &uv_accessor = accessors[2] = {}; + if (terrain_mesh.has_uvs()) { + // Create an accessor for vertex uvs + uv_accessor.buffer_view = &vertex_buffer_view; + uv_accessor.component_type = cgltf_component_type_r_32f; + uv_accessor.type = cgltf_type_vec2; + uv_accessor.offset = 3 * sizeof(float); + uv_accessor.count = vertex_count; + uv_accessor.has_min = true; + uv_accessor.has_max = true; + std::fill(uv_accessor.min, uv_accessor.min + 2, 0); + std::fill(uv_accessor.max, uv_accessor.max + 2, 1); + } + + // Create a mesh primitive. + std::array primitive_attributes; + cgltf_attribute &position_attribute = primitive_attributes[0] = {}; + std::string position_attribute_name = "POSITION\0"; + position_attribute.name = position_attribute_name.data(); + position_attribute.type = cgltf_attribute_type::cgltf_attribute_type_position; + position_attribute.index = 0; + position_attribute.data = &position_accessor; + cgltf_attribute &uv_attribute = primitive_attributes[1] = {}; + std::string uv_attribute_name = "TEXCOORD_0\0"; + if (terrain_mesh.has_uvs()) { + uv_attribute.name = uv_attribute_name.data(); + uv_attribute.type = cgltf_attribute_type::cgltf_attribute_type_texcoord; + uv_attribute.index = 0; + uv_attribute.data = &uv_accessor; + } + + // Create a gltf texture + std::array images; + cgltf_image &image = images[0] = {}; + image.buffer_view = &texture_buffer_view; + std::string image_mime_type = image_ext_to_mime(options.texture_format); + image.mime_type = image_mime_type.data(); + + std::array samplers; + cgltf_sampler &sampler = samplers[0] = {}; + sampler.min_filter = GL_LINEAR_MIPMAP_LINEAR; + sampler.mag_filter = GL_LINEAR; + sampler.wrap_s = GL_CLAMP_TO_EDGE; + sampler.wrap_t = GL_CLAMP_TO_EDGE; + + std::array textures; + cgltf_texture &texture = textures[0] = {}; + texture.image = ℑ + texture.sampler = &sampler; + + // Create a material + std::array materials; + cgltf_material &material = materials[0] = {}; + material.has_pbr_metallic_roughness = true; + material.pbr_metallic_roughness.base_color_factor[0] = 1.0f; + material.pbr_metallic_roughness.base_color_factor[1] = 0.9f; + material.pbr_metallic_roughness.base_color_factor[2] = 0.9f; + material.pbr_metallic_roughness.base_color_factor[3] = 1.0f; + material.pbr_metallic_roughness.roughness_factor = 1; + if (has_texture) { + material.pbr_metallic_roughness.base_color_texture.texture = &texture; + } + material.double_sided = true; + + // Build the primitive for the mesh + std::array primitives; + cgltf_primitive &primitive = primitives[0] = {}; + primitive.type = cgltf_primitive_type_triangles; + primitive.indices = &index_accessor; + primitive.attributes_count = primitive_attributes.size(); + primitive.attributes = primitive_attributes.data(); + if (!terrain_mesh.has_uvs()) { + primitive.attributes_count -= 1; + } + primitive.material = &material; + + // Build the actual mesh + std::array meshes; + cgltf_mesh &mesh = meshes[0] = {}; + mesh.primitives_count = 1; + mesh.primitives = &primitive; + + // Create the node hierachy. + // We create parent nodes to offset the position by the average calculate above. + // We need multiple parents to ensure that we dont lose our double precision accurary. + char *node_name = const_cast(options.name.data()); + std::array nodes; + cgltf_node &mesh_node = nodes[2] = {}; + mesh_node.name = node_name; + mesh_node.has_translation = true; + mesh_node.mesh = &mesh; + + cgltf_node &parent_node = nodes[1] = {}; + parent_node.name = node_name; + std::array parent_node_children = {&mesh_node}; + parent_node.children_count = parent_node_children.size(); + parent_node.children = parent_node_children.data(); + parent_node.has_translation = true; + + cgltf_node &parent_parent_node = nodes[0] = {}; + parent_parent_node.name = node_name; + std::array parent_parent_node_children = {&parent_node}; + parent_parent_node.children_count = parent_parent_node_children.size(); + parent_parent_node.children = parent_parent_node_children.data(); + parent_parent_node.has_translation = true; + + const glm::vec3 parent_parent_offset(average_position); + const glm::dvec3 parent_parent_offset_error = glm::dvec3(parent_parent_offset) - average_position; + const glm::vec3 parent_offset(-parent_parent_offset_error); + const glm::dvec3 parent_offset_error = glm::dvec3(parent_offset) + glm::dvec3(parent_parent_offset) - average_position; + const glm::vec3 mesh_offset(-parent_offset_error); + std::copy(glm::value_ptr(parent_parent_offset), glm::value_ptr(parent_parent_offset) + parent_parent_offset.length(), parent_parent_node.translation); + std::copy(glm::value_ptr(parent_offset), glm::value_ptr(parent_offset) + parent_offset.length(), parent_node.translation); + std::copy(glm::value_ptr(mesh_offset), glm::value_ptr(mesh_offset) + mesh_offset.length(), mesh_node.translation); + const glm::dvec3 full_error = (glm::dvec3(parent_parent_offset) + glm::dvec3(parent_offset) + glm::dvec3(mesh_offset)) - average_position; + // assert(glm::length(full_error) == 0); + if (full_error != glm::dvec3(0)) { + LOG_ERROR("Float transform trick failed (error: {})", glm::length(full_error)); + } + + // Create a scene + std::array scenes; + cgltf_scene &scene = scenes[0] = {}; + std::array scene_nodes = {&parent_parent_node}; + scene.nodes_count = scene_nodes.size(); + scene.nodes = scene_nodes.data(); + + // Set up data references + data.meshes_count = meshes.size(); + data.meshes = meshes.data(); + data.nodes_count = nodes.size(); + data.nodes = nodes.data(); + data.scenes_count = scenes.size(); + data.scenes = scenes.data(); + data.buffers_count = buffers.size(); + data.buffers = buffers.data(); + data.buffer_views_count = buffer_views.size(); + data.buffer_views = buffer_views.data(); + data.accessors_count = accessors.size(); + data.accessors = accessors.data(); + if (!terrain_mesh.has_uvs()) { + data.accessors_count -= 1; + } + data.materials_count = materials.size(); + data.materials = materials.data(); + if (has_texture) { + data.textures_count = textures.size(); + data.textures = textures.data(); + data.images_count = images.size(); + data.images = images.data(); + data.samplers_count = samplers.size(); + data.samplers = samplers.data(); + } else { + data.textures_count = 0; + data.images_count = 0; + data.samplers_count = 0; + data.buffer_views_count -= 1; + } + + // Set up extra metadata + std::string extras_str; + const auto &extra_metadata = options.metadata; + if (!extra_metadata.empty()) { + std::stringstream extras = {}; + extras << "{"; + for (auto const &[key, val] : extra_metadata) { + extras << "\n"; + extras << " "; + extras << "\"" << key << "\""; + extras << ": "; + extras << val; + extras << ","; + } + extras.seekp(-1, std::ios_base::end); // remove last "," + extras << "\n }"; + extras << "\0"; + extras_str = extras.str(); + data.extras.data = extras_str.data(); + } + + // ********************* Save the GLTF data to a file ********************* // + create_parent_directories(path); + cgltf_options gltf_options; + if (binary_output) { + gltf_options.type = cgltf_file_type_glb; + } + if (cgltf_write_file(&gltf_options, path.c_str(), &data) != cgltf_result_success) { + throw std::runtime_error("Failed to save GLTF file"); + } + + return {}; +} + +tl::expected load_from_path(const std::filesystem::path &path, const LoadOptions &options) { + tl::expected raw_mesh = load_raw_from_path(path); + if (!raw_mesh) { + return tl::unexpected(map_cgltf_error(raw_mesh.error())); + } + return load_mesh_from_raw(*raw_mesh, options); +} + +} // namespace gltf +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/gltf.h b/src/terrainlib/mesh/io/gltf.h new file mode 100644 index 0000000..9be06b0 --- /dev/null +++ b/src/terrainlib/mesh/io/gltf.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/io/error.h" +#include "mesh/io/options.h" + +namespace mesh { +namespace io { +namespace gltf { + +using RawMesh = std::unique_ptr; + +tl::expected load_from_path( + const std::filesystem::path &path, + const LoadOptions &options = {}); +tl::expected load_from_raw( + const RawMesh &mesh, + const LoadOptions &options = {}); + +tl::expected save_to_path( + const SimpleMesh &mesh, + const std::filesystem::path &path, + const SaveOptions &options = {}); +// tl::expected save_to_raw(const RawMesh &mesh, const SaveOptions &options = {}); + +tl::expected load_raw_from_path(const std::filesystem::path &path); + +} // namespace gltf +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/options.h b/src/terrainlib/mesh/io/options.h new file mode 100644 index 0000000..559a365 --- /dev/null +++ b/src/terrainlib/mesh/io/options.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace mesh { +namespace io { + +struct LoadOptions { +}; + +struct SaveOptions { + std::string texture_format = ".jpeg"; + std::string name = "Terrain"; + std::unordered_map metadata = {}; +}; + +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/terrain.cpp b/src/terrainlib/mesh/io/terrain.cpp new file mode 100644 index 0000000..da67cc4 --- /dev/null +++ b/src/terrainlib/mesh/io/terrain.cpp @@ -0,0 +1,147 @@ +#include + +#include "log.h" +#include "mesh/io/terrain.h" +#include "mesh/io/utils.h" + +using namespace mesh::io::utils; + +namespace mesh { +namespace io { +namespace terrain { + +namespace { +tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path) { + LOG_TRACE("Writing bytes to path {}", path.string()); + + std::ofstream ofs(path, std::ios::out | std::ios::binary); + if (!ofs.is_open()) { + LOG_ERROR("Failed to open file {}", path.string()); + return tl::unexpected(SaveMeshErrorKind::OpenFile); + } + + const unsigned long data_size = bytes.size(); + // ofs.write(reinterpret_cast(&data_size), sizeof(unsigned long)); + ofs.write(reinterpret_cast(bytes.data()), data_size); + + if (!ofs.good()) { + LOG_ERROR("Failed to write to file {}", path.string()); + ofs.close(); + return tl::unexpected(SaveMeshErrorKind::WriteFile); + } + + ofs.close(); + + return {}; +} + +tl::expected, LoadMeshError> read_bytes_from_path(const std::filesystem::path &path) { + LOG_TRACE("Reading bytes from path {}", path.string()); + + std::ifstream ifs(path, std::ios::in | std::ios::binary); + if (!ifs.is_open()) { + LOG_ERROR("Failed to open file {}", path.string()); + return tl::unexpected(LoadMeshErrorKind::FileNotFound); + } + + std::vector data; + + // get length of file + ifs.seekg(0, ifs.end); + const size_t length = ifs.tellg(); + ifs.seekg(0, ifs.beg); + + // read file + if (length > 0) { + data.resize(length); + ifs.read(reinterpret_cast(data.data()), length); + } + ifs.close(); + + return data; +} +} + +tl::expected load_from_path(const std::filesystem::path &path, const LoadOptions& options) { + const auto result = read_bytes_from_path(path); + if (!result.has_value()) { + return tl::unexpected(result.error()); + } + const std::vector bytes = result.value(); + return load_from_buffer(bytes, options); +} + +tl::expected, SaveMeshError> save_to_buffer(const SimpleMesh &mesh, const SaveOptions& options) { + LOG_TRACE("Serializing mesh to buffer"); + + // TODO: this ignores the texture format in SaveOptions + std::vector data; + zpp::bits::out out(data); + auto result = out(mesh); + if (zpp::bits::failure(result)) { + std::error_code error_code = std::make_error_code(result); + LOG_ERROR("Error while writing tile: {}", error_code.message()); + + switch (result) { + case std::errc::no_buffer_space: + case std::errc::message_size: + case std::errc::result_out_of_range: + return tl::unexpected(SaveMeshErrorKind::OutOfMemory); + break; + default: + UNREACHABLE(); + break; + } + } + + return data; +} + +tl::expected load_from_buffer(const std::span bytes, const LoadOptions &options) { + LOG_TRACE("Deserializing mesh from buffer"); + + zpp::bits::in in(bytes); + SimpleMesh mesh; + auto result = in(mesh); + if (zpp::bits::failure(result)) { + std::error_code error_code = std::make_error_code(result); + LOG_ERROR("error while reading mesh: {}", error_code.message()); + + switch (result) { + case std::errc::no_buffer_space: + case std::errc::message_size: + return tl::unexpected(LoadMeshErrorKind::OutOfMemory); + case std::errc::value_too_large: + case std::errc::bad_message: + case std::errc::protocol_error: + case std::errc::result_out_of_range: + return tl::unexpected(LoadMeshErrorKind::InvalidFormat); + case std::errc::not_supported: + case std::errc::invalid_argument: + UNREACHABLE(); + break; + default: + throw std::runtime_error("unexpected error"); + } + } + + return mesh; +} + +tl::expected save_to_path(const SimpleMesh &mesh, const std::filesystem::path &path, const SaveOptions& options) { + LOG_TRACE("Saving mesh as high precision mesh"); + + const auto result = save_to_buffer(mesh, options); + if (!result.has_value()) { + return tl::unexpected(result.error()); + } + const std::vector bytes = result.value(); + + create_parent_directories(path); + + return write_bytes_to_path(bytes, path); +} + +} // namespace terrain +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/terrain.h b/src/terrainlib/mesh/io/terrain.h new file mode 100644 index 0000000..03e2250 --- /dev/null +++ b/src/terrainlib/mesh/io/terrain.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include + +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/io/error.h" +#include "mesh/io/options.h" +#include "mesh/io/texture.h" + +namespace mesh { +namespace io { +namespace terrain { + +tl::expected load_from_path(const std::filesystem::path &path, const LoadOptions &options = {}); +tl::expected load_from_buffer(const std::span buffer, const LoadOptions &options = {}); + +tl::expected save_to_path(const SimpleMesh &mesh, const std::filesystem::path &path, const SaveOptions &options = {}); +tl::expected, SaveMeshError> save_to_buffer(const SimpleMesh &mesh, const SaveOptions &options = {}); + +} // namespace terrain +} // namespace io +} // namespace mesh + +// custom serialization +namespace zpp::bits { +template +constexpr auto serialize(auto &archive, glm::tvec2 &v) { + return archive(v.x, v.y); +} + +template +constexpr auto serialize(auto &archive, const glm::tvec2 &v) { + return archive(v.x, v.y); +} + +template +constexpr auto serialize(auto &archive, glm::tvec3 &v) { + return archive(v.x, v.y, v.z); +} + +template +constexpr auto serialize(auto &archive, const glm::tvec3 &v) { + return archive(v.x, v.y, v.z); +} + +auto serialize(auto &archive, cv::Mat &v) { + std::vector buf; + auto result = archive(buf); + v = mesh::io::texture::read_texture_from_encoded_bytes(buf); + return result; +} + +auto serialize(auto &archive, const cv::Mat &v) { + return archive(mesh::io::texture::write_texture_to_encoded_buffer(v, ".png")); +} +} // namespace zpp::bits diff --git a/src/terrainlib/mesh/io/texture.cpp b/src/terrainlib/mesh/io/texture.cpp new file mode 100644 index 0000000..df94bbc --- /dev/null +++ b/src/terrainlib/mesh/io/texture.cpp @@ -0,0 +1,27 @@ +#include "mesh/io/texture.h" + +namespace mesh { +namespace io { +namespace texture { + +cv::Mat read_texture_from_encoded_bytes(std::span buffer) { + cv::Mat raw_data = cv::Mat(1, buffer.size(), CV_8UC1, const_cast(buffer.data())); + cv::Mat mat = cv::imdecode(raw_data, cv::IMREAD_UNCHANGED); + mat.convertTo(mat, CV_8UC3); + return mat; +} + +void write_texture_to_encoded_buffer(const cv::Mat &image, std::vector &buffer, const std::string& extension) { + cv::Mat converted; + image.convertTo(converted, CV_8UC3); + cv::imencode(extension, image, buffer); +} +std::vector write_texture_to_encoded_buffer(const cv::Mat &image, const std::string &extension) { + std::vector buffer; + write_texture_to_encoded_buffer(image, buffer, extension); + return buffer; +} + +} // namespace texture +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/texture.h b/src/terrainlib/mesh/io/texture.h new file mode 100644 index 0000000..684be9e --- /dev/null +++ b/src/terrainlib/mesh/io/texture.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +#include + +namespace mesh { +namespace io { +namespace texture { + +cv::Mat read_texture_from_encoded_bytes(std::span buffer); +void write_texture_to_encoded_buffer(const cv::Mat &image, std::vector &buffer, const std::string &extension); +std::vector write_texture_to_encoded_buffer(const cv::Mat &image, const std::string &extension); + +} // namespace texture +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/utils.cpp b/src/terrainlib/mesh/io/utils.cpp new file mode 100644 index 0000000..d392903 --- /dev/null +++ b/src/terrainlib/mesh/io/utils.cpp @@ -0,0 +1,15 @@ +#include "mesh/io/utils.h" + +namespace mesh { +namespace io { +namespace utils { + +std::filesystem::path create_parent_directories(const std::filesystem::path &path) { + const std::filesystem::path parent_path = std::filesystem::absolute(path).parent_path(); + std::filesystem::create_directories(parent_path); + return parent_path; +} + +} // namespace utils +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/io/utils.h b/src/terrainlib/mesh/io/utils.h new file mode 100644 index 0000000..d93bb11 --- /dev/null +++ b/src/terrainlib/mesh/io/utils.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace mesh { +namespace io { +namespace utils { + +std::filesystem::path create_parent_directories(const std::filesystem::path &path); + +} // namespace utils +} // namespace io +} // namespace mesh diff --git a/src/terrainlib/mesh/non_copyable.h b/src/terrainlib/mesh/non_copyable.h deleted file mode 100644 index 6234c9c..0000000 --- a/src/terrainlib/mesh/non_copyable.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NONCOPYABLE_H -#define NONCOPYABLE_H - -class NonCopyable -{ - public: - NonCopyable (const NonCopyable &) = delete; - NonCopyable & operator = (const NonCopyable &) = delete; - - protected: - NonCopyable () = default; - ~NonCopyable () = default; /// Protected non-virtual destructor -}; - - -#endif diff --git a/src/terrainlib/mesh/raw_gltf.cpp b/src/terrainlib/mesh/raw_gltf.cpp deleted file mode 100644 index 3b5d31f..0000000 --- a/src/terrainlib/mesh/raw_gltf.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -#include "raw_gltf.h" - -tl::expected io::RawGltfMesh::load_from_path(const std::filesystem::path &path) { - cgltf_options options = {}; - cgltf_data *data = NULL; - const std::string path_str = path.string(); - const char *path_ptr = path_str.c_str(); - cgltf_result result = cgltf_parse_file(&options, path_ptr, &data); - if (result != cgltf_result::cgltf_result_success) { - return tl::unexpected(result); - } - result = cgltf_load_buffers(&options, data, path_ptr); - if (result != cgltf_result::cgltf_result_success) { - return tl::unexpected(result); - } - return io::RawGltfMesh(data); -} diff --git a/src/terrainlib/mesh/raw_gltf.h b/src/terrainlib/mesh/raw_gltf.h deleted file mode 100644 index 357c915..0000000 --- a/src/terrainlib/mesh/raw_gltf.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef RAW_GLTF_H -#define RAW_GLTF_H - -#include - -#include -#include - -#include "non_copyable.h" - -namespace io { - -class RawGltfMesh : public NonCopyable { -public: - cgltf_data *data; - - ~RawGltfMesh() { - if (this->data != nullptr) { - cgltf_free(this->data); - } - } - - // Move constructor - RawGltfMesh(RawGltfMesh &&other) { - this->data = other.data; - other.data = nullptr; - } - - // Move assignment operator - RawGltfMesh &operator=(RawGltfMesh &&other) { - if (this != &other) { - this->data = other.data; - other.data = nullptr; - } - return *this; - } - - static tl::expected load_from_path(const std::filesystem::path &path); - -private: - RawGltfMesh(cgltf_data *data) - : data(data) {} -}; - -} - -#endif diff --git a/src/terrainlib/mesh/terrain_mesh.h b/src/terrainlib/mesh/terrain_mesh.h deleted file mode 100644 index 1a3ccb8..0000000 --- a/src/terrainlib/mesh/terrain_mesh.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include -#include - - -class TerrainMesh { -public: - using Triangle = glm::uvec3; - using Edge = glm::uvec2; - using Position = glm::dvec3; - using Uv = glm::dvec2; - using Texture = cv::Mat; - using serialize = zpp::bits::members<4>; - - TerrainMesh(std::vector triangles, std::vector positions) - : TerrainMesh(triangles, positions, {}) {} - TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs) - : TerrainMesh(triangles, positions, uvs, std::nullopt) {} - TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) - : TerrainMesh(triangles, positions, uvs, std::optional(std::move(texture))) {} - TerrainMesh(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) - : triangles(triangles), positions(positions), uvs(uvs), texture(std::move(texture)) {} - TerrainMesh() = default; - TerrainMesh(TerrainMesh &&) = default; - TerrainMesh &operator=(TerrainMesh &&) = default; - TerrainMesh(const TerrainMesh &) = default; - TerrainMesh &operator=(const TerrainMesh &) = default; - - std::vector triangles; - std::vector positions; - std::vector uvs; - std::optional texture; - - size_t vertex_count() const { - return this->positions.size(); - } - size_t face_count() const { - return this->triangles.size(); - } - bool is_empty() const { - return this->vertex_count() == 0 && this->face_count() == 0; - } - - bool has_uvs() const { - return this->positions.size() == this->uvs.size(); - } - bool has_texture() const { - return this->texture.has_value(); - } -}; - -radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh); -radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes); - -std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size = 1000); -std::optional calculate_max_edge_length(const TerrainMesh &mesh); - -std::vector find_isolated_vertices(const TerrainMesh &mesh); -size_t remove_isolated_vertices(TerrainMesh & mesh); -size_t remove_triangles_of_negligible_size(TerrainMesh & mesh, const double threshold_percentage_of_average = 0.001); - -bool compare_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2); -bool compare_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2); -bool compare_equality_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2); -bool compare_equality_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2); - -template -inline auto find_duplicate_triangles(Triangles& triangles, bool ignore_orientation = true) { - std::sort(std::begin(triangles), std::end(triangles), ignore_orientation ? compare_triangles_ignore_orientation : compare_triangles); - return std::unique(std::begin(triangles), std::end(triangles), ignore_orientation ? compare_equality_triangles_ignore_orientation : compare_equality_triangles); -} -template <> -inline auto find_duplicate_triangles(TerrainMesh& mesh, bool ignore_orientation) { - return find_duplicate_triangles(mesh.triangles, ignore_orientation); -} -void remove_duplicate_triangles(TerrainMesh& mesh, bool ignore_orientation = true); -void remove_duplicate_triangles(std::vector& triangles, bool ignore_orientation = true); - -std::unordered_map> create_edge_to_triangle_index_mapping(const TerrainMesh &mesh); -std::vector count_vertex_adjacent_triangles(const TerrainMesh &mesh); - -std::vector find_non_manifold_edges(const TerrainMesh &mesh); -std::vector find_single_non_manifold_triangle_indices(const TerrainMesh &mesh); -void remove_single_non_manifold_triangles(TerrainMesh& mesh); - -void sort_and_normalize_triangles(TerrainMesh& mesh); -void sort_and_normalize_triangles(std::span triangles); - -void validate_mesh(const TerrainMesh &mesh); diff --git a/src/terrainlib/mesh/terrain_mesh.cpp b/src/terrainlib/mesh/utils.cpp similarity index 90% rename from src/terrainlib/mesh/terrain_mesh.cpp rename to src/terrainlib/mesh/utils.cpp index ace0553..b9e50c3 100644 --- a/src/terrainlib/mesh/terrain_mesh.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -1,10 +1,11 @@ #include #include -#include "terrain_mesh.h" +#include "SimpleMesh.h" +#include "utils.h" -radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh) { - radix::geometry::Aabb<3, double> bounds; +radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh) { + radix::geometry::Aabb3d bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); for (unsigned int j = 0; j < mesh.positions.size(); j++) { @@ -14,12 +15,12 @@ radix::geometry::Aabb<3, double> calculate_bounds(const TerrainMesh &mesh) { return bounds; } -radix::geometry::Aabb<3, double> calculate_bounds(std::span meshes) { - radix::geometry::Aabb<3, double> bounds; +radix::geometry::Aabb3d calculate_bounds(std::span meshes) { + radix::geometry::Aabb3d bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); for (unsigned int i = 0; i < meshes.size(); i++) { - const TerrainMesh &mesh = meshes[i]; + const SimpleMesh &mesh = meshes[i]; for (unsigned int j = 0; j < mesh.positions.size(); j++) { const auto &position = mesh.positions[j]; bounds.expand_by(position); @@ -28,7 +29,7 @@ radix::geometry::Aabb<3, double> calculate_bounds(std::span m return bounds; } -std::optional estimate_average_edge_length(const TerrainMesh &mesh, const size_t sample_size) { +std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size) { const auto &triangles = mesh.triangles; if (triangles.empty()) { return std::nullopt; @@ -64,7 +65,7 @@ std::optional estimate_average_edge_length(const TerrainMesh &mesh, cons return total_length / edge_count; } -std::optional calculate_max_edge_length(const TerrainMesh &mesh) { +std::optional calculate_max_edge_length(const SimpleMesh &mesh) { if (mesh.face_count() == 0) { return std::nullopt; } @@ -84,7 +85,7 @@ std::optional calculate_max_edge_length(const TerrainMesh &mesh) { return max_length; } -std::vector find_isolated_vertices(const TerrainMesh& mesh) { +std::vector find_isolated_vertices(const SimpleMesh& mesh) { std::vector connected; connected.resize(mesh.vertex_count()); std::fill(connected.begin(), connected.end(), false); @@ -104,7 +105,7 @@ std::vector find_isolated_vertices(const TerrainMesh& mesh) { return isolated; } -size_t remove_isolated_vertices(TerrainMesh& mesh) { +size_t remove_isolated_vertices(SimpleMesh& mesh) { const bool has_uvs = mesh.has_uvs(); const std::vector isolated = find_isolated_vertices(mesh); @@ -130,7 +131,7 @@ size_t remove_isolated_vertices(TerrainMesh& mesh) { return isolated.size(); } -size_t remove_triangles_of_negligible_size(TerrainMesh& mesh, const double threshold_percentage_of_average) { +size_t remove_triangles_of_negligible_size(SimpleMesh& mesh, const double threshold_percentage_of_average) { std::vector areas; areas.reserve(mesh.triangles.size()); for (glm::uvec3 &triangle : mesh.triangles) { @@ -215,14 +216,14 @@ bool compare_equality_triangles_ignore_orientation(const glm::uvec3 &t1, const g return std::is_permutation(&t1.x, &t1.z + 1, &t2.x); } -void remove_duplicate_triangles(TerrainMesh &mesh, bool ignore_orientation) { +void remove_duplicate_triangles(SimpleMesh &mesh, bool ignore_orientation) { remove_duplicate_triangles(mesh.triangles, ignore_orientation); } void remove_duplicate_triangles(std::vector &triangles, bool ignore_orientation) { triangles.erase(find_duplicate_triangles(triangles, ignore_orientation), triangles.end()); } -std::unordered_map> create_edge_to_triangle_index_mapping(const TerrainMesh &mesh) { +std::unordered_map> create_edge_to_triangle_index_mapping(const SimpleMesh &mesh) { std::unordered_map> edges_to_triangles; for (size_t i = 0; i < mesh.face_count(); i++) { glm::uvec3 triangle = mesh.triangles[i]; @@ -242,7 +243,7 @@ std::unordered_map> create_edge_to_triangle_inde return edges_to_triangles; } -std::vector count_vertex_adjacent_triangles(const TerrainMesh& mesh) { +std::vector count_vertex_adjacent_triangles(const SimpleMesh& mesh) { std::vector adjacent_triangle_count(mesh.vertex_count(), 0); for (const glm::uvec3& triangle : mesh.triangles) { @@ -254,7 +255,7 @@ std::vector count_vertex_adjacent_triangles(const TerrainMesh& mesh) { return adjacent_triangle_count; } -std::vector find_non_manifold_edges(const TerrainMesh& mesh) { +std::vector find_non_manifold_edges(const SimpleMesh& mesh) { std::unordered_map> edges_to_triangles = create_edge_to_triangle_index_mapping(mesh); std::vector non_manifold_edges; @@ -270,7 +271,7 @@ std::vector find_non_manifold_edges(const TerrainMesh& mesh) { return non_manifold_edges; } -std::vector find_single_non_manifold_triangle_indices(const TerrainMesh &mesh) { +std::vector find_single_non_manifold_triangle_indices(const SimpleMesh &mesh) { const std::vector adjacent_triangle_count = count_vertex_adjacent_triangles(mesh); const std::unordered_map> edges_to_triangles = create_edge_to_triangle_index_mapping(mesh); @@ -304,7 +305,7 @@ std::vector find_single_non_manifold_triangle_indices(const TerrainMesh return non_manifold_triangles; } -void remove_single_non_manifold_triangles(TerrainMesh& mesh) { +void remove_single_non_manifold_triangles(SimpleMesh& mesh) { std::vector non_manifold_triangles = find_single_non_manifold_triangle_indices(mesh); std::sort(non_manifold_triangles.begin(), non_manifold_triangles.end(), std::greater()); @@ -316,7 +317,7 @@ void remove_single_non_manifold_triangles(TerrainMesh& mesh) { remove_isolated_vertices(mesh); } -void sort_and_normalize_triangles(TerrainMesh& mesh) { +void sort_and_normalize_triangles(SimpleMesh& mesh) { sort_and_normalize_triangles(mesh.triangles); } void sort_and_normalize_triangles(std::span triangles) { @@ -329,7 +330,7 @@ void sort_and_normalize_triangles(std::span triangles) { std::sort(triangles.begin(), triangles.end(), compare_triangles); } -static void validate_sorted_normalized_mesh(const TerrainMesh &mesh) { +static void validate_sorted_normalized_mesh(const SimpleMesh &mesh) { // check correct count of uvs assert(!mesh.has_uvs() || mesh.positions.size() == mesh.uvs.size()); @@ -372,11 +373,11 @@ static void validate_sorted_normalized_mesh(const TerrainMesh &mesh) { assert(find_isolated_vertices(mesh).empty()); } -void validate_mesh(const TerrainMesh &mesh) { +void validate_mesh(const SimpleMesh &mesh) { #if NDEBUG return; #endif - TerrainMesh sorted(mesh); + SimpleMesh sorted(mesh); sort_and_normalize_triangles(sorted); validate_sorted_normalized_mesh(sorted); } diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h new file mode 100644 index 0000000..64b21df --- /dev/null +++ b/src/terrainlib/mesh/utils.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#include +#include +#include + +radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh); +radix::geometry::Aabb3d calculate_bounds(std::span meshes); + +std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size = 1000); +std::optional calculate_max_edge_length(const SimpleMesh &mesh); + +std::vector find_isolated_vertices(const SimpleMesh &mesh); +size_t remove_isolated_vertices(SimpleMesh & mesh); +size_t remove_triangles_of_negligible_size(SimpleMesh & mesh, const double threshold_percentage_of_average = 0.001); + +bool compare_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2); +bool compare_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2); +bool compare_equality_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2); +bool compare_equality_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2); + +template +inline auto find_duplicate_triangles(Triangles& triangles, bool ignore_orientation = true) { + std::sort(std::begin(triangles), std::end(triangles), ignore_orientation ? compare_triangles_ignore_orientation : compare_triangles); + return std::unique(std::begin(triangles), std::end(triangles), ignore_orientation ? compare_equality_triangles_ignore_orientation : compare_equality_triangles); +} +template <> +inline auto find_duplicate_triangles(SimpleMesh& mesh, bool ignore_orientation) { + return find_duplicate_triangles(mesh.triangles, ignore_orientation); +} +void remove_duplicate_triangles(SimpleMesh& mesh, bool ignore_orientation = true); +void remove_duplicate_triangles(std::vector& triangles, bool ignore_orientation = true); + +std::unordered_map> create_edge_to_triangle_index_mapping(const SimpleMesh &mesh); +std::vector count_vertex_adjacent_triangles(const SimpleMesh &mesh); + +std::vector find_non_manifold_edges(const SimpleMesh &mesh); +std::vector find_single_non_manifold_triangle_indices(const SimpleMesh &mesh); +void remove_single_non_manifold_triangles(SimpleMesh& mesh); + +void sort_and_normalize_triangles(SimpleMesh& mesh); +void sort_and_normalize_triangles(std::span triangles); + +void validate_mesh(const SimpleMesh &mesh); diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index 9b22ae0..f3fe591 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -18,24 +18,25 @@ #pragma once -#include "Exception.h" #include +#include +#include +#include + #include #include #include -#include #include -#include -#include +#include #include -#include +#include namespace srs { inline std::unique_ptr transformation(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs) { auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&source_srs, &target_srs)); if (!transformer) { - throw Exception("Couldn't create SRS transformation"); + throw std::runtime_error("Couldn't create SRS transformation"); } return transformer; } @@ -43,13 +44,13 @@ inline std::unique_ptr transformation(const OGRSpat template inline glm::tvec2 transform_point(OGRCoordinateTransformation *transform, glm::tvec2 p) { if (!transform->Transform(1, &p.x, &p.y)) - throw Exception("srs::transform_point(glm::tvec2) failed"); + throw std::runtime_error("srs::transform_point(glm::tvec2) failed"); return p; } template inline glm::tvec3 transform_point(OGRCoordinateTransformation *transform, glm::tvec3 p) { if (!transform->Transform(1, &p.x, &p.y, &p.z)) - throw Exception("srs::transform_point(glm::tvec3) failed"); + throw std::runtime_error("srs::transform_point(glm::tvec3) failed"); return p; } @@ -75,7 +76,7 @@ inline void transform_points_inplace(OGRCoordinateTransformation *transform, std } if (!transform->Transform(points.size(), xs.data(), ys.data())) { - throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + throw std::runtime_error("srs::transform_points_inplace(std::array, n>) failed"); } for (size_t i = 0; i < points.size(); ++i) { @@ -93,7 +94,7 @@ inline void transform_points_inplace(OGRCoordinateTransformation *transform, std } if (!transform->Transform(points.size(), xs.data(), ys.data())) { - throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + throw std::runtime_error("srs::transform_points_inplace(std::vector, n>) failed"); } for (size_t i = 0; i < points.size(); ++i) { @@ -114,7 +115,7 @@ inline void transform_points_inplace(OGRCoordinateTransformation *transform, std } if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { - throw Exception("srs::transform_points_inplace(std::array, n>) failed"); + throw std::runtime_error("srs::transform_points_inplace(std::array, n>) failed"); } for (size_t i = 0; i < points.size(); ++i) { @@ -138,7 +139,7 @@ inline void transform_points_inplace(OGRCoordinateTransformation *transform, std } if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { - throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + throw std::runtime_error("srs::transform_points_inplace(std::vector, n>) failed"); } for (size_t i = 0; i < points.size(); ++i) { @@ -172,7 +173,7 @@ inline std::vector> transform_points_to_2d(OGRCoordinateTransforma } if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { - throw Exception("srs::transform_points_inplace(std::vector, n>) failed"); + throw std::runtime_error("srs::transform_points_inplace(std::vector, n>) failed"); } std::vector> transformed; @@ -189,7 +190,7 @@ inline radix::tile::SrsBounds non_exact_bounds_transform(const radix::tile::SrsB std::array xs = {bounds.min.x, bounds.max.x}; std::array ys = {bounds.min.y, bounds.max.y}; if (!transform->Transform(2, xs.data(), ys.data())) { - throw Exception("srs::non_exact_bounds_transform failed"); + throw std::runtime_error("srs::non_exact_bounds_transform failed"); } return {{xs[0], ys[0]}, {xs[1], ys[1]}}; } @@ -200,7 +201,7 @@ inline radix::geometry::Aabb3d non_exact_bounds_transform(const radix::geometry: std::array ys = {bounds.min.y, bounds.max.y}; std::array zs = {bounds.min.z, bounds.max.z}; if (!transform->Transform(2, xs.data(), ys.data(), zs.data())) { - throw Exception("srs::non_exact_bounds_transform failed"); + throw std::runtime_error("srs::non_exact_bounds_transform failed"); } return {{xs[0], ys[0], zs[0]}, {xs[1], ys[1], zs[1]}}; } diff --git a/src/terrainmerger/convert.cpp b/src/terrainmerger/convert.cpp index 3cbb2a5..6e99bde 100644 --- a/src/terrainmerger/convert.cpp +++ b/src/terrainmerger/convert.cpp @@ -15,7 +15,7 @@ Point2 convert::glm2cgal(glm::dvec2 point) { return Point2(point[0], point[1]); } -SurfaceMesh convert::mesh2cgal(const TerrainMesh &mesh) { +SurfaceMesh convert::mesh2cgal(const SimpleMesh &mesh) { SurfaceMesh cgal_mesh; for (const glm::dvec3 &position : mesh.positions) { @@ -34,8 +34,8 @@ SurfaceMesh convert::mesh2cgal(const TerrainMesh &mesh) { return cgal_mesh; } -TerrainMesh convert::cgal2mesh(const SurfaceMesh &cgal_mesh) { - TerrainMesh mesh; +SimpleMesh convert::cgal2mesh(const SurfaceMesh &cgal_mesh) { + SimpleMesh mesh; const size_t vertex_count = CGAL::num_vertices(cgal_mesh); const size_t face_count = CGAL::num_faces(cgal_mesh); diff --git a/src/terrainmerger/convert.h b/src/terrainmerger/convert.h index ef6e53b..0a69cf1 100644 --- a/src/terrainmerger/convert.h +++ b/src/terrainmerger/convert.h @@ -11,8 +11,8 @@ glm::dvec2 cgal2glm(Point2 point); Point3 glm2cgal(glm::dvec3 point); Point2 glm2cgal(glm::dvec2 point); -SurfaceMesh mesh2cgal(const TerrainMesh& mesh); -TerrainMesh cgal2mesh(const SurfaceMesh& cgal_mesh); +SurfaceMesh mesh2cgal(const SimpleMesh& mesh); +SimpleMesh cgal2mesh(const SurfaceMesh& cgal_mesh); glm::uvec2 cv2glm(const cv::Size size); cv::Size glm2cv(const glm::uvec2 size); diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index 334e8f7..eb55c8b 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -7,8 +7,8 @@ #include "uv_map.h" #include "validate.h" -std::vector load_meshes_from_path(std::span paths, const bool print_errors = true) { - std::vector meshes; +std::vector load_meshes_from_path(std::span paths, const bool print_errors = true) { + std::vector meshes; meshes.reserve(paths.size()); for (const std::filesystem::path &path : paths) { auto result = io::load_mesh_from_path(path); @@ -20,7 +20,7 @@ std::vector load_meshes_from_path(std::span load_meshes_from_path(std::span result = uv_map::parameterize_mesh(mesh, uv_map::Algorithm::DiscreteConformalMap, uv_map::Border::Circle); if (result) { @@ -41,9 +41,9 @@ uv_map::UvMap parameterize_mesh(TerrainMesh &mesh) { } } -TerrainMesh simplify_mesh(const TerrainMesh &mesh, const cli::SimplificationArgs &args) { +SimpleMesh simplify_mesh(const SimpleMesh &mesh, const cli::SimplificationArgs &args) { const simplify::Result result = simplify::simplify_mesh(mesh, args.stop_condition); - const TerrainMesh &simplified_mesh = result.mesh; + const SimpleMesh &simplified_mesh = result.mesh; const size_t initial_vertex_count = mesh.positions.size(); const size_t initial_face_count = mesh.triangles.size(); @@ -59,10 +59,10 @@ TerrainMesh simplify_mesh(const TerrainMesh &mesh, const cli::SimplificationArgs void run(const cli::Args &args) { LOG_INFO("Loading meshes..."); - std::vector meshes = load_meshes_from_path(args.input_paths); + std::vector meshes = load_meshes_from_path(args.input_paths); - const bool meshes_have_uvs = std::all_of(meshes.begin(), meshes.end(), [](const TerrainMesh &mesh) { return mesh.has_uvs(); }); - const bool meshes_have_textures = std::all_of(meshes.begin(), meshes.end(), [](const TerrainMesh &mesh) { return mesh.has_texture(); }); + const bool meshes_have_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); + const bool meshes_have_textures = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_texture(); }); const std::optional texture_size = (!meshes.empty() && meshes[0].texture.has_value()) ? std::optional{convert::cv2glm(meshes[0].texture.value().size())} @@ -72,7 +72,7 @@ void run(const cli::Args &args) { LOG_INFO("Merging meshes..."); merge::VertexMapping vertex_mapping; - TerrainMesh merged_mesh = merge::merge_meshes(meshes, vertex_mapping); + SimpleMesh merged_mesh = merge::merge_meshes(meshes, vertex_mapping); if (args.save_intermediate_meshes) { const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".merged.glb"); LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path.string()); @@ -96,7 +96,7 @@ void run(const cli::Args &args) { } } - TerrainMesh simplified_mesh; + SimpleMesh simplified_mesh; if (args.simplification) { LOG_INFO("Simplifying merged mesh..."); simplified_mesh = simplify_mesh(merged_mesh, args.simplification.value()); diff --git a/src/terrainmerger/merge.cpp b/src/terrainmerger/merge.cpp index ccf945e..cccbea8 100644 --- a/src/terrainmerger/merge.cpp +++ b/src/terrainmerger/merge.cpp @@ -4,7 +4,8 @@ #include "convert.h" #include "log.h" #include "merge.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" +#include "mesh/utils.h" #include "validate.h" using namespace merge; @@ -167,15 +168,15 @@ class Grid3d { std::vector grid_data; }; -static radix::geometry::Aabb<3, double> pad_bounds(const radix::geometry::Aabb<3, double> &bounds, const double percentage) { +static radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { const glm::dvec3 bounds_padding = bounds.size() * percentage; - const radix::geometry::Aabb<3, double> padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); return padded_bounds; } template -static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb<3, double> &bounds, const size_t vertex_count) { - const radix::geometry::Aabb<3, double> padded_bounds = pad_bounds(bounds, 0.01); +static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { + const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); const double max_extends = max_component(padded_bounds.size()); const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; @@ -186,17 +187,17 @@ static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb<3, doubl } template -static Grid3d construct_grid_for_mesh(const TerrainMesh &mesh) { - const radix::geometry::Aabb<3, double> bounds = calculate_bounds(mesh); +static Grid3d construct_grid_for_mesh(const SimpleMesh &mesh) { + const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); const size_t vertex_count = mesh.vertex_count(); return _construct_grid_for_meshes(bounds, vertex_count); } template -static Grid3d construct_grid_for_meshes(const std::span meshes) { - const radix::geometry::Aabb<3, double> bounds = calculate_bounds(meshes); +static Grid3d construct_grid_for_meshes(const std::span meshes) { + const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); const size_t maximal_merged_mesh_size = std::transform_reduce( - meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const TerrainMesh &mesh) { return mesh.vertex_count(); }); + meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); } @@ -224,11 +225,11 @@ static double estimate_min_vertex_separation_between_meshes_after_merge(const Gr return std::sqrt(min_squared_distance); } -static double estimate_min_vertex_separation_between_meshes_after_merge(const std::span meshes, const VertexMapping &mapping) { +static double estimate_min_vertex_separation_between_meshes_after_merge(const std::span meshes, const VertexMapping &mapping) { Grid3d grid = construct_grid_for_meshes(meshes); for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const TerrainMesh &mesh = meshes[mesh_index]; + const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const glm::dvec3 &position = mesh.positions[vertex_index]; grid.insert(position, VertexId {mesh_index, vertex_index}); @@ -265,7 +266,7 @@ static double estimate_min_vertex_separation_between_meshes_after_merge(const st return std::sqrt(min_squared_distance); } -static double estimate_average_vertex_separation(const TerrainMesh &mesh, const size_t sample_size = 1000) { +static double estimate_average_vertex_separation(const SimpleMesh &mesh, const size_t sample_size = 1000) { std::vector triangles = mesh.triangles; std::random_shuffle(triangles.begin(), triangles.end()); @@ -285,7 +286,7 @@ static double estimate_average_vertex_separation(const TerrainMesh &mesh, const return std::sqrt(average_distance); } -static double estimate_average_vertex_seperation(const TerrainMesh &mesh, const size_t sample_size = 1000) { +static double estimate_average_vertex_seperation(const SimpleMesh &mesh, const size_t sample_size = 1000) { std::vector triangles = mesh.triangles; std::random_shuffle(triangles.begin(), triangles.end()); @@ -305,7 +306,7 @@ static double estimate_average_vertex_seperation(const TerrainMesh &mesh, const return std::sqrt(average_distance); } -static double estimate_min_edge_length(const TerrainMesh &mesh) { +static double estimate_min_edge_length(const SimpleMesh &mesh) { std::vector triangles = mesh.triangles; std::random_shuffle(triangles.begin(), triangles.end()); @@ -325,7 +326,7 @@ static double estimate_min_edge_length(const TerrainMesh &mesh) { return std::sqrt(min_edge_length); } -static double measure_min_edge_length(const TerrainMesh &mesh) { +static double measure_min_edge_length(const SimpleMesh &mesh) { const auto min = [](const auto a, const auto b) { return std::min(a, b); }; const double min_squared_edge_length = std::transform_reduce( @@ -435,7 +436,7 @@ static bool are_all_meshes_merged(const VertexMapping &mapping) { return union_find.is_joint(); } -VertexMapping merge::create_merge_mapping(const std::span meshes) { +VertexMapping merge::create_merge_mapping(const std::span meshes) { LOG_DEBUG("Finding shared vertices between {} meshes (epsilon=auto)", meshes.size()); const double min_edge_length = std::transform_reduce( @@ -475,16 +476,16 @@ VertexMapping merge::create_merge_mapping(const std::span mes return mapping; } -static bool are_all_bounds_connected(const std::span meshes) { +static bool are_all_bounds_connected(const std::span meshes) { if (meshes.size() <= 1) { return true; } - std::vector> mesh_bounds; + std::vector mesh_bounds; mesh_bounds.reserve(meshes.size()); std::transform(meshes.begin(), meshes.end(), std::back_inserter(mesh_bounds), - [](const TerrainMesh &mesh) { return pad_bounds(calculate_bounds(mesh), 0.01); }); + [](const SimpleMesh &mesh) { return pad_bounds(calculate_bounds(mesh), 0.01); }); for (size_t i = 0; i < mesh_bounds.size(); i++) { bool intersect_any_other = false; for (size_t j = 0; j < mesh_bounds.size(); j++) { @@ -506,7 +507,7 @@ static bool are_all_bounds_connected(const std::span meshes) return true; } -VertexMapping merge::create_merge_mapping(const std::span meshes, double distance_epsilon) { +VertexMapping merge::create_merge_mapping(const std::span meshes, double distance_epsilon) { if (meshes.empty()) { return {}; } @@ -520,7 +521,7 @@ VertexMapping merge::create_merge_mapping(const std::span mes mesh_sizes.reserve(meshes.size()); std::transform(meshes.begin(), meshes.end(), std::back_inserter(mesh_sizes), - [](const TerrainMesh &mesh) { return mesh.vertex_count(); }); + [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); const size_t maximal_merged_mesh_size = std::accumulate(mesh_sizes.begin(), mesh_sizes.end(), 0); VertexMapping mapping; @@ -533,7 +534,7 @@ VertexMapping merge::create_merge_mapping(const std::span mes size_t unique_vertices = 0; bool has_warned = false; for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const TerrainMesh &mesh = meshes[mesh_index]; + const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const glm::dvec3 &position = mesh.positions[vertex_index]; const VertexId current_vertex{ @@ -563,22 +564,22 @@ VertexMapping merge::create_merge_mapping(const std::span mes return mapping; } -TerrainMesh merge::apply_mapping(std::span meshes, const merge::VertexMapping &mapping) { +SimpleMesh merge::apply_mapping(std::span meshes, const merge::VertexMapping &mapping) { LOG_TRACE("Merging meshes based on mapping"); if (meshes.empty()) { return {}; } - TerrainMesh merged_mesh; + SimpleMesh merged_mesh; size_t max_combined_vertex_count = 0; size_t max_combined_face_count = 0; - for (const TerrainMesh &mesh : meshes) { + for (const SimpleMesh &mesh : meshes) { max_combined_vertex_count += mesh.vertex_count(); max_combined_face_count += mesh.face_count(); } - const bool has_uvs = std::all_of(meshes.begin(), meshes.end(), [](const TerrainMesh &mesh) { + const bool has_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); @@ -588,7 +589,7 @@ TerrainMesh merge::apply_mapping(std::span meshes, const merg merged_mesh.uvs.resize(max_combined_vertex_count); } for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const TerrainMesh &mesh = meshes[mesh_index]; + const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const size_t mapped_index = mapping.map(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; @@ -606,7 +607,7 @@ TerrainMesh merge::apply_mapping(std::span meshes, const merg merged_mesh.triangles.reserve(max_combined_face_count); for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const TerrainMesh &mesh = meshes[mesh_index]; + const SimpleMesh &mesh = meshes[mesh_index]; for (size_t triangle_index = 0; triangle_index < mesh.face_count(); triangle_index++) { const glm::uvec3 &triangle = mesh.triangles[triangle_index]; @@ -635,12 +636,12 @@ TerrainMesh merge::apply_mapping(std::span meshes, const merg return merged_mesh; } -TerrainMesh merge::merge_meshes(std::span meshes) { +SimpleMesh merge::merge_meshes(std::span meshes) { VertexMapping mapping; return merge::merge_meshes(meshes, mapping); } -TerrainMesh merge::merge_meshes(std::span meshes, merge::VertexMapping &mapping) { +SimpleMesh merge::merge_meshes(std::span meshes, merge::VertexMapping &mapping) { switch (meshes.size()) { case 0: return {}; @@ -653,12 +654,12 @@ TerrainMesh merge::merge_meshes(std::span meshes, merge::Vert } } -TerrainMesh merge::merge_meshes(std::span meshes, double distance_epsilon) { +SimpleMesh merge::merge_meshes(std::span meshes, double distance_epsilon) { VertexMapping mapping; return merge::merge_meshes(meshes, distance_epsilon, mapping); } -TerrainMesh merge::merge_meshes(std::span meshes, double distance_epsilon, merge::VertexMapping &mapping) { +SimpleMesh merge::merge_meshes(std::span meshes, double distance_epsilon, merge::VertexMapping &mapping) { switch (meshes.size()) { case 0: return {}; diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index b5eb86e..d9dfad1 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -150,15 +150,15 @@ class VertexMapping { std::vector> backward; }; -TerrainMesh merge_meshes(std::span meshes); -TerrainMesh merge_meshes(std::span meshes, VertexMapping &mapping); -TerrainMesh merge_meshes(std::span meshes, double distance_epsilon); -TerrainMesh merge_meshes(std::span meshes, double distance_epsilon, VertexMapping &mapping); +SimpleMesh merge_meshes(std::span meshes); +SimpleMesh merge_meshes(std::span meshes, VertexMapping &mapping); +SimpleMesh merge_meshes(std::span meshes, double distance_epsilon); +SimpleMesh merge_meshes(std::span meshes, double distance_epsilon, VertexMapping &mapping); -TerrainMesh apply_mapping(std::span meshes, const VertexMapping &mapping); +SimpleMesh apply_mapping(std::span meshes, const VertexMapping &mapping); -VertexMapping create_merge_mapping(std::span meshes); -VertexMapping create_merge_mapping(std::span meshes, double distance_epsilon); +VertexMapping create_merge_mapping(std::span meshes); +VertexMapping create_merge_mapping(std::span meshes, double distance_epsilon); } diff --git a/src/terrainmerger/pch.h b/src/terrainmerger/pch.h index c8fecce..43119b2 100644 --- a/src/terrainmerger/pch.h +++ b/src/terrainmerger/pch.h @@ -13,4 +13,4 @@ #include #include "cgal.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" diff --git a/src/terrainmerger/simplify.cpp b/src/terrainmerger/simplify.cpp index d49e36f..97d66c6 100644 --- a/src/terrainmerger/simplify.cpp +++ b/src/terrainmerger/simplify.cpp @@ -20,6 +20,7 @@ #include "simplify.h" #include "uv_map.h" #include "validate.h" +#include "mesh/utils.h" using namespace simplify; @@ -117,8 +118,8 @@ static double measure_max_absolute_error(const SurfaceMesh &original, const Surf return error + bound_on_error; } -static radix::geometry::Aabb<3, double> calculate_bounds(const SurfaceMesh &mesh) { - radix::geometry::Aabb<3, double> bounds; +static radix::geometry::Aabb3d calculate_bounds(const SurfaceMesh &mesh) { + radix::geometry::Aabb3d bounds; bounds.min = glm::dvec3(std::numeric_limits::infinity()); bounds.max = glm::dvec3(-std::numeric_limits::infinity()); @@ -449,7 +450,7 @@ static size_t _simplify_mesh( throw std::invalid_argument("invalid algorithm specified"); } -Result simplify::simplify_mesh(const TerrainMesh &mesh, std::span stop_conditions, Options options) { +Result simplify::simplify_mesh(const SimpleMesh&mesh, std::span stop_conditions, Options options) { // simplification fails with large numerical values so we normalize the values here. // EPECK is way too slow const size_t vertex_count = mesh.positions.size(); @@ -458,7 +459,7 @@ Result simplify::simplify_mesh(const TerrainMesh &mesh, std::span(vertex_count); } - TerrainMesh normalized_mesh = mesh; + SimpleMesh normalized_mesh = mesh; for (size_t i = 0; i < vertex_count; i++) { const glm::vec3 normalized_position = mesh.positions[i] - average_position; normalized_mesh.positions[i] = normalized_position; @@ -483,7 +484,7 @@ Result simplify::simplify_mesh(const TerrainMesh &mesh, std::span AttachedUvPropertyMa cv::Mat simplify_texture(const cv::Mat& texture, glm::uvec2 target_resolution); -void simplify_mesh_texture(TerrainMesh& mesh, glm::uvec2 target_resolution); +void simplify_mesh_texture(SimpleMesh& mesh, glm::uvec2 target_resolution); enum class Algorithm { GarlandHeckbert, @@ -43,12 +43,12 @@ struct Options { }; struct Result { - TerrainMesh mesh; + SimpleMesh mesh; double max_absolute_error; }; -Result simplify_mesh(const TerrainMesh &mesh, std::span stop_conditions, Options options = Options()); -inline Result simplify_mesh(const TerrainMesh &mesh, const StopCondition& stop_condition, Options options = Options()) { +Result simplify_mesh(const SimpleMesh &mesh, std::span stop_conditions, Options options = Options()); +inline Result simplify_mesh(const SimpleMesh &mesh, const StopCondition& stop_condition, Options options = Options()) { return simplify_mesh(mesh, std::span{&stop_condition, 1}, options); } } diff --git a/src/terrainmerger/uv_map.cpp b/src/terrainmerger/uv_map.cpp index e2ceade..8279107 100644 --- a/src/terrainmerger/uv_map.cpp +++ b/src/terrainmerger/uv_map.cpp @@ -98,7 +98,7 @@ tl::expected uv_map::parameterize_mesh(SurfaceMe return uv_uhm; } -tl::expected uv_map::parameterize_mesh(const TerrainMesh &mesh, Algorithm algorithm, Border border) { +tl::expected uv_map::parameterize_mesh(const SimpleMesh &mesh, Algorithm algorithm, Border border) { SurfaceMesh cgal_mesh = convert::mesh2cgal(mesh); return parameterize_mesh(cgal_mesh, algorithm, border); } @@ -160,12 +160,12 @@ static void warp_triangle(const cv::Mat &source_image, cv::Mat &target_image, st // TODO: reproject triangles Texture uv_map::merge_textures( - const std::span original_meshes, - const TerrainMesh &merged_mesh, + const std::span original_meshes, + const SimpleMesh &merged_mesh, const merge::VertexMapping &mapping, const UvMap &uv_map, const glm::uvec2 merged_texture_size) { - for (const TerrainMesh& mesh : original_meshes) { + for (const SimpleMesh& mesh : original_meshes) { assert(mesh.has_texture()); } @@ -182,7 +182,7 @@ Texture uv_map::merge_textures( const merge::TriangleInMesh source_mesh_and_triangle = mapping.find_source_triangle(mapped_triangle); const size_t source_mesh_index = source_mesh_and_triangle.mesh_index; - const TerrainMesh &source_mesh = original_meshes[source_mesh_index]; + const SimpleMesh &source_mesh = original_meshes[source_mesh_index]; const glm::uvec3 source_triangle = source_mesh_and_triangle.triangle; std::array source_uv_triangle; diff --git a/src/terrainmerger/uv_map.h b/src/terrainmerger/uv_map.h index 1cfd905..ec6c8f4 100644 --- a/src/terrainmerger/uv_map.h +++ b/src/terrainmerger/uv_map.h @@ -54,13 +54,13 @@ tl::expected parameterize_mesh( Border border); tl::expected parameterize_mesh( - const TerrainMesh &mesh, + const SimpleMesh &mesh, Algorithm algorithm, Border border); Texture merge_textures( - const std::span original_meshes, - const TerrainMesh& merged_mesh, + const std::span original_meshes, + const SimpleMesh& merged_mesh, const merge::VertexMapping &mapping, const UvMap& uv_map, const glm::uvec2 merged_texture_size); diff --git a/unittests/terrainbuilder/mesh.cpp b/unittests/terrainbuilder/mesh.cpp index 72f4eb4..ff8899d 100644 --- a/unittests/terrainbuilder/mesh.cpp +++ b/unittests/terrainbuilder/mesh.cpp @@ -32,13 +32,14 @@ #include "../catch2_helpers.h" #include "Dataset.h" #include "merge.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" #include "mesh_builder.h" +#include "mesh/io.h" +#include "mesh/utils.h" #include "octree/id.h" #include "octree/space.h" #include "srs.h" -#include "mesh/io.h" using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; using Point3 = Kernel::Point_3; @@ -56,7 +57,7 @@ Point3 glm2cgal(glm::dvec3 point) { return Point3(point[0], point[1], point[2]); } -SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { +SurfaceMesh mesh2cgal(const SimpleMesh &mesh) { SurfaceMesh cgal_mesh; for (const glm::dvec3 &position : mesh.positions) { @@ -76,7 +77,7 @@ SurfaceMesh mesh2cgal(const TerrainMesh &mesh) { return cgal_mesh; } -void check_mesh_basics(const TerrainMesh &mesh) { +void check_mesh_basics(const SimpleMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); CHECK(cgal_mesh.is_valid(true)); CHECK(CGAL::is_triangle_mesh(cgal_mesh)); @@ -84,7 +85,7 @@ void check_mesh_basics(const TerrainMesh &mesh) { CHECK_FALSE(CGAL::Polygon_mesh_processing::does_self_intersect(cgal_mesh)); } -void check_no_holes(const TerrainMesh &mesh) { +void check_no_holes(const SimpleMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); std::vector border_cycles; CGAL::Polygon_mesh_processing::extract_boundary_cycles(cgal_mesh, std::back_inserter(border_cycles)); @@ -92,7 +93,7 @@ void check_no_holes(const TerrainMesh &mesh) { CHECK(nb_holes == 0); } -size_t count_connected_components(const TerrainMesh &mesh) { +size_t count_connected_components(const SimpleMesh &mesh) { const SurfaceMesh cgal_mesh = mesh2cgal(mesh); using CcMap = CGAL::Unique_hash_map; using CcPropertyMap = boost::associative_property_map; @@ -103,7 +104,7 @@ size_t count_connected_components(const TerrainMesh &mesh) { return num; } -void check_uvs(const TerrainMesh &mesh) { +void check_uvs(const SimpleMesh &mesh) { REQUIRE(mesh.uvs.size() == mesh.positions.size()); for (const glm::dvec2 uv : mesh.uvs) { @@ -112,7 +113,7 @@ void check_uvs(const TerrainMesh &mesh) { } } -void check_non_empty(const TerrainMesh &mesh) { +void check_non_empty(const SimpleMesh &mesh) { REQUIRE(mesh.positions.size() > 0); REQUIRE(mesh.triangles.size() > 0); } @@ -227,7 +228,7 @@ TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuil if (!result) { FAIL("Failed to build mesh: " << result.error()); } - const TerrainMesh mesh = result.value(); + const SimpleMesh mesh = result.value(); SECTION("Basic mesh properties") { check_non_empty(mesh); @@ -280,7 +281,7 @@ TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuil filtered_triangles.push_back(tri); } } - TerrainMesh inside_flat_mesh; + SimpleMesh inside_flat_mesh; inside_flat_mesh.positions = flat_positions_in_ecef_srs; inside_flat_mesh.triangles = filtered_triangles; @@ -310,7 +311,7 @@ TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); - std::vector node_meshes; + std::vector node_meshes; for (const octree::Id &node : nodes) { const octree::Bounds node_bounds = space.get_node_bounds(node); radix::tile::SrsBounds output_texture_bounds; @@ -322,12 +323,12 @@ TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { if (!result.has_value()) { continue; } - const TerrainMesh mesh = result.value(); + const SimpleMesh mesh = result.value(); node_meshes.push_back(mesh); } CHECK(node_meshes.size() >= 3); - const TerrainMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-6); + const SimpleMesh merged_mesh = merge::merge_meshes(node_meshes, 1e-6); check_mesh_basics(merged_mesh); check_non_empty(merged_mesh); check_no_holes(merged_mesh); diff --git a/unittests/terrainbuilder/mesh_io.cpp b/unittests/terrainbuilder/mesh_io.cpp index 928d4d2..4670f13 100644 --- a/unittests/terrainbuilder/mesh_io.cpp +++ b/unittests/terrainbuilder/mesh_io.cpp @@ -18,6 +18,7 @@ *****************************************************************************/ #include +#include #include "../catch2_helpers.h" #include "mesh/io.h" @@ -49,7 +50,7 @@ bool mat_equals(const cv::Mat mat1, const cv::Mat mat2) { TEST_CASE("io roundtrip") { for (const auto& format : {"glb", "gltf"}) { DYNAMIC_SECTION(format) { - TerrainMesh mesh; + SimpleMesh mesh; mesh.positions.push_back(glm::dvec3(0, 0, 0)); mesh.positions.push_back(glm::dvec3(1, 0, 0)); @@ -67,19 +68,19 @@ TEST_CASE("io roundtrip") { mesh.texture = cv::Mat3b(100, 100); cv::randu(*mesh.texture, cv::Scalar(0, 0, 0), cv::Scalar(256, 256, 256)); - const std::filesystem::path mesh_path = fmt::format("./unittest_tiles/mesh.{}", format); + const std::filesystem::path mesh_path = fmt::format("./unittests/output/mesh.{}", format); std::filesystem::remove(mesh_path); REQUIRE(!std::filesystem::exists(mesh_path)); - io::save_mesh_to_path(mesh_path, mesh, io::SaveOptions {.texture_format = ".png"}); + mesh::io::save_to_path(mesh, mesh_path, mesh::io::SaveOptions{.texture_format = ".png"}); REQUIRE(std::filesystem::exists(mesh_path)); - const tl::expected result = io::load_mesh_from_path(mesh_path); + const tl::expected result = mesh::io::load_from_path(mesh_path); if (!result.has_value()) { FAIL(result.error().description()); } std::filesystem::remove(mesh_path); - const TerrainMesh roundtrip_mesh = result.value(); + const SimpleMesh roundtrip_mesh = result.value(); REQUIRE(roundtrip_mesh.positions == mesh.positions); REQUIRE(roundtrip_mesh.uvs == mesh.uvs); REQUIRE(roundtrip_mesh.triangles == mesh.triangles); @@ -90,9 +91,9 @@ TEST_CASE("io roundtrip") { } TEST_CASE("io roundtrip high precision") { - for (const auto& format : {"tile"}) { + for (const auto& format : {"terrain"}) { DYNAMIC_SECTION(format) { - TerrainMesh mesh; + SimpleMesh mesh; const double pi = std::numbers::pi_v; REQUIRE((double)(float)pi != pi); @@ -110,19 +111,19 @@ TEST_CASE("io roundtrip high precision") { mesh.texture = cv::Mat3b(100, 100); cv::randu(*mesh.texture, cv::Scalar(0, 0, 0), cv::Scalar(256, 256, 256)); - const std::filesystem::path mesh_path = fmt::format("./unittest_tiles/mesh.{}", format); + const std::filesystem::path mesh_path = fmt::format("./unittests/output/mesh.{}", format); std::filesystem::remove(mesh_path); REQUIRE(!std::filesystem::exists(mesh_path)); - io::save_mesh_to_path(mesh_path, mesh, io::SaveOptions {.texture_format = ".png"}); + mesh::io::save_to_path(mesh, mesh_path, mesh::io::SaveOptions{.texture_format = ".png"}); REQUIRE(std::filesystem::exists(mesh_path)); - const tl::expected result = io::load_mesh_from_path(mesh_path); + const tl::expected result = mesh::io::load_from_path(mesh_path); if (!result.has_value()) { FAIL(result.error().description()); } std::filesystem::remove(mesh_path); - const TerrainMesh roundtrip_mesh = result.value(); + const SimpleMesh roundtrip_mesh = result.value(); REQUIRE(roundtrip_mesh.positions == mesh.positions); REQUIRE(roundtrip_mesh.uvs == mesh.uvs); REQUIRE(roundtrip_mesh.triangles == mesh.triangles); @@ -133,9 +134,9 @@ TEST_CASE("io roundtrip high precision") { } TEST_CASE("io roundtrip no texture") { - for (const auto &format : {"gltf", "glb", "tile"}) { + for (const auto &format : {"gltf", "glb", "terrain"}) { DYNAMIC_SECTION(format) { - TerrainMesh mesh; + SimpleMesh mesh; const double pi = std::numbers::pi_v; REQUIRE((double)(float)pi != pi); @@ -153,19 +154,19 @@ TEST_CASE("io roundtrip no texture") { mesh.uvs.push_back(glm::dvec2(0, 1)); mesh.uvs.push_back(glm::dvec2(1, 1)); - const std::filesystem::path mesh_path = fmt::format("./unittest_tiles/mesh.{}", format); + const std::filesystem::path mesh_path = fmt::format("./unittests/output/mesh.{}", format); std::filesystem::remove(mesh_path); REQUIRE(!std::filesystem::exists(mesh_path)); - io::save_mesh_to_path(mesh_path, mesh); + mesh::io::save_to_path(mesh, mesh_path); REQUIRE(std::filesystem::exists(mesh_path)); - const tl::expected result = io::load_mesh_from_path(mesh_path); + const tl::expected result = mesh::io::load_from_path(mesh_path); if (!result.has_value()) { FAIL(result.error().description()); } // std::filesystem::remove(mesh_path); - const TerrainMesh roundtrip_mesh = result.value(); + const SimpleMesh roundtrip_mesh = result.value(); REQUIRE(roundtrip_mesh.positions == mesh.positions); REQUIRE(roundtrip_mesh.uvs == mesh.uvs); REQUIRE(roundtrip_mesh.triangles == mesh.triangles); @@ -175,9 +176,9 @@ TEST_CASE("io roundtrip no texture") { } TEST_CASE("io roundtrip no texture and uvs") { - for (const auto &format : {"gltf", "glb", "tile"}) { + for (const auto &format : {"gltf", "glb", "terrain"}) { DYNAMIC_SECTION(format) { - TerrainMesh mesh; + SimpleMesh mesh; const double pi = std::numbers::pi_v; REQUIRE((double)(float)pi != pi); @@ -190,19 +191,19 @@ TEST_CASE("io roundtrip no texture and uvs") { mesh.triangles.push_back(glm::uvec3(0, 2, 1)); mesh.triangles.push_back(glm::uvec3(1, 2, 3)); - const std::filesystem::path mesh_path = fmt::format("./unittest_tiles/mesh.{}", format); + const std::filesystem::path mesh_path = fmt::format("./unittests/output/mesh.{}", format); std::filesystem::remove(mesh_path); REQUIRE(!std::filesystem::exists(mesh_path)); - io::save_mesh_to_path(mesh_path, mesh); + mesh::io::save_to_path(mesh, mesh_path); REQUIRE(std::filesystem::exists(mesh_path)); - const tl::expected result = io::load_mesh_from_path(mesh_path); + const tl::expected result = mesh::io::load_from_path(mesh_path); if (!result.has_value()) { FAIL(result.error().description()); } std::filesystem::remove(mesh_path); - const TerrainMesh roundtrip_mesh = result.value(); + const SimpleMesh roundtrip_mesh = result.value(); REQUIRE(roundtrip_mesh.positions == mesh.positions); REQUIRE(!roundtrip_mesh.has_uvs()); REQUIRE(roundtrip_mesh.triangles == mesh.triangles); diff --git a/unittests/terrainbuilder/texture.cpp b/unittests/terrainbuilder/texture.cpp index f4bc25d..d212a7a 100644 --- a/unittests/terrainbuilder/texture.cpp +++ b/unittests/terrainbuilder/texture.cpp @@ -29,7 +29,7 @@ #include "ctb/Grid.hpp" #include "srs.h" -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" #include "texture_assembler.h" TEST_CASE("estimate_zoom_level", "[terrainbuilder]") { diff --git a/unittests/terrainmerger/convert.cpp b/unittests/terrainmerger/convert.cpp index 9b6db0b..446d185 100644 --- a/unittests/terrainmerger/convert.cpp +++ b/unittests/terrainmerger/convert.cpp @@ -5,7 +5,7 @@ #include "cgal.h" TEST_CASE("convert rountrip keeps precision") { - TerrainMesh mesh; + SimpleMesh mesh; const double pi = std::numbers::pi_v; REQUIRE((double)(float)pi != pi); @@ -17,7 +17,7 @@ TEST_CASE("convert rountrip keeps precision") { mesh.triangles.push_back(glm::uvec3(0, 2, 1)); const SurfaceMesh cgal_mesh = convert::mesh2cgal(mesh); - TerrainMesh roundtrip_mesh = convert::cgal2mesh(cgal_mesh); + SimpleMesh roundtrip_mesh = convert::cgal2mesh(cgal_mesh); sort_and_normalize_triangles(mesh.triangles); sort_and_normalize_triangles(roundtrip_mesh.triangles); diff --git a/unittests/terrainmerger/merge.cpp b/unittests/terrainmerger/merge.cpp index bb0db93..55d6da3 100644 --- a/unittests/terrainmerger/merge.cpp +++ b/unittests/terrainmerger/merge.cpp @@ -23,23 +23,23 @@ TEST_CASE("terrainmerger") { SECTION("two tris") { - TerrainMesh mesh1; + SimpleMesh mesh1; mesh1.positions.push_back(glm::dvec3(0, 0, 0)); mesh1.positions.push_back(glm::dvec3(1, 1, 0)); mesh1.positions.push_back(glm::dvec3(1, 0, 0)); mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); - TerrainMesh mesh2; + SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(1, 0, 0)); mesh2.positions.push_back(glm::dvec3(1, 1, 0)); mesh2.positions.push_back(glm::dvec3(0, 1, 0)); mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - std::array meshes = { std::move(mesh1), std::move(mesh2) }; + std::array meshes = { std::move(mesh1), std::move(mesh2) }; - TerrainMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = merge::merge_meshes(meshes, 0.1); - TerrainMesh expected; + SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); expected.positions.push_back(glm::dvec3(1, 1, 0)); expected.positions.push_back(glm::dvec3(1, 0, 0)); @@ -56,7 +56,7 @@ TEST_CASE("terrainmerger") { } SECTION("two tris with uvs") { - TerrainMesh mesh1; + SimpleMesh mesh1; mesh1.positions.push_back(glm::dvec3(0, 0, 0)); mesh1.positions.push_back(glm::dvec3(1, 1, 0)); mesh1.positions.push_back(glm::dvec3(1, 0, 0)); @@ -65,7 +65,7 @@ TEST_CASE("terrainmerger") { mesh1.uvs.push_back(glm::dvec2(1, 0)); mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); - TerrainMesh mesh2; + SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(1, 0, 0)); mesh2.positions.push_back(glm::dvec3(1, 1, 0)); mesh2.positions.push_back(glm::dvec3(0, 1, 0)); @@ -74,11 +74,11 @@ TEST_CASE("terrainmerger") { mesh2.uvs.push_back(glm::dvec2(0, 1)); mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - std::array meshes = {std::move(mesh1), std::move(mesh2)}; + std::array meshes = {std::move(mesh1), std::move(mesh2)}; - TerrainMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = merge::merge_meshes(meshes, 0.1); - TerrainMesh expected; + SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); expected.positions.push_back(glm::dvec3(1, 1, 0)); expected.positions.push_back(glm::dvec3(1, 0, 0)); @@ -99,7 +99,7 @@ TEST_CASE("terrainmerger") { } SECTION("distance epsilon") { - TerrainMesh mesh1; + SimpleMesh mesh1; mesh1.positions.push_back(glm::dvec3(0, 0, 0)); mesh1.positions.push_back(glm::dvec3(1, 0, 0)); mesh1.positions.push_back(glm::dvec3(0, 1, 0)); @@ -107,7 +107,7 @@ TEST_CASE("terrainmerger") { mesh1.triangles.push_back(glm::uvec3(0, 2, 1)); mesh1.triangles.push_back(glm::uvec3(1, 2, 3)); - TerrainMesh mesh2; + SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(0.91, 0, 0)); mesh2.positions.push_back(glm::dvec3(2, 0, 0)); mesh2.positions.push_back(glm::dvec3(1.11, 1, 0)); @@ -115,11 +115,11 @@ TEST_CASE("terrainmerger") { mesh2.triangles.push_back(glm::uvec3(0, 2, 1)); mesh2.triangles.push_back(glm::uvec3(1, 2, 3)); - std::array meshes = {std::move(mesh1), std::move(mesh2)}; + std::array meshes = {std::move(mesh1), std::move(mesh2)}; - TerrainMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = merge::merge_meshes(meshes, 0.1); - TerrainMesh expected; + SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); expected.positions.push_back(glm::dvec3(0.91, 0, 0)); expected.positions.push_back(glm::dvec3(0, 1, 0)); From 16d51945233a352cb300e778695b68b64053323c Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 14 May 2025 01:26:59 +0200 Subject: [PATCH 044/122] Move octree classes to terrainlib --- src/CMakeLists.txt | 8 +++++--- src/{terrainbuilder => terrainlib}/octree/id.h | 3 +-- src/{terrainbuilder => terrainlib}/octree/space.h | 0 src/{terrainbuilder => terrainlib}/octree/storage.h | 0 src/{terrainbuilder => terrainlib}/octree/utils.h | 0 5 files changed, 6 insertions(+), 5 deletions(-) rename src/{terrainbuilder => terrainlib}/octree/id.h (99%) rename src/{terrainbuilder => terrainlib}/octree/space.h (100%) rename src/{terrainbuilder => terrainlib}/octree/storage.h (100%) rename src/{terrainbuilder => terrainlib}/octree/utils.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0e86db..85ceefb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,11 @@ add_library(terrainlib terrainlib/mesh/SimpleMesh.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp + terrainlib/octree/id.h + terrainlib/octree/storage.h + terrainlib/octree/space.h + terrainlib/octree/utils.h + terrainlib/Dataset.h terrainlib/Dataset.cpp terrainlib/init.h terrainlib/init.cpp terrainlib/log.h terrainlib/log.cpp @@ -100,9 +105,6 @@ add_library(terrainbuilderlib terrainbuilder/raster.h terrainbuilder/terrainbuilder.h terrainbuilder/terrainbuilder.cpp - terrainbuilder/octree/id.h - terrainbuilder/octree/storage.h - terrainbuilder/octree/space.h ) target_include_directories(terrainbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainbuilder) target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) diff --git a/src/terrainbuilder/octree/id.h b/src/terrainlib/octree/id.h similarity index 99% rename from src/terrainbuilder/octree/id.h rename to src/terrainlib/octree/id.h index 9961e0b..1ad64ee 100644 --- a/src/terrainbuilder/octree/id.h +++ b/src/terrainlib/octree/id.h @@ -170,7 +170,6 @@ class Id { } // namespace octree -#include #include template <> struct fmt::formatter { @@ -192,7 +191,7 @@ struct fmt::formatter { #include #include -namespace octree{ +namespace octree { inline std::string to_string(const octree::Id &id) { return fmt::format("{}", id); } diff --git a/src/terrainbuilder/octree/space.h b/src/terrainlib/octree/space.h similarity index 100% rename from src/terrainbuilder/octree/space.h rename to src/terrainlib/octree/space.h diff --git a/src/terrainbuilder/octree/storage.h b/src/terrainlib/octree/storage.h similarity index 100% rename from src/terrainbuilder/octree/storage.h rename to src/terrainlib/octree/storage.h diff --git a/src/terrainbuilder/octree/utils.h b/src/terrainlib/octree/utils.h similarity index 100% rename from src/terrainbuilder/octree/utils.h rename to src/terrainlib/octree/utils.h From 1c1a1296dc0e003aec9733eae80f7b867fe36de0 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 14 May 2025 01:28:57 +0200 Subject: [PATCH 045/122] Use short nested namespaces --- src/terrainlib/mesh/io/error.h | 6 ++---- src/terrainlib/mesh/io/gltf.cpp | 8 ++------ src/terrainlib/mesh/io/gltf.h | 8 ++------ src/terrainlib/mesh/io/options.h | 7 +++---- src/terrainlib/mesh/io/terrain.cpp | 8 ++------ src/terrainlib/mesh/io/terrain.h | 8 ++------ src/terrainlib/mesh/io/utils.cpp | 8 ++------ src/terrainlib/mesh/io/utils.h | 8 ++------ 8 files changed, 17 insertions(+), 44 deletions(-) diff --git a/src/terrainlib/mesh/io/error.h b/src/terrainlib/mesh/io/error.h index ba6d55d..9c208ad 100644 --- a/src/terrainlib/mesh/io/error.h +++ b/src/terrainlib/mesh/io/error.h @@ -2,8 +2,7 @@ #include -namespace mesh { -namespace io { +namespace mesh::io { enum class LoadMeshErrorKind { UnsupportedFormat, @@ -98,5 +97,4 @@ class SaveMeshError { SaveMeshErrorKind kind; }; -} // namespace io -} // namespace mesh +} // namespace mesh::io diff --git a/src/terrainlib/mesh/io/gltf.cpp b/src/terrainlib/mesh/io/gltf.cpp index b6b867c..868941a 100644 --- a/src/terrainlib/mesh/io/gltf.cpp +++ b/src/terrainlib/mesh/io/gltf.cpp @@ -16,9 +16,7 @@ using namespace mesh::io::utils; -namespace mesh { -namespace io { -namespace gltf { +namespace mesh::io::gltf { namespace { const int GL_NEAREST = 0x2600; @@ -697,6 +695,4 @@ tl::expected load_from_path(const std::filesystem::pa return load_mesh_from_raw(*raw_mesh, options); } -} // namespace gltf -} // namespace io -} // namespace mesh +} // namespace mesh::io::gltf diff --git a/src/terrainlib/mesh/io/gltf.h b/src/terrainlib/mesh/io/gltf.h index 9be06b0..6075738 100644 --- a/src/terrainlib/mesh/io/gltf.h +++ b/src/terrainlib/mesh/io/gltf.h @@ -11,9 +11,7 @@ #include "mesh/io/error.h" #include "mesh/io/options.h" -namespace mesh { -namespace io { -namespace gltf { +namespace mesh::io::gltf { using RawMesh = std::unique_ptr; @@ -32,6 +30,4 @@ tl::expected save_to_path( tl::expected load_raw_from_path(const std::filesystem::path &path); -} // namespace gltf -} // namespace io -} // namespace mesh +} // namespace mesh::io::gltf diff --git a/src/terrainlib/mesh/io/options.h b/src/terrainlib/mesh/io/options.h index 559a365..e7c2ec2 100644 --- a/src/terrainlib/mesh/io/options.h +++ b/src/terrainlib/mesh/io/options.h @@ -3,8 +3,8 @@ #include #include -namespace mesh { -namespace io { + +namespace mesh::io { struct LoadOptions { }; @@ -15,5 +15,4 @@ struct SaveOptions { std::unordered_map metadata = {}; }; -} // namespace io -} // namespace mesh +} // namespace mesh::io diff --git a/src/terrainlib/mesh/io/terrain.cpp b/src/terrainlib/mesh/io/terrain.cpp index da67cc4..610cf8a 100644 --- a/src/terrainlib/mesh/io/terrain.cpp +++ b/src/terrainlib/mesh/io/terrain.cpp @@ -6,9 +6,7 @@ using namespace mesh::io::utils; -namespace mesh { -namespace io { -namespace terrain { +namespace mesh::io::terrain { namespace { tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path) { @@ -142,6 +140,4 @@ tl::expected save_to_path(const SimpleMesh &mesh, const std return write_bytes_to_path(bytes, path); } -} // namespace terrain -} // namespace io -} // namespace mesh +} // namespace mesh::io::terrain diff --git a/src/terrainlib/mesh/io/terrain.h b/src/terrainlib/mesh/io/terrain.h index 03e2250..38e8526 100644 --- a/src/terrainlib/mesh/io/terrain.h +++ b/src/terrainlib/mesh/io/terrain.h @@ -10,9 +10,7 @@ #include "mesh/io/options.h" #include "mesh/io/texture.h" -namespace mesh { -namespace io { -namespace terrain { +namespace mesh::io::terrain { tl::expected load_from_path(const std::filesystem::path &path, const LoadOptions &options = {}); tl::expected load_from_buffer(const std::span buffer, const LoadOptions &options = {}); @@ -20,9 +18,7 @@ tl::expected load_from_buffer(const std::span save_to_path(const SimpleMesh &mesh, const std::filesystem::path &path, const SaveOptions &options = {}); tl::expected, SaveMeshError> save_to_buffer(const SimpleMesh &mesh, const SaveOptions &options = {}); -} // namespace terrain -} // namespace io -} // namespace mesh +} // namespace mesh::io::terrain // custom serialization namespace zpp::bits { diff --git a/src/terrainlib/mesh/io/utils.cpp b/src/terrainlib/mesh/io/utils.cpp index d392903..97cd047 100644 --- a/src/terrainlib/mesh/io/utils.cpp +++ b/src/terrainlib/mesh/io/utils.cpp @@ -1,8 +1,6 @@ #include "mesh/io/utils.h" -namespace mesh { -namespace io { -namespace utils { +namespace mesh::io::utils { std::filesystem::path create_parent_directories(const std::filesystem::path &path) { const std::filesystem::path parent_path = std::filesystem::absolute(path).parent_path(); @@ -10,6 +8,4 @@ std::filesystem::path create_parent_directories(const std::filesystem::path &pat return parent_path; } -} // namespace utils -} // namespace io -} // namespace mesh +} // namespace mesh::io::utils diff --git a/src/terrainlib/mesh/io/utils.h b/src/terrainlib/mesh/io/utils.h index d93bb11..2b5cf8c 100644 --- a/src/terrainlib/mesh/io/utils.h +++ b/src/terrainlib/mesh/io/utils.h @@ -2,12 +2,8 @@ #include -namespace mesh { -namespace io { -namespace utils { +namespace mesh::io::utils { std::filesystem::path create_parent_directories(const std::filesystem::path &path); -} // namespace utils -} // namespace io -} // namespace mesh +} // namespace mesh::io::utils From 15cdb05326530f93af4a0974545869f07a460e15 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Wed, 21 May 2025 10:26:32 +0200 Subject: [PATCH 046/122] Move project into subfolder in preparation for integration into monorepo. --- src/{ => browser}/CMakeLists.txt | 1 + src/{ => browser}/core/Application.cpp | 240 ++++++++++++------ src/{ => browser}/core/Application.h | 8 +- src/{ => browser}/core/Buffer.cpp | 0 src/{ => browser}/core/Buffer.h | 0 src/{ => browser}/core/Camera.cpp | 4 +- src/{ => browser}/core/Camera.h | 0 src/{ => browser}/core/geometry/UnitCube.h | 0 src/{ => browser}/core/octree/id.h | 0 .../octree/rendering/OctreeRenderManager.cpp} | 154 +---------- .../octree/rendering/OctreeRenderManager.h | 47 ++++ src/browser/core/octree/space.h | 125 +++++++++ src/{ => browser}/core/octree/storage.h | 0 .../core/shader/GLUniformAbstractions.h | 0 src/{ => browser}/core/shader/Shader.cpp | 0 src/{ => browser}/core/shader/Shader.h | 0 .../core/shader/ShaderProgram.cpp | 0 src/{ => browser}/core/shader/ShaderProgram.h | 0 src/{ => browser}/core/shader/Uniform.h | 0 src/{ => browser}/core/window/Window.cpp | 0 src/{ => browser}/core/window/Window.h | 0 src/{ => browser}/main.cpp | 0 src/{ => browser}/res/CMakeLists.txt | 0 .../res/shaders/octree_lines.frag | 0 .../res/shaders/octree_lines.vert | 0 src/{ => browser}/utils/log/Log.cpp | 0 src/{ => browser}/utils/log/Log.h | 0 27 files changed, 357 insertions(+), 222 deletions(-) rename src/{ => browser}/CMakeLists.txt (98%) rename src/{ => browser}/core/Application.cpp (73%) rename src/{ => browser}/core/Application.h (84%) rename src/{ => browser}/core/Buffer.cpp (100%) rename src/{ => browser}/core/Buffer.h (100%) rename src/{ => browser}/core/Camera.cpp (94%) rename src/{ => browser}/core/Camera.h (100%) rename src/{ => browser}/core/geometry/UnitCube.h (100%) rename src/{ => browser}/core/octree/id.h (100%) rename src/{core/octree/space.h => browser/core/octree/rendering/OctreeRenderManager.cpp} (52%) create mode 100644 src/browser/core/octree/rendering/OctreeRenderManager.h create mode 100644 src/browser/core/octree/space.h rename src/{ => browser}/core/octree/storage.h (100%) rename src/{ => browser}/core/shader/GLUniformAbstractions.h (100%) rename src/{ => browser}/core/shader/Shader.cpp (100%) rename src/{ => browser}/core/shader/Shader.h (100%) rename src/{ => browser}/core/shader/ShaderProgram.cpp (100%) rename src/{ => browser}/core/shader/ShaderProgram.h (100%) rename src/{ => browser}/core/shader/Uniform.h (100%) rename src/{ => browser}/core/window/Window.cpp (100%) rename src/{ => browser}/core/window/Window.h (100%) rename src/{ => browser}/main.cpp (100%) rename src/{ => browser}/res/CMakeLists.txt (100%) rename src/{ => browser}/res/shaders/octree_lines.frag (100%) rename src/{ => browser}/res/shaders/octree_lines.vert (100%) rename src/{ => browser}/utils/log/Log.cpp (100%) rename src/{ => browser}/utils/log/Log.h (100%) diff --git a/src/CMakeLists.txt b/src/browser/CMakeLists.txt similarity index 98% rename from src/CMakeLists.txt rename to src/browser/CMakeLists.txt index 611b6c6..e6b1e2d 100644 --- a/src/CMakeLists.txt +++ b/src/browser/CMakeLists.txt @@ -134,6 +134,7 @@ add_executable(alpenite-browser core/octree/id.h core/octree/space.h + "core/octree/rendering/OctreeRenderManager.cpp" ) target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog radix imgui) target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/core/Application.cpp b/src/browser/core/Application.cpp similarity index 73% rename from src/core/Application.cpp rename to src/browser/core/Application.cpp index 9e0fb75..a870347 100644 --- a/src/core/Application.cpp +++ b/src/browser/core/Application.cpp @@ -16,6 +16,7 @@ #include "Camera.h" #include "geometry/UnitCube.h" #include "octree/space.h" +#include "octree/rendering/OctreeRenderManager.h" CMRC_DECLARE(res); @@ -24,6 +25,8 @@ Application::Application(std::string title, int width, int height) m_nav_mode = false; + m_refining_factor = 0.5f; + WindowConfig c = { .width = 1280, .height = 720, @@ -66,31 +69,16 @@ void Application::run() { LOG_INFO("Setting up key event callbacks"); m_window->register_key_event(GLFW_PRESS, GLFW_KEY_TAB, [this]() { toggle_nav_mode(); - - ImGuiIO& io = ImGui::GetIO(); + }); + m_window->register_key_event(GLFW_PRESS, GLFW_KEY_ESCAPE, [this]() { if (m_nav_mode) { - LOG_DEBUG("Entering Nav Mode"); - - io.ConfigFlags |= ImGuiConfigFlags_NoMouse; - io.ConfigFlags |= ImGuiConfigFlags_NoKeyboard; - - m_window->set_capture_mouse(true); - m_window->clear_accumulated_cursor_delta(); + toggle_nav_mode(); } else { - LOG_DEBUG("Exiting Nav Mode"); - - io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; - io.ConfigFlags &= ~ImGuiConfigFlags_NoKeyboard; - - m_window->set_capture_mouse(false); + m_window->set_should_close(true); } }); - m_window->register_key_event(GLFW_PRESS, GLFW_KEY_ESCAPE, [this]() { - m_window->set_should_close(true); - }); - m_window->register_scroll_event([this](glm::dvec2 scroll) { float old_speed = m_movement_speed; @@ -154,7 +142,7 @@ void Application::run() { std::vector vertices = UnitCube::vertices(); std::vector indices = UnitCube::line_indices(); - octree::Space space = octree::Space::earth(); + octree::OctreeRenderManager octree_render_manager(octree::Space::earth()); unsigned int VAO; glGenVertexArrays(1, &VAO); @@ -214,6 +202,8 @@ void Application::run() { glDepthFunc(GL_LESS); glClearColor(0.f, 0.f, 0.f, 1.f); + m_last_draw_amount = 0; + while (!m_window->should_close()) { m_window->poll_events(); @@ -227,11 +217,13 @@ void Application::run() { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - draw_camera_settings_window(); + draw_settings_window(); update_camera(frame_delta_time, U_view); - octree::OctreeRenderIntent rendering_intent = space.generate_octree_render_intent(octree::Id::root(), m_camera->get_position(), false); + octree::OctreeRenderIntent rendering_intent = octree_render_manager.generate_octree_render_intent(octree::Id::root(), m_camera->get_position(), false, m_refining_factor); + + m_last_draw_amount = rendering_intent.instance_count; cube_instance_active_buffer.set_data(rendering_intent.instances_active); cube_instance_model_buffer.set_data(rendering_intent.instances_model_mats); @@ -341,6 +333,30 @@ Application::~Application() { void Application::toggle_nav_mode() { m_nav_mode = !m_nav_mode; + + ImGuiIO& io = ImGui::GetIO(); + + if (m_nav_mode && io.WantCaptureKeyboard) { + // When Dear ImGui wants to capture the keyboard, do not switch to nav mode + m_nav_mode = false; + } + + if (m_nav_mode) { + LOG_DEBUG("Entering Nav Mode"); + + io.ConfigFlags |= ImGuiConfigFlags_NoMouse; + io.ConfigFlags |= ImGuiConfigFlags_NoKeyboard; + + m_window->set_capture_mouse(true); + m_window->clear_accumulated_cursor_delta(); + } else { + LOG_DEBUG("Exiting Nav Mode"); + + io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; + io.ConfigFlags &= ~ImGuiConfigFlags_NoKeyboard; + + m_window->set_capture_mouse(false); + } } void Application::init_glad() { @@ -364,38 +380,57 @@ void Application::init_gl() { glViewport(0, 0, m_width, m_height); } -void Application::draw_camera_settings_window() { +void Application::draw_settings_window() { const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSize(ImVec2(200, 400), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Camera Settings")) { + float window_width = glm::clamp(main_viewport->Size.x * 0.2f, 250.0f, 350.0f); + float window_height = main_viewport->Size.y; + + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); + + ImGuiWindowFlags flags = 0; + flags |= ImGuiWindowFlags_NoMove; + flags |= ImGuiWindowFlags_NoResize; + + if (!ImGui::Begin("Settings", NULL, flags)) { ImGui::End(); return; } - if (ImGui::CollapsingHeader("Position")) { + draw_octree_settings_section(); + draw_camera_settings_section(); + + ImGui::End(); +} + +void Application::draw_camera_settings_section() { + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (!ImGui::CollapsingHeader("Camera")) { + return; + } + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Position")) { bool cam_pos_edited = false; glm::dvec3 cam_pos = m_camera->get_position(); + ImGui::PushItemWidth(-80); - float double_input_width = ImGui::CalcTextSize("#########.#########").x; - - ImGui::SetNextItemWidth(double_input_width); ImGui::InputDouble("X", &cam_pos.x); if (ImGui::IsItemEdited()) { cam_pos_edited = true; } - ImGui::SetNextItemWidth(double_input_width); + //ImGui::SetNextItemWidth(double_input_width); ImGui::InputDouble("Y", &cam_pos.y); if (ImGui::IsItemEdited()) { cam_pos_edited = true; } - ImGui::SetNextItemWidth(double_input_width); + //ImGui::SetNextItemWidth(double_input_width); ImGui::InputDouble("Z", &cam_pos.z); if (ImGui::IsItemEdited() || cam_pos_edited) { @@ -403,66 +438,64 @@ void Application::draw_camera_settings_window() { m_camera->set_position(cam_pos); } - } - if (ImGui::CollapsingHeader("Orientation")) { - ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); - if (ImGui::TreeNode("Euler Angles")) { - bool euler_edited = false; - glm::vec3 euler = glm::degrees(m_camera->get_rotation_euler()); + ImGui::TreePop(); + } - ImGui::SliderFloat("Pitch (X)", &euler.x, -180.0f, 180.0f); - if (ImGui::IsItemEdited()) { - euler_edited = true; - } + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Orientation")) { + ImGui::SeparatorText("Euler Angles"); + bool euler_edited = false; + glm::vec3 euler = glm::degrees(m_camera->get_rotation_euler()); - ImGui::SliderFloat("Yaw (Y)", &euler.y, -90.0f, 90.0f); - if (ImGui::IsItemEdited()) { - euler_edited = true; - } + ImGui::SliderFloat("Pitch (X)", &euler.x, -180.0f, 180.0f); + if (ImGui::IsItemEdited()) { + euler_edited = true; + } - ImGui::SliderFloat("Roll (Z)", &euler.z, -180.0f, 180.0f); - if (ImGui::IsItemEdited() || euler_edited) { - euler_edited = true; + ImGui::SliderFloat("Yaw (Y)", &euler.y, -90.0f, 90.0f); + if (ImGui::IsItemEdited()) { + euler_edited = true; + } - m_camera->set_rotation_euler(glm::radians(euler)); - } + ImGui::SliderFloat("Roll (Z)", &euler.z, -180.0f, 180.0f); + if (ImGui::IsItemEdited() || euler_edited) { + euler_edited = true; - ImGui::TreePop(); + m_camera->set_rotation_euler(glm::radians(euler)); } - ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); - if (ImGui::TreeNode("Quaternion")) { - bool quat_edited = false; - glm::quat quat = m_camera->get_rotation_quat(); - - ImGui::SliderFloat("X", &quat.x, -1.0, 1.0); - if (ImGui::IsItemEdited()) { - quat_edited = true; - } + ImGui::SeparatorText("Quaternion"); + bool quat_edited = false; + glm::quat quat = m_camera->get_rotation_quat(); - ImGui::SliderFloat("Y", &quat.y, -1.0, 1.0); - if (ImGui::IsItemEdited()) { - quat_edited = true; - } + ImGui::SliderFloat("X", &quat.x, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } - ImGui::SliderFloat("Z", &quat.z, -1.0, 1.0); - if (ImGui::IsItemEdited()) { - quat_edited = true; - } + ImGui::SliderFloat("Y", &quat.y, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } - ImGui::SliderFloat("W", &quat.w, -1.0, 1.0); - if (ImGui::IsItemEdited() || quat_edited) { - quat_edited = true; + ImGui::SliderFloat("Z", &quat.z, -1.0, 1.0); + if (ImGui::IsItemEdited()) { + quat_edited = true; + } - m_camera->set_rotation_quat(glm::normalize(quat)); - } + ImGui::SliderFloat("W", &quat.w, -1.0, 1.0); + if (ImGui::IsItemEdited() || quat_edited) { + quat_edited = true; - ImGui::TreePop(); + m_camera->set_rotation_quat(glm::normalize(quat)); } + + ImGui::TreePop(); } - if (ImGui::CollapsingHeader("Projection")) { + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Projection")) { float fov = m_camera->get_fov(); ImGui::SliderFloat("FOV", &fov, 0.1f, 120.0f); @@ -485,9 +518,62 @@ void Application::draw_camera_settings_window() { } ImGui::Separator(); + + ImGui::TreePop(); } +} - ImGui::End(); +void Application::draw_octree_settings_section() { + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (!ImGui::CollapsingHeader("Octree")) { + return; + } + + ImGui::PushItemWidth(-80); + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Stats")) { + + ImGui::Text("Nodes Rendered: %d", m_last_draw_amount); + + ImGui::TreePop(); + } + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Filtering")) { + + ImGui::TreePop(); + } + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("Refining")) { + std::array metrics = { "Distance", "Level", "DGNSDNFOL"}; + size_t selected_idx = 0; + + if (ImGui::BeginCombo("Metric", metrics[selected_idx].c_str())) { + for (int i = 0; i < metrics.size(); i++) { + bool selected = selected_idx == i; + + if (ImGui::Selectable(metrics[i].c_str(), selected)) { + selected_idx = i; + selected = true; + } + + if (selected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + + if (ImGui::SliderFloat("Factor", &m_refining_factor, 0.0f, 2.0f)) { + + } + + ImGui::TreePop(); + } + + ImGui::PopItemWidth(); } void Application::gl_debug_callback(GLenum source, GLenum type, diff --git a/src/core/Application.h b/src/browser/core/Application.h similarity index 84% rename from src/core/Application.h rename to src/browser/core/Application.h index 7e9b200..9ec3b55 100644 --- a/src/core/Application.h +++ b/src/browser/core/Application.h @@ -29,12 +29,18 @@ class Application { bool m_nav_mode; + float m_refining_factor; + + size_t m_last_draw_amount; + void toggle_nav_mode(); void init_glad(); void init_gl(); - void draw_camera_settings_window(); + void draw_settings_window(); + void draw_camera_settings_section(); + void draw_octree_settings_section(); static void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, diff --git a/src/core/Buffer.cpp b/src/browser/core/Buffer.cpp similarity index 100% rename from src/core/Buffer.cpp rename to src/browser/core/Buffer.cpp diff --git a/src/core/Buffer.h b/src/browser/core/Buffer.h similarity index 100% rename from src/core/Buffer.h rename to src/browser/core/Buffer.h diff --git a/src/core/Camera.cpp b/src/browser/core/Camera.cpp similarity index 94% rename from src/core/Camera.cpp rename to src/browser/core/Camera.cpp index 4992e90..6bcaee6 100644 --- a/src/core/Camera.cpp +++ b/src/browser/core/Camera.cpp @@ -145,8 +145,8 @@ glm::mat4 Camera::view_matrix() { void Camera::update_view_matrix() { if (!m_view_matrix_cache.has_value()) { glm::mat4 rotation = glm::mat4_cast(m_rotation); - glm::mat4 translation = glm::translate(glm::dmat4(1.0f), m_position); //TODO: Use camera re-centering to mitigate precision losses at large values - m_view_matrix_cache.emplace(glm::inverse(translation * rotation)); + //glm::mat4 translation = glm::translate(glm::dmat4(1.0f), m_position); //TODO: Use camera re-centering to mitigate precision losses at large values + m_view_matrix_cache.emplace(glm::inverse(/*translation */ rotation)); } } diff --git a/src/core/Camera.h b/src/browser/core/Camera.h similarity index 100% rename from src/core/Camera.h rename to src/browser/core/Camera.h diff --git a/src/core/geometry/UnitCube.h b/src/browser/core/geometry/UnitCube.h similarity index 100% rename from src/core/geometry/UnitCube.h rename to src/browser/core/geometry/UnitCube.h diff --git a/src/core/octree/id.h b/src/browser/core/octree/id.h similarity index 100% rename from src/core/octree/id.h rename to src/browser/core/octree/id.h diff --git a/src/core/octree/space.h b/src/browser/core/octree/rendering/OctreeRenderManager.cpp similarity index 52% rename from src/core/octree/space.h rename to src/browser/core/octree/rendering/OctreeRenderManager.cpp index 5a2a94d..d2e24bb 100644 --- a/src/core/octree/space.h +++ b/src/browser/core/octree/rendering/OctreeRenderManager.cpp @@ -1,139 +1,13 @@ -#pragma once - -#include - -#include "id.h" -#include -#include -#include +#include "OctreeRenderManager.h" namespace octree { -using Bounds = radix::geometry::Aabb3d; - -struct OctreeRenderIntent { - std::vector instances_active; - std::vector instances_model_mats; - size_t instance_count; - - std::optional min_scene_distance; - std::optional max_scene_distance; - - std::optional closest_node; -}; - -class Space { -public: - const Bounds bounds; - - static constexpr Space earth() { - const double max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) - const double extends = max_radius * 1.1; // TODO: how much padding do we want here - return Space(Bounds( - {-extends, -extends, -extends}, {extends, extends, extends})); - } - - std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { - // We don't want to recurse indefinitely if the bounds are empty. - const glm::dvec3 target_size = target_bounds.size(); - if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { - throw std::invalid_argument("target bounds cannot be empty"); - } - - const std::array corners = radix::geometry::corners(target_bounds); - - const Bounds root_bounds = get_node_bounds(root); - // Check if all points of the target bounds are inside the root bounds. - bool all_corners_inside_root = true; - for (const auto &corner : corners) { - if (!root_bounds.contains_inclusive(corner)) { - all_corners_inside_root = false; - break; - } - } - - if (!all_corners_inside_root) { - return std::nullopt; // Target bounds are outside the defined space. - } - - Id current_smallest_encompassing_node = root; - while (current_smallest_encompassing_node.has_children()) { - const std::array children = current_smallest_encompassing_node.children().value(); - std::optional next_smallest; - - for (const auto &child : children) { - const Bounds child_bounds = get_node_bounds(child); - bool all_corners_inside_child = true; - for (const auto &corner : corners) { - if (!child_bounds.contains_inclusive(corner)) { - all_corners_inside_child = false; - break; - } - } - - if (all_corners_inside_child) { - next_smallest = child; - break; // Found a child that fully contains the bounds, go deeper. - } - } - - if (next_smallest.has_value()) { - current_smallest_encompassing_node = next_smallest.value(); - } else { - break; // No child fully contains the bounds, so the current node is the smallest. - } - } - - return current_smallest_encompassing_node; - } - - std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { - assert(target_level <= Id::max_level()); - - Id current = root; - const Bounds root_bounds = this->get_node_bounds(current); - if (!root_bounds.contains_exclusive(point)) { - return std::nullopt; - } - - while (current.level() < target_level && current.has_children()) { - for (const auto& child : current.children().value()) { - const Bounds child_bounds = this->get_node_bounds(child); - if (child_bounds.contains_exclusive(point)) { - current = child; - break; - } - } - } - - return current; + OctreeRenderManager::OctreeRenderManager(octree::Space space) : m_space(space) { } - Bounds get_node_bounds(const Id &id) const { - const auto coords = id.coords(); - const uint32_t level = id.level(); - const uint32_t resolution = 1 << level; - - // Calculate the size of a node at this level - const glm::dvec3 bounds_size = bounds.size(); - const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); - - // Calculate the minimum point of the node - const glm::dvec3 min_bound = bounds.min; - const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; - - // Calculate the maximum point of the node - const glm::dvec3 node_max = node_min + node_size; - Bounds node_bounds; - node_bounds.min = node_min; - node_bounds.max = node_max; - return node_bounds; - } - - OctreeRenderIntent generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only) { - // Defines under which ratio between dist(cam, node_bbox_centre) / node_bbox_size the node is split + OctreeRenderIntent OctreeRenderManager::generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only, float refining_ratio = 1.0f) { + // refining_ratio defines under which ratio between dist(cam, node_bbox_centre) / node_bbox_size the node is split // I.e.: dist = 2000 and node_bbox_size = 4000 -> ratio = 0.5 -> node would get refined - double refining_ratio = 1.0f; std::vector refining_ids; refining_ids.push_back(root); @@ -153,8 +27,8 @@ class Space { Id current = refining_ids.back(); refining_ids.pop_back(); - Bounds current_bounds = get_node_bounds(current); - + Bounds current_bounds = m_space.get_node_bounds(current); + double current_distance = glm::distance(current_bounds.centre(), cam_pos); double current_ratio = current_distance / glm::length(current_bounds.size()); @@ -183,7 +57,7 @@ class Space { if (!draw_neighbours_only) { glm::dmat4 model_scale = glm::scale(glm::dmat4(1.0f), current_bounds.size()); - glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre()); + glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre() - cam_pos); glm::mat4 model = model_translate * model_scale; instance_active.push_back(0.0f); @@ -209,14 +83,14 @@ class Space { // Add the current active node to the render list glm::dmat4 model_scale = glm::scale(glm::dmat4(1.0f), current_bounds.size()); - glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre()); + glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre() - cam_pos); glm::mat4 model = model_translate * model_scale; instance_active.push_back(1.0f); instance_models.push_back(glm::mat4(model)); for (auto neighbour : current.neighbours()) { - Bounds neighbour_bounds = get_node_bounds(neighbour); + Bounds neighbour_bounds = m_space.get_node_bounds(neighbour); double neighbour_distance = glm::distance(neighbour_bounds.centre(), cam_pos); @@ -250,7 +124,7 @@ class Space { if (closest.has_value()) { rendering_intent.closest_node = closest; rendering_intent.min_scene_distance = std::numeric_limits::infinity(); - for (glm::dvec3 closest_corner : radix::geometry::corners(get_node_bounds(closest.value()))) { + for (glm::dvec3 closest_corner : radix::geometry::corners(m_space.get_node_bounds(closest.value()))) { double dist = glm::distance(closest_corner, cam_pos); if (dist < rendering_intent.min_scene_distance) { @@ -260,7 +134,7 @@ class Space { } if (farthest.has_value()) { rendering_intent.max_scene_distance = 0; - for (glm::dvec3 farthest_corner : radix::geometry::corners(get_node_bounds(farthest.value()))) { + for (glm::dvec3 farthest_corner : radix::geometry::corners(m_space.get_node_bounds(farthest.value()))) { double dist = glm::distance(farthest_corner, cam_pos); if (dist > rendering_intent.max_scene_distance) { @@ -271,8 +145,4 @@ class Space { return rendering_intent; } - -private: -}; - -} // namespace octree +} \ No newline at end of file diff --git a/src/browser/core/octree/rendering/OctreeRenderManager.h b/src/browser/core/octree/rendering/OctreeRenderManager.h new file mode 100644 index 0000000..52f71c8 --- /dev/null +++ b/src/browser/core/octree/rendering/OctreeRenderManager.h @@ -0,0 +1,47 @@ +#pragma once +#include "../space.h" +#include "../id.h" +#include + +namespace octree { + + + + struct OctreeRenderIntent { + std::vector instances_active; + std::vector instances_model_mats; + size_t instance_count; + + std::optional min_scene_distance; + std::optional max_scene_distance; + + std::optional closest_node; + }; + + enum OctreeFilterParamType { + Float, + Double + }; + + struct OctreeFilterParam { + std::string name; + OctreeFilterParamType type; + std::any default_value; + std::string description; + }; + + struct OctreeFilterDefinition { + std::string name; + std::string description; + }; + + class OctreeRenderManager { + public: + OctreeRenderManager(Space space); + + OctreeRenderIntent generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only, float refining_ratio); + private: + octree::Space m_space; + }; + +} \ No newline at end of file diff --git a/src/browser/core/octree/space.h b/src/browser/core/octree/space.h new file mode 100644 index 0000000..1dc4841 --- /dev/null +++ b/src/browser/core/octree/space.h @@ -0,0 +1,125 @@ +#pragma once + +#include + +#include "id.h" +#include +#include +#include + +namespace octree { +using Bounds = radix::geometry::Aabb3d; + +class Space { +public: + const Bounds bounds; + + static constexpr Space earth() { + const double max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) + const double extends = max_radius * 1.1; // TODO: how much padding do we want here + return Space(Bounds( + {-extends, -extends, -extends}, {extends, extends, extends})); + } + + std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { + // We don't want to recurse indefinitely if the bounds are empty. + const glm::dvec3 target_size = target_bounds.size(); + if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { + throw std::invalid_argument("target bounds cannot be empty"); + } + + const std::array corners = radix::geometry::corners(target_bounds); + + const Bounds root_bounds = get_node_bounds(root); + // Check if all points of the target bounds are inside the root bounds. + bool all_corners_inside_root = true; + for (const auto &corner : corners) { + if (!root_bounds.contains_inclusive(corner)) { + all_corners_inside_root = false; + break; + } + } + + if (!all_corners_inside_root) { + return std::nullopt; // Target bounds are outside the defined space. + } + + Id current_smallest_encompassing_node = root; + while (current_smallest_encompassing_node.has_children()) { + const std::array children = current_smallest_encompassing_node.children().value(); + std::optional next_smallest; + + for (const auto &child : children) { + const Bounds child_bounds = get_node_bounds(child); + bool all_corners_inside_child = true; + for (const auto &corner : corners) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside_child = false; + break; + } + } + + if (all_corners_inside_child) { + next_smallest = child; + break; // Found a child that fully contains the bounds, go deeper. + } + } + + if (next_smallest.has_value()) { + current_smallest_encompassing_node = next_smallest.value(); + } else { + break; // No child fully contains the bounds, so the current node is the smallest. + } + } + + return current_smallest_encompassing_node; + } + + std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { + assert(target_level <= Id::max_level()); + + Id current = root; + const Bounds root_bounds = this->get_node_bounds(current); + if (!root_bounds.contains_exclusive(point)) { + return std::nullopt; + } + + while (current.level() < target_level && current.has_children()) { + for (const auto& child : current.children().value()) { + const Bounds child_bounds = this->get_node_bounds(child); + if (child_bounds.contains_exclusive(point)) { + current = child; + break; + } + } + } + + return current; + } + + Bounds get_node_bounds(const Id &id) const { + const auto coords = id.coords(); + const uint32_t level = id.level(); + const uint32_t resolution = 1 << level; + + // Calculate the size of a node at this level + const glm::dvec3 bounds_size = bounds.size(); + const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); + + // Calculate the minimum point of the node + const glm::dvec3 min_bound = bounds.min; + const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; + + // Calculate the maximum point of the node + const glm::dvec3 node_max = node_min + node_size; + + Bounds node_bounds; + node_bounds.min = node_min; + node_bounds.max = node_max; + return node_bounds; + } + +private: +}; + +} // namespace octree diff --git a/src/core/octree/storage.h b/src/browser/core/octree/storage.h similarity index 100% rename from src/core/octree/storage.h rename to src/browser/core/octree/storage.h diff --git a/src/core/shader/GLUniformAbstractions.h b/src/browser/core/shader/GLUniformAbstractions.h similarity index 100% rename from src/core/shader/GLUniformAbstractions.h rename to src/browser/core/shader/GLUniformAbstractions.h diff --git a/src/core/shader/Shader.cpp b/src/browser/core/shader/Shader.cpp similarity index 100% rename from src/core/shader/Shader.cpp rename to src/browser/core/shader/Shader.cpp diff --git a/src/core/shader/Shader.h b/src/browser/core/shader/Shader.h similarity index 100% rename from src/core/shader/Shader.h rename to src/browser/core/shader/Shader.h diff --git a/src/core/shader/ShaderProgram.cpp b/src/browser/core/shader/ShaderProgram.cpp similarity index 100% rename from src/core/shader/ShaderProgram.cpp rename to src/browser/core/shader/ShaderProgram.cpp diff --git a/src/core/shader/ShaderProgram.h b/src/browser/core/shader/ShaderProgram.h similarity index 100% rename from src/core/shader/ShaderProgram.h rename to src/browser/core/shader/ShaderProgram.h diff --git a/src/core/shader/Uniform.h b/src/browser/core/shader/Uniform.h similarity index 100% rename from src/core/shader/Uniform.h rename to src/browser/core/shader/Uniform.h diff --git a/src/core/window/Window.cpp b/src/browser/core/window/Window.cpp similarity index 100% rename from src/core/window/Window.cpp rename to src/browser/core/window/Window.cpp diff --git a/src/core/window/Window.h b/src/browser/core/window/Window.h similarity index 100% rename from src/core/window/Window.h rename to src/browser/core/window/Window.h diff --git a/src/main.cpp b/src/browser/main.cpp similarity index 100% rename from src/main.cpp rename to src/browser/main.cpp diff --git a/src/res/CMakeLists.txt b/src/browser/res/CMakeLists.txt similarity index 100% rename from src/res/CMakeLists.txt rename to src/browser/res/CMakeLists.txt diff --git a/src/res/shaders/octree_lines.frag b/src/browser/res/shaders/octree_lines.frag similarity index 100% rename from src/res/shaders/octree_lines.frag rename to src/browser/res/shaders/octree_lines.frag diff --git a/src/res/shaders/octree_lines.vert b/src/browser/res/shaders/octree_lines.vert similarity index 100% rename from src/res/shaders/octree_lines.vert rename to src/browser/res/shaders/octree_lines.vert diff --git a/src/utils/log/Log.cpp b/src/browser/utils/log/Log.cpp similarity index 100% rename from src/utils/log/Log.cpp rename to src/browser/utils/log/Log.cpp diff --git a/src/utils/log/Log.h b/src/browser/utils/log/Log.h similarity index 100% rename from src/utils/log/Log.h rename to src/browser/utils/log/Log.h From 4e2fb4b0d9e9530afc56881cf944140811806dc3 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 23 May 2025 19:57:45 +0200 Subject: [PATCH 047/122] Finish octree storage; Refactoring --- src/CMakeLists.txt | 22 +- src/terrainbuilder/main.cpp | 84 +++++-- src/terrainbuilder/terrainbuilder.cpp | 8 +- src/terrainbuilder/texture_assembler.h | 2 +- src/terrainlib/ProgressIndicator.h | 5 +- src/terrainlib/hash_utils.h | 60 +++++ src/terrainlib/io/Error.h | 97 ++++++++ src/terrainlib/io/bytes.cpp | 48 ++++ src/terrainlib/io/bytes.h | 16 ++ src/terrainlib/io/serialize.h | 23 ++ src/terrainlib/io/serialize.inl | 88 ++++++++ src/terrainlib/io/utils.cpp | 11 + src/terrainlib/io/utils.h | 9 + src/terrainlib/log.h | 2 + src/terrainlib/log_path.h | 19 ++ src/terrainlib/mesh/io.cpp | 2 +- src/terrainlib/mesh/io/error.h | 2 + src/terrainlib/mesh/io/terrain.cpp | 15 +- src/terrainlib/octree/{id.h => Id.h} | 73 +++++- src/terrainlib/octree/IndexMap.h | 70 ++++++ src/terrainlib/octree/NodeStatus.h | 75 +++++++ src/terrainlib/octree/{space.h => Space.h} | 2 +- src/terrainlib/octree/Storage.cpp | 209 ++++++++++++++++++ src/terrainlib/octree/Storage.h | 42 ++++ src/terrainlib/octree/disk/IndexFile.h | 22 ++ src/terrainlib/octree/disk/Layout.h | 47 ++++ src/terrainlib/octree/disk/layout/Strategy.h | 19 ++ .../octree/disk/layout/StrategyRegister.h | 84 +++++++ .../octree/disk/layout/strategy/Default.h | 15 ++ .../octree/disk/layout/strategy/Flat.h | 50 +++++ .../strategy/LevelAndCoordinateDirectories.h | 60 +++++ src/terrainlib/octree/storage.h | 54 ----- src/terrainlib/octree/traverse.h | 61 +++++ src/terrainlib/octree/utils.h | 23 +- src/terrainlib/srs.h | 45 ++-- src/terrainlib/string_utils.h | 30 +++ src/terrainlib/type_utils.h | 47 ++++ src/terrainmerger/main.cpp | 6 +- unittests/terrainbuilder/mesh.cpp | 4 +- unittests/terrainbuilder/octree_id.cpp | 2 +- unittests/terrainbuilder/octree_space.cpp | 4 +- 41 files changed, 1419 insertions(+), 138 deletions(-) create mode 100644 src/terrainlib/hash_utils.h create mode 100644 src/terrainlib/io/Error.h create mode 100644 src/terrainlib/io/bytes.cpp create mode 100644 src/terrainlib/io/bytes.h create mode 100644 src/terrainlib/io/serialize.h create mode 100644 src/terrainlib/io/serialize.inl create mode 100644 src/terrainlib/io/utils.cpp create mode 100644 src/terrainlib/io/utils.h create mode 100644 src/terrainlib/log_path.h rename src/terrainlib/octree/{id.h => Id.h} (76%) create mode 100644 src/terrainlib/octree/IndexMap.h create mode 100644 src/terrainlib/octree/NodeStatus.h rename src/terrainlib/octree/{space.h => Space.h} (99%) create mode 100644 src/terrainlib/octree/Storage.cpp create mode 100644 src/terrainlib/octree/Storage.h create mode 100644 src/terrainlib/octree/disk/IndexFile.h create mode 100644 src/terrainlib/octree/disk/Layout.h create mode 100644 src/terrainlib/octree/disk/layout/Strategy.h create mode 100644 src/terrainlib/octree/disk/layout/StrategyRegister.h create mode 100644 src/terrainlib/octree/disk/layout/strategy/Default.h create mode 100644 src/terrainlib/octree/disk/layout/strategy/Flat.h create mode 100644 src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h delete mode 100644 src/terrainlib/octree/storage.h create mode 100644 src/terrainlib/octree/traverse.h create mode 100644 src/terrainlib/string_utils.h create mode 100644 src/terrainlib/type_utils.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85ceefb..55ea6d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,11 @@ add_library(terrainlib terrainlib/ctb/TileCoordinate.hpp terrainlib/ctb/types.hpp + terrainlib/io/bytes.h terrainlib/io/bytes.cpp + terrainlib/io/Error.h + terrainlib/io/serialize.h + terrainlib/io/utils.h terrainlib/io/utils.cpp + terrainlib/mesh/io/error.h terrainlib/mesh/io/gltf.h terrainlib/mesh/io/gltf.cpp terrainlib/mesh/io/options.h @@ -77,16 +82,27 @@ add_library(terrainlib terrainlib/mesh/SimpleMesh.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp - terrainlib/octree/id.h - terrainlib/octree/storage.h - terrainlib/octree/space.h + terrainlib/octree/disk/layout/strategy/Flat.h + terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h + terrainlib/octree/disk/layout/Strategy.h + terrainlib/octree/disk/layout/StrategyRegister.h + terrainlib/octree/disk/IndexFile.h + terrainlib/octree/disk/Layout.h + terrainlib/octree/Id.h + terrainlib/octree/Storage.h terrainlib/octree/Storage.cpp + terrainlib/octree/IndexMap.h + terrainlib/octree/NodeStatus.h + terrainlib/octree/Space.h + terrainlib/octree/traverse.h terrainlib/octree/utils.h terrainlib/Dataset.h terrainlib/Dataset.cpp + terrainlib/hash_utils.h terrainlib/init.h terrainlib/init.cpp terrainlib/log.h terrainlib/log.cpp terrainlib/ProgressIndicator.h terrainlib/ProgressIndicator.cpp terrainlib/srs.h + terrainlib/string_utils.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index c1db8ab..85ba80f 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -8,22 +8,26 @@ #include #include #include + #include +#include +#include #include -#include "srs.h" #include "Dataset.h" -#include "terrainbuilder.h" -#include "log.h" #include "ProgressIndicator.h" +#include "log.h" +#include "srs.h" +#include "terrainbuilder.h" -#include "ctb/GlobalMercator.hpp" #include "ctb/GlobalGeodetic.hpp" +#include "ctb/GlobalMercator.hpp" #include "ctb/Grid.hpp" -#include "octree/id.h" -#include "octree/storage.h" -#include "octree/space.h" +#include "octree/Id.h" +#include "octree/Space.h" +#include "octree/Storage.h" +#include "octree/disk/layout/strategy/LevelAndCoordinateDirectories.h" #include "octree/utils.h" OGRSpatialReference parse_srs(const std::string &user_input) { @@ -102,13 +106,13 @@ radix::geometry::Aabb3d parse_bounds_from_node(const std::vector &data LOG_ERROR_AND_EXIT("Only ECEF (EPSG:4978) supported for --node."); } - const uint32_t zoom_level = data[0]; + const octree::Id::Level zoom_level = data[0]; octree::Id target_node = octree::Id::root(); if (data.size() == 2) { target_node = {zoom_level, data[1]}; } else if (data.size() == 4) { - const glm::uvec3 coords(data[1], data[2], data[3]); + const octree::Id::Coords coords(data[1], data[2], data[3]); target_node = {zoom_level, coords}; } else { LOG_ERROR_AND_EXIT("Invalid number of args for --node. Expected 2 or 4."); @@ -147,16 +151,18 @@ T expect(const std::optional &opt, const std::string &msg) { return *opt; } - void batch_build( Dataset &dataset, - const octree::Level target_level, + const octree::Id::Level target_level, const OGRSpatialReference &texture_srs, const std::optional &texture_base_path, const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_base_path, const std::string &output_format) { - const octree::Storage storage(output_base_path); + const octree::Storage storage = octree::open_folder( + output_base_path, + octree::disk::layout::strategy::make_default(), + output_format); const auto dataset_srs = dataset.srs(); const auto dataset_bounds = dataset.bounds3d(); @@ -174,9 +180,17 @@ void batch_build( tbb::task_group tg; std::function process_node; + tbb::enumerable_thread_specific> transform_ecef_dataset([&]() { + auto local_ecef_srs = ecef_srs; + auto local_dataset_srs = dataset_srs; + auto transform = srs::transformation(local_ecef_srs, local_dataset_srs); + return transform; + }); + process_node = [&](octree::Id node) { const auto node_bounds = space.get_node_bounds(node); - const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer(ecef_srs, dataset_srs, node_bounds); + const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer( + &*transform_ecef_dataset.local(), node_bounds); if (!radix::geometry::intersect(node_bounds_dataset_srs, dataset_bounds)) { return; @@ -185,7 +199,7 @@ void batch_build( if (node.level() < target_level) { if (auto children = node.children(); children.has_value()) { for (const auto &child : *children) { - tg.run([=] { process_node(child); }); + tg.run([&, child] { process_node(child); }); } } } else if (node.level() == target_level) { @@ -202,11 +216,32 @@ void batch_build( ProgressIndicator progress(target_nodes.size()); std::jthread progress_thread = progress.start_monitoring(); - std::for_each(std::execution::par, target_nodes.begin(), target_nodes.end(), [&](const auto &node) { + tbb::enumerable_thread_specific local_dataset([&]() { + return dataset.clone(); + }); + tbb::enumerable_thread_specific> local_ecef_srs([&]() { + return srs::clone(ecef_srs); + }); + tbb::enumerable_thread_specific> local_texture_srs([&]() { + return srs::clone(texture_srs); + }); + tbb::enumerable_thread_specific> local_mesh_srs([&]() { + return srs::clone(mesh_srs); + }); + tbb::parallel_for(size_t(0), target_nodes.size(), [&](size_t i) { + const auto &node = target_nodes[i]; + if (storage.has_node(node)) { + return; + } + + auto &dataset = local_dataset.local(); + auto &ecef_srs = *local_ecef_srs.local(); + auto &texture_srs = *local_texture_srs.local(); + auto &mesh_srs = *local_mesh_srs.local(); + const auto node_bounds = space.get_node_bounds(node); - auto local_dataset = dataset.clone(); const SimpleMesh mesh = terrainbuilder::build( - local_dataset, + dataset, ecef_srs, node_bounds, texture_srs, @@ -214,11 +249,14 @@ void batch_build( mesh_srs); if (!mesh.is_empty()) { - storage.save_node(node, mesh); + storage.write_node(node, mesh); } progress.task_finished(); }); + + progress_thread.join(); + storage.save_index(); } int run(std::span args) { @@ -274,7 +312,7 @@ int run(std::span args) { ->expected(2, 4); target->require_option(1); - single->add_option("--output", output_path, "Output path were the mesh is written to (.tile, .gltf or .glb)") + single->add_option("--output", output_path, "Output path were the mesh is written to (.terrain, .gltf or .glb)") ->required(); std::map scheme_str_map{ @@ -303,7 +341,7 @@ int run(std::span args) { auto *batch = app.add_subcommand("batch", "Build all nodes for a dataset at a given level") ->fallthrough(); - octree::Level target_level; + octree::Id::Level target_level; batch->add_option("--target-level", target_level, "Level of detail for batch generation") ->required(); std::filesystem::path output_base_path; @@ -311,14 +349,14 @@ int run(std::span args) { ->required(); std::string output_format; batch->add_option("--format", output_format, "Output mesh format") - ->check(CLI::IsMember({"glb", "gltf", "tile"})) - ->default_val("glb"); + ->check(CLI::IsMember({".glb", ".gltf", ".terrain"})) + ->default_val(".glb"); CLI11_PARSE(app, argc, argv); Log::init(log_level); - Dataset dataset(dataset_path); + Dataset dataset(dataset_path.string()); OGRSpatialReference mesh_srs = parse_srs(mesh_srs_input); OGRSpatialReference texture_srs = srs::webmercator(); diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 6fb27ab..0a6b714 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -18,7 +18,7 @@ #include "texture_assembler.h" #include "tile_provider.h" -#include "octree/space.h" +#include "octree/Space.h" namespace terrainbuilder { @@ -127,7 +127,7 @@ void build_and_save( texture_base_path, mesh_srs); - LOG_INFO("Writing mesh to output path {}", output_path.string()); + LOG_INFO("Writing mesh to output path {}", output_path); std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); @@ -146,11 +146,11 @@ void build_and_save( texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); */ if (!::mesh::io::save_to_path(mesh, output_path, ::mesh::io::SaveOptions{.metadata = metadata}).has_value()) { - LOG_ERROR("Failed to save mesh to file {}", output_path.string()); + LOG_ERROR("Failed to save mesh to file {}", output_path); exit(2); } LOG_DEBUG("Writing mesh took {}s", format_secs_since(start)); - LOG_INFO("Done", output_path.string()); + LOG_INFO("Done", output_path); } } diff --git a/src/terrainbuilder/texture_assembler.h b/src/terrainbuilder/texture_assembler.h index 253231f..7fee053 100644 --- a/src/terrainbuilder/texture_assembler.h +++ b/src/terrainbuilder/texture_assembler.h @@ -229,7 +229,7 @@ std::optional try_get_tile_path(const radix::tile::Id til if (tile_image.empty()) { const std::optional tile_path = try_get_tile_path(tile, tile_provider); if (tile_path.has_value()) { - LOG_ERROR("Failed to load image from path {}", tile_path.value().string()); + LOG_ERROR("Failed to load image from path {}", tile_path.value()); } else { LOG_ERROR("Failed to load tile texture"); } diff --git a/src/terrainlib/ProgressIndicator.h b/src/terrainlib/ProgressIndicator.h index 754c3fd..f714626 100644 --- a/src/terrainlib/ProgressIndicator.h +++ b/src/terrainlib/ProgressIndicator.h @@ -17,8 +17,7 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef PROGRESSINDICATOR_H -#define PROGRESSINDICATOR_H +#pragma once #include #include @@ -37,5 +36,3 @@ class ProgressIndicator { [[nodiscard]] std::string progress_bar() const; [[nodiscard]] std::string x_of_y_done_message() const; }; - -#endif // PROGRESSINDICATOR_H diff --git a/src/terrainlib/hash_utils.h b/src/terrainlib/hash_utils.h new file mode 100644 index 0000000..bef7743 --- /dev/null +++ b/src/terrainlib/hash_utils.h @@ -0,0 +1,60 @@ +namespace { +// from https://github.com/boostorg/container_hash/blob/ee5285bfa64843a11e29700298c83a37e3132fcd/include/boost/container_hash/detail/hash_mix.hpp#L17 +template +struct hash_mix_impl; + +template <> +struct hash_mix_impl<64> { + inline static std::uint64_t fn(std::uint64_t x) { + std::uint64_t const m = 0xe9846af9b1a615d; + + x ^= x >> 32; + x *= m; + x ^= x >> 32; + x *= m; + x ^= x >> 28; + + return x; + } +}; + +template <> +struct hash_mix_impl<32> { + inline static std::uint32_t fn(std::uint32_t x) { + std::uint32_t const m1 = 0x21f0aaad; + std::uint32_t const m2 = 0x735a2d97; + + x ^= x >> 16; + x *= m1; + x ^= x >> 15; + x *= m2; + x ^= x >> 15; + + return x; + } +}; + +inline std::size_t hash_mix(std::size_t v) { + return hash_mix_impl::fn(v); +} + +// from https://github.com/boostorg/container_hash/blob/ee5285bfa64843a11e29700298c83a37e3132fcd/include/boost/container_hash/hash.hpp#L468 +template +inline void hash_combine_core(std::size_t &seed, const T &v) { + seed = hash_mix(seed + 0x9e3779b9 + std::hash()(v)); +} + +// modified from https://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x/57595105#57595105 +template +void hash_combine_core(std::size_t &seed, const T &v, const Rest &...rest) { + seed = hash_mix(seed, v); + (hash_combine_core(seed, rest), ...); +} +} + +template +size_t hash_combine(const Rest &...rest) { + size_t h; + (hash_combine_core(h, rest), ...); + return h; +} diff --git a/src/terrainlib/io/Error.h b/src/terrainlib/io/Error.h new file mode 100644 index 0000000..b306e60 --- /dev/null +++ b/src/terrainlib/io/Error.h @@ -0,0 +1,97 @@ +#pragma once + +#include + +#include "log.h" + +namespace io { + +class Error { +public: + enum Value : uint8_t { + OpenFile, + WriteBytes, + DetermineSize, + ReadBytes, + Serialize, + Deserialize, + OutOfMemory + }; + + Error() = default; + constexpr Error(Value value) : _value(value) {} + + constexpr operator Value() const { + return this->_value; + } + explicit operator bool() const = delete; + constexpr bool operator==(Error other) const { + return this->_value == other._value; + } + constexpr bool operator!=(Error other) const { + return !(*this == other); + } + + std::string to_string() const; + +private: + Value _value; + +public: + using serialize = zpp::bits::members<1>; + friend zpp::bits::access; +}; + +} // namespace io + +#include +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const io::Error &error, FormatContext &ctx) { + const char *name = "Unknown"; + + switch (error) { + case io::Error::Value::OpenFile: + name = "OpenFile"; + break; + case io::Error::Value::WriteBytes: + name = "WriteBytes"; + break; + case io::Error::Value::DetermineSize: + name = "DetermineSize"; + break; + case io::Error::Value::ReadBytes: + name = "ReadBytes"; + break; + case io::Error::Value::Serialize: + name = "Serialize"; + break; + case io::Error::Value::Deserialize: + name = "Deserialize"; + break; + case io::Error::Value::OutOfMemory: + name = "OutOfMemory"; + break; + default: + UNREACHABLE(); + } + + return fmt::format_to(ctx.out(), "{}", name); + } +}; + +#include +#include +inline std::string io::Error::to_string() const { + return fmt::format("{}", *this); +} +inline std::ostream &operator<<(std::ostream &os, const io::Error &status) { + fmt::print(os, "{}", status); + return os; +} diff --git a/src/terrainlib/io/bytes.cpp b/src/terrainlib/io/bytes.cpp new file mode 100644 index 0000000..f8444e6 --- /dev/null +++ b/src/terrainlib/io/bytes.cpp @@ -0,0 +1,48 @@ +#include + +#include "io/bytes.h" +#include "io/utils.h" + +namespace io { + +tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path, bool make_dirs) { + if (make_dirs) { + utils::create_parent_directories(path); + } + + std::ofstream file(path, std::ios::binary); + if (!file.is_open()) { + return tl::unexpected(Error::OpenFile); + } + + file.write(reinterpret_cast(bytes.data()), static_cast(bytes.size())); + if (!file.good()) { + return tl::unexpected(Error::WriteBytes); + } + + return {}; +} + +tl::expected, Error> read_bytes_from_path(const std::filesystem::path& path) { + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file.is_open()) { + return tl::unexpected(Error::OpenFile); + } + + const std::streamsize size = file.tellg(); + if (size < 0) { + return tl::unexpected(Error::DetermineSize); + } + + std::vector buffer(static_cast(size)); + file.seekg(0); + file.read(reinterpret_cast(buffer.data()), size); + + if (!file.good()) { + return tl::unexpected(Error::ReadBytes); + } + + return buffer; +} + +} diff --git a/src/terrainlib/io/bytes.h b/src/terrainlib/io/bytes.h new file mode 100644 index 0000000..5c156cf --- /dev/null +++ b/src/terrainlib/io/bytes.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +#include + +#include "io/Error.h" + +namespace io { + +tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path, bool make_dirs = true); +tl::expected, Error> read_bytes_from_path(const std::filesystem::path &path); + +} diff --git a/src/terrainlib/io/serialize.h b/src/terrainlib/io/serialize.h new file mode 100644 index 0000000..05a72e6 --- /dev/null +++ b/src/terrainlib/io/serialize.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +#include "io/Error.h" + +namespace io { + +template +tl::expected, Error> write_to_bytes(const T &value); +template +tl::expected read_from_bytes(const std::span bytes); + +template +tl::expected write_to_path(const T &value, const std::filesystem::path &path, bool make_dirs = true); +template +tl::expected read_from_path(const std::filesystem::path &path); + +} + +#include "io/serialize.inl" diff --git a/src/terrainlib/io/serialize.inl b/src/terrainlib/io/serialize.inl new file mode 100644 index 0000000..90d7080 --- /dev/null +++ b/src/terrainlib/io/serialize.inl @@ -0,0 +1,88 @@ +#pragma once + +#include + +#include "io/bytes.h" +#include "io/utils.h" +#include "type_utils.h" + +namespace io { + +template +tl::expected, Error> write_to_bytes(const T &value) { + std::vector data; + zpp::bits::out out(data); + const auto result = out(value); + if (zpp::bits::failure(result)) { + std::error_code error_code = std::make_error_code(result); + LOG_ERROR("error while writing {}: {}", type_name(), error_code.message()); + + switch (result) { + case std::errc::no_buffer_space: // growing buffer would grow beyond the allocation limits or overflow. + case std::errc::message_size: // message size is beyond the user defined allocation limits. + case std::errc::result_out_of_range: // attempting to write or read from a too short buffer. + return tl::unexpected(Error::OutOfMemory); + case std::errc::value_too_large: // varint (variable length integer) encoding is beyond the representation limits. + case std::errc::bad_message: // attempt to read a variant of unrecognized type. + case std::errc::invalid_argument: // attempting to serialize null pointer or a value-less variant. + return tl::unexpected(Error::Serialize); + case std::errc::protocol_error: // attempt to deserialize an invalid protocol message. + case std::errc::not_supported: // attempt to call an RPC that is not listed as supported. + UNREACHABLE(); + default: + UNREACHABLE(); + } + } + return data; +} + +template +tl::expected read_from_bytes(const std::span bytes) { + zpp::bits::in in(bytes); + T value; + const auto result = in(value); + if (zpp::bits::failure(result)) { + std::error_code error_code = std::make_error_code(result); + LOG_ERROR("error while reading {}: {}", type_name(), error_code.message()); + + switch (result) { + case std::errc::no_buffer_space: // growing buffer would grow beyond the allocation limits or overflow. + case std::errc::message_size: // message size is beyond the user defined allocation limits. + case std::errc::result_out_of_range: // attempting to write or read from a too short buffer. + return tl::unexpected(Error::OutOfMemory); + case std::errc::value_too_large: // varint (variable length integer) encoding is beyond the representation limits. + case std::errc::bad_message: // attempt to read a variant of unrecognized type. + case std::errc::invalid_argument: // attempting to serialize null pointer or a value-less variant. + return tl::unexpected(Error::Deserialize); + case std::errc::protocol_error: // attempt to deserialize an invalid protocol message. + case std::errc::not_supported: // attempt to call an RPC that is not listed as supported. + UNREACHABLE(); + default: + UNREACHABLE(); + } + } + return value; +} + +template +tl::expected read_from_path(const std::filesystem::path &path) { + const auto result = read_bytes_from_path(path); + if (!result.has_value()) { + return tl::unexpected(result.error()); + } + const std::vector bytes = result.value(); + return read_from_bytes(bytes); +} + +template +tl::expected write_to_path(const T &value, const std::filesystem::path &path, bool make_dirs) { + const auto result = write_to_bytes(value); + if (!result.has_value()) { + return tl::unexpected(result.error()); + } + + const std::vector bytes = result.value(); + return write_bytes_to_path(bytes, path, make_dirs); +} + +} // namespace io diff --git a/src/terrainlib/io/utils.cpp b/src/terrainlib/io/utils.cpp new file mode 100644 index 0000000..452f293 --- /dev/null +++ b/src/terrainlib/io/utils.cpp @@ -0,0 +1,11 @@ +#include "mesh/io/utils.h" + +namespace io::utils { + +std::filesystem::path create_parent_directories(const std::filesystem::path &path) { + const std::filesystem::path parent_path = std::filesystem::absolute(path).parent_path(); + std::filesystem::create_directories(parent_path); + return parent_path; +} + +} // namespace io::utils diff --git a/src/terrainlib/io/utils.h b/src/terrainlib/io/utils.h new file mode 100644 index 0000000..8b6b4e6 --- /dev/null +++ b/src/terrainlib/io/utils.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace io::utils { + +std::filesystem::path create_parent_directories(const std::filesystem::path &path); + +} // namespace io::utils diff --git a/src/terrainlib/log.h b/src/terrainlib/log.h index 200a5db..1f30ab3 100644 --- a/src/terrainlib/log.h +++ b/src/terrainlib/log.h @@ -47,3 +47,5 @@ class Log { LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ _UNREACHABLE(); \ } while (0) + +#include "log_path.h" diff --git a/src/terrainlib/log_path.h b/src/terrainlib/log_path.h new file mode 100644 index 0000000..8a8d93a --- /dev/null +++ b/src/terrainlib/log_path.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include + +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const std::filesystem::path &path, FormatContext &ctx) { + return fmt::format_to(ctx.out(), "{}", std::filesystem::weakly_canonical(path).string()); + } +}; + diff --git a/src/terrainlib/mesh/io.cpp b/src/terrainlib/mesh/io.cpp index 04b3d04..e69a1c1 100644 --- a/src/terrainlib/mesh/io.cpp +++ b/src/terrainlib/mesh/io.cpp @@ -23,7 +23,7 @@ tl::expected save_to_path( const SimpleMesh &mesh, const std::filesystem::path &path, const SaveOptions &options) { - LOG_TRACE("Saving mesh to path {}", path.string()); + LOG_TRACE("Saving mesh to path {}", path); const std::filesystem::path extension = path.extension(); if (extension == ".glb" || extension == ".gltf") { diff --git a/src/terrainlib/mesh/io/error.h b/src/terrainlib/mesh/io/error.h index 9c208ad..4f00843 100644 --- a/src/terrainlib/mesh/io/error.h +++ b/src/terrainlib/mesh/io/error.h @@ -4,6 +4,8 @@ namespace mesh::io { +// TODO: use same setup as with NodeStatus here + enum class LoadMeshErrorKind { UnsupportedFormat, FileNotFound, diff --git a/src/terrainlib/mesh/io/terrain.cpp b/src/terrainlib/mesh/io/terrain.cpp index 610cf8a..b0721d5 100644 --- a/src/terrainlib/mesh/io/terrain.cpp +++ b/src/terrainlib/mesh/io/terrain.cpp @@ -9,12 +9,13 @@ using namespace mesh::io::utils; namespace mesh::io::terrain { namespace { -tl::expected write_bytes_to_path(const std::span bytes, const std::filesystem::path &path) { - LOG_TRACE("Writing bytes to path {}", path.string()); +tl::expected write_bytes_to_path( + const std::span bytes, const std::filesystem::path &path) { + LOG_TRACE("Writing bytes to path {}", path); std::ofstream ofs(path, std::ios::out | std::ios::binary); if (!ofs.is_open()) { - LOG_ERROR("Failed to open file {}", path.string()); + LOG_ERROR("Failed to open file {}", path); return tl::unexpected(SaveMeshErrorKind::OpenFile); } @@ -23,7 +24,7 @@ tl::expected write_bytes_to_path(const std::span(bytes.data()), data_size); if (!ofs.good()) { - LOG_ERROR("Failed to write to file {}", path.string()); + LOG_ERROR("Failed to write to file {}", path); ofs.close(); return tl::unexpected(SaveMeshErrorKind::WriteFile); } @@ -34,11 +35,11 @@ tl::expected write_bytes_to_path(const std::span, LoadMeshError> read_bytes_from_path(const std::filesystem::path &path) { - LOG_TRACE("Reading bytes from path {}", path.string()); + LOG_TRACE("Reading bytes from path {}", path); std::ifstream ifs(path, std::ios::in | std::ios::binary); if (!ifs.is_open()) { - LOG_ERROR("Failed to open file {}", path.string()); + LOG_ERROR("Failed to open file {}", path); return tl::unexpected(LoadMeshErrorKind::FileNotFound); } @@ -78,7 +79,7 @@ tl::expected, SaveMeshError> save_to_buffer(const SimpleMes auto result = out(mesh); if (zpp::bits::failure(result)) { std::error_code error_code = std::make_error_code(result); - LOG_ERROR("Error while writing tile: {}", error_code.message()); + LOG_ERROR("Error while writing mesh: {}", error_code.message()); switch (result) { case std::errc::no_buffer_space: diff --git a/src/terrainlib/octree/id.h b/src/terrainlib/octree/Id.h similarity index 76% rename from src/terrainlib/octree/id.h rename to src/terrainlib/octree/Id.h index 1ad64ee..8e42caa 100644 --- a/src/terrainlib/octree/id.h +++ b/src/terrainlib/octree/Id.h @@ -5,18 +5,21 @@ #include #include #include +#include #include -namespace octree { +#include "hash_utils.h" -using Level = uint32_t; -using Coord = uint32_t; -using Coords = glm::tvec3; -using Index = uint64_t; +namespace octree { class Id { public: + using Level = uint8_t; + using Coord = uint32_t; + using Coords = glm::tvec3; + using Index = uint64_t; + [[nodiscard]] static constexpr Level max_level() { return (sizeof(Index) * 8) / 3; } @@ -27,6 +30,7 @@ class Id { return (1ull << (3 * level)) - 1; } + constexpr Id() = default; // zpp::bits requires a default constructor constexpr Id(const Level level, const Coords coords) : Id(level, interleave3(coords)) { } @@ -36,6 +40,25 @@ class Id { assert(index <= Id::max_index_on_level(this->_level)); } + [[nodiscard]] static std::optional try_make(const Level level, const Coords coords) { + if (level > Id::max_level()) { + return std::nullopt; + } + if (glm::any(glm::greaterThan(coords, Coords(max_coord_on_level(level))))) { + return std::nullopt; + } + return Id(level, coords); + } + [[nodiscard]] static std::optional try_make(const Level level, const Index index) { + if (level > Id::max_level()) { + return std::nullopt; + } + if (index > Id::max_index_on_level(level)) { + return std::nullopt; + } + return Id(level, index); + } + [[nodiscard]] constexpr Level level() const { return this->_level; } @@ -129,6 +152,9 @@ class Id { bool operator==(const Id &other) const { return this->_level == other._level && this->_index == other._index; } + bool operator!=(const Id &other) const { + return !(*this == other); + } private: Level _level; @@ -200,3 +226,40 @@ inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { return os; } } + +namespace std { +template <> +struct hash { + std::size_t operator()(const octree::Id &id) const noexcept { + return hash_combine(id.level(), id.index_on_level()); + } +}; +} // namespace std + +#include +namespace zpp::bits { +namespace { +constexpr zpp::bits::errc success() { + return zpp::bits::errc(std::errc()); +} +} +constexpr auto serialize(auto &archive, octree::Id &id) { + octree::Id::Level level; + octree::Id::Index index; + auto result = archive(level, index); + if (failure(result)) { + return result; + } + + auto maybe_id = octree::Id::try_make(level, index); + if (!maybe_id) { + return zpp::bits::errc(std::errc::bad_message); + } + + id = *maybe_id; + return success(); +} +constexpr auto serialize(auto &archive, const octree::Id &id) { + return archive(id.level(), id.index_on_level()); +} +} diff --git a/src/terrainlib/octree/IndexMap.h b/src/terrainlib/octree/IndexMap.h new file mode 100644 index 0000000..f82cb7c --- /dev/null +++ b/src/terrainlib/octree/IndexMap.h @@ -0,0 +1,70 @@ +#pragma once + +#include + +#include + +#include "octree/Id.h" +#include "octree/NodeStatus.h" + +namespace octree { + +class IndexMap { +public: + using Container = std::unordered_map; + using iterator = Container::iterator; + using const_iterator = Container::const_iterator; + + std::optional get(Id id) const { + if (auto it = this->_index.find(id); it != this->_index.end()) { + return it->second; + } + return std::nullopt; + } + + void set(Id id, NodeStatus status) { + // TODO: update other nodes? + this->_index[id] = status; + } + + bool is_present(Id id) const { + auto it = this->_index.find(id); + return it != this->_index.end(); + } + bool is_absent(Id id) const { + return !this->is_present(id); + } + bool is(NodeStatus status, Id id) const { + return this->get(id) == status; + } + + void clear() { + this->_index.clear(); + } + bool empty() const { + return this->_index.empty(); + } + size_t size() const { + return this->_index.size(); + } + + const_iterator begin() const { + return this->_index.begin(); + } + const_iterator end() const { + return this->_index.end(); + } + const_iterator cbegin() const { + return this->_index.cbegin(); + } + const_iterator cend() const { + return this->_index.cend(); + } + +private: + Container _index; +public: + using serialize = zpp::bits::members<1>; + friend zpp::bits::access; +}; +} diff --git a/src/terrainlib/octree/NodeStatus.h b/src/terrainlib/octree/NodeStatus.h new file mode 100644 index 0000000..0379b8f --- /dev/null +++ b/src/terrainlib/octree/NodeStatus.h @@ -0,0 +1,75 @@ +#pragma once + +#include + +#include "log.h" +#include "octree/Id.h" + +namespace octree { + +class NodeStatus { +public: + enum Value : uint8_t { + Leaf = 0, + Inner = 1, + Virtual = 2 // not present on disk but has children + }; + + NodeStatus() = default; + constexpr NodeStatus(Value value) : _value(value) {} + + constexpr operator Value() const { + return this->_value; + } + explicit operator bool() const = delete; + constexpr bool operator==(NodeStatus other) const { + return this->_value == other._value; + } + constexpr bool operator!=(NodeStatus other) const { + return !(*this == other); + } + + std::string to_string() const; + +private: + Value _value; + +public: + using serialize = zpp::bits::members<1>; + friend zpp::bits::access; +}; + +} + +#include +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const octree::NodeStatus &status, FormatContext &ctx) { + switch (status) { + case octree::NodeStatus::Leaf: + return fmt::format_to(ctx.out(), "Leaf"); + case octree::NodeStatus::Inner: + return fmt::format_to(ctx.out(), "Inner"); + case octree::NodeStatus::Virtual: + return fmt::format_to(ctx.out(), "Virtual"); + default: + UNREACHABLE(); + } + } +}; + +#include +#include +inline std::string octree::NodeStatus::to_string() const { + return fmt::format("{}", *this); +} +inline std::ostream &operator<<(std::ostream &os, const octree::NodeStatus &status) { + fmt::print(os, "{}", status); + return os; +} diff --git a/src/terrainlib/octree/space.h b/src/terrainlib/octree/Space.h similarity index 99% rename from src/terrainlib/octree/space.h rename to src/terrainlib/octree/Space.h index 8fd881f..9f7841d 100644 --- a/src/terrainlib/octree/space.h +++ b/src/terrainlib/octree/Space.h @@ -2,7 +2,7 @@ #include -#include "id.h" +#include "octree/Id.h" namespace octree { using Bounds = radix::geometry::Aabb3d; diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp new file mode 100644 index 0000000..2472c53 --- /dev/null +++ b/src/terrainlib/octree/Storage.cpp @@ -0,0 +1,209 @@ +#include "octree/Storage.h" + +#include +#include +#include +#include +#include + +#include "log.h" +#include "mesh/io.h" +#include "octree/disk/IndexFile.h" +#include "octree/disk/layout/StrategyRegister.h" +#include "io/serialize.h" + +namespace octree { + +Storage::Storage(disk::Layout layout) + : _layout(std::move(layout)) {} + +Storage::Storage(IndexMap map, disk::Layout layout) + : _index(std::move(map)), _layout(std::move(layout)) {} + +std::optional Storage::read_node(const Id &id) const { + const auto node_path = this->get_node_path(id); + const auto result = mesh::io::load_from_path(node_path); + if (result.has_value()) { + return result.value(); + } else { + return std::nullopt; + } +} + +bool Storage::write_node(const Id &id, const Node &node) const { + const auto node_path = this->get_node_path(id); + const auto result = mesh::io::save_to_path(node, node_path); + return result.has_value(); +} + +bool Storage::has_node(const Id &id) const { + if (this->_index.has_value()) { + return this->_index->is_present(id); + } else { + return std::filesystem::exists(this->get_node_path(id)); + } +} + +std::filesystem::path Storage::get_node_path(const Id &id) const { + return this->_layout.get_node_path(id); +} + +bool Storage::save_index() const { + const auto index_path = this->_layout.base_path() / disk::v1::index_file_name(); + LOG_TRACE("Saving octree storage index to {}", index_path); + + disk::v1::IndexFile index_file; + if (this->_index.has_value()) { + index_file.map = this->_index.value(); + } + index_file.preferred_extension = this->_layout.extension_with_dot(); + index_file.layout_strategy_id = disk::layout::StrategyRegister::instance().get_id(this->_layout.strategy()); + + const auto result = io::write_to_path(index_file, index_path); + if (!result.has_value()) { + LOG_ERROR("Failed to save octree storage index to {}", index_path); + } + return result.has_value(); +} + +std::optional load_index(const std::filesystem::path &index_path) { + LOG_TRACE("Opening storage index {}", index_path); + + const auto result = io::read_from_path(index_path); + if (!result.has_value()) { + LOG_TRACE("Failed to open storage index due to {}", result.error()); + return std::nullopt; + } + auto index_file = result.value(); + LOG_TRACE("Successfully read storage index with {} entries.", index_file.map.size()); + auto index_map = std::move(index_file.map); + const auto base_path = index_path.parent_path(); + auto layout_strategy = disk::layout::StrategyRegister::instance().create(index_file.layout_strategy_id); + disk::Layout layout(base_path, std::move(layout_strategy), index_file.preferred_extension); + + return Storage(std::move(index_map), std::move(layout)); +} + +namespace { +std::optional> guess_layout_strategy( + const std::filesystem::path &base_path, + std::size_t max_files_to_check = 100) { + + if (!std::filesystem::is_directory(base_path)) { + return std::nullopt; + } + + std::vector candidate_paths; + for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { + if (max_files_to_check == 0) { + break; + } + if (!entry.is_regular_file() && !entry.is_symlink()) { + continue; + } + + const auto ext = entry.path().extension(); + // TODO: manage these somewhere else + if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { + continue; + } + + candidate_paths.emplace_back(std::filesystem::relative(entry.path(), base_path)); + max_files_to_check--; + } + + for (const auto &[_, make_strategy] : disk::layout::StrategyRegister::instance().factories()) { + auto strategy = make_strategy(); + bool matches_all = std::all_of(candidate_paths.begin(), candidate_paths.end(), + [&](const auto &rel_path) { + return strategy->get_id_from_relative_node_path(rel_path).has_value(); + }); + + if (matches_all) { + return strategy; + } + } + + return std::nullopt; +} + +void update_index(IndexMap &index, const disk::Layout &layout) { + index.clear(); + const auto &base_path = layout.base_path(); + + for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { + if (!entry.is_regular_file() && !entry.is_symlink()) { + continue; + } + + const auto ext = entry.path().extension(); + if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { + continue; + } + + auto id_opt = layout.get_id_from_node_path(entry.path()); + if (!id_opt) { + continue; + } + + const Id id = *id_opt; + index.set(id, NodeStatus::Leaf); + } + + std::unordered_set visited; + for (const auto &[id, _] : index) { + auto parent = id.parent(); + while (parent) { + if (visited.find(*parent) != visited.end()) { + break; + } + visited.insert(*parent); + + if (index.get(*parent)) { + index.set(*parent, NodeStatus::Inner); + } else { + index.set(*parent, NodeStatus::Virtual); + } + parent = parent->parent(); + } + } +} +} + +Storage open_folder( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy, + const std::string extension_with_dot, + bool save_index) { + LOG_TRACE("Opening storage folder {}", base_path); + + const std::filesystem::path index_path = base_path / disk::v1::index_file_name(); + auto storage_opt = load_index(index_path); + if (storage_opt.has_value()) { + LOG_TRACE("Loaded existing index"); + return std::move(storage_opt.value()); + } + + auto layout_strategy_opt = guess_layout_strategy(base_path); + if (layout_strategy_opt) { + LOG_TRACE("Guessed layout of dataset as {}", + disk::layout::StrategyRegister::instance().get_id(**layout_strategy_opt)); + } else { + LOG_WARN("Unable to determine layout of dataset, using default which is {}", + disk::layout::StrategyRegister::instance().get_id(*default_layout_strategy)); + layout_strategy_opt = std::move(default_layout_strategy); + } + + disk::Layout layout(base_path, std::move(*layout_strategy_opt), extension_with_dot); + IndexMap map; + update_index(map, layout); + + Storage storage(std::move(map), std::move(layout)); + if (save_index) { + storage.save_index(); + } + + return storage; +} + +} // namespace octree diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h new file mode 100644 index 0000000..312316a --- /dev/null +++ b/src/terrainlib/octree/Storage.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/io.h" +#include "octree/Id.h" +#include "octree/IndexMap.h" +#include "octree/disk/Layout.h" +#include "octree/disk/layout/Strategy.h" +#include "octree/disk/layout/strategy/Default.h" + +namespace octree { +using Node = SimpleMesh; + +class Storage { +public: + explicit Storage(disk::Layout layout); + explicit Storage(IndexMap map, disk::Layout layout); + + std::optional read_node(const Id &id) const; + bool write_node(const Id &id, const Node &node) const; + bool has_node(const Id &id) const; + std::filesystem::path get_node_path(const Id &id) const; + + bool save_index() const; + +private: + std::optional _index; + disk::Layout _layout; +}; + +std::optional open_index(const std::filesystem::path &index_path); +Storage open_folder( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), + const std::string extension_with_dot = ".terrain", + bool save_index = true); + +} // namespace octree diff --git a/src/terrainlib/octree/disk/IndexFile.h b/src/terrainlib/octree/disk/IndexFile.h new file mode 100644 index 0000000..ef3b584 --- /dev/null +++ b/src/terrainlib/octree/disk/IndexFile.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +#include "octree/IndexMap.h" + +namespace octree::disk::v1 { + +inline constexpr std::string_view index_file_name() { + return "terrain.index"; +} + +struct IndexFile { + using serialize = zpp::bits::members<3>; + + std::string layout_strategy_id; + std::string preferred_extension; + IndexMap map; +}; +} diff --git a/src/terrainlib/octree/disk/Layout.h b/src/terrainlib/octree/disk/Layout.h new file mode 100644 index 0000000..dcd561f --- /dev/null +++ b/src/terrainlib/octree/disk/Layout.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include + +#include "octree/Id.h" +#include "octree/disk/layout/Strategy.h" + +namespace octree::disk { + +class Layout { +public: + Layout(std::filesystem::path base_path, std::unique_ptr strategy, std::string extension_with_dot = ".terrain") + : _base_path(std::move(base_path)), _strategy(std::move(strategy)), _extension_with_dot(std::move(extension_with_dot)) { + assert(!_extension_with_dot.empty() && _extension_with_dot[0] == '.'); + } + + std::filesystem::path get_node_path(Id id) const { + return this->_base_path / this->_strategy->get_relative_node_path(id, this->_extension_with_dot); + } + std::optional get_id_from_node_path(const std::filesystem::path& path) const { + const std::filesystem::path relative_path = std::filesystem::relative(path, _base_path); + return this->_strategy->get_id_from_relative_node_path(relative_path); + } + + const std::filesystem::path& base_path() const { + return this->_base_path; + } + const layout::Strategy &strategy() const { + return *this->_strategy; + } + std::string_view extension_with_dot() const { + return this->_extension_with_dot; + } + std::string_view extension() const { + return this->extension_with_dot().substr(1); + } + +private: + std::filesystem::path _base_path; + std::unique_ptr _strategy; + std::string _extension_with_dot; +}; + +} diff --git a/src/terrainlib/octree/disk/layout/Strategy.h b/src/terrainlib/octree/disk/layout/Strategy.h new file mode 100644 index 0000000..a1d5fb7 --- /dev/null +++ b/src/terrainlib/octree/disk/layout/Strategy.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +#include "octree/Id.h" + +namespace octree::disk::layout { + +class Strategy { +public: + virtual ~Strategy() = default; + + virtual std::filesystem::path get_relative_node_path(Id id, std::string_view extension_with_dot) const = 0; + virtual std::optional get_id_from_relative_node_path(const std::filesystem::path &relative_path) const = 0; +}; + +} diff --git a/src/terrainlib/octree/disk/layout/StrategyRegister.h b/src/terrainlib/octree/disk/layout/StrategyRegister.h new file mode 100644 index 0000000..026a44f --- /dev/null +++ b/src/terrainlib/octree/disk/layout/StrategyRegister.h @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "octree/disk/layout/Strategy.h" +#include "log.h" + +namespace octree::disk::layout { + +class StrategyRegister { +public: + using Factory = std::function()>; + + static StrategyRegister &instance() { + static StrategyRegister inst; + return inst; + } + + template + void register_strategy(const std::string &id) { + this->_factories[id] = [] { return std::make_unique(); }; + this->_type_to_id[std::type_index(typeid(T))] = id; + } + + std::unique_ptr create(const std::string &id) const { + auto it = this->_factories.find(id); + if (it != this->_factories.end()) { + return (it->second)(); + } + return nullptr; + } + + const std::unordered_map &factories() const { + return this->_factories; + } + + template + std::string get_id() const { + return this->_get_id(typeid(T)); + } + + std::string get_id(const Strategy &s) const { + return this->_get_id(typeid(s)); + } + +private: + std::unordered_map _factories; + std::unordered_map _type_to_id; + + // Private ctor/dtor to enforce singleton + StrategyRegister() = default; + ~StrategyRegister() = default; + StrategyRegister(const StrategyRegister &) = delete; + StrategyRegister &operator=(const StrategyRegister &) = delete; + + std::string _get_id(std::type_index type_index) const { + auto it = this->_type_to_id.find(type_index); + if (it != this->_type_to_id.end()) { + return it->second; + } + LOG_ERROR_AND_EXIT("Encountered octree layout strategy not registered"); + } +}; + +} // namespace octree::disk::layout + +#include "octree/disk/layout/strategy/Flat.h" +#include "octree/disk/layout/strategy/LevelAndCoordinateDirectories.h" + +namespace { +template +struct Registrar { + Registrar(const std::string &id) { + octree::disk::layout::StrategyRegister::instance().register_strategy(id); + } +}; + +const Registrar reg_flat("flat"); +const Registrar reg_lacd("level_and_coordinate_directories"); +} diff --git a/src/terrainlib/octree/disk/layout/strategy/Default.h b/src/terrainlib/octree/disk/layout/strategy/Default.h new file mode 100644 index 0000000..45c7842 --- /dev/null +++ b/src/terrainlib/octree/disk/layout/strategy/Default.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include "octree/disk/layout/strategy/LevelAndCoordinateDirectories.h" + +namespace octree::disk::layout::strategy { + +using Default = LevelAndCoordinateDirectories; + +inline std::unique_ptr make_default() { + return std::make_unique(); +} + +} // namespace octree::disk::layout::strategy diff --git a/src/terrainlib/octree/disk/layout/strategy/Flat.h b/src/terrainlib/octree/disk/layout/strategy/Flat.h new file mode 100644 index 0000000..30a64a5 --- /dev/null +++ b/src/terrainlib/octree/disk/layout/strategy/Flat.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include + +#include + +#include "octree/Id.h" +#include "octree/disk/layout/Strategy.h" +#include "string_utils.h" + +namespace octree::disk::layout::strategy { + +class Flat : public Strategy { +public: + std::filesystem::path get_relative_node_path(Id id, std::string_view extension_with_dot) const override { + return fmt::format("{}-{}{}", id.level(), id.index_on_level(), extension_with_dot); + } + + std::optional get_id_from_relative_node_path(const std::filesystem::path &relative_path) const override { + assert(relative_path.is_relative()); + + const std::string _filestem = relative_path.stem().string(); + const std::string_view filestem = _filestem; + + const size_t dash_pos = filestem.find('-'); + if (dash_pos == std::string::npos) { + return std::nullopt; + } + const std::string_view level_str = filestem.substr(0, dash_pos); + const std::string_view index_str = filestem.substr(dash_pos + 1); + + const auto level_opt = from_chars(level_str); + if (!level_opt) { + return std::nullopt; + } + + const auto index_opt = from_chars(index_str); + if (!index_opt) { + return std::nullopt; + } + + const Id::Level level = *level_opt; + const Id::Index index = *index_opt; + return Id::try_make(level, index); + } +}; + +} // namespace octree::disk::layout::strategy diff --git a/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h b/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h new file mode 100644 index 0000000..a5a19e3 --- /dev/null +++ b/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include + +#include + +#include "octree/Id.h" +#include "octree/disk/layout/Strategy.h" +#include "string_utils.h" + +namespace octree::disk::layout::strategy { + +class LevelAndCoordinateDirectories : public Strategy { +public: + std::filesystem::path get_relative_node_path(Id id, std::string_view extension_with_dot) const override { + const Id::Coords coords = id.coords(); + return fmt::format("{}/{}/{}/{}{}", id.level(), coords.x, coords.y, coords.z, extension_with_dot); + } + std::optional get_id_from_relative_node_path(const std::filesystem::path &relative_path) const override { + assert(relative_path.is_relative()); + + auto it = relative_path.begin(); + if (std::distance(it, relative_path.end()) < 4) { + return std::nullopt; + } + + const auto level_opt = from_chars(it->native()); + if (!level_opt) { + return std::nullopt; + } + const Id::Level level = *level_opt; + ++it; + + const auto x_opt = from_chars(it->native()); + if (!x_opt) { + return std::nullopt; + } + const Id::Coord x = *x_opt; + ++it; + + const auto y_opt = from_chars(it->native()); + if (!x_opt) { + return std::nullopt; + } + const Id::Coord y = *y_opt; + ++it; + + const auto z_opt = from_chars(it->stem().native()); + if (!x_opt) { + return std::nullopt; + } + const Id::Coord z = *z_opt; + + return Id::try_make(level, {x, y, z}); + } +}; + +} // namespace octree::disk::layout::strategy diff --git a/src/terrainlib/octree/storage.h b/src/terrainlib/octree/storage.h deleted file mode 100644 index fc20eae..0000000 --- a/src/terrainlib/octree/storage.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "id.h" -#include "mesh/io.h" -#include "mesh/SimpleMesh.h" - -namespace octree { -using Node = SimpleMesh; - -class Storage { - public: - Storage(const std::filesystem::path &base_path) : base_path(base_path) {} - - std::optional load_node(const Id &id) const { - const auto node_path = this->get_node_path(id); - const auto result = mesh::io::load_from_path(node_path); - if (result.has_value()) { - return result.value(); - } else { - return std::nullopt; - } - } - - bool save_node(const Id &id, const Node &node) const { - const auto node_path = this->get_node_path(id); - const auto result = mesh::io::save_to_path(node, node_path); - return result.has_value(); - } - - bool has_node(const Id &id) const { - return std::filesystem::exists(this->get_node_path(id)); - } - - private: - std::filesystem::path get_node_path(const Id &id, std::string_view ext = "glb") const { - if (!ext.empty() && ext.front() == '.') { - ext = ext.substr(1); // Remove leading dot - } - - return base_path - / std::to_string(id.level()) - / std::to_string(id.x()) - / std::to_string(id.y()) - / fmt::format("{}.{}", id.z(), ext); - } - - private: - const std::filesystem::path base_path; -}; -} diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h new file mode 100644 index 0000000..41e432c --- /dev/null +++ b/src/terrainlib/octree/traverse.h @@ -0,0 +1,61 @@ +#pragma once + +namespace octree { + +enum class TraversalOrder { + DepthFirst, + BreadthFirst +}; + +template < + typename VisitFn, + typename RefineFn = std::function> +void traverse( + const Storage &storage, + VisitFn visit_fn, + TraversalOrder order = TraversalOrder::DepthFirst, + RefineFn refine_fn = [](const Id &) { return true; }, + const Id &root = Id::root()) { + if (!storage.has_node(root)) { + return; + } + + if (order == TraversalOrder::DepthFirst) { + std::function dfs; + dfs = [&](const Id& id) { + if (!storage.has_node(id) || !filter_fn(id)) return; + + visit_fn(id); + + if (refine_fn(id)) { + for (const auto& child_id : id.children()) { + dfs(child_id); + } + } + }; + dfs(root_id); + + } else { // BreadthFirst + std::queue queue; + queue.push(root_id); + + while (!queue.empty()) { + Id current = queue.front(); + queue.pop(); + + if (!storage.has_node(current) || !filter_fn(current)) { + continue; + } + + visit_fn(current); + + if (refine_fn(current)) { + for (const auto& child_id : current.children()) { + queue.push(child_id); + } + } + } + } +} + +} // namespace octree diff --git a/src/terrainlib/octree/utils.h b/src/terrainlib/octree/utils.h index 4ce9706..ae6a487 100644 --- a/src/terrainlib/octree/utils.h +++ b/src/terrainlib/octree/utils.h @@ -3,39 +3,38 @@ #include #include -#include "octree/id.h" +#include "octree/Id.h" namespace octree { -void for_each_descendant_at_level(const Id &node, const Level target_level, const std::function &callback) { +void for_each_descendant_at_level(const Id &node, const Id::Level target_level, const std::function &callback) { if (target_level <= node.level()) { return; } - const Level level_diff = target_level - node.level(); - const Index start = node.index_on_level() << (3 * level_diff); - const Index count = Index(1) << (3 * level_diff); + const Id::Level level_diff = target_level - node.level(); + const Id::Index start = node.index_on_level() << (3 * level_diff); + const Id::Index count = Id::Index(1) << (3 * level_diff); - for (Index i = 0; i < count; ++i) { + for (Id::Index i = 0; i < count; ++i) { callback(Id(target_level, start + i)); } } -std::vector list_descendant_at_level(const Id &node, const Level target_level) { +std::vector list_descendant_at_level(const Id &node, const Id::Level target_level) { if (target_level <= node.level()) { return {}; } - const Level level_diff = target_level - node.level(); - const Index start = node.index_on_level() << (3 * level_diff); - const Index count = Index(1) << (3 * level_diff); + const Id::Level level_diff = target_level - node.level(); + const Id::Index start = node.index_on_level() << (3 * level_diff); + const Id::Index count = Id::Index(1) << (3 * level_diff); std::vector nodes; nodes.reserve(count); - for (Index i = 0; i < count; ++i) { + for (Id::Index i = 0; i < count; ++i) { nodes.emplace_back(target_level, start + i); } return nodes; } - } diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index f3fe591..0c6d932 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -33,6 +33,11 @@ namespace srs { +inline std::unique_ptr clone(const OGRSpatialReference &srs) { + auto cloned = srs.Clone(); + return std::unique_ptr(cloned); +} + inline std::unique_ptr transformation(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs) { auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&source_srs, &target_srs)); if (!transformer) { @@ -209,14 +214,9 @@ inline radix::geometry::Aabb3d non_exact_bounds_transform(const radix::geometry: /// Transforms bounds from one srs to another, /// in such a way that all points inside the original bounds are guaranteed to also be in the new bounds. /// But there can be points inside the new bounds that were not present in the original ones. -inline radix::tile::SrsBounds encompassing_bounds_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { - if (source_srs.IsSame(&target_srs)) { - return source_bounds; - } - - const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); +inline radix::tile::SrsBounds encompassing_bounds_transfer(OGRCoordinateTransformation *transform, const radix::tile::SrsBounds &source_bounds) { radix::tile::SrsBounds target_bounds; - const int result = transformation->TransformBounds( + const int result = transform->TransformBounds( source_bounds.min.x, source_bounds.min.y, source_bounds.max.x, source_bounds.max.y, &target_bounds.min.x, &target_bounds.min.y, &target_bounds.max.x, &target_bounds.max.y, 21); @@ -225,17 +225,20 @@ inline radix::tile::SrsBounds encompassing_bounds_transfer(const OGRSpatialRefer } return target_bounds; } +inline radix::tile::SrsBounds encompassing_bounds_transfer(const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs, const radix::tile::SrsBounds &source_bounds) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + const std::unique_ptr transformation = srs::transformation(source_srs, target_srs); + return encompassing_bounds_transfer(transformation.get(), source_bounds); +} inline radix::geometry::Aabb3d encompassing_bounds_transfer( - const OGRSpatialReference &source_srs, - const OGRSpatialReference &target_srs, + OGRCoordinateTransformation *transform, const radix::geometry::Aabb3d &source_bounds, const uint32_t intermediate_points_edges = 21, const uint32_t intermediate_points_faces = 5) { - if (source_srs.IsSame(&target_srs)) { - return source_bounds; - } - std::vector points; // Add corner points @@ -274,8 +277,7 @@ inline radix::geometry::Aabb3d encompassing_bounds_transfer( } // Transform all collected points - const auto transform = srs::transformation(source_srs, target_srs); - transform_points_inplace(transform.get(), points); + transform_points_inplace(transform, points); // Compute bounds from transformed points radix::geometry::Aabb3d target_bounds; @@ -287,6 +289,19 @@ inline radix::geometry::Aabb3d encompassing_bounds_transfer( return target_bounds; } +inline radix::geometry::Aabb3d encompassing_bounds_transfer( + const OGRSpatialReference &source_srs, + const OGRSpatialReference &target_srs, + const radix::geometry::Aabb3d &source_bounds, + const uint32_t intermediate_points_edges = 21, + const uint32_t intermediate_points_faces = 5) { + if (source_srs.IsSame(&target_srs)) { + return source_bounds; + } + + const auto transform = srs::transformation(source_srs, target_srs); + return encompassing_bounds_transfer(transform.get(), source_bounds, intermediate_points_edges, intermediate_points_faces); +} inline tl::expected from_epsg(const uint32_t epsg) { OGRSpatialReference srs; diff --git a/src/terrainlib/string_utils.h b/src/terrainlib/string_utils.h new file mode 100644 index 0000000..ead1521 --- /dev/null +++ b/src/terrainlib/string_utils.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +template +std::optional from_chars(std::basic_string_view sv) { + static_assert(std::is_integral_v, "T must be an integral type"); + + if constexpr (std::is_same_v) { + T value; + auto [ptr, ec] = std::from_chars(sv.data(), sv.data() + sv.size(), value); + if (ec != std::errc()) + return std::nullopt; + return value; + } else { + std::string utf8(sv.begin(), sv.end()); + return from_chars(utf8); + } +} + +template +std::optional from_chars(const std::basic_string& s) { + const std::basic_string_view sv = s; + return from_chars(sv); +} diff --git a/src/terrainlib/type_utils.h b/src/terrainlib/type_utils.h new file mode 100644 index 0000000..fd93311 --- /dev/null +++ b/src/terrainlib/type_utils.h @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +// modified from https://stackoverflow.com/questions/1055452/c-get-name-of-type-in-template/59522794#59522794 +namespace { +template +[[nodiscard]] constexpr std::string_view function_signature() { +#ifndef _MSC_VER + return __PRETTY_FUNCTION__; +#else + return __FUNCSIG__; +#endif +} + +struct TypeNameFormat { + std::size_t junk_leading = 0; + std::size_t junk_total = 0; +}; + +constexpr TypeNameFormat type_name_format = [] { + TypeNameFormat ret; + std::string_view sample = function_signature(); + ret.junk_leading = sample.find("int"); + ret.junk_total = sample.size() - 3; + return ret; +}(); +static_assert(type_name_format.junk_leading != std::size_t(-1), "Unable to determine the type name format on this compiler."); + +template +static constexpr auto type_name_storage = [] { + std::array().size() - type_name_format.junk_total + 1> ret{}; + std::copy_n(function_signature().data() + type_name_format.junk_leading, ret.size() - 1, ret.data()); + return ret; +}(); +} + +template +[[nodiscard]] constexpr std::string_view type_name() { + return {type_name_storage.data(), type_name_storage.size() - 1}; +} + +template +[[nodiscard]] constexpr const char *type_name_c() { + return type_name_storage.data(); +} \ No newline at end of file diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index eb55c8b..9109e60 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -15,7 +15,7 @@ std::vector load_meshes_from_path(std::span Date: Fri, 23 May 2025 22:53:10 +0200 Subject: [PATCH 048/122] Fix path to string conversion on windows. --- src/terrainlib/mesh/io/gltf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terrainlib/mesh/io/gltf.cpp b/src/terrainlib/mesh/io/gltf.cpp index b6b867c..881da88 100644 --- a/src/terrainlib/mesh/io/gltf.cpp +++ b/src/terrainlib/mesh/io/gltf.cpp @@ -682,7 +682,7 @@ tl::expected save_to_path( if (binary_output) { gltf_options.type = cgltf_file_type_glb; } - if (cgltf_write_file(&gltf_options, path.c_str(), &data) != cgltf_result_success) { + if (cgltf_write_file(&gltf_options, path.string().c_str(), &data) != cgltf_result_success) { throw std::runtime_error("Failed to save GLTF file"); } From 5637fbaf9c6929d2461be6405e1972418053262a Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Fri, 23 May 2025 22:54:18 +0200 Subject: [PATCH 049/122] Integrate browser into monorepo CMake. --- src/CMakeLists.txt | 59 ++++- src/browser/CMakeLists.txt | 140 ------------ src/browser/core/Application.cpp | 20 +- src/browser/core/Buffer.cpp | 10 +- src/browser/core/Camera.cpp | 2 +- src/browser/core/octree/id.h | 203 ------------------ src/browser/core/octree/space.h | 125 ----------- src/browser/core/octree/storage.h | 46 ---- .../rendering/OctreeRenderManager.cpp | 76 ++++--- .../rendering/OctreeRenderManager.h | 28 ++- .../core/shader/GLUniformAbstractions.h | 1 + src/browser/core/shader/Shader.cpp | 8 +- src/browser/core/shader/ShaderProgram.cpp | 14 +- src/browser/core/window/Window.cpp | 20 +- src/browser/core/window/Window.h | 1 + src/browser/main.cpp | 15 +- src/browser/utils/log/Log.cpp | 22 -- src/browser/utils/log/Log.h | 72 ------- 18 files changed, 173 insertions(+), 689 deletions(-) delete mode 100644 src/browser/CMakeLists.txt delete mode 100644 src/browser/core/octree/id.h delete mode 100644 src/browser/core/octree/space.h delete mode 100644 src/browser/core/octree/storage.h rename src/browser/core/{octree => }/rendering/OctreeRenderManager.cpp (80%) rename src/browser/core/{octree => }/rendering/OctreeRenderManager.h (70%) delete mode 100644 src/browser/utils/log/Log.cpp delete mode 100644 src/browser/utils/log/Log.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85ceefb..5d9a63c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH add_library(Eigen3 INTERFACE) target_include_directories(Eigen3 INTERFACE ${eigen_SOURCE_DIR}) -alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF "-DBOOST_INCLUDE_LIBRARIES='graph'") +alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF "-DBOOST_INCLUDE_LIBRARIES='graph\;multiprecision\;heap\;format'") find_package(Boost CONFIG REQUIRED) include(../cmake/SetupGDAL.cmake) @@ -58,6 +58,39 @@ target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) +# Don't build glfw docs, tests and examples +set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +if (UNIX) + # Enable Wayland and X11 on Unix builds + set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) + set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) +endif (UNIX) +alp_add_git_repository(glfw URL https://github.com/glfw/glfw.git COMMITISH e7ea71be039836da3a98cea55ae5569cb5eb885c NOT_SYSTEM) + +alp_add_git_repository(glad URL https://github.com/Dav1dde/glad.git COMMITISH 431786d8126e4f383a81e36f47b61a5d52a1c20d DO_NOT_ADD_SUBPROJECT) +add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) +glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) + +alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237 NOT_SYSTEM) +add_subdirectory(browser/res) + +alp_add_git_repository(imgui URL https://github.com/ocornut/imgui.git COMMITISH 5f0acadf7db1b6d469f0771284e2e3f7818443ce DO_NOT_ADD_SUBPROJECT) +add_library(imgui STATIC + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp +) +target_include_directories(imgui PUBLIC + ${imgui_SOURCE_DIR} + ${imgui_SOURCE_DIR}/backends +) +target_link_libraries(imgui PUBLIC glfw) + add_library(terrainlib terrainlib/ctb/CTBException.hpp terrainlib/ctb/GlobalGeodetic.hpp terrainlib/ctb/GlobalGeodetic.cpp @@ -146,3 +179,27 @@ add_executable(terrainconvert terrainconvert/main.cpp ) target_link_libraries(terrainconvert PUBLIC terrainlib CLI11::CLI11) + +add_executable(browser + # browser/main2.cpp + + browser/main.cpp + + browser/core/Application.cpp + browser/core/window/Window.cpp + browser/core/shader/Shader.cpp + browser/core/shader/ShaderProgram.cpp + browser/core/shader/Uniform.h + browser/core/shader/GLUniformAbstractions.h + browser/core/Buffer.cpp + browser/core/Camera.cpp + + browser/core/geometry/UnitCube.h + + browser/core/rendering/OctreeRenderManager.cpp +) + +#target_compile_features(browser PRIVATE cxx_std_20) +#target_compile_options(browser PRIVATE /utf-8) +target_include_directories(browser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/browser) +target_link_libraries(browser PUBLIC terrainlib glfw glad_gl_core_46 resources-lib imgui) \ No newline at end of file diff --git a/src/browser/CMakeLists.txt b/src/browser/CMakeLists.txt deleted file mode 100644 index e6b1e2d..0000000 --- a/src/browser/CMakeLists.txt +++ /dev/null @@ -1,140 +0,0 @@ -include(FetchContent) - -if(NOT TARGET glm) - FetchContent_Declare(glm - GIT_REPOSITORY https://github.com/g-truc/glm - GIT_TAG master - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glm - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - message(STATUS "Including glm") - FetchContent_MakeAvailable(glm) -endif() - -if(NOT TARGET glfw) - FetchContent_Declare(glfw - GIT_REPOSITORY https://github.com/glfw/glfw - GIT_TAG master - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glfw - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - - # Don't build glfw docs, tests and examples - set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) - set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) - set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) - - if (UNIX) - # Disable Wayland and enable X11 - set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) - set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) - endif (UNIX) - - message(STATUS "Including glfw") - FetchContent_MakeAvailable(glfw) -endif() - -if(NOT TARGET glad_gl_core_46) - FetchContent_Declare(glad - GIT_REPOSITORY https://github.com/Dav1dde/glad - GIT_TAG glad2 - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/glad - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - message(STATUS "Including glad") - FetchContent_MakeAvailable(glad) - - # Generate glad/gl.h for OpenGL 4.6 - set(GLAD_SOURCES_DIR "${PROJECT_SOURCE_DIR}/3rdparty/glad") - add_subdirectory("${GLAD_SOURCES_DIR}/cmake" glad_cmake) - glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) -endif() - -if(NOT TARGET resources-lib) - FetchContent_Declare(CMakeRC - GIT_REPOSITORY https://github.com/vector-of-bool/cmrc.git - GIT_TAG master - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/CMakeRC - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - message(STATUS "Including CMakeRC") - FetchContent_MakeAvailable(CMakeRC) - - add_subdirectory(res) -endif() - -if(NOT TARGET spdlog) - FetchContent_Declare(spdlog - GIT_REPOSITORY https://github.com/gabime/spdlog.git - GIT_TAG v1.x - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/spdlog - GIT_PROGRESS TRUE - USES_TERMINAL_DOWNLOAD TRUE - ) - message(STATUS "Including spdlog") - FetchContent_MakeAvailable(spdlog) -endif() - -if(NOT TARGET radix) - FetchContent_Declare(radix - GIT_REPOSITORY https://github.com/AlpineMapsOrg/radix.git - GIT_TAG origin/main - SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/radix - SOURCE_SUBDIR src - ) - message(STATUS "Including radix") - FetchContent_MakeAvailable(radix) -endif() - -if(NOT TARGET imgui) - SET(IMGUI_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/imgui) - FetchContent_Declare(imgui - GIT_REPOSITORY https://github.com/ocornut/imgui.git - GIT_TAG origin/master - SOURCE_DIR ${IMGUI_SOURCE_DIR} - ) - message(STATUS "Including imgui") - #FetchContent_MakeAvailable(imgui) - - add_library(imgui STATIC - ${IMGUI_SOURCE_DIR}/imgui.cpp - ${IMGUI_SOURCE_DIR}/imgui_draw.cpp - ${IMGUI_SOURCE_DIR}/imgui_demo.cpp # TODO: Remove after use - ${IMGUI_SOURCE_DIR}/imgui_tables.cpp - ${IMGUI_SOURCE_DIR}/imgui_widgets.cpp - ${IMGUI_SOURCE_DIR}/backends/imgui_impl_glfw.cpp - ${IMGUI_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp - ) - target_include_directories(imgui PUBLIC - ${IMGUI_SOURCE_DIR} - ${IMGUI_SOURCE_DIR}/backends - ) - target_link_libraries(imgui PUBLIC glfw) -endif() - -add_executable(alpenite-browser - main.cpp - - core/Application.cpp - core/window/Window.cpp - core/shader/Shader.cpp - core/shader/ShaderProgram.cpp - core/shader/Uniform.h - core/shader/GLUniformAbstractions.h - core/Buffer.cpp - core/Camera.cpp - - utils/log/Log.cpp - - core/geometry/UnitCube.h - - core/octree/id.h - core/octree/space.h - "core/octree/rendering/OctreeRenderManager.cpp" -) -target_link_libraries(alpenite-browser PRIVATE glad_gl_core_46 glfw glm resources-lib spdlog radix imgui) -target_include_directories(alpenite-browser PRIVATE .) \ No newline at end of file diff --git a/src/browser/core/Application.cpp b/src/browser/core/Application.cpp index a870347..4c7eb5c 100644 --- a/src/browser/core/Application.cpp +++ b/src/browser/core/Application.cpp @@ -1,6 +1,8 @@ #include "Application.h" -#include "utils/log/Log.h" #include + +#include + #include // CMRC Resource Compiler @@ -16,7 +18,7 @@ #include "Camera.h" #include "geometry/UnitCube.h" #include "octree/space.h" -#include "octree/rendering/OctreeRenderManager.h" +#include "rendering/OctreeRenderManager.h" CMRC_DECLARE(res); @@ -363,11 +365,11 @@ void Application::init_glad() { // Load OpenGL functions, gladLoadGL returns the loaded version, 0 on error. int version = gladLoadGL(glfwGetProcAddress); if (version == 0) { - LOG_GL_FATAL_AND_EXIT("Failed to initialize OpenGL context"); + LOG_ERROR_AND_EXIT("Failed to initialize OpenGL context"); } // Successfully loaded OpenGL - LOG_GL_INFO("Loaded OpenGL {0}.{1}", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version)); + LOG_INFO("Loaded OpenGL {0}.{1}", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version)); } void Application::init_gl() { @@ -679,23 +681,23 @@ void Application::gl_debug_callback(GLenum source, GLenum type, switch (severity) { case GL_DEBUG_SEVERITY_HIGH: { - LOG_GL_ERROR(stringStream.str()); + LOG_ERROR(stringStream.str()); break; } case GL_DEBUG_SEVERITY_MEDIUM: { - LOG_GL_WARN(stringStream.str()); + LOG_WARN(stringStream.str()); break; } case GL_DEBUG_SEVERITY_LOW: { - LOG_GL_INFO(stringStream.str()); + LOG_INFO(stringStream.str()); break; } case GL_DEBUG_SEVERITY_NOTIFICATION: { - LOG_GL_DEBUG(stringStream.str()); + LOG_DEBUG(stringStream.str()); break; } default: { - LOG_GL_TRACE(stringStream.str()); + LOG_TRACE(stringStream.str()); break; } } diff --git a/src/browser/core/Buffer.cpp b/src/browser/core/Buffer.cpp index 54c9171..84c82d4 100644 --- a/src/browser/core/Buffer.cpp +++ b/src/browser/core/Buffer.cpp @@ -1,5 +1,5 @@ #include "Buffer.h" -#include +#include Buffer::Buffer(GLenum target = GL_ARRAY_BUFFER, GLenum usage = GL_STATIC_DRAW) : m_target(target), m_usage(usage) { glCreateBuffers(1, &m_handle); @@ -7,14 +7,14 @@ Buffer::Buffer(GLenum target = GL_ARRAY_BUFFER, GLenum usage = GL_STATIC_DRAW) : GLuint Buffer::handle() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried getting handle of Buffer with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried getting handle of Buffer with invalid handle!"); } return GLuint(); } void Buffer::bind() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried binding Buffer with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried binding Buffer with invalid handle!"); } glBindBuffer(m_target, m_handle); @@ -22,7 +22,7 @@ void Buffer::bind() { void Buffer::set_data(const void* data, const size_t size) { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried setting data to Buffer with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried setting data to Buffer with invalid handle!"); } glNamedBufferData(m_handle, size, data, m_usage); @@ -30,7 +30,7 @@ void Buffer::set_data(const void* data, const size_t size) { Buffer::~Buffer() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried destructing Buffer with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried destructing Buffer with invalid handle!"); } glDeleteBuffers(1, &m_handle); } diff --git a/src/browser/core/Camera.cpp b/src/browser/core/Camera.cpp index 6bcaee6..7483f75 100644 --- a/src/browser/core/Camera.cpp +++ b/src/browser/core/Camera.cpp @@ -1,5 +1,5 @@ #include "Camera.h" -#include +#include Camera::Camera(CameraConfig config) : m_fov_deg(config.fov_deg), diff --git a/src/browser/core/octree/id.h b/src/browser/core/octree/id.h deleted file mode 100644 index 0c8b454..0000000 --- a/src/browser/core/octree/id.h +++ /dev/null @@ -1,203 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace octree { - -using Level = uint32_t; -using Coord = uint32_t; -using Coords = glm::tvec3; -using Index = uint64_t; - -class Id { -public: - [[nodiscard]] static constexpr Level max_level() { - return (sizeof(Index) * 8) / 3; - } - [[nodiscard]] static constexpr Coord max_coord_on_level(const Level level) { - return (1ull << level) - 1; - } - [[nodiscard]] static constexpr Index max_index_on_level(const Level level) { - return (1ull << (3 * level)) - 1; - } - - constexpr Id(const Level level, const Coords coords) - : Id(level, interleave3(coords)) { - } - constexpr Id(const Level level, const Index index) - : _level(level), _index(index) { - assert(level <= Id::max_level()); - assert(index <= Id::max_index_on_level(this->_level)); - } - - [[nodiscard]] constexpr Level level() const { - return this->_level; - } - [[nodiscard]] constexpr Index index_on_level() const { - return this->_index; - } - [[nodiscard]] constexpr Coords coords() const { - return deinterleave3(this->index_on_level()); - } - [[nodiscard]] constexpr Coord x() const { - return this->coords().x; - } - [[nodiscard]] constexpr Coord y() const { - return this->coords().y; - } - [[nodiscard]] constexpr Coord z() const { - return this->coords().z; - } - - [[nodiscard]] constexpr std::optional neighbour(const glm::ivec3& d) const { - const Coord max_coord = Id::max_coord_on_level(this->level()); - const glm::ivec3 new_coords = glm::ivec3(this->coords()) + d; - if (glm::any(glm::lessThan(new_coords, glm::ivec3(0))) || glm::any(glm::greaterThan(new_coords, glm::ivec3(max_coord)))) { - return std::nullopt; - } - return Id(this->level(), Coords(new_coords)); - } - - [[nodiscard]] std::vector neighbours() const { - std::vector result; - result.reserve(26); - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - for (int dz = -1; dz <= 1; dz++) { - if (dx == 0 && dy == 0 && dz == 0) { - continue; // Skip the center itself - } - - const glm::ivec3 offset(dx, dy, dz); - const auto neighbour = this->neighbour({dx, dy, dz}); - if (!neighbour.has_value()) { - continue; - } - result.push_back(neighbour.value()); - } - } - } - return result; - } - - [[nodiscard]] constexpr std::optional parent() const { - if (this->level() == 0) { - return std::nullopt; - } - - const auto parent_coords = this->coords() / Coords(2); - return Id(this->level() - 1, parent_coords); - } - - [[nodiscard]] constexpr std::optional child(uint32_t child_index) const { - if (child_index > 7) { - throw std::invalid_argument("Invalid child index (must be 0-7)"); - } - if (!this->has_children()) { - return std::nullopt; - } - return this->_child(child_index); - } - - [[nodiscard]] constexpr std::optional> children() const { - if (!this->has_children()) { - return std::nullopt; - } - return std::array{ - this->_child(0), this->_child(1), this->_child(2), this->_child(3), - this->_child(4), this->_child(5), this->_child(6), this->_child(7)}; - } - - [[nodiscard]] constexpr bool has_children() const { - return this->level() < Id::max_level(); - } - - [[nodiscard]] constexpr bool is_root() const { - return this->level() == 0; - } - - [[nodiscard]] static constexpr Id root() { - return Id(0, 0); - } - - bool operator==(const Id &other) const { - return this->_level == other._level && this->_index == other._index; - } - -private: - Level _level; - Index _index; - - [[nodiscard]] constexpr Id _child(const uint32_t child_index) const { - assert(child_index <= 7); - return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); - } - - [[nodiscard]] static constexpr Index interleave3(const Coords &coords) { - assert(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); - - const Index x = coords.x; - const Index y = coords.y; - const Index z = coords.z; - - Index result = 0; - for (Level i = 0; i < Id::max_level(); i++) { - result |= ((x >> i) & 1) << (3 * i); - result |= ((y >> i) & 1) << (3 * i + 1); - result |= ((z >> i) & 1) << (3 * i + 2); - } - return result; - } - - [[nodiscard]] static constexpr Coords deinterleave3(Index index) { - Coord x = 0; - Coord y = 0; - Coord z = 0; - for (Level i = 0; i < Id::max_level(); i++) { - x |= ((index >> (3 * i)) & 1) << i; - y |= ((index >> (3 * i + 1)) & 1) << i; - z |= ((index >> (3 * i + 2)) & 1) << i; - } - return {x, y, z}; - } -}; - -} // namespace octree - -//#include -//#include -//template <> -//struct fmt::formatter { -// // Parses format specifications; here we ignore them. -// template -// constexpr auto parse(ParseContext &ctx) { -// return ctx.begin(); -// } -// -// // Format the Id object. -// template -// auto format(const octree::Id &id, FormatContext &ctx) { -// return fmt::format_to( -// ctx.out(), -// "Id(level={}, coords=({}, {}, {}), index={})", -// id.level(), id.x(), id.y(), id.z(), id.index_on_level()); -// } -//}; -// -//#include -//#include -//namespace octree{ -//inline std::string to_string(const octree::Id &id) { -// return fmt::format("{}", id); -//} -//inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { -// fmt::print(os, "{}", id); -// return os; -//} -//} diff --git a/src/browser/core/octree/space.h b/src/browser/core/octree/space.h deleted file mode 100644 index 1dc4841..0000000 --- a/src/browser/core/octree/space.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include - -#include "id.h" -#include -#include -#include - -namespace octree { -using Bounds = radix::geometry::Aabb3d; - -class Space { -public: - const Bounds bounds; - - static constexpr Space earth() { - const double max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) - const double extends = max_radius * 1.1; // TODO: how much padding do we want here - return Space(Bounds( - {-extends, -extends, -extends}, {extends, extends, extends})); - } - - std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { - // We don't want to recurse indefinitely if the bounds are empty. - const glm::dvec3 target_size = target_bounds.size(); - if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { - throw std::invalid_argument("target bounds cannot be empty"); - } - - const std::array corners = radix::geometry::corners(target_bounds); - - const Bounds root_bounds = get_node_bounds(root); - // Check if all points of the target bounds are inside the root bounds. - bool all_corners_inside_root = true; - for (const auto &corner : corners) { - if (!root_bounds.contains_inclusive(corner)) { - all_corners_inside_root = false; - break; - } - } - - if (!all_corners_inside_root) { - return std::nullopt; // Target bounds are outside the defined space. - } - - Id current_smallest_encompassing_node = root; - while (current_smallest_encompassing_node.has_children()) { - const std::array children = current_smallest_encompassing_node.children().value(); - std::optional next_smallest; - - for (const auto &child : children) { - const Bounds child_bounds = get_node_bounds(child); - bool all_corners_inside_child = true; - for (const auto &corner : corners) { - if (!child_bounds.contains_inclusive(corner)) { - all_corners_inside_child = false; - break; - } - } - - if (all_corners_inside_child) { - next_smallest = child; - break; // Found a child that fully contains the bounds, go deeper. - } - } - - if (next_smallest.has_value()) { - current_smallest_encompassing_node = next_smallest.value(); - } else { - break; // No child fully contains the bounds, so the current node is the smallest. - } - } - - return current_smallest_encompassing_node; - } - - std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { - assert(target_level <= Id::max_level()); - - Id current = root; - const Bounds root_bounds = this->get_node_bounds(current); - if (!root_bounds.contains_exclusive(point)) { - return std::nullopt; - } - - while (current.level() < target_level && current.has_children()) { - for (const auto& child : current.children().value()) { - const Bounds child_bounds = this->get_node_bounds(child); - if (child_bounds.contains_exclusive(point)) { - current = child; - break; - } - } - } - - return current; - } - - Bounds get_node_bounds(const Id &id) const { - const auto coords = id.coords(); - const uint32_t level = id.level(); - const uint32_t resolution = 1 << level; - - // Calculate the size of a node at this level - const glm::dvec3 bounds_size = bounds.size(); - const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); - - // Calculate the minimum point of the node - const glm::dvec3 min_bound = bounds.min; - const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; - - // Calculate the maximum point of the node - const glm::dvec3 node_max = node_min + node_size; - - Bounds node_bounds; - node_bounds.min = node_min; - node_bounds.max = node_max; - return node_bounds; - } - -private: -}; - -} // namespace octree diff --git a/src/browser/core/octree/storage.h b/src/browser/core/octree/storage.h deleted file mode 100644 index bb8831b..0000000 --- a/src/browser/core/octree/storage.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "id.h" -#include "mesh/io.h" -#include "mesh/terrain_mesh.h" - -namespace octree { -using Node = TerrainMesh; - -class Storage { - public: - Storage(const std::filesystem::path &basePath) : base_path(basePath) {} - - std::optional load_node(const Id &id) const { - const auto node_path = this->get_node_path(id); - const auto result = io::load_mesh_from_path(node_path); - if (result.has_value()) { - return result.value(); - } else { - return std::nullopt; - } - } - - bool save_node(const Id &id, const Node &node) const { - const auto node_path = this->get_node_path(id); - const auto result = io::save_mesh_to_path(node_path, node); - return result.has_value(); - } - - bool has_node(const Id &id) const { - return std::filesystem::exists(this->get_node_path(id)); - } - - private: - std::filesystem::path get_node_path(const Id &id) const { - return base_path / std::to_string(id.level()) / std::to_string(id.x()) / (std::to_string(id.y()) + ".gltf"); - } - - private: - const std::filesystem::path base_path; -}; -} diff --git a/src/browser/core/octree/rendering/OctreeRenderManager.cpp b/src/browser/core/rendering/OctreeRenderManager.cpp similarity index 80% rename from src/browser/core/octree/rendering/OctreeRenderManager.cpp rename to src/browser/core/rendering/OctreeRenderManager.cpp index d2e24bb..0e04ead 100644 --- a/src/browser/core/octree/rendering/OctreeRenderManager.cpp +++ b/src/browser/core/rendering/OctreeRenderManager.cpp @@ -1,11 +1,14 @@ #include "OctreeRenderManager.h" +#include -namespace octree { - OctreeRenderManager::OctreeRenderManager(octree::Space space) : m_space(space) { +namespace octree +{ + OctreeRenderManager::OctreeRenderManager(octree::Space space) : m_space(space) + { } - - OctreeRenderIntent OctreeRenderManager::generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only, float refining_ratio = 1.0f) { + OctreeRenderIntent OctreeRenderManager::generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only, float refining_ratio = 1.0f) + { // refining_ratio defines under which ratio between dist(cam, node_bbox_centre) / node_bbox_size the node is split // I.e.: dist = 2000 and node_bbox_size = 4000 -> ratio = 0.5 -> node would get refined @@ -22,8 +25,8 @@ namespace octree { std::optional closest; std::optional farthest; - - while (!refining_ids.empty()) { + while (!refining_ids.empty()) + { Id current = refining_ids.back(); refining_ids.pop_back(); @@ -32,30 +35,37 @@ namespace octree { double current_distance = glm::distance(current_bounds.centre(), cam_pos); double current_ratio = current_distance / glm::length(current_bounds.size()); - //LOG_DEBUG("DIST: {}, RATIO: {}", distance, current_ratio); + // LOG_DEBUG("DIST: {}, RATIO: {}", distance, current_ratio); - if (current_ratio <= refining_ratio && current.has_children()) { + if (current_ratio <= refining_ratio && current.has_children()) + { // Split node into 8 children, and add them to the refining list - for (Id child : current.children().value()) { + for (Id child : current.children().value()) + { refining_ids.push_back(child); } - } else { + } + else + { // Don't split. Check whether to render this node bool is_current_closest = false; bool is_current_farthest = false; - if (current_distance < closest_distance) { + if (current_distance < closest_distance) + { closest_distance = current_distance; is_current_closest = true; closest = current; } - if (current_distance > farthest_distance) { + if (current_distance > farthest_distance) + { farthest_distance = current_distance; is_current_farthest = true; farthest = current; } - if (!draw_neighbours_only) { + if (!draw_neighbours_only) + { glm::dmat4 model_scale = glm::scale(glm::dmat4(1.0f), current_bounds.size()); glm::dmat4 model_translate = glm::translate(glm::dmat4(1.0f), current_bounds.centre() - cam_pos); glm::mat4 model = model_translate * model_scale; @@ -63,16 +73,21 @@ namespace octree { instance_active.push_back(0.0f); instance_models.push_back(glm::mat4(model)); - if (is_current_closest) { + if (is_current_closest) + { // The current node, is the closest to this point. Mark it as active and mark the previous closest (if any) as inactive - if (closest_index.has_value()) { + if (closest_index.has_value()) + { instance_active[closest_index.value()] = 0.0f; } closest_index = instance_active.size() - 1; instance_active[closest_index.value()] = 1.0f; } - } else { - if (is_current_closest) { + } + else + { + if (is_current_closest) + { // The current node, is the closest to this point. Delete all nodes in the list instance_active.clear(); @@ -89,7 +104,8 @@ namespace octree { instance_active.push_back(1.0f); instance_models.push_back(glm::mat4(model)); - for (auto neighbour : current.neighbours()) { + for (auto neighbour : current.neighbours()) + { Bounds neighbour_bounds = m_space.get_node_bounds(neighbour); double neighbour_distance = glm::distance(neighbour_bounds.centre(), cam_pos); @@ -101,11 +117,13 @@ namespace octree { instance_active.push_back(0.0f); instance_models.push_back(glm::mat4(neighbour_model)); - if (neighbour_distance < closest_distance) { + if (neighbour_distance < closest_distance) + { closest_distance = current_distance; closest = neighbour; } - if (neighbour_distance > farthest_distance) { + if (neighbour_distance > farthest_distance) + { farthest_distance = current_distance; farthest = neighbour; } @@ -121,23 +139,29 @@ namespace octree { .instance_count = instance_models.size(), }; - if (closest.has_value()) { + if (closest.has_value()) + { rendering_intent.closest_node = closest; rendering_intent.min_scene_distance = std::numeric_limits::infinity(); - for (glm::dvec3 closest_corner : radix::geometry::corners(m_space.get_node_bounds(closest.value()))) { + for (glm::dvec3 closest_corner : radix::geometry::corners(m_space.get_node_bounds(closest.value()))) + { double dist = glm::distance(closest_corner, cam_pos); - if (dist < rendering_intent.min_scene_distance) { + if (dist < rendering_intent.min_scene_distance) + { rendering_intent.min_scene_distance = dist; } } } - if (farthest.has_value()) { + if (farthest.has_value()) + { rendering_intent.max_scene_distance = 0; - for (glm::dvec3 farthest_corner : radix::geometry::corners(m_space.get_node_bounds(farthest.value()))) { + for (glm::dvec3 farthest_corner : radix::geometry::corners(m_space.get_node_bounds(farthest.value()))) + { double dist = glm::distance(farthest_corner, cam_pos); - if (dist > rendering_intent.max_scene_distance) { + if (dist > rendering_intent.max_scene_distance) + { rendering_intent.max_scene_distance = dist; } } diff --git a/src/browser/core/octree/rendering/OctreeRenderManager.h b/src/browser/core/rendering/OctreeRenderManager.h similarity index 70% rename from src/browser/core/octree/rendering/OctreeRenderManager.h rename to src/browser/core/rendering/OctreeRenderManager.h index 52f71c8..9258ca1 100644 --- a/src/browser/core/octree/rendering/OctreeRenderManager.h +++ b/src/browser/core/rendering/OctreeRenderManager.h @@ -1,13 +1,14 @@ #pragma once -#include "../space.h" -#include "../id.h" +#include "octree/id.h" +#include "octree/space.h" #include +#include -namespace octree { +namespace octree +{ - - - struct OctreeRenderIntent { + struct OctreeRenderIntent + { std::vector instances_active; std::vector instances_model_mats; size_t instance_count; @@ -15,31 +16,36 @@ namespace octree { std::optional min_scene_distance; std::optional max_scene_distance; - std::optional closest_node; + std::optional closest_node; }; - enum OctreeFilterParamType { + enum OctreeFilterParamType + { Float, Double }; - struct OctreeFilterParam { + struct OctreeFilterParam + { std::string name; OctreeFilterParamType type; std::any default_value; std::string description; }; - struct OctreeFilterDefinition { + struct OctreeFilterDefinition + { std::string name; std::string description; }; - class OctreeRenderManager { + class OctreeRenderManager + { public: OctreeRenderManager(Space space); OctreeRenderIntent generate_octree_render_intent(const Id root, glm::dvec3 cam_pos, bool draw_neighbours_only, float refining_ratio); + private: octree::Space m_space; }; diff --git a/src/browser/core/shader/GLUniformAbstractions.h b/src/browser/core/shader/GLUniformAbstractions.h index 0041fd2..6697748 100644 --- a/src/browser/core/shader/GLUniformAbstractions.h +++ b/src/browser/core/shader/GLUniformAbstractions.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace { // vectors diff --git a/src/browser/core/shader/Shader.cpp b/src/browser/core/shader/Shader.cpp index a293eac..a569426 100644 --- a/src/browser/core/shader/Shader.cpp +++ b/src/browser/core/shader/Shader.cpp @@ -1,5 +1,5 @@ #include "Shader.h" -#include +#include Shader::Shader(GLenum type) : m_type(type) { m_handle = glCreateShader(m_type); @@ -7,7 +7,7 @@ Shader::Shader(GLenum type) : m_type(type) { void Shader::compile(std::string_view code) { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried compiling source for Shader with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried compiling source for Shader with invalid handle!"); } const char* code_ptr = code.data(); @@ -28,13 +28,13 @@ void Shader::compile(std::string_view code) { message.resize(log_size); glGetShaderInfoLog(m_handle, log_size, nullptr, &message[0]); - LOG_GL_FATAL_AND_EXIT(message); + LOG_ERROR_AND_EXIT(message); } } GLuint Shader::handle() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried getting handle of Shader with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried getting handle of Shader with invalid handle!"); } return m_handle; diff --git a/src/browser/core/shader/ShaderProgram.cpp b/src/browser/core/shader/ShaderProgram.cpp index 888e2b8..a815d36 100644 --- a/src/browser/core/shader/ShaderProgram.cpp +++ b/src/browser/core/shader/ShaderProgram.cpp @@ -1,6 +1,6 @@ #include "ShaderProgram.h" #include -#include +#include ShaderProgram::ShaderProgram() { m_handle = glCreateProgram(); @@ -8,14 +8,14 @@ ShaderProgram::ShaderProgram() { void ShaderProgram::attach(Shader shader) { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried attaching Shader to ShaderProgram with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried attaching Shader to ShaderProgram with invalid handle!"); } glAttachShader(m_handle, shader.handle()); } void ShaderProgram::link() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried linking ShaderProgram with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried linking ShaderProgram with invalid handle!"); } glLinkProgram(m_handle); @@ -33,7 +33,7 @@ void ShaderProgram::link() { message.resize(log_size); glGetProgramInfoLog(m_handle, log_size, nullptr, &message[0]); - LOG_GL_FATAL_AND_EXIT(message); + LOG_ERROR_AND_EXIT(message); } // load all uniform locations @@ -75,7 +75,7 @@ GLuint ShaderProgram::handle() { GLint ShaderProgram::get_uniform_location(std::string name) { const auto result = m_uniform_locations.find(name); if (result == m_uniform_locations.end()) { - LOG_GL_FATAL_AND_EXIT("Could not find Uniform '{}'", name); + LOG_ERROR_AND_EXIT("Could not find Uniform '{}'", name); } else { return result->second; } @@ -83,14 +83,14 @@ GLint ShaderProgram::get_uniform_location(std::string name) { void ShaderProgram::use() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried using ShaderProgram with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried using ShaderProgram with invalid handle!"); } glUseProgram(m_handle); } ShaderProgram::~ShaderProgram() { if (!handle_valid()) { - LOG_GL_FATAL_AND_EXIT("Tried destructing ShaderProgram with invalid handle!"); + LOG_ERROR_AND_EXIT("Tried destructing ShaderProgram with invalid handle!"); } glDeleteProgram(m_handle); } diff --git a/src/browser/core/window/Window.cpp b/src/browser/core/window/Window.cpp index 2f7a59d..ef4a696 100644 --- a/src/browser/core/window/Window.cpp +++ b/src/browser/core/window/Window.cpp @@ -1,5 +1,5 @@ #include "Window.h" -#include +#include std::atomic Window::glfw_initialized(false); std::atomic Window::window_instances(0); @@ -9,7 +9,7 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei const auto [gl_major_version, gl_minor_version] = config.opengl_version; - LOG_GL_INFO("Creating window \"{}\" with context: OpenGL {}.{}{}", m_title, gl_major_version, gl_minor_version, config.opengl_core_profile ? " CORE" : ""); + LOG_INFO("Creating window \"{}\" with context: OpenGL {}.{}{}", m_title, gl_major_version, gl_minor_version, config.opengl_core_profile ? " CORE" : ""); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, gl_major_version); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, gl_minor_version); @@ -19,7 +19,7 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei #ifdef _DEBUG // enable debug mode - LOG_GL_DEBUG("Setting OpenGL Debug Context"); + LOG_DEBUG("Setting OpenGL Debug Context"); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_FALSE); #endif // _DEBUG @@ -27,7 +27,7 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei m_handle = glfwCreateWindow(m_width, m_height, m_title.c_str(), NULL, NULL); if (m_handle == NULL) { update_window_count(-1); - LOG_GL_FATAL_AND_EXIT("Failed to create GLFW window"); + LOG_ERROR_AND_EXIT("Failed to create GLFW window"); } glfwMakeContextCurrent(m_handle); @@ -50,7 +50,7 @@ Window::Window(WindowConfig config) : m_width(config.width), m_height(config.hei } Window::~Window() { - LOG_GL_INFO("Destroying Window \"{}\"", m_title); + LOG_INFO("Destroying Window \"{}\"", m_title); glfwDestroyWindow(m_handle); update_window_count(-1); @@ -167,7 +167,7 @@ float Window::getAspectRatio() { } void Window::glfw_error_callback(int error, const char* description) { - LOG_GLFW_ERROR("[{}] {}", error, description); + LOG_ERROR("[{}] {}", error, description); } void Window::key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { @@ -243,10 +243,10 @@ void Window::update_window_count(int delta) { auto g_initialized = Window::glfw_initialized.load(std::memory_order_acquire); if (w_instances + delta < 0) { - LOG_GLFW_FATAL_AND_EXIT("Illegal window count change from {} >> {} by {}!", w_instances, w_instances + delta, delta); + LOG_ERROR_AND_EXIT("Illegal window count change from {} >> {} by {}!", w_instances, w_instances + delta, delta); } - LOG_GLFW_INFO("Window count changed from {} >> {} by {}!", w_instances, w_instances + delta, delta); + LOG_INFO("Window count changed from {} >> {} by {}!", w_instances, w_instances + delta, delta); // If the previous window count was 0 AND glfw is not initialized, initialize GLFW bool needs_glfw_init = w_instances == 0 && !Window::glfw_initialized; @@ -255,7 +255,7 @@ void Window::update_window_count(int delta) { bool needs_glfw_destruction = w_instances + delta == 0 && Window::glfw_initialized; if (needs_glfw_init) { - LOG_GLFW_INFO("Initializing GLFW"); + LOG_INFO("Initializing GLFW"); glfwInit(); glfwSetErrorCallback(glfw_error_callback); @@ -264,7 +264,7 @@ void Window::update_window_count(int delta) { } if (needs_glfw_destruction) { - LOG_GLFW_INFO("Terminating GLFW"); + LOG_INFO("Terminating GLFW"); glfwTerminate(); diff --git a/src/browser/core/window/Window.h b/src/browser/core/window/Window.h index e868bec..4d6703d 100644 --- a/src/browser/core/window/Window.h +++ b/src/browser/core/window/Window.h @@ -4,6 +4,7 @@ #include #include #include +#include #include struct WindowConfig { diff --git a/src/browser/main.cpp b/src/browser/main.cpp index a26a424..19552ee 100644 --- a/src/browser/main.cpp +++ b/src/browser/main.cpp @@ -1,16 +1,17 @@ #include "core/Application.h" -#include "utils/log/Log.h" +#include -int main() { +int main() +{ #ifdef DEBUG - Log::Init(spdlog::level::trace); + Log::init(spdlog::level::trace); #else - Log::Init(spdlog::level::info); + Log::init(spdlog::level::info); #endif - Application app("Alpenite Browser", 1280, 720); + Application app("Alpenite Browser", 1280, 720); - app.run(); + app.run(); - return 0; + return 0; } \ No newline at end of file diff --git a/src/browser/utils/log/Log.cpp b/src/browser/utils/log/Log.cpp deleted file mode 100644 index d996461..0000000 --- a/src/browser/utils/log/Log.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "Log.h" - -#include -#include - -std::shared_ptr Log::Logger; -std::shared_ptr Log::GLLogger; -std::shared_ptr Log::GLFWLogger; -std::shared_ptr Log::PXLogger; -std::shared_ptr Log::FTLogger; - -void Log::Init(spdlog::level::level_enum logLevel) -{ - spdlog::set_pattern("[%Y-%m-%d %T.%e] [%=3n] [%^%l%$] %v"); - Logger = spdlog::stderr_color_mt("LOG"); - GLLogger = spdlog::stderr_color_mt("GL"); - GLFWLogger = spdlog::stderr_color_mt("GLFW"); - - Logger->set_level(logLevel); - GLLogger->set_level(logLevel); - GLFWLogger->set_level(logLevel); -} diff --git a/src/browser/utils/log/Log.h b/src/browser/utils/log/Log.h deleted file mode 100644 index dc54d57..0000000 --- a/src/browser/utils/log/Log.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include -#include - -class Log -{ -private: - static std::shared_ptr Logger; - static std::shared_ptr GLLogger; - static std::shared_ptr GLFWLogger; - static std::shared_ptr PXLogger; - static std::shared_ptr FTLogger; - -public: - static void Init(spdlog::level::level_enum logLevel); - - inline static std::shared_ptr &GetLogger() - { - return Logger; - } - - inline static std::shared_ptr &GetGLLogger() - { - return GLLogger; - } - - inline static std::shared_ptr &GetGLFWLogger() - { - return GLFWLogger; - } -}; - -#define LOG_TRACE(...) ::Log::GetLogger()->trace(__VA_ARGS__) -#define LOG_DEBUG(...) ::Log::GetLogger()->debug(__VA_ARGS__) -#define LOG_INFO(...) ::Log::GetLogger()->info(__VA_ARGS__) -#define LOG_WARN(...) ::Log::GetLogger()->warn(__VA_ARGS__) -#define LOG_ERROR(...) ::Log::GetLogger()->error(__VA_ARGS__) -#define LOG_FATAL(...) ::Log::GetLogger()->critical(__VA_ARGS__) - -#define LOG_GL_TRACE(...) ::Log::GetGLLogger()->trace(__VA_ARGS__) -#define LOG_GL_DEBUG(...) ::Log::GetGLLogger()->debug(__VA_ARGS__) -#define LOG_GL_INFO(...) ::Log::GetGLLogger()->info(__VA_ARGS__) -#define LOG_GL_WARN(...) ::Log::GetGLLogger()->warn(__VA_ARGS__) -#define LOG_GL_ERROR(...) ::Log::GetGLLogger()->error(__VA_ARGS__) -#define LOG_GL_FATAL(...) ::Log::GetGLLogger()->critical(__VA_ARGS__) - -#define LOG_GLFW_TRACE(...) ::Log::GetGLFWLogger()->trace(__VA_ARGS__) -#define LOG_GLFW_DEBUG(...) ::Log::GetGLFWLogger()->debug(__VA_ARGS__) -#define LOG_GLFW_INFO(...) ::Log::GetGLFWLogger()->info(__VA_ARGS__) -#define LOG_GLFW_WARN(...) ::Log::GetGLFWLogger()->warn(__VA_ARGS__) -#define LOG_GLFW_ERROR(...) ::Log::GetGLFWLogger()->error(__VA_ARGS__) -#define LOG_GLFW_FATAL(...) ::Log::GetGLFWLogger()->critical(__VA_ARGS__) - -#define LOG_FATAL_AND_EXIT(...) \ - do \ - { \ - LOG_FATAL(__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (false) -#define LOG_GL_FATAL_AND_EXIT(...) \ - do \ - { \ - LOG_GL_FATAL(__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (false) -#define LOG_GLFW_FATAL_AND_EXIT(...) \ - do \ - { \ - LOG_GLFW_FATAL(__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (false) From 925e4bf236c32d566a81e832c0df2df2c3982888 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Fri, 23 May 2025 23:07:35 +0200 Subject: [PATCH 050/122] Remove unneeded submodule. --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e4034fd..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "sherpa"] - path = sherpa - url = git@github.com:AlpineMapsOrg/sherpa.git From c05a901642013f6fe292b1d3a7948959731fe209 Mon Sep 17 00:00:00 2001 From: Adrian Gawor <31725163+polskus@users.noreply.github.com> Date: Fri, 23 May 2025 23:23:56 +0200 Subject: [PATCH 051/122] Fix string related error in string_utils.h --- src/terrainlib/string_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terrainlib/string_utils.h b/src/terrainlib/string_utils.h index ead1521..64ec6d7 100644 --- a/src/terrainlib/string_utils.h +++ b/src/terrainlib/string_utils.h @@ -19,7 +19,7 @@ std::optional from_chars(std::basic_string_view sv) { return value; } else { std::string utf8(sv.begin(), sv.end()); - return from_chars(utf8); + return from_chars(std::string_view(utf8)); } } From 7f8e362d9bdcca2b64a8b7a8276bc9a69fccda7f Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 24 May 2025 19:06:59 +0200 Subject: [PATCH 052/122] Make transform_points_inplace into a single function --- src/terrainlib/srs.h | 110 ++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/src/terrainlib/srs.h b/src/terrainlib/srs.h index 0c6d932..7036641 100644 --- a/src/terrainlib/srs.h +++ b/src/terrainlib/srs.h @@ -21,7 +21,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -70,85 +73,54 @@ inline glm::tvec3 transform_point(const OGRSpatialReference &source_srs, cons return transform_point(transform.get(), p); } -template -inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { - std::array xs; - std::array ys; - - for (size_t i = 0; i < points.size(); i++) { - xs[i] = points[i].x; - ys[i] = points[i].y; - } - - if (!transform->Transform(points.size(), xs.data(), ys.data())) { - throw std::runtime_error("srs::transform_points_inplace(std::array, n>) failed"); +template +inline void transform_points_inplace(OGRCoordinateTransformation *transform, Container &points) { + using PointType = typename Container::value_type; + using T = typename PointType::value_type; + constexpr bool is_3d = (PointType::length() == 3); + constexpr bool is_array = std::is_array_v; + + const size_t size = points.size(); + + constexpr std::size_t array_size = is_array ? points.size() : 0; + using OutputContainer = std::conditional_t, std::vector>; + + OutputContainer xs, ys; + std::conditional_t zs; + + if constexpr (!is_array) { + xs.resize(size); + ys.resize(size); + if constexpr (PointType::length() == 3) { + zs.resize(size); + } } - for (size_t i = 0; i < points.size(); ++i) { - points[i] = {xs[i], ys[i]}; - } -} -template -inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { - std::vector xs; - std::vector ys; - - for (size_t i = 0; i < points.size(); i++) { + for (size_t i = 0; i < size; i++) { xs[i] = points[i].x; ys[i] = points[i].y; + if constexpr (is_3d) { + zs[i] = points[i].z; + } } - if (!transform->Transform(points.size(), xs.data(), ys.data())) { - throw std::runtime_error("srs::transform_points_inplace(std::vector, n>) failed"); - } - - for (size_t i = 0; i < points.size(); ++i) { - points[i] = {xs[i], ys[i]}; - } -} - -template -inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::array, n> &points) { - std::array xs; - std::array ys; - std::array zs; - - for (size_t i = 0; i < points.size(); i++) { - xs[i] = points[i].x; - ys[i] = points[i].y; - zs[i] = points[i].z; - } - - if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { - throw std::runtime_error("srs::transform_points_inplace(std::array, n>) failed"); - } - - for (size_t i = 0; i < points.size(); ++i) { - points[i] = {xs[i], ys[i], zs[i]}; - } -} -template -inline void transform_points_inplace(OGRCoordinateTransformation *transform, std::vector> &points) { - std::vector xs; - std::vector ys; - std::vector zs; - - xs.resize(points.size()); - ys.resize(points.size()); - zs.resize(points.size()); - - for (size_t i = 0; i < points.size(); i++) { - xs[i] = points[i].x; - ys[i] = points[i].y; - zs[i] = points[i].z; + bool success; + if constexpr (is_3d) { + success = transform->Transform(size, xs.data(), ys.data(), zs.data()); + } else { + success = transform->Transform(size, xs.data(), ys.data()); } - if (!transform->Transform(points.size(), xs.data(), ys.data(), zs.data())) { - throw std::runtime_error("srs::transform_points_inplace(std::vector, n>) failed"); + if (!success) { + throw std::runtime_error("srs::transform_points_inplace failed"); } - for (size_t i = 0; i < points.size(); ++i) { - points[i] = {xs[i], ys[i], zs[i]}; + for (size_t i = 0; i < size; i++) { + if constexpr (is_3d) { + points[i] = PointType(xs[i], ys[i], zs[i]); + } else { + points[i] = PointType(xs[i], ys[i]); + } } } From 29d12ed97e411750e0df8dbca3079cab21b47363 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 24 May 2025 19:07:20 +0200 Subject: [PATCH 053/122] Minor fixes and refactoring --- src/browser/core/Application.cpp | 2 +- .../core/rendering/OctreeRenderManager.h | 4 ++-- src/terrainbuilder/terrainbuilder.cpp | 21 +++++++------------ src/terrainlib/string_utils.h | 3 +-- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/browser/core/Application.cpp b/src/browser/core/Application.cpp index 4c7eb5c..a214219 100644 --- a/src/browser/core/Application.cpp +++ b/src/browser/core/Application.cpp @@ -17,7 +17,7 @@ #include "Buffer.h" #include "Camera.h" #include "geometry/UnitCube.h" -#include "octree/space.h" +#include "octree/Space.h" #include "rendering/OctreeRenderManager.h" CMRC_DECLARE(res); diff --git a/src/browser/core/rendering/OctreeRenderManager.h b/src/browser/core/rendering/OctreeRenderManager.h index 9258ca1..0682924 100644 --- a/src/browser/core/rendering/OctreeRenderManager.h +++ b/src/browser/core/rendering/OctreeRenderManager.h @@ -1,6 +1,6 @@ #pragma once -#include "octree/id.h" -#include "octree/space.h" +#include "octree/Id.h" +#include "octree/Space.h" #include #include diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 0a6b714..7a0e9cf 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -38,7 +38,7 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { : base_path(base_path) {} std::optional get_tile_path(const radix::tile::Id tile_id) const override { - return fmt::format("{}/{}/{}/{}.jpeg", this->base_path.generic_string(), tile_id.zoom_level, tile_id.coords.y, tile_id.coords.x); + return fmt::format("{}/{}/{}/{}.jpeg", this->base_path.string(), tile_id.zoom_level, tile_id.coords.y, tile_id.coords.x); } private: @@ -67,10 +67,6 @@ SimpleMesh build( const mesh::BuildError error = mesh_result.error(); if (error == mesh::BuildError::OutOfBounds) { const radix::tile::SrsBounds dataset_bounds = dataset.bounds(); - // const radix::tile::Id dataset_largest_tile = grid.findLargestContainedTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - // const radix::tile::Id dataset_encompassing_tile = grid.findSmallestEncompassingTile(dataset_bounds).value().to(radix::tile::Scheme::SlippyMap); - // const radix::tile::Id target_largest_tile = grid.findLargestContainedTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); - // const radix::tile::Id target_encompassing_tile = grid.findSmallestEncompassingTile(tile_bounds).value().to(radix::tile::Scheme::SlippyMap); LOG_ERROR("Target bounds are fully outside of dataset region\n" "Dataset {{\n" "\t x={}, y={}, w={}, h={}.\n" @@ -133,18 +129,15 @@ void build_and_save( start = std::chrono::high_resolution_clock::now(); // TODO: use a JSON libary instead std::unordered_map metadata; - // TODO: redo - /*/ metadata["mesh_srs"] = mesh_srs.GetAuthorityCode(nullptr); - metadata["bounds_srs"] = tile_srs.GetAuthorityCode(nullptr); + metadata["bounds_srs"] = target_bounds_srs.GetAuthorityCode(nullptr); metadata["texture_srs"] = texture_srs.GetAuthorityCode(nullptr); - metadata["tile_bounds"] = fmt::format( + metadata["bounds"] = fmt::format( "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", - tile_bounds.min.x, tile_bounds.min.y, tile_bounds.max.x, tile_bounds.max.y); - metadata["texture_bounds"] = fmt::format( - "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", - texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); - */ + target_bounds.min.x, target_bounds.min.y, target_bounds.max.x, target_bounds.max.y); + // metadata["texture_bounds"] = fmt::format( + // "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", + // texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); if (!::mesh::io::save_to_path(mesh, output_path, ::mesh::io::SaveOptions{.metadata = metadata}).has_value()) { LOG_ERROR("Failed to save mesh to file {}", output_path); exit(2); diff --git a/src/terrainlib/string_utils.h b/src/terrainlib/string_utils.h index 64ec6d7..600d92d 100644 --- a/src/terrainlib/string_utils.h +++ b/src/terrainlib/string_utils.h @@ -1,14 +1,13 @@ #pragma once #include -#include #include #include #include #include template -std::optional from_chars(std::basic_string_view sv) { +std::optional from_chars(const std::basic_string_view sv) { static_assert(std::is_integral_v, "T must be an integral type"); if constexpr (std::is_same_v) { From b7004e7db3cb8b142f7a12b369b0e6440595a338 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:08:14 +0200 Subject: [PATCH 054/122] Bring back tilebuilder --- src/CMakeLists.txt | 25 ++ src/terrainlib/ProgressIndicator.cpp | 15 +- src/terrainlib/ProgressIndicator.h | 2 +- src/tilebuilder/Dataset.cpp | 205 ++++++++++++++++ src/tilebuilder/DatasetReader.cpp | 222 ++++++++++++++++++ src/tilebuilder/DatasetReader.h | 56 +++++ src/tilebuilder/Exception.h | 35 +++ src/tilebuilder/Image.cpp | 20 ++ src/tilebuilder/Image.h | 105 +++++++++ src/tilebuilder/ParallelTileGenerator.cpp | 112 +++++++++ src/tilebuilder/ParallelTileGenerator.h | 76 ++++++ src/tilebuilder/ParallelTiler.cpp | 74 ++++++ .../tilebuilder/ParallelTiler.h | 29 +-- src/tilebuilder/TileHeightsGenerator.cpp | 84 +++++++ src/tilebuilder/TileHeightsGenerator.h | 39 +++ src/tilebuilder/Tiler.cpp | 72 ++++++ src/tilebuilder/Tiler.h | 48 ++++ src/tilebuilder/TopDownTiler.cpp | 38 +++ src/tilebuilder/TopDownTiler.h | 30 +++ src/tilebuilder/algorithms/primitives.h | 103 ++++++++ .../algorithms/raster_triangle_scanline.h | 101 ++++++++ src/tilebuilder/alpine_raster.cpp | 42 ++++ src/tilebuilder/alpine_raster.h | 52 ++++ src/tilebuilder/depth_first_tile_traverser.h | 41 ++++ src/tilebuilder/main.cpp | 40 ++++ src/tilebuilder/srs.h | 136 +++++++++++ unittests/CMakeLists.txt | 53 +++-- unittests/progress_indicator_test.cpp | 106 --------- unittests/{ => terrainlib}/dataset.cpp | 2 +- unittests/{ => terrainlib}/grid.cpp | 0 .../terrainlib/progress_indicator_test.cpp | 103 ++++++++ .../alpine_raster_format.cpp | 20 +- .../{ => tilebuilder}/dataset_reading.cpp | 18 +- .../depth_first_tile_traverser.cpp | 56 ++--- unittests/{ => tilebuilder}/image.cpp | 0 .../parallel_tile_generator.cpp | 6 +- .../{ => tilebuilder}/parallel_tiler.cpp | 22 +- .../tile_heights_generator.cpp | 4 +- .../{ => tilebuilder}/top_down_tiler.cpp | 22 +- 39 files changed, 1986 insertions(+), 228 deletions(-) create mode 100644 src/tilebuilder/Dataset.cpp create mode 100644 src/tilebuilder/DatasetReader.cpp create mode 100644 src/tilebuilder/DatasetReader.h create mode 100644 src/tilebuilder/Exception.h create mode 100644 src/tilebuilder/Image.cpp create mode 100644 src/tilebuilder/Image.h create mode 100644 src/tilebuilder/ParallelTileGenerator.cpp create mode 100644 src/tilebuilder/ParallelTileGenerator.h create mode 100644 src/tilebuilder/ParallelTiler.cpp rename unittests/main.cpp => src/tilebuilder/ParallelTiler.h (57%) create mode 100644 src/tilebuilder/TileHeightsGenerator.cpp create mode 100644 src/tilebuilder/TileHeightsGenerator.h create mode 100644 src/tilebuilder/Tiler.cpp create mode 100644 src/tilebuilder/Tiler.h create mode 100644 src/tilebuilder/TopDownTiler.cpp create mode 100644 src/tilebuilder/TopDownTiler.h create mode 100644 src/tilebuilder/algorithms/primitives.h create mode 100644 src/tilebuilder/algorithms/raster_triangle_scanline.h create mode 100644 src/tilebuilder/alpine_raster.cpp create mode 100644 src/tilebuilder/alpine_raster.h create mode 100644 src/tilebuilder/depth_first_tile_traverser.h create mode 100644 src/tilebuilder/main.cpp create mode 100644 src/tilebuilder/srs.h delete mode 100644 unittests/progress_indicator_test.cpp rename unittests/{ => terrainlib}/dataset.cpp (98%) rename unittests/{ => terrainlib}/grid.cpp (100%) create mode 100644 unittests/terrainlib/progress_indicator_test.cpp rename unittests/{ => tilebuilder}/alpine_raster_format.cpp (76%) rename unittests/{ => tilebuilder}/dataset_reading.cpp (94%) rename unittests/{ => tilebuilder}/depth_first_tile_traverser.cpp (73%) rename unittests/{ => tilebuilder}/image.cpp (100%) rename unittests/{ => tilebuilder}/parallel_tile_generator.cpp (92%) rename unittests/{ => tilebuilder}/parallel_tiler.cpp (93%) rename unittests/{ => tilebuilder}/tile_heights_generator.cpp (92%) rename unittests/{ => tilebuilder}/top_down_tiler.cpp (83%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ce46ec..4a3bd5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) find_package(CURL REQUIRED) + alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH 20de8b73bbbabaf2f94dd07c4ece8ff3590af531) @@ -144,6 +145,30 @@ if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) endif() + +add_library(tilebuilderlib + tilebuilder/alpine_raster.h tilebuilder/alpine_raster.cpp + tilebuilder/DatasetReader.h tilebuilder/DatasetReader.cpp + tilebuilder/depth_first_tile_traverser.h + tilebuilder/Exception.h + tilebuilder/Image.h tilebuilder/Image.cpp + tilebuilder/ParallelTileGenerator.h tilebuilder/ParallelTileGenerator.cpp + tilebuilder/ParallelTiler.h tilebuilder/ParallelTiler.cpp + tilebuilder/srs.h + tilebuilder/TileHeightsGenerator.h tilebuilder/TileHeightsGenerator.cpp + tilebuilder/Tiler.h tilebuilder/Tiler.cpp + tilebuilder/TopDownTiler.h tilebuilder/TopDownTiler.cpp + tilebuilder/algorithms/primitives.h + tilebuilder/algorithms/raster_triangle_scanline.h +) +target_include_directories(tilebuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tilebuilder) +target_link_libraries(tilebuilderlib PUBLIC terrainlib radix ZLIB::ZLIB GDAL::GDAL fmt) +add_executable(tilebuilder + tilebuilder/main.cpp +) +target_link_libraries(tilebuilder PUBLIC tilebuilderlib) + + add_library(terrainbuilderlib terrainbuilder/tile_provider.h terrainbuilder/mesh_builder.h diff --git a/src/terrainlib/ProgressIndicator.cpp b/src/terrainlib/ProgressIndicator.cpp index e81198b..1383aaf 100644 --- a/src/terrainlib/ProgressIndicator.cpp +++ b/src/terrainlib/ProgressIndicator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -64,17 +65,19 @@ std::jthread ProgressIndicator::start_monitoring() const { return thread; } -std::string ProgressIndicator::progress_bar() const { - const auto bar_width = 50; - const auto progress = uint32_t(bar_width * (double(m_step) / double(m_n_steps)) + 0.5); +std::string ProgressIndicator::progress_bar(const uint32_t bar_width) const { + assert(bar_width >= 2); + const auto inner_bar_width = bar_width - 2; + const auto step = m_step.load(); + const auto progress = step > 0 ? inner_bar_width * step / m_n_steps : 0; assert(progress <= bar_width); std::ostringstream oss; oss << "["; - for (uint32_t i = 0; i < bar_width; ++i) { - if (i < progress) { + for (uint32_t i = 0; i < inner_bar_width; i++) { + if (i < progress || step == m_n_steps) { oss << "="; - } else if (i == progress) { + } else if (i == progress && step != 0) { oss << ">"; } else { oss << " "; diff --git a/src/terrainlib/ProgressIndicator.h b/src/terrainlib/ProgressIndicator.h index f714626..fcf34eb 100644 --- a/src/terrainlib/ProgressIndicator.h +++ b/src/terrainlib/ProgressIndicator.h @@ -33,6 +33,6 @@ class ProgressIndicator { void task_finished(); [[nodiscard]] std::jthread start_monitoring() const; // join on the returned thread after the work is done!! - [[nodiscard]] std::string progress_bar() const; + [[nodiscard]] std::string progress_bar(const uint32_t bar_width=50) const; [[nodiscard]] std::string x_of_y_done_message() const; }; diff --git a/src/tilebuilder/Dataset.cpp b/src/tilebuilder/Dataset.cpp new file mode 100644 index 0000000..a1bd0d4 --- /dev/null +++ b/src/tilebuilder/Dataset.cpp @@ -0,0 +1,205 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "Dataset.h" + +#include +#include +#include +#include +#include + +#include + +#include "Exception.h" +#include "ctb/Grid.hpp" +#include "srs.h" +#include "tntn/gdal_init.h" +#include "tntn/logging.h" + +Dataset::Dataset(const std::string& path) +{ + tntn::initialize_gdal_once(); + m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); + if (!m_gdal_dataset) { + TNTN_LOG_FATAL("Couldn't open dataset {}.\n", path); + throw Exception(""); + } + m_name = std::regex_replace(path, std::regex("^.*/"), ""); + m_name = std::regex_replace(m_name, std::regex(R"(\.\w+$)"), ""); +} + +Dataset::Dataset(GDALDataset* dataset) +{ + tntn::initialize_gdal_once(); + m_gdal_dataset.reset(dataset); + if (!m_gdal_dataset) { + TNTN_LOG_FATAL("Dataset is null.\n"); + throw Exception("Dataset is null."); + } +} + +DatasetPtr Dataset::make_shared(const std::string& path) +{ + return std::make_shared(path); +} + +std::string Dataset::name() const +{ + return m_name; +} + +Dataset::~Dataset() = default; + +radix::tile::SrsBounds Dataset::bounds() const +{ + std::array adfGeoTransform = {}; + if (m_gdal_dataset->GetGeoTransform(adfGeoTransform.data()) != CE_None) + throw Exception("Could not get transformation information from source dataset"); + + // https://gdal.org/user/raster_data_model.html + // gdal has a row/column raster format, where row 0 is the top most row. + // an affine transform is used to convert row/column into the datasets SRS. + // computing bounds is going first from row/column to dataset SRS and then to target SRS + + // we don't support sheering or rotation for now + if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) + throw Exception("Dataset geo transform contains sheering or rotation. This is not supported!"); + + const double westX = adfGeoTransform[0]; + const double southY = adfGeoTransform[3] + (heightInPixels() * adfGeoTransform[5]); + + const double eastX = adfGeoTransform[0] + (widthInPixels() * adfGeoTransform[1]); + const double northY = adfGeoTransform[3]; + return { {westX, southY}, {eastX, northY} }; +} + +radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference& targetSrs) const +{ + const auto l_bounds = bounds(); + const auto west = l_bounds.min.x; + const auto east = l_bounds.max.x; + const auto north = l_bounds.max.y; + const auto south = l_bounds.min.y; + + + const auto data_srs = srs(); + if (targetSrs.IsSame(&data_srs)) + return l_bounds; + + // We need to transform the bounds to the target SRS + // this might involve warping, i.e. some of the edges can be arcs. + // therefore we want to walk the perimiter and get min/max from there. + // a resolution of 2000 samples per border should give a good enough approximation. + + // hey, check out inline virtual int TransformBounds(const double xmin, const double ymin, const double xmax, const double ymax, double *out_xmin, double *out_ymin, double *out_xmax, double *out_ymax, const int densify_pts) + std::vector x; + std::vector y; + auto addCoordinate = [&](double xv, double yv) { x.emplace_back(xv); y.emplace_back(yv); }; + + const auto deltaX = l_bounds.width() / 2000.0; + if (deltaX <= 0.0) + throw Exception("west coordinate > east coordinate. This is not supported."); + for (double s = west; s < east; s += deltaX) { + addCoordinate(s, south); + addCoordinate(s, north); + } + const auto deltaY = (north - south) / 2000.0; + if (deltaY <= 0.0) + throw Exception("south coordinate > north coordinate. This is not supported."); + for (double s = south; s < north; s += deltaY) { + addCoordinate(west, s); + addCoordinate(east, s); + } + // don't wanna miss out the max/max edge vertex + addCoordinate(east, north); + + const auto transformer = srs::transformation(srs(), targetSrs); + if (!transformer->Transform(int(x.size()), x.data(), y.data())) { + throw std::string("Could not transform dataset bounds to target SRS"); + } + + assert(!x.empty()); + assert(!y.empty()); + const double target_minX = *std::min_element(x.begin(), x.end()); + const double target_maxX = *std::max_element(x.begin(), x.end()); + const double target_minY = *std::min_element(y.begin(), y.end()); + const double target_maxY = *std::max_element(y.begin(), y.end()); + return { {target_minX, target_minY}, {target_maxX, target_maxY} }; +} + +OGRSpatialReference Dataset::srs() const +{ + const char* srcWKT = m_gdal_dataset->GetProjectionRef(); + if (!strlen(srcWKT)) + throw Exception("The source dataset does not have a spatial reference system assigned"); + auto srs = OGRSpatialReference(srcWKT); + srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + return srs; +} + +unsigned Dataset::widthInPixels() const +{ + return ctb::i_pixel(m_gdal_dataset->GetRasterXSize()); +} + +unsigned Dataset::heightInPixels() const +{ + return ctb::i_pixel(m_gdal_dataset->GetRasterYSize()); +} + +double Dataset::widthInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const +{ + return bounds.width() / pixelWidthIn(bounds_srs); +} + +double Dataset::heightInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const +{ + return bounds.height() / pixelHeightIn(bounds_srs); +} + +unsigned Dataset::n_bands() const +{ + const auto n = m_gdal_dataset->GetRasterCount(); + assert(n >= 0); + return unsigned(n); +} + +GDALDataset* Dataset::gdalDataset() +{ + return m_gdal_dataset.get(); +} + +double Dataset::gridResolution(const OGRSpatialReference& target_srs) const +{ + return std::min(pixelWidthIn(target_srs), pixelHeightIn(target_srs)); +} + +double Dataset::pixelWidthIn(const OGRSpatialReference& target_srs) const +{ + const auto b0 = bounds(); + const auto b1 = srs::nonExactBoundsTransform(b0, srs(), target_srs); + return b1.width() / widthInPixels(); +} + +double Dataset::pixelHeightIn(const OGRSpatialReference& target_srs) const +{ + const auto b = srs::nonExactBoundsTransform(bounds(), srs(), target_srs); + return b.height() / heightInPixels(); +} diff --git a/src/tilebuilder/DatasetReader.cpp b/src/tilebuilder/DatasetReader.cpp new file mode 100644 index 0000000..b7bfccf --- /dev/null +++ b/src/tilebuilder/DatasetReader.cpp @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright 2014 GeoData + * Copyright 2022 Adam Celarek + * + * Licensed 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 "DatasetReader.h" +#include "Dataset.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Dataset.h" +#include "Exception.h" +#include "Image.h" +#include "ctb/types.hpp" +#include "log.h" + +namespace { +std::string toWkt(const OGRSpatialReference& srs) +{ + char* wkt_char_string = nullptr; + srs.exportToWkt(&wkt_char_string); + std::string wkt_string(wkt_char_string); + CPLFree(wkt_char_string); + return wkt_string; +} + +std::array computeGeoTransform(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) +{ + return { bounds.min.x, bounds.width() / width, 0, + bounds.max.y, 0, -bounds.height() / height }; +} + +using GdalImageTransformArgsPtr = std::unique_ptr; +GdalImageTransformArgsPtr make_image_transform_args(const DatasetReader& reader, + Dataset* dataset, + const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) +{ + CPLStringList transformOptions; + if (reader.isReprojecting()) { + transformOptions.SetNameValue("SRC_SRS", reader.dataset_srs_wkt().c_str()); + transformOptions.SetNameValue("DST_SRS", reader.target_srs_wkt().c_str()); + } + auto args = GdalImageTransformArgsPtr(GDALCreateGenImgProjTransformer2(dataset->gdalDataset(), nullptr, transformOptions.List()), &GDALDestroyGenImgProjTransformer); + if (!args) { + throw Exception("GDALCreateGenImgProjTransformer2 failed."); + } + + const auto adfGeoTransform = computeGeoTransform(bounds, width, height); + GDALSetGenImgProjTransformerDstGeoTransform(args.get(), adfGeoTransform.data()); + + return args; +} + +using GdalWarpOptionsPtr = std::unique_ptr; +using WarpOptionData = std::pair; + +WarpOptionData makeWarpOptions(const DatasetReader& reader, Dataset* dataset, const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) +{ + auto options = GdalWarpOptionsPtr(GDALCreateWarpOptions(), &GDALDestroyWarpOptions); + options->hSrcDS = dataset->gdalDataset(); + options->nBandCount = 1; + options->eResampleAlg = GDALResampleAlg::GRA_Cubic; + options->panSrcBands = static_cast(CPLMalloc(sizeof(int) * 1)); + options->panDstBands = static_cast(CPLMalloc(sizeof(int) * 1)); + options->padfSrcNoDataReal = static_cast(CPLMalloc(sizeof(double) * 1)); + options->padfSrcNoDataImag = static_cast(CPLMalloc(sizeof(double) * 1)); + options->padfDstNoDataReal = static_cast(CPLMalloc(sizeof(double) * 1)); + options->padfDstNoDataImag = static_cast(CPLMalloc(sizeof(double) * 1)); + { + int bGotNoData = false; + double noDataValue = dataset->gdalDataset()->GetRasterBand(1)->GetNoDataValue(&bGotNoData); + if (!bGotNoData) + noDataValue = -32768; + + options->padfSrcNoDataReal[0] = noDataValue; + options->padfSrcNoDataImag[0] = 0; + options->padfDstNoDataReal[0] = noDataValue; + options->padfDstNoDataImag[0] = 0; + + options->panSrcBands[0] = int(reader.dataset_band()); + options->panDstBands[0] = 1; + } + constexpr auto use_approximation = true; + if (use_approximation) { + const auto error_threshold = 0.5; + auto image_transform_args = make_image_transform_args(reader, dataset, bounds, width, height); + options->pTransformerArg = GDALCreateApproxTransformer(GDALGenImgProjTransform, image_transform_args.get(), error_threshold); + options->pfnTransformer = GDALApproxTransform; + return { std::move(options), std::move(image_transform_args) }; + } + + options->pTransformerArg = make_image_transform_args(reader, dataset, bounds, width, height).release(); + options->pfnTransformer = GDALGenImgProjTransform; + + return { std::move(options), GdalImageTransformArgsPtr(nullptr, &GDALDestroyGenImgProjTransformer) }; +} + +#ifdef ATB_ENABLE_OVERVIEW_READING +std::shared_ptr getOverviewDataset(const std::shared_ptr& dataset, void* hTransformerArg, bool warn_on_missing_overviews) +{ + GDALDataset* poSrcDS = dataset->gdalDataset(); + int nOvLevel = -2; + int nOvCount = poSrcDS->GetRasterBand(1)->GetOverviewCount(); + + assert(nOvCount >= 0); + if (nOvCount == 0) { + if (warn_on_missing_overviews) + TNTN_LOG_WARN("No dataset overviews found."); + return dataset; + } + + std::array adfSuggestedGeoTransform; + std::array adfExtent; + int nPixels; + int nLines; + /* Compute what the "natural" output resolution (in pixels) would be for this */ + /* input dataset */ + if (GDALSuggestedWarpOutput2(poSrcDS, GDALGenImgProjTransform, hTransformerArg, + adfSuggestedGeoTransform.data(), &nPixels, &nLines, + adfExtent.data(), 0) + == CE_Failure) { + TNTN_LOG_WARN("GDALSuggestedWarpOutput2 failed. We won't use dataset overviews!"); + return dataset; + } + + double dfTargetRatio = 1.0 / adfSuggestedGeoTransform[1]; + // if( dfTargetRatio <= 1.0 ) { + // TNTN_LOG_WARN(fmt::format("dfTargetRatio {} <= 1.0. We won't use dataset overviews!\n", dfTargetRatio)); + // TNTN_LOG_WARN(fmt::format("Other values: nPixels={}, nLines={}, adfExtent={}/{}/{}/{}\n", + // nPixels, nLines, adfExtent[0], adfExtent[1], adfExtent[2], adfExtent[3])); + // TNTN_LOG_WARN(fmt::format("Other values: adfSuggestedGeoTransform={}/{}/{}/{}/{}/{}\n", + // adfSuggestedGeoTransform[0], adfSuggestedGeoTransform[1], adfSuggestedGeoTransform[2], + // adfSuggestedGeoTransform[3], adfSuggestedGeoTransform[4], adfSuggestedGeoTransform[5])); + // return dataset; + // } + + int iOvr; + for (iOvr = -1; iOvr < nOvCount - 1; iOvr++) { + const auto dfOvrRatio = (iOvr < 0) ? 1.0 : double(poSrcDS->GetRasterXSize()) / poSrcDS->GetRasterBand(1)->GetOverview(iOvr)->GetXSize(); + const auto dfNextOvrRatio = double(poSrcDS->GetRasterXSize()) / poSrcDS->GetRasterBand(1)->GetOverview(iOvr + 1)->GetXSize(); + if (dfOvrRatio < dfTargetRatio && dfNextOvrRatio > dfTargetRatio) + break; + if (std::abs(dfOvrRatio - dfTargetRatio) < 1e-1) + break; + } + iOvr += nOvLevel + 2; + if (iOvr >= 0) { + TNTN_LOG_DEBUG("WARPING: Selecting overview level {} for output dataset {}x{}\n", iOvr, nPixels, nLines); + return std::make_shared(static_cast(GDALCreateOverviewDataset(poSrcDS, iOvr, FALSE))); + } + return dataset; +} +#endif + +} + +DatasetReader::DatasetReader(const std::shared_ptr& dataset, const OGRSpatialReference& targetSRS, unsigned band, bool warn_on_missing_overviews) + : m_dataset(dataset) + , m_dataset_srs_wkt(toWkt(dataset->srs())) + , m_target_srs_wkt(toWkt(targetSRS)) + , m_requires_reprojection(!dataset->srs().IsSame(&targetSRS)) + , m_warn_on_missing_overviews(warn_on_missing_overviews) + , m_band(band) +{ + if (band > dataset->n_bands()) + throw Exception(fmt::format("Dataset does not contain band number {} (there are {} bands).", band, dataset->n_bands())); +} + +HeightData DatasetReader::read(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const +{ + return readFrom(m_dataset, bounds, width, height); +} + +HeightData DatasetReader::readWithOverviews(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const +{ +#ifdef ATB_ENABLE_OVERVIEW_READING + auto transformer_args = make_image_transform_args(*this, m_dataset.get(), bounds, width, height); + auto source_dataset = getOverviewDataset(m_dataset, transformer_args.get(), m_warn_on_missing_overviews); + + return readFrom(source_dataset, bounds, width, height); +#else + return read(bounds, width, height); +#endif +} + +HeightData DatasetReader::readFrom(const std::shared_ptr& source_dataset, const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const +{ + // if we have performance problems with the warping, it'd still be possible to approximate the warping operation with a linear transform (mostly when zoomed in / on higher zoom levels). + // CTB does this in GDALTiler.cpp around line 375 ("// Decide if we are doing an approximate or exact transformation"). + + auto warp_options = makeWarpOptions(*this, source_dataset.get(), bounds, width, height); + auto adfGeoTransform = computeGeoTransform(bounds, width, height); + auto warped_dataset = Dataset(static_cast(GDALCreateWarpedVRT(source_dataset->gdalDataset(), int(width), int(height), adfGeoTransform.data(), warp_options.first.get()))); + + auto* heights_band = warped_dataset.gdalDataset()->GetRasterBand(1); // non-owning pointer + auto heights_data = HeightData(width, height); + if (heights_band->RasterIO(GF_Read, 0, 0, int(width), int(height), + static_cast(heights_data.data()), int(width), int(height), GDT_Float32, 0, 0) + != CE_None) + throw Exception("couldn't read data"); + + return heights_data; +} diff --git a/src/tilebuilder/DatasetReader.h b/src/tilebuilder/DatasetReader.h new file mode 100644 index 0000000..6684db8 --- /dev/null +++ b/src/tilebuilder/DatasetReader.h @@ -0,0 +1,56 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef DATASETREADER_H +#define DATASETREADER_H + +#include +#include + +#include "Image.h" +#include + +class Dataset; +class OGRSpatialReference; + +class DatasetReader { +public: + DatasetReader(const std::shared_ptr& dataset, const OGRSpatialReference& targetSRS, unsigned band, bool warn_on_missing_overviews = true); + + HeightData read(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const; + HeightData readWithOverviews(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const; + + unsigned dataset_band() const { return m_band; } + bool isReprojecting() const { return m_requires_reprojection; } + std::string dataset_srs_wkt() const { return m_dataset_srs_wkt; } + std::string target_srs_wkt() const { return m_target_srs_wkt; } + +protected: + HeightData readFrom(const std::shared_ptr& dataset, const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const; + +private: + std::shared_ptr m_dataset; + std::string m_dataset_srs_wkt; + std::string m_target_srs_wkt; + bool m_requires_reprojection; + bool m_warn_on_missing_overviews; + unsigned m_band; +}; + +#endif // DATASETREADER_H diff --git a/src/tilebuilder/Exception.h b/src/tilebuilder/Exception.h new file mode 100644 index 0000000..6984a40 --- /dev/null +++ b/src/tilebuilder/Exception.h @@ -0,0 +1,35 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef EXCEPTION_H +#define EXCEPTION_H + +#include + +/// This represents a CTB runtime error +class Exception : public std::runtime_error { +public: + Exception(const std::string& message) + : std::runtime_error(message) + { + while (false) { } + } +}; + +#endif // EXCEPTION_H diff --git a/src/tilebuilder/Image.cpp b/src/tilebuilder/Image.cpp new file mode 100644 index 0000000..3b33465 --- /dev/null +++ b/src/tilebuilder/Image.cpp @@ -0,0 +1,20 @@ +#include +#include "Image.h" +#include + +void image::saveImageAsPng(const Image& inputImage, const std::string& path) +{ + const int width = static_cast(inputImage.width()); + const int height = static_cast(inputImage.height()); + + cv::Mat image(height, width, CV_8UC3); + + for (int row = 0; row < height; ++row) { + for (int col = 0; col < width; ++col) { + const glm::u8vec3& pixel = inputImage.pixel(height - row - 1, col); // Flip vertically + image.at(row, col) = cv::Vec3b(pixel.z, pixel.y, pixel.x); // RGB to BGR + } + } + + cv::imwrite(path, image); +} diff --git a/src/tilebuilder/Image.h b/src/tilebuilder/Image.h new file mode 100644 index 0000000..5785329 --- /dev/null +++ b/src/tilebuilder/Image.h @@ -0,0 +1,105 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef IMAGE_H +#define IMAGE_H + +#include +#include +#include +#include +#include +#include + +#include + +namespace tntn { +template +class Raster; +} + +template +class Image { +public: + Image() = default; + Image(unsigned width, unsigned height) + : m_width(width) + , m_height(height) + , m_data(size_t(m_width * m_height)) + { + } + + [[nodiscard]] unsigned width() const { return m_width; } + [[nodiscard]] unsigned height() const { return m_height; } + [[nodiscard]] T pixel(unsigned row, unsigned column) const + { + assert(column < m_width); + assert(row < m_height); + assert(m_data.size() == size_t(m_width * m_height)); + return m_data[row * m_width + column]; + } + + [[nodiscard]] float* data() { return m_data.data(); } + + [[nodiscard]] auto size() const { return m_data.size(); } + [[nodiscard]] auto begin() { return m_data.begin(); } + [[nodiscard]] auto end() { return m_data.end(); } + [[nodiscard]] auto begin() const { return m_data.begin(); } + [[nodiscard]] auto end() const { return m_data.end(); } + +private: + unsigned m_width = 0; + unsigned m_height = 0; + std::vector m_data; + + friend class tntn::Raster; +}; + +using HeightData = Image; +using RgbImage = Image; +using uchar = unsigned char; + +namespace image { +void saveImageAsPng(const Image& image, const std::string& path); + +template +[[nodiscard]] auto transformImage(const Image& i, Fun conversion_fun) -> Image +{ + using T2 = decltype(conversion_fun(*i.begin())); + Image i2(i.width(), i.height()); + std::transform(i.begin(), i.end(), i2.begin(), conversion_fun); + return i2; +} + +template +void debugOut(const Image& image, const std::string& path) +{ + auto [min, max] = std::ranges::minmax(image); + + // [min=min, ..] is required for cpp correctness. min/max from the capture are not variables, we need to copy them: + // https://stackoverflow.com/questions/50799719/reference-to-local-binding-declared-in-enclosing-function?noredirect=1&lq=1 + saveImageAsPng(transformImage(image, [min = min, max = max](auto v) { + const auto c = uchar(255.F * (float(v) - float(min)) / float(max - min)); + return glm::u8vec3(c, c, c); + }), + path); +} +} + +#endif // HEIGHTDATA_H diff --git a/src/tilebuilder/ParallelTileGenerator.cpp b/src/tilebuilder/ParallelTileGenerator.cpp new file mode 100644 index 0000000..3a8ed6c --- /dev/null +++ b/src/tilebuilder/ParallelTileGenerator.cpp @@ -0,0 +1,112 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "ParallelTileGenerator.h" +#include "ProgressIndicator.h" + +#include +#include + +#include + +#include "Dataset.h" +#include "ctb/GlobalGeodetic.hpp" +#include "ctb/GlobalMercator.hpp" + +#include +#include + +ParallelTileGenerator::ParallelTileGenerator(const std::string& input_data_path, const ctb::Grid& grid, const ParallelTiler& tiler, std::unique_ptr tile_writer, const std::string& output_data_path) + : m_output_data_path(output_data_path) + , m_input_data_path(input_data_path) + , m_grid(grid) + , m_tiler(tiler) + , m_tile_writer(std::move(tile_writer)) +{ +} + +ParallelTileGenerator ParallelTileGenerator::make(const std::string& input_data_path, + ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, + std::unique_ptr tile_writer, + const std::string& output_data_path, + unsigned grid_resolution) +{ + const auto dataset = Dataset::make_shared(input_data_path); + ctb::Grid grid = ctb::GlobalGeodetic(grid_resolution); + if (srs == ctb::Grid::Srs::SphericalMercator) + grid = ctb::GlobalMercator(grid_resolution); + const auto border = tile_writer->formatRequiresBorder(); + return { input_data_path, grid, ParallelTiler(grid, dataset->bounds(grid.getSRS()), border, tiling_scheme), std::move(tile_writer), output_data_path }; +} + +const ParallelTiler& ParallelTileGenerator::tiler() const +{ + return m_tiler; +} + +const ctb::Grid& ParallelTileGenerator::grid() const +{ + return m_grid; +} + +void ParallelTileGenerator::write(const radix::tile::Descriptor& tile, const HeightData& heights) const +{ + const auto dir_path = fmt::format("{}/{}/{}", m_output_data_path, tile.id.zoom_level, tile.id.coords.x); + const auto file_path = fmt::format("{}/{}.{}", dir_path, tile.id.coords.y, m_tile_writer->formatFileEnding()); + std::filesystem::create_directories(dir_path); + m_tile_writer->write(file_path, tile, heights); +} + +void ParallelTileGenerator::process(const std::pair& zoom_range, bool progress_bar_on_console, bool generate_world_wide_tiles) const +{ + auto tiler = m_tiler; + if (generate_world_wide_tiles) + tiler.setBounds(grid().getExtent()); + + const auto tiles = tiler.generateTiles(zoom_range); + + auto pi = ProgressIndicator(tiles.size()); + std::jthread monitoring_thread; + + if (progress_bar_on_console) + monitoring_thread = pi.start_monitoring(); // destructor will join. + + const auto fun = [&pi, progress_bar_on_console, this](const radix::tile::Descriptor& tile) { + // Recreating Dataset for every tile. This was the easiest fix for multithreading, + // and it takes only 0.5% of the time (half a percent). + // most of the cpu time is used in 'readWithOverviews' (specificly 'RasterIO', and + // 'VRTWarpedRasterBand::IReadBlock') and a bit in 'write' (specifically 'FreeImage_Save'). + const auto dataset = Dataset::make_shared(m_input_data_path); + DatasetReader reader(dataset, m_grid.getSRS(), 1, m_warn_on_missing_overviews); + const auto heights = reader.readWithOverviews(tile.srsBounds, tile.tileSize, tile.tileSize); + write(tile, heights); + if (progress_bar_on_console) + pi.task_finished(); + }; + std::for_each(std::execution::par, tiles.begin(), tiles.end(), fun); +} + +radix::tile::Border ParallelTileWriterInterface::formatRequiresBorder() const +{ + return m_format_requires_border; +} + +const std::string& ParallelTileWriterInterface::formatFileEnding() const +{ + return m_file_ending; +} diff --git a/src/tilebuilder/ParallelTileGenerator.h b/src/tilebuilder/ParallelTileGenerator.h new file mode 100644 index 0000000..f95a412 --- /dev/null +++ b/src/tilebuilder/ParallelTileGenerator.h @@ -0,0 +1,76 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef PARALLELTILEGENERATOR_H +#define PARALLELTILEGENERATOR_H + +#include +#include + +#include "Image.h" +#include "ParallelTiler.h" +#include "ctb/Grid.hpp" +#include "ctb/types.hpp" +#include + +class ParallelTileWriterInterface; + +class ParallelTileGenerator { + std::string m_output_data_path; + std::string m_input_data_path; + ctb::Grid m_grid; + ParallelTiler m_tiler; + std::unique_ptr m_tile_writer; + bool m_warn_on_missing_overviews = true; + +public: + ParallelTileGenerator(const std::string& input_data_path, const ctb::Grid& grid, const ParallelTiler& tiler, std::unique_ptr tile_writer, const std::string& output_data_path); + [[nodiscard]] static ParallelTileGenerator make(const std::string& input_data_path, + ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, + std::unique_ptr tile_writer, + const std::string& output_data_path, + unsigned grid_resolution = 256); + + void setWarnOnMissingOverviews(bool flag) { m_warn_on_missing_overviews = flag; } + [[nodiscard]] const ParallelTiler& tiler() const; + [[nodiscard]] const ctb::Grid& grid() const; + void write(const radix::tile::Descriptor& tile, const HeightData& heights) const; + void process(const std::pair& zoom_range, bool progress_bar_on_console = false, bool generate_world_wide_tiles = false) const; +}; + +class ParallelTileWriterInterface { + radix::tile::Border m_format_requires_border; + std::string m_file_ending; + +public: + ParallelTileWriterInterface(radix::tile::Border format_requires_border, const std::string& file_ending) + : m_format_requires_border(format_requires_border) + , m_file_ending(file_ending) + { + } + ParallelTileWriterInterface(const ParallelTileWriterInterface&) = default; + ParallelTileWriterInterface(ParallelTileWriterInterface&&) = default; + virtual ~ParallelTileWriterInterface() = default; + ParallelTileWriterInterface& operator=(const ParallelTileWriterInterface&) = default; + ParallelTileWriterInterface& operator=(ParallelTileWriterInterface&&) = default; + virtual void write(const std::string& file_path, const radix::tile::Descriptor& tile, const HeightData& heights) const = 0; + [[nodiscard]] radix::tile::Border formatRequiresBorder() const; + [[nodiscard]] const std::string& formatFileEnding() const; +}; + +#endif // PARALLELTILEGENERATOR_H diff --git a/src/tilebuilder/ParallelTiler.cpp b/src/tilebuilder/ParallelTiler.cpp new file mode 100644 index 0000000..3f1c295 --- /dev/null +++ b/src/tilebuilder/ParallelTiler.cpp @@ -0,0 +1,74 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "ParallelTiler.h" + +#include "Exception.h" +#include + +ParallelTiler::ParallelTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) : Tiler(grid, bounds, border, scheme) +{ +} + +radix::tile::Id ParallelTiler::southWestTile(unsigned zoom_level) const +{ + return grid().crsToTile(bounds().min, zoom_level).to(scheme()); +} + +radix::tile::Id ParallelTiler::northEastTile(unsigned zoom_level) const +{ + const auto epsilon = grid().resolution(zoom_level) / 100; + return grid().crsToTile(bounds().max - epsilon, zoom_level).to(scheme()); +} + +std::vector ParallelTiler::generateTiles(unsigned zoom_level) const +{ + // in the tms scheme south west corresponds to the smaller numbers. hence we can iterate from sw to ne + const auto sw = southWestTile(zoom_level).to(radix::tile::Scheme::Tms).coords; + const auto ne = northEastTile(zoom_level).to(radix::tile::Scheme::Tms).coords; + + std::vector tiles; + tiles.reserve((ne.y - sw.y + 1) * (ne.x - sw.x + 1)); + for (auto ty = sw.y; ty <= ne.y; ++ty) { + for (auto tx = sw.x; tx <= ne.x; ++tx) { + const auto tile_id = radix::tile::Id { zoom_level, { tx, ty }, radix::tile::Scheme::Tms }.to(scheme()); + tiles.emplace_back(tile_for(tile_id)); + if (tiles.size() >= 1'000'000'000) + // think about creating an on the fly tile generator. storing so many tiles takes a lot of memory. + throw Exception("Setting the zoom level so higher is probably not a good idea. This would generate more than 1'000 million tiles. " + "I'm aborting. If you really need this, then that means that the future is bright. But you'll have to edit the code..\n" + " . . \n / \\_/ \\ \n | O O | \n | ~V~ | _\n ~_ _ / // \n / \\ // \n" + " | || |/ \n | / \\ | \n || || \n \n"); + } + } + + return tiles; +} + +std::vector ParallelTiler::generateTiles(const std::pair& zoom_range) const +{ + std::vector tiles; + assert(zoom_range.first <= zoom_range.second); + for (ctb::i_zoom i = zoom_range.first; i <= zoom_range.second; ++i) { + auto zoom_level_tiles = generateTiles(i); + tiles.reserve(tiles.size() + zoom_level_tiles.size()); + std::move(zoom_level_tiles.begin(), zoom_level_tiles.end(), std::back_inserter(tiles)); + } + return tiles; +} diff --git a/unittests/main.cpp b/src/tilebuilder/ParallelTiler.h similarity index 57% rename from unittests/main.cpp rename to src/tilebuilder/ParallelTiler.h index 73406e0..7d01f0d 100644 --- a/unittests/main.cpp +++ b/src/tilebuilder/ParallelTiler.h @@ -17,26 +17,17 @@ * along with this program. If not, see . *****************************************************************************/ -#include -#include -#include +#pragma once -#define CATCH_CONFIG_MAIN -#include +#include "Tiler.h" -#ifdef NDEBUG -constexpr bool asserts_are_enabled = false; -#else -constexpr bool asserts_are_enabled = true; -#endif +class ParallelTiler : public Tiler { +public: + ParallelTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme); -TEST_CASE("check that asserts are enabled") -{ - CHECK(asserts_are_enabled); -} + [[nodiscard]] std::vector generateTiles(unsigned zoom_level) const; + [[nodiscard]] std::vector generateTiles(const std::pair& zoom_range) const; -TEST_CASE("check that NaNs are enabled (-ffast-math removes support, -fno-finite-math-only puts it back in)") -{ - CHECK(std::isnan(std::numeric_limits::quiet_NaN() * float(std::chrono::system_clock::now().time_since_epoch().count()))); - CHECK(std::isnan(double(std::numeric_limits::quiet_NaN() * float(std::chrono::system_clock::now().time_since_epoch().count())))); -} + [[nodiscard]] radix::tile::Id southWestTile(unsigned zoom_level) const; + [[nodiscard]] radix::tile::Id northEastTile(unsigned zoom_level) const; +}; diff --git a/src/tilebuilder/TileHeightsGenerator.cpp b/src/tilebuilder/TileHeightsGenerator.cpp new file mode 100644 index 0000000..0b577f6 --- /dev/null +++ b/src/tilebuilder/TileHeightsGenerator.cpp @@ -0,0 +1,84 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 madam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "TileHeightsGenerator.h" + +#include + +#include "Dataset.h" +#include "DatasetReader.h" +#include "TopDownTiler.h" +#include "ctb/GlobalGeodetic.hpp" +#include "ctb/GlobalMercator.hpp" +#include "depth_first_tile_traverser.h" +#include + +TileHeightsGenerator::TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path) + : m_input_data_path(std::move(input_data_path)) + , m_srs(srs) + , m_scheme(scheme) + , m_border(border) + , m_output_path(std::move(output_path)) +{ +} + +void TileHeightsGenerator::run(unsigned max_zoom_level) const +{ + struct MinMaxData { + radix::tile::Id tile_id; + std::pair min_max = std::make_pair(0, 9000); + }; + + const auto dataset = Dataset::make_shared(m_input_data_path); + + ctb::Grid grid = ctb::GlobalGeodetic(64); + if (m_srs == ctb::Grid::Srs::SphericalMercator) + grid = ctb::GlobalMercator(64); + const auto bounds = dataset->bounds(grid.getSRS()); + const auto tile_reader = DatasetReader(dataset, grid.getSRS(), 1, false); + const auto tiler = TopDownTiler(grid, bounds, m_border, m_scheme); + auto tile_heights = radix::TileHeights(); + + const auto read_function = [&](const radix::tile::Descriptor& tile) -> MinMaxData { + const auto tile_data = tile_reader.readWithOverviews(tile.srsBounds, tile.tileSize, tile.tileSize); + auto [min, max] = std::ranges::minmax(tile_data); + tile_heights.emplace(tile.id, std::make_pair(min, max)); + return { tile.id, std::make_pair(min, max) }; + }; + + std::vector>> aggregate_calls; + const auto aggregate_function = [&](const std::vector& data) -> MinMaxData { + const auto new_id = data.front().tile_id.parent(); + auto min_max = data.front().min_max; + for (const auto& d : data) { + min_max.first = std::min(min_max.first, d.min_max.first); + min_max.second = std::max(min_max.second, d.min_max.second); + } + tile_heights.emplace(new_id, min_max); + return { new_id, min_max }; + }; + + + traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 0, { 0, 0 }, m_scheme }, max_zoom_level); + if (m_srs == ctb::Grid::Srs::WGS84) { + // two root tiles + traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 0, { 1, 0 }, m_scheme }, max_zoom_level); + } + tile_heights.write_to(m_output_path); + +} diff --git a/src/tilebuilder/TileHeightsGenerator.h b/src/tilebuilder/TileHeightsGenerator.h new file mode 100644 index 0000000..0d64af5 --- /dev/null +++ b/src/tilebuilder/TileHeightsGenerator.h @@ -0,0 +1,39 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 madam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#pragma once + +#include +#include + +#include "ctb/Grid.hpp" +#include + + +class TileHeightsGenerator +{ + std::string m_input_data_path; + ctb::Grid::Srs m_srs; + radix::tile::Scheme m_scheme; + radix::tile::Border m_border; + std::filesystem::path m_output_path; +public: + TileHeightsGenerator(std::string input_data_path, ctb::Grid::Srs srs, radix::tile::Scheme scheme, radix::tile::Border border, std::filesystem::path output_path); + void run(unsigned max_zoom_level) const; +}; + diff --git a/src/tilebuilder/Tiler.cpp b/src/tilebuilder/Tiler.cpp new file mode 100644 index 0000000..00153c6 --- /dev/null +++ b/src/tilebuilder/Tiler.cpp @@ -0,0 +1,72 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 madam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "Tiler.h" + +#include + +Tiler::Tiler(ctb::Grid grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) + : m_grid(std::move(grid)) + , m_bounds(bounds) + , m_border_south_east(border) + , m_scheme(scheme) +{ + +} + +const ctb::Grid& Tiler::grid() const +{ + return m_grid; +} + +ctb::i_tile Tiler::grid_size() const +{ + return grid().tileSize(); +} + +ctb::i_tile Tiler::tile_size() const +{ + return grid_size() + unsigned(border_south_east()); +} + +radix::tile::Border Tiler::border_south_east() const +{ + return m_border_south_east; +} + +radix::tile::Descriptor Tiler::tile_for(const radix::tile::Id& tile_id) const +{ + radix::tile::SrsBounds srs_bounds = grid().srsBounds(tile_id, border_south_east() == radix::tile::Border::Yes); + return {tile_id, srs_bounds, grid().getEpsgCode(), grid_size(), tile_size()}; +} + +radix::tile::Scheme Tiler::scheme() const +{ + return m_scheme; +} + +const radix::tile::SrsBounds& Tiler::bounds() const +{ + return m_bounds; +} + +void Tiler::setBounds(const radix::tile::SrsBounds& newBounds) +{ + m_bounds = newBounds; +} + diff --git a/src/tilebuilder/Tiler.h b/src/tilebuilder/Tiler.h new file mode 100644 index 0000000..d477ce3 --- /dev/null +++ b/src/tilebuilder/Tiler.h @@ -0,0 +1,48 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#pragma once + +#include "ctb/Grid.hpp" +#include "ctb/types.hpp" +#include + +class Tiler +{ +public: + Tiler(ctb::Grid grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme); + + [[nodiscard]] radix::tile::Scheme scheme() const; + [[nodiscard]] const radix::tile::SrsBounds& bounds() const; + void setBounds(const radix::tile::SrsBounds& newBounds); + [[nodiscard]] radix::tile::Descriptor tile_for(const radix::tile::Id& tile_id) const; + +protected: + [[nodiscard]] const ctb::Grid& grid() const; + [[nodiscard]] ctb::i_tile grid_size() const; + [[nodiscard]] ctb::i_tile tile_size() const; + [[nodiscard]] radix::tile::Border border_south_east() const; + +private: + + const ctb::Grid m_grid; + radix::tile::SrsBounds m_bounds; + const radix::tile::Border m_border_south_east; + const radix::tile::Scheme m_scheme; +}; + diff --git a/src/tilebuilder/TopDownTiler.cpp b/src/tilebuilder/TopDownTiler.cpp new file mode 100644 index 0000000..9962962 --- /dev/null +++ b/src/tilebuilder/TopDownTiler.cpp @@ -0,0 +1,38 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "TopDownTiler.h" + +TopDownTiler::TopDownTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme) + : Tiler(grid, bounds, border, scheme) +{ +} + +std::vector TopDownTiler::generateTiles(const radix::tile::Id& parent_id) const +{ + assert(parent_id.scheme == scheme()); + const auto tile_ids = parent_id.to(scheme()).children(); + std::vector tiles; + for (const auto& tile_id : tile_ids) { + radix::tile::Descriptor t = tile_for(tile_id); + if (intersect(bounds(), t.srsBounds)) + tiles.push_back(std::move(t)); + } + + return tiles; +} diff --git a/src/tilebuilder/TopDownTiler.h b/src/tilebuilder/TopDownTiler.h new file mode 100644 index 0000000..a2e065d --- /dev/null +++ b/src/tilebuilder/TopDownTiler.h @@ -0,0 +1,30 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#pragma once +#include +#include "Tiler.h" +#include "ctb/Grid.hpp" +#include + +class TopDownTiler : public Tiler { +public: + TopDownTiler(const ctb::Grid& grid, const radix::tile::SrsBounds& bounds, radix::tile::Border border, radix::tile::Scheme scheme); + + [[nodiscard]] std::vector generateTiles(const radix::tile::Id& parent_id) const; +}; diff --git a/src/tilebuilder/algorithms/primitives.h b/src/tilebuilder/algorithms/primitives.h new file mode 100644 index 0000000..a610136 --- /dev/null +++ b/src/tilebuilder/algorithms/primitives.h @@ -0,0 +1,103 @@ +#include +#include +#include + +#ifndef ALGORITHMS_PRIMITIVES_H +#define ALGORITHMS_PRIMITIVES_H + +namespace primitives { + +// two times the area of the ccw triangle with vertices a, b, and c. +// negative, if the triangle is cw +template +inline T triAreaX2(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) +{ + // doesn't work for unsigned types. if you need that, come up with something :) + static_assert(std::is_signed_v); + return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); +} + +enum class Winding : char { + CW = -1, + Undefined = 0, + CCW = 1 +}; + +template +inline Winding winding(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) +{ + constexpr bool is_integral = std::is_integral_v; + if constexpr (is_integral) { + using Signed = typename std::conditional::type, T>::type; + auto v = (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) - (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); + if (v == 0) + return Winding::Undefined; + if (v < 0) + return Winding::CW; + return Winding::CCW; + } else { + auto v = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); + if (std::abs(v) < 0.0000000000000001) + return Winding::Undefined; + if (v < 0) + return Winding::CW; + return Winding::CCW; + } +} + +template +inline bool ccw(const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) +{ + constexpr bool is_integral = std::is_integral_v; + if constexpr (is_integral) { + using Signed = typename std::conditional::type, T>::type; + if constexpr (include_border) + return (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) >= (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); + return (Signed(b.x) - Signed(a.x)) * (Signed(c.y) - Signed(a.y)) > (Signed(b.y) - Signed(a.y)) * (Signed(c.x) - Signed(a.x)); + } + if constexpr (include_border) + return (b.x - a.x) * (c.y - a.y) >= (b.y - a.y) * (c.x - a.x); + return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x); +} + +template +inline bool rightOf(const glm::tvec2& x, const glm::tvec2& org, const glm::tvec2& dest) +{ + return ccw(x, dest, org); +} + +template +inline bool leftOf(const glm::tvec2& x, const glm::tvec2& org, const glm::tvec2& dest) +{ + return ccw(x, org, dest); +} + +// https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage +// the bottom edge of the raster is not included! +template +inline bool inside(const glm::tvec2& x, const glm::tvec2& a, const glm::tvec2& b, const glm::tvec2& c) +{ + constexpr bool is_integral = std::is_integral_v; + using Signed = typename std::conditional::type, T>::type; + using sVec = glm::tvec2; + // return leftOf(x, a, b) && leftOf(x, b, c) && leftOf(x, c, a); + const auto ccw = [](Winding w) { return w == Winding::CCW; }; + const auto undef = [](Winding w) { return w == Winding::Undefined; }; + const auto topleftedge = [](const sVec& edge) { return (edge.y == 0 && edge.x < 0) || edge.y < 0; }; + + const auto w_ab = winding(x, a, b); + const auto w_bc = winding(x, b, c); + const auto w_ca = winding(x, c, a); + const auto e_ab = sVec(b) - sVec(a); + const auto e_bc = sVec(c) - sVec(b); + const auto e_ca = sVec(a) - sVec(c); + + bool overlap = true; + overlap &= ccw(w_ab) || (undef(w_ab) && topleftedge(e_ab)); + overlap &= ccw(w_bc) || (undef(w_bc) && topleftedge(e_bc)); + overlap &= ccw(w_ca) || (undef(w_ca) && topleftedge(e_ca)); + return overlap; +} +} + +#endif diff --git a/src/tilebuilder/algorithms/raster_triangle_scanline.h b/src/tilebuilder/algorithms/raster_triangle_scanline.h new file mode 100644 index 0000000..7e22fdc --- /dev/null +++ b/src/tilebuilder/algorithms/raster_triangle_scanline.h @@ -0,0 +1,101 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef ALGORITHMS_RASTER_TRIANGLE_SCANLINE_H +#define ALGORITHMS_RASTER_TRIANGLE_SCANLINE_H + +#include "primitives.h" +#include "tntn/Raster.h" +#include +#include +#include + +namespace raster { + +template +void triangle_scanline(const tntn::Raster& raster, const glm::uvec2& a, const glm::uvec2& b, const glm::uvec2& c, const Lambda& fun) +{ + assert(primitives::winding(a, b, c) == primitives::Winding::CCW); + + const auto min = glm::min(glm::min(a, b), c); + const auto max = glm::max(glm::max(a, b), c); + for (auto y = min.y; y <= max.y; ++y) { + for (auto x = min.x; x <= max.x; ++x) { + const auto coord = glm::uvec2(x, y); + if (primitives::inside(coord, a, b, c)) + fun(coord, raster.value(coord.y, coord.x)); // raster is row / column + } + } + if (min.y == 0) { + // bottom row of raster is not included in primitives::inside, so check for it and make an extrawurscht. + const auto walk_bottom = [&](const glm::uvec2& a, const glm::uvec2& b) { + if ((b - a).y == 0 && a.y == 0) { + const auto end_x = std::max(a.x, b.x); + for (auto x = std::min(a.x, b.x); x < end_x; ++x) { + const auto coord = glm::uvec2(x, 0); + fun(coord, raster.value(coord.y, coord.x)); // raster is row / column + } + } + }; + walk_bottom(a, b); + walk_bottom(b, c); + walk_bottom(c, a); + } + const auto last_x = raster.get_width() - 1; + if (max.x == last_x) { + // similar with the rightmost column + const auto walk_right = [&](const glm::uvec2& a, const glm::uvec2& b) { + if ((b - a).x == 0 && a.x == last_x) { + const auto end_y = std::max(a.y, b.y); + for (auto y = std::min(a.y, b.y); y < end_y; ++y) { + const auto coord = glm::uvec2(last_x, y); + fun(coord, raster.value(coord.y, coord.x)); // raster is row / column + } + } + }; + walk_right(a, b); + walk_right(b, c); + walk_right(c, a); + } + // if (max.x == last_x && min.y == 0) { + // const auto check_br = [&](const glm::uvec2& a, const glm::uvec2& b) { + // if ((b - a).y == 0 && a.y == 0 && b.x == last_x) { + // const auto coord = glm::uvec2(last_x, 0); + // fun(coord, raster.value(coord.y, coord.x)); // raster is row / column + // } + // }; + // check_br(a, b); + // check_br(b, c); + // check_br(c, a); + // } + const auto last_y = raster.get_height() - 1; + if (max.x == last_x && max.y == last_y) { + const auto check_tr = [&](const glm::uvec2& a, const glm::uvec2& b) { + if ((b - a).x == 0 && b.y == last_y && b.x == last_x) { + const auto coord = glm::uvec2(last_x, last_y); + fun(coord, raster.value(coord.y, coord.x)); // raster is row / column + } + }; + check_tr(a, b); + check_tr(b, c); + check_tr(c, a); + } +} +} +#endif diff --git a/src/tilebuilder/alpine_raster.cpp b/src/tilebuilder/alpine_raster.cpp new file mode 100644 index 0000000..dfa075d --- /dev/null +++ b/src/tilebuilder/alpine_raster.cpp @@ -0,0 +1,42 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "alpine_raster.h" + +#include +#include +#include + +#include +#include + +#include "Image.h" +#include "ParallelTileGenerator.h" +#include "ctb/Grid.hpp" +#include + +ParallelTileGenerator alpine_raster::make_generator(const std::string& input_data_path, const std::string& output_data_path, ctb::Grid::Srs srs, radix::tile::Scheme tiling_scheme, radix::tile::Border border, unsigned grid_resolution) +{ + return ParallelTileGenerator::make(input_data_path, srs, tiling_scheme, std::make_unique(border), output_data_path, grid_resolution); +} + +void alpine_raster::TileWriter::write(const std::string& file_path, const radix::tile::Descriptor& tile, const HeightData& heights) const +{ + image::saveImageAsPng(image::transformImage(heights, radix::height_encoding::to_rgb), + file_path); +} diff --git a/src/tilebuilder/alpine_raster.h b/src/tilebuilder/alpine_raster.h new file mode 100644 index 0000000..966d55f --- /dev/null +++ b/src/tilebuilder/alpine_raster.h @@ -0,0 +1,52 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef ALPINERASTERGENERATOR_H +#define ALPINERASTERGENERATOR_H + +#include + +#include +#include + +#include "Image.h" +#include "ParallelTileGenerator.h" +#include +#include "ctb/Grid.hpp" + +namespace alpine_raster { + +class TileWriter : public ParallelTileWriterInterface { +public: + TileWriter(radix::tile::Border border) + : ParallelTileWriterInterface(border, "png") + { + } + void write(const std::string& base_path, const radix::tile::Descriptor& tile, const HeightData& heights) const override; +}; +[[nodiscard]] ParallelTileGenerator make_generator( + const std::string& input_data_path, + const std::string& output_data_path, + ctb::Grid::Srs srs, + radix::tile::Scheme tiling_scheme, + radix::tile::Border border, + unsigned grid_resolution = 256); +}; + +#endif // ALPINERASTERGENERATOR_H diff --git a/src/tilebuilder/depth_first_tile_traverser.h b/src/tilebuilder/depth_first_tile_traverser.h new file mode 100644 index 0000000..46acb78 --- /dev/null +++ b/src/tilebuilder/depth_first_tile_traverser.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#pragma once + +#include "TopDownTiler.h" + +template +auto traverse_depth_first_and_aggregate(const TopDownTiler& tiler, ReadFunction read, AggregateFunction aggregate, const radix::tile::Id& root_tile_id, unsigned max_zoom_level) + -> decltype(read(tiler.tile_for(root_tile_id))) +{ + using DataType = decltype(read(tiler.tile_for(root_tile_id))); + const auto subtiles = tiler.generateTiles(root_tile_id); + // subtiles can be empty if the parent tile had an overlap with the dataset extent only on the border pixels. + if (root_tile_id.zoom_level == max_zoom_level || subtiles.empty()) { + return read(tiler.tile_for(root_tile_id)); + } + + std::vector unaggregated_data; + for (const auto& tile : subtiles) { + auto tile_data = traverse_depth_first_and_aggregate(tiler, read, aggregate, tile.id, max_zoom_level); + unaggregated_data.emplace_back(std::move(tile_data)); + } + + return aggregate(unaggregated_data); +} diff --git a/src/tilebuilder/main.cpp b/src/tilebuilder/main.cpp new file mode 100644 index 0000000..c2f0fe0 --- /dev/null +++ b/src/tilebuilder/main.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include + +#include "ParallelTiler.h" +#include "TileHeightsGenerator.h" +#include "alpine_raster.h" +#include "ctb/Grid.hpp" + +int main() +{ + // const std::string input_raster = "/home/madam/rajaton/raw/Oe_2020/OeRect_01m_gs_31287.img"; + // const std::string output_path = "/home/madam/rajaton/tiles/atb_terrain/"; + //// const auto generator = alpine_raster::make_generator("./test_tiles/", "/home/madam/valtava/raw/Oe_2020/OeRect_01m_gs_31287.img", ctb::Grid::Srs::SphericalMercator, Tiler::Scheme::SlippyMap, Tiler::Border::No); + //// generator.process({16, 16}); + // const auto generator = cesium_tin_terra::make_generator(input_raster, output_path, ctb::Grid::Srs::WGS84, Tiler::Scheme::Tms, Tiler::Border::Yes); + // generator.process({0, 5}, true, true); + // generator.process({6, 16}, true, false); + + const std::string input_raster = "/home/madam/valtava/raw/Oe_2020/OeRect_01m_gs_31287.img"; +// const std::string input_raster = "/home/madam/valtava/raw/vienna/innenstadt_gs_1m_mgi.tif"; + const std::string output_path = "/home/madam/valtava/tiles/alpine_png2"; + // const auto generator = alpine_raster::make_generator("./test_tiles/", "/home/madam/valtava/raw/Oe_2020/OeRect_01m_gs_31287.img", ctb::Grid::Srs::SphericalMercator, Tiler::Scheme::SlippyMap, Tiler::Border::No); + // generator.process({16, 16}); + const auto generator = alpine_raster::make_generator(input_raster, output_path, ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes, 64); + // generator.process({0, 5}, true, true); + generator.process({ 15, 16 }, true, false); + + // const auto metadata = MetaDataGenerator::make(input_raster, ctb::Grid::Srs::WGS84, Tiler::Scheme::Tms); + // const auto json = layer_json_writer::process(metadata); + + //// generate height data (min and max) for tiles up to level 13 +// const auto base_path = std::filesystem::path(output_path); +// constexpr auto file_name = "height_data.atb"; +// const auto generator = TileHeightsGenerator(input_raster, ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); +// generator.run(13); + + return 0; +} diff --git a/src/tilebuilder/srs.h b/src/tilebuilder/srs.h new file mode 100644 index 0000000..5032536 --- /dev/null +++ b/src/tilebuilder/srs.h @@ -0,0 +1,136 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 alpinemaps.org + * Copyright (C) 2022 Adam Celarek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef SRS_H +#define SRS_H + +#include +#include +#include + +#include +#include +#include + +#include "Exception.h" +#include + +namespace srs { + +inline std::unique_ptr transformation(const OGRSpatialReference& source, const OGRSpatialReference& targetSrs) +{ + const auto data_srs = source; + auto transformer = std::unique_ptr(OGRCreateCoordinateTransformation(&data_srs, &targetSrs)); + if (!transformer) + throw Exception("Couldn't create SRS transformation"); + return transformer; +} + +// this transform is non exact, because we are only transforming the corner vertices. however, due to projection warping, a rectangle can become an trapezoid with curved edges. +inline radix::tile::SrsBounds nonExactBoundsTransform(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& sourceSrs, const OGRSpatialReference& targetSrs) +{ + const auto transform = transformation(sourceSrs, targetSrs); + std::array xes = { bounds.min.x, bounds.max.x }; + std::array yes = { bounds.min.y, bounds.max.y }; + if (!transform->Transform(2, xes.data(), yes.data())) + throw Exception("nonExactBoundsTransform failed"); + return { {xes[0], yes[0]}, {xes[1], yes[1]} }; +} + +template +inline glm::tvec3 to(const OGRSpatialReference& source_srs, const OGRSpatialReference& target_srs, glm::tvec3 p) +{ + const auto transform = transformation(source_srs, target_srs); + if (!transform->Transform(1, &p.x, &p.y, &p.z)) + throw Exception("srs::to(glm::tvec3) failed"); + return p; +} + +template +inline glm::tvec3 toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p) +{ + OGRSpatialReference ecef_srs; + ecef_srs.importFromEPSG(4978); + ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + return to(source_srs, ecef_srs, p); +} + +template +inline std::vector> toECEF(const OGRSpatialReference& source_srs, std::vector> points) +{ + std::vector xes; + std::vector ys; + std::vector zs; + xes.reserve(points.size()); + ys.reserve(points.size()); + zs.reserve(points.size()); + + for (const auto& p : points) { + xes.push_back(p.x); + ys.push_back(p.y); + zs.push_back(p.z); + } + + OGRSpatialReference ecef_srs; + ecef_srs.importFromEPSG(4978); + ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + const auto transform = transformation(source_srs, ecef_srs); + if (!transform->Transform(int(points.size()), xes.data(), ys.data(), zs.data())) + throw Exception("toECEF(glm::tvec3) failed"); + + for (size_t i = 0; i < points.size(); ++i) { + points[i] = { xes[i], ys[i], zs[i] }; + } + return points; +} + +template +inline std::array, n> toECEF(const OGRSpatialReference& source_srs, std::array, n> points) +{ + std::array xes; + std::array ys; + std::array zs; + + for (size_t i = 0; i < points.size(); ++i) { + xes[i] = points[i].x; + ys[i] = points[i].y; + zs[i] = points[i].z; + } + + OGRSpatialReference ecef_srs; + ecef_srs.importFromEPSG(4978); + ecef_srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); + const auto transform = transformation(source_srs, ecef_srs); + if (!transform->Transform(points.size(), xes.data(), ys.data(), zs.data())) + throw Exception("toECEF(glm::tvec3) failed"); + + for (size_t i = 0; i < points.size(); ++i) { + points[i] = { xes[i], ys[i], zs[i] }; + } + return points; +} + +template +inline std::array, 2> toECEF(const OGRSpatialReference& source_srs, const glm::tvec3& p1, const glm::tvec3& p2) +{ + return toECEF(source_srs, { p1, p2 }); +} +} + +#endif // SRS_H diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index a9c4b8d..0198ce2 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -10,38 +10,49 @@ if (NOT TARGET Catch2) alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.5.1) endif() -add_executable(unittests_terrainlib - alpine_raster_format.cpp - catch2_helpers.h - dataset.cpp - dataset_reading.cpp - depth_first_tile_traverser.cpp - grid.cpp - image.cpp - main.cpp - parallel_tile_generator.cpp - parallel_tiler.cpp - progress_indicator_test.cpp - tile_heights_generator.cpp - top_down_tiler.cpp +add_compile_definitions( + ATB_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/unittests/data/" + ATB_UNITTESTS_AUSTRIA_HIGHRES="${ATB_UNITTESTS_AUSTRIA_HIGHRES}" ) - -target_compile_definitions(unittests_terrainlib PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") -target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_AUSTRIA_HIGHRES=\"${ATB_UNITTESTS_AUSTRIA_HIGHRES}\"") + if (ATB_UNITTESTS_EXTENDED) - target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_EXTENDED=true") + add_compile_definitions(ATB_UNITTESTS_EXTENDED=true) else() - target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_EXTENDED=false") + add_compile_definitions(ATB_UNITTESTS_EXTENDED=false) endif() + if (ATB_UNITTESTS_DEBUG_IMAGES) - target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_DEBUG_IMAGES=true") + add_compile_definitions(ATB_UNITTESTS_DEBUG_IMAGES=true) else() - target_compile_definitions(unittests_terrainlib PUBLIC "ATB_UNITTESTS_DEBUG_IMAGES=false") + add_compile_definitions(ATB_UNITTESTS_DEBUG_IMAGES=false) endif() + +add_executable(unittests_terrainlib + catch2_helpers.h + terrainlib/dataset.cpp + terrainlib/grid.cpp + terrainlib/progress_indicator_test.cpp +) + target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) +add_executable(unittests_tilebuilder + catch2_helpers.h + tilebuilder/alpine_raster_format.cpp + tilebuilder/dataset_reading.cpp + tilebuilder/depth_first_tile_traverser.cpp + tilebuilder/image.cpp + tilebuilder/parallel_tile_generator.cpp + tilebuilder/parallel_tiler.cpp + tilebuilder/tile_heights_generator.cpp + tilebuilder/top_down_tiler.cpp +) + +target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2WithMain) + + add_executable(unittests_terrainmerger catch2_helpers.h terrainmerger/convert.cpp diff --git a/unittests/progress_indicator_test.cpp b/unittests/progress_indicator_test.cpp deleted file mode 100644 index c5016c5..0000000 --- a/unittests/progress_indicator_test.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 Adam Celarek - * Copyright (C) 2022 alpinemaps.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "ParallelTileGenerator.h" -#include "ProgressIndicator.h" -#include -#include -#include -#include - -using namespace std::literals; -using namespace radix; - -TEST_CASE("progress indicator") -{ - SECTION("throws on overflow") - { - { - auto pi = ProgressIndicator(0); - CHECK_THROWS(pi.taskFinished()); - } - { - auto pi = ProgressIndicator(1); - pi.taskFinished(); - CHECK_THROWS(pi.taskFinished()); - } - } - SECTION("bar and message") - { - const std::string m5 = "-----"; - const std::string m10 = m5 + m5; - const std::string m20 = m10 + m10; - const std::string m50 = m20 + m20 + m10; - const std::string b5 = "|||||"; - const std::string b10 = b5 + b5; - const std::string b20 = b10 + b10; - const std::string b50 = b20 + b20 + b10; - - auto pi = ProgressIndicator(4); - CHECK(pi.progressBar() == m50 + m50); - CHECK(pi.xOfYDoneMessagE() == "0/4"); - pi.taskFinished(); - CHECK(pi.progressBar() == b20 + b5 + m20 + m5 + m50); - CHECK(pi.xOfYDoneMessagE() == "1/4"); - pi.taskFinished(); - CHECK(pi.progressBar() == b50 + m50); - CHECK(pi.xOfYDoneMessagE() == "2/4"); - pi.taskFinished(); - CHECK(pi.progressBar() == b50 + b20 + b5 + m20 + m5); - CHECK(pi.xOfYDoneMessagE() == "3/4"); - pi.taskFinished(); - CHECK(pi.progressBar() == b50 + b50); - CHECK(pi.xOfYDoneMessagE() == "4/4"); - } - - SECTION("taskFinished is thread safe") - { - const auto tasks = std::vector(1000000); - auto pi = ProgressIndicator(tasks.size()); - std::for_each(std::execution::par, tasks.begin(), tasks.end(), [&](const auto&) { pi.taskFinished(); }); - CHECK_THROWS(pi.taskFinished()); - } - - SECTION("thread parallel reporting") - { - // no real test, because console output can't be easily tested. but at least we are test compiling the interface. - const auto tasks = std::vector(151); - auto pi = ProgressIndicator(tasks.size()); - auto monitoring_thread = pi.startMonitoring(); - std::for_each(std::execution::par, tasks.begin(), tasks.end(), [&](const auto&) { std::this_thread::sleep_for(10ms); pi.taskFinished(); }); - monitoring_thread.join(); - CHECK_THROWS(pi.taskFinished()); - } - - SECTION("parallel processing interface") - { - class MockTileWriter : public ParallelTileWriterInterface { - public: - MockTileWriter() - : ParallelTileWriterInterface(tile::Border::No, "empty") - { - } - void write(const std::string&, const tile::Descriptor&, const HeightData&) const override { std::this_thread::sleep_for(1ms); } - }; - - auto generator = ParallelTileGenerator::make(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, std::make_unique(), "./unittest_tiles/"); - generator.setWarnOnMissingOverviews(false); - generator.process({ 0, 8 }, true); - } -} diff --git a/unittests/dataset.cpp b/unittests/terrainlib/dataset.cpp similarity index 98% rename from unittests/dataset.cpp rename to unittests/terrainlib/dataset.cpp index 4ff40bc..067b8e1 100644 --- a/unittests/dataset.cpp +++ b/unittests/terrainlib/dataset.cpp @@ -29,7 +29,7 @@ using namespace radix; using Catch::Approx; -void checkBounds(const tile::SrsBounds& a, const tile::SrsBounds& b) +void checkBounds(const radix::tile::SrsBounds& a, const radix::tile::SrsBounds& b) { REQUIRE(a.height() > 0); REQUIRE(a.width() > 0); diff --git a/unittests/grid.cpp b/unittests/terrainlib/grid.cpp similarity index 100% rename from unittests/grid.cpp rename to unittests/terrainlib/grid.cpp diff --git a/unittests/terrainlib/progress_indicator_test.cpp b/unittests/terrainlib/progress_indicator_test.cpp new file mode 100644 index 0000000..b994ddb --- /dev/null +++ b/unittests/terrainlib/progress_indicator_test.cpp @@ -0,0 +1,103 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "ProgressIndicator.h" +#include +#include +#include +#include + +using namespace std::literals; + + +TEST_CASE("progress indicator") +{ + SECTION("throws on overflow") + { + { + auto pi = ProgressIndicator(0); + CHECK_THROWS(pi.task_finished()); + } + { + auto pi = ProgressIndicator(1); + pi.task_finished(); + CHECK_THROWS(pi.task_finished()); + } + } + + SECTION("message") + { + ProgressIndicator pi(4); + // Step 0 + CHECK(pi.x_of_y_done_message() == "0/4"); + + // Step 1 + pi.task_finished(); + CHECK(pi.x_of_y_done_message() == "1/4"); + + // Step 2 + pi.task_finished(); + CHECK(pi.x_of_y_done_message() == "2/4"); + + // Step 3 + pi.task_finished(); + CHECK(pi.x_of_y_done_message() == "3/4"); + + // Step 4 + pi.task_finished(); + CHECK(pi.x_of_y_done_message() == "4/4"); + } + + SECTION("bar small") + { + ProgressIndicator pi(2); + // Step 0 + CHECK(pi.progress_bar(2) == "[]"); + CHECK(pi.progress_bar(3) == "[ ]"); + + // Step 1 + pi.task_finished(); + CHECK(pi.progress_bar(2) == "[]"); + CHECK(pi.progress_bar(3) == "[>]"); + + // Step 2 + pi.task_finished(); + CHECK(pi.progress_bar(2) == "[]"); + CHECK(pi.progress_bar(3) == "[=]"); + } + + SECTION("task_finished is thread safe") + { + const auto tasks = std::vector(1000000); + auto pi = ProgressIndicator(tasks.size()); + std::for_each(std::execution::par, tasks.begin(), tasks.end(), [&](const auto&) { pi.task_finished(); }); + CHECK_THROWS(pi.task_finished()); + } + + SECTION("thread parallel reporting") + { + // no real test, because console output can't be easily tested. but at least we are test compiling the interface. + const auto tasks = std::vector(151); + auto pi = ProgressIndicator(tasks.size()); + auto monitoring_thread = pi.start_monitoring(); + std::for_each(std::execution::par, tasks.begin(), tasks.end(), [&](const auto&) { std::this_thread::sleep_for(10ms); pi.task_finished(); }); + monitoring_thread.join(); + CHECK_THROWS(pi.task_finished()); + } +} diff --git a/unittests/alpine_raster_format.cpp b/unittests/tilebuilder/alpine_raster_format.cpp similarity index 76% rename from unittests/alpine_raster_format.cpp rename to unittests/tilebuilder/alpine_raster_format.cpp index 5f71b60..df7f219 100644 --- a/unittests/alpine_raster_format.cpp +++ b/unittests/tilebuilder/alpine_raster_format.cpp @@ -30,9 +30,9 @@ using namespace radix; -tile::Border testTypeValue2Border(bool v) +radix::tile::Border testTypeValue2Border(bool v) { - return v ? tile::Border::Yes : tile::Border::No; + return v ? radix::tile::Border::Yes : radix::tile::Border::No; } TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::false_type) @@ -41,15 +41,15 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal SECTION("raste write") { - const auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, tile::Border::Yes); - generator.write(tile::Descriptor { {0, glm::uvec2(0, 0)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); + const auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes); + generator.write(radix::tile::Descriptor { {0, glm::uvec2(0, 0)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); CHECK(std::filesystem::exists("./unittest_tiles/0/0/0.png")); - generator.write(tile::Descriptor { {1, glm::uvec2(2, 3)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); + generator.write(radix::tile::Descriptor { {1, glm::uvec2(2, 3)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); CHECK(std::filesystem::exists("./unittest_tiles/1/2/3.png")); // check that a second write doesn't crash - generator.write(tile::Descriptor { {1, glm::uvec2(2, 3)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); + generator.write(radix::tile::Descriptor { {1, glm::uvec2(2, 3)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); CHECK(std::filesystem::exists("./unittest_tiles/1/2/3.png")); // in the best case, we would read back the data and check it. but that's too much work for now. @@ -58,12 +58,12 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal SECTION("process all tiles") { - auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, testTypeValue2Border(TestType::value)); + auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); generator.setWarnOnMissingOverviews(false); generator.process({ 0, 7 }); const auto tiles = generator.tiler().generateTiles({ 0, 7 }); - const auto check = [](const tile::Descriptor& t) { + const auto check = [](const radix::tile::Descriptor& t) { return std::filesystem::exists(fmt::format("./unittest_tiles/{}/{}/{}.png", t.id.zoom_level, t.id.coords.x, t.id.coords.y)); }; CHECK(std::transform_reduce(tiles.begin(), tiles.end(), true, std::logical_and<>(), check) == true); @@ -71,12 +71,12 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal #if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED SECTION("process all tiles with max zoom") { - auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, testTypeValue2Border(TestType::value)); + auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); generator.setWarnOnMissingOverviews(false); generator.process({ 4, 8 }); const auto tiles = generator.tiler().generateTiles({ 4, 8 }); - const auto check = [](const tile::Descriptor& t) { + const auto check = [](const radix::tile::Descriptor& t) { return std::filesystem::exists(fmt::format("./unittest_tiles/{}/{}/{}.png", t.id.zoom_level, t.id.coords.x, t.id.coords.y)); }; CHECK(std::transform_reduce(tiles.begin(), tiles.end(), true, std::logical_and<>(), check) == true); diff --git a/unittests/dataset_reading.cpp b/unittests/tilebuilder/dataset_reading.cpp similarity index 94% rename from unittests/dataset_reading.cpp rename to unittests/tilebuilder/dataset_reading.cpp index 9418806..f981570 100644 --- a/unittests/dataset_reading.cpp +++ b/unittests/tilebuilder/dataset_reading.cpp @@ -70,18 +70,18 @@ TEST_CASE("reading") std::make_tuple( "at100m", at100m, - tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, + radix::tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, std::make_tuple(100.0f, 120.0f, 3000.0f, 3800.0f)), // Austria is between 115 and 3798m std::make_tuple( "vienna20m", vienna20m, - tile::SrsBounds{{16.17, 48.14}, {16.59, 48.33}}, + radix::tile::SrsBounds{{16.17, 48.14}, {16.59, 48.33}}, std::make_tuple(140.0f, 180.0f, 500.0f, 560.0f)), // vienna, between 151 and 542m #endif std::make_tuple( "tauern10m", tauern10m, - tile::SrsBounds{{12.6934117, 47.0739300}, {12.6944580, 47.0748649}}, + radix::tile::SrsBounds{{12.6934117, 47.0739300}, {12.6944580, 47.0748649}}, std::make_tuple(3700.0f, 3720.0f, 3790.0f, 3800.0f)), // Grossglockner, 3798m with some surroundings }; @@ -95,7 +95,7 @@ TEST_CASE("reading") srs.importFromEPSG(test_srs); srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - const auto srs_bounds = srs::non_exact_bounds_transform(geodetic_bounds, geodetic_srs, srs); + const auto srs_bounds = srs::nonExactBoundsTransform(geodetic_bounds, geodetic_srs, srs); const auto reader = DatasetReader(dataset, srs, 1); if (ATB_UNITTESTS_DEBUG_IMAGES) { @@ -127,19 +127,19 @@ TEST_CASE("reading") std::make_tuple( "at100m", at100m, - tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, + radix::tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, 620U, 350U, 42.0, 22.0), #endif std::make_tuple( "pizbuin1m", pizbuin1m, - tile::SrsBounds{{10.105646780, 46.839864531}, {10.129815588, 46.847626067}}, + radix::tile::SrsBounds{{10.105646780, 46.839864531}, {10.129815588, 46.847626067}}, 740U, 315U, 3.01, 0.006), #if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED std::make_tuple( "pizbuin1m_highres", pizbuin1m, - tile::SrsBounds{{10.105646780, 46.839864531}, {10.129815588, 46.847626067}}, + radix::tile::SrsBounds{{10.105646780, 46.839864531}, {10.129815588, 46.847626067}}, 2000U, 850U, 10.0, 0.008), #endif }; @@ -251,7 +251,7 @@ TEST_CASE("reading") const auto srs = low_res_ds->srs(); const auto low_res_reader = DatasetReader(low_res_ds, srs, 1); const auto high_res_reader = DatasetReader(high_res_ds, srs, 1); - const auto srs_bounds = srs::nonExactBoundsTransform(tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, geodetic_srs, srs); + const auto srs_bounds = srs::nonExactBoundsTransform(radix::tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, geodetic_srs, srs); const auto render_width = unsigned(low_res_ds->widthInPixels(srs_bounds, srs)); const auto render_height = unsigned(low_res_ds->heightInPixels(srs_bounds, srs)); @@ -293,7 +293,7 @@ TEST_CASE("reading") const auto srs = low_res_ds->srs(); const auto low_res_reader = DatasetReader(low_res_ds, srs, 1); const auto high_res_reader = DatasetReader(high_res_ds, srs, 1); - const auto srs_bounds = srs::nonExactBoundsTransform(tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, geodetic_srs, srs); + const auto srs_bounds = srs::nonExactBoundsTransform(radix::tile::SrsBounds{{9.5, 46.4}, {17.1, 49.0}}, geodetic_srs, srs); const auto render_width = unsigned(low_res_ds->widthInPixels(srs_bounds, srs)) / 10; const auto render_height = unsigned(low_res_ds->heightInPixels(srs_bounds, srs)) / 10; diff --git a/unittests/depth_first_tile_traverser.cpp b/unittests/tilebuilder/depth_first_tile_traverser.cpp similarity index 73% rename from unittests/depth_first_tile_traverser.cpp rename to unittests/tilebuilder/depth_first_tile_traverser.cpp index 23c7949..8ad49f0 100644 --- a/unittests/depth_first_tile_traverser.cpp +++ b/unittests/tilebuilder/depth_first_tile_traverser.cpp @@ -32,13 +32,13 @@ using namespace radix; TEST_CASE("depth_first_tile_traverser interface") { struct ReadType { }; - const auto read_function = [&](tile::Descriptor) { return ReadType {}; }; + const auto read_function = [&](radix::tile::Descriptor) { return ReadType {}; }; const auto aggregate_function = [](std::vector) { return ReadType {}; }; const auto grid = ctb::GlobalMercator(); - const auto tiler = TopDownTiler(grid, grid.getExtent(), tile::Border::No, tile::Scheme::Tms); - const tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; + const auto tiler = TopDownTiler(grid, grid.getExtent(), radix::tile::Border::No, radix::tile::Scheme::Tms); + const radix::tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; const unsigned max_zoom_level = 3; ReadType result = traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, root_id, max_zoom_level); @@ -49,8 +49,8 @@ TEST_CASE("depth_first_tile_traverser basics") struct ReadType { glm::uvec2 d; }; - std::set read_tiles; - const auto read_function = [&](const tile::Descriptor& tile) { + std::set read_tiles; + const auto read_function = [&](const radix::tile::Descriptor& tile) { read_tiles.insert(tile.id); return ReadType {tile.id.coords}; }; @@ -68,15 +68,15 @@ TEST_CASE("depth_first_tile_traverser basics") }; const auto grid = ctb::GlobalMercator(); - const auto tiler = TopDownTiler(grid, grid.getExtent(), tile::Border::No, tile::Scheme::Tms); - const tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; + const auto tiler = TopDownTiler(grid, grid.getExtent(), radix::tile::Border::No, radix::tile::Scheme::Tms); + const radix::tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; SECTION("reads root tile #1") { const auto result = traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, root_id, 0); REQUIRE(read_tiles.size() == 1); CHECK(aggregate_calls.size() == 0); - CHECK(read_tiles.contains(tile::Id{0, {0, 0}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{0, {0, 0}, tiler.scheme()})); CHECK(result.d == glm::uvec2 { 0, 0 }); } @@ -84,7 +84,7 @@ TEST_CASE("depth_first_tile_traverser basics") { const auto result = traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 2, { 1, 3 } }, 2); REQUIRE(read_tiles.size() == 1); - CHECK(read_tiles.contains(tile::Id{2, {1, 3}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{2, {1, 3}, tiler.scheme()})); CHECK(result.d == glm::uvec2 { 1, 3 }); } @@ -92,10 +92,10 @@ TEST_CASE("depth_first_tile_traverser basics") { traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, { 0, { 0, 0 } }, 1); REQUIRE(read_tiles.size() == 4); - CHECK(read_tiles.contains(tile::Id{1, {0, 0}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{1, {0, 1}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{1, {1, 0}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{1, {1, 1}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{1, {0, 0}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{1, {0, 1}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{1, {1, 0}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{1, {1, 1}, tiler.scheme()})); } SECTION("aggregate is called correctly") @@ -119,11 +119,11 @@ TEST_CASE("depth_first_tile_traverser austrian heights") const auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_100m_mgi.tif"); // const auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto bounds = dataset->bounds(grid.getSRS()); - const auto tiler = TopDownTiler(grid, bounds, tile::Border::No, tile::Scheme::Tms); + const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, radix::tile::Scheme::Tms); const auto tile_reader = DatasetReader(dataset, grid.getSRS(), 1, false); // const auto dataset_reader = DatasetReader() - std::set read_tiles; - const auto read_function = [&](const tile::Descriptor& tile) -> std::pair { + std::set read_tiles; + const auto read_function = [&](const radix::tile::Descriptor& tile) -> std::pair { read_tiles.insert(tile.id); const auto tile_data = tile_reader.read(tile.srsBounds, tile.tileSize, tile.tileSize); auto [min, max] = std::ranges::minmax(tile_data); @@ -142,14 +142,14 @@ TEST_CASE("depth_first_tile_traverser austrian heights") return aggr; }; - const tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; + const radix::tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; SECTION("reads root tile") { const auto result = traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, root_id, 0); REQUIRE(read_tiles.size() == 1); CHECK(aggregate_calls.size() == 0); - CHECK(read_tiles.contains(tile::Id{0, {0, 0}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{0, {0, 0}, tiler.scheme()})); CHECK(result.first >= 0); CHECK(result.first <= 4000); CHECK(result.second >= 0); @@ -161,14 +161,14 @@ TEST_CASE("depth_first_tile_traverser austrian heights") const auto result = traverse_depth_first_and_aggregate(tiler, read_function, aggregate_function, root_id, 6); CHECK(read_tiles.size() == 6); CHECK(aggregate_calls.size() == 9); - CHECK(read_tiles.contains(tile::Id{6, {33, 41}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{6, {33, 42}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {33, 41}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {33, 42}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{6, {34, 41}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{6, {34, 42}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {34, 41}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {34, 42}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{6, {35, 41}, tiler.scheme()})); - CHECK(read_tiles.contains(tile::Id{6, {35, 42}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {35, 41}, tiler.scheme()})); + CHECK(read_tiles.contains(radix::tile::Id{6, {35, 42}, tiler.scheme()})); CHECK(result.first >= 0); CHECK(result.first <= 500); CHECK(result.second >= 2000); @@ -180,17 +180,17 @@ TEST_CASE("depth_first_tile_traverser aggregate is not called with an empty vect SECTION("web mercator") { const auto grid = ctb::GlobalMercator(); - // const auto bounds = tile::SrsBounds{ -180, -90, 0, 90 }; + // const auto bounds = radix::tile::SrsBounds{ -180, -90, 0, 90 }; auto bounds = grid.getExtent(); // this provokes the following situation: // parent tile is produced, because its border overlaps the extents // child tiles have smaller pixels -> their border does not overlap the extents any more. bounds.min.x = (bounds.width() / 256) / 4; - const auto tiler = TopDownTiler(grid, bounds, tile::Border::Yes, tile::Scheme::Tms); - const tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; + const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::Yes, radix::tile::Scheme::Tms); + const radix::tile::Id root_id = { 0, { 0, 0 }, tiler.scheme() }; - const auto read_function = [&](const tile::Descriptor&) -> int { + const auto read_function = [&](const radix::tile::Descriptor&) -> int { return 0; }; const auto aggregate_function = [&](const std::vector& data) -> int { diff --git a/unittests/image.cpp b/unittests/tilebuilder/image.cpp similarity index 100% rename from unittests/image.cpp rename to unittests/tilebuilder/image.cpp diff --git a/unittests/parallel_tile_generator.cpp b/unittests/tilebuilder/parallel_tile_generator.cpp similarity index 92% rename from unittests/parallel_tile_generator.cpp rename to unittests/tilebuilder/parallel_tile_generator.cpp index e516145..ade4164 100644 --- a/unittests/parallel_tile_generator.cpp +++ b/unittests/tilebuilder/parallel_tile_generator.cpp @@ -36,11 +36,11 @@ TEST_CASE("parallel tile generator") public: MockTileWriter(std::atomic* tile_counter) - : ParallelTileWriterInterface(tile::Border::No, "empty") + : ParallelTileWriterInterface(radix::tile::Border::No, "empty") , m_tile_counter(tile_counter) { } - void write(const std::string& file_path, const tile::Descriptor& tile, const HeightData& heights) const override + void write(const std::string& file_path, const radix::tile::Descriptor& tile, const HeightData& heights) const override { CHECK(!file_path.empty()); CHECK(tile.gridSize == 256); @@ -55,7 +55,7 @@ TEST_CASE("parallel tile generator") }; std::filesystem::path base_path = "./unittest_tiles/"; - auto generator = ParallelTileGenerator::make(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, std::make_unique(&tile_counter), base_path); + auto generator = ParallelTileGenerator::make(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, std::make_unique(&tile_counter), base_path); generator.setWarnOnMissingOverviews(false); SECTION("dataset tiles only") { diff --git a/unittests/parallel_tiler.cpp b/unittests/tilebuilder/parallel_tiler.cpp similarity index 93% rename from unittests/parallel_tiler.cpp rename to unittests/tilebuilder/parallel_tiler.cpp index 9f12cac..f638b14 100644 --- a/unittests/parallel_tiler.cpp +++ b/unittests/tilebuilder/parallel_tiler.cpp @@ -19,7 +19,7 @@ #include "Dataset.h" #include "ParallelTiler.h" -#include "catch2_helpers.h" +#include "../catch2_helpers.h" #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" #include @@ -35,11 +35,11 @@ using namespace radix; TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::false_type) { - // const auto bounds = tile::SrsBounds(1'000'000, 6'000'000, 2'000'000, 6'700'000); // in m + // const auto bounds = radix::tile::SrsBounds(1'000'000, 6'000'000, 2'000'000, 6'700'000); // in m SECTION("mercator / level 0") { const auto grid = ctb::GlobalMercator(); - const auto tiler = ParallelTiler(grid, grid.getExtent(), tile::Border::No, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, grid.getExtent(), radix::tile::Border::No, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(0).coords == glm::uvec2(0, 0)); CHECK(tiler.southWestTile(0).coords == glm::uvec2(0, 0)); @@ -63,7 +63,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f { const auto grid = ctb::GlobalMercator(); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); - const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), tile::Border::No, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::No, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(1, TestType::value ? 1 : 0)); CHECK(tiler.southWestTile(1).coords == glm::uvec2(1, TestType::value ? 1 : 0)); @@ -106,7 +106,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f SECTION("geodetic tms / level 0") { const auto grid = ctb::GlobalGeodetic(64); - const auto tiler = ParallelTiler(grid, grid.getExtent(), tile::Border::Yes, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, grid.getExtent(), radix::tile::Border::Yes, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(0).coords == glm::uvec2(1, 0)); CHECK(tiler.southWestTile(0).coords == glm::uvec2(0, 0)); @@ -144,7 +144,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f { const auto grid = ctb::GlobalGeodetic(64); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); - const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), tile::Border::Yes, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::Yes, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(2, TestType::value ? 1 : 0)); CHECK(tiler.southWestTile(1).coords == glm::uvec2(2, TestType::value ? 1 : 0)); @@ -190,7 +190,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f { const auto grid = ctb::GlobalMercator(); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/capehorn/small.tif"); - const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), tile::Border::No, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::No, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(0, TestType::value ? 0 : 1)); CHECK(tiler.southWestTile(1).coords == glm::uvec2(0, TestType::value ? 0 : 1)); @@ -234,7 +234,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f { const auto grid = ctb::GlobalGeodetic(64); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/capehorn/small.tif"); - const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), tile::Border::Yes, TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap); + const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::Yes, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(1, TestType::value ? 0 : 1)); CHECK(tiler.southWestTile(1).coords == glm::uvec2(1, TestType::value ? 0 : 1)); @@ -281,7 +281,7 @@ TEST_CASE("ParallelTiler returns tiles for several zoom levels") { const auto dataset = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto grid = ctb::GlobalMercator(256); - const auto tiler = ParallelTiler(grid, dataset.bounds(grid.getSRS()), tile::Border::Yes, tile::Scheme::Tms); + const auto tiler = ParallelTiler(grid, dataset.bounds(grid.getSRS()), radix::tile::Border::Yes, radix::tile::Scheme::Tms); SECTION("generate from 0 to 7") { @@ -301,7 +301,7 @@ TEST_CASE("ParallelTiler returns tiles for several zoom levels") CHECK(n_tiles[6] == 6); CHECK(n_tiles[7] == 12); - const auto check = [](const tile::Descriptor& t) { + const auto check = [](const radix::tile::Descriptor& t) { return t.tileSize == 257 && t.gridSize == 256; }; CHECK(std::transform_reduce(tiles.begin(), tiles.end(), true, std::logical_and<>(), check) == true); @@ -320,7 +320,7 @@ TEST_CASE("ParallelTiler returns tiles for several zoom levels") CHECK(n_tiles[5] == 4); CHECK(n_tiles[6] == 6); - const auto check = [](const tile::Descriptor& t) { + const auto check = [](const radix::tile::Descriptor& t) { return t.tileSize == 257 && t.gridSize == 256; }; CHECK(std::transform_reduce(tiles.begin(), tiles.end(), true, std::logical_and<>(), check) == true); diff --git a/unittests/tile_heights_generator.cpp b/unittests/tilebuilder/tile_heights_generator.cpp similarity index 92% rename from unittests/tile_heights_generator.cpp rename to unittests/tilebuilder/tile_heights_generator.cpp index 1978cda..40d23b2 100644 --- a/unittests/tile_heights_generator.cpp +++ b/unittests/tilebuilder/tile_heights_generator.cpp @@ -30,7 +30,7 @@ TEST_CASE("TileHeightsGenerator") constexpr auto file_name = "height_data.atb"; SECTION("mercator") { - const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, tile::Scheme::Tms, tile::Border::Yes, base_path / file_name); + const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); generator.run(8); const auto heights = TileHeights::read_from(base_path / file_name); @@ -50,7 +50,7 @@ TEST_CASE("TileHeightsGenerator") } SECTION("geodetic") { - const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::WGS84, tile::Scheme::Tms, tile::Border::Yes, base_path / file_name); + const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::WGS84, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); generator.run(8); const auto heights = TileHeights::read_from(base_path / file_name); diff --git a/unittests/top_down_tiler.cpp b/unittests/tilebuilder/top_down_tiler.cpp similarity index 83% rename from unittests/top_down_tiler.cpp rename to unittests/tilebuilder/top_down_tiler.cpp index 01d9bc8..f20071b 100644 --- a/unittests/top_down_tiler.cpp +++ b/unittests/tilebuilder/top_down_tiler.cpp @@ -27,12 +27,12 @@ using namespace radix; namespace { -void compare_tile_lists(const std::vector& a_tiles, std::vector b_tiles) +void compare_tile_lists(const std::vector& a_tiles, std::vector b_tiles) { CHECK(a_tiles.size() == b_tiles.size()); for (const auto& tile : a_tiles) { - const auto matching_tile_iter = std::find_if(b_tiles.begin(), b_tiles.end(), [&](const tile::Descriptor& t) { + const auto matching_tile_iter = std::find_if(b_tiles.begin(), b_tiles.end(), [&](const radix::tile::Descriptor& t) { return t.id == tile.id; }); REQUIRE(matching_tile_iter != b_tiles.end()); @@ -51,16 +51,16 @@ void compare_tile_lists(const std::vector& a_tiles, std::vecto TEMPLATE_TEST_CASE("BottomUpTiler, using tms scheme", "", std::true_type, std::false_type) { - const auto scheme = TestType::value ? tile::Scheme::Tms : tile::Scheme::SlippyMap; + const auto scheme = TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap; SECTION("mercator / level 0 all") { const auto grid = ctb::GlobalMercator(); - const auto tiler = TopDownTiler(grid, grid.getExtent(), tile::Border::No, scheme); + const auto tiler = TopDownTiler(grid, grid.getExtent(), radix::tile::Border::No, scheme); const auto tiles = tiler.generateTiles({0, { 0, 0 }, scheme}); REQUIRE(tiles.size() == 4); - const auto parallel_tiler = ParallelTiler(grid, grid.getExtent(), tile::Border::No, scheme); + const auto parallel_tiler = ParallelTiler(grid, grid.getExtent(), radix::tile::Border::No, scheme); compare_tile_lists(tiles, parallel_tiler.generateTiles(1)); } @@ -69,22 +69,22 @@ TEMPLATE_TEST_CASE("BottomUpTiler, using tms scheme", "", std::true_type, std::f const auto grid = ctb::GlobalMercator(); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto bounds = dataset->bounds(grid.getSRS()); - const auto tiler = TopDownTiler(grid, bounds, tile::Border::No, scheme); + const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, scheme); const auto tiles = tiler.generateTiles({0, { 0, 0 }, scheme}); REQUIRE(tiles.size() == 1); - const auto parallel_tiler = ParallelTiler(grid, bounds, tile::Border::No, scheme); + const auto parallel_tiler = ParallelTiler(grid, bounds, radix::tile::Border::No, scheme); compare_tile_lists(tiles, parallel_tiler.generateTiles(1)); } SECTION("geodetic / level 0 east half") { const auto grid = ctb::GlobalGeodetic(); - const auto tiler = TopDownTiler(grid, grid.getExtent(), tile::Border::No, scheme); + const auto tiler = TopDownTiler(grid, grid.getExtent(), radix::tile::Border::No, scheme); const auto tiles = tiler.generateTiles({0, { 1, 0 }, scheme}); REQUIRE(tiles.size() == 4); - const auto parallel_tiler = ParallelTiler(grid, {{0, -90}, {180, 90}}, tile::Border::No, scheme); + const auto parallel_tiler = ParallelTiler(grid, {{0, -90}, {180, 90}}, radix::tile::Border::No, scheme); compare_tile_lists(tiles, parallel_tiler.generateTiles(1)); } @@ -93,11 +93,11 @@ TEMPLATE_TEST_CASE("BottomUpTiler, using tms scheme", "", std::true_type, std::f const auto grid = ctb::GlobalGeodetic(); auto dataset = Dataset::make_shared(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto bounds = dataset->bounds(grid.getSRS()); - const auto tiler = TopDownTiler(grid, bounds, tile::Border::No, scheme); + const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, scheme); const auto tiles = tiler.generateTiles({0, { 1, 0 }, scheme}); REQUIRE(tiles.size() == 1); - const auto parallel_tiler = ParallelTiler(grid, bounds, tile::Border::No, scheme); + const auto parallel_tiler = ParallelTiler(grid, bounds, radix::tile::Border::No, scheme); compare_tile_lists(tiles, parallel_tiler.generateTiles(1)); } } From a5616300df20bd907d3d6ce37c1c91ca319c0b3b Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:08:41 +0200 Subject: [PATCH 055/122] Fix terrainmerger tests --- unittests/terrainmerger/convert.cpp | 1 + unittests/terrainmerger/merge.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/unittests/terrainmerger/convert.cpp b/unittests/terrainmerger/convert.cpp index 446d185..9360a51 100644 --- a/unittests/terrainmerger/convert.cpp +++ b/unittests/terrainmerger/convert.cpp @@ -1,6 +1,7 @@ #include #include #include "mesh/io.h" +#include "mesh/utils.h" #include "convert.h" #include "cgal.h" diff --git a/unittests/terrainmerger/merge.cpp b/unittests/terrainmerger/merge.cpp index 55d6da3..06ca10c 100644 --- a/unittests/terrainmerger/merge.cpp +++ b/unittests/terrainmerger/merge.cpp @@ -20,6 +20,7 @@ #define CATCH_CONFIG_MAIN #include #include "merge.h" +#include "mesh/utils.h" TEST_CASE("terrainmerger") { SECTION("two tris") { From 351b68fa5b321775b8817739f9593a46e3edd6f4 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:08:56 +0200 Subject: [PATCH 056/122] Fix terrainconvert --- src/terrainconvert/cli.cpp | 2 +- src/terrainconvert/cli.h | 4 +--- src/terrainconvert/main.cpp | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/terrainconvert/cli.cpp b/src/terrainconvert/cli.cpp index 08d4e10..4d9ee3c 100644 --- a/src/terrainconvert/cli.cpp +++ b/src/terrainconvert/cli.cpp @@ -6,7 +6,7 @@ using namespace cli; Args cli::parse(int argc, const char * const* argv) { assert(argc >= 0); - CLI::App app{"Terrain Convert"}; + CLI::App app{"terrainconvert"}; std::filesystem::path input_path; app.add_option("--input", input_path, "Path of tile to be converted") diff --git a/src/terrainconvert/cli.h b/src/terrainconvert/cli.h index 089e74e..dde4122 100644 --- a/src/terrainconvert/cli.h +++ b/src/terrainconvert/cli.h @@ -1,5 +1,4 @@ -#ifndef TERRAINCONVERT_CLI_H -#define TERRAINCONVERT_CCLI_H +#pragma once #include #include @@ -18,4 +17,3 @@ namespace cli { Args parse(int argc, const char *const *argv); } -#endif diff --git a/src/terrainconvert/main.cpp b/src/terrainconvert/main.cpp index 62d0b06..be97c9e 100644 --- a/src/terrainconvert/main.cpp +++ b/src/terrainconvert/main.cpp @@ -4,14 +4,14 @@ #include #include -#include "mesh/terrain_mesh.h" +#include "mesh/SimpleMesh.h" #include "mesh/io.h" #include "log.h" #include "cli.h" void run(const cli::Args& args) { LOG_INFO("Loading input mesh..."); - const tl::expected load_result = io::load_mesh_from_path(args.input_path); + const tl::expected load_result = mesh::io::load_from_path(args.input_path); if (!load_result.has_value()) { LOG_ERROR("Failed to load mesh: {}", load_result.error().description()); return; @@ -30,7 +30,7 @@ void run(const cli::Args& args) { } LOG_INFO("Writing output mesh..."); - const tl::expected save_result = io::save_mesh_to_path(args.output_path, mesh); + const tl::expected save_result = mesh::io::save_to_path(mesh, args.output_path); if (!save_result.has_value()) { LOG_ERROR("Failed to save mesh: {}", save_result.error().description()); return; From 129baeea74fc950f4d5e5e827279aca4735a6a9f Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:09:29 +0200 Subject: [PATCH 057/122] Correctly handle empty storage folder --- src/terrainlib/octree/Storage.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp index 2472c53..43223bf 100644 --- a/src/terrainlib/octree/Storage.cpp +++ b/src/terrainlib/octree/Storage.cpp @@ -177,6 +177,15 @@ Storage open_folder( bool save_index) { LOG_TRACE("Opening storage folder {}", base_path); + if (!std::filesystem::is_directory(base_path)) { + if (std::filesystem::exists(base_path)) { + LOG_ERROR_AND_EXIT("Base path {} exists but is not a directory", base_path); + } + + LOG_TRACE("Base path {} does not exist, creating it", base_path); + std::filesystem::create_directories(base_path); + } + const std::filesystem::path index_path = base_path / disk::v1::index_file_name(); auto storage_opt = load_index(index_path); if (storage_opt.has_value()) { From e5231a3d03cff87524678b556983edd4b34ce4de Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:09:39 +0200 Subject: [PATCH 058/122] Fix tile_downloader --- src/tile_downloader/main.cpp | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/tile_downloader/main.cpp b/src/tile_downloader/main.cpp index fe89b41..30594e4 100644 --- a/src/tile_downloader/main.cpp +++ b/src/tile_downloader/main.cpp @@ -98,7 +98,7 @@ bool create_directories2(const std::filesystem::path& path) { class TileUrlBuilder { public: - virtual std::string build_url(const tile::Id &tile_id) const = 0; + virtual std::string build_url(const radix::tile::Id &tile_id) const = 0; }; // https://mapsneu.wien.gv.at/basemapneu/1.0.0/WMTSCapabilities.xml @@ -109,8 +109,8 @@ class BasemapTileUrlBuilder : public TileUrlBuilder { this->style = map_get_or_default(args, "style"sv, "normal"sv); } - std::string build_url(const tile::Id &tile_id) const { - const tile::Id google_tile_id = tile_id.to(tile::Scheme::SlippyMap); + std::string build_url(const radix::tile::Id &tile_id) const { + const radix::tile::Id google_tile_id = tile_id.to(radix::tile::Scheme::SlippyMap); return fmt::format( "https://mapsneu.wien.gv.at/basemap/{}/{}/google3857/{}/{}/{}.jpeg", layer, style, google_tile_id.zoom_level, google_tile_id.coords.y, google_tile_id.coords.x); @@ -124,10 +124,10 @@ class BasemapTileUrlBuilder : public TileUrlBuilder { // https://gataki.cg.tuwien.ac.at/raw/basemap/tiles/11/710/1098.jpeg class GatakiTileUrlBuilder : public TileUrlBuilder { public: - GatakiTileUrlBuilder(const std::map &args) {} + GatakiTileUrlBuilder(const std::map &_args) {} - std::string build_url(const tile::Id &tile_id) const { - const tile::Id google_tile_id = tile_id.to(tile::Scheme::SlippyMap); + std::string build_url(const radix::tile::Id &tile_id) const { + const radix::tile::Id google_tile_id = tile_id.to(radix::tile::Scheme::SlippyMap); return fmt::format( "https://gataki.cg.tuwien.ac.at/raw/basemap/tiles/{}/{}/{}.jpeg", google_tile_id.zoom_level, google_tile_id.coords.y, google_tile_id.coords.x); @@ -136,17 +136,17 @@ class GatakiTileUrlBuilder : public TileUrlBuilder { private: }; -static std::string format_tile(const tile::Id tile) { +static std::string format_tile(const radix::tile::Id tile) { return fmt::format("Tile[Zoom={}, X={}, Y={}]", tile.zoom_level, tile.coords.x, tile.coords.y); } -void print_tile(const tile::Id tile) { +void print_tile(const radix::tile::Id tile) { std::string tile_str = format_tile(tile); fmt::print("{}", tile_str); std::fflush(nullptr); } -void update_tile_status(const tile::Id tile, const std::string_view status, const bool final) { +void update_tile_status(const radix::tile::Id tile, const std::string_view status, const bool final) { std::string tile_str = format_tile(tile); fmt::print("\33[2K\r{} ({}){}", tile_str, status, final ? "\n" : ""); std::fflush(nullptr); @@ -180,10 +180,10 @@ size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) { } struct ProgressCallbackData { - tile::Id tile; + radix::tile::Id tile; }; -int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { +int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t _ultotal, curl_off_t _ulnow) { ProgressCallbackData &data = *static_cast(clientp); if (dltotal == 0) { @@ -253,7 +253,7 @@ class TileDownloader } } - DownloadResult download_tile_by_url(const tile::Id tile, const std::string &url, const std::filesystem::path &path) const { + DownloadResult download_tile_by_url(const radix::tile::Id tile, const std::string &url, const std::filesystem::path &path) const { if (verbosity > 0) print_tile(tile); @@ -348,13 +348,13 @@ class TileDownloader return DownloadResult::Failed; } - DownloadResult download_tile_by_id(const tile::Id tile) const { + DownloadResult download_tile_by_id(const radix::tile::Id tile) const { const std::string url = this->url_builder->build_url(tile); const std::string path = this->get_tile_path(tile); return this->download_tile_by_url(tile, url, path); } - DownloadResult download_tile_by_id_recursive(const tile::Id root_id) const { + DownloadResult download_tile_by_id_recursive(const radix::tile::Id root_id) const { const std::string url = this->url_builder->build_url(root_id); const DownloadResult result = this->download_tile_by_id(root_id); @@ -362,13 +362,13 @@ class TileDownloader return result; } - const std::array subtiles = root_id.children(); + const std::array subtiles = root_id.children(); for (size_t i = 0; i < subtiles.size(); i++) { - const tile::Id &tile = subtiles[i]; + const radix::tile::Id &tile = subtiles[i]; if (early_skip && i + 1 < subtiles.size()) { - const tile::Id &next_tile = subtiles[i + 1]; + const radix::tile::Id &next_tile = subtiles[i + 1]; const std::string next_tile_path = this->get_tile_path(next_tile); if (std::filesystem::exists(next_tile_path)) { print_tile(tile); @@ -394,9 +394,9 @@ class TileDownloader std::string_view file_name_template; CURL *curl; bool early_skip; - std::optional max_zoom_level; + std::optional max_zoom_level; - std::string get_tile_path(const tile::Id tile) const { + std::string get_tile_path(const radix::tile::Id tile) const { std::string file_path(this->output_path); string_replace_all(file_path, "{zoom}"sv, std::to_string(tile.zoom_level)); string_replace_all(file_path, "{x}"sv, std::to_string(tile.coords.x)); @@ -449,11 +449,11 @@ int main(int argc, char *argv[]) { // Parse spatial reference system and scheme const unsigned int srs = svtoui(map_get_or_default(arg_map, "srs"sv, "3857"sv)); const std::string_view scheme_str = map_get_or_default(arg_map, "scheme"sv, "SlippyMap"sv); - tile::Scheme scheme; + radix::tile::Scheme scheme; if (string_equals_ignore_case(scheme_str, "SlippyMap") || string_equals_ignore_case(scheme_str, "Google") || string_equals_ignore_case(scheme_str, "XYZ")) { - scheme = tile::Scheme::SlippyMap; + scheme = radix::tile::Scheme::SlippyMap; } else if (string_equals_ignore_case(scheme_str, "TMS")) { - scheme = tile::Scheme::Tms; + scheme = radix::tile::Scheme::Tms; } else { throw std::runtime_error(fmt::format("unsupported srs scheme \"{}\"", scheme_str)); } @@ -470,7 +470,7 @@ int main(int argc, char *argv[]) { const unsigned int zoom = svtoui(map_get_required(arg_map, "zoom")); const unsigned int x = svtoui(map_get_required(arg_map, "x")); const unsigned int y = svtoui(map_get_required(arg_map, "y")); - const tile::Id root_id = {zoom, {x, y}, scheme}; + const radix::tile::Id root_id = {zoom, {x, y}, scheme}; // Download tile and subtiles recursively. TileDownloader downloader(url_builder.get(), arg_map); From f37f725881110e132ecfe45a720d55bb6a76e1d6 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 18:09:57 +0200 Subject: [PATCH 059/122] Remove old batch scripts --- batch-builder.py | 68 ----------------------- batch-converter.py | 45 --------------- batch-merger.py | 135 --------------------------------------------- 3 files changed, 248 deletions(-) delete mode 100644 batch-builder.py delete mode 100644 batch-converter.py delete mode 100644 batch-merger.py diff --git a/batch-builder.py b/batch-builder.py deleted file mode 100644 index ba4b093..0000000 --- a/batch-builder.py +++ /dev/null @@ -1,68 +0,0 @@ -import argparse -import subprocess -import os -from tqdm import tqdm - -def get_children(tile_x, tile_y): - children = [] - for i in range(4): - x = 2 * tile_x + (i % 2) - y = 2 * tile_y + (i // 2) - children.append((x, y)) - return children - -def build_command(terrainbuilder_path, tile_x, tile_y, zoom, output_dir, force_rebuild, args): - output_path = os.path.join(output_dir, str(zoom), str(tile_y), f"{tile_x}.tile") - # print(output_path) - if (not force_rebuild) and os.path.exists(output_path): - # print("\tSkipped") - return - - command = [ - terrainbuilder_path, - "--tile", str(zoom), str(tile_x), str(tile_y), - *args, - "--output", output_path - ] - try: - subprocess.run(command, check=True, stdout=subprocess.PIPE) - except subprocess.CalledProcessError as e: - print("CMD\n", terrainbuilder_path, "--tile", str(zoom), str(tile_x), str(tile_y), *args, "--output", output_path) - pass - -def process_tile(terrainbuilder_path, tile_x, tile_y, zoom, output_dir, args, build_intermediate, force_rebuild, bar): - if build_intermediate or zoom == args.target_zoom: - # print(f"({zoom}, {tile_x}, {tile_y})") - bar.set_description(f"({zoom}, {tile_x}, {tile_y})") - build_command(terrainbuilder_path, tile_x, tile_y, zoom, output_dir, force_rebuild, [str(arg) for arg in args.command_args]) - bar.update(1) - # print() - - if zoom < args.target_zoom: - children = get_children(tile_x, tile_y) - for child in children: - process_tile(terrainbuilder_path, child[0], child[1], zoom + 1, output_dir, args, build_intermediate, force_rebuild, bar) - -def main(): - parser = argparse.ArgumentParser(description="Calculate and build a command for EPSG 3857 tiles.") - parser.add_argument("--terrainbuilder", required=True, help="Path to the terrainbuilder executable") - parser.add_argument("--tile", nargs=3, type=int, required=True, help="EPSG 3857 tile Zoom, X and Y (e.g., 10 1234 5678)") - parser.add_argument("--target-zoom", type=int, required=True, help="Target zoom level") - parser.add_argument("--output-dir", required=True, help="Root output directory path") - parser.add_argument("--build-intermediate", action="store_true", help="Execute for intermediate nodes as well") - parser.add_argument("--force-rebuild", action="store_true", help="Force rebuild existing tiles") - parser.add_argument("command_args", nargs=argparse.REMAINDER, help="Command arguments for terrainbuilder") - - args = parser.parse_args() - - terrainbuilder_path = args.terrainbuilder - root_zoom, tile_x, tile_y = args.tile[0], args.tile[1], args.tile[2] - - num_tiles = 4**(args.target_zoom - root_zoom) - if args.build_intermediate: - num_tiles += (num_tiles - 1) / 3 - with tqdm(total=num_tiles) as bar: - process_tile(terrainbuilder_path, tile_x, tile_y, root_zoom, args.output_dir, args, args.build_intermediate, args.force_rebuild, bar) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/batch-converter.py b/batch-converter.py deleted file mode 100644 index 74bf310..0000000 --- a/batch-converter.py +++ /dev/null @@ -1,45 +0,0 @@ -import argparse -import subprocess -import os -import shutil -from pathlib import Path - -def convert_command(terrainconverter_path, input_file, output_file): - command = [ - terrainconverter_path, - "--input", input_file, - "--output", output_file, - "--verbosity", "info"] - try: - subprocess.run(command, check=False) - except subprocess.CalledProcessError as e: - print("ERROR") - pass - -def main(): - parser = argparse.ArgumentParser(description="Recursively convert all .tile files in a folder structure to .glb files") - parser.add_argument("--terrainconverter", required=True, help="Path to the terrainconverter executable") - parser.add_argument("--dir", required=True, help="The root folder containing the .tile files") - parser.add_argument("--suffix", help="A suffix that will get inserted like so: .glb to the output files") - - args = parser.parse_args() - - terrainconverter_path = args.terrainconverter - tiles_root_path = args.dir - suffix = args.suffix - - pathlist = Path(tiles_root_path).glob('**/*.tile') - for path in pathlist: - in_file = path - out_file = path.with_stem(f"{path.stem}{suffix if suffix else ''}").with_suffix(".glb") - - exists = os.path.exists(out_file) - - print(f"{in_file} >>> {out_file}{' SKIP' if exists else ''}") - - if not exists: - convert_command(terrainconverter_path, in_file, out_file) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/batch-merger.py b/batch-merger.py deleted file mode 100644 index 42231d8..0000000 --- a/batch-merger.py +++ /dev/null @@ -1,135 +0,0 @@ -import argparse -import subprocess -import os -import shutil - -def get_target_error(zoom_level): - meters_per_pixel = [ - 156_543, - 78_272, - 39_136, - 19_568, - 9_784, - 4_892, - 2_446, - 1_223, - 611.496, - 305.748, - 152.874, - 76.437, - 38.219, - 19.109, - 9.555, - 4.777, - 2.389, - 1.194, - 0.597, - 0.299, - 0.149 - ] - return meters_per_pixel[zoom_level] - -def get_children(tile_x, tile_y): - children = [] - for i in range(4): - x = 2 * tile_x + (i % 2) - y = 2 * tile_y + (i // 2) - children.append((x, y)) - return children - -def build_command(terrainmerger_path, tile_x, tile_y, zoom, children_to_merge, output_dir, force_rebuild, args): - output_path = os.path.join(output_dir, str(zoom), str(tile_y), f"{tile_x}.tile") - if (not force_rebuild) and os.path.exists(output_path): - print("\tSkipped") - return - - command = [ - terrainmerger_path, - "--input" - ] + children_to_merge + ["--output", output_path, "--verbosity", "trace", "--save-debug-meshes", "--simplify-error-absolute", str(get_target_error(zoom))] - print(command) - try: - subprocess.run(command, check=False) - except subprocess.CalledProcessError as e: - print("ERROR") - pass - -def process_tile(terrainmerger_path, tile_x, tile_y, zoom, output_dir, force_rebuild, args): - indent_level = zoom - args.root_tile[0] + 1 - parent_indent = " " * (indent_level - 1) - indent = " " * indent_level - - if zoom == args.max_zoom: - # If we are at the max zoom level, just attempt to copy the mesh tile to the output folder - input_path = os.path.join(args.input_dir, str(zoom), str(tile_y), f"{tile_x}.tile") - output_path = os.path.join(output_dir, str(zoom), str(tile_y), f"{tile_x}.tile") - print(f"{parent_indent}[{zoom},{tile_x},{tile_y}]", end="") - if not force_rebuild and os.path.exists(output_path): - print(" SKIPPING COPY") - return - - print(f" PROCESSING") - - if os.path.exists(input_path): - output_path_dir = os.path.dirname(output_path) - if not os.path.exists(output_path_dir): - print(f"{indent} CREATE {output_path_dir}") - os.makedirs(output_path_dir, exist_ok=True) - print(f"{indent} COPY {input_path} -> {output_path}") - shutil.copy2(input_path, output_path) - else: - print(f"{indent} NOT FOUND {input_path}") - - if zoom < args.max_zoom: - # print(output_dir) - print(f"{parent_indent}[{zoom},{tile_x},{tile_y}]", end="") - parent_output_path = os.path.join(output_dir, str(zoom), str(tile_y), f"{tile_x}.tile") - print(parent_output_path) - if not force_rebuild and os.path.exists(parent_output_path): - print(" SKIPPING") - return - - print(f" PROCESSING") - - children = get_children(tile_x, tile_y) - # Check if each child tile meshes exist, if not try to build them. - children_to_merge = [] - for child in children: - child_tile_x = child[0] - child_tile_y = child[1] - child_zoom = zoom + 1 - print(f"{indent}[{child_zoom},{child_tile_x},{child_tile_y}]", end="") - child_output_path = os.path.join(output_dir, str(child_zoom), str(child_tile_y), f"{child_tile_x}.tile") - if not os.path.exists(child_output_path): - print(f" {child_output_path} doesn't exist, PROCESSING") - process_tile(terrainmerger_path, child_tile_x, child_tile_y, child_zoom, output_dir, force_rebuild, args) - - # If the building of the child tile succeeded, add it to the list for merging - if os.path.exists(child_output_path): - children_to_merge.append(child_output_path) - - if len(children_to_merge) > 0: - print(f"{parent_indent}[{zoom},{tile_x},{tile_y}] MERGING {children_to_merge}") - build_command(terrainmerger_path, tile_x, tile_y, zoom, children_to_merge, output_dir, force_rebuild, args) - else: - print(f"{parent_indent}[{zoom},{tile_x},{tile_y}] NOTHING TO MERGE") - -def main(): - parser = argparse.ArgumentParser(description="Create tile hierarchy by merging bottom up from the lowest level.") - parser.add_argument("--terrainmerger", required=True, help="Path to the terrainmerger executable") - parser.add_argument("--root-tile", nargs=3, type=int, required=True, help="EPSG 3857 tile Zoom, X and Y (e.g., 10 1234 5678)") - parser.add_argument("--max-zoom", type=int, required=True, help="The maximum zoom level to search for tile meshes") - parser.add_argument("--input-dir", required=True, help="Root input directory path") - parser.add_argument("--output-dir", required=True, help="Root output directory path") - parser.add_argument("--force-rebuild", action="store_true", help="Force rebuild/remerge existing tiles") - parser.add_argument("command_args", nargs=argparse.REMAINDER, help="Command arguments for terrainmerger") - - args = parser.parse_args() - - terrainmerger_path = args.terrainmerger - root_zoom, tile_x, tile_y = args.root_tile[0], args.root_tile[1], args.root_tile[2] - - process_tile(terrainmerger_path, tile_x, tile_y, root_zoom, args.output_dir, args.force_rebuild, args) - -if __name__ == "__main__": - main() \ No newline at end of file From 273a2d2a91a11e70eb5c17854ee0dc2389b42abe Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 22:06:34 +0200 Subject: [PATCH 060/122] Update index in storage ops --- src/terrainlib/hash_utils.h | 2 +- src/terrainlib/octree/IndexMap.h | 136 +++++++++++++++++++++++++++-- src/terrainlib/octree/Storage.cpp | 34 +++++++- src/terrainlib/octree/Storage.h | 3 +- unittests/CMakeLists.txt | 1 + unittests/catch2_helpers.h | 34 ++++++-- unittests/terrainlib/index_map.cpp | 101 +++++++++++++++++++++ 7 files changed, 290 insertions(+), 21 deletions(-) create mode 100644 unittests/terrainlib/index_map.cpp diff --git a/src/terrainlib/hash_utils.h b/src/terrainlib/hash_utils.h index bef7743..400b44b 100644 --- a/src/terrainlib/hash_utils.h +++ b/src/terrainlib/hash_utils.h @@ -54,7 +54,7 @@ void hash_combine_core(std::size_t &seed, const T &v, const Rest &...rest) { template size_t hash_combine(const Rest &...rest) { - size_t h; + size_t h = 0x9e3779b9; (hash_combine_core(h, rest), ...); return h; } diff --git a/src/terrainlib/octree/IndexMap.h b/src/terrainlib/octree/IndexMap.h index f82cb7c..72743d5 100644 --- a/src/terrainlib/octree/IndexMap.h +++ b/src/terrainlib/octree/IndexMap.h @@ -6,6 +6,7 @@ #include "octree/Id.h" #include "octree/NodeStatus.h" +#include "log.h" namespace octree { @@ -16,15 +17,82 @@ class IndexMap { using const_iterator = Container::const_iterator; std::optional get(Id id) const { - if (auto it = this->_index.find(id); it != this->_index.end()) { - return it->second; + const NodeStatus* status = this->get_raw(id); + if (status != nullptr) { + return *status; + } else { + return std::nullopt; } - return std::nullopt; } - void set(Id id, NodeStatus status) { - // TODO: update other nodes? - this->_index[id] = status; + void add(Id id) { + NodeStatus* status = this->get_raw(id); + if (status != nullptr) { + switch (*status) { + case NodeStatus::Inner: + case NodeStatus::Leaf: + // Nothing to do + break; + case NodeStatus::Virtual: + this->set_raw(id, NodeStatus::Inner); + break; + } + return; + } + + const auto parent_opt = id.parent(); + if (!parent_opt.has_value()) { + assert(id.is_root()); + if (this->empty()) { + this->set_raw(id, NodeStatus::Leaf); + return; + } else { + UNREACHABLE(); + return; + } + } + + const auto parent = parent_opt.value(); + const NodeStatus* parent_status = this->get_raw(parent); + if (parent_status == nullptr) { + this->add(parent); + this->set_raw(parent, NodeStatus::Virtual); + this->set_raw(id, NodeStatus::Leaf); + return; + } + + switch (*parent_status) { + case NodeStatus::Leaf: + this->set_raw(parent, NodeStatus::Inner); + this->set_raw(id, NodeStatus::Leaf); + break; + case NodeStatus::Inner: + case NodeStatus::Virtual: + this->set_raw(id, NodeStatus::Leaf); + break; + } + } + + bool remove(Id id) { + NodeStatus* status = this->get_raw(id); + if (status == nullptr) { + return false; + } + + switch (*status) { + case NodeStatus::Inner: + *status = NodeStatus::Virtual; + return true; + case NodeStatus::Virtual: + // Nothing to do + return false; + case NodeStatus::Leaf: + this->remove_raw(id); + this->update_parent_after_remove(id); + return true; + } + + UNREACHABLE(); } bool is_present(Id id) const { @@ -61,8 +129,64 @@ class IndexMap { return this->_index.cend(); } + + NodeStatus* get_raw(Id id) { + if (auto it = this->_index.find(id); it != this->_index.end()) { + return &it->second; + } + return nullptr; + } + const NodeStatus* get_raw(Id id) const { + if (auto it = this->_index.find(id); it != this->_index.end()) { + return &it->second; + } + return nullptr; + } + void set_raw(Id id, NodeStatus status) { + this->_index[id] = status; + } + void remove_raw(Id id) { + this->_index.erase(id); + } + + private: Container _index; + + void update_parent_after_remove(Id id) { + const auto parent_opt = id.parent(); + if (!parent_opt.has_value()) { + return; + } + + const auto parent = parent_opt.value(); + NodeStatus* parent_status = this->get_raw(parent); + assert(parent_status != nullptr); + + // We know there are children since we just removed one + assert(parent.has_children()); + const auto siblings = parent.children().value(); + for (const auto& sibling : siblings) { + if (this->is_present(sibling) && sibling != id) { + return; + } + } + + switch (*parent_status) { + case NodeStatus::Inner: + *parent_status = NodeStatus::Leaf; + break; + case NodeStatus::Virtual: + this->remove_raw(parent); + this->update_parent_after_remove(parent); + break; + case NodeStatus::Leaf: + UNREACHABLE(); + break; + } + } + + public: using serialize = zpp::bits::members<1>; friend zpp::bits::access; diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp index 43223bf..c301bb6 100644 --- a/src/terrainlib/octree/Storage.cpp +++ b/src/terrainlib/octree/Storage.cpp @@ -21,6 +21,12 @@ Storage::Storage(IndexMap map, disk::Layout layout) : _index(std::move(map)), _layout(std::move(layout)) {} std::optional Storage::read_node(const Id &id) const { + if (this->_index.has_value()) { + const auto& index = this->_index.value(); + if (index.is_absent(id)) { + return std::nullopt; + } + } const auto node_path = this->get_node_path(id); const auto result = mesh::io::load_from_path(node_path); if (result.has_value()) { @@ -30,12 +36,32 @@ std::optional Storage::read_node(const Id &id) const { } } -bool Storage::write_node(const Id &id, const Node &node) const { +bool Storage::write_node(const Id &id, const Node &node) { const auto node_path = this->get_node_path(id); const auto result = mesh::io::save_to_path(node, node_path); + if (result.has_value() && this->_index.has_value()) { + auto& index = this->_index.value(); + index.add(id); + } return result.has_value(); } +bool Storage::remove_node(const Id &id) { + if (this->_index.has_value()) { + const auto& index = this->_index.value(); + if (index.is_absent(id)) { + return false; + } + } + const auto node_path = this->get_node_path(id); + const bool result = std::filesystem::remove(node_path); + if (this->_index.has_value()) { + auto& index = this->_index.value(); + index.remove(id); + } + return result; +} + bool Storage::has_node(const Id &id) const { if (this->_index.has_value()) { return this->_index->is_present(id); @@ -147,7 +173,7 @@ void update_index(IndexMap &index, const disk::Layout &layout) { } const Id id = *id_opt; - index.set(id, NodeStatus::Leaf); + index.set_raw(id, NodeStatus::Leaf); } std::unordered_set visited; @@ -160,9 +186,9 @@ void update_index(IndexMap &index, const disk::Layout &layout) { visited.insert(*parent); if (index.get(*parent)) { - index.set(*parent, NodeStatus::Inner); + index.set_raw(*parent, NodeStatus::Inner); } else { - index.set(*parent, NodeStatus::Virtual); + index.set_raw(*parent, NodeStatus::Virtual); } parent = parent->parent(); } diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index 312316a..c173d3e 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -21,7 +21,8 @@ class Storage { explicit Storage(IndexMap map, disk::Layout layout); std::optional read_node(const Id &id) const; - bool write_node(const Id &id, const Node &node) const; + bool write_node(const Id &id, const Node &node); + bool remove_node(const Id &id); bool has_node(const Id &id) const; std::filesystem::path get_node_path(const Id &id) const; diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 0198ce2..0d474f4 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -33,6 +33,7 @@ add_executable(unittests_terrainlib terrainlib/dataset.cpp terrainlib/grid.cpp terrainlib/progress_indicator_test.cpp + terrainlib/index_map.cpp ) target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) diff --git a/unittests/catch2_helpers.h b/unittests/catch2_helpers.h index a577a07..819b0a0 100644 --- a/unittests/catch2_helpers.h +++ b/unittests/catch2_helpers.h @@ -17,24 +17,40 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef CATCH2_HELPERS_H -#define CATCH2_HELPERS_H +#pragma once + +#include #include #include - #include -namespace Catch { +#include "octree/NodeStatus.h" -// template<> +namespace Catch { template struct StringMaker> { - static std::string convert(const glm::vec& value) - { + static std::string convert(const glm::vec& value) { return glm::to_string(value); } }; -} -#endif // CATCH2_HELPERS_H +template<> +struct StringMaker { + static std::string convert(const octree::NodeStatus& status) { + return status.to_string(); + } +}; + +template +struct StringMaker> { + static std::string convert(const std::optional& opt) { + if (opt.has_value()) { + return StringMaker>>::convert(opt.value()); + } else { + return "nullopt"; + } + } +}; + +} diff --git a/unittests/terrainlib/index_map.cpp b/unittests/terrainlib/index_map.cpp new file mode 100644 index 0000000..92308d8 --- /dev/null +++ b/unittests/terrainlib/index_map.cpp @@ -0,0 +1,101 @@ +#include "../catch2_helpers.h" + +#include "octree/IndexMap.h" + +using namespace octree; + + +TEST_CASE("IndexMap basic operations") { + IndexMap index; + + SECTION("Add root node") { + Id root = Id::root(); + index.add(root); + CHECK(index.is_present(root)); + CHECK(index.is(NodeStatus::Leaf, root)); + CHECK(index.get(root) == std::optional(NodeStatus::Leaf)); + } + + SECTION("Add child node creates virtual parent") { + Id root = Id::root(); + Id child = root.child(3).value(); + index.add(child); + CHECK(index.is_present(root)); + CHECK(index.is(NodeStatus::Virtual, root)); + CHECK(index.is_present(child)); + CHECK(index.is(NodeStatus::Leaf, child)); + } + + SECTION("Add child note promotes parent to inner") { + Id root = Id::root(); + Id child1 = root.child(0).value(); + index.add(child1); + index.add(root); + CHECK(index.is(NodeStatus::Leaf, child1)); + CHECK(index.is(NodeStatus::Inner, root)); + } + + SECTION("Removing a leaf node cleans up correctly") { + Id root = Id::root(); + Id child = root.child(2).value(); + index.add(child); + CHECK(index.is_present(child)); + index.remove(child); + CHECK(index.is_absent(child)); + CHECK(index.is_absent(root)); + } + + SECTION("Removing one of two children of an inner keeps it inner") { + Id root = Id::root(); + Id child1 = root.child(0).value(); + Id child2 = root.child(1).value(); + index.add(root); + index.add(child1); + index.add(child2); + index.remove(child1); + + CHECK(index.is_absent(child1)); + CHECK(index.is(NodeStatus::Leaf, child2)); + CHECK(index.is(NodeStatus::Inner, root)); + } + + SECTION("Removing last child of inner converts it to leaf") { + Id root = Id::root(); + Id child1 = root.child(0).value(); + index.add(child1); + index.add(root); + + index.remove(child1); + + CHECK(index.is_absent(child1)); + CHECK(index.is(NodeStatus::Leaf, root)); + } + + SECTION("Clear works") { + Id a = Id::root().child(1).value(); + Id b = Id::root().child(2).value(); + index.add(a); + index.add(b); + CHECK(index.size() == 3); // root + a + b + index.clear(); + CHECK(index.empty()); + } + + SECTION("Serialization round-trip") { + IndexMap original; + original.add(Id::root().child(3).value()); + + const std::errc success {}; + + std::vector buffer; + zpp::bits::out out(buffer); + CHECK(out(original).code == success); + + IndexMap loaded; + zpp::bits::in in(buffer); + CHECK(in(loaded).code == success); + + CHECK(original.size() == loaded.size()); + CHECK(loaded.is_present(Id::root().child(3).value())); + } +} From 8356c244877b02c9a82eba8731173029754a24ba Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 22:07:54 +0200 Subject: [PATCH 061/122] Rename terrainmerger --- src/CMakeLists.txt | 51 ++++--- src/terrainmerger/cli.cpp | 69 +-------- src/terrainmerger/cli.h | 54 ++----- src/terrainmerger/main.cpp | 122 +--------------- src/{terrainmerger => terrainsimplify}/cgal.h | 0 src/terrainsimplify/cli.cpp | 110 ++++++++++++++ src/terrainsimplify/cli.h | 54 +++++++ .../convert.cpp | 0 .../convert.h | 0 src/terrainsimplify/main.cpp | 135 ++++++++++++++++++ .../merge.cpp | 0 .../merge.h | 0 src/{terrainmerger => terrainsimplify}/pch.h | 0 .../simplify.cpp | 0 .../simplify.h | 0 .../uv_map.cpp | 0 .../uv_map.h | 0 .../validate.h | 0 unittests/CMakeLists.txt | 10 +- .../convert.cpp | 0 .../merge.cpp | 0 21 files changed, 354 insertions(+), 251 deletions(-) rename src/{terrainmerger => terrainsimplify}/cgal.h (100%) create mode 100644 src/terrainsimplify/cli.cpp create mode 100644 src/terrainsimplify/cli.h rename src/{terrainmerger => terrainsimplify}/convert.cpp (100%) rename src/{terrainmerger => terrainsimplify}/convert.h (100%) create mode 100644 src/terrainsimplify/main.cpp rename src/{terrainmerger => terrainsimplify}/merge.cpp (100%) rename src/{terrainmerger => terrainsimplify}/merge.h (100%) rename src/{terrainmerger => terrainsimplify}/pch.h (100%) rename src/{terrainmerger => terrainsimplify}/simplify.cpp (100%) rename src/{terrainmerger => terrainsimplify}/simplify.h (100%) rename src/{terrainmerger => terrainsimplify}/uv_map.cpp (100%) rename src/{terrainmerger => terrainsimplify}/uv_map.h (100%) rename src/{terrainmerger => terrainsimplify}/validate.h (100%) rename unittests/{terrainmerger => terrainsimplify}/convert.cpp (100%) rename unittests/{terrainmerger => terrainsimplify}/merge.cpp (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a3bd5a..f908405 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,6 +169,18 @@ add_executable(tilebuilder target_link_libraries(tilebuilder PUBLIC tilebuilderlib) +add_library(terrainmergerlib + terrainmerger/cli.h +) +target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) +target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) +add_executable(terrainmerger + terrainmerger/main.cpp + terrainmerger/cli.h terrainmerger/cli.cpp +) +target_link_libraries(terrainmerger PUBLIC terrainmergerlib) + + add_library(terrainbuilderlib terrainbuilder/tile_provider.h terrainbuilder/mesh_builder.h @@ -187,27 +199,28 @@ add_executable(terrainbuilder ) target_link_libraries(terrainbuilder PUBLIC terrainbuilderlib) -add_library(terrainmergerlib - terrainmerger/cli.h - terrainmerger/cli.cpp - terrainmerger/merge.h - terrainmerger/merge.cpp - terrainmerger/simplify.h - terrainmerger/simplify.cpp - terrainmerger/uv_map.h - terrainmerger/uv_map.cpp - terrainmerger/cgal.h - terrainmerger/convert.h - terrainmerger/convert.cpp - terrainmerger/validate.h + +add_library(terrainsimplifylib + terrainsimplify/cli.h + terrainsimplify/cli.cpp + terrainsimplify/merge.h + terrainsimplify/merge.cpp + terrainsimplify/simplify.h + terrainsimplify/simplify.cpp + terrainsimplify/uv_map.h + terrainsimplify/uv_map.cpp + terrainsimplify/cgal.h + terrainsimplify/convert.h + terrainsimplify/convert.cpp + terrainsimplify/validate.h ) -target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) -target_precompile_headers(terrainmergerlib PRIVATE terrainmerger/pch.h) -target_link_libraries(terrainmergerlib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) -add_executable(terrainmerger - terrainmerger/main.cpp +target_include_directories(terrainsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainsimplify) +target_precompile_headers(terrainsimplifylib PRIVATE terrainsimplify/pch.h) +target_link_libraries(terrainsimplifylib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) +add_executable(terrainsimplify + terrainsimplify/main.cpp ) -target_link_libraries(terrainmerger PUBLIC terrainmergerlib) +target_link_libraries(terrainsimplify PUBLIC terrainsimplifylib) add_executable(tile-downloader tile_downloader/main.cpp diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index 8543a5a..cc5fc0d 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -8,56 +8,20 @@ using namespace cli; Args cli::parse(int argc, const char * const * argv) { assert(argc >= 0); - CLI::App app{"Terrain Merger"}; + CLI::App app{"terrainmerger"}; app.allow_windows_style_options(); // argv = app.ensure_utf8(argv); std::vector input_paths; - app.add_option("--input", input_paths, "Paths to tiles that should be merged") + app.add_option("--input", input_paths, "Paths to datasets that should be merged") ->required() ->expected(-1) ->check(CLI::ExistingFile); std::filesystem::path output_path; - app.add_option("--output", output_path, "Path to output the merged tile to") + app.add_option("--output", output_path, "Path to output write the merged dataset to") ->required(); - bool no_mesh_simplification = false; - app.add_flag("--no-simplify", no_mesh_simplification, "Disable mesh simplification"); - - std::optional simplification_vertex_ratio; - app.add_option("--simplify-vertex-ratio", simplification_vertex_ratio, "Target mesh vertex simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_edge_ratio; - app.add_option("--simplify-edge-ratio", simplification_edge_ratio, "Target mesh edge simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_face_ratio; - app.add_option("--simplify-face-ratio", simplification_face_ratio, "Target mesh face simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_target_error_relative; - app.add_option("--simplify-error-relative", simplification_target_error_relative, "Relative mesh simplification error bound") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_target_error_absolute; - app.add_option("--simplify-error-absolute", simplification_target_error_absolute, "Absolute mesh simplification error bound") - ->check(CLI::PositiveNumber) - ->excludes("--no-simplify"); - - std::vector target_texture_resolution; - app.add_option("--texture-resolution", target_texture_resolution, "Resolution of merged mesh texture") - ->check(CLI::PositiveNumber) - ->expected(2); - - bool save_intermediate_meshes = false; - app.add_flag("--save-debug-meshes", save_intermediate_meshes, "Output intermediate meshes"); - spdlog::level::level_enum log_level = spdlog::level::level_enum::info; const std::map log_level_names{ {"off", spdlog::level::level_enum::off}, @@ -75,36 +39,11 @@ Args cli::parse(int argc, const char * const * argv) { } catch (const CLI::ParseError &e) { exit(app.exit(e)); } + Args args; args.input_paths = input_paths; args.output_path = output_path; args.log_level = log_level; - args.save_intermediate_meshes = save_intermediate_meshes; - if (target_texture_resolution.size() == 2) { - args.target_texture_resolution = {target_texture_resolution[0], target_texture_resolution[1]}; - } - if (!no_mesh_simplification) { - SimplificationArgs simplification_args = {}; - if (simplification_vertex_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::VertexRatio { .ratio=simplification_vertex_ratio.value() }); - } - if (simplification_edge_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=simplification_edge_ratio.value() }); - } - if (simplification_face_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::FaceRatio { .ratio=simplification_face_ratio.value() }); - } - if (simplification_target_error_relative.has_value()) { - simplification_args.stop_condition.push_back(simplify::RelativeError { .error_bound = simplification_target_error_relative.value() }); - } - if (simplification_target_error_absolute.has_value()) { - simplification_args.stop_condition.push_back(simplify::AbsoluteError { .error_bound=simplification_target_error_absolute.value() }); - } - if (simplification_args.stop_condition.empty()) { - simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=1.0/args.input_paths.size() }); - } - args.simplification = simplification_args; - } return args; } diff --git a/src/terrainmerger/cli.h b/src/terrainmerger/cli.h index 147290a..f9f396e 100644 --- a/src/terrainmerger/cli.h +++ b/src/terrainmerger/cli.h @@ -1,54 +1,18 @@ -#ifndef CLI_H -#define CLI_H +#pragma once -#include "pch.h" +#include +#include #include -#include "simplify.h" - namespace cli { - struct SimplificationArgs { - std::vector stop_condition; - }; - - struct Args { - std::filesystem::path output_path; - std::vector input_paths; - std::optional simplification; - spdlog::level::level_enum log_level; - bool save_intermediate_meshes; - std::optional target_texture_resolution; - }; - Args parse(int argc, const char *const *argv); +struct Args { + spdlog::level::level_enum log_level; + std::vector input_paths; + std::filesystem::path output_path; +}; - namespace { - template - Args _parse(const std::span args) { - std::array raw_args; - std::transform(args.begin(), args.end(), raw_args.begin(), - [](const T &str) { return str.data(); }); - return cli::parse(raw_args.size(), raw_args.data()); - } - template - Args _parse(const std::span args) { - std::vector raw_args; - raw_args.resize(args.size()); - std::transform(args.begin(), args.end(), raw_args.begin(), - [](const T &str) { return str.data(); }); - return cli::parse(raw_args.size(), raw_args.data()); - } - } +Args parse(int argc, const char *const *argv); - template - Args cli::parse(const std::span args) { - return _parse(args); - } - template - Args cli::parse(const std::span args) { - return _parse(args); - } } - -#endif diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index 9109e60..3478f8c 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -1,124 +1,11 @@ -#include "cli.h" -#include "convert.h" +#include + #include "log.h" +#include "cli.h" #include "merge.h" -#include "mesh/io.h" -#include "simplify.h" -#include "uv_map.h" -#include "validate.h" - -std::vector load_meshes_from_path(std::span paths, const bool print_errors = true) { - std::vector meshes; - meshes.reserve(paths.size()); - for (const std::filesystem::path &path : paths) { - auto result = io::load_mesh_from_path(path); - if (!result.has_value()) { - const io::LoadMeshError error = result.error(); - if (print_errors) { - LOG_ERROR("Failed to load mesh from {}: {}", path, error.description()); - } - exit(EXIT_FAILURE); - } - - const SimpleMesh mesh = std::move(result.value()); - validate_mesh(mesh); - validate_mesh(convert::mesh2cgal(mesh)); - meshes.push_back(mesh); - } - - return meshes; -} - -uv_map::UvMap parameterize_mesh(SimpleMesh &mesh) { - const tl::expected result = - uv_map::parameterize_mesh(mesh, uv_map::Algorithm::DiscreteConformalMap, uv_map::Border::Circle); - if (result) { - return result.value(); - } else { - const uv_map::UvParameterizationError error = result.error(); - LOG_ERROR("Failed to parameterize merged mesh due to '{}'", error.description()); - exit(EXIT_FAILURE); - } -} - -SimpleMesh simplify_mesh(const SimpleMesh &mesh, const cli::SimplificationArgs &args) { - const simplify::Result result = simplify::simplify_mesh(mesh, args.stop_condition); - const SimpleMesh &simplified_mesh = result.mesh; - - const size_t initial_vertex_count = mesh.positions.size(); - const size_t initial_face_count = mesh.triangles.size(); - const size_t simplified_vertex_count = simplified_mesh.positions.size(); - const size_t simplified_face_count = simplified_mesh.triangles.size(); - - LOG_DEBUG("Simplified mesh to {}/{} vertices and {}/{} faces", - simplified_vertex_count, initial_vertex_count, - simplified_face_count, initial_face_count); - - return result.mesh; -} void run(const cli::Args &args) { - LOG_INFO("Loading meshes..."); - std::vector meshes = load_meshes_from_path(args.input_paths); - - const bool meshes_have_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); - const bool meshes_have_textures = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_texture(); }); - - const std::optional texture_size = (!meshes.empty() && meshes[0].texture.has_value()) - ? std::optional{convert::cv2glm(meshes[0].texture.value().size())} - : std::nullopt; - const glm::uvec2 target_texture_size = args.target_texture_resolution.has_value() ? - args.target_texture_resolution.value() : (texture_size.has_value() ? texture_size.value() : glm::uvec2(256)); - - LOG_INFO("Merging meshes..."); - merge::VertexMapping vertex_mapping; - SimpleMesh merged_mesh = merge::merge_meshes(meshes, vertex_mapping); - if (args.save_intermediate_meshes) { - const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".merged.glb"); - LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "merged"}); - } - - if (meshes_have_uvs) { - LOG_INFO("Calculating uv mapping..."); - const uv_map::UvMap uv_map = parameterize_mesh(merged_mesh); - merged_mesh.uvs = uv_map::decode_uv_map(uv_map, merged_mesh.vertex_count()); - - if (meshes_have_textures) { - LOG_INFO("Merging textures..."); - merged_mesh.texture = uv_map::merge_textures(meshes, merged_mesh, vertex_mapping, uv_map, target_texture_size * glm::uvec2(2)); - - if (args.save_intermediate_meshes) { - const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".textured.glb"); - LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "textured"}); - } - } - } - - SimpleMesh simplified_mesh; - if (args.simplification) { - LOG_INFO("Simplifying merged mesh..."); - simplified_mesh = simplify_mesh(merged_mesh, args.simplification.value()); - - if (merged_mesh.texture.has_value()) { - LOG_INFO("Simplifying merged texture..."); - simplified_mesh.texture = simplify::simplify_texture(merged_mesh.texture.value(), target_texture_size); - } - - if (args.save_intermediate_meshes) { - const std::filesystem::path simplified_mesh_path = std::filesystem::path(args.output_path).replace_extension(".simplified.glb"); - LOG_DEBUG("Saving simplified mesh to {}", simplified_mesh_path.string()); - io::save_mesh_to_path(simplified_mesh_path, simplified_mesh, io::SaveOptions{.name = "simplified"}); - } - } else { - simplified_mesh = merged_mesh; - } - - LOG_INFO("Saving final mesh..."); - io::save_mesh_to_path(args.output_path, simplified_mesh); - - LOG_INFO("Done"); + std::vector } int main(int argc, char **argv) { @@ -133,3 +20,4 @@ int main(int argc, char **argv) { run(args); } + diff --git a/src/terrainmerger/cgal.h b/src/terrainsimplify/cgal.h similarity index 100% rename from src/terrainmerger/cgal.h rename to src/terrainsimplify/cgal.h diff --git a/src/terrainsimplify/cli.cpp b/src/terrainsimplify/cli.cpp new file mode 100644 index 0000000..e01e049 --- /dev/null +++ b/src/terrainsimplify/cli.cpp @@ -0,0 +1,110 @@ +#include "cli.h" + +#include +#include + +using namespace cli; + +Args cli::parse(int argc, const char * const * argv) { + assert(argc >= 0); + + CLI::App app{"terrainsimplify"}; + app.allow_windows_style_options(); + // argv = app.ensure_utf8(argv); + + std::vector input_paths; + app.add_option("--input", input_paths, "Paths to tiles that should be merged") + ->required() + ->expected(-1) + ->check(CLI::ExistingFile); + + std::filesystem::path output_path; + app.add_option("--output", output_path, "Path to output the merged tile to") + ->required(); + + bool no_mesh_simplification = false; + app.add_flag("--no-simplify", no_mesh_simplification, "Disable mesh simplification"); + + std::optional simplification_vertex_ratio; + app.add_option("--simplify-vertex-ratio", simplification_vertex_ratio, "Target mesh vertex simplification factor") + ->check(CLI::Range(0.0, 1.0)) + ->excludes("--no-simplify"); + + std::optional simplification_edge_ratio; + app.add_option("--simplify-edge-ratio", simplification_edge_ratio, "Target mesh edge simplification factor") + ->check(CLI::Range(0.0, 1.0)) + ->excludes("--no-simplify"); + + std::optional simplification_face_ratio; + app.add_option("--simplify-face-ratio", simplification_face_ratio, "Target mesh face simplification factor") + ->check(CLI::Range(0.0, 1.0)) + ->excludes("--no-simplify"); + + std::optional simplification_target_error_relative; + app.add_option("--simplify-error-relative", simplification_target_error_relative, "Relative mesh simplification error bound") + ->check(CLI::Range(0.0, 1.0)) + ->excludes("--no-simplify"); + + std::optional simplification_target_error_absolute; + app.add_option("--simplify-error-absolute", simplification_target_error_absolute, "Absolute mesh simplification error bound") + ->check(CLI::PositiveNumber) + ->excludes("--no-simplify"); + + std::vector target_texture_resolution; + app.add_option("--texture-resolution", target_texture_resolution, "Resolution of merged mesh texture") + ->check(CLI::PositiveNumber) + ->expected(2); + + bool save_intermediate_meshes = false; + app.add_flag("--save-debug-meshes", save_intermediate_meshes, "Output intermediate meshes"); + + spdlog::level::level_enum log_level = spdlog::level::level_enum::info; + const std::map log_level_names{ + {"off", spdlog::level::level_enum::off}, + {"critical", spdlog::level::level_enum::critical}, + {"error", spdlog::level::level_enum::err}, + {"warn", spdlog::level::level_enum::warn}, + {"info", spdlog::level::level_enum::info}, + {"debug", spdlog::level::level_enum::debug}, + {"trace", spdlog::level::level_enum::trace}}; + app.add_option("--verbosity", log_level, "Verbosity level of logging") + ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)); + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError &e) { + exit(app.exit(e)); + } + Args args; + args.input_paths = input_paths; + args.output_path = output_path; + args.log_level = log_level; + args.save_intermediate_meshes = save_intermediate_meshes; + if (target_texture_resolution.size() == 2) { + args.target_texture_resolution = {target_texture_resolution[0], target_texture_resolution[1]}; + } + if (!no_mesh_simplification) { + SimplificationArgs simplification_args = {}; + if (simplification_vertex_ratio.has_value()) { + simplification_args.stop_condition.push_back(simplify::VertexRatio { .ratio=simplification_vertex_ratio.value() }); + } + if (simplification_edge_ratio.has_value()) { + simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=simplification_edge_ratio.value() }); + } + if (simplification_face_ratio.has_value()) { + simplification_args.stop_condition.push_back(simplify::FaceRatio { .ratio=simplification_face_ratio.value() }); + } + if (simplification_target_error_relative.has_value()) { + simplification_args.stop_condition.push_back(simplify::RelativeError { .error_bound = simplification_target_error_relative.value() }); + } + if (simplification_target_error_absolute.has_value()) { + simplification_args.stop_condition.push_back(simplify::AbsoluteError { .error_bound=simplification_target_error_absolute.value() }); + } + if (simplification_args.stop_condition.empty()) { + simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=1.0/args.input_paths.size() }); + } + args.simplification = simplification_args; + } + + return args; +} diff --git a/src/terrainsimplify/cli.h b/src/terrainsimplify/cli.h new file mode 100644 index 0000000..147290a --- /dev/null +++ b/src/terrainsimplify/cli.h @@ -0,0 +1,54 @@ +#ifndef CLI_H +#define CLI_H + +#include "pch.h" + +#include + +#include "simplify.h" + +namespace cli { + struct SimplificationArgs { + std::vector stop_condition; + }; + + struct Args { + std::filesystem::path output_path; + std::vector input_paths; + std::optional simplification; + spdlog::level::level_enum log_level; + bool save_intermediate_meshes; + std::optional target_texture_resolution; + }; + + Args parse(int argc, const char *const *argv); + + namespace { + template + Args _parse(const std::span args) { + std::array raw_args; + std::transform(args.begin(), args.end(), raw_args.begin(), + [](const T &str) { return str.data(); }); + return cli::parse(raw_args.size(), raw_args.data()); + } + template + Args _parse(const std::span args) { + std::vector raw_args; + raw_args.resize(args.size()); + std::transform(args.begin(), args.end(), raw_args.begin(), + [](const T &str) { return str.data(); }); + return cli::parse(raw_args.size(), raw_args.data()); + } + } + + template + Args cli::parse(const std::span args) { + return _parse(args); + } + template + Args cli::parse(const std::span args) { + return _parse(args); + } +} + +#endif diff --git a/src/terrainmerger/convert.cpp b/src/terrainsimplify/convert.cpp similarity index 100% rename from src/terrainmerger/convert.cpp rename to src/terrainsimplify/convert.cpp diff --git a/src/terrainmerger/convert.h b/src/terrainsimplify/convert.h similarity index 100% rename from src/terrainmerger/convert.h rename to src/terrainsimplify/convert.h diff --git a/src/terrainsimplify/main.cpp b/src/terrainsimplify/main.cpp new file mode 100644 index 0000000..9109e60 --- /dev/null +++ b/src/terrainsimplify/main.cpp @@ -0,0 +1,135 @@ +#include "cli.h" +#include "convert.h" +#include "log.h" +#include "merge.h" +#include "mesh/io.h" +#include "simplify.h" +#include "uv_map.h" +#include "validate.h" + +std::vector load_meshes_from_path(std::span paths, const bool print_errors = true) { + std::vector meshes; + meshes.reserve(paths.size()); + for (const std::filesystem::path &path : paths) { + auto result = io::load_mesh_from_path(path); + if (!result.has_value()) { + const io::LoadMeshError error = result.error(); + if (print_errors) { + LOG_ERROR("Failed to load mesh from {}: {}", path, error.description()); + } + exit(EXIT_FAILURE); + } + + const SimpleMesh mesh = std::move(result.value()); + validate_mesh(mesh); + validate_mesh(convert::mesh2cgal(mesh)); + meshes.push_back(mesh); + } + + return meshes; +} + +uv_map::UvMap parameterize_mesh(SimpleMesh &mesh) { + const tl::expected result = + uv_map::parameterize_mesh(mesh, uv_map::Algorithm::DiscreteConformalMap, uv_map::Border::Circle); + if (result) { + return result.value(); + } else { + const uv_map::UvParameterizationError error = result.error(); + LOG_ERROR("Failed to parameterize merged mesh due to '{}'", error.description()); + exit(EXIT_FAILURE); + } +} + +SimpleMesh simplify_mesh(const SimpleMesh &mesh, const cli::SimplificationArgs &args) { + const simplify::Result result = simplify::simplify_mesh(mesh, args.stop_condition); + const SimpleMesh &simplified_mesh = result.mesh; + + const size_t initial_vertex_count = mesh.positions.size(); + const size_t initial_face_count = mesh.triangles.size(); + const size_t simplified_vertex_count = simplified_mesh.positions.size(); + const size_t simplified_face_count = simplified_mesh.triangles.size(); + + LOG_DEBUG("Simplified mesh to {}/{} vertices and {}/{} faces", + simplified_vertex_count, initial_vertex_count, + simplified_face_count, initial_face_count); + + return result.mesh; +} + +void run(const cli::Args &args) { + LOG_INFO("Loading meshes..."); + std::vector meshes = load_meshes_from_path(args.input_paths); + + const bool meshes_have_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); + const bool meshes_have_textures = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_texture(); }); + + const std::optional texture_size = (!meshes.empty() && meshes[0].texture.has_value()) + ? std::optional{convert::cv2glm(meshes[0].texture.value().size())} + : std::nullopt; + const glm::uvec2 target_texture_size = args.target_texture_resolution.has_value() ? + args.target_texture_resolution.value() : (texture_size.has_value() ? texture_size.value() : glm::uvec2(256)); + + LOG_INFO("Merging meshes..."); + merge::VertexMapping vertex_mapping; + SimpleMesh merged_mesh = merge::merge_meshes(meshes, vertex_mapping); + if (args.save_intermediate_meshes) { + const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".merged.glb"); + LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); + io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "merged"}); + } + + if (meshes_have_uvs) { + LOG_INFO("Calculating uv mapping..."); + const uv_map::UvMap uv_map = parameterize_mesh(merged_mesh); + merged_mesh.uvs = uv_map::decode_uv_map(uv_map, merged_mesh.vertex_count()); + + if (meshes_have_textures) { + LOG_INFO("Merging textures..."); + merged_mesh.texture = uv_map::merge_textures(meshes, merged_mesh, vertex_mapping, uv_map, target_texture_size * glm::uvec2(2)); + + if (args.save_intermediate_meshes) { + const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".textured.glb"); + LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); + io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "textured"}); + } + } + } + + SimpleMesh simplified_mesh; + if (args.simplification) { + LOG_INFO("Simplifying merged mesh..."); + simplified_mesh = simplify_mesh(merged_mesh, args.simplification.value()); + + if (merged_mesh.texture.has_value()) { + LOG_INFO("Simplifying merged texture..."); + simplified_mesh.texture = simplify::simplify_texture(merged_mesh.texture.value(), target_texture_size); + } + + if (args.save_intermediate_meshes) { + const std::filesystem::path simplified_mesh_path = std::filesystem::path(args.output_path).replace_extension(".simplified.glb"); + LOG_DEBUG("Saving simplified mesh to {}", simplified_mesh_path.string()); + io::save_mesh_to_path(simplified_mesh_path, simplified_mesh, io::SaveOptions{.name = "simplified"}); + } + } else { + simplified_mesh = merged_mesh; + } + + LOG_INFO("Saving final mesh..."); + io::save_mesh_to_path(args.output_path, simplified_mesh); + + LOG_INFO("Done"); +} + +int main(int argc, char **argv) { + const cli::Args args = cli::parse(argc, argv); + Log::init(args.log_level); + + const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), + [](const std::string &acc, const char *arg) { + return acc + (acc.empty() ? "" : " ") + arg; + }); + LOG_DEBUG("Running with: {}", arg_str); + + run(args); +} diff --git a/src/terrainmerger/merge.cpp b/src/terrainsimplify/merge.cpp similarity index 100% rename from src/terrainmerger/merge.cpp rename to src/terrainsimplify/merge.cpp diff --git a/src/terrainmerger/merge.h b/src/terrainsimplify/merge.h similarity index 100% rename from src/terrainmerger/merge.h rename to src/terrainsimplify/merge.h diff --git a/src/terrainmerger/pch.h b/src/terrainsimplify/pch.h similarity index 100% rename from src/terrainmerger/pch.h rename to src/terrainsimplify/pch.h diff --git a/src/terrainmerger/simplify.cpp b/src/terrainsimplify/simplify.cpp similarity index 100% rename from src/terrainmerger/simplify.cpp rename to src/terrainsimplify/simplify.cpp diff --git a/src/terrainmerger/simplify.h b/src/terrainsimplify/simplify.h similarity index 100% rename from src/terrainmerger/simplify.h rename to src/terrainsimplify/simplify.h diff --git a/src/terrainmerger/uv_map.cpp b/src/terrainsimplify/uv_map.cpp similarity index 100% rename from src/terrainmerger/uv_map.cpp rename to src/terrainsimplify/uv_map.cpp diff --git a/src/terrainmerger/uv_map.h b/src/terrainsimplify/uv_map.h similarity index 100% rename from src/terrainmerger/uv_map.h rename to src/terrainsimplify/uv_map.h diff --git a/src/terrainmerger/validate.h b/src/terrainsimplify/validate.h similarity index 100% rename from src/terrainmerger/validate.h rename to src/terrainsimplify/validate.h diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 0d474f4..5f11fe9 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -54,13 +54,13 @@ add_executable(unittests_tilebuilder target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2WithMain) -add_executable(unittests_terrainmerger +add_executable(unittests_terrainsimplify catch2_helpers.h - terrainmerger/convert.cpp - terrainmerger/merge.cpp + terrainsimplify/convert.cpp + terrainsimplify/merge.cpp ) -target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib Catch2::Catch2WithMain) +target_link_libraries(unittests_terrainsimplify PUBLIC terrainsimplifylib Catch2::Catch2WithMain) add_executable(unittests_terrainbuilder @@ -72,5 +72,5 @@ add_executable(unittests_terrainbuilder terrainbuilder/texture.cpp ) -target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainmergerlib terrainlib Catch2WithMain) +target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainsimplifylib terrainlib Catch2WithMain) target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") diff --git a/unittests/terrainmerger/convert.cpp b/unittests/terrainsimplify/convert.cpp similarity index 100% rename from unittests/terrainmerger/convert.cpp rename to unittests/terrainsimplify/convert.cpp diff --git a/unittests/terrainmerger/merge.cpp b/unittests/terrainsimplify/merge.cpp similarity index 100% rename from unittests/terrainmerger/merge.cpp rename to unittests/terrainsimplify/merge.cpp From 8a0cd8430f9425acb02c6e394405929317cdc646 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 22:33:32 +0200 Subject: [PATCH 062/122] Move terrainlib tests to correct location --- unittests/CMakeLists.txt | 6 +++--- unittests/{terrainbuilder => terrainlib}/mesh_io.cpp | 0 unittests/{terrainbuilder => terrainlib}/octree_id.cpp | 0 unittests/{terrainbuilder => terrainlib}/octree_space.cpp | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename unittests/{terrainbuilder => terrainlib}/mesh_io.cpp (100%) rename unittests/{terrainbuilder => terrainlib}/octree_id.cpp (100%) rename unittests/{terrainbuilder => terrainlib}/octree_space.cpp (100%) diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 5f11fe9..dac6072 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -34,6 +34,9 @@ add_executable(unittests_terrainlib terrainlib/grid.cpp terrainlib/progress_indicator_test.cpp terrainlib/index_map.cpp + terrainlib/octree_id.cpp + terrainlib/octree_space.cpp + terrainlib/mesh_io.cpp ) target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) @@ -65,10 +68,7 @@ target_link_libraries(unittests_terrainsimplify PUBLIC terrainsimplifylib Catch2 add_executable(unittests_terrainbuilder catch2_helpers.h - terrainbuilder/octree_id.cpp - terrainbuilder/octree_space.cpp terrainbuilder/mesh.cpp - terrainbuilder/mesh_io.cpp terrainbuilder/texture.cpp ) diff --git a/unittests/terrainbuilder/mesh_io.cpp b/unittests/terrainlib/mesh_io.cpp similarity index 100% rename from unittests/terrainbuilder/mesh_io.cpp rename to unittests/terrainlib/mesh_io.cpp diff --git a/unittests/terrainbuilder/octree_id.cpp b/unittests/terrainlib/octree_id.cpp similarity index 100% rename from unittests/terrainbuilder/octree_id.cpp rename to unittests/terrainlib/octree_id.cpp diff --git a/unittests/terrainbuilder/octree_space.cpp b/unittests/terrainlib/octree_space.cpp similarity index 100% rename from unittests/terrainbuilder/octree_space.cpp rename to unittests/terrainlib/octree_space.cpp From 9a1fddbd51eb2a7415d86b3d633600d4ca1d181b Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 23:21:34 +0200 Subject: [PATCH 063/122] Split IndexMap and Space into .h and .cpp --- src/CMakeLists.txt | 4 +- src/terrainlib/octree/IndexMap.cpp | 172 ++++++++++++++++++++++++++ src/terrainlib/octree/IndexMap.h | 191 ++++------------------------- src/terrainlib/octree/Space.cpp | 120 ++++++++++++++++++ src/terrainlib/octree/Space.h | 117 ++---------------- 5 files changed, 328 insertions(+), 276 deletions(-) create mode 100644 src/terrainlib/octree/IndexMap.cpp create mode 100644 src/terrainlib/octree/Space.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f908405..68e99db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -124,9 +124,9 @@ add_library(terrainlib terrainlib/octree/disk/Layout.h terrainlib/octree/Id.h terrainlib/octree/Storage.h terrainlib/octree/Storage.cpp - terrainlib/octree/IndexMap.h + terrainlib/octree/IndexMap.h terrainlib/octree/IndexMap.cpp terrainlib/octree/NodeStatus.h - terrainlib/octree/Space.h + terrainlib/octree/Space.h terrainlib/octree/Space.cpp terrainlib/octree/traverse.h terrainlib/octree/utils.h diff --git a/src/terrainlib/octree/IndexMap.cpp b/src/terrainlib/octree/IndexMap.cpp new file mode 100644 index 0000000..ed1ad9f --- /dev/null +++ b/src/terrainlib/octree/IndexMap.cpp @@ -0,0 +1,172 @@ +#include "octree/IndexMap.h" +#include "log.h" + +namespace octree { + +std::optional IndexMap::get(Id id) const { + const NodeStatus* status = this->get_raw(id); + if (status != nullptr) { + return *status; + } else { + return std::nullopt; + } +} + +void IndexMap::add(Id id) { + NodeStatus* status = this->get_raw(id); + if (status != nullptr) { + switch (*status) { + case NodeStatus::Inner: + case NodeStatus::Leaf: + // Nothing to do + break; + case NodeStatus::Virtual: + this->set_raw(id, NodeStatus::Inner); + break; + } + return; + } + + const auto parent_opt = id.parent(); + if (!parent_opt.has_value()) { + assert(id.is_root()); + if (this->empty()) { + this->set_raw(id, NodeStatus::Leaf); + return; + } else { + UNREACHABLE(); + return; + } + } + + const auto parent = parent_opt.value(); + const NodeStatus* parent_status = this->get_raw(parent); + if (parent_status == nullptr) { + this->add(parent); + this->set_raw(parent, NodeStatus::Virtual); + this->set_raw(id, NodeStatus::Leaf); + return; + } + + switch (*parent_status) { + case NodeStatus::Leaf: + this->set_raw(parent, NodeStatus::Inner); + this->set_raw(id, NodeStatus::Leaf); + break; + case NodeStatus::Inner: + case NodeStatus::Virtual: + this->set_raw(id, NodeStatus::Leaf); + break; + } +} + +bool IndexMap::remove(Id id) { + NodeStatus* status = this->get_raw(id); + if (status == nullptr) { + return false; + } + + switch (*status) { + case NodeStatus::Inner: + *status = NodeStatus::Virtual; + return true; + case NodeStatus::Virtual: + // Nothing to do + return false; + case NodeStatus::Leaf: + this->remove_raw(id); + this->update_parent_after_remove(id); + return true; + } + + UNREACHABLE(); +} + +bool IndexMap::is_present(Id id) const { + auto it = this->_index.find(id); + return it != this->_index.end(); +} +bool IndexMap::is_absent(Id id) const { + return !this->is_present(id); +} +bool IndexMap::is(NodeStatus status, Id id) const { + return this->get(id) == status; +} + +void IndexMap::clear() { + this->_index.clear(); +} +bool IndexMap::empty() const { + return this->_index.empty(); +} +size_t IndexMap::size() const { + return this->_index.size(); +} + +IndexMap::const_iterator IndexMap::begin() const { + return this->_index.begin(); +} +IndexMap::const_iterator IndexMap::end() const { + return this->_index.end(); +} +IndexMap::const_iterator IndexMap::cbegin() const { + return this->_index.cbegin(); +} +IndexMap::const_iterator IndexMap::cend() const { + return this->_index.cend(); +} + + +NodeStatus* IndexMap::get_raw(Id id) { + if (auto it = this->_index.find(id); it != this->_index.end()) { + return &it->second; + } + return nullptr; +} +const NodeStatus* IndexMap::get_raw(Id id) const { + if (auto it = this->_index.find(id); it != this->_index.end()) { + return &it->second; + } + return nullptr; +} +void IndexMap::set_raw(Id id, NodeStatus status) { + this->_index[id] = status; +} +void IndexMap::remove_raw(Id id) { + this->_index.erase(id); +} + +void IndexMap::update_parent_after_remove(Id id) { + const auto parent_opt = id.parent(); + if (!parent_opt.has_value()) { + return; + } + + const auto parent = parent_opt.value(); + NodeStatus* parent_status = this->get_raw(parent); + assert(parent_status != nullptr); + + // We know there are children since we just removed one + assert(parent.has_children()); + const auto siblings = parent.children().value(); + for (const auto& sibling : siblings) { + if (this->is_present(sibling) && sibling != id) { + return; + } + } + + switch (*parent_status) { + case NodeStatus::Inner: + *parent_status = NodeStatus::Leaf; + break; + case NodeStatus::Virtual: + this->remove_raw(parent); + this->update_parent_after_remove(parent); + break; + case NodeStatus::Leaf: + UNREACHABLE(); + break; + } +} + +} diff --git a/src/terrainlib/octree/IndexMap.h b/src/terrainlib/octree/IndexMap.h index 72743d5..e249424 100644 --- a/src/terrainlib/octree/IndexMap.h +++ b/src/terrainlib/octree/IndexMap.h @@ -1,12 +1,12 @@ #pragma once #include +#include #include #include "octree/Id.h" #include "octree/NodeStatus.h" -#include "log.h" namespace octree { @@ -16,179 +16,34 @@ class IndexMap { using iterator = Container::iterator; using const_iterator = Container::const_iterator; - std::optional get(Id id) const { - const NodeStatus* status = this->get_raw(id); - if (status != nullptr) { - return *status; - } else { - return std::nullopt; - } - } + std::optional get(Id id) const; + void add(Id id); + bool remove(Id id); - void add(Id id) { - NodeStatus* status = this->get_raw(id); - if (status != nullptr) { - switch (*status) { - case NodeStatus::Inner: - case NodeStatus::Leaf: - // Nothing to do - break; - case NodeStatus::Virtual: - this->set_raw(id, NodeStatus::Inner); - break; - } - return; - } + bool is_present(Id id) const; + bool is_absent(Id id) const; + bool is(NodeStatus status, Id id) const; - const auto parent_opt = id.parent(); - if (!parent_opt.has_value()) { - assert(id.is_root()); - if (this->empty()) { - this->set_raw(id, NodeStatus::Leaf); - return; - } else { - UNREACHABLE(); - return; - } - } - - const auto parent = parent_opt.value(); - const NodeStatus* parent_status = this->get_raw(parent); - if (parent_status == nullptr) { - this->add(parent); - this->set_raw(parent, NodeStatus::Virtual); - this->set_raw(id, NodeStatus::Leaf); - return; - } + void clear(); + bool empty() const; + size_t size() const; - switch (*parent_status) { - case NodeStatus::Leaf: - this->set_raw(parent, NodeStatus::Inner); - this->set_raw(id, NodeStatus::Leaf); - break; - case NodeStatus::Inner: - case NodeStatus::Virtual: - this->set_raw(id, NodeStatus::Leaf); - break; - } - } + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; - bool remove(Id id) { - NodeStatus* status = this->get_raw(id); - if (status == nullptr) { - return false; - } - - switch (*status) { - case NodeStatus::Inner: - *status = NodeStatus::Virtual; - return true; - case NodeStatus::Virtual: - // Nothing to do - return false; - case NodeStatus::Leaf: - this->remove_raw(id); - this->update_parent_after_remove(id); - return true; - } - - UNREACHABLE(); - } - - bool is_present(Id id) const { - auto it = this->_index.find(id); - return it != this->_index.end(); - } - bool is_absent(Id id) const { - return !this->is_present(id); - } - bool is(NodeStatus status, Id id) const { - return this->get(id) == status; - } - - void clear() { - this->_index.clear(); - } - bool empty() const { - return this->_index.empty(); - } - size_t size() const { - return this->_index.size(); - } - - const_iterator begin() const { - return this->_index.begin(); - } - const_iterator end() const { - return this->_index.end(); - } - const_iterator cbegin() const { - return this->_index.cbegin(); - } - const_iterator cend() const { - return this->_index.cend(); - } - - - NodeStatus* get_raw(Id id) { - if (auto it = this->_index.find(id); it != this->_index.end()) { - return &it->second; - } - return nullptr; - } - const NodeStatus* get_raw(Id id) const { - if (auto it = this->_index.find(id); it != this->_index.end()) { - return &it->second; - } - return nullptr; - } - void set_raw(Id id, NodeStatus status) { - this->_index[id] = status; - } - void remove_raw(Id id) { - this->_index.erase(id); - } + NodeStatus* get_raw(Id id); + const NodeStatus* get_raw(Id id) const; + void set_raw(Id id, NodeStatus status); + void remove_raw(Id id); + using serialize = zpp::bits::members<1>; + friend zpp::bits::access; private: Container _index; - - void update_parent_after_remove(Id id) { - const auto parent_opt = id.parent(); - if (!parent_opt.has_value()) { - return; - } - - const auto parent = parent_opt.value(); - NodeStatus* parent_status = this->get_raw(parent); - assert(parent_status != nullptr); - - // We know there are children since we just removed one - assert(parent.has_children()); - const auto siblings = parent.children().value(); - for (const auto& sibling : siblings) { - if (this->is_present(sibling) && sibling != id) { - return; - } - } - - switch (*parent_status) { - case NodeStatus::Inner: - *parent_status = NodeStatus::Leaf; - break; - case NodeStatus::Virtual: - this->remove_raw(parent); - this->update_parent_after_remove(parent); - break; - case NodeStatus::Leaf: - UNREACHABLE(); - break; - } - } - - -public: - using serialize = zpp::bits::members<1>; - friend zpp::bits::access; + void update_parent_after_remove(Id id); }; -} + +} // namespace octree diff --git a/src/terrainlib/octree/Space.cpp b/src/terrainlib/octree/Space.cpp new file mode 100644 index 0000000..41275b9 --- /dev/null +++ b/src/terrainlib/octree/Space.cpp @@ -0,0 +1,120 @@ +#include "octree/Space.h" + +namespace octree { + +Space::Space(Bounds bounds) : _bounds(bounds) { + assert(glm::all(glm::greaterThan(this->_bounds.size(), glm::dvec3(0)))); +} + +Space Space::earth() { + const float max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) + const float extends = max_radius * 1.1; // TODO: how much padding do we want here + return Space(Bounds( + {-extends, -extends, -extends}, {extends, extends, extends})); +} + +std::optional Space::find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root) const { + // We don't want to recurse indefinitely if the bounds are empty. + const glm::dvec3 target_size = target_bounds.size(); + if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { + throw std::invalid_argument("target bounds cannot be empty"); + } + + const std::array corners = radix::geometry::corners(target_bounds); + + const Bounds root_bounds = get_node_bounds(root); + // Check if all points of the target bounds are inside the root bounds. + bool all_corners_inside_root = true; + for (const auto &corner : corners) { + if (!root_bounds.contains_inclusive(corner)) { + all_corners_inside_root = false; + break; + } + } + + if (!all_corners_inside_root) { + return std::nullopt; // Target bounds are outside the defined space. + } + + Id current_smallest_encompassing_node = root; + while (current_smallest_encompassing_node.has_children()) { + const std::array children = current_smallest_encompassing_node.children().value(); + std::optional next_smallest; + + for (const auto &child : children) { + const Bounds child_bounds = get_node_bounds(child); + bool all_corners_inside_child = true; + for (const auto &corner : corners) { + if (!child_bounds.contains_inclusive(corner)) { + all_corners_inside_child = false; + break; + } + } + + if (all_corners_inside_child) { + next_smallest = child; + break; // Found a child that fully contains the bounds, go deeper. + } + } + + if (next_smallest.has_value()) { + current_smallest_encompassing_node = next_smallest.value(); + } else { + break; // No child fully contains the bounds, so the current node is the smallest. + } + } + + return current_smallest_encompassing_node; +} + +std::optional Space::find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root) const { + assert(target_level <= Id::max_level()); + + Id current = root; + const Bounds root_bounds = this->get_node_bounds(current); + if (!root_bounds.contains_exclusive(point)) { + return std::nullopt; + } + + // TODO: this could be much more efficient + while (current.level() < target_level) { + const auto children = current.children().value(); + for (const auto& child : children) { + const Bounds child_bounds = this->get_node_bounds(child); + if (child_bounds.contains_exclusive(point)) { + current = child; + break; + } + } + } + + return current; +} + +Bounds Space::get_node_bounds(const Id &id) const { + const auto coords = id.coords(); + const uint32_t level = id.level(); + const uint32_t resolution = 1 << level; + + // Calculate the size of a node at this level + const glm::dvec3 bounds_size = this->_bounds.size(); + const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); + + // Calculate the minimum point of the node + const glm::dvec3 min_bound = this->_bounds.min; + const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; + + // Calculate the maximum point of the node + const glm::dvec3 node_max = node_min + node_size; + + Bounds node_bounds; + node_bounds.min = node_min; + node_bounds.max = node_max; + return node_bounds; +} + +const Bounds& Space::bounds() const { + return this->_bounds; +} + +} // namespace octree diff --git a/src/terrainlib/octree/Space.h b/src/terrainlib/octree/Space.h index 9f7841d..ae0187d 100644 --- a/src/terrainlib/octree/Space.h +++ b/src/terrainlib/octree/Space.h @@ -1,6 +1,9 @@ #pragma once +#include + #include +#include #include "octree/Id.h" @@ -10,116 +13,18 @@ using Bounds = radix::geometry::Aabb3d; // TODO: add srs to this? class Space { public: - const Bounds bounds; - - static constexpr Space earth() { - const float max_radius = 6384400; // from https://en.wikipedia.org/wiki/Summits_farthest_from_the_Earth%27s_center#:~:text=Dormant%20Volcano,6%2C267%20metres%20(20%2C561%20ft) - const float extends = max_radius * 1.1; // TODO: how much padding do we want here - return Space(Bounds( - {-extends, -extends, -extends}, {extends, extends, extends})); - } - - std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const { - // We don't want to recurse indefinitely if the bounds are empty. - const glm::dvec3 target_size = target_bounds.size(); - if (target_size.x == 0 || target_size.y == 0 || target_size.z == 0) { - throw std::invalid_argument("target bounds cannot be empty"); - } - - const std::array corners = radix::geometry::corners(target_bounds); - - const Bounds root_bounds = get_node_bounds(root); - // Check if all points of the target bounds are inside the root bounds. - bool all_corners_inside_root = true; - for (const auto &corner : corners) { - if (!root_bounds.contains_inclusive(corner)) { - all_corners_inside_root = false; - break; - } - } - - if (!all_corners_inside_root) { - return std::nullopt; // Target bounds are outside the defined space. - } - - Id current_smallest_encompassing_node = root; - while (current_smallest_encompassing_node.has_children()) { - const std::array children = current_smallest_encompassing_node.children().value(); - std::optional next_smallest; - - for (const auto &child : children) { - const Bounds child_bounds = get_node_bounds(child); - bool all_corners_inside_child = true; - for (const auto &corner : corners) { - if (!child_bounds.contains_inclusive(corner)) { - all_corners_inside_child = false; - break; - } - } - - if (all_corners_inside_child) { - next_smallest = child; - break; // Found a child that fully contains the bounds, go deeper. - } - } + explicit Space(Bounds bounds); + static Space earth(); - if (next_smallest.has_value()) { - current_smallest_encompassing_node = next_smallest.value(); - } else { - break; // No child fully contains the bounds, so the current node is the smallest. - } - } + std::optional find_smallest_node_encompassing_bounds(const Bounds &target_bounds, const Id root = Id::root()) const ; + std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const; - return current_smallest_encompassing_node; - } - - std::optional find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root = Id::root()) const { - assert(target_level <= Id::max_level()); - - Id current = root; - const Bounds root_bounds = this->get_node_bounds(current); - if (!root_bounds.contains_exclusive(point)) { - return std::nullopt; - } - - // TODO: this could be much more efficient - while (current.level() < target_level) { - const auto children = current.children().value(); - for (const auto& child : children) { - const Bounds child_bounds = this->get_node_bounds(child); - if (child_bounds.contains_exclusive(point)) { - current = child; - break; - } - } - } - - return current; - } - - Bounds get_node_bounds(const Id &id) const { - const auto coords = id.coords(); - const uint32_t level = id.level(); - const uint32_t resolution = 1 << level; - - // Calculate the size of a node at this level - const glm::dvec3 bounds_size = bounds.size(); - const glm::dvec3 node_size = bounds_size / glm::dvec3(resolution); - - // Calculate the minimum point of the node - const glm::dvec3 min_bound = bounds.min; - const glm::dvec3 node_min = min_bound + glm::dvec3(coords) * node_size; - - // Calculate the maximum point of the node - const glm::dvec3 node_max = node_min + node_size; - - Bounds node_bounds; - node_bounds.min = node_min; - node_bounds.max = node_max; - return node_bounds; - } + Bounds get_node_bounds(const Id &id) const; + const Bounds& bounds() const; private: + const Bounds _bounds; + }; } // namespace octree From f0edc02391c28ce6fabfdd4c0628f8001534a7b8 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 23:22:16 +0200 Subject: [PATCH 064/122] Add index accessor on Storage --- src/terrainlib/octree/Storage.cpp | 8 ++++++++ src/terrainlib/octree/Storage.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp index c301bb6..8b73477 100644 --- a/src/terrainlib/octree/Storage.cpp +++ b/src/terrainlib/octree/Storage.cpp @@ -74,6 +74,14 @@ std::filesystem::path Storage::get_node_path(const Id &id) const { return this->_layout.get_node_path(id); } +const IndexMap* Storage::index() const { + if (this->_index.has_value()) { + return &this->_index.value(); + } else { + return nullptr; + } +} + bool Storage::save_index() const { const auto index_path = this->_layout.base_path() / disk::v1::index_file_name(); LOG_TRACE("Saving octree storage index to {}", index_path); diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index c173d3e..556705a 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -26,6 +26,7 @@ class Storage { bool has_node(const Id &id) const; std::filesystem::path get_node_path(const Id &id) const; + const IndexMap* index() const; bool save_index() const; private: @@ -33,7 +34,7 @@ class Storage { disk::Layout _layout; }; -std::optional open_index(const std::filesystem::path &index_path); +std::optional load_index(const std::filesystem::path &index_path); Storage open_folder( const std::filesystem::path &base_path, std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), From d7ecba517c030ca0f6b18cb5f7a39aa7372cff21 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 23:22:25 +0200 Subject: [PATCH 065/122] Fix tests --- unittests/terrainlib/octree_space.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/unittests/terrainlib/octree_space.cpp b/unittests/terrainlib/octree_space.cpp index 82ed126..b795b12 100644 --- a/unittests/terrainlib/octree_space.cpp +++ b/unittests/terrainlib/octree_space.cpp @@ -10,7 +10,7 @@ using namespace octree; TEST_CASE("find_smallest_node_encompassing_bounds includes full space", "[octree::Space]") { Space space = Space::earth(); - auto full_space_id = space.find_smallest_node_encompassing_bounds(space.bounds); + auto full_space_id = space.find_smallest_node_encompassing_bounds(space.bounds()); REQUIRE(full_space_id.has_value()); CHECK(full_space_id.value() == Id::root()); } @@ -19,8 +19,8 @@ TEST_CASE("find_smallest_node_encompassing_bounds returns more specific child", Space space = Space::earth(); Bounds inner_box{ - space.bounds.min, - space.bounds.min + space.bounds.size() / 2.0 + space.bounds().min, + space.bounds().min + space.bounds().size() / 2.0 }; auto id = space.find_smallest_node_encompassing_bounds(inner_box); @@ -31,11 +31,11 @@ TEST_CASE("find_smallest_node_encompassing_bounds returns more specific child", TEST_CASE("find_smallest_node_encompassing_bounds returns nullopt for out-of-bounds", "[octree::Space]") { Space space = Space::earth(); - glm::dvec3 offset = space.bounds.size() * 2.0; + glm::dvec3 offset = space.bounds().size() * 2.0; Bounds far_away{ - space.bounds.min + offset, - space.bounds.min + offset + glm::dvec3(1.0) + space.bounds().min + offset, + space.bounds().min + offset + glm::dvec3(1.0) }; auto id = space.find_smallest_node_encompassing_bounds(far_away); @@ -55,12 +55,12 @@ TEST_CASE("find_smallest_node_encompassing_bounds returns smallest valid node", Space space = Space::earth(); // Pick a very small bounds somewhere inside the root - glm::dvec3 offset = space.bounds.size() * 0.1; - glm::dvec3 size = space.bounds.size() * 0.001; + glm::dvec3 offset = space.bounds().size() * 0.1; + glm::dvec3 size = space.bounds().size() * 0.001; Bounds target{ - space.bounds.min + offset, - space.bounds.min + offset + size}; + space.bounds().min + offset, + space.bounds().min + offset + size}; auto maybe_id = space.find_smallest_node_encompassing_bounds(target); REQUIRE(maybe_id.has_value()); From 26bd671e3778207f0f03768161a49203e4510873 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 29 May 2025 23:22:46 +0200 Subject: [PATCH 066/122] Fix octree traverse and add tests --- src/terrainlib/octree/traverse.h | 49 +++++---- unittests/CMakeLists.txt | 1 + unittests/terrainlib/index_traverse.cpp | 135 ++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 unittests/terrainlib/index_traverse.cpp diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index 41e432c..bf79430 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -1,5 +1,12 @@ #pragma once +#include +#include + +#include "octree/Id.h" +#include "octree/Storage.h" +#include "log.h" + namespace octree { enum class TraversalOrder { @@ -11,51 +18,57 @@ template < typename VisitFn, typename RefineFn = std::function> void traverse( - const Storage &storage, + const IndexMap& index, VisitFn visit_fn, - TraversalOrder order = TraversalOrder::DepthFirst, RefineFn refine_fn = [](const Id &) { return true; }, - const Id &root = Id::root()) { - if (!storage.has_node(root)) { + const Id &root = Id::root(), + TraversalOrder order = TraversalOrder::DepthFirst) { + if (!index.is_present(root)) { return; } if (order == TraversalOrder::DepthFirst) { std::function dfs; - dfs = [&](const Id& id) { - if (!storage.has_node(id) || !filter_fn(id)) return; + dfs = [&](const Id& current) { + if (!index.is_present(current)) { + return; + } - visit_fn(id); + visit_fn(current); - if (refine_fn(id)) { - for (const auto& child_id : id.children()) { - dfs(child_id); + if (current.has_children() && refine_fn(current)) { + const auto children = current.children().value(); + for (const auto& child : children) { + dfs(child); } } }; - dfs(root_id); - - } else { // BreadthFirst + dfs(root); + } else if (order == TraversalOrder::BreadthFirst) { std::queue queue; - queue.push(root_id); + queue.push(root); while (!queue.empty()) { Id current = queue.front(); queue.pop(); - if (!storage.has_node(current) || !filter_fn(current)) { + if (!index.is_present(current)) { continue; } visit_fn(current); - if (refine_fn(current)) { - for (const auto& child_id : current.children()) { - queue.push(child_id); + if (current.has_children() && refine_fn(current)) { + const auto children = current.children().value(); + for (const auto& child : children) { + queue.push(child); } } } + } else { + UNREACHABLE(); } } + } // namespace octree diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index dac6072..37ead07 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(unittests_terrainlib terrainlib/grid.cpp terrainlib/progress_indicator_test.cpp terrainlib/index_map.cpp + terrainlib/index_traverse.cpp terrainlib/octree_id.cpp terrainlib/octree_space.cpp terrainlib/mesh_io.cpp diff --git a/unittests/terrainlib/index_traverse.cpp b/unittests/terrainlib/index_traverse.cpp new file mode 100644 index 0000000..2384c18 --- /dev/null +++ b/unittests/terrainlib/index_traverse.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include + +#include "octree/Id.h" +#include "octree/IndexMap.h" +#include "octree/traverse.h" + +using namespace octree; + +TEST_CASE("octree::traverse basic") { + IndexMap index; + + const Id root = Id::root(); + index.add(root); + + const auto children = root.children().value(); + for (const auto& child : children) { + index.add(child); + } + + SECTION("traversal visits root then children") { + std::vector visited; + traverse( + index, + [&](const Id& id) { + visited.push_back(id); + }, + [](const Id&) { return true; }, // refine always + root, + TraversalOrder::DepthFirst + ); + + CHECK(visited.front() == root); + CHECK(visited.size() == 9); // root + 8 children + std::vector expected(children.begin(), children.end()); + visited.erase(visited.begin()); + CHECK(visited == expected); + } + + SECTION("Refine function disables recursion") { + std::vector visited; + traverse( + index, + [&](const Id& id) { + visited.push_back(id); + }, + [](const Id&) { return false; }, // don't refine + root, + TraversalOrder::DepthFirst + ); + + CHECK(visited.size() == 1); + CHECK(visited.front() == root); + } + + SECTION("Traversal skips when root is missing") { + IndexMap empty; + bool visited = false; + + traverse( + empty, + [&](const Id&) { + visited = true; + }, + [](const Id&) { return true; }, + root, + TraversalOrder::DepthFirst + ); + + CHECK_FALSE(visited); + } +} + +TEST_CASE("octree::traverse with depth") { + IndexMap index; + + const Id root = Id::root(); + index.add(root); + + const auto children = root.children().value(); + const Id c0 = children[0]; + const Id c1 = children[1]; + const Id c2 = children[2]; + + index.add(c0); + index.add(c1); + index.add(c2); + + // Add grandchildren + const Id gc0 = c0.child(0).value(); // grandchild of c0 + const Id gc1 = c2.child(1).value(); // grandchild of c2 + + index.add(gc0); + index.add(gc1); + + SECTION("DFS visits deeply before siblings") { + std::vector visited; + traverse( + index, + [&](const Id& id) { + visited.push_back(id); + }, + [](const Id&) { return true; }, + root, + TraversalOrder::DepthFirst + ); + + REQUIRE(visited.size() == 6); + + // DFS order should be: root, c0, gc0, c1, c2, gc1 + std::vector expected{root, c0, gc0, c1, c2, gc1}; + CHECK(visited == expected); + } + + SECTION("BFS visits all nodes level by level") { + std::vector visited; + traverse( + index, + [&](const Id& id) { + visited.push_back(id); + }, + [](const Id&) { return true; }, + root, + TraversalOrder::BreadthFirst + ); + + REQUIRE(visited.size() == 6); + + // BFS order should be: root, c0, c1, c2, gc0, gc1 + std::vector expected{root, c0, c1, c2, gc0, gc1}; + CHECK(visited == expected); + } +} From 6ef2d643739687d07a2daeb675e28761a9f03379 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 10:21:15 +0200 Subject: [PATCH 067/122] Fix build of terrainsimplify --- src/terrainsimplify/main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/terrainsimplify/main.cpp b/src/terrainsimplify/main.cpp index 9109e60..b375cd4 100644 --- a/src/terrainsimplify/main.cpp +++ b/src/terrainsimplify/main.cpp @@ -3,6 +3,7 @@ #include "log.h" #include "merge.h" #include "mesh/io.h" +#include "mesh/utils.h" #include "simplify.h" #include "uv_map.h" #include "validate.h" @@ -11,9 +12,9 @@ std::vector load_meshes_from_path(std::span meshes; meshes.reserve(paths.size()); for (const std::filesystem::path &path : paths) { - auto result = io::load_mesh_from_path(path); + auto result = mesh::io::load_from_path(path); if (!result.has_value()) { - const io::LoadMeshError error = result.error(); + const mesh::io::LoadMeshError error = result.error(); if (print_errors) { LOG_ERROR("Failed to load mesh from {}: {}", path, error.description()); } @@ -76,7 +77,7 @@ void run(const cli::Args &args) { if (args.save_intermediate_meshes) { const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".merged.glb"); LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "merged"}); + mesh::io::save_to_path(merged_mesh, merged_mesh_path, mesh::io::SaveOptions{.name = "merged"}); } if (meshes_have_uvs) { @@ -91,7 +92,7 @@ void run(const cli::Args &args) { if (args.save_intermediate_meshes) { const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".textured.glb"); LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - io::save_mesh_to_path(merged_mesh_path, merged_mesh, io::SaveOptions{.name = "textured"}); + mesh::io::save_to_path(merged_mesh, merged_mesh_path, mesh::io::SaveOptions{.name = "textured"}); } } } @@ -109,14 +110,14 @@ void run(const cli::Args &args) { if (args.save_intermediate_meshes) { const std::filesystem::path simplified_mesh_path = std::filesystem::path(args.output_path).replace_extension(".simplified.glb"); LOG_DEBUG("Saving simplified mesh to {}", simplified_mesh_path.string()); - io::save_mesh_to_path(simplified_mesh_path, simplified_mesh, io::SaveOptions{.name = "simplified"}); + mesh::io::save_to_path(simplified_mesh, simplified_mesh_path, mesh::io::SaveOptions{.name = "simplified"}); } } else { simplified_mesh = merged_mesh; } LOG_INFO("Saving final mesh..."); - io::save_mesh_to_path(args.output_path, simplified_mesh); + mesh::io::save_to_path(simplified_mesh, args.output_path); LOG_INFO("Done"); } From bb7679919b842ca3b8681fad03d4e915ec8cc973 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 10:21:57 +0200 Subject: [PATCH 068/122] Add ensure_indexed on Storage --- src/terrainlib/OnceCell.h | 53 +++++++++++++++++++++++++++++++ src/terrainlib/OnceLock.h | 49 ++++++++++++++++++++++++++++ src/terrainlib/octree/Storage.cpp | 52 ++++++++++++++++++------------ src/terrainlib/octree/Storage.h | 5 ++- 4 files changed, 137 insertions(+), 22 deletions(-) create mode 100644 src/terrainlib/OnceCell.h create mode 100644 src/terrainlib/OnceLock.h diff --git a/src/terrainlib/OnceCell.h b/src/terrainlib/OnceCell.h new file mode 100644 index 0000000..f95dbfa --- /dev/null +++ b/src/terrainlib/OnceCell.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include + +template +class OnceCell { +public: + OnceCell() = default; + OnceCell(T value) { + this->_value = std::move(value); + } + + // Returns true if the value was set; false if already initialized + T& set(T value) { + if (this->_value.has_value()) { + return *this->_value; + } + this->_value = std::move(value); + return *this->_value; + } + const T& set(T value) const { + if (this->_value.has_value()) { + return *this->_value; + } + this->_value = std::move(value); + return *this->_value; + } + + // Lazily initialize value using init_fn if not already set + template + const T& get_or_init(F&& init_fn) const { + if (!this->_value.has_value()) { + this->_value = init_fn(); + } + return *this->_value; + } + + T* get() { + return this->_value ? &*this->_value : nullptr; + } + const T* get() const { + return this->_value ? &*this->_value : nullptr; + } + + bool is_initialized() const { + return this->_value.has_value(); + } + +private: + mutable std::optional _value; +}; diff --git a/src/terrainlib/OnceLock.h b/src/terrainlib/OnceLock.h new file mode 100644 index 0000000..b187bce --- /dev/null +++ b/src/terrainlib/OnceLock.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include + +template +class OnceLock { +public: + OnceLock() = default; + OnceLock(const OnceLock&) = delete; + OnceLock& operator=(const OnceLock&) = delete; + + // Initialize with a value (if not already set) + bool set(T value) { + if (this->is_initialized()) { + return false; // Already initialized + } + bool initialized = false; + std::call_once(this->_init_flag, [this, &value, &initialized]() { + this->_value.emplace(std::move(value)); + initialized = true; + }); + return initialized; + } + + // Lazily initialize using a function + template + const T& get_or_init(F&& init_fn) const { + std::call_once(this->_init_flag, [this, &init_fn]() { + this->_value.emplace(init_fn()); + }); + return *this->_value; + } + + // Get without initializing (returns nullptr if uninitialized) + const T* get() const { + return this->_value ? &*this->_value : nullptr; + } + + bool is_initialized() const { + return this->_value.has_value(); + } + +private: + mutable std::optional _value; + mutable std::once_flag _init_flag; +}; diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp index 8b73477..6edb97d 100644 --- a/src/terrainlib/octree/Storage.cpp +++ b/src/terrainlib/octree/Storage.cpp @@ -21,9 +21,8 @@ Storage::Storage(IndexMap map, disk::Layout layout) : _index(std::move(map)), _layout(std::move(layout)) {} std::optional Storage::read_node(const Id &id) const { - if (this->_index.has_value()) { - const auto& index = this->_index.value(); - if (index.is_absent(id)) { + if (const auto* index = this->_index.get()) { + if (index->is_absent(id)) { return std::nullopt; } } @@ -39,32 +38,31 @@ std::optional Storage::read_node(const Id &id) const { bool Storage::write_node(const Id &id, const Node &node) { const auto node_path = this->get_node_path(id); const auto result = mesh::io::save_to_path(node, node_path); - if (result.has_value() && this->_index.has_value()) { - auto& index = this->_index.value(); - index.add(id); + if (result.has_value()) { + if (auto* index = this->_index.get()) { + index->add(id); + } } return result.has_value(); } bool Storage::remove_node(const Id &id) { - if (this->_index.has_value()) { - const auto& index = this->_index.value(); - if (index.is_absent(id)) { + if (const auto* index = this->_index.get()) { + if (index->is_absent(id)) { return false; } } const auto node_path = this->get_node_path(id); const bool result = std::filesystem::remove(node_path); - if (this->_index.has_value()) { - auto& index = this->_index.value(); - index.remove(id); + if (auto* index = this->_index.get()) { + index->remove(id); } return result; } bool Storage::has_node(const Id &id) const { - if (this->_index.has_value()) { - return this->_index->is_present(id); + if (const auto* index = this->_index.get()) { + return index->is_present(id); } else { return std::filesystem::exists(this->get_node_path(id)); } @@ -75,11 +73,11 @@ std::filesystem::path Storage::get_node_path(const Id &id) const { } const IndexMap* Storage::index() const { - if (this->_index.has_value()) { - return &this->_index.value(); - } else { - return nullptr; - } + return this->_index.get(); +} + +bool Storage::has_index() const { + return this->_index.is_initialized(); } bool Storage::save_index() const { @@ -87,8 +85,8 @@ bool Storage::save_index() const { LOG_TRACE("Saving octree storage index to {}", index_path); disk::v1::IndexFile index_file; - if (this->_index.has_value()) { - index_file.map = this->_index.value(); + if (const auto* index = this->_index.get()) { + index_file.map = *index; } index_file.preferred_extension = this->_layout.extension_with_dot(); index_file.layout_strategy_id = disk::layout::StrategyRegister::instance().get_id(this->_layout.strategy()); @@ -249,4 +247,16 @@ Storage open_folder( return storage; } +const IndexMap& Storage::ensure_indexed() const { + if (const auto* index = this->_index.get()) { + return *index; + } + + LOG_TRACE("Index not present, creating empty index"); + IndexMap index; + update_index(index, this->_layout); + LOG_TRACE("Index created with {} entries", index.size()); + return this->_index.set(std::move(index)); +} + } // namespace octree diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index 556705a..5bf0ac9 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -6,6 +6,7 @@ #include "mesh/SimpleMesh.h" #include "mesh/io.h" +#include "OnceCell.h" #include "octree/Id.h" #include "octree/IndexMap.h" #include "octree/disk/Layout.h" @@ -27,10 +28,12 @@ class Storage { std::filesystem::path get_node_path(const Id &id) const; const IndexMap* index() const; + bool has_index() const; bool save_index() const; + const IndexMap& ensure_indexed() const; private: - std::optional _index; + OnceCell _index; disk::Layout _layout; }; From 135e998551d3105d03c24e6ab8ff7b991927ca8c Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 10:22:15 +0200 Subject: [PATCH 069/122] Fix constness warning in terrainbuilder --- src/terrainbuilder/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index 85ba80f..9e48275 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -159,7 +159,7 @@ void batch_build( const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_base_path, const std::string &output_format) { - const octree::Storage storage = octree::open_folder( + octree::Storage storage = octree::open_folder( output_base_path, octree::disk::layout::strategy::make_default(), output_format); From 635406d3aae75caca98e7bb62dd9be283f357ba1 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 10:49:54 +0200 Subject: [PATCH 070/122] Add status to traversal visit --- src/terrainlib/octree/traverse.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index bf79430..3ae4613 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -30,11 +30,13 @@ void traverse( if (order == TraversalOrder::DepthFirst) { std::function dfs; dfs = [&](const Id& current) { - if (!index.is_present(current)) { + auto current_status_opt = index.get(current); + if (!current_status_opt) { return; } - - visit_fn(current); + const auto current_status = current_status_opt.value(); + + visit_fn(current, current_status); if (current.has_children() && refine_fn(current)) { const auto children = current.children().value(); @@ -52,11 +54,13 @@ void traverse( Id current = queue.front(); queue.pop(); - if (!index.is_present(current)) { - continue; + auto current_status_opt = index.get(current); + if (!current_status_opt) { + return; } + const auto current_status = current_status_opt.value(); - visit_fn(current); + visit_fn(current, current_status); if (current.has_children() && refine_fn(current)) { const auto children = current.children().value(); From c1b9340a907bcb6f1616c7ab3768f0135a890c6d Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 14:33:52 +0200 Subject: [PATCH 071/122] Create output dir in terrainbuilder --- src/terrainbuilder/main.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index 9e48275..6e5f058 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -159,6 +159,13 @@ void batch_build( const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_base_path, const std::string &output_format) { + if (!std::filesystem::exists(output_base_path)) { + LOG_TRACE("Output base path {} does not exist, creating it", output_base_path); + std::filesystem::create_directories(output_base_path); + } else if (!std::filesystem::is_directory(output_base_path)) { + LOG_ERROR_AND_EXIT("Output base path {} exists but is not a directory", output_base_path); + } + octree::Storage storage = octree::open_folder( output_base_path, octree::disk::layout::strategy::make_default(), @@ -230,7 +237,7 @@ void batch_build( }); tbb::parallel_for(size_t(0), target_nodes.size(), [&](size_t i) { const auto &node = target_nodes[i]; - if (storage.has_node(node)) { + if (storage.has_node(node)) { // TODO: correctly handle virtual nodes return; } From c00ec9ff3f68a3c4b66f9e333d0327fe6acf8dbb Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 14:34:27 +0200 Subject: [PATCH 072/122] Move mesh clipping and reindexing into terrainlib --- src/terrainbuilder/mesh_builder.cpp | 147 +--------------------------- src/terrainlib/mesh/utils.cpp | 146 +++++++++++++++++++++++++++ src/terrainlib/mesh/utils.h | 5 + 3 files changed, 152 insertions(+), 146 deletions(-) diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index 25e89ef..e05f0be 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -118,151 +118,6 @@ SimpleMesh transform_mesh(const SimpleMesh &source_mesh, const OGRSpatialReferen return target_mesh; } -SimpleMesh reindex_mesh(const SimpleMesh &mesh) { - std::vector new_positions; - new_positions.reserve(mesh.vertex_count()); - std::vector new_triangles; - new_triangles.reserve(mesh.face_count()); - const uint32_t invalid_index = static_cast(-1); - std::vector index_map(mesh.positions.size(), invalid_index); - - for (const auto &triangle : mesh.triangles) { - glm::uvec3 new_triangle_indices; - for (size_t i = 0; i < 3; i++) { - const uint32_t old_index = triangle[i]; - if (index_map[old_index] == invalid_index) { - // Vertex newly encountered - const uint32_t new_index = new_positions.size(); - new_positions.push_back(mesh.positions[old_index]); - new_triangle_indices[i] = new_index; - index_map[old_index] = new_index; - } else { - // Vertex already encountered - new_triangle_indices[i] = index_map[old_index]; - } - } - new_triangles.push_back(new_triangle_indices); - } - - return SimpleMesh(new_triangles, new_positions); -} - -namespace { - struct DVec3Hash { - std::size_t operator()(const glm::dvec3 &v) const { - std::size_t h1 = std::hash{}(v.x); - std::size_t h2 = std::hash{}(v.y); - std::size_t h3 = std::hash{}(v.z); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } - }; - - struct DVec3Equal { - const double epsilon; - - bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { - return glm::all(glm::epsilonEqual(a, b, 1e-8)); - } - }; -} - -SimpleMesh clip_mesh(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { - if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { - return {}; - } - - // Calculate epsilon to merge newly created vertices - const double max_edge_length = calculate_max_edge_length(mesh).value(); - const double average_edge_length = estimate_average_edge_length(mesh).value(); - const double epsilon = average_edge_length / 1000; - - std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); - - // Construct 6 axis-aligned clipping planes from the bounding box - using Plane = radix::geometry::Plane; - const std::array planes = { - Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left - Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right - Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom - Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top - Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near - Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far - }; - - std::vector new_positions = mesh.positions; - std::vector new_triangles; - new_triangles.reserve(mesh.face_count()); - - // Iterate over each triangle in the mesh - for (const glm::uvec3 &source_triangle : mesh.triangles) { - using Tri = radix::geometry::Triangle<3, double>; - - // Get the positions for the current triangle - const Tri triangle = { - mesh.positions[source_triangle.x], - mesh.positions[source_triangle.y], - mesh.positions[source_triangle.z]}; - - const uint8_t inside_count = std::count_if(triangle.begin(), triangle.end(), [&](const auto &vertex) { - return bounds.contains_inclusive(vertex); - }); - if (inside_count == 0) { - // Triangle vertices are not inside the bounds, however there can still be intersection - if (std::any_of(triangle.begin(), triangle.end(), [&](const auto &vertex) { - return radix::geometry::distance_sq(bounds, vertex) > max_edge_length * max_edge_length; - })) { - continue; - } - } - if (inside_count == source_triangle.length()) { - new_triangles.push_back(source_triangle); - continue; - } - - // Start with the original triangle - // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle - const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); - for (const auto &clipped_triangle : clipped_triangles) { - glm::uvec3 decomposed_triangle; - for (size_t i = 0; i < clipped_triangle.size(); i++) { - const auto &vertex = clipped_triangle[i]; - std::optional vertex_index; - - // Check if this vertex was already in the source triangle - for (size_t j = 0; j < triangle.size(); j++) { - const auto &source_vertex = triangle[j]; - if (vertex == source_vertex) { - vertex_index = source_triangle[j]; - break; - } - } - - // Check if this vertex was already added - if (!vertex_index.has_value()) { - const auto it = seen_vertices.find(vertex); - if (it != seen_vertices.cend()) { - vertex_index = it->second; - } - - } - - // Add a new vertex - if (!vertex_index.has_value()) { - vertex_index = new_positions.size(); - new_positions.push_back(vertex); - seen_vertices.emplace(vertex, vertex_index.value()); - } - - decomposed_triangle[i] = vertex_index.value(); - } - new_triangles.push_back(decomposed_triangle); - } - } - - // TODO: derive new_positions from seen_vertices - return reindex_mesh(SimpleMesh(new_triangles, new_positions)); -} - std::vector generate_uv_space(const std::vector& positions, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds& texture_bounds) { std::vector uvs = srs::transform_points_to_2d(srs::transformation(mesh_srs, texture_srs).get(), positions); texture_bounds = radix::tile::SrsBounds(radix::geometry::find_bounds(uvs)); @@ -337,7 +192,7 @@ tl::expected build_reference_mesh_patch( LOG_TRACE("Clipping mesh based on target bounds"); const SimpleMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); - SimpleMesh clipped_mesh = clip_mesh(mesh_in_clip_srs, clip_bounds); + SimpleMesh clipped_mesh = clip_mesh_on_bounds(mesh_in_clip_srs, clip_bounds); // Check if there are any vertices left if (clipped_mesh.vertex_count() == 0 || clipped_mesh.face_count() == 0) { return tl::unexpected(BuildError::EmptyRegion); diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index b9e50c3..bf37b10 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -381,3 +381,149 @@ void validate_mesh(const SimpleMesh &mesh) { sort_and_normalize_triangles(sorted); validate_sorted_normalized_mesh(sorted); } + + +SimpleMesh reindex_mesh(const SimpleMesh &mesh) { + std::vector new_positions; + new_positions.reserve(mesh.vertex_count()); + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + const uint32_t invalid_index = static_cast(-1); + std::vector index_map(mesh.positions.size(), invalid_index); + + for (const auto &triangle : mesh.triangles) { + glm::uvec3 new_triangle_indices; + for (size_t i = 0; i < 3; i++) { + const uint32_t old_index = triangle[i]; + if (index_map[old_index] == invalid_index) { + // Vertex newly encountered + const uint32_t new_index = new_positions.size(); + new_positions.push_back(mesh.positions[old_index]); + new_triangle_indices[i] = new_index; + index_map[old_index] = new_index; + } else { + // Vertex already encountered + new_triangle_indices[i] = index_map[old_index]; + } + } + new_triangles.push_back(new_triangle_indices); + } + + return SimpleMesh(new_triangles, new_positions); +} + +namespace { + struct DVec3Hash { + std::size_t operator()(const glm::dvec3 &v) const { + std::size_t h1 = std::hash{}(v.x); + std::size_t h2 = std::hash{}(v.y); + std::size_t h3 = std::hash{}(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } + }; + + struct DVec3Equal { + const double epsilon; + + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, 1e-8)); + } + }; +} + +SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { + if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { + return {}; + } + + // Calculate epsilon to merge newly created vertices + const double max_edge_length = calculate_max_edge_length(mesh).value(); + const double average_edge_length = estimate_average_edge_length(mesh).value(); + const double epsilon = average_edge_length / 1000; + + std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); + + // Construct 6 axis-aligned clipping planes from the bounding box + using Plane = radix::geometry::Plane; + const std::array planes = { + Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left + Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right + Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom + Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top + Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near + Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far + }; + + std::vector new_positions = mesh.positions; + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + + // Iterate over each triangle in the mesh + for (const glm::uvec3 &source_triangle : mesh.triangles) { + using Tri = radix::geometry::Triangle<3, double>; + + // Get the positions for the current triangle + const Tri triangle = { + mesh.positions[source_triangle.x], + mesh.positions[source_triangle.y], + mesh.positions[source_triangle.z]}; + + const uint8_t inside_count = std::count_if(triangle.begin(), triangle.end(), [&](const auto &vertex) { + return bounds.contains_inclusive(vertex); + }); + if (inside_count == 0) { + // Triangle vertices are not inside the bounds, however there can still be intersection + if (std::any_of(triangle.begin(), triangle.end(), [&](const auto &vertex) { + return radix::geometry::distance_sq(bounds, vertex) > max_edge_length * max_edge_length; + })) { + continue; + } + } + if (inside_count == source_triangle.length()) { + new_triangles.push_back(source_triangle); + continue; + } + + // Start with the original triangle + // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle + const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); + for (const auto &clipped_triangle : clipped_triangles) { + glm::uvec3 decomposed_triangle; + for (size_t i = 0; i < clipped_triangle.size(); i++) { + const auto &vertex = clipped_triangle[i]; + std::optional vertex_index; + + // Check if this vertex was already in the source triangle + for (size_t j = 0; j < triangle.size(); j++) { + const auto &source_vertex = triangle[j]; + if (vertex == source_vertex) { + vertex_index = source_triangle[j]; + break; + } + } + + // Check if this vertex was already added + if (!vertex_index.has_value()) { + const auto it = seen_vertices.find(vertex); + if (it != seen_vertices.cend()) { + vertex_index = it->second; + } + + } + + // Add a new vertex + if (!vertex_index.has_value()) { + vertex_index = new_positions.size(); + new_positions.push_back(vertex); + seen_vertices.emplace(vertex, vertex_index.value()); + } + + decomposed_triangle[i] = vertex_index.value(); + } + new_triangles.push_back(decomposed_triangle); + } + } + + // TODO: derive new_positions from seen_vertices + return reindex_mesh(SimpleMesh(new_triangles, new_positions)); +} diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index 64b21df..a0c2ebf 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -7,6 +7,8 @@ #include #include +// TODO: put in mesh namespace + radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh); radix::geometry::Aabb3d calculate_bounds(std::span meshes); @@ -45,3 +47,6 @@ void sort_and_normalize_triangles(SimpleMesh& mesh); void sort_and_normalize_triangles(std::span triangles); void validate_mesh(const SimpleMesh &mesh); + +SimpleMesh reindex_mesh(const SimpleMesh &mesh); +SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); From 5c6369fdeb9cd968f3eed8c6233d126a94853bbd Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 14:35:05 +0200 Subject: [PATCH 073/122] Require exact height bounds and compute if needed --- src/terrainlib/Dataset.cpp | 4 ++-- src/terrainlib/Dataset.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 0823541..8477784 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -93,11 +93,11 @@ radix::tile::SrsBounds Dataset::bounds() const { return {{westX, southY}, {eastX, northY}}; } -radix::tile::SrsAndHeightBounds Dataset::bounds3d() const { +radix::tile::SrsAndHeightBounds Dataset::bounds3d(bool approx_ok) const { const auto band = this->m_gdal_dataset->GetRasterBand(1); glm::dvec2 height_range; - if (!band->GetStatistics(1, 0, &height_range.x, &height_range.y, nullptr, nullptr)) { + if (!band->GetStatistics(approx_ok, true, &height_range.x, &height_range.y, nullptr, nullptr)) { throw std::runtime_error("Could not determine dataset height bounds"); } diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index 622dc01..c7fba33 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -47,7 +47,7 @@ class Dataset { [[nodiscard]] std::string name() const; [[nodiscard]] radix::tile::SrsBounds bounds() const; - [[nodiscard]] radix::tile::SrsAndHeightBounds bounds3d() const; + [[nodiscard]] radix::tile::SrsAndHeightBounds bounds3d(bool approx_ok = false) const; [[nodiscard]] radix::tile::SrsBounds bounds(const OGRSpatialReference &targetSrs) const; [[nodiscard]] OGRSpatialReference srs() const; [[nodiscard]] unsigned int widthInPixels() const; From ac69e5b2581ed4269fe075ad185ff4c7ddd1f6fb Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 30 May 2025 14:47:59 +0200 Subject: [PATCH 074/122] Fix comparison of NodeStatus in edge cases --- src/terrainlib/octree/NodeStatus.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/terrainlib/octree/NodeStatus.h b/src/terrainlib/octree/NodeStatus.h index 0379b8f..757c179 100644 --- a/src/terrainlib/octree/NodeStatus.h +++ b/src/terrainlib/octree/NodeStatus.h @@ -28,6 +28,12 @@ class NodeStatus { constexpr bool operator!=(NodeStatus other) const { return !(*this == other); } + constexpr bool operator==(Value other_value) const { + return this->_value == other_value; + } + constexpr bool operator!=(Value other_value) const { + return this->_value != other_value; + } std::string to_string() const; From 9003a3dfab6326b4458f17478f9376b6baab56b2 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 3 Jun 2025 14:03:22 +0200 Subject: [PATCH 075/122] Fix build of browser on windows --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 68e99db..4c50fc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,7 @@ add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237 NOT_SYSTEM) -add_subdirectory(browser/res) +add_subdirectory(browser/res resources-lib) alp_add_git_repository(imgui URL https://github.com/ocornut/imgui.git COMMITISH 5f0acadf7db1b6d469f0771284e2e3f7818443ce DO_NOT_ADD_SUBPROJECT) add_library(imgui STATIC From bb10eeedd316345327704f937794486104cdb01d Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 4 Jun 2025 14:13:59 +0200 Subject: [PATCH 076/122] Initial version of terrainmerger --- src/CMakeLists.txt | 2 +- src/terrainlib/octree/Storage.h | 14 ++ src/terrainlib/octree/traverse.h | 4 +- src/terrainmerger/cli.cpp | 3 +- src/terrainmerger/main.cpp | 17 ++- src/terrainmerger/merge.h | 225 +++++++++++++++++++++++++++++++ 6 files changed, 259 insertions(+), 6 deletions(-) create mode 100644 src/terrainmerger/merge.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c50fc4..7ffd157 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -170,7 +170,7 @@ target_link_libraries(tilebuilder PUBLIC tilebuilderlib) add_library(terrainmergerlib - terrainmerger/cli.h + terrainmerger/merge.h ) target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index 5bf0ac9..1eff783 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -16,6 +16,18 @@ namespace octree { using Node = SimpleMesh; +struct NodeAndId { + Id id; + Node node; + + NodeAndId() = default; + NodeAndId(Id id, Node node) : id(std::move(id)), node(std::move(node)) {} + + operator Node() const { + return std::move(node); + } +}; + class Storage { public: explicit Storage(disk::Layout layout); @@ -26,6 +38,8 @@ class Storage { bool remove_node(const Id &id); bool has_node(const Id &id) const; std::filesystem::path get_node_path(const Id &id) const; + + const IndexMap* index() const; bool has_index() const; diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index 3ae4613..967c79a 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -19,8 +19,8 @@ template < typename RefineFn = std::function> void traverse( const IndexMap& index, - VisitFn visit_fn, - RefineFn refine_fn = [](const Id &) { return true; }, + VisitFn&& visit_fn, + RefineFn&& refine_fn = [](const Id &) { return true; }, const Id &root = Id::root(), TraversalOrder order = TraversalOrder::DepthFirst) { if (!index.is_present(root)) { diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index cc5fc0d..84c1476 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -16,7 +16,7 @@ Args cli::parse(int argc, const char * const * argv) { app.add_option("--input", input_paths, "Paths to datasets that should be merged") ->required() ->expected(-1) - ->check(CLI::ExistingFile); + ->check(CLI::ExistingDirectory); std::filesystem::path output_path; app.add_option("--output", output_path, "Path to output write the merged dataset to") @@ -39,7 +39,6 @@ Args cli::parse(int argc, const char * const * argv) { } catch (const CLI::ParseError &e) { exit(app.exit(e)); } - Args args; args.input_paths = input_paths; args.output_path = output_path; diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index 3478f8c..5744a55 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -5,7 +5,22 @@ #include "merge.h" void run(const cli::Args &args) { - std::vector + if (!std::filesystem::exists(args.output_path)) { + std::filesystem::create_directories(args.output_path); + } + + octree::Storage output_storage = octree::open_folder(args.output_path); + std::vector input_storages; + for (const auto &input_path : args.input_paths) { + if (!std::filesystem::exists(input_path)) { + LOG_ERROR("Input path '{}' does not exist.", input_path.string()); + return; + } + auto input_storage = octree::open_folder(input_path); + input_storages.push_back(std::move(input_storage)); + } + + merge_datasets(output_storage, input_storages); } int main(int argc, char **argv) { diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h new file mode 100644 index 0000000..0250a73 --- /dev/null +++ b/src/terrainmerger/merge.h @@ -0,0 +1,225 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/utils.h" +#include "octree/Storage.h" +#include "octree/traverse.h" +#include "octree/NodeStatus.h" +#include "octree/Space.h" +#include "log.h" + +inline SimpleMesh merge_meshes( + const SimpleMesh& mesh1, // base mesh + const SimpleMesh& mesh2 // priority mesh +) { + if (mesh1.is_empty()) { + return mesh2; + } + if (mesh2.is_empty()) { + return mesh1; + } + + // TODO: actual merge + return mesh2; +} + +inline std::optional> split_mesh_into_children(const octree::NodeAndId& node) { + if (!node.id.has_children()) { + return std::nullopt; + } + + const auto space = octree::Space::earth(); // TODO: store in storage + + const auto children = node.id.children().value(); + std::array child_nodes; + for (size_t i = 0; i < children.size(); i++) { + const auto& child_id = children[i]; + const auto child_bounds = space.get_node_bounds(child_id); + const auto child_mesh = clip_mesh_on_bounds(node.node, child_bounds); + child_nodes[i] = {child_id, std::move(child_mesh)}; + } + return child_nodes; +} + +struct MergeState { + octree::Storage& output; + const octree::Storage& input; + const octree::IndexMap& output_index; + const octree::IndexMap& input_index; +}; + +inline void merge_leaves( + MergeState& state, + const octree::Id& id +) { + LOG_INFO("Merging leaves for id: {}", id); + + assert(state.output_index.is(octree::NodeStatus::Leaf, id)); + assert(state.input_index.is(octree::NodeStatus::Leaf, id)); + const auto output_mesh = state.output.read_node(id).value(); + const auto input_mesh = state.input.read_node(id).value(); + SimpleMesh merged_mesh = merge_meshes( + output_mesh, + input_mesh + ); + state.output.write_node(id, merged_mesh); +} + +inline void merge_with_leaf( + MergeState &state, + const octree::Id &id, + const SimpleMesh &leaf_mesh, + bool leaf_is_output, // true if leaf is from output, false if from input + bool leaf_is_clipped // true if the leaf mesh was generated by clipping +) { + LOG_INFO("Merging leaf from {} for id: {}", + leaf_is_output ? "output" : "input", + id + ); + + if (leaf_is_output) { + if (leaf_is_clipped) { + assert(state.output_index.is_absent(id)); + } else { + assert(state.output_index.is(octree::NodeStatus::Leaf, id)); + } + assert(state.input_index.is(octree::NodeStatus::Virtual, id)); + } else { + if (leaf_is_clipped) { + assert(state.input_index.is_absent(id)); + } else { + assert(state.input_index.is(octree::NodeStatus::Leaf, id)); + } + assert(state.output_index.is(octree::NodeStatus::Virtual, id)); + } + assert(id.has_children()); + + // Split the leaf mesh into children + const auto leaf_children = split_mesh_into_children({id, leaf_mesh}); + assert(leaf_children.has_value()); + + // Merge each child + for (const auto& child : *leaf_children) { + const auto& child_id = child.id; + const auto& child_mesh = child.node; + + // Load other child mesh from the other dataset + const auto other_status_opt = leaf_is_output + ? state.input_index.get(child_id) + : state.output_index.get(child_id); + if (!other_status_opt.has_value()) { + // TODO: dont generate meshes for non-existing input nodes + // If the other child does not exist, we can just write the clipped mesh from the leaf + state.output.write_node(child_id, child_mesh); + continue; + } + const auto other_status = other_status_opt.value(); + assert(other_status != octree::NodeStatus::Inner); + + if (other_status == octree::NodeStatus::Virtual) { + // If the other child is virtual, we recurse further + merge_with_leaf(state, child_id, child_mesh, leaf_is_output, true); + } else if (other_status == octree::NodeStatus::Leaf) { + // If the other child is a leaf, we can merge it directly + SimpleMesh merged_mesh; + if (leaf_is_output) { + // If the leaf is from output, we read from input + const auto other_mesh = state.input.read_node(child_id).value(); + merged_mesh = merge_meshes(child_mesh, other_mesh); + } else { + // If the leaf is from input, we read from output + const auto other_mesh = state.output.read_node(child_id).value(); + merged_mesh = merge_meshes(other_mesh, child_mesh); + } + state.output.write_node(child_id, merged_mesh); + } else { + UNREACHABLE(); + } + } +} + +inline void copy_subtree_to_output( + MergeState& state, + const octree::Id& id +) { + LOG_INFO("Copying subtree to output for id: {}", id); + + assert(state.input.has_node(id)); + assert(!state.output.has_node(id)); + + octree::traverse( + state.input_index, + [&](const octree::Id& child_id, const octree::NodeStatus& status) { + if (status == octree::NodeStatus::Virtual) { + return; + } + assert(status == octree::NodeStatus::Leaf); + + const auto child_mesh = state.input.read_node(child_id).value(); + state.output.write_node(child_id, child_mesh); + }, + [](const octree::Id &) { return true; }, + id + ); +} + +inline void merge_node( + MergeState& state, + const octree::Id& id +) { + LOG_INFO("Merging nodes for id: {}", id); + + const auto output_state_opt = state.output_index.get(id); + const auto input_state_opt = state.input_index.get(id); + + if (!input_state_opt.has_value()) { + // If the input does not have the node, we can skip it + return; + } + if (!output_state_opt.has_value()) { + // If the output does not have the node, we can copy it + copy_subtree_to_output(state, id); + return; + } + + const auto output_status = output_state_opt.value(); + const auto input_status = input_state_opt.value(); + + assert(output_status != octree::NodeStatus::Inner); + assert(input_status != octree::NodeStatus::Inner); + + if (output_status == octree::NodeStatus::Leaf && input_status == octree::NodeStatus::Leaf) { + // If both nodes are leaves, we can merge them directly + merge_leaves(state, id); + } else if (output_status == octree::NodeStatus::Leaf && input_status == octree::NodeStatus::Virtual) { + merge_with_leaf(state, id, state.output.read_node(id).value(), true, false); + } else if (output_status == octree::NodeStatus::Virtual && input_status == octree::NodeStatus::Leaf) { + merge_with_leaf(state, id, state.input.read_node(id).value(), false, false); + } else if (output_status == octree::NodeStatus::Virtual && input_status == octree::NodeStatus::Virtual) { + // If both nodes are virtual, recurse + assert(id.has_children()); + const auto children = id.children().value(); + for (const auto& child_id : children) { + merge_node(state, child_id); + } + } else { + UNREACHABLE(); + } +} + +inline void merge_datasets(octree::Storage& output, const octree::Storage& input) { + const auto& output_index = output.ensure_indexed(); + const auto& input_index = input.ensure_indexed(); + + MergeState state{output, input, output_index, input_index}; + merge_node(state, octree::Id::root()); +} + +inline void merge_datasets(octree::Storage& output, const std::span inputs) { + for (const auto& input : inputs) { + merge_datasets(output, input); + } +} From c1e4b6dded68e416e31e154cc0e95765f2d2cd40 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 4 Jun 2025 14:22:18 +0200 Subject: [PATCH 077/122] Rework Dataset a bit --- src/terrainbuilder/main.cpp | 2 +- src/terrainlib/Dataset.cpp | 69 ++++++-- src/terrainlib/Dataset.h | 31 ++-- src/terrainlib/init.cpp | 27 +++ src/tilebuilder/Dataset.cpp | 205 ---------------------- src/tilebuilder/ParallelTileGenerator.cpp | 2 +- src/tilebuilder/TileHeightsGenerator.cpp | 2 +- 7 files changed, 101 insertions(+), 237 deletions(-) delete mode 100644 src/tilebuilder/Dataset.cpp diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index 6e5f058..fc92a79 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -172,7 +172,7 @@ void batch_build( output_format); const auto dataset_srs = dataset.srs(); - const auto dataset_bounds = dataset.bounds3d(); + const auto dataset_bounds = dataset.bounds3d(true); const auto ecef_srs = srs::ecef(); const auto ecef_bounds = srs::encompassing_bounds_transfer( diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 8477784..d9e97f7 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -32,29 +32,53 @@ #include "log.h" #include "srs.h" -Dataset::Dataset(const std::string &path) { +static GDALDataset *open_gdal_dataset(const std::filesystem::path &path, unsigned int flags) { initialize_gdal_once(); - m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); - if (!m_gdal_dataset) { - LOG_ERROR("Couldn't open dataset {}.\n", path); - throw std::runtime_error(""); + const std::string path_str = path.string(); + return static_cast(GDALOpenEx(path_str.c_str(), flags, nullptr, nullptr, nullptr)); +} + +std::optional Dataset::open_raster(std::filesystem::path path) { + if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_RASTER)) { + return std::optional(Dataset(path, dataset)); + } + LOG_ERROR("Couldn't open raster dataset {}.\n", path); + return std::nullopt; +} +std::optional Dataset::open_vector(std::filesystem::path path) { + if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_VECTOR)) { + return std::optional(Dataset(path, dataset)); + } + LOG_ERROR("Couldn't open vector dataset {}.\n", path); + return std::nullopt; +} +std::optional> Dataset::open_shared_raster(std::filesystem::path path) { + if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_RASTER | GDAL_OF_SHARED | GDAL_OF_THREAD_SAFE)) { + return std::make_shared(Dataset(path, dataset)); + } + LOG_ERROR("Couldn't open shared raster dataset {}.\n", path); + return std::nullopt; +} + +Dataset::Dataset(std::filesystem::path path) { + if (GDALDataset *dataset = open_gdal_dataset(path, 0)) { + m_path = path; + m_gdal_dataset.reset(dataset); + } else { + LOG_ERROR("Failed to open dataset at path: {}\n", path.string()); + throw std::runtime_error("Failed to open dataset at path: " + path.string()); } - m_path = path; - m_name = std::regex_replace(path, std::regex("^.*/"), ""); - m_name = std::regex_replace(m_name, std::regex(R"(\.\w+$)"), ""); } Dataset::Dataset(GDALDataset *dataset) { - initialize_gdal_once(); m_gdal_dataset.reset(dataset); if (!m_gdal_dataset) { LOG_ERROR("Dataset is null.\n"); throw std::runtime_error("Dataset is null."); } } - -DatasetPtr Dataset::make_shared(const std::string &path) { - return std::make_shared(path); +Dataset::Dataset(const std::filesystem::path path, GDALDataset *dataset) : Dataset(dataset) { + m_path = path; } Dataset Dataset::clone() { @@ -66,7 +90,19 @@ Dataset Dataset::clone() { } std::string Dataset::name() const { - return m_name; + if (m_path.has_value()) { + return m_path->filename().string(); + } + if (m_gdal_dataset) { + const char *name = m_gdal_dataset->GetDescription(); + if (name && strlen(name) > 0) { + return std::string(name); + } + else { + return "Anonymous"; + } + } + UNREACHABLE(); } Dataset::~Dataset() = default; @@ -97,8 +133,11 @@ radix::tile::SrsAndHeightBounds Dataset::bounds3d(bool approx_ok) const { const auto band = this->m_gdal_dataset->GetRasterBand(1); glm::dvec2 height_range; - if (!band->GetStatistics(approx_ok, true, &height_range.x, &height_range.y, nullptr, nullptr)) { - throw std::runtime_error("Could not determine dataset height bounds"); + if (!band->GetStatistics(approx_ok, false, &height_range.x, &height_range.y, nullptr, nullptr)) { + const char *unit = band->GetUnitType(); + assert(unit != nullptr); + assert(strcmp(unit, "m") || strcmp(unit, "meters")); + height_range = {-11000.0, 9000.0}; // Mariana Trench and Mount Everest } const auto bounds2d = this->bounds(); diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index c7fba33..74c1c50 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -17,33 +17,37 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef DATASET_H -#define DATASET_H +#pragma once #include #include +#include +#include #include class GDALDataset; class OGRSpatialReference; -class OGRCoordinateTransformation; - -namespace ctb { -class Grid; -} class Dataset; using DatasetPtr = std::shared_ptr; class Dataset { public: - Dataset(const std::string& path); + Dataset(std::filesystem::path path); Dataset(GDALDataset* dataset); // takes over ownership ~Dataset(); - static DatasetPtr make_shared(const std::string &path); + static std::optional open_raster(std::filesystem::path path); + static std::optional open_vector(std::filesystem::path path); + static std::optional> open_shared_raster(std::filesystem::path path); Dataset clone(); + Dataset(Dataset &&) noexcept = default; + Dataset &operator=(Dataset &&) noexcept = default; + + Dataset(const Dataset &) = delete; + Dataset &operator=(const Dataset &) = delete; + [[nodiscard]] std::string name() const; [[nodiscard]] radix::tile::SrsBounds bounds() const; @@ -62,9 +66,8 @@ class Dataset { [[nodiscard]] double pixelHeightIn(const OGRSpatialReference &target_srs) const; private: - std::unique_ptr m_gdal_dataset; - std::optional m_path; - std::string m_name; - }; + Dataset(const std::filesystem::path path, GDALDataset *dataset); -#endif + std::unique_ptr m_gdal_dataset; + std::optional m_path; +}; diff --git a/src/terrainlib/init.cpp b/src/terrainlib/init.cpp index 1e835d7..41514ac 100644 --- a/src/terrainlib/init.cpp +++ b/src/terrainlib/init.cpp @@ -7,9 +7,36 @@ std::once_flag g_gdal_initialized_once_flag; +inline void GdalErrorHandler(CPLErr eErrClass, int err_no, const char *msg) { + spdlog::level::level_enum level; + switch (eErrClass) { + case CE_None: + return; + case CE_Debug: + level = spdlog::level::debug; + break; + case CE_Warning: + level = spdlog::level::warn; + break; + case CE_Failure: + level = spdlog::level::err; + break; + case CE_Fatal: + level = spdlog::level::critical; + break; + default: + level = spdlog::level::err; + LOG_WARN("Unknown GDAL error class: {}", (int)eErrClass); + break; + } + + Log::get_logger().get()->log(level, "GDAL({}): {}", err_no, msg); +} + void initialize_gdal_once() { std::call_once(g_gdal_initialized_once_flag, []() { LOG_DEBUG("calling GDALAllRegister..."); + CPLSetErrorHandler(GdalErrorHandler); GDALAllRegister(); }); } diff --git a/src/tilebuilder/Dataset.cpp b/src/tilebuilder/Dataset.cpp deleted file mode 100644 index a1bd0d4..0000000 --- a/src/tilebuilder/Dataset.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/***************************************************************************** - * Alpine Terrain Builder - * Copyright (C) 2022 alpinemaps.org - * Copyright (C) 2022 Adam Celarek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "Dataset.h" - -#include -#include -#include -#include -#include - -#include - -#include "Exception.h" -#include "ctb/Grid.hpp" -#include "srs.h" -#include "tntn/gdal_init.h" -#include "tntn/logging.h" - -Dataset::Dataset(const std::string& path) -{ - tntn::initialize_gdal_once(); - m_gdal_dataset.reset(static_cast(GDALOpen(path.c_str(), GA_ReadOnly))); - if (!m_gdal_dataset) { - TNTN_LOG_FATAL("Couldn't open dataset {}.\n", path); - throw Exception(""); - } - m_name = std::regex_replace(path, std::regex("^.*/"), ""); - m_name = std::regex_replace(m_name, std::regex(R"(\.\w+$)"), ""); -} - -Dataset::Dataset(GDALDataset* dataset) -{ - tntn::initialize_gdal_once(); - m_gdal_dataset.reset(dataset); - if (!m_gdal_dataset) { - TNTN_LOG_FATAL("Dataset is null.\n"); - throw Exception("Dataset is null."); - } -} - -DatasetPtr Dataset::make_shared(const std::string& path) -{ - return std::make_shared(path); -} - -std::string Dataset::name() const -{ - return m_name; -} - -Dataset::~Dataset() = default; - -radix::tile::SrsBounds Dataset::bounds() const -{ - std::array adfGeoTransform = {}; - if (m_gdal_dataset->GetGeoTransform(adfGeoTransform.data()) != CE_None) - throw Exception("Could not get transformation information from source dataset"); - - // https://gdal.org/user/raster_data_model.html - // gdal has a row/column raster format, where row 0 is the top most row. - // an affine transform is used to convert row/column into the datasets SRS. - // computing bounds is going first from row/column to dataset SRS and then to target SRS - - // we don't support sheering or rotation for now - if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) - throw Exception("Dataset geo transform contains sheering or rotation. This is not supported!"); - - const double westX = adfGeoTransform[0]; - const double southY = adfGeoTransform[3] + (heightInPixels() * adfGeoTransform[5]); - - const double eastX = adfGeoTransform[0] + (widthInPixels() * adfGeoTransform[1]); - const double northY = adfGeoTransform[3]; - return { {westX, southY}, {eastX, northY} }; -} - -radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference& targetSrs) const -{ - const auto l_bounds = bounds(); - const auto west = l_bounds.min.x; - const auto east = l_bounds.max.x; - const auto north = l_bounds.max.y; - const auto south = l_bounds.min.y; - - - const auto data_srs = srs(); - if (targetSrs.IsSame(&data_srs)) - return l_bounds; - - // We need to transform the bounds to the target SRS - // this might involve warping, i.e. some of the edges can be arcs. - // therefore we want to walk the perimiter and get min/max from there. - // a resolution of 2000 samples per border should give a good enough approximation. - - // hey, check out inline virtual int TransformBounds(const double xmin, const double ymin, const double xmax, const double ymax, double *out_xmin, double *out_ymin, double *out_xmax, double *out_ymax, const int densify_pts) - std::vector x; - std::vector y; - auto addCoordinate = [&](double xv, double yv) { x.emplace_back(xv); y.emplace_back(yv); }; - - const auto deltaX = l_bounds.width() / 2000.0; - if (deltaX <= 0.0) - throw Exception("west coordinate > east coordinate. This is not supported."); - for (double s = west; s < east; s += deltaX) { - addCoordinate(s, south); - addCoordinate(s, north); - } - const auto deltaY = (north - south) / 2000.0; - if (deltaY <= 0.0) - throw Exception("south coordinate > north coordinate. This is not supported."); - for (double s = south; s < north; s += deltaY) { - addCoordinate(west, s); - addCoordinate(east, s); - } - // don't wanna miss out the max/max edge vertex - addCoordinate(east, north); - - const auto transformer = srs::transformation(srs(), targetSrs); - if (!transformer->Transform(int(x.size()), x.data(), y.data())) { - throw std::string("Could not transform dataset bounds to target SRS"); - } - - assert(!x.empty()); - assert(!y.empty()); - const double target_minX = *std::min_element(x.begin(), x.end()); - const double target_maxX = *std::max_element(x.begin(), x.end()); - const double target_minY = *std::min_element(y.begin(), y.end()); - const double target_maxY = *std::max_element(y.begin(), y.end()); - return { {target_minX, target_minY}, {target_maxX, target_maxY} }; -} - -OGRSpatialReference Dataset::srs() const -{ - const char* srcWKT = m_gdal_dataset->GetProjectionRef(); - if (!strlen(srcWKT)) - throw Exception("The source dataset does not have a spatial reference system assigned"); - auto srs = OGRSpatialReference(srcWKT); - srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - return srs; -} - -unsigned Dataset::widthInPixels() const -{ - return ctb::i_pixel(m_gdal_dataset->GetRasterXSize()); -} - -unsigned Dataset::heightInPixels() const -{ - return ctb::i_pixel(m_gdal_dataset->GetRasterYSize()); -} - -double Dataset::widthInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const -{ - return bounds.width() / pixelWidthIn(bounds_srs); -} - -double Dataset::heightInPixels(const radix::tile::SrsBounds& bounds, const OGRSpatialReference& bounds_srs) const -{ - return bounds.height() / pixelHeightIn(bounds_srs); -} - -unsigned Dataset::n_bands() const -{ - const auto n = m_gdal_dataset->GetRasterCount(); - assert(n >= 0); - return unsigned(n); -} - -GDALDataset* Dataset::gdalDataset() -{ - return m_gdal_dataset.get(); -} - -double Dataset::gridResolution(const OGRSpatialReference& target_srs) const -{ - return std::min(pixelWidthIn(target_srs), pixelHeightIn(target_srs)); -} - -double Dataset::pixelWidthIn(const OGRSpatialReference& target_srs) const -{ - const auto b0 = bounds(); - const auto b1 = srs::nonExactBoundsTransform(b0, srs(), target_srs); - return b1.width() / widthInPixels(); -} - -double Dataset::pixelHeightIn(const OGRSpatialReference& target_srs) const -{ - const auto b = srs::nonExactBoundsTransform(bounds(), srs(), target_srs); - return b.height() / heightInPixels(); -} diff --git a/src/tilebuilder/ParallelTileGenerator.cpp b/src/tilebuilder/ParallelTileGenerator.cpp index 3a8ed6c..a268518 100644 --- a/src/tilebuilder/ParallelTileGenerator.cpp +++ b/src/tilebuilder/ParallelTileGenerator.cpp @@ -46,7 +46,7 @@ ParallelTileGenerator ParallelTileGenerator::make(const std::string& input_data_ const std::string& output_data_path, unsigned grid_resolution) { - const auto dataset = Dataset::make_shared(input_data_path); + const auto dataset = std::make_shared(std::filesystem::path(input_data_path)); ctb::Grid grid = ctb::GlobalGeodetic(grid_resolution); if (srs == ctb::Grid::Srs::SphericalMercator) grid = ctb::GlobalMercator(grid_resolution); diff --git a/src/tilebuilder/TileHeightsGenerator.cpp b/src/tilebuilder/TileHeightsGenerator.cpp index 0b577f6..6c816dd 100644 --- a/src/tilebuilder/TileHeightsGenerator.cpp +++ b/src/tilebuilder/TileHeightsGenerator.cpp @@ -44,7 +44,7 @@ void TileHeightsGenerator::run(unsigned max_zoom_level) const std::pair min_max = std::make_pair(0, 9000); }; - const auto dataset = Dataset::make_shared(m_input_data_path); + const auto dataset = std::make_shared(std::filesystem::path(m_input_data_path)); ctb::Grid grid = ctb::GlobalGeodetic(64); if (m_srs == ctb::Grid::Srs::SphericalMercator) From d021ec17736da81c7b30929a4361541aa7dcdf15 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 4 Jun 2025 22:06:23 +0200 Subject: [PATCH 078/122] Move cgal defs to terrainlib --- src/CMakeLists.txt | 6 ++--- .../mesh}/cgal.h | 3 +++ .../mesh}/convert.cpp | 17 +++++--------- src/terrainlib/mesh/convert.h | 19 ++++++++++++++++ src/terrainlib/mesh/utils.cpp | 1 + src/terrainsimplify/convert.h | 22 ------------------- src/terrainsimplify/merge.cpp | 2 +- src/terrainsimplify/pch.h | 2 +- src/terrainsimplify/uv_map.cpp | 2 +- unittests/CMakeLists.txt | 2 +- .../convert.cpp | 2 +- 11 files changed, 36 insertions(+), 42 deletions(-) rename src/{terrainsimplify => terrainlib/mesh}/cgal.h (96%) rename src/{terrainsimplify => terrainlib/mesh}/convert.cpp (84%) create mode 100644 src/terrainlib/mesh/convert.h delete mode 100644 src/terrainsimplify/convert.h rename unittests/{terrainsimplify => terrainlib}/convert.cpp (97%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ffd157..94c64e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,6 +112,9 @@ add_library(terrainlib terrainlib/mesh/io/texture.h terrainlib/mesh/io/texture.cpp terrainlib/mesh/io/utils.h terrainlib/mesh/io/utils.cpp + terrainlib/mesh/cgal.h + terrainlib/mesh/convert.h + terrainlib/mesh/convert.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp terrainlib/mesh/SimpleMesh.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp @@ -209,9 +212,6 @@ add_library(terrainsimplifylib terrainsimplify/simplify.cpp terrainsimplify/uv_map.h terrainsimplify/uv_map.cpp - terrainsimplify/cgal.h - terrainsimplify/convert.h - terrainsimplify/convert.cpp terrainsimplify/validate.h ) target_include_directories(terrainsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainsimplify) diff --git a/src/terrainsimplify/cgal.h b/src/terrainlib/mesh/cgal.h similarity index 96% rename from src/terrainsimplify/cgal.h rename to src/terrainlib/mesh/cgal.h index d66bcc0..5a76b2d 100644 --- a/src/terrainsimplify/cgal.h +++ b/src/terrainlib/mesh/cgal.h @@ -5,6 +5,7 @@ #include #include +namespace cgal { #define DEFINE_KERNEL(K) \ using Kernel = K; \ using Point2 = Kernel::Point_2; \ @@ -32,3 +33,5 @@ namespace simple { DEFINE_KERNEL(CGAL::Exact_predicates_inexact_constructions_kernel) #undef DEFINE_KERNEL + +} // namespace cgal diff --git a/src/terrainsimplify/convert.cpp b/src/terrainlib/mesh/convert.cpp similarity index 84% rename from src/terrainsimplify/convert.cpp rename to src/terrainlib/mesh/convert.cpp index 6e99bde..5b68934 100644 --- a/src/terrainsimplify/convert.cpp +++ b/src/terrainlib/mesh/convert.cpp @@ -1,7 +1,8 @@ #include "convert.h" #include "log.h" -#include "validate.h" - + +using namespace cgal; + glm::dvec3 convert::cgal2glm(Point3 point) { return glm::dvec3(CGAL::to_double(point[0]), CGAL::to_double(point[1]), CGAL::to_double(point[2])); } @@ -15,7 +16,7 @@ Point2 convert::glm2cgal(glm::dvec2 point) { return Point2(point[0], point[1]); } -SurfaceMesh convert::mesh2cgal(const SimpleMesh &mesh) { +SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { SurfaceMesh cgal_mesh; for (const glm::dvec3 &position : mesh.positions) { @@ -34,7 +35,7 @@ SurfaceMesh convert::mesh2cgal(const SimpleMesh &mesh) { return cgal_mesh; } -SimpleMesh convert::cgal2mesh(const SurfaceMesh &cgal_mesh) { +SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { SimpleMesh mesh; const size_t vertex_count = CGAL::num_vertices(cgal_mesh); @@ -59,11 +60,3 @@ SimpleMesh convert::cgal2mesh(const SurfaceMesh &cgal_mesh) { return mesh; } - -glm::uvec2 convert::cv2glm(const cv::Size size) { - return glm::uvec2(size.width, size.height); -} - -cv::Size convert::glm2cv(const glm::uvec2 size) { - return cv::Size(size.x, size.y); -} diff --git a/src/terrainlib/mesh/convert.h b/src/terrainlib/mesh/convert.h new file mode 100644 index 0000000..a4fc255 --- /dev/null +++ b/src/terrainlib/mesh/convert.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "cgal.h" +#include "mesh/SimpleMesh.h" + +namespace convert { + +glm::dvec3 cgal2glm(cgal::Point3 point); +glm::dvec2 cgal2glm(cgal::Point2 point); + +cgal::Point3 glm2cgal(glm::dvec3 point); +cgal::Point2 glm2cgal(glm::dvec2 point); + +cgal::SurfaceMesh to_cgal_mesh(const SimpleMesh& mesh); +SimpleMesh to_simple_mesh(const cgal::SurfaceMesh& cgal_mesh); + +} diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index bf37b10..d98d436 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -527,3 +527,4 @@ SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aa // TODO: derive new_positions from seen_vertices return reindex_mesh(SimpleMesh(new_triangles, new_positions)); } + diff --git a/src/terrainsimplify/convert.h b/src/terrainsimplify/convert.h deleted file mode 100644 index 0a69cf1..0000000 --- a/src/terrainsimplify/convert.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CONVERT_H -#define CONVERT_H - -#include "pch.h" - -namespace convert { - -glm::dvec3 cgal2glm(Point3 point); -glm::dvec2 cgal2glm(Point2 point); - -Point3 glm2cgal(glm::dvec3 point); -Point2 glm2cgal(glm::dvec2 point); - -SurfaceMesh mesh2cgal(const SimpleMesh& mesh); -SimpleMesh cgal2mesh(const SurfaceMesh& cgal_mesh); - -glm::uvec2 cv2glm(const cv::Size size); -cv::Size glm2cv(const glm::uvec2 size); - -} - -#endif diff --git a/src/terrainsimplify/merge.cpp b/src/terrainsimplify/merge.cpp index cccbea8..5937635 100644 --- a/src/terrainsimplify/merge.cpp +++ b/src/terrainsimplify/merge.cpp @@ -1,7 +1,7 @@ #include #include -#include "convert.h" +#include "mesh/convert.h" #include "log.h" #include "merge.h" #include "mesh/SimpleMesh.h" diff --git a/src/terrainsimplify/pch.h b/src/terrainsimplify/pch.h index 43119b2..b5f1bd6 100644 --- a/src/terrainsimplify/pch.h +++ b/src/terrainsimplify/pch.h @@ -12,5 +12,5 @@ #include #include -#include "cgal.h" +#include "mesh/cgal.h" #include "mesh/SimpleMesh.h" diff --git a/src/terrainsimplify/uv_map.cpp b/src/terrainsimplify/uv_map.cpp index 8279107..d59231f 100644 --- a/src/terrainsimplify/uv_map.cpp +++ b/src/terrainsimplify/uv_map.cpp @@ -9,7 +9,7 @@ #include #include -#include "convert.h" +#include "mesh/convert.h" #include "merge.h" #include "uv_map.h" diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 37ead07..d430592 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -30,6 +30,7 @@ endif() add_executable(unittests_terrainlib catch2_helpers.h + terrainlib/convert.cpp terrainlib/dataset.cpp terrainlib/grid.cpp terrainlib/progress_indicator_test.cpp @@ -60,7 +61,6 @@ target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2 add_executable(unittests_terrainsimplify catch2_helpers.h - terrainsimplify/convert.cpp terrainsimplify/merge.cpp ) diff --git a/unittests/terrainsimplify/convert.cpp b/unittests/terrainlib/convert.cpp similarity index 97% rename from unittests/terrainsimplify/convert.cpp rename to unittests/terrainlib/convert.cpp index 9360a51..fe8c63e 100644 --- a/unittests/terrainsimplify/convert.cpp +++ b/unittests/terrainlib/convert.cpp @@ -2,7 +2,7 @@ #include #include "mesh/io.h" #include "mesh/utils.h" -#include "convert.h" +#include "mesh/convert.h" #include "cgal.h" TEST_CASE("convert rountrip keeps precision") { From 4a5e3f019fc03fc1a44a8ac6e9c65c5a1e12a785 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 7 Jun 2025 17:53:03 +0200 Subject: [PATCH 079/122] Fix: Add cgal as terrainlib dep --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94c64e0..d5deb1f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,7 +142,7 @@ add_library(terrainlib terrainlib/string_utils.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) From f82b02b3f4eafa673268f2c7c26ef093fd8c6994 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 7 Jun 2025 17:54:38 +0200 Subject: [PATCH 080/122] Fix: warning in terrainlib unittest --- unittests/terrainlib/octree_space.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unittests/terrainlib/octree_space.cpp b/unittests/terrainlib/octree_space.cpp index b795b12..a944247 100644 --- a/unittests/terrainlib/octree_space.cpp +++ b/unittests/terrainlib/octree_space.cpp @@ -75,7 +75,9 @@ TEST_CASE("find_smallest_node_encompassing_bounds returns smallest valid node", } // Now check that no child of this node fully contains the target - for (const auto &child_id : id.children().value()) { + REQUIRE(id.has_children()); + const auto children = id.children().value(); + for (const auto &child_id : children) { Bounds child_bounds = space.get_node_bounds(child_id); bool all_corners_inside = true; for (const auto &corner : radix::geometry::corners(target)) { From 564fa44d8029eec259c407046dc7b925770883f1 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 7 Jun 2025 18:00:07 +0200 Subject: [PATCH 081/122] Fix: terrainlib unittests and impl --- src/terrainlib/Dataset.cpp | 2 +- src/terrainlib/octree/traverse.h | 2 +- unittests/terrainlib/convert.cpp | 6 +++--- unittests/terrainlib/index_traverse.cpp | 25 +++++++++++-------------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index d9e97f7..2145a6c 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -91,7 +91,7 @@ Dataset Dataset::clone() { std::string Dataset::name() const { if (m_path.has_value()) { - return m_path->filename().string(); + return m_path->stem().string(); } if (m_gdal_dataset) { const char *name = m_gdal_dataset->GetDescription(); diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index 967c79a..d513caf 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -56,7 +56,7 @@ void traverse( auto current_status_opt = index.get(current); if (!current_status_opt) { - return; + continue; } const auto current_status = current_status_opt.value(); diff --git a/unittests/terrainlib/convert.cpp b/unittests/terrainlib/convert.cpp index fe8c63e..3ae2940 100644 --- a/unittests/terrainlib/convert.cpp +++ b/unittests/terrainlib/convert.cpp @@ -3,7 +3,7 @@ #include "mesh/io.h" #include "mesh/utils.h" #include "mesh/convert.h" -#include "cgal.h" +#include "mesh/cgal.h" TEST_CASE("convert rountrip keeps precision") { SimpleMesh mesh; @@ -17,8 +17,8 @@ TEST_CASE("convert rountrip keeps precision") { mesh.triangles.push_back(glm::uvec3(0, 2, 1)); - const SurfaceMesh cgal_mesh = convert::mesh2cgal(mesh); - SimpleMesh roundtrip_mesh = convert::cgal2mesh(cgal_mesh); + const cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); + SimpleMesh roundtrip_mesh = convert::to_simple_mesh(cgal_mesh); sort_and_normalize_triangles(mesh.triangles); sort_and_normalize_triangles(roundtrip_mesh.triangles); diff --git a/unittests/terrainlib/index_traverse.cpp b/unittests/terrainlib/index_traverse.cpp index 2384c18..d81f365 100644 --- a/unittests/terrainlib/index_traverse.cpp +++ b/unittests/terrainlib/index_traverse.cpp @@ -24,13 +24,12 @@ TEST_CASE("octree::traverse basic") { std::vector visited; traverse( index, - [&](const Id& id) { + [&](const Id &id, const NodeStatus &) { visited.push_back(id); }, - [](const Id&) { return true; }, // refine always + [](const Id &) { return true; }, // refine always root, - TraversalOrder::DepthFirst - ); + TraversalOrder::DepthFirst); CHECK(visited.front() == root); CHECK(visited.size() == 9); // root + 8 children @@ -43,13 +42,12 @@ TEST_CASE("octree::traverse basic") { std::vector visited; traverse( index, - [&](const Id& id) { + [&](const Id &id, const NodeStatus &) { visited.push_back(id); }, - [](const Id&) { return false; }, // don't refine + [](const Id &) { return false; }, // don't refine root, - TraversalOrder::DepthFirst - ); + TraversalOrder::DepthFirst); CHECK(visited.size() == 1); CHECK(visited.front() == root); @@ -61,7 +59,7 @@ TEST_CASE("octree::traverse basic") { traverse( empty, - [&](const Id&) { + [&](const Id&, const NodeStatus&) { visited = true; }, [](const Id&) { return true; }, @@ -99,7 +97,7 @@ TEST_CASE("octree::traverse with depth") { std::vector visited; traverse( index, - [&](const Id& id) { + [&](const Id& id, const NodeStatus&) { visited.push_back(id); }, [](const Id&) { return true; }, @@ -118,13 +116,12 @@ TEST_CASE("octree::traverse with depth") { std::vector visited; traverse( index, - [&](const Id& id) { + [&](const Id &id, const NodeStatus &) { visited.push_back(id); }, - [](const Id&) { return true; }, + [](const Id &) { return true; }, root, - TraversalOrder::BreadthFirst - ); + TraversalOrder::BreadthFirst); REQUIRE(visited.size() == 6); From 4d340bb3e2f58a1456ecc27742f79586433fdba9 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 7 Jun 2025 19:20:14 +0200 Subject: [PATCH 082/122] Fix unittests --- unittests/CMakeLists.txt | 1 + unittests/catch2_helpers.h | 28 +++------------------------- unittests/terrainlib/convert.cpp | 9 +++++++-- unittests/terrainlib/dataset.cpp | 28 +++++++++++----------------- unittests/terrainlib/grid.cpp | 11 ++++------- unittests/terrainlib/index_map.cpp | 1 - 6 files changed, 26 insertions(+), 52 deletions(-) diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index d430592..749aba2 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -6,6 +6,7 @@ option(ATB_UNITTESTS_EXTENDED "perform extended unit tests (they take long)" OFF option(ATB_UNITTESTS_DEBUG_IMAGES "output debug height images for visual comparison" OFF) set(ATB_UNITTESTS_AUSTRIA_HIGHRES CACHE FILEPATH "path to the high res austrian dataset (terrain model, i.e., OeRect_01m_gt_31287.img)") +add_compile_definitions(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) if (NOT TARGET Catch2) alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.5.1) endif() diff --git a/unittests/catch2_helpers.h b/unittests/catch2_helpers.h index 819b0a0..d75a274 100644 --- a/unittests/catch2_helpers.h +++ b/unittests/catch2_helpers.h @@ -19,38 +19,16 @@ #pragma once -#include - +#include #include -#include +#include #include -#include "octree/NodeStatus.h" - namespace Catch { template struct StringMaker> { - static std::string convert(const glm::vec& value) { + static std::string convert(const glm::vec &value) { return glm::to_string(value); } }; - -template<> -struct StringMaker { - static std::string convert(const octree::NodeStatus& status) { - return status.to_string(); - } -}; - -template -struct StringMaker> { - static std::string convert(const std::optional& opt) { - if (opt.has_value()) { - return StringMaker>>::convert(opt.value()); - } else { - return "nullopt"; - } - } -}; - } diff --git a/unittests/terrainlib/convert.cpp b/unittests/terrainlib/convert.cpp index 3ae2940..8a8348e 100644 --- a/unittests/terrainlib/convert.cpp +++ b/unittests/terrainlib/convert.cpp @@ -1,6 +1,11 @@ -#include +#include "../catch2_helpers.h" + +#include + #include -#include "mesh/io.h" +#include + +#include "mesh/SimpleMesh.h" #include "mesh/utils.h" #include "mesh/convert.h" #include "mesh/cgal.h" diff --git a/unittests/terrainlib/dataset.cpp b/unittests/terrainlib/dataset.cpp index 067b8e1..f536c7f 100644 --- a/unittests/terrainlib/dataset.cpp +++ b/unittests/terrainlib/dataset.cpp @@ -17,8 +17,9 @@ * along with this program. If not, see . *****************************************************************************/ +#include "../catch2_helpers.h" + #include -#include #include "Dataset.h" #include "ctb/GlobalGeodetic.hpp" @@ -29,8 +30,7 @@ using namespace radix; using Catch::Approx; -void checkBounds(const radix::tile::SrsBounds& a, const radix::tile::SrsBounds& b) -{ +void checkBounds(const radix::tile::SrsBounds &a, const radix::tile::SrsBounds &b) { REQUIRE(a.height() > 0); REQUIRE(a.width() > 0); REQUIRE(b.height() > 0); @@ -43,8 +43,7 @@ void checkBounds(const radix::tile::SrsBounds& a, const radix::tile::SrsBounds& REQUIRE(widthErrorIn < 0.001); } -TEST_CASE("datasets are as expected") -{ +TEST_CASE("datasets are as expected") { auto d_mgi = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); auto d_wgs84 = Dataset(ATB_TEST_DATA_DIR "/austria/at_wgs84.tif"); @@ -56,22 +55,19 @@ TEST_CASE("datasets are as expected") wgs84.importFromEPSG(4326); wgs84.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); - SECTION("file name") - { + SECTION("file name") { CHECK(d_mgi.name() == "at_mgi"); CHECK(d_wgs84.name() == "at_wgs84"); } - SECTION("SRS") - { + SECTION("SRS") { REQUIRE_FALSE(d_mgi.srs().IsEmpty()); REQUIRE_FALSE(d_wgs84.srs().IsEmpty()); const auto wgs84 = d_wgs84.srs(); REQUIRE_FALSE(d_mgi.srs().IsSame(&wgs84)); } - SECTION("bounds") - { + SECTION("bounds") { { // fmt::print("webmercator: \n"); checkBounds(d_mgi.bounds(webmercator), d_wgs84.bounds(webmercator)); @@ -88,8 +84,7 @@ TEST_CASE("datasets are as expected") // checkBounds(d_mgi.bounds(d_mgi.srs()), d_wgs84.bounds(d_mgi.srs())); // } } - SECTION("resolution") - { + SECTION("resolution") { CHECK(d_mgi.widthInPixels() == 620); CHECK(d_mgi.heightInPixels() == 350); CHECK(d_mgi.n_bands() == 1); @@ -111,8 +106,7 @@ TEST_CASE("datasets are as expected") } } -TEST_CASE("bbox width pixels") -{ +TEST_CASE("bbox width pixels") { auto d_mgi = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); auto d_wgs84 = Dataset(ATB_TEST_DATA_DIR "/austria/at_wgs84.tif"); @@ -128,8 +122,8 @@ TEST_CASE("bbox width pixels") auto adjust_bounds = [](auto bounds) { const auto unadjusted_width = bounds.width(); const auto unadjusted_height = bounds.height(); - bounds.min += glm::dvec2{ unadjusted_width * 0.2, unadjusted_height * 0.3 }; - bounds.max -= glm::dvec2{ unadjusted_width * 0.1, unadjusted_height * 0.2 }; + bounds.min += glm::dvec2{unadjusted_width * 0.2, unadjusted_height * 0.3}; + bounds.max -= glm::dvec2{unadjusted_width * 0.1, unadjusted_height * 0.2}; return bounds; }; diff --git a/unittests/terrainlib/grid.cpp b/unittests/terrainlib/grid.cpp index bf24a35..d8df7af 100644 --- a/unittests/terrainlib/grid.cpp +++ b/unittests/terrainlib/grid.cpp @@ -17,8 +17,8 @@ * along with this program. If not, see . *****************************************************************************/ -#include #include +#include #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" @@ -30,10 +30,8 @@ using Catch::Approx; -TEST_CASE("grid") -{ - SECTION("epsg codes") - { +TEST_CASE("grid") { + SECTION("epsg codes") { const auto geodetic = ctb::GlobalGeodetic(256); CHECK(geodetic.getEpsgCode() == 4326); @@ -43,8 +41,7 @@ TEST_CASE("grid") CHECK(!geodetic.getSRS().IsSame(&webmercator.getSRS())); } - SECTION("bounds") - { + SECTION("bounds") { const auto geodetic = ctb::GlobalGeodetic(256); CHECK(geodetic.getExtent().min.x == Approx(-180.0)); CHECK(geodetic.getExtent().max.x == Approx(180.0)); diff --git a/unittests/terrainlib/index_map.cpp b/unittests/terrainlib/index_map.cpp index 92308d8..5d595c2 100644 --- a/unittests/terrainlib/index_map.cpp +++ b/unittests/terrainlib/index_map.cpp @@ -4,7 +4,6 @@ using namespace octree; - TEST_CASE("IndexMap basic operations") { IndexMap index; From 9ee12ef9635c3a6877cb592c780e1fb39668d990 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 7 Jun 2025 19:20:28 +0200 Subject: [PATCH 083/122] Update Catch2 to 3.8.1 --- unittests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 749aba2..e407b36 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -8,7 +8,7 @@ set(ATB_UNITTESTS_AUSTRIA_HIGHRES CACHE FILEPATH "path to the high res austrian add_compile_definitions(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) if (NOT TARGET Catch2) - alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.5.1) + alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.8.1) endif() From 84a365dd98a4f028d8ba94aec03aaf41d5524e93 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 13 Jun 2025 12:05:19 +0200 Subject: [PATCH 084/122] Move mat_equals to helper header --- unittests/CMakeLists.txt | 2 ++ unittests/opencv_helpers.h | 27 ++++++++++++++ unittests/terrainlib/mesh_io.cpp | 61 ++++++++++---------------------- 3 files changed, 48 insertions(+), 42 deletions(-) create mode 100644 unittests/opencv_helpers.h diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index e407b36..39a2d49 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -31,6 +31,8 @@ endif() add_executable(unittests_terrainlib catch2_helpers.h + opencv_helpers.h + terrainlib/convert.cpp terrainlib/dataset.cpp terrainlib/grid.cpp diff --git a/unittests/opencv_helpers.h b/unittests/opencv_helpers.h new file mode 100644 index 0000000..ccb0bc4 --- /dev/null +++ b/unittests/opencv_helpers.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +// modified from https://stackoverflow.com/a/32440830/6304917 +inline bool mat_equals(const cv::Mat mat1, const cv::Mat mat2) { + if (mat1.dims != mat2.dims || + mat1.size != mat2.size || + mat1.elemSize() != mat2.elemSize()) { + return false; + } + + if (mat1.isContinuous() && mat2.isContinuous()) { + return std::memcmp(mat1.ptr(), mat2.ptr(), mat1.total() * mat1.elemSize()) == 0; + } else { + const cv::Mat *arrays[] = {&mat1, &mat2, 0}; + uchar *ptrs[2]; + cv::NAryMatIterator it(arrays, ptrs, 2); + for (unsigned int p = 0; p < it.nplanes; p++, ++it) { + if (memcmp(it.ptrs[0], it.ptrs[1], it.size * mat1.elemSize()) != 0) { + return false; + } + } + + return true; + } +} diff --git a/unittests/terrainlib/mesh_io.cpp b/unittests/terrainlib/mesh_io.cpp index 4670f13..29f276c 100644 --- a/unittests/terrainlib/mesh_io.cpp +++ b/unittests/terrainlib/mesh_io.cpp @@ -21,32 +21,9 @@ #include #include "../catch2_helpers.h" +#include "../opencv_helpers.h" #include "mesh/io.h" -// modified from https://stackoverflow.com/a/32440830/6304917 -bool mat_equals(const cv::Mat mat1, const cv::Mat mat2) { - if (mat1.dims != mat2.dims || - mat1.size != mat2.size || - mat1.elemSize() != mat2.elemSize()) { - return false; - } - - if (mat1.isContinuous() && mat2.isContinuous()) { - return std::memcmp(mat1.ptr(), mat2.ptr(), mat1.total() * mat1.elemSize()) == 0; - } else { - const cv::Mat *arrays[] = {&mat1, &mat2, 0}; - uchar *ptrs[2]; - cv::NAryMatIterator it(arrays, ptrs, 2); - for (unsigned int p = 0; p < it.nplanes; p++, ++it) { - if (memcmp(it.ptrs[0], it.ptrs[1], it.size * mat1.elemSize()) != 0) { - return false; - } - } - - return true; - } -} - TEST_CASE("io roundtrip") { for (const auto& format : {"glb", "gltf"}) { DYNAMIC_SECTION(format) { @@ -81,11 +58,11 @@ TEST_CASE("io roundtrip") { } std::filesystem::remove(mesh_path); const SimpleMesh roundtrip_mesh = result.value(); - REQUIRE(roundtrip_mesh.positions == mesh.positions); - REQUIRE(roundtrip_mesh.uvs == mesh.uvs); - REQUIRE(roundtrip_mesh.triangles == mesh.triangles); - REQUIRE(roundtrip_mesh.texture.has_value()); - REQUIRE(mat_equals(*roundtrip_mesh.texture, *mesh.texture)); + CHECK(roundtrip_mesh.positions == mesh.positions); + CHECK(roundtrip_mesh.uvs == mesh.uvs); + CHECK(roundtrip_mesh.triangles == mesh.triangles); + CHECK(roundtrip_mesh.texture.has_value()); + CHECK(mat_equals(*roundtrip_mesh.texture, *mesh.texture)); } } } @@ -124,11 +101,11 @@ TEST_CASE("io roundtrip high precision") { } std::filesystem::remove(mesh_path); const SimpleMesh roundtrip_mesh = result.value(); - REQUIRE(roundtrip_mesh.positions == mesh.positions); - REQUIRE(roundtrip_mesh.uvs == mesh.uvs); - REQUIRE(roundtrip_mesh.triangles == mesh.triangles); - REQUIRE(roundtrip_mesh.texture.has_value()); - REQUIRE(mat_equals(*roundtrip_mesh.texture, *mesh.texture)); + CHECK(roundtrip_mesh.positions == mesh.positions); + CHECK(roundtrip_mesh.uvs == mesh.uvs); + CHECK(roundtrip_mesh.triangles == mesh.triangles); + CHECK(roundtrip_mesh.texture.has_value()); + CHECK(mat_equals(*roundtrip_mesh.texture, *mesh.texture)); } } } @@ -167,10 +144,10 @@ TEST_CASE("io roundtrip no texture") { } // std::filesystem::remove(mesh_path); const SimpleMesh roundtrip_mesh = result.value(); - REQUIRE(roundtrip_mesh.positions == mesh.positions); - REQUIRE(roundtrip_mesh.uvs == mesh.uvs); - REQUIRE(roundtrip_mesh.triangles == mesh.triangles); - REQUIRE(!roundtrip_mesh.texture.has_value()); + CHECK(roundtrip_mesh.positions == mesh.positions); + CHECK(roundtrip_mesh.uvs == mesh.uvs); + CHECK(roundtrip_mesh.triangles == mesh.triangles); + CHECK(!roundtrip_mesh.texture.has_value()); } } } @@ -204,10 +181,10 @@ TEST_CASE("io roundtrip no texture and uvs") { } std::filesystem::remove(mesh_path); const SimpleMesh roundtrip_mesh = result.value(); - REQUIRE(roundtrip_mesh.positions == mesh.positions); - REQUIRE(!roundtrip_mesh.has_uvs()); - REQUIRE(roundtrip_mesh.triangles == mesh.triangles); - REQUIRE(!roundtrip_mesh.texture.has_value()); + CHECK(roundtrip_mesh.positions == mesh.positions); + CHECK(!roundtrip_mesh.has_uvs()); + CHECK(roundtrip_mesh.triangles == mesh.triangles); + CHECK(!roundtrip_mesh.texture.has_value()); } } } From 205fe3f15c124f05b705c30b32ac540f98891733 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 13 Jun 2025 12:06:57 +0200 Subject: [PATCH 085/122] Speed up and fix mesh clipping --- .gitignore | 1 + src/CMakeLists.txt | 2 + src/terrainlib/hash_utils.h | 2 + src/terrainlib/log.h | 4 +- src/terrainlib/{log_path.h => log_impls.h} | 13 + src/terrainlib/mesh/SimpleMesh.h | 2 +- src/terrainlib/mesh/TriangleSoup.h | 69 +++++ src/terrainlib/mesh/clip.cpp | 314 +++++++++++++++++++++ src/terrainlib/mesh/clip.h | 10 + src/terrainlib/mesh/io/gltf.cpp | 1 + src/terrainlib/mesh/utils.cpp | 291 +++++++++---------- src/terrainlib/mesh/utils.h | 1 + unittests/CMakeLists.txt | 2 + unittests/catch2_helpers.h | 21 +- unittests/terrainlib/mesh_clip.cpp | 312 ++++++++++++++++++++ unittests/terrainlib/mesh_utils.cpp | 84 ++++++ 16 files changed, 963 insertions(+), 166 deletions(-) rename src/terrainlib/{log_path.h => log_impls.h} (52%) create mode 100644 src/terrainlib/mesh/TriangleSoup.h create mode 100644 src/terrainlib/mesh/clip.cpp create mode 100644 src/terrainlib/mesh/clip.h create mode 100644 unittests/terrainlib/mesh_clip.cpp create mode 100644 unittests/terrainlib/mesh_utils.cpp diff --git a/.gitignore b/.gitignore index 4cfb18f..b6efe32 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.tif *.tif.aux.xml +*.terrain /CMakeLists.txt.user build/ .vscode diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5deb1f..d29e8b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,10 +113,12 @@ add_library(terrainlib terrainlib/mesh/io/utils.h terrainlib/mesh/io/utils.cpp terrainlib/mesh/cgal.h + terrainlib/mesh/clip.h terrainlib/mesh/clip.cpp terrainlib/mesh/convert.h terrainlib/mesh/convert.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp terrainlib/mesh/SimpleMesh.h + terrainlib/mesh/TriangleSoup.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp terrainlib/octree/disk/layout/strategy/Flat.h diff --git a/src/terrainlib/hash_utils.h b/src/terrainlib/hash_utils.h index 400b44b..8f7866d 100644 --- a/src/terrainlib/hash_utils.h +++ b/src/terrainlib/hash_utils.h @@ -1,3 +1,5 @@ +#pragma once + namespace { // from https://github.com/boostorg/container_hash/blob/ee5285bfa64843a11e29700298c83a37e3132fcd/include/boost/container_hash/detail/hash_mix.hpp#L17 template diff --git a/src/terrainlib/log.h b/src/terrainlib/log.h index 1f30ab3..3d80488 100644 --- a/src/terrainlib/log.h +++ b/src/terrainlib/log.h @@ -15,7 +15,7 @@ class Log { inline static std::shared_ptr& get_logger() { if (Log::logger == nullptr) { - Log::init(spdlog::level::level_enum::trace); + Log::init(spdlog::level::level_enum::info); } return Log::logger; } @@ -48,4 +48,4 @@ class Log { _UNREACHABLE(); \ } while (0) -#include "log_path.h" +#include "log_impls.h" diff --git a/src/terrainlib/log_path.h b/src/terrainlib/log_impls.h similarity index 52% rename from src/terrainlib/log_path.h rename to src/terrainlib/log_impls.h index 8a8d93a..791dcf0 100644 --- a/src/terrainlib/log_path.h +++ b/src/terrainlib/log_impls.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -17,3 +18,15 @@ struct fmt::formatter { } }; +template +struct fmt::formatter> { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const glm::vec &vec, FormatContext &ctx) { + return fmt::format_to(ctx.out(), "{}", glm::to_string(vec)); + } +}; diff --git a/src/terrainlib/mesh/SimpleMesh.h b/src/terrainlib/mesh/SimpleMesh.h index 0a0eafb..e20c559 100644 --- a/src/terrainlib/mesh/SimpleMesh.h +++ b/src/terrainlib/mesh/SimpleMesh.h @@ -46,7 +46,7 @@ class SimpleMesh { } bool has_uvs() const { - return this->positions.size() == this->uvs.size(); + return this->uvs.size() > 0; } bool has_texture() const { return this->texture.has_value(); diff --git a/src/terrainlib/mesh/TriangleSoup.h b/src/terrainlib/mesh/TriangleSoup.h new file mode 100644 index 0000000..433403d --- /dev/null +++ b/src/terrainlib/mesh/TriangleSoup.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include + +#include + +#include "mesh/SimpleMesh.h" + +using TriangleSoup = std::vector>; + +inline TriangleSoup to_triangle_soup(const SimpleMesh &mesh) { + TriangleSoup soup; + soup.reserve(mesh.triangles.size()); + for (const glm::uvec3 &indices : mesh.triangles) { + soup.push_back({mesh.positions[indices[0]], + mesh.positions[indices[1]], + mesh.positions[indices[2]]}); + } + return soup; +} + +inline void sort_triangle_soup(TriangleSoup &soup) { + for (auto &triangle : soup) { + // Normalize triangle orientation by rotating so smallest vertex is first + uint32_t min_index = 0; + glm::dvec3 min_vertex = triangle[min_index]; + for (uint32_t i = 1; i < 3; i++) { + const auto ¤t_vertex = triangle[i]; + if (current_vertex.x < min_vertex.x || + (current_vertex.x == min_vertex.x && + (current_vertex.y < min_vertex.y || + (current_vertex.y == min_vertex.y && current_vertex.z < min_vertex.z)))) { + min_index = i; + min_vertex = current_vertex; + } + } + + // Rotate to put the smallest vertex first + if (min_index == 1) { + triangle = {triangle[1], triangle[2], triangle[0]}; + } else if (min_index == 2) { + triangle = {triangle[2], triangle[0], triangle[1]}; + } + } + + // Sort the list of triangles + std::sort(soup.begin(), soup.end(), [](const auto &a, const auto &b) { + for (int i = 0; i < 3; ++i) { + if (a[i].x != b[i].x) { + return a[i].x < b[i].x; + } + if (a[i].y != b[i].y) { + return a[i].y < b[i].y; + } + if (a[i].z != b[i].z) { + return a[i].z < b[i].z; + } + } + return false; // triangles are equal + }); +} + +inline TriangleSoup to_sorted_triangle_soup(const SimpleMesh &mesh) { + auto soup = to_triangle_soup(mesh); + sort_triangle_soup(soup); + return soup; +} diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp new file mode 100644 index 0000000..8210e04 --- /dev/null +++ b/src/terrainlib/mesh/clip.cpp @@ -0,0 +1,314 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "hash_utils.h" +#include "log.h" +#include "mesh/clip.h" +#include "mesh/utils.h" +#include "mesh/cgal.h" +#include "mesh/convert.h" + +namespace { +double significant_above_epsilon(double x, double epsilon) { + const double residual = std::fmod(x, epsilon); + return x - residual; +} + +bool is_degenerate(std::array triangle) { + return triangle[0] == triangle[1] || triangle[1] == triangle[2] || triangle[2] == triangle[0]; +} + +struct DVec3Hash { + const double epsilon; + + std::size_t operator()(const glm::dvec3 &v) const { + return hash_combine( + significant_above_epsilon(v.x, epsilon), + significant_above_epsilon(v.y, epsilon), + significant_above_epsilon(v.z, epsilon)); + } +}; + +struct DVec3Equal { + const double epsilon; + + bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { + return glm::all(glm::epsilonEqual(a, b, epsilon)); + } +}; +} // namespace + +SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { + assert(mesh.has_uvs() == false && "Clipping a mesh with UVs is not supported yet."); + + if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { + return {}; + } + + // Construct 6 axis-aligned clipping planes from the bounding box + using Plane = radix::geometry::Plane; + const std::array planes = { + Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left + Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right + Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom + Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top + Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near + Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far + }; + + std::vector new_positions; + new_positions.reserve(mesh.vertex_count()); + std::vector new_triangles; + new_triangles.reserve(mesh.face_count()); + + // Prepare a spatial hash map to deduplicate intersection vertices + const double average_edge_length = estimate_average_edge_length(mesh, 100).value(); + const double epsilon = average_edge_length / 1000; + std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(epsilon), DVec3Equal(epsilon)); + auto add_intersection_vertex = [&](const glm::dvec3& vertex) { + const auto it = seen_vertices.find(vertex); + if (it != seen_vertices.cend()) { + return it->second; + } else { + const uint32_t vertex_index = new_positions.size(); + new_positions.push_back(vertex); + seen_vertices.emplace(vertex, vertex_index); + return vertex_index; + } + }; + + // Create another simpler mapping for the vertices copied directly from the input mesh + const uint32_t invalid_index = static_cast(-1); + std::vector position_mapping(mesh.vertex_count(), invalid_index); + auto add_original_vertex = [&](const uint32_t original_index, const glm::dvec3 &vertex) { + uint32_t &mapped = position_mapping[original_index]; + if (mapped == invalid_index) { + mapped = new_positions.size(); + new_positions.emplace_back(vertex); + } + return mapped; + }; + + // Prepare temporary storage for intermediate triangles, + // to avoid allocating a new vector for each triangle in the slow path. + struct TriangleAndVertices { + glm::uvec3 original_indices; // Indices of the vertices in the original mesh + std::array vertices; + uint8_t next_plane_to_clip; // Count which planes have already clipped this triangle + }; + std::vector triangles_left_to_clip; + triangles_left_to_clip.reserve(6); + + // Iterate over each triangle in the mesh + for (const glm::uvec3 &source_triangle : mesh.triangles) { + // Get the positions for the current triangle + std::array source_vertices = { + mesh.positions[source_triangle.x], + mesh.positions[source_triangle.y], + mesh.positions[source_triangle.z]}; + + // Start with a few quick checks to try to avoid the slow path + const uint8_t in_bounds_count = std::count_if(source_vertices.begin(), source_vertices.end(), [&](const auto &vertex) { + return bounds.contains_inclusive(vertex); + }); + if (in_bounds_count == 0) { + // Calculate the triangle bounds and perform an intersection check + const glm::dvec3 triangle_min = glm::min(glm::min(source_vertices[0], source_vertices[1]), source_vertices[2]); + const glm::dvec3 triangle_max = glm::max(glm::max(source_vertices[0], source_vertices[1]), source_vertices[2]); + if (!radix::geometry::intersect(bounds, radix::geometry::Aabb3d{triangle_min, triangle_max})) { + continue; + } + } + if (in_bounds_count == 3) { + // All vertices are in bounds, so we can directly add the vertex to the result mesh + glm::uvec3 new_triangle; + for (uint32_t i = 0; i < 3; i++) { + new_triangle[i] = add_original_vertex(source_triangle[i], source_vertices[i]); + } + new_triangles.push_back(new_triangle); + continue; + } + + // Slow path: Clip triangle against all planes + TriangleAndVertices current_triangle_and_vertices = {source_triangle, source_vertices, 0}; + triangles_left_to_clip.clear(); + + // This outer loop iterates over the intermediate triangles potentially produced in the 2 inside 1 outside case + // The current_triangle_and_vertices is updated isnide the switch or at the end of the loop + while (true) { + const glm::uvec3 &original_indices = current_triangle_and_vertices.original_indices; + const std::array &vertices = current_triangle_and_vertices.vertices; + bool skip_triangle = false; + + // Clip the current triangle against all planes + for (uint8_t plane_index = current_triangle_and_vertices.next_plane_to_clip; plane_index < planes.size(); plane_index++) { + const Plane &plane = planes[plane_index]; + + // Check the distance of each vertex to the plane + // and determine how many vertices are inside or outside the plane + const std::array distance_to_plane = { + radix::geometry::distance(plane, vertices[0]), + radix::geometry::distance(plane, vertices[1]), + radix::geometry::distance(plane, vertices[2])}; + + const std::array vertex_inside = { + distance_to_plane[0] >= 0, + distance_to_plane[1] >= 0, + distance_to_plane[2] >= 0}; + const uint32_t inside_count = vertex_inside[0] + vertex_inside[1] + vertex_inside[2]; + + // We need to use an if chain here since C++ does not like variable declarations in switch cases + if (inside_count == 0) { + // All vertices are on the outside of the plane, so we skip the triangle + skip_triangle = true; + break; + } else if (inside_count == 3) { + // All vertices are on the inside of the plane, so we keep the triangle as is + // and continue with the next plane + continue; + } else if (inside_count == 1) { + // A single vertex is inside the plane, cut the other two off. + + // First identify the vertices + uint32_t inside_tri_index, outside1_tri_index, outside2_tri_index; + for (uint32_t i = 0; i < 3; i++) { + if (vertex_inside[i]) { + inside_tri_index = i; + outside1_tri_index = (i + 1) % 3; + outside2_tri_index = (i + 2) % 3; + break; + } + } + + // Skip the triangle if it only touches the plane + if (distance_to_plane[inside_tri_index] == 0) { + skip_triangle = true; + break; + } + + // Then compute the intersections + const glm::dvec3 inside_vertex = vertices[inside_tri_index]; + const glm::dvec3 outside1_vertex = vertices[outside1_tri_index]; + const glm::dvec3 outside2_vertex = vertices[outside2_tri_index]; + + const glm::dvec3 intersection1 = radix::geometry::intersection(radix::geometry::Edge{inside_vertex, outside1_vertex}, plane); + const glm::dvec3 intersection2 = radix::geometry::intersection(radix::geometry::Edge{inside_vertex, outside2_vertex}, plane); + + // Finally create the new triangle and use it as the current triangle + const glm::uvec3 new_triangle( + original_indices[inside_tri_index], invalid_index, invalid_index); + const std::array new_vertices = { + vertices[inside_tri_index], + intersection1, + intersection2}; + if (is_degenerate(new_vertices)) { + skip_triangle = true; + break; + } + current_triangle_and_vertices = {new_triangle, new_vertices, static_cast(plane_index + 1)}; + } else if (inside_count == 2) { + // Two vertices is inside the plane, cut the last one off and split the triangle. + + // First identify the vertices + uint32_t outside_tri_index, inside1_tri_index, inside2_tri_index; + for (uint32_t i = 0; i < 3; i++) { + if (!vertex_inside[i]) { + outside_tri_index = i; + inside1_tri_index = (i + 1) % 3; + inside2_tri_index = (i + 2) % 3; + break; + } + } + + // Then compute the intersections + const glm::dvec3 outside_vertex = vertices[outside_tri_index]; + const glm::dvec3 inside1_vertex = vertices[inside1_tri_index]; + const glm::dvec3 inside2_vertex = vertices[inside2_tri_index]; + + const glm::dvec3 intersection1 = radix::geometry::intersection(radix::geometry::Edge{outside_vertex, inside1_vertex}, plane); + const glm::dvec3 intersection2 = radix::geometry::intersection(radix::geometry::Edge{outside_vertex, inside2_vertex}, plane); + + // Finally create the new triangles + // and use the first one as the current triangle + // while pushing the second one to the list of triangles left to clip + // quad order: outside - int1 - inside1 - inside2 - int2 + const glm::uvec3 new_triangle1( + original_indices[inside1_tri_index], original_indices[inside2_tri_index], invalid_index); + const glm::uvec3 new_triangle2( + original_indices[inside2_tri_index], invalid_index, invalid_index); + const std::array new_vertices1 = { + inside1_vertex, + inside2_vertex, + intersection1}; + const std::array new_vertices2 = { + inside2_vertex, + intersection2, + intersection1}; + if (is_degenerate(new_vertices2)) { + current_triangle_and_vertices = {new_triangle1, new_vertices1, static_cast(plane_index + 1)}; + } else if (is_degenerate(new_vertices1)) { + current_triangle_and_vertices = {new_triangle2, new_vertices2, static_cast(plane_index + 1)}; + } else { + current_triangle_and_vertices = {new_triangle1, new_vertices1, static_cast(plane_index + 1)}; + triangles_left_to_clip.emplace_back(new_triangle2, new_vertices2, static_cast(plane_index + 1)); + } + } else { + UNREACHABLE(); + } + } + + if (skip_triangle) { + break; + } + + // If we reached here we have clipped triangle that was not discarded + // However since it may contain new vertices not in the original mesh + // we need to add them to the output mesh while avoiding duplicates + glm::uvec3 indices; + for (uint32_t i = 0; i < 3; i++) { + const auto &original_vertex_index = original_indices[i]; + auto &vertex_index = indices[i]; + const auto &vertex = vertices[i]; + if (original_vertex_index == invalid_index) { + // We have a vertex not in the original mesh -> look up in the spatial hash map + vertex_index = add_intersection_vertex(vertex); + } else { + // We have a vertex in the original mesh -> look up in the boolean vector + vertex_index = add_original_vertex(original_vertex_index, vertex); + } + } + new_triangles.push_back(indices); + + // Continue with the next triangle if there are any left to clip + if (triangles_left_to_clip.empty()) { + break; + } else { + current_triangle_and_vertices = triangles_left_to_clip.back(); + triangles_left_to_clip.pop_back(); + } + } + } + + return SimpleMesh(new_triangles, new_positions); +} + +SimpleMesh mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh) { + // Convert meshes to CGAL format + cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); + cgal::SurfaceMesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); + + // Perform clipping using CGAL + const bool result = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh); + if (!result) { + throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); + } + + // Convert back to SimpleMesh format + return convert::to_simple_mesh(cgal_mesh); +} diff --git a/src/terrainlib/mesh/clip.h b/src/terrainlib/mesh/clip.h new file mode 100644 index 0000000..6377189 --- /dev/null +++ b/src/terrainlib/mesh/clip.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +#include "mesh/SimpleMesh.h" + +namespace mesh { +SimpleMesh clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); +SimpleMesh clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh); +} diff --git a/src/terrainlib/mesh/io/gltf.cpp b/src/terrainlib/mesh/io/gltf.cpp index a3a3e53..17ba6eb 100644 --- a/src/terrainlib/mesh/io/gltf.cpp +++ b/src/terrainlib/mesh/io/gltf.cpp @@ -579,6 +579,7 @@ tl::expected save_to_path( // Create the node hierachy. // We create parent nodes to offset the position by the average calculate above. // We need multiple parents to ensure that we dont lose our double precision accurary. + // TODO: dont create this hierachy if the translation is 0 char *node_name = const_cast(options.name.data()); std::array nodes; cgltf_node &mesh_node = nodes[2] = {}; diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index d98d436..6fc6488 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -1,8 +1,10 @@ #include #include -#include "SimpleMesh.h" -#include "utils.h" +#include "log.h" +#include "mesh/SimpleMesh.h" +#include "mesh/TriangleSoup.h" +#include "mesh/utils.h" radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh) { radix::geometry::Aabb3d bounds; @@ -31,38 +33,32 @@ radix::geometry::Aabb3d calculate_bounds(std::span meshes) { std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size) { const auto &triangles = mesh.triangles; - if (triangles.empty()) { + const auto &positions = mesh.positions; + const size_t num_triangles = triangles.size(); + + if (num_triangles == 0) { return std::nullopt; } - // Random sampling setup - std::vector sampled_triangles; - sampled_triangles.reserve(std::min(sample_size, triangles.size())); - - std::random_device rd; - std::mt19937 rng(rd()); - std::sample(triangles.begin(), triangles.end(), - std::back_inserter(sampled_triangles), - std::min(sample_size, triangles.size()), - rng); + const size_t triangle_sample_size = std::min((sample_size+2)/3, mesh.face_count()); + const size_t stride = std::max(1, num_triangles / triangle_sample_size); double total_length = 0.0; - size_t edge_count = 0; - for (const auto &tri : sampled_triangles) { - const glm::dvec3 &a = mesh.positions[tri.x]; - const glm::dvec3 &b = mesh.positions[tri.y]; - const glm::dvec3 &c = mesh.positions[tri.z]; + // Use a small offset to avoid sampling only the first part of the mesh + const size_t offset = (num_triangles / 7) % num_triangles; - total_length += glm::distance(a, b); - total_length += glm::distance(b, c); - total_length += glm::distance(c, a); + for (size_t i = 0; i < triangle_sample_size; i++) { + const auto &tri = triangles[(offset + i * stride) % num_triangles]; - edge_count += 3; + const glm::dvec3 &a = positions[tri.x]; + const glm::dvec3 &b = positions[tri.y]; + const glm::dvec3 &c = positions[tri.z]; + + total_length += glm::distance(a, b) + glm::distance(b, c) + glm::distance(c, a); } - assert(edge_count > 0); - return total_length / edge_count; + return total_length / triangle_sample_size; } std::optional calculate_max_edge_length(const SimpleMesh &mesh) { @@ -85,7 +81,7 @@ std::optional calculate_max_edge_length(const SimpleMesh &mesh) { return max_length; } -std::vector find_isolated_vertices(const SimpleMesh& mesh) { +std::vector find_isolated_vertices(const SimpleMesh &mesh) { std::vector connected; connected.resize(mesh.vertex_count()); std::fill(connected.begin(), connected.end(), false); @@ -105,7 +101,7 @@ std::vector find_isolated_vertices(const SimpleMesh& mesh) { return isolated; } -size_t remove_isolated_vertices(SimpleMesh& mesh) { +size_t remove_isolated_vertices(SimpleMesh &mesh) { const bool has_uvs = mesh.has_uvs(); const std::vector isolated = find_isolated_vertices(mesh); @@ -131,7 +127,7 @@ size_t remove_isolated_vertices(SimpleMesh& mesh) { return isolated.size(); } -size_t remove_triangles_of_negligible_size(SimpleMesh& mesh, const double threshold_percentage_of_average) { +size_t remove_triangles_of_negligible_size(SimpleMesh &mesh, const double threshold_percentage_of_average) { std::vector areas; areas.reserve(mesh.triangles.size()); for (glm::uvec3 &triangle : mesh.triangles) { @@ -243,10 +239,10 @@ std::unordered_map> create_edge_to_triangle_inde return edges_to_triangles; } -std::vector count_vertex_adjacent_triangles(const SimpleMesh& mesh) { +std::vector count_vertex_adjacent_triangles(const SimpleMesh &mesh) { std::vector adjacent_triangle_count(mesh.vertex_count(), 0); - for (const glm::uvec3& triangle : mesh.triangles) { + for (const glm::uvec3 &triangle : mesh.triangles) { for (size_t k = 0; k < static_cast(triangle.length()); k++) { adjacent_triangle_count[triangle[k]]++; } @@ -255,7 +251,7 @@ std::vector count_vertex_adjacent_triangles(const SimpleMesh& mesh) { return adjacent_triangle_count; } -std::vector find_non_manifold_edges(const SimpleMesh& mesh) { +std::vector find_non_manifold_edges(const SimpleMesh &mesh) { std::unordered_map> edges_to_triangles = create_edge_to_triangle_index_mapping(mesh); std::vector non_manifold_edges; @@ -305,7 +301,7 @@ std::vector find_single_non_manifold_triangle_indices(const SimpleMesh & return non_manifold_triangles; } -void remove_single_non_manifold_triangles(SimpleMesh& mesh) { +void remove_single_non_manifold_triangles(SimpleMesh &mesh) { std::vector non_manifold_triangles = find_single_non_manifold_triangle_indices(mesh); std::sort(non_manifold_triangles.begin(), non_manifold_triangles.end(), std::greater()); @@ -317,7 +313,7 @@ void remove_single_non_manifold_triangles(SimpleMesh& mesh) { remove_isolated_vertices(mesh); } -void sort_and_normalize_triangles(SimpleMesh& mesh) { +void sort_and_normalize_triangles(SimpleMesh &mesh) { sort_and_normalize_triangles(mesh.triangles); } void sort_and_normalize_triangles(std::span triangles) { @@ -331,10 +327,10 @@ void sort_and_normalize_triangles(std::span triangles) { } static void validate_sorted_normalized_mesh(const SimpleMesh &mesh) { - // check correct count of uvs + // Check correct count of uvs assert(!mesh.has_uvs() || mesh.positions.size() == mesh.uvs.size()); - // check uvs between 0 and 1 + // Check uvs between 0 and 1 for (const glm::dvec2 &uv : mesh.uvs) { for (size_t k = 0; k < static_cast(uv.length()); k++) { assert(uv[k] >= 0); @@ -342,7 +338,7 @@ static void validate_sorted_normalized_mesh(const SimpleMesh &mesh) { } } - // check for vertex indices in triangles outside valid range + // Check for vertex indices in triangles outside valid range for (const glm::uvec3 &triangle : mesh.triangles) { for (size_t k = 0; k < static_cast(triangle.length()); k++) { const size_t vertex_index = triangle[k]; @@ -350,27 +346,49 @@ static void validate_sorted_normalized_mesh(const SimpleMesh &mesh) { } } - // check for degenerate triangles + // Check for degenerate triangles for (const glm::uvec3 &triangle : mesh.triangles) { assert(triangle.x != triangle.y); assert(triangle.y != triangle.z); + assert(triangle.x != triangle.z); } - // check for duplicated triangles + // Check for duplicated triangles assert(mesh.triangles.end() == std::adjacent_find(mesh.triangles.begin(), mesh.triangles.end())); - // check for duplicated triangles with different orientation + // Check for duplicated triangles with different orientations std::vector triangles_ignore_orientation(mesh.triangles); - // sort vertices in triangles + // Sort vertices in triangles for (glm::uvec3 &triangle : triangles_ignore_orientation) { - std::sort(&triangle.x, &triangle.z); + std::sort(&triangle.x, &triangle.z + 1); } std::vector triangles_ignore_orientation2(triangles_ignore_orientation); sort_and_normalize_triangles(triangles_ignore_orientation); assert(triangles_ignore_orientation.end() == std::adjacent_find(triangles_ignore_orientation.begin(), triangles_ignore_orientation.end())); - // check for isolated vertices + // Check for isolated vertices assert(find_isolated_vertices(mesh).empty()); + + // Check for duplicate vertices + const double epsilon = 1e-9; + auto almost_equal = [epsilon](const glm::dvec3 &a, const glm::dvec3 &b) { + return glm::all(glm::lessThan(glm::abs(a - b), glm::dvec3(epsilon))); + }; + + std::vector sorted_positions = mesh.positions; + std::sort(sorted_positions.begin(), sorted_positions.end(), [](const glm::dvec3 &a, const glm::dvec3 &b) { + if (a.x != b.x) { + return a.x < b.x; + } + if (a.y != b.y) { + return a.y < b.y; + } + return a.z < b.z; + }); + + for (size_t i = 1; i < sorted_positions.size(); ++i) { + assert(!almost_equal(sorted_positions[i - 1], sorted_positions[i])); + } } void validate_mesh(const SimpleMesh &mesh) { @@ -382,12 +400,74 @@ void validate_mesh(const SimpleMesh &mesh) { validate_sorted_normalized_mesh(sorted); } +void reindex_mesh(SimpleMesh &mesh) { + struct Entry { + uint32_t new_index; + uint32_t inv_index; + }; + + const uint32_t invalid_index = static_cast(-1); + const Entry invalid_entry = Entry{invalid_index, invalid_index}; + std::vector index_map(mesh.positions.size(), invalid_entry); + + // Adjust triangles + uint32_t next_new_index = 0; + for (auto &triangle : mesh.triangles) { + for (uint32_t i = 0; i < 3; i++) { + Entry &entry = index_map[triangle[i]]; + if (entry.new_index == invalid_index) { + // Vertex newly encountered + entry.new_index = triangle[i] = next_new_index; + next_new_index += 1; + } else { + // Vertex already encountered + triangle[i] = entry.new_index; + } + } + } + const uint32_t new_vertex_count = next_new_index; + + // Add the inverse index + for (uint32_t old_index = 0; old_index < index_map.size(); old_index++) { + Entry &entry = index_map[old_index]; + if (entry.new_index == invalid_index) { + // This vertex was not used in any triangle + continue; + } + index_map[entry.new_index].inv_index = old_index; + } + + // Adjust vertices + for (uint32_t old_index = 0; old_index < new_vertex_count; old_index++) { + const Entry entry = index_map[old_index]; + std::swap(mesh.positions[old_index], mesh.positions[entry.inv_index]); + if (mesh.has_uvs()) { + std::swap(mesh.uvs[old_index], mesh.uvs[entry.inv_index]); + } + index_map[entry.inv_index].new_index = entry.new_index; + + if (entry.new_index != invalid_index) { + index_map[entry.new_index].inv_index = entry.inv_index; + } + } + + // Remove unused vertices + mesh.positions.resize(new_vertex_count); + if (mesh.has_uvs()) { + mesh.uvs.resize(new_vertex_count); + } +} SimpleMesh reindex_mesh(const SimpleMesh &mesh) { - std::vector new_positions; - new_positions.reserve(mesh.vertex_count()); std::vector new_triangles; new_triangles.reserve(mesh.face_count()); + std::vector new_positions; + new_positions.reserve(mesh.vertex_count()); + std::vector new_uvs; + if (mesh.has_uvs()) { + new_uvs.reserve(mesh.vertex_count()); + } + const uint32_t invalid_index = static_cast(-1); std::vector index_map(mesh.positions.size(), invalid_index); @@ -399,6 +479,9 @@ SimpleMesh reindex_mesh(const SimpleMesh &mesh) { // Vertex newly encountered const uint32_t new_index = new_positions.size(); new_positions.push_back(mesh.positions[old_index]); + if (mesh.has_uvs()) { + new_uvs.push_back(mesh.uvs[old_index]); + } new_triangle_indices[i] = new_index; index_map[old_index] = new_index; } else { @@ -409,122 +492,10 @@ SimpleMesh reindex_mesh(const SimpleMesh &mesh) { new_triangles.push_back(new_triangle_indices); } - return SimpleMesh(new_triangles, new_positions); -} - -namespace { - struct DVec3Hash { - std::size_t operator()(const glm::dvec3 &v) const { - std::size_t h1 = std::hash{}(v.x); - std::size_t h2 = std::hash{}(v.y); - std::size_t h3 = std::hash{}(v.z); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } - }; - - struct DVec3Equal { - const double epsilon; - - bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { - return glm::all(glm::epsilonEqual(a, b, 1e-8)); - } - }; -} - -SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { - if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { - return {}; - } - - // Calculate epsilon to merge newly created vertices - const double max_edge_length = calculate_max_edge_length(mesh).value(); - const double average_edge_length = estimate_average_edge_length(mesh).value(); - const double epsilon = average_edge_length / 1000; - - std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(), DVec3Equal(epsilon)); - - // Construct 6 axis-aligned clipping planes from the bounding box - using Plane = radix::geometry::Plane; - const std::array planes = { - Plane(glm::dvec3(1.0, 0.0, 0.0), -bounds.min.x), // left - Plane(glm::dvec3(-1.0, 0.0, 0.0), bounds.max.x), // right - Plane(glm::dvec3(0.0, 1.0, 0.0), -bounds.min.y), // bottom - Plane(glm::dvec3(0.0, -1.0, 0.0), bounds.max.y), // top - Plane(glm::dvec3(0.0, 0.0, 1.0), -bounds.min.z), // near - Plane(glm::dvec3(0.0, 0.0, -1.0), bounds.max.z) // far - }; - - std::vector new_positions = mesh.positions; - std::vector new_triangles; - new_triangles.reserve(mesh.face_count()); - - // Iterate over each triangle in the mesh - for (const glm::uvec3 &source_triangle : mesh.triangles) { - using Tri = radix::geometry::Triangle<3, double>; - - // Get the positions for the current triangle - const Tri triangle = { - mesh.positions[source_triangle.x], - mesh.positions[source_triangle.y], - mesh.positions[source_triangle.z]}; - - const uint8_t inside_count = std::count_if(triangle.begin(), triangle.end(), [&](const auto &vertex) { - return bounds.contains_inclusive(vertex); - }); - if (inside_count == 0) { - // Triangle vertices are not inside the bounds, however there can still be intersection - if (std::any_of(triangle.begin(), triangle.end(), [&](const auto &vertex) { - return radix::geometry::distance_sq(bounds, vertex) > max_edge_length * max_edge_length; - })) { - continue; - } - } - if (inside_count == source_triangle.length()) { - new_triangles.push_back(source_triangle); - continue; - } - - // Start with the original triangle - // TODO: this is rather inefficient since six vectors are allocated for each clipped triangle - const std::vector clipped_triangles = radix::geometry::clip(std::vector{triangle}, planes); - for (const auto &clipped_triangle : clipped_triangles) { - glm::uvec3 decomposed_triangle; - for (size_t i = 0; i < clipped_triangle.size(); i++) { - const auto &vertex = clipped_triangle[i]; - std::optional vertex_index; - - // Check if this vertex was already in the source triangle - for (size_t j = 0; j < triangle.size(); j++) { - const auto &source_vertex = triangle[j]; - if (vertex == source_vertex) { - vertex_index = source_triangle[j]; - break; - } - } - - // Check if this vertex was already added - if (!vertex_index.has_value()) { - const auto it = seen_vertices.find(vertex); - if (it != seen_vertices.cend()) { - vertex_index = it->second; - } - - } - - // Add a new vertex - if (!vertex_index.has_value()) { - vertex_index = new_positions.size(); - new_positions.push_back(vertex); - seen_vertices.emplace(vertex, vertex_index.value()); - } - - decomposed_triangle[i] = vertex_index.value(); - } - new_triangles.push_back(decomposed_triangle); - } + SimpleMesh new_mesh(new_triangles, new_positions); + if (mesh.has_uvs()) { + new_mesh.uvs = std::move(new_uvs); } - - // TODO: derive new_positions from seen_vertices - return reindex_mesh(SimpleMesh(new_triangles, new_positions)); + new_mesh.texture = mesh.texture; + return new_mesh; } - diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index a0c2ebf..7950fcc 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -48,5 +48,6 @@ void sort_and_normalize_triangles(std::span triangles); void validate_mesh(const SimpleMesh &mesh); +void reindex_mesh(SimpleMesh &mesh); SimpleMesh reindex_mesh(const SimpleMesh &mesh); SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 39a2d49..0b6df39 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -42,6 +42,8 @@ add_executable(unittests_terrainlib terrainlib/octree_id.cpp terrainlib/octree_space.cpp terrainlib/mesh_io.cpp + terrainlib/mesh_utils.cpp + terrainlib/mesh_clip.cpp ) target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) diff --git a/unittests/catch2_helpers.h b/unittests/catch2_helpers.h index d75a274..e94072b 100644 --- a/unittests/catch2_helpers.h +++ b/unittests/catch2_helpers.h @@ -23,12 +23,27 @@ #include #include #include +#include +#include + +#include "type_utils.h" namespace Catch { -template -struct StringMaker> { - static std::string convert(const glm::vec &value) { +template +struct StringMaker> { + static std::string convert(const glm::vec &value) { return glm::to_string(value); } }; + +template +struct StringMaker> { + static std::string convert(const radix::geometry::Aabb &value) { + return fmt::format("Aabb{}{}(({}, {}, {}) - ({}, {}, {}))", + N, + type_name()[0], + value.min.x, value.min.y, value.min.z, + value.max.x, value.max.y, value.max.z); + } +}; } diff --git a/unittests/terrainlib/mesh_clip.cpp b/unittests/terrainlib/mesh_clip.cpp new file mode 100644 index 0000000..e903f63 --- /dev/null +++ b/unittests/terrainlib/mesh_clip.cpp @@ -0,0 +1,312 @@ +#include + +#define CATCH_CONFIG_ENABLE_BENCHMARKING +#include +#include + +#include "../catch2_helpers.h" +#include "../opencv_helpers.h" + +#include "mesh/SimpleMesh.h" +#include "mesh/TriangleSoup.h" +#include "mesh/cgal.h" +#include "mesh/clip.h" +#include "mesh/convert.h" +#include "mesh/io.h" +#include "mesh/utils.h" +#include "octree/Space.h" +#include "octree/Id.h" + +TEST_CASE("empty mesh") { + const SimpleMesh mesh; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1.0, -1.0, -1.0), glm::dvec3(1.0, 1.0, 1.0)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + CHECK(clipped_mesh.positions.empty()); + CHECK(clipped_mesh.triangles.empty()); + CHECK(clipped_mesh.uvs.empty()); + CHECK(!clipped_mesh.texture.has_value()); +} + +TEST_CASE("single triangle in bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(1, 1, 1)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + CHECK(mesh.positions == clipped_mesh.positions); + CHECK(mesh.triangles == clipped_mesh.triangles); +} + +TEST_CASE("single triangle out of bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(-0.1, -0.1, -0.1)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + CHECK(clipped_mesh.positions == std::vector{}); + CHECK(clipped_mesh.triangles == std::vector{}); +} + +TEST_CASE("single triangle touching bounds in point") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(0, 0, 0)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + CHECK(clipped_mesh.positions == std::vector{}); + CHECK(clipped_mesh.triangles == std::vector{}); +} + +TEST_CASE("single triangle touching bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(0.5, 0.5, 0)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + const TriangleSoup clipped_soup = to_sorted_triangle_soup(clipped_mesh); + if (clipped_soup.size() == 1) { + CHECK(clipped_soup == TriangleSoup{{glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0, 0), + glm::dvec3(0, 0.5, 0)}}); + } else { + CHECK(clipped_soup == TriangleSoup{{ + glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0, 0), + glm::dvec3(0.5, 0.5, 0), + }, + { + glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0.5, 0), + glm::dvec3(0, 0.5, 0), + }}); + } +} + +TEST_CASE("single triangle with single vertex in bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(0.5, 0.5, 0.5)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + const TriangleSoup clipped_soup = to_sorted_triangle_soup(clipped_mesh); + if (clipped_soup.size() == 1) { + CHECK(clipped_soup == TriangleSoup{{glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0, 0), + glm::dvec3(0, 0.5, 0)}}); + } else { + CHECK(clipped_soup == TriangleSoup{{ + glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0, 0), + glm::dvec3(0.5, 0.5, 0), + }, + { + glm::dvec3(0, 0, 0), + glm::dvec3(0.5, 0.5, 0), + glm::dvec3(0, 0.5, 0), + }}); + } +} + +TEST_CASE("single triangle with two vertices in bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(-0.5, 0, 0), + glm::dvec3(0.5, 0, 0), + glm::dvec3(0.5, 1, 0), + }; + mesh.triangles = { + glm::uvec3(0, 1, 2)}; + const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(0.5, 0.5, 0.5)); + const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + const TriangleSoup clipped_soup = to_sorted_triangle_soup(clipped_mesh); + + const TriangleSoup expected1 = { + {glm::dvec3(-0.5, 0, 0), glm::dvec3(0.5, 0, 0), glm::dvec3(0.5, 0.5, 0)}, + {glm::dvec3(-0.5, 0, 0), glm::dvec3(0.5, 0.5, 0), glm::dvec3(0.0, 0.5, 0)}}; + + const TriangleSoup expected2 = { + {glm::dvec3(-0.5, 0, 0), glm::dvec3(0.5, 0, 0), glm::dvec3(0.0, 0.5, 0)}, + {glm::dvec3(0.0, 0.5, 0), glm::dvec3(0.5, 0, 0), glm::dvec3(0.5, 0.5, 0)}}; + + CAPTURE(clipped_soup); + CAPTURE(expected1); + CAPTURE(expected2); + CHECK((clipped_soup == expected1 || clipped_soup == expected2)); +} + +void run_checks(const SimpleMesh &mesh, const SimpleMesh &clipped_mesh, const radix::geometry::Aabb3d &bounds) { + validate_mesh(clipped_mesh); + + // Check that no vertices are outside the bounds + for (const auto &position : clipped_mesh.positions) { + // INFO(fmt::format("Vertex: {}", position)); + REQUIRE(bounds.contains_inclusive(position)); + } + + // Check that the source triangles that were fully inside the bounds are still present + // and the ones that are outside removed or changed. + for (const auto &triangle : mesh.triangles) { + CAPTURE(triangle); + CAPTURE(mesh.positions[triangle[0]]); + CAPTURE(mesh.positions[triangle[1]]); + CAPTURE(mesh.positions[triangle[2]]); + bool should_be_kept = true; + for (uint32_t i = 0; i < 3; ++i) { + if (!bounds.contains_inclusive(mesh.positions[triangle[i]])) { + should_be_kept = false; + break; + } + } + + bool found = false; + std::array vertices = { + mesh.positions[triangle.x], + mesh.positions[triangle.y], + mesh.positions[triangle.z]}; + for (const auto &clipped_triangle : clipped_mesh.triangles) { + bool matches = true; + for (uint32_t i = 0; i < 3; ++i) { + const auto &clipped_position = clipped_mesh.positions[clipped_triangle[i]]; + if (std::find(vertices.begin(), vertices.end(), clipped_position) == vertices.end()) { + matches = false; + CAPTURE(clipped_triangle); + break; + } + } + if (matches) { + found = true; + break; + } + } + + REQUIRE(should_be_kept == found); + } +} + +TEST_CASE("mesh::clip_on_bounds") { + const std::filesystem::path mesh_path = ATB_TEST_DATA_DIR "/meshes/6857.terrain"; + auto mesh_result = mesh::io::load_from_path(mesh_path); + REQUIRE(mesh_result.has_value()); + SimpleMesh &mesh = mesh_result.value(); + mesh.uvs.clear(); // Ensure no UVs are present, as clipping with UVs is not supported yet. + mesh.texture = std::nullopt; + + // Create cube mesh + mesh.positions = { + glm::dvec3(-1.0, -1.0, -1.0), // 0 + glm::dvec3(1.0, -1.0, -1.0), // 1 + glm::dvec3(1.0, 1.0, -1.0), // 2 + glm::dvec3(-1.0, 1.0, -1.0), // 3 + glm::dvec3(-1.0, -1.0, 1.0), // 4 + glm::dvec3(1.0, -1.0, 1.0), // 5 + glm::dvec3(1.0, 1.0, 1.0), // 6 + glm::dvec3(-1.0, 1.0, 1.0) // 7 + }; + + mesh.triangles = { + // Bottom face + glm::uvec3(0, 1, 2), + glm::uvec3(0, 2, 3), + // Top face + glm::uvec3(4, 5, 6), + glm::uvec3(4, 6, 7), + // Front face + glm::uvec3(0, 1, 5), + glm::uvec3(0, 5, 4), + // Back face + glm::uvec3(3, 2, 6), + glm::uvec3(3, 6, 7), + // Left face + glm::uvec3(0, 3, 7), + glm::uvec3(0, 7, 4), + // Right face + glm::uvec3(1, 2, 6), + glm::uvec3(1, 6, 5)}; + + validate_mesh(mesh); + + const std::array bounds_array = { + radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, -2.0), glm::dvec3(2.0, 2.0, 2.0)), + radix::geometry::Aabb3d(glm::dvec3(2.0, 2.0, 2.0), glm::dvec3(3.0, 3.0, 3.0)), + radix::geometry::Aabb3d(glm::dvec3(-1.0, -1.0, -1.0), glm::dvec3(1.0, 1.0, 1.0)), + radix::geometry::Aabb3d(glm::dvec3(0.5, 0.5, 0.5), glm::dvec3(2.0, 2.0, 2.0)), + radix::geometry::Aabb3d(glm::dvec3(-0.5, -0.5, -0.5), glm::dvec3(0.5, 0.5, 0.5)), + // tiny slice of one side: + radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, -2.0), glm::dvec3(-0.99, 2.0, 2.0)), // -x + radix::geometry::Aabb3d(glm::dvec3(0.99, -2.0, -2.0), glm::dvec3(2.0, 2.0, 2.0)), // +x + radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, -2.0), glm::dvec3(2.0, -0.99, 2.0)), // -y + radix::geometry::Aabb3d(glm::dvec3(-2.0, 0.99, -2.0), glm::dvec3(2.0, 2.0, 2.0)), // +y + radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, -2.0), glm::dvec3(2.0, 2.0, -0.99)), // -z + radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, 0.99), glm::dvec3(2.0, 2.0, 2.0)) // +z + }; + + const radix::geometry::Aabb3d mesh_bounds = calculate_bounds(mesh); + const glm::dvec3 mesh_centre = (mesh_bounds.max + mesh_bounds.min) / glm::dvec3(2); + const glm::dvec3 mesh_extends = mesh_bounds.size() / glm::dvec3(2); + for (const auto &relative_bounds : bounds_array) { + CAPTURE(relative_bounds); + const radix::geometry::Aabb3d bounds{ + mesh_centre + relative_bounds.min * mesh_extends, + mesh_centre + relative_bounds.max * mesh_extends}; + CAPTURE(bounds); + SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + run_checks(mesh, clipped_mesh, bounds); + } +} + +TEST_CASE("mesh::clip_on_bounds benchmark") { + BENCHMARK_ADVANCED("clip based on octree")(Catch::Benchmark::Chronometer meter) { + const std::filesystem::path mesh_path = ATB_TEST_DATA_DIR "/meshes/6857.terrain"; + auto mesh_result = mesh::io::load_from_path(mesh_path); + REQUIRE(mesh_result.has_value()); + SimpleMesh &mesh = mesh_result.value(); + mesh.uvs.clear(); + mesh.texture = std::nullopt; + + const octree::Space space = octree::Space::earth(); + const auto mesh_bounds = calculate_bounds(mesh); + const octree::Id id = space.find_smallest_node_encompassing_bounds(mesh_bounds).value(); + const auto child_ids = id.children().value(); + std::vector child_bounds; + child_bounds.reserve(child_ids.size()); + for (const auto &child_id : child_ids) { + const auto bounds = space.get_node_bounds(child_id); + child_bounds.push_back(bounds); + } + + meter.measure([mesh, child_bounds] { + std::vector child_meshes; + child_meshes.reserve(child_bounds.size()); + for (const auto &bounds : child_bounds) { + const auto clipped_mesh = mesh::clip_on_bounds(mesh, bounds); + child_meshes.push_back(clipped_mesh); + } + return child_meshes; + }); + }; +} diff --git a/unittests/terrainlib/mesh_utils.cpp b/unittests/terrainlib/mesh_utils.cpp new file mode 100644 index 0000000..729b258 --- /dev/null +++ b/unittests/terrainlib/mesh_utils.cpp @@ -0,0 +1,84 @@ +#include + +#include "../catch2_helpers.h" +#include "../opencv_helpers.h" + +#include "mesh/SimpleMesh.h" +#include "mesh/utils.h" + +TEST_CASE("calculate_bounds") { + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0.0, 0.0, 0.0), + glm::dvec3(1.0, 1.0, 1.0), + glm::dvec3(-1.0, -1.0, -1.0)}; + + const auto bounds = calculate_bounds(mesh); + CHECK(bounds.min == glm::dvec3(-1.0, -1.0, -1.0)); + CHECK(bounds.max == glm::dvec3(1.0, 1.0, 1.0)); +} + +TEST_CASE("reindex_mesh") { + using Catch::Matchers::UnorderedEquals; + + SimpleMesh mesh; + mesh.positions = { + glm::dvec3(0.0, 0.0, 0.0), + glm::dvec3(1.0, 1.0, 1.0), + glm::dvec3(2.0, 2.0, 2.0), + glm::dvec3(3.0, 3.0, 3.0), + glm::dvec3(4.0, 4.0, 4.0)}; + mesh.uvs = { + glm::dvec2(0.0, 0.0), + glm::dvec2(1.0, 1.0), + glm::dvec2(2.0, 2.0), + glm::dvec2(3.0, 3.0), + glm::dvec2(4.0, 4.0)}; + mesh.triangles = { + glm::uvec3(1, 4, 3), + glm::uvec3(1, 0, 3), + }; + mesh.texture = cv::Mat3b(100, 100); + + auto run_checks = [&](SimpleMesh &original, SimpleMesh &reindexed) { + CHECK(original.positions != reindexed.positions); + CHECK(original.triangles != reindexed.triangles); + + CHECK(reindexed.positions.size() == 4); + CHECK(reindexed.uvs.size() == 4); + CHECK(reindexed.triangles.size() == original.triangles.size()); + + for (uint32_t i = 0; i < original.triangles.size(); i++) { + const glm::uvec3 &triangle = original.triangles[i]; + const glm::uvec3 &reindexed_triangle = reindexed.triangles[i]; + for (uint32_t j = 0; j < 3; j++) { + const uint32_t original_index = triangle[j]; + const uint32_t new_index = reindexed_triangle[j]; + CHECK(original.positions[original_index] == reindexed.positions[new_index]); + CHECK(original.uvs[original_index] == reindexed.uvs[new_index]); + } + } + CHECK_THAT(reindexed.positions, UnorderedEquals({glm::dvec3(0.0, 0.0, 0.0), + glm::dvec3(1.0, 1.0, 1.0), + glm::dvec3(3.0, 3.0, 3.0), + glm::dvec3(4.0, 4.0, 4.0)})); + CHECK_THAT(reindexed.uvs, UnorderedEquals({glm::dvec2(0.0, 0.0), + glm::dvec2(1.0, 1.0), + glm::dvec2(3.0, 3.0), + glm::dvec2(4.0, 4.0)})); + CHECK(reindexed.texture.has_value()); + CHECK(mat_equals(*reindexed.texture, *original.texture)); + }; + + SECTION("const SimpleMesh& overload") { + SimpleMesh reindexed_mesh = reindex_mesh(static_cast(mesh)); + run_checks(mesh, reindexed_mesh); + } + + SECTION("non-const SimpleMesh& overload") { + SimpleMesh original_mesh = mesh; + reindex_mesh(static_cast(mesh)); + SimpleMesh reindexed_mesh = std::move(mesh); + run_checks(original_mesh, reindexed_mesh); + } +} From a43a402e3cc9d7a9adf718adaced4071b34fd8b0 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 3 Jul 2025 11:33:21 +0200 Subject: [PATCH 086/122] WIP terrainmerger --- README.md | 2 +- src/CMakeLists.txt | 26 +- src/terrainbuilder/border.h | 6 +- src/terrainbuilder/main.cpp | 140 +---- src/terrainbuilder/mesh_builder.cpp | 68 +- src/terrainbuilder/mesh_builder.h | 12 +- src/terrainbuilder/raster.h | 11 +- src/terrainbuilder/raw_dataset_reader.h | 57 +- src/terrainbuilder/terrainbuilder.cpp | 183 +++++- src/terrainbuilder/terrainbuilder.h | 18 +- src/terrainbuilder/texture_assembler.h | 17 +- src/terrainconvert/cli.cpp | 2 +- src/terrainlib/Dataset.cpp | 23 +- src/terrainlib/Dataset.h | 5 +- src/terrainlib/OnceCell.h | 53 -- src/terrainlib/OnceLock.h | 49 -- src/terrainlib/ProgressIndicator.cpp | 5 +- src/terrainlib/hash_utils.h | 48 +- src/terrainlib/io/Error.h | 1 + src/terrainlib/io/serialize.h | 2 + src/terrainlib/log.h | 10 +- src/terrainlib/log_impls.h | 20 +- src/terrainlib/mesh/SimpleMesh.h | 36 +- src/terrainlib/mesh/boolean.cpp | 32 + src/terrainlib/mesh/boolean.h | 13 + src/terrainlib/mesh/cgal.h | 19 +- src/terrainlib/mesh/clip.cpp | 245 +++++++- src/terrainlib/mesh/convert.cpp | 64 +- src/terrainlib/mesh/convert.h | 40 +- src/terrainlib/mesh/io.cpp | 7 +- src/terrainlib/mesh/io.h | 4 +- src/terrainlib/mesh/io/gltf.cpp | 7 +- src/terrainlib/mesh/io/terrain.cpp | 6 +- .../mesh}/merge.cpp | 99 +-- .../mesh}/merge.h | 36 +- src/terrainlib/mesh/utils.cpp | 179 ++---- src/terrainlib/mesh/utils.h | 12 +- src/terrainlib/mesh/utils.inl | 29 + src/terrainlib/mesh/validate.h | 15 + src/terrainlib/mesh/validate.inl | 111 ++++ src/terrainlib/octree/Id.h | 30 +- src/terrainlib/octree/IndexMap.cpp | 23 +- src/terrainlib/octree/IndexMap.h | 2 +- src/terrainlib/octree/Space.cpp | 4 +- src/terrainlib/octree/Storage.cpp | 262 -------- src/terrainlib/octree/Storage.h | 64 +- src/terrainlib/octree/disk/Layout.h | 4 +- .../octree/disk/layout/strategy/Flat.h | 2 +- .../strategy/LevelAndCoordinateDirectories.h | 2 +- src/terrainlib/octree/storage/IStorage.h | 40 ++ .../octree/storage/IndexedStorage.h | 64 ++ src/terrainlib/octree/storage/RawStorage.cpp | 41 ++ src/terrainlib/octree/storage/RawStorage.h | 36 ++ src/terrainlib/octree/storage/Storage.h | 242 ++++++++ src/terrainlib/octree/storage/cache/Dummy.h | 19 + src/terrainlib/octree/storage/cache/ICache.h | 18 + .../octree/storage/cache/LruCache.h | 66 ++ src/terrainlib/octree/storage/helpers.cpp | 123 ++++ src/terrainlib/octree/storage/helpers.h | 23 + src/terrainlib/octree/storage/open.cpp | 87 +++ src/terrainlib/octree/storage/open.h | 26 + src/terrainlib/pch.h | 17 + src/terrainmerger/cli.cpp | 3 +- src/terrainmerger/earth.h | 18 + src/terrainmerger/main.cpp | 13 +- src/terrainmerger/mask.h | 583 ++++++++++++++++++ src/terrainmerger/merge.h | 203 ++++-- src/terrainsimplify/cli.cpp | 2 +- src/terrainsimplify/simplify.cpp | 12 +- src/terrainsimplify/uv_map.cpp | 2 +- src/terrainsimplify/validate.h | 29 - src/tile_downloader/main.cpp | 10 +- unittests/CMakeLists.txt | 21 +- unittests/terrainlib/mesh_clip.cpp | 23 +- unittests/terrainmerger/mask.cpp | 0 75 files changed, 2662 insertions(+), 1164 deletions(-) delete mode 100644 src/terrainlib/OnceCell.h delete mode 100644 src/terrainlib/OnceLock.h create mode 100644 src/terrainlib/mesh/boolean.cpp create mode 100644 src/terrainlib/mesh/boolean.h rename src/{terrainsimplify => terrainlib/mesh}/merge.cpp (87%) rename src/{terrainsimplify => terrainlib/mesh}/merge.h (84%) create mode 100644 src/terrainlib/mesh/utils.inl create mode 100644 src/terrainlib/mesh/validate.h create mode 100644 src/terrainlib/mesh/validate.inl delete mode 100644 src/terrainlib/octree/Storage.cpp create mode 100644 src/terrainlib/octree/storage/IStorage.h create mode 100644 src/terrainlib/octree/storage/IndexedStorage.h create mode 100644 src/terrainlib/octree/storage/RawStorage.cpp create mode 100644 src/terrainlib/octree/storage/RawStorage.h create mode 100644 src/terrainlib/octree/storage/Storage.h create mode 100644 src/terrainlib/octree/storage/cache/Dummy.h create mode 100644 src/terrainlib/octree/storage/cache/ICache.h create mode 100644 src/terrainlib/octree/storage/cache/LruCache.h create mode 100644 src/terrainlib/octree/storage/helpers.cpp create mode 100644 src/terrainlib/octree/storage/helpers.h create mode 100644 src/terrainlib/octree/storage/open.cpp create mode 100644 src/terrainlib/octree/storage/open.h create mode 100644 src/terrainlib/pch.h create mode 100644 src/terrainmerger/earth.h create mode 100644 src/terrainmerger/mask.h delete mode 100644 src/terrainsimplify/validate.h create mode 100644 unittests/terrainmerger/mask.cpp diff --git a/README.md b/README.md index bbbbf88..e4af0bd 100644 --- a/README.md +++ b/README.md @@ -84,4 +84,4 @@ In order to build, you need to install: - tbb (intel threading building blocks) sudo apt-get install libcgal-dev libopencv-dev libfmt-dev libglm-dev libgdal-dev catch2 libfreeimage-dev libtbb-dev libcurl4-openssl-dev -(libgmp-dev libmpfr-dev libeigen3-dev) \ No newline at end of file +(libgmp-dev libmpfr-dev libsqlite3-dev) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d29e8b3..920b8b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,8 @@ alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COM add_library(zpp_bits INTERFACE) target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) +alp_add_git_repository(libassert URL https://github.com/jeremy-rifkin/libassert.git COMMITISH v2.1.0) + alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) # Don't build glfw docs, tests and examples @@ -112,23 +114,36 @@ add_library(terrainlib terrainlib/mesh/io/texture.h terrainlib/mesh/io/texture.cpp terrainlib/mesh/io/utils.h terrainlib/mesh/io/utils.cpp + terrainlib/mesh/boolean.h terrainlib/mesh/boolean.cpp terrainlib/mesh/cgal.h terrainlib/mesh/clip.h terrainlib/mesh/clip.cpp terrainlib/mesh/convert.h terrainlib/mesh/convert.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp + terrainlib/mesh/merge.h terrainlib/mesh/merge.cpp terrainlib/mesh/SimpleMesh.h terrainlib/mesh/TriangleSoup.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp + terrainlib/mesh/validate.h + terrainlib/octree/disk/layout/strategy/Default.h terrainlib/octree/disk/layout/strategy/Flat.h terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h terrainlib/octree/disk/layout/Strategy.h terrainlib/octree/disk/layout/StrategyRegister.h terrainlib/octree/disk/IndexFile.h terrainlib/octree/disk/Layout.h + terrainlib/octree/storage/cache/Dummy.h + terrainlib/octree/storage/cache/ICache.h + terrainlib/octree/storage/cache/LruCache.h + terrainlib/octree/storage/helpers.h terrainlib/octree/storage/helpers.cpp + terrainlib/octree/storage/IndexedStorage.h + terrainlib/octree/storage/IStorage.h + terrainlib/octree/storage/open.h terrainlib/octree/storage/open.cpp + terrainlib/octree/storage/RawStorage.h terrainlib/octree/storage/RawStorage.cpp + terrainlib/octree/storage/Storage.h terrainlib/octree/Id.h - terrainlib/octree/Storage.h terrainlib/octree/Storage.cpp + terrainlib/octree/Storage.h terrainlib/octree/IndexMap.h terrainlib/octree/IndexMap.cpp terrainlib/octree/NodeStatus.h terrainlib/octree/Space.h terrainlib/octree/Space.cpp @@ -144,7 +159,7 @@ add_library(terrainlib terrainlib/string_utils.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) @@ -176,6 +191,7 @@ target_link_libraries(tilebuilder PUBLIC tilebuilderlib) add_library(terrainmergerlib terrainmerger/merge.h + terrainmerger/mask.h ) target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) @@ -208,13 +224,10 @@ target_link_libraries(terrainbuilder PUBLIC terrainbuilderlib) add_library(terrainsimplifylib terrainsimplify/cli.h terrainsimplify/cli.cpp - terrainsimplify/merge.h - terrainsimplify/merge.cpp terrainsimplify/simplify.h terrainsimplify/simplify.cpp terrainsimplify/uv_map.h terrainsimplify/uv_map.cpp - terrainsimplify/validate.h ) target_include_directories(terrainsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainsimplify) target_precompile_headers(terrainsimplifylib PRIVATE terrainsimplify/pch.h) @@ -258,4 +271,5 @@ add_executable(browser #target_compile_features(browser PRIVATE cxx_std_20) #target_compile_options(browser PRIVATE /utf-8) target_include_directories(browser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/browser) -target_link_libraries(browser PUBLIC terrainlib glfw glad_gl_core_46 resources-lib imgui) \ No newline at end of file +target_link_libraries(browser PUBLIC terrainlib glfw glad_gl_core_46 resources-lib imgui) + diff --git a/src/terrainbuilder/border.h b/src/terrainbuilder/border.h index 01746ea..a527901 100644 --- a/src/terrainbuilder/border.h +++ b/src/terrainbuilder/border.h @@ -1,5 +1,4 @@ -#ifndef BORDER_H -#define BORDER_H +#pragma once #include @@ -88,6 +87,5 @@ inline void add_border_to_aabb(radix::geometry::Aabb2 &bounds, const Border< bounds.max.x = saturating_add(bounds.max.x, border.right); bounds.max.y = saturating_add(bounds.max.y, border.bottom); } -} -#endif +} diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index fc92a79..ccf66da 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -9,27 +9,16 @@ #include #include -#include -#include -#include -#include - #include "Dataset.h" -#include "ProgressIndicator.h" #include "log.h" #include "srs.h" #include "terrainbuilder.h" +#include "octree/Space.h" #include "ctb/GlobalGeodetic.hpp" #include "ctb/GlobalMercator.hpp" #include "ctb/Grid.hpp" -#include "octree/Id.h" -#include "octree/Space.h" -#include "octree/Storage.h" -#include "octree/disk/layout/strategy/LevelAndCoordinateDirectories.h" -#include "octree/utils.h" - OGRSpatialReference parse_srs(const std::string &user_input) { const auto result = srs::from_user_input(user_input); if (!result.has_value()) { @@ -143,129 +132,6 @@ radix::geometry::Aabb3d parse_target_bounds( UNREACHABLE(); } -template -T expect(const std::optional &opt, const std::string &msg) { - if (!opt) { - LOG_ERROR_AND_EXIT(msg); - } - return *opt; -} - -void batch_build( - Dataset &dataset, - const octree::Id::Level target_level, - const OGRSpatialReference &texture_srs, - const std::optional &texture_base_path, - const OGRSpatialReference &mesh_srs, - const std::filesystem::path &output_base_path, - const std::string &output_format) { - if (!std::filesystem::exists(output_base_path)) { - LOG_TRACE("Output base path {} does not exist, creating it", output_base_path); - std::filesystem::create_directories(output_base_path); - } else if (!std::filesystem::is_directory(output_base_path)) { - LOG_ERROR_AND_EXIT("Output base path {} exists but is not a directory", output_base_path); - } - - octree::Storage storage = octree::open_folder( - output_base_path, - octree::disk::layout::strategy::make_default(), - output_format); - - const auto dataset_srs = dataset.srs(); - const auto dataset_bounds = dataset.bounds3d(true); - - const auto ecef_srs = srs::ecef(); - const auto ecef_bounds = srs::encompassing_bounds_transfer( - dataset_srs, ecef_srs, dataset_bounds); - const auto space = octree::Space::earth(); - const auto root_node = expect( - space.find_smallest_node_encompassing_bounds(ecef_bounds), - "Dataset is outside the octree root node."); - - tbb::concurrent_vector concurrent_targets; - - tbb::task_group tg; - std::function process_node; - - tbb::enumerable_thread_specific> transform_ecef_dataset([&]() { - auto local_ecef_srs = ecef_srs; - auto local_dataset_srs = dataset_srs; - auto transform = srs::transformation(local_ecef_srs, local_dataset_srs); - return transform; - }); - - process_node = [&](octree::Id node) { - const auto node_bounds = space.get_node_bounds(node); - const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer( - &*transform_ecef_dataset.local(), node_bounds); - - if (!radix::geometry::intersect(node_bounds_dataset_srs, dataset_bounds)) { - return; - } - - if (node.level() < target_level) { - if (auto children = node.children(); children.has_value()) { - for (const auto &child : *children) { - tg.run([&, child] { process_node(child); }); - } - } - } else if (node.level() == target_level) { - concurrent_targets.push_back(node); - } - }; - - tg.run([&] { process_node(root_node); }); - tg.wait(); // Wait for all tasks - - std::vector target_nodes; - target_nodes.assign(concurrent_targets.begin(), concurrent_targets.end()); - - ProgressIndicator progress(target_nodes.size()); - std::jthread progress_thread = progress.start_monitoring(); - - tbb::enumerable_thread_specific local_dataset([&]() { - return dataset.clone(); - }); - tbb::enumerable_thread_specific> local_ecef_srs([&]() { - return srs::clone(ecef_srs); - }); - tbb::enumerable_thread_specific> local_texture_srs([&]() { - return srs::clone(texture_srs); - }); - tbb::enumerable_thread_specific> local_mesh_srs([&]() { - return srs::clone(mesh_srs); - }); - tbb::parallel_for(size_t(0), target_nodes.size(), [&](size_t i) { - const auto &node = target_nodes[i]; - if (storage.has_node(node)) { // TODO: correctly handle virtual nodes - return; - } - - auto &dataset = local_dataset.local(); - auto &ecef_srs = *local_ecef_srs.local(); - auto &texture_srs = *local_texture_srs.local(); - auto &mesh_srs = *local_mesh_srs.local(); - - const auto node_bounds = space.get_node_bounds(node); - const SimpleMesh mesh = terrainbuilder::build( - dataset, - ecef_srs, - node_bounds, - texture_srs, - texture_base_path, - mesh_srs); - - if (!mesh.is_empty()) { - storage.write_node(node, mesh); - } - - progress.task_finished(); - }); - - progress_thread.join(); - storage.save_index(); -} - int run(std::span args) { int argc = args.size(); char **argv = args.data(); @@ -376,7 +242,7 @@ int run(std::span args) { target_tile_scheme, target_srs); - terrainbuilder::build_and_save( + terrainbuilder::build_and_save_patch( dataset, target_srs, target_bounds, @@ -387,7 +253,7 @@ int run(std::span args) { } if (*batch) { - batch_build( + terrainbuilder::build_all_patches( dataset, target_level, texture_srs, diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index e05f0be..deb323f 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -8,24 +8,31 @@ #include #include #include +#include #include "Dataset.h" #include "log.h" #include "mesh/SimpleMesh.h" +#include "mesh/utils.h" #include "mesh_builder.h" #include "raster.h" #include "raw_dataset_reader.h" #include "srs.h" -#include "mesh/utils.h" +#include "mesh/clip.h" +#include "mesh/validate.h" + +// TODO: remove +#include "raster_to_image.h" -namespace terrainbuilder::mesh { +// TODO: fix namespace +namespace terrainbuilder { -std::ostream &operator<<(std::ostream &os, BuildError error) { +std::ostream &operator<<(std::ostream &os, BuildMeshError error) { switch (error) { - case BuildError::OutOfBounds: + case BuildMeshError::OutOfBounds: os << "out of bounds"; break; - case BuildError::EmptyRegion: + case BuildMeshError::EmptyRegion: os << "empty region"; break; default: @@ -35,23 +42,19 @@ std::ostream &operator<<(std::ostream &os, BuildError error) { return os; } +namespace { +using PixelBounds = radix::geometry::Aabb2i; + template -static glm::dvec2 apply_transform(std::array transform, const glm::tvec2 &v) { +glm::dvec2 apply_transform(std::array transform, const glm::tvec2 &v) { glm::dvec2 result; GDALApplyGeoTransform(transform.data(), v.x, v.y, &result.x, &result.y); return result; } -using PixelBounds = radix::geometry::Aabb2i; - // TODO:: write documentation // TODO: use referencedBounds -bool is_valid(float height) { - return !isnan(height) && !isinf(height) /* <- invalid values */ - && height > -20000 && height < 20000; /* <- padding */ -} - glm::dvec3 convert_pixel_to_vertex(const float height, const raster::Coords pixel_coords, const RawDatasetReader& reader, const PixelBounds& pixel_bounds) { const glm::dvec2 point_offset_in_raster(0.5); // Convert pixel coordinates into a point in the dataset's srs. const glm::dvec2 coords_raster_relative = glm::dvec2(pixel_coords) + point_offset_in_raster; @@ -76,15 +79,15 @@ SimpleMesh meshify(const raster::Raster& source_points, const raster positions.push_back(point); return index; }); - assert(positions.size() == valid_vertex_count); + DEBUG_ASSERT(positions.size() == valid_vertex_count); // Allocate triangle vector const size_t max_triangle_count = (source_points.width() - 1) * (source_points.height() - 1) * 2; std::vector triangles; triangles.reserve(max_triangle_count); - for (size_t x = 0; x < source_points.width() - 1; x++) { - for (size_t y = 0; y < source_points.height() - 1; y++) { + for (size_t y = 0; y < source_points.height() - 1; y++) { + for (size_t x = 0; x < source_points.width() - 1; x++) { const std::array quad { raster::Coords{x, y}, raster::Coords{x + 1, y}, @@ -104,11 +107,16 @@ SimpleMesh meshify(const raster::Raster& source_points, const raster } } } - assert(triangles.size() <= max_triangle_count); + DEBUG_ASSERT(triangles.size() <= max_triangle_count); return SimpleMesh(triangles, positions); } +SimpleMesh transform_mesh(SimpleMesh&& source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference &target_srs) { + const auto transform = srs::transformation(source_srs, target_srs); + srs::transform_points_inplace(transform.get(), source_mesh.positions); + return source_mesh; +} SimpleMesh transform_mesh(const SimpleMesh &source_mesh, const OGRSpatialReference &source_srs, const OGRSpatialReference& target_srs) { SimpleMesh target_mesh; target_mesh.positions = srs::transform_points(source_srs, target_srs, source_mesh.positions); @@ -135,8 +143,9 @@ radix::geometry::Aabb3d extend_bounds_to_3d(radix::geometry::Aabb2d bounds2d) { const glm::dvec3 max(bounds2d.max, infinity); return radix::geometry::Aabb3d(min, max); } +} -tl::expected build_reference_mesh_tile( +tl::expected build_reference_mesh_tile( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &tile_srs, const radix::tile::SrsBounds &tile_bounds, @@ -144,7 +153,7 @@ tl::expected build_reference_mesh_tile( return build_reference_mesh_patch(dataset, mesh_srs, tile_srs, extend_bounds_to_3d(tile_bounds), texture_srs, texture_bounds); } -tl::expected build_reference_mesh_patch( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, @@ -165,9 +174,9 @@ tl::expected build_reference_mesh_patch( radix::geometry::Aabb2i pixel_bounds = reader.transform_srs_bounds_to_pixel_bounds(target_bounds_in_source_srs); add_border_to_aabb(pixel_bounds, Border(1)); LOG_TRACE("Reading pixels [({}, {})-({}, {})] from dataset", pixel_bounds.min.x, pixel_bounds.min.y, pixel_bounds.max.x, pixel_bounds.max.y); - const std::optional read_result = reader.read_data_in_pixel_bounds(pixel_bounds, true); + const std::optional read_result = reader.read_data_in_pixel_bounds_clamped(pixel_bounds); if (!read_result.has_value() || read_result->size() == 0) { - return tl::unexpected(BuildError::OutOfBounds); + return tl::unexpected(BuildMeshError::OutOfBounds); } const raster::HeightMap height_map = read_result.value(); @@ -176,7 +185,6 @@ tl::expected build_reference_mesh_patch( const raster::Mask valid_mask = raster::transform(height_map, [=](const float height) { return height != no_data_value; }); - // const raster::Mask valid_mask = raster::transform(height_map, is_valid); LOG_TRACE("Transforming pixels to vertices"); const raster::Raster source_points = raster::transform(height_map, valid_mask, [&](const float height, const raster::Coords& coords) { @@ -184,18 +192,18 @@ tl::expected build_reference_mesh_patch( }); LOG_TRACE("Generating triangles"); - const SimpleMesh mesh_in_source_srs = meshify(source_points, valid_mask); + SimpleMesh mesh_in_source_srs = meshify(source_points, valid_mask); // Check if we even have any valid vertices. Can happen if all of the region is padding. if (mesh_in_source_srs.vertex_count() == 0 || mesh_in_source_srs.face_count() == 0) { - return tl::unexpected(BuildError::EmptyRegion); + return tl::unexpected(BuildMeshError::EmptyRegion); } LOG_TRACE("Clipping mesh based on target bounds"); - const SimpleMesh mesh_in_clip_srs = transform_mesh(mesh_in_source_srs, source_srs, clip_srs); - SimpleMesh clipped_mesh = clip_mesh_on_bounds(mesh_in_clip_srs, clip_bounds); + const SimpleMesh mesh_in_clip_srs = transform_mesh(std::move(mesh_in_source_srs), source_srs, clip_srs); + SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh_in_clip_srs, clip_bounds); // Check if there are any vertices left if (clipped_mesh.vertex_count() == 0 || clipped_mesh.face_count() == 0) { - return tl::unexpected(BuildError::EmptyRegion); + return tl::unexpected(BuildMeshError::EmptyRegion); } // TODO: move this to another function? @@ -203,11 +211,11 @@ tl::expected build_reference_mesh_patch( clipped_mesh.uvs = generate_uv_space(clipped_mesh.positions, clip_srs, texture_srs, texture_bounds); LOG_TRACE("Transforming mesh into output srs"); - SimpleMesh target_mesh = transform_mesh(clipped_mesh, clip_srs, mesh_srs); + SimpleMesh target_mesh = transform_mesh(std::move(clipped_mesh), clip_srs, mesh_srs); remove_isolated_vertices(target_mesh); // TODO: is this still required? - validate_mesh(target_mesh); + mesh::validate(target_mesh); return target_mesh; } -} // namespace terrainbuilder::mesh +} diff --git a/src/terrainbuilder/mesh_builder.h b/src/terrainbuilder/mesh_builder.h index 5e68ce5..acf3e4b 100644 --- a/src/terrainbuilder/mesh_builder.h +++ b/src/terrainbuilder/mesh_builder.h @@ -1,5 +1,4 @@ -#ifndef MESHBUILDING_H -#define MESHBUILDING_H +#pragma once #include @@ -9,20 +8,19 @@ #include "mesh/SimpleMesh.h" #include "border.h" -namespace terrainbuilder::mesh { +namespace terrainbuilder { -enum class BuildError { +enum class BuildMeshError { OutOfBounds, EmptyRegion }; -std::ostream &operator<<(std::ostream &os, BuildError error); +std::ostream &operator<<(std::ostream &os, BuildMeshError error); /// Builds a mesh from the given height dataset. -tl::expected build_reference_mesh_patch( +tl::expected build_reference_mesh_patch( Dataset &dataset, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &clip_srs, const radix::geometry::Aabb3d &clip_bounds, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds &texture_bounds); } -#endif diff --git a/src/terrainbuilder/raster.h b/src/terrainbuilder/raster.h index 3a53587..a9a7d39 100644 --- a/src/terrainbuilder/raster.h +++ b/src/terrainbuilder/raster.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace raster { @@ -25,8 +26,8 @@ class Raster { return this->_height; } [[nodiscard]] decltype(auto) pixel(const Coords &coords) { - assert(coords.x < this->_width); - assert(coords.y < this->_height); + DEBUG_ASSERT(coords.x < this->_width); + DEBUG_ASSERT(coords.y < this->_height); const Index pixel_index = this->index(coords); if constexpr (std::is_same_v) { return static_cast(this->_data[pixel_index]); @@ -35,8 +36,8 @@ class Raster { } } [[nodiscard]] decltype(auto) pixel(const Coords &coords) const { - assert(coords.x < this->_width); - assert(coords.y < this->_height); + DEBUG_ASSERT(coords.x < this->_width); + DEBUG_ASSERT(coords.y < this->_height); const Index pixel_index = this->index(coords); if constexpr (std::is_same_v) { return static_cast(this->_data[pixel_index]); @@ -141,4 +142,4 @@ template F> } return output; } -} \ No newline at end of file +} diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/terrainbuilder/raw_dataset_reader.h index fb20f8a..9eed966 100644 --- a/src/terrainbuilder/raw_dataset_reader.h +++ b/src/terrainbuilder/raw_dataset_reader.h @@ -1,5 +1,4 @@ -#ifndef RAWDATASETREADER_H -#define RAWDATASETREADER_H +#pragma once #include #include @@ -36,7 +35,7 @@ class RawDatasetReader { } double get_no_data_value() { - assert(this->dataset->GetRasterCount() >= 1); + DEBUG_ASSERT(this->dataset->GetRasterCount() >= 1); GDALRasterBand *height_band = this->dataset->GetRasterBand(1); return height_band->GetNoDataValue(); } @@ -47,29 +46,19 @@ class RawDatasetReader { } // TODO: support reading other data types - std::optional read_data_in_pixel_bounds(radix::geometry::Aabb2i bounds, const bool clamp_bounds = false) { - if (clamp_bounds) { - const glm::ivec2 max_in_bounds = glm::ivec2(this->dataset_size()) - glm::ivec2(1); - bounds.min = glm::clamp(bounds.min, glm::ivec2(0), max_in_bounds); - bounds.max = glm::clamp(bounds.max, bounds.min, max_in_bounds); - } - - assert(glm::all(glm::greaterThanEqual(bounds.min, glm::ivec2(0)))); - assert(glm::all(glm::greaterThanEqual(bounds.max, glm::ivec2(0)))); - assert(glm::all(glm::lessThan(bounds.min, glm::ivec2(this->dataset_size())))); - assert(glm::all(glm::lessThan(bounds.max, glm::ivec2(this->dataset_size())))); + std::optional read_data_in_pixel_bounds(const radix::geometry::Aabb2i& bounds) { + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(bounds.min, glm::ivec2(0)))); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(bounds.max, glm::ivec2(0)))); + DEBUG_ASSERT(glm::all(glm::lessThan(bounds.min, glm::ivec2(this->dataset_size())))); + DEBUG_ASSERT(glm::all(glm::lessThan(bounds.max, glm::ivec2(this->dataset_size())))); - assert(this->dataset->GetRasterCount() >= 1); + DEBUG_ASSERT(this->dataset->GetRasterCount() >= 1); GDALRasterBand *height_band = this->dataset->GetRasterBand(1); // non-owning pointer // Initialize the HeightData for reading raster::HeightMap height_data(bounds.width(), bounds.height()); if (bounds.width() == 0 || bounds.height() == 0) { - if (clamp_bounds) { - LOG_WARN("Target dataset bounds are empty (clamped)"); - } else { - LOG_WARN("Target dataset bounds are empty"); - } + LOG_WARN("Target dataset bounds are empty"); return height_data; } @@ -86,13 +75,33 @@ class RawDatasetReader { return height_data; } + std::optional read_data_in_pixel_bounds_clamped(radix::geometry::Aabb2i &bounds) { + const auto original_bounds = bounds; + + const glm::ivec2 max_in_bounds = glm::ivec2(this->dataset_size()) - glm::ivec2(1); + bounds.min = glm::clamp(bounds.min, glm::ivec2(0), max_in_bounds); + bounds.max = glm::clamp(bounds.max, bounds.min, max_in_bounds); - std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds, const bool clamp_bounds = false) { + if (original_bounds != bounds) { + LOG_TRACE("Clamped target dataset bounds from [({}, {})-({}, {})] to [({}, {})-({}, {})]", + original_bounds.min.x, original_bounds.min.y, original_bounds.max.x, original_bounds.max.y, + bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y); + } + + if (bounds.width() == 0 || bounds.height() == 0) { + LOG_WARN("Target dataset bounds are empty (clamped)"); + return raster::HeightMap(0, 0); + } + + return this->read_data_in_pixel_bounds(bounds); + } + + std::optional read_data_in_srs_bounds(const radix::tile::SrsBounds &bounds) { // Transform the SrsBounds to pixel space - const radix::geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); + radix::geometry::Aabb2i pixel_bounds = this->transform_srs_bounds_to_pixel_bounds(bounds); // Use the transformed pixel bounds to read data - return this->read_data_in_pixel_bounds(pixel_bounds, clamp_bounds); + return this->read_data_in_pixel_bounds(pixel_bounds); } radix::geometry::Aabb2i transform_srs_bounds_to_pixel_bounds(const radix::tile::SrsBounds &bounds) const { @@ -154,5 +163,3 @@ class RawDatasetReader { }; } - -#endif diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 7a0e9cf..4c15def 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -5,20 +5,31 @@ #include #include +#include +#include +#include +#include + #include "Dataset.h" #include "ctb/GlobalMercator.hpp" #include "ctb/Grid.hpp" #include "srs.h" +#include "ProgressIndicator.h" #include "log.h" -#include "mesh/io.h" #include "mesh/SimpleMesh.h" +#include "mesh/io.h" #include "mesh_builder.h" #include "terrainbuilder.h" #include "texture_assembler.h" #include "tile_provider.h" +#include "mesh/validate.h" +#include "octree/Id.h" #include "octree/Space.h" +#include "octree/Storage.h" +#include "octree/disk/layout/strategy/LevelAndCoordinateDirectories.h" +#include "octree/utils.h" namespace terrainbuilder { @@ -45,7 +56,7 @@ class BasemapSchemeTilePathProvider : public TilePathProvider { std::filesystem::path base_path; }; -SimpleMesh build( +std::optional build_patch( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -58,14 +69,14 @@ SimpleMesh build( std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); LOG_INFO("Building mesh..."); - tl::expected mesh_result = mesh::build_reference_mesh_patch( + tl::expected mesh_result = build_reference_mesh_patch( dataset, mesh_srs, target_bounds_srs, target_bounds, texture_srs, texture_bounds); if (!mesh_result.has_value()) { - const mesh::BuildError error = mesh_result.error(); - if (error == mesh::BuildError::OutOfBounds) { + const BuildMeshError error = mesh_result.error(); + if (error == BuildMeshError::OutOfBounds) { const radix::tile::SrsBounds dataset_bounds = dataset.bounds(); LOG_ERROR("Target bounds are fully outside of dataset region\n" "Dataset {{\n" @@ -76,12 +87,10 @@ SimpleMesh build( "}}", dataset_bounds.min.x, dataset_bounds.min.y, dataset_bounds.width(), dataset_bounds.height(), target_bounds.min.x, target_bounds.min.y, target_bounds.size().x, target_bounds.size().y); - // TODO: exit(1); - return {}; - } else if (error == mesh::BuildError::EmptyRegion) { + return std::nullopt; + } else if (error == BuildMeshError::EmptyRegion) { LOG_WARN("Target bounds are inside dataset, but the region is empty"); - // TODO: exit(0); - return {}; + return std::nullopt; } } SimpleMesh mesh = mesh_result.value(); @@ -92,10 +101,10 @@ SimpleMesh build( start = std::chrono::high_resolution_clock::now(); LOG_INFO("Assembling mesh texture"); BasemapSchemeTilePathProvider tile_provider(texture_base_path.value()); - std::optional texture = texture::assemble_texture_from_tiles(grid, texture_srs, texture_bounds, tile_provider); + std::optional texture = assemble_texture_from_tiles(grid, texture_srs, texture_bounds, tile_provider); if (!texture.has_value()) { LOG_ERROR("Failed to assemble texture"); - exit(1); + // TODO: should we return nullopt here? } mesh.texture = texture; LOG_DEBUG("Assembling mesh texture took {}s", format_secs_since(start)); @@ -107,7 +116,7 @@ SimpleMesh build( return mesh; } -void build_and_save( +void build_and_save_patch( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -115,13 +124,17 @@ void build_and_save( const std::optional texture_base_path, const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_path) { - const SimpleMesh mesh = build( + auto mesh_result = build_patch( dataset, target_bounds_srs, target_bounds, texture_srs, texture_base_path, mesh_srs); + if (!mesh_result.has_value()) { + return; + } + const SimpleMesh mesh = std::move(mesh_result.value()); LOG_INFO("Writing mesh to output path {}", output_path); @@ -138,7 +151,7 @@ void build_and_save( // metadata["texture_bounds"] = fmt::format( // "{{ \"min\": {{ \"x\": {}, \"y\": {} }}, \"max\": {{ \"x\": {}, \"y\": {} }} }}", // texture_bounds.min.x, texture_bounds.min.y, texture_bounds.max.x, texture_bounds.max.y); - if (!::mesh::io::save_to_path(mesh, output_path, ::mesh::io::SaveOptions{.metadata = metadata}).has_value()) { + if (!mesh::io::save_to_path(mesh, output_path, mesh::io::SaveOptions{.metadata = metadata}).has_value()) { LOG_ERROR("Failed to save mesh to file {}", output_path); exit(2); } @@ -146,4 +159,144 @@ void build_and_save( LOG_INFO("Done", output_path); } +namespace { +template +T expect(const std::optional &opt, const std::string &msg) { + if (!opt) { + LOG_ERROR_AND_EXIT(msg); + } + return *opt; +} +} + +void build_all_patches( + Dataset &dataset, + const octree::Id::Level target_level, + const OGRSpatialReference &texture_srs, + const std::optional &texture_base_path, + const OGRSpatialReference &mesh_srs, + const std::filesystem::path &output_base_path, + const std::string &output_format) { + if (!std::filesystem::exists(output_base_path)) { + LOG_TRACE("Output base path {} does not exist, creating it", output_base_path); + std::filesystem::create_directories(output_base_path); + } else if (!std::filesystem::is_directory(output_base_path)) { + LOG_ERROR_AND_EXIT("Output base path {} exists but is not a directory", output_base_path); + } + + octree::Storage storage = octree::open_folder( + output_base_path, + octree::disk::layout::strategy::make_default(), + output_format); + + const auto dataset_srs = dataset.srs(); + const auto dataset_bounds = dataset.bounds3d(true); + + const auto ecef_srs = srs::ecef(); + const auto ecef_bounds = srs::encompassing_bounds_transfer( + dataset_srs, ecef_srs, dataset_bounds); + const auto space = octree::Space::earth(); + const auto root_node = expect( + space.find_smallest_node_encompassing_bounds(ecef_bounds), + "Dataset is outside the octree root node."); + + tbb::concurrent_vector concurrent_targets; + + tbb::task_group tg; + std::function process_node; + + tbb::enumerable_thread_specific> transform_ecef_dataset([&]() { + auto local_ecef_srs = ecef_srs; + auto local_dataset_srs = dataset_srs; + auto transform = srs::transformation(local_ecef_srs, local_dataset_srs); + return transform; + }); + + process_node = [&](octree::Id node) { + const auto node_bounds = space.get_node_bounds(node); + const auto node_bounds_dataset_srs = srs::encompassing_bounds_transfer( + &*transform_ecef_dataset.local(), node_bounds); + + if (!radix::geometry::intersect(node_bounds_dataset_srs, dataset_bounds)) { + return; + } + + if (node.level() < target_level) { + if (auto children = node.children(); children.has_value()) { + for (const auto &child : *children) { + tg.run([&, child] { process_node(child); }); + } + } + } else if (node.level() == target_level) { + concurrent_targets.push_back(node); + } + }; + + tg.run([&] { process_node(root_node); }); + tg.wait(); // Wait for all tasks + + std::vector target_nodes; + target_nodes.assign(concurrent_targets.begin(), concurrent_targets.end()); + + ProgressIndicator progress(target_nodes.size()); + std::jthread progress_thread = progress.start_monitoring(); + + tbb::enumerable_thread_specific local_dataset([&]() { + return dataset.clone(); + }); + tbb::enumerable_thread_specific> local_ecef_srs([&]() { + return srs::clone(ecef_srs); + }); + tbb::enumerable_thread_specific> local_texture_srs([&]() { + return srs::clone(texture_srs); + }); + tbb::enumerable_thread_specific> local_mesh_srs([&]() { + return srs::clone(mesh_srs); + }); + + // Decrease log level to error to avoid excessive logging during mesh building + auto logger = Log::get_logger(); + const auto original_level = logger->level(); + const auto new_level = spdlog::level::err; + // Only set to if it's more restrictive than current level + if (new_level >= original_level) { + logger->set_level(new_level); + } + + tbb::parallel_for(size_t(0), target_nodes.size(), [&](size_t i) { + const auto &node = target_nodes[i]; + if (storage.has_node(node)) { + progress.task_finished(); // TODO: correctly handle virtual nodes + return; + } + + auto &dataset = local_dataset.local(); + auto &ecef_srs = *local_ecef_srs.local(); + auto &texture_srs = *local_texture_srs.local(); + auto &mesh_srs = *local_mesh_srs.local(); + + const auto node_bounds = space.get_node_bounds(node); + auto mesh_result = terrainbuilder::build_patch( + dataset, + ecef_srs, + node_bounds, + texture_srs, + texture_base_path, + mesh_srs); + + if (mesh_result.has_value()) { + const auto mesh = std::move(mesh_result.value()); + mesh::validate(mesh); + storage.write_node(node, mesh); + } + + progress.task_finished(); + }); + + // Restore original level + logger->set_level(original_level); + + progress_thread.join(); + storage.save_or_create_index(); +} } diff --git a/src/terrainbuilder/terrainbuilder.h b/src/terrainbuilder/terrainbuilder.h index 59c9e53..e295072 100644 --- a/src/terrainbuilder/terrainbuilder.h +++ b/src/terrainbuilder/terrainbuilder.h @@ -1,16 +1,16 @@ -#ifndef TERRAINBUILDER_H -#define TERRAINBUILDER_H +#pragma once #include #include #include "Dataset.h" +#include "octree/Id.h" #include "mesh/SimpleMesh.h" namespace terrainbuilder { -void build_and_save( +void build_and_save_patch( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -19,7 +19,7 @@ void build_and_save( const OGRSpatialReference &mesh_srs, const std::filesystem::path &output_path); -SimpleMesh build( +std::optional build_patch( Dataset &dataset, const OGRSpatialReference &target_bounds_srs, const radix::geometry::Aabb3d &target_bounds, @@ -27,6 +27,12 @@ SimpleMesh build( const std::optional texture_base_path, const OGRSpatialReference &mesh_srs); +void build_all_patches( + Dataset &dataset, + const octree::Id::Level target_level, + const OGRSpatialReference &texture_srs, + const std::optional &texture_base_path, + const OGRSpatialReference &mesh_srs, + const std::filesystem::path &output_base_path, + const std::string &output_format); } - -#endif diff --git a/src/terrainbuilder/texture_assembler.h b/src/terrainbuilder/texture_assembler.h index 7fee053..e326e0c 100644 --- a/src/terrainbuilder/texture_assembler.h +++ b/src/terrainbuilder/texture_assembler.h @@ -1,5 +1,4 @@ -#ifndef TEXTUREASSEMBLER_H -#define TEXTUREASSEMBLER_H +#pragma once #include #include @@ -19,7 +18,7 @@ #include "tile_provider.h" #include "log.h" -namespace terrainbuilder::texture { +namespace terrainbuilder { /// Estimates the zoom level of the target bounds in relation to some reference tile given by its zoom level and bounds. [[nodiscard]] unsigned int estimate_zoom_level( @@ -29,7 +28,7 @@ namespace terrainbuilder::texture { const glm::dvec2 relative_size = reference_tile_bounds.size() / target_bounds.size(); const double relative_factor = (relative_size.x + relative_size.y) / 2; const int zoom_level_change = std::rint(std::log2(relative_factor)); - assert(static_cast(reference_zoom_level) + zoom_level_change >= 0); + DEBUG_ASSERT(static_cast(reference_zoom_level) + zoom_level_change >= 0); return reference_zoom_level + zoom_level_change; } @@ -208,7 +207,7 @@ std::optional try_get_tile_path(const radix::tile::Id til for (const radix::tile::Id &tile : tiles_to_splatter) { max_zoom_level = std::max(tile.zoom_level, max_zoom_level); } - assert(max_zoom_level >= root_tile.zoom_level); + DEBUG_ASSERT(max_zoom_level >= root_tile.zoom_level); const unsigned int zoom_level_range = max_zoom_level - root_tile.zoom_level; // Choose any tile to load infer like tile size and format to allocate our texture buffer accordingly. @@ -247,7 +246,7 @@ std::optional try_get_tile_path(const radix::tile::Id til // Pixel bounds of this image relative to the root tile. const radix::geometry::Aabb2ui pixel_tile_bounds = calculate_pixel_tile_bounds(tile, root_tile, tile_image_size, max_zoom_level); - assert(glm::all(glm::greaterThanEqual(pixel_tile_bounds.size(), current_tile_image_size))); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(pixel_tile_bounds.size(), current_tile_image_size))); // Pixel bounds relative to the target image texture region. const glm::ivec2 tile_target_position = glm::ivec2(pixel_tile_bounds.min) - glm::ivec2(target_image_region.min); @@ -285,8 +284,7 @@ std::optional try_get_tile_path(const radix::tile::Id til const radix::tile::SrsBounds encompassing_bounds = srs::encompassing_bounds_transfer(target_srs, grid.getSRS(), target_bounds); // Then we find the smallest tile (id) that encompasses these bounds. const radix::tile::Id smallest_encompassing_tile = grid.findSmallestEncompassingTile(encompassing_bounds).value().to(radix::tile::Scheme::SlippyMap); - LOG_TRACE("Smallest encompassing tile for texture bounds is [{}, ({}, {})]", - smallest_encompassing_tile.zoom_level, smallest_encompassing_tile.coords.x, smallest_encompassing_tile.coords.y); + LOG_TRACE("Smallest encompassing tile for texture bounds is {}", radix::tile::to_string(smallest_encompassing_tile)); if (max_zoom.has_value() && smallest_encompassing_tile.zoom_level > max_zoom.value()) { return std::nullopt; @@ -306,6 +304,5 @@ std::optional try_get_tile_path(const radix::tile::Id til // Splatter tiles into texture buffer return splatter_tiles_to_texture(smallest_encompassing_tile, grid, encompassing_bounds, tile_provider, tiles_to_splatter, rescale_filter); } -} -#endif +} diff --git a/src/terrainconvert/cli.cpp b/src/terrainconvert/cli.cpp index 4d9ee3c..d2d191b 100644 --- a/src/terrainconvert/cli.cpp +++ b/src/terrainconvert/cli.cpp @@ -5,7 +5,7 @@ using namespace cli; Args cli::parse(int argc, const char * const* argv) { - assert(argc >= 0); + DEBUG_ASSERT(argc >= 0); CLI::App app{"terrainconvert"}; std::filesystem::path input_path; diff --git a/src/terrainlib/Dataset.cpp b/src/terrainlib/Dataset.cpp index 2145a6c..c6d2b76 100644 --- a/src/terrainlib/Dataset.cpp +++ b/src/terrainlib/Dataset.cpp @@ -26,6 +26,7 @@ #include #include +#include #include "ctb/Grid.hpp" #include "init.h" @@ -40,21 +41,21 @@ static GDALDataset *open_gdal_dataset(const std::filesystem::path &path, unsigne std::optional Dataset::open_raster(std::filesystem::path path) { if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_RASTER)) { - return std::optional(Dataset(path, dataset)); + return std::optional(std::move(Dataset(path, dataset))); } LOG_ERROR("Couldn't open raster dataset {}.\n", path); return std::nullopt; } std::optional Dataset::open_vector(std::filesystem::path path) { if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_VECTOR)) { - return std::optional(Dataset(path, dataset)); + return std::optional(std::move(Dataset(path, dataset))); } LOG_ERROR("Couldn't open vector dataset {}.\n", path); return std::nullopt; } std::optional> Dataset::open_shared_raster(std::filesystem::path path) { if (GDALDataset *dataset = open_gdal_dataset(path, GDAL_OF_RASTER | GDAL_OF_SHARED | GDAL_OF_THREAD_SAFE)) { - return std::make_shared(Dataset(path, dataset)); + return std::make_shared(std::move(Dataset(path, dataset))); } LOG_ERROR("Couldn't open shared raster dataset {}.\n", path); return std::nullopt; @@ -82,8 +83,9 @@ Dataset::Dataset(const std::filesystem::path path, GDALDataset *dataset) : Datas } Dataset Dataset::clone() { + LOG_TRACE("Cloning dataset {}.", m_path.has_value() ? m_path->string() : "unknown"); if (!m_path.has_value()) { - LOG_ERROR("Cannot clone dataset.\n"); + LOG_ERROR("Cannot clone dataset."); throw std::runtime_error("Cannot clone dataset."); } return Dataset(this->m_path.value()); @@ -135,8 +137,8 @@ radix::tile::SrsAndHeightBounds Dataset::bounds3d(bool approx_ok) const { glm::dvec2 height_range; if (!band->GetStatistics(approx_ok, false, &height_range.x, &height_range.y, nullptr, nullptr)) { const char *unit = band->GetUnitType(); - assert(unit != nullptr); - assert(strcmp(unit, "m") || strcmp(unit, "meters")); + DEBUG_ASSERT(unit != nullptr); + DEBUG_ASSERT(strcmp(unit, "m") || strcmp(unit, "meters")); height_range = {-11000.0, 9000.0}; // Mariana Trench and Mount Everest } @@ -190,8 +192,8 @@ radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) con throw std::string("Could not transform dataset bounds to target SRS"); } - assert(!x.empty()); - assert(!y.empty()); + DEBUG_ASSERT(!x.empty()); + DEBUG_ASSERT(!y.empty()); const double target_minX = *std::min_element(x.begin(), x.end()); const double target_maxX = *std::max_element(x.begin(), x.end()); const double target_minY = *std::min_element(y.begin(), y.end()); @@ -201,8 +203,9 @@ radix::tile::SrsBounds Dataset::bounds(const OGRSpatialReference &targetSrs) con OGRSpatialReference Dataset::srs() const { const char *srcWKT = m_gdal_dataset->GetProjectionRef(); - if (!strlen(srcWKT)) + if (!strlen(srcWKT)) { throw std::runtime_error("The source dataset does not have a spatial reference system assigned"); + } auto srs = OGRSpatialReference(srcWKT); srs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); return srs; @@ -226,7 +229,7 @@ double Dataset::heightInPixels(const radix::tile::SrsBounds &bounds, const OGRSp unsigned Dataset::n_bands() const { const auto n = m_gdal_dataset->GetRasterCount(); - assert(n >= 0); + DEBUG_ASSERT(n >= 0); return unsigned(n); } diff --git a/src/terrainlib/Dataset.h b/src/terrainlib/Dataset.h index 74c1c50..9868bb4 100644 --- a/src/terrainlib/Dataset.h +++ b/src/terrainlib/Dataset.h @@ -25,13 +25,11 @@ #include #include +#include "log.h" class GDALDataset; class OGRSpatialReference; -class Dataset; -using DatasetPtr = std::shared_ptr; - class Dataset { public: Dataset(std::filesystem::path path); @@ -67,7 +65,6 @@ class Dataset { private: Dataset(const std::filesystem::path path, GDALDataset *dataset); - std::unique_ptr m_gdal_dataset; std::optional m_path; }; diff --git a/src/terrainlib/OnceCell.h b/src/terrainlib/OnceCell.h deleted file mode 100644 index f95dbfa..0000000 --- a/src/terrainlib/OnceCell.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include -#include - -template -class OnceCell { -public: - OnceCell() = default; - OnceCell(T value) { - this->_value = std::move(value); - } - - // Returns true if the value was set; false if already initialized - T& set(T value) { - if (this->_value.has_value()) { - return *this->_value; - } - this->_value = std::move(value); - return *this->_value; - } - const T& set(T value) const { - if (this->_value.has_value()) { - return *this->_value; - } - this->_value = std::move(value); - return *this->_value; - } - - // Lazily initialize value using init_fn if not already set - template - const T& get_or_init(F&& init_fn) const { - if (!this->_value.has_value()) { - this->_value = init_fn(); - } - return *this->_value; - } - - T* get() { - return this->_value ? &*this->_value : nullptr; - } - const T* get() const { - return this->_value ? &*this->_value : nullptr; - } - - bool is_initialized() const { - return this->_value.has_value(); - } - -private: - mutable std::optional _value; -}; diff --git a/src/terrainlib/OnceLock.h b/src/terrainlib/OnceLock.h deleted file mode 100644 index b187bce..0000000 --- a/src/terrainlib/OnceLock.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -class OnceLock { -public: - OnceLock() = default; - OnceLock(const OnceLock&) = delete; - OnceLock& operator=(const OnceLock&) = delete; - - // Initialize with a value (if not already set) - bool set(T value) { - if (this->is_initialized()) { - return false; // Already initialized - } - bool initialized = false; - std::call_once(this->_init_flag, [this, &value, &initialized]() { - this->_value.emplace(std::move(value)); - initialized = true; - }); - return initialized; - } - - // Lazily initialize using a function - template - const T& get_or_init(F&& init_fn) const { - std::call_once(this->_init_flag, [this, &init_fn]() { - this->_value.emplace(init_fn()); - }); - return *this->_value; - } - - // Get without initializing (returns nullptr if uninitialized) - const T* get() const { - return this->_value ? &*this->_value : nullptr; - } - - bool is_initialized() const { - return this->_value.has_value(); - } - -private: - mutable std::optional _value; - mutable std::once_flag _init_flag; -}; diff --git a/src/terrainlib/ProgressIndicator.cpp b/src/terrainlib/ProgressIndicator.cpp index 1383aaf..ce1e67a 100644 --- a/src/terrainlib/ProgressIndicator.cpp +++ b/src/terrainlib/ProgressIndicator.cpp @@ -25,6 +25,7 @@ #include #include +#include using namespace std::literals; @@ -66,11 +67,11 @@ std::jthread ProgressIndicator::start_monitoring() const { } std::string ProgressIndicator::progress_bar(const uint32_t bar_width) const { - assert(bar_width >= 2); + DEBUG_ASSERT(bar_width >= 2); const auto inner_bar_width = bar_width - 2; const auto step = m_step.load(); const auto progress = step > 0 ? inner_bar_width * step / m_n_steps : 0; - assert(progress <= bar_width); + DEBUG_ASSERT(progress <= bar_width); std::ostringstream oss; oss << "["; diff --git a/src/terrainlib/hash_utils.h b/src/terrainlib/hash_utils.h index 8f7866d..95b97cf 100644 --- a/src/terrainlib/hash_utils.h +++ b/src/terrainlib/hash_utils.h @@ -1,14 +1,16 @@ #pragma once +namespace hash { + namespace { // from https://github.com/boostorg/container_hash/blob/ee5285bfa64843a11e29700298c83a37e3132fcd/include/boost/container_hash/detail/hash_mix.hpp#L17 -template -struct hash_mix_impl; +template +struct mix_impl; template <> -struct hash_mix_impl<64> { - inline static std::uint64_t fn(std::uint64_t x) { - std::uint64_t const m = 0xe9846af9b1a615d; +struct mix_impl<64> { + inline static uint64_t fn(uint64_t x) { + uint64_t const m = 0xe9846af9b1a615d; x ^= x >> 32; x *= m; @@ -21,10 +23,10 @@ struct hash_mix_impl<64> { }; template <> -struct hash_mix_impl<32> { - inline static std::uint32_t fn(std::uint32_t x) { - std::uint32_t const m1 = 0x21f0aaad; - std::uint32_t const m2 = 0x735a2d97; +struct mix_impl<32> { + inline static uint32_t fn(uint32_t x) { + uint32_t const m1 = 0x21f0aaad; + uint32_t const m2 = 0x735a2d97; x ^= x >> 16; x *= m1; @@ -36,27 +38,33 @@ struct hash_mix_impl<32> { } }; -inline std::size_t hash_mix(std::size_t v) { - return hash_mix_impl::fn(v); +inline size_t mix(size_t v) { + return mix_impl::fn(v); +} +} + +constexpr size_t default_seed() { + return 0x9e3779b9; } // from https://github.com/boostorg/container_hash/blob/ee5285bfa64843a11e29700298c83a37e3132fcd/include/boost/container_hash/hash.hpp#L468 template -inline void hash_combine_core(std::size_t &seed, const T &v) { - seed = hash_mix(seed + 0x9e3779b9 + std::hash()(v)); +inline void append(size_t &seed, const T &v) { + seed = mix(seed + 0x9e3779b9 + std::hash()(v)); } // modified from https://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x/57595105#57595105 template -void hash_combine_core(std::size_t &seed, const T &v, const Rest &...rest) { - seed = hash_mix(seed, v); - (hash_combine_core(seed, rest), ...); -} +void append(size_t &seed, const T &v, const Rest &...rest) { + seed = mix(seed, v); + (append(seed, rest), ...); } template -size_t hash_combine(const Rest &...rest) { - size_t h = 0x9e3779b9; - (hash_combine_core(h, rest), ...); +size_t combine(const Rest &...rest) { + size_t h = default_seed(); + (append(h, rest), ...); return h; } + +} diff --git a/src/terrainlib/io/Error.h b/src/terrainlib/io/Error.h index b306e60..be85f51 100644 --- a/src/terrainlib/io/Error.h +++ b/src/terrainlib/io/Error.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "log.h" diff --git a/src/terrainlib/io/serialize.h b/src/terrainlib/io/serialize.h index 05a72e6..55919e2 100644 --- a/src/terrainlib/io/serialize.h +++ b/src/terrainlib/io/serialize.h @@ -4,6 +4,8 @@ #include #include +#include + #include "io/Error.h" namespace io { diff --git a/src/terrainlib/log.h b/src/terrainlib/log.h index 3d80488..701d107 100644 --- a/src/terrainlib/log.h +++ b/src/terrainlib/log.h @@ -4,6 +4,7 @@ #define SPDLOG_FMT_EXTERNAL #define FMT_HEADER_ONLY #endif +#include "log_impls.h" #include #include @@ -11,8 +12,7 @@ class Log { private: static std::shared_ptr logger; public: - static void init(spdlog::level::level_enum logLevel); - + static void init(spdlog::level::level_enum level); inline static std::shared_ptr& get_logger() { if (Log::logger == nullptr) { Log::init(spdlog::level::level_enum::info); @@ -31,7 +31,8 @@ class Log { LOG_ERROR(__VA_ARGS__); \ exit(1); \ } while (false) - + +/* #if __cplusplus >= 202302L #define _UNREACHABLE() std::unreachable() #elif defined(__GNUC__) || defined(__clang__) @@ -47,5 +48,4 @@ class Log { LOG_ERROR("Reached unreachable code at %s:%d", __FILE__, __LINE__); \ _UNREACHABLE(); \ } while (0) - -#include "log_impls.h" +*/ diff --git a/src/terrainlib/log_impls.h b/src/terrainlib/log_impls.h index 791dcf0..a7eb543 100644 --- a/src/terrainlib/log_impls.h +++ b/src/terrainlib/log_impls.h @@ -2,11 +2,13 @@ #include #include +#include #include +namespace fmt { template <> -struct fmt::formatter { +struct formatter { template constexpr auto parse(ParseContext &ctx) { return ctx.begin(); @@ -19,7 +21,7 @@ struct fmt::formatter { }; template -struct fmt::formatter> { +struct formatter> { template constexpr auto parse(ParseContext &ctx) { return ctx.begin(); @@ -30,3 +32,17 @@ struct fmt::formatter> { return fmt::format_to(ctx.out(), "{}", glm::to_string(vec)); } }; + +template +struct formatter> { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const radix::geometry::Aabb &aabb, FormatContext &ctx) { + return fmt::format_to(ctx.out(), "[{}-{}]", glm::to_string(aabb.min), glm::to_string(aabb.max)); + } +}; +} \ No newline at end of file diff --git a/src/terrainlib/mesh/SimpleMesh.h b/src/terrainlib/mesh/SimpleMesh.h index e20c559..7807ce3 100644 --- a/src/terrainlib/mesh/SimpleMesh.h +++ b/src/terrainlib/mesh/SimpleMesh.h @@ -7,28 +7,29 @@ #include #include -class SimpleMesh { +template +class SimpleMesh_ { public: using Triangle = glm::uvec3; using Edge = glm::uvec2; - using Position = glm::dvec3; - using Uv = glm::dvec2; + using Position = glm::vec; + using Uv = glm::vec<2, T>; using Texture = cv::Mat; using serialize = zpp::bits::members<4>; - SimpleMesh(std::vector triangles, std::vector positions) - : SimpleMesh(triangles, positions, {}) {} - SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs) - : SimpleMesh(triangles, positions, uvs, std::nullopt) {} - SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) - : SimpleMesh(triangles, positions, uvs, std::optional(std::move(texture))) {} - SimpleMesh(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) + SimpleMesh_(std::vector triangles, std::vector positions) + : SimpleMesh_(triangles, positions, {}) {} + SimpleMesh_(std::vector triangles, std::vector positions, std::vector uvs) + : SimpleMesh_(triangles, positions, uvs, std::nullopt) {} + SimpleMesh_(std::vector triangles, std::vector positions, std::vector uvs, Texture texture) + : SimpleMesh_(triangles, positions, uvs, std::optional(std::move(texture))) {} + SimpleMesh_(std::vector triangles, std::vector positions, std::vector uvs, std::optional texture) : triangles(triangles), positions(positions), uvs(uvs), texture(std::move(texture)) {} - SimpleMesh() = default; - SimpleMesh(SimpleMesh &&) = default; - SimpleMesh &operator=(SimpleMesh &&) = default; - SimpleMesh(const SimpleMesh &) = default; - SimpleMesh &operator=(const SimpleMesh &) = default; + SimpleMesh_() = default; + SimpleMesh_(SimpleMesh_ &&) = default; + SimpleMesh_ &operator=(SimpleMesh_ &&) = default; + SimpleMesh_(const SimpleMesh_ &) = default; + SimpleMesh_ &operator=(const SimpleMesh_ &) = default; std::vector triangles; std::vector positions; @@ -52,3 +53,8 @@ class SimpleMesh { return this->texture.has_value(); } }; + +using SimpleMesh3d = SimpleMesh_<3, double>; +using SimpleMesh2d = SimpleMesh_<2, double>; + +using SimpleMesh = SimpleMesh3d; diff --git a/src/terrainlib/mesh/boolean.cpp b/src/terrainlib/mesh/boolean.cpp new file mode 100644 index 0000000..e302121 --- /dev/null +++ b/src/terrainlib/mesh/boolean.cpp @@ -0,0 +1,32 @@ + +#include + +#include "mesh/boolean.h" +#include "mesh/convert.h" +#include "mesh/cgal.h" + +using namespace mesh; + +IntersectionAndDifference mesh::intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b) { + cgal::SurfaceMesh cgal_a = convert::to_cgal_mesh(a); + cgal::SurfaceMesh cgal_b = convert::to_cgal_mesh(b); + + cgal::SurfaceMesh cgal_intersection; + cgal::SurfaceMesh cgal_difference; + std::array, 4> cgal_out; + const size_t intersection_index = CGAL::Polygon_mesh_processing::Corefinement::Boolean_operation_type::INTERSECTION; + const size_t difference_index = CGAL::Polygon_mesh_processing::Corefinement::Boolean_operation_type::TM1_MINUS_TM2; + cgal_out[intersection_index] = &cgal_intersection; + cgal_out[difference_index] = &cgal_difference; + + const std::array cgal_result = + CGAL::Polygon_mesh_processing::corefine_and_compute_boolean_operations(cgal_a, cgal_b, cgal_out); + if (!cgal_result[intersection_index] || !cgal_result[difference_index]) { + throw std::runtime_error("corefine_and_compute_boolean_operations failed"); + } + + IntersectionAndDifference result; + result.intersection = convert::to_simple_mesh(cgal_intersection); + result.difference = convert::to_simple_mesh(cgal_difference); + return result; +} diff --git a/src/terrainlib/mesh/boolean.h b/src/terrainlib/mesh/boolean.h new file mode 100644 index 0000000..9650c63 --- /dev/null +++ b/src/terrainlib/mesh/boolean.h @@ -0,0 +1,13 @@ +#pragma once + +#include "mesh/SimpleMesh.h" + +namespace mesh { + +struct IntersectionAndDifference { + SimpleMesh intersection; + SimpleMesh difference; // a - b +}; +IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b); + +} diff --git a/src/terrainlib/mesh/cgal.h b/src/terrainlib/mesh/cgal.h index 5a76b2d..b2bb9d4 100644 --- a/src/terrainlib/mesh/cgal.h +++ b/src/terrainlib/mesh/cgal.h @@ -1,19 +1,20 @@ #pragma once -#include -#include #include #include +#include +#include namespace cgal { -#define DEFINE_KERNEL(K) \ - using Kernel = K; \ - using Point2 = Kernel::Point_2; \ - using Point3 = Kernel::Point_3; \ - using SurfaceMesh = CGAL::Surface_mesh; \ - using VertexDescriptor = boost::graph_traits::vertex_descriptor; \ +#define DEFINE_KERNEL(K) \ + using Kernel = K; \ + using Point2 = Kernel::Point_2; \ + using Point3 = Kernel::Point_3; \ + using SurfaceMesh = CGAL::Surface_mesh; \ + using VertexIndex = SurfaceMesh::Vertex_index; \ + using VertexDescriptor = boost::graph_traits::vertex_descriptor; \ using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; \ - using EdgeDescriptor = boost::graph_traits::edge_descriptor; \ + using EdgeDescriptor = boost::graph_traits::edge_descriptor; \ using FaceDescriptor = boost::graph_traits::face_descriptor; namespace kernel { diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index 8210e04..7de10d0 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -2,10 +2,12 @@ #include #include #include +#include +#include #include +#include #include -#include #include "hash_utils.h" #include "log.h" @@ -13,6 +15,7 @@ #include "mesh/utils.h" #include "mesh/cgal.h" #include "mesh/convert.h" +#include "mesh/validate.h" namespace { double significant_above_epsilon(double x, double epsilon) { @@ -20,7 +23,8 @@ double significant_above_epsilon(double x, double epsilon) { return x - residual; } -bool is_degenerate(std::array triangle) { +template +bool is_degenerate(const T& triangle) { return triangle[0] == triangle[1] || triangle[1] == triangle[2] || triangle[2] == triangle[0]; } @@ -28,7 +32,7 @@ struct DVec3Hash { const double epsilon; std::size_t operator()(const glm::dvec3 &v) const { - return hash_combine( + return hash::combine( significant_above_epsilon(v.x, epsilon), significant_above_epsilon(v.y, epsilon), significant_above_epsilon(v.z, epsilon)); @@ -42,15 +46,42 @@ struct DVec3Equal { return glm::all(glm::epsilonEqual(a, b, epsilon)); } }; + +template +struct Intersection { + glm::tvec3 point; + T t; // The parameter value along the line at which the intersection occurs +}; + +// Copy of radix::geometry::intersection function that outputs the t value. +template +std::optional> compute_intersection(const radix::geometry::Line<3, T> &line, const radix::geometry::Plane &plane) { + const auto dot = glm::dot(plane.normal, line.direction); + if (std::abs(dot) < radix::geometry::epsilon) { + return {}; + } + const T t = (-plane.distance - glm::dot(plane.normal, line.point)) / dot; + return Intersection(line.point + t * line.direction, t); +} + +// Copy of radix::geometry::intersection function that outputs the t value. +template +Intersection compute_intersection(const radix::geometry::Edge<3, T> &line, const radix::geometry::Plane &plane) { + const auto direction = line[1] - line[0]; + return compute_intersection(radix::geometry::Line{line[0], direction}, plane).value(); +} + } // namespace SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { - assert(mesh.has_uvs() == false && "Clipping a mesh with UVs is not supported yet."); - if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { return {}; } + if (mesh.has_uvs() && mesh.uvs.size() != mesh.vertex_count()) { + LOG_ERROR_AND_EXIT("Mesh has Uvs, but the number of Uvs does not match the number of vertices."); + } + // Construct 6 axis-aligned clipping planes from the bounding box using Plane = radix::geometry::Plane; const std::array planes = { @@ -64,6 +95,8 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A std::vector new_positions; new_positions.reserve(mesh.vertex_count()); + std::vector new_uvs; + new_uvs.reserve(mesh.uvs.size()); std::vector new_triangles; new_triangles.reserve(mesh.face_count()); @@ -71,13 +104,16 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A const double average_edge_length = estimate_average_edge_length(mesh, 100).value(); const double epsilon = average_edge_length / 1000; std::unordered_map seen_vertices(mesh.positions.size(), DVec3Hash(epsilon), DVec3Equal(epsilon)); - auto add_intersection_vertex = [&](const glm::dvec3& vertex) { + auto add_intersection_vertex = [&](const glm::dvec3& vertex, const glm::dvec2 &Uv) { const auto it = seen_vertices.find(vertex); if (it != seen_vertices.cend()) { return it->second; } else { const uint32_t vertex_index = new_positions.size(); new_positions.push_back(vertex); + if (mesh.has_uvs()) { + new_uvs.push_back(Uv); + } seen_vertices.emplace(vertex, vertex_index); return vertex_index; } @@ -91,6 +127,9 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A if (mapped == invalid_index) { mapped = new_positions.size(); new_positions.emplace_back(vertex); + if (mesh.has_uvs()) { + new_uvs.emplace_back(mesh.uvs[original_index]); + } } return mapped; }; @@ -100,6 +139,7 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A struct TriangleAndVertices { glm::uvec3 original_indices; // Indices of the vertices in the original mesh std::array vertices; + std::array uvs; uint8_t next_plane_to_clip; // Count which planes have already clipped this triangle }; std::vector triangles_left_to_clip; @@ -108,7 +148,7 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A // Iterate over each triangle in the mesh for (const glm::uvec3 &source_triangle : mesh.triangles) { // Get the positions for the current triangle - std::array source_vertices = { + const std::array source_vertices = { mesh.positions[source_triangle.x], mesh.positions[source_triangle.y], mesh.positions[source_triangle.z]}; @@ -135,8 +175,16 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A continue; } + const std::array source_uvs = mesh.has_uvs() ? std::array{ + mesh.uvs[source_triangle.x], + mesh.uvs[source_triangle.y], + mesh.uvs[source_triangle.z]} : std::array{ + glm::dvec2(0.0, 0.0), + glm::dvec2(0.0, 0.0), + glm::dvec2(0.0, 0.0)}; + // Slow path: Clip triangle against all planes - TriangleAndVertices current_triangle_and_vertices = {source_triangle, source_vertices, 0}; + TriangleAndVertices current_triangle_and_vertices = {source_triangle, source_vertices, source_uvs, 0}; triangles_left_to_clip.clear(); // This outer loop iterates over the intermediate triangles potentially produced in the 2 inside 1 outside case @@ -144,6 +192,7 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A while (true) { const glm::uvec3 &original_indices = current_triangle_and_vertices.original_indices; const std::array &vertices = current_triangle_and_vertices.vertices; + const std::array &uvs = current_triangle_and_vertices.uvs; bool skip_triangle = false; // Clip the current triangle against all planes @@ -197,21 +246,32 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A const glm::dvec3 outside1_vertex = vertices[outside1_tri_index]; const glm::dvec3 outside2_vertex = vertices[outside2_tri_index]; - const glm::dvec3 intersection1 = radix::geometry::intersection(radix::geometry::Edge{inside_vertex, outside1_vertex}, plane); - const glm::dvec3 intersection2 = radix::geometry::intersection(radix::geometry::Edge{inside_vertex, outside2_vertex}, plane); + const Intersection intersection1 = compute_intersection(radix::geometry::Edge{inside_vertex, outside1_vertex}, plane); + const Intersection intersection2 = compute_intersection(radix::geometry::Edge{inside_vertex, outside2_vertex}, plane); + + // Compute the Uvs for the vertices and intersection points + const glm::dvec2 inside_uv = uvs[inside_tri_index]; + const glm::dvec2 outside1_uv = uvs[outside1_tri_index]; + const glm::dvec2 outside2_uv = uvs[outside2_tri_index]; + const glm::dvec2 intersection1_uv = glm::mix(inside_uv, outside1_uv, intersection1.t); + const glm::dvec2 intersection2_uv = glm::mix(inside_uv, outside2_uv, intersection2.t); // Finally create the new triangle and use it as the current triangle const glm::uvec3 new_triangle( original_indices[inside_tri_index], invalid_index, invalid_index); const std::array new_vertices = { - vertices[inside_tri_index], - intersection1, - intersection2}; + inside_vertex, + intersection1.point, + intersection2.point}; + const std::array new_uvs = { + inside_uv, + intersection1_uv, + intersection2_uv}; if (is_degenerate(new_vertices)) { skip_triangle = true; break; } - current_triangle_and_vertices = {new_triangle, new_vertices, static_cast(plane_index + 1)}; + current_triangle_and_vertices = {new_triangle, new_vertices, new_uvs, static_cast(plane_index + 1)}; } else if (inside_count == 2) { // Two vertices is inside the plane, cut the last one off and split the triangle. @@ -231,8 +291,15 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A const glm::dvec3 inside1_vertex = vertices[inside1_tri_index]; const glm::dvec3 inside2_vertex = vertices[inside2_tri_index]; - const glm::dvec3 intersection1 = radix::geometry::intersection(radix::geometry::Edge{outside_vertex, inside1_vertex}, plane); - const glm::dvec3 intersection2 = radix::geometry::intersection(radix::geometry::Edge{outside_vertex, inside2_vertex}, plane); + const Intersection intersection1 = compute_intersection(radix::geometry::Edge{outside_vertex, inside1_vertex}, plane); + const Intersection intersection2 = compute_intersection(radix::geometry::Edge{outside_vertex, inside2_vertex}, plane); + + // Compute the Uvs for the vertices and intersection points + const glm::dvec2 outside_uv = uvs[outside_tri_index]; + const glm::dvec2 inside1_uv = uvs[inside1_tri_index]; + const glm::dvec2 inside2_uv = uvs[inside2_tri_index]; + const glm::dvec2 intersection1_uv = glm::mix(outside_uv, inside1_uv, intersection1.t); + const glm::dvec2 intersection2_uv = glm::mix(outside_uv, inside2_uv, intersection2.t); // Finally create the new triangles // and use the first one as the current triangle @@ -245,18 +312,34 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A const std::array new_vertices1 = { inside1_vertex, inside2_vertex, - intersection1}; + intersection1.point}; const std::array new_vertices2 = { inside2_vertex, - intersection2, - intersection1}; + intersection2.point, + intersection1.point}; + const std::array new_uvs1 = { + inside1_uv, + inside2_uv, + intersection1_uv}; ; + const std::array new_uvs2 = { + inside2_uv, + intersection2_uv, + intersection1_uv}; + if (is_degenerate(new_vertices2)) { - current_triangle_and_vertices = {new_triangle1, new_vertices1, static_cast(plane_index + 1)}; - } else if (is_degenerate(new_vertices1)) { - current_triangle_and_vertices = {new_triangle2, new_vertices2, static_cast(plane_index + 1)}; + if (is_degenerate(new_vertices1)) { + skip_triangle = true; + break; + } else { + current_triangle_and_vertices = {new_triangle1, new_vertices1, new_uvs1, static_cast(plane_index + 1)}; + } } else { - current_triangle_and_vertices = {new_triangle1, new_vertices1, static_cast(plane_index + 1)}; - triangles_left_to_clip.emplace_back(new_triangle2, new_vertices2, static_cast(plane_index + 1)); + if (is_degenerate(new_vertices1)) { + current_triangle_and_vertices = {new_triangle2, new_vertices2, new_uvs2, static_cast(plane_index + 1)}; + } else { + current_triangle_and_vertices = {new_triangle1, new_vertices1, new_uvs1, static_cast(plane_index + 1)}; + triangles_left_to_clip.emplace_back(new_triangle2, new_vertices2, new_uvs2, static_cast(plane_index + 1)); + } } } else { UNREACHABLE(); @@ -275,14 +358,16 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A const auto &original_vertex_index = original_indices[i]; auto &vertex_index = indices[i]; const auto &vertex = vertices[i]; + const auto &uv = uvs[i]; if (original_vertex_index == invalid_index) { // We have a vertex not in the original mesh -> look up in the spatial hash map - vertex_index = add_intersection_vertex(vertex); + vertex_index = add_intersection_vertex(vertex, uv); } else { // We have a vertex in the original mesh -> look up in the boolean vector vertex_index = add_original_vertex(original_vertex_index, vertex); } } + DEBUG_ASSERT(!is_degenerate(indices)); new_triangles.push_back(indices); // Continue with the next triangle if there are any left to clip @@ -295,20 +380,116 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A } } - return SimpleMesh(new_triangles, new_positions); + const SimpleMesh clipped_mesh(new_triangles, new_positions, new_uvs, mesh.texture); + mesh::validate(clipped_mesh); + return clipped_mesh; +} + +namespace { +template +struct UvInterpolatorVisitor : public CGAL::Polygon_mesh_processing::Corefinement::Default_visitor { + using HalfedgeDescriptor = typename boost::graph_traits::halfedge_descriptor; + using VertexDescriptor = typename boost::graph_traits::vertex_descriptor; + using VertexIndex = typename TriangleMesh::Vertex_index; + + UvMap& uv_map; + + UvInterpolatorVisitor(UvMap& uv_map) : uv_map(uv_map) {} + + std::vector> intersection_uvs; + + /* + VertexDescriptor edge_split_source; + VertexDescriptor edge_split_target; + + // called before the edge of h in tm is split. + // Each subsequent call to edge_split() until the call to after_edge_split() will correspond to the split of that edge. + // If edge_split(h_i, tm) is called for i=1 to n, h_1, h_2, ... ,h_n, h is the sequence of halfedges representing the edge split (with the same initial orientation). + // There is only one call per edge. + void before_edge_split(HalfedgeDescriptor h, const TriangleMesh &tm) { + edge_split_source = tm.source(h); + edge_split_target = tm.target(h); + } + + // called when a new split is done. The target of hnew is a new split vertex. There is only one call per edge. + void edge_split(HalfedgeDescriptor hnew, const TriangleMesh &tm) { + // Calculate t value for the split vertex + const auto old_source_position = tm.point(edge_split_source); + const auto old_target_position = tm.point(edge_split_target); + const auto new_position = tm.point(hnew); + const auto t = glm::distance(new_position, old_source_position) / glm::distance(old_target_position, old_source_position); + + // Interpolate UVs for the split vertex based on the original vertices + const auto old_source_uv = uv_map[edge_split_source]; + const auto old_target_uv = uv_map[edge_split_target]; + const auto new_uv = glm::mix(old_source_uv, old_target_uv, t); + uv_map[tm.target(hnew)] = new_uv; + }*/ + + // called when a new intersection point is detected. + // The intersection is detected using a face of tm_f and an edge of tm_e. + void intersection_point_detected( + size_t i_id, int sdim, + HalfedgeDescriptor h_e, HalfedgeDescriptor h_f, + const TriangleMesh& tm_e, const TriangleMesh& tm_f, bool is_target_coplanar, bool is_source_coplanar) { + DEBUG_ASSERT(i_id == intersection_uvs.size()); + if (tm_e.template property_map("v:uv").has_value()) { + // The edge belongs to the mesh being clipped + intersection_uvs.emplace_back(true, h_e); + } else { + // The edge belongs to the mesh that is clipping + intersection_uvs.emplace_back(false, h_f); + } + } + + void new_vertex_added(size_t i_id, VertexDescriptor vh, const TriangleMesh& tm) { + const auto [is_edge, halfedge] = intersection_uvs[i_id]; + if (is_edge) { + // The vertex was created from an edge being split + const auto source_vertex = tm.source(halfedge); + const auto target_vertex = tm.target(halfedge); + // Calculate t value for the split vertex + const auto old_source_position = convert::to_glm_point(tm.point(source_vertex)); + const auto old_target_position = convert::to_glm_point(tm.point(target_vertex)); + const auto new_position = convert::to_glm_point(tm.point(vh)); + const auto t = glm::distance(new_position, old_source_position) / glm::distance(old_target_position, old_source_position); + // Interpolate UVs for the split vertex based on the original vertices + const auto old_source_uv = uv_map[source_vertex]; + const auto old_target_uv = uv_map[target_vertex]; + const auto new_uv = glm::mix(old_source_uv, old_target_uv, t); + uv_map[vh] = new_uv; + } else { + // The vertex was created inside a face + // TODO: + } + } +}; } SimpleMesh mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh) { - // Convert meshes to CGAL format + using UvMap = cgal::SurfaceMesh::Property_map; + cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); cgal::SurfaceMesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); - // Perform clipping using CGAL - const bool result = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh); - if (!result) { + bool success; + if (mesh.has_uvs()) { + UvMap uv_map = cgal_mesh.property_map("v:uv").value(); + const auto params = CGAL::Polygon_mesh_processing::parameters::visitor( + UvInterpolatorVisitor(uv_map)); + success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); + } else { + success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh); + } + if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); } - // Convert back to SimpleMesh format - return convert::to_simple_mesh(cgal_mesh); + cgal_mesh.collect_garbage(); + SimpleMesh result = convert::to_simple_mesh(cgal_mesh); + if (mesh.has_texture()) { + result.texture = mesh.texture.value(); + } + return result; } + diff --git a/src/terrainlib/mesh/convert.cpp b/src/terrainlib/mesh/convert.cpp index 5b68934..29caa0a 100644 --- a/src/terrainlib/mesh/convert.cpp +++ b/src/terrainlib/mesh/convert.cpp @@ -1,35 +1,43 @@ -#include "convert.h" +#include + +#include "mesh/convert.h" #include "log.h" +#include "mesh/validate.h" using namespace cgal; -glm::dvec3 convert::cgal2glm(Point3 point) { - return glm::dvec3(CGAL::to_double(point[0]), CGAL::to_double(point[1]), CGAL::to_double(point[2])); -} -glm::dvec2 convert::cgal2glm(Point2 point) { - return glm::dvec2(CGAL::to_double(point[0]), CGAL::to_double(point[1])); -} -Point3 convert::glm2cgal(glm::dvec3 point) { - return Point3(point[0], point[1], point[2]); -} -Point2 convert::glm2cgal(glm::dvec2 point) { - return Point2(point[0], point[1]); -} +using UvMap = SurfaceMesh::Property_map; SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { SurfaceMesh cgal_mesh; + const size_t approx_num_edges = (mesh.face_count() * 3) / 2; + cgal_mesh.reserve(mesh.vertex_count(), approx_num_edges, mesh.face_count()); + + UvMap uv_map; + if (mesh.has_uvs()) { + auto [map, inserted] = cgal_mesh.add_property_map("v:uv"); + DEBUG_ASSERT(inserted); + uv_map = std::move(map); + } - for (const glm::dvec3 &position : mesh.positions) { - const CGAL::SM_Vertex_index vertex = cgal_mesh.add_vertex(glm2cgal(position)); - assert(vertex != SurfaceMesh::null_vertex()); + for (size_t index = 0; index < mesh.positions.size(); ++index) { + const glm::dvec3 &position = mesh.positions[index]; + const cgal::VertexIndex vertex = cgal_mesh.add_vertex(to_cgal_point(position)); + DEBUG_ASSERT(vertex != SurfaceMesh::null_vertex()); + if (mesh.has_uvs()) { + const glm::dvec2 &uv = mesh.uvs[index]; + uv_map[vertex] = uv; + } } + mesh::validate(mesh); + for (const glm::uvec3 &triangle : mesh.triangles) { const CGAL::SM_Face_index face = cgal_mesh.add_face( - CGAL::SM_Vertex_index(triangle.x), - CGAL::SM_Vertex_index(triangle.y), - CGAL::SM_Vertex_index(triangle.z)); - assert(face != SurfaceMesh::null_face()); + cgal::VertexIndex(triangle.x), + cgal::VertexIndex(triangle.y), + cgal::VertexIndex(triangle.z)); + DEBUG_ASSERT(face != SurfaceMesh::null_face()); } return cgal_mesh; @@ -38,14 +46,28 @@ SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { SimpleMesh mesh; + auto uv_map_opt = cgal_mesh.property_map("v:uv"); + const bool has_uvs = uv_map_opt.has_value(); + UvMap uv_map; + if (has_uvs) { + uv_map = std::move(uv_map_opt.value()); + } + const size_t vertex_count = CGAL::num_vertices(cgal_mesh); const size_t face_count = CGAL::num_faces(cgal_mesh); mesh.positions.resize(vertex_count); + if (has_uvs) { + mesh.uvs.resize(vertex_count); + } mesh.triangles.reserve(face_count); for (const CGAL::SM_Vertex_index vertex_index : cgal_mesh.vertices()) { const Point3 &position = cgal_mesh.point(vertex_index); - mesh.positions[vertex_index] = cgal2glm(position); + mesh.positions[vertex_index] = to_glm_point(position); + if (has_uvs) { + const glm::dvec2 &uv = uv_map[vertex_index]; + mesh.uvs[vertex_index] = uv; + } } for (const CGAL::SM_Face_index face_index : cgal_mesh.faces()) { diff --git a/src/terrainlib/mesh/convert.h b/src/terrainlib/mesh/convert.h index a4fc255..25a5610 100644 --- a/src/terrainlib/mesh/convert.h +++ b/src/terrainlib/mesh/convert.h @@ -2,16 +2,44 @@ #include -#include "cgal.h" -#include "mesh/SimpleMesh.h" +#include "pch.h" namespace convert { -glm::dvec3 cgal2glm(cgal::Point3 point); -glm::dvec2 cgal2glm(cgal::Point2 point); +namespace { +// Helper to detect if Point has a member function `.z()` +template +struct has_z : std::false_type {}; -cgal::Point3 glm2cgal(glm::dvec3 point); -cgal::Point2 glm2cgal(glm::dvec2 point); +template +struct has_z().z())>> : std::true_type {}; +} + +template ::value, int> = 0> +glm::dvec2 to_glm_point(const Point2 &point) { + return glm::dvec2( + CGAL::to_double(point.x()), + CGAL::to_double(point.y())); +} +template ::value, int> = 0> +glm::dvec3 to_glm_point(const Point3 &point) { + return glm::dvec3( + CGAL::to_double(point.x()), + CGAL::to_double(point.y()), + CGAL::to_double(point.z())); +} + + +template +typename Kernel::Point_3 to_cgal_point(const glm::dvec3 &point) { + return typename Kernel::Point_3(point.x, point.y, point.z); +} +template +typename Kernel::Point_2 to_cgal_point(const glm::dvec2 &point) { + return typename Kernel::Point_2(point.x, point.y); +} cgal::SurfaceMesh to_cgal_mesh(const SimpleMesh& mesh); SimpleMesh to_simple_mesh(const cgal::SurfaceMesh& cgal_mesh); diff --git a/src/terrainlib/mesh/io.cpp b/src/terrainlib/mesh/io.cpp index e69a1c1..c370a05 100644 --- a/src/terrainlib/mesh/io.cpp +++ b/src/terrainlib/mesh/io.cpp @@ -2,9 +2,9 @@ #include "log.h" #include "mesh/io/gltf.h" #include "mesh/io/terrain.h" +#include "mesh/validate.h" -namespace mesh { -namespace io { +namespace mesh::io { tl::expected load_from_path( const std::filesystem::path &path, @@ -25,6 +25,8 @@ tl::expected save_to_path( const SaveOptions &options) { LOG_TRACE("Saving mesh to path {}", path); + mesh::validate(mesh); + const std::filesystem::path extension = path.extension(); if (extension == ".glb" || extension == ".gltf") { return gltf::save_to_path(mesh, path, options); @@ -36,4 +38,3 @@ tl::expected save_to_path( } } -} diff --git a/src/terrainlib/mesh/io.h b/src/terrainlib/mesh/io.h index 82923c8..81fb076 100644 --- a/src/terrainlib/mesh/io.h +++ b/src/terrainlib/mesh/io.h @@ -8,8 +8,7 @@ #include "mesh/io/options.h" #include "mesh/io/error.h" -namespace mesh { -namespace io { +namespace mesh::io { tl::expected load_from_path( const std::filesystem::path &path, @@ -21,4 +20,3 @@ tl::expected save_to_path( const SaveOptions& options = {}); } -} diff --git a/src/terrainlib/mesh/io/gltf.cpp b/src/terrainlib/mesh/io/gltf.cpp index 17ba6eb..2048b7e 100644 --- a/src/terrainlib/mesh/io/gltf.cpp +++ b/src/terrainlib/mesh/io/gltf.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #define CGLTF_IMPLEMENTATION #define CGLTF_WRITE_IMPLEMENTATION @@ -242,7 +243,7 @@ LoadMeshError map_cgltf_error(cgltf_result result) { case cgltf_result::cgltf_result_out_of_memory: return LoadMeshErrorKind::OutOfMemory; default: - assert(false); + UNREACHABLE(); break; } } @@ -283,7 +284,7 @@ tl::expected load_raw_from_path(const std::filesystem::pa return RawMesh(data, cgltf_free); } -tl::expected load_mesh_from_raw(const RawMesh &raw, const LoadOptions& options) { +tl::expected load_mesh_from_raw(const RawMesh &raw, const LoadOptions& /* options */) { LOG_TRACE("Loading mesh from gltf data"); const cgltf_data &data = *raw; @@ -610,7 +611,7 @@ tl::expected save_to_path( std::copy(glm::value_ptr(parent_offset), glm::value_ptr(parent_offset) + parent_offset.length(), parent_node.translation); std::copy(glm::value_ptr(mesh_offset), glm::value_ptr(mesh_offset) + mesh_offset.length(), mesh_node.translation); const glm::dvec3 full_error = (glm::dvec3(parent_parent_offset) + glm::dvec3(parent_offset) + glm::dvec3(mesh_offset)) - average_position; - // assert(glm::length(full_error) == 0); + // DEBUG_ASSERT(glm::length(full_error) == 0); if (full_error != glm::dvec3(0)) { LOG_ERROR("Float transform trick failed (error: {})", glm::length(full_error)); } diff --git a/src/terrainlib/mesh/io/terrain.cpp b/src/terrainlib/mesh/io/terrain.cpp index b0721d5..27f1a52 100644 --- a/src/terrainlib/mesh/io/terrain.cpp +++ b/src/terrainlib/mesh/io/terrain.cpp @@ -1,5 +1,7 @@ #include +#include + #include "log.h" #include "mesh/io/terrain.h" #include "mesh/io/utils.h" @@ -70,7 +72,7 @@ tl::expected load_from_path(const std::filesystem::pa return load_from_buffer(bytes, options); } -tl::expected, SaveMeshError> save_to_buffer(const SimpleMesh &mesh, const SaveOptions& options) { +tl::expected, SaveMeshError> save_to_buffer(const SimpleMesh &mesh, const SaveOptions& /* options */) { LOG_TRACE("Serializing mesh to buffer"); // TODO: this ignores the texture format in SaveOptions @@ -96,7 +98,7 @@ tl::expected, SaveMeshError> save_to_buffer(const SimpleMes return data; } -tl::expected load_from_buffer(const std::span bytes, const LoadOptions &options) { +tl::expected load_from_buffer(const std::span bytes, const LoadOptions & /* options */) { LOG_TRACE("Deserializing mesh from buffer"); zpp::bits::in in(bytes); diff --git a/src/terrainsimplify/merge.cpp b/src/terrainlib/mesh/merge.cpp similarity index 87% rename from src/terrainsimplify/merge.cpp rename to src/terrainlib/mesh/merge.cpp index 5937635..cc995f7 100644 --- a/src/terrainsimplify/merge.cpp +++ b/src/terrainlib/mesh/merge.cpp @@ -1,14 +1,14 @@ #include -#include + +#include #include "mesh/convert.h" #include "log.h" -#include "merge.h" -#include "mesh/SimpleMesh.h" +#include "mesh/merge.h" #include "mesh/utils.h" -#include "validate.h" +#include "mesh/validate.h" -using namespace merge; +using namespace mesh::merge; template static T max_component(const glm::tvec3 &vector) { @@ -20,6 +20,7 @@ static T min_component(const glm::tvec3 &vector) { return glm::min(glm::min(vector.x, vector.y), vector.z); } +// TODO: rewrite using unordered_map? template class Grid3d { public: @@ -28,7 +29,7 @@ class Grid3d { grid_data.resize(divisions.x * divisions.y * divisions.z); } - struct GridCellItem { + struct GridCellItem { glm::dvec3 point; T value; }; @@ -38,7 +39,7 @@ class Grid3d { }; std::optional> find(const glm::dvec3 point, const double epsilon = 0.1f) { - assert(epsilon > 0); + DEBUG_ASSERT(epsilon > 0); if (!is_in_bounds(point)) { return std::nullopt; @@ -54,7 +55,7 @@ class Grid3d { } const glm::dvec3 distance_from_contained_cell_center = point - cell_size * (glm::dvec3(grid_index) + glm::dvec3(0.5)); - if (glm::all(glm::lessThan(distance_from_contained_cell_center + epsilon, cell_size))) { + if (glm::all(glm::lessThan(distance_from_contained_cell_center + epsilon, cell_size))) { // TODO: shouldnt this be cell_size / 2? cell_radius = 0; } @@ -64,12 +65,12 @@ class Grid3d { for (int dx = -cell_radius; dx <= cell_radius; dx++) { for (int dy = -cell_radius; dy <= cell_radius; dy++) { for (int dz = -cell_radius; dz <= cell_radius; dz++) { - glm::ivec3 _neighbor_index = glm::ivec3(grid_index) + glm::ivec3(dx, dy, dz); + const glm::ivec3 _neighbor_index = glm::ivec3(grid_index) + glm::ivec3(dx, dy, dz); if (!this->is_valid_grid_index(_neighbor_index)) { continue; } - glm::uvec3 neighbor_index(_neighbor_index); + const glm::uvec3 neighbor_index(_neighbor_index); const size_t cell_index = this->calculate_cell_index(neighbor_index); GridCell &cell = this->grid_data[cell_index]; @@ -266,46 +267,6 @@ static double estimate_min_vertex_separation_between_meshes_after_merge(const st return std::sqrt(min_squared_distance); } -static double estimate_average_vertex_separation(const SimpleMesh &mesh, const size_t sample_size = 1000) { - std::vector triangles = mesh.triangles; - std::random_shuffle(triangles.begin(), triangles.end()); - - size_t count = std::min(triangles.size(), sample_size); - double average_distance = 0; - for (size_t i = 0; i < count; i++) { - const glm::uvec3 &triangle = triangles[i]; - - const size_t first_index_in_triangle = i % triangle.length(); - const size_t first_index = triangle[first_index_in_triangle]; - const size_t second_index = triangle[(first_index_in_triangle + 1) % triangle.length()]; - - const double distance2 = glm::distance(mesh.positions[first_index], mesh.positions[second_index]); - average_distance += distance2 / count; - } - - return std::sqrt(average_distance); -} - -static double estimate_average_vertex_seperation(const SimpleMesh &mesh, const size_t sample_size = 1000) { - std::vector triangles = mesh.triangles; - std::random_shuffle(triangles.begin(), triangles.end()); - - size_t count = std::min(triangles.size(), sample_size); - double average_distance = 0; - for (size_t i = 0; i < count; i++) { - const glm::uvec3 &triangle = triangles[i]; - - const size_t first_index_in_triangle = i % triangle.length(); - const size_t first_index = triangle[first_index_in_triangle]; - const size_t second_index = triangle[(first_index_in_triangle + 1) % triangle.length()]; - - const double distance2 = glm::distance(mesh.positions[first_index], mesh.positions[second_index]); - average_distance += distance2 / count; - } - - return std::sqrt(average_distance); -} - static double estimate_min_edge_length(const SimpleMesh &mesh) { std::vector triangles = mesh.triangles; std::random_shuffle(triangles.begin(), triangles.end()); @@ -436,7 +397,7 @@ static bool are_all_meshes_merged(const VertexMapping &mapping) { return union_find.is_joint(); } -VertexMapping merge::create_merge_mapping(const std::span meshes) { +VertexMapping mesh::merge::create_merge_mapping(const std::span meshes) { LOG_DEBUG("Finding shared vertices between {} meshes (epsilon=auto)", meshes.size()); const double min_edge_length = std::transform_reduce( @@ -445,6 +406,10 @@ VertexMapping merge::create_merge_mapping(const std::span mesh std::numeric_limits::infinity(), [](const double a, const double b) { return std::min(a, b); }, measure_min_edge_length); // XXX: use approximate_min_edge_length in Release? + if (min_edge_length == std::numeric_limits::infinity()) { + return {}; + } + DEBUG_ASSERT(min_edge_length > 0); double distance_epsilon = min_edge_length / 1000; LOG_TRACE("Starting with distance epsilon of {:g}", distance_epsilon); @@ -458,7 +423,7 @@ VertexMapping merge::create_merge_mapping(const std::span mesh const double min_vertex_separation_after_merge = estimate_min_vertex_separation_between_meshes_after_merge(meshes, mapping); if (min_vertex_separation_after_merge > min_edge_length / 2) { - LOG_TRACE("Found vertices in merged mesh that are much closer than in the source meshes, suggesting and incomplete merge"); + LOG_TRACE("Found vertices in merged mesh that are much closer than in the source meshes, suggesting an incomplete merge"); continue; } @@ -507,7 +472,7 @@ static bool are_all_bounds_connected(const std::span meshes) { return true; } -VertexMapping merge::create_merge_mapping(const std::span meshes, double distance_epsilon) { +VertexMapping mesh::merge::create_merge_mapping(const std::span meshes, double distance_epsilon) { if (meshes.empty()) { return {}; } @@ -564,7 +529,7 @@ VertexMapping merge::create_merge_mapping(const std::span mesh return mapping; } -SimpleMesh merge::apply_mapping(std::span meshes, const merge::VertexMapping &mapping) { +SimpleMesh mesh::merge::apply_mapping(std::span meshes, const mesh::merge::VertexMapping &mapping) { LOG_TRACE("Merging meshes based on mapping"); if (meshes.empty()) { return {}; @@ -599,7 +564,7 @@ SimpleMesh merge::apply_mapping(std::span meshes, const merge: max_vertex_index = std::max(max_vertex_index, mapped_index); } } - assert(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); + DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); merged_mesh.positions.resize(max_vertex_index + 1); if (has_uvs) { merged_mesh.uvs.resize(max_vertex_index + 1); @@ -630,18 +595,18 @@ SimpleMesh merge::apply_mapping(std::span meshes, const merge: LOG_WARN("Not all meshes were merged together"); } - validate_mesh(merged_mesh); - validate_mesh(convert::mesh2cgal(merged_mesh)); + mesh::validate(merged_mesh); + mesh::validate(convert::to_cgal_mesh(merged_mesh)); return merged_mesh; } -SimpleMesh merge::merge_meshes(std::span meshes) { +SimpleMesh mesh::merge::merge_meshes(std::span meshes) { VertexMapping mapping; - return merge::merge_meshes(meshes, mapping); + return mesh::merge::merge_meshes(meshes, mapping); } -SimpleMesh merge::merge_meshes(std::span meshes, merge::VertexMapping &mapping) { +SimpleMesh mesh::merge::merge_meshes(std::span meshes, mesh::merge::VertexMapping &mapping) { switch (meshes.size()) { case 0: return {}; @@ -649,17 +614,17 @@ SimpleMesh merge::merge_meshes(std::span meshes, merge::Vertex mapping = VertexMapping::identity(meshes[0].vertex_count()); return meshes[0]; default: - mapping = merge::create_merge_mapping(meshes); - return merge::apply_mapping(meshes, mapping); + mapping = mesh::merge::create_merge_mapping(meshes); + return mesh::merge::apply_mapping(meshes, mapping); } } -SimpleMesh merge::merge_meshes(std::span meshes, double distance_epsilon) { +SimpleMesh mesh::merge::merge_meshes(std::span meshes, double distance_epsilon) { VertexMapping mapping; - return merge::merge_meshes(meshes, distance_epsilon, mapping); + return mesh::merge::merge_meshes(meshes, distance_epsilon, mapping); } -SimpleMesh merge::merge_meshes(std::span meshes, double distance_epsilon, merge::VertexMapping &mapping) { +SimpleMesh mesh::merge::merge_meshes(std::span meshes, double distance_epsilon, mesh::merge::VertexMapping &mapping) { switch (meshes.size()) { case 0: return {}; @@ -667,7 +632,7 @@ SimpleMesh merge::merge_meshes(std::span meshes, double distan mapping = VertexMapping::identity(meshes[0].vertex_count()); return meshes[0]; default: - mapping = merge::create_merge_mapping(meshes, distance_epsilon); - return merge::apply_mapping(meshes, mapping); + mapping = mesh::merge::create_merge_mapping(meshes, distance_epsilon); + return mesh::merge::apply_mapping(meshes, mapping); } } diff --git a/src/terrainsimplify/merge.h b/src/terrainlib/mesh/merge.h similarity index 84% rename from src/terrainsimplify/merge.h rename to src/terrainlib/mesh/merge.h index d9dfad1..606c5dd 100644 --- a/src/terrainsimplify/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -1,11 +1,13 @@ -#ifndef MERGE_H -#define MERGE_H - -#include "pch.h" +#pragma once #include +#include +#include +#include + +#include "pch.h" -namespace merge { +namespace mesh::merge { struct VertexId { size_t mesh_index; @@ -100,7 +102,7 @@ class VertexMapping { return std::nullopt; } - assert(this->map(VertexId { .mesh_index = mesh_index, .vertex_index = source_vertex.value() }) == mapped_vertex_index); + DEBUG_ASSERT(this->map(VertexId { .mesh_index = mesh_index, .vertex_index = source_vertex.value() }) == mapped_vertex_index); } return source_triangle; @@ -127,20 +129,20 @@ class VertexMapping { void validate() const { for (size_t i = 0; i < this->mesh_count(); i++) { - assert(this->forward[i].size() == this->backward[i].size()); + DEBUG_ASSERT(this->forward[i].size() == this->backward[i].size()); for (size_t j = 0; j < this->forward[i].size(); j++) { const size_t mapped = this->map(VertexId { .mesh_index = i, .vertex_index = j }); const std::optional inv_mapped = this->map_inverse(i, mapped); - assert(inv_mapped.has_value()); - assert(inv_mapped.value() == j); + DEBUG_ASSERT(inv_mapped.has_value()); + DEBUG_ASSERT(inv_mapped.value() == j); } for (const std::pair e : this->backward[i]) { const std::optional inv_mapped = this->map_inverse(i, e.first); - assert(inv_mapped.has_value()); + DEBUG_ASSERT(inv_mapped.has_value()); const size_t mapped = this->map(VertexId{.mesh_index = i, .vertex_index = inv_mapped.value()}); - assert(mapped == e.first); + DEBUG_ASSERT(mapped == e.first); } } } @@ -150,6 +152,8 @@ class VertexMapping { std::vector> backward; }; +// TODO: fix namespace and naming +// TODO: accept refs SimpleMesh merge_meshes(std::span meshes); SimpleMesh merge_meshes(std::span meshes, VertexMapping &mapping); SimpleMesh merge_meshes(std::span meshes, double distance_epsilon); @@ -160,7 +164,15 @@ SimpleMesh apply_mapping(std::span meshes, const VertexMapping VertexMapping create_merge_mapping(std::span meshes); VertexMapping create_merge_mapping(std::span meshes, double distance_epsilon); +// TODO: +inline SimpleMesh merge_meshes(const SimpleMesh &mesh1, const SimpleMesh &mesh2) { + std::array meshes = {mesh1, mesh2}; + return merge_meshes(meshes); +} +inline SimpleMesh merge_meshes(const SimpleMesh& mesh1, const SimpleMesh& mesh2, const SimpleMesh& mesh3) { + std::array meshes = {mesh1, mesh2, mesh3}; + return merge_meshes(meshes); +} } -#endif diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index 6fc6488..2d15aab 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -5,6 +5,7 @@ #include "mesh/SimpleMesh.h" #include "mesh/TriangleSoup.h" #include "mesh/utils.h" +#include "mesh/validate.h" radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh) { radix::geometry::Aabb3d bounds; @@ -81,26 +82,6 @@ std::optional calculate_max_edge_length(const SimpleMesh &mesh) { return max_length; } -std::vector find_isolated_vertices(const SimpleMesh &mesh) { - std::vector connected; - connected.resize(mesh.vertex_count()); - std::fill(connected.begin(), connected.end(), false); - for (const glm::uvec3 &triangle : mesh.triangles) { - for (size_t k = 0; k < static_cast(triangle.length()); k++) { - connected[triangle[k]] = true; - } - } - - std::vector isolated; - for (size_t i = 0; i < mesh.vertex_count(); i++) { - if (!connected[i]) { - isolated.push_back(i); - } - } - - return isolated; -} - size_t remove_isolated_vertices(SimpleMesh &mesh) { const bool has_uvs = mesh.has_uvs(); const std::vector isolated = find_isolated_vertices(mesh); @@ -136,26 +117,29 @@ size_t remove_triangles_of_negligible_size(SimpleMesh &mesh, const double thresh mesh.positions[triangle.y], mesh.positions[triangle.z]}; - // const double area = Kernel().compute_area_3_object()(cgal_points[0], cgal_points[1], cgal_points[2]); - const double area = 0.5 * std::abs( - points[0].x * (points[1].y - points[2].y) + - points[1].x * (points[2].y - points[0].y) + - points[2].x * (points[0].y - points[1].y)); + // const double area = Kernel().compute_area_3_object()(cgal_points[0], + // cgal_points[1], cgal_points[2]); + const double area = + 0.5 * std::abs(points[0].x * (points[1].y - points[2].y) + + points[1].x * (points[2].y - points[0].y) + + points[2].x * (points[0].y - points[1].y)); areas.push_back(area); } - const double average_area = std::reduce(areas.begin(), areas.end()) / static_cast(areas.size()); - const size_t erased_count = std::erase_if(mesh.triangles, [&](const glm::uvec3 &triangle) { - const size_t index = &triangle - &*mesh.triangles.begin(); - const double area = areas[index]; - return area < average_area * threshold_percentage_of_average; - }); + const double average_area = + std::reduce(areas.begin(), areas.end()) / static_cast(areas.size()); + const size_t erased_count = + std::erase_if(mesh.triangles, [&](const glm::uvec3 &triangle) { + const size_t index = &triangle - &*mesh.triangles.begin(); + const double area = areas[index]; + return area < average_area * threshold_percentage_of_average; + }); return erased_count; } -static glm::uvec3 normalize_triangle(const glm::uvec3 &triangle) { +glm::uvec3 normalize_triangle(const glm::uvec3 &triangle) { unsigned int min_index = 0; for (size_t k = 1; k < static_cast(triangle.length()); k++) { if (triangle[min_index] > triangle[k]) { @@ -174,6 +158,16 @@ static glm::uvec3 normalize_triangle(const glm::uvec3 &triangle) { return normalized_triangle; } +void sort_and_normalize_triangles(std::span triangles) { + // sort vertices in triangles + for (glm::uvec3 &triangle : triangles) { + triangle = normalize_triangle(triangle); + } + + // sort triangle vector + std::sort(triangles.begin(), triangles.end(), compare_triangles); +} + template void erase_by_index(std::vector &vec, std::size_t pos) { typename std::vector::iterator it = vec.begin(); @@ -208,15 +202,18 @@ bool compare_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 bool compare_equality_triangles(const glm::uvec3 &t1, const glm::uvec3 &t2) { return normalize_triangle(t1) == normalize_triangle(t2); } -bool compare_equality_triangles_ignore_orientation(const glm::uvec3 &t1, const glm::uvec3 &t2) { +bool compare_equality_triangles_ignore_orientation(const glm::uvec3 &t1, + const glm::uvec3 &t2) { return std::is_permutation(&t1.x, &t1.z + 1, &t2.x); } void remove_duplicate_triangles(SimpleMesh &mesh, bool ignore_orientation) { remove_duplicate_triangles(mesh.triangles, ignore_orientation); } -void remove_duplicate_triangles(std::vector &triangles, bool ignore_orientation) { - triangles.erase(find_duplicate_triangles(triangles, ignore_orientation), triangles.end()); +void remove_duplicate_triangles(std::vector &triangles, + bool ignore_orientation) { + triangles.erase(find_duplicate_triangles(triangles, ignore_orientation), + triangles.end()); } std::unordered_map> create_edge_to_triangle_index_mapping(const SimpleMesh &mesh) { @@ -225,13 +222,13 @@ std::unordered_map> create_edge_to_triangle_inde glm::uvec3 triangle = mesh.triangles[i]; std::sort(&triangle.x, &triangle.z + 1); - const std::array edges{ - glm::uvec2(triangle.x, triangle.y), - glm::uvec2(triangle.y, triangle.z), - glm::uvec2(triangle.x, triangle.z)}; + const std::array edges{glm::uvec2(triangle.x, triangle.y), + glm::uvec2(triangle.y, triangle.z), + glm::uvec2(triangle.x, triangle.z)}; for (const glm::uvec2 edge : edges) { - auto result = edges_to_triangles.try_emplace(edge, std::vector()).first; + auto result = + edges_to_triangles.try_emplace(edge, std::vector()).first; std::vector &list = result->second; list.push_back(i); } @@ -268,8 +265,10 @@ std::vector find_non_manifold_edges(const SimpleMesh &mesh) { } std::vector find_single_non_manifold_triangle_indices(const SimpleMesh &mesh) { - const std::vector adjacent_triangle_count = count_vertex_adjacent_triangles(mesh); - const std::unordered_map> edges_to_triangles = create_edge_to_triangle_index_mapping(mesh); + const std::vector adjacent_triangle_count = + count_vertex_adjacent_triangles(mesh); + const std::unordered_map> edges_to_triangles = + create_edge_to_triangle_index_mapping(mesh); std::vector non_manifold_triangles; for (auto entry : edges_to_triangles) { @@ -287,8 +286,8 @@ std::vector find_single_non_manifold_triangle_indices(const SimpleMesh & continue; } - // We check if the third vertex of the triangle with the non-manifold edge is unconnected - // as we can be sure in this case that its a flap. + // We check if the third vertex of the triangle with the non-manifold + // edge is unconnected as we can be sure in this case that its a flap. // TODO: a general flap detection method would need to change this part. if (adjacent_triangle_count[triangle[k]] <= 1) { non_manifold_triangles.push_back(triangle_index); @@ -304,7 +303,10 @@ std::vector find_single_non_manifold_triangle_indices(const SimpleMesh & void remove_single_non_manifold_triangles(SimpleMesh &mesh) { std::vector non_manifold_triangles = find_single_non_manifold_triangle_indices(mesh); - std::sort(non_manifold_triangles.begin(), non_manifold_triangles.end(), std::greater()); + + std::sort(non_manifold_triangles.begin(), + non_manifold_triangles.end(), + std::greater()); for (const size_t triangle_index : non_manifold_triangles) { erase_by_index(mesh.triangles, triangle_index); @@ -313,93 +315,6 @@ void remove_single_non_manifold_triangles(SimpleMesh &mesh) { remove_isolated_vertices(mesh); } -void sort_and_normalize_triangles(SimpleMesh &mesh) { - sort_and_normalize_triangles(mesh.triangles); -} -void sort_and_normalize_triangles(std::span triangles) { - // sort vertices in triangles - for (glm::uvec3 &triangle : triangles) { - triangle = normalize_triangle(triangle); - } - - // sort triangle vector - std::sort(triangles.begin(), triangles.end(), compare_triangles); -} - -static void validate_sorted_normalized_mesh(const SimpleMesh &mesh) { - // Check correct count of uvs - assert(!mesh.has_uvs() || mesh.positions.size() == mesh.uvs.size()); - - // Check uvs between 0 and 1 - for (const glm::dvec2 &uv : mesh.uvs) { - for (size_t k = 0; k < static_cast(uv.length()); k++) { - assert(uv[k] >= 0); - assert(uv[k] <= 1); - } - } - - // Check for vertex indices in triangles outside valid range - for (const glm::uvec3 &triangle : mesh.triangles) { - for (size_t k = 0; k < static_cast(triangle.length()); k++) { - const size_t vertex_index = triangle[k]; - assert(vertex_index < mesh.vertex_count()); - } - } - - // Check for degenerate triangles - for (const glm::uvec3 &triangle : mesh.triangles) { - assert(triangle.x != triangle.y); - assert(triangle.y != triangle.z); - assert(triangle.x != triangle.z); - } - - // Check for duplicated triangles - assert(mesh.triangles.end() == std::adjacent_find(mesh.triangles.begin(), mesh.triangles.end())); - - // Check for duplicated triangles with different orientations - std::vector triangles_ignore_orientation(mesh.triangles); - // Sort vertices in triangles - for (glm::uvec3 &triangle : triangles_ignore_orientation) { - std::sort(&triangle.x, &triangle.z + 1); - } - std::vector triangles_ignore_orientation2(triangles_ignore_orientation); - sort_and_normalize_triangles(triangles_ignore_orientation); - assert(triangles_ignore_orientation.end() == std::adjacent_find(triangles_ignore_orientation.begin(), triangles_ignore_orientation.end())); - - // Check for isolated vertices - assert(find_isolated_vertices(mesh).empty()); - - // Check for duplicate vertices - const double epsilon = 1e-9; - auto almost_equal = [epsilon](const glm::dvec3 &a, const glm::dvec3 &b) { - return glm::all(glm::lessThan(glm::abs(a - b), glm::dvec3(epsilon))); - }; - - std::vector sorted_positions = mesh.positions; - std::sort(sorted_positions.begin(), sorted_positions.end(), [](const glm::dvec3 &a, const glm::dvec3 &b) { - if (a.x != b.x) { - return a.x < b.x; - } - if (a.y != b.y) { - return a.y < b.y; - } - return a.z < b.z; - }); - - for (size_t i = 1; i < sorted_positions.size(); ++i) { - assert(!almost_equal(sorted_positions[i - 1], sorted_positions[i])); - } -} - -void validate_mesh(const SimpleMesh &mesh) { -#if NDEBUG - return; -#endif - SimpleMesh sorted(mesh); - sort_and_normalize_triangles(sorted); - validate_sorted_normalized_mesh(sorted); -} - void reindex_mesh(SimpleMesh &mesh) { struct Entry { uint32_t new_index; diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index 7950fcc..15aa395 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -8,6 +8,7 @@ #include // TODO: put in mesh namespace +// TODO: make all methods work with SimpleMesh_ radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh); radix::geometry::Aabb3d calculate_bounds(std::span meshes); @@ -15,7 +16,8 @@ radix::geometry::Aabb3d calculate_bounds(std::span meshes); std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size = 1000); std::optional calculate_max_edge_length(const SimpleMesh &mesh); -std::vector find_isolated_vertices(const SimpleMesh &mesh); +template +std::vector find_isolated_vertices(const SimpleMesh_ &mesh); size_t remove_isolated_vertices(SimpleMesh & mesh); size_t remove_triangles_of_negligible_size(SimpleMesh & mesh, const double threshold_percentage_of_average = 0.001); @@ -43,11 +45,11 @@ std::vector find_non_manifold_edges(const SimpleMesh &mesh); std::vector find_single_non_manifold_triangle_indices(const SimpleMesh &mesh); void remove_single_non_manifold_triangles(SimpleMesh& mesh); -void sort_and_normalize_triangles(SimpleMesh& mesh); +template +void sort_and_normalize_triangles(SimpleMesh_ &mesh); void sort_and_normalize_triangles(std::span triangles); -void validate_mesh(const SimpleMesh &mesh); - void reindex_mesh(SimpleMesh &mesh); SimpleMesh reindex_mesh(const SimpleMesh &mesh); -SimpleMesh clip_mesh_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); + +#include "utils.inl" diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl new file mode 100644 index 0000000..56a5b14 --- /dev/null +++ b/src/terrainlib/mesh/utils.inl @@ -0,0 +1,29 @@ +#pragma once + +#include "mesh/SimpleMesh.h" + +template +std::vector find_isolated_vertices(const SimpleMesh_ &mesh) { + std::vector connected; + connected.resize(mesh.vertex_count()); + std::fill(connected.begin(), connected.end(), false); + for (const glm::uvec3 &triangle : mesh.triangles) { + for (size_t k = 0; k < static_cast(triangle.length()); k++) { + connected[triangle[k]] = true; + } + } + + std::vector isolated; + for (size_t i = 0; i < mesh.vertex_count(); i++) { + if (!connected[i]) { + isolated.push_back(i); + } + } + + return isolated; +} + +template +void sort_and_normalize_triangles(SimpleMesh_ &mesh) { + sort_and_normalize_triangles(mesh.triangles); +} diff --git a/src/terrainlib/mesh/validate.h b/src/terrainlib/mesh/validate.h new file mode 100644 index 0000000..e244e42 --- /dev/null +++ b/src/terrainlib/mesh/validate.h @@ -0,0 +1,15 @@ +#pragma once + +#include "pch.h" + +namespace mesh { + +template +inline void validate(const SimpleMesh_ &mesh); + +template +inline void validate(const CGAL::Surface_mesh &mesh); + +} + +#include "mesh/validate.inl" diff --git a/src/terrainlib/mesh/validate.inl b/src/terrainlib/mesh/validate.inl new file mode 100644 index 0000000..1b724be --- /dev/null +++ b/src/terrainlib/mesh/validate.inl @@ -0,0 +1,111 @@ +#pragma once + +#include "pch.h" +#include "mesh/utils.h" + +#include +#include + +namespace mesh { + +namespace { +template +void validate_sorted_normalized_mesh(const SimpleMesh_ &mesh) { + using Mesh = SimpleMesh_; + using Triangle = typename Mesh::Triangle; + using Position = typename Mesh::Position; + using Uv = typename Mesh::Uv; + static_assert(n_dims == 2 || n_dims == 3, "Mesh must be 2D or 3D"); + + // Check correct count of uvs + DEBUG_ASSERT(!mesh.has_uvs() || mesh.positions.size() == mesh.uvs.size()); + + // Check uvs between 0 and 1 + for (const Uv &uv : mesh.uvs) { + for (size_t k = 0; k < static_cast(uv.length()); k++) { + DEBUG_ASSERT(uv[k] >= 0); + DEBUG_ASSERT(uv[k] <= 1); + } + } + + // Check for vertex indices in triangles outside valid range + for (const Triangle &triangle : mesh.triangles) { + for (size_t k = 0; k < static_cast(triangle.length()); k++) { + const size_t vertex_index = triangle[k]; + DEBUG_ASSERT(vertex_index < mesh.vertex_count()); + } + } + + // Check for degenerate triangles + for (const Triangle &triangle : mesh.triangles) { + DEBUG_ASSERT(triangle.x != triangle.y); + DEBUG_ASSERT(triangle.y != triangle.z); + DEBUG_ASSERT(triangle.x != triangle.z); + } + + // Check for duplicated triangles + DEBUG_ASSERT(mesh.triangles.end() == std::adjacent_find(mesh.triangles.begin(), mesh.triangles.end())); + + // Check for duplicated triangles with different orientations + std::vector triangles_ignore_orientation(mesh.triangles); + // Sort vertices in triangles + for (Triangle &triangle : triangles_ignore_orientation) { + std::sort(&triangle.x, &triangle.z + 1); + } + std::vector triangles_ignore_orientation2(triangles_ignore_orientation); + sort_and_normalize_triangles(triangles_ignore_orientation); + DEBUG_ASSERT(triangles_ignore_orientation.end() == std::adjacent_find(triangles_ignore_orientation.begin(), triangles_ignore_orientation.end())); + + // Check for isolated vertices + DEBUG_ASSERT(find_isolated_vertices(mesh).empty()); + + // Check for duplicate vertices + const double epsilon = 1e-9; + auto almost_equal = [epsilon](const Position &a, const Position &b) { + return glm::all(glm::lessThan(glm::abs(a - b), Position(epsilon))); + }; + + std::vector sorted_positions = mesh.positions; + std::sort(sorted_positions.begin(), sorted_positions.end(), [&](const Position &a, const Position &b) { + if (a.x != b.x) { + return a.x < b.x; + } + if constexpr (n_dims == 2) { + return a.y < b.y; + } else if constexpr (n_dims == 3) { + if (a.y != b.y) { + return a.y < b.y; + } + return a.z < b.z; + } + }); + + for (size_t i = 1; i < sorted_positions.size(); i++) { + DEBUG_ASSERT(!almost_equal(sorted_positions[i - 1], sorted_positions[i])); + } +} +} // namespace + +template +void validate(const SimpleMesh_ &mesh) { +#if NDEBUG + return; +#endif + SimpleMesh_ sorted(mesh); + sort_and_normalize_triangles(sorted); + validate_sorted_normalized_mesh(sorted); +} + +template +inline void validate(const CGAL::Surface_mesh &mesh) { +#if NDEBUG + return; +#endif + + DEBUG_ASSERT(mesh.is_valid()); + DEBUG_ASSERT(CGAL::is_triangle_mesh(mesh)); + DEBUG_ASSERT(CGAL::is_valid_polygon_mesh(mesh)); + DEBUG_ASSERT(!CGAL::Polygon_mesh_processing::does_self_intersect(mesh)); +} + +} diff --git a/src/terrainlib/octree/Id.h b/src/terrainlib/octree/Id.h index 8e42caa..3e2c52d 100644 --- a/src/terrainlib/octree/Id.h +++ b/src/terrainlib/octree/Id.h @@ -8,6 +8,7 @@ #include #include +#include #include "hash_utils.h" @@ -36,8 +37,8 @@ class Id { } constexpr Id(const Level level, const Index index) : _level(level), _index(index) { - assert(level <= Id::max_level()); - assert(index <= Id::max_index_on_level(this->_level)); + DEBUG_ASSERT(level <= Id::max_level()); + DEBUG_ASSERT(index <= Id::max_index_on_level(this->_level)); } [[nodiscard]] static std::optional try_make(const Level level, const Coords coords) { @@ -149,24 +150,35 @@ class Id { return Id(0, 0); } - bool operator==(const Id &other) const { + constexpr bool operator==(const Id &other) const { return this->_level == other._level && this->_index == other._index; } - bool operator!=(const Id &other) const { + constexpr bool operator!=(const Id &other) const { return !(*this == other); } + constexpr std::strong_ordering operator<=>(const Id &other) const { + if (this->_level < other._level) { + return std::strong_ordering::less; + } + if (this->_level > other._level) { + return std::strong_ordering::greater; + } + return this->_index <=> other._index; + } + + std::string to_string() const; private: Level _level; Index _index; [[nodiscard]] constexpr Id _child(const uint32_t child_index) const { - assert(child_index <= 7); + DEBUG_ASSERT(child_index <= 7); return Id(this->level() + 1, (this->index_on_level() << 3) | child_index); } [[nodiscard]] static constexpr Index interleave3(const Coords &coords) { - assert(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); + DEBUG_ASSERT(glm::all(glm::lessThanEqual(coords, Coords(Id::max_coord_on_level(Id::max_level()))))); const Index x = coords.x; const Index y = coords.y; @@ -218,8 +230,8 @@ struct fmt::formatter { #include #include namespace octree { -inline std::string to_string(const octree::Id &id) { - return fmt::format("{}", id); +inline std::string octree::Id::to_string() const { + return fmt::format("{}", *this); } inline std::ostream &operator<<(std::ostream &os, const octree::Id &id) { fmt::print(os, "{}", id); @@ -231,7 +243,7 @@ namespace std { template <> struct hash { std::size_t operator()(const octree::Id &id) const noexcept { - return hash_combine(id.level(), id.index_on_level()); + return ::hash::combine(id.level(), id.index_on_level()); } }; } // namespace std diff --git a/src/terrainlib/octree/IndexMap.cpp b/src/terrainlib/octree/IndexMap.cpp index ed1ad9f..724adb6 100644 --- a/src/terrainlib/octree/IndexMap.cpp +++ b/src/terrainlib/octree/IndexMap.cpp @@ -1,3 +1,5 @@ +#include + #include "octree/IndexMap.h" #include "log.h" @@ -12,30 +14,29 @@ std::optional IndexMap::get(Id id) const { } } -void IndexMap::add(Id id) { +bool IndexMap::add(Id id) { NodeStatus* status = this->get_raw(id); if (status != nullptr) { switch (*status) { case NodeStatus::Inner: case NodeStatus::Leaf: // Nothing to do - break; + return false; case NodeStatus::Virtual: this->set_raw(id, NodeStatus::Inner); - break; + return true; } - return; } const auto parent_opt = id.parent(); if (!parent_opt.has_value()) { - assert(id.is_root()); + DEBUG_ASSERT(id.is_root()); if (this->empty()) { this->set_raw(id, NodeStatus::Leaf); - return; + return true; } else { UNREACHABLE(); - return; + return true; } } @@ -45,7 +46,7 @@ void IndexMap::add(Id id) { this->add(parent); this->set_raw(parent, NodeStatus::Virtual); this->set_raw(id, NodeStatus::Leaf); - return; + return true; } switch (*parent_status) { @@ -58,6 +59,8 @@ void IndexMap::add(Id id) { this->set_raw(id, NodeStatus::Leaf); break; } + + return true; } bool IndexMap::remove(Id id) { @@ -144,10 +147,10 @@ void IndexMap::update_parent_after_remove(Id id) { const auto parent = parent_opt.value(); NodeStatus* parent_status = this->get_raw(parent); - assert(parent_status != nullptr); + DEBUG_ASSERT(parent_status != nullptr); // We know there are children since we just removed one - assert(parent.has_children()); + DEBUG_ASSERT(parent.has_children()); const auto siblings = parent.children().value(); for (const auto& sibling : siblings) { if (this->is_present(sibling) && sibling != id) { diff --git a/src/terrainlib/octree/IndexMap.h b/src/terrainlib/octree/IndexMap.h index e249424..c5dbf53 100644 --- a/src/terrainlib/octree/IndexMap.h +++ b/src/terrainlib/octree/IndexMap.h @@ -17,7 +17,7 @@ class IndexMap { using const_iterator = Container::const_iterator; std::optional get(Id id) const; - void add(Id id); + bool add(Id id); bool remove(Id id); bool is_present(Id id) const; diff --git a/src/terrainlib/octree/Space.cpp b/src/terrainlib/octree/Space.cpp index 41275b9..fefddea 100644 --- a/src/terrainlib/octree/Space.cpp +++ b/src/terrainlib/octree/Space.cpp @@ -3,7 +3,7 @@ namespace octree { Space::Space(Bounds bounds) : _bounds(bounds) { - assert(glm::all(glm::greaterThan(this->_bounds.size(), glm::dvec3(0)))); + DEBUG_ASSERT(glm::all(glm::greaterThan(this->_bounds.size(), glm::dvec3(0)))); } Space Space::earth() { @@ -68,7 +68,7 @@ std::optional Space::find_smallest_node_encompassing_bounds(const Bounds &ta } std::optional Space::find_node_at_level_containing_point(const glm::dvec3& point, const uint32_t target_level, const Id root) const { - assert(target_level <= Id::max_level()); + DEBUG_ASSERT(target_level <= Id::max_level()); Id current = root; const Bounds root_bounds = this->get_node_bounds(current); diff --git a/src/terrainlib/octree/Storage.cpp b/src/terrainlib/octree/Storage.cpp deleted file mode 100644 index 6edb97d..0000000 --- a/src/terrainlib/octree/Storage.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "octree/Storage.h" - -#include -#include -#include -#include -#include - -#include "log.h" -#include "mesh/io.h" -#include "octree/disk/IndexFile.h" -#include "octree/disk/layout/StrategyRegister.h" -#include "io/serialize.h" - -namespace octree { - -Storage::Storage(disk::Layout layout) - : _layout(std::move(layout)) {} - -Storage::Storage(IndexMap map, disk::Layout layout) - : _index(std::move(map)), _layout(std::move(layout)) {} - -std::optional Storage::read_node(const Id &id) const { - if (const auto* index = this->_index.get()) { - if (index->is_absent(id)) { - return std::nullopt; - } - } - const auto node_path = this->get_node_path(id); - const auto result = mesh::io::load_from_path(node_path); - if (result.has_value()) { - return result.value(); - } else { - return std::nullopt; - } -} - -bool Storage::write_node(const Id &id, const Node &node) { - const auto node_path = this->get_node_path(id); - const auto result = mesh::io::save_to_path(node, node_path); - if (result.has_value()) { - if (auto* index = this->_index.get()) { - index->add(id); - } - } - return result.has_value(); -} - -bool Storage::remove_node(const Id &id) { - if (const auto* index = this->_index.get()) { - if (index->is_absent(id)) { - return false; - } - } - const auto node_path = this->get_node_path(id); - const bool result = std::filesystem::remove(node_path); - if (auto* index = this->_index.get()) { - index->remove(id); - } - return result; -} - -bool Storage::has_node(const Id &id) const { - if (const auto* index = this->_index.get()) { - return index->is_present(id); - } else { - return std::filesystem::exists(this->get_node_path(id)); - } -} - -std::filesystem::path Storage::get_node_path(const Id &id) const { - return this->_layout.get_node_path(id); -} - -const IndexMap* Storage::index() const { - return this->_index.get(); -} - -bool Storage::has_index() const { - return this->_index.is_initialized(); -} - -bool Storage::save_index() const { - const auto index_path = this->_layout.base_path() / disk::v1::index_file_name(); - LOG_TRACE("Saving octree storage index to {}", index_path); - - disk::v1::IndexFile index_file; - if (const auto* index = this->_index.get()) { - index_file.map = *index; - } - index_file.preferred_extension = this->_layout.extension_with_dot(); - index_file.layout_strategy_id = disk::layout::StrategyRegister::instance().get_id(this->_layout.strategy()); - - const auto result = io::write_to_path(index_file, index_path); - if (!result.has_value()) { - LOG_ERROR("Failed to save octree storage index to {}", index_path); - } - return result.has_value(); -} - -std::optional load_index(const std::filesystem::path &index_path) { - LOG_TRACE("Opening storage index {}", index_path); - - const auto result = io::read_from_path(index_path); - if (!result.has_value()) { - LOG_TRACE("Failed to open storage index due to {}", result.error()); - return std::nullopt; - } - auto index_file = result.value(); - LOG_TRACE("Successfully read storage index with {} entries.", index_file.map.size()); - auto index_map = std::move(index_file.map); - const auto base_path = index_path.parent_path(); - auto layout_strategy = disk::layout::StrategyRegister::instance().create(index_file.layout_strategy_id); - disk::Layout layout(base_path, std::move(layout_strategy), index_file.preferred_extension); - - return Storage(std::move(index_map), std::move(layout)); -} - -namespace { -std::optional> guess_layout_strategy( - const std::filesystem::path &base_path, - std::size_t max_files_to_check = 100) { - - if (!std::filesystem::is_directory(base_path)) { - return std::nullopt; - } - - std::vector candidate_paths; - for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { - if (max_files_to_check == 0) { - break; - } - if (!entry.is_regular_file() && !entry.is_symlink()) { - continue; - } - - const auto ext = entry.path().extension(); - // TODO: manage these somewhere else - if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { - continue; - } - - candidate_paths.emplace_back(std::filesystem::relative(entry.path(), base_path)); - max_files_to_check--; - } - - for (const auto &[_, make_strategy] : disk::layout::StrategyRegister::instance().factories()) { - auto strategy = make_strategy(); - bool matches_all = std::all_of(candidate_paths.begin(), candidate_paths.end(), - [&](const auto &rel_path) { - return strategy->get_id_from_relative_node_path(rel_path).has_value(); - }); - - if (matches_all) { - return strategy; - } - } - - return std::nullopt; -} - -void update_index(IndexMap &index, const disk::Layout &layout) { - index.clear(); - const auto &base_path = layout.base_path(); - - for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { - if (!entry.is_regular_file() && !entry.is_symlink()) { - continue; - } - - const auto ext = entry.path().extension(); - if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { - continue; - } - - auto id_opt = layout.get_id_from_node_path(entry.path()); - if (!id_opt) { - continue; - } - - const Id id = *id_opt; - index.set_raw(id, NodeStatus::Leaf); - } - - std::unordered_set visited; - for (const auto &[id, _] : index) { - auto parent = id.parent(); - while (parent) { - if (visited.find(*parent) != visited.end()) { - break; - } - visited.insert(*parent); - - if (index.get(*parent)) { - index.set_raw(*parent, NodeStatus::Inner); - } else { - index.set_raw(*parent, NodeStatus::Virtual); - } - parent = parent->parent(); - } - } -} -} - -Storage open_folder( - const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy, - const std::string extension_with_dot, - bool save_index) { - LOG_TRACE("Opening storage folder {}", base_path); - - if (!std::filesystem::is_directory(base_path)) { - if (std::filesystem::exists(base_path)) { - LOG_ERROR_AND_EXIT("Base path {} exists but is not a directory", base_path); - } - - LOG_TRACE("Base path {} does not exist, creating it", base_path); - std::filesystem::create_directories(base_path); - } - - const std::filesystem::path index_path = base_path / disk::v1::index_file_name(); - auto storage_opt = load_index(index_path); - if (storage_opt.has_value()) { - LOG_TRACE("Loaded existing index"); - return std::move(storage_opt.value()); - } - - auto layout_strategy_opt = guess_layout_strategy(base_path); - if (layout_strategy_opt) { - LOG_TRACE("Guessed layout of dataset as {}", - disk::layout::StrategyRegister::instance().get_id(**layout_strategy_opt)); - } else { - LOG_WARN("Unable to determine layout of dataset, using default which is {}", - disk::layout::StrategyRegister::instance().get_id(*default_layout_strategy)); - layout_strategy_opt = std::move(default_layout_strategy); - } - - disk::Layout layout(base_path, std::move(*layout_strategy_opt), extension_with_dot); - IndexMap map; - update_index(map, layout); - - Storage storage(std::move(map), std::move(layout)); - if (save_index) { - storage.save_index(); - } - - return storage; -} - -const IndexMap& Storage::ensure_indexed() const { - if (const auto* index = this->_index.get()) { - return *index; - } - - LOG_TRACE("Index not present, creating empty index"); - IndexMap index; - update_index(index, this->_layout); - LOG_TRACE("Index created with {} entries", index.size()); - return this->_index.set(std::move(index)); -} - -} // namespace octree diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index 1eff783..c2653d6 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -1,61 +1,7 @@ #pragma once -#include -#include -#include - -#include "mesh/SimpleMesh.h" -#include "mesh/io.h" -#include "OnceCell.h" -#include "octree/Id.h" -#include "octree/IndexMap.h" -#include "octree/disk/Layout.h" -#include "octree/disk/layout/Strategy.h" -#include "octree/disk/layout/strategy/Default.h" - -namespace octree { -using Node = SimpleMesh; - -struct NodeAndId { - Id id; - Node node; - - NodeAndId() = default; - NodeAndId(Id id, Node node) : id(std::move(id)), node(std::move(node)) {} - - operator Node() const { - return std::move(node); - } -}; - -class Storage { -public: - explicit Storage(disk::Layout layout); - explicit Storage(IndexMap map, disk::Layout layout); - - std::optional read_node(const Id &id) const; - bool write_node(const Id &id, const Node &node); - bool remove_node(const Id &id); - bool has_node(const Id &id) const; - std::filesystem::path get_node_path(const Id &id) const; - - - - const IndexMap* index() const; - bool has_index() const; - bool save_index() const; - const IndexMap& ensure_indexed() const; - -private: - OnceCell _index; - disk::Layout _layout; -}; - -std::optional load_index(const std::filesystem::path &index_path); -Storage open_folder( - const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), - const std::string extension_with_dot = ".terrain", - bool save_index = true); - -} // namespace octree +#include "octree/storage/IStorage.h" +#include "octree/storage/RawStorage.h" +#include "octree/storage/Storage.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/storage/open.h" diff --git a/src/terrainlib/octree/disk/Layout.h b/src/terrainlib/octree/disk/Layout.h index dcd561f..e13d569 100644 --- a/src/terrainlib/octree/disk/Layout.h +++ b/src/terrainlib/octree/disk/Layout.h @@ -5,6 +5,8 @@ #include #include +#include + #include "octree/Id.h" #include "octree/disk/layout/Strategy.h" @@ -14,7 +16,7 @@ class Layout { public: Layout(std::filesystem::path base_path, std::unique_ptr strategy, std::string extension_with_dot = ".terrain") : _base_path(std::move(base_path)), _strategy(std::move(strategy)), _extension_with_dot(std::move(extension_with_dot)) { - assert(!_extension_with_dot.empty() && _extension_with_dot[0] == '.'); + DEBUG_ASSERT(!_extension_with_dot.empty() && _extension_with_dot[0] == '.'); } std::filesystem::path get_node_path(Id id) const { diff --git a/src/terrainlib/octree/disk/layout/strategy/Flat.h b/src/terrainlib/octree/disk/layout/strategy/Flat.h index 30a64a5..0a11a94 100644 --- a/src/terrainlib/octree/disk/layout/strategy/Flat.h +++ b/src/terrainlib/octree/disk/layout/strategy/Flat.h @@ -19,7 +19,7 @@ class Flat : public Strategy { } std::optional get_id_from_relative_node_path(const std::filesystem::path &relative_path) const override { - assert(relative_path.is_relative()); + DEBUG_ASSERT(relative_path.is_relative()); const std::string _filestem = relative_path.stem().string(); const std::string_view filestem = _filestem; diff --git a/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h b/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h index a5a19e3..442b06c 100644 --- a/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h +++ b/src/terrainlib/octree/disk/layout/strategy/LevelAndCoordinateDirectories.h @@ -19,7 +19,7 @@ class LevelAndCoordinateDirectories : public Strategy { return fmt::format("{}/{}/{}/{}{}", id.level(), coords.x, coords.y, coords.z, extension_with_dot); } std::optional get_id_from_relative_node_path(const std::filesystem::path &relative_path) const override { - assert(relative_path.is_relative()); + DEBUG_ASSERT(relative_path.is_relative()); auto it = relative_path.begin(); if (std::distance(it, relative_path.end()) < 4) { diff --git a/src/terrainlib/octree/storage/IStorage.h b/src/terrainlib/octree/storage/IStorage.h new file mode 100644 index 0000000..02bd199 --- /dev/null +++ b/src/terrainlib/octree/storage/IStorage.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include + +#include "mesh/SimpleMesh.h" +#include "octree/Id.h" +#include "mesh/io/error.h" + +namespace octree { +using Node = SimpleMesh; + +struct IdAndNode { + Id id; + Node node; + + IdAndNode() = default; + IdAndNode(Id id, Node node) : id(std::move(id)), node(std::move(node)) {} + + operator Node() const { + return std::move(node); + } + operator Id() const { + return id; + } +}; + +class IStorage { +public: + virtual ~IStorage() = default; + virtual tl::expected read_node(const Id &id) const = 0; + virtual tl::expected write_node(const Id &id, const Node &node) = 0; + virtual bool remove_node(const Id &id) = 0; + virtual bool has_node(const Id &id) const = 0; + virtual std::filesystem::path get_node_path(const Id &id) const = 0; + virtual std::filesystem::path base_path() const = 0; +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/IndexedStorage.h b/src/terrainlib/octree/storage/IndexedStorage.h new file mode 100644 index 0000000..52c87ae --- /dev/null +++ b/src/terrainlib/octree/storage/IndexedStorage.h @@ -0,0 +1,64 @@ +#pragma once + +#include + +#include + +#include "octree/Id.h" +#include "octree/storage/helpers.h" +#include "octree/IndexMap.h" +#include "octree/storage/Storage.h" +#include "octree/disk/Layout.h" + +namespace octree { + +class IndexedStorage : public Storage { +public: + explicit IndexedStorage(Storage inner) noexcept + : Storage(std::move(inner)) { + this->ensure_indexed(); + DEBUG_ASSERT(this->is_indexed()); + } + explicit IndexedStorage(RawStorage inner, IndexMap map) noexcept + : Storage(std::move(inner), std::move(map)) { + DEBUG_ASSERT(this->is_indexed()); + } + + IndexedStorage &operator=(const IndexedStorage &) = delete; + IndexedStorage(const IndexedStorage &) = delete; + IndexedStorage(IndexedStorage &&) = default; + IndexedStorage &operator=(IndexedStorage &&) = default; + + ~IndexedStorage() override { + if (this->is_index_dirty()) { + LOG_WARN("Index was not saved upon IndexedStorage destruction, use save_index()."); + } + } + + const IndexMap& index() const noexcept { + DEBUG_ASSERT(this->is_indexed()); + return Storage::index().value(); + } + void update_index() noexcept { + Storage::update_index(); + } + tl::expected save_index() const noexcept { + if (!this->is_index_dirty()) { + return {}; + } + + auto result = helpers::save_index_map(this->index(), this->layout()); + if (result.has_value()) { + this->set_index_dirty(false); + } + return result; + } + +private: + IndexMap& index_mut() noexcept { + DEBUG_ASSERT(this->is_indexed()); + return Storage::index_mut().value(); + } +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp new file mode 100644 index 0000000..23db99b --- /dev/null +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -0,0 +1,41 @@ +#include "octree/Storage.h" + +#include "mesh/io.h" + +namespace octree { + +RawStorage::RawStorage(disk::Layout layout) noexcept + : _layout(std::move(layout)) {} + +tl::expected RawStorage::read_node(const Id &id) const noexcept { + const auto node_path = this->get_node_path(id); + return mesh::io::load_from_path(node_path); +} + +tl::expected RawStorage::write_node(const Id &id, const Node &node) noexcept { + const auto node_path = this->get_node_path(id); + return mesh::io::save_to_path(node, node_path); +} + +bool RawStorage::remove_node(const Id &id) noexcept { + const auto node_path = this->get_node_path(id); + return std::filesystem::remove(node_path); +} + +bool RawStorage::has_node(const Id &id) const noexcept { + return std::filesystem::exists(this->get_node_path(id)); +} + +std::filesystem::path RawStorage::get_node_path(const Id &id) const noexcept { + return this->_layout.get_node_path(id); +} + +std::filesystem::path RawStorage::base_path() const noexcept { + return this->_layout.base_path(); +} + +const disk::Layout& RawStorage::layout() const noexcept { + return this->_layout; +} + +} // namespace octree diff --git a/src/terrainlib/octree/storage/RawStorage.h b/src/terrainlib/octree/storage/RawStorage.h new file mode 100644 index 0000000..4006e04 --- /dev/null +++ b/src/terrainlib/octree/storage/RawStorage.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +#include + +#include "octree/Id.h" +#include "octree/storage/IStorage.h" +#include "octree/disk/Layout.h" +#include "mesh/io/error.h" + +namespace octree { + +class RawStorage : public IStorage { +public: + explicit RawStorage(disk::Layout layout) noexcept; + ~RawStorage() = default; + RawStorage& operator=(const RawStorage&) = delete; + RawStorage(const RawStorage&) = delete; + RawStorage(RawStorage&&) = default; + RawStorage& operator=(RawStorage&&) = default; + + tl::expected read_node(const Id &id) const noexcept override; + tl::expected write_node(const Id &id, const Node &node) noexcept override; + bool remove_node(const Id &id) noexcept override; + bool has_node(const Id &id) const noexcept override; + std::filesystem::path get_node_path(const Id &id) const noexcept override; + std::filesystem::path base_path() const noexcept override; + + const disk::Layout& layout() const noexcept; + +private: + disk::Layout _layout; +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h new file mode 100644 index 0000000..516c469 --- /dev/null +++ b/src/terrainlib/octree/storage/Storage.h @@ -0,0 +1,242 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include "mesh/io.h" +#include "octree/Id.h" +#include "octree/IndexMap.h" +#include "octree/storage/cache/ICache.h" +#include "octree/storage/RawStorage.h" +#include "octree/storage/helpers.h" +#include "octree/disk/Layout.h" +#include "octree/disk/layout/strategy/Default.h" + +namespace octree { + +namespace detail { +struct MaybeIndex { + std::optional map; + mutable bool dirty = false; + + explicit MaybeIndex() + : map(std::nullopt) {} + explicit MaybeIndex(IndexMap map) + : map(std::move(map)) {} + + bool add(const Id &id) noexcept { + if (this->map.has_value()) { + this->dirty = true; + return this->map->add(id); + } + return false; + } + + bool remove(const Id &id) noexcept { + if (this->map.has_value()) { + this->dirty = true; + return this->map->remove(id); + } + return false; + } + + bool contains(const Id &id, const bool def = false) const noexcept { + if (this->map.has_value()) { + return this->map->is_present(id); + } + return def; + } +}; + +struct MaybeCache : public ICache { + std::optional> cache; + + explicit MaybeCache() + : cache(std::nullopt) {} + explicit MaybeCache(std::unique_ptr cache) + : cache(std::move(cache)) {} + + std::optional get(const Id& id) noexcept override { + if (this->cache.has_value()) { + return this->cache->get()->get(id); + } + return std::nullopt; + } + + bool put(const Id &id, const Node &node) noexcept override { + if (this->cache.has_value()) { + return this->cache->get()->put(id, node); + } + return false; + } + + bool remove(const Id &id) noexcept override { + if (this->cache.has_value()) { + return this->cache->get()->remove(id); + } + return false; + } + + bool contains(const Id &id) const noexcept override { + if (this->cache.has_value()) { + return this->cache->get()->contains(id); + } + return false; + } +}; +} + +class Storage : public IStorage { +public: + explicit Storage(RawStorage inner) + : _inner(std::move(inner)) {} + explicit Storage(RawStorage inner, IndexMap index) + : _inner(std::move(inner)), _index(detail::MaybeIndex(std::move(index))) {} + + Storage& operator=(const Storage&) = delete; + Storage(const Storage&) = delete; + Storage(Storage&&) = default; + Storage& operator=(Storage&&) = default; + + ~Storage() override { + if (this->_index.map.has_value() && this->_index.dirty) { + auto result = helpers::save_index_map(this->_index.map.value(), this->_inner.layout()); + if (!result.has_value()) { + LOG_ERROR("Failed to automatically save index when closing storage: {}", result.error()); + } + } + } + + tl::expected read_node(const Id &id) const noexcept override { + if (const auto node_opt = this->_cache.get(id)) { + return node_opt.value(); + } + + if (!this->_index.contains(id, true)) { + return tl::unexpected(mesh::io::LoadMeshErrorKind::FileNotFound); + } + + const auto result = this->_inner.read_node(id); + if (result.has_value()) { + this->_cache.put(id, result.value()); + } + return result; + } + + tl::expected write_node(const Id &id, const Node &node) noexcept override { + const auto result = this->_inner.write_node(id, node); + if (result.has_value()) { + this->_cache.put(id, node); + this->_index.add(id); + } + return result; + } + + bool remove_node(const Id &id) noexcept override { + this->_cache.remove(id); + this->_index.remove(id); + return this->_inner.remove_node(id); + } + + bool has_node(const Id &id) const noexcept override { + return + this->_cache.contains(id) || + this->_index.contains(id, false) || + this->_inner.has_node(id); + } + + std::filesystem::path get_node_path(const Id &id) const noexcept override { + return this->_inner.get_node_path(id); + } + + std::filesystem::path base_path() const noexcept override { + return this->_inner.base_path(); + } + + bool is_indexed() const noexcept { + return this->_index.map.has_value(); + } + + void ensure_indexed() noexcept { + if (this->is_indexed()) { + return; + } + + LOG_TRACE("Index not present, creating empty index"); + IndexMap map; + helpers::update_index_map(map, this->_inner.layout()); + LOG_TRACE("Index created with {} entries", map.size()); + this->_index.map = std::move(map); + } + + std::optional> index() const noexcept { + // I miss Option::as_ref + if (this->_index.map.has_value()) { + return this->_index.map.value(); + } else { + return std::nullopt; + } + } + + std::optional>& cache() noexcept { + return this->_cache.cache; + } + + std::optional> cache() const noexcept { + if (this->_cache.cache.has_value()) { + return *this->_cache.cache.value(); + } else { + return std::nullopt; + } + } + + tl::expected save_or_create_index() noexcept { + if (this->is_indexed() && !this->_index.dirty) { + return {}; + } + + this->ensure_indexed(); + + auto result = helpers::save_index_map(this->index().value(), this->_inner.layout()); + if (result.has_value()) { + this->_index.dirty = false; + } + return result; + } + +protected: + const octree::disk::Layout &layout() const noexcept { + return this->_inner.layout(); + } + + std::optional &index_mut() noexcept { + return this->_index.map; + } + + bool is_index_dirty() const noexcept { + return this->_index.dirty; + } + void set_index_dirty(const bool val = true) const noexcept { + this->_index.dirty = val; + } + + void update_index() noexcept { + if (!this->is_indexed()) { + return; + } + + helpers::update_index_map(this->index_mut().value(), this->_inner.layout()); + this->_index.dirty = false; + } + +private: + RawStorage _inner; + detail::MaybeIndex _index = detail::MaybeIndex(); + mutable detail::MaybeCache _cache = detail::MaybeCache(); +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/cache/Dummy.h b/src/terrainlib/octree/storage/cache/Dummy.h new file mode 100644 index 0000000..282123a --- /dev/null +++ b/src/terrainlib/octree/storage/cache/Dummy.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "octree/Id.h" +#include "octree/RawStorage.h" +#include "octree/cache/ICache.h" + +namespace octree { + +class Dummy : public ICache { +public: + std::optional get(const Id &) override { return std::nullopt; } + bool put(const Id &, const Node &) override { return false; } + bool remove(const Id &) override { return false; } + bool contains(const Id &) const override { return false; } +}; + +} diff --git a/src/terrainlib/octree/storage/cache/ICache.h b/src/terrainlib/octree/storage/cache/ICache.h new file mode 100644 index 0000000..2f836a2 --- /dev/null +++ b/src/terrainlib/octree/storage/cache/ICache.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "octree/Id.h" +#include "octree/storage/IStorage.h" + +namespace octree { + +class ICache { +public: + virtual std::optional get(const Id& id) noexcept = 0; + virtual bool put(const Id &id, const Node &node) noexcept = 0; + virtual bool remove(const Id &id) noexcept = 0; + virtual bool contains(const Id &id) const noexcept = 0; +}; + +} diff --git a/src/terrainlib/octree/storage/cache/LruCache.h b/src/terrainlib/octree/storage/cache/LruCache.h new file mode 100644 index 0000000..8d34ec5 --- /dev/null +++ b/src/terrainlib/octree/storage/cache/LruCache.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include + +#include "octree/Id.h" +#include "octree/RawStorage.h" +#include "octree/cache/ICache.h" + +namespace octree { + +// TODO: UNTESTED +template +class LruCache : public ICache { +public: + explicit LruCache(const size_t capacity) : _capacity(capacity) {} + + std::optional get(const Key& key) { + auto it = this->_map.find(key); + if (it == this->_map.end()) return std::nullopt; + + // Move to front (most recently used) + this->_usage.splice(this->_usage.begin(), this->_usage, it->second.second); + return it->second.first; + } + + void put(const Key& key, const Value& value) { + auto it = this->_map.find(key); + if (it != this->_map.end()) { + // Update value and move to front + it->second.first = value; + this->_usage.splice(this->_usage.begin(), this->_usage, it->second.second); + } else { + // Insert new entry + if (this->_map.size() == _capacity) { + // Evict least recently used + const Key& lru_key = this->_usage.back(); + this->_map.erase(lru_key); + this->_usage.pop_back(); + } + + this->_usage.push_front(key); + this->_map[key] = { value, this->_usage.begin() }; + } + } + + void remove(const Key& key) { + auto it = this->_map.find(key); + if (it != this->_map.end()) { + this->_usage.erase(it->second.second); + this->_map.erase(it); + } + } + + bool contains(const Key& key) const { + return this->_map.contains(key); + } + +private: + size_t _capacity; + std::list _usage; + std::unordered_map::iterator>> _map; +}; + +} diff --git a/src/terrainlib/octree/storage/helpers.cpp b/src/terrainlib/octree/storage/helpers.cpp new file mode 100644 index 0000000..0192b24 --- /dev/null +++ b/src/terrainlib/octree/storage/helpers.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "octree/storage/helpers.h" +#include "io/serialize.h" +#include "octree/NodeStatus.h" +#include "octree/IndexMap.h" +#include "octree/disk/IndexFile.h" +#include "octree/disk/Layout.h" +#include "octree/disk/layout/Strategy.h" +#include "octree/disk/layout/StrategyRegister.h" + +namespace octree::helpers { +std::optional> guess_layout_strategy( + const std::filesystem::path &base_path, + size_t max_files_to_check ) { + + if (!std::filesystem::is_directory(base_path)) { + return std::nullopt; + } + + std::vector candidate_paths; + for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { + if (max_files_to_check == 0) { + break; + } + if (!entry.is_regular_file() && !entry.is_symlink()) { + continue; + } + + const auto ext = entry.path().extension(); + // TODO: manage these somewhere else + if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { + continue; + } + + candidate_paths.emplace_back(std::filesystem::relative(entry.path(), base_path)); + max_files_to_check--; + } + + for (const auto &[_, make_strategy] : disk::layout::StrategyRegister::instance().factories()) { + auto strategy = make_strategy(); + bool matches_all = std::all_of(candidate_paths.begin(), candidate_paths.end(), + [&](const auto &rel_path) { + return strategy->get_id_from_relative_node_path(rel_path).has_value(); + }); + + if (matches_all) { + return strategy; + } + } + + return std::nullopt; +} + +tl::expected save_index_map(const IndexMap& index, const disk::Layout& layout) { + const auto index_path = layout.base_path() / disk::v1::index_file_name(); + LOG_TRACE("Saving octree storage index to {}", index_path); + + disk::v1::IndexFile index_file; + index_file.map = index; + index_file.preferred_extension = layout.extension_with_dot(); + index_file.layout_strategy_id = disk::layout::StrategyRegister::instance().get_id(layout.strategy()); + + const auto result = io::write_to_path(index_file, index_path); + if (!result.has_value()) { + LOG_ERROR("Failed to save octree storage index to {}", index_path); + return tl::unexpected(result.error()); + } + return {}; +} + +void update_index_map(IndexMap &index, const disk::Layout &layout) { + index.clear(); + const auto &base_path = layout.base_path(); + + std::filesystem::create_directories(base_path); + + for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { + if (!entry.is_regular_file() && !entry.is_symlink()) { + continue; + } + + const auto ext = entry.path().extension(); + if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { + continue; + } + + auto id_opt = layout.get_id_from_node_path(entry.path()); + if (!id_opt) { + continue; + } + + const Id id = *id_opt; + index.set_raw(id, NodeStatus::Leaf); + } + + std::unordered_set visited; + for (const auto &[id, _] : index) { + auto parent = id.parent(); + while (parent) { + if (visited.find(*parent) != visited.end()) { + break; + } + visited.insert(*parent); + + if (index.get(*parent)) { + index.set_raw(*parent, NodeStatus::Inner); + } else { + index.set_raw(*parent, NodeStatus::Virtual); + } + parent = parent->parent(); + } + } +} + +} diff --git a/src/terrainlib/octree/storage/helpers.h b/src/terrainlib/octree/storage/helpers.h new file mode 100644 index 0000000..21ce111 --- /dev/null +++ b/src/terrainlib/octree/storage/helpers.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +#include + +#include "io/Error.h" +#include "octree/IndexMap.h" +#include "octree/disk/IndexFile.h" +#include "octree/disk/Layout.h" +#include "octree/disk/layout/Strategy.h" + +namespace octree::helpers { + +std::optional> guess_layout_strategy( + const std::filesystem::path &base_path, + size_t max_files_to_check = 100); +tl::expected save_index_map(const IndexMap &index, const disk::Layout &layout); +void update_index_map(IndexMap &index, const disk::Layout &layout); + +} diff --git a/src/terrainlib/octree/storage/open.cpp b/src/terrainlib/octree/storage/open.cpp new file mode 100644 index 0000000..2a5f404 --- /dev/null +++ b/src/terrainlib/octree/storage/open.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include + +#include "io/serialize.h" +#include "log.h" +#include "mesh/io.h" +#include "octree/disk/IndexFile.h" +#include "octree/disk/layout/StrategyRegister.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/storage/helpers.h" +#include "octree/storage/open.h" + +namespace octree { + +tl::expected open_index(const std::filesystem::path &index_path) { + LOG_TRACE("Opening storage index {}", index_path); + + const auto result = io::read_from_path(index_path); + if (!result.has_value()) { + LOG_TRACE("Failed to open storage index due to {}", result.error()); + return tl::unexpected(result.error()); + } + auto index_file = result.value(); + LOG_TRACE("Successfully read storage index with {} entries.", index_file.map.size()); + auto index_map = std::move(index_file.map); + const auto base_path = index_path.parent_path(); + auto layout_strategy = disk::layout::StrategyRegister::instance().create(index_file.layout_strategy_id); + disk::Layout layout(base_path, std::move(layout_strategy), index_file.preferred_extension); + RawStorage raw_storage(std::move(layout)); + return IndexedStorage(std::move(raw_storage), std::move(index_map)); +} + +Storage open_folder( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy, + const std::string extension_with_dot, + bool create_index) { + LOG_TRACE("Opening storage folder {}", base_path); + + if (!std::filesystem::is_directory(base_path)) { + if (std::filesystem::exists(base_path)) { + LOG_ERROR_AND_EXIT("Base path {} exists but is not a directory", base_path); + } + + LOG_TRACE("Base path {} does not exist, creating it", base_path); + std::filesystem::create_directories(base_path); + } + + const std::filesystem::path index_path = base_path / disk::v1::index_file_name(); + auto storage_opt = open_index(index_path); + if (storage_opt.has_value()) { + LOG_TRACE("Loaded existing index"); + return Storage(std::move(storage_opt.value())); + } + + auto layout_strategy_opt = helpers::guess_layout_strategy(base_path); + if (layout_strategy_opt) { + LOG_TRACE("Guessed layout of dataset as {}", + disk::layout::StrategyRegister::instance().get_id(**layout_strategy_opt)); + } else { + LOG_WARN("Unable to determine layout of dataset, using default which is {}", + disk::layout::StrategyRegister::instance().get_id(*default_layout_strategy)); + layout_strategy_opt = std::move(default_layout_strategy); + } + + disk::Layout layout(base_path, std::move(*layout_strategy_opt), extension_with_dot); + if (!create_index) { + return Storage(RawStorage(std::move(layout))); + } + + IndexMap map; + helpers::update_index_map(map, layout); + helpers::save_index_map(map, layout); + return Storage(RawStorage(std::move(layout)), std::move(map)); +} + +IndexedStorage open_folder_indexed( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy, + const std::string extension_with_dot) { + return IndexedStorage(open_folder(base_path, std::move(default_layout_strategy), extension_with_dot, true)); +} + +} // namespace octree diff --git a/src/terrainlib/octree/storage/open.h b/src/terrainlib/octree/storage/open.h new file mode 100644 index 0000000..824b34a --- /dev/null +++ b/src/terrainlib/octree/storage/open.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include + +#include "octree/storage/Storage.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/disk/layout/strategy/Default.h" +#include "io/Error.h" + +namespace octree { + +tl::expected open_index(const std::filesystem::path &index_path); +Storage open_folder( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), + const std::string extension_with_dot = ".terrain", + bool create_index = false); +IndexedStorage open_folder_indexed( + const std::filesystem::path &base_path, + std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), + const std::string extension_with_dot = ".terrain"); + +} \ No newline at end of file diff --git a/src/terrainlib/pch.h b/src/terrainlib/pch.h new file mode 100644 index 0000000..0149b59 --- /dev/null +++ b/src/terrainlib/pch.h @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/cgal.h" diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index 84c1476..d231a71 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -6,7 +6,7 @@ using namespace cli; Args cli::parse(int argc, const char * const * argv) { - assert(argc >= 0); + DEBUG_ASSERT(argc >= 0); CLI::App app{"terrainmerger"}; app.allow_windows_style_options(); @@ -39,6 +39,7 @@ Args cli::parse(int argc, const char * const * argv) { } catch (const CLI::ParseError &e) { exit(app.exit(e)); } + Args args; args.input_paths = input_paths; args.output_path = output_path; diff --git a/src/terrainmerger/earth.h b/src/terrainmerger/earth.h new file mode 100644 index 0000000..a6349fc --- /dev/null +++ b/src/terrainmerger/earth.h @@ -0,0 +1,18 @@ +#pragma once + +namespace earth { + constexpr double largest_radius() { + // Chimborazo + return 6384400; + } + constexpr double smallest_radius() { + // Litke Deep + return 6351704.3; + } + constexpr double radius() { + return 6371008; + } + constexpr glm::dvec2 radius_range() { + return {smallest_radius(), largest_radius()}; + } +} \ No newline at end of file diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index 5744a55..a556fa4 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -1,23 +1,26 @@ #include +#include +#include #include "log.h" #include "cli.h" #include "merge.h" +#include "mask.h" +#include "octree/Storage.h" void run(const cli::Args &args) { if (!std::filesystem::exists(args.output_path)) { std::filesystem::create_directories(args.output_path); } - octree::Storage output_storage = octree::open_folder(args.output_path); - std::vector input_storages; + octree::IndexedStorage output_storage = octree::open_folder_indexed(args.output_path); + std::vector input_storages; for (const auto &input_path : args.input_paths) { if (!std::filesystem::exists(input_path)) { - LOG_ERROR("Input path '{}' does not exist.", input_path.string()); + LOG_ERROR("Input path '{}' does not exist.", input_path); return; } - auto input_storage = octree::open_folder(input_path); - input_storages.push_back(std::move(input_storage)); + input_storages.emplace_back(octree::open_folder_indexed(input_path)); } merge_datasets(output_storage, input_storages); diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h new file mode 100644 index 0000000..e9ec99a --- /dev/null +++ b/src/terrainmerger/mask.h @@ -0,0 +1,583 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include "Dataset.h" +#include "mesh/SimpleMesh.h" +#include "mesh/cgal.h" +#include "mesh/convert.h" +#include "mesh/validate.h" +#include "srs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using Kernel = cgal::kernel::epeck::Kernel; +using Point2 = Kernel::Point_2; +using Polygon2 = CGAL::Polygon_2; +using PolygonWithHoles2 = CGAL::Polygon_with_holes_2; +using PolygonSet2 = CGAL::Polygon_set_2; +using MultipolygonWithHoles2 = CGAL::Multipolygon_with_holes_2; + +namespace mask { + +namespace { + template + static glm::vec scale_to_length(const glm::vec &v, const T target_length) { + const T len = glm::length(v); + if (len == T(0)) { + return glm::vec(T(0)); + } + return v * (target_length / len); + } +} + +enum class LoadErrorKind { + UnsupportedFormat, + FileNotFound, + EmptySource +}; + +class LoadError { +public: + LoadError() = default; + constexpr LoadError(LoadErrorKind kind) + : kind(kind) {} + + operator LoadErrorKind() const { + return this->kind; + } + constexpr bool operator==(LoadError other) const { + return this->kind == other.kind; + } + constexpr bool operator!=(LoadError other) const { + return this->kind != other.kind; + } + + std::string description() const { + switch (kind) { + case LoadErrorKind::UnsupportedFormat: + return "format not supported"; + case LoadErrorKind::FileNotFound: + return "file not found"; + case LoadErrorKind::EmptySource: + return "empty input source"; + default: + return "unknown error"; + } + } + + friend std::ostream &operator<<(std::ostream &os, const LoadError &err) { + return os << err.description(); + } + +private: + LoadErrorKind kind; +}; + +class SphereProjector { +public: + explicit SphereProjector(glm::dvec3 tangent_point) { + // Set up local tangent frame + this->radius = glm::length(tangent_point); + const glm::dvec3 a = tangent_point / radius; + const glm::dvec3 not_parallel_to_normal = a.z < 0.9 ? glm::dvec3(0, 0, 1) : glm::dvec3(0, 1, 0); + const glm::dvec3 b = glm::cross(a, not_parallel_to_normal); + const glm::dvec3 c = glm::cross(a, b); + + // Build rotation matrix (local tangent space basis) + this->rotation = glm::mat3(a, b, c); + this->inv_rotation = glm::transpose(this->rotation); + } + + glm::dvec2 project_point(const glm::dvec3 &cartesian) const { + // TODO: project onto tangent plane instead? + const glm::dvec3 rotated = rotation * glm::normalize(cartesian); + return cartesian_to_lon_lat(rotated); + } + + glm::dvec3 unproject_point(const glm::dvec2 &lon_lat) const { + const glm::dvec3 cartesian = lon_lat_to_cartesian(lon_lat); + const glm::dvec3 unrotated_point = inv_rotation * cartesian; + const glm::dvec3 point_on_sphere = unrotated_point * radius; + return point_on_sphere; + } + +private: + static glm::dvec2 cartesian_to_lon_lat(const glm::dvec3 &point) { + const glm::dvec3 normalized = glm::normalize(point); + const double lon = std::atan2(normalized.y, normalized.x); + const double lat = std::asin(normalized.z); + return glm::dvec2(lon, lat); + } + + static glm::dvec3 lon_lat_to_cartesian(const glm::dvec2 &lon_lat) { + const double lon = lon_lat.x; + const double lat = lon_lat.y; + + const double cosLat = std::cos(lat); + return glm::dvec3( + cosLat * std::cos(lon), + cosLat * std::sin(lon), + std::sin(lat)); + } + + double radius; + glm::mat3 rotation; + glm::mat3 inv_rotation; +}; + +struct ReferencedPolygonMask { + MultipolygonWithHoles2 polygons; + OGRSpatialReference srs; +}; + +struct SpherePolygonMask { + MultipolygonWithHoles2 polygons; + SphereProjector projector; +}; + +struct SphereMeshMask { + SimpleMesh3d mesh; +}; + +struct MeshMask { + SimpleMesh3d mesh; +}; + +namespace { +std::optional convert_ring(const OGRLinearRing &ring, bool is_outer) { + uint32_t num_points = ring.getNumPoints(); + if (ring.get_IsClosed()) { + num_points--; + } + if (num_points < 3) { + return std::nullopt; + } + + Polygon2 polygon; + for (uint32_t i = 0; i < num_points; i++) { + polygon.push_back(Point2(ring.getX(i), ring.getY(i))); + } + + if (!polygon.is_simple()) { + // Contains self intersections or duplicate points + LOG_WARN("Skipping non-simple polygon"); + return std::nullopt; + } + + if (is_outer != polygon.is_counterclockwise_oriented()) { + polygon.reverse_orientation(); + } + + return polygon; +} + +std::optional convert_polygon(const OGRPolygon &ogr_polygon) { + const OGRLinearRing *outer_ring = ogr_polygon.getExteriorRing(); + DEBUG_ASSERT(outer_ring); + + auto outer_opt = convert_ring(*outer_ring, true); + if (!outer_opt) { + return std::nullopt; + } + const Polygon2 outer = std::move(outer_opt.value()); + + PolygonWithHoles2 polygon(outer); + const uint32_t num_holes = static_cast(ogr_polygon.getNumInteriorRings()); + for (uint32_t i = 0; i < num_holes; i++) { + const OGRLinearRing *inner = ogr_polygon.getInteriorRing(i); + DEBUG_ASSERT(inner); + auto hole_opt = convert_ring(*inner, false); + if (!hole_opt) { + continue; + } + Polygon2 hole = std::move(hole_opt.value()); + polygon.add_hole(std::move(hole)); + } + + return polygon; +} + +void process_geometry(const OGRGeometry &geometry, MultipolygonWithHoles2 &out) { + const OGRwkbGeometryType geometry_type = wkbFlatten(geometry.getGeometryType()); // map 2.5d to 2d + + switch (geometry_type) { + case wkbPolygon: { + const OGRPolygon *polygon = geometry.toPolygon(); + DEBUG_ASSERT(polygon); + if (auto result = convert_polygon(*polygon)) { + out.add_polygon_with_holes(std::move(*result)); + } + break; + } + + case wkbMultiPolygon: + case wkbGeometryCollection: { + const OGRGeometryCollection *collection = geometry.toGeometryCollection(); + DEBUG_ASSERT(collection); + const uint32_t num_children = collection->getNumGeometries(); + for (uint32_t i = 0; i < num_children; i++) { + process_geometry(*collection->getGeometryRef(i), out); + } + break; + } + + default: + LOG_WARN("Skipping unsupported geometry type: {}", OGRGeometryTypeToName(geometry_type)); + break; + } +} + +void convert_to_ecef_and_project_onto_sphere(MultipolygonWithHoles2 &polygons, const SphereProjector &projector, const OGRSpatialReference &srs) { + const auto srs_transform = srs::transformation(srs, srs::ecef()); + for (auto &polygon : polygons.polygons_with_holes()) { + for (auto &cgal_point : polygon.outer_boundary()) { + const glm::dvec2 source_point = convert::to_glm_point(cgal_point); + const glm::dvec3 ecef_point = srs::transform_point(srs_transform.get(), glm::dvec3(source_point, 0)); + const glm::dvec2 projected_point = projector.project_point(ecef_point); + cgal_point = Point2(projected_point.x, projected_point.y); + } + for (auto &hole : polygon.holes()) { + for (auto &cgal_point : hole) { + const glm::dvec2 source_point = convert::to_glm_point(cgal_point); + const glm::dvec3 ecef_point = srs::transform_point(srs_transform.get(), glm::dvec3(source_point, 0)); + const glm::dvec2 projected_point = projector.project_point(ecef_point); + cgal_point = Point2(projected_point.x, projected_point.y); + } + } + } +} + +template +auto length2(const Vec &v) -> decltype(glm::dot(v, v)) { + return glm::dot(v, v); +} + +glm::dvec2 calculate_radius_squared_range(const SimpleMesh3d &mesh) { + const double infinity = std::numeric_limits::infinity(); + double min_radius_sq = +infinity; + double max_radius_sq = -infinity; + + for (const glm::dvec3 &position : mesh.positions) { + const double radius_sq = length2(position); + min_radius_sq = std::min(min_radius_sq, radius_sq); + max_radius_sq = std::max(max_radius_sq, radius_sq); + } + + return glm::dvec2(min_radius_sq, max_radius_sq); +} +glm::dvec2 calculate_radius_range(const SimpleMesh3d &mesh) { + return glm::sqrt(calculate_radius_squared_range(mesh)); +} + +glm::dvec2 calculate_radius_squared_range(const std::span meshes) { + const double infinity = std::numeric_limits::infinity(); + double min_radius_sq = +infinity; + double max_radius_sq = -infinity; + + for (const SimpleMesh3d &mesh : meshes) { + const auto radius_sq_range = calculate_radius_squared_range(mesh); + min_radius_sq = std::min(min_radius_sq, radius_sq_range.x); + max_radius_sq = std::min(max_radius_sq, radius_sq_range.y); + } + + return glm::dvec2(min_radius_sq, max_radius_sq); +} +glm::dvec2 calculate_radius_range(const std::span meshes) { + return glm::sqrt(calculate_radius_squared_range(meshes)); +} + +} // namespace + +inline tl::expected load_referenced_from_dataset(Dataset& mask_dataset) { + GDALDataset *dataset = mask_dataset.gdalDataset(); + + MultipolygonWithHoles2 polygons; + for (auto &&feature_layer_pair : dataset->GetFeatures()) { + OGRGeometry *geometry = feature_layer_pair.feature->GetGeometryRef(); + DEBUG_ASSERT(geometry); + process_geometry(*geometry, polygons); + } + + if (polygons.is_empty()) { + LOG_ERROR("No valid polygons found in mask dataset '{}'", mask_dataset.name()); + return tl::unexpected(LoadErrorKind::EmptySource); + } + + OGRSpatialReference srs; + // TODO: remove this try catch + try { + srs = mask_dataset.srs(); + } catch (std::runtime_error &e) { + LOG_WARN("Mask does not reference an srs, assuming WGS84"); + srs = srs::wgs84(); + } + + return ReferencedPolygonMask{.polygons = std::move(polygons), .srs = std::move(srs)}; +} + +inline SpherePolygonMask project_onto_sphere(ReferencedPolygonMask ref_mask, const double radius) { + auto mask_2d = std::move(ref_mask.polygons); + auto srs = std::move(ref_mask.srs); + + // Translate to ecef and project onto sphere + const auto source_bounds_cgal = mask_2d.bbox(); + const radix::geometry::Aabb3d source_bounds( + glm::dvec3(source_bounds_cgal.xmin(), source_bounds_cgal.ymin(), 0), + glm::dvec3(source_bounds_cgal.xmax(), source_bounds_cgal.ymax(), 0)); + const radix::geometry::Aabb3d ecef_bounds = srs::non_exact_bounds_transform(source_bounds, srs, srs::ecef()); + const glm::dvec3 bounds_center = ecef_bounds.centre(); + const glm::dvec3 tangent_point = scale_to_length(bounds_center, radius); + const SphereProjector projector(tangent_point); + convert_to_ecef_and_project_onto_sphere(mask_2d, projector, srs); + return SpherePolygonMask(mask_2d, projector); +} + +// Triangulation type definitions +using VertexBase = CGAL::Triangulation_vertex_base_2; +using FaceBase = CGAL::Constrained_triangulation_face_base_2; +using TDS = CGAL::Triangulation_data_structure_2; +using ExactTag = CGAL::Exact_predicates_tag; +using CDT = CGAL::Constrained_Delaunay_triangulation_2; +using FaceHandle = CDT::Face_handle; +using VertexHandle = CDT::Vertex_handle; + +inline SphereMeshMask triangulate(const SpherePolygonMask &mask) { + // Fix self intersections + const MultipolygonWithHoles2 polygons = CGAL::Polygon_repair::repair(mask.polygons); + + CDT cdt; + for (const auto &polygon : polygons.polygons_with_holes()) { + const auto &boundary = polygon.outer_boundary(); + cdt.insert_constraint(boundary.vertices_begin(), boundary.vertices_end(), true); + + for (const auto &hole : polygon.holes()) { + cdt.insert_constraint(hole.vertices_begin(), hole.vertices_end(), true); + } + } + + std::unordered_map in_domain_map; + boost::associative_property_map> in_domain(in_domain_map); + + // Mark facets that are inside the domain bounded by the polygon + CGAL::mark_domain_in_triangulation(cdt, in_domain); + DEBUG_ASSERT(cdt.is_valid()); + + // Build the resulting triangle mesh + SimpleMesh3d result; + // Map from CGAL vertex handles to output mesh indices + std::unordered_map vertex_index_map; + + for (FaceHandle face : cdt.finite_face_handles()) { + if (!get(in_domain, face)) { + continue; + } + + glm::uvec3 triangle; + for (uint32_t i = 0; i < 3; i++) { + const VertexHandle vertex = face->vertex(i); + auto [it, inserted] = vertex_index_map.emplace(vertex, 0); + if (inserted) { + const uint32_t new_index = result.positions.size(); + const Point2 &cgal_point = vertex->point(); + const glm::dvec2 point2d = convert::to_glm_point(cgal_point); + const glm::dvec3 point3d = mask.projector.unproject_point(point2d); + result.positions.push_back(point3d); + it->second = new_index; + } + triangle[i] = it->second; + } + + result.triangles.push_back(triangle); + } + + return SphereMeshMask(result); +} + +namespace { + struct ClosestFurthestCorners { + glm::dvec3 closest; + glm::dvec3 farthest; + }; + + ClosestFurthestCorners find_closest_and_farthest_corners(const radix::geometry::Aabb3d &bounds, const glm::dvec3 &point) { + const glm::dvec3 dist_min = glm::abs(point - bounds.min); + const glm::dvec3 dist_max = glm::abs(point - bounds.max); + + glm::dvec3 closest, farthest; + + for (uint32_t i = 0; i < 3; ++i) { + if (dist_min[i] < dist_max[i]) { + closest[i] = bounds.min[i]; + farthest[i] = bounds.max[i]; + } else { + closest[i] = bounds.max[i]; + farthest[i] = bounds.min[i]; + } + } + + return {closest, farthest}; + } +} + +inline glm::dvec2 calculate_radius_range(const radix::geometry::Aabb3d& bounds) { + const auto corners = find_closest_and_farthest_corners(bounds, glm::dvec3(0)); + return glm::dvec2(glm::length(corners.closest), glm::length(corners.farthest)); +} + +inline glm::dvec2 pad_radius_range(const glm::dvec2& radius_range, double padding_fraction) { + DEBUG_ASSERT(radius_range.x >= 0 || radius_range.y >= 0); + DEBUG_ASSERT(radius_range.y > radius_range.x); + + if (padding_fraction == 0.0) { + return radius_range; + } + + const double radius_range_center = (radius_range.x + radius_range.y) / 2; + const double radius_range_extends = (radius_range.y - radius_range.x) / 2; + const double padded_radius_range_extends = radius_range_extends * padding_fraction; + return glm::dvec2(radius_range_center - padded_radius_range_extends, radius_range_center + padded_radius_range_extends); +} + +inline MeshMask extrude( + const SphereMeshMask &mask, + const glm::dvec2& radius_range) { + cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mask.mesh); + + cgal::SurfaceMesh output_mesh; + auto bottom = [&](cgal::VertexDescriptor input_vertex, cgal::VertexDescriptor output_vertex) { + const cgal::Point3 input_point = cgal_mesh.point(input_vertex); + const glm::dvec3 glm_input_point = convert::to_glm_point(input_point); + const glm::dvec3 glm_offset_point = scale_to_length(glm_input_point, radius_range.x); + const cgal::Point3 offset_point = convert::to_cgal_point(glm_offset_point); + output_mesh.point(output_vertex) = offset_point; + }; + auto top = [&](cgal::VertexDescriptor input_vertex, cgal::VertexDescriptor output_vertex) { + const cgal::Point3 input_point = cgal_mesh.point(input_vertex); + const glm::dvec3 glm_input_point = convert::to_glm_point(input_point); + const glm::dvec3 glm_offset_point = scale_to_length(glm_input_point, radius_range.y); + const cgal::Point3 offset_point = convert::to_cgal_point(glm_offset_point); + output_mesh.point(output_vertex) = offset_point; + }; + CGAL::Polygon_mesh_processing::extrude_mesh(cgal_mesh, output_mesh, bottom, top); + + return MeshMask(convert::to_simple_mesh(output_mesh)); +} + +inline MeshMask extrude( + const SphereMeshMask &mask, + const radix::geometry::Aabb3d &mesh_bounds, + const double padding_fraction = 0.0) { + const glm::dvec2 radius_range = calculate_radius_range(mesh_bounds); + const glm::dvec2 padded_radius_range = pad_radius_range(radius_range, padding_fraction); + return extrude(mask, padded_radius_range); +} + +inline tl::expected load_referenced_from_path(const std::filesystem::path &path) { + if (!std::filesystem::exists(path)) { + LOG_ERROR("Mask file does not exist: {}", path); + return tl::unexpected(LoadErrorKind::FileNotFound); + } + + auto ds_opt = Dataset::open_vector(path); + if (!ds_opt.has_value()) { + LOG_ERROR("Failed to load mask datset: {}", path); + return tl::unexpected(LoadErrorKind::FileNotFound); + } + Dataset dataset = std::move(ds_opt.value()); + return load_referenced_from_dataset(dataset); +} + +inline tl::expected load_from_path(const std::filesystem::path &path, const glm::dvec2& radius_range) { + auto ref_mask_res = load_referenced_from_path(path); + if (!ref_mask_res.has_value()) { + return tl::unexpected(ref_mask_res.error()); + } + ReferencedPolygonMask ref_polygon_mask = std::move(ref_mask_res.value()); + SpherePolygonMask sphere_polygon_mask = project_onto_sphere(std::move(ref_polygon_mask), radius_range.x); + SphereMeshMask sphere_mesh_mask = triangulate(sphere_polygon_mask); + MeshMask mesh_mask = extrude(sphere_mesh_mask, radius_range); + + return mesh_mask; +} + +inline SpherePolygonMask compute_mesh_shadow(const SimpleMesh3d &mesh, const glm::dvec3 &tangent_point) { + const SphereProjector projector(tangent_point); + + // Rotate each point into local frame and convert to lat lon + std::vector projected_vertices; + projected_vertices.reserve(mesh.positions.size()); + for (const glm::dvec3 &vertex : mesh.positions) { + projected_vertices.push_back(projector.project_point(vertex)); + } + + // Validate the mesh before processing + SimpleMesh2d projected_mesh; + projected_mesh.positions = projected_vertices; + projected_mesh.triangles = mesh.triangles; + mesh::validate(projected_mesh); + + // Then get the outer boundary (i.e. the mask) of this 2D mesh. + // PolygonSet2 triangles; + std::vector triangles; + triangles.reserve(mesh.triangles.size()); + Polygon2 triangle; + triangle.reserve(3); + for (const glm::uvec3 &indices : mesh.triangles) { + triangle.clear(); + + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex_index = indices[i]; + const glm::dvec2 position = projected_vertices[vertex_index]; + triangle.push_back(Point2(position.x, position.y)); + } + + if (!triangle.is_simple()) { + // Contains self intersections or duplicate points + continue; + } + + // Ensure consistent orientation + if (!triangle.is_counterclockwise_oriented()) { + triangle.reverse_orientation(); + } + + triangles.push_back(triangle); + } + + MultipolygonWithHoles2 polygons; + CGAL::join(triangles.begin(), triangles.end(), std::back_inserter(polygons)); + return SpherePolygonMask(polygons, projector); +} + +inline SpherePolygonMask compute_mesh_shadow(const SimpleMesh3d &mesh, const glm::dvec3 &direction, const double radius) { + const glm::dvec3 tangent_point = scale_to_length(direction, radius); + return compute_mesh_shadow(mesh, tangent_point); +} + +inline SpherePolygonMask compute_mesh_shadow(const SimpleMesh3d &mesh, const double radius) { + const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); + return compute_mesh_shadow(mesh, bounds.centre(), radius); +} + +inline MeshMask create_from_mesh(const SimpleMesh3d &mesh, const glm::dvec3 &tangent_point, const glm::dvec2 &radius_range) { + SpherePolygonMask sphere_polygon_mask = compute_mesh_shadow(mesh, tangent_point); + SphereMeshMask sphere_mesh_mask = triangulate(sphere_polygon_mask); + return extrude(sphere_mesh_mask, radius_range); +} + +} diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index 0250a73..252bd4f 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -5,28 +5,99 @@ #include "mesh/SimpleMesh.h" #include "mesh/utils.h" -#include "octree/Storage.h" -#include "octree/traverse.h" +#include "earth.h" +#include "log.h" +#include "mask.h" +#include "mesh/boolean.h" +#include "mesh/clip.h" +#include "mesh/merge.h" +#include "mesh/validate.h" +#include "octree/Id.h" #include "octree/NodeStatus.h" #include "octree/Space.h" -#include "log.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/storage/open.h" +#include "octree/traverse.h" -inline SimpleMesh merge_meshes( - const SimpleMesh& mesh1, // base mesh - const SimpleMesh& mesh2 // priority mesh +using MeshMask = mask::MeshMask; + +inline SimpleMesh combine_meshes( + const SimpleMesh& a, + const SimpleMesh& b ) { - if (mesh1.is_empty()) { - return mesh2; + if (a.is_empty()) { + return b; + } + if (b.is_empty()) { + return a; } - if (mesh2.is_empty()) { - return mesh1; + + SimpleMesh combined_mesh; + combined_mesh.positions.reserve(a.vertex_count() + b.vertex_count()); + combined_mesh.uvs.reserve(a.vertex_count() + b.vertex_count()); + combined_mesh.triangles.reserve(a.face_count() + b.face_count()); + combined_mesh.positions.insert(combined_mesh.positions.end(), a.positions.begin(), a.positions.end()); + combined_mesh.positions.insert(combined_mesh.positions.end(), b.positions.begin(), b.positions.end()); + combined_mesh.uvs.insert(combined_mesh.uvs.end(), a.uvs.begin(), a.uvs.end()); + combined_mesh.uvs.insert(combined_mesh.uvs.end(), b.uvs.begin(), b.uvs.end()); + combined_mesh.triangles.insert(combined_mesh.triangles.end(), a.triangles.begin(), a.triangles.end()); + const size_t offset = a.vertex_count(); + for (const auto& triangle : b.triangles) { + combined_mesh.triangles.emplace_back(triangle.x + offset, triangle.y + offset, triangle.z + offset); + } +} + +inline SimpleMesh merge_meshes( + const SimpleMesh& base_mesh, // base mesh + const SimpleMesh& new_mesh, // priority mesh + const std::optional mask +) { + // TODO: dont convert to SimpleMesh all the time + if (mask.has_value()) { + const SimpleMesh new_mesh_clipped = mesh::clip_on_mesh(new_mesh, mask->mesh); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask->mesh); + + return combine_meshes(base_mesh_clipped, new_mesh_clipped); + // return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh_clipped); + } else { + // If one mesh is empty, return the other + // We can only do this if there is no mask, otherwise we need to at least clip the meshes + if (base_mesh.is_empty()) { + return new_mesh; + } + if (new_mesh.is_empty()) { + return base_mesh; + } + + // TODO: this doesnt really work well if there are intersections + return mesh::merge::merge_meshes(base_mesh, new_mesh); } - // TODO: actual merge - return mesh2; + /* + TODO: Advanced merging + const auto base_mesh_bounds = calculate_bounds(base_mesh); + auto bounds = base_mesh_bounds; + bounds.expand_by(new_mesh_bounds); + const glm::dvec3 tangent_point = bounds.centre(); + const glm::dvec2 radius_range = mask::pad_radius_range(mask::calculate_radius_range(bounds), 2); + if (mask.has_value()) { + auto result = mesh::intersection_and_difference(new_mesh, mask->mesh); + const SimpleMesh new_mesh_in_mask = std::move(result.intersection); + const SimpleMesh new_mesh_out_mask = std::move(result.difference); + const MeshMask mask_base_mesh = mask::create_from_mesh(base_mesh, tangent_point, radius_range); + const SimpleMesh new_mesh_out_mask_clipped = mesh::clip_on_mesh(new_mesh_out_mask, mask_base_mesh.mesh); + const MeshMask mask_new_mesh_in_mask = mask::create_from_mesh(new_mesh_in_mask, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh_in_mask.mesh); + return mesh::merge::merge_meshes(new_mesh_out_mask_clipped, base_mesh_clipped, new_mesh_in_mask); + } else { + const MeshMask mask_new_mesh = mask::create_from_mesh(new_mesh, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh.mesh); + return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh); + } + */ } -inline std::optional> split_mesh_into_children(const octree::NodeAndId& node) { +inline std::optional> split_mesh_into_children(const octree::IdAndNode& node) { if (!node.id.has_children()) { return std::nullopt; } @@ -34,36 +105,42 @@ inline std::optional> split_mesh_into_children( const auto space = octree::Space::earth(); // TODO: store in storage const auto children = node.id.children().value(); - std::array child_nodes; + std::array child_nodes; for (size_t i = 0; i < children.size(); i++) { const auto& child_id = children[i]; const auto child_bounds = space.get_node_bounds(child_id); - const auto child_mesh = clip_mesh_on_bounds(node.node, child_bounds); + const_cast(node.node).uvs.clear(); // TODO: remove this when we can handle uvs during clipping + const auto child_mesh = mesh::clip_on_bounds(node.node, child_bounds); + mesh::validate(child_mesh); child_nodes[i] = {child_id, std::move(child_mesh)}; } return child_nodes; } struct MergeState { - octree::Storage& output; - const octree::Storage& input; - const octree::IndexMap& output_index; - const octree::IndexMap& input_index; + octree::IndexedStorage& output; + const octree::IndexedStorage& input; + const std::optional &input_mask; }; inline void merge_leaves( MergeState& state, const octree::Id& id ) { - LOG_INFO("Merging leaves for id: {}", id); + LOG_TRACE("Merging leaves for id: {}", id); - assert(state.output_index.is(octree::NodeStatus::Leaf, id)); - assert(state.input_index.is(octree::NodeStatus::Leaf, id)); + DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Leaf, id)); + DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Leaf, id)); const auto output_mesh = state.output.read_node(id).value(); const auto input_mesh = state.input.read_node(id).value(); + + mesh::validate(output_mesh); + mesh::validate(input_mesh); + SimpleMesh merged_mesh = merge_meshes( output_mesh, - input_mesh + input_mesh, + state.input_mask ); state.output.write_node(id, merged_mesh); } @@ -75,31 +152,30 @@ inline void merge_with_leaf( bool leaf_is_output, // true if leaf is from output, false if from input bool leaf_is_clipped // true if the leaf mesh was generated by clipping ) { - LOG_INFO("Merging leaf from {} for id: {}", - leaf_is_output ? "output" : "input", - id - ); + LOG_TRACE("Merging leaf from {} for id: {}", + leaf_is_output ? "output" : "input", + id); if (leaf_is_output) { if (leaf_is_clipped) { - assert(state.output_index.is_absent(id)); + DEBUG_ASSERT(state.output.index().is_absent(id)); } else { - assert(state.output_index.is(octree::NodeStatus::Leaf, id)); + DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Leaf, id)); } - assert(state.input_index.is(octree::NodeStatus::Virtual, id)); + DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Virtual, id)); } else { if (leaf_is_clipped) { - assert(state.input_index.is_absent(id)); + DEBUG_ASSERT(state.input.index().is_absent(id)); } else { - assert(state.input_index.is(octree::NodeStatus::Leaf, id)); + DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Leaf, id)); } - assert(state.output_index.is(octree::NodeStatus::Virtual, id)); + DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Virtual, id)); } - assert(id.has_children()); + DEBUG_ASSERT(id.has_children()); // Split the leaf mesh into children const auto leaf_children = split_mesh_into_children({id, leaf_mesh}); - assert(leaf_children.has_value()); + DEBUG_ASSERT(leaf_children.has_value()); // Merge each child for (const auto& child : *leaf_children) { @@ -108,8 +184,8 @@ inline void merge_with_leaf( // Load other child mesh from the other dataset const auto other_status_opt = leaf_is_output - ? state.input_index.get(child_id) - : state.output_index.get(child_id); + ? state.input.index().get(child_id) + : state.output.index().get(child_id); if (!other_status_opt.has_value()) { // TODO: dont generate meshes for non-existing input nodes // If the other child does not exist, we can just write the clipped mesh from the leaf @@ -117,7 +193,7 @@ inline void merge_with_leaf( continue; } const auto other_status = other_status_opt.value(); - assert(other_status != octree::NodeStatus::Inner); + DEBUG_ASSERT(other_status != octree::NodeStatus::Inner); if (other_status == octree::NodeStatus::Virtual) { // If the other child is virtual, we recurse further @@ -128,11 +204,11 @@ inline void merge_with_leaf( if (leaf_is_output) { // If the leaf is from output, we read from input const auto other_mesh = state.input.read_node(child_id).value(); - merged_mesh = merge_meshes(child_mesh, other_mesh); + merged_mesh = merge_meshes(child_mesh, other_mesh, state.input_mask); } else { // If the leaf is from input, we read from output const auto other_mesh = state.output.read_node(child_id).value(); - merged_mesh = merge_meshes(other_mesh, child_mesh); + merged_mesh = merge_meshes(other_mesh, child_mesh, state.input_mask); } state.output.write_node(child_id, merged_mesh); } else { @@ -145,18 +221,18 @@ inline void copy_subtree_to_output( MergeState& state, const octree::Id& id ) { - LOG_INFO("Copying subtree to output for id: {}", id); + LOG_TRACE("Copying subtree to output for id: {}", id); - assert(state.input.has_node(id)); - assert(!state.output.has_node(id)); + DEBUG_ASSERT(state.input.has_node(id)); + DEBUG_ASSERT(!state.output.has_node(id)); octree::traverse( - state.input_index, + state.input.index(), [&](const octree::Id& child_id, const octree::NodeStatus& status) { if (status == octree::NodeStatus::Virtual) { return; } - assert(status == octree::NodeStatus::Leaf); + DEBUG_ASSERT(status == octree::NodeStatus::Leaf); const auto child_mesh = state.input.read_node(child_id).value(); state.output.write_node(child_id, child_mesh); @@ -170,10 +246,10 @@ inline void merge_node( MergeState& state, const octree::Id& id ) { - LOG_INFO("Merging nodes for id: {}", id); + LOG_TRACE("Merging nodes for id: {}", id); - const auto output_state_opt = state.output_index.get(id); - const auto input_state_opt = state.input_index.get(id); + const auto output_state_opt = state.output.index().get(id); + const auto input_state_opt = state.input.index().get(id); if (!input_state_opt.has_value()) { // If the input does not have the node, we can skip it @@ -188,8 +264,8 @@ inline void merge_node( const auto output_status = output_state_opt.value(); const auto input_status = input_state_opt.value(); - assert(output_status != octree::NodeStatus::Inner); - assert(input_status != octree::NodeStatus::Inner); + DEBUG_ASSERT(output_status != octree::NodeStatus::Inner); + DEBUG_ASSERT(input_status != octree::NodeStatus::Inner); if (output_status == octree::NodeStatus::Leaf && input_status == octree::NodeStatus::Leaf) { // If both nodes are leaves, we can merge them directly @@ -200,7 +276,7 @@ inline void merge_node( merge_with_leaf(state, id, state.input.read_node(id).value(), false, false); } else if (output_status == octree::NodeStatus::Virtual && input_status == octree::NodeStatus::Virtual) { // If both nodes are virtual, recurse - assert(id.has_children()); + DEBUG_ASSERT(id.has_children()); const auto children = id.children().value(); for (const auto& child_id : children) { merge_node(state, child_id); @@ -210,15 +286,30 @@ inline void merge_node( } } -inline void merge_datasets(octree::Storage& output, const octree::Storage& input) { - const auto& output_index = output.ensure_indexed(); - const auto& input_index = input.ensure_indexed(); +inline void merge_datasets(octree::IndexedStorage& output, const octree::IndexedStorage& input) { + std::optional mask = std::nullopt; + const auto mask_path = input.base_path() / "mask.geojson"; + LOG_TRACE("Looking for mask file at {}", mask_path); + if (std::filesystem::exists(mask_path)) { + LOG_INFO("Loading mask file from {}", mask_path); + const glm::dvec2 radius_range = mask::pad_radius_range(earth::radius_range(), 2); + auto mask_result = mask::load_from_path(mask_path, radius_range); + if (mask_result.has_value()) { + mask = std::move(mask_result.value()); + LOG_DEBUG("Loaded mask successfully"); + } else { + LOG_ERROR("Failed to load mask: {}", mask_result.error().description()); + } + } else { + LOG_DEBUG("No mask file found at {}, proceeding without mask", mask_path); + } - MergeState state{output, input, output_index, input_index}; + MergeState state{output, input, mask}; merge_node(state, octree::Id::root()); + output.save_index(); } -inline void merge_datasets(octree::Storage& output, const std::span inputs) { +inline void merge_datasets(octree::IndexedStorage& output, const std::span inputs) { for (const auto& input : inputs) { merge_datasets(output, input); } diff --git a/src/terrainsimplify/cli.cpp b/src/terrainsimplify/cli.cpp index e01e049..a2ff0a2 100644 --- a/src/terrainsimplify/cli.cpp +++ b/src/terrainsimplify/cli.cpp @@ -6,7 +6,7 @@ using namespace cli; Args cli::parse(int argc, const char * const * argv) { - assert(argc >= 0); + DEBUG_ASSERT(argc >= 0); CLI::App app{"terrainsimplify"}; app.allow_windows_style_options(); diff --git a/src/terrainsimplify/simplify.cpp b/src/terrainsimplify/simplify.cpp index 97d66c6..17a78e3 100644 --- a/src/terrainsimplify/simplify.cpp +++ b/src/terrainsimplify/simplify.cpp @@ -19,7 +19,7 @@ #include "log.h" #include "simplify.h" #include "uv_map.h" -#include "validate.h" +#include "mesh/validate.h" #include "mesh/utils.h" using namespace simplify; @@ -134,7 +134,7 @@ static std::pair check_condition(const VertexRatio &vertex_ratio, const double modified_vertex_count = modified.number_of_vertices(); const double current_ratio = static_cast(modified_vertex_count) / original.num_vertices(); // LOG_TRACE("Current vertex ratio is {:g}% with target {:g}%", current_ratio * 100, vertex_ratio.ratio * 100); - assert(current_ratio >= 0 && current_ratio <= 1); + DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); const bool fulfilled = current_ratio <= vertex_ratio.ratio; return {fulfilled, current_ratio}; } @@ -142,7 +142,7 @@ static std::pair check_condition(const EdgeRatio &edge_ratio, cons const double modified_edge_count = modified.number_of_edges(); const double current_ratio = static_cast(modified_edge_count) / original.num_edges(); // LOG_TRACE("Current edge ratio is {:g}% with target {:g}%", current_ratio * 100, edge_ratio.ratio * 100); - assert(current_ratio >= 0 && current_ratio <= 1); + DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); const bool fulfilled = current_ratio <= edge_ratio.ratio; return {fulfilled, current_ratio}; } @@ -150,7 +150,7 @@ static std::pair check_condition(const FaceRatio &face_ratio, cons const double modified_face_count = modified.number_of_faces(); const double current_ratio = static_cast(modified_face_count) / original.num_faces(); // LOG_TRACE("Current face ratio is {:g}% with target {:g}%", current_ratio * 100, face_ratio.ratio * 100); - assert(current_ratio >= 0 && current_ratio <= 1); + DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); const bool fulfilled = current_ratio <= face_ratio.ratio; return {fulfilled, current_ratio}; } @@ -495,8 +495,8 @@ Result simplify::simplify_mesh(const SimpleMesh&mesh, std::span -#include -#include - -template -inline size_t count_connected_components(const CGAL::Surface_mesh &mesh) { - typedef CGAL::Unique_hash_map CcMap; - typedef boost::associative_property_map CcPropertyMap; - - CcMap cc_map; - CcPropertyMap cc_pmap(cc_map); - const size_t num = CGAL::Polygon_mesh_processing::connected_components(mesh, cc_pmap); - return num; -} - -template -inline void validate_mesh(const CGAL::Surface_mesh &mesh) { -#if !NDEBUG - return; -#endif - - assert(mesh.is_valid()); - assert(CGAL::is_triangle_mesh(mesh)); - assert(CGAL::is_valid_polygon_mesh(mesh)); - assert(count_connected_components(mesh) == 1); - assert(!CGAL::Polygon_mesh_processing::does_self_intersect(mesh)); -} diff --git a/src/tile_downloader/main.cpp b/src/tile_downloader/main.cpp index 30594e4..8c476a3 100644 --- a/src/tile_downloader/main.cpp +++ b/src/tile_downloader/main.cpp @@ -98,6 +98,7 @@ bool create_directories2(const std::filesystem::path& path) { class TileUrlBuilder { public: + virtual ~TileUrlBuilder() = default; virtual std::string build_url(const radix::tile::Id &tile_id) const = 0; }; @@ -124,7 +125,7 @@ class BasemapTileUrlBuilder : public TileUrlBuilder { // https://gataki.cg.tuwien.ac.at/raw/basemap/tiles/11/710/1098.jpeg class GatakiTileUrlBuilder : public TileUrlBuilder { public: - GatakiTileUrlBuilder(const std::map &_args) {} + GatakiTileUrlBuilder(const std::map & /* args */) {} std::string build_url(const radix::tile::Id &tile_id) const { const radix::tile::Id google_tile_id = tile_id.to(radix::tile::Scheme::SlippyMap); @@ -132,8 +133,6 @@ class GatakiTileUrlBuilder : public TileUrlBuilder { "https://gataki.cg.tuwien.ac.at/raw/basemap/tiles/{}/{}/{}.jpeg", google_tile_id.zoom_level, google_tile_id.coords.y, google_tile_id.coords.x); } - -private: }; static std::string format_tile(const radix::tile::Id tile) { @@ -183,7 +182,7 @@ struct ProgressCallbackData { radix::tile::Id tile; }; -int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t _ultotal, curl_off_t _ulnow) { +int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t /* ultotal */, curl_off_t /* ulnow */) { ProgressCallbackData &data = *static_cast(clientp); if (dltotal == 0) { @@ -227,8 +226,7 @@ enum DownloadResult { Failed }; -class TileDownloader -{ +class TileDownloader { public: TileDownloader(TileUrlBuilder *url_builder, const std::map &args) { this->url_builder = url_builder; diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 0b6df39..5a16374 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -36,16 +36,15 @@ add_executable(unittests_terrainlib terrainlib/convert.cpp terrainlib/dataset.cpp terrainlib/grid.cpp - terrainlib/progress_indicator_test.cpp terrainlib/index_map.cpp terrainlib/index_traverse.cpp - terrainlib/octree_id.cpp - terrainlib/octree_space.cpp + terrainlib/mesh_clip.cpp terrainlib/mesh_io.cpp terrainlib/mesh_utils.cpp - terrainlib/mesh_clip.cpp + terrainlib/octree_id.cpp + terrainlib/octree_space.cpp + terrainlib/progress_indicator_test.cpp ) - target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) @@ -59,8 +58,7 @@ add_executable(unittests_tilebuilder tilebuilder/parallel_tiler.cpp tilebuilder/tile_heights_generator.cpp tilebuilder/top_down_tiler.cpp -) - +) target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2WithMain) @@ -68,7 +66,6 @@ add_executable(unittests_terrainsimplify catch2_helpers.h terrainsimplify/merge.cpp ) - target_link_libraries(unittests_terrainsimplify PUBLIC terrainsimplifylib Catch2::Catch2WithMain) @@ -77,6 +74,12 @@ add_executable(unittests_terrainbuilder terrainbuilder/mesh.cpp terrainbuilder/texture.cpp ) - target_link_libraries(unittests_terrainbuilder PUBLIC terrainbuilderlib terrainsimplifylib terrainlib Catch2WithMain) target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") + + +add_executable(unittests_terrainmerger + catch2_helpers.h + terrainmerger/mask.cpp +) +target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib terrainlib Catch2WithMain) diff --git a/unittests/terrainlib/mesh_clip.cpp b/unittests/terrainlib/mesh_clip.cpp index e903f63..3596e66 100644 --- a/unittests/terrainlib/mesh_clip.cpp +++ b/unittests/terrainlib/mesh_clip.cpp @@ -14,6 +14,7 @@ #include "mesh/convert.h" #include "mesh/io.h" #include "mesh/utils.h" +#include "mesh/validate.h" #include "octree/Space.h" #include "octree/Id.h" @@ -34,11 +35,17 @@ TEST_CASE("single triangle in bounds") { glm::dvec3(1, 0, 0), glm::dvec3(0, 1, 0), }; + mesh.uvs = { + glm::dvec2(0, 0), + glm::dvec2(1, 0), + glm::dvec2(0, 1), + }; mesh.triangles = { glm::uvec3(0, 1, 2)}; const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(1, 1, 1)); const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); CHECK(mesh.positions == clipped_mesh.positions); + CHECK(mesh.uvs == clipped_mesh.uvs); CHECK(mesh.triangles == clipped_mesh.triangles); } @@ -49,11 +56,17 @@ TEST_CASE("single triangle out of bounds") { glm::dvec3(1, 0, 0), glm::dvec3(0, 1, 0), }; + mesh.uvs = { + glm::dvec2(0, 0), + glm::dvec2(1, 0), + glm::dvec2(0, 1), + }; mesh.triangles = { glm::uvec3(0, 1, 2)}; const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(-0.1, -0.1, -0.1)); const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); CHECK(clipped_mesh.positions == std::vector{}); + CHECK(clipped_mesh.uvs == std::vector{}); CHECK(clipped_mesh.triangles == std::vector{}); } @@ -64,11 +77,17 @@ TEST_CASE("single triangle touching bounds in point") { glm::dvec3(1, 0, 0), glm::dvec3(0, 1, 0), }; + mesh.uvs = { + glm::dvec2(0, 0), + glm::dvec2(1, 0), + glm::dvec2(0, 1), + }; mesh.triangles = { glm::uvec3(0, 1, 2)}; const radix::geometry::Aabb3d bounds(glm::dvec3(-1, -1, -1), glm::dvec3(0, 0, 0)); const SimpleMesh clipped_mesh = mesh::clip_on_bounds(mesh, bounds); CHECK(clipped_mesh.positions == std::vector{}); + CHECK(clipped_mesh.uvs == std::vector{}); CHECK(clipped_mesh.triangles == std::vector{}); } @@ -160,7 +179,7 @@ TEST_CASE("single triangle with two vertices in bounds") { } void run_checks(const SimpleMesh &mesh, const SimpleMesh &clipped_mesh, const radix::geometry::Aabb3d &bounds) { - validate_mesh(clipped_mesh); + mesh::validate(clipped_mesh); // Check that no vertices are outside the bounds for (const auto &position : clipped_mesh.positions) { @@ -248,7 +267,7 @@ TEST_CASE("mesh::clip_on_bounds") { glm::uvec3(1, 2, 6), glm::uvec3(1, 6, 5)}; - validate_mesh(mesh); + mesh::validate(mesh); const std::array bounds_array = { radix::geometry::Aabb3d(glm::dvec3(-2.0, -2.0, -2.0), glm::dvec3(2.0, 2.0, 2.0)), diff --git a/unittests/terrainmerger/mask.cpp b/unittests/terrainmerger/mask.cpp new file mode 100644 index 0000000..e69de29 From 747bba18d697236ad969077bfdb45eb3b8b59aac Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 3 Jul 2025 11:34:43 +0200 Subject: [PATCH 087/122] Remove IStorage --- src/terrainlib/octree/Storage.h | 1 - src/terrainlib/octree/storage/IStorage.h | 40 -------------------- src/terrainlib/octree/storage/Node.h | 24 ++++++++++++ src/terrainlib/octree/storage/RawStorage.cpp | 5 ++- src/terrainlib/octree/storage/RawStorage.h | 19 +++++----- src/terrainlib/octree/storage/Storage.h | 17 +++++---- src/terrainlib/octree/storage/cache/ICache.h | 2 +- 7 files changed, 47 insertions(+), 61 deletions(-) delete mode 100644 src/terrainlib/octree/storage/IStorage.h create mode 100644 src/terrainlib/octree/storage/Node.h diff --git a/src/terrainlib/octree/Storage.h b/src/terrainlib/octree/Storage.h index c2653d6..77ca21f 100644 --- a/src/terrainlib/octree/Storage.h +++ b/src/terrainlib/octree/Storage.h @@ -1,6 +1,5 @@ #pragma once -#include "octree/storage/IStorage.h" #include "octree/storage/RawStorage.h" #include "octree/storage/Storage.h" #include "octree/storage/IndexedStorage.h" diff --git a/src/terrainlib/octree/storage/IStorage.h b/src/terrainlib/octree/storage/IStorage.h deleted file mode 100644 index 02bd199..0000000 --- a/src/terrainlib/octree/storage/IStorage.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -#include - -#include "mesh/SimpleMesh.h" -#include "octree/Id.h" -#include "mesh/io/error.h" - -namespace octree { -using Node = SimpleMesh; - -struct IdAndNode { - Id id; - Node node; - - IdAndNode() = default; - IdAndNode(Id id, Node node) : id(std::move(id)), node(std::move(node)) {} - - operator Node() const { - return std::move(node); - } - operator Id() const { - return id; - } -}; - -class IStorage { -public: - virtual ~IStorage() = default; - virtual tl::expected read_node(const Id &id) const = 0; - virtual tl::expected write_node(const Id &id, const Node &node) = 0; - virtual bool remove_node(const Id &id) = 0; - virtual bool has_node(const Id &id) const = 0; - virtual std::filesystem::path get_node_path(const Id &id) const = 0; - virtual std::filesystem::path base_path() const = 0; -}; - -} // namespace octree diff --git a/src/terrainlib/octree/storage/Node.h b/src/terrainlib/octree/storage/Node.h new file mode 100644 index 0000000..947b7ba --- /dev/null +++ b/src/terrainlib/octree/storage/Node.h @@ -0,0 +1,24 @@ +#pragma once + +#include "mesh/SimpleMesh.h" +#include "octree/Id.h" + +namespace octree { +using Node = SimpleMesh; + +struct IdAndNode { + Id id; + Node node; + + IdAndNode() = default; + IdAndNode(Id id, Node node) : id(std::move(id)), node(std::move(node)) {} + + operator Node() const { + return std::move(node); + } + operator Id() const { + return id; + } +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp index 23db99b..9c549e0 100644 --- a/src/terrainlib/octree/storage/RawStorage.cpp +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -12,12 +12,13 @@ tl::expected RawStorage::read_node(const Id &id) return mesh::io::load_from_path(node_path); } -tl::expected RawStorage::write_node(const Id &id, const Node &node) noexcept { +tl::expected RawStorage::write_node(const Id &id, const Node &node) const noexcept { const auto node_path = this->get_node_path(id); return mesh::io::save_to_path(node, node_path); } -bool RawStorage::remove_node(const Id &id) noexcept { + +bool RawStorage::remove_node(const Id &id) const noexcept { const auto node_path = this->get_node_path(id); return std::filesystem::remove(node_path); } diff --git a/src/terrainlib/octree/storage/RawStorage.h b/src/terrainlib/octree/storage/RawStorage.h index 4006e04..b373a7e 100644 --- a/src/terrainlib/octree/storage/RawStorage.h +++ b/src/terrainlib/octree/storage/RawStorage.h @@ -4,14 +4,15 @@ #include +#include "mesh/io/error.h" #include "octree/Id.h" -#include "octree/storage/IStorage.h" #include "octree/disk/Layout.h" -#include "mesh/io/error.h" +#include "octree/storage/Node.h" +#include "octree/storage/Error.h" namespace octree { -class RawStorage : public IStorage { +class RawStorage { public: explicit RawStorage(disk::Layout layout) noexcept; ~RawStorage() = default; @@ -20,12 +21,12 @@ class RawStorage : public IStorage { RawStorage(RawStorage&&) = default; RawStorage& operator=(RawStorage&&) = default; - tl::expected read_node(const Id &id) const noexcept override; - tl::expected write_node(const Id &id, const Node &node) noexcept override; - bool remove_node(const Id &id) noexcept override; - bool has_node(const Id &id) const noexcept override; - std::filesystem::path get_node_path(const Id &id) const noexcept override; - std::filesystem::path base_path() const noexcept override; + tl::expected read_node(const Id &id) const noexcept; + tl::expected write_node(const Id &id, const Node &node) const noexcept; + bool remove_node(const Id &id) const noexcept; + bool has_node(const Id &id) const noexcept; + std::filesystem::path get_node_path(const Id &id) const noexcept; + std::filesystem::path base_path() const noexcept; const disk::Layout& layout() const noexcept; diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 516c469..75900b5 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -90,7 +90,7 @@ struct MaybeCache : public ICache { }; } -class Storage : public IStorage { +class Storage { public: explicit Storage(RawStorage inner) : _inner(std::move(inner)) {} @@ -102,7 +102,7 @@ class Storage : public IStorage { Storage(Storage&&) = default; Storage& operator=(Storage&&) = default; - ~Storage() override { + virtual ~Storage() { if (this->_index.map.has_value() && this->_index.dirty) { auto result = helpers::save_index_map(this->_index.map.value(), this->_inner.layout()); if (!result.has_value()) { @@ -111,7 +111,7 @@ class Storage : public IStorage { } } - tl::expected read_node(const Id &id) const noexcept override { + tl::expected read_node(const Id &id) const noexcept { if (const auto node_opt = this->_cache.get(id)) { return node_opt.value(); } @@ -127,7 +127,7 @@ class Storage : public IStorage { return result; } - tl::expected write_node(const Id &id, const Node &node) noexcept override { + tl::expected write_node(const Id &id, const Node &node) noexcept { const auto result = this->_inner.write_node(id, node); if (result.has_value()) { this->_cache.put(id, node); @@ -136,24 +136,25 @@ class Storage : public IStorage { return result; } - bool remove_node(const Id &id) noexcept override { + + bool remove_node(const Id &id) noexcept { this->_cache.remove(id); this->_index.remove(id); return this->_inner.remove_node(id); } - bool has_node(const Id &id) const noexcept override { + bool has_node(const Id &id) const noexcept { return this->_cache.contains(id) || this->_index.contains(id, false) || this->_inner.has_node(id); } - std::filesystem::path get_node_path(const Id &id) const noexcept override { + std::filesystem::path get_node_path(const Id &id) const noexcept { return this->_inner.get_node_path(id); } - std::filesystem::path base_path() const noexcept override { + std::filesystem::path base_path() const noexcept { return this->_inner.base_path(); } diff --git a/src/terrainlib/octree/storage/cache/ICache.h b/src/terrainlib/octree/storage/cache/ICache.h index 2f836a2..dd2eb5f 100644 --- a/src/terrainlib/octree/storage/cache/ICache.h +++ b/src/terrainlib/octree/storage/cache/ICache.h @@ -3,7 +3,7 @@ #include #include "octree/Id.h" -#include "octree/storage/IStorage.h" +#include "octree/storage/Node.h" namespace octree { From ea8c3a0901df8e0f1e9edd89fef69c3d833fe944 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 3 Jul 2025 11:35:32 +0200 Subject: [PATCH 088/122] Fix bug with degenerate triangles in clip_on_bounds --- src/terrainlib/mesh/clip.cpp | 39 +++++++++++++++++++++++++++--------- src/terrainlib/mesh/clip.h | 2 ++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index 7de10d0..01d2690 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -23,10 +23,20 @@ double significant_above_epsilon(double x, double epsilon) { return x - residual; } -template -bool is_degenerate(const T& triangle) { +bool is_degenerate(const glm::uvec3& triangle) { return triangle[0] == triangle[1] || triangle[1] == triangle[2] || triangle[2] == triangle[0]; } +template +bool epsilon_equal(const glm::tvec3& a, const glm::tvec3& b, const T epsilon) { + return glm::all(glm::epsilonEqual(a, b, epsilon)); + // return glm::length2(a - b) < epsilon * epsilon; +} +template +bool is_degenerate(const std::array, 3>& triangle, const T epsilon) { + return epsilon_equal(triangle[0], triangle[1], epsilon) || + epsilon_equal(triangle[1], triangle[2], epsilon) || + epsilon_equal(triangle[2], triangle[0], epsilon); +} struct DVec3Hash { const double epsilon; @@ -43,7 +53,7 @@ struct DVec3Equal { const double epsilon; bool operator()(const glm::dvec3 &a, const glm::dvec3 &b) const { - return glm::all(glm::epsilonEqual(a, b, epsilon)); + return epsilon_equal(a, b, epsilon); } }; @@ -74,6 +84,8 @@ Intersection compute_intersection(const radix::geometry::Edge<3, T> &line, co } // namespace SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { + mesh::validate(mesh); + if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { return {}; } @@ -267,7 +279,7 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A inside_uv, intersection1_uv, intersection2_uv}; - if (is_degenerate(new_vertices)) { + if (is_degenerate(new_vertices, epsilon)) { skip_triangle = true; break; } @@ -326,15 +338,15 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A intersection2_uv, intersection1_uv}; - if (is_degenerate(new_vertices2)) { - if (is_degenerate(new_vertices1)) { + if (is_degenerate(new_vertices2, epsilon)) { + if (is_degenerate(new_vertices1, epsilon)) { skip_triangle = true; break; } else { current_triangle_and_vertices = {new_triangle1, new_vertices1, new_uvs1, static_cast(plane_index + 1)}; } } else { - if (is_degenerate(new_vertices1)) { + if (is_degenerate(new_vertices1, epsilon)) { current_triangle_and_vertices = {new_triangle2, new_vertices2, new_uvs2, static_cast(plane_index + 1)}; } else { current_triangle_and_vertices = {new_triangle1, new_vertices1, new_uvs1, static_cast(plane_index + 1)}; @@ -367,8 +379,17 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A vertex_index = add_original_vertex(original_vertex_index, vertex); } } - DEBUG_ASSERT(!is_degenerate(indices)); - new_triangles.push_back(indices); + if (is_degenerate(indices)) { + // It should not be possible to have a degenerate triangle that contains + // a new vertex here + for (uint32_t i = 0; i < 3; i++) { + if (original_indices[i] == invalid_index) { + DEBUG_ASSERT(indices[i] != new_positions.size() - 1); + } + } + } else { + new_triangles.push_back(indices); + } // Continue with the next triangle if there are any left to clip if (triangles_left_to_clip.empty()) { diff --git a/src/terrainlib/mesh/clip.h b/src/terrainlib/mesh/clip.h index 6377189..65d64ab 100644 --- a/src/terrainlib/mesh/clip.h +++ b/src/terrainlib/mesh/clip.h @@ -5,6 +5,8 @@ #include "mesh/SimpleMesh.h" namespace mesh { + SimpleMesh clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); SimpleMesh clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh); + } From 590a9f79e062b134c0953ff6093486431d30ad3a Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 3 Jul 2025 11:36:56 +0200 Subject: [PATCH 089/122] Create hardlinks when copying nodes --- src/CMakeLists.txt | 1 - src/terrainlib/octree/IndexMap.cpp | 1 - src/terrainlib/octree/storage/Error.h | 55 ++++++++++++++++++++ src/terrainlib/octree/storage/RawStorage.cpp | 25 +++++++++ src/terrainlib/octree/storage/RawStorage.h | 1 + src/terrainlib/octree/storage/Storage.h | 13 +++++ src/terrainmerger/merge.h | 14 ++--- 7 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 src/terrainlib/octree/storage/Error.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 920b8b0..6e404a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,7 +138,6 @@ add_library(terrainlib terrainlib/octree/storage/cache/LruCache.h terrainlib/octree/storage/helpers.h terrainlib/octree/storage/helpers.cpp terrainlib/octree/storage/IndexedStorage.h - terrainlib/octree/storage/IStorage.h terrainlib/octree/storage/open.h terrainlib/octree/storage/open.cpp terrainlib/octree/storage/RawStorage.h terrainlib/octree/storage/RawStorage.cpp terrainlib/octree/storage/Storage.h diff --git a/src/terrainlib/octree/IndexMap.cpp b/src/terrainlib/octree/IndexMap.cpp index 724adb6..8bb7e53 100644 --- a/src/terrainlib/octree/IndexMap.cpp +++ b/src/terrainlib/octree/IndexMap.cpp @@ -119,7 +119,6 @@ IndexMap::const_iterator IndexMap::cend() const { return this->_index.cend(); } - NodeStatus* IndexMap::get_raw(Id id) { if (auto it = this->_index.find(id); it != this->_index.end()) { return &it->second; diff --git a/src/terrainlib/octree/storage/Error.h b/src/terrainlib/octree/storage/Error.h new file mode 100644 index 0000000..892534e --- /dev/null +++ b/src/terrainlib/octree/storage/Error.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +namespace octree { + +enum class CopyMeshErrorKind { + FileNotFound, + CreateLink, + CreateDirectories, + RemoveOld +}; + +// TODO: store the std::error_code in the CopyMeshError +class CopyMeshError { +public: + CopyMeshError() = default; + constexpr CopyMeshError(CopyMeshErrorKind kind) + : kind(kind) {} + + operator CopyMeshErrorKind() const { + return this->kind; + } + constexpr bool operator==(CopyMeshError other) const { + return this->kind == other.kind; + } + constexpr bool operator!=(CopyMeshError other) const { + return this->kind != other.kind; + } + + std::string description() const { + switch (kind) { + case CopyMeshErrorKind::FileNotFound: + return "file not found"; + case CopyMeshErrorKind::CreateLink: + return "cannot create hard link"; + case CopyMeshErrorKind::CreateDirectories: + return "cannot create directories"; + case CopyMeshErrorKind::RemoveOld: + return "cannot remove current file"; + default: + return "undefined error"; + } + } + + friend std::ostream &operator<<(std::ostream &os, const CopyMeshError &err) { + return os << err.description(); + } + +private: + CopyMeshErrorKind kind; +}; + +} // namespace octree diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp index 9c549e0..ead38e3 100644 --- a/src/terrainlib/octree/storage/RawStorage.cpp +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -17,6 +17,31 @@ tl::expected RawStorage::write_node(const Id &id, return mesh::io::save_to_path(node, node_path); } +tl::expected RawStorage::copy_node_to(const Id &id, const RawStorage &target) const noexcept { + const auto source_node_path = this->get_node_path(id); + if (!this->has_node(id)) { + return tl::unexpected(CopyMeshErrorKind::FileNotFound); + } + std::error_code ec; + const auto target_node_path = target.get_node_path(id); + if (std::filesystem::remove(target_node_path, ec)) { + if (ec) { + return tl::unexpected(CopyMeshErrorKind::RemoveOld); + } + } + std::filesystem::create_directories(target_node_path.parent_path(), ec); + if (ec) { + return tl::unexpected(CopyMeshErrorKind::CreateDirectories); + } + std::filesystem::create_hard_link( + source_node_path, + target_node_path, + ec); + if (ec) { + return tl::unexpected(CopyMeshErrorKind::CreateLink); + } + return {}; +} bool RawStorage::remove_node(const Id &id) const noexcept { const auto node_path = this->get_node_path(id); diff --git a/src/terrainlib/octree/storage/RawStorage.h b/src/terrainlib/octree/storage/RawStorage.h index b373a7e..e1c3789 100644 --- a/src/terrainlib/octree/storage/RawStorage.h +++ b/src/terrainlib/octree/storage/RawStorage.h @@ -23,6 +23,7 @@ class RawStorage { tl::expected read_node(const Id &id) const noexcept; tl::expected write_node(const Id &id, const Node &node) const noexcept; + tl::expected copy_node_to(const Id &id, const RawStorage &target) const noexcept; bool remove_node(const Id &id) const noexcept; bool has_node(const Id &id) const noexcept; std::filesystem::path get_node_path(const Id &id) const noexcept; diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 75900b5..63dfdba 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -136,6 +136,19 @@ class Storage { return result; } + tl::expected copy_node_to(const Id &id, Storage &target) const { + if (!this->_index.contains(id, true)) { + return tl::unexpected(CopyMeshErrorKind::FileNotFound); + } + + const auto result = this->_inner.copy_node_to(id, target._inner); + if (result.has_value() && target.is_indexed()) { + auto& index = target.index_mut().value(); + index.add(id); + target.set_index_dirty(); + } + return result; + } bool remove_node(const Id &id) noexcept { this->_cache.remove(id); diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index 252bd4f..d049589 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -3,6 +3,8 @@ #include #include +#include + #include "mesh/SimpleMesh.h" #include "mesh/utils.h" #include "earth.h" @@ -142,6 +144,7 @@ inline void merge_leaves( input_mesh, state.input_mask ); + // TODO: use copy_node_to if the merged mesh is the same as the output mesh state.output.write_node(id, merged_mesh); } @@ -227,19 +230,18 @@ inline void copy_subtree_to_output( DEBUG_ASSERT(!state.output.has_node(id)); octree::traverse( - state.input.index(), - [&](const octree::Id& child_id, const octree::NodeStatus& status) { + state.input.index(), + [&](const octree::Id &child_id, const octree::NodeStatus &status) { if (status == octree::NodeStatus::Virtual) { return; } DEBUG_ASSERT(status == octree::NodeStatus::Leaf); - const auto child_mesh = state.input.read_node(child_id).value(); - state.output.write_node(child_id, child_mesh); + const auto result = state.input.copy_node_to(child_id, state.output); + DEBUG_ASSERT(result.has_value()); }, [](const octree::Id &) { return true; }, - id - ); + id); } inline void merge_node( From d852f169fbf20936744dea6bb01a8dc55a6886e0 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 4 Jul 2025 17:30:49 +0200 Subject: [PATCH 090/122] Add --threads to terrainbuilder --- src/terrainbuilder/main.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/terrainbuilder/main.cpp b/src/terrainbuilder/main.cpp index ccf66da..36be478 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/terrainbuilder/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "Dataset.h" #include "log.h" @@ -224,6 +225,9 @@ int run(std::span args) { batch->add_option("--format", output_format, "Output mesh format") ->check(CLI::IsMember({".glb", ".gltf", ".terrain"})) ->default_val(".glb"); + uint32_t num_threads = 0; + batch->add_option("--threads", num_threads, "Number of threads to use") + ->check(CLI::PositiveNumber); CLI11_PARSE(app, argc, argv); @@ -253,6 +257,12 @@ int run(std::span args) { } if (*batch) { + std::optional tbb_control; + if (num_threads > 0) { + LOG_INFO("Using {} threads for batch processing.", num_threads); + tbb_control.emplace(tbb::global_control(tbb::global_control::max_allowed_parallelism, num_threads)); + } + terrainbuilder::build_all_patches( dataset, target_level, From 239303daa3dc66caf5c49c4df3070630e62b365f Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 4 Jul 2025 17:31:49 +0200 Subject: [PATCH 091/122] Fix some unused warnings on release --- src/terrainlib/mesh/merge.h | 2 ++ src/terrainlib/mesh/validate.inl | 11 ++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 606c5dd..4a17a94 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -128,6 +128,7 @@ class VertexMapping { } void validate() const { +#ifndef NDEBUG for (size_t i = 0; i < this->mesh_count(); i++) { DEBUG_ASSERT(this->forward[i].size() == this->backward[i].size()); @@ -145,6 +146,7 @@ class VertexMapping { DEBUG_ASSERT(mapped == e.first); } } +#endif } private: diff --git a/src/terrainlib/mesh/validate.inl b/src/terrainlib/mesh/validate.inl index 1b724be..9451135 100644 --- a/src/terrainlib/mesh/validate.inl +++ b/src/terrainlib/mesh/validate.inl @@ -88,24 +88,21 @@ void validate_sorted_normalized_mesh(const SimpleMesh_ &mesh) { template void validate(const SimpleMesh_ &mesh) { -#if NDEBUG - return; -#endif +#ifndef NDEBUG SimpleMesh_ sorted(mesh); sort_and_normalize_triangles(sorted); validate_sorted_normalized_mesh(sorted); +#endif } template inline void validate(const CGAL::Surface_mesh &mesh) { -#if NDEBUG - return; -#endif - +#ifndef NDEBUG DEBUG_ASSERT(mesh.is_valid()); DEBUG_ASSERT(CGAL::is_triangle_mesh(mesh)); DEBUG_ASSERT(CGAL::is_valid_polygon_mesh(mesh)); DEBUG_ASSERT(!CGAL::Polygon_mesh_processing::does_self_intersect(mesh)); +#endif } } From 2338128fb66daf031e62dd621b66b40ed10411d6 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 4 Jul 2025 17:33:29 +0200 Subject: [PATCH 092/122] Fix SphereProjector, add tests and move to new file --- src/terrainmerger/SphereProjector.h | 58 ++++++++++++++++ src/terrainmerger/mask.h | 53 +-------------- unittests/CMakeLists.txt | 2 +- unittests/terrainmerger/mask.cpp | 0 unittests/terrainmerger/sphere_projector.cpp | 69 ++++++++++++++++++++ 5 files changed, 129 insertions(+), 53 deletions(-) create mode 100644 src/terrainmerger/SphereProjector.h delete mode 100644 unittests/terrainmerger/mask.cpp create mode 100644 unittests/terrainmerger/sphere_projector.cpp diff --git a/src/terrainmerger/SphereProjector.h b/src/terrainmerger/SphereProjector.h new file mode 100644 index 0000000..9d95762 --- /dev/null +++ b/src/terrainmerger/SphereProjector.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +namespace { +glm::dvec2 cartesian_to_lon_lat(const glm::dvec3 &point) { + const glm::dvec3 normalized = glm::normalize(point); + const double lon = std::atan2(normalized.y, normalized.x); + const double lat = std::asin(normalized.z); + return glm::dvec2(lon, lat); +} + +glm::dvec3 lon_lat_to_cartesian(const glm::dvec2 &lon_lat) { + const double lon = lon_lat.x; + const double lat = lon_lat.y; + + const double cos_lat = std::cos(lat); + return glm::dvec3( + cos_lat * std::cos(lon), + cos_lat * std::sin(lon), + std::sin(lat)); +} +} + +class SphereProjector { +public: + explicit SphereProjector(glm::dvec3 tangent_point) { + // Set up local tangent frame + this->radius = glm::length(tangent_point); + const glm::dvec3 a = tangent_point / radius; + const glm::dvec3 not_parallel_to_normal = a.z < 0.9 ? glm::dvec3(0, 0, 1) : glm::dvec3(0, 1, 0); + const glm::dvec3 b = glm::normalize(glm::cross(a, not_parallel_to_normal)); + const glm::dvec3 c = glm::normalize(glm::cross(a, b)); + + // Build rotation matrix (local tangent space basis) + this->rotation = glm::mat3(a, b, c); + this->inv_rotation = glm::transpose(this->rotation); + } + + glm::dvec2 project_point(const glm::dvec3 &cartesian) const { + // TODO: project onto tangent plane instead? + const glm::dvec3 rotated = glm::normalize(rotation * cartesian); + return cartesian_to_lon_lat(rotated); + } + + glm::dvec3 unproject_point(const glm::dvec2 &lon_lat) const { + const glm::dvec3 cartesian = lon_lat_to_cartesian(lon_lat); + const glm::dvec3 unrotated_point = inv_rotation * cartesian; + const glm::dvec3 point_on_sphere = unrotated_point * radius; + return point_on_sphere; + } + +private: + double radius; + glm::mat3 rotation; + glm::mat3 inv_rotation; +}; diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h index e9ec99a..fa63c77 100644 --- a/src/terrainmerger/mask.h +++ b/src/terrainmerger/mask.h @@ -13,6 +13,7 @@ #include "mesh/convert.h" #include "mesh/validate.h" #include "srs.h" +#include "SphereProjector.h" #include #include @@ -88,58 +89,6 @@ class LoadError { LoadErrorKind kind; }; -class SphereProjector { -public: - explicit SphereProjector(glm::dvec3 tangent_point) { - // Set up local tangent frame - this->radius = glm::length(tangent_point); - const glm::dvec3 a = tangent_point / radius; - const glm::dvec3 not_parallel_to_normal = a.z < 0.9 ? glm::dvec3(0, 0, 1) : glm::dvec3(0, 1, 0); - const glm::dvec3 b = glm::cross(a, not_parallel_to_normal); - const glm::dvec3 c = glm::cross(a, b); - - // Build rotation matrix (local tangent space basis) - this->rotation = glm::mat3(a, b, c); - this->inv_rotation = glm::transpose(this->rotation); - } - - glm::dvec2 project_point(const glm::dvec3 &cartesian) const { - // TODO: project onto tangent plane instead? - const glm::dvec3 rotated = rotation * glm::normalize(cartesian); - return cartesian_to_lon_lat(rotated); - } - - glm::dvec3 unproject_point(const glm::dvec2 &lon_lat) const { - const glm::dvec3 cartesian = lon_lat_to_cartesian(lon_lat); - const glm::dvec3 unrotated_point = inv_rotation * cartesian; - const glm::dvec3 point_on_sphere = unrotated_point * radius; - return point_on_sphere; - } - -private: - static glm::dvec2 cartesian_to_lon_lat(const glm::dvec3 &point) { - const glm::dvec3 normalized = glm::normalize(point); - const double lon = std::atan2(normalized.y, normalized.x); - const double lat = std::asin(normalized.z); - return glm::dvec2(lon, lat); - } - - static glm::dvec3 lon_lat_to_cartesian(const glm::dvec2 &lon_lat) { - const double lon = lon_lat.x; - const double lat = lon_lat.y; - - const double cosLat = std::cos(lat); - return glm::dvec3( - cosLat * std::cos(lon), - cosLat * std::sin(lon), - std::sin(lat)); - } - - double radius; - glm::mat3 rotation; - glm::mat3 inv_rotation; -}; - struct ReferencedPolygonMask { MultipolygonWithHoles2 polygons; OGRSpatialReference srs; diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 5a16374..bbfccca 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -80,6 +80,6 @@ target_compile_definitions(unittests_terrainbuilder PUBLIC "ATB_TEST_DATA_DIR=\" add_executable(unittests_terrainmerger catch2_helpers.h - terrainmerger/mask.cpp + terrainmerger/sphere_projector.cpp ) target_link_libraries(unittests_terrainmerger PUBLIC terrainmergerlib terrainlib Catch2WithMain) diff --git a/unittests/terrainmerger/mask.cpp b/unittests/terrainmerger/mask.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/unittests/terrainmerger/sphere_projector.cpp b/unittests/terrainmerger/sphere_projector.cpp new file mode 100644 index 0000000..03f4076 --- /dev/null +++ b/unittests/terrainmerger/sphere_projector.cpp @@ -0,0 +1,69 @@ +#include "../catch2_helpers.h" + +#include +#include +#include + +#include "SphereProjector.h" +#include "log.h" + +static constexpr double epsilon = 1e-6; +inline void check_equal(const glm::dvec2& a, const glm::dvec2& b) { + CHECK(a.x == Catch::Approx(b.x).margin(epsilon)); + CHECK(a.y == Catch::Approx(b.y).margin(epsilon)); +} +inline void check_equal(const glm::dvec3& a, const glm::dvec3& b) { + CHECK(a.x == Catch::Approx(b.x).margin(epsilon)); + CHECK(a.y == Catch::Approx(b.y).margin(epsilon)); + CHECK(a.z == Catch::Approx(b.z).margin(epsilon)); +} + +TEST_CASE("SphereProjector: roundtrip for standard origin") { + const double radius = 10.0; + const glm::dvec3 tangent_point(radius, 0.0, 0.0); + const SphereProjector projector(tangent_point); + + const std::array test_points = { + glm::dvec3{ radius, 0.0, 0.0}, + glm::dvec3{ 0.0, radius, 0.0}, + glm::dvec3{ 0.0, 0.0, radius}, + glm::dvec3{-radius, 0.0, 0.0}, + glm::dvec3{ 0.0, -radius, 0.0} + }; + + for (const auto& point : test_points) { + INFO(fmt::format("point: {}", point)); + const auto projected = projector.project_point(point); + INFO(fmt::format("projected: {}", projected)); + const auto unprojected = projector.unproject_point(projected); + INFO(fmt::format("unprojected: {}", unprojected)); + + check_equal(unprojected, point); + CHECK(glm::length(unprojected) == Catch::Approx(radius).margin(epsilon)); + } +} + +TEST_CASE("SphereProjector: roundtrip for non-standard origin") { + const glm::dvec3 tangent_point(10, 5, 6); + const double radius = glm::length(tangent_point); + const SphereProjector projector(tangent_point); + + const std::array test_points = { + glm::dvec3{ radius, 0.0, 0.0}, + glm::dvec3{ 0.0, radius, 0.0}, + glm::dvec3{ 0.0, 0.0, radius}, + glm::dvec3{-radius, 0.0, 0.0}, + glm::dvec3{ 0.0, -radius, 0.0} + }; + + for (const auto& point : test_points) { + INFO(fmt::format("point: {}", point)); + const auto projected = projector.project_point(point); + INFO(fmt::format("projected: {}", projected)); + const auto unprojected = projector.unproject_point(projected); + INFO(fmt::format("unprojected: {}", unprojected)); + + check_equal(unprojected, point); + CHECK(glm::length(unprojected) == Catch::Approx(radius).margin(epsilon)); + } +} From 6b787a9ca4fcb91baf465bb7be7306886650e422 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 4 Jul 2025 17:35:13 +0200 Subject: [PATCH 093/122] Add cut subcommand --- src/terrainmerger/cli.cpp | 53 +++++++++++++++++++++++-------- src/terrainmerger/cli.h | 17 ++++++++-- src/terrainmerger/cut.h | 65 ++++++++++++++++++++++++++++++++++++++ src/terrainmerger/main.cpp | 58 ++++++++++++++++++++++++++-------- src/terrainmerger/merge.h | 28 ++++++++++++++++ 5 files changed, 193 insertions(+), 28 deletions(-) create mode 100644 src/terrainmerger/cut.h diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index d231a71..8133ee7 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -2,6 +2,7 @@ #include #include +#include using namespace cli; @@ -11,18 +12,38 @@ Args cli::parse(int argc, const char * const * argv) { CLI::App app{"terrainmerger"}; app.allow_windows_style_options(); // argv = app.ensure_utf8(argv); - - std::vector input_paths; - app.add_option("--input", input_paths, "Paths to datasets that should be merged") + + auto& merge = *app.add_subcommand("merge"); + MergeArgs merge_args; + merge.add_option("--base", merge_args.base_path, "Path to base dataset") + ->required() + ->check(CLI::ExistingDirectory); + + merge.add_option("--new", merge_args.new_path, "Path to new dataset to merge into base") ->required() - ->expected(-1) ->check(CLI::ExistingDirectory); - std::filesystem::path output_path; - app.add_option("--output", output_path, "Path to output write the merged dataset to") - ->required(); + merge.add_option("--mask", merge_args.mask_path, "Path to a mask denoting the valid area of the new dataset") + ->check(CLI::ExistingFile); - spdlog::level::level_enum log_level = spdlog::level::level_enum::info; + merge.add_option("--output", merge_args.output_path, "Path to output write the merged dataset to (defaults to --base)"); + + merge.fallthrough(); + + auto& cut = *app.add_subcommand("cut"); + CutArgs cut_args; + cut.add_option("--input", cut_args.input_path, "Path to dataset to cut") + ->required() + ->check(CLI::ExistingDirectory); + + cut.add_option("--mask", cut_args.mask_path, "Path to a mask denoting the regions to retain") + ->check(CLI::ExistingFile); + + cut.add_option("--output", cut_args.output_path, "Path to output the cut dataset to"); + + cut.fallthrough(); + + spdlog::level::level_enum log_level; const std::map log_level_names{ {"off", spdlog::level::level_enum::off}, {"critical", spdlog::level::level_enum::critical}, @@ -32,7 +53,10 @@ Args cli::parse(int argc, const char * const * argv) { {"debug", spdlog::level::level_enum::debug}, {"trace", spdlog::level::level_enum::trace}}; app.add_option("--verbosity", log_level, "Verbosity level of logging") - ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)); + ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)) + ->default_val(spdlog::level::level_enum::info); + + app.require_subcommand(1); try { app.parse(argc, argv); @@ -41,9 +65,12 @@ Args cli::parse(int argc, const char * const * argv) { } Args args; - args.input_paths = input_paths; - args.output_path = output_path; - args.log_level = log_level; - + if (merge) { + merge_args.log_level = log_level; + args = std::move(merge_args); + } else if (cut) { + cut_args.log_level = log_level; + args = std::move(cut_args); + } return args; } diff --git a/src/terrainmerger/cli.h b/src/terrainmerger/cli.h index f9f396e..7bb489a 100644 --- a/src/terrainmerger/cli.h +++ b/src/terrainmerger/cli.h @@ -7,12 +7,25 @@ namespace cli { -struct Args { +struct BaseArgs { spdlog::level::level_enum log_level; - std::vector input_paths; +}; + +struct MergeArgs : public BaseArgs { + std::filesystem::path base_path; + std::filesystem::path new_path; + std::optional mask_path; + std::optional output_path; +}; + +struct CutArgs : public BaseArgs { + std::filesystem::path input_path; std::filesystem::path output_path; + std::filesystem::path mask_path; }; +using Args = std::variant; + Args parse(int argc, const char *const *argv); } diff --git a/src/terrainmerger/cut.h b/src/terrainmerger/cut.h new file mode 100644 index 0000000..1f2250d --- /dev/null +++ b/src/terrainmerger/cut.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +#include "mesh/SimpleMesh.h" +#include "log.h" +#include "mask.h" +#include "merge.h" +#include "octree/Id.h" +#include "octree/NodeStatus.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/storage/open.h" +#include "octree/traverse.h" + +inline void cut_dataset( + const octree::IndexedStorage &input, + const MeshMask& mask, + octree::Storage &output) { + + mesh::io::save_to_path(mask.mesh, "./mask.glb"); + + octree::traverse( + input.index(), + [&](const octree::Id &id, const octree::NodeStatus &status) { + if (status == octree::NodeStatus::Virtual) { + return; + } + DEBUG_ASSERT(status == octree::NodeStatus::Leaf); + + const SimpleMesh mesh = DEBUG_ASSERT_VAL(input.read_node(id)).value(); + LOG_TRACE("Cutting mesh at {}", id); + const ClipResult result = clip_on_mask(mesh, mask); + if (result.is_unchanged()) { + LOG_TRACE("Mesh was fully inside the mask"); + DEBUG_ASSERT_VAL(input.copy_node_to(id, output)); + } else { + const SimpleMesh& clipped_mesh = result.mesh(); + if (clipped_mesh.is_empty()) { + LOG_TRACE("Mesh was clipped from {} vertices and {} triangles to {} vertices and {} triangles", + mesh.vertex_count(), mesh.face_count(), clipped_mesh.vertex_count(), clipped_mesh.face_count()); + DEBUG_ASSERT_VAL(output.write_node(id, result.mesh())); + } else { + LOG_TRACE("Mesh was fully ouside the mask"); + } + } + }); + + output.save_or_create_index(); +} + +inline void cut_dataset( + const octree::IndexedStorage &input_dataset, + const MeshMask& mask, + const std::filesystem::path &output_path) { + LOG_TRACE("Creating output dataset at {}", output_path); + std::filesystem::create_directories(output_path); + + octree::IndexedStorage output_dataset = octree::open_folder_indexed(output_path, octree::disk::layout::strategy::make_default(), ".glb"); + if (!output_dataset.index().empty()) { + LOG_ERROR_AND_EXIT("Output dataset has to be empty."); + } + + cut_dataset(input_dataset, mask, output_dataset); +} + diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index a556fa4..e71c0d4 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -6,29 +6,61 @@ #include "cli.h" #include "merge.h" #include "mask.h" +#include "cut.h" #include "octree/Storage.h" +#include "optional_utils.h" -void run(const cli::Args &args) { - if (!std::filesystem::exists(args.output_path)) { - std::filesystem::create_directories(args.output_path); +std::optional load_mask_from_path(const std::filesystem::path& path) { + if (std::filesystem::exists(path)) { + LOG_INFO("Loading mask file from {}", path); + const glm::dvec2 radius_range = mask::pad_radius_range(earth::radius_range(), 2); + auto result = mask::load_from_path(path, radius_range); + if (result.has_value()) { + const auto mask = result.value(); + LOG_DEBUG("Loaded mask successfully ({} vertices, {} triangles)", + mask.mesh.vertex_count(), mask.mesh.face_count()); + return mask; + } else { + LOG_ERROR("Failed to load mask: {}", result.error().description()); + } + } else { + LOG_DEBUG("No mask file found at {}, proceeding without mask", path); } - octree::IndexedStorage output_storage = octree::open_folder_indexed(args.output_path); - std::vector input_storages; - for (const auto &input_path : args.input_paths) { - if (!std::filesystem::exists(input_path)) { - LOG_ERROR("Input path '{}' does not exist.", input_path); - return; - } - input_storages.emplace_back(octree::open_folder_indexed(input_path)); + return std::nullopt; +} + +void run(const cli::MergeArgs& args) { + LOG_TRACE("Loading base dataset from {}", args.base_path); + octree::IndexedStorage base_dataset = octree::open_folder_indexed(args.base_path); + + LOG_TRACE("Loading new dataset from {}", args.new_path); + octree::IndexedStorage new_dataset = octree::open_folder_indexed(args.new_path); + + std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); + + if (args.output_path.has_value()) { + return merge_datasets(base_dataset, new_dataset, args.output_path.value(), mask); + } else { + return merge_datasets(base_dataset, new_dataset, mask); } +} - merge_datasets(output_storage, input_storages); +void run(const cli::CutArgs& args) { + LOG_TRACE("Loading input dataset from {}", args.input_path); + const octree::IndexedStorage input_dataset = octree::open_folder_indexed(args.input_path); + const mask::MeshMask mask = DEBUG_ASSERT_VAL(load_mask_from_path(args.mask_path)).value(); + cut_dataset(input_dataset, mask, args.output_path); +} + +void run(const cli::Args &args) { + std::visit([](const auto& args) { run(args); }, args); } int main(int argc, char **argv) { const cli::Args args = cli::parse(argc, argv); - Log::init(args.log_level); + const auto log_level = std::visit([](const auto& args) { return args.log_level; }, args); + Log::init(log_level); const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), [](const std::string &acc, const char *arg) { diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index d049589..c91f9c3 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -53,6 +53,34 @@ inline SimpleMesh merge_meshes( const SimpleMesh& base_mesh, // base mesh const SimpleMesh& new_mesh, // priority mesh const std::optional mask +struct ClipResult { + bool was_clipped() const { + return std::holds_alternative(this->value); + } + bool is_unchanged() const { + return std::holds_alternative>(this->value); + } + + const SimpleMesh &mesh() const { + return std::visit([](const auto &value) -> const SimpleMesh & { + return value; + }, this->value); + } + + static ClipResult from_clipped(SimpleMesh mesh) { + return ClipResult(std::move(mesh)); + } + static ClipResult from_input(const SimpleMesh &mesh) { + return ClipResult(std::reference_wrapper(mesh)); + } + + std::variant, SimpleMesh> value; +}; + +inline ClipResult clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask) { + const SimpleMesh clipped = mesh::clip_on_mesh(mesh, mask.mesh); + return ClipResult::from_clipped(std::move(clipped)); +} ) { // TODO: dont convert to SimpleMesh all the time if (mask.has_value()) { From c55f0dfc1e9eb3eebabf9375784b103e043fe8c6 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 4 Jul 2025 17:37:53 +0200 Subject: [PATCH 094/122] Minor fixes --- src/CMakeLists.txt | 5 ++++- src/terrainlib/mesh/io/terrain.cpp | 2 +- src/terrainlib/octree/storage/Storage.h | 2 +- src/terrainlib/octree/storage/open.cpp | 4 +++- src/terrainlib/octree/traverse.h | 11 +++++++---- src/terrainmerger/mask.h | 4 ++-- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e404a1..cb9e26b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,10 @@ project(terrain_builder_src LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") +# TODO: This is needed to avoid NDEBUG being undefined on Release +if (CMAKE_BUILD_TYPE MATCHES Release) + set(ALP_ENABLE_ASSERTS OFF CACHE BOOL "" FORCE) +endif() option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) @@ -12,7 +16,6 @@ find_package(TBB REQUIRED) find_package(ZLIB REQUIRED) find_package(CURL REQUIRED) - alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 10.2.1) alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH 20de8b73bbbabaf2f94dd07c4ece8ff3590af531) diff --git a/src/terrainlib/mesh/io/terrain.cpp b/src/terrainlib/mesh/io/terrain.cpp index 27f1a52..a014194 100644 --- a/src/terrainlib/mesh/io/terrain.cpp +++ b/src/terrainlib/mesh/io/terrain.cpp @@ -130,7 +130,7 @@ tl::expected load_from_buffer(const std::span save_to_path(const SimpleMesh &mesh, const std::filesystem::path &path, const SaveOptions& options) { - LOG_TRACE("Saving mesh as high precision mesh"); + LOG_TRACE("Saving mesh as high precision terrain"); const auto result = save_to_buffer(mesh, options); if (!result.has_value()) { diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 63dfdba..4bd6576 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -222,11 +222,11 @@ class Storage { return result; } -protected: const octree::disk::Layout &layout() const noexcept { return this->_inner.layout(); } +protected: std::optional &index_mut() noexcept { return this->_index.map; } diff --git a/src/terrainlib/octree/storage/open.cpp b/src/terrainlib/octree/storage/open.cpp index 2a5f404..a77494d 100644 --- a/src/terrainlib/octree/storage/open.cpp +++ b/src/terrainlib/octree/storage/open.cpp @@ -73,7 +73,9 @@ Storage open_folder( IndexMap map; helpers::update_index_map(map, layout); - helpers::save_index_map(map, layout); + if (!map.empty()) { + helpers::save_index_map(map, layout); + } return Storage(RawStorage(std::move(layout)), std::move(map)); } diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index d513caf..356a76b 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -14,13 +14,17 @@ enum class TraversalOrder { BreadthFirst }; +constexpr bool always_refine(const Id &) { + return true; +} + template < typename VisitFn, typename RefineFn = std::function> void traverse( - const IndexMap& index, - VisitFn&& visit_fn, - RefineFn&& refine_fn = [](const Id &) { return true; }, + const IndexMap &index, + VisitFn &&visit_fn, + RefineFn &&refine_fn = always_refine, const Id &root = Id::root(), TraversalOrder order = TraversalOrder::DepthFirst) { if (!index.is_present(root)) { @@ -74,5 +78,4 @@ void traverse( } } - } // namespace octree diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h index fa63c77..aae519f 100644 --- a/src/terrainmerger/mask.h +++ b/src/terrainmerger/mask.h @@ -198,14 +198,14 @@ void convert_to_ecef_and_project_onto_sphere(MultipolygonWithHoles2 &polygons, c const glm::dvec2 source_point = convert::to_glm_point(cgal_point); const glm::dvec3 ecef_point = srs::transform_point(srs_transform.get(), glm::dvec3(source_point, 0)); const glm::dvec2 projected_point = projector.project_point(ecef_point); - cgal_point = Point2(projected_point.x, projected_point.y); + cgal_point = convert::to_cgal_point(projected_point); } for (auto &hole : polygon.holes()) { for (auto &cgal_point : hole) { const glm::dvec2 source_point = convert::to_glm_point(cgal_point); const glm::dvec3 ecef_point = srs::transform_point(srs_transform.get(), glm::dvec3(source_point, 0)); const glm::dvec2 projected_point = projector.project_point(ecef_point); - cgal_point = Point2(projected_point.x, projected_point.y); + cgal_point = convert::to_cgal_point(projected_point); } } } From 1eff2e9e5cdf075dbb5eab3b6ba5a8793abf47d0 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Sat, 5 Jul 2025 19:02:29 +0200 Subject: [PATCH 095/122] Add index browser --- src/CMakeLists.txt | 14 +- src/index_browser/cli.cpp | 43 ++++ src/index_browser/cli.h | 17 ++ src/index_browser/main.cpp | 235 ++++++++++++++++++++ src/terrainlib/octree/NodeStatus.h | 6 +- src/terrainlib/octree/NodeStatusOrMissing.h | 143 ++++++++++++ src/terrainlib/octree/traverse.h | 10 +- 7 files changed, 457 insertions(+), 11 deletions(-) create mode 100644 src/index_browser/cli.cpp create mode 100644 src/index_browser/cli.h create mode 100644 src/index_browser/main.cpp create mode 100644 src/terrainlib/octree/NodeStatusOrMissing.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb9e26b..61ae708 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,6 +62,9 @@ target_include_directories(zpp_bits INTERFACE ${zpp_bits_SOURCE_DIR}) alp_add_git_repository(libassert URL https://github.com/jeremy-rifkin/libassert.git COMMITISH v2.1.0) +alp_add_git_repository(magic_enum URL https://github.com/Neargye/magic_enum.git COMMITISH v0.9.7) + +alp_add_git_repository(ftxui URL https://github.com/ArthurSonzogni/FTXUI COMMITISH v6.1.9) alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) # Don't build glfw docs, tests and examples @@ -161,7 +164,7 @@ add_library(terrainlib terrainlib/string_utils.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert magic_enum::magic_enum) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) @@ -245,12 +248,17 @@ add_executable(tile-downloader target_link_libraries(tile-downloader PUBLIC terrainlib ${CURL_LIBRARIES}) add_executable(terrainconvert - terrainconvert/cli.h - terrainconvert/cli.cpp + terrainconvert/cli.h terrainconvert/cli.cpp terrainconvert/main.cpp ) target_link_libraries(terrainconvert PUBLIC terrainlib CLI11::CLI11) +add_executable(index_browser + index_browser/cli.h index_browser/cli.cpp + index_browser/main.cpp +) +target_link_libraries(index_browser PUBLIC terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) + add_executable(browser # browser/main2.cpp diff --git a/src/index_browser/cli.cpp b/src/index_browser/cli.cpp new file mode 100644 index 0000000..d03b873 --- /dev/null +++ b/src/index_browser/cli.cpp @@ -0,0 +1,43 @@ +#include "cli.h" + +#include +#include +#include + +using namespace cli; + +Args cli::parse(int argc, const char * const * argv) { + DEBUG_ASSERT(argc >= 0); + + Args args; + CLI::App app{"index browser"}; + app.positionals_at_end(false); + app.allow_windows_style_options(false); + + app.add_option("dataset,--dataset", args.dataset_path, "Folder or index file of dataset to browser") + ->check(CLI::ExistingPath) + ->required(); + + app.add_flag("--full", args.full_view, "Start at octree root instead of dataset root."); + + const std::map + log_level_names{ + {"off", spdlog::level::level_enum::off}, + {"critical", spdlog::level::level_enum::critical}, + {"error", spdlog::level::level_enum::err}, + {"warn", spdlog::level::level_enum::warn}, + {"info", spdlog::level::level_enum::info}, + {"debug", spdlog::level::level_enum::debug}, + {"trace", spdlog::level::level_enum::trace}}; + app.add_option("--verbosity", args.log_level, "Verbosity level of logging") + ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)) + ->default_val(spdlog::level::level_enum::info); + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError &e) { + exit(app.exit(e)); + } + + return args; +} diff --git a/src/index_browser/cli.h b/src/index_browser/cli.h new file mode 100644 index 0000000..dcbb8bd --- /dev/null +++ b/src/index_browser/cli.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include + +namespace cli { + +struct Args { + std::filesystem::path dataset_path; + bool full_view; + spdlog::level::level_enum log_level; +}; + +Args parse(int argc, const char *const *argv); + +} diff --git a/src/index_browser/main.cpp b/src/index_browser/main.cpp new file mode 100644 index 0000000..3e90b9d --- /dev/null +++ b/src/index_browser/main.cpp @@ -0,0 +1,235 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "octree/Id.h" +#include "octree/NodeStatus.h" +#include "octree/NodeStatusOrMissing.h" +#include "octree/Storage.h" +#include "octree/traverse.h" +#include "cli.h" + +namespace { +struct DisplayNode { + octree::Id id; + octree::NodeStatusOrMissing status; + bool expanded = false; +}; + +class TreeView { +public: + using iterator = std::list::iterator; + using const_iterator = std::list::const_iterator; + + explicit TreeView(const octree::IndexMap &index, const octree::Id root) : root(root), _index(index) { + const octree::NodeStatusOrMissing status = this->_index.get(root); + this->_view.emplace_back(root, status, false); + } + + size_t size() const { + return this->_view.size(); + } + + iterator begin() { + return this->_view.begin(); + } + iterator end() { + return this->_view.end(); + } + const_iterator begin() const { + return this->_view.begin(); + } + const_iterator end() const { + return this->_view.end(); + } + + void expand_node(const size_t display_index) { + iterator it = this->_view.begin(); + std::advance(it, display_index); + return expand_node(it); + } + void expand_node(iterator it) { + DisplayNode &parent = *it; + if (parent.expanded || !parent.id.has_children()) { + return; + } + + const auto children = parent.id.children().value(); + for (const auto &child_id : children) { + auto status_opt = this->_index.get(child_id); + if (!status_opt.has_value()) { + continue; + } + const octree::NodeStatus status = status_opt.value(); + it++; + it = this->_view.emplace(it, child_id, status, false); + } + + parent.expanded = true; + } + + void collapse_node(const size_t display_index) { + iterator it = this->_view.begin(); + std::advance(it, display_index); + return collapse_node(it); + } + void collapse_node(iterator it) { + DisplayNode &parent = *it; + if (!parent.expanded) { + return; + } + + it++; + while (it != this->_view.end()) { + DisplayNode &node = *it; + if (node.id.parent() != parent.id) { + break; + } + + if (node.expanded) { + this->collapse_node(it); + } + it = this->_view.erase(it); + } + + parent.expanded = false; + } + + const octree::Id root; + +private: + std::list _view; + const octree::IndexMap &_index; +}; + +//--------------------------------------------------------------------- +// Find the first non‑virtual node by BFS (may use octree::traverse) +//--------------------------------------------------------------------- +const octree::Id find_deepest_root(const octree::IndexMap &index, const octree::Id &root = octree::Id::root()) { + switch (octree::NodeStatusOrMissing(index.get(root))) { + case octree::NodeStatusOrMissing::Missing: + return octree::Id::root(); + case octree::NodeStatusOrMissing::Leaf: + return root; + default: + break; + } + + octree::Id current = root; + while (current.has_children()) { + const auto children = current.children().value(); + std::optional next; + for (const octree::Id &child_id : children) { + if (!index.get(child_id).has_value()) { + continue; + } + if (next.has_value()) { + return current; + } + next = child_id; + } + if (next.has_value()) { + current = next.value(); + } else { + return current; + } + } + + return current; +} + +} // namespace + +octree::IndexedStorage open_path_indexed(const std::filesystem::path& path) { + if (std::filesystem::is_directory(path)) { + return octree::open_folder_indexed(path); + } else { + return octree::open_index(path).value(); + } +} + +ftxui::Element render_line(const DisplayNode &node, size_t base_level, bool is_selected) { + const size_t depth = node.id.level() - base_level; + const size_t indent = depth * 2; + auto text_line = ftxui::text(fmt::format("{:<{}} {} [{}]", + "", indent, + node.id, + node.status)); + if (is_selected) { + return text_line | ftxui::inverted; + } + return text_line; +} + +int run(const cli::Args &args) { + const octree::IndexedStorage storage = open_path_indexed(args.dataset_path); + const octree::IndexMap &index = storage.index(); + const octree::Id root_id = args.full_view ? octree::Id::root() : find_deepest_root(index); + + TreeView tree_view(index, root_id); + + size_t selected = 0; + auto renderer = ftxui::Renderer([&] { + ftxui::Elements lines; + lines.reserve(tree_view.size()); + size_t i = 0; + for (auto it = tree_view.begin(); it != tree_view.end(); i++, it++) { + lines.push_back(render_line(*it, tree_view.root.level(), i == selected)); + } + return ftxui::vbox(std::move(lines)) | ftxui::frame | ftxui::border; + }); + + auto screen = ftxui::ScreenInteractive::Fullscreen(); + + auto container = ftxui::CatchEvent(renderer, [&](ftxui::Event e) { + if (e == ftxui::Event::ArrowUp) { + if (selected > 0) { + selected--; + } + return true; + } + if (e == ftxui::Event::ArrowDown) { + if (selected + 1 < tree_view.size()) { + selected++; + } + return true; + } + if (e == ftxui::Event::ArrowRight) { + tree_view.expand_node(selected); + return true; + } + if (e == ftxui::Event::ArrowLeft) { + tree_view.collapse_node(selected); + return true; + } + if ((e == ftxui::Event::Character('q') || e == ftxui::Event::Character('Q') || e == ftxui::Event::Escape)) { + screen.Exit(); + return true; + } + return false; + }); + + screen.Loop(container); + + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) { + const cli::Args args = cli::parse(argc, argv); + Log::init(args.log_level); + + const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), + [](const std::string &acc, const char *arg) { + return acc + (acc.empty() ? "" : " ") + arg; + }); + LOG_DEBUG("Running with: {}", arg_str); + + return run(args); +} diff --git a/src/terrainlib/octree/NodeStatus.h b/src/terrainlib/octree/NodeStatus.h index 757c179..9187bc9 100644 --- a/src/terrainlib/octree/NodeStatus.h +++ b/src/terrainlib/octree/NodeStatus.h @@ -3,19 +3,19 @@ #include #include "log.h" -#include "octree/Id.h" namespace octree { class NodeStatus { public: - enum Value : uint8_t { + using Underlying = uint8_t; + enum Value : Underlying { Leaf = 0, Inner = 1, Virtual = 2 // not present on disk but has children }; - NodeStatus() = default; + constexpr NodeStatus() = default; constexpr NodeStatus(Value value) : _value(value) {} constexpr operator Value() const { diff --git a/src/terrainlib/octree/NodeStatusOrMissing.h b/src/terrainlib/octree/NodeStatusOrMissing.h new file mode 100644 index 0000000..803ebc0 --- /dev/null +++ b/src/terrainlib/octree/NodeStatusOrMissing.h @@ -0,0 +1,143 @@ +#pragma once + +#include + +#include +#include + +#include "octree/NodeStatus.h" + +namespace octree { + +class NodeStatusOrMissing { +public: + using Underlying = NodeStatus::Underlying; + enum Value : Underlying { + Leaf = 0, + Inner = 1, + Virtual = 2, // not present on disk but has children + Missing = 3 + }; + + constexpr NodeStatusOrMissing() = default; + constexpr NodeStatusOrMissing(Value value) : _value(value) {} + NodeStatusOrMissing(NodeStatus opt) : _value(from_status(opt)) {} + NodeStatusOrMissing(std::optional opt) : _value(from_optional_status(opt)) {} + + constexpr operator Value() const { + return this->_value; + } + constexpr operator std::optional() const { + return this->to_optional_status(); + } + explicit operator bool() const = delete; + constexpr bool operator==(NodeStatusOrMissing other) const { + return this->_value == other._value; + } + constexpr bool operator!=(NodeStatusOrMissing other) const { + return !(*this == other); + } + constexpr bool operator==(Value other_value) const { + return this->_value == other_value; + } + constexpr bool operator!=(Value other_value) const { + return this->_value != other_value; + } + + std::string to_string() const; + +private: + constexpr static NodeStatusOrMissing from_status(NodeStatus status) noexcept { + return static_cast(static_cast(status)); + } + constexpr static NodeStatusOrMissing from_optional_status(std::optional opt) noexcept { + if (opt.has_value()) { + return from_status(opt.value()); + } else { + return NodeStatusOrMissing::Missing; + } + } + constexpr std::optional to_optional_status() const noexcept { + if (this->_value == NodeStatusOrMissing::Missing) { + return std::nullopt; + } else { + return static_cast(this->_value); + } + } + +public: + Value _value; + +public: + using serialize = zpp::bits::members<1>; + friend zpp::bits::access; +}; + +} + +#include +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext &ctx) { + return ctx.begin(); + } + + template + auto format(const octree::NodeStatusOrMissing &status, FormatContext &ctx) { + switch (status) { + case octree::NodeStatusOrMissing::Leaf: + return fmt::format_to(ctx.out(), "Leaf"); + case octree::NodeStatusOrMissing::Inner: + return fmt::format_to(ctx.out(), "Inner"); + case octree::NodeStatusOrMissing::Virtual: + return fmt::format_to(ctx.out(), "Virtual"); + case octree::NodeStatusOrMissing::Missing: + return fmt::format_to(ctx.out(), "Missing"); + default: + UNREACHABLE(); + } + } +}; + +#include +#include +inline std::string octree::NodeStatusOrMissing::to_string() const { + return fmt::format("{}", *this); +} +inline std::ostream &operator<<(std::ostream &os, const octree::NodeStatusOrMissing &status) { + fmt::print(os, "{}", status); + return os; +} + +namespace octree { +namespace { +template +consteval bool _verify_enum_values(std::index_sequence) { + constexpr auto ns_values = magic_enum::enum_values(); + constexpr auto nsom_values = magic_enum::enum_values(); + + return ((magic_enum::enum_underlying(ns_values[Is]) == + magic_enum::enum_underlying(nsom_values[Is])) && + ...); +} + +consteval bool _verify_enum() { + static_assert( + std::is_same_v, + magic_enum::underlying_type_t>, + "Mismatched underlying type"); + + constexpr auto ns_values = magic_enum::enum_values(); + constexpr auto nsom_values = magic_enum::enum_values(); + + static_assert(nsom_values.size() == ns_values.size() + 1, "Mismatched enum counts"); + + static_assert(_verify_enum_values(std::make_index_sequence()), + "Enum value mismatch"); + + return true; +} +static_assert(_verify_enum()); +} +} \ No newline at end of file diff --git a/src/terrainlib/octree/traverse.h b/src/terrainlib/octree/traverse.h index 356a76b..a6d7615 100644 --- a/src/terrainlib/octree/traverse.h +++ b/src/terrainlib/octree/traverse.h @@ -39,10 +39,10 @@ void traverse( return; } const auto current_status = current_status_opt.value(); - - visit_fn(current, current_status); - if (current.has_children() && refine_fn(current)) { + std::forward(visit_fn)(current, current_status); + + if (current.has_children() && std::forward(refine_fn)(current)) { const auto children = current.children().value(); for (const auto& child : children) { dfs(child); @@ -64,9 +64,9 @@ void traverse( } const auto current_status = current_status_opt.value(); - visit_fn(current, current_status); + std::forward(visit_fn)(current, current_status); - if (current.has_children() && refine_fn(current)) { + if (current.has_children() && std::forward(refine_fn)(current)) { const auto children = current.children().value(); for (const auto& child : children) { queue.push(child); From 19aae318fb1d24acaa744eb5839499cde9f88f5e Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 6 Aug 2025 12:42:58 +0200 Subject: [PATCH 096/122] Rewrite terrainmerger --- src/terrainlib/Cow.h | 86 ++++ src/terrainlib/octree/storage/cache/Dummy.h | 4 +- src/terrainmerger/NodeLoader.h | 77 ++++ src/terrainmerger/NodeWriter.h | 49 +++ src/terrainmerger/SimpleMutex.h | 44 ++ src/terrainmerger/cli.cpp | 26 +- src/terrainmerger/cli.h | 12 +- src/terrainmerger/cut.h | 140 +++++-- src/terrainmerger/earth.h | 2 +- src/terrainmerger/main.cpp | 23 +- src/terrainmerger/mask.h | 37 +- src/terrainmerger/merge.h | 427 ++++++-------------- src/terrainmerger/merge/NodeData.h | 43 ++ src/terrainmerger/merge/Result.h | 23 ++ src/terrainmerger/merge/visitor/Base.h | 19 + src/terrainmerger/merge/visitor/Masked.h | 93 +++++ src/terrainmerger/merge/visitor/Simple.h | 54 +++ src/terrainmerger/utils.h | 10 + 18 files changed, 788 insertions(+), 381 deletions(-) create mode 100644 src/terrainlib/Cow.h create mode 100644 src/terrainmerger/NodeLoader.h create mode 100644 src/terrainmerger/NodeWriter.h create mode 100644 src/terrainmerger/SimpleMutex.h create mode 100644 src/terrainmerger/merge/NodeData.h create mode 100644 src/terrainmerger/merge/Result.h create mode 100644 src/terrainmerger/merge/visitor/Base.h create mode 100644 src/terrainmerger/merge/visitor/Masked.h create mode 100644 src/terrainmerger/merge/visitor/Simple.h create mode 100644 src/terrainmerger/utils.h diff --git a/src/terrainlib/Cow.h b/src/terrainlib/Cow.h new file mode 100644 index 0000000..ab516f7 --- /dev/null +++ b/src/terrainlib/Cow.h @@ -0,0 +1,86 @@ +#pragma once + +#include +#include +#include + +template +concept NotPtrOrRef = (!std::is_pointer_v) && (!std::is_reference_v); + +template +struct Cow { + using OwnedType = std::remove_const_t; + using RawRefType = T&; + using RefType = std::reference_wrapper; + std::variant data; + + // explicit Cow(T&& value) + // : data(std::move(value)) {} + template , T>>> + explicit Cow(U &&value) : data(std::forward(value)) {} + explicit Cow(T &ref) + : data(std::ref(ref)) {} + template >> + Cow(Cow&& other) + : data(std::visit([](auto &data) -> std::variant { + return data; + }, other)) {} + + static Cow from_owned(T value) { + return Cow(std::move(value)); + } + static Cow from_ref(T &ref) { + return Cow(ref); + } + + Cow(const Cow &) = default; + Cow(Cow &&) noexcept = default; + Cow &operator=(const Cow &) = default; + Cow &operator=(Cow &&) noexcept = default; + + bool is_owned() const noexcept { + return std::holds_alternative(this->data); + } + bool is_ref() const noexcept { + return std::holds_alternative(this->data); + } + + T &get() { + return std::visit([](auto &data) -> T& { return data; }, this->data); + } + const T &get() const { + return std::visit([](const auto &data) -> const T& { return data; }, this->data); + } + + T &operator*() { + return get(); + } + const T &operator*() const { + return get(); + } + + T *operator->() { + return &get(); + } + const T *operator->() const { + return &get(); + } + + operator T &() { + return get(); + } + operator const T &() const { + return get(); + } + + operator Cow() const { + if (is_owned()) { + return Cow(get()); + } else { + return Cow(std::ref(get())); + } + } +}; + +template +Cow(T &&) -> Cow>>; diff --git a/src/terrainlib/octree/storage/cache/Dummy.h b/src/terrainlib/octree/storage/cache/Dummy.h index 282123a..e32647a 100644 --- a/src/terrainlib/octree/storage/cache/Dummy.h +++ b/src/terrainlib/octree/storage/cache/Dummy.h @@ -3,8 +3,8 @@ #include #include "octree/Id.h" -#include "octree/RawStorage.h" -#include "octree/cache/ICache.h" +#include "octree/storage/RawStorage.h" +#include "octree/storage/cache/ICache.h" namespace octree { diff --git a/src/terrainmerger/NodeLoader.h b/src/terrainmerger/NodeLoader.h new file mode 100644 index 0000000..fa3f08f --- /dev/null +++ b/src/terrainmerger/NodeLoader.h @@ -0,0 +1,77 @@ +#pragma once + +#include + +#include + +#include "NodeLoader.h" +#include "mesh/SimpleMesh.h" +#include "mesh/clip.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" +#include "octree/Space.h" +#include "octree/storage/IndexedStorage.h" +#include "octree/storage/cache/Dummy.h" +#include "octree/storage/cache/ICache.h" + +class NodeLoader { +public: + NodeLoader(const octree::IndexedStorage &storage, octree::cache::ICache &cache) + : _storage(storage), _cache(cache), _space(octree::Space::earth()) { + if (storage.cache().has_value() && dynamic_cast(&cache) != nullptr) { + LOG_WARN("Backing storage for NodeLoader instance is cached but another cache was provided leading to double caching."); + } + } + + octree::NodeStatusOrMissing get_status(const octree::Id &id) const noexcept { + return this->_storage.index().get(id); + } + + // Try to retrieve or reconstruct node mesh by ID + std::optional load_node(const octree::Id &id) const noexcept { + // Try cache + if (auto cached = this->_cache.get(id); cached.has_value()) { + return cached.value(); + } + + // Try storage + auto mesh_opt = this->_storage.read_node(id); + if (mesh_opt.has_value()) { + auto mesh = mesh_opt.value(); + this->_cache.put(id, mesh); + return mesh; + } + + // Try ancestors + for (auto parent = id.parent(); parent.has_value(); parent = parent->parent()) { + const auto &parent_id = *parent; + + // Try cache + if (auto cached = this->_cache.get(parent_id); cached.has_value()) { + return cached; + } + + // Try storage + auto parent_mesh_opt = this->_storage.read_node(parent_id); + if (parent_mesh_opt.has_value()) { + auto parent_mesh = mesh_opt.value(); + const auto bounds = this->_space.get_node_bounds(id); + const auto clipped = mesh::clip_on_bounds(parent_mesh, bounds); + this->_cache.put(id, clipped); + return clipped; + } + } + + // Nothing found + return std::nullopt; + } + + const octree::IndexedStorage &storage() const { + return this->_storage; + } + +private: + const octree::IndexedStorage &_storage; + octree::cache::ICache &_cache; + const octree::Space _space; +}; diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h new file mode 100644 index 0000000..6dd0a74 --- /dev/null +++ b/src/terrainmerger/NodeWriter.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#include "NodeLoader.h" +#include "mesh/SimpleMesh.h" +#include "octree/Id.h" +#include "octree/NodeStatus.h" +#include "octree/storage/Storage.h" +#include "octree/traverse.h" + +// TODO: make thread safe +class NodeWriter { +public: + NodeWriter(octree::Storage &storage) : _storage(storage) {} + + bool has_node(const octree::Id &id) { + if (this->_overwrite) { + return false; + } else { + return this->_storage.has_node(id); + } + } + + void write_node(const octree::Id &id, const SimpleMesh &mesh) { + DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); + } + + void copy_subtree_to_output( + const octree::Id &id, + const NodeLoader &loader) { + octree::traverse( + loader.storage().index(), + [&](const octree::Id &child_id, const octree::NodeStatus &status) { + if (status == octree::NodeStatus::Virtual) { + return; + } + DEBUG_ASSERT(status == octree::NodeStatus::Leaf); + + DEBUG_ASSERT_VAL(loader.storage().copy_node_to(child_id, this->_storage)); + }, + octree::always_refine, + id); + } + +private: + octree::Storage &_storage; + bool _overwrite = false; +}; diff --git a/src/terrainmerger/SimpleMutex.h b/src/terrainmerger/SimpleMutex.h new file mode 100644 index 0000000..56d5277 --- /dev/null +++ b/src/terrainmerger/SimpleMutex.h @@ -0,0 +1,44 @@ +#include +#include + +template +class SimpleMutex { +public: + SimpleMutex() = default; + + explicit SimpleMutex(T value) : value_(std::move(value)) {} + + // Disable copy and move to avoid ownership issues + SimpleMutex(const SimpleMutex &) = delete; + SimpleMutex &operator=(const SimpleMutex &) = delete; + + // Access wrapper: provides scoped locking and reference + class LockGuard { + public: + LockGuard(std::mutex &mutex, T &value) + : lock_(mutex), ref_(value) {} + + T &get() { + return ref_; + } + T *operator->() { + return &ref_; + } + T &operator*() { + return ref_; + } + + private: + std::unique_lock lock_; + T &ref_; + }; + + // Lock and return access to the inner value + LockGuard lock() { + return LockGuard(mutex_, value_); + } + +private: + T value_; + mutable std::mutex mutex_; +}; diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index 8133ee7..7020454 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -1,19 +1,19 @@ #include "cli.h" #include -#include #include +#include using namespace cli; -Args cli::parse(int argc, const char * const * argv) { +Args cli::parse(int argc, const char *const *argv) { DEBUG_ASSERT(argc >= 0); CLI::App app{"terrainmerger"}; app.allow_windows_style_options(); // argv = app.ensure_utf8(argv); - auto& merge = *app.add_subcommand("merge"); + auto &merge = *app.add_subcommand("merge"); MergeArgs merge_args; merge.add_option("--base", merge_args.base_path, "Path to base dataset") ->required() @@ -26,11 +26,21 @@ Args cli::parse(int argc, const char * const * argv) { merge.add_option("--mask", merge_args.mask_path, "Path to a mask denoting the valid area of the new dataset") ->check(CLI::ExistingFile); - merge.add_option("--output", merge_args.output_path, "Path to output write the merged dataset to (defaults to --base)"); + merge.add_option("--output", merge_args.output_path, "Path to output write the merged dataset to") + ->required(); + + merge.add_option("--overwrite", merge_args.overwrite_output, "Overwrite any data already in output"); + + /* + const std::map method_names{ + {"combine", MergeAlgorithm::Combine}, {"masked", MergeAlgorithm::Masked}, {"project", MergeAlgorithm::Project}}; + merge.add_option("--method", merge_args.algorihm, "Method to use for merging") + ->transform(CLI::CheckedTransformer(method_names, CLI::ignore_case)); + */ merge.fallthrough(); - auto& cut = *app.add_subcommand("cut"); + auto &cut = *app.add_subcommand("cut"); CutArgs cut_args; cut.add_option("--input", cut_args.input_path, "Path to dataset to cut") ->required() @@ -59,7 +69,11 @@ Args cli::parse(int argc, const char * const * argv) { app.require_subcommand(1); try { - app.parse(argc, argv); + // app.parse(argc, argv); + // app.parse("--input ../../../meshes/innenstadt2 ../../../meshes/vienna2 --output ../../../meshes/out --verbosity trace"); + // app.parse("merge --new ../../../meshes/innenstadt3 --base ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out --verbosity trace"); + app.parse("cut --input ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out3 --verbosity trace"); + std::filesystem::remove_all("../../../meshes/out3"); } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/terrainmerger/cli.h b/src/terrainmerger/cli.h index 7bb489a..13e42c3 100644 --- a/src/terrainmerger/cli.h +++ b/src/terrainmerger/cli.h @@ -11,11 +11,21 @@ struct BaseArgs { spdlog::level::level_enum log_level; }; +/* +enum class MergeAlgorithm { + Combine, + Masked, + Project +}; +*/ + struct MergeArgs : public BaseArgs { std::filesystem::path base_path; std::filesystem::path new_path; + std::filesystem::path output_path; std::optional mask_path; - std::optional output_path; + // MergeAlgorithm algorihm; + bool overwrite_output; }; struct CutArgs : public BaseArgs { diff --git a/src/terrainmerger/cut.h b/src/terrainmerger/cut.h index 1f2250d..5dcf241 100644 --- a/src/terrainmerger/cut.h +++ b/src/terrainmerger/cut.h @@ -5,46 +5,124 @@ #include "mesh/SimpleMesh.h" #include "log.h" #include "mask.h" -#include "merge.h" #include "octree/Id.h" #include "octree/NodeStatus.h" #include "octree/storage/IndexedStorage.h" #include "octree/storage/open.h" +#include "octree/Space.h" #include "octree/traverse.h" +#include "utils.h" +#include "Cow.h" + +struct Context { + const octree::IndexedStorage& input; + octree::Storage& output; + const octree::Space space; +}; + +void cut_node( + Context& ctx, + const octree::Id& id, + const MeshMask& mask); + +inline void cut_leaf_node( + Context& ctx, + const octree::Id& id, + const MeshMask& mask +) { + DEBUG_ASSERT(ctx.input.index().is(octree::NodeStatus::Leaf, id)); + + const SimpleMesh mesh = DEBUG_ASSERT_VAL(ctx.input.read_node(id)).value(); + LOG_TRACE("Cutting mesh at {} using mask with {} vertices and {} triangles", + id, mask.mesh.vertex_count(), mask.mesh.face_count()); + const Cow clipped = clip_on_mask(mesh, mask); + if (clipped.is_ref()) { + LOG_TRACE("Mesh was fully inside the mask"); + DEBUG_ASSERT_VAL(ctx.input.copy_node_to(id, ctx.output)); + } else { + const SimpleMesh &clipped_mesh = clipped; + if (!clipped_mesh.is_empty()) { + LOG_TRACE("Mesh was clipped from {} vertices and {} triangles to {} vertices and {} triangles", + mesh.vertex_count(), mesh.face_count(), clipped_mesh.vertex_count(), clipped_mesh.face_count()); + DEBUG_ASSERT_VAL(ctx.output.write_node(id, clipped_mesh)); + } else { + LOG_TRACE("Mesh was fully ouside the mask"); + } + } +} + +namespace { +template +radix::geometry::Aabb pad_bounds(const radix::geometry::Aabb &bounds, const T factor) { + using Vec = glm::vec; + const Vec center = bounds.centre(); + const Vec half_size = bounds.size() * (factor / T(2)); + const Vec new_min = center - half_size; + const Vec new_max = center + half_size; + return radix::geometry::Aabb(new_min, new_max); +} +} + +inline void cut_virtual_node( + Context& ctx, + const octree::Id& id, + const MeshMask& mask +) { + DEBUG_ASSERT(ctx.input.index().is(octree::NodeStatus::Virtual, id)); + DEBUG_ASSERT(id.has_children()); + + const auto children = id.children().value(); + for (const octree::Id& child_id : children) { + // TODO: split mask based on inner planes instead + const auto child_bounds = pad_bounds(ctx.space.get_node_bounds(child_id), 1.25); + LOG_TRACE("Clipping mask for {}", child_id); + const auto child_mask = MeshMask(mesh::clip_on_bounds_and_cap(mask.mesh, child_bounds)); + cut_node(ctx, child_id, child_mask); + } +} + +inline void cut_node( + Context& ctx, + const octree::Id& id, + const MeshMask& mask +) { + if (mask.mesh.is_empty()) { + return; + } + + /* + Uncomment to output masks + const auto path = ctx.output.get_node_path(id); + const auto new_path = path.parent_path() / + (path.stem().string() + "-mask" + path.extension().string()); + mesh::io::save_to_path(mask.mesh, new_path); + */ + + const auto status_opt = ctx.input.index().get(id); + if (!status_opt.has_value()) { + return; + } + + const octree::NodeStatus status = status_opt.value(); + switch (status) { + case octree::NodeStatus::Virtual: + cut_virtual_node(ctx, id, mask); + break; + case octree::NodeStatus::Leaf: + cut_leaf_node(ctx, id, mask); + break; + default: + UNREACHABLE(); + break; + } +} inline void cut_dataset( const octree::IndexedStorage &input, const MeshMask& mask, octree::Storage &output) { - - mesh::io::save_to_path(mask.mesh, "./mask.glb"); - - octree::traverse( - input.index(), - [&](const octree::Id &id, const octree::NodeStatus &status) { - if (status == octree::NodeStatus::Virtual) { - return; - } - DEBUG_ASSERT(status == octree::NodeStatus::Leaf); - - const SimpleMesh mesh = DEBUG_ASSERT_VAL(input.read_node(id)).value(); - LOG_TRACE("Cutting mesh at {}", id); - const ClipResult result = clip_on_mask(mesh, mask); - if (result.is_unchanged()) { - LOG_TRACE("Mesh was fully inside the mask"); - DEBUG_ASSERT_VAL(input.copy_node_to(id, output)); - } else { - const SimpleMesh& clipped_mesh = result.mesh(); - if (clipped_mesh.is_empty()) { - LOG_TRACE("Mesh was clipped from {} vertices and {} triangles to {} vertices and {} triangles", - mesh.vertex_count(), mesh.face_count(), clipped_mesh.vertex_count(), clipped_mesh.face_count()); - DEBUG_ASSERT_VAL(output.write_node(id, result.mesh())); - } else { - LOG_TRACE("Mesh was fully ouside the mask"); - } - } - }); - + Context ctx(input, output, octree::Space::earth()); + cut_node(ctx, octree::Id::root(), mask); output.save_or_create_index(); } @@ -55,7 +133,7 @@ inline void cut_dataset( LOG_TRACE("Creating output dataset at {}", output_path); std::filesystem::create_directories(output_path); - octree::IndexedStorage output_dataset = octree::open_folder_indexed(output_path, octree::disk::layout::strategy::make_default(), ".glb"); + octree::IndexedStorage output_dataset = octree::open_folder_indexed(output_path, octree::OpenOptions(octree::disk::layout::strategy::make_default(), ".glb")); if (!output_dataset.index().empty()) { LOG_ERROR_AND_EXIT("Output dataset has to be empty."); } diff --git a/src/terrainmerger/earth.h b/src/terrainmerger/earth.h index a6349fc..448f9b0 100644 --- a/src/terrainmerger/earth.h +++ b/src/terrainmerger/earth.h @@ -15,4 +15,4 @@ namespace earth { constexpr glm::dvec2 radius_range() { return {smallest_radius(), largest_radius()}; } -} \ No newline at end of file +} diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index e71c0d4..a85e55a 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -2,15 +2,16 @@ #include #include -#include "log.h" #include "cli.h" -#include "merge.h" -#include "mask.h" #include "cut.h" +#include "log.h" +#include "mask.h" +#include "merge.h" #include "octree/Storage.h" #include "optional_utils.h" +#include "earth.h" -std::optional load_mask_from_path(const std::filesystem::path& path) { +std::optional load_mask_from_path(const std::filesystem::path& path) { if (std::filesystem::exists(path)) { LOG_INFO("Loading mask file from {}", path); const glm::dvec2 radius_range = mask::pad_radius_range(earth::radius_range(), 2); @@ -37,19 +38,19 @@ void run(const cli::MergeArgs& args) { LOG_TRACE("Loading new dataset from {}", args.new_path); octree::IndexedStorage new_dataset = octree::open_folder_indexed(args.new_path); - std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); + LOG_TRACE("Creating output dataset at {}", args.output_path); + std::filesystem::create_directories(args.output_path); + octree::Storage output_dataset = octree::open_folder(args.output_path); - if (args.output_path.has_value()) { - return merge_datasets(base_dataset, new_dataset, args.output_path.value(), mask); - } else { - return merge_datasets(base_dataset, new_dataset, mask); - } + std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); + + return merge_datasets(base_dataset, new_dataset, output_dataset, mask); } void run(const cli::CutArgs& args) { LOG_TRACE("Loading input dataset from {}", args.input_path); const octree::IndexedStorage input_dataset = octree::open_folder_indexed(args.input_path); - const mask::MeshMask mask = DEBUG_ASSERT_VAL(load_mask_from_path(args.mask_path)).value(); + const MeshMask mask = DEBUG_ASSERT_VAL(load_mask_from_path(args.mask_path)).value(); cut_dataset(input_dataset, mask, args.output_path); } diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h index aae519f..678dd69 100644 --- a/src/terrainmerger/mask.h +++ b/src/terrainmerger/mask.h @@ -33,6 +33,24 @@ using PolygonWithHoles2 = CGAL::Polygon_with_holes_2; using PolygonSet2 = CGAL::Polygon_set_2; using MultipolygonWithHoles2 = CGAL::Multipolygon_with_holes_2; +struct ReferencedPolygonMask { + MultipolygonWithHoles2 polygons; + OGRSpatialReference srs; +}; + +struct SpherePolygonMask { + MultipolygonWithHoles2 polygons; + SphereProjector projector; +}; + +struct SphereMeshMask { + SimpleMesh3d mesh; +}; + +struct MeshMask { + SimpleMesh3d mesh; +}; + namespace mask { namespace { @@ -89,24 +107,6 @@ class LoadError { LoadErrorKind kind; }; -struct ReferencedPolygonMask { - MultipolygonWithHoles2 polygons; - OGRSpatialReference srs; -}; - -struct SpherePolygonMask { - MultipolygonWithHoles2 polygons; - SphereProjector projector; -}; - -struct SphereMeshMask { - SimpleMesh3d mesh; -}; - -struct MeshMask { - SimpleMesh3d mesh; -}; - namespace { std::optional convert_ring(const OGRLinearRing &ring, bool is_outer) { uint32_t num_points = ring.getNumPoints(); @@ -271,6 +271,7 @@ inline tl::expected load_referenced_from_datas // TODO: remove this try catch try { srs = mask_dataset.srs(); + srs.SetAxisMappingStrategy(OAMS_AUTHORITY_COMPLIANT); // TODO } catch (std::runtime_error &e) { LOG_WARN("Mask does not reference an srs, assuming WGS84"); srs = srs::wgs84(); diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index c91f9c3..e200f83 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -1,346 +1,151 @@ #pragma once -#include -#include +#include +#include -#include - -#include "mesh/SimpleMesh.h" -#include "mesh/utils.h" -#include "earth.h" -#include "log.h" #include "mask.h" -#include "mesh/boolean.h" -#include "mesh/clip.h" -#include "mesh/merge.h" -#include "mesh/validate.h" +#include "merge/NodeData.h" +#include "merge/Result.h" #include "octree/Id.h" -#include "octree/NodeStatus.h" -#include "octree/Space.h" -#include "octree/storage/IndexedStorage.h" -#include "octree/storage/open.h" -#include "octree/traverse.h" - -using MeshMask = mask::MeshMask; +#include "octree/NodeStatusOrMissing.h" +#include "NodeLoader.h" +#include "NodeWriter.h" +#include "octree/storage/cache/Dummy.h" +#include "merge/visitor/Masked.h" +#include "merge/visitor/Simple.h" + +inline std::string get_dataset_name(const octree::Storage &storage) { + return storage.layout().base_path().filename().string(); +} -inline SimpleMesh combine_meshes( - const SimpleMesh& a, - const SimpleMesh& b -) { - if (a.is_empty()) { - return b; - } - if (b.is_empty()) { - return a; - } +template +using smallest_uint_t = + std::conditional_t<(N <= UINT8_MAX), uint8_t, + std::conditional_t<(N <= UINT16_MAX), uint16_t, + std::conditional_t<(N <= UINT32_MAX), uint32_t, + uint64_t>>>; - SimpleMesh combined_mesh; - combined_mesh.positions.reserve(a.vertex_count() + b.vertex_count()); - combined_mesh.uvs.reserve(a.vertex_count() + b.vertex_count()); - combined_mesh.triangles.reserve(a.face_count() + b.face_count()); - combined_mesh.positions.insert(combined_mesh.positions.end(), a.positions.begin(), a.positions.end()); - combined_mesh.positions.insert(combined_mesh.positions.end(), b.positions.begin(), b.positions.end()); - combined_mesh.uvs.insert(combined_mesh.uvs.end(), a.uvs.begin(), a.uvs.end()); - combined_mesh.uvs.insert(combined_mesh.uvs.end(), b.uvs.begin(), b.uvs.end()); - combined_mesh.triangles.insert(combined_mesh.triangles.end(), a.triangles.begin(), a.triangles.end()); - const size_t offset = a.vertex_count(); - for (const auto& triangle : b.triangles) { - combined_mesh.triangles.emplace_back(triangle.x + offset, triangle.y + offset, triangle.z + offset); - } -} +template +class Merger { +public: + using Status = octree::NodeStatusOrMissing; -inline SimpleMesh merge_meshes( - const SimpleMesh& base_mesh, // base mesh - const SimpleMesh& new_mesh, // priority mesh - const std::optional mask -struct ClipResult { - bool was_clipped() const { - return std::holds_alternative(this->value); - } - bool is_unchanged() const { - return std::holds_alternative>(this->value); - } + Merger( + Visitor& visitor, + const NodeLoader &left, + const NodeLoader &right, + NodeWriter &output) : _visitor(visitor), _left(left), _right(right), _output(output) { - const SimpleMesh &mesh() const { - return std::visit([](const auto &value) -> const SimpleMesh & { - return value; - }, this->value); } - static ClipResult from_clipped(SimpleMesh mesh) { - return ClipResult(std::move(mesh)); - } - static ClipResult from_input(const SimpleMesh &mesh) { - return ClipResult(std::reference_wrapper(mesh)); + void merge_node(const octree::Id &id) { + const Status left_status = this->_left.get_status(id); + const Status right_status = this->_right.get_status(id); + return this->merge_node(id, left_status, right_status); } - std::variant, SimpleMesh> value; -}; - -inline ClipResult clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask) { - const SimpleMesh clipped = mesh::clip_on_mesh(mesh, mask.mesh); - return ClipResult::from_clipped(std::move(clipped)); -} -) { - // TODO: dont convert to SimpleMesh all the time - if (mask.has_value()) { - const SimpleMesh new_mesh_clipped = mesh::clip_on_mesh(new_mesh, mask->mesh); - const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask->mesh); - - return combine_meshes(base_mesh_clipped, new_mesh_clipped); - // return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh_clipped); - } else { - // If one mesh is empty, return the other - // We can only do this if there is no mask, otherwise we need to at least clip the meshes - if (base_mesh.is_empty()) { - return new_mesh; - } - if (new_mesh.is_empty()) { - return base_mesh; + void merge_node( + const octree::Id &id, + const Status left_status, + const Status right_status + ) { + if (this->_output.has_node(id)) { + return; // Already merged perviously } - // TODO: this doesnt really work well if there are intersections - return mesh::merge::merge_meshes(base_mesh, new_mesh); + const auto merge_result = this->call_merge(id, left_status, right_status); + std::visit([&](const auto &result) { + using Result = std::decay_t; + if constexpr (std::is_same_v) { + DEBUG_ASSERT(id.has_children()); + const auto children = id.children().value(); + for (const auto &child_id : children) { + this->merge_node(child_id); + } + } else if constexpr (std::is_same_v) { + this->_output.copy_subtree_to_output(id, result.is_left ? this->_left : this->_right); + } else if constexpr (std::is_same_v) { + this->_output.write_node(id, result.mesh); + } else if constexpr (std::is_same_v) { + // do nothing + } + }, merge_result); } - /* - TODO: Advanced merging - const auto base_mesh_bounds = calculate_bounds(base_mesh); - auto bounds = base_mesh_bounds; - bounds.expand_by(new_mesh_bounds); - const glm::dvec3 tangent_point = bounds.centre(); - const glm::dvec2 radius_range = mask::pad_radius_range(mask::calculate_radius_range(bounds), 2); - if (mask.has_value()) { - auto result = mesh::intersection_and_difference(new_mesh, mask->mesh); - const SimpleMesh new_mesh_in_mask = std::move(result.intersection); - const SimpleMesh new_mesh_out_mask = std::move(result.difference); - const MeshMask mask_base_mesh = mask::create_from_mesh(base_mesh, tangent_point, radius_range); - const SimpleMesh new_mesh_out_mask_clipped = mesh::clip_on_mesh(new_mesh_out_mask, mask_base_mesh.mesh); - const MeshMask mask_new_mesh_in_mask = mask::create_from_mesh(new_mesh_in_mask, tangent_point, radius_range); - const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh_in_mask.mesh); - return mesh::merge::merge_meshes(new_mesh_out_mask_clipped, base_mesh_clipped, new_mesh_in_mask); - } else { - const MeshMask mask_new_mesh = mask::create_from_mesh(new_mesh, tangent_point, radius_range); - const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh.mesh); - return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh); - } - */ -} +private: + static constexpr auto STATUSES = magic_enum::enum_values(); + static constexpr auto _STATUS_COUNT = STATUSES.size(); + static constexpr auto _MAX_INDEX = _STATUS_COUNT * _STATUS_COUNT; + using Index = smallest_uint_t<_MAX_INDEX>; + static constexpr Index STATUS_COUNT = static_cast(_STATUS_COUNT); + static constexpr Index MAX_INDEX = static_cast(_MAX_INDEX); -inline std::optional> split_mesh_into_children(const octree::IdAndNode& node) { - if (!node.id.has_children()) { - return std::nullopt; + static constexpr Index get_index(Status left, Status right) { + return static_cast(left) * STATUS_COUNT + static_cast(right); } - const auto space = octree::Space::earth(); // TODO: store in storage + merge::Result call_merge( + const octree::Id &id, + Status left, + Status right) { + const Index index = get_index(left, right); - const auto children = node.id.children().value(); - std::array child_nodes; - for (size_t i = 0; i < children.size(); i++) { - const auto& child_id = children[i]; - const auto child_bounds = space.get_node_bounds(child_id); - const_cast(node.node).uvs.clear(); // TODO: remove this when we can handle uvs during clipping - const auto child_mesh = mesh::clip_on_bounds(node.node, child_bounds); - mesh::validate(child_mesh); - child_nodes[i] = {child_id, std::move(child_mesh)}; + switch (index) { +#define ALP_GENERATE_CASE(left_status, right_status) \ + case get_index(Status::left_status, Status::right_status): { \ + merge::NodeData left_node(id, this->_left); \ + merge::NodeData right_node(id, this->_right); \ + return this->_visitor.template visit(id, left_node, right_node); \ } - return child_nodes; -} -struct MergeState { - octree::IndexedStorage& output; - const octree::IndexedStorage& input; - const std::optional &input_mask; -}; + ALP_GENERATE_CASE(Missing, Missing); + ALP_GENERATE_CASE(Missing, Leaf); + ALP_GENERATE_CASE(Missing, Virtual); -inline void merge_leaves( - MergeState& state, - const octree::Id& id -) { - LOG_TRACE("Merging leaves for id: {}", id); + ALP_GENERATE_CASE(Leaf, Missing); + ALP_GENERATE_CASE(Leaf, Leaf); + ALP_GENERATE_CASE(Leaf, Virtual); - DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Leaf, id)); - DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Leaf, id)); - const auto output_mesh = state.output.read_node(id).value(); - const auto input_mesh = state.input.read_node(id).value(); + ALP_GENERATE_CASE(Virtual, Missing); + ALP_GENERATE_CASE(Virtual, Leaf); + ALP_GENERATE_CASE(Virtual, Virtual); +#undef ALP_GENERATE_CASE - mesh::validate(output_mesh); - mesh::validate(input_mesh); - - SimpleMesh merged_mesh = merge_meshes( - output_mesh, - input_mesh, - state.input_mask - ); - // TODO: use copy_node_to if the merged mesh is the same as the output mesh - state.output.write_node(id, merged_mesh); -} - -inline void merge_with_leaf( - MergeState &state, - const octree::Id &id, - const SimpleMesh &leaf_mesh, - bool leaf_is_output, // true if leaf is from output, false if from input - bool leaf_is_clipped // true if the leaf mesh was generated by clipping -) { - LOG_TRACE("Merging leaf from {} for id: {}", - leaf_is_output ? "output" : "input", - id); - - if (leaf_is_output) { - if (leaf_is_clipped) { - DEBUG_ASSERT(state.output.index().is_absent(id)); - } else { - DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Leaf, id)); - } - DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Virtual, id)); - } else { - if (leaf_is_clipped) { - DEBUG_ASSERT(state.input.index().is_absent(id)); - } else { - DEBUG_ASSERT(state.input.index().is(octree::NodeStatus::Leaf, id)); - } - DEBUG_ASSERT(state.output.index().is(octree::NodeStatus::Virtual, id)); - } - DEBUG_ASSERT(id.has_children()); - - // Split the leaf mesh into children - const auto leaf_children = split_mesh_into_children({id, leaf_mesh}); - DEBUG_ASSERT(leaf_children.has_value()); - - // Merge each child - for (const auto& child : *leaf_children) { - const auto& child_id = child.id; - const auto& child_mesh = child.node; - - // Load other child mesh from the other dataset - const auto other_status_opt = leaf_is_output - ? state.input.index().get(child_id) - : state.output.index().get(child_id); - if (!other_status_opt.has_value()) { - // TODO: dont generate meshes for non-existing input nodes - // If the other child does not exist, we can just write the clipped mesh from the leaf - state.output.write_node(child_id, child_mesh); - continue; - } - const auto other_status = other_status_opt.value(); - DEBUG_ASSERT(other_status != octree::NodeStatus::Inner); - - if (other_status == octree::NodeStatus::Virtual) { - // If the other child is virtual, we recurse further - merge_with_leaf(state, child_id, child_mesh, leaf_is_output, true); - } else if (other_status == octree::NodeStatus::Leaf) { - // If the other child is a leaf, we can merge it directly - SimpleMesh merged_mesh; - if (leaf_is_output) { - // If the leaf is from output, we read from input - const auto other_mesh = state.input.read_node(child_id).value(); - merged_mesh = merge_meshes(child_mesh, other_mesh, state.input_mask); - } else { - // If the leaf is from input, we read from output - const auto other_mesh = state.output.read_node(child_id).value(); - merged_mesh = merge_meshes(other_mesh, child_mesh, state.input_mask); - } - state.output.write_node(child_id, merged_mesh); - } else { + default: UNREACHABLE(); } } -} - -inline void copy_subtree_to_output( - MergeState& state, - const octree::Id& id -) { - LOG_TRACE("Copying subtree to output for id: {}", id); - - DEBUG_ASSERT(state.input.has_node(id)); - DEBUG_ASSERT(!state.output.has_node(id)); - - octree::traverse( - state.input.index(), - [&](const octree::Id &child_id, const octree::NodeStatus &status) { - if (status == octree::NodeStatus::Virtual) { - return; - } - DEBUG_ASSERT(status == octree::NodeStatus::Leaf); - - const auto result = state.input.copy_node_to(child_id, state.output); - DEBUG_ASSERT(result.has_value()); - }, - [](const octree::Id &) { return true; }, - id); -} - -inline void merge_node( - MergeState& state, - const octree::Id& id -) { - LOG_TRACE("Merging nodes for id: {}", id); - - const auto output_state_opt = state.output.index().get(id); - const auto input_state_opt = state.input.index().get(id); - - if (!input_state_opt.has_value()) { - // If the input does not have the node, we can skip it - return; - } - if (!output_state_opt.has_value()) { - // If the output does not have the node, we can copy it - copy_subtree_to_output(state, id); - return; - } - - const auto output_status = output_state_opt.value(); - const auto input_status = input_state_opt.value(); - DEBUG_ASSERT(output_status != octree::NodeStatus::Inner); - DEBUG_ASSERT(input_status != octree::NodeStatus::Inner); - - if (output_status == octree::NodeStatus::Leaf && input_status == octree::NodeStatus::Leaf) { - // If both nodes are leaves, we can merge them directly - merge_leaves(state, id); - } else if (output_status == octree::NodeStatus::Leaf && input_status == octree::NodeStatus::Virtual) { - merge_with_leaf(state, id, state.output.read_node(id).value(), true, false); - } else if (output_status == octree::NodeStatus::Virtual && input_status == octree::NodeStatus::Leaf) { - merge_with_leaf(state, id, state.input.read_node(id).value(), false, false); - } else if (output_status == octree::NodeStatus::Virtual && input_status == octree::NodeStatus::Virtual) { - // If both nodes are virtual, recurse - DEBUG_ASSERT(id.has_children()); - const auto children = id.children().value(); - for (const auto& child_id : children) { - merge_node(state, child_id); - } - } else { - UNREACHABLE(); - } -} + Visitor& _visitor; + NodeLoader _left; + NodeLoader _right; + NodeWriter _output; +}; -inline void merge_datasets(octree::IndexedStorage& output, const octree::IndexedStorage& input) { - std::optional mask = std::nullopt; - const auto mask_path = input.base_path() / "mask.geojson"; - LOG_TRACE("Looking for mask file at {}", mask_path); - if (std::filesystem::exists(mask_path)) { - LOG_INFO("Loading mask file from {}", mask_path); - const glm::dvec2 radius_range = mask::pad_radius_range(earth::radius_range(), 2); - auto mask_result = mask::load_from_path(mask_path, radius_range); - if (mask_result.has_value()) { - mask = std::move(mask_result.value()); - LOG_DEBUG("Loaded mask successfully"); - } else { - LOG_ERROR("Failed to load mask: {}", mask_result.error().description()); - } +inline void merge_datasets( + const octree::IndexedStorage &left_dataset, + const octree::IndexedStorage &right_dataset, + octree::Storage &output_dataset, + const std::optional mask = std::nullopt) { + LOG_TRACE("Merging {} and {} into {}", + get_dataset_name(left_dataset), + get_dataset_name(right_dataset), + get_dataset_name(output_dataset)); + + octree::cache::Dummy left_cache; + NodeLoader left(left_dataset, left_cache); + octree::cache::Dummy right_cache; + NodeLoader right(right_dataset, right_cache); + NodeWriter output(output_dataset); + if (mask.has_value()) { + merge::visitor::Masked visitor {mask.value()}; + Merger merger(visitor, left, right, output); + merger.merge_node(octree::Id::root()); } else { - LOG_DEBUG("No mask file found at {}, proceeding without mask", mask_path); + merge::visitor::Simple visitor; + Merger merger(visitor, left, right, output); + merger.merge_node(octree::Id::root()); } - MergeState state{output, input, mask}; - merge_node(state, octree::Id::root()); - output.save_index(); -} - -inline void merge_datasets(octree::IndexedStorage& output, const std::span inputs) { - for (const auto& input : inputs) { - merge_datasets(output, input); - } + output_dataset.save_or_create_index(); } diff --git a/src/terrainmerger/merge/NodeData.h b/src/terrainmerger/merge/NodeData.h new file mode 100644 index 0000000..e37c05e --- /dev/null +++ b/src/terrainmerger/merge/NodeData.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "NodeLoader.h" +#include "log.h" +#include "mesh/SimpleMesh.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" +#include "octree/Storage.h" + +namespace merge { + +template +class NodeData { +public: + constexpr explicit NodeData(octree::Id id, const NodeLoader &loader) : _id(id), _loader(loader) {} + + const SimpleMesh &mesh() const { + static_assert(Status != octree::NodeStatusOrMissing::Missing, "Trying to access mesh from missing node."); + + if (!this->_mesh.has_value()) { + auto result = this->_loader.load_node(this->_id); + if (result.has_value()) { + this->_mesh = result.value(); + } else { + LOG_ERROR_AND_EXIT("Failed to read node from loader that should be present"); + } + } + return this->_mesh.value(); + } + + static constexpr octree::NodeStatusOrMissing status() { + return Status; + } + +private: + octree::Id _id; + const NodeLoader &_loader; + mutable std::optional _mesh; +}; + +} // namespace merge diff --git a/src/terrainmerger/merge/Result.h b/src/terrainmerger/merge/Result.h new file mode 100644 index 0000000..d0b3bbc --- /dev/null +++ b/src/terrainmerger/merge/Result.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "mesh/SimpleMesh.h" + +namespace merge { + +struct Recurse {}; + +struct Ignore {}; + +struct Unchanged { + bool is_left; +}; + +struct Merged { + SimpleMesh mesh; +}; + +using Result = std::variant; + +} // namespace merge diff --git a/src/terrainmerger/merge/visitor/Base.h b/src/terrainmerger/merge/visitor/Base.h new file mode 100644 index 0000000..30156c2 --- /dev/null +++ b/src/terrainmerger/merge/visitor/Base.h @@ -0,0 +1,19 @@ +#pragma once + +#include "merge/NodeData.h" +#include "merge/Result.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" + +namespace merge::visitor { +class Base { +public: + virtual ~Base() = default; + + template + Result visit( + const octree::Id &id, + NodeData &left, + NodeData &right); +}; +} // namespace merge::visitor diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h new file mode 100644 index 0000000..eba276b --- /dev/null +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -0,0 +1,93 @@ +#pragma once + +#include "mask.h" +#include "merge/NodeData.h" +#include "merge/Result.h" +#include "merge/visitor/Base.h" +#include "mesh/merge.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" +#include "utils.h" + +namespace merge::visitor { +namespace { +inline Result merge_meshes( + const SimpleMesh &base_mesh, + const SimpleMesh &new_mesh, + const MeshMask &mask) { + const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask); + const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask); + if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { + return Unchanged{true}; + } + if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { + return Unchanged{false}; + } + + const SimpleMesh merged_mesh = mesh::merge(base_mesh_clipped, new_mesh_clipped); + return Merged{merged_mesh}; + + /* + TODO: Advanced merging + const auto base_mesh_bounds = calculate_bounds(base_mesh); + auto bounds = base_mesh_bounds; + bounds.expand_by(new_mesh_bounds); + const glm::dvec3 tangent_point = bounds.centre(); + const glm::dvec2 radius_range = mask::pad_radius_range(mask::calculate_radius_range(bounds), 2); + if (mask.has_value()) { + auto result = mesh::intersection_and_difference(new_mesh, mask->mesh); + const SimpleMesh new_mesh_in_mask = std::move(result.intersection); + const SimpleMesh new_mesh_out_mask = std::move(result.difference); + const MeshMask mask_base_mesh = mask::create_from_mesh(base_mesh, tangent_point, radius_range); + const SimpleMesh new_mesh_out_mask_clipped = mesh::clip_on_mesh(new_mesh_out_mask, mask_base_mesh.mesh); + const MeshMask mask_new_mesh_in_mask = mask::create_from_mesh(new_mesh_in_mask, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh_in_mask.mesh); + return mesh::merge::merge_meshes(new_mesh_out_mask_clipped, base_mesh_clipped, new_mesh_in_mask); + } else { + const MeshMask mask_new_mesh = mask::create_from_mesh(new_mesh, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh.mesh); + return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh); + } + */ +} +} // namespace + +class Masked : public Base { +public: + using Status = octree::NodeStatusOrMissing; + + explicit Masked(MeshMask mask) : mask(mask) {} + + MeshMask mask; + + template + Result visit( + const octree::Id &, + NodeData &left, + NodeData &right) { + + if constexpr (right.status() == Status::Missing) { + return Unchanged{false}; + } + + if constexpr (left.status() == Status::Missing) { + if constexpr (right.status() == Status::Leaf) { + auto result = clip_on_mask(right.mesh(), this->mask); + if (result.is_ref()) { + return Unchanged{true}; + } else { + return Merged{result}; + } + } else { + return Recurse{}; + } + } + + if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { + return merge_meshes(right.mesh(), left.mesh(), this->mask); + } + + return Recurse{}; + } +}; +} // namespace merge::visitor diff --git a/src/terrainmerger/merge/visitor/Simple.h b/src/terrainmerger/merge/visitor/Simple.h new file mode 100644 index 0000000..09a1d9c --- /dev/null +++ b/src/terrainmerger/merge/visitor/Simple.h @@ -0,0 +1,54 @@ +#pragma once + +#include "merge/Result.h" +#include "merge/NodeData.h" +#include "merge/visitor/Base.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" + +namespace merge::visitor { +namespace { +inline Result merge_meshes( + const SimpleMesh &base_mesh, // left + const SimpleMesh &new_mesh // right +) { + // If one mesh is empty, return the other + if (base_mesh.is_empty()) { + return Unchanged { false }; + } + if (new_mesh.is_empty()) { + return Unchanged { true }; + } + + // TODO: this doesnt really work well if there are intersections + const SimpleMesh merged_mesh = mesh::merge(base_mesh, new_mesh); + return Merged {merged_mesh}; +} +} + +class Simple : public Base { +public: + using Status = octree::NodeStatusOrMissing; + + template + Result visit( + const octree::Id &, + const NodeData &left, + const NodeData &right) { + + if constexpr (right.status() == Status::Missing) { + return Unchanged{false}; + } + + if constexpr (left.status() == Status::Missing) { + return Unchanged{true}; + } + + if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { + return merge_meshes(right.mesh(), left.mesh()); + } + + return Recurse{}; + } +}; +} \ No newline at end of file diff --git a/src/terrainmerger/utils.h b/src/terrainmerger/utils.h new file mode 100644 index 0000000..e52bf5b --- /dev/null +++ b/src/terrainmerger/utils.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Cow.h" +#include "mask.h" +#include "mesh/SimpleMesh.h" +#include "mesh/clip.h" + +inline Cow clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask) { + return mesh::clip_on_mesh(mesh, mask.mesh); +} From 10851214198d7ad52c055b9d816675b09c4089e0 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Wed, 6 Aug 2025 12:43:36 +0200 Subject: [PATCH 097/122] Prepare for new mesh merging --- src/CMakeLists.txt | 7 + src/terrainlib/spatial_lookup/Grid.h | 272 ++++++++++++++++++ src/terrainlib/spatial_lookup/Hashmap.h | 221 ++++++++++++++ src/terrainlib/spatial_lookup/NDLoopHelper.h | 20 ++ src/terrainlib/spatial_lookup/SpatialLookup.h | 30 ++ .../spatial_lookup/SpatialLookupExt.h | 101 +++++++ src/terrainlib/type_utils.h | 30 +- 7 files changed, 680 insertions(+), 1 deletion(-) create mode 100644 src/terrainlib/spatial_lookup/Grid.h create mode 100644 src/terrainlib/spatial_lookup/Hashmap.h create mode 100644 src/terrainlib/spatial_lookup/NDLoopHelper.h create mode 100644 src/terrainlib/spatial_lookup/SpatialLookup.h create mode 100644 src/terrainlib/spatial_lookup/SpatialLookupExt.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61ae708..4ec9a20 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -127,6 +127,8 @@ add_library(terrainlib terrainlib/mesh/convert.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp terrainlib/mesh/merge.h terrainlib/mesh/merge.cpp + terrainlib/mesh/merge/Deduplicate.h + terrainlib/mesh/merge/VertexMapping.h terrainlib/mesh/SimpleMesh.h terrainlib/mesh/TriangleSoup.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp @@ -155,6 +157,11 @@ add_library(terrainlib terrainlib/octree/traverse.h terrainlib/octree/utils.h + terrainlib/spatial_lookup/Grid.h + terrainlib/spatial_lookup/NDLoopHelper.h + terrainlib/spatial_lookup/SpatialLookup.h + terrainlib/spatial_lookup/Hashmap.h + terrainlib/Dataset.h terrainlib/Dataset.cpp terrainlib/hash_utils.h terrainlib/init.h terrainlib/init.cpp diff --git a/src/terrainlib/spatial_lookup/Grid.h b/src/terrainlib/spatial_lookup/Grid.h new file mode 100644 index 0000000..f48f1a9 --- /dev/null +++ b/src/terrainlib/spatial_lookup/Grid.h @@ -0,0 +1,272 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +#include "log.h" +#include "mesh/SimpleMesh.h" +#include "spatial_lookup/NDLoopHelper.h" +#include "spatial_lookup/SpatialLookup.h" +#include "spatial_lookup/SpatialLookupExt.h" + +namespace spatial_lookup { + +template +class Grid : public SpatialLookup { +public: + using Self = Grid; + using Base = SpatialLookup; + using Vec = glm::vec; + using CellIndex = glm::vec; + using CellOffset = glm::vec; + + Grid(const Vec origin, const Vec size, const CellIndex divisions) + : origin(origin), size(size), divisions(divisions) { + this->_point_count = 0; + this->_data.resize(glm::compMul(divisions)); + } + + struct CellItem { + Vec point; + Value value; + }; + + struct Cell { + std::vector items; + }; + + void clear() override { + this->_data.clear(); + this->_point_count = 0; + } + + void insert(const Vec &point, const Value value) override { + if (!this->is_in_bounds(point)) { + return; + } + + const size_t cell_index = this->calculate_cell_index(point); + + const CellItem item{ + .point = point, + .value = value}; + Cell &cell = this->_data[cell_index]; + cell.items.push_back(item); + this->_point_count += 1; + + if (cell.items.size() >= 1000) { + LOG_WARN("Large number of points inside single grid cell: {} ({} overall)", cell.items.size(), this->_point_count); + } + } + + template + void for_all_near(const Vec &point, const Distance epsilon, Func &&func) { + const_cast(this)->for_all_near(point, epsilon, [&](const Vec &vec, const Value &value, const Distance distance_sq) { + func(vec, const_cast(value), distance_sq); + }); + } + template + void for_all_near(const Vec &point, const Distance epsilon, Func &&func) const { + DEBUG_ASSERT(epsilon > 0); + + if (!this->is_in_bounds(point)) { + return; + } + + const CellIndex grid_index = this->calculate_grid_index(point); + const Vec cell_size = this->cell_size(); + uint32_t cell_radius; + + const Vec relative_cell_point = point - cell_size * Vec(grid_index); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(relative_cell_point, Vec(0)))); + DEBUG_ASSERT(glm::all(glm::lessThan(relative_cell_point, cell_size))); + const Vec distance_from_cell_bounds = glm::min(relative_cell_point, cell_size - relative_cell_point); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(distance_from_cell_bounds, Vec(0)))); + DEBUG_ASSERT(glm::all(glm::lessThan(distance_from_cell_bounds * Component(2), cell_size))); + if (glm::all(glm::greaterThanEqual(distance_from_cell_bounds, Vec(epsilon)))) { + cell_radius = 0; + } else { + const Component max_cell_size = glm::compMax(cell_size); + cell_radius = std::ceil(epsilon / max_cell_size); + if (cell_radius > 1) { + LOG_WARN("Grid lookup epsilon ({}) is high compared to cell size {} resulting in cell radius of {}", + epsilon, cell_size, cell_radius); + } + } + + const Distance epsilon_sq = epsilon * epsilon; + CellOffset offset; + + NDLoopHelper::for_each_offset(cell_radius, offset, [&](const CellOffset &offset) { + const CellOffset _neighbor_index = CellOffset(grid_index) + offset; + if (!this->is_valid_grid_index(_neighbor_index)) { + return; + } + + const CellIndex neighbor_index(_neighbor_index); + const size_t cell_index = this->calculate_cell_index(neighbor_index); + const Cell &cell = this->_data[cell_index]; + + for (const CellItem &item : cell.items) { + const Distance distance_sq = helpers::distance_sq(point, item.point); + if (distance_sq < epsilon_sq) { + func(item.point, item.value, distance_sq); + } + } + }); + } + void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNear func) override { + this->for_all_near(point, epsilon, std::move(func)); + } + void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNearConst func) const override { + this->for_all_near(point, epsilon, std::move(func)); + } + + template + std::optional> find_nearest(const Vec &point, const Distance epsilon) { + return helpers::find_nearest(*this, point, epsilon); + } + template + std::optional> find_nearest(const Vec &point, const Distance epsilon) const { + return helpers::find_nearest(*this, point, epsilon); + } + std::optional> find_nearest(const Vec &point, const Component epsilon) override { + return this->find_nearest(point, epsilon); + } + std::optional> find_nearest(const Vec &point, const Component epsilon) const override { + return this->find_nearest(point, epsilon); + } + + template + bool find_all_near(const Vec &point, const Distance epsilon, Vector &out) { + return helpers::find_all_near(*this, point, epsilon, out); + } + template + bool find_all_near(const Vec &point, const Distance epsilon, Vector &out) const { + return helpers::find_all_near(*this, point, epsilon, out); + } + bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) override { + return this->find_all_near>>(point, epsilon, out); + } + bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const override { + return this->find_all_near>>(point, epsilon, out); + } + + bool is_in_bounds(const Vec point) const { + const Vec max_bounds = origin + size; + return glm::all(glm::greaterThanEqual(point, origin)) && + glm::all(glm::lessThanEqual(point, max_bounds)); + } + + Vec cell_size() const { + return this->size / Vec(this->divisions); + } + + CellIndex calculate_grid_index(const Vec point) const { + return CellIndex((point - this->origin) / this->cell_size()); + } + + size_t calculate_cell_index(const Vec point) const { + const CellIndex grid_index = this->calculate_grid_index(point); + return this->calculate_cell_index(grid_index); + } + + size_t calculate_cell_index(const CellIndex grid_index) const { + size_t index = 0; + size_t stride = 1; + + for (size_t i = 0; i < n_dims; i++) { + index += grid_index[i] * stride; + stride *= divisions[i]; + } + + return index; + } + + bool is_point_inside_cell(const Vec &point, const CellIndex &grid_index) const { + const Vec cell_size = this->cell_size(); + const Vec cell_min = this->origin + Vec(grid_index) * cell_size; + const Vec cell_max = cell_min + cell_size; + + return glm::all(glm::greaterThanEqual(point, cell_min)) && glm::all(glm::lessThanEqual(point, cell_max)); + } + + bool is_valid_grid_index(const CellOffset &grid_index) const { + return glm::all(glm::greaterThanEqual(grid_index, CellOffset(0))) && this->is_valid_grid_index(CellIndex(grid_index)); + } + bool is_valid_grid_index(const CellIndex &grid_index) const { + return glm::all(glm::lessThan(grid_index, divisions)); + } + + const Cell &cell(const CellIndex &grid_index) const { + return this->cell(this->calculate_cell_index(grid_index)); + } + const Cell &cell(const size_t cell_index) const { + return this->_data[cell_index]; + } + + const std::span cells() const { + return this->_data; + } + + /*const*/ Vec origin; + /*const*/ Vec size; + /*const*/ glm::vec divisions; + +private: + size_t _point_count; + std::vector _data; + + static_assert(SpatialLookupExt); +}; + +template +using Grid2d = Grid<2, double, Value>; +template +using Grid3d = Grid<3, double, Value>; + +} + +/* +namespace { +radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { + const glm::dvec3 bounds_padding = bounds.size() * percentage; + const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + return padded_bounds; +} + +template +Grid _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { + const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); + + const double max_extends = max_component(padded_bounds.size()); + const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; + const glm::uvec3 grid_divisions = glm::max(glm::uvec3(2 * std::cbrt(vertex_count) * relative_extends), glm::uvec3(1)); + Grid grid(padded_bounds.min, padded_bounds.size(), grid_divisions); + + return grid; +} +} // namespace + +template +inline Grid construct_grid_for_mesh(const SimpleMesh_ &mesh) { + const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); + const size_t vertex_count = mesh.vertex_count(); + return _construct_grid_for_meshes(bounds, vertex_count); +} + +template +inline Grid construct_grid_for_meshes(const std::span> meshes) { + const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); + const size_t maximal_merged_mesh_size = std::transform_reduce( + meshes.begin(), meshes.end(), 0, + [](const size_t a, const size_t b) { return a + b; }, + [](const SimpleMesh_ &mesh) { return mesh.vertex_count(); }); + return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); +} +*/ \ No newline at end of file diff --git a/src/terrainlib/spatial_lookup/Hashmap.h b/src/terrainlib/spatial_lookup/Hashmap.h new file mode 100644 index 0000000..4f0d204 --- /dev/null +++ b/src/terrainlib/spatial_lookup/Hashmap.h @@ -0,0 +1,221 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +#include "NDLoopHelper.h" +#include "SpatialLookup.h" +#include "hash_utils.h" + +namespace spatial_lookup { +namespace { +template +T remainder(const T x, const T y) { + if constexpr (std::is_integral::value) { + return x % y; + } else { + return std::fmod(x, y); + } +} + +template +T quantize(const T x, const T epsilon) { + return x - remainder(x, epsilon); +} + +template +glm::vec remainder(const glm::vec &v, const T epsilon) { + glm::vec result; + for (glm::length_t i = 0; i < n_dims; i++) { + result[i] = remainder(v[i], epsilon); + } + return result; +} + +template +glm::vec quantize(const glm::vec& v, const T epsilon) { + glm::vec result; + for (glm::length_t i = 0; i < n_dims; i++) { + result[i] = quantize(v[i], epsilon); + } + return result; +} + +template +struct VecHash { + using Vec = glm::vec; + + T epsilon; + + size_t operator()(const Vec &v) const noexcept { + size_t seed = hash::default_seed(); + for (glm::length_t i = 0; i < n_dims; i++) { + hash::append(seed, quantize(v[i], epsilon)); + } + return seed; + } +}; + +template +struct NeverEqual { + bool operator()(const T &, const T &) const noexcept { + return false; + } +}; + +} // namespace + +template +class Hashmap : public SpatialLookup { +public: + using Self = Hashmap; + using Base = SpatialLookup; + using Vec = glm::vec; + using Equal = NeverEqual; + using Hash = VecHash; + using Container = std::unordered_map; + using iterator = typename Container::iterator; + using const_iterator = typename Container::const_iterator; + using Bounds = radix::geometry::Aabb; + + explicit Hashmap(Component epsilon) + : _epsilon(epsilon), + _store(0, Hash(epsilon), Equal()) {} + + void clear() override { + this->_store.clear(); + this->_bounds = Bounds(); + } + + [[nodiscard]] bool empty() const { + return this->_store.empty(); + } + + [[nodiscard]] size_t size() const { + return this->_store.size(); + } + + void insert(const Vec& point, const Value value) override { + this->_store.emplace(point, std::move(value)); + this->_bounds.expand_by(point); + } + + template + void for_all_near(const Vec &point, const Distance epsilon, Func &&func) { + const_cast(this)->for_all_near(point, epsilon, [&](const Vec &vec, const Value &value, const Distance distance_sq) { + func(vec, const_cast(value), distance_sq); + }); + } + template + void for_all_near(const Vec &key, const _Distance _lookup_epsilon, Func &&func) const { + using Distance = MoreExact<_Distance, Component>; + const Distance lookup_epsilon = _lookup_epsilon; + DEBUG_ASSERT(lookup_epsilon > 0); + + const Distance lookup_epsilon2 = lookup_epsilon * lookup_epsilon; + if (radix::geometry::distance_sq(this->_bounds, key) > lookup_epsilon2) { + return; + } + + const uint32_t lookup_radius = this->_find_lookup_radius(key, lookup_epsilon); + const Vec quantized_key = this->_quantize(key); + const Vec base_key = quantized_key + Vec(this->_epsilon * 0.5f); + + glm::vec offset; + NDLoopHelper::for_each_offset(lookup_radius, offset, [&](const glm::vec &offset) { + const Vec neighbor_key = base_key + Vec(offset) * this->_epsilon; + size_t bucket_idx = this->_store.bucket(neighbor_key); + for (auto it = _store.begin(bucket_idx); it != _store.end(bucket_idx); ++it) { + const Vec &point = it->first; + const Value &value = it->second; + + if (this->_quantize(neighbor_key) != this->_quantize(point)) { + continue; // Skip if the key does not match + } + + const Distance distance2 = helpers::distance_sq(key, point); + if (distance2 < lookup_epsilon2) { + func(point, value, distance2); + } + } + }); + } + void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNear func) override { + this->for_all_near(point, epsilon, std::move(func)); + } + void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNearConst func) const override { + this->for_all_near(point, epsilon, std::move(func)); + } + + template + std::optional> find_nearest(const Vec &point, Distance epsilon) { + return helpers::find_nearest(*this, point, epsilon); + } + template + std::optional> find_nearest(const Vec &point, Distance epsilon) const { + return helpers::find_nearest(*this, point, epsilon); + } + std::optional> find_nearest(const Vec &point, const Component epsilon) override { + return this->find_nearest(point, epsilon); + } + std::optional> find_nearest(const Vec &point, const Component epsilon) const override { + return this->find_nearest(point, epsilon); + } + + template + bool find_all_near(const Vec &point, Distance epsilon, Vector &out) { + return helpers::find_all_near(*this, point, epsilon, out); + } + template + bool find_all_near(const Vec &point, Distance epsilon, Vector &out) const { + return helpers::find_all_near(*this, point, epsilon, out); + } + bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) override { + return this->find_all_near>>(point, epsilon, out); + } + bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const override { + return this->find_all_near>>(point, epsilon, out); + } + +private: + Vec _quantize(const Vec &v) const { + return quantize(v, this->_epsilon); + } + + template + uint32_t _find_lookup_radius(const Vec &key, const Distance lookup_epsilon) const { + const Distance store_epsilon = this->_epsilon; + if (lookup_epsilon < store_epsilon) { + // Check if it is sufficient to check only the cell of the key + const auto quantization_remainder = remainder(glm::vec(key), Distance(this->_epsilon)); + const Distance distance_to_next_key = std::min( + glm::compMin(quantization_remainder), + Distance(this->_epsilon) - glm::compMax(quantization_remainder)); + DEBUG_ASSERT(distance_to_next_key >= 0); + DEBUG_ASSERT(distance_to_next_key * 2 < this->_epsilon); + if (distance_to_next_key > lookup_epsilon) { + return 0; + } + } + + const uint32_t lookup_radius = static_cast(std::ceil(lookup_epsilon / this->_epsilon)); + if (lookup_radius > 1) { + LOG_WARN("Lookup epsilon {} is large compared to quantization epsilon {} resulting in lookup radius of {}", + lookup_epsilon, this->_epsilon, lookup_radius); + } + return lookup_radius; + } + + /*const*/ Component _epsilon; + Container _store; + Bounds _bounds; + + static_assert(SpatialLookupExt); +}; +} diff --git a/src/terrainlib/spatial_lookup/NDLoopHelper.h b/src/terrainlib/spatial_lookup/NDLoopHelper.h new file mode 100644 index 0000000..a3ff484 --- /dev/null +++ b/src/terrainlib/spatial_lookup/NDLoopHelper.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +template +struct NDLoopHelper { + using Offset = glm::vec; + + template + static void for_each_offset(const int32_t radius, Offset &offset, Func &&func) { + if constexpr (current_dim == n_dims) { + func(offset); + } else { + for (int32_t i = -radius; i <= radius; i++) { + offset[current_dim] = i; + NDLoopHelper::for_each_offset(radius, offset, std::forward(func)); + } + } + } +}; diff --git a/src/terrainlib/spatial_lookup/SpatialLookup.h b/src/terrainlib/spatial_lookup/SpatialLookup.h new file mode 100644 index 0000000..49c6c5f --- /dev/null +++ b/src/terrainlib/spatial_lookup/SpatialLookup.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#include + +namespace spatial_lookup { + +template +class SpatialLookup { +public: + using Vec = glm::vec; + using ForAllNear = std::function; + using ForAllNearConst = std::function; + + virtual void clear() = 0; + virtual void insert(const Vec &point, const Value value) = 0; + + virtual std::optional> find_nearest(const Vec &point, const Component epsilon) = 0; + virtual std::optional> find_nearest(const Vec &point, const Component epsilon) const = 0; + + virtual bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) = 0; + virtual bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const = 0; + + virtual void for_all_near(const Vec &point, const Component epsilon, ForAllNear func) = 0; + virtual void for_all_near(const Vec &point, const Component epsilon, ForAllNearConst func) const = 0; +}; + +} // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/SpatialLookupExt.h b/src/terrainlib/spatial_lookup/SpatialLookupExt.h new file mode 100644 index 0000000..5271933 --- /dev/null +++ b/src/terrainlib/spatial_lookup/SpatialLookupExt.h @@ -0,0 +1,101 @@ +#pragma once + +#include + +#include +#include + +namespace spatial_lookup { + +template +concept SpatialLookupExt = requires( + T t, + const T ct, + const Vec &point, + Value &value_ref, + Value value, + Distance epsilon) { + { t.clear() } -> std::same_as; + { t.insert(point, value) } -> std::same_as; + + { t.find_nearest(point, epsilon) } -> std::same_as>>; + { ct.find_nearest(point, epsilon) } -> std::same_as>>; + + requires requires(std::vector &out) { + { out.emplace_back(value) }; + + { t.find_all_near(point, epsilon, out) } -> std::same_as; + { ct.find_all_near(point, epsilon, out) } -> std::same_as; + }; + + { + t.for_all_near(point, epsilon, [](const Vec &, Value &, decltype(epsilon)){}) + } -> std::same_as; + { + ct.for_all_near(point, epsilon, [](const Vec &, const Value &, decltype(epsilon)) {}) + } -> std::same_as; +}; + +namespace helpers { + +// Calculate distance^2, works with all types +template +auto distance_sq(const glm::vec &a, const glm::vec &b) { + using T = MoreExact; + using Vec = glm::vec; + + if constexpr (std::is_floating_point_v) { + return glm::distance2(Vec(a), Vec(b)); + } else { + const auto diff = a - b; + const auto diff_sq = diff * diff; + return glm::compAdd(diff_sq); + } +} + +template < + typename SpatialLookup, + typename Vec, + typename Distance, + typename Value> +std::optional> find_nearest( + SpatialLookup &lookup, + const Vec &point, + const Distance epsilon) { + assert(epsilon > 0); + Distance closest_distance2 = std::numeric_limits::max(); + Value* closest_value = nullptr; + + lookup.for_all_near(point, epsilon, [&](const Vec&, Value& value, Distance dist2) { + if (dist2 < closest_distance2) { + closest_distance2 = dist2; + closest_value = &value; + } + }); + + if (closest_value) { + return std::ref(*closest_value); + } + return std::nullopt; +} + +template < + typename SpatialLookup, + typename Vec, + typename Distance, + typename Vector, + typename Value> +bool find_all_near( + SpatialLookup &lookup, + const Vec &point, + const Distance epsilon, + Vector &out) { + out.clear(); + lookup.for_all_near(point, epsilon, [&](const Vec&, Value& value, Distance) { + out.emplace_back(value); + }); + return !out.empty(); +} +} + +} diff --git a/src/terrainlib/type_utils.h b/src/terrainlib/type_utils.h index fd93311..1782ea5 100644 --- a/src/terrainlib/type_utils.h +++ b/src/terrainlib/type_utils.h @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include // modified from https://stackoverflow.com/questions/1055452/c-get-name-of-type-in-template/59522794#59522794 namespace { @@ -44,4 +46,30 @@ template template [[nodiscard]] constexpr const char *type_name_c() { return type_name_storage.data(); -} \ No newline at end of file +} + +template +std::string type_name(const T &obj) { + int status; + std::unique_ptr res{ + abi::__cxa_demangle(typeid(obj).name(), nullptr, nullptr, &status), + std::free}; + return (status == 0) ? res.get() : typeid(obj).name(); +} + +// Generic helper to determine the "more exact" type, preferring floating point types +template +struct MoreExactType { +private: + static constexpr bool t1_is_fp = std::is_floating_point_v; + static constexpr bool t2_is_fp = std::is_floating_point_v; + +public: + using type = std::conditional_t< + (t1_is_fp && !t2_is_fp), T1, + std::conditional_t<(t2_is_fp && !t1_is_fp), T2, + std::conditional_t<(sizeof(T1) >= sizeof(T2)), T1, T2>>>; +}; + +template +using MoreExact = typename MoreExactType::type; \ No newline at end of file From f7785b13fb258edabccb997a91cb5166bfa4a3d7 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 7 Aug 2025 15:33:29 +0200 Subject: [PATCH 098/122] Rewrite mesh merging --- src/CMakeLists.txt | 12 +- src/terrainlib/MoreExact.h | 20 + src/terrainlib/UnionFind.h | 58 ++ src/terrainlib/mesh/PointWithMeta.h | 15 + src/terrainlib/mesh/clip.cpp | 240 +++++-- src/terrainlib/mesh/clip.h | 9 +- src/terrainlib/mesh/merge.cpp | 635 +----------------- src/terrainlib/mesh/merge.h | 184 +---- .../mesh/merging/EpsilonVertexDeduplicate.h | 36 + .../mesh/merging/VertexDeduplicate.h | 34 + src/terrainlib/mesh/merging/VertexMapping.h | 176 +++++ src/terrainlib/mesh/merging/mapping.cpp | 335 +++++++++ src/terrainlib/mesh/merging/mapping.h | 23 + src/terrainlib/mesh/utils.cpp | 46 +- src/terrainlib/mesh/utils.h | 3 + src/terrainlib/spatial_lookup/CellBased.h | 189 ++++++ .../spatial_lookup/CellBasedStorage.h | 40 ++ src/terrainlib/spatial_lookup/Grid.h | 223 +----- src/terrainlib/spatial_lookup/GridStorage.h | 161 +++++ src/terrainlib/spatial_lookup/Hashmap.h | 221 +----- .../spatial_lookup/HashmapStorage.h | 136 ++++ src/terrainlib/spatial_lookup/NDLoopHelper.h | 16 +- src/terrainlib/spatial_lookup/SpatialLookup.h | 37 +- .../spatial_lookup/SpatialLookupExt.h | 101 --- src/terrainlib/type_utils.h | 17 - unittests/CMakeLists.txt | 4 +- unittests/terrainlib/mesh_clip.cpp | 2 + .../merge.cpp => terrainlib/mesh_merge.cpp} | 20 +- unittests/terrainlib/mesh_merge_mapping.cpp | 142 ++++ unittests/terrainlib/spatial_lookup.cpp | 119 ++++ 30 files changed, 1814 insertions(+), 1440 deletions(-) create mode 100644 src/terrainlib/MoreExact.h create mode 100644 src/terrainlib/UnionFind.h create mode 100644 src/terrainlib/mesh/PointWithMeta.h create mode 100644 src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h create mode 100644 src/terrainlib/mesh/merging/VertexDeduplicate.h create mode 100644 src/terrainlib/mesh/merging/VertexMapping.h create mode 100644 src/terrainlib/mesh/merging/mapping.cpp create mode 100644 src/terrainlib/mesh/merging/mapping.h create mode 100644 src/terrainlib/spatial_lookup/CellBased.h create mode 100644 src/terrainlib/spatial_lookup/CellBasedStorage.h create mode 100644 src/terrainlib/spatial_lookup/GridStorage.h create mode 100644 src/terrainlib/spatial_lookup/HashmapStorage.h delete mode 100644 src/terrainlib/spatial_lookup/SpatialLookupExt.h rename unittests/{terrainsimplify/merge.cpp => terrainlib/mesh_merge.cpp} (91%) create mode 100644 unittests/terrainlib/mesh_merge_mapping.cpp create mode 100644 unittests/terrainlib/spatial_lookup.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4ec9a20..106d675 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -127,8 +127,10 @@ add_library(terrainlib terrainlib/mesh/convert.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp terrainlib/mesh/merge.h terrainlib/mesh/merge.cpp - terrainlib/mesh/merge/Deduplicate.h - terrainlib/mesh/merge/VertexMapping.h + terrainlib/mesh/merging/VertexDeduplicate.h + terrainlib/mesh/merging/EpsilonVertexDeduplicate.h + terrainlib/mesh/merging/VertexMapping.h + terrainlib/mesh/merging/mapping.h terrainlib/mesh/merging/mapping.cpp terrainlib/mesh/SimpleMesh.h terrainlib/mesh/TriangleSoup.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp @@ -157,10 +159,14 @@ add_library(terrainlib terrainlib/octree/traverse.h terrainlib/octree/utils.h + terrainlib/spatial_lookup/CellBased.h + terrainlib/spatial_lookup/CellBasedStorage.h terrainlib/spatial_lookup/Grid.h + terrainlib/spatial_lookup/GridStorage.h + terrainlib/spatial_lookup/Hashmap.h + terrainlib/spatial_lookup/HashmapStorage.h terrainlib/spatial_lookup/NDLoopHelper.h terrainlib/spatial_lookup/SpatialLookup.h - terrainlib/spatial_lookup/Hashmap.h terrainlib/Dataset.h terrainlib/Dataset.cpp terrainlib/hash_utils.h diff --git a/src/terrainlib/MoreExact.h b/src/terrainlib/MoreExact.h new file mode 100644 index 0000000..881878e --- /dev/null +++ b/src/terrainlib/MoreExact.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +// Generic helper to determine the "more exact" type, preferring floating point types +template +struct MoreExactType { +private: + static constexpr bool t1_is_fp = std::is_floating_point_v; + static constexpr bool t2_is_fp = std::is_floating_point_v; + +public: + using type = std::conditional_t< + (t1_is_fp && !t2_is_fp), T1, + std::conditional_t<(t2_is_fp && !t1_is_fp), T2, + std::conditional_t<(sizeof(T1) >= sizeof(T2)), T1, T2>>>; +}; + +template +using MoreExact = typename MoreExactType::type; \ No newline at end of file diff --git a/src/terrainlib/UnionFind.h b/src/terrainlib/UnionFind.h new file mode 100644 index 0000000..327eb8c --- /dev/null +++ b/src/terrainlib/UnionFind.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +class UnionFind { +public: + using Index = size_t; + + explicit UnionFind(const size_t size) + : _parents(size), _sizes(size, 1) { + std::iota(this->_parents.begin(), this->_parents.end(), 0); + } + + [[nodiscard]] Index find(const Index x) { + Index &x_parent = this->_parents[x]; + if (x_parent != x) { + const Index x_rep = this->find(x_parent); + x_parent = x_rep; + } + return x_parent /* this is x_rep */; + } + + void make_union(const Index x, const Index y) { + const Index x_rep = this->find(x); + const Index y_rep = this->find(y); + + if (x_rep == y_rep) { + return; + } + + const Index x_size = this->_sizes[x_rep]; + const Index y_size = this->_sizes[y_rep]; + if (x_size < y_size) { + this->_parents[x_rep] = y_rep; + this->_sizes[y_rep] += this->_sizes[x_rep]; + } else { + this->_parents[y_rep] = x_rep; + this->_sizes[x_rep] += this->_sizes[y_rep]; + } + } + + [[nodiscard]] Index size() { + return this->_parents.size(); + } + + [[nodiscard]] bool is_joint() { + return std::find(this->_sizes.begin(), this->_sizes.end(), this->size()) != this->_sizes.end(); + } + + [[nodiscard]] bool is_disjoint() { + return !this->is_joint(); + } + +private: + std::vector _parents; + std::vector _sizes; +}; diff --git a/src/terrainlib/mesh/PointWithMeta.h b/src/terrainlib/mesh/PointWithMeta.h new file mode 100644 index 0000000..474a689 --- /dev/null +++ b/src/terrainlib/mesh/PointWithMeta.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +template +struct PointWithMeta { + using Vec = glm::vec; + + Vec point; + Meta meta; + + operator const Vec &() const { + return this->point; + } +}; diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index 01d2690..b5ddf9a 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -15,8 +16,8 @@ #include "mesh/utils.h" #include "mesh/cgal.h" #include "mesh/convert.h" -#include "mesh/validate.h" - +#include "mesh/validate.h" + namespace { double significant_above_epsilon(double x, double epsilon) { const double residual = std::fmod(x, epsilon); @@ -83,11 +84,12 @@ Intersection compute_intersection(const radix::geometry::Edge<3, T> &line, co } // namespace -SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { + +Cow mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds) { mesh::validate(mesh); if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { - return {}; + return Cow(SimpleMesh::empty()); } if (mesh.has_uvs() && mesh.uvs.size() != mesh.vertex_count()) { @@ -401,12 +403,96 @@ SimpleMesh mesh::clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::A } } - const SimpleMesh clipped_mesh(new_triangles, new_positions, new_uvs, mesh.texture); + SimpleMesh clipped_mesh(new_triangles, new_positions, new_uvs, mesh.texture); mesh::validate(clipped_mesh); - return clipped_mesh; + return Cow(std::move(clipped_mesh)); +} + +namespace { +template +struct HasIntersectionsVisitor : public CGAL::Polygon_mesh_processing::Corefinement::Default_visitor { + using HalfedgeDescriptor = typename boost::graph_traits::halfedge_descriptor; + + bool has_intersections = false; + + // called when a new intersection point is detected. + // The intersection is detected using a face of tm_f and an edge of tm_e. + void intersection_point_detected( + size_t /*i_id*/, int /*sdim*/, + HalfedgeDescriptor /*h_e*/, HalfedgeDescriptor /*h_f*/, + const TriangleMesh& /*tm_e*/, const TriangleMesh& /*tm_f*/, bool /*is_target_coplanar*/, bool /*is_source_coplanar*/) { + this->has_intersections = true; + } +}; +} + +Cow mesh::clip_on_bounds_and_cap(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds, const bool remesh_planar_patches) { + ASSERT(!mesh.has_uvs()); + cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); + + const CGAL::Iso_cuboid_3 cgal_bounds( + convert::to_cgal_point(bounds.min), + convert::to_cgal_point(bounds.max)); + HasIntersectionsVisitor visitor; + const auto clip_params = CGAL::Polygon_mesh_processing::parameters::clip_volume(true) + .visitor(visitor); + cgal::SurfaceMesh result_cgal_mesh; + const bool success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_bounds, clip_params); + if (!success) { + throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); + } + if (!visitor.has_intersections) { + return Cow(mesh); + } + + cgal_mesh.collect_garbage(); + + if (!remesh_planar_patches) { + return Cow(convert::to_simple_mesh(cgal_mesh)); + } + + cgal::SurfaceMesh remeshed_cgal_mesh; + const auto remesh_params = CGAL::Polygon_mesh_processing::parameters::cosine_of_maximum_angle(0.999); + CGAL::Polygon_mesh_processing::remesh_planar_patches(cgal_mesh, remeshed_cgal_mesh, remesh_params); + remeshed_cgal_mesh.collect_garbage(); + return Cow(convert::to_simple_mesh(remeshed_cgal_mesh)); } namespace { +template +glm::vec compute_barycentric( + const glm::vec &point, + const glm::vec &a, + const glm::vec &b, + const glm::vec &c +) { + using Vec = glm::vec; + + Vec v0 = b - a; + Vec v1 = c - a; + Vec v2 = point - a; + + T d00 = glm::dot(v0, v0); + T d01 = glm::dot(v0, v1); + T d11 = glm::dot(v1, v1); + T d20 = glm::dot(v2, v0); + T d21 = glm::dot(v2, v1); + + T denom = d00 * d11 - d01 * d01; + ASSERT(denom != 0); + T inv_denom = 1 / denom; + + T v = (d11 * d20 - d01 * d21) * inv_denom; + T w = (d00 * d21 - d01 * d20) * inv_denom; + T u = 1 - v - w; + + return Vec(u, v, w); +} +template +glm::vec compute_barycentric(const glm::vec &point, const std::array, 3>& triangle) { + return compute_barycentric(point, triangle[0], triangle[1], triangle[2]); +} + template struct UvInterpolatorVisitor : public CGAL::Polygon_mesh_processing::Corefinement::Default_visitor { using HalfedgeDescriptor = typename boost::graph_traits::halfedge_descriptor; @@ -414,103 +500,127 @@ struct UvInterpolatorVisitor : public CGAL::Polygon_mesh_processing::Corefinemen using VertexIndex = typename TriangleMesh::Vertex_index; UvMap& uv_map; - - UvInterpolatorVisitor(UvMap& uv_map) : uv_map(uv_map) {} + TriangleMesh &mesh; - std::vector> intersection_uvs; + struct Vertex { + glm::dvec3 position; + glm::dvec2 uv; + }; - /* - VertexDescriptor edge_split_source; - VertexDescriptor edge_split_target; + UvInterpolatorVisitor(UvMap& uv_map, TriangleMesh& mesh) : uv_map(uv_map), mesh(mesh) {} - // called before the edge of h in tm is split. - // Each subsequent call to edge_split() until the call to after_edge_split() will correspond to the split of that edge. - // If edge_split(h_i, tm) is called for i=1 to n, h_1, h_2, ... ,h_n, h is the sequence of halfedges representing the edge split (with the same initial orientation). - // There is only one call per edge. - void before_edge_split(HalfedgeDescriptor h, const TriangleMesh &tm) { - edge_split_source = tm.source(h); - edge_split_target = tm.target(h); - } + struct EdgeIntersection { + Vertex source; + Vertex target; + }; - // called when a new split is done. The target of hnew is a new split vertex. There is only one call per edge. - void edge_split(HalfedgeDescriptor hnew, const TriangleMesh &tm) { - // Calculate t value for the split vertex - const auto old_source_position = tm.point(edge_split_source); - const auto old_target_position = tm.point(edge_split_target); - const auto new_position = tm.point(hnew); - const auto t = glm::distance(new_position, old_source_position) / glm::distance(old_target_position, old_source_position); - - // Interpolate UVs for the split vertex based on the original vertices - const auto old_source_uv = uv_map[edge_split_source]; - const auto old_target_uv = uv_map[edge_split_target]; - const auto new_uv = glm::mix(old_source_uv, old_target_uv, t); - uv_map[tm.target(hnew)] = new_uv; - }*/ + struct FaceIntersection { + std::array vertices; + }; + std::vector> intersections; // called when a new intersection point is detected. // The intersection is detected using a face of tm_f and an edge of tm_e. void intersection_point_detected( - size_t i_id, int sdim, + size_t i_id, int /*sdim*/, HalfedgeDescriptor h_e, HalfedgeDescriptor h_f, - const TriangleMesh& tm_e, const TriangleMesh& tm_f, bool is_target_coplanar, bool is_source_coplanar) { - DEBUG_ASSERT(i_id == intersection_uvs.size()); - if (tm_e.template property_map("v:uv").has_value()) { + const TriangleMesh& tm_e, const TriangleMesh& tm_f, bool /*is_target_coplanar*/, bool /*is_source_coplanar*/) { + DEBUG_ASSERT(i_id == intersections.size()); + if (&mesh == &tm_e) { // The edge belongs to the mesh being clipped - intersection_uvs.emplace_back(true, h_e); + const auto source_vertex = mesh.source(h_e); + const auto target_vertex = mesh.target(h_e); + const auto source_position = convert::to_glm_point(mesh.point(source_vertex)); + const auto target_position = convert::to_glm_point(mesh.point(target_vertex)); + const auto source_uv = uv_map[source_vertex]; + const auto target_uv = uv_map[target_vertex]; + intersections.emplace_back(EdgeIntersection { + Vertex(source_position, source_uv), + Vertex(target_position, target_uv) + }); } else { - // The edge belongs to the mesh that is clipping - intersection_uvs.emplace_back(false, h_f); + DEBUG_ASSERT(&mesh == &tm_f); + // The face belongs to the mesh that is being clipping + std::array triangle; + unsigned int i = 0; + for (const cgal::VertexIndex vertex_index : CGAL::vertices_around_face(h_f, tm_f)) { + ASSERT(i < triangle.size()); + const auto position = convert::to_glm_point(mesh.point(vertex_index)); + const auto uv = uv_map[vertex_index]; + triangle[i] = Vertex(position, uv); + i++; + } + + intersections.emplace_back(FaceIntersection { + triangle + }); } } void new_vertex_added(size_t i_id, VertexDescriptor vh, const TriangleMesh& tm) { - const auto [is_edge, halfedge] = intersection_uvs[i_id]; - if (is_edge) { - // The vertex was created from an edge being split - const auto source_vertex = tm.source(halfedge); - const auto target_vertex = tm.target(halfedge); - // Calculate t value for the split vertex - const auto old_source_position = convert::to_glm_point(tm.point(source_vertex)); - const auto old_target_position = convert::to_glm_point(tm.point(target_vertex)); - const auto new_position = convert::to_glm_point(tm.point(vh)); - const auto t = glm::distance(new_position, old_source_position) / glm::distance(old_target_position, old_source_position); - // Interpolate UVs for the split vertex based on the original vertices - const auto old_source_uv = uv_map[source_vertex]; - const auto old_target_uv = uv_map[target_vertex]; - const auto new_uv = glm::mix(old_source_uv, old_target_uv, t); - uv_map[vh] = new_uv; - } else { - // The vertex was created inside a face - // TODO: + DEBUG_ASSERT(i_id < intersections.size()); + if (&tm != &mesh) { + return; } + + const glm::dvec3 new_position = convert::to_glm_point(mesh.point(vh)); + const glm::dvec2 new_uv = std::visit([&](const auto& intersection) { + using Intersection = std::decay_t; + if constexpr (std::is_same_v) { + const double edge_length = glm::distance(intersection.source.position, intersection.target.position); + const double t = glm::distance(new_position, intersection.source.position) / edge_length; + return glm::mix(intersection.source.uv, intersection.target.uv, t); + } else { + const glm::dvec3 barycentric = compute_barycentric( + new_position, + intersection.vertices[0].position, + intersection.vertices[1].position, + intersection.vertices[2].position + ); + // return glm::dvec2(1, 1); + return barycentric[0] * intersection.vertices[0].uv + + barycentric[1] * intersection.vertices[1].uv + + barycentric[2] * intersection.vertices[2].uv; + } + }, intersections[i_id]); + uv_map[vh] = new_uv; } }; -} +} // namespace -SimpleMesh mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh) { +Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh) { using UvMap = cgal::SurfaceMesh::Property_map; cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); cgal::SurfaceMesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); bool success; + bool is_same_as_input; if (mesh.has_uvs()) { UvMap uv_map = cgal_mesh.property_map("v:uv").value(); - const auto params = CGAL::Polygon_mesh_processing::parameters::visitor( - UvInterpolatorVisitor(uv_map)); + UvInterpolatorVisitor visitor(uv_map, cgal_mesh); + const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); + is_same_as_input = visitor.intersections.empty(); } else { - success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh); + HasIntersectionsVisitor visitor; + const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); + success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); + is_same_as_input = visitor.has_intersections; } if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); } + if (is_same_as_input) { + return Cow(mesh); + } + cgal_mesh.collect_garbage(); SimpleMesh result = convert::to_simple_mesh(cgal_mesh); if (mesh.has_texture()) { result.texture = mesh.texture.value(); } - return result; + return Cow(std::move(result)); } diff --git a/src/terrainlib/mesh/clip.h b/src/terrainlib/mesh/clip.h index 65d64ab..852e74c 100644 --- a/src/terrainlib/mesh/clip.h +++ b/src/terrainlib/mesh/clip.h @@ -3,10 +3,15 @@ #include #include "mesh/SimpleMesh.h" +#include "Cow.h" namespace mesh { -SimpleMesh clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); -SimpleMesh clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh); +Cow clip_on_bounds(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds); +Cow clip_on_bounds_and_cap( + const SimpleMesh &mesh, + const radix::geometry::Aabb3d &bounds, + const bool remesh_planar_patches = true); +Cow clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh); } diff --git a/src/terrainlib/mesh/merge.cpp b/src/terrainlib/mesh/merge.cpp index cc995f7..4491d15 100644 --- a/src/terrainlib/mesh/merge.cpp +++ b/src/terrainlib/mesh/merge.cpp @@ -1,638 +1,45 @@ -#include - -#include - -#include "mesh/convert.h" -#include "log.h" #include "mesh/merge.h" -#include "mesh/utils.h" -#include "mesh/validate.h" - -using namespace mesh::merge; - -template -static T max_component(const glm::tvec3 &vector) { - return glm::max(glm::max(vector.x, vector.y), vector.z); -} - -template -static T min_component(const glm::tvec3 &vector) { - return glm::min(glm::min(vector.x, vector.y), vector.z); -} - -// TODO: rewrite using unordered_map? -template -class Grid3d { -public: - Grid3d(const glm::dvec3 origin, const glm::dvec3 size, const glm::uvec3 divisions) - : origin(origin), size(size), divisions(divisions) { - grid_data.resize(divisions.x * divisions.y * divisions.z); - } - - struct GridCellItem { - glm::dvec3 point; - T value; - }; - - struct GridCell { - std::vector items; - }; - - std::optional> find(const glm::dvec3 point, const double epsilon = 0.1f) { - DEBUG_ASSERT(epsilon > 0); - - if (!is_in_bounds(point)) { - return std::nullopt; - } - - const glm::uvec3 grid_index = this->calculate_grid_index(point); - const glm::dvec3 cell_size = this->cell_size(); - const double max_cell_size = max_component(cell_size); - int cell_radius = std::ceil(epsilon / max_cell_size); - if (cell_radius > 1) { - LOG_WARN("Grid lookup epsilon ({:g}) is high compared to cell size ({:g}, {:g}, {:g}) resulting in cell radius of {}", - epsilon, cell_size.x, cell_size.y, cell_size.z, cell_radius); - } - - const glm::dvec3 distance_from_contained_cell_center = point - cell_size * (glm::dvec3(grid_index) + glm::dvec3(0.5)); - if (glm::all(glm::lessThan(distance_from_contained_cell_center + epsilon, cell_size))) { // TODO: shouldnt this be cell_size / 2? - cell_radius = 0; - } - - std::optional> closest_value; - double closest_distance = std::numeric_limits::infinity(); - - for (int dx = -cell_radius; dx <= cell_radius; dx++) { - for (int dy = -cell_radius; dy <= cell_radius; dy++) { - for (int dz = -cell_radius; dz <= cell_radius; dz++) { - const glm::ivec3 _neighbor_index = glm::ivec3(grid_index) + glm::ivec3(dx, dy, dz); - if (!this->is_valid_grid_index(_neighbor_index)) { - continue; - } - - const glm::uvec3 neighbor_index(_neighbor_index); - const size_t cell_index = this->calculate_cell_index(neighbor_index); - GridCell &cell = this->grid_data[cell_index]; - - for (GridCellItem &item : cell.items) { - const double distance = glm::distance(point, item.point); - if (distance < epsilon && distance < closest_distance) { - closest_value = item.value; - closest_distance = distance; - } - } - } - } - } - - return closest_value; - } - - std::optional> find(const glm::dvec3 point, const double epsilon = 0.1f) const { - return const_cast>>( - const_cast(this)->find(point, epsilon)); - } - - void insert(const glm::dvec3 point, const T value) { - if (!is_in_bounds(point)) { - return; - } - - const size_t cell_index = this->calculate_cell_index(point); - - const GridCellItem item{ - .point = point, - .value = value}; - GridCell &cell = grid_data[cell_index]; - cell.items.push_back(item); - this->overall_point_count += 1; - - if (cell.items.size() >= 1000) { - LOG_WARN("Large number of points inside single grid cell: {} ({} overall)", cell.items.size(), this->overall_point_count); - } - } - - bool is_in_bounds(const glm::dvec3 point) const { - const glm::dvec3 max_bounds = origin + size; - return glm::all(glm::greaterThanEqual(point, origin)) && glm::all(glm::lessThanEqual(point, max_bounds)); - } - - glm::dvec3 cell_size() const { - return this->size / glm::dvec3(this->divisions); - } - - glm::uvec3 calculate_grid_index(const glm::dvec3 point) const { - return glm::uvec3((point - this->origin) / this->cell_size()); - } - - size_t calculate_cell_index(const glm::dvec3 point) const { - const glm::uvec3 grid_index = this->calculate_grid_index(point); - return this->calculate_cell_index(grid_index); - } - - size_t calculate_cell_index(const glm::uvec3 grid_index) const { - return grid_index.x + grid_index.y * divisions.x + grid_index.z * divisions.x * divisions.y; - } - - bool is_point_inside_cell(const glm::dvec3 &point, const glm::uvec3 &grid_index) const { - const glm::dvec3 cell_size = this->cell_size(); - const glm::dvec3 cell_min = this->origin + glm::dvec3(grid_index) * cell_size; - const glm::dvec3 cell_max = cell_min + cell_size; - - return glm::all(glm::greaterThanEqual(point, cell_min)) && glm::all(glm::lessThanEqual(point, cell_max)); - } - - bool is_valid_grid_index(const glm::ivec3 &grid_index) const { - return grid_index.x >= 0 && grid_index.y >= 0 && grid_index.z >= 0 && this->is_valid_grid_index(glm::uvec3(grid_index)); - } - bool is_valid_grid_index(const glm::uvec3 &grid_index) const { - return grid_index.x < divisions.x && grid_index.y < divisions.y && grid_index.z < divisions.z; - } - - const GridCell &cell(const glm::uvec3 &grid_index) const { - return this->cell(calculate_cell_index(grid_index)); - } - const GridCell &cell(const size_t cell_index) const { - return this->grid_data[cell_index]; - } - - const std::span cells() const { - return this->grid_data; - } - - const glm::dvec3 origin; - const glm::dvec3 size; - const glm::uvec3 divisions; - -private: - size_t overall_point_count; - std::vector grid_data; -}; - -static radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { - const glm::dvec3 bounds_padding = bounds.size() * percentage; - const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); - return padded_bounds; -} - -template -static Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { - const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); - - const double max_extends = max_component(padded_bounds.size()); - const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; - const glm::uvec3 grid_divisions = glm::max(glm::uvec3(2 * std::cbrt(vertex_count) * relative_extends), glm::uvec3(1)); - Grid3d grid(padded_bounds.min, padded_bounds.size(), grid_divisions); - - return grid; -} - -template -static Grid3d construct_grid_for_mesh(const SimpleMesh &mesh) { - const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); - const size_t vertex_count = mesh.vertex_count(); - return _construct_grid_for_meshes(bounds, vertex_count); -} - -template -static Grid3d construct_grid_for_meshes(const std::span meshes) { - const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); - const size_t maximal_merged_mesh_size = std::transform_reduce( - meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); - return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); -} - -static double estimate_min_vertex_separation_between_meshes_after_merge(const Grid3d &grid, const VertexMapping &mapping) { - double min_squared_distance = std::numeric_limits::infinity(); - for (const Grid3d::GridCell &cell : grid.cells()) { - for (auto first = cell.items.begin(); first != cell.items.end(); ++first) { - for (auto second = first + 1; second != cell.items.end(); ++second) { - const size_t mesh1 = first->value.mesh_index; - const size_t mesh2 = second->value.mesh_index; - - if (mesh1 == mesh2) { - continue; - } - - const glm::dvec3 &point1 = first->point; - const glm::dvec3 &point2 = second->point; - - const double squared_distance = glm::distance2(point1, point2); - min_squared_distance = std::min(min_squared_distance, squared_distance); - } - } - } - - return std::sqrt(min_squared_distance); -} - -static double estimate_min_vertex_separation_between_meshes_after_merge(const std::span meshes, const VertexMapping &mapping) { - Grid3d grid = construct_grid_for_meshes(meshes); - - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { - const glm::dvec3 &position = mesh.positions[vertex_index]; - grid.insert(position, VertexId {mesh_index, vertex_index}); - } - } - - double min_squared_distance = std::numeric_limits::infinity(); - for (const Grid3d::GridCell &cell : grid.cells()) { - for (auto first = cell.items.begin(); first != cell.items.end(); ++first) { - for (auto second = first + 1; second != cell.items.end(); ++second) { - const size_t mesh1 = first->value.mesh_index; - const size_t mesh2 = second->value.mesh_index; - - if (mesh1 == mesh2) { - // Both vertices from the same mesh - continue; - } - - const size_t mapped1 = mapping.map(first->value); - const size_t mapped2 = mapping.map(second->value); - if (mapped1 == mapped2) { - // Vertices were already merged - continue; - } - - const glm::dvec3 &point1 = first->point; - const glm::dvec3 &point2 = second->point; - const double squared_distance = glm::distance2(point1, point2); - min_squared_distance = std::min(min_squared_distance, squared_distance); - } - } - } - - return std::sqrt(min_squared_distance); -} - -static double estimate_min_edge_length(const SimpleMesh &mesh) { - std::vector triangles = mesh.triangles; - std::random_shuffle(triangles.begin(), triangles.end()); - - const size_t count = std::min(triangles.size(), std::max(1000, static_cast(triangles.size() * 0.01))); - double min_edge_length = std::numeric_limits::infinity(); - for (size_t i = 0; i < count; i++) { - const glm::uvec3 &triangle = triangles[i]; - - const size_t first_index_in_triangle = i % triangle.length(); - const size_t first_index = triangle[first_index_in_triangle]; - const size_t second_index = triangle[(first_index_in_triangle + 1) % triangle.length()]; - - const double distance2 = glm::distance2(mesh.positions[first_index], mesh.positions[second_index]); - min_edge_length = std::min(distance2, min_edge_length); - } - - return std::sqrt(min_edge_length); -} - -static double measure_min_edge_length(const SimpleMesh &mesh) { - const auto min = [](const auto a, const auto b) { return std::min(a, b); }; - - const double min_squared_edge_length = std::transform_reduce( - mesh.triangles.begin(), mesh.triangles.end(), - std::numeric_limits::infinity(), min, - [&](const glm::uvec3 &triangle) { - const std::array positions{ - mesh.positions[triangle[0]], - mesh.positions[triangle[1]], - mesh.positions[triangle[2]], - }; +#include "mesh/merging/mapping.h" +#include "mesh/merging/VertexMapping.h" - return std::transform_reduce( - positions.begin(), positions.end(), - std::numeric_limits::infinity(), min, - [&](const glm::dvec3 &v1) { - const size_t i = std::distance(positions.begin(), &v1); - const glm::dvec3 v2 = positions[(i + 1) % positions.size()]; - return glm::distance2(v1, v2); - }); - }); +namespace mesh { - return std::sqrt(min_squared_edge_length); -} - -class UnionFind { - using IndexType = size_t; - using SizeType = size_t; - - std::vector parents; - std::vector sizes; - -public: - UnionFind(const size_t size) { - this->parents.resize(size); - std::iota(this->parents.begin(), this->parents.end(), 0); - - this->sizes.resize(size, 1); - } - - size_t find(const IndexType x) { - IndexType &x_parent = this->parents[x]; - if (x_parent != x) { - const IndexType x_rep = find(x_parent); - x_parent = x_rep; - } - return x_parent /* this is x_rep */; - } - - void make_union(const IndexType x, const IndexType y) { - const IndexType x_rep = find(x); - const IndexType y_rep = find(y); - - if (x_rep == y_rep) { - return; - } - - const SizeType x_size = this->sizes[x_rep]; - const SizeType y_size = this->sizes[y_rep]; - if (x_size < y_size) { - this->parents[x_rep] = y_rep; - this->sizes[y_rep] += this->sizes[x_rep]; - } else { - this->parents[y_rep] = x_rep; - this->sizes[x_rep] += this->sizes[y_rep]; - } - } - - size_t size() { - return this->parents.size(); - } - - bool is_joint() { - return std::find(this->sizes.begin(), this->sizes.end(), this->size()) != this->sizes.end(); - } - - bool is_disjoint() { - return !this->is_joint(); - } -}; - -static bool are_all_meshes_merged(const VertexMapping &mapping) { - UnionFind union_find(mapping.mesh_count()); - - const size_t maximal_merged_mesh_index = mapping.find_max_merged_index(); - - std::unordered_set observed_sources; - observed_sources.reserve(mapping.mesh_count()); - for (size_t vertex_index = 0; vertex_index < maximal_merged_mesh_index; vertex_index++) { - observed_sources.clear(); - for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { - if (auto opt = mapping.map_inverse(mesh_index, vertex_index); opt.has_value()) { - observed_sources.insert(mesh_index); - if (observed_sources.size() > 1) { - for (size_t observed_source : observed_sources) { - if (observed_source == mesh_index) { - continue; - } - - union_find.make_union(observed_source, mesh_index); - } - } - } - } - } - - return union_find.is_joint(); -} - -VertexMapping mesh::merge::create_merge_mapping(const std::span meshes) { - LOG_DEBUG("Finding shared vertices between {} meshes (epsilon=auto)", meshes.size()); - - const double min_edge_length = std::transform_reduce( - meshes.begin(), - meshes.end(), - std::numeric_limits::infinity(), - [](const double a, const double b) { return std::min(a, b); }, - measure_min_edge_length); // XXX: use approximate_min_edge_length in Release? - if (min_edge_length == std::numeric_limits::infinity()) { - return {}; - } - DEBUG_ASSERT(min_edge_length > 0); - double distance_epsilon = min_edge_length / 1000; - LOG_TRACE("Starting with distance epsilon of {:g}", distance_epsilon); - - VertexMapping mapping; - bool success = false; - for (size_t i = 0; i < 10; i++) { - mapping = create_merge_mapping(meshes, distance_epsilon); - - if (are_all_meshes_merged(mapping)) { - LOG_TRACE("Found distance epsilon that connects all meshes"); - - const double min_vertex_separation_after_merge = estimate_min_vertex_separation_between_meshes_after_merge(meshes, mapping); - if (min_vertex_separation_after_merge > min_edge_length / 2) { - LOG_TRACE("Found vertices in merged mesh that are much closer than in the source meshes, suggesting an incomplete merge"); - continue; - } - - success = true; - break; - } - distance_epsilon *= 10; - LOG_TRACE("Increasing distance epsilon to {:g}", distance_epsilon); - } - - if (!success) { - LOG_TRACE("Failed to find appropriate distance epsilon"); - } - - return mapping; -} - -static bool are_all_bounds_connected(const std::span meshes) { - if (meshes.size() <= 1) { - return true; - } - - std::vector mesh_bounds; - mesh_bounds.reserve(meshes.size()); - std::transform(meshes.begin(), meshes.end(), - std::back_inserter(mesh_bounds), - [](const SimpleMesh &mesh) { return pad_bounds(calculate_bounds(mesh), 0.01); }); - for (size_t i = 0; i < mesh_bounds.size(); i++) { - bool intersect_any_other = false; - for (size_t j = 0; j < mesh_bounds.size(); j++) { - if (i == j) { - continue; - } - - if (radix::geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { - intersect_any_other = true; - break; - } - } - if (!intersect_any_other) { - LOG_WARN("Mesh at index {} is not close to any other mesh", i); - return false; - } - } - - return true; -} - -VertexMapping mesh::merge::create_merge_mapping(const std::span meshes, double distance_epsilon) { - if (meshes.empty()) { - return {}; - } - if (meshes.size() == 1) { - return VertexMapping::identity(meshes[0].vertex_count()); - } - - LOG_TRACE("Finding shared vertices between {} meshes (epsilon={:g})", meshes.size(), distance_epsilon); - - std::vector mesh_sizes; - mesh_sizes.reserve(meshes.size()); - std::transform(meshes.begin(), meshes.end(), - std::back_inserter(mesh_sizes), - [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); - const size_t maximal_merged_mesh_size = std::accumulate(mesh_sizes.begin(), mesh_sizes.end(), 0); - - VertexMapping mapping; - mapping.init(mesh_sizes); - - // Create a grid as a spatial acceleration structure, its size and granularity depends on the meshes. - // Note that this is not very performant if the meshes are actually disconnected. - Grid3d grid = construct_grid_for_meshes(meshes); - - size_t unique_vertices = 0; - bool has_warned = false; - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { - const glm::dvec3 &position = mesh.positions[vertex_index]; - const VertexId current_vertex{ - .mesh_index = mesh_index, - .vertex_index = vertex_index}; - - const std::optional> other_vertex = grid.find(position, distance_epsilon); - if (!has_warned && other_vertex.has_value() && other_vertex->get().mesh_index == current_vertex.mesh_index) { - LOG_WARN("Merge distance epsilon is large and would perform intra-mesh merges"); - has_warned = true; - } - if (other_vertex.has_value() && other_vertex->get().mesh_index != current_vertex.mesh_index) { - // duplicated - mapping.add_bidirectional(current_vertex, mapping.map(other_vertex.value())); - } else { - grid.insert(position, current_vertex); - mapping.add_bidirectional(current_vertex, unique_vertices); - - unique_vertices += 1; - } - } - } - - LOG_DEBUG("Identified {} shared and {} unique vertices", maximal_merged_mesh_size - unique_vertices, unique_vertices); - mapping.validate(); - - return mapping; -} - -SimpleMesh mesh::merge::apply_mapping(std::span meshes, const mesh::merge::VertexMapping &mapping) { - LOG_TRACE("Merging meshes based on mapping"); - if (meshes.empty()) { +/* +SimpleMesh merge(const std::span> meshes) { + switch (meshes.size()) { + case 0: return {}; + case 1: + return meshes[0]; + default: + const merging::VertexMapping mapping = merging::create_mapping(meshes); + return merging::apply_mapping(meshes, mapping); } - - SimpleMesh merged_mesh; - - size_t max_combined_vertex_count = 0; - size_t max_combined_face_count = 0; - for (const SimpleMesh &mesh : meshes) { - max_combined_vertex_count += mesh.vertex_count(); - max_combined_face_count += mesh.face_count(); - } - - const bool has_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { - return mesh.has_uvs(); - }); - - size_t max_vertex_index = 0; - merged_mesh.positions.resize(max_combined_vertex_count); - if (has_uvs) { - merged_mesh.uvs.resize(max_combined_vertex_count); - } - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { - const size_t mapped_index = mapping.map(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); - merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; - if (has_uvs) { - merged_mesh.uvs[mapped_index] = mesh.uvs[vertex_index]; - } - max_vertex_index = std::max(max_vertex_index, mapped_index); - } - } - DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); - merged_mesh.positions.resize(max_vertex_index + 1); - if (has_uvs) { - merged_mesh.uvs.resize(max_vertex_index + 1); - } - - merged_mesh.triangles.reserve(max_combined_face_count); - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - for (size_t triangle_index = 0; triangle_index < mesh.face_count(); triangle_index++) { - const glm::uvec3 &triangle = mesh.triangles[triangle_index]; - - glm::uvec3 new_triangle; - for (size_t k = 0; k < static_cast(triangle.length()); k++) { - new_triangle[k] = mapping.map(VertexId{.mesh_index = mesh_index, .vertex_index = triangle[k]}); - } - if (new_triangle[0] == new_triangle[1] || - new_triangle[1] == new_triangle[2] || - new_triangle[2] == new_triangle[0]) { - LOG_WARN("Skipping illegal triangle while merging"); - continue; - } - - merged_mesh.triangles.push_back(new_triangle); - } - } - - if (!are_all_meshes_merged(mapping)) { - LOG_WARN("Not all meshes were merged together"); - } - - mesh::validate(merged_mesh); - mesh::validate(convert::to_cgal_mesh(merged_mesh)); - - return merged_mesh; } + */ -SimpleMesh mesh::merge::merge_meshes(std::span meshes) { - VertexMapping mapping; - return mesh::merge::merge_meshes(meshes, mapping); -} - -SimpleMesh mesh::merge::merge_meshes(std::span meshes, mesh::merge::VertexMapping &mapping) { +SimpleMesh merge(const std::span> meshes, double distance_epsilon) { switch (meshes.size()) { case 0: return {}; case 1: - mapping = VertexMapping::identity(meshes[0].vertex_count()); return meshes[0]; default: - mapping = mesh::merge::create_merge_mapping(meshes); - return mesh::merge::apply_mapping(meshes, mapping); + const merging::VertexMapping mapping = merging::create_mapping(meshes, distance_epsilon); + return merging::apply_mapping(meshes, mapping); } } -SimpleMesh mesh::merge::merge_meshes(std::span meshes, double distance_epsilon) { - VertexMapping mapping; - return mesh::merge::merge_meshes(meshes, distance_epsilon, mapping); -} - -SimpleMesh mesh::merge::merge_meshes(std::span meshes, double distance_epsilon, mesh::merge::VertexMapping &mapping) { +SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate) { switch (meshes.size()) { case 0: return {}; case 1: - mapping = VertexMapping::identity(meshes[0].vertex_count()); return meshes[0]; default: - mapping = mesh::merge::create_merge_mapping(meshes, distance_epsilon); - return mesh::merge::apply_mapping(meshes, mapping); + const merging::VertexMapping mapping = merging::create_mapping(meshes, deduplicate); + return merging::apply_mapping(meshes, mapping); } } + +} // namespace mesh diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 4a17a94..2f66a9a 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -5,176 +5,30 @@ #include #include +#include "mesh/merging/VertexDeduplicate.h" +#include "mesh/merging/VertexMapping.h" #include "pch.h" -namespace mesh::merge { +namespace mesh { -struct VertexId { - size_t mesh_index; - size_t vertex_index; -}; +// SimpleMesh merge(const std::span> meshes); +SimpleMesh merge(const std::span> meshes, double distance_epsilon); +SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate); -struct TriangleInMesh { - size_t mesh_index; - glm::uvec3 triangle; -}; - -class VertexMapping { -public: - static VertexMapping identity(const size_t vertex_count) { - VertexMapping mapping; - mapping.init({&vertex_count, 1}); - for (size_t i = 0; i < vertex_count; i++) { - mapping.add_bidirectional(VertexId{.mesh_index = 0, .vertex_index = i}, i); - } - return mapping; - } - - void init(std::span vertex_counts) { - this->forward.resize(vertex_counts.size()); - for (size_t i = 0; i < vertex_counts.size(); i++) { - this->forward[i].resize(vertex_counts[i]); - } - - this->backward.resize(vertex_counts.size()); - for (size_t i = 0; i < vertex_counts.size(); i++) { - this->backward[i].reserve(vertex_counts[i]); - } - } - - void add_bidirectional(VertexId source, size_t mapped) { - this->add_forward(source, mapped); - this->add_backward(source, mapped); - } - - void add_forward(VertexId source, size_t mapped) { - this->forward[source.mesh_index][source.vertex_index] = mapped; - } - - void add_backward(VertexId source, size_t mapped) { - this->backward[source.mesh_index][mapped] = source.vertex_index; - } - - size_t map(VertexId source) const { - return this->forward.at(source.mesh_index).at(source.vertex_index); - } - - std::optional map_inverse(size_t mesh_index, size_t mapped_index) const { - const auto it = this->backward.at(mesh_index).find(mapped_index); - if (it != this->backward.at(mesh_index).end()) { - return it->second; - } - return std::nullopt; - } - - std::vector map_inverse_exists(size_t mapped_index) const { - std::vector exists; - exists.reserve(this->mesh_count()); - for (size_t mesh_index = 0; mesh_index < this->mesh_count(); mesh_index++) { - if (this->map_inverse(mapped_index, mesh_index)) { - exists.push_back(mesh_index); - } - } - return exists; - } - - TriangleInMesh find_source_triangle(glm::uvec3 mapped_triangle) const { - for (size_t mesh_index = 0; mesh_index < this->mesh_count(); mesh_index++) { - const std::optional source_triangle_opt = this->find_source_triangle_in_mesh(mapped_triangle, mesh_index); - if (source_triangle_opt.has_value()) { - const glm::uvec3 source_triangle = source_triangle_opt.value(); - return TriangleInMesh { .mesh_index=mesh_index, .triangle=source_triangle }; - } - } - - throw std::runtime_error("illegal state in vertex mapping"); - } - - std::optional find_source_triangle_in_mesh(glm::uvec3 mapped_triangle, size_t mesh_index) const { - glm::uvec3 source_triangle; - - for (size_t i = 0; i < static_cast(mapped_triangle.length()); i++) { - const size_t mapped_vertex_index = mapped_triangle[i]; - const std::optional source_vertex = this->map_inverse(mesh_index, mapped_vertex_index); - if (source_vertex.has_value()) { - source_triangle[i] = source_vertex.value(); - } else { - return std::nullopt; - } - - DEBUG_ASSERT(this->map(VertexId { .mesh_index = mesh_index, .vertex_index = source_vertex.value() }) == mapped_vertex_index); - } - - return source_triangle; - } - - size_t mesh_count() const { - return this->backward.size(); - } - - size_t find_max_merged_index() const { - size_t max_index = 0; - for (size_t i = 0; i < this->mesh_count(); i++) { - if (this->forward[i].empty()) { - continue; - } - max_index = std::max(max_index, *std::max_element(this->forward[i].begin(), this->forward[i].end())); - } - return max_index; - } - - size_t mesh_vertex_count(const size_t mesh_index) const { - return this->forward[mesh_index].size(); - } - - void validate() const { -#ifndef NDEBUG - for (size_t i = 0; i < this->mesh_count(); i++) { - DEBUG_ASSERT(this->forward[i].size() == this->backward[i].size()); - - for (size_t j = 0; j < this->forward[i].size(); j++) { - const size_t mapped = this->map(VertexId { .mesh_index = i, .vertex_index = j }); - const std::optional inv_mapped = this->map_inverse(i, mapped); - DEBUG_ASSERT(inv_mapped.has_value()); - DEBUG_ASSERT(inv_mapped.value() == j); - } - - for (const std::pair e : this->backward[i]) { - const std::optional inv_mapped = this->map_inverse(i, e.first); - DEBUG_ASSERT(inv_mapped.has_value()); - const size_t mapped = this->map(VertexId{.mesh_index = i, .vertex_index = inv_mapped.value()}); - DEBUG_ASSERT(mapped == e.first); - } - } -#endif - } - - private: - std::vector> forward; - std::vector> backward; -}; - -// TODO: fix namespace and naming -// TODO: accept refs -SimpleMesh merge_meshes(std::span meshes); -SimpleMesh merge_meshes(std::span meshes, VertexMapping &mapping); -SimpleMesh merge_meshes(std::span meshes, double distance_epsilon); -SimpleMesh merge_meshes(std::span meshes, double distance_epsilon, VertexMapping &mapping); - -SimpleMesh apply_mapping(std::span meshes, const VertexMapping &mapping); - -VertexMapping create_merge_mapping(std::span meshes); -VertexMapping create_merge_mapping(std::span meshes, double distance_epsilon); - -// TODO: -inline SimpleMesh merge_meshes(const SimpleMesh &mesh1, const SimpleMesh &mesh2) { - std::array meshes = {mesh1, mesh2}; - return merge_meshes(meshes); +template +SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, Args &&...args) { + const std::array, 2> meshes = {mesh1, mesh2}; + return merge(std::span>(meshes), std::forward(args)...); } -inline SimpleMesh merge_meshes(const SimpleMesh& mesh1, const SimpleMesh& mesh2, const SimpleMesh& mesh3) { - std::array meshes = {mesh1, mesh2, mesh3}; - return merge_meshes(meshes); +template +SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, const SimpleMesh &mesh3, Args &&...args) { + const std::array, 3> meshes = {mesh1, mesh2, mesh3}; + return merge(std::span>(meshes), std::forward(args)...); } - +template +SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, const SimpleMesh &mesh3, const SimpleMesh& mesh4, Args &&...args) { + const std::array, 4> meshes = {mesh1, mesh2, mesh3, mesh4}; + return merge(std::span>(meshes), std::forward(args)...); } +} diff --git a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h new file mode 100644 index 0000000..53cfc07 --- /dev/null +++ b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h @@ -0,0 +1,36 @@ +#pragma once + +#include "spatial_lookup/SpatialLookup.h" +#include "mesh/merging/VertexDeduplicate.h" + +namespace mesh::merging { + +template Lookup> +class EpsilonVertexDeduplicate : public VertexDeduplicate { +public: + using Vec = glm::vec; + + EpsilonVertexDeduplicate(Lookup &lookup, Component epsilon) + : _lookup(lookup), + _epsilon(epsilon) {} + + void add(const Vec &point, const Meta meta) override { + this->_lookup.insert(point, meta); + } + bool get(const Vec &point, std::vector> &duplicates) const override { + return this->_lookup.find_all_near(point, this->_epsilon, duplicates); + } + +private: + Lookup &_lookup; + Component _epsilon; +}; + +// This deduction guide is placed after your class definition +template class CellBased, + typename EpsilonType> +EpsilonVertexDeduplicate(CellBased &lookup, EpsilonType epsilon) + -> EpsilonVertexDeduplicate>; + +} diff --git a/src/terrainlib/mesh/merging/VertexDeduplicate.h b/src/terrainlib/mesh/merging/VertexDeduplicate.h new file mode 100644 index 0000000..749a2ef --- /dev/null +++ b/src/terrainlib/mesh/merging/VertexDeduplicate.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include + +namespace mesh::merging { + +template +class VertexDeduplicate { +public: + using Vec = glm::vec; + + virtual ~VertexDeduplicate() = default; + + virtual void add(const Vec& point, const Meta meta) = 0; + virtual bool get(const Vec& point, std::vector> &duplicates) const = 0; + virtual bool get_or_add(const Vec &point, const Meta meta, std::vector> &duplicates) { + if (this->get(point, duplicates)) { + return false; + } else { + this->add(point, meta); + return true; + } + } + std::vector> get(const Vec &point) const { + std::vector> duplicates; + this->get(point, duplicates); + return duplicates; + } +}; + +} diff --git a/src/terrainlib/mesh/merging/VertexMapping.h b/src/terrainlib/mesh/merging/VertexMapping.h new file mode 100644 index 0000000..a83da39 --- /dev/null +++ b/src/terrainlib/mesh/merging/VertexMapping.h @@ -0,0 +1,176 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace mesh::merging { + +// Identifies a specific vertex within a particular mesh. +struct VertexId { + size_t mesh_index; + size_t vertex_index; +}; + +// Represents a triangle from a specific mesh. +struct TriangleInMesh { + size_t mesh_index; + glm::uvec3 triangle; +}; + +// Manages mapping between the vertices of multiple original meshes and the corresponding vertices in a merged mesh. +class VertexMapping { +public: + // Creates a mapping where every vertex maps to itself (identity mapping) for a single mesh. + static VertexMapping identity(const size_t vertex_count) { + VertexMapping mapping; + mapping.init({&vertex_count, 1}); + for (size_t i = 0; i < vertex_count; i++) { + mapping.add_bidirectional(VertexId{.mesh_index = 0, .vertex_index = i}, i); + } + return mapping; + } + + // Initializes the mapping structures based on per-mesh vertex counts. + void init(std::span vertex_counts) { + this->forward.resize(vertex_counts.size()); + for (size_t i = 0; i < vertex_counts.size(); i++) { + this->forward[i].resize(vertex_counts[i]); + } + + this->backward.resize(vertex_counts.size()); + for (size_t i = 0; i < vertex_counts.size(); i++) { + this->backward[i].reserve(vertex_counts[i]); + } + } + + // Adds a forward and backward mapping between a source vertex and a merged index. + void add_bidirectional(VertexId source, size_t mapped) { + this->add_forward(source, mapped); + this->add_backward(source, mapped); + } + + void add_forward(VertexId source, size_t mapped) { + this->forward[source.mesh_index][source.vertex_index] = mapped; + } + + void add_backward(VertexId source, size_t mapped) { + this->backward[source.mesh_index][mapped] = source.vertex_index; + } + + // Returns the merged vertex index for a given source vertex. + size_t map_forward(VertexId source) const { + return this->forward.at(source.mesh_index).at(source.vertex_index); + } + + // Returns the original vertex index for a given merged index and mesh, if it exists. + std::optional map_backward(size_t mesh_index, size_t mapped_index) const { + const auto it = this->backward.at(mesh_index).find(mapped_index); + if (it != this->backward.at(mesh_index).end()) { + return it->second; + } + return std::nullopt; + } + + // Returns a list of meshes in which a given merged index exists. + std::vector find_source_meshes(size_t mapped_index) const { + std::vector exists; + exists.reserve(this->mesh_count()); + for (size_t mesh_index = 0; mesh_index < this->mesh_count(); mesh_index++) { + if (this->map_backward(mesh_index, mapped_index)) { + exists.push_back(mesh_index); + } + } + return exists; + } + + // Searches all meshes to find a triangle whose vertices map to the given merged triangle. + TriangleInMesh find_source_triangle(glm::uvec3 mapped_triangle) const { + for (size_t mesh_index = 0; mesh_index < this->mesh_count(); mesh_index++) { + const std::optional source_triangle_opt = this->find_source_triangle_in_mesh(mapped_triangle, mesh_index); + if (source_triangle_opt.has_value()) { + const glm::uvec3 source_triangle = source_triangle_opt.value(); + return TriangleInMesh { .mesh_index=mesh_index, .triangle=source_triangle }; + } + } + + throw std::runtime_error("illegal state in vertex mapping"); + } + + // Attempts to find the source triangle (in a specific mesh) corresponding to the given mapped triangle. + std::optional find_source_triangle_in_mesh(glm::uvec3 mapped_triangle, size_t mesh_index) const { + glm::uvec3 source_triangle; + + for (size_t i = 0; i < static_cast(mapped_triangle.length()); i++) { + const size_t mapped_vertex_index = mapped_triangle[i]; + const std::optional source_vertex = this->map_backward(mesh_index, mapped_vertex_index); + if (source_vertex.has_value()) { + source_triangle[i] = source_vertex.value(); + } else { + return std::nullopt; + } + + DEBUG_ASSERT(this->map_forward(VertexId { .mesh_index = mesh_index, .vertex_index = source_vertex.value() }) == mapped_vertex_index); + } + + return source_triangle; + } + + // Returns the number of meshes tracked by this mapping. + size_t mesh_count() const { + return this->backward.size(); + } + + // Finds the maximum vertex index in the merged mesh. + size_t find_max_merged_index() const { + size_t max_index = 0; + for (size_t i = 0; i < this->mesh_count(); i++) { + if (this->forward[i].empty()) { + continue; + } + max_index = std::max(max_index, *std::max_element(this->forward[i].begin(), this->forward[i].end())); + } + return max_index; + } + + // Returns the number of vertices in a specific source mesh. + size_t mesh_vertex_count(const size_t mesh_index) const { + return this->forward[mesh_index].size(); + } + + // Performs internal consistency checks in debug mode. + void validate() const { +#ifndef NDEBUG + for (size_t i = 0; i < this->mesh_count(); i++) { + DEBUG_ASSERT(this->forward[i].size() == this->backward[i].size()); + + for (size_t j = 0; j < this->forward[i].size(); j++) { + const size_t mapped = this->map_forward(VertexId { .mesh_index = i, .vertex_index = j }); + const std::optional inv_mapped = this->map_backward(i, mapped); + DEBUG_ASSERT(inv_mapped.has_value()); + DEBUG_ASSERT(inv_mapped.value() == j); + } + + for (const std::pair e : this->backward[i]) { + const std::optional inv_mapped = this->map_backward(i, e.first); + DEBUG_ASSERT(inv_mapped.has_value()); + const size_t mapped = this->map_forward(VertexId{.mesh_index = i, .vertex_index = inv_mapped.value()}); + DEBUG_ASSERT(mapped == e.first); + } + } +#endif + } + +private: + // TODO: backward mapping could be a single unordered_map + + // Forward mapping: [mesh_index][vertex_index] -> merged index. + std::vector> forward; + // Backward mapping: [mesh_index][merged index] -> original vertex index. + std::vector> backward; +}; + +} diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp new file mode 100644 index 0000000..fc81c2e --- /dev/null +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -0,0 +1,335 @@ +#include + +#include + +#include "UnionFind.h" +#include "log.h" +#include "mesh/convert.h" +#include "mesh/merging/EpsilonVertexDeduplicate.h" +#include "mesh/merging/mapping.h" +#include "mesh/utils.h" +#include "mesh/validate.h" +#include "spatial_lookup/Hashmap.h" +#include "type_utils.h" + +namespace mesh::merging { + +VertexMapping create_mapping(const std::span> meshes, double distance_epsilon) { + auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); + auto deduplicate = EpsilonVertexDeduplicate(map, distance_epsilon); + return create_mapping(meshes, deduplicate); +} + +VertexMapping create_mapping(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { + if (meshes.empty()) { + return {}; + } + if (meshes.size() == 1) { + return VertexMapping::identity(meshes[0].get().vertex_count()); + } + + LOG_TRACE("Finding shared vertices between {} meshes (deduplication using {})", meshes.size(), type_name(deduplicate)); + + std::vector mesh_sizes; + mesh_sizes.reserve(meshes.size()); + std::transform(meshes.begin(), meshes.end(), + std::back_inserter(mesh_sizes), + [](const auto &mesh) { return mesh.get().vertex_count(); }); + const size_t maximal_merged_mesh_size = std::accumulate(mesh_sizes.begin(), mesh_sizes.end(), 0); + + VertexMapping mapping; + mapping.init(mesh_sizes); + + size_t unique_vertices = 0; + bool has_warned = false; + std::vector> duplicate_vertices; + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + const glm::dvec3 &position = mesh.positions[vertex_index]; + const VertexId current_vertex{ + .mesh_index = mesh_index, + .vertex_index = vertex_index}; + + if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { + // Duplicates detected + for (const auto& other_vertex : duplicate_vertices) { + // Warn if we would perform intra mesh merges (but dont actually do them) + if (other_vertex.get().mesh_index == current_vertex.mesh_index) { + if (!has_warned) { + LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); + has_warned = true; + break; + } + } else { + mapping.add_bidirectional(current_vertex, mapping.map_forward(other_vertex.get())); + } + } + duplicate_vertices.clear(); + } else { + // New vertex / No duplicates + mapping.add_bidirectional(current_vertex, unique_vertices); + unique_vertices += 1; + } + } + } + + LOG_DEBUG("Identified {} shared and {} unique vertices", maximal_merged_mesh_size - unique_vertices, unique_vertices); + mapping.validate(); + + return mapping; +} + +/* +namespace { +radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { + const glm::dvec3 bounds_padding = bounds.size() * percentage; + const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + return padded_bounds; +} + +bool are_all_bounds_connected(std::span> meshes) { + if (meshes.size() <= 1) { + return true; + } + + std::vector mesh_bounds; + mesh_bounds.reserve(meshes.size()); + std::transform(meshes.begin(), meshes.end(), + std::back_inserter(mesh_bounds), + [](const SimpleMesh &mesh) { return pad_bounds(calculate_bounds(mesh), 0.01); }); + for (size_t i = 0; i < mesh_bounds.size(); i++) { + bool intersect_any_other = false; + for (size_t j = 0; j < mesh_bounds.size(); j++) { + if (i == j) { + continue; + } + + if (radix::geometry::intersect(mesh_bounds[i], mesh_bounds[j])) { + intersect_any_other = true; + break; + } + } + if (!intersect_any_other) { + LOG_WARN("Mesh at index {} is not close to any other mesh", i); + return false; + } + } + + return true; +} + +bool are_all_meshes_merged(const VertexMapping &mapping) { + UnionFind union_find(mapping.mesh_count()); + + const size_t maximal_merged_mesh_index = mapping.find_max_merged_index(); + + std::unordered_set observed_sources; + observed_sources.reserve(mapping.mesh_count()); + for (size_t vertex_index = 0; vertex_index < maximal_merged_mesh_index; vertex_index++) { + observed_sources.clear(); + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + if (auto opt = mapping.map_inverse(mesh_index, vertex_index); opt.has_value()) { + observed_sources.insert(mesh_index); + if (observed_sources.size() > 1) { + for (size_t observed_source : observed_sources) { + if (observed_source == mesh_index) { + continue; + } + + union_find.make_union(observed_source, mesh_index); + } + } + } + } + } + + return union_find.is_joint(); +} + +template Lookup> +double estimate_min_vertex_separation_between_meshes_after_merge(const Lookup &lookup, const VertexMapping &mapping) { + double min_squared_distance = std::numeric_limits::infinity(); + lookup.for_all_cells([&](const Vec& point, const Value& value) { + + }); + for (const Grid3d::GridCell &cell : grid.cells()) { + for (auto first = cell.items.begin(); first != cell.items.end(); ++first) { + for (auto second = first + 1; second != cell.items.end(); ++second) { + const size_t mesh1 = first->value.mesh_index; + const size_t mesh2 = second->value.mesh_index; + + if (mesh1 == mesh2) { + continue; + } + + const glm::dvec3 &point1 = first->point; + const glm::dvec3 &point2 = second->point; + + const double squared_distance = glm::distance2(point1, point2); + min_squared_distance = std::min(min_squared_distance, squared_distance); + } + } + } + + return std::sqrt(min_squared_distance); +} + +double estimate_min_vertex_separation_between_meshes_after_merge(const std::span meshes, const VertexMapping &mapping) { + Grid3d grid = construct_grid_for_meshes(meshes); + + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + const glm::dvec3 &position = mesh.positions[vertex_index]; + grid.insert(position, VertexId{mesh_index, vertex_index}); + } + } + + double min_squared_distance = std::numeric_limits::infinity(); + for (const Grid3d::GridCell &cell : grid.cells()) { + for (auto first = cell.items.begin(); first != cell.items.end(); ++first) { + for (auto second = first + 1; second != cell.items.end(); ++second) { + const size_t mesh1 = first->value.mesh_index; + const size_t mesh2 = second->value.mesh_index; + + if (mesh1 == mesh2) { + // Both vertices from the same mesh + continue; + } + + const size_t mapped1 = mapping.map(first->value); + const size_t mapped2 = mapping.map(second->value); + if (mapped1 == mapped2) { + // Vertices were already merged + continue; + } + + const glm::dvec3 &point1 = first->point; + const glm::dvec3 &point2 = second->point; + const double squared_distance = glm::distance2(point1, point2); + min_squared_distance = std::min(min_squared_distance, squared_distance); + } + } + } + + return std::sqrt(min_squared_distance); +} + +} // namespace + +VertexMapping create_connecting_mapping(std::span> meshes) { + LOG_DEBUG("Finding shared vertices between {} meshes (epsilon=auto)", meshes.size()); + + const double inf = std::numeric_limits::infinity(); + const double min_edge_length_sq = std::transform_reduce( + meshes.begin(), + meshes.end(), + inf, + [](const double a, const double b) { return std::min(a, b); }, + [](const SimpleMesh &m) { return calculate_min_edge_length_squared(m).value_or(inf); }); + if (min_edge_length_sq == inf) { + return {}; + } + const double min_edge_length = std::sqrt(min_edge_length_sq.value()); + DEBUG_ASSERT(min_edge_length > 0); + double distance_epsilon = min_edge_length / 1000; + LOG_TRACE("Starting with distance epsilon of {:g}", distance_epsilon); + + VertexMapping mapping; + bool success = false; + for (size_t i = 0; i < 10; i++) { + mapping = create_mapping(meshes, distance_epsilon); + + if (are_all_meshes_merged(mapping)) { + LOG_TRACE("Found distance epsilon that connects all meshes"); + + const double min_vertex_separation_after_merge = estimate_min_vertex_separation_between_meshes_after_merge(meshes, mapping); + if (min_vertex_separation_after_merge > min_edge_length / 2) { + LOG_TRACE("Found vertices in merged mesh that are much closer than in the source meshes, suggesting an incomplete merge"); + continue; + } + + success = true; + break; + } + distance_epsilon *= 10; + LOG_TRACE("Increasing distance epsilon to {:g}", distance_epsilon); + } + + if (!success) { + LOG_TRACE("Failed to find appropriate distance epsilon"); + } + + return mapping; +} + */ + +SimpleMesh apply_mapping(const std::span> meshes, const VertexMapping &mapping) { + LOG_TRACE("Merging meshes based on mapping"); + if (meshes.empty()) { + return {}; + } + + SimpleMesh merged_mesh; + + size_t max_combined_vertex_count = 0; + size_t max_combined_face_count = 0; + for (const SimpleMesh &mesh : meshes) { + max_combined_vertex_count += mesh.vertex_count(); + max_combined_face_count += mesh.face_count(); + } + + const bool has_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { + return mesh.has_uvs(); + }); + + size_t max_vertex_index = 0; + merged_mesh.positions.resize(max_combined_vertex_count); + if (has_uvs) { + merged_mesh.uvs.resize(max_combined_vertex_count); + } + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + const size_t mapped_index = mapping.map_forward(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); + merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; + if (has_uvs) { + merged_mesh.uvs[mapped_index] = mesh.uvs[vertex_index]; + } + max_vertex_index = std::max(max_vertex_index, mapped_index); + } + } + DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); + merged_mesh.positions.resize(max_vertex_index + 1); + if (has_uvs) { + merged_mesh.uvs.resize(max_vertex_index + 1); + } + + merged_mesh.triangles.reserve(max_combined_face_count); + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; + for (size_t triangle_index = 0; triangle_index < mesh.face_count(); triangle_index++) { + const glm::uvec3 &triangle = mesh.triangles[triangle_index]; + + glm::uvec3 new_triangle; + for (size_t k = 0; k < static_cast(triangle.length()); k++) { + new_triangle[k] = mapping.map_forward(VertexId{.mesh_index = mesh_index, .vertex_index = triangle[k]}); + } + if (new_triangle[0] == new_triangle[1] || + new_triangle[1] == new_triangle[2] || + new_triangle[2] == new_triangle[0]) { + LOG_WARN("Skipping illegal triangle while merging"); + continue; + } + + merged_mesh.triangles.push_back(new_triangle); + } + } + + mesh::validate(merged_mesh); + // mesh::validate(convert::to_cgal_mesh(merged_mesh)); + + return merged_mesh; +} +} diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h new file mode 100644 index 0000000..26f3a5c --- /dev/null +++ b/src/terrainlib/mesh/merging/mapping.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/merging/VertexDeduplicate.h" +#include "mesh/merging/VertexMapping.h" + +namespace mesh::merging { + +// VertexMapping create_connecting_mapping(std::span meshes); +VertexMapping create_mapping( + const std::span> meshes, + double distance_epsilon); +VertexMapping create_mapping( + std::span> meshes, + VertexDeduplicate<3, double, VertexId>& deduplicate); + +SimpleMesh apply_mapping( + const std::span> meshes, + const VertexMapping &mapping); + +} // namespace mesh::merging diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index 2d15aab..97a29df 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -62,7 +62,7 @@ std::optional estimate_average_edge_length(const SimpleMesh &mesh, const return total_length / triangle_sample_size; } -std::optional calculate_max_edge_length(const SimpleMesh &mesh) { +std::optional calculate_max_edge_length_squared(const SimpleMesh &mesh) { if (mesh.face_count() == 0) { return std::nullopt; } @@ -73,15 +73,53 @@ std::optional calculate_max_edge_length(const SimpleMesh &mesh) { const glm::dvec3 &b = mesh.positions[tri.y]; const glm::dvec3 &c = mesh.positions[tri.z]; - const double ab = glm::distance(a, b); - const double bc = glm::distance(b, c); - const double ca = glm::distance(c, a); + const double ab = glm::distance2(a, b); + const double bc = glm::distance2(b, c); + const double ca = glm::distance2(c, a); max_length = std::max({ab, bc, ca, max_length}); } return max_length; } +std::optional calculate_min_edge_length_squared(const SimpleMesh &mesh) { + if (mesh.face_count() == 0) { + return std::nullopt; + } + + double max_length = 0.0; + for (const auto &tri : mesh.triangles) { + const glm::dvec3 &a = mesh.positions[tri.x]; + const glm::dvec3 &b = mesh.positions[tri.y]; + const glm::dvec3 &c = mesh.positions[tri.z]; + + const double ab = glm::distance2(a, b); + const double bc = glm::distance2(b, c); + const double ca = glm::distance2(c, a); + + max_length = std::min({ab, bc, ca, max_length}); + } + return max_length; +} + +std::optional calculate_max_edge_length(const SimpleMesh &mesh) { + auto length_sq_opt = calculate_max_edge_length_squared(mesh); + if (length_sq_opt.has_value()) { + return std::sqrt(length_sq_opt.value()); + } else { + return std::nullopt; + } +} + +std::optional calculate_min_edge_length(const SimpleMesh &mesh) { + auto length_sq_opt = calculate_min_edge_length_squared(mesh); + if (length_sq_opt.has_value()) { + return std::sqrt(length_sq_opt.value()); + } else { + return std::nullopt; + } +} + size_t remove_isolated_vertices(SimpleMesh &mesh) { const bool has_uvs = mesh.has_uvs(); const std::vector isolated = find_isolated_vertices(mesh); diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index 15aa395..c08eba2 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -15,6 +15,9 @@ radix::geometry::Aabb3d calculate_bounds(std::span meshes); std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size = 1000); std::optional calculate_max_edge_length(const SimpleMesh &mesh); +std::optional calculate_min_edge_length(const SimpleMesh &mesh); +std::optional calculate_max_edge_length_squared(const SimpleMesh &mesh); +std::optional calculate_min_edge_length_squared(const SimpleMesh &mesh); template std::vector find_isolated_vertices(const SimpleMesh_ &mesh); diff --git a/src/terrainlib/spatial_lookup/CellBased.h b/src/terrainlib/spatial_lookup/CellBased.h new file mode 100644 index 0000000..dcb9a94 --- /dev/null +++ b/src/terrainlib/spatial_lookup/CellBased.h @@ -0,0 +1,189 @@ +#pragma once + +#include +#include +#include + +#include "MoreExact.h" +#include "log.h" +#include "spatial_lookup/CellBasedStorage.h" +#include "spatial_lookup/NDLoopHelper.h" +#include "spatial_lookup/SpatialLookup.h" +#include + +namespace spatial_lookup { + +namespace { +// Calculate distance^2, works with all types +template +auto distance_sq(const glm::vec &a, const glm::vec &b) { + using T = MoreExact; + using Vec = glm::vec; + + if constexpr (std::is_floating_point_v) { + return glm::distance2(Vec(a), Vec(b)); + } else { + const auto diff = a - b; + const auto diff_sq = diff * diff; + return glm::compAdd(diff_sq); + } +} + +template +std::optional> _find_nearest( + SpatialLookup &lookup, + const typename SpatialLookup::Vec &point, + const Distance epsilon) { + using Vec = SpatialLookup::Vec; + using Value = SpatialLookup::Value; + + Distance closest_distance2 = std::numeric_limits::max(); + Value *closest_value = nullptr; + + lookup.for_all_near(point, epsilon, [&](const Vec &, Value &value, Distance dist2) { + if (dist2 < closest_distance2) { + closest_distance2 = dist2; + closest_value = &value; + } + }); + + if (closest_value) { + return std::ref(*closest_value); + } + return std::nullopt; +} + +template +bool _find_all_near( + SpatialLookup &lookup, + const typename SpatialLookup::Vec &point, + const Distance epsilon, + Vector &out) { + using Vec = SpatialLookup::Vec; + using Value = SpatialLookup::Value; + + out.clear(); + lookup.for_all_near(point, epsilon, [&](const Vec &, Value &value, Distance) { + out.emplace_back(value); + }); + return !out.empty(); +} +} + +template Storage> +class CellBased { +public: + using Self = CellBased; + using Vec = glm::vec; + using Value = _Value; + using Bounds = radix::geometry::Aabb; + using CellIndex = typename Storage::CellIndex; + + template + explicit CellBased(Args &&...args) : _storage(std::forward(args)...) {} + + void clear() { + this->_storage.clear(); + } + + bool insert(const Vec& point, const Value value) { + const bool inserted = this->_storage.insert(point, value); + if (inserted) { + this->_bounds.expand_by(point); + } + return inserted; + } + + const Bounds &bounds() const { + return this->_bounds; + } + + template + bool for_all_near(const Vec &point, const _Distance _epsilon, const Func func) const { + using Distance = MoreExact<_Distance, Component>; + const Distance epsilon = _epsilon; + DEBUG_ASSERT(epsilon > 0); + + const Distance epsilon2 = epsilon * epsilon; + if (radix::geometry::distance_sq(this->_bounds, point) > epsilon2) { + return false; + } + + const CellIndex cell_index = this->_storage.point_to_cell_index(point); + const uint32_t lookup_radius = this->_find_lookup_radius(cell_index, point, epsilon); + + bool any_found = false; + NDLoopHelper::for_each_offset(lookup_radius, [&](const glm::vec &offset) { + const CellIndex neighbor_index = this->_storage.offset_cell_index(cell_index, offset); + any_found |= this->_storage.for_all_in_cell(neighbor_index, [=](const Vec &neighbor_point, const Value &value) { + const Distance distance2 = distance_sq(point, neighbor_point); + if (distance2 < epsilon2) { + func(point, value, distance2); + } + }); + }); + + return any_found; + } + template + bool for_all_near(const Vec &point, const Distance epsilon, const Func func) { + return const_cast(this)->for_all_near(point, epsilon, [&](const Vec &vec, const Value &value, const Distance distance_sq) { + func(vec, const_cast(value), distance_sq); + }); + } + + template + std::optional> find_nearest( + const Vec &point, + const Distance epsilon) const { + return _find_nearest(*this, point, epsilon); + } + template + std::optional> find_nearest( + const Vec &point, + const Distance epsilon) { + return _find_nearest(*this, point, epsilon); + } + + template + bool find_all_near( + const Vec &point, + const Distance epsilon, + Vector &out) const { + return _find_all_near(*this, point, epsilon, out); + } + template + bool find_all_near( + const Vec &point, + const Distance epsilon, + Vector &out) { + return _find_all_near(*this, point, epsilon, out); + } + +private: + Storage _storage; + Bounds _bounds; + + template + uint32_t _find_lookup_radius(const CellIndex& index, const Vec &point, const Distance epsilon) const { + const Bounds cell_bounds = this->_storage.cell_bounds(index); + const Vec cell_size = cell_bounds.size(); + const Vec relative_cell_point = point - cell_bounds.min; + const Vec distance_from_cell_bounds = glm::min(relative_cell_point, cell_size - relative_cell_point); + if (glm::all(glm::greaterThanEqual(distance_from_cell_bounds, Vec(epsilon)))) { + return 0; + } else { + const Component max_cell_size = glm::compMax(cell_size); + const uint32_t radius = std::ceil(epsilon / max_cell_size); + if (radius > 1) { + LOG_WARN("Lookup epsilon ({}) is too large compared to cell size {} resulting in cell radius of {}", + epsilon, cell_size, radius); + } + return radius; + } + } + + static_assert(SpatialLookup); +}; + +} // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/CellBasedStorage.h b/src/terrainlib/spatial_lookup/CellBasedStorage.h new file mode 100644 index 0000000..60117ad --- /dev/null +++ b/src/terrainlib/spatial_lookup/CellBasedStorage.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace spatial_lookup { + +template < + typename T, + glm::length_t n_dims, + typename Component, + typename Value> +concept CellBasedStorage = requires( + T storage, + const T const_storage, + typename T::CellIndex index, + Value value, + const glm::vec point, + const glm::vec offset) { + typename T::CellIndex; + + { const_storage.point_to_cell_index(point) } -> std::same_as; + { const_storage.offset_cell_index(index, offset) } -> std::same_as; + { const_storage.cell_bounds(index) } -> std::same_as>; + + { storage.insert(point, value) } -> std::same_as; + + { + storage.for_all_in_cell(index, [](const glm::vec&, Value&) {}) + } -> std::same_as; + { + const_storage.for_all_in_cell(index, [](const glm::vec&, const Value&) {}) + } -> std::same_as; +}; + +} // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/Grid.h b/src/terrainlib/spatial_lookup/Grid.h index f48f1a9..f0e5164 100644 --- a/src/terrainlib/spatial_lookup/Grid.h +++ b/src/terrainlib/spatial_lookup/Grid.h @@ -1,229 +1,12 @@ #pragma once -#include -#include -#include - -#include -#include -#include - -#include "log.h" -#include "mesh/SimpleMesh.h" -#include "spatial_lookup/NDLoopHelper.h" -#include "spatial_lookup/SpatialLookup.h" -#include "spatial_lookup/SpatialLookupExt.h" +#include "spatial_lookup/GridStorage.h" +#include "spatial_lookup/CellBased.h" namespace spatial_lookup { template -class Grid : public SpatialLookup { -public: - using Self = Grid; - using Base = SpatialLookup; - using Vec = glm::vec; - using CellIndex = glm::vec; - using CellOffset = glm::vec; - - Grid(const Vec origin, const Vec size, const CellIndex divisions) - : origin(origin), size(size), divisions(divisions) { - this->_point_count = 0; - this->_data.resize(glm::compMul(divisions)); - } - - struct CellItem { - Vec point; - Value value; - }; - - struct Cell { - std::vector items; - }; - - void clear() override { - this->_data.clear(); - this->_point_count = 0; - } - - void insert(const Vec &point, const Value value) override { - if (!this->is_in_bounds(point)) { - return; - } - - const size_t cell_index = this->calculate_cell_index(point); - - const CellItem item{ - .point = point, - .value = value}; - Cell &cell = this->_data[cell_index]; - cell.items.push_back(item); - this->_point_count += 1; - - if (cell.items.size() >= 1000) { - LOG_WARN("Large number of points inside single grid cell: {} ({} overall)", cell.items.size(), this->_point_count); - } - } - - template - void for_all_near(const Vec &point, const Distance epsilon, Func &&func) { - const_cast(this)->for_all_near(point, epsilon, [&](const Vec &vec, const Value &value, const Distance distance_sq) { - func(vec, const_cast(value), distance_sq); - }); - } - template - void for_all_near(const Vec &point, const Distance epsilon, Func &&func) const { - DEBUG_ASSERT(epsilon > 0); - - if (!this->is_in_bounds(point)) { - return; - } - - const CellIndex grid_index = this->calculate_grid_index(point); - const Vec cell_size = this->cell_size(); - uint32_t cell_radius; - - const Vec relative_cell_point = point - cell_size * Vec(grid_index); - DEBUG_ASSERT(glm::all(glm::greaterThanEqual(relative_cell_point, Vec(0)))); - DEBUG_ASSERT(glm::all(glm::lessThan(relative_cell_point, cell_size))); - const Vec distance_from_cell_bounds = glm::min(relative_cell_point, cell_size - relative_cell_point); - DEBUG_ASSERT(glm::all(glm::greaterThanEqual(distance_from_cell_bounds, Vec(0)))); - DEBUG_ASSERT(glm::all(glm::lessThan(distance_from_cell_bounds * Component(2), cell_size))); - if (glm::all(glm::greaterThanEqual(distance_from_cell_bounds, Vec(epsilon)))) { - cell_radius = 0; - } else { - const Component max_cell_size = glm::compMax(cell_size); - cell_radius = std::ceil(epsilon / max_cell_size); - if (cell_radius > 1) { - LOG_WARN("Grid lookup epsilon ({}) is high compared to cell size {} resulting in cell radius of {}", - epsilon, cell_size, cell_radius); - } - } - - const Distance epsilon_sq = epsilon * epsilon; - CellOffset offset; - - NDLoopHelper::for_each_offset(cell_radius, offset, [&](const CellOffset &offset) { - const CellOffset _neighbor_index = CellOffset(grid_index) + offset; - if (!this->is_valid_grid_index(_neighbor_index)) { - return; - } - - const CellIndex neighbor_index(_neighbor_index); - const size_t cell_index = this->calculate_cell_index(neighbor_index); - const Cell &cell = this->_data[cell_index]; - - for (const CellItem &item : cell.items) { - const Distance distance_sq = helpers::distance_sq(point, item.point); - if (distance_sq < epsilon_sq) { - func(item.point, item.value, distance_sq); - } - } - }); - } - void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNear func) override { - this->for_all_near(point, epsilon, std::move(func)); - } - void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNearConst func) const override { - this->for_all_near(point, epsilon, std::move(func)); - } - - template - std::optional> find_nearest(const Vec &point, const Distance epsilon) { - return helpers::find_nearest(*this, point, epsilon); - } - template - std::optional> find_nearest(const Vec &point, const Distance epsilon) const { - return helpers::find_nearest(*this, point, epsilon); - } - std::optional> find_nearest(const Vec &point, const Component epsilon) override { - return this->find_nearest(point, epsilon); - } - std::optional> find_nearest(const Vec &point, const Component epsilon) const override { - return this->find_nearest(point, epsilon); - } - - template - bool find_all_near(const Vec &point, const Distance epsilon, Vector &out) { - return helpers::find_all_near(*this, point, epsilon, out); - } - template - bool find_all_near(const Vec &point, const Distance epsilon, Vector &out) const { - return helpers::find_all_near(*this, point, epsilon, out); - } - bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) override { - return this->find_all_near>>(point, epsilon, out); - } - bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const override { - return this->find_all_near>>(point, epsilon, out); - } - - bool is_in_bounds(const Vec point) const { - const Vec max_bounds = origin + size; - return glm::all(glm::greaterThanEqual(point, origin)) && - glm::all(glm::lessThanEqual(point, max_bounds)); - } - - Vec cell_size() const { - return this->size / Vec(this->divisions); - } - - CellIndex calculate_grid_index(const Vec point) const { - return CellIndex((point - this->origin) / this->cell_size()); - } - - size_t calculate_cell_index(const Vec point) const { - const CellIndex grid_index = this->calculate_grid_index(point); - return this->calculate_cell_index(grid_index); - } - - size_t calculate_cell_index(const CellIndex grid_index) const { - size_t index = 0; - size_t stride = 1; - - for (size_t i = 0; i < n_dims; i++) { - index += grid_index[i] * stride; - stride *= divisions[i]; - } - - return index; - } - - bool is_point_inside_cell(const Vec &point, const CellIndex &grid_index) const { - const Vec cell_size = this->cell_size(); - const Vec cell_min = this->origin + Vec(grid_index) * cell_size; - const Vec cell_max = cell_min + cell_size; - - return glm::all(glm::greaterThanEqual(point, cell_min)) && glm::all(glm::lessThanEqual(point, cell_max)); - } - - bool is_valid_grid_index(const CellOffset &grid_index) const { - return glm::all(glm::greaterThanEqual(grid_index, CellOffset(0))) && this->is_valid_grid_index(CellIndex(grid_index)); - } - bool is_valid_grid_index(const CellIndex &grid_index) const { - return glm::all(glm::lessThan(grid_index, divisions)); - } - - const Cell &cell(const CellIndex &grid_index) const { - return this->cell(this->calculate_cell_index(grid_index)); - } - const Cell &cell(const size_t cell_index) const { - return this->_data[cell_index]; - } - - const std::span cells() const { - return this->_data; - } - - /*const*/ Vec origin; - /*const*/ Vec size; - /*const*/ glm::vec divisions; - -private: - size_t _point_count; - std::vector _data; - - static_assert(SpatialLookupExt); -}; +using Grid = CellBased>; template using Grid2d = Grid<2, double, Value>; diff --git a/src/terrainlib/spatial_lookup/GridStorage.h b/src/terrainlib/spatial_lookup/GridStorage.h new file mode 100644 index 0000000..b86d867 --- /dev/null +++ b/src/terrainlib/spatial_lookup/GridStorage.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include + +#include +#include + +#include "spatial_lookup/CellBasedStorage.h" + +namespace spatial_lookup { + +template +class GridStorage { +public: + using Self = GridStorage; + using Vec = glm::vec; + using Bounds = radix::geometry::Aabb; + using CellIndex = uint32_t; + using CellOffset = int32_t; + using GridIndex = glm::vec; + using GridOffset = glm::vec; + + GridStorage(const Vec origin, const Vec size, const GridIndex divisions) + : _origin(origin), _size(size), _divisions(divisions) { + this->_point_count = 0; + this->_data.resize(glm::compMul(divisions)); + } + + struct Item { + Vec point; + Value value; + }; + + struct Cell { + std::vector items; + }; + + void clear() { + for (auto &cell : this->_data) { + cell.items.clear(); + } + this->_point_count = 0; + } + + [[nodiscard]] bool empty() const { + return this->_data.empty(); + } + + [[nodiscard]] size_t size() const { + return this->_data.size(); + } + + [[nodiscard]] GridIndex point_to_grid_index(const Vec &point) const { + return GridIndex((point - this->_origin) / this->cell_size()); + } + [[nodiscard]] CellIndex point_to_cell_index(const Vec &point) const { + return this->grid_to_cell_index(this->point_to_grid_index(point)); + } + [[nodiscard]] CellIndex grid_to_cell_index(const GridIndex &grid_index) const { + CellIndex index = 0; + CellIndex stride = 1; + + for (CellIndex i = 0; i < n_dims; i++) { + index += grid_index[i] * stride; + stride *= this->_divisions[i]; + } + + return index; + } + [[nodiscard]] CellIndex grid_to_cell_index(const GridOffset &grid_index) const { + CellOffset index = 0; + CellOffset stride = 1; + + for (CellOffset i = 0; i < n_dims; i++) { + index += grid_index[i] * stride; + stride *= this->_divisions[i]; + } + + return CellIndex(index); // this may wrap, but we check the validity later anyways + } + [[nodiscard]] CellIndex offset_cell_index(const CellIndex index, const GridOffset &offset) const { + return index + this->grid_to_cell_index(offset); + } + + [[nodiscard]] GridIndex cell_to_grid_index(const CellIndex index) const { + GridIndex grid_index; + CellIndex current_index = index; + for (CellIndex i = 0; i < n_dims; i++) { + grid_index[i] = current_index % this->_divisions[i]; + current_index /= this->_divisions[i]; + } + return grid_index; + } + [[nodiscard]] Bounds cell_bounds(const CellIndex index) const { + const GridIndex grid_index = this->cell_to_grid_index(index); + const Vec cell_size = this->cell_size(); + const Vec cell_min = this->_origin + Vec(grid_index) * cell_size; + const Vec cell_max = cell_min + cell_size; + return Bounds{ + .min = cell_min, + .max = cell_max + }; + } + + bool insert(const Vec &point, const Value value) { + const CellIndex index = this->point_to_cell_index(point); + + if (!this->is_valid_cell_index(index)) { + return false; + } + + const Item item{ + .point = point, + .value = value}; + Cell &cell = this->_data[index]; + cell.items.push_back(std::move(item)); + this->_point_count += 1; + + return true; + } + + template + bool for_all_in_cell(const CellIndex index, Func &&func) const { + if (!this->is_valid_cell_index(index)) { + return false; + } + + const Cell &cell = this->_data[index]; + for (const Item &item : cell.items) { + func(item.point, item.value); + } + + return !cell.items.empty(); + } + template + bool for_all_in_cell(const CellIndex index, Func &&func) { + return const_cast(this)->for_all_in_cell(index, [&](const Vec &vec, const Value &value) { + func(vec, const_cast(value)); + }); + } + + [[nodiscard]] Vec cell_size() const { + return this->_size / Vec(this->_divisions); + } + + bool is_valid_cell_index(const CellIndex &index) const { + return index < this->_data.size(); + } + +private: + size_t _point_count; + std::vector _data; + Vec _origin; + Vec _size; + glm::vec _divisions; + + // static_assert(CellBasedStorage); +}; + +} diff --git a/src/terrainlib/spatial_lookup/Hashmap.h b/src/terrainlib/spatial_lookup/Hashmap.h index 4f0d204..22159aa 100644 --- a/src/terrainlib/spatial_lookup/Hashmap.h +++ b/src/terrainlib/spatial_lookup/Hashmap.h @@ -1,221 +1,16 @@ #pragma once -#include -#include - -#include -#include -#include -#include -#include - -#include "NDLoopHelper.h" -#include "SpatialLookup.h" -#include "hash_utils.h" +#include "spatial_lookup/CellBased.h" +#include "spatial_lookup/HashmapStorage.h" namespace spatial_lookup { -namespace { -template -T remainder(const T x, const T y) { - if constexpr (std::is_integral::value) { - return x % y; - } else { - return std::fmod(x, y); - } -} - -template -T quantize(const T x, const T epsilon) { - return x - remainder(x, epsilon); -} - -template -glm::vec remainder(const glm::vec &v, const T epsilon) { - glm::vec result; - for (glm::length_t i = 0; i < n_dims; i++) { - result[i] = remainder(v[i], epsilon); - } - return result; -} - -template -glm::vec quantize(const glm::vec& v, const T epsilon) { - glm::vec result; - for (glm::length_t i = 0; i < n_dims; i++) { - result[i] = quantize(v[i], epsilon); - } - return result; -} - -template -struct VecHash { - using Vec = glm::vec; - - T epsilon; - - size_t operator()(const Vec &v) const noexcept { - size_t seed = hash::default_seed(); - for (glm::length_t i = 0; i < n_dims; i++) { - hash::append(seed, quantize(v[i], epsilon)); - } - return seed; - } -}; - -template -struct NeverEqual { - bool operator()(const T &, const T &) const noexcept { - return false; - } -}; - -} // namespace template -class Hashmap : public SpatialLookup { -public: - using Self = Hashmap; - using Base = SpatialLookup; - using Vec = glm::vec; - using Equal = NeverEqual; - using Hash = VecHash; - using Container = std::unordered_map; - using iterator = typename Container::iterator; - using const_iterator = typename Container::const_iterator; - using Bounds = radix::geometry::Aabb; - - explicit Hashmap(Component epsilon) - : _epsilon(epsilon), - _store(0, Hash(epsilon), Equal()) {} - - void clear() override { - this->_store.clear(); - this->_bounds = Bounds(); - } - - [[nodiscard]] bool empty() const { - return this->_store.empty(); - } - - [[nodiscard]] size_t size() const { - return this->_store.size(); - } - - void insert(const Vec& point, const Value value) override { - this->_store.emplace(point, std::move(value)); - this->_bounds.expand_by(point); - } - - template - void for_all_near(const Vec &point, const Distance epsilon, Func &&func) { - const_cast(this)->for_all_near(point, epsilon, [&](const Vec &vec, const Value &value, const Distance distance_sq) { - func(vec, const_cast(value), distance_sq); - }); - } - template - void for_all_near(const Vec &key, const _Distance _lookup_epsilon, Func &&func) const { - using Distance = MoreExact<_Distance, Component>; - const Distance lookup_epsilon = _lookup_epsilon; - DEBUG_ASSERT(lookup_epsilon > 0); - - const Distance lookup_epsilon2 = lookup_epsilon * lookup_epsilon; - if (radix::geometry::distance_sq(this->_bounds, key) > lookup_epsilon2) { - return; - } - - const uint32_t lookup_radius = this->_find_lookup_radius(key, lookup_epsilon); - const Vec quantized_key = this->_quantize(key); - const Vec base_key = quantized_key + Vec(this->_epsilon * 0.5f); - - glm::vec offset; - NDLoopHelper::for_each_offset(lookup_radius, offset, [&](const glm::vec &offset) { - const Vec neighbor_key = base_key + Vec(offset) * this->_epsilon; - size_t bucket_idx = this->_store.bucket(neighbor_key); - for (auto it = _store.begin(bucket_idx); it != _store.end(bucket_idx); ++it) { - const Vec &point = it->first; - const Value &value = it->second; - - if (this->_quantize(neighbor_key) != this->_quantize(point)) { - continue; // Skip if the key does not match - } - - const Distance distance2 = helpers::distance_sq(key, point); - if (distance2 < lookup_epsilon2) { - func(point, value, distance2); - } - } - }); - } - void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNear func) override { - this->for_all_near(point, epsilon, std::move(func)); - } - void for_all_near(const Vec &point, const Component epsilon, typename Base::ForAllNearConst func) const override { - this->for_all_near(point, epsilon, std::move(func)); - } - - template - std::optional> find_nearest(const Vec &point, Distance epsilon) { - return helpers::find_nearest(*this, point, epsilon); - } - template - std::optional> find_nearest(const Vec &point, Distance epsilon) const { - return helpers::find_nearest(*this, point, epsilon); - } - std::optional> find_nearest(const Vec &point, const Component epsilon) override { - return this->find_nearest(point, epsilon); - } - std::optional> find_nearest(const Vec &point, const Component epsilon) const override { - return this->find_nearest(point, epsilon); - } - - template - bool find_all_near(const Vec &point, Distance epsilon, Vector &out) { - return helpers::find_all_near(*this, point, epsilon, out); - } - template - bool find_all_near(const Vec &point, Distance epsilon, Vector &out) const { - return helpers::find_all_near(*this, point, epsilon, out); - } - bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) override { - return this->find_all_near>>(point, epsilon, out); - } - bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const override { - return this->find_all_near>>(point, epsilon, out); - } - -private: - Vec _quantize(const Vec &v) const { - return quantize(v, this->_epsilon); - } - - template - uint32_t _find_lookup_radius(const Vec &key, const Distance lookup_epsilon) const { - const Distance store_epsilon = this->_epsilon; - if (lookup_epsilon < store_epsilon) { - // Check if it is sufficient to check only the cell of the key - const auto quantization_remainder = remainder(glm::vec(key), Distance(this->_epsilon)); - const Distance distance_to_next_key = std::min( - glm::compMin(quantization_remainder), - Distance(this->_epsilon) - glm::compMax(quantization_remainder)); - DEBUG_ASSERT(distance_to_next_key >= 0); - DEBUG_ASSERT(distance_to_next_key * 2 < this->_epsilon); - if (distance_to_next_key > lookup_epsilon) { - return 0; - } - } - - const uint32_t lookup_radius = static_cast(std::ceil(lookup_epsilon / this->_epsilon)); - if (lookup_radius > 1) { - LOG_WARN("Lookup epsilon {} is large compared to quantization epsilon {} resulting in lookup radius of {}", - lookup_epsilon, this->_epsilon, lookup_radius); - } - return lookup_radius; - } +using Hashmap = CellBased>; - /*const*/ Component _epsilon; - Container _store; - Bounds _bounds; +template +using Hashmap2d = Hashmap<2, double, Value>; +template +using Hashmap3d = Hashmap<3, double, Value>; - static_assert(SpatialLookupExt); -}; -} +} // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/HashmapStorage.h b/src/terrainlib/spatial_lookup/HashmapStorage.h new file mode 100644 index 0000000..a98ba14 --- /dev/null +++ b/src/terrainlib/spatial_lookup/HashmapStorage.h @@ -0,0 +1,136 @@ +#pragma once + +#include + +#include + +#include "spatial_lookup/CellBasedStorage.h" +#include "hash_utils.h" + +namespace spatial_lookup { +namespace { +template +T quantize(const T x, const T epsilon) { + // x - remainder(x, epsilon) is not idempotent + return std::floor(x / epsilon) * epsilon; +} + +template +glm::vec quantize(const glm::vec &v, const T epsilon) { + glm::vec result; + for (glm::length_t i = 0; i < n_dims; i++) { + result[i] = quantize(v[i], epsilon); + } + return result; +} + +template +struct VecHash { + using Vec = glm::vec; + + explicit VecHash(T epsilon) : epsilon(epsilon) {} + + T epsilon; + + size_t operator()(const Vec &v) const noexcept { + size_t seed = hash::default_seed(); + for (glm::length_t i = 0; i < n_dims; i++) { + hash::append(seed, quantize(v[i], this->epsilon)); + } + return seed; + } +}; + +template +struct NeverEqual { + bool operator()(const T &, const T &) const noexcept { + return false; + } +}; + +} // namespace + +template +class HashmapStorage { +public: + using Self = HashmapStorage; + using Vec = glm::vec; + using Bounds = radix::geometry::Aabb; + using Hash = VecHash ; + using Equal = NeverEqual; + + struct CellIndex { + explicit CellIndex(const Vec& v) : quantized(v) {} + + const Vec quantized; + }; + + explicit HashmapStorage(Component epsilon) + : _epsilon(epsilon), _store(0, Hash(epsilon), Equal()) { + } + + void clear() { + this->_store.clear(); + } + + [[nodiscard]] bool empty() const { + return this->_store.empty(); + } + + [[nodiscard]] size_t size() const { + return this->_store.size(); + } + + [[nodiscard]] CellIndex point_to_cell_index(const Vec &point) const { + return CellIndex(quantize(point, this->_epsilon)); + } + [[nodiscard]] CellIndex offset_cell_index(const CellIndex index, const glm::vec &offset) const { + return point_to_cell_index(index.quantized + (Vec(offset) + Component(0.5)) * this->_epsilon); + } + + [[nodiscard]] Bounds cell_bounds(const CellIndex index) const { + return Bounds { + .min = index.quantized, + .max = index.quantized + this->_epsilon + }; + } + + bool insert(const Vec &point, const Value value) { + this->_store.emplace(point, std::move(value)); + return true; + } + + template + bool for_all_in_cell(const CellIndex index, Func &&func) const { + const size_t bucket_idx = this->_store.bucket(index.quantized + Vec(0.5 * this->_epsilon)); + bool any_found = false; + + for (auto it = this->_store.begin(bucket_idx); it != this->_store.end(bucket_idx); it++) { + const Vec &point = it->first; + const Value &value = it->second; + + if (index.quantized != quantize(point, this->_epsilon)) { + continue; // Skip if the key does not match + } + + any_found = true; + func(point, value); + } + + return any_found; + } + template + bool for_all_in_cell(const CellIndex index, Func &&func) { + return const_cast(this)->for_all_in_cell(index, [&](const Vec &vec, const Value &value) { + func(vec, const_cast(value)); + }); + } + +private: + Component _epsilon; + std::unordered_map _store; + + // static_assert(CellBasedStorage); +}; + +} // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/NDLoopHelper.h b/src/terrainlib/spatial_lookup/NDLoopHelper.h index a3ff484..3f044e9 100644 --- a/src/terrainlib/spatial_lookup/NDLoopHelper.h +++ b/src/terrainlib/spatial_lookup/NDLoopHelper.h @@ -3,18 +3,28 @@ #include template -struct NDLoopHelper { +class NDLoopHelper { +public: using Offset = glm::vec; template - static void for_each_offset(const int32_t radius, Offset &offset, Func &&func) { + static void for_each_offset(const uint32_t radius, Func &&func) { + Offset offset; + _for_each_offset(static_cast(radius), offset, std::forward(func)); + } + +private: + template + static void _for_each_offset(const int32_t radius, Offset &offset, Func &&func) { if constexpr (current_dim == n_dims) { func(offset); } else { for (int32_t i = -radius; i <= radius; i++) { offset[current_dim] = i; - NDLoopHelper::for_each_offset(radius, offset, std::forward(func)); + NDLoopHelper::_for_each_offset(radius, offset, std::forward(func)); } } } + + friend class NDLoopHelper; }; diff --git a/src/terrainlib/spatial_lookup/SpatialLookup.h b/src/terrainlib/spatial_lookup/SpatialLookup.h index 49c6c5f..4cfde7e 100644 --- a/src/terrainlib/spatial_lookup/SpatialLookup.h +++ b/src/terrainlib/spatial_lookup/SpatialLookup.h @@ -1,30 +1,27 @@ #pragma once -#include -#include +#include #include namespace spatial_lookup { -template -class SpatialLookup { -public: - using Vec = glm::vec; - using ForAllNear = std::function; - using ForAllNearConst = std::function; - - virtual void clear() = 0; - virtual void insert(const Vec &point, const Value value) = 0; - - virtual std::optional> find_nearest(const Vec &point, const Component epsilon) = 0; - virtual std::optional> find_nearest(const Vec &point, const Component epsilon) const = 0; - - virtual bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) = 0; - virtual bool find_all_near(const Vec &point, const Component epsilon, std::vector> &out) const = 0; - - virtual void for_all_near(const Vec &point, const Component epsilon, ForAllNear func) = 0; - virtual void for_all_near(const Vec &point, const Component epsilon, ForAllNearConst func) const = 0; +template +concept SpatialLookup = requires( + T t, + const T ct, + const glm::vec &point, + Value value, + Component epsilon) { + { t.clear() } -> std::same_as; + { t.insert(point, value) } -> std::same_as; + + { + t.for_all_near(point, epsilon, [](const glm::vec &, Value &, const Component) {}) + } -> std::same_as; + { + ct.for_all_near(point, epsilon, [](const glm::vec &, const Value &, const Component) {}) + } -> std::same_as; }; } // namespace spatial_lookup diff --git a/src/terrainlib/spatial_lookup/SpatialLookupExt.h b/src/terrainlib/spatial_lookup/SpatialLookupExt.h deleted file mode 100644 index 5271933..0000000 --- a/src/terrainlib/spatial_lookup/SpatialLookupExt.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace spatial_lookup { - -template -concept SpatialLookupExt = requires( - T t, - const T ct, - const Vec &point, - Value &value_ref, - Value value, - Distance epsilon) { - { t.clear() } -> std::same_as; - { t.insert(point, value) } -> std::same_as; - - { t.find_nearest(point, epsilon) } -> std::same_as>>; - { ct.find_nearest(point, epsilon) } -> std::same_as>>; - - requires requires(std::vector &out) { - { out.emplace_back(value) }; - - { t.find_all_near(point, epsilon, out) } -> std::same_as; - { ct.find_all_near(point, epsilon, out) } -> std::same_as; - }; - - { - t.for_all_near(point, epsilon, [](const Vec &, Value &, decltype(epsilon)){}) - } -> std::same_as; - { - ct.for_all_near(point, epsilon, [](const Vec &, const Value &, decltype(epsilon)) {}) - } -> std::same_as; -}; - -namespace helpers { - -// Calculate distance^2, works with all types -template -auto distance_sq(const glm::vec &a, const glm::vec &b) { - using T = MoreExact; - using Vec = glm::vec; - - if constexpr (std::is_floating_point_v) { - return glm::distance2(Vec(a), Vec(b)); - } else { - const auto diff = a - b; - const auto diff_sq = diff * diff; - return glm::compAdd(diff_sq); - } -} - -template < - typename SpatialLookup, - typename Vec, - typename Distance, - typename Value> -std::optional> find_nearest( - SpatialLookup &lookup, - const Vec &point, - const Distance epsilon) { - assert(epsilon > 0); - Distance closest_distance2 = std::numeric_limits::max(); - Value* closest_value = nullptr; - - lookup.for_all_near(point, epsilon, [&](const Vec&, Value& value, Distance dist2) { - if (dist2 < closest_distance2) { - closest_distance2 = dist2; - closest_value = &value; - } - }); - - if (closest_value) { - return std::ref(*closest_value); - } - return std::nullopt; -} - -template < - typename SpatialLookup, - typename Vec, - typename Distance, - typename Vector, - typename Value> -bool find_all_near( - SpatialLookup &lookup, - const Vec &point, - const Distance epsilon, - Vector &out) { - out.clear(); - lookup.for_all_near(point, epsilon, [&](const Vec&, Value& value, Distance) { - out.emplace_back(value); - }); - return !out.empty(); -} -} - -} diff --git a/src/terrainlib/type_utils.h b/src/terrainlib/type_utils.h index 1782ea5..186a918 100644 --- a/src/terrainlib/type_utils.h +++ b/src/terrainlib/type_utils.h @@ -56,20 +56,3 @@ std::string type_name(const T &obj) { std::free}; return (status == 0) ? res.get() : typeid(obj).name(); } - -// Generic helper to determine the "more exact" type, preferring floating point types -template -struct MoreExactType { -private: - static constexpr bool t1_is_fp = std::is_floating_point_v; - static constexpr bool t2_is_fp = std::is_floating_point_v; - -public: - using type = std::conditional_t< - (t1_is_fp && !t2_is_fp), T1, - std::conditional_t<(t2_is_fp && !t1_is_fp), T2, - std::conditional_t<(sizeof(T1) >= sizeof(T2)), T1, T2>>>; -}; - -template -using MoreExact = typename MoreExactType::type; \ No newline at end of file diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index bbfccca..eae986d 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -44,6 +44,9 @@ add_executable(unittests_terrainlib terrainlib/octree_id.cpp terrainlib/octree_space.cpp terrainlib/progress_indicator_test.cpp + terrainlib/spatial_lookup.cpp + terrainlib/mesh_merge_mapping.cpp + terrainlib/mesh_merge.cpp ) target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) @@ -64,7 +67,6 @@ target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2 add_executable(unittests_terrainsimplify catch2_helpers.h - terrainsimplify/merge.cpp ) target_link_libraries(unittests_terrainsimplify PUBLIC terrainsimplifylib Catch2::Catch2WithMain) diff --git a/unittests/terrainlib/mesh_clip.cpp b/unittests/terrainlib/mesh_clip.cpp index 3596e66..4b648dd 100644 --- a/unittests/terrainlib/mesh_clip.cpp +++ b/unittests/terrainlib/mesh_clip.cpp @@ -298,6 +298,7 @@ TEST_CASE("mesh::clip_on_bounds") { } } +#ifdef NDEBUG TEST_CASE("mesh::clip_on_bounds benchmark") { BENCHMARK_ADVANCED("clip based on octree")(Catch::Benchmark::Chronometer meter) { const std::filesystem::path mesh_path = ATB_TEST_DATA_DIR "/meshes/6857.terrain"; @@ -329,3 +330,4 @@ TEST_CASE("mesh::clip_on_bounds benchmark") { }); }; } +#endif diff --git a/unittests/terrainsimplify/merge.cpp b/unittests/terrainlib/mesh_merge.cpp similarity index 91% rename from unittests/terrainsimplify/merge.cpp rename to unittests/terrainlib/mesh_merge.cpp index 06ca10c..4ecbcc5 100644 --- a/unittests/terrainsimplify/merge.cpp +++ b/unittests/terrainlib/mesh_merge.cpp @@ -17,9 +17,11 @@ * along with this program. If not, see . *****************************************************************************/ -#define CATCH_CONFIG_MAIN -#include -#include "merge.h" +#include + +#include "../catch2_helpers.h" +#include "mesh/SimpleMesh.h" +#include "mesh/merge.h" #include "mesh/utils.h" TEST_CASE("terrainmerger") { @@ -36,9 +38,7 @@ TEST_CASE("terrainmerger") { mesh2.positions.push_back(glm::dvec3(0, 1, 0)); mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - std::array meshes = { std::move(mesh1), std::move(mesh2) }; - - SimpleMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -75,9 +75,7 @@ TEST_CASE("terrainmerger") { mesh2.uvs.push_back(glm::dvec2(0, 1)); mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - std::array meshes = {std::move(mesh1), std::move(mesh2)}; - - SimpleMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -116,9 +114,7 @@ TEST_CASE("terrainmerger") { mesh2.triangles.push_back(glm::uvec3(0, 2, 1)); mesh2.triangles.push_back(glm::uvec3(1, 2, 3)); - std::array meshes = {std::move(mesh1), std::move(mesh2)}; - - SimpleMesh actual = merge::merge_meshes(meshes, 0.1); + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); diff --git a/unittests/terrainlib/mesh_merge_mapping.cpp b/unittests/terrainlib/mesh_merge_mapping.cpp new file mode 100644 index 0000000..0f1b2d7 --- /dev/null +++ b/unittests/terrainlib/mesh_merge_mapping.cpp @@ -0,0 +1,142 @@ +/***************************************************************************** + * Alpine Terrain Builder + * Copyright (C) 2022 Adam Celarek + * Copyright (C) 2022 alpinemaps.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "../catch2_helpers.h" +#include "mesh/SimpleMesh.h" +#include "mesh/merging/mapping.h" +#include +#include "spatial_lookup/CellBasedStorage.h" +#include "spatial_lookup/GridStorage.h" +#include "spatial_lookup/HashmapStorage.h" + +using mesh::merging::VertexId; +using mesh::merging::VertexMapping; + +TEST_CASE("merging::create_mapping") { + SECTION("minimum test") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(0, 0, 0)); + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + size_t idx1 = mapping.map_forward(VertexId{0, 0}); + size_t idx2 = mapping.map_forward(VertexId{1, 0}); + CHECK(idx1 == idx2); + } + + SECTION("two identical positions are merged") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + mesh1.positions.push_back(glm::dvec3(1, 1, 0)); + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(1, 0, 0)); // identical to mesh1[2] + mesh2.positions.push_back(glm::dvec3(1, 1, 0)); // identical to mesh1[1] + mesh2.positions.push_back(glm::dvec3(0, 1, 0)); + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + // Merged index of (1, 0, 0) should be the same for both meshes + size_t idx1 = mapping.map_forward(VertexId{0, 2}); + size_t idx2 = mapping.map_forward(VertexId{1, 0}); + REQUIRE(idx1 == idx2); + + // Merged index of (1,1,0) should be the same for both + size_t idx3 = mapping.map_forward(VertexId{0, 1}); + size_t idx4 = mapping.map_forward(VertexId{1, 1}); + REQUIRE(idx3 == idx4); + + // (0, 1, 0) should be unique + size_t idx5 = mapping.map_forward(VertexId{1, 2}); + REQUIRE(idx5 != idx1); + REQUIRE(idx5 != idx3); + + // Total unique merged vertices should be 4 + REQUIRE(mapping.find_max_merged_index() + 1 == 4); + } + + SECTION("similar vertices within epsilon are merged") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(1.05, 0, 0)); // should be merged if epsilon >= 0.1 + mesh2.positions.push_back(glm::dvec3(2, 0, 0)); + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + size_t idx1 = mapping.map_forward(VertexId{0, 1}); // (1, 0, 0) + size_t idx2 = mapping.map_forward(VertexId{1, 0}); // (1.05, 0, 0) + + // They are within epsilon => should be merged + CHECK(idx1 == idx2); + + // The far point should be separate + size_t idx3 = mapping.map_forward(VertexId{1, 1}); // (2, 0, 0) + CHECK(idx3 != idx1); + + CHECK(mapping.find_max_merged_index() + 1 == 3); + } + + SECTION("similar vertices are NOT merged if outside epsilon") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(1.10000001, 0, 0)); + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // epsilon too small + + size_t idx1 = mapping.map_forward(VertexId{0, 0}); + size_t idx2 = mapping.map_forward(VertexId{1, 0}); + + REQUIRE(idx1 != idx2); + REQUIRE(mapping.find_max_merged_index() + 1 == 2); + } + + SECTION("identity mapping on disjoint meshes") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(2, 0, 0)); + mesh2.positions.push_back(glm::dvec3(3, 0, 0)); + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // all far apart + + REQUIRE(mapping.find_max_merged_index() + 1 == 4); + REQUIRE(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{0, 1})); + REQUIRE(mapping.map_forward(VertexId{1, 0}) != mapping.map_forward(VertexId{1, 1})); + } +} diff --git a/unittests/terrainlib/spatial_lookup.cpp b/unittests/terrainlib/spatial_lookup.cpp new file mode 100644 index 0000000..961e0e6 --- /dev/null +++ b/unittests/terrainlib/spatial_lookup.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#include + +#include "../catch2_helpers.h" +#include "spatial_lookup/Grid.h" +#include "spatial_lookup/Hashmap.h" + +// 3D string test +TEMPLATE_TEST_CASE("SpatialLookup insert and find_near", "[SpatialLookup]", + (spatial_lookup::Hashmap<3, float, std::string>), + (spatial_lookup::Grid<3, float, std::string>)) { + std::optional map_opt = std::nullopt; + if constexpr (std::is_same_v>) { + map_opt = spatial_lookup::Hashmap<3, float, std::string>(0.1f); + } else { + map_opt = spatial_lookup::Grid<3, float, std::string>(glm::vec3(0.0f), glm::vec3(4.0f), glm::uvec3(4)); + } + TestType map = std::move(map_opt.value()); + + const glm::vec3 p1(1.0, 2.0, 3.0); + const glm::vec3 p2(1.05, 2.0, 3.0); // within epsilon of p1 + const glm::vec3 p3(2.0, 2.0, 3.0); // outside epsilon of p1 + + map.insert(p1, "P1"); + map.insert(p2, "P2"); + map.insert(p3, "P3"); + + std::vector found; + + SECTION("Find points near p2 within 0.01") { + const bool found_any = map.find_all_near(p2, 0.01, found); + CHECK(found_any); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({"P2"})); + } + + SECTION("Find points near p1 within 0.1") { + const bool found_any = map.find_all_near(p1, 0.1, found); + CHECK(found_any); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({"P1", "P2"})); + } + + SECTION("Find points near p1 with tighter epsilon") { + const bool found_any = map.find_all_near(p1, 0.04, found); + CHECK(found_any); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({"P1"})); + } + + SECTION("Find points not near any other points") { + const bool found_any = map.find_all_near(glm::vec3(3.0, 3.0, 3.0), 1, found); + CHECK(!found_any); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({})); + } +} + +// 2D int test +TEMPLATE_TEST_CASE("SpatialLookup 2D and int keys", "[SpatialLookup]", + (spatial_lookup::Hashmap<2, int, int>), + (spatial_lookup::Grid<2, int, int>)) { + std::optional map_opt = std::nullopt; + if constexpr (std::is_same_v>) { + map_opt = spatial_lookup::Hashmap<2, int, int>(1); + } else { + map_opt = spatial_lookup::Grid<2, int, int>(glm::ivec2(0), glm::ivec2(6), glm::uvec2(6)); + } + TestType map = std::move(map_opt.value()); + + const glm::ivec2 p1(0, 0); + const glm::ivec2 p2(1, 1); + const glm::ivec2 p3(5, 5); + + map.insert(p1, 100); + map.insert(p2, 200); + map.insert(p3, 300); + + std::vector found; + + SECTION("Find near p1 with epsilon 1") { + const bool ok = map.find_all_near(p1, 1, found); + CHECK(ok); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({100})); + } + + SECTION("Find near p2 with epsilon 2") { + const bool ok = map.find_all_near(p2, 2, found); + CHECK(ok); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({100, 200})); + } + + SECTION("Find away with epsilon 1 fails") { + const bool ok = map.find_all_near(glm::ivec2(3, 3), 1, found); + CHECK(!ok); + CHECK(found.empty()); + } +} + +// 3D int duplicate points test +TEMPLATE_TEST_CASE("SpatialLookup with duplicate points", "[SpatialLookup]", + (spatial_lookup::Hashmap<3, float, int>), + (spatial_lookup::Grid<3, float, int>)) { + std::optional map_opt = std::nullopt; + if constexpr (std::is_same_v>) { + map_opt = spatial_lookup::Hashmap<3, float, int>(0.1f); + } else { + map_opt = spatial_lookup::Grid<3, float, int>(glm::vec3(0.0f), glm::vec3(2.0f), glm::uvec3(2)); + } + TestType map = std::move(map_opt.value()); + + const glm::vec3 p(1.0f, 1.0f, 1.0f); + map.insert(p, 42); + map.insert(p, 43); + + std::vector found; + const bool ok = map.find_all_near(p, 0.01f, found); + + CHECK(ok); + CHECK_THAT(found, Catch::Matchers::UnorderedEquals({42, 43})); +} From 14786fd7b1a962d56760cc3ec752367a91d4fa4b Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 12 Aug 2025 12:17:35 +0200 Subject: [PATCH 099/122] Merger rewrite done (but slow) --- src/terrainlib/Cow.h | 28 ++++----- src/terrainlib/mesh/boolean.cpp | 18 +++++- src/terrainlib/mesh/boolean.h | 2 + src/terrainlib/mesh/cgal.h | 3 +- src/terrainlib/mesh/clip.cpp | 23 +++++--- src/terrainlib/mesh/convert.cpp | 16 +++--- src/terrainlib/mesh/merge.cpp | 2 - src/terrainlib/mesh/merge.h | 2 +- src/terrainlib/mesh/merging/mapping.cpp | 15 +++++ src/terrainlib/mesh/merging/mapping.h | 2 + src/terrainlib/mesh/utils.cpp | 9 +++ src/terrainlib/mesh/utils.h | 5 ++ src/terrainlib/octree/storage/RawStorage.cpp | 13 +++++ src/terrainlib/octree/storage/Storage.h | 11 ++-- src/terrainlib/octree/storage/cache/Dummy.h | 18 ++++-- src/terrainlib/octree/storage/cache/ICache.h | 2 +- .../octree/storage/cache/LruCache.h | 6 +- src/terrainlib/octree/storage/helpers.cpp | 57 ++++++++++++++----- src/terrainlib/octree/storage/helpers.h | 7 ++- src/terrainlib/octree/storage/open.cpp | 34 ++++++----- src/terrainlib/octree/storage/open.h | 14 +++-- src/terrainlib/optional_utils.h | 32 +++++++++++ src/terrainmerger/NodeLoader.h | 2 +- src/terrainmerger/cli.cpp | 4 +- src/terrainmerger/cut.h | 4 +- src/terrainmerger/mask.h | 2 +- src/terrainmerger/merge/visitor/Masked.h | 3 +- .../terrainlib/spatial_multi_hashmap.cpp | 0 28 files changed, 242 insertions(+), 92 deletions(-) create mode 100644 src/terrainlib/optional_utils.h create mode 100644 unittests/terrainlib/spatial_multi_hashmap.cpp diff --git a/src/terrainlib/Cow.h b/src/terrainlib/Cow.h index ab516f7..b57da5e 100644 --- a/src/terrainlib/Cow.h +++ b/src/terrainlib/Cow.h @@ -14,23 +14,14 @@ struct Cow { using RefType = std::reference_wrapper; std::variant data; - // explicit Cow(T&& value) - // : data(std::move(value)) {} - template , T>>> - explicit Cow(U &&value) : data(std::forward(value)) {} - explicit Cow(T &ref) - : data(std::ref(ref)) {} - template >> - Cow(Cow&& other) - : data(std::visit([](auto &data) -> std::variant { - return data; - }, other)) {} + explicit Cow(OwnedType&& value) : data(std::move(value)) {} + explicit Cow(T& ref) : data(std::ref(ref)) {} - static Cow from_owned(T value) { - return Cow(std::move(value)); + static Cow from_owned(OwnedType &&value) { + return Cow(std::move(value)); } - static Cow from_ref(T &ref) { - return Cow(ref); + static Cow from_ref(RefType ref) { + return Cow(ref); } Cow(const Cow &) = default; @@ -73,11 +64,12 @@ struct Cow { return get(); } - operator Cow() const { + operator Cow() & = delete; + operator Cow() && { if (is_owned()) { - return Cow(get()); + return Cow::from_owned(std::move(std::get(data))); } else { - return Cow(std::ref(get())); + return Cow::from_ref(std::ref(get())); } } }; diff --git a/src/terrainlib/mesh/boolean.cpp b/src/terrainlib/mesh/boolean.cpp index e302121..08f9aaf 100644 --- a/src/terrainlib/mesh/boolean.cpp +++ b/src/terrainlib/mesh/boolean.cpp @@ -1,13 +1,19 @@ #include +#include #include "mesh/boolean.h" #include "mesh/convert.h" #include "mesh/cgal.h" +#include "mesh/clip.h" +#include "mesh/utils.h" -using namespace mesh; +namespace mesh { + +IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b) { + ASSERT(!a.has_uvs()); + ASSERT(!b.has_uvs()); -IntersectionAndDifference mesh::intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b) { cgal::SurfaceMesh cgal_a = convert::to_cgal_mesh(a); cgal::SurfaceMesh cgal_b = convert::to_cgal_mesh(b); @@ -30,3 +36,11 @@ IntersectionAndDifference mesh::intersection_and_difference(const SimpleMesh &a, result.difference = convert::to_simple_mesh(cgal_difference); return result; } + + +SimpleMesh difference(const SimpleMesh &a, const SimpleMesh &b) { + SimpleMesh b_inv(b.triangles, b.positions); + flip_orientation(b_inv); + return mesh::clip_on_mesh(a, b_inv); +} +} \ No newline at end of file diff --git a/src/terrainlib/mesh/boolean.h b/src/terrainlib/mesh/boolean.h index 9650c63..b99b2d1 100644 --- a/src/terrainlib/mesh/boolean.h +++ b/src/terrainlib/mesh/boolean.h @@ -10,4 +10,6 @@ struct IntersectionAndDifference { }; IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b); +SimpleMesh difference(const SimpleMesh &a, const SimpleMesh &b); + } diff --git a/src/terrainlib/mesh/cgal.h b/src/terrainlib/mesh/cgal.h index b2bb9d4..1125cf0 100644 --- a/src/terrainlib/mesh/cgal.h +++ b/src/terrainlib/mesh/cgal.h @@ -11,7 +11,8 @@ namespace cgal { using Point2 = Kernel::Point_2; \ using Point3 = Kernel::Point_3; \ using SurfaceMesh = CGAL::Surface_mesh; \ - using VertexIndex = SurfaceMesh::Vertex_index; \ + using VertexIndex = SurfaceMesh::Vertex_index; \ + using FaceIndex = SurfaceMesh::Face_index; \ using VertexDescriptor = boost::graph_traits::vertex_descriptor; \ using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; \ using EdgeDescriptor = boost::graph_traits::edge_descriptor; \ diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index b5ddf9a..1f0c3ee 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -89,7 +89,7 @@ Cow mesh::clip_on_bounds(const SimpleMesh &mesh, const radix:: mesh::validate(mesh); if (mesh.vertex_count() == 0 || mesh.face_count() == 0) { - return Cow(SimpleMesh::empty()); + return Cow(SimpleMesh()); } if (mesh.has_uvs() && mesh.uvs.size() != mesh.vertex_count()) { @@ -441,7 +441,12 @@ Cow mesh::clip_on_bounds_and_cap(const SimpleMesh &mesh, const if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); } - if (!visitor.has_intersections) { + LOG_TRACE("Clip result: original {} faces -> clipped {} faces. Intersections: {}", + mesh.face_count(), cgal_mesh.number_of_faces(), visitor.has_intersections); + if (cgal_mesh.number_of_faces() == 0) { + return Cow(SimpleMesh()); + } + if (!visitor.has_intersections && cgal_mesh.number_of_faces() == mesh.face_count()) { return Cow(mesh); } @@ -595,27 +600,29 @@ Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMes cgal::SurfaceMesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); bool success; - bool is_same_as_input; + bool has_intersections; if (mesh.has_uvs()) { UvMap uv_map = cgal_mesh.property_map("v:uv").value(); UvInterpolatorVisitor visitor(uv_map, cgal_mesh); const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); - is_same_as_input = visitor.intersections.empty(); + has_intersections = visitor.intersections.empty(); } else { HasIntersectionsVisitor visitor; const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); - is_same_as_input = visitor.has_intersections; + has_intersections = visitor.has_intersections; } if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); } - - if (is_same_as_input) { + if (cgal_mesh.number_of_faces() == 0) { + return Cow(SimpleMesh()); + } + if (!has_intersections && cgal_mesh.number_of_faces() == mesh.face_count()) { return Cow(mesh); } - + cgal_mesh.collect_garbage(); SimpleMesh result = convert::to_simple_mesh(cgal_mesh); if (mesh.has_texture()) { diff --git a/src/terrainlib/mesh/convert.cpp b/src/terrainlib/mesh/convert.cpp index 29caa0a..806f998 100644 --- a/src/terrainlib/mesh/convert.cpp +++ b/src/terrainlib/mesh/convert.cpp @@ -30,10 +30,8 @@ SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { } } - mesh::validate(mesh); - for (const glm::uvec3 &triangle : mesh.triangles) { - const CGAL::SM_Face_index face = cgal_mesh.add_face( + const cgal::FaceIndex face = cgal_mesh.add_face( cgal::VertexIndex(triangle.x), cgal::VertexIndex(triangle.y), cgal::VertexIndex(triangle.z)); @@ -44,9 +42,11 @@ SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { } SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { + ASSERT(!cgal_mesh.has_garbage()); + SimpleMesh mesh; - auto uv_map_opt = cgal_mesh.property_map("v:uv"); + auto uv_map_opt = cgal_mesh.property_map("v:uv"); const bool has_uvs = uv_map_opt.has_value(); UvMap uv_map; if (has_uvs) { @@ -61,7 +61,7 @@ SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { } mesh.triangles.reserve(face_count); - for (const CGAL::SM_Vertex_index vertex_index : cgal_mesh.vertices()) { + for (const cgal::VertexIndex vertex_index : cgal_mesh.vertices()) { const Point3 &position = cgal_mesh.point(vertex_index); mesh.positions[vertex_index] = to_glm_point(position); if (has_uvs) { @@ -70,15 +70,17 @@ SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { } } - for (const CGAL::SM_Face_index face_index : cgal_mesh.faces()) { + for (const cgal::FaceIndex face_index : cgal_mesh.faces()) { glm::uvec3 triangle; unsigned int i = 0; - for (const CGAL::SM_Vertex_index vertex_index : CGAL::vertices_around_face(cgal_mesh.halfedge(face_index), cgal_mesh)) { + for (const cgal::VertexIndex vertex_index : CGAL::vertices_around_face(cgal_mesh.halfedge(face_index), cgal_mesh)) { triangle[i] = vertex_index; i++; } mesh.triangles.push_back(triangle); } + mesh::validate(mesh); + return mesh; } diff --git a/src/terrainlib/mesh/merge.cpp b/src/terrainlib/mesh/merge.cpp index 4491d15..17be55a 100644 --- a/src/terrainlib/mesh/merge.cpp +++ b/src/terrainlib/mesh/merge.cpp @@ -4,7 +4,6 @@ namespace mesh { -/* SimpleMesh merge(const std::span> meshes) { switch (meshes.size()) { case 0: @@ -16,7 +15,6 @@ SimpleMesh merge(const std::span> return merging::apply_mapping(meshes, mapping); } } - */ SimpleMesh merge(const std::span> meshes, double distance_epsilon) { switch (meshes.size()) { diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 2f66a9a..68a0c92 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -11,7 +11,7 @@ namespace mesh { -// SimpleMesh merge(const std::span> meshes); +SimpleMesh merge(const std::span> meshes); SimpleMesh merge(const std::span> meshes, double distance_epsilon); SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate); diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index fc81c2e..6996b02 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -14,6 +14,21 @@ namespace mesh::merging { +VertexMapping create_mapping(const std::span> meshes) { + if (meshes.empty()) { + return {}; + } + + const double average_edge_length_sum = std::accumulate( + meshes.begin(), meshes.end(), 0.0, + [](double sum, const std::reference_wrapper &mesh_ref) { + return sum + estimate_average_edge_length(mesh_ref.get()).value_or(0); + }); + const double average_edge_length = average_edge_length_sum / meshes.size(); + const double distance_epsilon = average_edge_length / 100; + return create_mapping(meshes, distance_epsilon); +} + VertexMapping create_mapping(const std::span> meshes, double distance_epsilon) { auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); auto deduplicate = EpsilonVertexDeduplicate(map, distance_epsilon); diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 26f3a5c..0daa063 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -9,6 +9,8 @@ namespace mesh::merging { // VertexMapping create_connecting_mapping(std::span meshes); +VertexMapping create_mapping( + const std::span> meshes); VertexMapping create_mapping( const std::span> meshes, double distance_epsilon); diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index 97a29df..29461fb 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -452,3 +452,12 @@ SimpleMesh reindex_mesh(const SimpleMesh &mesh) { new_mesh.texture = mesh.texture; return new_mesh; } + +void flip_triangle_orientation(glm::uvec3 &triangle) { + std::swap(triangle.z, triangle.x); +} +void flip_triangle_orientations(std::vector &triangles) { + for (auto& triangle : triangles) { + flip_triangle_orientation(triangle); + } +} diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index c08eba2..a20181b 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -55,4 +55,9 @@ void sort_and_normalize_triangles(std::span triangles); void reindex_mesh(SimpleMesh &mesh); SimpleMesh reindex_mesh(const SimpleMesh &mesh); +void flip_triangle_orientation(glm::uvec3 &triangle); +void flip_triangle_orientations(std::vector &triangles); +template +void flip_orientation(SimpleMesh_ &mesh); + #include "utils.inl" diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp index ead38e3..9d5ba13 100644 --- a/src/terrainlib/octree/storage/RawStorage.cpp +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -24,6 +24,19 @@ tl::expected RawStorage::copy_node_to(const Id &id, const R } std::error_code ec; const auto target_node_path = target.get_node_path(id); + if (source_node_path.extension() != target_node_path.extension()) { + // TODO: should this error instead? + const auto load_result = mesh::io::load_from_path(source_node_path); + if (!load_result.has_value()) { + + } + const Node node = load_result.value(); + const auto save_result = mesh::io::save_to_path(node, target_node_path); + if (!save_result.has_value()) { + + } + return {}; + } if (std::filesystem::remove(target_node_path, ec)) { if (ec) { return tl::unexpected(CopyMeshErrorKind::RemoveOld); diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 4bd6576..0668a06 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -52,7 +52,7 @@ struct MaybeIndex { } }; -struct MaybeCache : public ICache { +struct MaybeCache : public cache::ICache { std::optional> cache; explicit MaybeCache() @@ -127,7 +127,8 @@ class Storage { return result; } - tl::expected write_node(const Id &id, const Node &node) noexcept { + tl::expected write_node(const Id &id, const Node &node, const bool overwrite = false) noexcept { + // TODO: implement overwrite const auto result = this->_inner.write_node(id, node); if (result.has_value()) { this->_cache.put(id, node); @@ -196,11 +197,11 @@ class Storage { } } - std::optional>& cache() noexcept { + std::optional> &cache() noexcept { return this->_cache.cache; } - - std::optional> cache() const noexcept { + + std::optional> cache() const noexcept { if (this->_cache.cache.has_value()) { return *this->_cache.cache.value(); } else { diff --git a/src/terrainlib/octree/storage/cache/Dummy.h b/src/terrainlib/octree/storage/cache/Dummy.h index e32647a..9fed72d 100644 --- a/src/terrainlib/octree/storage/cache/Dummy.h +++ b/src/terrainlib/octree/storage/cache/Dummy.h @@ -6,14 +6,22 @@ #include "octree/storage/RawStorage.h" #include "octree/storage/cache/ICache.h" -namespace octree { +namespace octree::cache { class Dummy : public ICache { public: - std::optional get(const Id &) override { return std::nullopt; } - bool put(const Id &, const Node &) override { return false; } - bool remove(const Id &) override { return false; } - bool contains(const Id &) const override { return false; } + std::optional get(const Id &) noexcept override { + return std::nullopt; + } + bool put(const Id &, const Node &) noexcept override { + return false; + } + bool remove(const Id &) noexcept override { + return false; + } + bool contains(const Id &) const noexcept override { + return false; + } }; } diff --git a/src/terrainlib/octree/storage/cache/ICache.h b/src/terrainlib/octree/storage/cache/ICache.h index dd2eb5f..fb36f65 100644 --- a/src/terrainlib/octree/storage/cache/ICache.h +++ b/src/terrainlib/octree/storage/cache/ICache.h @@ -5,7 +5,7 @@ #include "octree/Id.h" #include "octree/storage/Node.h" -namespace octree { +namespace octree::cache { class ICache { public: diff --git a/src/terrainlib/octree/storage/cache/LruCache.h b/src/terrainlib/octree/storage/cache/LruCache.h index 8d34ec5..b1b317c 100644 --- a/src/terrainlib/octree/storage/cache/LruCache.h +++ b/src/terrainlib/octree/storage/cache/LruCache.h @@ -8,13 +8,13 @@ #include "octree/RawStorage.h" #include "octree/cache/ICache.h" -namespace octree { +namespace octree::cache { // TODO: UNTESTED template -class LruCache : public ICache { +class Lru : public ICache { public: - explicit LruCache(const size_t capacity) : _capacity(capacity) {} + explicit Lru(const size_t capacity) : _capacity(capacity) {} std::optional get(const Key& key) { auto it = this->_map.find(key); diff --git a/src/terrainlib/octree/storage/helpers.cpp b/src/terrainlib/octree/storage/helpers.cpp index 0192b24..b7c2a48 100644 --- a/src/terrainlib/octree/storage/helpers.cpp +++ b/src/terrainlib/octree/storage/helpers.cpp @@ -17,15 +17,34 @@ #include "octree/disk/layout/StrategyRegister.h" namespace octree::helpers { -std::optional> guess_layout_strategy( +namespace { +template +std::optional find_max_key(const std::unordered_map& map) { + if (map.empty()) { + return std::nullopt; + } + + auto max_it = map.begin(); + for (auto it = std::next(max_it); it != map.end(); it++) { + if (it->second > max_it->second) { + max_it = it; + } + } + + return max_it->first; +} +} + +std::optional guess_layout_strategy( const std::filesystem::path &base_path, - size_t max_files_to_check ) { + size_t max_files_to_check) { if (!std::filesystem::is_directory(base_path)) { return std::nullopt; } std::vector candidate_paths; + std::unordered_map extension_counters; for (const auto &entry : std::filesystem::recursive_directory_iterator(base_path)) { if (max_files_to_check == 0) { break; @@ -35,27 +54,39 @@ std::optional> guess_layout_strategy( } const auto ext = entry.path().extension(); - // TODO: manage these somewhere else - if (ext != ".terrain" && ext != ".glb" && ext != ".gltf") { + if (ext == ".index") { continue; } + extension_counters[ext]++; candidate_paths.emplace_back(std::filesystem::relative(entry.path(), base_path)); max_files_to_check--; } + std::optional most_common_ext = find_max_key(extension_counters); + + std::unique_ptr best_strategy; + size_t best_match_count = 0; + const auto &factories = disk::layout::StrategyRegister::instance().factories(); + for (const auto &[_, make_strategy] : factories) { + auto strategy = make_strategy(); // assume returns unique_ptr + + size_t match_count = 0; + for (const auto &rel_path : candidate_paths) { + if (strategy->get_id_from_relative_node_path(rel_path).has_value()) { + match_count++; + } + } - for (const auto &[_, make_strategy] : disk::layout::StrategyRegister::instance().factories()) { - auto strategy = make_strategy(); - bool matches_all = std::all_of(candidate_paths.begin(), candidate_paths.end(), - [&](const auto &rel_path) { - return strategy->get_id_from_relative_node_path(rel_path).has_value(); - }); - - if (matches_all) { - return strategy; + if (match_count > best_match_count) { + best_match_count = match_count; + best_strategy = std::move(strategy); } } + if (best_strategy && most_common_ext.has_value()) { + return LayoutWithoutBase(std::move(best_strategy), most_common_ext.value()); + } + return std::nullopt; } diff --git a/src/terrainlib/octree/storage/helpers.h b/src/terrainlib/octree/storage/helpers.h index 21ce111..a7dff81 100644 --- a/src/terrainlib/octree/storage/helpers.h +++ b/src/terrainlib/octree/storage/helpers.h @@ -14,7 +14,12 @@ namespace octree::helpers { -std::optional> guess_layout_strategy( +struct LayoutWithoutBase { + std::unique_ptr strategy; + std::string extension_with_dot; +}; + +std::optional guess_layout_strategy( const std::filesystem::path &base_path, size_t max_files_to_check = 100); tl::expected save_index_map(const IndexMap &index, const disk::Layout &layout); diff --git a/src/terrainlib/octree/storage/open.cpp b/src/terrainlib/octree/storage/open.cpp index a77494d..6415369 100644 --- a/src/terrainlib/octree/storage/open.cpp +++ b/src/terrainlib/octree/storage/open.cpp @@ -35,9 +35,8 @@ tl::expected open_index(const std::filesystem::path & Storage open_folder( const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy, - const std::string extension_with_dot, - bool create_index) { + bool create_index, + OpenOptions options) { LOG_TRACE("Opening storage folder {}", base_path); if (!std::filesystem::is_directory(base_path)) { @@ -56,17 +55,25 @@ Storage open_folder( return Storage(std::move(storage_opt.value())); } - auto layout_strategy_opt = helpers::guess_layout_strategy(base_path); - if (layout_strategy_opt) { - LOG_TRACE("Guessed layout of dataset as {}", - disk::layout::StrategyRegister::instance().get_id(**layout_strategy_opt)); + auto layout_info_opt = helpers::guess_layout_strategy(base_path); + if (layout_info_opt.has_value()) { + const octree::helpers::LayoutWithoutBase &layout_info = layout_info_opt.value(); + LOG_TRACE("Guessed layout strategy of dataset as {} and extension as {}", + disk::layout::StrategyRegister::instance().get_id(*layout_info.strategy), + layout_info.extension_with_dot); } else { - LOG_WARN("Unable to determine layout of dataset, using default which is {}", - disk::layout::StrategyRegister::instance().get_id(*default_layout_strategy)); - layout_strategy_opt = std::move(default_layout_strategy); + auto default_layout_strategy = std::move(options.default_layout_strategy); + if (!default_layout_strategy) { + default_layout_strategy = disk::layout::strategy::make_default(); + } + auto default_extension_with_dot = options.preferred_extension_with_dot.has_value() ? options.preferred_extension_with_dot.value() : ".terrain"; + LOG_WARN("Unable to determine layout of dataset, using layout strategy {} and extension {}", + disk::layout::StrategyRegister::instance().get_id(*default_layout_strategy), + default_extension_with_dot); + layout_info_opt = std::move(octree::helpers::LayoutWithoutBase(std::move(default_layout_strategy), default_extension_with_dot)); } - disk::Layout layout(base_path, std::move(*layout_strategy_opt), extension_with_dot); + disk::Layout layout(base_path, std::move(layout_info_opt->strategy), layout_info_opt->extension_with_dot); if (!create_index) { return Storage(RawStorage(std::move(layout))); } @@ -81,9 +88,8 @@ Storage open_folder( IndexedStorage open_folder_indexed( const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy, - const std::string extension_with_dot) { - return IndexedStorage(open_folder(base_path, std::move(default_layout_strategy), extension_with_dot, true)); + OpenOptions options) { + return IndexedStorage(open_folder(base_path, true, std::move(options))); } } // namespace octree diff --git a/src/terrainlib/octree/storage/open.h b/src/terrainlib/octree/storage/open.h index 824b34a..7f9d780 100644 --- a/src/terrainlib/octree/storage/open.h +++ b/src/terrainlib/octree/storage/open.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -12,15 +13,18 @@ namespace octree { +struct OpenOptions { + std::unique_ptr default_layout_strategy; + std::optional preferred_extension_with_dot; +}; + tl::expected open_index(const std::filesystem::path &index_path); Storage open_folder( const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), - const std::string extension_with_dot = ".terrain", - bool create_index = false); + const bool create_index = false, + OpenOptions options = {}); IndexedStorage open_folder_indexed( const std::filesystem::path &base_path, - std::unique_ptr default_layout_strategy = disk::layout::strategy::make_default(), - const std::string extension_with_dot = ".terrain"); + OpenOptions options = {}); } \ No newline at end of file diff --git a/src/terrainlib/optional_utils.h b/src/terrainlib/optional_utils.h new file mode 100644 index 0000000..d0ba3bc --- /dev/null +++ b/src/terrainlib/optional_utils.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +template +std::optional> as_ref(const std::optional &option) { + if (option.has_value()) { + return option.value(); + } else { + return std::nullopt; + } +} + +template +auto map(const std::optional &option, Func &&f) -> std::optional> { + using U = std::invoke_result_t; + + if (option.has_value()) { + return std::optional{f(option.value())}; + } else { + return std::nullopt; + } +} + +template +std::optional flatten(const std::optional> option) { + if (option.has_value()) { + return option.value(); + } else { + return std::nullopt; + } +} diff --git a/src/terrainmerger/NodeLoader.h b/src/terrainmerger/NodeLoader.h index fa3f08f..b29dd20 100644 --- a/src/terrainmerger/NodeLoader.h +++ b/src/terrainmerger/NodeLoader.h @@ -19,7 +19,7 @@ class NodeLoader { NodeLoader(const octree::IndexedStorage &storage, octree::cache::ICache &cache) : _storage(storage), _cache(cache), _space(octree::Space::earth()) { if (storage.cache().has_value() && dynamic_cast(&cache) != nullptr) { - LOG_WARN("Backing storage for NodeLoader instance is cached but another cache was provided leading to double caching."); + LOG_WARN("Backing storage for NodeLoader instance is cached, but another cache was provided leading to double caching."); } } diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index 7020454..96282ff 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -71,8 +71,8 @@ Args cli::parse(int argc, const char *const *argv) { try { // app.parse(argc, argv); // app.parse("--input ../../../meshes/innenstadt2 ../../../meshes/vienna2 --output ../../../meshes/out --verbosity trace"); - // app.parse("merge --new ../../../meshes/innenstadt3 --base ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out --verbosity trace"); - app.parse("cut --input ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out3 --verbosity trace"); + app.parse("merge --new ../../../meshes/innenstadt3 --base ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out --verbosity trace"); + // app.parse("cut --input ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out3 --verbosity trace"); std::filesystem::remove_all("../../../meshes/out3"); } catch (const CLI::ParseError &e) { exit(app.exit(e)); diff --git a/src/terrainmerger/cut.h b/src/terrainmerger/cut.h index 5dcf241..f3d3013 100644 --- a/src/terrainmerger/cut.h +++ b/src/terrainmerger/cut.h @@ -87,16 +87,18 @@ inline void cut_node( const MeshMask& mask ) { if (mask.mesh.is_empty()) { + LOG_TRACE("Mesh was fully ouside the mask"); return; } /* Uncomment to output masks + */ const auto path = ctx.output.get_node_path(id); const auto new_path = path.parent_path() / (path.stem().string() + "-mask" + path.extension().string()); mesh::io::save_to_path(mask.mesh, new_path); - */ + const auto status_opt = ctx.input.index().get(id); if (!status_opt.has_value()) { diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h index 678dd69..484d528 100644 --- a/src/terrainmerger/mask.h +++ b/src/terrainmerger/mask.h @@ -271,10 +271,10 @@ inline tl::expected load_referenced_from_datas // TODO: remove this try catch try { srs = mask_dataset.srs(); - srs.SetAxisMappingStrategy(OAMS_AUTHORITY_COMPLIANT); // TODO } catch (std::runtime_error &e) { LOG_WARN("Mask does not reference an srs, assuming WGS84"); srs = srs::wgs84(); + // srs.SetAxisMappingStrategy(OAMS_AUTHORITY_COMPLIANT); } return ReferencedPolygonMask{.polygons = std::move(polygons), .srs = std::move(srs)}; diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index eba276b..17f2dbd 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -64,7 +64,8 @@ class Masked : public Base { Result visit( const octree::Id &, NodeData &left, - NodeData &right) { + NodeData &right, + ) { if constexpr (right.status() == Status::Missing) { return Unchanged{false}; diff --git a/unittests/terrainlib/spatial_multi_hashmap.cpp b/unittests/terrainlib/spatial_multi_hashmap.cpp new file mode 100644 index 0000000..e69de29 From 3c3afd6f7f742742fa28a492c1e52447ab9420c7 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 12 Aug 2025 14:12:03 +0200 Subject: [PATCH 100/122] Fix terrainbuilder --- src/terrainbuilder/mesh_builder.cpp | 3 --- src/terrainbuilder/terrainbuilder.cpp | 7 +++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/terrainbuilder/mesh_builder.cpp index deb323f..d79abbd 100644 --- a/src/terrainbuilder/mesh_builder.cpp +++ b/src/terrainbuilder/mesh_builder.cpp @@ -21,9 +21,6 @@ #include "mesh/clip.h" #include "mesh/validate.h" -// TODO: remove -#include "raster_to_image.h" - // TODO: fix namespace namespace terrainbuilder { diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/terrainbuilder/terrainbuilder.cpp index 4c15def..a15f926 100644 --- a/src/terrainbuilder/terrainbuilder.cpp +++ b/src/terrainbuilder/terrainbuilder.cpp @@ -186,8 +186,11 @@ void build_all_patches( octree::Storage storage = octree::open_folder( output_base_path, - octree::disk::layout::strategy::make_default(), - output_format); + false, + octree::OpenOptions { + .preferred_extension_with_dot = output_format + } + ); const auto dataset_srs = dataset.srs(); const auto dataset_bounds = dataset.bounds3d(true); From eb12ac4b2f9a8e72ad6f071948c8166e76ac689e Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 12 Aug 2025 14:12:18 +0200 Subject: [PATCH 101/122] Fix index building --- src/terrainlib/octree/storage/helpers.cpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/terrainlib/octree/storage/helpers.cpp b/src/terrainlib/octree/storage/helpers.cpp index b7c2a48..0983fc2 100644 --- a/src/terrainlib/octree/storage/helpers.cpp +++ b/src/terrainlib/octree/storage/helpers.cpp @@ -129,25 +129,7 @@ void update_index_map(IndexMap &index, const disk::Layout &layout) { } const Id id = *id_opt; - index.set_raw(id, NodeStatus::Leaf); - } - - std::unordered_set visited; - for (const auto &[id, _] : index) { - auto parent = id.parent(); - while (parent) { - if (visited.find(*parent) != visited.end()) { - break; - } - visited.insert(*parent); - - if (index.get(*parent)) { - index.set_raw(*parent, NodeStatus::Inner); - } else { - index.set_raw(*parent, NodeStatus::Virtual); - } - parent = parent->parent(); - } + index.add(id); } } From 23e7eab2c659213ad5fa322ccb4799f2cbe11b3c Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 12 Aug 2025 17:23:15 +0200 Subject: [PATCH 102/122] Support showing mesh metadata in index_browser --- src/index_browser/cli.cpp | 4 +- src/index_browser/main.cpp | 112 ++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/index_browser/cli.cpp b/src/index_browser/cli.cpp index d03b873..8b19db3 100644 --- a/src/index_browser/cli.cpp +++ b/src/index_browser/cli.cpp @@ -18,6 +18,7 @@ Args cli::parse(int argc, const char * const * argv) { ->check(CLI::ExistingPath) ->required(); + args.full_view = false; app.add_flag("--full", args.full_view, "Start at octree root instead of dataset root."); const std::map @@ -34,7 +35,8 @@ Args cli::parse(int argc, const char * const * argv) { ->default_val(spdlog::level::level_enum::info); try { - app.parse(argc, argv); + app.parse("--dataset ../../../meshes/innenstadt"); + // app.parse(argc, argv); } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/index_browser/main.cpp b/src/index_browser/main.cpp index 3e90b9d..764b34e 100644 --- a/src/index_browser/main.cpp +++ b/src/index_browser/main.cpp @@ -17,20 +17,31 @@ #include "cli.h" namespace { -struct DisplayNode { +struct IndexNode { octree::Id id; octree::NodeStatusOrMissing status; bool expanded = false; }; +struct MeshNode { + octree::Id id; + size_t vertex_count; + size_t face_count; +}; +struct ErrorNode { + octree::Id id; + std::string message; +}; + +using DisplayEntry = std::variant; class TreeView { public: - using iterator = std::list::iterator; - using const_iterator = std::list::const_iterator; + using iterator = std::list::iterator; + using const_iterator = std::list::const_iterator; - explicit TreeView(const octree::IndexMap &index, const octree::Id root) : root(root), _index(index) { - const octree::NodeStatusOrMissing status = this->_index.get(root); - this->_view.emplace_back(root, status, false); + explicit TreeView(const octree::IndexedStorage &storage, const octree::Id root) : root(root), _storage(storage) { + const octree::NodeStatusOrMissing status = this->_storage.index().get(root); + this->_view.emplace_back(IndexNode{root, status, false}); } size_t size() const { @@ -56,23 +67,43 @@ class TreeView { return expand_node(it); } void expand_node(iterator it) { - DisplayNode &parent = *it; - if (parent.expanded || !parent.id.has_children()) { + if (!std::holds_alternative(*it)) { + return; + } + IndexNode &parent = std::get(*it); + if (parent.expanded) { + return; + } + parent.expanded = true; + + if (parent.status == octree::NodeStatusOrMissing::Leaf) { + auto result = this->_storage.read_node(parent.id); + DisplayEntry entry; + if (result.has_value()) { + const auto &mesh = result.value(); + entry = MeshNode{parent.id, mesh.vertex_count(), mesh.face_count()}; + } else { + entry = ErrorNode{parent.id, result.error().description()}; + } + it++; + it = this->_view.emplace(it, entry); return; } + if (!parent.id.has_children()) { + return; + } const auto children = parent.id.children().value(); for (const auto &child_id : children) { - auto status_opt = this->_index.get(child_id); + auto status_opt = this->_storage.index().get(child_id); if (!status_opt.has_value()) { continue; } const octree::NodeStatus status = status_opt.value(); + IndexNode child_node{child_id, status, false}; it++; - it = this->_view.emplace(it, child_id, status, false); + it = this->_view.emplace(it, child_node); } - - parent.expanded = true; } void collapse_node(const size_t display_index) { @@ -81,37 +112,40 @@ class TreeView { return collapse_node(it); } void collapse_node(iterator it) { - DisplayNode &parent = *it; + if (!std::holds_alternative(*it)) { + return; + } + IndexNode &parent = std::get(*it); if (!parent.expanded) { return; } + parent.expanded = false; + + if (parent.status == octree::NodeStatusOrMissing::Leaf) { + it++; + it = this->_view.erase(it); + return; + } it++; while (it != this->_view.end()) { - DisplayNode &node = *it; - if (node.id.parent() != parent.id) { + const octree::Id id = std::visit([](const auto &node) { return node.id; }, *it); + if (id.parent() != parent.id) { break; } - if (node.expanded) { - this->collapse_node(it); - } + this->collapse_node(it); it = this->_view.erase(it); } - - parent.expanded = false; } const octree::Id root; private: - std::list _view; - const octree::IndexMap &_index; + std::list _view; + const octree::IndexedStorage& _storage; }; -//--------------------------------------------------------------------- -// Find the first non‑virtual node by BFS (may use octree::traverse) -//--------------------------------------------------------------------- const octree::Id find_deepest_root(const octree::IndexMap &index, const octree::Id &root = octree::Id::root()) { switch (octree::NodeStatusOrMissing(index.get(root))) { case octree::NodeStatusOrMissing::Missing: @@ -155,13 +189,27 @@ octree::IndexedStorage open_path_indexed(const std::filesystem::path& path) { } } -ftxui::Element render_line(const DisplayNode &node, size_t base_level, bool is_selected) { - const size_t depth = node.id.level() - base_level; +std::string render_line_content(const DisplayEntry &entry) { + return std::visit([](const auto &node) { + using NodeType = std::remove_cvref_t; + if constexpr (std::is_same_v) { + return fmt::format("{} [{}]", node.id, node.status); + } else if constexpr (std::is_same_v) { + return fmt::format("Mesh({} vertices, {} faces)", node.vertex_count, node.face_count); + } else if constexpr (std::is_same_v) { + return fmt::format("Error({})", node.message); + } + }, entry); +} +ftxui::Element render_line(const DisplayEntry &entry, size_t base_level, bool is_selected) { + const octree::Id id = std::visit([](const auto &node) { return node.id; }, entry); + size_t depth = id.level() - base_level; + if (!std::holds_alternative(entry)) { + depth += 1; + } const size_t indent = depth * 2; - auto text_line = ftxui::text(fmt::format("{:<{}} {} [{}]", - "", indent, - node.id, - node.status)); + auto text_line = ftxui::text(fmt::format("{:<{}} {}", + "", indent, render_line_content(entry))); if (is_selected) { return text_line | ftxui::inverted; } @@ -173,7 +221,7 @@ int run(const cli::Args &args) { const octree::IndexMap &index = storage.index(); const octree::Id root_id = args.full_view ? octree::Id::root() : find_deepest_root(index); - TreeView tree_view(index, root_id); + TreeView tree_view(storage, root_id); size_t selected = 0; auto renderer = ftxui::Renderer([&] { From 44d42e98fb8f2b17c242d3c6b190df3207a24b07 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 14 Aug 2025 13:58:00 +0200 Subject: [PATCH 103/122] Mostly fix merger, fix clipper --- src/terrainlib/mesh/boolean.cpp | 6 -- src/terrainlib/mesh/clip.cpp | 24 +++++- src/terrainlib/mesh/clip.h | 2 +- src/terrainlib/mesh/utils.inl | 5 ++ src/terrainlib/octree/storage/Error.h | 4 +- src/terrainlib/octree/storage/RawStorage.cpp | 50 +++++++++++- src/terrainlib/octree/storage/RawStorage.h | 3 +- src/terrainlib/octree/storage/Storage.h | 18 +++-- src/terrainmerger/NodeLoader.h | 7 +- src/terrainmerger/NodeWriter.h | 2 +- src/terrainmerger/cli.cpp | 7 +- src/terrainmerger/cli.h | 1 + src/terrainmerger/cut.h | 31 +++---- src/terrainmerger/main.cpp | 13 ++- src/terrainmerger/merge.h | 20 +++-- src/terrainmerger/merge/NodeData.h | 2 +- src/terrainmerger/merge/Result.h | 2 +- src/terrainmerger/merge/visitor/Masked.h | 85 +++++++++++++++----- src/terrainmerger/utils.h | 17 +++- 19 files changed, 216 insertions(+), 83 deletions(-) diff --git a/src/terrainlib/mesh/boolean.cpp b/src/terrainlib/mesh/boolean.cpp index 08f9aaf..30ce053 100644 --- a/src/terrainlib/mesh/boolean.cpp +++ b/src/terrainlib/mesh/boolean.cpp @@ -37,10 +37,4 @@ IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const return result; } - -SimpleMesh difference(const SimpleMesh &a, const SimpleMesh &b) { - SimpleMesh b_inv(b.triangles, b.positions); - flip_orientation(b_inv); - return mesh::clip_on_mesh(a, b_inv); -} } \ No newline at end of file diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index 1f0c3ee..8860f4f 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -593,7 +593,26 @@ struct UvInterpolatorVisitor : public CGAL::Polygon_mesh_processing::Corefinemen }; } // namespace -Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh) { +Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh &clip_mesh, const bool keep_inside) { + // short circuit the empty mesh case + // this is a common case since we clip the mask in the terrainmerger on the octree node bounds + // which often results in empty masks + if (clip_mesh.face_count() == 0) { + if (keep_inside) { + return Cow::from_owned(SimpleMesh()); + } else { + return Cow::from_ref(mesh); + } + } + + // If we want to keep everything outside the clip_mesh we simply invert it and recurse + if (!keep_inside) { + SimpleMesh clip_mesh_inv(clip_mesh.triangles, clip_mesh.positions); + flip_orientation(clip_mesh_inv); + return mesh::clip_on_mesh(mesh, clip_mesh_inv, !keep_inside); + } + + // Convert both meshes to cgal and use their clipping logic. using UvMap = cgal::SurfaceMesh::Property_map; cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); @@ -606,7 +625,7 @@ Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMes UvInterpolatorVisitor visitor(uv_map, cgal_mesh); const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); - has_intersections = visitor.intersections.empty(); + has_intersections = !visitor.intersections.empty(); } else { HasIntersectionsVisitor visitor; const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); @@ -630,4 +649,3 @@ Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMes } return Cow(std::move(result)); } - diff --git a/src/terrainlib/mesh/clip.h b/src/terrainlib/mesh/clip.h index 852e74c..09dad90 100644 --- a/src/terrainlib/mesh/clip.h +++ b/src/terrainlib/mesh/clip.h @@ -12,6 +12,6 @@ Cow clip_on_bounds_and_cap( const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds, const bool remesh_planar_patches = true); -Cow clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh); +Cow clip_on_mesh(const SimpleMesh &mesh, const SimpleMesh& clip_mesh, const bool keep_inside = true); } diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl index 56a5b14..55fa527 100644 --- a/src/terrainlib/mesh/utils.inl +++ b/src/terrainlib/mesh/utils.inl @@ -27,3 +27,8 @@ template void sort_and_normalize_triangles(SimpleMesh_ &mesh) { sort_and_normalize_triangles(mesh.triangles); } + +template +void flip_orientation(SimpleMesh_ &mesh) { + flip_triangle_orientations(mesh.triangles); +} diff --git a/src/terrainlib/octree/storage/Error.h b/src/terrainlib/octree/storage/Error.h index 892534e..4512d09 100644 --- a/src/terrainlib/octree/storage/Error.h +++ b/src/terrainlib/octree/storage/Error.h @@ -9,7 +9,9 @@ enum class CopyMeshErrorKind { FileNotFound, CreateLink, CreateDirectories, - RemoveOld + RemoveOld, + Read, + Write }; // TODO: store the std::error_code in the CopyMeshError diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp index 9d5ba13..c6e4356 100644 --- a/src/terrainlib/octree/storage/RawStorage.cpp +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -16,7 +16,7 @@ tl::expected RawStorage::write_node(const Id &id, const auto node_path = this->get_node_path(id); return mesh::io::save_to_path(node, node_path); } - +/* tl::expected RawStorage::copy_node_to(const Id &id, const RawStorage &target) const noexcept { const auto source_node_path = this->get_node_path(id); if (!this->has_node(id)) { @@ -55,6 +55,54 @@ tl::expected RawStorage::copy_node_to(const Id &id, const R } return {}; } +*/ +tl::expected RawStorage::copy_node_from(const Id &id, const RawStorage &source) noexcept { + if (!source.has_node(id)) { + return tl::unexpected(CopyMeshErrorKind::FileNotFound); + } + + const auto source_node_path = source.get_node_path(id); + const auto target_node_path = this->get_node_path(id); + if (source_node_path.extension() != target_node_path.extension()) { + // TODO: should this error instead? + const auto load_result = mesh::io::load_from_path(source_node_path); + if (!load_result.has_value()) { + return tl::unexpected(CopyMeshErrorKind::Read); + } + const Node node = load_result.value(); + const auto save_result = mesh::io::save_to_path(node, target_node_path); + if (!save_result.has_value()) { + return tl::unexpected(CopyMeshErrorKind::Write); + } + return {}; + } + + std::error_code ec; + if (std::filesystem::remove(target_node_path, ec)) { + if (ec) { + return tl::unexpected(CopyMeshErrorKind::RemoveOld); + } + } + + std::filesystem::create_directories(target_node_path.parent_path(), ec); + if (ec) { + return tl::unexpected(CopyMeshErrorKind::CreateDirectories); + } + + std::filesystem::create_hard_link( + source_node_path, + target_node_path, + ec); + if (ec) { + return tl::unexpected(CopyMeshErrorKind::CreateLink); + } + + return {}; +} + +tl::expected RawStorage::copy_node_to(const Id &id, RawStorage &target) const noexcept { + return target.copy_node_from(id, *this); +} bool RawStorage::remove_node(const Id &id) const noexcept { const auto node_path = this->get_node_path(id); diff --git a/src/terrainlib/octree/storage/RawStorage.h b/src/terrainlib/octree/storage/RawStorage.h index e1c3789..a011bb0 100644 --- a/src/terrainlib/octree/storage/RawStorage.h +++ b/src/terrainlib/octree/storage/RawStorage.h @@ -23,7 +23,8 @@ class RawStorage { tl::expected read_node(const Id &id) const noexcept; tl::expected write_node(const Id &id, const Node &node) const noexcept; - tl::expected copy_node_to(const Id &id, const RawStorage &target) const noexcept; + tl::expected copy_node_from(const Id &id, const RawStorage &target) noexcept; + tl::expected copy_node_to(const Id &id, RawStorage &target) const noexcept; bool remove_node(const Id &id) const noexcept; bool has_node(const Id &id) const noexcept; std::filesystem::path get_node_path(const Id &id) const noexcept; diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 0668a06..6e7f138 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -137,20 +137,24 @@ class Storage { return result; } - tl::expected copy_node_to(const Id &id, Storage &target) const { - if (!this->_index.contains(id, true)) { + tl::expected copy_node_from(const Id &id, const Storage &source) noexcept { + if (!source._index.contains(id, true)) { return tl::unexpected(CopyMeshErrorKind::FileNotFound); } - - const auto result = this->_inner.copy_node_to(id, target._inner); - if (result.has_value() && target.is_indexed()) { - auto& index = target.index_mut().value(); + // TODO: check overwrite + const auto result = this->_inner.copy_node_from(id, source._inner); + if (result.has_value() && this->is_indexed()) { + auto& index = this->_index.map.value(); index.add(id); - target.set_index_dirty(); + this->set_index_dirty(); } return result; } + tl::expected copy_node_to(const Id &id, Storage &target) const noexcept { + return target.copy_node_from(id, *this); + } + bool remove_node(const Id &id) noexcept { this->_cache.remove(id); this->_index.remove(id); diff --git a/src/terrainmerger/NodeLoader.h b/src/terrainmerger/NodeLoader.h index b29dd20..48075bd 100644 --- a/src/terrainmerger/NodeLoader.h +++ b/src/terrainmerger/NodeLoader.h @@ -16,8 +16,8 @@ class NodeLoader { public: - NodeLoader(const octree::IndexedStorage &storage, octree::cache::ICache &cache) - : _storage(storage), _cache(cache), _space(octree::Space::earth()) { + NodeLoader(const octree::IndexedStorage &storage, octree::cache::ICache &cache, octree::Space space) + : _storage(storage), _cache(cache), _space(space) { if (storage.cache().has_value() && dynamic_cast(&cache) != nullptr) { LOG_WARN("Backing storage for NodeLoader instance is cached, but another cache was provided leading to double caching."); } @@ -28,6 +28,7 @@ class NodeLoader { } // Try to retrieve or reconstruct node mesh by ID + // TODO: return const ref instead? std::optional load_node(const octree::Id &id) const noexcept { // Try cache if (auto cached = this->_cache.get(id); cached.has_value()) { @@ -54,7 +55,7 @@ class NodeLoader { // Try storage auto parent_mesh_opt = this->_storage.read_node(parent_id); if (parent_mesh_opt.has_value()) { - auto parent_mesh = mesh_opt.value(); + auto parent_mesh = parent_mesh_opt.value(); const auto bounds = this->_space.get_node_bounds(id); const auto clipped = mesh::clip_on_bounds(parent_mesh, bounds); this->_cache.put(id, clipped); diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index 6dd0a74..85c0fdc 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -37,7 +37,7 @@ class NodeWriter { } DEBUG_ASSERT(status == octree::NodeStatus::Leaf); - DEBUG_ASSERT_VAL(loader.storage().copy_node_to(child_id, this->_storage)); + DEBUG_ASSERT_VAL(this->_storage.copy_node_from(child_id, loader.storage())); }, octree::always_refine, id); diff --git a/src/terrainmerger/cli.cpp b/src/terrainmerger/cli.cpp index 96282ff..7afe3c0 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/terrainmerger/cli.cpp @@ -51,6 +51,8 @@ Args cli::parse(int argc, const char *const *argv) { cut.add_option("--output", cut_args.output_path, "Path to output the cut dataset to"); + app.add_flag("--keep-inside,!--keep-outside", cut_args.keep_inside, "Keep the part of the dataset thats inside/outside the mask."); + cut.fallthrough(); spdlog::level::level_enum log_level; @@ -71,9 +73,8 @@ Args cli::parse(int argc, const char *const *argv) { try { // app.parse(argc, argv); // app.parse("--input ../../../meshes/innenstadt2 ../../../meshes/vienna2 --output ../../../meshes/out --verbosity trace"); - app.parse("merge --new ../../../meshes/innenstadt3 --base ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out --verbosity trace"); - // app.parse("cut --input ../../../meshes/vienna2 --mask ../../../meshes/mask.geojson --output ../../../meshes/out3 --verbosity trace"); - std::filesystem::remove_all("../../../meshes/out3"); + app.parse("merge --new ../../../meshes/innenstadt --base ../../../meshes/vienna --mask ../../../meshes/mask.geojson --output ../../../meshes/out-merge --verbosity trace"); + // app.parse("cut --input ../../../meshes/innenstadt --mask ../../../meshes/mask.geojson --output ../../../meshes/out-cut --keep-outside --verbosity trace"); } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/terrainmerger/cli.h b/src/terrainmerger/cli.h index 13e42c3..d8fb6f8 100644 --- a/src/terrainmerger/cli.h +++ b/src/terrainmerger/cli.h @@ -32,6 +32,7 @@ struct CutArgs : public BaseArgs { std::filesystem::path input_path; std::filesystem::path output_path; std::filesystem::path mask_path; + bool keep_inside; }; using Args = std::variant; diff --git a/src/terrainmerger/cut.h b/src/terrainmerger/cut.h index f3d3013..39ebb5c 100644 --- a/src/terrainmerger/cut.h +++ b/src/terrainmerger/cut.h @@ -18,6 +18,7 @@ struct Context { const octree::IndexedStorage& input; octree::Storage& output; const octree::Space space; + const bool keep_inside; }; void cut_node( @@ -35,10 +36,10 @@ inline void cut_leaf_node( const SimpleMesh mesh = DEBUG_ASSERT_VAL(ctx.input.read_node(id)).value(); LOG_TRACE("Cutting mesh at {} using mask with {} vertices and {} triangles", id, mask.mesh.vertex_count(), mask.mesh.face_count()); - const Cow clipped = clip_on_mask(mesh, mask); + const Cow clipped = clip_on_mask(mesh, mask, ctx.keep_inside); if (clipped.is_ref()) { LOG_TRACE("Mesh was fully inside the mask"); - DEBUG_ASSERT_VAL(ctx.input.copy_node_to(id, ctx.output)); + DEBUG_ASSERT_VAL(ctx.output.copy_node_from(id, ctx.input)); } else { const SimpleMesh &clipped_mesh = clipped; if (!clipped_mesh.is_empty()) { @@ -46,23 +47,11 @@ inline void cut_leaf_node( mesh.vertex_count(), mesh.face_count(), clipped_mesh.vertex_count(), clipped_mesh.face_count()); DEBUG_ASSERT_VAL(ctx.output.write_node(id, clipped_mesh)); } else { - LOG_TRACE("Mesh was fully ouside the mask"); + LOG_TRACE("Mesh was fully outside the mask"); } } } -namespace { -template -radix::geometry::Aabb pad_bounds(const radix::geometry::Aabb &bounds, const T factor) { - using Vec = glm::vec; - const Vec center = bounds.centre(); - const Vec half_size = bounds.size() * (factor / T(2)); - const Vec new_min = center - half_size; - const Vec new_max = center + half_size; - return radix::geometry::Aabb(new_min, new_max); -} -} - inline void cut_virtual_node( Context& ctx, const octree::Id& id, @@ -86,8 +75,8 @@ inline void cut_node( const octree::Id& id, const MeshMask& mask ) { - if (mask.mesh.is_empty()) { - LOG_TRACE("Mesh was fully ouside the mask"); + if (ctx.keep_inside && mask.mesh.is_empty()) { + LOG_TRACE("Mesh was fully outside the mask"); return; } @@ -122,7 +111,8 @@ inline void cut_node( inline void cut_dataset( const octree::IndexedStorage &input, const MeshMask& mask, - octree::Storage &output) { + octree::Storage &output, + const bool keep_inside) { Context ctx(input, output, octree::Space::earth()); cut_node(ctx, octree::Id::root(), mask); output.save_or_create_index(); @@ -131,7 +121,8 @@ inline void cut_dataset( inline void cut_dataset( const octree::IndexedStorage &input_dataset, const MeshMask& mask, - const std::filesystem::path &output_path) { + const std::filesystem::path &output_path, + const bool keep_inside) { LOG_TRACE("Creating output dataset at {}", output_path); std::filesystem::create_directories(output_path); @@ -140,6 +131,6 @@ inline void cut_dataset( LOG_ERROR_AND_EXIT("Output dataset has to be empty."); } - cut_dataset(input_dataset, mask, output_dataset); + cut_dataset(input_dataset, mask, output_dataset, keep_inside); } diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index a85e55a..ddcf270 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -40,7 +40,7 @@ void run(const cli::MergeArgs& args) { LOG_TRACE("Creating output dataset at {}", args.output_path); std::filesystem::create_directories(args.output_path); - octree::Storage output_dataset = octree::open_folder(args.output_path); + octree::Storage output_dataset = octree::open_folder(args.output_path, false, octree::OpenOptions{.preferred_extension_with_dot = ".glb"}); std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); @@ -51,7 +51,7 @@ void run(const cli::CutArgs& args) { LOG_TRACE("Loading input dataset from {}", args.input_path); const octree::IndexedStorage input_dataset = octree::open_folder_indexed(args.input_path); const MeshMask mask = DEBUG_ASSERT_VAL(load_mask_from_path(args.mask_path)).value(); - cut_dataset(input_dataset, mask, args.output_path); + cut_dataset(input_dataset, mask, args.output_path, args.keep_inside); } void run(const cli::Args &args) { @@ -69,6 +69,15 @@ int main(int argc, char **argv) { }); LOG_DEBUG("Running with: {}", arg_str); + // TODO: remove + std::filesystem::path source = "../../../meshes/out-merge"; + std::filesystem::path destination = "/mnt/c/Users/Admin/Downloads/out-merge"; + std::filesystem::remove_all(source); run(args); + std::filesystem::remove_all(destination); + std::filesystem::create_directories(destination); + std::filesystem::copy(source, destination, + std::filesystem::copy_options::recursive | + std::filesystem::copy_options::overwrite_existing); } diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index e200f83..57d2de9 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -32,10 +32,9 @@ class Merger { Merger( Visitor& visitor, - const NodeLoader &left, - const NodeLoader &right, - NodeWriter &output) : _visitor(visitor), _left(left), _right(right), _output(output) { - + NodeLoader left, + NodeLoader right, + NodeWriter output) : _visitor(visitor), _left(left), _right(right), _output(output) { } void merge_node(const octree::Id &id) { @@ -50,23 +49,27 @@ class Merger { const Status right_status ) { if (this->_output.has_node(id)) { - return; // Already merged perviously + return; // Already merged previously } const auto merge_result = this->call_merge(id, left_status, right_status); std::visit([&](const auto &result) { using Result = std::decay_t; if constexpr (std::is_same_v) { + LOG_DEBUG("Node {} needs recusion", id); DEBUG_ASSERT(id.has_children()); const auto children = id.children().value(); for (const auto &child_id : children) { this->merge_node(child_id); } } else if constexpr (std::is_same_v) { + LOG_DEBUG("Node {} remains unchanged (same as {})", id, (result.is_left ? "left" : "right")); this->_output.copy_subtree_to_output(id, result.is_left ? this->_left : this->_right); } else if constexpr (std::is_same_v) { + LOG_DEBUG("Node {} was merged", id); this->_output.write_node(id, result.mesh); } else if constexpr (std::is_same_v) { + LOG_DEBUG("Node {} was ignored", id); // do nothing } }, merge_result); @@ -132,13 +135,14 @@ inline void merge_datasets( get_dataset_name(right_dataset), get_dataset_name(output_dataset)); + octree::Space space = octree::Space::earth(); octree::cache::Dummy left_cache; - NodeLoader left(left_dataset, left_cache); + NodeLoader left(left_dataset, left_cache, space); octree::cache::Dummy right_cache; - NodeLoader right(right_dataset, right_cache); + NodeLoader right(right_dataset, right_cache, space); NodeWriter output(output_dataset); if (mask.has_value()) { - merge::visitor::Masked visitor {mask.value()}; + merge::visitor::Masked visitor {mask.value(), space}; Merger merger(visitor, left, right, output); merger.merge_node(octree::Id::root()); } else { diff --git a/src/terrainmerger/merge/NodeData.h b/src/terrainmerger/merge/NodeData.h index e37c05e..f64168e 100644 --- a/src/terrainmerger/merge/NodeData.h +++ b/src/terrainmerger/merge/NodeData.h @@ -17,7 +17,7 @@ class NodeData { constexpr explicit NodeData(octree::Id id, const NodeLoader &loader) : _id(id), _loader(loader) {} const SimpleMesh &mesh() const { - static_assert(Status != octree::NodeStatusOrMissing::Missing, "Trying to access mesh from missing node."); + // static_assert(Status != octree::NodeStatusOrMissing::Missing, "Trying to access mesh from missing node."); if (!this->_mesh.has_value()) { auto result = this->_loader.load_node(this->_id); diff --git a/src/terrainmerger/merge/Result.h b/src/terrainmerger/merge/Result.h index d0b3bbc..c7b17d6 100644 --- a/src/terrainmerger/merge/Result.h +++ b/src/terrainmerger/merge/Result.h @@ -18,6 +18,6 @@ struct Merged { SimpleMesh mesh; }; -using Result = std::variant; +using Result = std::variant; } // namespace merge diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 17f2dbd..929669c 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -15,13 +15,15 @@ inline Result merge_meshes( const SimpleMesh &base_mesh, const SimpleMesh &new_mesh, const MeshMask &mask) { - const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask); - const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask); + + const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask, true); + const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); + if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { - return Unchanged{true}; + return Unchanged{.is_left = true}; } if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { - return Unchanged{false}; + return Unchanged{.is_left = false}; } const SimpleMesh merged_mesh = mesh::merge(base_mesh_clipped, new_mesh_clipped); @@ -56,39 +58,78 @@ class Masked : public Base { public: using Status = octree::NodeStatusOrMissing; - explicit Masked(MeshMask mask) : mask(mask) {} - - MeshMask mask; + explicit Masked(MeshMask mask, octree::Space space) : _space(space) { + this->_masks[octree::Id::root()] = mask; + } template Result visit( - const octree::Id &, + const octree::Id &id, NodeData &left, - NodeData &right, - ) { + NodeData &right) { + if constexpr (left.status() == Status::Missing && right.status() == Status::Missing) { + return Ignore{}; + } - if constexpr (right.status() == Status::Missing) { - return Unchanged{false}; + if constexpr (left.status() == Status::Leaf) { + const MeshMask &mask = this->mask_for_node(id); + auto result = clip_on_mask(left.mesh(), mask, false); + if (result->is_empty()) { + return Ignore{}; + } else if (result.is_ref()) { + return Unchanged{.is_left = true}; + } else { + // TODO: ensure move here + return Merged{result}; + } } - if constexpr (left.status() == Status::Missing) { - if constexpr (right.status() == Status::Leaf) { - auto result = clip_on_mask(right.mesh(), this->mask); - if (result.is_ref()) { - return Unchanged{true}; - } else { - return Merged{result}; - } + if constexpr (right.status() == Status::Leaf) { + const MeshMask &mask = this->mask_for_node(id); + auto result = clip_on_mask(right.mesh(), mask, true); + if (result->is_empty()) { + return Ignore{}; + } else if (result.is_ref()) { + return Unchanged{.is_left = false}; } else { - return Recurse{}; + return Merged{result}; } } if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { - return merge_meshes(right.mesh(), left.mesh(), this->mask); + const MeshMask &mask = this->mask_for_node(id); + return merge_meshes(right.mesh(), left.mesh(), mask); } return Recurse{}; } + +private: + std::unordered_map _masks = {}; + octree::Space _space; + + const MeshMask& mask_for_node(const octree::Id id) { + // TODO: evict old masks or rewrite such that merge.h handles passing in the masks + // we return in Recurse{} + + // Try to find cached mask first + if (auto it = this->_masks.find(id); it != this->_masks.end()) { + return it->second; + } + + // Recursively get parent mask (root always exists) + const octree::Id parent_id = id.parent().value(); + const MeshMask &parent_mask = this->mask_for_node(parent_id); + + // Clip mask based on parent + const auto bounds = pad_bounds(this->_space.get_node_bounds(id), 1.1); + LOG_TRACE("Clipping mask for {}", id); + auto [it, inserted] = this->_masks.try_emplace( + id, + mesh::clip_on_bounds_and_cap(parent_mask.mesh, bounds) + ); + + return it->second; + } }; } // namespace merge::visitor diff --git a/src/terrainmerger/utils.h b/src/terrainmerger/utils.h index e52bf5b..d3e223d 100644 --- a/src/terrainmerger/utils.h +++ b/src/terrainmerger/utils.h @@ -1,10 +1,23 @@ #pragma once +#include +#include + #include "Cow.h" #include "mask.h" #include "mesh/SimpleMesh.h" #include "mesh/clip.h" -inline Cow clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask) { - return mesh::clip_on_mesh(mesh, mask.mesh); +inline Cow clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask, const bool keep_inside = true) { + return mesh::clip_on_mesh(mesh, mask.mesh, keep_inside); +} + +template +radix::geometry::Aabb pad_bounds(const radix::geometry::Aabb &bounds, const T factor) { + using Vec = glm::vec; + const Vec center = bounds.centre(); + const Vec half_size = bounds.size() * (factor / T(2)); + const Vec new_min = center - half_size; + const Vec new_max = center + half_size; + return radix::geometry::Aabb(new_min, new_max); } From b3d79d3a04f7871e9ca78d47a2159b330843ccd3 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 15 Aug 2025 16:15:27 +0200 Subject: [PATCH 104/122] Add mesh merger utility --- src/mesh_merger/cli.cpp | 47 ++++++++++++++++++++++++++++++ src/mesh_merger/cli.h | 20 +++++++++++++ src/mesh_merger/main.cpp | 62 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/mesh_merger/cli.cpp create mode 100644 src/mesh_merger/cli.h create mode 100644 src/mesh_merger/main.cpp diff --git a/src/mesh_merger/cli.cpp b/src/mesh_merger/cli.cpp new file mode 100644 index 0000000..b0804c4 --- /dev/null +++ b/src/mesh_merger/cli.cpp @@ -0,0 +1,47 @@ +#include "cli.h" + +#include +#include +#include + +using namespace cli; + +Args cli::parse(int argc, const char * const * argv) { + DEBUG_ASSERT(argc >= 0); + + Args args; + CLI::App app{"mesh merger"}; + app.positionals_at_end(false); + app.allow_windows_style_options(false); + + app.add_option("--input", args.mesh_paths, "Meshes to to merge together") + ->check(CLI::ExistingFile) + ->required(); + + app.add_option("--output", args.output_path, "Path to write the merged mesh to") + ->required(); + + app.add_option("--epsilon", args.epsilon, "Epsilon for vertex deduplication") + ->check(CLI::Range(std::numeric_limits::min(), std::numeric_limits::max())); + + const std::map + log_level_names{ + {"off", spdlog::level::level_enum::off}, + {"critical", spdlog::level::level_enum::critical}, + {"error", spdlog::level::level_enum::err}, + {"warn", spdlog::level::level_enum::warn}, + {"info", spdlog::level::level_enum::info}, + {"debug", spdlog::level::level_enum::debug}, + {"trace", spdlog::level::level_enum::trace}}; + app.add_option("--verbosity", args.log_level, "Verbosity level of logging") + ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)) + ->default_val(spdlog::level::level_enum::info); + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError &e) { + exit(app.exit(e)); + } + + return args; +} diff --git a/src/mesh_merger/cli.h b/src/mesh_merger/cli.h new file mode 100644 index 0000000..0ae05d8 --- /dev/null +++ b/src/mesh_merger/cli.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +#include + +namespace cli { + +struct Args { + std::vector mesh_paths; + std::filesystem::path output_path; + std::optional epsilon; + spdlog::level::level_enum log_level; +}; + +Args parse(int argc, const char *const *argv); + +} diff --git a/src/mesh_merger/main.cpp b/src/mesh_merger/main.cpp new file mode 100644 index 0000000..87feca1 --- /dev/null +++ b/src/mesh_merger/main.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +#include "cli.h" +#include "log.h" +#include "mesh/SimpleMesh.h" +#include "mesh/io.h" +#include "mesh/merge.h" + +SimpleMesh merge(const std::span meshes, const std::optional epsilon) { + std::vector> mesh_refs; + mesh_refs.reserve(meshes.size()); + for (const SimpleMesh &mesh : meshes) { + mesh_refs.push_back(mesh); + } + + if (epsilon.has_value()) { + return mesh::merge(mesh_refs, epsilon.value()); + } else { + return mesh::merge(mesh_refs); + } +} + +void run(const cli::Args &args) { + std::vector meshes; + meshes.reserve(args.mesh_paths.size()); + for (const std::filesystem::path& mesh_path : args.mesh_paths) { + LOG_INFO("Loading mesh from {}", mesh_path); + auto result = mesh::io::load_from_path(mesh_path); + if (!result.has_value()) { + LOG_ERROR_AND_EXIT("Failed to load mesh to {} due to {}", mesh_path, result.error().description()); + } + const SimpleMesh mesh = result.value(); + meshes.push_back(mesh); + } + + LOG_INFO("Merging meshes"); + const SimpleMesh merged = merge(meshes, args.epsilon); + + LOG_INFO("Saving mesh to {}", args.output_path); + auto result = mesh::io::save_to_path(merged, args.output_path); + if (!result.has_value()) { + LOG_ERROR_AND_EXIT("Failed to save mesh to {} due to {}", args.output_path, result.error().description()); + } +} + +int main(int argc, char **argv) { + const cli::Args args = cli::parse(argc, argv); + Log::init(args.log_level); + + const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), + [](const std::string &acc, const char *arg) { + return acc + (acc.empty() ? "" : " ") + arg; + }); + LOG_DEBUG("Running with: {}", arg_str); + + run(args); + return 0; +} From 85626aee86c1ef2fcc15639165b33563815b42f3 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 15 Aug 2025 16:15:45 +0200 Subject: [PATCH 105/122] Finish terrainmerger (mostly) --- out.txt | 0 src/CMakeLists.txt | 8 +- src/index_browser/cli.cpp | 3 +- src/index_browser/main.cpp | 30 ++- src/terrainlib/mesh/boolean.cpp | 2 - src/terrainlib/mesh/boolean.h | 2 - src/terrainlib/mesh/io/error.h | 3 +- .../mesh/merging/EpsilonVertexDeduplicate.h | 6 +- src/terrainlib/mesh/merging/mapping.cpp | 178 ++++++++++--- src/terrainlib/mesh/utils.cpp | 47 ++-- src/terrainlib/mesh/utils.h | 3 +- src/terrainlib/mesh/validate.inl | 3 +- src/terrainlib/octree/storage/open.h | 4 +- src/terrainlib/optional_utils.h | 10 +- src/terrainlib/spatial_lookup/CellBased.h | 2 +- src/terrainmerger/NodeWriter.h | 1 + src/terrainmerger/cut.h | 2 +- src/terrainmerger/main.cpp | 1 + src/terrainmerger/merge.h | 68 +++-- src/terrainmerger/merge/NodeData.h | 42 +++- src/terrainmerger/merge/Result.h | 18 +- src/terrainmerger/merge/visitor/Base.h | 19 -- src/terrainmerger/merge/visitor/Masked.h | 234 +++++++++++------- src/terrainmerger/merge/visitor/Simple.h | 58 +++-- src/terrainmerger/merge/visitor/Visitor.h | 26 ++ unittests/terrainlib/mesh_merge.cpp | 75 +++++- unittests/terrainlib/mesh_merge_mapping.cpp | 39 ++- 27 files changed, 632 insertions(+), 252 deletions(-) create mode 100644 out.txt delete mode 100644 src/terrainmerger/merge/visitor/Base.h create mode 100644 src/terrainmerger/merge/visitor/Visitor.h diff --git a/out.txt b/out.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 106d675..f5d6bc1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") # TODO: This is needed to avoid NDEBUG being undefined on Release if (CMAKE_BUILD_TYPE MATCHES Release) - set(ALP_ENABLE_ASSERTS OFF CACHE BOOL "" FORCE) + # set(ALP_ENABLE_ASSERTS OFF CACHE BOOL "" FORCE) endif() option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) @@ -272,6 +272,12 @@ add_executable(index_browser ) target_link_libraries(index_browser PUBLIC terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) +add_executable(mesh_merger + mesh_merger/cli.h mesh_merger/cli.cpp + mesh_merger/main.cpp +) +target_link_libraries(mesh_merger PUBLIC terrainlib CLI11::CLI11) + add_executable(browser # browser/main2.cpp diff --git a/src/index_browser/cli.cpp b/src/index_browser/cli.cpp index 8b19db3..ad8d771 100644 --- a/src/index_browser/cli.cpp +++ b/src/index_browser/cli.cpp @@ -35,8 +35,7 @@ Args cli::parse(int argc, const char * const * argv) { ->default_val(spdlog::level::level_enum::info); try { - app.parse("--dataset ../../../meshes/innenstadt"); - // app.parse(argc, argv); + app.parse(argc, argv); } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/index_browser/main.cpp b/src/index_browser/main.cpp index 764b34e..e087d1e 100644 --- a/src/index_browser/main.cpp +++ b/src/index_browser/main.cpp @@ -224,37 +224,57 @@ int run(const cli::Args &args) { TreeView tree_view(storage, root_id); size_t selected = 0; + size_t scroll_offset = 0; + size_t visible_lines = 0; + auto screen = ftxui::ScreenInteractive::Fullscreen(); auto renderer = ftxui::Renderer([&] { ftxui::Elements lines; lines.reserve(tree_view.size()); - size_t i = 0; - for (auto it = tree_view.begin(); it != tree_view.end(); i++, it++) { + + visible_lines = std::max(1, screen.dimy() - 2); + + for (size_t i = scroll_offset; + i < tree_view.size() && (i - scroll_offset) < visible_lines; + ++i) { + auto it = tree_view.begin(); + std::advance(it, i); lines.push_back(render_line(*it, tree_view.root.level(), i == selected)); } - return ftxui::vbox(std::move(lines)) | ftxui::frame | ftxui::border; - }); - auto screen = ftxui::ScreenInteractive::Fullscreen(); + return ftxui::vbox(std::move(lines)) | ftxui::border; + }); auto container = ftxui::CatchEvent(renderer, [&](ftxui::Event e) { + auto ensure_visible = [&] { + if (selected < scroll_offset) { + scroll_offset = selected; + } else if (selected >= scroll_offset + visible_lines) { + scroll_offset = selected - visible_lines + 1; + } + }; + if (e == ftxui::Event::ArrowUp) { if (selected > 0) { selected--; + ensure_visible(); } return true; } if (e == ftxui::Event::ArrowDown) { if (selected + 1 < tree_view.size()) { selected++; + ensure_visible(); } return true; } if (e == ftxui::Event::ArrowRight) { tree_view.expand_node(selected); + ensure_visible(); return true; } if (e == ftxui::Event::ArrowLeft) { tree_view.collapse_node(selected); + ensure_visible(); return true; } if ((e == ftxui::Event::Character('q') || e == ftxui::Event::Character('Q') || e == ftxui::Event::Escape)) { diff --git a/src/terrainlib/mesh/boolean.cpp b/src/terrainlib/mesh/boolean.cpp index 30ce053..5704b8d 100644 --- a/src/terrainlib/mesh/boolean.cpp +++ b/src/terrainlib/mesh/boolean.cpp @@ -5,8 +5,6 @@ #include "mesh/boolean.h" #include "mesh/convert.h" #include "mesh/cgal.h" -#include "mesh/clip.h" -#include "mesh/utils.h" namespace mesh { diff --git a/src/terrainlib/mesh/boolean.h b/src/terrainlib/mesh/boolean.h index b99b2d1..9650c63 100644 --- a/src/terrainlib/mesh/boolean.h +++ b/src/terrainlib/mesh/boolean.h @@ -10,6 +10,4 @@ struct IntersectionAndDifference { }; IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const SimpleMesh &b); -SimpleMesh difference(const SimpleMesh &a, const SimpleMesh &b); - } diff --git a/src/terrainlib/mesh/io/error.h b/src/terrainlib/mesh/io/error.h index 4f00843..ffd10c9 100644 --- a/src/terrainlib/mesh/io/error.h +++ b/src/terrainlib/mesh/io/error.h @@ -45,7 +45,8 @@ class LoadMeshError { } friend std::ostream &operator<<(std::ostream &os, const LoadMeshError &err) { - return os << err.description(); + os << err.description(); + return os; } private: diff --git a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h index 53cfc07..5e5a3a8 100644 --- a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h @@ -13,7 +13,10 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate_epsilon; + } void add(const Vec &point, const Meta meta) override { this->_lookup.insert(point, meta); } @@ -26,7 +29,6 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate class CellBased, typename EpsilonType> diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index 6996b02..a7dfeaa 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -1,6 +1,9 @@ #include +#include +#include #include +#include #include "UnionFind.h" #include "log.h" @@ -9,30 +12,114 @@ #include "mesh/merging/mapping.h" #include "mesh/utils.h" #include "mesh/validate.h" +#include "spatial_lookup/Grid.h" #include "spatial_lookup/Hashmap.h" #include "type_utils.h" namespace mesh::merging { +namespace { +radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { + const glm::dvec3 bounds_padding = bounds.size() * percentage; + const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + return padded_bounds; +} + +template +spatial_lookup::Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { + const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); + + const double max_extends = glm::compMax(padded_bounds.size()); + const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; + const glm::uvec3 grid_divisions = glm::max(glm::uvec3(2 * std::cbrt(vertex_count) * relative_extends), glm::uvec3(1)); + spatial_lookup::Grid3d grid(padded_bounds.min, padded_bounds.size(), grid_divisions); + + return grid; +} + +template +spatial_lookup::Grid3d construct_grid_for_mesh(const SimpleMesh &mesh) { + const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); + const size_t vertex_count = mesh.vertex_count(); + return _construct_grid_for_meshes(bounds, vertex_count); +} + +template +spatial_lookup::Grid3d construct_grid_for_meshes(const std::span> meshes) { + const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); + const size_t maximal_merged_mesh_size = std::transform_reduce( + meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); + return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); +} + +double estimate_merge_epsilon(const std::span> meshes) {double total_length = 0.0; + size_t total_triangle_count = 0; + for (const auto &mesh_ref : meshes) { + const SimpleMesh &mesh = mesh_ref.get(); + const auto avg_length_opt = estimate_average_edge_length(mesh); + if (avg_length_opt) { + const size_t num_triangles = mesh.triangles.size(); + total_length += avg_length_opt.value() * num_triangles; + total_triangle_count += num_triangles; + } + } + + const double average_edge_length = total_length / total_triangle_count; + const double distance_epsilon = average_edge_length / 1000; + return distance_epsilon; +} +} + VertexMapping create_mapping(const std::span> meshes) { if (meshes.empty()) { return {}; } - const double average_edge_length_sum = std::accumulate( - meshes.begin(), meshes.end(), 0.0, - [](double sum, const std::reference_wrapper &mesh_ref) { - return sum + estimate_average_edge_length(mesh_ref.get()).value_or(0); - }); - const double average_edge_length = average_edge_length_sum / meshes.size(); - const double distance_epsilon = average_edge_length / 100; + const double distance_epsilon = estimate_merge_epsilon(meshes); return create_mapping(meshes, distance_epsilon); } +namespace { +void validate_epsilon_mapping( + const VertexMapping &mapping, + const std::span> meshes, + double epsilon) { + const double epsilon2 = epsilon * epsilon; + + const size_t max_merged_index = mapping.find_max_merged_index(); + + std::vector originals; + for (size_t merged_index = 0; merged_index <= max_merged_index; merged_index++) { + // Collect all original vertices mapping to this merged index + originals.clear(); + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + const std::optional vertex_index = mapping.map_backward(mesh_index, merged_index); + if (vertex_index.has_value()) { + originals.push_back(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index.value()}); + } + } + + // Check all pairs of original vertices for this merged vertex + for (size_t i = 0; i < originals.size(); i++) { + const glm::dvec3 &pi = meshes[originals[i].mesh_index].get().positions[originals[i].vertex_index]; + for (size_t j = i + 1; j < originals.size(); j++) { + const glm::dvec3 &pj = meshes[originals[j].mesh_index].get().positions[originals[j].vertex_index]; + const double dist2 = glm::distance2(pi, pj); + DEBUG_ASSERT(dist2 <= epsilon2); + } + } + } +} +} + VertexMapping create_mapping(const std::span> meshes, double distance_epsilon) { - auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); + // auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); + auto map = construct_grid_for_meshes(meshes); auto deduplicate = EpsilonVertexDeduplicate(map, distance_epsilon); - return create_mapping(meshes, deduplicate); + LOG_TRACE("Creating merge mapping with epsilon = {}", distance_epsilon); + const VertexMapping mapping = create_mapping(meshes, deduplicate); + validate_epsilon_mapping(mapping, meshes, distance_epsilon); + return mapping; } VertexMapping create_mapping(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { @@ -43,7 +130,11 @@ VertexMapping create_mapping(const std::span mesh_sizes; mesh_sizes.reserve(meshes.size()); @@ -57,6 +148,10 @@ VertexMapping create_mapping(const std::span> duplicate_vertices; for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { const SimpleMesh &mesh = meshes[mesh_index]; @@ -66,25 +161,40 @@ VertexMapping create_mapping(const std::span> nearest_duplicate; + for (const auto &other_vertex : duplicate_vertices) { // Warn if we would perform intra mesh merges (but dont actually do them) if (other_vertex.get().mesh_index == current_vertex.mesh_index) { if (!has_warned) { LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); has_warned = true; - break; } } else { - mapping.add_bidirectional(current_vertex, mapping.map_forward(other_vertex.get())); + double distance2 = 0; + // Only caluclate the distance if there is actually more than a single duplicate vertex + if (duplicate_vertices.size() > 1) { + distance2 = glm::distance2(mesh.positions[other_vertex.get().vertex_index], position); + } + if (!nearest_duplicate.has_value() || nearest_duplicate.value().second > distance2) { + nearest_duplicate = {other_vertex.get(), distance2}; + } } } + if (nearest_duplicate.has_value()) { + mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); + } else { + deduplicate.add(position, current_vertex); + add_unique_vertex(current_vertex); + } duplicate_vertices.clear(); } else { // New vertex / No duplicates - mapping.add_bidirectional(current_vertex, unique_vertices); - unique_vertices += 1; + add_unique_vertex(current_vertex); } } } @@ -94,7 +204,6 @@ VertexMapping create_mapping(const std::span written(max_combined_vertex_count, false); +#endif size_t max_vertex_index = 0; merged_mesh.positions.resize(max_combined_vertex_count); - if (has_uvs) { - merged_mesh.uvs.resize(max_combined_vertex_count); - } for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const size_t mapped_index = mapping.map_forward(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); - merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; - if (has_uvs) { - merged_mesh.uvs[mapped_index] = mesh.uvs[vertex_index]; + const glm::dvec3 position = mesh.positions[vertex_index]; +#ifndef NDEBUG + if (written[mapped_index]) { + const glm::dvec3 &old = merged_mesh.positions[mapped_index]; + const double dist2 = glm::distance2(position, old); + DEBUG_ASSERT(dist2 <= distance_epsilon * distance_epsilon); + } else { + written[mapped_index] = true; } +#endif + merged_mesh.positions[mapped_index] = position; max_vertex_index = std::max(max_vertex_index, mapped_index); } } DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); merged_mesh.positions.resize(max_vertex_index + 1); - if (has_uvs) { - merged_mesh.uvs.resize(max_vertex_index + 1); - } merged_mesh.triangles.reserve(max_combined_face_count); for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { @@ -334,7 +450,7 @@ SimpleMesh apply_mapping(const std::span::infinity()); - bounds.max = glm::dvec3(-std::numeric_limits::infinity()); - for (unsigned int j = 0; j < mesh.positions.size(); j++) { - const auto &position = mesh.positions[j]; - bounds.expand_by(position); - } - return bounds; +namespace { +template +const T& unwrap(const T& t) { + return t; } -radix::geometry::Aabb3d calculate_bounds(std::span meshes) { +template +const T& unwrap(const std::reference_wrapper& t) { + return t.get(); +} + +template +radix::geometry::Aabb3d calculate_bounds_range(const MeshRange &meshes) { radix::geometry::Aabb3d bounds; - bounds.min = glm::dvec3(std::numeric_limits::infinity()); - bounds.max = glm::dvec3(-std::numeric_limits::infinity()); - for (unsigned int i = 0; i < meshes.size(); i++) { - const SimpleMesh &mesh = meshes[i]; - for (unsigned int j = 0; j < mesh.positions.size(); j++) { - const auto &position = mesh.positions[j]; + constexpr double inf = std::numeric_limits::infinity(); + bounds.min = glm::dvec3(+inf); + bounds.max = glm::dvec3(-inf); + + for (const auto &wrapper : meshes) { + const auto &mesh = unwrap(wrapper); + for (const auto &position : mesh.positions) { bounds.expand_by(position); } } return bounds; } +} + +radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh) { + return calculate_bounds_range(std::array{std::cref(mesh)}); +} + +radix::geometry::Aabb3d calculate_bounds(std::span meshes) { + return calculate_bounds_range(meshes); +} + +radix::geometry::Aabb3d calculate_bounds(std::span> meshes) { + return calculate_bounds_range(meshes); +} std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size) { const auto &triangles = mesh.triangles; diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index a20181b..a077353 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -11,7 +11,8 @@ // TODO: make all methods work with SimpleMesh_ radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh); -radix::geometry::Aabb3d calculate_bounds(std::span meshes); +radix::geometry::Aabb3d calculate_bounds(const std::span meshes); +radix::geometry::Aabb3d calculate_bounds(const std::span> meshes); std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size = 1000); std::optional calculate_max_edge_length(const SimpleMesh &mesh); diff --git a/src/terrainlib/mesh/validate.inl b/src/terrainlib/mesh/validate.inl index 9451135..406e90c 100644 --- a/src/terrainlib/mesh/validate.inl +++ b/src/terrainlib/mesh/validate.inl @@ -95,7 +95,7 @@ void validate(const SimpleMesh_ &mesh) { #endif } -template +template inline void validate(const CGAL::Surface_mesh &mesh) { #ifndef NDEBUG DEBUG_ASSERT(mesh.is_valid()); @@ -104,5 +104,4 @@ inline void validate(const CGAL::Surface_mesh &mesh) { DEBUG_ASSERT(!CGAL::Polygon_mesh_processing::does_self_intersect(mesh)); #endif } - } diff --git a/src/terrainlib/octree/storage/open.h b/src/terrainlib/octree/storage/open.h index 7f9d780..71fca2f 100644 --- a/src/terrainlib/octree/storage/open.h +++ b/src/terrainlib/octree/storage/open.h @@ -14,8 +14,8 @@ namespace octree { struct OpenOptions { - std::unique_ptr default_layout_strategy; - std::optional preferred_extension_with_dot; + std::unique_ptr default_layout_strategy = {}; + std::optional preferred_extension_with_dot = {}; }; tl::expected open_index(const std::filesystem::path &index_path); diff --git a/src/terrainlib/optional_utils.h b/src/terrainlib/optional_utils.h index d0ba3bc..88b1a33 100644 --- a/src/terrainlib/optional_utils.h +++ b/src/terrainlib/optional_utils.h @@ -3,7 +3,15 @@ #include template -std::optional> as_ref(const std::optional &option) { +std::optional> as_ref(const std::optional &option) { + if (option.has_value()) { + return option.value(); + } else { + return std::nullopt; + } +} +template +std::optional> as_ref(std::optional &option) { if (option.has_value()) { return option.value(); } else { diff --git a/src/terrainlib/spatial_lookup/CellBased.h b/src/terrainlib/spatial_lookup/CellBased.h index dcb9a94..7df510a 100644 --- a/src/terrainlib/spatial_lookup/CellBased.h +++ b/src/terrainlib/spatial_lookup/CellBased.h @@ -183,7 +183,7 @@ class CellBased { } } - static_assert(SpatialLookup); + // static_assert(SpatialLookup); }; } // namespace spatial_lookup diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index 85c0fdc..3cf0112 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -23,6 +23,7 @@ class NodeWriter { } void write_node(const octree::Id &id, const SimpleMesh &mesh) { + mesh::validate(mesh); DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); } diff --git a/src/terrainmerger/cut.h b/src/terrainmerger/cut.h index 39ebb5c..52add8b 100644 --- a/src/terrainmerger/cut.h +++ b/src/terrainmerger/cut.h @@ -113,7 +113,7 @@ inline void cut_dataset( const MeshMask& mask, octree::Storage &output, const bool keep_inside) { - Context ctx(input, output, octree::Space::earth()); + Context ctx(input, output, octree::Space::earth(), keep_inside); cut_node(ctx, octree::Id::root(), mask); output.save_or_create_index(); } diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index ddcf270..2f46315 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -41,6 +41,7 @@ void run(const cli::MergeArgs& args) { LOG_TRACE("Creating output dataset at {}", args.output_path); std::filesystem::create_directories(args.output_path); octree::Storage output_dataset = octree::open_folder(args.output_path, false, octree::OpenOptions{.preferred_extension_with_dot = ".glb"}); + std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); diff --git a/src/terrainmerger/merge.h b/src/terrainmerger/merge.h index 57d2de9..4d40e51 100644 --- a/src/terrainmerger/merge.h +++ b/src/terrainmerger/merge.h @@ -3,16 +3,17 @@ #include #include +#include "NodeLoader.h" +#include "NodeWriter.h" #include "mask.h" #include "merge/NodeData.h" #include "merge/Result.h" +#include "merge/visitor/Masked.h" +#include "merge/visitor/Simple.h" +#include "merge/visitor/Visitor.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" -#include "NodeLoader.h" -#include "NodeWriter.h" #include "octree/storage/cache/Dummy.h" -#include "merge/visitor/Masked.h" -#include "merge/visitor/Simple.h" inline std::string get_dataset_name(const octree::Storage &storage) { return storage.layout().base_path().filename().string(); @@ -25,10 +26,12 @@ using smallest_uint_t = std::conditional_t<(N <= UINT32_MAX), uint32_t, uint64_t>>>; -template +template class Merger { public: using Status = octree::NodeStatusOrMissing; + using Context = Visitor::Context; + using Result = merge::Result; Merger( Visitor& visitor, @@ -37,39 +40,61 @@ class Merger { NodeWriter output) : _visitor(visitor), _left(left), _right(right), _output(output) { } - void merge_node(const octree::Id &id) { + void merge_root() { + const octree::Id id = octree::Id::root(); + const Context ctx = this->_visitor.make_root_context(); + merge_node(id, ctx); + } + + void merge_node(const octree::Id &id, const Context& ctx) { const Status left_status = this->_left.get_status(id); const Status right_status = this->_right.get_status(id); - return this->merge_node(id, left_status, right_status); + return this->merge_node(id, left_status, right_status, ctx); } void merge_node( const octree::Id &id, const Status left_status, - const Status right_status + const Status right_status, + const Context& ctx ) { + LOG_DEBUG("[{}] Start merging (left = {}, right = {})", id, left_status, right_status); if (this->_output.has_node(id)) { + LOG_DEBUG("[{}] Already merged, skipping...", id); return; // Already merged previously } - const auto merge_result = this->call_merge(id, left_status, right_status); + const auto merge_result = this->call_merge(id, left_status, right_status, ctx); std::visit([&](const auto &result) { using Result = std::decay_t; - if constexpr (std::is_same_v) { - LOG_DEBUG("Node {} needs recusion", id); + if constexpr (std::is_same_v>) { + LOG_DEBUG("[{}] needs recursion", id); DEBUG_ASSERT(id.has_children()); const auto children = id.children().value(); for (const auto &child_id : children) { - this->merge_node(child_id); + this->merge_node(child_id, result.context); } } else if constexpr (std::is_same_v) { - LOG_DEBUG("Node {} remains unchanged (same as {})", id, (result.is_left ? "left" : "right")); - this->_output.copy_subtree_to_output(id, result.is_left ? this->_left : this->_right); + LOG_DEBUG("[{}] remains unchanged (same as {})", id, (result.source == merge::Source::Left ? "left" : "right")); + // If the node should remain unchanged, but its not present on disk we cannot copy it. + if (result.source == merge::Source::Left && left_status == Status::Missing) { + auto mesh_opt = this->_left.load_node(id); + if (mesh_opt.has_value()) { + this->_output.write_node(id, mesh_opt.value()); + } + } else if (result.source == merge::Source::Right && right_status == Status::Missing) { + auto mesh_opt = this->_right.load_node(id); + if (mesh_opt.has_value()) { + this->_output.write_node(id, mesh_opt.value()); + } + } else { + this->_output.copy_subtree_to_output(id, result.source == merge::Source::Left ? this->_left : this->_right); + } } else if constexpr (std::is_same_v) { - LOG_DEBUG("Node {} was merged", id); + LOG_DEBUG("[{}] was merged", id); this->_output.write_node(id, result.mesh); } else if constexpr (std::is_same_v) { - LOG_DEBUG("Node {} was ignored", id); + LOG_DEBUG("[{}] was ignored", id); // do nothing } }, merge_result); @@ -87,10 +112,11 @@ class Merger { return static_cast(left) * STATUS_COUNT + static_cast(right); } - merge::Result call_merge( + Result call_merge( const octree::Id &id, Status left, - Status right) { + Status right, + const Context& ctx) { const Index index = get_index(left, right); switch (index) { @@ -98,7 +124,7 @@ class Merger { case get_index(Status::left_status, Status::right_status): { \ merge::NodeData left_node(id, this->_left); \ merge::NodeData right_node(id, this->_right); \ - return this->_visitor.template visit(id, left_node, right_node); \ + return this->_visitor.template visit(id, left_node, right_node, ctx); \ } ALP_GENERATE_CASE(Missing, Missing); @@ -144,11 +170,11 @@ inline void merge_datasets( if (mask.has_value()) { merge::visitor::Masked visitor {mask.value(), space}; Merger merger(visitor, left, right, output); - merger.merge_node(octree::Id::root()); + merger.merge_root(); } else { merge::visitor::Simple visitor; Merger merger(visitor, left, right, output); - merger.merge_node(octree::Id::root()); + merger.merge_root(); } output_dataset.save_or_create_index(); diff --git a/src/terrainmerger/merge/NodeData.h b/src/terrainmerger/merge/NodeData.h index f64168e..f280d2b 100644 --- a/src/terrainmerger/merge/NodeData.h +++ b/src/terrainmerger/merge/NodeData.h @@ -8,6 +8,7 @@ #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" #include "octree/Storage.h" +#include "optional_utils.h" namespace merge { @@ -16,25 +17,44 @@ class NodeData { public: constexpr explicit NodeData(octree::Id id, const NodeLoader &loader) : _id(id), _loader(loader) {} - const SimpleMesh &mesh() const { - // static_assert(Status != octree::NodeStatusOrMissing::Missing, "Trying to access mesh from missing node."); + static constexpr octree::NodeStatusOrMissing status() { + return Status; + } + + octree::Id id() const { + return this->_id; + } + + // Status::Leaf or Status::Inner guarantuess a node is present + template + std::enable_if_t + mesh() const { + auto mesh = this->load_mesh(); + if (mesh.has_value()) { + return this->_mesh.value(); + } else { + LOG_ERROR_AND_EXIT("Failed to read node from loader that should be present"); + } + } - if (!this->_mesh.has_value()) { + // Status::Missing and Status::Virtual do not exist on disk, but may be the child of a leaf or inner node + template + std::enable_if_t>> + mesh() const { + return this->load_mesh(); + } + +private: + std::optional> load_mesh() const { + if (!_mesh.has_value()) { auto result = this->_loader.load_node(this->_id); if (result.has_value()) { this->_mesh = result.value(); - } else { - LOG_ERROR_AND_EXIT("Failed to read node from loader that should be present"); } } - return this->_mesh.value(); - } - - static constexpr octree::NodeStatusOrMissing status() { - return Status; + return as_ref(this->_mesh); } -private: octree::Id _id; const NodeLoader &_loader; mutable std::optional _mesh; diff --git a/src/terrainmerger/merge/Result.h b/src/terrainmerger/merge/Result.h index c7b17d6..86c9589 100644 --- a/src/terrainmerger/merge/Result.h +++ b/src/terrainmerger/merge/Result.h @@ -6,18 +6,30 @@ namespace merge { -struct Recurse {}; +template +struct Recurse { + // TODO: make optional? + Context context; +}; +template +Recurse(Context) -> Recurse; struct Ignore {}; +enum class Source { + Left, + Right +}; + struct Unchanged { - bool is_left; + Source source; }; struct Merged { SimpleMesh mesh; }; -using Result = std::variant; +template +using Result = std::variant, Ignore, Unchanged, Merged>; } // namespace merge diff --git a/src/terrainmerger/merge/visitor/Base.h b/src/terrainmerger/merge/visitor/Base.h deleted file mode 100644 index 30156c2..0000000 --- a/src/terrainmerger/merge/visitor/Base.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "merge/NodeData.h" -#include "merge/Result.h" -#include "octree/Id.h" -#include "octree/NodeStatusOrMissing.h" - -namespace merge::visitor { -class Base { -public: - virtual ~Base() = default; - - template - Result visit( - const octree::Id &id, - NodeData &left, - NodeData &right); -}; -} // namespace merge::visitor diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 929669c..9556555 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -3,133 +3,199 @@ #include "mask.h" #include "merge/NodeData.h" #include "merge/Result.h" -#include "merge/visitor/Base.h" +#include "merge/visitor/Visitor.h" #include "mesh/merge.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" #include "utils.h" namespace merge::visitor { -namespace { -inline Result merge_meshes( - const SimpleMesh &base_mesh, - const SimpleMesh &new_mesh, - const MeshMask &mask) { - - const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask, true); - const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); - - if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { - return Unchanged{.is_left = true}; - } - if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { - return Unchanged{.is_left = false}; - } - - const SimpleMesh merged_mesh = mesh::merge(base_mesh_clipped, new_mesh_clipped); - return Merged{merged_mesh}; - - /* - TODO: Advanced merging - const auto base_mesh_bounds = calculate_bounds(base_mesh); - auto bounds = base_mesh_bounds; - bounds.expand_by(new_mesh_bounds); - const glm::dvec3 tangent_point = bounds.centre(); - const glm::dvec2 radius_range = mask::pad_radius_range(mask::calculate_radius_range(bounds), 2); - if (mask.has_value()) { - auto result = mesh::intersection_and_difference(new_mesh, mask->mesh); - const SimpleMesh new_mesh_in_mask = std::move(result.intersection); - const SimpleMesh new_mesh_out_mask = std::move(result.difference); - const MeshMask mask_base_mesh = mask::create_from_mesh(base_mesh, tangent_point, radius_range); - const SimpleMesh new_mesh_out_mask_clipped = mesh::clip_on_mesh(new_mesh_out_mask, mask_base_mesh.mesh); - const MeshMask mask_new_mesh_in_mask = mask::create_from_mesh(new_mesh_in_mask, tangent_point, radius_range); - const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh_in_mask.mesh); - return mesh::merge::merge_meshes(new_mesh_out_mask_clipped, base_mesh_clipped, new_mesh_in_mask); - } else { - const MeshMask mask_new_mesh = mask::create_from_mesh(new_mesh, tangent_point, radius_range); - const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh.mesh); - return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh); - } - */ -} -} // namespace -class Masked : public Base { +class Masked { public: using Status = octree::NodeStatusOrMissing; - - explicit Masked(MeshMask mask, octree::Space space) : _space(space) { - this->_masks[octree::Id::root()] = mask; + struct Context { + MeshMask mask; + bool has_left_parent; + bool has_right_parent; + }; + using Result = merge::Result; + + explicit Masked(MeshMask mask, octree::Space space) : _mask(mask), _space(space) { } + + Context make_root_context() { + return Context{ + .mask = this->_mask, + .has_left_parent = false, + .has_right_parent = false, + }; } template Result visit( const octree::Id &id, - NodeData &left, - NodeData &right) { + const NodeData &left, + const NodeData &right, + const Context &ctx) { + if constexpr (left.status() == Status::Inner || right.status() == Status::Inner) { + UNREACHABLE(); + } + if constexpr (left.status() == Status::Missing && right.status() == Status::Missing) { - return Ignore{}; + DEBUG_ASSERT(!(ctx.has_left_parent && ctx.has_right_parent)); + if (!ctx.has_left_parent && !ctx.has_right_parent) { + return Ignore{}; + } + } + + // If the parent mask is empty, we can just return whatevers on the left + if constexpr (left.status() != Status::Missing) { + if (ctx.mask.mesh.is_empty()) { + return Unchanged{Source::Left}; + } + } + + LOG_TRACE("Clipping mask for {}", id); + const auto bounds = pad_bounds(this->_space.get_node_bounds(id), 1.1); + MeshMask mask(mesh::clip_on_bounds_and_cap(ctx.mask.mesh, bounds)); + + // Same when the current mask is empty + if constexpr (left.status() != Status::Missing) { + if (mask.mesh.is_empty()) { + return Unchanged{Source::Left}; + } } - if constexpr (left.status() == Status::Leaf) { - const MeshMask &mask = this->mask_for_node(id); + // If we have two leaf nodes we can directly merge them. + if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { + return this->merge_meshes(left.mesh(), right.mesh(), true, true, mask); + } + + // If we have a left leaf we either directly return it (after clipping) + // or merge if right has a non-missing parent + if constexpr (left.status() == Status::Leaf && right.status() == Status::Missing) { + if (ctx.has_right_parent) { + return this->merge_meshes(left.mesh(), right.mesh().value(), true, false, mask); + } + + // Right node is actually missing, just return the clipped left node auto result = clip_on_mask(left.mesh(), mask, false); if (result->is_empty()) { return Ignore{}; } else if (result.is_ref()) { - return Unchanged{.is_left = true}; + return Unchanged{Source::Left}; } else { - // TODO: ensure move here return Merged{result}; } } + + // If we have a right leaf we either directly return it (after clipping) + // or merge if left has a non-missing parent + if constexpr (left.status() == Status::Missing && right.status() == Status::Leaf) { + if (ctx.has_left_parent) { + return this->merge_meshes(left.mesh().value(), right.mesh(), false, true, mask); + } - if constexpr (right.status() == Status::Leaf) { - const MeshMask &mask = this->mask_for_node(id); + // Left node is actually missing, just return the clipped right node auto result = clip_on_mask(right.mesh(), mask, true); if (result->is_empty()) { return Ignore{}; } else if (result.is_ref()) { - return Unchanged{.is_left = false}; + return Unchanged{Source::Right}; } else { return Merged{result}; } } - if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { - const MeshMask &mask = this->mask_for_node(id); - return merge_meshes(right.mesh(), left.mesh(), mask); + if constexpr (left.status() == Status::Missing && right.status() == Status::Missing) { + DEBUG_ASSERT(ctx.has_left_parent || ctx.has_right_parent); + if (ctx.has_left_parent) { + auto result = clip_on_mask(left.mesh().value(), mask, false); + if (result->is_empty()) { + return Ignore{}; + } else { + return Merged{result}; + } + } + if (ctx.has_right_parent) { + auto result = clip_on_mask(right.mesh().value(), mask, true); + if (result->is_empty()) { + return Ignore{}; + } else { + return Merged{result}; + } + } } - return Recurse{}; + if constexpr (left.status() == Status::Virtual || right.status() == Status::Virtual) { + return Recurse{ + Context{ + .mask = mask, + .has_left_parent = ctx.has_left_parent || left.status() == Status::Leaf, + .has_right_parent = ctx.has_right_parent || right.status() == Status::Leaf + } + }; + } + + UNREACHABLE(); } private: - std::unordered_map _masks = {}; - octree::Space _space; - - const MeshMask& mask_for_node(const octree::Id id) { - // TODO: evict old masks or rewrite such that merge.h handles passing in the masks - // we return in Recurse{} + Result merge_meshes( + const SimpleMesh &base_mesh, + const SimpleMesh &new_mesh, + const bool can_ref_base_mesh, + const bool can_ref_new_mesh, + const MeshMask &mask) { + const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask, true); + const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); + + if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { + if (can_ref_base_mesh) { + return Unchanged{Source::Left}; + } else { + return Merged{base_mesh_clipped}; + } + } + if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { + if (can_ref_new_mesh) { + return Unchanged{Source::Right}; + } else { + return Merged{new_mesh_clipped}; + } + } - // Try to find cached mask first - if (auto it = this->_masks.find(id); it != this->_masks.end()) { - return it->second; + const SimpleMesh merged_mesh = mesh::merge(base_mesh_clipped, new_mesh_clipped); + return Merged{merged_mesh}; + + /* + TODO: Advanced merging + const auto base_mesh_bounds = calculate_bounds(base_mesh); + auto bounds = base_mesh_bounds; + bounds.expand_by(new_mesh_bounds); + const glm::dvec3 tangent_point = bounds.centre(); + const glm::dvec2 radius_range = mask::pad_radius_range(mask::calculate_radius_range(bounds), 2); + if (mask.has_value()) { + auto result = mesh::intersection_and_difference(new_mesh, mask->mesh); + const SimpleMesh new_mesh_in_mask = std::move(result.intersection); + const SimpleMesh new_mesh_out_mask = std::move(result.difference); + const MeshMask mask_base_mesh = mask::create_from_mesh(base_mesh, tangent_point, radius_range); + const SimpleMesh new_mesh_out_mask_clipped = mesh::clip_on_mesh(new_mesh_out_mask, mask_base_mesh.mesh); + const MeshMask mask_new_mesh_in_mask = mask::create_from_mesh(new_mesh_in_mask, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh_in_mask.mesh); + return mesh::merge::merge_meshes(new_mesh_out_mask_clipped, base_mesh_clipped, new_mesh_in_mask); + } else { + const MeshMask mask_new_mesh = mask::create_from_mesh(new_mesh, tangent_point, radius_range); + const SimpleMesh base_mesh_clipped = mesh::clip_on_mesh(base_mesh, mask_new_mesh.mesh); + return mesh::merge::merge_meshes(base_mesh_clipped, new_mesh); } + */ + } - // Recursively get parent mask (root always exists) - const octree::Id parent_id = id.parent().value(); - const MeshMask &parent_mask = this->mask_for_node(parent_id); + MeshMask _mask = {}; + octree::Space _space; +}; - // Clip mask based on parent - const auto bounds = pad_bounds(this->_space.get_node_bounds(id), 1.1); - LOG_TRACE("Clipping mask for {}", id); - auto [it, inserted] = this->_masks.try_emplace( - id, - mesh::clip_on_bounds_and_cap(parent_mask.mesh, bounds) - ); +static_assert(Visitor); - return it->second; - } -}; } // namespace merge::visitor diff --git a/src/terrainmerger/merge/visitor/Simple.h b/src/terrainmerger/merge/visitor/Simple.h index 09a1d9c..890c884 100644 --- a/src/terrainmerger/merge/visitor/Simple.h +++ b/src/terrainmerger/merge/visitor/Simple.h @@ -2,53 +2,63 @@ #include "merge/Result.h" #include "merge/NodeData.h" -#include "merge/visitor/Base.h" +#include "merge/visitor/Visitor.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" namespace merge::visitor { -namespace { -inline Result merge_meshes( - const SimpleMesh &base_mesh, // left - const SimpleMesh &new_mesh // right -) { - // If one mesh is empty, return the other - if (base_mesh.is_empty()) { - return Unchanged { false }; - } - if (new_mesh.is_empty()) { - return Unchanged { true }; - } - - // TODO: this doesnt really work well if there are intersections - const SimpleMesh merged_mesh = mesh::merge(base_mesh, new_mesh); - return Merged {merged_mesh}; -} -} -class Simple : public Base { +class Simple { public: using Status = octree::NodeStatusOrMissing; + struct Context{}; + using Result = merge::Result; + + Context make_root_context() { + return {}; + } template Result visit( const octree::Id &, const NodeData &left, - const NodeData &right) { + const NodeData &right, + const Context& ctx) { if constexpr (right.status() == Status::Missing) { - return Unchanged{false}; + return Unchanged{Source::Left}; } if constexpr (left.status() == Status::Missing) { - return Unchanged{true}; + return Unchanged{Source::Right}; } if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { return merge_meshes(right.mesh(), left.mesh()); } - return Recurse{}; + return Recurse{ctx}; + } + +private: + Result merge_meshes( + const SimpleMesh &base_mesh, // left + const SimpleMesh &new_mesh // right + ) { + // If one mesh is empty, return the other + if (base_mesh.is_empty()) { + return Unchanged { Source::Right }; + } + if (new_mesh.is_empty()) { + return Unchanged { Source::Left }; + } + + // TODO: this doesnt really work well if there are intersections + const SimpleMesh merged_mesh = mesh::merge(base_mesh, new_mesh); + return Merged{merged_mesh}; } }; + +static_assert(Visitor); + } \ No newline at end of file diff --git a/src/terrainmerger/merge/visitor/Visitor.h b/src/terrainmerger/merge/visitor/Visitor.h new file mode 100644 index 0000000..35206fe --- /dev/null +++ b/src/terrainmerger/merge/visitor/Visitor.h @@ -0,0 +1,26 @@ +#pragma once + +#include "merge/NodeData.h" +#include "merge/Result.h" +#include "octree/Id.h" +#include "octree/NodeStatusOrMissing.h" + +namespace merge { +template +concept Visitor = requires(T t, const octree::Id &id) { + // Must define a nested Context type + typename T::Context; + + // Must provide a way to create the root context + { t.make_root_context() } -> std::same_as; + + { + t.template visit( + id, + std::declval &>(), + std::declval &>(), + std::declval()) + } -> std::same_as>; +}; + +} // namespace merge diff --git a/unittests/terrainlib/mesh_merge.cpp b/unittests/terrainlib/mesh_merge.cpp index 4ecbcc5..ffe3a0d 100644 --- a/unittests/terrainlib/mesh_merge.cpp +++ b/unittests/terrainlib/mesh_merge.cpp @@ -25,7 +25,7 @@ #include "mesh/utils.h" TEST_CASE("terrainmerger") { - SECTION("two tris") { + SECTION("two tris with shared edge") { SimpleMesh mesh1; mesh1.positions.push_back(glm::dvec3(0, 0, 0)); mesh1.positions.push_back(glm::dvec3(1, 1, 0)); @@ -51,9 +51,9 @@ TEST_CASE("terrainmerger") { sort_and_normalize_triangles(actual.triangles); sort_and_normalize_triangles(expected.triangles); - REQUIRE(expected.positions == actual.positions); - REQUIRE(expected.uvs == actual.uvs); - REQUIRE(expected.triangles == actual.triangles); + CHECK(expected.positions == actual.positions); + CHECK(expected.uvs == actual.uvs); + CHECK(expected.triangles == actual.triangles); } SECTION("two tris with uvs") { @@ -92,9 +92,9 @@ TEST_CASE("terrainmerger") { sort_and_normalize_triangles(actual.triangles); sort_and_normalize_triangles(expected.triangles); - REQUIRE(expected.positions == actual.positions); - REQUIRE(expected.uvs == actual.uvs); - REQUIRE(expected.triangles == actual.triangles); + CHECK(expected.positions == actual.positions); + CHECK(expected.uvs == actual.uvs); + CHECK(expected.triangles == actual.triangles); } SECTION("distance epsilon") { @@ -135,8 +135,63 @@ TEST_CASE("terrainmerger") { sort_and_normalize_triangles(actual.triangles); sort_and_normalize_triangles(expected.triangles); - REQUIRE(expected.positions == actual.positions); - REQUIRE(expected.uvs == actual.uvs); - REQUIRE(expected.triangles == actual.triangles); + CHECK(expected.positions == actual.positions); + CHECK(expected.uvs == actual.uvs); + CHECK(expected.triangles == actual.triangles); + } + + SECTION("merge with empty mesh") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + mesh1.positions.push_back(glm::dvec3(0, 1, 0)); + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2; // empty + + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); + + CHECK(mesh1.positions == actual.positions); + CHECK(mesh1.uvs == actual.uvs); + CHECK(mesh1.triangles == actual.triangles); + } + + /* + TODO: this currently fails since we dont deduplicate the triangles + SECTION("identical meshes collapse to one") { + SimpleMesh mesh1; + mesh1.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0)}; + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2 = mesh1; + + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.001); + + CHECK(actual.positions == mesh1.positions); + CHECK(actual.triangles == mesh1.triangles); + }*/ + + SECTION("epsilon too small prevents merging") { + SimpleMesh mesh1; + mesh1.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0)}; + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2; + mesh2.positions = { + glm::dvec3(1.05, 0, 0), // within large epsilon, not small + glm::dvec3(2, 0, 0), + glm::dvec3(1, 1, 0)}; + mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); + + auto merged_small = mesh::merge(mesh1, mesh2, 0.01); + auto merged_large = mesh::merge(mesh1, mesh2, 0.1); + + CHECK(merged_small.positions.size() > merged_large.positions.size()); } } diff --git a/unittests/terrainlib/mesh_merge_mapping.cpp b/unittests/terrainlib/mesh_merge_mapping.cpp index 0f1b2d7..f8fe677 100644 --- a/unittests/terrainlib/mesh_merge_mapping.cpp +++ b/unittests/terrainlib/mesh_merge_mapping.cpp @@ -63,20 +63,20 @@ TEST_CASE("merging::create_mapping") { // Merged index of (1, 0, 0) should be the same for both meshes size_t idx1 = mapping.map_forward(VertexId{0, 2}); size_t idx2 = mapping.map_forward(VertexId{1, 0}); - REQUIRE(idx1 == idx2); + CHECK(idx1 == idx2); // Merged index of (1,1,0) should be the same for both size_t idx3 = mapping.map_forward(VertexId{0, 1}); size_t idx4 = mapping.map_forward(VertexId{1, 1}); - REQUIRE(idx3 == idx4); + CHECK(idx3 == idx4); // (0, 1, 0) should be unique size_t idx5 = mapping.map_forward(VertexId{1, 2}); - REQUIRE(idx5 != idx1); - REQUIRE(idx5 != idx3); + CHECK(idx5 != idx1); + CHECK(idx5 != idx3); // Total unique merged vertices should be 4 - REQUIRE(mapping.find_max_merged_index() + 1 == 4); + CHECK(mapping.find_max_merged_index() + 1 == 4); } SECTION("similar vertices within epsilon are merged") { @@ -118,8 +118,8 @@ TEST_CASE("merging::create_mapping") { size_t idx1 = mapping.map_forward(VertexId{0, 0}); size_t idx2 = mapping.map_forward(VertexId{1, 0}); - REQUIRE(idx1 != idx2); - REQUIRE(mapping.find_max_merged_index() + 1 == 2); + CHECK(idx1 != idx2); + CHECK(mapping.find_max_merged_index() + 1 == 2); } SECTION("identity mapping on disjoint meshes") { @@ -135,8 +135,27 @@ TEST_CASE("merging::create_mapping") { VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // all far apart - REQUIRE(mapping.find_max_merged_index() + 1 == 4); - REQUIRE(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{0, 1})); - REQUIRE(mapping.map_forward(VertexId{1, 0}) != mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.find_max_merged_index() + 1 == 4); + CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{0, 1})); + CHECK(mapping.map_forward(VertexId{1, 0}) != mapping.map_forward(VertexId{1, 1})); + } + + SECTION("identical meshes collapse to one") { + SimpleMesh mesh1; + mesh1.positions = { + glm::dvec3(0, 0, 0), + glm::dvec3(1, 0, 0), + glm::dvec3(0, 1, 0)}; + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2 = mesh1; + + std::array, 2> meshes = {mesh1, mesh2}; + + VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + CHECK(mapping.map_forward(VertexId{0, 0}) == mapping.map_forward(VertexId{1, 0})); + CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.map_forward(VertexId{0, 2}) == mapping.map_forward(VertexId{1, 2})); } } From c30c8421724e28814f0e218203653a3598782ed6 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 15 Aug 2025 21:14:33 +0200 Subject: [PATCH 106/122] Ignore vertical distance during merging --- src/CMakeLists.txt | 1 + .../SphereProjector.h | 0 src/terrainlib/mesh/merge.h | 23 ++++++- .../mesh/merging/EpsilonVertexDeduplicate.h | 4 +- .../mesh/merging/SphereVertexDeduplicate.h | 32 +++++++++ .../mesh/merging/SphereVertexDeduplicate2.h | 42 ++++++++++++ src/terrainlib/mesh/merging/helpers.h | 65 +++++++++++++++++++ src/terrainlib/mesh/merging/mapping.cpp | 55 +--------------- src/terrainlib/mesh/merging/mapping.h | 1 + src/terrainlib/mesh/utils.cpp | 40 ------------ src/terrainlib/mesh/utils.h | 9 ++- src/terrainlib/mesh/utils.inl | 37 +++++++++++ .../spatial_lookup/HashmapStorage.h | 5 +- src/terrainmerger/main.cpp | 1 - src/terrainmerger/merge/visitor/Masked.h | 22 ++++++- 15 files changed, 235 insertions(+), 102 deletions(-) rename src/{terrainmerger => terrainlib}/SphereProjector.h (100%) create mode 100644 src/terrainlib/mesh/merging/SphereVertexDeduplicate.h create mode 100644 src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h create mode 100644 src/terrainlib/mesh/merging/helpers.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f5d6bc1..bc7b7b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -173,6 +173,7 @@ add_library(terrainlib terrainlib/init.h terrainlib/init.cpp terrainlib/log.h terrainlib/log.cpp terrainlib/ProgressIndicator.h terrainlib/ProgressIndicator.cpp + terrainlib/SphereProjector.h terrainlib/srs.h terrainlib/string_utils.h ) diff --git a/src/terrainmerger/SphereProjector.h b/src/terrainlib/SphereProjector.h similarity index 100% rename from src/terrainmerger/SphereProjector.h rename to src/terrainlib/SphereProjector.h diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 68a0c92..550813f 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -15,6 +15,28 @@ SimpleMesh merge(const std::span> SimpleMesh merge(const std::span> meshes, double distance_epsilon); SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate); +template +SimpleMesh merge(const std::span meshes, Args &&...args) { + std::array, N> refs; + for (size_t i=0; i, N>(refs), std::forward(args)...); +} +template +SimpleMesh merge(const std::span meshes, Args &&...args) { + std::vector> refs; + refs.reserve(meshes.size()); + for (const auto &mesh : meshes) { + refs.push_back(std::cref(mesh)); + } + return merge(std::span>(refs), std::forward(args)...); +} + +template +SimpleMesh merge(const SimpleMesh &mesh1, Args &&...args) { + return mesh1; +} template SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, Args &&...args) { const std::array, 2> meshes = {mesh1, mesh2}; @@ -30,5 +52,4 @@ SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, const SimpleM const std::array, 4> meshes = {mesh1, mesh2, mesh3, mesh4}; return merge(std::span>(meshes), std::forward(args)...); } - } diff --git a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h index 5e5a3a8..8d33957 100644 --- a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h @@ -17,10 +17,10 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate_epsilon; } - void add(const Vec &point, const Meta meta) override { + virtual void add(const Vec &point, const Meta meta) override { this->_lookup.insert(point, meta); } - bool get(const Vec &point, std::vector> &duplicates) const override { + virtual bool get(const Vec &point, std::vector> &duplicates) const override { return this->_lookup.find_all_near(point, this->_epsilon, duplicates); } diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h b/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h new file mode 100644 index 0000000..c8f6951 --- /dev/null +++ b/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h @@ -0,0 +1,32 @@ +#pragma once + +#include "mesh/merging/EpsilonVertexDeduplicate.h" +#include "mesh/merging/VertexDeduplicate.h" +#include "spatial_lookup/SpatialLookup.h" + +namespace mesh::merging { + +template Lookup> +class SphereVertexDeduplicate : public VertexDeduplicate<3, double, Meta> { +public: + using Vec = glm::vec<3, double>; + using MappedVec = glm::vec<2, double>; + + SphereVertexDeduplicate(Lookup &lookup, double epsilon, Vec tangent_point) + : _inner(lookup, epsilon), _projector(tangent_point) {} + + void add(const Vec &point, const Meta meta) override { + const MappedVec mapped = this->_projector.project_point(point); + this->_inner.add(mapped, meta); + } + bool get(const Vec &point, std::vector> &duplicates) const override { + const MappedVec mapped = this->_projector.project_point(point); + return this->_inner.get(mapped, duplicates); + } + +private: + EpsilonVertexDeduplicate<2, double, Meta, Lookup> _inner; + SphereProjector _projector; +}; + +} diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h b/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h new file mode 100644 index 0000000..6fd4c94 --- /dev/null +++ b/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h @@ -0,0 +1,42 @@ +#pragma once + +#include "mesh/merging/EpsilonVertexDeduplicate.h" +#include "mesh/merging/VertexDeduplicate.h" +#include "spatial_lookup/SpatialLookup.h" + +namespace mesh::merging { + +namespace { +template +glm::vec scale_to_length(const glm::vec &v, const T target_length) { + const T len = glm::length(v); + if (len == T(0)) { + return glm::vec(T(0)); + } + return v * (target_length / len); +} +} + +template Lookup> +class SphereVertexDeduplicate2 : public VertexDeduplicate<3, double, Meta> { +public: + using Vec = glm::vec<3, double>; + + SphereVertexDeduplicate2(Lookup &lookup, double epsilon, double radius) + : _inner(lookup, epsilon), _radius(radius) {} + + void add(const Vec &point, const Meta meta) override { + const Vec mapped = scale_to_length(point, this->_radius); + this->_inner.add(mapped, meta); + } + bool get(const Vec &point, std::vector> &duplicates) const override { + const Vec mapped = scale_to_length(point, this->_radius); + return this->_inner.get(mapped, duplicates); + } + +private: + EpsilonVertexDeduplicate<3, double, Meta, Lookup> _inner; + double _radius; +}; +} + diff --git a/src/terrainlib/mesh/merging/helpers.h b/src/terrainlib/mesh/merging/helpers.h new file mode 100644 index 0000000..a376c38 --- /dev/null +++ b/src/terrainlib/mesh/merging/helpers.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/utils.h" +#include "spatial_lookup/Grid.h" + +namespace mesh::merging { + +inline double estimate_merge_epsilon(const std::span> meshes) { + double total_length = 0.0; + size_t total_triangle_count = 0; + for (const auto &mesh_ref : meshes) { + const SimpleMesh &mesh = mesh_ref.get(); + const auto avg_length_opt = estimate_average_edge_length(mesh); + if (avg_length_opt) { + const size_t num_triangles = mesh.triangles.size(); + total_length += avg_length_opt.value() * num_triangles; + total_triangle_count += num_triangles; + } + } + + const double average_edge_length = total_length / total_triangle_count; + const double distance_epsilon = average_edge_length / 1000; + return distance_epsilon; +} + +namespace { +radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { + const glm::dvec3 bounds_padding = bounds.size() * percentage; + const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); + return padded_bounds; +} + +template +spatial_lookup::Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { + const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); + + const double max_extends = glm::compMax(padded_bounds.size()); + const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; + const glm::uvec3 grid_divisions = glm::max(glm::uvec3(2 * std::cbrt(vertex_count) * relative_extends), glm::uvec3(1)); + spatial_lookup::Grid3d grid(padded_bounds.min, padded_bounds.size(), grid_divisions); + + return grid; +} +} + +template +spatial_lookup::Grid3d construct_grid_for_mesh(const SimpleMesh &mesh) { + const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); + const size_t vertex_count = mesh.vertex_count(); + return _construct_grid_for_meshes(bounds, vertex_count); +} + +template +spatial_lookup::Grid3d construct_grid_for_meshes(const std::span> meshes) { + const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); + const size_t maximal_merged_mesh_size = std::transform_reduce( + meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); + return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); +} + +} // namespace mesh::merging diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index a7dfeaa..a3df5c0 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -10,6 +10,7 @@ #include "mesh/convert.h" #include "mesh/merging/EpsilonVertexDeduplicate.h" #include "mesh/merging/mapping.h" +#include "mesh/merging/helpers.h" #include "mesh/utils.h" #include "mesh/validate.h" #include "spatial_lookup/Grid.h" @@ -18,58 +19,6 @@ namespace mesh::merging { -namespace { -radix::geometry::Aabb3d pad_bounds(const radix::geometry::Aabb3d &bounds, const double percentage) { - const glm::dvec3 bounds_padding = bounds.size() * percentage; - const radix::geometry::Aabb3d padded_bounds(bounds.min - bounds_padding, bounds.max + bounds_padding); - return padded_bounds; -} - -template -spatial_lookup::Grid3d _construct_grid_for_meshes(const radix::geometry::Aabb3d &bounds, const size_t vertex_count) { - const radix::geometry::Aabb3d padded_bounds = pad_bounds(bounds, 0.01); - - const double max_extends = glm::compMax(padded_bounds.size()); - const glm::dvec3 relative_extends = padded_bounds.size() / max_extends; - const glm::uvec3 grid_divisions = glm::max(glm::uvec3(2 * std::cbrt(vertex_count) * relative_extends), glm::uvec3(1)); - spatial_lookup::Grid3d grid(padded_bounds.min, padded_bounds.size(), grid_divisions); - - return grid; -} - -template -spatial_lookup::Grid3d construct_grid_for_mesh(const SimpleMesh &mesh) { - const radix::geometry::Aabb3d bounds = calculate_bounds(mesh); - const size_t vertex_count = mesh.vertex_count(); - return _construct_grid_for_meshes(bounds, vertex_count); -} - -template -spatial_lookup::Grid3d construct_grid_for_meshes(const std::span> meshes) { - const radix::geometry::Aabb3d bounds = calculate_bounds(meshes); - const size_t maximal_merged_mesh_size = std::transform_reduce( - meshes.begin(), meshes.end(), 0, [](const size_t a, const size_t b) { return a + b; }, [](const SimpleMesh &mesh) { return mesh.vertex_count(); }); - return _construct_grid_for_meshes(bounds, maximal_merged_mesh_size); -} - -double estimate_merge_epsilon(const std::span> meshes) {double total_length = 0.0; - size_t total_triangle_count = 0; - for (const auto &mesh_ref : meshes) { - const SimpleMesh &mesh = mesh_ref.get(); - const auto avg_length_opt = estimate_average_edge_length(mesh); - if (avg_length_opt) { - const size_t num_triangles = mesh.triangles.size(); - total_length += avg_length_opt.value() * num_triangles; - total_triangle_count += num_triangles; - } - } - - const double average_edge_length = total_length / total_triangle_count; - const double distance_epsilon = average_edge_length / 1000; - return distance_epsilon; -} -} - VertexMapping create_mapping(const std::span> meshes) { if (meshes.empty()) { return {}; @@ -84,6 +33,7 @@ void validate_epsilon_mapping( const VertexMapping &mapping, const std::span> meshes, double epsilon) { +#ifndef NDEBUG const double epsilon2 = epsilon * epsilon; const size_t max_merged_index = mapping.find_max_merged_index(); @@ -109,6 +59,7 @@ void validate_epsilon_mapping( } } } +#endif } } diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 0daa063..30d721d 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -9,6 +9,7 @@ namespace mesh::merging { // VertexMapping create_connecting_mapping(std::span meshes); + VertexMapping create_mapping( const std::span> meshes); VertexMapping create_mapping( diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index 4785bae..723358a 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -7,46 +7,6 @@ #include "mesh/utils.h" #include "mesh/validate.h" -namespace { -template -const T& unwrap(const T& t) { - return t; -} - -template -const T& unwrap(const std::reference_wrapper& t) { - return t.get(); -} - -template -radix::geometry::Aabb3d calculate_bounds_range(const MeshRange &meshes) { - radix::geometry::Aabb3d bounds; - constexpr double inf = std::numeric_limits::infinity(); - bounds.min = glm::dvec3(+inf); - bounds.max = glm::dvec3(-inf); - - for (const auto &wrapper : meshes) { - const auto &mesh = unwrap(wrapper); - for (const auto &position : mesh.positions) { - bounds.expand_by(position); - } - } - return bounds; -} -} - -radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh) { - return calculate_bounds_range(std::array{std::cref(mesh)}); -} - -radix::geometry::Aabb3d calculate_bounds(std::span meshes) { - return calculate_bounds_range(meshes); -} - -radix::geometry::Aabb3d calculate_bounds(std::span> meshes) { - return calculate_bounds_range(meshes); -} - std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size) { const auto &triangles = mesh.triangles; const auto &positions = mesh.positions; diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index a077353..de7f5b5 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -10,9 +10,12 @@ // TODO: put in mesh namespace // TODO: make all methods work with SimpleMesh_ -radix::geometry::Aabb3d calculate_bounds(const SimpleMesh &mesh); -radix::geometry::Aabb3d calculate_bounds(const std::span meshes); -radix::geometry::Aabb3d calculate_bounds(const std::span> meshes); +template +radix::geometry::Aabb calculate_bounds(const SimpleMesh_ &mesh); +template +radix::geometry::Aabb calculate_bounds(const std::span> meshes); +template +radix::geometry::Aabb calculate_bounds(const std::span>> meshes); std::optional estimate_average_edge_length(const SimpleMesh &mesh, const size_t sample_size = 1000); std::optional calculate_max_edge_length(const SimpleMesh &mesh); diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl index 55fa527..9187035 100644 --- a/src/terrainlib/mesh/utils.inl +++ b/src/terrainlib/mesh/utils.inl @@ -2,6 +2,43 @@ #include "mesh/SimpleMesh.h" +namespace { +template +auto calculate_bounds_range(const MeshRange &meshes) { + using Mesh = std::unwrap_reference_t>; + using Vec = std::remove_cvref_t().positions[0])>; + using T = typename Vec::value_type; + constexpr glm::length_t n_dims = Vec::length(); + + radix::geometry::Aabb bounds; + constexpr T inf = std::numeric_limits::infinity(); + bounds.min = Vec(+inf); + bounds.max = Vec(-inf); + + for (const auto &mesh_ref : meshes) { + const Mesh &mesh = mesh_ref; + for (const auto &position : mesh.positions) { + bounds.expand_by(position); + } + } + + return bounds; +} +} + +template +radix::geometry::Aabb calculate_bounds(const SimpleMesh_ &mesh) { + return calculate_bounds_range(std::array{std::cref(mesh)}); +} +template +radix::geometry::Aabb calculate_bounds(const std::span> meshes) { + return calculate_bounds_range(meshes); +} +template +radix::geometry::Aabb calculate_bounds(const std::span>> meshes) { + return calculate_bounds_range(meshes); +} + template std::vector find_isolated_vertices(const SimpleMesh_ &mesh) { std::vector connected; diff --git a/src/terrainlib/spatial_lookup/HashmapStorage.h b/src/terrainlib/spatial_lookup/HashmapStorage.h index a98ba14..0b4a129 100644 --- a/src/terrainlib/spatial_lookup/HashmapStorage.h +++ b/src/terrainlib/spatial_lookup/HashmapStorage.h @@ -56,8 +56,6 @@ class HashmapStorage { using Self = HashmapStorage; using Vec = glm::vec; using Bounds = radix::geometry::Aabb; - using Hash = VecHash ; - using Equal = NeverEqual; struct CellIndex { explicit CellIndex(const Vec& v) : quantized(v) {} @@ -127,6 +125,9 @@ class HashmapStorage { } private: + using Hash = VecHash; + using Equal = NeverEqual; + Component _epsilon; std::unordered_map _store; diff --git a/src/terrainmerger/main.cpp b/src/terrainmerger/main.cpp index 2f46315..5e8091c 100644 --- a/src/terrainmerger/main.cpp +++ b/src/terrainmerger/main.cpp @@ -42,7 +42,6 @@ void run(const cli::MergeArgs& args) { std::filesystem::create_directories(args.output_path); octree::Storage output_dataset = octree::open_folder(args.output_path, false, octree::OpenOptions{.preferred_extension_with_dot = ".glb"}); - std::optional mask = flatten(map(args.mask_path, load_mask_from_path)); return merge_datasets(base_dataset, new_dataset, output_dataset, mask); diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 9556555..1fc1de6 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -5,8 +5,12 @@ #include "merge/Result.h" #include "merge/visitor/Visitor.h" #include "mesh/merge.h" +#include "mesh/merging/SphereVertexDeduplicate.h" +#include "mesh/merging/SphereVertexDeduplicate2.h" +#include "mesh/merging/helpers.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" +#include "spatial_lookup/Hashmap.h" #include "utils.h" namespace merge::visitor { @@ -165,7 +169,23 @@ class Masked { } } - const SimpleMesh merged_mesh = mesh::merge(base_mesh_clipped, new_mesh_clipped); + const std::array, 2> meshes = {base_mesh_clipped.get(), new_mesh_clipped.get()}; + const double distance_epsilon = mesh::merging::estimate_merge_epsilon(meshes); + /* + spatial_lookup::Hashmap2d map(distance_epsilon * 3); + const glm::dvec3 tangent_point = meshes[0].get().positions[0]; + mesh::merging::SphereVertexDeduplicate< + mesh::merging::VertexId, + spatial_lookup::Hashmap2d + > deduplicate(map, 0.01, tangent_point); + */ + auto map = mesh::merging::construct_grid_for_meshes(meshes); + const double radius = glm::length(meshes[0].get().positions[0]); + mesh::merging::SphereVertexDeduplicate2< + mesh::merging::VertexId, + decltype(map) + > deduplicate(map, distance_epsilon, radius); + const SimpleMesh merged_mesh = mesh::merge(meshes, deduplicate); return Merged{merged_mesh}; /* From b36965512b18c3f1d26990a4c0020da5e282b9a9 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 15 Aug 2025 23:59:24 +0200 Subject: [PATCH 107/122] Remove tntn docs --- docs/tntn/Mesh Generation Algorithms.md | 59 ------ docs/tntn/NOTICE | 31 --- docs/tntn/Terra.md | 179 ---------------- docs/tntn/Zemlya.md | 197 ------------------ .../4D859D9DDCB9690EFB04E6CCC75FABDC.jpg | Bin 75136 -> 0 bytes .../7AD175B29AB688F685EBE45F6D46FAE3.jpg | Bin 40616 -> 0 bytes .../BCF6BEB84B3CEAA40839170C4E5ACF22.jpg | Bin 554840 -> 0 bytes docs/tntn/resources/dem2tin.jpg | Bin 167246 -> 0 bytes 8 files changed, 466 deletions(-) delete mode 100644 docs/tntn/Mesh Generation Algorithms.md delete mode 100644 docs/tntn/NOTICE delete mode 100644 docs/tntn/Terra.md delete mode 100644 docs/tntn/Zemlya.md delete mode 100644 docs/tntn/resources/4D859D9DDCB9690EFB04E6CCC75FABDC.jpg delete mode 100644 docs/tntn/resources/7AD175B29AB688F685EBE45F6D46FAE3.jpg delete mode 100644 docs/tntn/resources/BCF6BEB84B3CEAA40839170C4E5ACF22.jpg delete mode 100644 docs/tntn/resources/dem2tin.jpg diff --git a/docs/tntn/Mesh Generation Algorithms.md b/docs/tntn/Mesh Generation Algorithms.md deleted file mode 100644 index 617b9fd..0000000 --- a/docs/tntn/Mesh Generation Algorithms.md +++ /dev/null @@ -1,59 +0,0 @@ -# Mesh Generation Algorithms - -Surface mesh models are commonly used in computer graphics, mechanical engineering and other fields for both visualization and simulation. There are generally two broad categories of such surface mesh models: a Triangulated Regular Network (TRN), and a Triangulated Irregular Network (TIN). - -A Triangulated Regular Network (TRN) simply connects input raster points into a uniform grid of triangles. The resulting surface mesh uses the same number of triangles in each unit area, so they are typically quite dense and thus unsuitable for data visualization. - -A Triangulated Irregular Network (TIN) takes advantage of the fact that natural terrains often consist of slowly-changing areas that can be approximated with fewer number of triangles per unit area. The resulting mesh uses significantly fewer triangles compared to a TRN, thus is more suitable for both data storage and visualization. The amount of information loss can be controlled by a given meshing parameter (vertical error tolerance in meters), thus different levels of compression can be used depending on the user's requirement. - -![BCF6BEB84B3CEAA40839170C4E5ACF22.jpg](https://raw.githubusercontent.com/heremaps/tin-terrain/algorithm-docs.ylian/docs/resources/BCF6BEB84B3CEAA40839170C4E5ACF22.jpg) (Figures are from: Garland, Michael, and Paul S. Heckbert. "Fast polygonal approximation of terrains and height fields." (1995).) - -## The TIN Model - -The Triangulated Irregular Network (TIN) surface model consists of irregularly spaced points connected into various sizes of faces (triangles) that approximate the original terrain surface. Fewers vertices or triangles are used in smooth areas and more are used in rough areas. The TIN model is currently used in numerous GIS applications. - -A good TIN model should have the following properties: -* It should give a good approximation of the original terrain surface in both smooth and rough areas. The error map of the TIN model should not contain noticable features from the original terrain surface. -* The difference between the TIN model and the original terrain surface should be predictable and controllable, meaning that the error metric of the TIN model should go down in a predictable manner as more vertices or triangles are used. -* The TIN model generation should be fast. - -Mathematically speaking, creating a TIN model is a 2D surface approximation problem. The ideal surface most likely would not consist of only points from the original raster, but may be slightly above or below the original raster points. However, a 2D surface approximation algorithm such as Poisson Surface Reconstruction is usually very computation-intensive. That's why most practical TIN generation algorithms used today only insert points from the original raster. This approach reduces the complexity of a 2D surface approximation problem to picking key points then applying Delaunay triangulation. - -## Algorithms for TIN Generation - -There are many classes of TIN generation algorithms, but they can be roughly categorized into the following groups: -* One pass feature methods, which pick "feature" points (such as peaks, pits, ridges, and valleys) in one pass and use them as the vertex set for Delaunay triangulation. -* Multi-pass refinement methods, which start with a minimal approximation and use multiple passes to insert points from the original raster, and retriangulate at every step. -* Multi-pass decimation methods, which start with a regular mesh, then iteratively delete vertices from the mesh. - -### One-pass feature methods - -Various one-pass feature methods have been developed in the past few decades. We are not going to discuss these methods in detail, but only list below the most important methods and their papers. - -1. Fowler and Little Algorithm: - Fowler, Robert J., and James J. Little. "Automatic extraction of irregular network digital terrain models." ACM SIGGRAPH Computer Graphics 13.2 (1979): 199-207. -2. VIP (Very Important Points) Algorithm: - Chen, Zi-Tan, and J. Armando Guevara. "Systematic selection of very important points (VIP) from digital terrain model for constructing triangular irregular networks." Auto-carto. Vol. 8. 1987. -3. Lee's Drop Heuristic Algorithm: - Lee, Jay. "Comparison of existing methods for building triangular irregular network, models of terrain from grid digital elevation models." International Journal of Geographical Information System 5.3 (1991): 267-285. - -### Multi-pass refinement methods - -Michael Garland gave a detailed comparison of multi-pass refinement methods in his 1995 paper (Garland, Michael, and Paul S. Heckbert. "Fast polygonal approximation of terrains and height fields." (1995)). He concluded that the greedy insertion algorithm gives the best result for various types of terrains. (The most difficult case is a mix of slowly-varying terrain with fast-changing local features inside one raster.) Also, he compared the results from using several different error metrics, and concluded that the simplest error metric (absolute error) actually works the best. In his paper he also made several optimizations to the greedy insertion algorithm to significantly improve its performance. - -The greedy insertion algorithm is a refinement algorithm. It starts with a simple triangulation of the raster (typically forming two triangles with four corner points of the raster), then on each pass, finds the raster point with the highest error in the current approximation, and inserts it into the mesh. After inserting the point, we retriangulate the mesh using incremental Delaunay triangulation (meaning that only the triangles near the inserted points are updated), and then we repeat the process until no point with an error above a given threshold is left. - -This algorithm is called "greedy" because an inserted point cannot be updated or removed in subsequent passes. This algorithm uses sequential insertion (inserting one point at a time) instead of parallel insertion (inserting all points that exceed the error threshold at once) because parallel insertion often results in worse results since it doesn't take into account the mesh changes while other points are being inserted. - -Michael Garland implemented his version of the Greedy Insertion algorithm in a software package called [Terra](https://mgarland.org/software/terra.html) and released it to the public domain. - -The Terra algorithm is implemented in the "TIN Terrain" tool as the "terra" method. This is currently the default meshing algorithm used by the "TIN Terrain" tool. - -### Multi-pass decimation methods - -We will not cover the multi-pass decimation methods here since we haven't yet looked into them. Feel free to contribute your edits to this section. - -## Algorithms implemented in "TIN Terrain" - -Several meshing algorithms have been implemented in the "TIN Terrain" tool. In the same folder of this document, you will find other documents explaining these algorithms in detail. - diff --git a/docs/tntn/NOTICE b/docs/tntn/NOTICE deleted file mode 100644 index 6a1cab5..0000000 --- a/docs/tntn/NOTICE +++ /dev/null @@ -1,31 +0,0 @@ -The files in this directory are from tin-terrain: -https://github.com/adam-ce/tin-terrain -forked from -https://github.com/heremaps/tin-terrain - -------------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (C) 2018 HERE Europe B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -------------------------------------------------------------------------------- diff --git a/docs/tntn/Terra.md b/docs/tntn/Terra.md deleted file mode 100644 index e851a5a..0000000 --- a/docs/tntn/Terra.md +++ /dev/null @@ -1,179 +0,0 @@ -# Terra - -The "Terra" meshing algorithm implemented in the TIN Terrain tool is based on [Michael Garland's 1995 research paper](https://mgarland.org/papers/scape.pdf) on greedy insertion algorithms and his [open-source implementation](https://mgarland.org/software/terra.html) (released to public domain). - -Paper: Garland, Michael, and Paul S. Heckbert. "Fast polygonal approximation of terrains and height fields." (1995). - -## Algorithm - -The basic algorithm of greedy insertion starts with a simple triangulation of the original raster. For example, you can use the four corner points of the original raster to form two triangles as the initial mesh. - -Then on each pass, find the raster point with the highest error in the current mesh, and insert it as a new vertex. The mesh is then updated using incremental Delaunay triangulation. - -The insertion process is greedy, meaning that once a point is inserted, it's never updated or deleted. It's also sequential, as only one point is inserted at a time. - -The error metric is defined as the absolute difference between the height value of the original raster point and the interpolated height value at the same point of the current mesh approximation. This simple error metric definition turns out to work better than more sophisticated ones. - -The incremental Delaunay triangulation works as follows: -1. To insert a new vertex A, first locate its containing triangle. -2. Add "spoke" edges from vertex A to the vertices of this containing triangle. -3. All perimeter edges of the containing polygon need to be validated since they may not conform to Delaunay requirements any more. All invalid edges must be swapped with the other diagonal of the quadrilateral containing them. Continue this process until no invalid edges are left. - -Since it is costly to scan the whole raster to find the highest error point, we can cache the error calculations by storing the highest error point (called a "candidate point") of each triangle in the current mesh approximation. When a triangle is changed, we update the candidate point of this triangle. This way we can avoid recalculating the highest error points of all triangles on each insertion. - -## Implementation - -Below we describe in detail how the "Terra" meshing algorithm is implemented in the TIN Terrain tool. - -### Quad-Edge Data Structure - -The Quad-Edge data structure is used to efficiently describe and walk the mesh. This data structure is designed to find the vertices/edges/faces immediately adjacent to a given vertex/edge/face in constant time. - -In the TIN Terrain tool, the quad-edge data structure is implemented in "QuadEdge.h/cpp" and "DelaunayTriangle.h/cpp". - -![7AD175B29AB688F685EBE45F6D46FAE3.jpg](https://raw.githubusercontent.com/heremaps/tin-terrain/algorithm-docs.ylian/docs/resources/7AD175B29AB688F685EBE45F6D46FAE3.jpg) - -(Illustration from ) - -Each QuadEdge object internally stores pointers to three more edges: its inverse (`e->Sym`), dual edge pointing to the left (`e->Rot`), and dual edge pointing to the right (`e->InvRot`), as shown in the illustration above. - -```c -class QuadEdge -{ - qe_ptr qnext; //aka Rot - qe_ptr qprev; //aka invRot - qe_ptr self_ptr; - qe_ptr next; //aka Onext - - //next edge around origin, with same origin - qe_ptr Onext() const noexcept { return next; } - - //edge pointing opposite to this - qe_ptr Sym() const { return qnext->qnext; } - - //dual edge pointing to the left of this - qe_ptr Rot() const noexcept { return qnext; } - - //dual edge pointing to the right of this - qe_ptr invRot() const noexcept { return qprev; } -} -``` - -![4D859D9DDCB9690EFB04E6CCC75FABDC.jpg](https://raw.githubusercontent.com/heremaps/tin-terrain/algorithm-docs.ylian/docs/resources/4D859D9DDCB9690EFB04E6CCC75FABDC.jpg) - -(Illustration from ) - -With these pointers, a QuadEdge object can quickly find the adjacent vertices/edges/faces. For example, `e->Rot()->Onext()->Rot()` gives the previous edge around the same origin. - -Below are convenience methods defined in the QuadEdge class for quick access to adjacent edges: - -```c -class QuadEdge -{ - //next edge around origin, with same origin - qe_ptr Onext() const noexcept { return next; } - - //edge pointing opposite to this - qe_ptr Sym() const { return qnext->qnext; } - - //dual edge pointing to the left of this - qe_ptr Rot() const noexcept { return qnext; } - - //dual edge pointing to the right of this - qe_ptr invRot() const noexcept { return qprev; } - - // Synthesized methods - qe_ptr Oprev() const { return Rot()->Onext()->Rot(); } - qe_ptr Dnext() const { return Sym()->Onext()->Sym(); } - qe_ptr Dprev() const { return invRot()->Onext()->invRot(); } - - //next edge around left face, with same left face - qe_ptr Lnext() const { return invRot()->Onext()->Rot(); } - //prev edge around left face, with same left face - qe_ptr Lprev() const { return Onext()->Sym(); } - - //next edge around right face, with same right face - qe_ptr Rnext() const { return Rot()->Onext()->invRot(); } - //prev edge around right face, with same right face - qe_ptr Rprev() const { return Sym()->Onext(); } -}; -``` - -For a deeper understanding of the Quad-Edge data structure, please read this handout: - - - -### Incremental Delaunay - -The incremental Delaunay triangulation is implemented in "DelaunayMesh.h/cpp". The key method in this class is `DelaunayMesh::insert()`, which inserts a new vertex into the mesh. Inserting a new vertex requires creating spokes from the new vertex to the vertices of the enclosing triangle, as well as updating the affected edges so that they still satisfy Delaunay requirements. - -```c -void DelaunayMesh::insert(const Point2D x, dt_ptr tri) -{ - qe_ptr e = tri ? locate(x, tri->getAnchor()) : locate(x); - - if((x == e->Org()) || (x == e->Dest())) - { - // point is already in the mesh, skip it - return; - } - else - { - qe_ptr start_spoke = spoke(x, e); - if(start_spoke) - { - optimize(x, start_spoke->Sym()); - } - } -} -``` - -Every time a triangle is updated during re-triangulation, we scan the triangle again to update the candidate point with the greatest error, as discussed in the next section. - -### Greedy Insertion - -The greedy insertion algorithm is implemented in "TerraMesh.h/cpp". - -The algorithm starts with an initial mesh configuration: two triangles formed by four corner points. If any corner point is missing from the original raster, we fill the point with its closest average value. - -```c -// Ensure the four corners are not NO_VALUE, otherwise the algorithm can't proceed. -this->repair_point(0, 0); -this->repair_point(0, h - 1); -this->repair_point(w - 1, h - 1); -this->repair_point(w - 1, 0); - -// Initialize the mesh to two triangles with the height field grid corners as vertices -this->init_mesh(glm::dvec2(0, 0), glm::dvec2(0, h - 1), glm::dvec2(w - 1, h - 1), glm::dvec2(w - 1, 0)); -``` - -Then we scan all the triangles and push the points with highest errors in each triangle into a priority queue. The candidates points are stored in a priority queue, because we want to retrieve the point with the greatest error as quickly as possible. We iterate this process until no point with an error higher than a given `max-error` tolerance is found. - -Note that an inserted point is immediately marked as used, so it won't be scanned again in the future. An inserted point is never updated or removed. - -```c -// Scan all the triangles and push all candidates into a stack -dt_ptr t = m_first_face; -while(t) -{ - scan_triangle(t); - t = t->getLink(); -} - -// Iterate until the error threshold is met -while(!m_candidates.empty()) -{ - Candidate candidate = m_candidates.grab_greatest(); - - if(candidate.importance < m_max_error) continue; - - // Skip if the candidate is not the latest - if(m_token.value(candidate.y, candidate.x) != candidate.token) continue; - - m_used.value(candidate.y, candidate.x) = 1; - - this->insert(glm::dvec2(candidate.x, candidate.y), candidate.triangle); -} -``` - -After the iteration process is over, we can export the mesh to an OBJ file using the `TerraMesh::convert_to_mesh()` method. diff --git a/docs/tntn/Zemlya.md b/docs/tntn/Zemlya.md deleted file mode 100644 index 116d485..0000000 --- a/docs/tntn/Zemlya.md +++ /dev/null @@ -1,197 +0,0 @@ -# Zemlya - -Like Terra, the "Zemlya" meshing algorithm implemented in the TIN Terrain tool is also a greedy insertion algorithm, but with ideas borrowed from cartographic maps, particularly the quad-tree data structure commonly used in web maps. - -In general, Zemlya offers similar performance and slightly better mesh qualities (given the same number of vertices/triangles) as Terra, especially for DTM (Digital Terrain Model) datasets. - -With the `tin-terrain` command line tool, you can pass in an option `--method zemlya` to use Zemlya as the mesh generation algorithm. - -## Hierarchical Greedy Insertion - -The idea of "Zemlya" came from the quad-tree data structure often used in web maps. In web maps, different zoom levels are used to display maps at different levels of details. When you look at a terrain map, at lower zoom levels you only see big mountain ranges, but as you zoom into the map, you start to see more and more detailed local terrain features. - -The key insight is that resamping the original heightmap at different resolutions can reveal terrain structures at corresponding scales. By resampling at different zoom levels, we can fix the Greedy Insertion algorithm’s biggest shortcoming: its heavy dependency on the points from the original raster. - -Zemlya is a hierarchical greedy insertion algorithm. The algorithm works as follows: - -1. First, it repeatedly downsamples the original raster to create average values for lower zoom levels, all the way to zoom level 1. -2. Then it iterates over all the zoom levels in a top-down fashion, starting with zoom level 1. At each zoom level, we start with the mesh generated from the previous zoom level, then insert the average values at this zoom level using the same greedy insertion algorithm as in Terra. -3. We iterate over all the zoom levels until we reach the final zoom level, which consists of points from the original raster. - -If we only run greedy insertion on the final zoom level, Zemlya is equivalent to Terra. However, by taking advantage of average values from previous levels and gradually refining the terrain meshes, we can achieve better mesh qualities using fewer vertices/triangles, since mesh approximations from previous zoom levels provide a much better initial configuration than the simplistic initial mesh used in Terra. - -Compared to the Greedy Insertion algorithm: - -* We have to scan more points since we iterate over all the lower zoom levels as well. For 1M points, N = 1000, number of zoom levels = 10, so Zemlya need to scan around 1.33M points, about 33% more than Terra. -* However, since Zemlya always starts with a pretty good mesh approximation at each zoom level, the required amount of adjustment becomes significantly less. This means fewer triangles/vertices will be actually inserted into the final mesh. -* Zemlya uses not only point values from the original raster, but also many levels of average values, so it’s not as heavily dependent on the data points in the original raster as Terra. - -## Implementation - -In the TIN Terrain tool, the Zemlya meshing algorithm is implemented in "ZemlyaMeshing.h/cpp". - -The key method is `ZemlyaMesh::greedy_insert(double max_error)`. It takes a single input parameter which is the vertical error tolerance in meters. This input parameter should be set to a value comparable to or larger than the spatial resolution of the original raster, since the meshing algorithm will not be able to produce a mesh with a higher resolution than in the original raster. - -In the `greedy_insert()` method implementation, we first create another raster `m_sample` to store average values, with the same dimensions as the original raster. - -```c -int w = m_raster->get_width(); -int h = m_raster->get_height(); -m_sample.allocate(w, h); -``` - -We also determine the max zoom level, which is the level where the original raster lies. Since we downsample every four pixels into one pixel as we move up a zoom level, the max level can be calculated by `log2(max(width, height))`. - -```c -m_max_level = static_cast(ceil(log2(w > h ? w : h))); -``` - -Then we calculate the average values by repeatedly downsampling the original raster points. At zoom level `m_max_level - 1`, we average over the values from the original raster, which are stored in `m_raster`. As we go up one more level, we average over the values from the previous level `m_max_level - 1`, which are stored in `m_sample`. We continue this downsampling process until we reach level 1. - -Note that we have to take special caution when dealing with missing values. We devised a special averaging function which essentially ignores missing values from input points, and returns the average value of only non-missing input points. If all input points to the averaging function are missing, the averaging function returns `NAN`. - -```c -// Downsampling -for(int level = m_max_level - 1; level >= 1; level--) -{ - int step = m_max_level - level; - for(int y = 0; y < h; y += pow(2, step)) - { - for(int x = 0; x < w; x += pow(2, step)) - { - if(step == 1) - { - double v1 = y < h && x < w ? m_raster->value(y, x) : NAN; - double v2 = y < h && x + 1 < w ? m_raster->value(y, x + 1) : NAN; - double v3 = y + 1 < h && x < w ? m_raster->value(y + 1, x) : NAN; - double v4 = y + 1 < h && x + 1 < w ? m_raster->value(y + 1, x + 1) : NAN; - - if(y + 1 < h && x + 1 < w) - { - m_sample.value(y + 1, x + 1) = average_of(v1, v2, v3, v4, no_data_value); - } - } - else - { - int co = pow(2, step - 1); // offset - int d = pow(2, step - 2); // delta - - double v1 = y + co - d < h && x + co - d < w - ? m_sample.value(y + co - d, x + co - d) - : NAN; - double v2 = y + co - d < h && x + co + d < w - ? m_sample.value(y + co - d, x + co + d) - : NAN; - double v3 = y + co + d < h && x + co - d < w - ? m_sample.value(y + co + d, x + co - d) - : NAN; - double v4 = y + co + d < h && x + co + d < w - ? m_sample.value(y + co + d, x + co + d) - : NAN; - - if(y + co < h && x + co < w) - { - m_sample.value(y + co, x + co) = - average_of(v1, v2, v3, v4, no_data_value); - } - } - } - } -} -``` - -We also need to take care of points lying outside of the original raster's bounds. Those out-of-bounds values are simply treated as `NAN` in the averaging process. - -Then we start with zoom level 1, and use an initial configuration of two triangles formed by the four corner points of the original raster. This is the same as in Terra. - -```c -// Ensure the four corners are not NAN, otherwise the algorithm can't proceed. -this->repair_point(0, 0); -this->repair_point(0, h - 1); -this->repair_point(w - 1, h - 1); -this->repair_point(w - 1, 0); - -// Initialize the mesh to two triangles with the height field grid corners as vertices -this->init_mesh(glm::dvec2(0, 0), glm::dvec2(0, h - 1), glm::dvec2(w - 1, h - 1), glm::dvec2(w - 1, 0)); -``` - -We also create three more temporary rasters: `m_result` is used to store vertices in the final mesh, `m_insert` is used to store points to insert at each zoom level, and `m_used` is used to mark which point is already inserted so it won't be inserted again at this zoom level. - -Then we iterate over the zoom levels. - -```c -for(int level = 1; level <= m_max_level; level++) -{ - // 1. figure out which points may be inserted at this zoom level - // 2. insert the points using greedy insertion -} -``` - -There are two crucial steps we perform at each zoom level: -1. Figure out which points we may insert at this zoom level -2. Insert the points using the greedy insertion algorithm (same as in Terra) - -Which points should we insert at a particular zoom level? We need to insert average points in `m_sample` for this zoom level, but we also need to update points from previous levels by shrinking their commanding areas. This is crucial because average values from lower zoom levels represent values from bigger areas, but all points we insert at a zoom level must have the same size of commanding areas, or put another way, every downsampled pixel should have the same resolution at a particular zoom level. These updated points from previous levels are also added to `m_insert` so they also participate in the greedy insertion process. Note that unlike Terra, Zemlya *does* update points that are already inserted in previous zoom levels, and updating inserted points triggers retriangulation of edges around that point. - -This is how we update the points from previous levels: - -```c -double d = pow(2, step - 3); // delta - -for(int y = 0; y < h; y++) -{ - for(int x = 0; x < w; x++) - { - double& z = m_insert.value(y, x); - if(terra::is_no_data(z, no_data_value)) - { - continue; - } - - const double v1 = - y - d < h && x - d < w ? m_sample.value(y - d, x - d) : NAN; - const double v2 = - y - d < h && x + d < w ? m_sample.value(y - d, x + d) : NAN; - const double v3 = - y + d < h && x - d < w ? m_sample.value(y + d, x - d) : NAN; - const double v4 = - y + d < h && x + d < w ? m_sample.value(y + d, x + d) : NAN; - const double avg = average_of(v1, v2, v3, v4, no_data_value); - if(terra::is_no_data(avg, no_data_value)) - { - continue; - } - z = avg; - } -} -``` - -After we figure out which points to insert at a zoom level, we insert them one by one using the same greedy insertion algorithm as used in Terra. - -```c -// Iterate until the error threshold is met -while(!m_candidates.empty()) -{ - terra::Candidate candidate = m_candidates.grab_greatest(); - - if(candidate.importance < m_max_error) continue; - - // Skip if the candidate is not the latest - if(m_token.value(candidate.y, candidate.x) != candidate.token) continue; - - m_result.value(candidate.y, candidate.x) = candidate.z; - m_used.value(candidate.y, candidate.x) = 1; - - this->insert(glm::dvec2(candidate.x, candidate.y), candidate.triangle); -} -``` - -Finally, after the iteration process is over, we can export the mesh to an OBJ file using the `ZemlyaMesh::convert_to_mesh()` method. - -## Related Research - -After we implemented the Zemlya meshing algorithm, we found out that this idea was already discovered and explored in at least one paper: - -[Zheng, Xianwei, et al. "A VIRTUAL GLOBE-BASED MULTI-RESOLUTION TIN SURFACE MODELING AND VISUALIZETION METHOD." International Archives of the Photogrammetry, Remote Sensing & Spatial Information Sciences 41 (2016).](https://www.int-arch-photogramm-remote-sens-spatial-inf-sci.net/XLI-B2/459/2016/isprs-archives-XLI-B2-459-2016.pdf) - -This paper describes a very similar hierarchical enhancement to the Terra meshing algorithm, although they opted to adjust the "max error" input parameter to achieve different meshing resolutions instead of precomputing a pyramid of average values from the original raster. These two approaches are equivalent in principle. diff --git a/docs/tntn/resources/4D859D9DDCB9690EFB04E6CCC75FABDC.jpg b/docs/tntn/resources/4D859D9DDCB9690EFB04E6CCC75FABDC.jpg deleted file mode 100644 index 9abf4c344f85895870f32920c17e6ddd4a181261..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75136 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

%LiDXf9?Bkg)}N`hv&!AmC@+Z7O#asz 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%0Aprug;z-Fky>l035h1i&Y*7Ga$scysHQXco8 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

jG(;FF-1$AfQDN?C4kNL&MAZtq9LerJfB5uz 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 XQ96dm}Zw?i;)-03(u1-!6v&c=>kI z?03%Tk5XESw;5Xe13Avlna-paGB>y%)}h;2M2p9*pb@4vHn8(&g>rY~>&0(Vfk_lW z$Tq9oRSW7NP-7_j_35L;GLus#-;^RI z&0D=Iy^RYJu*E;KQ} z_dVGI9n^TJ%Ka!&ewIA&>UHC*`#bSzz#(tTX%=E=jVZ|Ge6!p+(OA*+VJJnN*Jd?) zd{^VZ)2Romh$k_9XZ=78(N4w&Epetl3hdSu2!8J^3w=*c=Y@opH%L4EDVcw8$WA@x zzRL~wYr9Ve*IhgrDL~JjB?Iq|4f83GLR(_K$^_4w>eH8}WnB-iIBa|B<*Lcmuo({M z*`NA6AnW+?(lwnEYSRYQELV02X4I6AWytV2Z7Rm-j@OF>-`i(3ap04EXd~xLcDw*t zQ}S5rRP0gAy!ku{^4AA6vettliGT=x%Cvz`F^~e9J90-Hz$S3pXn*;w#gdG!mK>SpDWB?!%m8D6jjfgR4hq zYL_DmQPG#qthDs+nR&BXW<PN3t@&KzrZRNa zil7(1FYV`E9#89m=$A&>bsTOZjQnA&1qDURvFcZcCsen0nCP-EVfrw;SoSjrQatl2BeOERjNI;YO_rIERZ9e1Pos2s zao3lupVGfUB{%h*oJ0E1r>#78(jDM|1chD_tCZ{*PT;g4EBkeLv18L9!8Vop-AQkV zA8Gs}OxubQ z37_6M91--jHZD_CSZVxWpTYY?+*w%9iYUd9pyixUr?g5~Vs+@SUWv|lqj^CIJKbns z+M>QjPxim<*bwvvJ&Z~Ex6B-Y!^)uL*q0HYygso+@3cysP`imt=;ghxmKQS>kE?po z8OA$L%*0%*=MurWO0M2$BY^9!Iy>PaiFo%@aq-vI6_hoeUVRnbr8voc6u6GnQMo9eu&# zlZT1;RtYzdZLyGSBxabr3+tnU!yJGMv#4ik8OHwgXhlo4rjF1cxd1r)Da1{JioPOR ze>?T-ZNA?`8k`*f$jV%f;7$5LRy|yjbEIi(y{;(Y z$qTBoy_IlxiycFvK%|%_y)d;|k@uxp>E!AIv~z*~c2|0dbXYMHnVcJjplKVTcPD3< zKI@& ztm@=P=yVxJ;Kwy*5y`y$oHMnu-EGsEU1S3V$w9u!#_zMe@ZB{?99*pj5K{`Lk`gv~QfztEa zrLAhVLHJ4-NTZYE4PtjUdNH=?$iQbr6E;yDA`x~2D>64oL+it`Gi5JcJ~dbQu;cCQYvk8~p_d3^1- zXF*fwIlvhh1yE_4AjbzlzW}vVa>8VH{ojm%2i%yBlkUCyr7O1`eXQ93_{eq@bZHkT zjt4hFEtA5{!1`lJ9u$psGKsXJE#sshJ5;LXP`ZkV$aQ>L@T#D`_1Ejii7K}=m1c(Y z$&*X7!T|EMA)>J0Df0^41aJCE&-zg!lI32ZiXB}Y-(H@aI!EVcyHh20+Sx--v=Ux% zbY{o^%NEk^fW9D@NG%K2H7!kN<}mM=2+9A#y*Jm?8m$d_v?JZXz$#u-`F7!}d{)D~ z85D^O>Nc%GYVct5zIZc6&Ew$GRHx57evh8kqOwg33ok;{)r0Hy$qx`ee+P%14YP$? zjuGYc5qE~5qInVwlj*}O`%969bFVzndCY^$sg^`#+YGtcNx9bVlkk z#+bF-JebdA3M>^`0iqmgIL9c-&T$OrL)!A{bvJ8@7jJMV%=w{p+#S7pf`>WZ4b{78 z`IM%sv+>IlWxO6lb-;_7d;?Hp2touqaND$Ge-<)RE2^tM2|aAK`n0D}(8BRv58-uV z#9LcH9Bk4@>tJszb0*1xHrBFJEtlg$#SQ>C*+eI5cfit0luuvR(p+M^^_r*L0k~| z3gVvt^g~~#h)RA3296jXYLg9!(K7vXmz0GIK4|+Iepp&WIM>Q|GEp)^00mMbzzO+~ zvPrM{cU*|Al;qBQujow5)lCW);KRy+U!an5fXEEq_CYJls zuXk7XexGpNwOZm;>zg&WX&5CL8uL@_TB7~0nIHB81`4t)I2+3&Ib{{j zvb^X%X(mcD5k3h|vy8a{4!A2ppR~d|(m&2df41GSc_-JS)G>HgwyMZKmry)CM zP1J7IYb#0bLeWWD_c+SRMQu^t0xo&5=Wm7Pf-`Q9HMr0=sxvfm`HDFbBh-L0cS)CU zH;UK%#Vz0$`DF*l8hR-(R|^`K&tZCV$ji^@OH^VDR^AL?fh1Ffp`%Nrb}5;ri|uHK ze?2qx`t~(+<-u;3s~A4cVLExMSt1EmJ-7Tg%nwPS!8#r;{I->zbhY@_R(d42=#0fR z=^finhrj(1_EHqzxSt&YZhr;rEdZ2bp*4{s?|Vg~CG5 z9>fedt;8~lJIF#44^6UY5{39ghk#KqpxJQ6!66B|V z#9=Zh?X09DyA%XjrzqAY=Jevu%N}e!C%42#!`o{rRgbDZ95mQtrme8tfmyjmX-*u0 zAz>5UGwFk1zXX;zoyQh6E|piI_J%tN8PB3hEXofW+7&LdRhm=o-u(TUe{|VmjAmcD zgslL>%>rc=$ROil_3@(qqi4q2Of|ElJWi~6OcpF^$q3y}?zsJ2@X4LEkPWB+>mq`s zF`D_7mDX-6+ueG~eR|q?GFU8!+HNSRoRz2apue!;Kz+!=7wtcLAkaK$1%W2YJ{(SE zn$iWj5DyiMacy`hj;=gC&QXgX?`_$bV?X%EJWj?wH3niq88AE?{*JeuH-;~-r3F*^ zQ*Lv7MhfXV$=K@k;z@oRWMz?G*ytz*K`Ql3+cs_g)bvV=pxA7@(}vD??#x#pU12)X zaUj)9dx4HjEVc{-4b6KLE#jT3W&VYkV%hJY2Q4KCpQlotK{IOa7Tp23++;lPLRUth z^27Vj4X^hvHzd9i+WU?v<}>(5^EThEueka>Af8XAsCpy^;@KFQ%#sZn2cndTo zEG=Win+H9IF`c1We|n~a7~dx?ZmvnVems5q6}01)93Gnw zjdkS7Ck?JUA-|aiCiTl{6SJ}hqR@4gqN%0nJ?l7<<<${D5fZ`funT+?-Mhx@=@(1i zOihNvJ9RrsRfRo__4=$C?a>{QwR`wSjq6TrwCikh;kEF#(Z@RAyB1)R2!W6n$GfPG zLlWZp-SKldyS`+PCO_!&{t{-pi~YQUk$xH~!0QDN7`2RJAekNm7;Ur>;~PD!6SimZ z{@YQR0FUsMynx=G&Cs{$0AwE7Ga;67iPQVw5Jq52Hd#IgOb8y-%y^niq|O75^{MW- zUsd9*p(riFEj_9r@k7Rm3lDS*|HXfq(Z8BjnWil5_u&yUz@wAR)^H*%Zq$x~MEG6eV&bGfa!` zg5;4b%t-#C!H+v~CnmH!z2IL80pw{3fT2*)z?(z>;mc>4ts?;;&XKxjN7si+^;5?y z#sbPz%=RWrnl&8>I(B$x%gwrrn%hAZUTw1kM<52ccpxGDGS(D)+?&pN+v!w-%cR>q z(lxOjc8NZJj?|hM|29Dj2V8pmenOE6N}yeI@(r_$g#{5B zRqx6&sBNxz%J=IWynkHdGsSdeK^wtKcLUTO(6HeXx3~ev;a37vmbqS1nVPmA1)3uU-J@+&EK)yra!M+ z7r42S&c9|~TvNOz*6=~M{o_IQQW~;|-VbybV4X8-9}V*toq%`Q^-+4UB7T>Uq{B|r z+~f{vx>FZH?zr<4=Z`(g`@4gy69sTV0P}@JvO(D=W22Rv99&jR@4rr;E)ST+OTc9t zNiO|fN0V)bJ-b4Egit||>0g5`X1Ai^#{PkPAh)jWY z2i3C%Rn+rud{pg#_XR^XLgw`N7?#WZ?DLpzvV8N7X|yf9I~CDFmb{CQLK<#fr#eiZ z>dS>6z2k#UKhtKV#;!QmUHIi_kRKRWNze)?&4)U%l;+s5@4D$p|21D8SDE~kJ9t0@GgZ*N-V&)<3obhCntvcgkJX-_Q+Bly zikc5v(DJ=W~(Gd)8J|r+@WU;@` zklDa+1u}_dF-w53#!hvn+q%H9GSia8exH zJDd8KMd=NlM3KhGKz-~(r)FHyT*kkJTw>}CT4YGJZEo(PT zg_}%SLZgmK~s ztn>*Y;jc-dAg6T;WU6kh7xN2NqLeS_KJ(~twEs0*|F;kny(5^nam-u5DR~z2#m%H* z5cF5(oOJfL8(i4Pa9Rqz++cN=U1Jj}c<_-%_Q?#!?>f>KO&VE#L1K%eM;n*2>^tl{ z>{*({Bv5Qr}-o_`RD^{p82-N4peb5CwPtRc+Y+z_#H2Ua;@Rv-g_l`~!K}g!%aY z{tSXiLWi=tw=ybshv1T$HPuSjKZaRu!o&(PJ!8{FC_Y6TU+-D}1lj9S`QSv*%Fig_^I&|;$ z8-G7p&zR!gLk@EN5lbSeCH-NA#V|x ztntjFrgG>>xEY5#s`89ZFwrZG z9A*vAf=^){M8OPA0MW1$6VJR)&je@q^k(b^j&n2IeTXATm{`arF#mk?kj))FT5zOP zMr#ILF{5xCxeSD0U+0(w^s%-EXgsvCuswv%+2iz!4Z_HBz50GG&!IQqg-*KXe_5!$ zLqCZze z5nV4}%qZ5e*PM%0@XGH~9q!FFCi>OO0=;#y@t3Zcs|eJH-iQ3{=IyKOhV6w70=6wN zhnz&gAS?&ReK$edJ4w!!a1uM_?Xl`+%}AatY;Q8|kVPyXVjuPmb(3oxn_=50{*gD8 za=bewWbAp>Kqzt5DCwxPv5mp87(^&<0CAv7bYf{1JPSK)-3=N(Ua294q@a5vBaJ3d z0b+|zmWl`Ny5x<_Au3=kQ`lM5Ljos+amKs}9D1ofykW-9Z$GrkU}1jZG?5B-z02J@ zfMBT?io;iOS3&Dy_&iw#>m6xy>yK5VoFr-Cn@I8dN#D|+t_xoTrcveTs+Jk5P?{tH zz+piU#%f80x4+P!V50+fc0DU`E@40^XTp8IV};&$IfN>X^^j{70m}q+2K5|g%zuO3 ze}Rzm#K~Jj)gcD8s`!n@SFAA|pMN0xuClGbX>Pb;D#N+ftS#VMg%j)T)p%_dnUdCa z$rAESU_l=viEZ^&#U`KRPo?i3&aU|8k=#|^mKJ?$_2z?C=ZQI=9@7WJP$Xz7!E;<; zQLrjF%{-Xhqu+OC=*$4Vi1%e+Rq>&T54*CjuK(jp(IH|2zGAKwf#XRIdaTQR@b9Ur)t#mEX3V{J6v6ht;%r%#c$kVWle;|`W%;iz6 zH#XG?+Y0gk8bMRVO;+x!zL`jwtJiZzfBUMwP?#QMO{tm{CMsCPwrCtn|LA##YXIsn zE4&GGu9oQ$PDpsQsGK@}58fjH+UN7ikMZ(aMTJ1hjOa;JlZt2FF$DNntKyff3s`Fo zEN6xdv%b7?w9yqLA}jcX9-lbVaBDr%)T+$EVS>8j_;bC-k#oV%>6)uLaYTtm6kC}^ zh6BdeH}Z@tyv^zP>&Z4Z?K&eP6U%}{_<+yl4&4KSmIA*P`8Ht)z>~G={sZ~Zzm*}2 zxS!3-wnaqPx5DTb{(<}jzYzTgGB%z645U>-zy7Q*GVE)BNEZJR82w@xkCG)=|Kis;PY^`we?BU_&g!k^TZ_|c{`GB z0}NfXG>zuxK5o>c=P=j0oAsKqyG)Ho9|sl^7EhZD9$FF>+z6nJz3$w%UH&$b#FOHv zg7{T{$+ov&yRGSBA&m zUmh6ORJi!K=+{aQd)6_!dwV`6%6^XADaxwE)*_;L8igxW!~_z0T58z&b@Gx2GgrWr zpa_yMlan@!sf5m{?K75bwqca+L{ns>!bHAR{B)kj@AlpIt16_-R(!YrKqX@tkD=8y zF?4D2#I@GJ^&}U`aWj<>T3VO#I4gFZ8{$srjz+F5$D~hVS;3O*%ORRz+wb zMrF-|cY(I?%m02scV`w=f0_463(*;tNc!_cB1Bb{3@&?HwkkLE}_PHx{BpOxP(UmbfDeu$q| zkON9*arQM%@IMesZY~A{Ewvfv+qALbyJG(rX>T45b^ONtk|K$bvdfeul~CCVnN~}Z zq^vR7X)u*-%9xQXStleSrp;28$zEb6dr`z#$1=vW$qX}OOlJ9=kKcKo^E~JLb*^*% zaP^OCuFQPq^S$5q{k~uCs^QndV@Bhu0}prfKGDKWn_n%2jbEIclb-^b5kZ%Bn)B>^ z`!JYH8n1WFzikrCnbZs|dujW=X1IVSOcnXb*9D|_uBr|0BrBjWw8XVt#70lU^`!{5 zHg4Pe{ugoE{=feG+sWZH@B$fk*qdOB^P#|78Ud`O#1Di5SjZ&2LHHRf=ey9XEu!-WXXbiOs8a% z(;@57;qy1yNBTtH?-%P9Zo#%$0BbBMex1|_r$}_bWJ1tz*5YK3*=W%l?rr%js(o!^ z*5>Hu%bIalcjXvq3a5@d^2eu88%E!=lR2iW(!_H2`C=7vB&z-o!d**;mW8wtn04R6o630}keV5!mI;iJ<=pcDdLZrf{aT34}-y(7Ij zvOe>~=~2pv){(Hx!!M#PJ9?cw|4{w|85T;I82ZJj5M)$aoK<6&2L<4G|Ccab$Ihw(h{L7ylEP5LFKCyQ#;N_m=bsYK#AyUe$7jb4dU;68u5Yn?^Ie&%erE_!wompX*JRLVdRn zo4v564*l??_d!@H>8sB#QLUauob>Wo>kX`^aF1{Vx)mMFGZzj6514fsYN^8=z2-tW z`*uR9WZ5?$*^%sjL>%QBcjmyfa&OZKbRI{Z8_w>f(j*c{0RU4nxAeeBVA|OX&!ZJm z_w{?ioa;l|Dt{WDokYq8-agWK|IvJ^2u&ylmJ>-Jtxw$oq=ubBn{p$)!821Vm}oT2 zh;)!Tt>rC_SA6{W&Z~r*rrk>QSu)yQ)?de5fH&_VenOKDXFedwgB0uSze65l#2d%< zlCh{}O#J|wZHK%ow&WJ2-+4RwEWOPACwLnO_etOe^M$MMPqK1~tK~a6L7eKterh-O5v%i$B)$Y0W$#Q<+k~9p5uTf+`c&?uOgJhyCSAUYWmhRE1 zXcktX^0NA6$;=t#&)8y`@@JG?`Yby8`6mn362+I}AV@_!@U*$S*`{t-qB{WK9^&4R z+NT%#^Ud_>wQr}5?GHMKFW1)eQ;QXjod9IhdO?;@gF89r(uSvW05lBw%>vP2%vjR5 z{=*YJpVa03*A2d3^vSS!i2fuM@AytrOdiSU6X5m1cxXHa&LxDik)3^X2hk~a&0tDV z>(l50t5W2ijOXumbXWUm-`~DFyL|H{fM8YRs0wfxaVoaM5HkvwiHLQdbZN}8Fqr%B zD5rNsu}{kl9$=qx_x^L(p^tv(3HcQrMl??r^A%bL1Fi*0^d)ZBtgeAPU!U#sX-#pt zav+>m@%a5?W0@Vo(Bp5#PkxaQ6yu#yzOxRUR0{kfXu~n8cz`0nRw$x-9{e<5S@3N_ z74cj1T1WYOcD=_FQIV&+*)WMwVmQ#5Xb@r91OnPnhMc>C=R|$Px=T`vL$EO^F>+VZ zkcZSbdfu^8pAt0bPu)z*oH+IGChFOCswk-Cj$;Ft#QFZ*GN68D%R0Uqb`fO<(WgUK zA(E$By7Zq89wH&g+m3DeanvKs<_T&c^*x=$)k$XD0u7k40-a96cwYy_xT0frZ`GNA zvlaetE*9jR(Jn1hXVKarhZO!j_kL(LX2`QdO93RL93K?EFI~ac(3sHn34J-Fn!wa( z%#Kx|(JyBYs9JR}?2AesLiR7;ZZ!j!LahM^hNW}3d2<7dCN}iinBFRW3m_663&|!k zO&deYk6JX}t;E^*QU8=Z{GLEmi&TgE}f@?={AMcIpBnw01NNxiy+vpmJ_9woH5zT3h~#Q zzN+Y#l-AkY9EY`}qgge7+bSIHjvy}*bD)k*ij#N$b)FRe*`Pk- ztWB!b_Xmcj|Mi*`WtT#}iH(4`pbmH~$8ILMc+V?(r|^Gx!JIoRWX_*rD-H zP=667AcJ$wWXLg}nWuFVwPzQ80W|MTD3~-ezRH1d*XF3P@8jYis8Y9&qFB-EKY#+y5 zVoxch`(xUlF>l5x3D~U0 z(jt0GfuvM6hrG+#P4P#TrPGv4Fx#4A4KnIUad26{-vs+G0f}X3tHB7>iYmiPuHO|3 zrew=L#|9ElSD4-O-v~ZVe=YtVJ_!XacLOk}l|e%Vm7pTZP$5>)gIj`2=I?sWyxdan zb+*50OVyI^#sR!gVq%Ne%YS-z6<=@75L98tu{ESjrcj6P#&#~G<3-%;jfEM}^4VU& zd4tb8AAYJ4589`^{Nqf+x7n4GyCIB!JQ>VqXkAnm%^?xi;1CxvAj`GxdTfFpSJ!Wq zt8uILb~Xzup9%Q(y+-!S&1y^MU-Gl?+8zcJ1V9bIWUw?eDv!o2OSe?~Q&7b>Yc2ik z_a4+hxwqLRBQIXYbG%Qk_=p`?%S#_4L+kR|2GXcXLiKSBFm3@BPDYHwn1PXb@F6BY z&6M0wW&Zhej+;e|!itZQT(`&F!&8z<#w$$>DHf03^ARr^Oxh~c19iT79&5pK!~nQ{ zWe|=%2h8~a=*eQj~mHWzz%WfJA$NkBDko)$bcz#`yjq}^D5!sg$?z2EA$ zu)Z^CK}Fs83O9H#DX16`;3A5&Lx0}O`;W-2ck_rjDnpV7!HmGvF^b$m&IQ)bC$uW( zSY4Oq$e>r3ks+I~ousP?M8UljTTQJUYsoi$wMg=g@o#R_A_#|c606Em6P1FIpYRGg zib}P&RJ~)s@M|UWM_O!JYLkX!qgrm2?6=e_$B&b+Oe@KbtyZ)#DuH)7)A^}-0@WQR{ipA5uFX+pdV!1oW9hSp-N*eb(k9@ zlXlh<6obvYY7k*VdaL)|1v-WM>mD}wx6G|3t826Bu`RYFz8trcT&I8RrGp z^H~=?!?c~!I+Iwb^h)6_-=y(&OSEkA?X>6}SA)I(D1}{1T^X2!alA*dLDU2|Q2#d| z@g$Yi1(J#z_vJ-$h|aJc)4QPm$8_i8yw7TgJx7|Ee#j5QE+zcyTnT~@a8==*SaATo zF9Aq5HI&4;VFTk6oBo&^7mWU#8FH~pb9=mp8EU!J_R{jJitsKGKk!6-`wPHRj-V7j z5_bv8EF{agg&&KL3`NWv;pM4!2J~`Art3pOjICFW)J!~x55LEUjF07D`l)Xf8LKSK z^K2cah~;iKZU^lZQD-EiAw$I|_t)U{CVWVA^Igr1ZwFT__5?!BR=jw;gJ21Lgbk%( z0SbUbS(+mPa-j+}`OvGO%jPjALk(5NOy7fz-L5Haw95)MPtrgJb1Dlqj-=rLs~TrZ z;`*``L3JAe%r}(0RAYNX>oMQV(W?zDI~gXFtZb95IXCw{@`l}ed(%ezFDU3B6M5jG zZfL?;g60nqGH6_7YE3q>KZUl)q}z`&!YWuKxGcw`XlLcyD(^XLo>x|MS@FQu&8klgx-= zO@3525afX~MM%1iHEv(XSl|{UNn6XrhO<4Ux&%3MHz5g^b{I=DKwo0~%>5dsQKscim z9YP^|ZID<$ z3CN1^`+(Y)Csajg2?xDE^emv;D!aOU_MfvOnc4o0>B}Dz?7S4ppEOrHbA*SF&c7s4+YZ8-+Z< zgb`bLs%S$lm4Mb|^)Si+65V60QsP1Vek=`|e=1--prNcq(`2@9$7HnJQ;Q3?JAR%A zf6w?D&85d+!r%%ZNC3JN+HK=zyvL8O{LL{NX^9$YNL)Uj*5tIJ8FJ?M9_#(>&qX~( z<4jjUi3bco>@%F^QQ~1?_l*2E0yBcTeV)?de)y=gsb^}mw~>=9FPk0&_H7)ym3)oR zw*^VC>mHCWwJ#xviy}aq|!b#v0003MVXD^u5 zYJ;hmX(vAMu1ma74;2=A)I6X0<$13IcC(n%P)W2_=bz3BgRiQ)tKxO1Lr6Xj<7=}& zlInN{m=UVk;#g12X<$Fb}ZgK^O)OXsr1h^2K0|pWhuAb16Qk@paB~Q#(Fof z}Clh4aNmZ>!G8zk~fVCk{eTBGf}r zymIF<4)@T~8shuy&97|8+tU9fZ+~7y5snG+EoISRAczM+U)nm2zQR_2!U`}@yXhU+=$GVUG56Sr|r+0Yx zxwn7p6BF$}G70=T(X16emj{?}Qk|fO>CM{({GRfQ;CSbw$RAx4Qr81sBLjEOWW84X zq!|I?@;jZCa4>oZ64BX=Kl zPP=vTq>cpIzHRjxB!}cn02g1dpa3JzwVT6tLq*+Cb+qWT&4lpSgJ0GxRo)|>_jw#0hF+#Tf2%c|9U~~gFtcv9UK8CB!TDibRCK!2Q8SBXj&t`lIFQS~`4fBaw zBG*doLi_i5nawp|XYn%<+<6)x1LXdXG0`B3vsC zPyHq!!2FR){LAmbsdLBlQB{mR!@KX6rRar3O!kdeJ-5<0?%EbrV^yh@o^(=6Ib}do z?UFbFNQ4P<&e1~7hNI)71CF|_-d+M2&HoObsQRLNaPrUFL*;3&gDV$r&O&FbEK&LE z*T>$VWd%tjKj?(;*J-WhvTm0Lcap|(X&y4(dMJCvcG&ssWhpIiclBQ#X5=2>#wfO7 zG5xUj{G=CF)$e-G%sua%J=vZ+2T z01|;gW9f9@RWX`eadJ0Qs>NE5%E_^*vyG&^cjg3TyXLBekvZiuaRKTtfApJSWw33> zuz?xooNR6l=wwB(WOC-P(m|%pffTfkD6;mCf})Af9sLluYg<}2FFI?bNc6^BfwLSO zwxFZANRZPFhU`RBJ~(*}VyH)+6DX%E@v3fz@S($lMP~f3sv++}UqW6jrZ1nMZ+ z5l*`6fP_l(xq!MkRe~%xAlBE-&cDvhSk*XRx3%~aKj)^?&&yU?-4HF68W2U(N7Uj@ z)9?wf1{{OQe(5sO5^9kCx7EPz!*CVz#qz$$cY4SeHOGn+4gUj;4yz%yZHuC#Xa_+S z$v0GI7TO7!m;~>?+w)-Rj(Sh=#Ra=zh2vXFn>KHag1ap}eAE9_*_$`mq^Wz~1Kbu= z#&Mn&<|_qs|Ku?vmZD^fGc>5eI0bth)%^E-SK#|Z*ZJm`cM8vBcb+-Y{_da0(?BTw z*GEr}4aOfo9NGm>B_60{_jD{A_%&=~K3os@x1Mq#s}mC zd3IwyoKAu;uzn7dwK?L4GDI{*yS~x6Z%bitbAN&N>Ff!kEFd>8Z_ZNCPdDA386@@- zIf3BF2!MDDBqfKke{}*s#rQ)+ZX zt3ZzsoojP_;T)pS%6{m0dFYDYwt3#RE5$_tF_{fab z%_ihR4xVqaxJsIEq9MBp52)KMPVn|&#^Ca+ttS5wxyJhOsNl3UGGHSCr?t{g`~71L z=eaF={Sx!vcK-kyL}DAq@Vddo!tBMuIV5EZMr{HGlx^|;|A(@@4V3Mh6${O$=!F4! zk|}>@GRL2d1A|FI2DVn`{$Kk*`@z4hikILJ&3EL;4~P%9SD60TYzF;E@5N|zRnG;& zco}W1$6=zj;}RDXb7>gOA&mSV_5H(tt5iLb%!4lvvG*;1C6@YUG*DyWgiWG>)x zMMk)jJaJ4r9PA=MF@DKOH5;~hkzPT?*5~!J5I|@ z8YO}f@WoG~z?g2JS(q;XRPP&@eQeXT5aY=wIvRsJ9cvrv62H4%xb>iGIIAd4D~=xI z%*o+=6+A`4g7Fh&)`C}-P_!RgdLX?8R^>WAxvwk~A>ChicWrC7J6!8lW#Q!uVW)4N zoFdkX{!uAoc=OcxMl5I=$$yDLpcSVWJRqMM2DQV3;tf^1U17*fPQ^Y2t00=Kx%ObD zIJXT0jyM>k)bI@WCaf#?dY5~LEF4(WZfBEhH*WS)|DC^xzDHnIdg}hl4aTkQJ&QXV zxNQVmHrQQK6pmu+ns7u2W(dEl#m<+G7oT^DE_j@HOFpmfkgUz1*Z2hu8O~7dKfg0s z*%|k*{bEG3=ydD@j1md~bnP4Bp@rrfsGKtiT+G#`x>y7Ew+0{^D8kRmLz{!f#$6f58{X{p80)b3ib5>9|>$Nr}v;f1ueql%=+5hwGE) z&;>vMF!dCGF7Nis@9&C|7Ab2(o#z*h5W zA3+z)uOOM&w}eJ9@2dhSi4DPV=uFzY3NJMS*eRx>NCxG2*j0#UCqbZQzmTBMQ?sB>Ka)N zF#O1gpI8c>W7xu7dBOK$YY~sKLIoMkZhszgvOI&`)2JTZoTjv0h`s5@x4W48i5x8u z;Rs+HEdkC_dIABhUHk6@mDtiuCctQl?6dPaSyk3*7y7pJ`;F(Z<4h0CT?=!3n#uy` zX3il&4#^*gDhM0Sl%6ew$)Szd^;<(DQ(hDY|J6I~g8UoPZF{&m=0#1W4=m#2UfMnA zX-~c+_a5&uNF>5B7Jy~qDtmWwCfd~3c!YyHO*Tq1O zS16gtBGaPVArO$(gk|~K)eW{7f{h{%hRI_QsfY}IlemT4){tMve;p@~*ZEJubND=Z z=UYJ$28zDOH7>c4cekrLna=du8iqXoY^P0(1Am`a!}E>p6HrB*2s(!*@~A zP!&$B1hZfFBTlIIU43f(GBhNG33T0Lheu#7#iyYu)tcm`-(N?)2R5%S%0~gobjYcLUGJ z%s5RFI!A<49#grckHs77vwpVop-vIWb=dQMI7NQ;9DD9@UMvFDw_eY*Q z5Q()%-419WaJq~M!-KLSp`6PIz%1Id+CUq=r z8ZgEsT))Npz*{xfZ@3KE{^nHb)cU559QdnTZVzuaxUB1248hv9i!*EV-ZQin>qkbx zcweB;#gvK(`(WM^TJ}CU4?7LBrw3o1d#AMm_e2E>w@I=TV(l#q*+Dnp(#F}R3mxPs z4e590muEI{{C1MpKH|@dtimZvv<|+T;7JQ&)&s?#EG*Iw4s{v*GamZ_c#<@_bGy0b zcC2V7o~IJjh%tfJPjD;F-e<}k_&4|A?6#q9YKNB7bARto8bkuw*k0F@{9?oikx$Um z-(?hjdO<6!?78#htM^vLiQ~x*Fn2UX4nvW)h<|56Vsb@2IR)t zz2+;z12 zQl!HltY&DQwb5iJHQbUfuWxjDpMvQKVOy2jwYwV1oBN3U{CrFVN>DcfAaW|j)Wrd8 zv-%Pds&-0yle>s|$&bhnpH2JwQ6ra%Pyx!a_j6XRL*5a0fO}W*NnozwZLA## z%M>&GqabHRHV=QYFC{-`$V{*uMD7tf;i`NSq8`_gXU9#xR-=PxsC89L;k_EnKhsHX zwt3U>?wO2fJG|aHffNX=RcZ~PUI!xW1Fx_>8%i@?x}(PmGU)F5pS&-2e0cxQ@wV;i zI^zF5Lzd8soA3qI#$2m4=M#5=ow-IgNZrTQ%dC@5P^|3=VD2&qt8OE2~DR5T^4fb@enJg5l@GM9S`rw^IJf- ztQwGk@g%VC05>D9p&QLqC81Ja@wMGA7L|b8r6a`C~9s_+CK{HW-(Tt^37r zqg`Q(7G4=^KzzNZr*oP-)<0}4iJ3N0P`XDu#alMnA)z&v48q66h&l*MW#okKDei|k zxC(cm`>m04v&Gx-{7~=Tky1Ub;hPUbpSXHYe3Tr}Tu$SN0>h4_u)Vn_&4X^xiIb%U z74IG`V@>y@Mts`a{9(wqiQ;Q|xIg<-qZ3lU_RJbK!@*rdn91MEGvV6`o}=vo0n>UY zs6f?rOE+$|!o{F;o^jk3se12Dgn1oA4>IL0kV;jmnseQA=|SAVH|Zi0Cq;hit_*bG z>m0h^ioczSIxMh+4bqD)5;Fpt-Z$A>+LUA@ozbj3D;ryZ5GpIu%LIx91uV4?Dl|L^ zjd9#CJ$GpE!5Htw>f8Wt#TTsW27&(hIqv*_M9wXA;n#kGVKrcq`}3mtun~)Jo(aM% zFG*B5&8p~_JE1r1Kl4cpiHxSN=!g=4ib9=jjMc4Ka#=FDI zHcDdejsJoBe>3>aIqLW(;Svb1s(iM?12y^`Rd<^0`(5(-=&N8oCUTrr>~+@hUAyk? ze6>pwt0&-_`M}|j!{dUM`*ngG_V)wC(p7)|?PYtGw-WkblgJ)8s}dUw*@QmhOj$Qb z;QQWzwq&`!w37I6OeCg2WYu6?M|iNxV9vDrwI!B&0qy(RK2&F|GE~W9GMp;v>OzfN zrZVhj;anGJZE_s{&_eCGA@Al#>M!iROue(DmFyWCegxKd?fnUpc_Uh zn}vQ1^nj+QYc@3vmnbJ+Xp)XD|5{w^S@bSDYBT#o0QIu&FA~=iG=X(`9H#iJNLfVNBaOPnWsJuXjqy?Y`)sW0%;or=#pt?X(T!e0I#( zR7k)y3-Y3FeVgi5L$^HnPm9ucN3c~Sh%xA1aky!|AB|h04D~_x#s7t{6~an z~cIOg8k3n|IHwL=?g3n1}(g~ z9nZ@6^WjXyH0Ss&e8||WDdRH;KcaGm1&@sg6MfwjiTHX?Y=^slPDvH{#*P~%&wa(o zPPI?=sXk&kyK?`V=({w)JfM@qGeZeOOE@UxRdbi@TY&~*Q)9CZ?Qn|qIYBwF?22%C zVDRe8mZSC*i;-vR$StSJ<{Kq?-zOQ%Q9Qf$Jy*kp>K|r*dbua*nwpBp3U=IOj=*dx z82~r@_y@Xu@_pl&B6wH9U)wi`8qYMitbOa2DaZWpSLDi+GvcD4hrfoyxAWn=C}A6{ zk-EVM`;0zP&ULyxWVB%J=?u0k5HHUhs^TE*QZ~OhB~Jg*b0{&6=6Wx6p5!|~={pU2 z2}=Bnf~Q1tv;w=2yFS+4+*niY9@N-qZ1v=pU~7<&^C%dB2;3 z%@6wumY2rq-S`Fo*x>CC#@FIOtT0N`VKl$>Fshy+0>ppuj0>xJ{YF`$RMwFN8l{&lci&)u)SWf=xu(0XGHb1yx&w4FsTn3j=~0=6xoLNbG}6+jkR zPw(m5bP<6EO(j?umaEgl1bKB-S!-IAb-M~Kv5LuDthSs!flm(kISl=rkq*A_Gi_wdaG&8yIOYNJm3fbv2(Vnzyg`db0r;VsXrAt(>GFN}tu z?$sWTg3bguZ+-(H0oI&aP}MK+4q?8*WJo~+NfhfueP?FIy{?s4A6 zNxaBOUyMkJ%Tayn-nbEuP%JB`Asz);&^TrZ3xnNkt?BL-TlF`v)v<~qHNMTw^HuH9 zWZS4X2GP%2Q{%k@pqeOlLdFN^`1WyhAZwt9g;pUO&xb|iRJctPP9JrfJ5soH0{Kdg z694g~P2Ue0DW3+?>@&Ecr51WW*BmspQeh%O(CM~gK~vrPm%7~jS2I$_&!v6RHY-Yr z7dpEY20`TZx}}M=eUFPZeLantz&4GwHLw-ZLT3lIaVOg@v<1MM+A4#h*<}N}QUlCi z=2~q%o_XcCGIJK#cyL(6#(wh!GS-)nQmoFpV7iXMYj%m38@wo9pSosO=kzxFz*UUf z(QtK@ePVlDT0uGVDiRbPUc14041tb=MB&b@d?x|^N6TD?gG$tUpNiyqqL||+|6hF% z2~T!Lb)Q2S04A>u7tSdYq*&~J26(N=PIK%7n9P^Kw#wg)CJ>XX*D0@}a7W>1mp@KW z{(Sz?`@Z|`H*rPAEw&Sf&DCTV&RH|c*u@4C3p*By_r&OWVm&;18ivbUHx(W)(z@#Q z1w~N{IBA$YA)hFC&I<=S7FeW`^CGpwJ^6klWGnL|HLSR=!^G)E=)EihJjeIAMYglN zg>);RxlaIM8IG>rz)s`%3Mzn`x#tqQyQ;G2H17iW5Tj{Nrt!HC_g)dxU!{Ju)Cf4D zURsCQEu4hyz-$xFaHx_SsJtYM$*5i=d~@SH+G~Ol588BNGy}7|g_u6`PfFwdkFcX+ zN0gFkiuZnV8&h_$Y^_wnShEfT1X>ekfoc8e_cTQre3b!xldpwJg(*aCn>6RP+^x#RQzC+U&zBC3`TtGw2$uRG z-}~Uszj(GMl}ToY&%xq}3MdjC4hZ2fJGK$V1dXQT;dNDk!p{oE1!FG)5EY6nlelPFvZ4#-}3(k`sf& zfBGta^+7!oPJ`@M3 zVgJdlK$I`%8#fDVh)j7YbEA2e(5CGE*Uubi3spPY*W5EQaGXTG;?5s>OIN5$cGkj5 zo1p`F-wH$uIddRBhYUCvFbEbwN@(=jL24M`BVNp0L&cnmDXkwRY>pP6VV>!|>c3-A z`{hA@nr-z8hxBdZOAg+2uMu!jBs5uW9a{A?v}(@uV8WQ}sjoM7r4=0&Dr@gy9^azn zIry%Z2QV*yI(Y{C!!ZZWw6E@yGzZ*YYP`aKL}ZPsd^|iacYpi((sR!{L04Srx^uQ< zU$#bQg@WXiV(Kbx(uuCv>1jwyPRD}zob~JyF4Sm1F<1`2GkDD8?%iPb#QH3D`C0Z2 zxjQaL2<9VOvryMj&md>GS1W~M{}E|wVlZEEw=JD#A;Gzw?L+KNIY3Hw8w{i0vmA() zl6?DFgO)pX#Tva`O#B1Bu zGfx|qYu4-co|Jh`*E%dlN)`6N>Zu8&8_nEK9>8<@*^y`PtiExb0xNsW#R*_jUOH~gx3rs?`C}Vvqu3`Nq(&m{F zMumZtY9HL!m2-_ZmsHgD*^0>z0myY@X~P_ha)zGF7~}=Ifp+KrsEQ+>|)nbPSxUiVpJ@!EmS-?oq@0q494o~&nafaiDysOS zf+_I^b~L$|^69A}^Il?Zf%0eVXL}CHy2|QKU_)RTc-bY4Ja>TeRFEl@;VwhC=lO=1 z0zpYvX^}dvV*G2MhM?gU?h^Lk+-CEHHwm@zl@KM7F|OpC1BK4{Bgiv?#S8a*ynH`QFQ1r~dTi!P#TH4$Xp9TrwDESK*lEJY%#OcZ_F%KFm#) z$mFZOaB~Z$FpCSX`#iRbK@A~P$MKgkts5UzZ?j45-5Mz}_E^|MZ7@i}2IJ!}x?Bmi z`79NOrJeZ3w=chucjjzEt*M#b-=U?{xzS*Q7wDIemS<(GBNpEz3|X)qY*QKI6fX$1 zK$E}$B8S3=h3T8g-=ofy#qzN_kKj2QhjE6!mYjqu2eWwGUoR)o=UAW6>^Hp0fuYCq z23?^Kv?2rWP)=OcoYN(7ts}Zx3&?gy!TrMH`W}69*2Cn(nVr7Juj@V&6k|h?yPB9T zY;#VOpdKU3C3&)SQjJ?VKJhP3zJCEoW=JRK zJb{)Qj79}=QJNoP&|$ZiFu@I2a;~d2dx+q<`godMgPYmzI`%Ixm%Qz&ht4ihaLaEI zWf?HvV_7Q~1@)HOb>j7RULg(n5$guET6nMrvKOmD{9GQD6(@N6DPf{&{&HYAFe`6_ zfSg{F8`Rw`n`gGO0MbOS^o9*m?;PK(>b`ah9zm|2%XZ%4dCEESDuRRyVXz0xcT#_}`<{H3B7v zK9+&@WbwQNl^Z6U1oac~05+krW#|UG&%dlXt2%hdqxoN5{oORBU-xYN@(+YZGwu^~x+D-I|O%{Odqkn*g#AN+d!OOA9eO7{?2y!Y*H z-GTpzcq3D(jX$#@*0&k@Cm=e~ue({hm#^=1tEM zzp^2DS4iV4oLcap*=TQJcfkUoIM^2SZ6U0Y-AJgsp>S8P3dF%r+iNI==>=x5?~}9Y zD;iw9qT_qy_%j(KjgUqPqmJuvrT{Zw$-MVw=Fi#?3Sq05P4VdEl!vWK zq0&qKr6-|YTvy!^r&HbZ5s(#pyM=0kTC@iX3eun*=l~tuyeJayw z8!iRkdO0ecmg}cIu5eYppS#4V0WM%Q;V@Lvh?EMK=A%iH^^?wDk{jC%kTsm6vnB;=s>Yg2+V&;>hZ?qK#bdHhzH zksNh9FX?>gO|9(i2R+JzO%&udLL{HE=lx6mHym;m8p3-)uS3) z+COKSAD_Md;HTN{KWAjRiGBi-r2*QOtIEQ67F%!uX1k}^rNcpXW_~?6C8E`;_jBkW zKfB-iLeDrXBTKFiF*`oKZnWByu8x>T;z;$Tsh0b=K6FmIAWgV~E8HD@dB{I=wV=mA z#jCZRCrLjYgxCd>K%ox49m|He( zQSe{&`@_wE{y)^OpO;HbH5^RttLq1FW{O<{6L?N8SC{TVQon`*>*H64>jfG^Uq1Wm z?%FXmX{Y@+q}Hle^@zgqI8*PWT2FGr(qytwlF19d_FH8cg>+;Um(YUrX5YW#MR2^- zY6~5)`wsa1FZru4`mqWNvgh&OFgCD%(bkwy*4lYi_4Aj1*1tEca1rNtevP%)3UB)l z>(P&9?|xxkq;XxV`=&<~E&*IWW1WyBY7;omZMeyuG-Uefdl1!LdjGjR=K`Jrt_>BLL3jr+w20uma^yUqs=Tw}qX#n<$cC(7W0jWOkwVCbYHVsm@i8VDITWjuYCQ+jHN&RyR z2z_P|lo)UbB2lmopEF?YC7^v-i%$TVsT(S3xyO1gtL&fs%|;azx#5HMwG$;QmCRWe zy#8sTpZ#R{GstE^LdzYV3#cS&F-1Hzz7;4H;$O6o8Codsk;K0)ik$YJo&`neS?4R3 zKj-AL1`jKXRrw1)L4l_~4115HOw_>i;uUk+&AyFAj@I3Wk14RLj8*T6z-!LWYm`6j z$#~(g`pi#mLcWBjEgVu;5WL3vI7pzv+o4jJy=`nU+QgGRqxBxD5`{Lyoy#Bg{153% zduV;|m-50T@Zt@8tWxAa`i2gHvz)rkaGA!jaON5%;7OqW`^~rB=uJs$|Ml0}E;hF> ze81>NMJrTp*te){D9G=3&`xbHE1fAMHM-ox zh7scMJBd)?2z0yAlH?zisG7MCx;(sekQGp(RxF@I8T*GG*5;=vET{f^w|l(_ATw*& ziU5YafM8W{8o0sqP%p9*%Ogl#rC`OOh8I@z@Xv8WBVVKS*#caf9<1BBplCylmQf<^{8x?k5g+x1?nS?N?+Ae%b{F|OFzMR? zn8VDyJVUB*oGMw}vco?TS(@;!c_?GqwtOPR2~!lSmVLO__TEZ0H($-AhI{6cpazQ^ zh%bnG66iZi-NqegvzoH{3Up}Iw)JCUe)reLgT6aHwDQS?U~*~rCetp`gBfWM<^do~ z*gEUBCG}tsW*+;-Zm#O+a&KG2XL_LZ|I)i5r}s%@6(gqfNx}9GbV3|o2Uzie*;!J! zr!2#$)l3y-KqCWV$lE_0R=Hb*;1st0YUAQ&-J>ac!%qI$F9tgLIs=_Z3Yi|wXz~Sh z-ldIGSM1l&VzN-B_s6m(ME~b>YykWG>sIa02lG*xkc%L1vjOLm96@8-5bVG|e9PB-!d#1gfv~VQ-S85Ya2{SYU0cXy8V_VatiR;9c zM90qRrsb&=C;R(^8F^l6sjQ&WA|J?CP zop z!v0r`E^Q7kjCrPhxne)=mY%Yc!8ZF-H2kDFXag~MH&MReB*H*anHfI$CrdDzLW`-g z>h9rLtG z$e~aRro#M|o<$?J{NF0Aoq1YkC!G)Nd}pvrltFDE-sgF47~1x|=DG6qnpqdKUI!N# zPldzh+tdQ_l=XJNY;>T%3etJEEy`Pgs7}#DoG5@w``-v zOl99g2r*Pp1;we?KSGO7}kX)fc92#(H7%dm9_&MDj zW03Ri0`Y~(+4aIZW2W~axq`Vs{vHH$3_k}?^SAAFd%FL5n&r2i&&1@2t-{vp6UQVE zspNiJNW1nq;SX{QBtFF_!eu~LRvask1D5McJwnf5qOdOM@$8CWGE1%1vYcJBUNMWK zG`RZyEPq~m=Z~XH%pBUmqQ?(SfZ>+H@!sICb3lZ-D=@A8gMD4weyled|8MN;_5WdC znHR4fr74X;>kO%-704vUOJLyFLldFr;^v!=X|UBgl03}70fy0CnlFQh}L;E?&(<@z>So!ePOIZ2FHeNWz%dIXrwd_5f} z;~1i3GZ0~eD11|T;FJG*@|UILY=vyj@wD4J8ZG$agVLa{sGZR}=+2$-O)?)b*|K_<6k zTpWCLnx73QVH6*in>adABj}A3iF{gBFATQ{l$lQn=}SHCNANaJ#wnw=HV~(ptRYL5 z$0hkZ&W-Na|TSygEawZ;7k$to*k0 zQ5zQps7H0vtIM(~qctk8UfLdxrZoOFClgb&5MaWW(*%EYE2{3U} z`S7)>I2(11IH>&F?$w>`SBE+KRFiGkxp+SqcvHZ_en z8{_Uv@26Zp-tbCSZ5OdJjXtO6t!Qvzo-6NA@B+9z0?=KM2B9vyczLN&Q^R*iF9$P) z7J1oG2?qSksR8%_{MfN`$6s01!ExHMUK+dsutpNF{`j4-BhMyL^J!5W;nIS!O}$ct zpWgA4gZSvHwh4ZV8Y!>D6c1{I2@Q>#y&*+o;GkxTRI5sjqXl;X`&zp!l3^E_4yC*zj5!tO*h72j>cZ)QWj5mOJB~5w(h*9?zhO%JCwd+hF4V|05?cS<7pViQIc(Q(C zY39X-)aS<Ene|H9oY0C#Qv z54gMEw%23GX+DZtwSYMYZZ~zN2S8P;-sz&0ThiDeHR`^D4UTp-->+4Tm zu?jr5tM_h!h3boNrXqvD1Q}(sXd?E&ecDxP+^F;)J=NAJia=od^Sl><=?*V$yi#-7 zf9OrA!iQmb&NxIE>VYK&lTT*S&yn#-spON{q3?x+2Fs>ga?Xxew*BX%|Cg5b*mz&*b)HrZ+`>5PFq{F2vy z;iq5M$7n|YKV^XsDwtvd$dSg9k1Rl6NhWpVO42c53(YWGrxtl!@9Db*1kPpV!q1m| z3NOkN4?aGAP`9H>g`L!D#d1W04_Mot$|PSD6!o_5@Ow~B`qtErZUVA+CSf(0PAH_Sa@F{H&77|D%7XPoz+ys}RY;w^ zvS+lYN5;e7ir#y{z6d=G!`)9{IdBM^eIJ;YXe5eFR1#XQ*N?hYA<^GmU$pvA%lmN^ zMr`=O`t??aqgKSq)^~c`JKBII0Xpbjp}i6TT4an+l!c73L%7rn)iX#y5z(acFA$iB5(fHfe`b(us(`BhXNlmTFLoc(r@bcC8P z#=R58GT?mK!Sq0;Rw1$ShMpr^f`^V%QC8x3t;x-Rc}Lo5jxc`)WIfp(%92{yMjNK~ zz#2-r^;vQgNy;Dx|Gi=Q~g1B z*J5m7?QWbp9;_x7k%C$vnZL*sWtd zLMe!7jF95fG9mF5-aDfj_dZ?o^T#N>uDp{IosgH{dGO+qYl9)!T``X?Sc6s~N1Q-| zEFii)nH~#glne?gmR${Ugr*<1&n@~R8yj=spHdLhi{@h9G8gwcEn89D$QZ#j5cuoF zl3^-z&UIN&Y(;$2SGRT^Kb>*u>$9A%Y35wkTIt*yj%@{ua;5-zGa4-)MM+F6R}E{0 z&3{k%b(t=8jQ5>I^To=?<|!lQ+8TbnMp8$mxfb-Qn5s_eOJ{bUEcHlj!J>^{Sv{Fy z7T7n9U2c4@lvHDtC-B@J`7hVPW+&#k@iG&_GGN-0y5~%j_Y_CHwGktN@#gVOpZ4I72Woje_LXf$Ydp+{(#^MW(n$v4%o- z7pb2vF?mAHw50Vi5c763Xad5;)fZygBL`7u3sl}^(0*6hqr)K43ITqlyn=BF)DG4GMq zT?{h`+BT5S(+!ASwl7TJ$ZIyEXAAAs&fA0RgOeY*%@5M>yB?BMZ0LLp)SoOAZ+5?= zBq)&tYqV!HS>0j0qpNNGV_wzTYD3l%Kn`CCmFywB|;`pPM46bpzPY(lj>p)<37{3SN8}&vSvfm+JA%mRA>K{8U08 zK$$1-9c(B_))RD?Aj85{5){VVO>ZF+N{FUoBA3hLVrzzaPi#0HtW@J^XXgQr<|lle zAc-;2H7o_b76Fv~J2B?NONXMw-%$&B=MkoG&zS}TUy^3H*lqAfZ z`io}QckO5cb}gg6tu9{wta+5JX?Y&HBPkIS4%s!SCQ9p)7a9?Uu04TVp4s6 zyq<3IQQ87HJ4?lDYw=^Zsse4SZ?u@*Xm0(Pp4{&L;hExh$KO?jcu&j=k9kPPE%lGv zBkVHgj8H~Z5JAiT-7Lgl(eYu)$$t)Tgw=RxP7A?c=?^pwc=C35pk0JY$O)$*f3^V6V}AIL73)?PONr@4sP%yeZt9=WT@ZG- zW5>-!%oh11Nk1;pZWkmOaXm4lLgl|l}#IL6nJ$H=mYqpme@_wrO%Zj{2la5cY z2$j2_Z7jCzY*ztc&xQWSJB9%@|j7Lgs&qJ-2%;vCR~QA zPIXuO6<>v?%@8)ttQ4L>W$~UcaZHCrtG^c|DG`R-YOg5RRRPO-jS0#2eLqRgP1exg zcg|3H<1`$9o=6$=>@$+tU$vaUxbzi&Z$K-mEQF<&aPpRR;z`xoV;fgW(j|R?XGC-< z-Q}N;TYK7{(S(5KgErA2?bNl&Z?5@!P<~w98u@WW_OiIw*qeK~ODgSW*?HjJAD&{U zXL1Y)l}QouiVZjavc&c)Q-q_p)YD#&b-yX^HGINV#(MNG*QXAeHK*S;8Hi~g!k55S z{l`RftI@(4NfsigIN?Yhr;wtpoR)KfN&= zt-7nt&RH)U1={1C;J5&`E1}0&zi8dSTHIRC-E&t!K;0uGl=0ak)tjFWvAoUDWnQCg zcA@uS;#?&`OCKp3<p2A-Y(B&Nf)s#B6V zsQj7On1s5dDz$^~6b8$$YF^!tGS#U`z=E<9MhM*f#8(JPYBLpy4sftZY@ z23{?AR(>&do>dk&7yzxG`HECr;OoE;4-GzVtezlQw5HiQtv~s$a%$a*S7gEA%ycZ* zCpvHv(d`(wCLVHBIKA&0o8>+yJSszqF50B0rW=Le`VLtZb*$B~ujS^+!&il#;c>xT zFe1bP>p;8t({0t*|BrEQ>XY0H`6WZfJ^nnXe*bM}PpQX+vD;aHBtbY!e&Ozwi99AK zl5$Ax08;j`p5m5!1>5h9SZCHvH3wS))cz>GfBArC?Y%nqIALI_MOR41lbHf6`;{6d zl#q~Cm*$+K?g|Ex^kx*b_t&?InHb3i@?dC(IfMsIa+*M&q?Lf}`TZQ}vyE8Mt!elH z1|(B&`huj>h>+)bON5txC)lW;GdsWxvg3Y$m-P#9u0L(MznJ7W+OVfFSFUM~$)xrg z|8qSrCcmgrCB6eg55XhwV#u%fr-i#3BMM*2hi`C3$M7R3XYICAj@B3!g(lN=d!dI+ z1?OAX{*>M#kD_JwYgT~<`3jcYR=k(BA9K$fGWcm{uEz6gg3Q-5>&0*w3xGzF!~?zc zHzRUYghA}D9A)M8hkBQf5A>*)&#ms4_|-TkWo6U>)xvbRZwbT=Cy;;@cLmX~NzjEY zOZ<3}`gr_jll+HRRmi!UFn}w4AraX9W_y?=^Ci6qZY1d1K9G<9P)}QI7;ktocv@=E1%>hjUVS_Wm-5%%QO!@S;hJV&}X>0pz&aSilYQ!{$5OFyr0Z zV58whdcIAXl-H&2^@k@VXjOKLa$s0T~ zp9p1_Og55ZOyAUVp@3*j;2L9^xyh;uHxsUBdgTv{I?-JujZ=?t)NqqB0|_<#nVv77 zRQV9WTV06u%W?cDJ&7t=;e!$1`s92u1zx+@FS*q?N}2YP+~qaegav;!KSH!kDqJ>3 zJ+X~~AI>RP^!?{!oUG58!`Hc>C%(RoUIxAxVsA{jOTxz-MXg=^yrH9q3UdMRjwO z6WU_S7a(aEYuw+C5AJ_Q{)bQ+MznRFXXl_o^}0`}M(I1=eZr-wtTaJ(>cSHF7>}7x zY4DFE+|qj60{gJ3+rH->68OB#Sl2ZMts9IWw@O3g_eVZl`r#W!*dS2l^YLCu@?{6Z z$g@|4F>52PyHD9zw6FzBY*&ni=^fs~d<+rZJv9-KZGsnFF7rv9SrO|K&D2-tJ>inC zy4ds#(+=ue_&$?>uT798&-n@!Xmz1ibpT0`?=CN0fI!_8l>%`f-B<&)d*tF%rNUqipQl>itc_$xb#zr z>-KH};Sx?Lg0v6+5Jp_;fl9RRQ<4WbG!kV}VqIdR3``J_c_}(KomVA#%?({eHVj{f>Cm)dAfpHdx!O#4#j5n}FIv0fS!}md%+!@cRJ=nhCN4z zg!;SA+-BEq`I&UW>R{1OusIt&JE}6iu{3(;t3KIFJZMg##yFzcI7NK_rlW4m+fSqc zt!w7eBw4)A@YE>7rh#tNy*V|}`{ZHcyqzd<))17K`W>J3Hl?33PR}ajJ))}Hx!(z* z0}6JkJ`RHu^a2>VY=8*!f!ex5_wCpC>nKaY4C9>n_~&tGw_M{2` zq%Ml82$D_5(4x#Rx-Ef_P7*>Non-#HG4|VfYG|5j=5jtHk}NKw*;;hD?}+j(^qsI+ zQvsG2x(`!N0PU*7T%2!Nm6>l>n=#L+daP2#%y7-8hu;3Q3@yIN-LywrK_v2A$MzNp zM1ojFaTMVgF^nH{azjr2>O^Yq&N~ByxR>3;?`n@b@T2O{i?*mtE?x-Gld6T0Cpv_t zrx` z60FoZ?WVFBS@g(MN~l4X>jyV2QRuK=nfFgu++FqV>7TdqD7FSof1dB90Jhr~1eDAZ z*6}o+Zm=oPUVz(4qBQB^>6Z#VrQjOT@~>dipTX?cx2Y=jk@V4H1E< z_v*$(U~56c>O4#95OT?O!Yj_XrXfN>l)&)#zUms#pNG>}mD_KW5IKHCwuR9%Mn#LE z2RK^n6ueIY#J06%OtH3+HW6b}c);(kB% z1AW0YpcJFj+D~?r=|k}}@!N1N^{Ng!op|o^c`70!>rWTMn0b^`7rZ`579wWMM@3Zt zXy+G1bi+#^A018f`sbnNP)YH32)lcs_(8miF;Fzd6 zm1Z@{j%u;xpw}$JIf? zQdv}vY~GB{&eM6SEKcdI z84QB9_UmFYI*}(1Ex)p~MBwJiraWqbAD7t%;hK>D>i#}N-m1XMU zUVTORrz#gs#U4bPUFD4%2Evg?>?}}JQi!=PB)#IAoA#dQIzSoT-*NnUo4i9LzS<$* zqt#-dO5l_f)KLEyX}y4sXWW?p0rgQNoX|(mzhM<=rncNLfo*OMO4PhCRps?+rTLAI z(B4x-f~MG;L>=`FJU3J5JQ)8&SBSc+JIW1pG&`5b+15Xr1)$MYQtWMNYnsN6f6ZFo zGwepdpCsU62g4vQ1`KBWKoeQl5avzsQ+0D|!5&8XDa6{pJFDf@n_rT$->ood?>m$G z_K8h;+=~$Izmb-pk+csi2erhQ6Fpy$e7y!w7Bl^eZ|P+te&<}6`=p4|QB%0s7=MbD za;!sk#2eNKS?^<=MFa1|UZ`)VmnF+HDy#~()`IhA2wn}%Gj(dXvTvCrb+=W|AwcPF zTNGKS1FYOfuySBt9LLn^dRH?GE{z2YuPN zG(*N8c4ey}d2{{IJXRVB>)iHxw5LPdX-B?}cif&Pu2Exn9l zcAS|w=QB(K<>vveJ|a-FSharLy}G%`Q*utOzt8*qhOCXS=Z)08mkYfXD@epfMiWSK zlLro`iO6;-Y0A5Bb@PE(GkGyOGBcKl?*TOHlKr6dUI}lVFkv$4;$N;aw_;dXHuVt{wm0~UO^M+ z#n!>7V#QOdS^G)~ZcQ`K_0+lcWY!#+D)G^(69@>4E;=pxoW07m2!17SUj%?HUezJ= zD6E#0@H?B(`t>)14hvs+UFcfwjgW$8-@dL9Opl+ZDf7Vn!`$Uq>Znk5Dq4jzC=DTi zb3+mhs5*eM{Te7}zrOfEBhH^^)}$f3w3lyKY)Ll71CeQ0HAUh_%d9}EC7-wIQlbN7 zLJ{-rjU~>5p(6E{HcEU<1~8tzbjR>9oHL z0sZJya&nQ4e(io)IW0qD_X1z1ACCVxnwuj@i}D-v%}6sopzE(U>>@?BAE*69s`k#w zj?{;}bFn=52<9za$e+ObSwsB59o5B{KbM4GK8@v~!H9|sGSiagI^BV(^Xi7kO(F3g zmwI;2??^^}e>tFBUv5h-*FV#xVeh=ZxMQx>P*Hycf?EQL9X^Hy)1H0^^1|#?EnN%T z&yo+aaE4}(`sCcDb8Rj4X_h^)$-i7LuA5F;{5dewde6y&b&bS?^~wu?91=JSbaPpU z^=wiG6_h_jj-0MAJy)EO?7I5xMM5oilCkVY!iOU_rGHl?YPZrAyk(lT?B9ZlZ^D(@(eRAjs>@B!4omr-nU z=7(ck?P3F4Do!vK9vfX!Jvc5Meg_kRP@N4_qC$1v#O_RhdaE2m#vvwjzADCDhPE!f z*(vCMZe*jr?X+v*wlQz_c#U4hcwVU&E=ai~`d0#m{+lM>tUhHxck1t6l%$grj=XOU_C!k5F=(IbSMD8H~jquxYIYLQjRs0;A1) zepqCh_yB!P{CH^PNqyke^B+B?HC3KxnQDTSBQ#NtrDdkUQ5hvo5zB!!2v+U6H6#sgyE^S3Oy}J zp&bqWG$zTu3ROfM_XvL5v7mCHYj-JNu195LjQ9HrwYZR#b z6p&B1GPL}GAS>!f+ui(H<+=Gdxe z=@ZBXEul$5)dLVz4W|e^czg9LexP1U5fpm`4);&VfwmkF`kDXNfk;#*C&jhvBdsZd zK)bFm1(=F%AZQBpf7RUR@*Uv5PtVv?fcsK(UxL2R`H2y*518oO4>ScY%nmW9=b>Qc zheS$mqpBx_ML(Py zzcX{L+iPE!%jkyhh}!ONbyiDFLT&M>ZiIXN8c`BlBVn*cLuw!e69?f*5fWf_b(zVI z7LEQ$8PUtO8*^~9j*~k(`R-6c(#h+0K6M>me!%Q2LCLdg(MG#U>}<2sOxx+s+|wf` zw~EFC){rB|71A^o40aO2`}6vEPLssqsZjNUTU>vBFgTiM@Xq>G1m=(SNa@$CodBeUQEFCY(WzJUfR2;fzA-pxv61cJ!^p z1o0=uX&M!BmG}qo-Nae0CbtO4>V4Ly8Tr$d2u1+A0OOHF4C{mmo1Jh&u1=Gex&`dy zR-20>o*GSumJA$CIyIy4LaFi9i`ome6Ydudsn20NNnx5S70&RS2)h7S>4Jnn)~$QB zHU2O&RI?!Wsn>nKo#HqADHmmjxyT=9@TZn?**WdJNDRgC1CaWSuoEeOB7FjtUJYAE z$o_?YH9s1slz1P>4h*Lrw=NStjuZVp z*L?1jY>ToFQEVSQ$u*~=ed0eTvuXi5T|nk$uF(n@K0pz0s|Z@>`S;r%X1|6Ydl@2_wPgD-{FdKfP= z+oF;y?*+~d<$no#JpW=bfXQ8}{;qnp_cYm4Mlhs4)KL1pa zaTvY+?#7$ItYZG!A}caYh+roPBHO}E9_ESg4xfttFc3*E_W69#T3oQ(^SU% z^iARai89+0qdKy*cEx^@I3mLm%M2o+!|$$6y7a4tuY-@sWic5)8b93qJ2_E|gtWyX z|AgcTMM3Xl6Crh1FtsIJRYcH^!;C3-fDy%27+5yfH6<4`j{BL7YGCi+&0EccHVUDp zS3-48G=7ADNl=GfVb=}1x7W<{!pKXBnx;)WZ~N1lLm>v`$48K zjC^)=AS4o6&nPLJob#UJ=JdCINOaKHd?@DNeYb7YljliJ(@PIQu}4`&fE!q3+K~Zy zj|cwP`*w*O-BHx7yh&u|c&KjAq2Qj7;&NR@x7Eu|0{+6ci)tEfbgU)24~EVoo?{y~ zsRa)>($(?;^pfz_{r9f3OdpXRxQ@9Nyhycd^i6J>|1O@Tn7qD8)NYqUe`#*)(gI1K z1+>VVx6C=ABU9%}r`^n7c9gnG-Jg25GV=a~hX&7Kz5v@(Px!g$!$bm*EkjspyCU>p zaG6Hs>etcjIEE_IR# z0TtFZV^qz1AVvE2tM~5DMF9qs2_hiFGVCK>AB1FQ#WC_)lNe9gIjwhCnw$~ht;7Pv zyU7rFF}fS^yre_CwY)}^vx?}J*fXS<+NVFY>cm#w`7@H71AmGi)cG|37yNrM`+3+m zbq0Bt65tS=QiQb&G8%S1z}YkxiiCRFCE)8M8d-`+9?*F!N0+$>Iu7Kd=YDMm+xAHm z_-?0O4w$vo=X+6ZQ1j=le{!#n-E(}sBnZU3!|Yn%i*0>MX)=Q_n+4(4%_AFGHW@pP z`3TRNxg&?cBe1~7R6h5@Xki3%H|e<+4aNWwv(%?7<7IoSjudDq9Wc#0Pd%XoX|;nR2tP>>`=Hs|Jsc&|~@W1+?F?giLtpJy|Ckw5!t z+6@&CIz`6p$lk3p)8kBo(ccV$EFr_de!;DG+)Rg7RF#B_8-(^YqlxNlA(t0RYD|6!=i&c? znQz%88?6HL#{*=-x+lvOX=gpUdmnxD!ONL)i9W%~4<+j#AP;K-xwg3aq)gsoe1UWf zLCj!OGX+@+yYh5Ggqav}XrPC!t~JM29w5x>@U!gXvuVJh{AYd>vlQ z&X?B$&REq1=zV}4C2i}*cA=#Y8q+yK^niw%`>@%Ztf04Kv~{7Z%LFCe(+Id;}=?V+hcx zYd{@1{TB6Nh2>FACs;*z_XuZ0i-hX4i07Q#IPPy^KJI*HR9=?v?r|p6Z=N(&K#(`Cr6;`*iVMh2 z5a@n8DzcF1G0Y*36tb#o4J{Z%u97>ElJUPw4(b_W*lx@0uvgpk& zxU6IDu~F-0{cmNwGWU4oQAV>ekIilZ6%XEfnAkEev>rh#p~%8`cJFvnV3G1Czv@4D zh=Rfu&kRL94Thhn=y~zd@PFbjab)W&c~Au^#=K|iK)M+# zb1^ORREq~bZm*T9RWIRFhkQ1@Q(bGaao#J*Z0~MBHEyg`q!bBvZlqY67yE&j8Gqdjw#%FUd{n$D~ z0v@DAT6G9iCBg(biXiBXnOVdvaBUrVxDl+Bdwq1%z&P9-{d3N)dG!(z?P&y(so52H zkE&_Kg^Zr32qNE29PJ@qusFK9dB~A6;7}WpL2VA~Oz1uHFP9Ef<`wnMc$*W$iFx1< zc79lx18MesneHXr5J!EOZX#5rsz&wTV zs3J~uHN$q5ey#4@bd)X+O78KdoH;$KV4D20VBo{`)48%sP#qeQYnYvn_rXtXGA`1R z5>VDGGiGmBH}nw7sd!bO40(6_?5KBe@YRd>hoje@nU>t&hvepAPGptQNDH8XX9?(n z=JC(}KB{4a9SwJ_F!P!u_b*v@)0^2id%>@Lpr$A}{(qyrGuxEJ_-y~W({4}0))W21ZZ@v}qD4Z$IZX=VoJI}P1S9K8W~K`5W4e7;ZH4(|s5tdz*1$rd%FkYJn(L;FPEdnv|!4#pWb<;pZfz`go zqFG&m&?g;73RxOWH!Xw8CHtFtf5^O~&4dP0h7SS=#J7E}{%aag0ZR=o?S=>!}zIdxzYaEHJ zk>C7W4nlix3qRgJh<^QFwb!sAr&u%X-3wna^L3yK-E1$4FP3KkCW(Z0-Bn*}u=gu= zy^yrz4pP6pu3`eE!_rxkJlN%N{C-Wm7c3l))7m}UwUC}nH@PC|;DWU45}lemOXZy{ zY=Mco4IdGbN$i&9VkO;VhwTa>SUPYRU#qTZ3Nz#CqcVu_tijsU)+f7c!S!19`k%am zha_~a-*&3!^h0D+z~a!&21H9pP6e(Rq=IrWAt6Mm3--jKfn06ZKaklwFrb3EgC@f2 zB!|gxJo9F|P!#88J)avwc>02gWnj{YUk{e+xE1AV`I&q@B$_=8&^gY`ZuIo~d= zn4<9ScBfAtFFAJP{OMmcAKGv7gI7a3`pg;zm_0&y$k2`?K_9dc?O~=OY*pK$d1S!- z+lG?vph3yIi!BnpM`V0@gp(JK|B8^RDn|JMeht9+7m>_47+4~xt& z5zcjKx9-OG2|L63c~$COo$OQWlUjM9PD0B8RnslKDx%IkcDfm_S&ktgJ*XaEuk&!U z{FucrpMENCm`7{ypmm1k&uT7FlojK06uIgnUJ&pr3?u(x+5# zU-Z7EC`)DxeZ*c9KfjUohxI{!Zud6$ERWGc5KyiK%%0n^0X1cf(Sb*P3yH5)vEo)X z>yLWk+QcmD^R;iP?NE64@B}H?D2Ley#Q|!cq8ez=D&BeB+Z(m}L zwRo-Wb$I{Evh%%QK`h9B1R7p1dEkc)0xX(TR!$xr$AC?Gn%1p_b`lI!p%B70eli z@Ic`Q%+ywQUbTyiph6$`?%L(AC9@-Ux?HMba*0cQ{tfnzL~+Vwue1FJj1-=k6|h^Y zPPQAZH6zx&^DdG+@U_|9X6ncx(>9e)VuCFqUuI|2ZUz!Fm*L>0=9M%x-9v<}chJ@t zuh<#!#=(idXOCKj+$IdvPLvm9+5NW8J1xr1d5dUGAk2RHD|_AKLxwp4j}ur!Q8Yh9 zb>qdzO=GAM)_9id*}f8D{O<#Yq;}Gmvi=A#9GM^fChsy3G{icArA^XLC`x$#-`TqZ zDr@R0tSZ!6*Qrn8ve;}cu8`auKqIO!p)6Oh?Ef9}#10K!2gdDPU(=OEh~1nr zg?_#YlxiSrFUTZOW+5!VCg89%D zxx7AQII>-zoxBNhPl_;JPgTcEwclAB9*#Fv720Dd5~fmAQpJ7J9_{TR^_SXXZZrJY zt*vsbE2tnkf@(v)nFAG zOR9aCsk|NLpf=IX0olqY&gZ*1j85dW+>j}@cz&vnHEVuGj3e?d7f2fKeTX_&zKlPh zm-%FRMLWU6k^iawx6U}vPa7}y@#R-#a&$nCl`<{6C(A1g>`SbJk>uiUNQ zRlEx6BHiLsF@awkK6W-?>AS_s7GJmBbX?~Sc)EVe2{9Z`At!os^`G?>y7UtIad9U1 zTE;Fe?$0wiSP|tV!!>kqYZw52-_dqH?}<4jy7Dh(96?^;(WA<>MxN~n-JnG6f4MX& zD6E?Et!mqg&!A^G$I$(`lI+}!`K^rt1-QE=ov*t>-p}6&nI_mBDTAFo|I9CzsQt4? zlzb!9)+W?t0XwDG1384c7EH%5w8tp4;tv6wp!~d<*1$TlZ6n z*iHX(eZS3A26AH6i~n+cHPqh*GC`wxC{c@yrwSY@0tvvOUr3$klWp}WMBoE_Qp1Zl z7I@;P^YC-IF{Q`+cP3u+t5ZnQlgz4%OaZziLztQ1uRQ*NET^%?IXHF?+BSx(Ft%)d zexqe(TBZ%3ysu0sQ>WFK_y&E^y|v?McML((PDYkYoAVF zjCW($RVXo*9ZHnunOjG}LkSJ;05~WJf-Uocvh?8p}g(VyGYtS&R%AIu~n(Fb)*eRqxzHCdiAF! z^MO<)aPt|LQhy7e$)d(@lC@i)JRaYpwi_!p|sDb?St@UhT`YvXr^lk#}f- z;mU5t``AhEigO6;h<2gX_LFqG_&|ZdU>7%49EK#gRYop7<%h0&K582qc6bZ1*gQ zs!#%&=32(n63FVEHEd>e!Aqe8(_q@U`H2X$0{-LhRM{mvv0dv^d=sWHiV^IFynL;q ziuaEujpFZ>SA@B=x3l?;Hu3YXuyq;FTLlZj2oXd3(b9rku!ldDS;J1X>Ao|ATp?CHh$$zy z`8H%lIPZ6?Wz`pHAeUxwBsZx^H0(A;rd>ic*4KlzQ}W{B`AVxG&S2}kWGnx;NXFr1 zPyqxIFQzaQ`NCZJr0%cF#sdb!>w`~>^vc@)<(fI)A`;__8C7|-3A^R=26dKcL93(m zX6@K@R|z@8|1qYj2k*J~XubO(V+K396W#}VNv1>Is6Tbp_nd+ptE znj%U@>p{f5AHj2vv^S3VR_3YNKmHqm{Qu$yqdOrKr)u%(B{qSeHPvYSFBcXP=dRaCD4s_B%jL>>{ebIjtQyb1 zqyIx#Y)5pI+Q5Ja=IMd{K62X)yN7~r@+N)_u+%sNC>P!f5@p6mBTzL9tSf*%$v8Cs zYpadsw~s8|!Ovi@^jdWe%|DU|mQDUOe>$p`5sX(>sX)=S`^cadamXj{)R7K@l=*pj z4|)&hli5Lb2{3IaeZk+u6EhZ+H{#41^Uv<+@mPE<9@Wp$e!Ew*HPx+-{r2$b6qUR4 z3H=wBxxwwh4ZWikj;)(3rHd^XWRhccFVQMVgeP-3?;oV6+AS@AaqEAsRqklG@8Yw& zUU8{OIU%x}Ao$jn^gIhF7ASTJu$u8qMA_6d(#!f=@z;XZSFZ5!(Ylb>+NjULr;jA` zu}JDbd)MQBfL)6B^mFRL^O@eF*Ex^0OUxjbTt@V&gd0+e+@-d7(+*RK{!qe?RxW#^n6NC?bqL>56knLlaq)V6{cZA$ud8F zB3G*UjKBNg z#Io&vP}y9>1|B(2yT6mRap&F+30AXy?RQMksAK*3C`Ly1~%B>hHXV6|p)8 zc*JDGHn3^cV7*k#eg)<+wgBkfvt&7P`haZeB+7|`JzQC$7C7=d+HaG38<%MHU_@=N zW)M9mM(O>dgc7-ImOpwJ4Q0QFdi-M9fMBhLs;3kz|J;-XZ`)j4;pB|VT=ufadY}km zkIj$5BI|BjnFoqtAbvE?Zj!|Cp#{ZJAmCQ{K2OPyHd;rmdCC*9n%3N+AUnDDMBuEI;PC5x~f0O(s*pCpczEg-+&~5dI=Fi{;PGKzq>9Cn0QnB+FXtM9gNZ2ybgmsOle)g=Xj~h6SDcL`R z*ndE$YZv}YYjDE97f4jKo|&1kao7dEbr&zcr_xA?(VKqy4~s#AIs!#+)x8XPVpDzB zP*rW=pz(wWOKJBE`yJQ;${;t%=n8s?^Qf69L}u04rlD0Y=j4X93Hy_F>5=)+mxC{B zn#p3^&fG72nMn*Ub}7(eK&L0%>5X9JnAKZGp0(<%_Ti|xX)0b$q0EiI7X{67?jJQ^ z-T0;Vsq8~X|C@MW!6cxhQeekpeAwsaIW08l-i402QvjU3SnXUM*6U?ix4oG8fNPB* zshnBhMX#04l;oHGCp84dxWvo^B{1e7#0K6G)k!+Mdt5H2sZrAZO^j9r`Ig<4sKY;Q7+1Drnd~8^LMmH}B}*nLOR}^o+f;}# zp|Ue(L`b#}iZaQT?E7x)M99uqX2uj*h8b#1&GLP&zW4pRmver9Jm)-rbWZ1#Gc}*< zb6wZ#^?ogI5)>5TsiJ(q$SSVIB4ibLV(eEI68ZCEIBvM2{nNBu;8Cs50lGr^6WF@? zcDMp(8d_;uO52_$CsymeWI?n)3(75sTU3M51*Gmml6x3ENX$iKTP8K&%f*OuT6?y# z_p;+*56fe8#W*0ZX(f7!6J|Yp3zUWDH@x@KZs2i^3!Z4}-^zssL&To_t7(1%1Ffw) z#H5W;szFEFaR&M0NEu6wX5W8gvTgLS5|uLOI4IlkRJ2`3GhECO{gX;KF%)L?0dQFPr&VCX{yAc1PU0hyGnu{jx9e}_xM(V^&Y=+Zb9i@3e7J$7@k#z z>xO}7qYW}Gls+(uR^#+Mc4)y;!!_#a3YPC9N=1vbG?76ayLnlB-7Y(q$jMWUxY;gJ z5=D1o;NLSKDJpfUhX74s9UThA~w{quT(+mZ1}vdJ?sF^ zjeswtTeEQ*Mk?rGjHJJlkIhtztaiD$nLDsqz(ClgYjDlrt;mhJNc7(e;(nk#IUKWH(f^V@-XgWCneu(*hgV9$KH!FCNHPy{ zhM@x9HSpPDdJC00sn%kQ6bnLjk2_k|;otcjgxza(Vk)*=czibMt*O~iGF%ni0|k!R0RV97rq1*L|MD_TfA* zAhI7wRjV+RTeRGpqlOM{_j$%vT}(!=>fX+|+3^VxDD2gm7Np1jHMVbP9j*n+zO^8D zY$sTL%1nKf7h~kpPiHZjL|}ThcpIm8Ok-o~qr=%+gxFFsf9;t!Fa7=gr$Kzg;t##;coni@SD-4aGP~ z7!iy8H?zdzt2>}lm3oQ zl9;(cj|0y&3_=#EM^e+}A9NC~PcDsVH5VsnEQj9v)>83>TP$TU#Mb@m?brjQ=p(DL$BHB}#Oew^&RfZM=_hOknjE=&a(#Ocina=X zO5t3$W*y+{cSeew5m-%m#L~EtauDWXW7D&?@h5aE=Yu!@gd}D=(Ox}vjYo~@GS6xE z{bNs6dSNf|cK=9vRr(Xgmj9Bbj8jmbMa7tVBlxdb1}0AtUu==ammKeke{12Y>(`iQztONuE&nNTxsPigP-c^)Xux6+lOJpOSw2YTjCMcOVrv}kJ{XUV$~~W*TlnYr{pRt)l(}G! z=mm0MmUw(>yew672GT{S)$L5$yGr2t7jQPI1>;6GMRBmC_l`gRS}oLe#~So0r{^dS zHCH)W#OJtFU3h#d=!2jXlxhQep2<(~rNxkSH%30Fyf8eSgXz>ezZFIC&bw1IIG{{sPT68B&^qF21>sUb%Em zB{Y{+lzNGz+;fVAbcP$%3`_tcF-Um4zS%R5`ub^>YQ)Y3ufS{dV_Jh*tvbj-$e9yu z!&EIqVQ1le^P2~E8os;BL;JR7ZRj6>?%JK93WE01(Hfo#DwBpbd7k>|`I2=Rd8YLN z*FFZ1-!(Y|bw}36N61WU^`1@5m+#U9hX za_nQlZ#zP8?^7#HWIR~BZ3Be@bTnV$!jQCjQ|K0&l8-8OS8n-F6t~9h@p=Kvb zK0pv@;cPH>Iq>AMi+eJmEeZVt$vPxKH$f@6R>%Lrq_SqB(9VWo^FsOTylouxjN zkbgJo{lbpdCnc%XBOb0i!B5>?#GbtT1#~Xl=;Itfx>QMb3+s}ldrL!YXi4E(38pJI zN0mowkVv-vwxET>DaXs+RqSk%v7nkeL{4-n{3Lo16qt^*YlbWAr)qZj;H%A29jO`d zehGRtP{|SBb2qcs@H+b5g)uWFmZCg)yid04&yB=^9PA202Vu7S64;0bw}c&o;z(L; zCnigN8^{Hh36I2d+sWPDUT}HrR@=e;6?S7wQ%3R^|3)Pk9#r0K6|YOtKMTC>9Rjg;kuuRgj8mae8<--*Au>R~MLT;gZ+EKJns z9OnyO&7PiChzODYJrYA|dF_C_9e8`$!nHmP{=J!VeEyx@9|!za9}H}D=IlZvEueiW z-$;Y96!DxKNUW?yL5j=qhVjz-n2m)iI+)Y8dTz;Q_A$F^eT`%pyi8kkC#FuNyATxE z!0%#W1QpVJmki>pFp@S8rud6#ZPTfPBV{#?M?)TB!DBN zW_Kfp_Hw5OeT3$g-Wd4!=(yIK53N-Z!_t`!cRq$Yv~E-$C{p_TR2tEt#|0t_ajxYv z)8Oz0+B#w1&KnHXrI_ei%CV8_Rl2^~Q&_EO!Gq1!fxgQQgS)xOL5e@TjU_kq`!=GO zXFUkQEj~bTHDx3bAJjYDg@50h@VT~oX|P)gv_yX~JUM(zW9hKW{k47bEq1BsIe2wF z2xBy(2Yv&Ed(m(O?ejN!LX1jX+*~zkoK6myYh;sdmDEZ`@MMTy;bXibiYE7j5W3+J z*n=1#h{N{5AZR0&$JDP8xge-@bJL`jo|co8T$be<_3y5Y)s2a>t~%qy=b2{*Qc5Fx zxPo^#-ZJG-d)S$6vO&_FgqrjOjasm7dj9%j>AJBGn;M3(zP_?R(Tux(g!ZHPkcl2~ z#bqbb8AFw(i!m&iMxNmHY&(lU9|T=7`zbBKrK|XYScDb_o#5khlBccm&U|n(SNDjt z5&)#-uIwa3X{I&n3d7_B`U|uc+Ur1(^+Fm))!e~U_#tW*+^>2>O9`mdyE8ATb|;^e z=3l;kISBNx5tG1ryg6kErv~<5Wq&8Al3Y3ZQ+^4W-RgO(b_og}sy?>Z7tded*bkc@ zXj(cQ{#-e2?SS1_#dBZn!MQ<^37L?dm#e@7rR_+`i!BHPfYq0Xq^`peKB5 z9_p%Wp~}vyfi$HT7@+CS=)>`{te9u!21#&nr$yxLT`?P_-p%37fk`DMUyisD``H(} ztKr6=ZP~Y!sn3~!RYEA$|8Sso zt~Wp_rKoo=_8uPxh)b)cHzH}i^b0i1Gs7puDWHME2+Xf0JLBbwvMt@SIs5Fcjc1!0 zxr*@})8jvhzTF|YB?UC}8`H#6P53_;jKm5l54Rr62;o4dT^rur4T@Mi{`R$``|*s? zdoo8kYCbkss7Z54K&QV;v1BTI0m#>ZTu>eckgxMyW8T{3*t}WCy9DiDqP2-1)rl4@ zHLr^eFHyWcBnpQvR#IKa8G!nN_Yin62zY{QZyGsCz~0ig$fNY5N9C78uX45Q@cx~1 z0>UlNQ7Jj|jVEWc_K;vz(2YpySrF)GLo80h%b8|4fOc)cAWlcQc2B#P*s{BuRNx#O z>gL;h1KVUhy@BK>K{rIHxx}QTwi75M)hue6rr8x{(A$)jSV|hyTi$u(r8sl@KU~(L z4TK7@hjH)M|AEqPu=`t}e{NBkVN4pCy#c};zhFMzWyD-@qmuL$l6(u1`oZ%;3T{2k zx^s#$JBk5=Vc*Mj*{L9tb^=;SNNDk=;%+iVN)Q+U{se#dV+6RYbw;3aKIc1^r)dz> z^{lJf(_^BiB*WJ)$U_q_L@a2^If9gw8F9v8y4+_`rX8Qz>MYYQ;x z@jYPc1Ofw4=zfX)ss%%>UmA%3l&CbLl60=bKJ-bT0iT$2$Nsetm*)4ha}RFC49Urt z{u}WsaC$M-K3$=`>~ydL3zy{>fhZw>Nedd@*&`pn7!*WCX;vBh>{~SH{^0HWR27{1 zUeIR>hHM~AcrfHZ{ti8){g!o$7)*JE*u@`9bq_A|gg%PUt!`r)3Y?A!7U~!IBC+?J z_Afxxi2z!utW6$?t+u0>(F$*mvXD6r0$W;18|NkXFUdq+8{0Jcs^k&NRa``nLzND3 zp~^utZ9j|`_HZjgL4+35r!M9dNOF(6Z7lU!<-IHQ$NvDppNMkO?E=Tnijo?Z0Sm|x z0O4eXBv>!@B|#P~7UaaTB&w@)JDZl0;tXN~<8-22ndo=ddRJ}5MxaM;0i$mKSPaez z>`%E2Ws=Qo26?O3$>icUl!e<9{-`p!O8|dpTN-P9qGyQB&ov8Q2Tvs{&FH9#H>n&-{P-SR zV|#Ix859c=Hfo!7e9RjKA?MLb%aT3`6r|Ov%Wi#1TNJo9zpUeSC@KBU@XeiGvu+sB zVSi$$f^_#-4uHRKiQiUF`y8l2Q!GpQ?Bu)}@C3t*)0W58Z$qlRN4D~8oAWn(r{VNo zb_UQzjof9JFduNfV&pYYHe`91Zk>RpN879Rw@OQ=6w^8vln!Y8ap^iLV7xuQeXa+{ zZ~WNlFgHzU&LHkUn*bQ-T=#%Uurv$RmQVXXzSkCiqggiE-RoXOdCAdC-nFf5GJvIxonKp$vW~VC(u;sr zj+@@aPGFhPOq>}DWtwq@T--MK3qLc@=W{YXsl6!oG3fA4`J-WtzEO3vLt(LtiXo{` zAk14Vqb#}&=!`$R7NQcTu68)nO3fqWM8w*}$v4`<8l=*ePU*;3sQ!1p>ldKM&^@@y z=?>g1j_4kZKE|^9wnF3Y#EMx3R68l{?)4G2)_fSNTjH&Y*x-`sy${>?^|J+}-0?6N zH^4N|ZfT`ADco6BL5Ug=`w4-=qot}FUxk$oFMqwdTPLQtJN)JP3<50jlAlABo^^!MJ-l;dp+m^-fGqbQj` zbs#|~y3GBYQLF^&G#H%6{hciDyrUgvM7S}T^ADH4KeM(p=Xb_Z=+&A0h@x5M2g9;L z)o|H`YT)k2CT)P&M(d-Vv)YmnPLA?Ep_Dknx@Z_$_*b70C`$YCVpilwsG}c zJ^jr;A{2`EAr*GbLHT~_I`c51kRbeQRNFkSA+7ej)RJq1Mse%#&%ERNn^;waXsery zE~Ywq0tcchaQQ3`_8ZR0H6z80ZfAMyo#~_1V}9W~vjXAiUiv(d8$$*fN_vii@!XlU zOb^ai!ofCG1au$fQTgl$xfR4Ox%rcYRc*!!n?`>%n=6<(L@44C7kM70>@E4668WQ9 z%y@6O0sJMr3cFGLnKKM7KS0)nx9NC-z=^e-&v9~^Yiw-L328Z%v;A96c+=FlBSo`S z98(?Xq`9#Q%vd8Bo|^LgKn_->r85QkY7ul$_{bua_+8O zQftQw#sl*VdgXcy{1o$K?XmHe!1_@4l{jrzwoF|m&$uu4reVV4=5 zLb2LHCwJ`*k8ajXdf-W?tdS3#MWh)ocxXpjG1L%_qJy3=y4!a zP6~CAohWu*)vj&ycW9;3*hpM#Nrb!gge~q(q*CwttNzDk%@{=atRnEge=C8p^CGO1fD#;#LItNogq(b!SR#!k0b`we|8ZV57?~x z(gK)JXu~BC`ic2PW?uQLqNNM3ujOPq9CwM_pad$p9@s2IpMLi)4pRqYwlqs}VV5Qs zdIrYRX6U@0tr6L6kH!{!3H-Qv`@VbNW3O6?2%cAOTn}!4AMVxb)ejHRO~3&B8v%Vr z5QDjcIN^?O#{Uccw(MjH|Nnu%?vc^N*;TR*pv*OgtL8Dw{A>lrxy? zF*S`3`_YyzDI81I_2K>VmW-SiF5wbRkW; zGuZIP=ULC&QsXxCggy7L51bv;yoJ(%Y67kxsIusMM)hMecmlyFSqz>D+~_hGSBk8B zpxLsPYZ$2HW>VL}hC4kAsr@To>r=NbAElZN%zwXy!Gq*3Ai`BZPh$iy z2*NCkEJ=tnyu37bK41-_d3EeTG<{$Zz+cOM@V6Gg-{SuXf2D9Gb5m{|pFdff{juUg%F>A^O)3DB_Sr%lCSk6yS*$T5m~1l} zO0T5mne|FF@#R1HxK<9_v-fGjt*tHbsh3KANNpN&YsnkSWhfSMGf$%X2zzkuHZj2D z1Ve<$I{CC4ogSx%Bro0d_TDqT>8%K*X--ryFFmpb<5o0zC(`NPt_bii4#f4%7WY9R zMlcirz=VGQxat1@z=s1Yvkcx)(oMXK_F3c_7M+~Ye#V3bodsWh8a2t7odSrXeMEtS1FFO)OJ!gbruqq||1D-=sIE`p=X&Q#B* zmd9>x`Dca3s-(CCx(B;?ri4Y>#$wU!fBq-k#w+HsAmup#_ z99SCuQ~n{Lr0_iU;9m42%&gOqR8wpjX8=<>9WA!vm~piQ13^~VoU5Yo zwp=@V+|7L^W0cFV9~UP#-Wp^FxEm$(2)x>^6V5xrv{^eIr|N*x5Q$&NzFFs}!d6BnZZQ#1;f(e$&FcQ=1XrG-gf#)A6Y zCC=S&3tw-?#lGgN4;$`OCaI8agjFVi;OoO&W4j8tW0e8siZxPGTGPpVZX@a zelD&(@KUXR!E0Q0-|gD}5Np9M+KECnHu@)?W66`E-5>1zwEugG4cC6QfBCXFXy#j| z`HuzJb_Vf`q4!_=n3Px`dQr4{GU6Oz55X50|ds26_z;R8oRKK&jDr0 zZq~N+3fSzkA4B(j_?aA*WL10DM=@c{BDkS>;Pj2 zPn3dE_`Z+S<xXUz^Bu(i{qaUiWgHooB{VCT3ar(UVkt&Z5ojpZ|#!6>+Q*TVX?B5fp=Niu%!!h-=D{wV-FTwjZ z<$Q#u+pZc^J0j61ku67k``V{+^w&><^xq$|htM3`>kE9cw;aPpGuijq?_usXf>q})d%dt8vM{?4_{ph$F~xKv_v7I|*B*0yfPCGG#8oLzv&1xQGWsyQfC1?> z+Bfyq8})?e`}`Ur05jz|Rq}K*l4C!&vWM$L|H>8tuhNx$h+T|x4f8_FF7|vjD@Jr( zAJw2_J*}Orl-9{V_*5X}RAG+H;pu5H)0EuHC!=rk956NJ|8x|m)#5_jl16tfYP2#s zsOW((J5oTgfg>ZeD`3FcO2bSq_4>FAw1Z_Qwca7)CbPDO&c88Db0&~u+A)Ht>ru~A zZ;vm9hQp$N@Mq{Vz0&U3E!(jqVf2TLK%kTpoJJWig`5#}DTMiM&e2KjfGB(N)tVZi zx*Vn6AIP`}X_?`k^9do?jVM|Msjzb{=_N-z?sf#6-(##kp~j*Ajh0oeXL437570NC zsR<3)G6?i1WTr)9hyEeEMUvTdGwfr^URM{p?5=^!hvqi#)&? zhE^7CWB~WDBe0qBKVR(YQIM`}9@TC(4t^{o8;zAS{STMs+g(TA^_#$_>VDd=h3=0x(SZ zcm-2+m%dl8!}g-?9%^!nE;@Z?h(r!5(5!UU`-0S2c<~UnHZ0lDQ4T~_5vZV%Yf}Jp z&$KBp5}z1V5`m0Q*!i5Eh#LHnnC53gUY+dcLNB>?W{o7!-=LK>3B~B)QdnY}La*fr zNpQ6~>^}6mUsjR+=fw1}l-A_*Mjw1RJrPvw0-!2Ltug6Uv48XMwzB888)`2|2O1i$afua$M5#DhY?%eSud z~x1$&L9sVwx!_;PAF4N$EN5Vt8j1=n<>0P!o z9-Z9-S8`I!^Q!j`v{Q}wB~6I@FSN^nJ+}r^Io%!lR>RPs=ud_M&!qRk_f*ZHW2tAe zs~tohd>QQ7JkCuVVVn$PiH*=ho7pMlEl$*`v7N5Wm8jbD2Dc+PQ)_|g$}dSSuPE+^ z%Vq_hEEr1?IA3Aa@Qqw@*fq{RlrJ@96)LJV=+-bNN$IbdQhOn%Eq^{9tL1&lH7OnN zJ_og#P#Us503(5x2J^C34v#%O%m1DQ2U>G!H2QDR;iM<~_U$z< z!CsE&b36h+Sufr6Ft?!E!5!9}s0i25`Qu~_&faVCt6oSruG@i-^@iO2PH zA@sH`s|Nf_8w~GF&ra-NwQ;_J<8WkSjwy@jxY2g_CmKpMO+`|7x^?ZXlOI%FP_oi> z%7r-aJ(=&$vS#r#^@Cas_Zb=0#tv?{I+Pxq*|&fI1dz zG!*C?NLu~H%;|D~JFIp(ASQnEDqnl&@0j@ex6j5F^D4sm3_AWhn zQp}}(Bcmzc`pRQ4D)9a--^F$I!a;1kJH;GZZPqFC5R_c0#A)}W6U?I;MPFasSu}^O zq?H6Gw^~nfPX1Zp2q-c&U>(qB83bvTbCPZx=h(t~-`%USi~P_IqteGYKQ=`#Fbi;IAm_=S zme@!Z1+%k=_CBeHdsC1?JmXDigCa_k3ZH{W53V)RD7&RiR51I;_UM4wr5`yg?Pza(|UFv0he zr?mRA6Jg=Y*9>Vf1*drq*W+^%sQ-6=Pm-UaO-m#YRoX{HQMPVk3wInODr1T==}(W= zy$~t%8~#A9v+?BmQ%%}sx$;wROR(56G!y7*_j_e^WnNoLDt6-f8$ZaIu&CpP=iJ(H z-$P}3~Zy}Xxk~^Aj>A~eK6@pgLMk{+eH8E?hADadO&wjPHuI3W|MXt zd}kT_V{L1|1qH*A-gI|r~+(8}ydb_oFez&GtzPZA{XR*JFN^w33 z+#S^gZelgf1`A{lnsKNF+Ud zKP<|J5^ty0#~iDE_S1v=7vD=32h_WE|4a4Wh1T?SdbyiMz;MMu{?m@*?eb3D4-DRP ztk+yVqEOHl1la@mHqXzVyphW z|KG|K$bTmOFFmvES6nqV2|v&GD#+&+UZ7oN<0(=6cX>N@wyO_BBvYE1Cp>W6zcu$T zd@X3wktJ&J7sISWogA#w6#1sF)!vIaPUdyJc&icA91wi)*RSz!tdRcR$&8{6a(?9KaK=Adix1U3u>{O0G_OPq_uZ`?yBCygt|+L3#X#|s*^3uX z^{>f1l>vZk1am(r0aGW;f{J1uU=rH|sddf8Yi+92nGUV?o961;je;K<9j<@6l^++e z9`%SdaN2RD6aErcZ?<8=d&-tVg=rWM=_j+!S0GhQLL^#M*>V4;XG_2iOZ)Ok!==!zFpy0U1p#gV{XO=+NNI zWnH0?v#<6OHy#8R0E)KJo=I<~^|jl~*^zLuzr);}sXf_mkq5?dgiGx&Y+UZTuzSSi z?W>5NiQT8>PhU6)t$3i3`lH>7<$C5_-qKRcDhSdaKRob;;CPTJusojbozWrYjx-8 zb@L^%>+t&azh*6W3W>Jv%zh7IgJbRjCjq&43cKH*$rPmcT%GWn`50;XR`bK#tw%B% zu11c{<|*?Uf(Hf@J-Al^-)~OCsv5z-UYJiTT3^dzyP4$AJxOxI! z4(KqyGpkJ3&i%>Y=L^?^&!mzADcBE;@+J2TcN)3V`5;XszbvTO&W57?VAH(hchQB* z4G}swXU0Dgs}7V9f_)uVB7x#<4p(7AA@~zVUg(R&6*1s9sin1v8UBHvthDQ55$eo0 z_nMn#abM1)9t)FI-Hmj9pG8X;MZ$t-|Z2DuD=Vlo7g=@L=aI^`b|JgGGM(vFTF9 z)?mZgQatgfRRzUg#PXEd$MDlI&tm9YAsq%b2kHvBJfcN1$BHCu0>@r!qE5ZVXiuD; zuWdZ*JllKV48KX!O_SP+J14wbHCYl+6OgQ?#2LodQ{GbHCe+f`c2fbupLLQxTd3Lp ze%1QyW3)%+skV@Q$?GOD*2cfeY?hKJk!3){p#WlK;7g##&quS<3I+en(nyAbIvmghXnOGrO(L07>9B5@d|@V)mlt82E8gU+m)8R(GZqJxd~> zPE2q{*~`r4^nAZ@s<+ZJyGPHX59%p#uc-%iV?gWb4}h?j+`F**8OSapZEE0~SI!#w zhWcg6!Lkp)Sls^Xn>=oaoSVG4+Xk{7cOM%|s2QQ$U_ud?DziimlyMI!E16|cwRx^7Vi@iUMmXmh7!8L4L1NJ>ec~u(S`$c2Y@+hvg7JNMrFd8Jq1D0 z?Z9xl=%O)iBk>303jHn4KPG7e^c zIxHK-FGwTr1b`-AxUq+p_{HBzLj4_b!i2}8yqH{>1UWLK<=i_rh z0RvuEb$PpTh9lL%E1pt9ijI3Plx5NFKry&5(-@9=$i@PeQ!~mL*nXZbZaK?FEo1X% zE{)swCx6cWQCvHqf2KjC$1R3or&kXHK`idBmzvTBXtyo4< z^nVo6BfoIcxE+I$r*8bHgYK3H+*-dNfq4`Lr7yGJ8mR&ye=c|@HH|Ym|6=1x{Z+Sw zR%M^p+s-@xIfJdc+gBNIHb?z)@E;p)=mVlXqw2D} z1ivU`>>00}GaogXU8FRVUPt~IFlA)T9c>F>1ALCaM&W7*8wMmz$WNdnpN#2-b2&O6 z)b^6Iin#kL?COHmktAQo-m&(%I{m8WX}(GJpo8WZ%ZuH>;Q>N)37FeR;-Wlt<%J4O zD%Zu`t7L7uD$Zai-Qhu1_I-t^CXe8*<2zi$^r3r5qm%4<9JoH#Lt-{-F+v{oXzu23 z-s!_LYvS|9r1j9a@+`j`!=7rfcRLN2AP4Q&F%MyLW}P@$juOfn6jve%QO+kbdhLf6 z-~0L&ApW9EFV;(d z0KJBzPQ`q(@Z~E)D>is|Q@(u=?eD+S?*eP#dTbSlt-A@UlcuOMwUAJ7w6=$dciP|1 zmx}V0?_sAG!v6XvjvcGOJ^T10SFin%q4l|=EvfW$_9uVbETkJNqHgmH<;CA22<{c8 zr81K>j4|@Xx4i8-=`#(!+BNw*vZvuH{L6FW<2WyyB-!b3v`i2I7;Vd`5TsnMDt8Y40I_7alOgzO`fv8TU&4weRQDK^9vQ+t zH>=*VRb=B;^0R*QLbhYG4s>DQ!y&iaG!Z=t30DFA2iL2~D(zNg^b?FPM96;lS~faI zRoL_|(rxl6({ii1((R()Wfk>mVexz6e8Qp8SxjpW*g>>-kQ^8vB(a3auC(E}TzmVT zFun}#JDyZyF}0>JhC{^_DIUcNi1@u{6HpO$63i1G1p{KXG-!l(%N}woY>7YecQNzR zR!x|`G$6`U-Y;DBo<2^IQ7YmMxYBs&8!vn|m#j-^WNM(N;SxA^&G^3xQA@{Y5_sOU zw)*15ezgj%vAPidp7yI+Tl{9p7g7&?(SAnbw`bP_9X=LYhmA12ru+PtWm3$pj%-aj z-c@&3`m~4TlL|-k67jE=%8v{*4w_|iIg%^D=+Mgvx@1S$LmQ`uuxr|+80kAb*~)Pj z+{e{we!kr-EvW&caGzw^A3|sJx<9|z82#OUu%uXXF0vcG2jhi_!3bjzSUyJI4Qh@3 z!_s_)&&`RN8L7VBIl4=2@r%fxTFs=G;N`m?M1b|mFuG7c}uh2Ko%2r?ZwV}JWLlKG>-He&>3ED?ys zj4sQGAGP2rH)XY-q!e&^Hmxy?J}zdHJ|lX-+#smjhh5GwLWZbxVGjM1neBGLWy4Z? z733$xyF;vcu{>bK`<#FGQu|=OW#Jv~qcZg(Qc9Pot9HPi1>SGt-p z+(DQNG+2b+!YPNEzwf3%c!{rM3Fcu-+&;9$O}^XLNBi@NHdXs!_pm^DQ@aa}-k^HA z3S*0CBjDN8x>;RfzE$Kr#M@TU7H}+OG{OsU^qyc8zQ6CV3twws2gs^^jy3?P7s9}> zr#WlWk*yok$C3P|_NY`FX?08*JViP!5AXk%U38ZiaGmcrMCM4iJS&%e8E9^#&=c@# zLM&REK_HDJsu^Oym0Hr%KFcWKzTo0d`{z|#FYmY_U!%B_cdzKP3Jt&UX}0^s5$ZKJ z{Fxp>WMWd!5ai;t*22>{v+)h>gd4VLrKQOqj*fM1uDGjx*;Yz{ykq58zbv9J-hWa0!_2WN%f}L|Vphjs?_JymqLRoB#CE-O=2|^r6X)kkIXiMNCgd z2FORP+7U`2)6f%ElhMKE?ov2JQ;5p*yoN!{d7f3@5G@fC9Ma*;lK(`XDV4zbR}6&6 z{+R)<=@8aZUolAriZF}OCN#Wu4_;EQ^iVX12Q;P#I%^;z$~5qZ3C zKI;hsn>2bh7EL26K$~LZq|Y$Th_lp zuk)!rNq`mwOz;PGJ?^%e2dJqub%5Sl{v)c z80{zv45_Y3_(4)3MVkunMF%DxC)9#)r|s?Pvu~?@!WZWzlo2BTeN55he9ON}|82(~ z#?Aq!4ZrbgQ*)Qf|8+=n=GzW4;53-=w_3Q!8eZdl;c8}f&ZiMIS-&$^2<|m4jkE8c zV^5w?;y2{;PII9@kE4S?bPTw*K@Zm0@crBgIe; zrb+*yjB?$dTny!sO)nLvd%oiDoa$B31*yJ0O zBb}cuU$u*s1eK#1g{9yUR1fPwp!HCi)ahu{*`*P|xkb~==l1cmHG5R7oM5TZ--X;i z$>AqyMmMSdmSH5F!dP8`%JGHo5x=#A zUffJQ)M5Gf*0T-JUQq?>w!zy0kzk4+ZZ@@haSwH}tezBl-0AxI_3UxmsI)h8Yw04N ztUKrPUIZy3_l!0A%oGCLnMT@@LRqlmIr<>S$_Pxg2oj#7b@?SuUnH|@kMFDQkW&kl z^>dWE$gR8RIDL%@0jA|p=4Et$_8#E%#qcqfyOwmrORZ|t>kC$GE$PU-hi7J;ikfbx zEZQ_HdFLuFJ06l!dA;90?PL*@N@IMlGI->5J*r#kVe`C%H*v=-(QAyEiQ}dVCfupLX&Cj169M1E zwJ9GT@p2y_s6Bb7Be~rZ|-D zEB>_8}{)KaR|wf>cs z?T~n{^vGSE&*qO;`&DYg1dD;WxPjf$CT5Q^X9SYq!a***Xpu8!ygw%jV{VOUkR7cM z{(`1~W`_?3%^hDeIq?(u11#|oax{)=1GpKK3ssziOYkx}#K@;;uq^TjtCg1#_m;K= zvaXNg4c_Wx%*7tQHFxB28AN4uBo58Z=Y~s&XblY{R0}eNfvhqQfI6R9ek*oz3z7&CmcMbaI#2-f$;RFPWL)gk zkb>-i!tY|=b93gO-w!VV!Z{|{2fXnhb+;R2(vY#yDBUF>DHTOtcPJ<=aW+p6$t~Gq zKbm)ku04_waVz|ch^h5uI6DoX3}`g2CTZgaF@O<9#2o_6kSGTVq+b4|Dpw;AS_>C! zRKIxX{12p?EOW8pM+o;VV2+&=?0_khb566k*hOuUj0(n_?KEig8?R|Tn2EGYRKC zC)Gnt-Ryvzd!5RM#a~XbD}LF`g@Uv@%cBnGFRfc$+3AwiW&z|$_;Wou z7@;t^Jxf;37ky{WcR_t>x(hc4Tv$-b9HbLA2Wf9RIdx>B1#;|Jj-wOeRamiOtu967 z@2zHlbI%lQ&#kc6_ulf&T;b?(CPTJ1;%L&O#N_fI)!sp>ofR!DJLkSp`F&ZZpPScj z>g+@RZ|wQX8qf7BX%1t>E;rIg596`GAYpfzT9BpIWUu~v>TS`$YVk~PQ5GOEP6@qW zsp=@jK9f20l5Qi!CE@`;;I zWBi`xkk7YB(+LbxIZBP;M23O2?$hNX=fF7ILtod8{e^7RIk@4XeiTN}k28D9R6eKR z>e=kpZ>X!i`45nAw+4Qu@x?isjaZ;3hB{098#>W>5QN{xqm zO-$Qe_s7t0f-~3)#mmm)977M{ti{dBb;CtU?b_RPB8gGhq+jpv!fO9F_Uv}l%fw&*bLm0bZOBkv`1u$* zE|T8FF2Frx+tFJYD!D;7%y4lR8xvP-D<+nY{cS(8v!O}BpKg5hor@9l?lH0+z)mRe zwf|z50f&N}A3>%yLa%r?w{b*bL7!fJ#eDLVy3>%zafWXD}=K;1foqe18_~SSo1ZkWn zEFQWSB=2FDM#5XvKdl)7fD7b}R*#xKhvl#ao271cc;tQGI6{7OXwT3?^bkx2=QT2m zq&I=0F+JA9Z@*xoP*JN7vkvPatsB?}T!{Qfzt-czu>g1O`EIM!d&UZZ?#I<^b>i?o zbX)iyPlY}IxE1I=q}?JK-GE(`Gu-Ku8Sp)7%g?;9hKx=YWXV&b)7 z0v&~(c)RG|=WVQ?`D`tg%>+>7r4uGL3>49;D(FuKi$+mT(@>dp1>|jwCZ8 zDCtVWI5FHK`BtPa#Ly!#u$_+e-xy zqcf8?A)%lYk=IGj=v-XX%Cg46YgG+J1}-e-kd;mW2PI}hot8nbq~V^mI5EXo9#q{Z z|Agy1cPGE6I9=a%2n};T`yg0tAm?_9RENK#KJ<-{?_KC#v<7Dm3tDZG$?yn_RE-tH zv1-~26hHLYO=|u?I^6lHWPitL{`r@OCY4IBQ8W7;&IiE$#RZWt08(&+5cif~>Pjyi zc0daPz-_KkoC{AzrX*_&fLk}+;|%`D4m0@c;^O&B7{;(9qewxzGwlK zq4ZdHzPBP2>#;Ghj~kbEPaaL17I88AFWS7v{gyHMgz3rYfYt7TRMFcU(J>Y3__+diNY zlkd2OM<)RC!>gS4y#oGL{Krp?JYIJtBHAgQUnVhLHsa_Zc%4cIfe(cSMIPlwP()X^ zj*;A?Hgcb7?kQYNw9yAYGu;t`=Rc3-HxoVi;XGcykb&7@SKGj9YIND8$%Hcq-h65ZD^rZdJYgl%U$h5=JlI88p7qk z1*rS6==$9@dS~C-8S^Bx^k>6^6~EE!gzrvh!zA< z#}2hi@oLoe`t9$G1m9zUWCp)*4gmsJf2B<~Oc+8UM^{nu3tjGgp3AnntM&HJ8tlD` z9l{89)N%EfNqpPKFacLbp>!?>6U+zLGwuAQ|@W zWh&?{t4BYRh+!urvL|@JSQ)qiB<*jw@Q>jQN$UczX!n90TJq+_lxAuX#Hq=OjdiNJ z?IX=2R}9^e%yU!;{)GB2NCgMTNIM5H2Eo2>^mFtp!Lsgyh2_p#_sQrw;XTLjff91( zFDEGN|EeR?1*?T8;e2tFxM|6FO9Kerl>-y|-Me%iE*WIjeDCDB)TJ9Ar01&rz%uJU z*Qtr@6(BTWKxir?N8#geKxhX3TWBtC2u-UEp*i_!t#*6Pp&bvGH0-av(>24zJ$YeLzlGsgDF}h)(`&OChnsfK{Griy9uU~ssc{%K`(h=kJQRG7$ z(-xmZ-NDzz7(rPKY6{>jwt4O%v8Kw%4VPyW5-$E6DG+@h5+?TW*x?U^v5)_FTXgpCut}9q0&}xw~Mj2ZmoI~R<#$g&K?rK?Ddf5);9~^nH>GA9A15?PS*b9Ct_Tiab zxYuS}B-8XZ2F5zc-&V&t1&MXnN(J3ITSOylZx2TuN&xDEn>4?5M%_x_)=DQ#3_Af+ zX)@G~x7>%>%iPmg^zpEL{%L=mg0zfp%O}6c?IiyK&%!O%;H*b0q;AFT2!>ZhxAiva z`JW+c)ZVPQ+LCjTG`K79vsa$j#0d+l@%Xz+`FAXe1^h@?_!`(ToE*t(C8?J5_H{Sj#XoI3vV1x@f6%mmkJ&}7UxiP7Xe{@n*-M>CP}MESo3 zT*{F_ZsqSs3r95RQ6%S#>!-`{UkgOSB!YjV_%Z-4OXh9G0zi2y5kzKGiup%C+G(ZT zKz#rV>3R?71TTW0SyUl0`sNJ^uO_ye*&PdRJ#TWLmW3IYVYm?X2wIGNmno}m$=ts9 z+0e+;x!NEn!ao8gJ^AGnHsD+OJ72itgNS1=V_X{mI&A?jelFPx=&vU4KrSrugGDg- zM};iqeV8q@@4#Oi<=V61ri)tZ!(PP>A#1`KS^8@oa1pFXP`Axsli}uS^kkRgFZEoM zvO@O9&X&cT{%3csPaWa&1qAr^@DPJkyn2f|uGKM;dJn(lw~9)i@Oob%Yc_!kkI?&` zt5##GF@MQ9^v(;*02znvM}D9`bmA^gZGw6^k zG`~$ILGKxA)(33l{>*X=v3*l8fB+Mr;X6%+6wZuT?h0-whw2`LJybJt-9K?sv+mQf zH*Y5GOZ5@$ymc3LK6H=7Je}{zKZG%>1G3XJHSB8`S1Pc6nLeT_Z<=?(wxaFO&4x7n zPT1krc|qVUVxG@Pg%Lj?tHzpX@RXL#%;wI4fL8YW^)`1cp|xClI*gvbq~#Z zDu}LWdZJFGPhZtd7)P{=-1xxYeFc>YC%Pn%XwR?*d70c@bRCosBt(y@3TlCkbs$RW zxb}86c~tuXMv&}oxfHw1RG%4b0rJXJ=^N+~f13*3u1Rk?uxN0-RyR@aylbH-Yq9Vd5cteIU8Tr z!=Ar=W&b}?p47v$VL;)ilFs^5E5?tlQz z<+}}6wvKNAPj9+dm@zd6-`Zr3iZ+PilgChcW5!;?`+}a2tZvTZU4%qA$Ivkh$@gk- zh6h7zi@P1{VlreBZF0N(OPHk2w+2(sapOPHrE|*nLC9q@6)FT)=Z6hsU?=2Naks3D z*S(P1*w4t#%UE-4zfjxycDyf37{8^qP1n6 zXtf!v9o_8E*I5v(>)S`eCfSHZMdtXKL&Vp_@WUxVACD^&Q?Q#jMo>V8Ya{T(sYnsco7k*a=vF(8yDVDXsfWObR zv<+SD;o4s*dLHMNWWV<~Z~WW&maYa#N;{33c6Fp?fD%EoILVh;5q^n#DMXA)H_9g~ zM@|(cxXHt>A3Hcgj)S5Z+Hp-j95;+E??sc?K4o~vfaJWoar@<F{PrRYc$L|qm`9u|n7xoI zV<0gYu&vaC2O%9NW;?IWmSuiA`)6Q|&e|p0Zzrw)7Koy2OG_Ng6Zo|gmaO9;ib9Z)38(=)6pRqSV~$RQfXFWj|`GAp;2|AuggmzG)wMf9B2H- zZGBtChgJeI$UPV_UL`yL4{D!Mp>`(Om5EBuxTjC}{kX}2ju0KM&iByMZ7NLo5T;JC zN23(h()WmtpDq!YS;Y~jD#15PA+vh{3r3jVgH;^iE4ynahWV1+J*w`Hh8i8#w%)Us zp69WmSu9{;D)rE||Cl8g(qX~q_;kPt7@&1FXm=t~&UY8jH>9PuklQTP#lFoAei;A4 z!;8zRO83=wiNMRL0$4$?ltwcTLFTOsyMGO6UY=Ku@4cB5y>>l9tFt39CmMcRRbtCY zjs<@J4xV6s1BpyX=6$7MwP}8A>=9~I%ylaE=FEJ5H`DR9z@}!(?QPuO5Qya}0H!9> z<-H<2_Bo^`l4i^rRi??v=Z1Z)ZmKCnTx=yYavkVLVXb`C5es*^Qamvs7p3?0Q~76& zc(F#**f72zvI5^;R3s;M@YI+>-j^fq)HXL~t!u*74Yu z|JxU4mF3QM1lBy0F5I*)+UD$tU;nrIpZ8q0eSPepPVTXY%UhRE5%|ZfdJ-C7wy#mE z{X5Hp9qw8>*|GK*H*OL+B^l1o+$PbsPd)=el4{{?xUbwW=u*MH%8Zry0?~TudbLT8 z3G1PiTED)^xXTZ5S;3zM?bOLqVBJhC(N28HGP)&E)mP0i^t|t|e+9QDrQhN04Ez1z zX$+aX^}mpXZ<0FEBFm9em>#)qKe}-#4VJWC~90O+s0;@8m1OOB+`mr73K-f3sYIWBwziSBa z;q0}#8sG^I{Emg46==V8s$XP51;&J}XhZwCYWlW;jP;di8nxm-9l4|b z#gU7moVKNd`n_1)GC7y_ypr8a0r`hBd0cZS6s(#skTx@}6$jud04&&spCpYti_!67 zCYAoOZX*XzJkP!GakC3c;08dPg=Wqs=7%s(fHW$A2t(Ogf7^`04*mT z94zk^h(o1?(CO|Dq^L1ZzklI!rOAOW9svr5*01dsLSC9v4j#$VKZCo8?s+CD!F${S zuy^np$##?+e+VwxvLA{8yPq9^=0q3cNwE2R3dJt;TlS%l71~YN-r#*(Y>xR3>%mII6&c9>&T5QE+))7rq#c{X?LCc~L{-vRDS%&LrfJ$3WR)yvbL|N2=Je4jYM z?;}-5Cti6(H(h$p(fQ#9Pu}yS`xZSY50;72DyT2)-0i0sbUG_#URL{q??%^EG4VA< z7S!Yg^2wGO&@jiO_4N;|HrNLKp8H*!-6eNlrBYL?A7A1o+ePlq+5h%S(e|R}&m`e2 z|D}4S3_TjeAd1*tymAZVv`3hO0w*fWxMyVvc6!W+lWLT*@9VwzEA_j*ZIeaNU!F$J zlE4{sQin!fWHHS+Y;SVQ?jKkarha{KU^v>xIrTzqV?*U+v3vb6QJ~7uDCqVd!w1%% zi33UmPiU03GBL{@2OrNwnoS2%#1(7>){idNHuUGBP}@zNO&?5jjjh#I?Uyv$^tZr& zbSi^9u)*CBxF1pm+k+>f?$sQ&aNnI5Vs?Wdes706Iu#LmV#+jI{(`#4pmhf`F7sh; zD@~{l#GB4xK{D+Io(_^el2Gz=bIf#3(o#i#_4JdYZbPoWpOhwzt1Ouu)IX!!Z8%Bb zeCW5jIs1MfjZ{r)CrxnPia$sFoF}AHpuXlWoG510CZcz2Ys%?D_)Aqlk)vHmFni5kDM3~U9b>( z_UF;No$41krl7IrK0J`R9lgewy~E!d;3>f3)!ko>wK+y=Arb59ldt|b;E)+>2cX~?mUSbf>(7|q>F*5$XQD#B4J=v6}W~m?KzURh# z_o_Om>+60^^>D=k8^?QUp-D%|VjOwk%yl(Z`xH4!kP+&rANl&O$XjyFtDh4ZXP#fG z(A@k-dixb_+QA_^tT@I@lw4$B8di9MnfxBB5zt!!@vo; zNleq667Mwg>G-%XnI;5O|7<&45X^)IR51FWUilDO2f@VMk6gkAMD>}BP3`qf&mMnl zu;_O|*!{*eb#0~AKbQQEL@!|qq?p=^bs(;<%`RiMBw>z6Yaq!nv+=_tp9-$gb{>|D7`l4>$6gM==p7qYbDL!)9$9`*-1 z&5lI&aHr~z6bRmCY?NWeVLu@i;r?nOY&Wpeb_CNu8LoCAnoYIGEge-~xk#*yLsoH4 zRp?bPZpyuUw=H7(r{{ms)Wu_QMVKQ@gGB{tt_74o-Dm0o*_55~`fNOzs;GrOQE<^* z7d3P6;n=6{9cQT#_aX+#eYi^Udp#KYGVcjSn`6&C%*@XK1ZBFSUn9%&p6+!0yV@J| zf0>jNg`GGnD`X@vJrZ{Lz>H8bB*;0&?}8JXsM37HfWHN#YmkWrN2*!w)Bv;e@6Us` zd`qKmaow5ac1*kW#+KdZPMiG%7aY>6g4fZ;4#sB(1vp z)|h@Msd?)e7=8E5)e0?#GIh(eqcPMtST*6UvR0JqUJ!aVCH^K7QU6bl~ttP$K z3wd7gmnmj{Y3#c*koE7HWz$QL1IHXY1yTb~=#ufbqKfVTCood5hW%sgfL4EcnavwB zJ5)?)b@0nOl|TVyY(bnnrXI~g0kiQz5HEmFn=U@#*g|XVmU=`YE2^p1Q`4PeS8nXE z_xK?*YW(%LUplr*hqc+Q-TBbzz;WS^k%UNB33n{_Lpskfwu4Px%({-j@|L8r^>X6q zO5(D5q*vhnvcj3l5SZSdgR#Ru$vBSn59DT2;3Oe|R8_YmL<==&n=&J^^0R7*UV)*q zuz-8*2SIf8`-SaH^WvzT-xNXJvWMi7p-2LDJHNlc2mn-qB*lOHqJEv5a!Igo5SZ)JFCgtY3h7lRBM_Xv-@kHt}_t=`95R zcSq8r=gmT}Ve-?r`nJCRYm?0Yc@{STno$-`{|RjF2`vxrI{Z3j;3O%nlb+V`7Gi-M8DQSUCecnAg3v#ee=n9^iMvs>d=paQ>$$C0;3C9PNZ)`6n1NVxs5+ zl47>{yECzqhxx<9_WO80p9$OEncSa7=o=BrgA{<;=tS0{(p&VoXX`;*GxsPfJ)!ny$s&6oQvD?z|Qefk34-7Bjk>~jRxNHekHFGh&dc^i#Aq6M?g(%M!S68{p4w} zM)A}0dS}N2*A6{-z+R)o4(4qAB#`N%VT->%adftAWny8vyBh~`gWXFg&Mvor95Z%S zY+z4s+Ot-bM1kp76EB#W+|&RAUF#9#s1vX*&29Yw<{po7~L z9@cE?-?|d%5HvM=?_J^*SD&LtwrHiz#0cCZbW2V~OiLzWTtV5l9W=)hX>Tzcdcopn zM!kY^qr~i{8;5B3zxgI!nA~-#DBks?xtG>v)nz(RbQ$a_fc;bkl+e2N0b#Dqpv6UI zP6s7wL|%T3LL~OBBU0O*QZrbew6JqQmQoWNMfn|4jyFg5z_qL^K2`qFH>Mg@v$82$QmNrxyi!`)xu!hK{fQ4B?%|hzGYJ5>6A4iITo{bF@*XBO z*P=5N<$-W~)WKJgA3S4Fe*PO98CaNg_e(d-TyXLbiwrU{26w47ghdz7IeP{A$^h@~ ztSuBvPc>f=ug$`l6a|Za&wX=gE&;5WeRjG|yIMN$KXZLo>#KLX8n_<8A6z{7cf zKMJd|P~Hz^97k?XKj>SNx@elc@>=2DutE7p>|*tdOwC47b1qf`W5LVEp$sVg)7^1b zn5$q3=QYhUb&csgytFfgV?CyqrL66{RX(7~&U)voO8hMWuml2c)EHZT zGeF&#Ia8oN^m-6;x*@Bui?h|W15`CnNKAO2*z~DAq?G)2k5IMEUB+VVwN_O5+~UuDEpIc=siO~dN&LW13O5@vBr>LP6PmP~ z`yfQ0L4lnZBGjm?Y+u*`nRm%tnvB~eZ+P<-_PKWUCXZ(V8ACD_maGX}Y|uYrpT(@{2U?lWSE5A3=L9 z11pCGkk#m=Mi!M`Tf#zgxxw#P*c7$C&?_IFudTd1mq+|-i(8Be-Y}#x;m60*4Qgd( zDWDA!m_Gaw_u<5DaEq&EH?R=#Q99)!XIU05>t!zN@>lcO(el^2QPHX|PP{#{_%0w- z*j3m`Q|^bl93;o|0lw@~{!Z*?cvX$rSv(yj8JM>_&&k1eN9_%h*(Ec-mqAY7wzr4e zE=E(ot1m*0Gz5T-&+}fih;y}Au=sL}IKyE(I+y5RrV_BLd5CBpyjOYZ`=R2^gUh|A zpuO|9N5Kjixpa~ffY}9U)6`7amsr$}e37oH9V5m|fa`>GI6F2Ua3y6Qj~TE4y2NI6%FKCu}3Df_32t3|o# z`5gb=owVae4u{A4G!~0IJjc|?kv_%w+WbXvONNUPD;$9iX20SE`J@UsIy+gd-H4KLN zrJux+M4?t0R@e;^{bXbT9&M9~k0w;qKz; z4-rN4&hZC{l|XTr8caD2W@7@uTeZds#$1K0m@0I5Tp3q}5v#!gUASjz>k?E-Ro;~` zf@3CK{Hv7%iIcy zU#IZZ=jtMgf&{Pn1!T$oG0aSV8C+n9v<1-wRX7Fcxb{!yf7{zH+5!)mp;yKbQt+v)fT1)w?#l0{OrVolUcT@u>1>NQyv z)jmh5d=T3&ssCe_2KxAbR!$u9_yS*;>9Tn6IcUQL+gjY2QA_2ZY!_#~5=*Z$O;SHc zr-Odf-0{Kd8~$RbYu%q!XE)!*P(fXWBq(GC(^#f9&@4vWGtB&=H1E&T%4>;5qf2@; z@{;4@KiB_5`#zAsx-g0iI7h%872JaZf$i=WW92Si`v*>v8;fG(yPs$BpU2{YQ4w1o z`7Hz&=N+GQ`*`6cVSoE~r>Dxl!SKqT<`>U_VKy;yx~Zbj>E2G5c+*M0x&rMX%Xaa; zu^jV8)JWO&w7w1fTleYdjI-%`$%*bZ&wVUJr{ttL+h!=zA=(kCJRfZN*Wj^rY;&PO zcCWPWw$5cPc05yTF8E_MxI{BEcz$Bv>uA6(P$F2VLMg{1ML$Njhvly6lQMk;8r%Na@Pa zsAUjf^PQ)-eaf;Nisl6(^{4~Oc}6E67H?GfWB zWeH|~%|F@2rE$v)M}$7&z#N9MKm#`eV0VF6zk*5qhAVTAuy)rTKwtkU?o3%;v(8y! zudv15R#i7wj9Q-QHW#39uaJkQj__WC57^2$Wtju=w(z7Dr7_Hw3Tt1MLA>6ECLIct zku09e{L^G|*8ldke>7=6pBy|5IL*B+MnJ*^k+ugEAsgyy5|6XCU2<fRergaC-Lya>u+;q9SEFEJLN89OD9b8IARRqT?1uK$kxA2z=k5H4jS&;YKDJFL>n_2s$A}~QNB4FN0>Wl=YL|}Wy&pIVp z!8Wk|Y2rPChrlO=&V#J;d30)fo@L>4NHp^6iSI|9Cql)4&WGwM% zq17#60?-dPc+I$wW{No4?RD8FykI5rpaDP%#i{c1Zr-U-;K&NhXpJ&I^JuCrr;!p|+e%_%;38@jR6-D+C^Qu~`WBxU5_Z}DzH^rf-P`=?1-uX`fG}Ri z{>UPAQd1O2J8Ci#3l3C`{q9XyIQMQO^h)zEYH9Jr>6ETx)vZmT5B3GjI4yWcE?(pu z4TKB8{qW+zJ0#q+uL!DcH~Z!J6`>zMh=#~isG z{Mr)077W-84Z!xhZZR?V#pPg%!}q^*L%$L4%~8tZCPcN~)+fEz^q!#5L{iQ+cM4n^ z13t1vBF7m!#zu;O+af{=?M*&6$kn=8G#~94l--V~|LcoLUCZ$Dy~oy9gx=g$*QOVP z%yDgt6cpVF-v*`}_u)G*<_w4Z2I_OBZiwWZb2SAz&H7uHoi9Z>RLP~FFaBj%D}C;G zPe{sdygc_1FCS2^K{~bV23F>CIai9lB90DXyWDndm0M0OcmKky+p##Q>t6)4$I}cj zNeU7-psjSricPNpzMuo7V#EAf;QlaOI5D)u-Hp<@*{$%AR{tc=>>|h^{7a82YAPBD z_VGtx#OU|%aVm|F-lC4yq?_EK6YlZ%4u>r*hK3T|gP%|(zV;V|*rw`O)Jh+0yDfGC z0W(0j43PkSb`pg4`tN`YQy;MFWAtK*rshnf(e16D7vzK4&9$t=mdcZRrKY+Bryg&* zasV3^G|(L*DS_>yZn6jk4u>I6*br)0^JfEZW=3j3+gIUdsZx{vX!-%omUOiE`^Vb> zF1vvchZ6;bu$v%QTiyCff)Ou**3wus{&7uuygfW>8VsWyA2-Sx?7?eR?tc2%j=yqD z@-fbrl)6!mlnVFvP+(_6GAx%iz8sY06I0@_DM&esSQT{Ryobfz_Ve+t#EEzQsHT55 z-5>q{aTh@7ixyphEJZ?-j0`0-V?&n4Y{=4_*#9a^$NsA<{asNFnnv;?sqwI_8A~{( zSlc=(<#)N$g^{Z)(}d0%8L@>6^|3jWK;KsJRPiaCmpYxvD`1a>@6pIi>ThdhJiyc|8s~G4^C?Kt7S&eTz=S!y zs3TOUi?5c`*>GW9Bw68n%{x6WF;cGooA?Jy*}He@elq#kj1BrtO(IF+{85wL>>LP1 zE9M>*`9}tuyT(i&Ub^y+40crBr*vXVw(dj6q%dw556g@*hc>4LA z>_Bbni!exx#6$MnoyMt$hc8?zqr1GTJE{MVGTn40H0)Y%In@3V?asD_v>Buc20LN! zcPVcZr`@c>Qi7E>WjTNW)Ng8e(502S+1hj z!Bn>RX^{tpt=h-Vo;LlII0~3e8y>~+ZeagkU^%%!purvXzChz`-Dl~sxmEW|6-Hk@ zKT4M$jURX{f2lpvSIa|UOwB3^%mUUH8LuGwHh@~K!ue5wuXJz9TBq_`a??>ZS}P7v z5udC%jc1>){A#7doBE=g`m>;`3_{Y7tr?UxHUaoUmZUg3RzxJ$7tEmeN$^8-bm-pQ;Ly9r5_;=%sMb<1z1|3@Xf%h~myV9Ot1Z zd-ErUed-$TJMOxqedDsxsRUPH7frbguw|OSivnJU5Q3N0gkou)V3F<_i$~jAs*oQ! z5gYQhYBZc!#}><5Yxg2nBMOwPVVnJ$?ddCbz!Un^!NIl^N%3LHFcmo*|*rbVusYJS^!TMXO_M1VoYjNj=g%qm=KT}diXW5L=8GII_0 zq6=WvqoLXjgDd*aGOarAd7mE$)_nWxis!lf4_#KrnZ2MX?GF=4o4pGn-V-2)8?S)m zw^gd|Wi~FzU+XMyS3NDZCGc1Ze;2=eLz}X@%Q459b@$-j)I{~Y;C@9uKD27EImk`_ zC2HD09^n%PB4m^g-vS%{YP56}*(Ca*Jxxb#Tsw{T6f27MVQWHKw3Sph#Jxq3vv~r9 zY2jGo6(CFjJ>ef=S`UP&&!^AVHyWH|1?k9YQ((*i68$z54I;zl0D1(MgcRs%q>QGM z#Xnr?*4Sf1A5cb>kNj~$J+IweZTG*Q5&E@@VXVC|)_%!0=GBq{4b&&NH(1Vzw54c! zCO;R&zEkS#k2S(3NC4n8OTlVkDe$U_+Wi@(Yse^oow$5WiIEQTiWXj#dfiYMO-;ZjT4L|n*qisa-vP#`~(Z0&}8Uk zneAJde13}gZ*eL>fq)=T$w_b;1f(zez@!h@kWwkgY2;!j=MtLK*0As+y<9B)x;e*Y zXf@p|=2XhQ{EfwIPe#bC$hMQb)-BUvts$sA`i;#6GcBa1=Ofr2ud6~oR_+Uv1er5AxT-75-^4=RRtSYW?w;h z;O_N{eH|g<>?evjd-nL`E|GaNN*dt?H>diD-H5S-WPHgTcc%M=So=+W`! z(Q>bh%azuFo0bj{9u@DpD0QYcKRz>YXGUSvfDl@TE&n+RaSyK0bo4b4E<|_pQZOFK z27B2j_PKPg|J=(eu4_J}k(03>fyuJTkfX{K1i}3Aou^*hOa??xfB0O7k01HP16#2-L1FCkL@7TAt4d=uz~Oy&9jqHw!!O!?)`;G(&~ z7e}&xP8VL4d<*;9(bRZFbvya@SL7#=Ek|0#3(D%%1p83`&EAX)^-XE6uGJdblNfr2 z71yo{$_jFf{}vGM<|yGlyD)S361pU42_wepWq=w1W_Ncre`EtH3BJXxCM_RH%uIAN zC+MSjD3)SLyV>Z|oQ@l{=OUvZ3v4m2?E$3sx4?;nWbnRmaC}oFINB;iQbqZnTaLEy zfa3RqO9rq_vc+ehy3V(A>`tQ@_^pp0nwklih4uqI_f+vu1O(8+Bye^4ZXAn4k``N} z`JbpVH7K#bI`*7Fa+4h{78PjnM2yKcN!F?0kXxNJzG=V?>}JUE^|>fs0*-!%7l)NX zgV@bFF0SILa(D9bBWL3HdhB0!I;8ur@@CfR1W;OaUUnABOwxooTZoBY1P5@IHYgX) znRYN^|7yqWFyE*KB#O;Xaw1i%=q6 zJE6&-Xnw5$f3Hk8a%HxQ5s);m1yHsBNeEx?tH0Com* zmLUy)-w3V@%trjaQDa5D-#ndj#H^{nQ2E1}T37c;8(#BZz7afH=}G1s9E zCtKoAqWSoTl-Z6PQJu<~)R)~?bJc@Yjf%c0y74l=0j1R-PLy^u^iiAHUX8YyySm^C zn|*{EHscQS(n;P(Ny1_s7&L%phsGEtxwFpf=EIx6+tk}w9aUF6$L${PQLC;wpe7L@ z#6}z&G(w66)V8QHzm_?h$RE@-VKa+u8R^1u7i|Eue1|*kBccMp_a2}8Tc9XcM?;d* z$WVBHB*&Up#oaR)`0<26YLlsI-7R;CzNjG6%M=+ZFDUwB%AZNP!qQEq6W9wbeWc1q z<~ze=+~=v=X|>f67lxmx?t+0ME>VDtfC6kxg+@J=n!)7Gb^TZ-H+` zQ=atO@Gy+Q-vS!_;B)Eu_HTh7n_5JNfaM-^2AZdflOkvUKRsFTFaNMF@25mByXP%~ zGqjJ;-1OgH)}+avjS@XfMMM0 zm#?rB1(FZgT3_q1m&^l>j_d} zLBZp@2jEQ?DwiXW^4Jb)wRVy&&JQKVJ;r-zfq=L3ZuN`29r?YlwQ;aQzf7(C3*zeR zn*Ow4;Lg3=RRSS0W76Ff@+j_{HkgFB{e&du#%8fg z2@YTsST^x|C6NEA!KYaq*SHj@yt_edWKrPaeMO@eeYX$)I4o2`bLoLq&ECUUm0_m< z>8Pkh;N^`ZU2Uqn5jC;N=+#uBumj19z*^W%BA!`3ynAW+jw1@5scOa$(rYQi6y;rHnN`5qf%1V zo8I(16EGJ5@An2|)p9ehf#`6u+ZijvdxSC6(E@h)ayzee-6*ppXf4N zi#tGQG%D9`KRL7n3N*Fujt%WjP#p0(e|ThnvHER+Ef~>_XK3dtIM&2+953_NP7i&7 z;O!wdolsXfgfN*(nak30i5C?KgKz#DUU%<{l>h7Bb!0l!m6)?Bzu7|=M=w+{g(NQi z$!@A*A=v~5~G9YT(qb3>0m?3kou|rr<7OeeA+LEb@NqTW$ z8g@PMfY+ZpWNU?aY?q^%-;l zC358@ai5^jX7J{Q+tTpS?)EiHo zmzw_v(hHtAaH96&Dy!jmAhWxZa-%RNjhOtXr{y^R>#Iq98U7YU0_GnI?xvKz|Ia@q zzsE4v)(yDwj8^Avz9+_|sNXVmx-W5+Fqc5e1-+j<8NOI0^WkI>Wp!(XWuwtcHQbpC z8+{mpe~_e3X=c>zu>PC z=Rmx=W&sJ=G}-e?qhzJ*!xiBZc`2of*1I#e7j0vF3%dmlUhtY1;A9Svy+gv|v+cKv zox84KyY(fGmV!Ia3BYi2XOU71SXVWcem^UBI^#ofbYGlNDSLWr>ky0$s^>vT5u z-MeCY?@v89-0>}Bz`2ZVMb?tiDlFA7_6_ftvJ{8(spg{2g935^dmiC3eJ2<+SW6r7;L03RNvNCM?yT3|ycfC&yg+2OXOGpo75GTF=P zP(SLK_3-M!?ZJC`zPFJu<^FJcRN&d)t*e%SuC8?VgQ(SYF@2l`1ZtFpH;oYzM zbPlDPpW6nylF$het^MR9t(Hr4R6M-KW~rHJ(1{br9>%!ityrYHv^<96=gE`9yPDoM zB$xy&msLn>MQk4bvnTE6tI`NhSB@kYUK0~LGVV|$7ZX9Vf>VZ#S<8J~r8oZguy*Cx z@5Q&4XR12fmk$0d&};j6Wuv!O;AUMbay$_XK&zwgx9sJfXLgt^S27E_yOj$Q%3lUH zqz_%5bF@BJ@iIu`nqQjm9`rinyQeky(4=n=5CBAjKnh(Tq~R*#SC>n+w+L604MH?W z!%WZ#UspU$(mX`IsQIl+~{} z6a%7IPUCO|txlKi^0smLoT{8JBd#8C(gha;pNM0JKm!~l=vOOTMmLHe!F6IH$Hf5$ zv()2k==Yd$4F~J@Ju~(~33{q==7^8u8l_k=uG(e^@q+6IAvm7cPe_GbESDs%L$RTT z`I%gbt#AU z3@+-1ErszXH`x`;Q^$68b_LC;^1 zjnv@h>lI9xHK)O#%*5LCQ={Og2f*n2lVs|dN(at5CaDWvTaW|XdD^2WgRAw-O~KXf z>E{`}WV&+dsj;75M1E;L*x3=vl{nB|9svhijC&-&tgd4ybim`y2%Wu85DAii>pRZ1 z($DllhY*yFr8;r5)?J5HcVzZ#wL0u96z6Oa0jBBTq6My|KkyF8JK$1UHjb5aX5Jj- z+Q?<6duf8;MR8TrdK5m}>phNoCh0l;VUgx$pJ>UY@NyB{gfcy)sue%O_zjg~}sXigCR*yr@17C`LJ{>*jE$ z`qmT5L$P9r>Jg*K&lCcn`2BDp3vD_sjqJAkoQdxk zy4()VT=OpHz#zdCKDj4(XT9xXp{tOfZX+oL*cO%II`s$<@+n(1@GmwfG!0xsu zxCXbV)sL=Dx{JdQy0ztpWiHQ+y@2lop$B)3H*p5LRaXTlykhuO1h5r6g;0Pg0uv*E zBeW>@cnuU^7!ZvN8_|ApelYCYeOj-~?li3P-UIF5G9@nj>b}UzU|-}FVE1f1Or={k z@rQ0Gw>)9#w5@A(e#w3qw1x^UwvpzqoF7gl^{Gf@JN`P=Q9^$Q5;?)_YrGd0;UaB_ zNd#y^?h{GIxR#(vHZ{Ypkx#_z?a99H0y^hUDoWc+j9rihMXlElcLLEtY6XFp+PcM? zbX*c;w#&ZMKn}faXl^-V_h8K=a2K@PH~dcd#5z@V^Zfn8=2~Z@76r$^WTXn!Mom;k zB*4KAW7Dh~sfuNp8)RWhH+ zHu{qTGg9J?v5a45_#Yg4a$;CXKcoXBT*VK~bg13M)L;3hFxYd;M)z+mkH8gU@(0)f z&<9q)oTnn0KvXf12+C33lOG*eB9}kpZeFjQoEz4ENa*Ql(a8Z>L47=DGa5OKUy5es z(D92u@+#_Reewv&%kzAd;ngEU?wpt<(}8UM5c-QkJ)&vH!zyhd5joQ?>bL>T1%M;` zr~SL|r6Y9tu@fdA6%nQ@4U5H80HplqqhiHG{=~@ zZqUX{cY?A}(sQ>8ir!3&&zW6+mHj4}omwgumC+NEctVlI`E)Jfm;yYA0DNOEykg7E zkRPLcg$~<>Ir$mmUlXDVu&}o9vqXsYThdM7U8b1y#_eB%ME;EyYDOJ{yQGIV>enqH{&uiq1clY<@XnBWh&O&qA<)-0P zMT>zn_=Nj$GA5!73`c{IBHAqHa^EPm?7|y4>go^8(_j2Zq8hqc;%=RF)9m?!hMmOr z@^|pSb~_M$rvb5;$~nt*%sBDCID6A@DBSn|n-oe+2t`bxRAM4a3#L*eNfEM6g&2}# z8;qGEdkCS3scgwIVTP<@mt^0^HZv$|syva9E5w+wQ0mQUVs=jDwC$H}(}#!r8zob2=KMUhqyxC4{Yo)077 zn-UL~a~n301A&P)!vTt+-%N(_`x|QQgUpdwRi;)_2z>FSYvsA-7TO~VGe zR(rH3KgCvdkNoNt?y?+&{c;xWxA|yYLUwk1srr$agWwybtrcFK6agCG0rnlHRhpD!$dubJGo}ibi95C9*^JHcXs*Xm$4Z(gRbW+%qi*QScN> zo{(dGVyE1uti{V|FowH_5cW+mCKa{Wm-Mg8C0(pRP1<&92UWIn%_01K5J4|Iy$$0{2V+JTlhjp{3jw9RD6g_eD(3B9;bvm?UOxK;}2$1q1kKCL_o zp*3bYf<>63Ubr3H5DpA8#_;NyPdw8`P8@x{?p5PqIZiL5FSykc?H<0pv48Jt&Zp_8 z#lj6Stgmb#X3advEVqPUCgwz&^fd7_b45!_Le<^Dd&d$!jUN@yc>AFp&nY(9`B12$ z^6al)U>h-XyO9BZ8c`+p^e3Qjx%&ahd)X45>+{!#pcjUHh>F@Qv5-9ma*`J+_oxX( zWt^zKa0j9z*akd`l|^m7kKqzramF{+o5pb%ckjHo-T*4B9Y?OY-mVy1GB0@3mT%Xcfb>eL*V%}Brt-LOY>^!&c5r~iU4)Zj1pBEU@) z!Hb7`0L>*0)?yh4uMDa$@ti$8QZ)9O0DT%+$akd$-)&a>5x# zw**R@QIZ4+nG9MXc0eM1-M|jdF8yu?5iidyGWH4g6@P1x)*@xPU^w3%l%G^|lI-{D zkqCcuuIjJPbDVXGc{LHRuRmblhP`109U(<7UN!pC$Z>1LxgE2Uze_KCIC*FA(n&*w zl=#hT=p>Bt<+Ml~$qih-+XF+;H?nM2>ulc~Dh|>C-#Ld4Y3&}V6RVCd7zRtHBR61* z1`4bdwhS{EL}jHy=-w1;qUAewOxwn!<5VYEBkIZWgYf|stYS1Pi_L?u2BYK4X5! zl6(S4LbFK7l79puXW_hT-9+y;{_&6F_XAiTn@F{(8y0mDTh`n|q?;BMTI^i3B^C|E z{X^%PlR;#I9IrkQFU38;P7Hjc~NJUu&Xm2~DI%_601(Xc=BxoL`- z$fED9?SI8FlgX_6VCb|Dwbp`_TK&ttHyCyk@@tm0qvakP1AN$4vv(7Fo#Jji=*W9u zWW8Q3`fU!Q#0TRG5kiP2)~$c)ATgor4!_g-%?jkbvnGzFaP7(JVT4<7O7btjZL<0Y zQ4o3!!xZRA-8p-|!wG#c%(vdjlI)9R^X4G|XT%hG97)w@Q;~mSqjfVs+ly*nxH?7_ zrF?CQ7{ti&hY;2HR=Nj8pDxDqau(~%-4mzQG$avIc(9|s^Mvr5BB#=G|DjPAn-8In z(DfWiOwX(kFSlts`{>I2;$QA<>xg9{vwEBU!@Xbra<2&$^O?Qn$fw_CWS+li8)?F$ z6(_*gLEEwO7(;W8V@>i%mxIT>9fY&rO@k3NOsbn#aM$&L`(X+9gq)Sn+?h})TWuzj zj=*zwFveGNfb%7FsqTJb(R3HJx^Cd-RK12*yT#E43!On}R!57rNtZ@Ww-bJ~hYBb6 zvozQpOd+bpW=Ba0JX(Wxy$~N;08XBG&WcHslih5@nfUg)$O~gb)58DZUR+A&p1?eiN|g-13nhoO zk+yT)87Hj9(OUBb%$%m=V>O$bQs3n@=F-*8eGIHl?Z5A|?*YKjZ@N+Qc%a6p=OvJQ zk^KE=33h^Cspp@rCs*;b!=;2Ukub+oy2AEq!=+E|?i1nt{FG4JdHGdRF#H}KybV)F z8m=>NtS`XTe7uc@m+@{oP!ZqLJ@k{~XlN>Vd1<)x`qq#^W7WGC58kBKT@&8y!cE4o z0)e;oF#0_EI4X;cy*D}Y3TiIr5*i4xPuLrKn%85O|R}TdmVQ<B z8?mpy(=mz(dprs-YjP~6xisIlV18S{1-u^K^oM0%<4ss23v*Y&xTTgcHg~rTo>|W z_F%?Wv2c@dtGXxb`+gxhX5ybOG%FlAzNP1B=d`|vE|Ho%0dJiXh9kk6gWXNr&y{*( z1O|T@o+9EUmdWX@)8^ZHU%dRKa6|>&qZ86|!AweR=678`xDA&hS;R{4qwtgd^Ohaw z-mYIF^0sK3LX1E_p(1I^s(?7A0X_s1Bi6K8AaNjA=VoBJjNZ z8K)6vYFZaZ2~%ep!+$0ybPeDCTKz@L4{&I@+wR|9-R&LzpX%gvgX2R>Q<@%VOug^LYdF)=Q*6*9I+weWg`-;C-@-;AhIO5!DCdUs+ zk~0$Enq(tt#z7)j$x6nUyh-k5hrN$-zg;Cr{uV#*7kS?ayIeZ8@`iH{1BA-@Nj?~9 zkmp)O>hwgL(;7`X$cBY4dh#di$+PtuZ6+|QJ<-1pkUvLUL)RE2X`NN9=}4aR2O{f8 zjtWW4`j`N-DE=laZb?m(nB3l`($u*{Ic0#A@ zSm(eD5h2NSttT)|ANgqJu2`lS1K6-Q$~xJf?R_l8Mdg`RVdwLQb5#Q=+nKutG4Ut4BHbXFvNFNAK^23U<&@ z){+rbxb_&P?syzw#?pFJ<6c0{Dc96N*JQe!tzHlG*{0?bt@+JIfxQS`HOT{?G$+@j z#1;YRy?dGOHL&gd_~neyFwkn7uh}R?WU_$uUN#E&)XBb=XVP(&7S6E7zv^B zC?f6sljE#+m81LFG1N7&?=_5ka@o}KpAo(4)CPyB)K807_nymuH7Z~$&%MLC<0c)c zfaitTP|6xTFud%0DC8-@$FSiP&HueqoA(JPa%Y!0DbdMvcTZ}C-j>S^;or08aRBQQ zp*3==ar24hG__8#Ui}Uiu)goqFY&`mSw6WX1+(Wo)D6rHt{;ooJ0c@>U{cj%oydW) zO<6^}d?Vpy5IqS3YfTKr?6cc~q^6K%ua_$wzRM%4pSA=RO&d5)(*6=?#mWAwo27DSa&8XkRioKzDCi%eyg*nlxc+x5C6tOUVMLH64{i-P(WdL{A_B2eUUhdP@y<)+z*YTBGtF)v*h20ht$sCb)v=&UC-)fG z>PG?@)ENAO8vQX-?kdBseX5Y{w}`Y_31%#f>1!`Ty`K`S4py~)&d^FVK6WeQ){mCG z%_4Rn%>c?40ZVL?TOjd>ifYokWxn#5589-2{Re+>F@?an>2})v$JdS9+q%sJ+TOJ6 zlW^o%^LwC`n?Mx|>)H8X1!(DCQhl)Im81`iqnc{osv5Lk3i@VVVm*D zei>_Uhrc9wTSnljMOyoTA;gpY3T;!$E}wI0tgo&b`ngp0!{>Ho)DKOc{g?QCo2l(* z?QU;u>$1+O=RDwUVfQmR6xm3yy6p&iOgC9_!b?v!<08RPOlqC@Il02id^flY>Yn@W zd$fB0Y}Yl2^C)0qSj6dMP}~$TU!X*S{CoDi1%sa#=xUHvHaSe>c!!1T)uh`@ze^Vt z_B2`tGT&3>P}XH$244{^$;MKW1u!Eubzk35*7hRDNQ`9mGq23+=eAaL!fE#J-haHH zb~4&(%g5i2uRK1o(;3}28-$_5_lZzs-q3dxa2T5))vK{TIgT~i4ubcn)ys8s^shfc>+|${8 z?`x`Zr)RXmr|u2OXv(FpU{xDPdVAUc<>+{U#1@qfrP}vsMFR6jZ6RX0F6d35VrRs& z%a48E-h8o_;xqZtIs?&gl2&Ia#c#$4SMsVF%t5g^m-~-^{qSwZSazwGyhT&VN%>!d zA5&z7baYwkyBSHfofunI7cX81N1kVSjdO1^#5!?u_jTrCYMM@s5pvYpgF~<4(3RiC zlvOkSJWp%yJe0lveEV-V@fhI}N025{O1edwvhEm%i(^!so!Ig|%6%K{(&VMF6W#f3 z{wE|gh;L$F6HR+Ar98T!*rpOMuuSrVO%wr_aUMW-(8k~#_O7c=q~%@s~|T&(Z8DLFRHqT_ARb@!N~QjTfCQ;)0j@a`XJicqa5Wy%Z!8te8lUl^xA%< z`JDdly>!5F1+E*LA+poqh(HTPUpbp|15gFgqiv3C2W-N29BuTC8)#WtG zW7V6Z1u}JT{M~GIV_uQ2^Ifa}s&7<<@#AA%&VreHu=)pio9~@dk~>5^Jd9nW${e$-3YcS zq6NqT5zOfgQ)+i<}j}kNrpeqRzxo0c(ON zHfjD2BFBU+-SI$U>}4rRp)Dg=OW!2kbHPNZOC)k)15qXO8_H1OTgx!N@jD=5Ky?N? zt0)I92eOqf$j3)ByV`J1rFFsJRYIQ?u;bfiR!%9`bAA8!E7Vk#r*xI9_2dMch%WvK z?t^4KvnOO$lW7_Ivn;q>8rQHnp2?^`gstB}(^V9nJw4ustuc-M1tpvFcl0tcDVr@k zAdi~ywAHW4;uCjjIZyQm-j%V`y zu+B==XMOn;P#_sA%_?I>?9 z?%K=y#B1O}-lN)B_ea2x`dp5GOVv4=kH&b0^m5`iz3D&=$csEh^J^lKyegnA7GZ03 zRup++j&sYQHXr}iGWXC_^IxW@D2##<3wL#=Rq^29L6+-(B$=~)qGa=Ww3@P(nW zfFbv~#`FVm*ziNb-}Xy|33eL@B3{lhtp66^`?yvs^nPA8W%MUJ?oX>xK>?D#kCZVs z*865#wsm8I#=dJ^5hot?VJ_}_h29H_z%(y|yL_sa4q#@I?BUPv)uV?YjkeTV4J#75K-VZw@`?96%WdCF;4Rb>tq2Huup- zQix?KQ+~m#H!tMyZzFQBa&Srva6K9zeZUSe1uGI0))B6o>ufUNq^R9?gNSh_5^IQ) zGOr@jcBeef;Qa2^{o^dR%HjApwtqOsq^9f=c;BQr^hh8;KonIBr=H`3SpJ_bK=-ko zt`79510wSfx-O7Y0TLy`qxq6v@T&1R12ZaaS1+y2`{=A!u&;l?_v2^3jBN(39l8;% z;8=L=hxI3&IkGX!f%l?G8`G_Hl8t3nnT_e-;$}r;?c_pj#_+*Mw{M$1qLg)0OP_uN!owLrpQJ!&G9Ni<+Z~VS``n z*SdRJ*85dWd&6*C8GY74Ua`@MB_naRZxI(6hKp@d8I>A7pQR|9 z={P%?V>pLC%TU5IA=FMB4I0(7Wyr^^;Ug2QH#4sdG@~Y(-|e}waXAmZMen0V>e=-c zd?o3YWej4whAwADWZo#-FOWIjmXaUZ+ZB6AzecYV+{PrBbuyx>~W)=9yuLF?Ez_9Pzqs=oFw@}r+Rg22HJ4%YJp0Fxsk4a}K#9e*#^ZZBcD7q~f;m#}EpEAm(7KPA`#p`4ZQLy7W5v?u=$%(6Eh3h+ux= zt9KNS{dP;4$v{G`j05A&)f=POpI+lRsAMWDoukhmL{zPN-ZCx1y3e7szn;}lBZ9m#1g%%q5fmX?2YBn)F9rk%| z&RrXUq)8%BEl4ay=9fDr^!q;o%x8$2z}zRKCdOJz{edvQ8P)MX)%K%d(!TfgBS-CH zX^)Ib*&>WgGqxPVA9Npo-rMuj@gy}Ex;}JA-{Qb#h?v%&as2g*0=xfz{`voq$jgAU z-QZ7wO$i>((d9af1x%rSTd1|a7+V!p+-2~O!1AuwKjSa{tIY*rw{mM>;}>odq0l6& z7Jtu`^9LVs|3dlM?{kwiPg4*7@Ov=Z+Nc1Q^^J01T;q|nwhDHZp@{w6N#0Am>7n#s z5+^?Mj+Q#)k6WMN%1Yfvax6mBNEUr_7-0r7bymdhi#QkDrZbkSlghJmMRv^)&Q_$6kZTA>3pL*k7he#0Xg@j4tGO(~Z`sUs6Eb@3v3rhf4pP`j zq8Nk>%Ksd@sL*umo9RnJqWLZUp&DFogdMN|o!Ir~n#hv44DgeKD!HA#B~S*O%Z`Fk zBL%ObNFQ2>e&ti>AFlPm+!MnmBEr>Id1CGIka(Ss#QvRgj^Fj{gaYhjD@zAY{<1rN zBl*p1@lc@T-tqtP2mW$xN}mVei_tkojsYC!{BfxBGeRKm`1r;}4yv7jZD}D@wp?Gg zq|z@=fXYx+_m99)ex~PNBbm@Y=`C+F;s>dkZO7fYqw@S#@y>4L)FOj; z-X^c$kRx`oziZ>8s#^3f+xe2spFbvrVPU1O;lHOG|@~MzxgoN0Jml22t|F8f$jEX&3rFLo*wH zbA_xMotcmDQrd4VURDvr(JkOD6OQ&Z|MshTJ@fR$-DMjLvrS zsSM7|y2!SStj#I8D<5-bwvD!Hi=7>qeE)21j~)5p4Z*Bw@NkSL^U2rI3L~K10*@d` z5DfKA#ukRk(Z&BfW>?>XCF$X4Nj!6?DcXOueRQ|i;NfelQ#c1ipd)>Wlo{; z@|%RX`h#eFTBF40^~1y)%%ce}BwcR@7Jj!a{3Pe(W?=cb8sy-(AUJBk4E6?oZw{PS z6ShbgBjIvnJ4USfNohar`t9P0={K&zd3VLLKg1;;{{E#@yKLDdg=5SIM(Cjcx(BP2 zm&i4wg~bu+nyz>xVp3W&yWE~|Y}@D4vNwOwte-y@Y7j5W)mj9310*j*1P&YxH*5@O zmkQlP;V-c>DKqd@R#r}R!m;A7Dq5KqBQgr#9{)M5|K-UKCwYOdz>NhKX4Pdn1I?K% zuz!f@KzE~J9GFI>oBH~HXb$#XYwO3DQ_`L*s)OPM%@dQq)BSEjAx-*Vk5GjOeZ`N# znTI^qp}U?NGdSW?uw*BfyI;z*aI$gZh0iasd1OSP@j`3gt4BgLmzO{bD0xZ@Y@Iy? z?9gD<%4w8ohrE9B0cIn=a_o;S?pRHo?$qk~eV;`I=LbE{{30Ye`*r%Gpf#CMfut!r z1Y3jS&33dO!Rx}dbi8#qHKZzns7d<0Af0e`e}0p_(w*`L-15UhLaeO6`=uuE^Zjl8 zPeb)vS45kX`teR)FlvG#%B76B@C;}4wcqFMi(Bqz788vn#Ey=eg0dza12)x~Hf#8U zjme4(&bgsd-7se(=Ky4`s(Fu3Xov59l%D`05i_>$XqV=qimK7sj)y?bhP`ib288>7 zn>vy@-l3@9;gH-W2HACmEL-s&>8~-9|FGGW-&d!tSozjXv_K;@Uww;LKPdO6%h;-K zExvnZ(c2mQ@s8A(_=CjSF+y1HQPhFKLb-t}n`06Ww_5oa-P^aNU7Io>G6I-tjgI8_ zp$~mvQyHezq(o}JJlpmz+n+U^+v9F1j*?q7W<~XnXbX@LB}w+GmN!VtHpd&;WwicO!K{mXvcKcInYs1uqr;dkFk7J~P;v2d zyRokQWEeF!idGiZ9@_qHJS+NR#+XClr}Kt&pYBbn)=E-y9uzdKM>>r~g8$DjP*V6h z!oU_(hD=fs)xx}0y=V!GWC~&z5VKi$DX?tk7q8jXGz1r(QNe zFq3@6G2-oT$|)Uj?e9Ly=hR|-NCc&8>kid=Uv|--Z81K1@a*fIaPprO))X(z=qQMW zVp8EzSph~u^~|X1;xKCB8H8N(+>3%kUt4Sk4N{a-H;(?Wl6zR}>O4muo2!O)SU#%j zr$>RAj1qK6&T5FpAOHA)dDLmjJM=-iXp-l)th-c&EvK~0V~(O|4Qs$M{icxLgOCP2 zDd`TfM?Bt063N#lGzEv6Tr;JWc9p9iUp9@O&@3uUuDsN$n|(%cUu8|#yx*{MxHi0(NJU;HQd&{J-PW)3P1z55y`ySZphx{OO!l1GXV(u03JrbW zmx<)Xa^+x8egemaCr-LyyT;mNpask<^{cby@AASFy5 z`xfp4jhZ8PbXZQBg2|8nTU60arXfA2!R}A=$7hpsszG5=L-xJdrW*6c8``TD^Xc8a z{+rO<*n4YiHE`%_sh`mP41VWY^QMDLM|q+zEY@fsONQ9df5b0@WzpkV$*ssRS#J^e z;F6=iI?lO=-otyt4F;~BF8XZ>Zr3E61Qw-Fy}Wl!XEFId#|C>T8fC{_VP&?p}#OIH<_ZT)67p5Dz6Bj>Lo*%l{ z*Lt~I;i;Ryiv>uq8PD=v#nTYc7|D9ze}lJpLu2JliakO~kX0A`-h|wtC@2m|f19fH zTUdxrPKO`HpXU*>X*^$2~Tz1KG=#ogGtGJlAl!x~@7oe5a^DmXKRl z_sg>ydo}i@TN(EO~$jr|7Ov-m7F=O<12^4f+WUYWhP(8uMG#hJXAmEyYMl1eY$uX z6-^It7dz?^FAxd3=0Fbxe*`6tcVH*8Sy60kKD)?@X})BeLC(l4SGBcjQ_8X$>-@Sv z);14Og=&4?kM_&xy~XYVM&>sF&3U{kgYBiLH0tOR5=6Cf)cW!;wx)MrPhV^5B1xg?3|baArDe)YX*uC&qu!#M%R>#7UAK#Vt5{WE zDgAICed$HdfwlOaVUlkGBpO%U-?sJyLDWp4X?UECG#%6Fh1ipZRLzKvVfh!6#(v1P z5u8I3u22wHjnY7(aF*oY0*0znl z^7f24GUMO)jCSs6g!d@ci|5K}U(uub9=_M~!7!%^<}DBtkm;xpGFwhlpU)V?gaZu5C!Q zyw_Lyl(M;*zEu1rty>#4@hluzrIR*j1O>Tzn_zdXbnEQl+CeVzwbv1vC8WE+Ts(?A zJ^3l}2I0BvrJ}Pf`TOsspWf&dxX;}KcFCIZXGoPrPkus0fu`)Ir3_p8>Tq6VLuPx4 zN9oe$GjivFR~;-hi zq*#xS5;B12pdN-A@-bp}V%(!EH?kKov=7fHTF~ zW;I3w)x#3?%~KtDJO0=Qs|Z^uxZa8=-SX*`WUqiV4~K#Cr=XQ{^q2FvM_47UNC7*g z!OXh=32d0f-k+*_1Rfe$$Dx2&@q+4fE&f0>SXlaJR@=D!Tby38hQdP$tsCW}`}Mw{JyfmV3W+8WKq|h5 zT}!B&i*m(4;EeT^6wS4_O@!#f1kStslNl%$eM9i~_};y*w_|-d@F}~NS;=J9JCKt) zZt{V_C%#A8)v?kGQHe00Um0ejl#kVMKD#sqJLj}+iiqqK53{4o(0sx0t&zPQ3&vIb zbC3X-1S-Dm!pMQs1Q%7iAi}Pb^}|GUW48iUVq4Ecd3}LmnGIihI>!c--%5Oh%8&ts zx+ZJE@W0L!&JH_Rz)Calr7jOGyJ4$NNXhqIHG7(}sC0u)Yl;P*71)Hqwr5jSn`#@WpcjM)aeAas#Ukl$mL*PfztTnGl>H3K+`S*_ry;{vdkEp zZDP9>QSeT3Y7InkO1{^13AuY4sZ(MDfIiBcB5!@ z_afy($%mcqh^pSvd>a+(xp>&Pt{h#xuKVkjOkNff+fsq^GZPz01*ke1Jr{p7=@)K zd8SL0NAPZk_o(!XUv^Y{r~~KG+D)unTS;!w5iG~SXJUQU$fgz`FL@U`#u8YrNV{uV zoiY5@jcdb1aZQwT+eYD=t?N$YGg3x9hlZP!w$!LU@kY!(78CGM_uiRE`d-nid(SHt9JcMqncumE2=h*((15}afI;}L?X5_xUD}9w`H~A zdI3oJwRl`j7`^usc{jPoc`^KP!;F@GiRVbND7`L6&)=g6Djv(=&iQT&`((;2pT z`yY6+3bTw=IYtI7I!@Ld1}s|k|FGy-zm8xZTWsEgUc`~$&q{%9g`1D>=_X3wWE3=I zzO@XY3933cr_I$yi=XF`ciH3{-8i;9AV42hqiem#fSOq0+l7b$a~2(Z6iW+jgmb}N z_uYBZyY-h3-bMP`G}(t>y>n*_y5imK7I&xda|}G|2cr|u@m#@)V11IsR^-#iiYYe+ zR%Zw=ffJB9XMppREj?$3t~BUyqITMT;P2;?tFcucU5F=OndQqOHqaDM@2BCr55<*w zk==@eJ=4y*%KP-c@Y60l8*epv^nA6Yj^F^c)%K#a31mpLlMoeNX+p%HiU}X4UINBk~;Ry zVQ?*=m=a_1!lmWJ+(hm4{{`Ri5rj0!i?pS0Kd&6?swmRFv2r>pLbL2v)`hk!Oqpj_ z&_ANmHC^|v7YXF*RhyoL2=U^KVBBzC8Qj$Z#&TdnS``mD`?r2L@$wK8$_iY4m=Ncn zVSQD2$mD;3SFh=`&EF{HXx;|{4W=V4cr}c30j&dO9C&t`UAk(+NFbrQa&*Ue$+9tH z&+dbtl6S5=(b#-0U(Y$tABGBHPV+mV5Ux3+wX5T_e*4;%i+(bNWkt(UP6}u6gv;v_ zF86$An}1Iov-st-OWc;11;2*{eN;ji_cr??=L$-{JpN=4Vqy-k5d0z3g+b-}AL9F#pOmFdI#PDW>QUi=pV;R|;>2jPns>y{FuC%g^Uf+41 zoh{>dVcljV^QGOx4+`nQffMXt4r-~IR3phY=6ImO>_;;;no~XH-ABk*A}n`JWwV|c zWF#h5Z9U_*%2&+XvMG!Pxbdts!?J;pGNC-m=j=I$RhaQ6r=_#WDntrP5U`S-&j zRzTT-_JPIb$KBH+pZ&q4?=^qAjDz6Xu_a6R69_@B;A_w2Vx%8T9)qcbyxqK6sTeN`^HT2 z-1+19oHh}B6PQR45p8r|aJK1w9QmcDLunnzLWhpCNkpsP609w|<{^ zT&ob-wOepwZdHa^1m+-gEe_P4-^JHw!}Af|^1JP%K8<4z$OpFfvT9!j8tR0nnn;#T zPAqYrKRvE^gj5+rhj8wqj{rhBg87Ufn6{P4bvX3LYp#|J{UdOFY)Cs8?5*SzzX`nU2}CzQn58 zCc1I!!IXPq^!Q$tXQJ7xhdcsC0*z&U>+Fxj5{n{;9E6-#O`ZEl76w;zc~eri>~&(G zm~qN6#7T&P#0`dpz{5|YL|AOdV65Eeab!EW7o#GgFvouhId6fM9 zkKxbb`w^!Bh<^SLh{mE0HB7NOd3gc8Pv*qAflL_7kx>(0$S8XHvnP!PhxFuI$h=18 z!I?TA9$Yq6+y6Oo;W>I*Uu~!i?uCuUoB%nmIC3WI+z|J&fp4K_hHaIB{DuC)mFj`> z2?x{XP1>bIm5*S!7IfgN*5HVteR*#&2AKZ3qE!SFsC45>yn}-O0et5t#MRr6gi90$737MQoE#h6>i@BiWgI80 zy}ejxZmMpWil^r=IMf)rSw1`FCWBrMHa3JRRbdM*Wy%xe{N8qX2MSSiKMUBr*mue3 zo`-Hf281@>&E#mDqvFIpv()0<*qUhPg70R$qC(5vO-iY!oU=q+fAS3*oCZ?N)suYSz|TthJ+F_)faZ**ZkwC!W{0*H@Rw zpceM+I=TtcYT<-n`V{8~2o3~xbBm&-+@p*`IYp-KA+R{xe)}QV0pe3*zs2yx*d%ws z>K~p9#!s`_c;zIdhIBI&Vh|3NP@V@zP%|J|-cvpvmDaY7v}(H@RHOHB|ER{nZK-<) zjw3}C+^;rlI5tTF!Gko~oGl3~fQh^`5N9fv%soS$G3xO3A%qkR|MDy=n>QnH<`r%~ zt9+J(L1l0CYY|u{P51*frWVtZ+VvDjoe~kEKNZ7V((Fg?Yxd6mC0=t2&g6fI_i#%} zt-wzCUbY~U1G>B!*n7ze=xyu`ip7ccR8%U+Um?&tL-vzuIdNdI)h41 zA4a<#EU^SW^YmB?@(9LE1rlYSoPq3eJ33HR~UNb4^*!%xB-vk*A|= z72K|h7O*8jPyG}afS7P^vJZkG*9m(ZVmu({=+tTu*(v|~uF2LLh!)8MRR8wu8yR58 zwdb`2oHqWHbgzFx1Plut=Y1@x#1!^JI!$eua9DS(T3pGz#Pi~GtDmR5qLEh2kqVZS zUzBj2<r+?&Nb<5urSc;*7Jbz@^>Gdr{SEZ#bN*UyBUY!*X z0qI}xIFdJ(%%OmCXvu+d4F`beTLXUaFXbAk+NG3jmC*c2HyN2c5)NKiZCm&BkZ}mk}S_3yhNfCHp zXhXf?HAlp^^v8rA%6z+GYF^6(zEYY_Q_Z-~5Nn2#y60lP7fgTKh3CgVokY`$QE4m+ zz+9{s1YmBH9(bjVG$|tW>q;FYYThrW7R;Lld!-!84yg1yVLEtFW8;Y6V?%%VeF)k7 z3ZPC1IJ8ueXs*@VcJ#UM+ad43xYdcF7W2*G{Pz6Xs+3Bjp8eMUQs+}3^vGv}os{HZ zu(azu+;iK|O994CmP#>>hV{rNH_Zgc#&PZ~4amBXry%4c=g};QW%u8=Nhz{lv z;ch-66wNn`NOQ0aV8`Lbh!6vF9 z^VAJcJzU`sR4(lsV%SaoYbGyEdpV1q*WT=O3;-@ThX8OX0C2l9xH~}lfE3q*mxfUS z9v^|+V*`9ulwLdeP{HjyGXv}0cS8coE*;@5R$Y?Jk=Sc517`kzj(}S$HgdiI-v*D< z!xC_lki`AW*%GDvF{_Y@Gv&=?4M&CVI>{b5JM(G>?;gI}7f5wGETy?#Y;UGI%`Q=A zFZV==m&=(^hc%0jTMeYjJ8nk{&{f_2`yjf1hX1o@8Y44;dd4~5)2gD7f|M`5XSS<)%cxtg;np(Sr!T=gx`2wg-*_g)|{AN z|Mj;EIIQa5bXyOsY!_`3#E_A%-XvPaX63s$?J^0rUkdX1R9PwV5qNGKepx z^vk14SSOekMa{6}%v5iv_^+2nT~wU3a}M3p?YFi0$TSE2;p+6s*4n=9zwKDEJQ7A` zY6&X!YYHols{7I71R`-2P5L}_>}OOXkk^ig7(UG37cBD&mrU}3Om5I(BG_Er_rQZ`N`H10H>6U70kWBoZXaz?{ab$*PH$y6^&VYOl@Xfpl}vuAbeVLGLzu1w6PK zylkDd$8$T;HZ)5q1U$CEkEX7kkQnUz5!zIn{rR5h9`KpkGQ%g{y6g_yaM9m~ylVc@HfcQE#2MN^Hh=8w)Fr}DL&rY@f{+qEuANs>5+AArZg*AIB(SP)Qg z2Q3gMuq{T|g)dD|(BC=+&GQ>o9U{omT-N~QYZzXIsBgt-=KdZ ze1BlvKN*C3Fs*5((M=HU$+0Fib`wJV>HuA}{>A34$OCetIUnAiso3(dpDay@X~QK$ zCCUxdnR0p+j*=i5<^oM2@$^?%)|q#QD4on)|5uVNAhocThGQSGj4?Wbeh9*i6qyl! zu<}U0%qV}n6zmVx>ko6MZL7Er`oFI2SR`y?=EBpq#hoW#Ln;G&V~ms;EF!~q9^U?Q zor_>9beX!02LGywH@D*)e5dx-v4wbc)eK(_#A6qH$tv^x@g#5FrM)_iC)A?R`xSoh z;wSs3VAA|1kFDwwL7M98-}pO9IJdoVyA8A$!>#bDZ;=fSb-y;_m4|5=->!J?dF%Ko z>kyCoMM}@J=e-o_e%LL3G*^%JoaBj!H4+@;Zeyl7D+w@+GLbT+O45wdFI7D|4(}n2 z9HeS}yYSxT2NA-^Tg!2p2Ex9<+$B-#cU~>dwKskCp4!x{sZH zTD!~CTe^Oyb{xIaIL>cT%|fTV z``~@jWz6c{nC7mSJKGO@@cwDede63DtWd!wHwk_>=+Op*Id8Fya~Lg*w;eiO86M|k z8E%lc`ARg+J3}o7{}v2tA(P%0*(p?>iW56H1c+dZo;E0g1NbD&{?X1U(Gl3>*L@+? zm50SteL7F=0R!xfO*V+7*|s&&oYaydXk%h#q<&2R%9=;?gWtDja&l-t-Sr?ou1R*L zo1xOtbR@~*K3wAawYez-Dz)#ptyqYA(j@rG%bn0X->ogMhek31_WMc9|6%XV_3!Mv;Uh#x7#UPDx}NhKv~s*=CCI zsabkX-`}-8*L6Sl^}1fq{onojqd$5zedaUAd7j64Ebrs}2Dem1JhT!t#-&Z8cj%~u zbd7n?#^M=@#)e2XdXO1YcO^OG2hsz)uopRu*j+WuwHvdv{oaUY=@J?wzYr7?Vxo=~sY^FJkI>gryGXG6BCT)$ib?%86-(->8 zz`$0(c&T4!r&he5oC z>PV9YVqBA!a?u&nJ+!*Jv}*3=0VBWd(@t?5vqE{bOWc2D?~%^iF>#|n}!#5mVD3_(I2jTTKgcb8M9U5V7H zTgZx6O+iNbD7qabHcM|w;kc3NYwe18(=@C7-_-#Ei;QeZ27J6&M)Ca@wm!&z?C7+)Zt2^$w_S*;#kiH$e1DtJCvLlTxia{KyvF2Glu z<_%uIh&sW;$0Kszj_=j~hJN>dN6q`6|E+@|5Q8~RYc{UQleh>Fs`z%ZV6oG&h^4oR zgv0;J((47lQaeJCF~2*y!`;wVn6Aoc&DS0vGt@wYlO-@n`2ONP0zv$nsy7<5cdosW z8OcDMNqi~Wff)N;z&jvRY8TiT=Ci}3R=0kc0otJ3K4u3kADGS)Wgma5>f6{*6KHnE z3y?1S=&=Hw@>(VPR2SAt{{Mo6_qhm+O6ep1nBmMPIdhN8*L$7C)0-bW{1WWle1 zPUI_q=Z{A1#hl_q5xqcUQqNX~QNIp^c78K9 zt*Hs3=&CkELm@OuT0SI!6QoS+E_Y7dDD>t7f*kMW17L4Qx4HJ!9@f0ZkED?1#`?omN66moQV}c&KV2&_uKPz#c(YSK;ht@+}y{}#` zDB?Y^P~)Tc{D&%YO#`1I`ymHXqa)r*v0YoqP=ipI6G|*)r&Ei&X)Gsrf+1H54+Q z-mC`rgJyYjxk{c{B>-fc@^?H^^eU|_eR%+rNI|0Z4EVzCHoNjDd9hM4}(4(MlNUQ{iz((2E_?*|wkZUy;d)tOM7Q zlT!-#AE_IO?K*#izW~#74>gS>!#yFM#eR;3=r74B+hKB;_DQ~@-H6(amedq@O>rB3JP3&EYDEXF3rj4<-zzbHMb^uB zJ=X7))(WI`-5!4YXab~lt%0Zzzb6)OUe*%ZQ4bJXLIK|ZO|`=q)X(<}rpM6m=N!I2s$ zFh7QMdiZix^7FSz(OZ0kFrQ5X4a8tKEtkWo{ZUzzs?`K=Tw!Ef3t1{_=I!i|XFZ{= zDnaPp-PT$mG$IR z_wvbp%;3p+{jehyEZZdiBi=P(ps`b+c6N4m58eO*q^^R_-+Lh7efy${@gQ*9(fHl!^R`?IkO_u0Vc75Aw47`$%SjrZFIMig-^K{2j z50Jhir6$KuxJ&z>dWS-f>)qVDz(0F`MzA{+owZcPGKR#NdXNwmmUI&`Xz$!)zw^p6 zSk4(Y4-R`iX*H|6TxVB3Uhn)u<_PEOjN<*{Kw0w72P1{XN< z%$;RMAPxrxzI?P}XZRcZ^rH*D8ifZhJm3eKLM!Lm;Wb%H$*d6WC|7CFLA>xXVv-A-LH6*8?So!}AwX?0}}w8@2%FaTA#R+>zRent%Zzx~W7O z3M$t%AJ%~@?l`nwrokT&^S8Y2Y2>4JUcyYc3xSi10AgkcW-mgL=oPM^b&>&!ph8=x za+NCMJrjO~N~h4;&($0}cG;-mLd;j{V=$HUgmIMF3h6SmW>9VYA3tll2;=#fLB$Kw_cI9U~lqfF4HI)Q(EJ zR?1qxC=#f7kB&0T!aQ%(b>_dTeW>;`@XLMl%db|yE_y3wG3$W_XP+GNJcG3K1Qemv zP3ssB>Z((1M)y_52nC5=%wb*iy?nW#w{iPTqrJ0Y&bNy08xMidu12*5HFgtEP-H6r z2NttVjLxR%WY5KF=q4WU9@JDpfqJHG(ixkR9|4d747Nocmz*Y6QBt{rXg;O~9S(|k z+L%-HGJK*)_HsFdow-9IhT$?7wEKQvAa zRCR*<-*gP1gF8ric1?`|Rr|(^{Tw7%QP1i&gh^4sPi22)F%19{x*SUl`^iL{lOF=# zHU`yGyW_58FLsd6Id=w!7M><)#|#JDD$L!(<9$Db@77&AejE=$3;Ui@i!EWO1DG3V zftb-%Q{J#0HnK$u?!6+rPM(}P9UrJkyW{k!F71J}bOz$i*&Du%mdpC!n+xff58m528>7eABNRw|Hy`S6^R7?9>&fnmZqXUfmMdWCM?SUa5qIl`0hsDNFo`wdPbUFR z)XHgF!&Z0WDn?mGQA07=wUfVR=h5BxH(nRE+4#zvbo4Mwb>UQov*X@e+jIA&FcJIG&Vn5*&?PB#$&es(+zL7w#F?%~F{zVnk zN4M;rk{uzy{YIHTp}e*_a%Xz)HT5onS3yyS%BQ8D#*L|YnfCASpNLh`DFlH{)KlsM zoF8sHk7gMif|u{~4`#hLzN8T#xQCGrUK6JC~2o1i=%2ya42j zK}+LQA~~!DD_p_AMd)rcHvsW7rd9cMjnoNmfpbGuFQ2My^AQj!xW#UNC`94M>R@~F z>YO^@i3mCNQHHbyT_8Dx<9{~qyk2Q$7Qhc)_>`Xl3_md}P5bA)B z7_1gJr5N~Yw&LfdCOKLeUmI!gjn{|WDV z8`@+6Y6Ufk{^_73uBbD{Y@o@BUeJ*pI8q+3B->p0Wi@uC=v>vO3)U{y0Z$p?_s>{< zMQ9!@UN)T08((B5(un{?4%njV?}y~=KyzVncO`SHJ-vhWZ2R_QaPAs6Py3ax#+Qss zo{v3hWA|*J_F$Chi_`d)AbG%>3%)yQ&3aufS&)Izprw28-}JY8>AmYrD^Chnm(`p0 z?Lotxp64Q2?L=9E0Jj?}IY2OGZ(+>Egu(^C8@MG+Y0{%)J5$zi)x}R^H6`C0UJklgVC5;)Ho1;dX4j1jVDMBaQ9A3`Dq(JW0v^_iqv1;Kq`)-+J2O( zOClN{Co}5n%){}mhzK0GzdVrJ(Pz6iL2X~cr#Ipb9daQ#HB=>p=ZSo|bTan+yIaw@ zU6w(Q&V4*ZCAiR0<8bC>I#{|W6nzA~oh?_4e%IDmR9b?FXB%jEybTuoVxlX5^dRnT z{Kqs{<^>tJzTFPcg}=plhzO)4gWsnPQ}9K=n%s(}pun2I({m0r^-V*%>b6?FZLes&;CPV_cIy4?8?&Rjv{JfBe{Iok>49JfuX6ed6&MrQX_*h06}gy=nAYA63W-y z)gU(#wnOn|$_TDCuUfhdo=U03fy)KdS5H<9tkedIA$H1}e6m5OJbCSGQzWBW@iy_g zVp^UdigzX*e-jDlR8UORW;m)9lkNRrO$fz@u0A!STlBWx_1Kl>&+FkAPF7B~*9TNy z&D{=UMiuWLM)>qkz^L_6hni$q`!IJItFcWU#h`d{&`rFfw8XhzlKD*h*dxlh@qHJ| z_gU~ht9XPzE}Z5zw+sg@6A4Z%R}ca_(nJo5%tz-@rQ<{7T}IocNRGAdn(52SBQHz$ z9FRRdXyc(?At)ggm22YubYs~TK)LP{WwoL$d#Z_H;&VM-yyzi-z)K z9+jwRy75;E_wcsS9&z5cm~jbSR127}66Ais?KFb3%(0(?6`bf_6wzPaSWA)c?T zOLeSxbdT0;AN|#F?2Bm67x7!gGX1Z){irP_GT62}K_lTe=;}6uus9PDbfU%Jw?{w1 z)yg%Sbi;xJ#gC*VNT(yy#vXO6h~eH1^&$X8l7Aa0Z62ke$P?4ZsE~eXpL(p?NNgNN zN8|aE>q`YW8)4ZV2Txu)6>BK5`~?Z9l#f;1vv` zyJfQm86|_O%ipRWfRX0wr`~y_jR$|t6tmp>>(*g^KveLAAOL(&ExrRrMl#JRKZ{@b z98xA2XmB7^xf>&rD!tUq3I<)gBh$8scD*S+1~vtA zCR9$X%p-^>&8Hp%@mBbi>68lvgKvV4sfy?^n z|NfQM&j~lmCY& zj=Kw;ZZqt`{a7=ytQllvcqf!Up)64LbiZ;^O3UtHana-U^$%LHBi!AP7SMx~MpR`j zYfWpwPC=1Dr3>~}%*>mn+p4c@*vJruW-stxg->;f%;!vOYfkM3@KIUrdx{8{us6hh zChQ*6mFKe`SU-l@H?w2u@-_#JYd_XF7Pf!cyxe1cpye@a)lL8optM=7xbeAZN+be^ zkCb+ErQT-G{hjMt{cEmU9yqX>>+WQ3vD2$Rw*S+nvR^!4G3f%+ArKKXq=gt}?O0Lh zfpn^oY52=a-({1_@DodgnR*4PWTs5)<7K^9=M-;Ucy;c#JqsVLH-NV^+D!+%ZIT zYV=y3B-v)>%PkG>_S{oq6W_A~v}6(jjWX0Fht;f8uS=Q#Li+I}woq#Hf%ZrUcgW;; z6O>N-0&n3ef7X%L+goE5EU%Q0gfc*sJ&?reqr^MYsZG;_1A(nm2tVd!uB1PaS*=8Tf)|Y zJXtae2KW|Ys{8K2Pz3+?O#K_^bDi~4cG3|R(d=e@hjec-k%wn*?D25@HhUjUY(c~k zw-JOfykKs|6u`qx=@lfU!7D-Hkh`tdhwba{LJoz!)@lC$a6cmre7H$$M=-oPs}nKq z%}g5vdR(@cz0kAg=>6RT=ov@C04Oe;938dZo8C*gc8~v2NhaAru;MrmyXUU#JmMN| zoYex*wUm~i?Q9>Ez(uH-ii%qroO7=RzVZ5+T)ccF%JrI%aY1PIzK^&&=$<$D2gIuG z2rounCjy8dxYAb=X@R-A!v(|vOq^2HXibf1m7D`e3+xZ5NbMHhkQ>{Q7lZSKkMC#B zamtO%Ut;_jnu%1{u6czWH8t5cOI<9;w=1{3T*)#BT+J3U-!Hb$@v8_)-WLcSfRcxR zi896q#I>r}QImsoLPJ>L_l<3CUK%I+)|$O-9*q~c#$J2;QksWxD8NGQ+gWv_9cZw7 z=S|o!d*BiXuN>o}rX;rE^u-{Zua7<`r^qp0HHAqTJj=I#*mCDqsc>)mfq7r7F~)$C zO$>mEvo#>e8603T5$^^PUtjAAXgz>e z%+}|LVnqNAeKx6W`KBz;S-RcW`M7#PT3k~Wq^EJV>EcH|GQT6prcV3N?o>|?h_p9LR_m!Jw58NnG5e4%UMK|FJ4spu@bQdx&8QT)vWAqcspe~;A8K& zWkxTUaf+@fLs84CMPu6uDh*Z9Ux&QXOl%Du9v0meyBTz2s%P$)65lr>_yXcq%vL}! zD8wuTSBxUsaj26rUQPzFY-pmPPblli&7=I8`Wa`O;$jbf_y9A%F6;z0VHzrQL2C&{bbPIXFd=`XOQC8!G;R5L#VvK=DWM>VZ$fT1#OpL$oE+ zk@K|a0L$DbSEP~=){Yl7Hzvie)m0~aTeZn3FBC4h_|-<|7*9XXlD_I0Im!;=HPBP& zrpt)LIX|wtS$9HFHmo->^m>ESRQR-9yF(n|v zbpkSC!&8Up-SJ;*7@=<}7C%$Qdy5whtRk*@H%{!c()8rtkM_w2wS^dVAD7<>Fn_J-HwDXNX*1?LeH$L2z#VyNBBggxh zMUm9*B`O2e(ij%ebjNqbU&uHNSskIKa^c9CD}>4?=VdgW4I2d58gehjFE>rIFLp43U#b2U88f+!-K1blP94bk6qcjk zFi(#8ij$31LOWSAW*te$SH9AXwS{jCIFas1#R<2LAElNzL?1*r+VxloM4kiq^Mr)6RJT>{H4te|J-2qRR6jPY+vP=K0Qb&MOc; zz(FEhH^ddk4*gyQ({|qNQxfm0hQB2`*195V6CWryGjq_&eBW9g8R6pr=LKoi&W&Baw16V2|kJe&AQ?z(ik&R$+M0Y2O%SaPl; z6i(Nlc1pnkHtnFc>_gs}W>Zmw^#8Bua1N^>WIpT+FIbdHlsVN9rRIF)y|Jma=W&IP zoL5Z;=<2kMc42AYZC+sbUO@gdNn*m9e>fDVaV5g|^!wRR*_fPzuRP^;$vl?-j1WkY z<(c9XfNEV{MBZkA9R!E8+7TdC5ohmX=tY*gj7_+FAFU4~$Tv6EJn@X*zgdz2g4HJ@ z2GYBGhl=U2PJ9Hh3f~3-5AJ7B6G=5X66O&`UEa)0=Rs!5a_l`8l~rf|Mr&khDc&zzwRUxWC4)h$~Usg?SD;6&z@2G!xQ#g zAQSr$zKiIMj6>~MCHjH-5e*k(bd(_i6Z6-X$|K7@D|>UdEGj)#${APp~-n`bfHC=Y;9dZ%p zAE$}Hs)=5>@$hz(h>;^1qikgpS8#l+ zIH0%t(gltX(;wQ;LUKnqry3Qi&9&w)+zt{=% z%Q@0s8FzI~8O|FI64-KZ&+1}H2B6{iZNv!SNsC*z84FcESBRSEySBv@HF0Uj?e_fu zds%u&DdoiN*~_E2Wowoj#sHv2zIQV%pazD3DWg2{mH%C5Iw@}GTy>*wpkm`mronS- zxqwQ`wvX)rB^zh$VR8>HPev2IrX-x~kc21y$I)9s?pMG~d;%X+$Oe=LBKS4Kq zWv3E#<{dHVp%)hRyb;b&=n$XPQG!H4RPl<*&nH2WxAr z)r~T>4S7DlQc=8B5VQpk29`n38xXBUVud+{;Krc9(eD27Ylc#cuqa&Jn=5V(I?-mA zTno-CgZ>wP)VY5@i`9M%rwer5q_S*E` zp>-KO56y>{%@6E7&BN7fl3p68gZbJeYdWeGC#s7OSl}u_W;6}$Pcsf;&gM76sJ$g= zHkbCPx!e4EO3HH#Ii5rF2C6E=R`(;E*H}Kb9eoZYvYj)OT~iCv1}O#p{>(+tq9wGy zYE??;58AiYbnjBo6WE*FZJc~iMnFvzGyh_Au67V57Zd~-D)G;KE4puyYhOCaI#&B1 z^>UTN>nN4vnmSw5esuQ?4J;>2XIK z^xpzf54-%2;Ww(ZKHM|!0jL_}eM&85IkX(ib7W|QB951Ej^$`3>)e0Hei_PQk0ZQ1V&nhPKK5bOb2qLI zNVw1`)0Qp9=a_cT1BQ?pqdsc=U7x0w;9{lU?X2`}SwFoc^6erqi{n6ArCMMM+Rk}T^Oa2rhUHCT5`TFnUxBa#il_!^~u-RQa5X)MIS!5z#nhB4`FyU7CeK}}3KRrj0U)gZqvG(OHb_An$O zxIIZ-eyl%+`+>;ImFITl@nZHfGI3j7L0>F3Ay6vt%1D4mLj!$%;@#2jqAL!|mwVnQ z$KUGt>TL044Dds8cOV(D>@s6m|78qS)K)N8_w$0*8Tb6}Du?(t&~# zz?WTu7T);LdjZ{SaWqEDyTE5OGIXi{{eiVFI$UIBlWo?xig%5TquUww->(w~3@0Ta za|lU|CmJEH8pb01k~&du#C>P!g>jtUM>zee8J%~%!TmHYwL#;*3kWaBzb=!SJZZf< z0u=hN;l|R)w+_O|4~=*8vBn8MiN{+cyCHApHu`Eep!V)$-5PU+a=K+-!>Zbn+F&r( zxscoB;0PHdvybUXM~TKq++b|=)d@MKCugJ04aJorMuC(1mjY2gA*p@~85(GG$5^oHFVWQ}Pp)*zY7MnG?I41LVV`Bx!J_%0$bhBJ8 zW4Ly>Z-JZugXMa+ESs&sc1R?h`_r^O<<3; zq2jWMQ3dJkSlH)~ZehWXV+JuLcY;4U4pd)Jy4`D_)l+mI;fRqh0P}(m3B0~j@KIg$ zKPcskGF%sRK1oE6dw24PEV4i!($Hl(o7ESzn(z zvlE%8y>_%W)41Xop0GdVSb^xN{0kNUp~X8U$nz_<9Z^}lG(*jcGAM2prRKPDVD9lV zBhf!NMS&-JOzvnFrE48Zx-;1wIY`_a0(3GufXr)ZJkW)vQj)Zq0MFB{X-n#taIQ&6 z>hb>fMgEz$;D^LFJl@%+SnR3@5a+;1@R?N}2=On#!-gnZF%&34-R<;$eOT;#KdFQe9!{TH8^ zbt$NDQgq790J9!n$Ztw}pw}R6sNF=lnM1AhPL8_k^=dhd`%%1p=i#zXJD?$E=x38X zfYB(|ND?S}^>RfAt}=`oL48FG{dj?Hvn@JEsmlA?czn<-YTbTziPbk|w}pLTkg%Wo zg?kLnr@>WrMz5X=wO+5K4}T{}(7zPq@@;pUup`{$mU!LXj=d$Yg=k-cf>cwNMyRRd zjYCX7deK9jW<#V$sQ)V$njsV_`78SOr|0@)eRgMc{}-d1mk^P}>Bq#%Fc9AJ1Nbjp zHHLCxIE4PG@mq#bra@`{zAs9v!9wafDU>6s^T*1F5WuI`t+w`0fht|B|4g4Y;$0#1 zfug@pfZqLzy!5z|%cdaG+}hE=sQ6nVz1)OqYn_eUqa`Z|AR+^of%%B1Eo z&m__urL`YYgGV8*Q6_lbaCOkdXGV08@(Y7zH)$FMKICqPra`K&243mHvAX6*TMtjR zs|+=VrPT2L9(mEo_5^5|2YzIBlu0T*@szEJ6yk_yM9;4g_{8Jj3cr)d84VI^~PL%a`z+%&$J%p-0i2csZgP+i~x!Ap$X6YJd zv9c7Kj(SX!?D-u{jSmjQiQZ56U`2-vG(E=A~BrqJmU(?)i$e ztEn!Z_pCJ59E$yxw(V-HQE5bzI4XdB1Yny1bp_8LRvD67xV}~fm}diL( zdhzz&1Zb{{ScOdFNV!(H+l`S!d@>>kdvr6j$7 zX_<8eI?D9tlw8O1U@lbWP`^EyS&YBFyyoT{VP3d+QR_x#*dBA^hD=1WZ-H6tuqLd?lQTG15}aag2jN)+?fOb~eeR%%%*%KM2^Vh!#A7FO-afF`3wsP_iK8S7D&k8$nqUccNis1ld zz3jU5+j{Q4qcnXhRd_MZlP->~M#dd!vDqI| zzw3Cv`L)}+zYnlZV*9b$Rg7%VO{?DD=`pjoJt}Mz)GL6<>a9S{mg&<1zn>6(=+~L! z^eGZVpKhAgb|QV?BT#SKiPr$1rp5 zgXkso+t;#<@oyDO`|b&Wjf=yz?_+}ii?uqAr;Sz@O>}?oHBsuSzkFi;0hlYXiWYe3 zpaG{7aRE4hTy2ED&?}A3dBQ0p81Y-mw*(xyeN9)>EQ1qcn3BKw%y}^J^bO{BP8N6H zcWdex+g2g+O?3eGBdH+$^g9Zt)24EFMl46$TVZ|u1E{rH^?(y(xi`{1lp#a~;wy== z{tF1PCS#AXmc^Q~$sPN;t3}^p`JH-J|9kRY-VM&*7~LIVYzb*9te1ut@j*ze_57Zk z|EZT&5&-WQ{rRinG@x7rdDEk$-ql30JGT z?t0w-jvE8OLR*D~PJ+E*iSz99hKHj_m-`1>bg?5&K&gvG3*_rS)NL$z;32Qy6#J@1 z#_c-Ax3w8w@$J5m86k&W-V?@>26)XS>;(RN{&%QuCqp%M4KIbh3&QorC2VL)aiB(F z$DJ;y=wwQR!fPx1g8<_66CA$|MFbzYwkiRA6IMB9+vr>zAJicva^&mwjhV}Pwl1Wo zuQ?>}up1yta9t$>u@Qc>J8COik<@ha`NBE3ehjmYpfW6W^yaOJLQK$fF<<|`gxLx^M@>6`q}Uq72p^(&KTzcGv(%@5`bycfPnVyeUY5@*^+LvGY}Z<;lIbpG%@ncbg}I0^X_U~ zk_{Yos(Z26QNQGoD@Hrzn@ZcIqXd1>h4jAb25-@jsU-*vFMukji_fB*@e31N?=B>jw zBT6=a}yWoVLn zRqfk^mF+7{HdyX?dPPW@2)k6B2d(=%3!KCo5XgES(AB%KQjK(E62^X}%*MJouGP4# zJ03r!pOkdD1owyMf*0EmT)^kK{X{_{zG93Pgrfz?FEnn;5Ew5DC}5c6f3=jd9^(z} zRxQK+Wq$&mi4y$7GyQOrmb7(us0}LGU@m#>SZGci;av);gB+oh1>4B;!ECu#q65@W zU`w^s{)EP?u4O)FMp<4$ZQ}VV!mtNJQ$hc* z10fHX{eqHe^W;$eT&cWeSvPjBGV$l~Y^#iuh{$22fMPku1-!Kd_hX(s2H0ggs$Srz>}~Oyf8rHQCh>l+}flBs-FoIL5jI0E?X`UREWvmZ-wgb*g*mck6m!BdlA=~ z5j4<|mIq+Ct^st_chb_i@Agn8$18Ksod3f=Jo>{wQLi_5TviHh`XR20(t($P!n<>i zgMC!uZz9nMu_4{*NKOe@|K1eL#~rwKPr*C39wuy?gifIae|EYX=2@`Rs`MT~*&N#8gZ!cynx<|A zdq#odgp}r%=IBnXjua7sG?d=$ViNClsohr~ew|k~$S{WwchVO73_LLtCj#CyuWGJM z!@ENk6by|0yBd{A3D+NOTnI;sQM#EqQMQTu??aQ)3DIENfYt5A051E%MRz@>Nsr^5)x)BMmZ#?!|bT;P&%V2M^=fO)6`8>PV%3Y~iY%xnvsFbFPP9vhY zij2|tmpi^TNY!ywhoz1vEjL>5;be4w$AVLK5iS0YS3SbG-aL~R`eyJSP()YO>VPi5h3F|ZQeu}1K~Y2p2y zSff;nnmX5GWw7{F@{uj&pA`mYB`3OsgW)?6(`m$Nt(MfCw$sEYmyHx1`GesNt5c(! z$K2w&rfUd3nRD@n|GF&jz2)>+wkV6~LKoA8K>5e{ufp z|8V}QNlAeRQIfxpgAMElfeq|Q=c8st95RtZ!#bu6hIBNvVbw0g~tDLDPK{#`<&ubCvX68LU~*3t%!ufaev# z*bWo4=MDOk53%jvxE2Y~jqe9IK3QxrB-0z3pmx%;I`0K{H8P(*dbzNb z60bFTA@gWPXz%P{e$#l@$DEaX(oYV1*X?D4-u!+5LL_^hQ-{BV;sRb$ZFOeA4ZRgO^G(z)CV7T?um~elh7^NpC>!AfI!q_~- z2?0FagAIbDi9j=$5iI&l9&^q)Ze)uc_-o6O=wq#jcj!)R67Vxm@`Q1qL{VMe3c6aZ z7!&9k4Y6mQtdYB_@@WE`^HVvWT!n}Yx*3~B0y2mg<&oOuFn|%6u@zhF*suwIZS705 zf%-<;G&>)iF%jBIBRZ&oI4=kaK`b?z9K?6?k79fX8m?Z|++ma$Dlw98=9V<9=UBJS zDu{bp6^YjXO`uCxA`Kqr(x0pgZeWqg#AZF(Oh?wTa!or_5cmt+;q%X7A5#e}ff3N}`wM87^gy$olbk zGQ9f5_EC*!`gyf3WA(Kwzykn8H?VyUCkH@cZHPO4_!h3cnS{X7^OhII0Jvz(o6mQ)rN zxHeUVY2xhN(Of`T#@_+S=c659e7^1n8Ivx?wQp-u2GH5;j*5fJqRW~VUz)BEEkI1v z3%Y11x;0|FU>X;5l^)dQ7T)!HTZYCksm$M(<`2yrozz>nN`{x_+B(rw*<$;d?sV{_ z_;`h#zyL-5xr*bQ!muE)__Gb;AD(Q-p1rfshka>(0-hy{XN##a-AB2qz7&~tTko!P zbg6ZWO}MQc^k|d5ty4?n!N!~bMW;UjT#6_FZx4-5$zgb2WE3@vXvd$e3J8XNO6WaRJ2UytvdxPw!Q40@i{nEF zU%m?bI!69)zYeJVfnWFdFMge)_~O3FH8ACV6%|3O#I^f!CD?-14K;(;gI08p6G*|z zlY^JO=qh#9)BeI{!DB+_D7Dk0J>!5Yw0Fg*S>raEF1~ zoMv6}lxUPgg?7Y=8RMI%mo;Et{NZ66;HJGfFci3d=@lbj8W>Jr0Mna!YsMHG@PKx3 zFV58degK^EVYV~)f?eDWoP16G3-;v^BS2dk$|}7>D?5GCB>CHQzA@RLRtmHiq@QLi zlX(ZU|1_B8!|xpX@XcDWf^oKR*KK1PQ57W3pBVwRIuY<0BiTFu@Z>MjK;2%p7(}53 zTzLfjC^r@#kAp7y<*{!Q?KTfCnB5Nf!_(6LTY;bqLRyd4I0hL(1;AcD#Qa?-3v8Mg zkg0Y1uWtd*{fm*u7A*xQBc7T=+y>2cB6h929pr3YxF#CIn=A6<%wOf6R0Mn13{xMH zq+X*V+k}I=K}A1=-lAh#OVBj|_5aSqs3{XCQs<_Hou>3;>#EMX-fwd2x5orWc>8m~e4{ zsvT0)3heK{D&5N?xIp~>GQh7K)R~#U=C21f^DkUAJ|@H;1w-Sy5TZ*<0WU6Ij?j|!^GoZB6nxG9mPc^p zf3f8FVZpzz(Eq&hO~40FM}S7xaGs1JCtuEv(alz&Pv~a*qv((Q5COXoJ9C4cyc5_% zTGj<-2Wg{79whUJ$BfiLWFOK+at$s2%ihL5{~s^sKcD-LZT(L>{L>Eq(arr|wjXNa z@gOi%AbQ~?eU}T-d7ZdjwQ^3Zfk_B&p8;cUomC_{f_SjIe|&?x-J8YF?E~UeNU|Jt zIV)}jV@X~3+AuV6o`lCQ=VxF2F=bw#Yms!sU0cFwNnXP4AGOoLf3KbXXZnhN{ypJu zDv1B79sUgc)29DZoBem6|1c2n?AMqVa z$)nrjA!SlqJV4y0#uyM|LW2aS7H=+$W?%dAK!2B|_E-JWa&vnlv$@&ozqA3^8uWI* zN*e@mk{uE6U-7M*QT1{_x6BpH$kw;xM7^L`s+=Qft=HD_z3g!hI62?>Eki_(4+cMra^hK&%oKN%+K*s$8TA=Yv1eiK@V|- zDQz^%XW=9@>M_jg|B6D?-nU}nuUY2DQx8Q_TITZjP zz6IKtNj5F31rhKwMCZ1P53yY5vfF*4-0#-Jr+4iH`Ve$`3K@_lO40?Gj{za$2JFp}Bv zmmxsiaXL3onk_!PY(tH@ON?pqEj247FWTO@uVBIRZLjuA@1$J+wM1qKr;4zP+YPTS zBrWe_y#87iQtG1^8iUAo{`MD4bN7SqAG^2QH>r6+6vt}eTI~tPvHg_l3#rR_3|Fd4 zH>f1qrO1$l{M$m+k7*wHYI8&8_O4q(TX|lsy2rANxs&kP`mUgOgJOjn>aeu9pNH>UelEzv33@>k0+ZeSkUG92h@8mW0HhoT06TUbd!Ipl z#G&ZPA>FaJ+TOe6PIPTQ{>eWF$c{``P-JjdDC8k3W$EXPR@Bt>M257p?ZI|e{gwlc zmy3{xcFu;jK8I0GtN#FIjRvy3SHS+lv9}HbemXw(ag$>MA%^02NY2xjZSZ;uuB|LeXFe24yv* zx+!=?F888FR!G&M?U!DQ-0IjV$Yud+g2cPk9s^c*>v`x%ImVN&6;+GeZkF$dFYFC` zy=!^D+N6U1g%cJg^zIL69p2xmpijL`D}Ep8x)I`@K#WQX#R0A4>U_;@K3&pKChM(m zgymiC88A2m9nfM+W=-p}CB>+^`m!@Qgj%;7=o(FLN=kS$bJdhxrv`VKY!2^*ZsSVMp2DQ6=Q?W28I z#l<{H;&gQ;uD&pDDd!pu#gFr#%xgo@x{gD6eKsLaTfYLbN5UVTL1KP3yNe;fE?jK~ zG*f4;k=$lto&xmGU!wnk^Q(F2}qtxA{Y6l+XGuv5g{L_g$%x;!}$SP&x?odyE0L|ydF4pO{p65B9ydu9@q4Z?ElqohS2dVmBf^2ggLh)FNR{Op9hFy1df?eT+SJ zUahQuKksQdJ-#=>^}8KcriGr^^Np8^Rt^Q&a_30%&Udhf2IcYYPtImgeG@DMjlR6x zlNO}>HBW$dcjQ|u?sOy08M&8AJDDxYY(DFT5ltbYo)U!-!SDWXw0;e^(>~)>Q%tz7zav;^|DhHAHr{h$2*aGF*vAWDTSAO7I|?}^PfqL} zukh_=Bk5s&TFv0|#H_-X7@t*Jc*#@OUy~dFqUgBE*W~vT8~YM~G*bpbTzj;BRle)C zP5w)}$hX!X`*d?BoQs16CS0Zon;w90&mf}sYlum>&ug1gt|>)JkK zS@gm8|8StapJapLXIyzChb@Zh#2n{1n1kC)6Xg(6xZBkQ{ zfs>fMbb3+zaj%4l?0118$vl155LK5eH$+1*yeN1%ZU8UKYO6vs1tmT^>uI=9eCIOm zV&J9C@=moJblLVBogIKblcZk3>=jd?nLe9INU87Y8rWTl=&tUmP6{{6q zaFnx+UQ&yVPrK2U0m*`M?;upbl3@Q8m_%GACnF?QO;tIP+m>_Q)t_0L{*Zrc+x174 z7efnLWk34~E1JTtGm(bb)6uzy|fxxJW39oyL0+ToYo2 ztVEGLk%ndOJddB7_exHp3);a8ZtzJsIB0^90bu~zeFwTV2h0Y~iR zCo>jgJ#3cOGu2MP`8Hs=<1b7hxYDbgQkLqdi-=8)7(~fOz1paryc|La6tHoDIf3I< zV}(yM-8Wyr5A_}Ywe52A@13+5t50YwgeGesS7`V{EX^e%sVp3(?U_S5z^QAoZseOW z8n_oQ{n$n<<2Or)FA>EmT)qfh^Q{RaiDWALm#2NdvqL`pMdMdZYVj2^c1OJ?!K~M0(BDCOlJ)xDoo2u-ePz8%j!LQ)x z|F|9O675o2gG#6BNjLINu3Db8<+KL3FNWOb`hs3@%KJi#e>`=WirgDeH1man*{V?V zTQAR3o>|LsF16Q4>KE!xeLEv3&M`g>2KhhqMb;`;Hem>K*rJ%VKiSk8qY&eI)upxp z>sFWc+}lk)eab>_@3m5=2d-bcSFv@PASym175+6G z|GxT{BVX(a2ip%;o+9s&DLAQ9I7d*D`OUSOfqJtacG%kM>K5Kc>G3~-e7g%g8A~Aa z;8IYaKyck!!k&;z4WqlyRwSMKZawXyr=pv1{Nn6KTVWZ?VbPy+@|(cS2>0bP{NJpAz z*RIG*D^NcoH5KYiC?44b6l-wR+E&ZsQ129Z((*RYZ0e@=t0!J)xxleby?4%$4h+0SUzlsIL!D8zjcmtztNC1g`zGvp z&Z(jpx%A@MN63IpIu*%P(5DYE5aoV_)}T-;Ti*Plk5 zs)wDT{lP39=e1z=V>=KS(EuzQEzA50k&g~DoIaQ6y#rx@uV7qSnv9)wrO>(%t*wBi z>jFhrEdkh5n0}B}_nn?p)s_#KFT&@p-(g)3R{GEz$kgI*`#1T5yaojL_!&`l%KuWw zpd7}D)bl^~yG`|%P4(S)W^_yq|EWDKnsyuYn*6$gVF64cYUK$9MGAK^@T;L49_tI)H%G9P7cOw76Dt1C z#W$>iZ^^A33|@`l^E`O1J@#=OpWi}h9} zG>sa+!VFX`Kk?o+KcbqjHg}aU<=7&W_EW&O>^>+fsnX#L&sxk!+_u(Tz|(p7$R8u8 zq26$DGU1Kd=kK!LLIZZWY<+LevQ>pM&l5?2V_Omsn4=(fDr#zj`VJa8!rJ}fb>N22 zcHE5zuSFl7{491j9nrG(^EhHKD|MrON6cqN&xQ8DBwBJA+q zWNTu%a)SIHAZ8jpcLHlg79mmy^A@ZSMll$wsYDu~^I5AkT~b6p^oqaaaG~dP@SO{{ z4!+!~nkw6lFSP+d=-Jj29Buxv%@*($S0m5Obmh5rHxFi{zFgWcyb}k#+Zso8KRM!@ z{9#Bl265G|)J3W|7ZBpt3pk&U6L9@RY|u$$7=}_VzUMs)8#F#PZopltRlV3??mVE< zd+J5Z$3k+*bb*vzMi{rl9d(} z54n)YY=Z~>>Bc0u@TzjKsQgAQBdQwPakEVr4V$zvL~FB*9MDV@&NNiJ6@42u zOjvOQkFcF-&Xq&3bAaIdA~m?u45&e$Q?=eZk2I*fw-EdAi&wkME2MG}3}9^-KCA&6 zf-9>z#C{E-sACgWQCMo(Sj~D-i;LqN?!eadd8w`cD#k9DVQfPm!;quz#y!QWw^Fl` zrHj@2q^}%R`Xz(QX3LyfXfzu%p^0*3m)V9+T9nTKguSDjnclj_EA-D9CkYJh>F5yk zvk)3~Edb7oHjz@2i)Ef$oqormw^dQ=nWZ_F&;Nu@ze=#(E}Wo~ITC}o@EzZuDT3{A z_&r1lq(@}fZ0Gm1DHB*$C@CL~QA16DN&P{md!K`XxUF?feFkSl%h1{Xj=U$lVvM0D z)OQpBFr@olLVeWo8j)-oQqpTqv2C}V_^8Lqe*9C>UHOOBi(udHr2K=e#R1dP;mtpU z?Kos;WlSpwrHYLME#<7IeVzfn zD|4!gzm1ON{A+DE0;r})Y?Mrcy60&Y_sN+y^{_p{GM{IjJ^#6vbAONcHg!Lt!TKS{ zz_%x4`U(3pC|X|y@r~<)b-ct6jeQ*;>y+GzFdgxCz1bJgr+Mjy{qsT_))r#X)YlBZ z3BM$t%iFYyMT_w?W4@H{>s)p&?>*>p9-6kJbegSZ6phi_o_khBG&Y*(hdjdXZ8|?T zxqbvJDu9IqZVA}rhdKM9kbi`v;y*C^6irA=@EfDsT->c1w*OqI6RyxwoKW)S=Wr)}?HPHtpAmXH!T^;e#@tisLNk+f4@VXa8@jCwC3JILJ~moq?~! zME>ikIz7%8oE!3|TZdju{FpcAXnOGAC+&9;?T61+i968q_zBg_0or0aTngJ^hp|A1 z4Wm)PxqJ=g5J23V%+Xd(3oyT(pZd(T@%zkG*|BRt$Ht$df*H0{WH@sS026U6bNxji zR?d%2NShYjs8N!M&!7T6&%n(Sz?DAVX0^NwNJl}Q0tTgt z2v1k#i#u_yU}ga9qazsWYaD-`Yu%9P_+{b!c)jGVu#4oX4o1& ze8ai?^z=omzAP7^Z7GM-7R`PeuULbrKL8bTe9;C_Hr^j6fj33TqpilZNB#=b1(*62 zwPo!)^ZmwSyMaDkIY9s@HRQPQ$*2Zl_zo0%9*S(+%I_Ti+VI8gBqyT0NIJvkjL`u1$Wg;WL z@}GE#|C|)L3n8_6BZ?=MNXd ztGb0wM^`$w=Wf}zcI4*A(*FNRG$Bv@BvSH0@;WmS4t_i!5zwZ?v8e0MK!3$B2|tLm+wZY7$HlaoYGuYLB-T^TC#&DCgGydMc*s zqNncQOg=^nD&e!jz)=8W2;m{%eYe9O;KUh=P!035ToaJ%8fXlyJiaLS%BoIzXU3gw z`tY#mI_v}nocA5az?cHAX4Hx-$IK5~U)aL*`E7V$ZKVIVS=4yal-Jy4E2$Fg6BHM!HjDaeHHlW@7f|g80*)(Z*N$R(Il=g1lPrLNR3K2^qq+!|BUoR5K%Xox zbX?_pu5d(02Ywg_Y5&VsoC9-Ggx)d9Hw>7U(U58yZm3S*wZi=?fG`y7xH_e_*nl~K z_WUc5-M|$BA=XbUPY&1w@(ZFS@EXdA%!`?#*bZwePbQg~zVMWk@t$RJ&da9PU7AFi z2~FzGO8RhP>(ur=0DrTeRm~T_2E=xEK?4-T7R<~$soW4MHrYJ2+}}oPcsorZYNB^4 znAYUG^WaIPeQLmTPQPOz;&5<2oEu#?fp3Giu4=?qIhA=SKhphkTohKfefrY6RkZ#` zY!EpOuF99fdP^aN7nL}ohLlq9B*W}`|Q5tS#RW~87vX*y|6z0bzx{CDb|oN6cXe4;I#aW<>_y!mp%jUVm&w z6L)U3&tBJOYp!}TgVY9Gs5qcqC=rmy|~R3v#*`m6r?uPRHaX4^q>qXKWUuuR~vG z#?yARiT{B7cQw^*gtlydVDqt;N7H6-jT)uix5)|*5>GNOh&UqYJYNDyUj>YJV@$$I z2WyfV>hGbOy0vR+*)d$(e`Gf)&f@9yy64;B9virSaRm}2_e>xsf6i&H2NWuYk}6!A zSM4upF{~sVxn=8Kny7lq@)1l8!w(6 z+rv$dxF9I^t1D1wcJ{SB{oJQdx3;x7yEyIRW0X(IMRw-U!Ps@s*VqwZN`3uXgqAkMKGVr`L=SqwD({ zw|!NUjVHC;0*o?O$A!YD?2WI!_GwUrPO)ATfADmn{y_UqMdqa{KffZ=Tz17 zmG=kaFCrVTfgh4(w$XvKkAS)W0JRZ0N?cuD+Y0w6XiXyqt-{@ZxMq25?uf)5jqzN1 zo%5~qNwvey?_w761AI{1JPUX{LRomA2m-p{U>R4OOD?F*NpGujR=WMtteLWeE zyU#m?2P=**Va^(&13WsIdJ_s3(hJ8^^@)mT1iy#>=~{4FrvP$QZlAE$hVrs4e7Kyz zROE}>QA4&NS*IrH1|GPi6~;VcU39eA$;kD@>}6M>&u4GP^i%`aJ?;>n1g|GDW~f9B z?p26Y)<>N&M7Tw(B1f)v86bVvkh;&(8rh45*0 zbv?RJU-E|W&eq!fZ?yZ5-lJ>ZAfo;e+!ERmZx_1~p?gf$*TNARn|?OSzi~Cov*N&h z9b3^SeGLN9@}R&YcmgBLA0{&0GSi54Aq)od7uyUPLT7CzMr%>LDD{I{L^5_MH%dO9Mu7XV3D0>jfWZ|grl|DKwiC8xuXXQwj z+}r7}K4|f4@$`EUMC#If>tVhamPKb*^GdKjl5koGBONpZ4JprArCP@zjlZ5>YwSET z`^Obg!=HgG<+HbrU~i%XBe$CI&aB$=CtAPcEcUNyZS(4E+2U4f>3SFpKFHg~r3B)b z&O_5u%j~Rr=1af(56l(A-}w9QxwSSE-w;ul|DRytnBbo>5LjaYHlM(^Y~#IaJdefGO^z)%$t8unyLG+drI{fz zz3xZ)1s*@rUqDT@0D+!SX4KIyd^l!AL!XHQDjr2k2mb`s`MnDpFPLel50nehaRxuJOqp{mH1cSk?RTr_)d(9UmhHNzC;Jd>IBCQ+hJ;mHuQ;{_%oP2pB+}( zzCX2k`0NS6A=||?c5Mh>93*Fi>v#kNrKHV*+0R@AK~ChgPQKX0i;26Dx+Ar$;JYEWoXl#zy?G4215n{#BxOD?WX|E?~Cbs^ivh!*Y_VISkdpZ z@uNtP^64;d)8iU|EtvX)%sdO?cI?^FvN7((^4fx$?|&M9C!EEF+keemI3GLGrU5R? z1-I-Z2IFVC=o?)yQq(b4!o%X_`7K1p%K9bYx9;taUtd1o(xOoc6rEhTikbYgEY>K$ zCkLpPy*ZDd0Qxp2$bNV1vJr7JdmwWRk$Ac3v4&Zgzx#i=yJEN2%>y>@;LIriYY^o4 zV|vYTZwcJph0?>g9uLnYzUF(}ndYYO-6yUGI;(woDf!Z*NwzTiJ80}d06msZycCRN z&YWISzGu}A0xj6ePNPF`2i@H z{r3ml{_YY;`R>_8aJ^-~H0Xqpx0PU@HgYp8U4Lf&OY92&0(3^fsOc_uUZIT<*FCQ9 z*cfR~Md6HNV~YJJ$)Y}KO@VR4h z*EWiuVKa9BteB`rdoe56RESE^NX@QeU zn-<=48)Xt#1(Kw~A1ZhhPrP8Vb3-oYt{gGnA}6k`6S?`OP@h!&gsB^E8j^_FK58XF z{pRy#B#7P^v)^DwOG#NbEASOaaAd(D9VEAc$gcb=Ptfx*KdVp|ET$gy{!l`)Z3Rv7DOM1k~ua%P?B7yS3MPx`EDaRZ*k{GzR)sMpOxs{ zi1m6lw&&1UH{5;5m@g&?re*DaI^w@V%C+3RPzTFsmFB~)sqU}rxp!B4%ltv5wMX_p zXL$>Y%HOvNVBUWDmnvmF{AUpAb3sHCs=ES82R+#Dd4^wYjz=Ijw#R(P4_(eti<)Fd zp`L@_5A;h+b^<_4VpqD!NtX54JJD3Mad=*4qSY}!QPSPz4jrTm3w?M zeDXB}x~I6+FEBh{$Y(x`x!*scGyh`bXgYt?c;|grGpYp0c`e3s%|e)cF2h`Tnrf=O z%ea;M?qX9B+Y-N~T%>dss`=v6ErCBmruEq_h`Miu&2(e6fWB@%f|cDl9~tj)eXV;$ zZ$@oj-%zfw<618+c_GF|7@Q*MB3McWO1Y1B6r|w3uqKD$O#5gPV#+sD{XzIlw-5lT#Mj~Pjlq>LS%;a@YR?V53QW98~%20aFobznOoMo zb=j{xUH(?lj*n-e#*xzqwkJ3V5;32!Z|3tkrbp-~;eh*@38tKAlM}=squ*C|*gaZU zK-7PmieFpVE4Z8|zy%8~-U9;~o$Nqk|L(<2>+3)XnE34mc{-HeGeG94jI+(TGFZNt zI|o#HJIv8oy2N{5n(>2HCn`S4ay^gTAnf5atLSeK+ve#n*`=BGcw>xp353sJ4Lk!+ zlg7ObekMV>d~qqVoRzdsHQFXF%259dzxTbLH_7$JmT-;>4bsxNJ#K(zxTuTe}9 z|=b^zOINvJZ3I z5OWaqePiB0V)t_TZn2^_+KU6-=N+`4-)>o0Y}6Cl4CNKA4ykTqBA__0kH4@_j-TWrUEL@*ZGQ_;nMQ5Crc#-dQ5 z?HByY@0(zCdpq6P$eAS!vSVIo&WV_0fOzf%#?+r}>B^P$^cr2CI=4-esVbZdrbP0!Hm(zzxy@>Y+5un1W<|H*^zVw#(y zx&7L!%4upWg3Y=h=eGBL&dErG9Td-0?6nb_{F$DeQ&s9UGi3QYU1Rsw#F6)fZKrte zY^>3ypnUIxQUZ~7Q(AH)1p?>-u4#i zL9w;7%ab{08=+TRw$3ie*_eAa4VzdFs7-YoB2pT1u-onq48Xl?xx|1Tj-MTD_0pB zkw$Pcwr?_m@&v?EL>aJ}>+z7@Twf1NsGLwbU2xFQ)NhjL8+Z=69W&m7fnB2iBXI&W z;|J@FXB3^8#=SMV7XXV&9g{>m%#ihJKt4THq`WH|X(*hicq3wP$v?(zgZi>1Ja z?lgS)S76B?8yW|stKhF6;b<+efTRB{;K^BRJ%Db_fF%5L9uDX+z`e&?5maNw;9goU z{Ty(V2TdHLPjAI&x#}+T+1ld^v6LjRg2^)oz8HadV1^wG&Ct9gyqGm<1lNND72V60 zj<;r-!+$h`Y(PuB^9cd07LIx5&^Z`nfoGTGosl<%+;{>a#PZDT+^bCUKI8azL+N~t zOV*zYtD|ptO&obu98q+oafsLMPGH^D*3GL}VIuQc*uRu=LzrV0A z&1Tks`7X36tb^88$J_wi0^o!otRyRT7*EqtUjT>EZL44NKUC&kO)9*aOdGs)P7nA= zK5ds8|FM*5VLK`{;9pQc3v{N+F-UbNlqKq%;^HIxP87Xo$eDoxRUbz2m22hvUaYLa z`uB75a?IX}MvF1c%yr-I0s^jI0iF*)CPO&)u^lEgVR&IXmSRVnHnT4!Y%^@oSt|RU z{M5bv1KKclRy;M{r=)o+?~LI3tcQS0Rr-UH$l#Ed9k zte=V50K#SZul&4sF^`)^D5{t(lxkg?+Duo!PT{60%`1<#f|{?eG1L5k*}cJ<@~R>fX>cE7KB(5ql5t;8e{#&qYzW$`Bz%D{2|YTpIA$OnV99_VMaD;>fL3Z^BG;WcK%IYh`1l_i;BR0SPVRh_ZZNWI`z5{3II%$i zGyyz=!-S1Kzl;0^m)s^X&qYjHoiA~!{V~ax9aJE!^I8CC{26m<)X z?hY_2ID{NXCXy4$JKA<}@9dw6tfo~Y)tYe%4vLV~)9&nFdoef1#{Ktaa=~?_0elM+ z490*1^L|%1s;;819txv)-FFC!hIQo*=TEP54lkPY$vQof5?U0v>?^;H>dGX6vh%<6 z+$ygUqru$*Zh!dW53(C4#C2@5Jd;mzvVqsld3aybt1~_ve^wOi=8g~KwFvl|OkO5# z!jg9d+_B*#2PO}e9%Ldcdi1h{+MVm(`dGgBWAL$)s2TccCM>m8zq&k`Zk%8_>#>k} z`@m}K*P~@GvhOo)65%4 zDSXo$(l++i69O?m1%wxC$(gZ4wjpqn58^+BK)Z~&Wpws;5RqpX^Q4GpiIf7w+Xz6S z#_T{vcn zJ!rz!O<|z`{#4AEa~^$@S7{~7!9=2ZNY}A)R{HuKJY0C~-O@LYoM<5E%#UF#(7;ObLD#3HY`5+?3W)ta_cr;eJc(fk#{ zj+Xuv2(y!C<9mjt6qeZ^c*#%LUcAN-(>YhS^lNJkP9kE4=jJ_cM(0H;_&%OE-s>+p%HOtxrL|xoV?{=2F?18#17Cdg_8#iT z!v$ai&E=O-O&C!q0t~?(D1?cD$6JOIs5MukE$40;w4S*8wq~S5WhMP|%6GI2-3j@Epw*4QE4cgz-^h^@Lr>UDxW4#YN^k%44hLq*EckB2|MO#wzincVbDq=rW z0b4U!O8#S5U5p2DXaHOiGiIaDJbmAIrMc$2ibe$@Uw!ru@A<~#dq(-LAMJIL5``BH z?E3-)_|90$IBZL#aSvaUSGB-8lO0&u>TR_*fu{4Qa_`sJCNWxiMeSnl`17(4>L!*8-i019TK z55X@HpycXWd{s}>3-2vYuK!$fH%br`j)BSZ4lg-Y?amL*8|dA*Y9?!H`%&kET1H^1U;va5N*NFvV*l|R-J_vCe zMXtkmt=XW~u`w<4te|H}{vE=??)I~?YOZyWiR?Hq)I@B@p4KZ=q%3B7e$R-_KC}@_ zswSiqAIMQQ$`5dSQt(l1$rh|=$_jk*z-l6nZL@^X%lZ9x{C6T*XDggk3HQ70@ogNR(GX^4GilW*|g!TumU>*YvH3F+m*~Cw+I>T6taKB;lcH^}Q`ZN*`CX zvS8<;CYQ0@_y-tO=o>TiJcM9nO-P>ULcI<&Jf(e36TAOlvu*d|_>W(+EbxONAUkuI zR|D$hTO638l#_%qh|um5ym%th%U|o==!-kZEDgl(q*7L%0FEy<2zJ*5aw>`r6pT_P z`PNv40J3Z_eJteWCuiH7tm|3*YUr5hpZdSo+K%y_5q*t!aQ94bkFgwS!EZ^cX|0}` z*4*W6LW;#-f$l0u?8Vgwg%2PsnwsRY|}+$NR3Kb&&{Om z(SoiX`(?ivvo$&&H6Y3W<0TCEXyOQHH1BN~j#LdID?1;GPqtI-W8c8?S%tT68A?|y zR5MuzV)FzzIMC4X2(8MIb%UP#ORL``m%nHE_MFc8L8?kSWeSyFe&gnDeBG(z%&dad zUe9CyV1GbF%$OqO^_#$|Mj}W2PQj!S3 zmDdL7$gR@>;gjz&(%2DujYO37?$kJgS?qQ*q$7YDxHqMf{~<(I4Xt4GjhFJf?f!oKSgq+;+>$j2OXodFy+K z_RPfl#7<?*_%m#KN?x7z_xW?)VbttW|O%1DxG*1qG zrDwa}7eB;WMyT&Gs)Y{0QMIb=-E*L5PjZs!Ozvxi- zlTW2w+2wFUcJHRonEK0-45`5NOdySp?^_k-?i@wybL<0EPQIr(3hyvmNDb5}tABj5 z_?pcH{4QARugmn|v!W~lbJ+>X1_PW1GFcg>3U6UZ&-+DFN zEgbmPIX3olAg2ny0ASKYa7Q4o1wknTFg7?#YLu4vz-pI2bNND$UDu#gW|+tHL_590v(qR zxjoyJ8}jM>870>dvM|;+BpoZINDJwyW;i;+r7^o^`|h@sWO-Q*&m7;?nDp{(zozD* z_C8%xK}Z6O!1pif1FO)X^X$s8TB^Hl!)VPXqb?ou9a7c@^#9B_={k-ug0XdmF9^Sm z9p1FBYEJqwW81%B#+}9tffLSw4DB&*N6hqrZiuB)E|RJ9^F2$$f-?5X=L`N}y}z>P zhQ+(>Qq~Um?=ae#0#?^q$l*5NhaEG`H&%ZC&LF~-y*7Axcl$4~huZGqh2iO&a)R7$ zY{z@@+9Tr`6Mip|_k41?gguA@8i8$GSEeUhis_OvugTo!iIjmh&c$Bm9F~m_5pd4E z&HvJK1yntWl&55Z=*k|>g-8w^pTgIIklldySN%N4v0K6A&&4s>;{L-y+JOld4{5Dd zDdAlq5P1rJfvB8q7y!THAH?)~)IO_@jG$#NjWsyIJ?GOy!tX?M8DRH|BJK{0eogGf zZ|9z4`f}CsnJ3|?{M|^I07GiaGnH?KB@Gvxp3OAc?6Y>lyuo&~w;410K!%T!LR4;b zpm2bDE>>SuWhL3HRQ4&L9e#D2*;iD3;y)(Bm(VkgS0pGds8TYO{Bg{>^$U5uKYKSX zEd^fL`_zph@k_+^eqlvT1hxTOKftboMmYkyTvpNXa2HPs3(Fi%~qt+N(p=Jw)kNT^e#5ME1aSx9v($-}_Ud>2sg2 zr#q-f(0L73;sVT}DPsG)2`>#nsUp_fb!TpaLN2oUVp>sA((i~PUv@XujXezs#O^6D z-wm4|jMnGKV7iIQTrXfSk3t}=zts$CF6*Z{nS0ea=^p*EsKr2T3CsI-;Za(Y-tIOj z$djqd-rzN2jJZd6uR%EWS3n*|HSbzg40sFpS=Y@`!Oiu%_ZXGf+9tbY6a)_2=%Ilh z7dMOT*jw+3$|TprGwK1Wu#_QwXQC%Tp_jxaDbMc8(e3|mX;Dt_w<1>^_E$hJixt5G z5?eeq{dFwcN|S}x^gFofoCEy1aO~Tgs5cYMFTX3~g*9f}Juz9cop>`aEUmZVBVuo} zl5oaT!OegEWr-zm1;?@;j)P^Iot7TuU8z;2k-0T^3Y?=G`d8q4G0GWy=Ra2}7e@e@ zJXw$(>w*D#`Yux61G9ottLNy;?e#*Th@XXu1e^s+g`dsRKZf{tHS)zKe{WMOjI`<&b{JW-8yeG z(z(P|aGvQ3(S4>7Zf_H=-fYG>!8ryB2>d-j0`)7{cyf43Zjymv+wSl8fiT4T^x0t3 zxucS?mvnV#tMy->hv5%_XUPJABhhaNbi;P(>tj<2wMJV_Y9npfFJJe~(r2r(Pw+DNI+6OFxE*03B-Gir zV^$8V1Bauc&lwsVARXIUgPWqe5kj+`X&3%xivCYEDFylkIEZ%wRV`mCQD$ipCvJ5F zj}7d*z4!Il<=8S=hnsTfG%*2@AD|5l2N|`M1XhEY-O1kuFQ4IA)JCGut~FWW{a zlF&6T&-~m{CTV^l-}OyX>$}ZuQig4=382rX{T|GE2x!3(;Em ze0Z@2qlTF#C8nCAUi98TAHRC%W>G*ODOV|ikw z@cNnVhwrfU>4O<%x2*NQ8$){{0N^+Z+i{fWfNy5tBG@HG2$8iF9;8R>RzslsoVcu;Omofu03$3 zGZM~qgKl$_BR4!C`Qo|A)LwIs>k}#`vh#8t*Vc}8XZG3Vr^?O%3k;G*9nx3x*^^*M zfAGf;gtiw6(Z*e&1I2!8gilrPkop7XqO~%$mQf@gW+%1-BpN9N7(H-xB&J(|uL9v^ zfDGM7wpUd5nTk+}TZ8btz@igyLW(YNy$a3vQvFKD#EiPB?b&)qX zd9U|&%35X|#)Rq1$mUo?M$sbDTFnD@Kcltiw0KIi=lW?rIef?c)*b6=;8Dk=a0LKf z{~Z5Ap#dbw%sdj0C$l_gWXpK%cA z9r;J0ItoKmKJ`pcIBR|I5YzXjP;{|SA8Y!HFS+~ zXPKWv?=c}uh}WVZ5RYQV0XY_Zu=@nY>N%xMG|mrXdE?jP*8CeItZR2?Gku?iAGX!V z=BT}_EZ%WhNa$vk+a7%^?z--~=k zdJk~0c3>?{5_zxr+CcxYn6DbZ^5a`Vu9dtNC-YMtB&yiJ38O;-e^NI4_~Pl{+KqoW zunOGUu#I+vT%aZF!2(Q;*>nAugXE_V_dgH*+NypuV_i@UE`r&L0VvI*KsZf_SN!|N za6Nnn6zWi)v3W*Cb@Hs?e^JT%QIEhm4VJK|C>GGfE6x3AQ(~1Du=1(K2@KEAqaliD zMwwtjn*P@(-|nmMyg-nc%n3xF0<(E_hTnlwYz-_qQn}<*W>+3Sx@nZ4^h)ipLjPud zY-1ZWm#WBEjAHI5`g&cvz~s%fk|Nlr=XYJvC6N@6hNWwW@l}0XZ_FW73m@~_VvOujvBw$@@HzXo&3{3(cc!{`{Z7yFOx@t^jPziO^0nDpIG=+~2Wj~h79 zvN1QmuaGU5&1h4b>6gAN)u*uh%jiD*KFEs4za)MYPH zMw=#dtjhz|HFpQL!~gcd>Q%_PbpEx{pWhPN)~5(yj)jo`X?Brn0rklE$(1s#ZYb6dJ!^SP)p z&nM-m{Eci~sopc99}lKYI)Ei_F~Qeg#@6}9A+EyG2yDxWUVO4;*M_t4k<+dG8zFp%-E+0pE$qKG3mN34#7C2 z`Oe)_NaIQ}YG976)Eg+lw&BIDNwoyZ;!c zTkS8|Nf`OYk~vLy?YXo2R_i0n%~(+Zg2k)DnNzSna=j=6D0Pv{*&kVQD*qR8?-|ro z_x1~;G^s(lw5T){5Rs-*A|eQ)U_+V^6_FA#N=HIMkzS%8pl}N)AR=O*nKN_dIdkSYGw+A@12BpvJ9}Sit*iV>CnR~h>8mNC&3bTHU7!2+%es%u1a*F(oT-mEWJ=hDA z-4+ZKXvlT~^x$}BE}oV})j~j4rn)$lQuJ)Akcx?0-fR2C{CQgupf$EHFqz}~GHP#a zUCaQ<#KcQT>FjRlAmJh&SYg@X|A)vaDf4CK);+&pf-KAsc{+1YdgInT$LQ@?C!a#t zCkJp4zbEvn-{SF3S2EhUs6d<}R7K$Q7!vbySxP&_x zty##bHU0Tcw|0dM=eY}S1iuPTzx?mR>HijH|LgA|IP*K_q3J=^b>p}ePjvY;2-TC% z*J8XaQ0t37O7h&wdO{y+n0>M-qh682mi8F5aNn_pQ4YM9sLCAuIe6UlG)-mzltvvS!FnJ3;OanWb2(SP1-pE3bRPL-!RPrfEn)}q#m4^> z1Bd_bK1>H*5@p-=W63ID-j2B24D>GQS5qPc@*-#R5cOe%uFGc@Dl*`Wd_r62`j@9+ zXL&d!gk0Pme0mPNT6eW_j*PF%CZqB?at-_07xL58P`|yW?(?yn=GSPoEKBTg0o@MI zJHZ{{8Zk_Xl2}Doq?>D42I&{+0D85s!M^}i541G0_4~BMpNri9CkN8>JR^3_n=NJ8 zg8&mbZ(XUS_mGq${myuO<+PhnNmKmwcku@iQM6;A(eTHLZplP*h@h(mBplL2n7xoM zW51n4%8crxrom#Sh}g@CiCrrcg0aTFFb4MdJ3+AE}bK+bq^mJDN`ZBr;n)UJW{ zjoux-em)?PFI|vzJ`*`u3UG$AYori3q#4@LigII!KQoRhIG3}!9pK8}Y&maa>@Z51 zCziPK(D7i4ON0Vh2iW2axn6Se7Rvi&SisOP@0%yJuV7v`E`JHzNmRiKux|C&!+8=qh-3B5{fJJzT{zhazM}zisiz@pmqYr6dXvHFsBdO zfmP07^<9-yWZF#;%eyh>TY?8rG~(nS81k0Sf=qxA*JjSvt{z(50P@=+oc+~(>6a8=y)4~) z;?=Fa*Q+)+4I#I=!6_D3WYd%7hOr0Uuk{o=mP2>MXFRNbT>=aMgsyyu4PTD<*mQ|{`~8aWB#m5k#O zF~W6XSZnTQpe};wMoz3y-y+_F^=NkyX)J0ApUcbqNkYk%ZC!85dS4cj(*8+tk$3BM zG8faP$@YVK!L@ioy}_(w*v}_Q$njWV$d7)8N>*@{O?JQJoTpQ|l##03D4*fDEzH^a zYJftDFJAS4S9$x~*_%G2uPPf*dB94$H{;%M&9XuS+ z{>I(-bh0AC7e|6!h0w~arHO{LyKb!x*N6@^>Mf_NuOz7=!qZLY0F4bn#?1GeGVX4$ zES(Jq6G0>>rN?|1aoA%SIK+K>A#lK(_rQ&3(g!Yojh(5-Q5uLf1R95hu%P4YLEwf> zS-lCX?t0KuqCA#!qP#cUALW-Jvv=!KfSx%|+dP#-4l3 z(s1^>_ob_+R^BWW%`a8%#~#Cu5$j8P3n0y_d4+6uU|U>)aDhV0{Unx}vbY(0G=^_A z+&QCKj(eM8DmCh~QUFlcFT%*3Cvd44y?gZ!Ldwv}-)cSv5TxJik&m<}6pta|iO^v$ zaxZZb&79@@(}JQ`Q}Ia^2E@dfV|M55tlX-yPaR=MCZ^yY#aNF#Moy^Xl!^49t>nXi z7LQ|EGu-2zlv{~A8vEA@mjfx__2cgkA59{zH zE-Aq`yFm8_S$e^i@CxArki!LC=-s$>>l!$u;j}uI&2(KQ1^R7s>%-zLynF;jM6U@x zZgtohg}Afw8_yMyqmz5u_H$B9eHmJ_Yw3nWem}0n5J8vrb7=lIX56N4hi1UBIc2R` z7#{2q2UNK~5rRQTNS)SaE#BExNOAXYJV z^aPx}n@GKy!@7x_SjL*Bbe?$M+Bnj)@3E2blY2ahb)F#t`X|Blwh^Vds+im0b~c%)eTw2o_MR6$ zx2d}bB?$u!txxKxL$PtrqjZPM$Y9X11o#b{9MKP#T(AdlybDq#Tw#hBV9nBRXcwe~ z4wcGy|BGj2U3b**W_MP$`Cb||iWVjE5a11wSUY`@E9KY}aq%+$T8q$FW7 zfmGBqjSa~wbDyS0AA3Ul637x4aJ{>HLVje}361U~`ZB$1NGqo|NU1kTpPp6i-ET z!S-OJ7(0M$TS~iY(PER=X7TPpT={f&fzh2Wdn6^octly_zCd|t2BCma2D_;^!-*}W z#eA19=IK^f>5lGn-PrX$k7L#o(l0?d8(Zc9=ydC<-L81BarJSuvzHE1E?*{+^xF~j9|a*IxSsxF%|Mp;4Ou zWRK{s@$S|14frruYDm{*E7%MJHo5tydG~i1cY>_)J?z(`K>Q%+KND6B&@0KtYGZ;q zcykp%vT|De&PeFN$}<3q^Q(K6#GVqt}D-=c+`SVI`NjtaCAt2@g@9e|AbU>zi`c*XHOPAH;F2OuWz1& z4;ZthSzuP`57Ggy@CrSGDF`ma40Cd1jxpL7NR>I!`B~>hzV*F*qOd3B5_`p`oi=GK z6N~^65}M6>&U=wjn#lIo8I8FdOf^|(%RMTm=;_UR^MDdcnDgWcxlX6JcuI^=3&S^>E1W0)J2Bc^+FJJWWKiJju}VyF~GdpZ~M-kG?(uB1e9 z+QhMrhUw24N1KZ+0ePDp)O}REY~t3k+{c(>q^m#P`kmOnAwzfQB*<{dZG4<3K}f}k zFqBPAW+zGQFa~k&%iVdquxKyeGeY}#DB}7^uzj@y_zW5y2l!m*7)$D4=aUGna;+q7 zLwBQ_rYj~N?I%^y*Utz7Nx|#5b}u3tC_5j}T?J_*&>+d__?Ji6_k?)bEB9V+)Z1&< z_Pi^x{pV1hlIqXPgV-#VF$)fnyNHrRuR$K@U!ERgfi=f513SCs#>Dmv7gf>z=w%e6 z=sz6ZCl{b1Zig&l`ILR9JvIOCGs2{03QB8>|1LRnlUUA5`~|68_=gM^Wc>KwUR*n#F(wmL|jk z!K3pQ;6}+4_{+m=y*HCf3h^(>NPf(YO};USOr0hszq|7Sk!O6NcNIVq`8C1r`<^?E zqn`tJ-VZft16r}19CM>ymJRS9mxNZt3M(C?eHrAp!c!gE4=Dm`ANp}- z1#~yO0(RyBfxX+0MIEbrGXcRa;l!uj^dwzL@KfmO>@2QdMDOi8|2H_o;_@w2F za%%i>w_vd+)>2G83%`d+Ljm71&nGx!>7KR{@78}NoGn;3)z1@xqhA?}DWE$dl8F*r zIX?v50jWfSoK6jIT4i?8?ewBc>!$Vp(F!k1jfKNqIgf_-kM0|;xbdx6^1GT%^@&u0 zM+c@)t_po3ESPXb%31e->Jr^ykuAfpqnI}rmOeDKB)BYY8HE~YxQ*&J@IOrN7Ji(c zyo)fR3%a#`=;&2VmehIH6}C;P$2E`m8i(dO>jQy9`u9e>Kh()@O_}&!#Y+H!wCl z6c{13rOL>2^dCm|K9zRwxvX}<{+DRUvwM4DMV-FPfRTO7avP|%_^KEPT0*(cR~Kl! zJ+~vw$*Jo0cYpEMzyFvAN(Ag%<~9_ZVA2Cr#TG^ulIS-!8n$EP`a`|uj<;P^lY5A%cc^ek!!{_}~n zf8^ZspSK11u>xuTIQ=#Q_w{Nsv;`&~?T$q61DG8QyROocPy$tu`*oe~_kSNc zeDvwDcEX}2^9VhZmR1M_o^FFSsWg#mUkj{jWyeVV53@&97It=am9_BSlc6|v!NRLNc_U)3LrLR2XL^x>GrE-Jgt9gscd@}$p89j{TbpUVGY5?dF&<9Zp$B%ZySr-oA_}+j#v^IjO;R| zrJ-5D*KqA!NI^D#=p0SM{nYux^XsR?JT)ioc=~_-O#hQt9HQ*DpZFdZl?&@7!otqF zAxLuWBf*^OUtA6w^m*4NTBS=DHUG2F=EFPv`ehqGxY9iC5K`0`D`Y`M3bUO!FKV^WNeDrV)oaV*<(yAmGVw)4 z)Ask3$cxLW*;3O-27ylD)=V-RoVqcuxx=_xcn5w05E!Zf+lL^#SeI)bSE%fj&Fw~G z$I`F#4C$FT{k;2dckVh2(m?kBkmmwzoh2To&rAnxVr8ul+X;yV|MHlBulas-X7T&) zllei<&ssI$8|CFy01>s(3aiZR0(+{1B2>WaV}RD|8D?K)^>Evvu$ze5B~n_V-sDQQ zwz1lfHF^2RRNsMP8-xVJUE*Jd1nEE~(Djdbj4|Zo*PeGe#n64oRagHs0;uT6JsXey zX}hA=XRP~hU|uUV%7=Hm^d(WQP3S*9=|y3H1+=FOa}e4r0alNE0D1;LkpZQfgjKZl zKakdoK6~T2#YdChC-?LR0%Jj12?P9lG$XH97G7=L3c8QpoiH9honrH9B_Xq4r4e$H ze^jpP728-Jwa|z{-1i}L!BU8I3*9(K(}AW%!NnnJ&Fk8<>9DSp%p0#zG~xDOuLt&$ zT92NlJ!T!**>(tgjB@NWk?sUqU*T8g8(wy}K!bBw=m%#sli#y( zr;6L?1;NdO9%3wqFx=dkc=4Sb%`;*|EE8@=MOaxmMV#BZBU7VL`p0Ggd=HS=Kxa7kJ(N@xGlD|GN=2* z)#ixecEggU&YgcuvTUtbAC3%~K1M14F}Z3`1<+Ht!sB4{%g2VYB3?jE%5JvFYgTs3 zX8zemS?RYM9$|jo^so`k<>8heAS@uc!d|Qh>;#;C)|tJ7(M%Pn_nia#I+Ww&u6box z^?l5kkH^I)MpZp8ruZmmO|z9Hd^%DNad(sRsFpY-)vmz7$7zggWRKBI4UG!KI$E1_ zpYCtSzi`WC&xt2{d4b03tpkJsGNh3}`$(=QuiDL$NohevrO4$YXX~%}1Q31eKR1A) zGx+I!WIntSL6ZWXm!H!LS^(}t*u80ilxY>Q(fn}>^!qM_0!{L@7aI+TR7>;aZ04g)lnclBjeMws#luFyA%@O zl6Y~4uV~(n$WC6fN@NzIicAAq6I|gO)+vm|5ZEb!n56`Wc$jYblcxR_y}^h#9{cuN z!vEPLsjdnS0?K!6&?;=(1rz`j+e82`?=FIpN3K2p!+fv*gRbQ^>G8SKF>Z-xW&joD zPbl7z$59uEhId0r;2!ER;9dCLVQy3dEH9|7sBZl``>aRi>NB8TuYLHzX1N`V`SHf^zeC3wfy^8A z;3n}hz~j#Yp|lH74hYQCob*~8sc#n6jgt%0@4j?xVoBlZ^WxxxJ+*Fh1N>Mr^XjMdcze0+SMJ}O4l@g|@daX9o| z8j$G+jMWjgZVC6xjG3Lg5lPGWiL%MVxSasygeO=azaXPpBB%)H5R47>)0Zd}4f@QB zS(+}TE!)*y_sW4`(zKg~JMy!yDt|F1O0kv)ck^GKs`1qkpz*hMIzv|mW65y9>k_WV zd1rP#NSS#X@G^}iT(|S?odxCcl|#4Q_9-3}eI&#?LzF>Ko+0ZHY-ufbTVs6lX{>zg+#HlnLJ85hzdHV?b-rPT+M-?pXsC;P|rF@jioY6OU)b*<} z{jH;|uz6`RPpcKqgj@-y!9Z{ba9Ude8R+v+9H*Xs7a_PD;JTI4=-`$0e}%Qpq4AK^e$@dm`WAx6MsrIxKbe$9{G6j=;79r)%4OQ?*ukcVL7J#R_>JF-`KRG#c$ zd07E*9bWD?5}HP2?F*A*77xF5JBRPyz7<;G*K2r}k7&a`>x zbuNlB{t7#VsFZ!iLb3I8DBR{b9dt*&N=t2o*2?)kMQL|mU@-Vbd!8Nvy_0YWTzez( zcfuezWtd_(pew^lK<0oV8oa0KDNdAuj^>8~QQ$0}ca{Dsg|{8`a{1C}=0~Lk#36x? zX2*dWFb~%eLHUJ@IZ@Cx2qraY4B?LNzxLA+iG{>Qq0G8HC(|aPM|rfEo|J`TQ%xLL z#0|sj^Cf*s4=zF&XT%N}>wJsByR}SQH$KjT7b4Twu0l=>WBU}xuba)Gb^g&^Hs@k2q<9saWBP+|loLB@TCU#+bjq z*arHk{mXMj==cYU0uNgkBC52`A)yoG4|sZC5F-rN*|kE0eNWf0{_qI@dIdQtgAL<$ zlj-)zhqx*M;yd=G^!d4NxCG|vyt{W-?qhQBJqHtMaDzRo()qCo7x?X1ESUy0akvpY^Dq<9d&}pDA9s7;daFa69I*O28GHheyP|QhpyAZ!d@e zeR!PrT7oOOgYdBF$_ewNlGFQRX8479l)?B(N~Jj8wh-2ZnBbke3Q|J8CB`cdYJ9yw zDb9bR{Pb=7hZ(J8J+b^sfq?hdj_kO^2pn)2+$1a-NLZh-L>>bqn5vw12h#fN6vhym zEIIt*mbxt^ODLT>-VV$6v$!h^3t5onlCh%0}liKQoB2;-T2bym`;onOK= zc{3j5@(eKErOv3*?^ewIT)}ynHGpAJWfjhqYl@?c5qC^tL;&!@mmIAyEiiR$*wotA zRzU5D+|5$WjN^pWVWM^$$j#dgRyT2^!wx|1|2pFwQ4AA_6PygT%L|i?@IQ5!>=WH~ zHF)*A5AUB(AOuPwTo+LSL7B%*F4#i%o95STV}_SG*ENH#4*fbR*J}}TVw{$PC!!0c zRDdMB+e>VF+fMo|Ih<(G*NRPlr1RtZhtxZa+?6(k_U=0QE1d9}=;Z)Zwqk&(fZsT< zEJ-4LnK6ZmsA|sd45xlL9_c7bte8_eo!`;w4Uk5uL2$ge{?|4=$ic0Jj>BX0l^!i^ zkLBN+-*enY)AD!UZd2M_0Nnr^fZ)lM2P#?Mi9BTdDtL1u<@wnNEjMY?>gkrE>lWjt zDp}iN;Fmd|d!7E5Y{@qUX@NaDDM{@Ctv>E;HqDDQo1DSx-8QWCp~V9HzG95%gHN1+ zGYGUvhQI>#cHXS**xI?T-Ayh_9Y4jd`cm!Hy?PbPnZg4D;|?{+9X*E0@)teRq;EK0 zxel&|pT~vp10)yjj%bn-^Qh=i#Ow{&f(-7OAymTh0gpi%tH}Khm#e|25aqZUVRgsZ z`eo1EEURmBrRzsZO>BN!oVsU}4k(i^aP7gs8d8#|gjjV4F=u&}eHExu;1Us_P^AnH ziia7`KDp#jh8HA#55Iq_*^2M&ZyrI-pUPTWa?D5IA>QZ(K;ywrtmBvqP$hLT=s2yo zb~OLsUYFoqKdyhU55b8a(M#9*O1uH;mr}6sZ{XtL^kTN*oHDu_yE~>kh-Ieh=2H?s zCSmJ^_lpVLX(0$YLkqg>-ImNqDDLCkfWlE%(^wfx1tL2_Ud2#+NK@;O&c3>~k(RCFzSm=DYHlGn!+$e!xA5@* zeZCe4>`+X)WmQzhHZ>W@)BsXx^6lWv%h~5{$RAg9^i(<{ze73*0L9mUhXU@WCyeCD zZU2hfhdj-G0PU;j2Z;r-ic^TY?e_dAxyM6^{^mK({@Xj#hu?I(0~OSCVk;ksX18xU z4dZx;ltehpoEJOVgr`N!B9rs=3c9zaUVQUv$d$F5_!|53^Gm(o|9B>|ISi-O3JMw0 zA<#w`CQgi3jj!3p4l!G$9n8T(d;eM#cp``r=zv24 zX!7Gp84KsDGCz!+_XSWR-%z-pb1|;fbY#{TZY6>Q+_6g_KvdxJxK*dozx3@{VlNrm zZ=6oNNqBey(J;npR_nN-VTxOu)Wo%v`^3-B>;=YnWwwRr)gQ2btI|$f z`!P0*s+%&SHHML$Q6Ih)>lSJ4~2aPA&|`On{R zizEof-389ag9)5!;_5*dHy*V)$Fv5oc+rPg>D`XPM->Qg4~A9g!W2W}Kkq4y>(4Z~ z>$}gyoEaHL(B$L-Q6M-B;e{vhx^arl71>u9(c|pPAvq7o1qM3Gf2_aPU9A3<4|Vfk z?}sVx!BJ=k+3KCV7_<7G2=1cOMgi+Mc1QtD6Z5A|JvX+`bWo9I$ZRG2SXV;iGS5kW zZs6Tf{egxw;C=;?jk@u;J)p=D=aSm^$7|s`*ca%V<-T*S!(#`r-)?mZh&3Y(xb!dBT`1pM#snNbNrhk%A2!wwTE~2xZo{5$nT6YqY|?V zAQMgQIjwdg(`@lyp6w&!n>xrxWcr0cNKLmBFnVNGLx>7(d&6>jE$SNTTk3~4{@hF- zQ%t%4`*ZW7y4BwSKDccpS$K9e`t00llA8(7h(7tT%`9z1#ID@|B%+%4e2|(U&_S z(3l)ss-7$424t8u#?sqFAd9&{;FBnaAG|eGdwhS!q*uf7aO-bk&E`-ctOLBIA;_&l zzG7~GCQs(y4U_Fab(ib*5NCM2xbb$v+3)h?+sm?_vy*oHj2duo<#Y_;uKx@4fM(&e z@mU;65jke)ZaF9OD=*Ni*!InGs9Zpww?g!R-IZFk*2nKeIKA)#ERpks1an1*^@clw ztF|ZN==I%PRXD>m)5hj@)#y}B&Q&L2x@l2OUTDO473Lu4@rJ`r2)MRFeRCBLSUn!b z#Cq2L6@|n!g)uTW+|@$z?S*{^yWUqRYQ2Io70GM_`woNLiXW%$G&d}|nw*1cHQoS=C4 z<+CG~uBB!iGk>yU8CfgV-vX~T?lO7y{gU47bLZ@vJnhvvja1?e9A!8I(DpBlrdu$u zL_kv8NxaAgqdU;EVw851<8pAkZ3dVd49!H0W~i5X%H&(4?0`>-J)TH&>Wo3Qe~Xfd zL>Fd~pa7Ph2d*9d7hb?uGxURw>sU+nIKi? z+^P49vGEa?DcjJX_WenA%_=;Od(=4m=aFjMQCt3fsC&68Naz6WnQ%c|C=gh?8o$TpZ?xjJw`E z6f}7=ee!X{trvG4G=VPVRZy#(!HWCoVf%0rL=-~$49M#olG-#H8`hnbYA#d)#C}{- zKhA9{^y-*V71_h4(o$IefFHiBh{9k`+{TAekn6OaXA@cjRzoh+>K=RU1 zE~({A1!}CxCMJli0I+T{I!YKFR7UYhZRix~-b9@~^2 zRJ(KB>GH?@QAb+@scSMT1=Ya`X>EsHdW%=&PQXdEcK575svpVDiUc}GKNq-SJ|k?G zh&dd|v-d)A0X=bf=130f(7BtMw?fv1L)hg^-X0v?o=8IWstDquN%g&v&S3&R-EYUr z(ek5eHA?d57s%}%LMzFv73K|2PMa7&?CsiEiy`vXyxw>&=ini8W>7m}%~mzo+w&7> z)yfemi?}~luw=yQK2JcJiNn@%KNS4-LWmGo-QEMPiX9SQVTgb~Cx)F-xJ{Uar{QGS z9vJ;{_Y~qP%J+qx&)I+8Xntz;%YUZPh6f7&H{3uiwI_(9Y6pQ?uk_*rNBo42L92&N z{;nb(zP&F6K1WCQ^W5Q15$mkuSck)ol5M_X((HP%s_3dkh0_^t{Y_~-TiVtWndN$` zT5|=H<&@G6-HC+`l_Q*LoDXdGQoa^c@z%BP_43yI@y7mfhq$i?tq{&qunZOJ z9`7Q;zn_s#QnfUCNVZ;U|!4-|fOVv$+tdJ={_tS;QR_2FGp6hfCssU%kZOrQZO9^W4* znjU0DbV}~tG~0jjD1+=0t8Jw>U@y!ygh0~H*TQ*kNPrHGx09pcRXHi93!_-2PwM08 z87IlcOw~U|k3WMpu+A+W0PYMS5*lx&`{eGi{&~+ru)*-pBt6`0|6-tFl(9lJUY%sTVZ766k((t* zok5pRPw5}5UoUaTH)4O882fRf&a4{Jd#PtSz21K_Ma?OGmvbA*@=B}iBOJC1r~ZKF z{mL@jbm}dLLhb_g?u2-SoOW^=Nxh9YOLH`GK;3KfFkd;i{I>K_=Ofe{K>+(f#SjdN#` zW$ggBQv;(4UW+zVL*!-4LyxH`L?Pcx{RR(YHXgN>n=Tx7+oeb_^Wp6UmB$=3;{d7l zc5kLiV%vr0xXmTO$oFWP)GM|K2uck1bG{;Rq__<{q%j^&Ei{L7Ph6+!}X z+%HfQ7HJJ4D2on!(3A(bvfFG8MtuS$!(X+7H1jy}ZFu-T|CZPB^A|^Nsnl+Rs+S++ z2r*`C6YxC^b?+L+2TX8NbX0nl6<5qO9kLJ5{D19bRcTzP3mnvFBhito1(X%oWE*l4 zPyO{Gm?3qlF~-g=$#6(1qyH}DP|wuKYkTD{1OL)R+%2LsgzEt+ukdKoi?azXL9FlM z12$*p6whh(Dmkr#Ko&e%LZJP91e{7hkYh2*mvG`O-a8n(tER1*x*Tr_@(SKqwm!K@ zAi*9I>Gu7h%t*Q(q)*qR4koskP>%Ig)TRA&{ciTw-qxpLO*8GCr#qF zjx#EL>*(OU$$;O+P6O5gVm!DLaKO@!BG!;s_2^s9oDu{jmslg1=ug9#_-%I+<7*F| zs~eYPzzhpNzdw~HaO87<);7pGVmz?JTpbR9cmt78Py!EdH?1bF+^ikw`{pSEvfFQAhViZ}Qja)_*)gl_&(rhdg-zH`wA(I`-#GAMsM`KPhW*%oQ zu|9KOmH&iKnE>w_RaPiQY}9-QCcHADRb?~7=SSR^z^TDKUjk3fWd)hWo>Urqi1Vq? z?=Uw5gE`~=Qd`6ER8xI*c4+hm8z=kPxMwc+GmtnzQ>S&%apzxkL_>$6*dpzB>lf}WZC0Ws-dQwT+(}^n-JA}@LjVop z0Z!P(_G|U+4pV|BIk8|mXfDEejj{AW7tzVFZ+|3DGyaebW06q4| zVR>S9$5I5l*OK$Kb2{gzEijKh2^%sM?}eui6ivx|{R=~lxr%{9;jANmSKQ!hB8ZKfy?tq% zW5C;07p!wrP=oBiTyJF*bn5P2amB@~1^d*_(_L!-&Z5k6OH-_VfU;g6GW}I>9!-l+ z|GSSxiCeVO`+H#MmTw$Qwj$?c5IGetjor^aS~c>cCTI573)BsRFSFUR?<&~z&pdxl zrSCdU$Op1*YmmlT2b$DLCB))2pP=HKTt7cHGjg$MY?B~Gt}88H&dEDH?xejlwvy+xvkWb$*7@?&BKuD86;W}M@l`8~Kg*xnf#boU ziE)pBaoyGpZTix}Knzt2i5x^&O@NA4nyGDA+|^3eeh?+h~#QhjT; zf2B=#s8%uUxXjVi+z9kP)!wOEq7TN&O*w3-9$XR`Mgs<5Bj9Z|3z9rU>+6kZMdT@x zYi~fa@V@4ZF@uPh*vIoy>pZ==>uVDLwyH_*Whybmb6$txdQPk*8w?6tMxbWh^&Ndu z71Zkrr%IE_eU9GKJQs!~Po-WE`~gb44C)L5I+n*At`Bv5JXcF9PW|Vsel%HTQ;@A} zHCG@EunIzU1W3_w3b>m0U+T3V);amzpkCu#tmO5KD-QtjF#y{^e*T4TS@CmL+_WTwsG19s9>cT4KK z@>%2c8k6((2Xtzt_B3#QySVK?V4@_JS|Hv0is3lUOjb*nGbQ?r;{EXEj-GrN$Yhq)RtH8qrg%$rNDelX z*;Jsb1b~Pl7+ie=v z1Vw}gV&cWE9SM2C?ZEc}kNgT-1uacJ4zz=%@O@=Q3yMUU7g5(_?e7M!?OqO0OtZU? zm2R7Rd%?#{`nq^Wn>?qGNJ+rKaK3Poi3R61cQ58D1J71Bmukp}6nDNIed&Wucim~D z$f17%Pr?ZZ#Tqm3E;2tGIZF`BXi9(aa#?n)By7L0f3Xc?ts$A~MWl?N?7;P7|3)u% zH`F?bahM%c@YC~qbaq#kn)fkn7{chNK5|5`9Ub39?7;1qf{d>*G+t1f6Zbq_R(NK4 zZ#Mnp&1fgydYRwwB#?MLH|Kv3F#uYJSlyersT*&8cszwf(sxkdtMa4NRDK%fQ2 z+FcMwt`SSc?k(tQI;WugF8^^9J0>SEZ*Ipp0l!2`MNnX`r-EltSh3K-`-$KVH zzIyaYp?l!F_SuD>zpJDVs6IxH_x8jn&I%?yv$q)jMclaTG!Mk|J-NHK=s-^S;+(Ef z*dVnxrN#2aAZ2jI_ft{7(mu@r46WM^JvS~xJId`)QE%Yn|A2M`Ga|aHimQIs-p-JU z{BdW(e`~d;!({F_z^LMpbU$PEGbCtFtcH#L%d_F>^en9V3Rr(*xf<5@DUbixUv9#4fz$ByK6Fl60|3Px2G5URjq_T22!LQi79+$B0|JRSr3O-U zzHf{VN-*e@*S|c&7m-J?(+IjXnukj+JzE9+WaxLNy;`i7@Nk)!vJ{+P<`->w8uKT|y&uu46;CQ%za51Dnq*{j z@-`eOY3?h@=|M=An>-A~Y*1~kb49sgH00II zb1A6%rv9eFlZ&Z(K=qslXp7{VKq!_zuKgVG4pI)48`nP&Jv)^si+ZMxYWxVRo)1xf zUKReSKLW_1NtI2Zz$gv3dXcJ(&=_0qE;qenZSHdVPUFTg!)@@O>8ErjiKn6Q*K8N) z2Gu{JqfSL5UcTkxOBY*3*Ol9{;%bfIGR5Lwj{cOtyN0~Q1wARcJvxe559=g~Lt4~b zjl+Z%#bExegxW~64)>*TBg(EBjlD4fLs@rX(|vef07v9E4v7W3&G&PAxXL3x&fkXf zI=r!rXt@*8w(hT*dibckxp*M*ivwFxk#)>>yS`mF8L_JcM|Ie}Xs$=kNkQ-ZrX9qw zj@Vl=@gyW|*QXl;5#yT{EOYK>W&wYTTLs2}aVAN(#S1hDB;2N4X8g8etfcZ#7Ktxy zt~;g)U~iMmZ~s{LI6jAlG+~{45I!P6QH^3$9Z4VTZF;l%4ZRVZL>YY&WE_%NZlNVU z(ARK5@QEMtJusi8uQR{UVKgZQ%=OzQJo(Kr)r_WHyF(63L- z<+vZW9pcP2jeB89+XS5RT zYP8Uyh(M3N{o0i^{zK7%48jM{G1f%0r3e(*Di~StD?#0_xdToQ;<^ix3{VmM540M; z3{ClkhT;Prmnz-X`2I;#3834bha30eQ*z}#IK--G0vA&+@Avec=jKHx3j3s^MI_7{ z2rlnDd)mb4psEn^^WbM>y+kg#wzg!~hx|@0t~^`fVzaULtKj+;cnoBQ1MN6?>)Vj0 zF)fZk=y946rHj{w-&cvAC5oNBGg)!-=1Ww0F=xf(!A}0aMTIgON1tNe1_76boyZ5n zA`w88>fHLOR_rQ*Q=fTC<2uAu^V zrrpgLA5i;PSFhhQ(ovD0*r{CJBgfrk#WDtnQI8Ua+iXHoEm_33O*5H~VIFszQTwWf ze&oJ--^W)cS33`1jQ<5@==C5fjr>9$tR;f33GH^@e9SskriSt3`jbbe`W|l>vi>G@ z89;OB0>&TAQtWZ_SyUX5o!_lB>rLyPYlZb7WI)KiBTaSWEWP$Q5&X~BlDg;GH%^7` zePPO{Y)kO{i&{K-#eLwFr$(8k zaK(OrH#>n52a^>^P&oDyNUm&fV#Q#=$!Tf|G8?`Px*9^5s{+j-8L+rj9oZ3w5yQ|l zYPDm)kFJXrp9aJo&T^#xqu&ktcjW(+#QCpn@c-`5TA&O0*SZ9V7U!!%pAa+|I`I;b zE|^Y`unK>(_@$iLtoH_^?!BO9Ylx?pK5~q=5Qx(K>+c4%fB(yuS6$=FSFa4t zv_yGSt;xnSiHeYaMGUgrLf z?!G)6>iFN+nq((SwyB7+W|uIP5RyvS871q4N*GKtcG zOc>voneNB$+cIPD-mrv$qERE!1s`YlpG&>`U>xrYIJag*-HHLOfo&~RX6 z_zuQ_4Yc9GMKMnzpg3)_sFf;hhMe8o;mWGwkZ-2lw=@&O7FtTLGLo>w0$_sfj^Hcg zM6=_;oKbSRw6Z)M+NjGq|$9m ze1@|s<_K;b0e`T~x*r$sd~ZX3xt1sO=rZ|xcjkL`e>a zwH-_cYJ&MnZk~yMJfZJH z_UKw{W!}j`LBfZZh(YDLtj~szq+4#RTs)pUWX{&6xvPoOgcYY-L;jRM90f)|Ev4wC zD{)c$)->PS-nAdi)B>$jGCiVCikA$`@850GX=7WJT2d|%Hn|&jW4CmsD?AMAfe{{4^tzZD+-V}Fn5#}b= z4JRgV{?5Ri;EI`x$vg#X8nFj8@(f{8kJOvLBZ5G^=p%m`qPy3882|$YZaD4ZlbG@@ zfr5`7!Ydj%oVp&RK_ILu_M|5R9Z5jtn2%>3#dm{^*^pY0uCw|utQ@+&QYl8Jjc>W# zc%>=t5;@Z`*&uzz_vbJLAIxh>eLseXiXMQKIc<;W}(hkWATnuy^lWEoE2{W zsSs=tNVxEBflYBT;-LYWBe{k=7zY#5E^BM3MHZp%_P_6SFjf0`NMH*T?IUxdkPz7I zgiuIwSsb2NSYW_-(JnwY8K;X@qU0=vyZE!=*`mGPE`J_Ly@`K!FpV=9zFYFb#qj?4 z2_P{piSNHT}Y0W#;C;x zzJLJQawae-z_}B)7kxVPxh~FMG56)-4NI~_=>zmfxzy8YWw&*fWO*1x?V8MwFp67* z&4jW!72N*&#xkg-F2odd%5PjCSSRk&xdSP-=dAn#R|^1>JQz@gY@id9%#)bG!Z)kg zJLl0{P$Aid$FDgdQM*!pV&c2R>+U->cK#IuHnszNm`dm*O`bZ~JvdoxHcCfQ;oY?; z+Fus4h9+ybuhbQC8i{CsM)kp;o6j=%i9rKC?3?x%tLsKp6o=KnSa5#w-+w<`Q(x&F z<1`>{lL9-i2?!Q|$2kXP3kC0dB~1srk}Kxx6QA_2|BT|PzI;IwxlzpAI|`BqHK=&U z1Z@tb?(j25UZ+#FNY*pcZRD!K6`mv4U!HJ_N=M&Di25OZH*uyjvL@jh`QY>j&+(7b zr*X7(Dxnt(DZyglK&hFh6~yPg0a1Zmw6c_Xhk56)f^U4CQzsl!pCq_QXCMp9jH zsKzUA?&Tu9E@k?Q1Y3U}bh*g20ds+OuL-$9a8l!av~w9JGFAP2OUr#dCAYn9rh^Sv zyzqwswH7-WagmV&tbqgp1FM$5ru>(i21O=$F)7Q{N~gV8rg2b3&q7YH+bU^*xY*TaV*6Tzf8hbF+b!Y#D@DY3U89nQ`0IB z3{|cUwRcb1D($hV8wr2#; z{wZ4JvW_g8*Al>R?3|ImR%z`7|O#}c0!O97z?1uTyagJ&n`jQTCL*j9>&=Hninuo;enFQKK`B%PqR?BVHab9bmQogI%~N1b@3Cz8fZrRK88x zF=Kuj(c#MLF?=7@*@&}>0CRam>=zcdPG;I4s?+pj1zb-WWVWlQr%dS8^rWyed#vqzW7~thQ)pkpaKz9 z=nzIe5IBNG74jOMq{0w*N^aUpRp9DI1ZZ|stFM=enoAk6E}Vjmr;0-T;8tW)VD$Ya zWc4ltFc6|~@`gl^TKE0o44L)!>X-D0C5 zy)EmX)k&hcuP?pg&2IumtINhf3ZqqO$Ao@^@c>S2Z9r6CNGGeBbi?@RL8LboeaH$I zqmeN^jb|QnR)OHsMHHBi{@aOvDE_*B;A z{g!DKH_#2vflds-5~PdZdtp3SFT5<;xDKi(`{&V0b@4!%;Wz-H$_Xj^N;O#Ampup6 zYiK}U0F1DSlQ=N{kiz>2OsbOy@~JJod5wvie0sg&Q`YUp*ppVb_iMzTu6eRLbAaV` z9u+%T+zrGFI|iW>?DmWY_34T2hpC9@@lMUfOAdaG3g@!yO|SjtRsR?+?G>p6w(1E2 zYrD8F;f-P}+{YDu-oX%|n5vCb9Fg;Kl--jpCB?7Z zbv2h>ywpLU!F}-Cx?q~=>#s-48N(9uhZhjF(wSXUwwbPw+Y2_zH+kfopULZaq{T=^*tg&z0eI>XU}{2yx)0!J9F)nY^M53V!0oTVrykH zG2FF9Tlb~?5Pjk};(o<0=LG#-4clLqusbLEOc2GJbR|qbtY)JbPnR~O=92cqgbba% zX{u}|-@H2g@?7KZ$5%AWpPV>Wko?7dqiZJ!Gi>0!E3C~;AlsxGG?Ze=$vA%JKVl+_ z!;e?h)YU8;IBNA&*n>8JMc_j~8Aen$cC7I-LI1c02z^h}I-#sUP%y84*kmg3UWIHzcLFfO;oq50Na;du-^@u^-U-XGFV2%^<}Qa> z3f{=%v!|h0)b2mE?6-SMU196#8*A#+BDM|&E7DxeODMDJsDq*0LhtR z2Ng-mUA`KzbB-=Ur8SbQZO^=|kDc~if3z}hA-^xQd>)84GFZ?G6m2|j`vD)gfLD92 z?LEm}DczQ*KP^(u?QenEri>Ta&-KNi`DS3CoyDC`>}{f^;Yi>8uzb#o0u{brSDJlu z*a%w3Pw!a9wcC~o7N_lL&3-=jUra%+%9sTmGYTR zM@EYrh!XhjwNQbOGAy6HF8cdX-(EJ<3)04aOhz(igUw}EK;_Dc@Se6 zj1FmXrdW00b%vYnqeVleR5{QP5)tTRDy3Uf|FWb$11U}{uDg6mC~0&*_Ybj~9KOeI zp{jD3`}{%IVh^(iR;xO=;<|H~Znndf+AjMja8=Lm`9d%%=4hVs{qw1Kj0N%bDcCTl zD7^<9)mc0dhY&MV1aWKzJes*grK)T)EPX4_>xpb>ZtvTiRf7YVnphv^Itdh0&aHvbG#G)a^NP? z?F+kP)u4_Nx+zsA2ec7PhXX3L2Mu$FN;O{BS_I0?uHCt1v4Y5hQBK<=VqrQk=qT69 zHHrXvFntpz<%{7QJzP61W!I$nDEpI~QrrHFTenUEx-=FsK%h&1rU;PiQ}M)HgmAkS zD#6MEZB4qTsr7;o-LG;WUz3&N)*U1nJ}rKE7w~Tbsp~DzQ2M%HqK4MxDD%GcZ!Uyi zT>S z2$<}j@2&>Y@f|H~h3A0cO^Q~ZWIRerYD8Fqm#+;ZIlj;F99Uu$zR|vCa2iSTqFzX) zw*LvX#=dL*J{CRo8uj_xCE=QnHlcmCKk&)`nkExLd&?+*6Pq#YjEC*}(U++TU^Hbi zR1i`>q88faC2RY$S#h7`ix6RbuupC$(eD9JqX%IcNrbJunZd!(r=U#5M2rwp%%|Bn zJIpZqyGbzpf)%4Q8!Z%w4DKNSs)HXV8} zE9k>cvWda-;IG3|U~F}W6j|9Xbtfy?ZHEsxN2DA|6n(zOG$T9GKI7f?RorCgjQDaX zsW7s+ER`wY+W;46<$kd!{;KwT&7`x-UWr7tVlJO!hd5$J#^M_3A{8{d;r1clVxLAy zOn$JOmD&?zsJ5Mo%Uo20oe-%d#eLkH+Cr0NJcRoY*cT9d7%h}qm-Cmqr|drVURCBj z{ooku{>anp(x5{vvlECG25d|*10$1Nm5{@WIpH_49P^p2GPlHZ?|G4X8o%ju$=a#s z3Pp!4AsT@N9~L^+*Od+(&0U`JB!>m8)PbDiSJ}?VZb^$wj*K5BzfYKc&oMigVJ^C9 z(@{8~M?1$TXcu0Bv$gZ0c#=yPc_X)yMWLnuX8F=^Cst@%tn!YM!kMA8pS>}SNj8_vr zv5<1UaH5MmpP-H9N6mK%eM{X3Fg0p9_EvQdnd?$a20_ zL3pZZk@c~9Ycr8c8xPliS3F&}!}qZAy~qArVn41tbC**6ATN?vNd#~n zy=5)R4ym^Y=$vB(mbD3div{*mHxFvctIi60u$rKYEDV8IFHxK>IrRG13_y#Z_pHjS zqb=W}#y`2#GS`1zDll&X5zGfB=p)DEuY|ns23B@k5EC;CKU){2c(6Pr!u%Kn2*f>( z$KWi(fu@Z&T@khiEM7O+QLDPj+g>;+t>%YbH+3a4&VBeCWY9<#Dg%VDD(FM|VL#A& z+DJ|fPJ{>EKGY=D9Hp@GE&`Z~KY&w0+EyyT3Qz8Giml?%fM(1xnr8ilg>7U<8LVg? zsEzVto_3Xj?{T(vo3dsjbkVZgh?(f>OlJjpjXsBaiv2q1U~xGw0Ufhe4RCZca0xyu zU#yLvxj+rMFMfXg!DpG*H%}>OTHWONM#D`EMqz6bmakC@iGc|LXhZyzllGKK( zCO7;|o-LcWqv{M+U4H)7;Yhe3o)}BuYxM@2fcvmJXMt$J^Xi6cn33ek2xDRAlPaucS_KRFL<&GPwGkI1Y9!2fHXcpA={XS3B8p4Hc27E|D z$%M#jkSA5@RNZKuGb-z-|EeJTK~4FUqkTUwKjRe)a`L02Ea-oQd90tRX6PKOeSmjUFj2>$GHH80RCv*RBq%l|y(G7GjicKdV z(&hH>1$KwtUK^?7X_1l;jmlY!DF1Y+Z(o{gVn7lf<{n6P#6T<%$Mh6ZOr#JAh2nU! zV})O{Ze!(V&VCM`3q?HdYh)%mc+!lPHf_#=WD0K>5W7*EkH$XG}jzJdg@ zD1?=;SFS)}7M}<+`C=&iyY9HN2{(K}>&#xwz&<+(+~cZxY%GiyPMmLX9*hU{0ZFw4 zqI2mr79nSCs>$0SSe%zcm-|ym=JQs2@W9a-Idog9!a8|2oX1!8&`A9B^k;=I6}Kg$ z`QMIb6TVkGfI!6H=wc+btD2BVGwNI>@=S4WBv1JbRDd{08XaVB90Gv2(}|y1?(ywt z(0y&Dl!+3ICx+!|1BN)eTluZT?~w^qtPckNw9rWeI73s zzPuKroYgJ4{p{UEWlZEgW*DA0|Cz^r3`E%n7)1l?mT&iRZHMP`ujfokp6Ai%b2rEX z%)~4zAre3z^*Zf;a8OtC_f(YlU6Kg!4-hoGBNxmIWG3h(AZ7A3LUtl}fdFE>F-HV) z2`1^QVUFofxEsxLv124H2Fo!%3-%h<%3obHG9y(^@78J~wMa8v<4%mm?{AC?8+^^k;q_$&i{YK2>T7>el9*?K!CCuZ z3Mc_$lHs0Vag6r&cPmOWTSq!IGOH!#W0sNIk03>m2kR}bkhF+_F?ojJYB@JFA077c z{1N{2t;hCw59S!Ss`_A=>9qRK*ivCV*nQf`jJqG#c@|>o7JqAaDb3Zsl`jB-3y%>L zd)yRq#yk-l2m&hTiE}~GGaW#YJn3_2*b&SzWcNW|4{zLu#s}5Aea6%7mVwe^H5r`{_pzAM0*YLmR z{Y**i5&bnS`Z(JoFPMQK*F|JnHWO5|JF1JaVxxvIa-l#zrr)7n*B&|?aYJcF%okQD#5T`&IwMN)r7%v^@GFC{J+QQMVjbX1X)D79;7G-y6^m-cGY>cm&iFTW%X#x&wt?h0@&P$Brm>+1_yhjPTOYh*|_ z?3K~j#Uq#Xz$TSxNaz5#JB?ICH&)68mrS>+KwY+a9Q@hLHuQFIn4uItDC=8}q0+uT zK}^0eMoHaZd|`E92O@fCil?Gb(r>D=MQ|eG604@?aQPqrtCYP1Ac?`rWYR)ijOoyP z!9W+>tG2Z{@8_5_H8$StD2p^}nv(i%_yFi~7~0Q+5@C0wi%D@Y`DMzAH*McL4|FL)5>D6=L`<~;aJQ}?cv^;SWBXTYGo~w zsSTtT;lvdD{*6@ON%^r2govBVLdMifw$z7hvu!J zCsdJBj)vwXFVm)N>oZrXa&(Eko+d>b%gcc;S0-VsUKvpt#t$UH{zsH!r)C zJ%ip?0T*6K0Qh>oU}V63vEcl5D3w*Im5Y*cj^7q@1m#1v8eiF6+xI?ZD^1s5(NF|Y zV$iqDwWG1$8C^#ti`I5oSzbx{! zb(2FKcW(+x+~GftTu-O{glZ@=m%+x8kN3X6qVvQ~QaAZ_AnKjb=L9SfGGz0Rej{L^o_tI zV_k~0y%RG=C~0iNM#+-(Wb#R6wv|G%;TNuj&9-jwiioD zjMz}C2&n?L7YfnhOUvKa!6v41RnVQcz-Gpkk42QejO`fQZg?07*6}N5E!3{vJ467E@%G{n@ps{S!)2pKA&)0w)fC_cljNCXnZzxOOUF?;B(* z9T30GN#Nj}jX|_*d(%aNXi7uveEmCcUpJ20M#|msVJ3iqELx>Heo;LCVBuZAMHdWZ^I{O0*v$0XGwd02_*mZA@o|J8 zMj9nfZj7r!i&CX58^-Ro)K9C{k01{p-#!kU7uUHGz>L1|jbeg)ecH6e+osx@%o~k0 z%`JII{mBdVH~D*5Y`=K0MZ$r1{c8l}GeQXbIh?BwFa4_)#X}lvAsZbtB}SU+B~&J# zG}Vlgh+XA*|BKHX`YJGipfxs90z1{GkhCX5hPO#Jyl&2}PCorAV)&bRBLZ?OcaH9H zZJO2SFhT;Yo#;xx9Ah}6p1BY69$se&>MqP6Q>CuuiT$G&)6SK4d)Nkg$u8IRC(vE; zL2f(bKp?YNHjuaxTE>#tU|`6%F865`=(T*>=j zuB@^V`>%zRQ~iOWDCKUvbUQDkXFp>m{{6&hJeAF6L@~ zX;jCe_1Cj3hsjtCGm9$|sC|2a5EX@-aCiKq6fG2ZqJgr5xD~arB4sjGB(~L{QG^V; zekn3uPo;^*_7=Wdq3Ppq{AFSLFpIK3Q!sczgz?NbF;s7YecsSH;P<=1n?M~QcMZ~O zq~(B@T3!Rh7fdnIT@BmFJese@a|ZoVE^YO4g<=lo=F#~w%PpH}o^DA2x~T|-e|}|* z>Eb5dWRBGdsqkz9F=%3ZL$nCIr4H6Zoe%BT0;DjWLApPNyX^;#Jbv!w9P)tgxy?Z# zSqeP)0Pgs1EtHC&Si^)-?*YQaSY$!miR6WCJSVReJ^SXm^>n<25g!XCuj6)LuwcQM zX{J>1F%DSwmC;V1Q{_u6j5X$a17RtvJ$Jv$*|=sn7ah46&emNx*3$eBxq-i9|Giqj z{~Ac^PdXX5?7DLleTOOqwaf@~F+{rao+c%Y8^pc3Fl%S|IZB*f6 z#VgbyFLJ`Wkm0~7n1-oi-R3d%UN9(4dt2&^bn^JqFrFz-)t|X@uIK^tV2soMiEaG1 zzqijoJ3-u(UGbeM%{78c8JO1BmWhy_VDyA47Ax@i)7$ROdE?m?&Xc1<3>(Id)q!LeQeq=E&7E3IFu^Nlf z!x)){x69Br!{V2KZTtvMmD|g9|H92>8Ow~IhrrkU7W9Tv4f&}{3W)e3Cf1*tV`=Y= zKg|z$5vmJ|?f$aFqn$}MlD@@Gl#nvt3db5H#oD|RWcgs$884UgN-Tf?P;QEMSZjgg z0=N!aLFv@Yg!}%>fdO@u3Y|-ur;(hkv068;pAM6l&Hn5HR{B*`OE;bmPJD~6H(!2C zIyvc1;m?ZXxEuQE{MxKyIWRoRP}DML_2-!&TEbI ziW6*au`FnR$cXA>aSie%-_vqK?YZI1Q(ksdpxjK}{`bij%n7C-pzRV{+I1<4E6U~H z1mdx*D?bS5zZ5q%H#fW;<=z*dcBnDQdQRZ`4~9kTs7$iwj|AZWNC8eaw&{Xl-D zltSnb4_Az&i(V^rMkU)=`I{c(ZAYJvQR=Rl0Z<%kNBSv>Y_Wd*@Ma75TtK4Cr}KTX zk-EMIp*W&cMQKg_xb`2#kg1x=Pv_^_*y2AJkJ7I(KNZ%_cVZ__GWjLOn4GAwufB90 zD*HJA=kGkcNcK*eGUxh~$gbh`n5}iIE6;wJM3G|h>%~|MZydvuILE)&O`lLKu&a%6 zy&snH<(Pj_?d`O%X9BCjJAH24!|E5FyhMuWZtXjzVRc(lU-6le1MF+MC~Bsoeb3O7 zZa1w_|GO=m2lT`*mt2a(PF?53aG-aE7$TSh_<90e^ebG}uR%|E8YOO#w(fGS%F`;M z;?EO?jJ&CP$+H7;qU-6)_S8H$sPA?yirO=&@>NBYEuych;^{Ai3L~z^CdP%!*vws< zq@q9;2-@MS^qbIWs->elbQ>%q7Zi3(HFd=H;dbnGQ-9POGB8X14-t`h5sn6za|bv7~AN6EqmH(fJmu3=j40A!r@lwx9to~;9p~f=WhjcRDSdkN)Z(R z$L?oa)K1R7uUYNp9=?45XEC(N5a>QGRk`Ok&%_9^PFN)pcIHYR(+Yi$EHGKYwwnKsibNb8XNhu+I298V|VQiCV%wuPFH1iPC39+=g>(}Vmu|Jl>s z*hRMf_wK&1POE{~K}FaB{N=GduJ+x>r=idunq5w~ana%Cj!^j1J@21Z0q2utAgbNi zRjK{{?h3ngqvlKV-z(RwKZd{TOo{pBSBKb#5kIXo$Q8d)a`(`~oB@{8($RY_?0qIM zH{ONi48}r7asgnn7g4vCQrDk|5kQC4{$;TkCr5tffBb5d^YX8%^OstJT2r3|>+C!M zO`Q>nTiRX39?Yj1YbbF>2J>5@a(P+7IT@vzEMWX|(T7LHLh?qWgO)DKp7#0C4QnaH zFu`(M^?GZ4#+Q+=<|?-;Sf$(_%-A^)Qp+ zp14kR!G?Ouc2~!({xF*Tx=I{uTV@qAde0=0m{`1N0fQiAk4u!+WkV4nl<81Hu| z$5uzm8>d8xv;2P!zIA_9f|C!_KimrZy!m!yP`~>CIT|S9hIDp3A?HR1D`R2b3@y*D z7_J^^N~xA=h|}-Ex;Xuad5+4p@mKEFy+v?(%R6)-`LJ-=!H2+4s?-V?hdJdu+Ey#_ z-%q=vm_s=iReWQi?jG5kJ{CHd<3__U zUlE*!_jcIO^3VyAbvO@Be3S$T8$C!6;)?h$^ zT)E!YyKTB!R{BaiT_)pZYnD<>?DQD^mA}Y4=03`3mn#%xUOPN@t*))U^|pp=?DLo; zTm{;Q!jBIJ#QUO!twuE#U+;z_^MiN$HM0TsRubfUb`OBej2>i8QlyJU(Dsh5+zcjg z8@vm5-wMOZYx;V;X(a~O5{u@*hOob7OzMJHb~ zt7OMd5qXMcEb|AW5Z5dyYb5$qxUZIvQ-qUQsJz0MoMiS$>~th1x=tIu7qaPMGo_5> z`j#cOLk-dTjUGGGEQ2$rU|9gUPk@wORD#7JO6}{$bNONUH`O@=SP)P2=iB%iRzhoU z1hDhFWs^K{f6KF6*is!>|^-nD)|4|$MXNn`~OGKWB-4-7XMM_@ptln05CPj<^TWy diff --git a/docs/tntn/resources/dem2tin.jpg b/docs/tntn/resources/dem2tin.jpg deleted file mode 100644 index 63cd0148a945dfd37faa787ab51537966fa7b17a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167246 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
HIOsG|Zc(3h%1?mw z5ON|ybdF$|+Df{m*^O2!wQ>%sDzP9!o*=LHB55t!*(OVcl(!X1101q}lc1}50oeKr zN17N#NrSq^aQsT5L}t z74sRdm+qrQ2QZ!G{T8_UDa;^AUkFzImv3cQ{-|*a4MX&)Xg%RMu5H1{E49PHUfsgx z3o-dv1W4jK+A6H$^DDE+q71fo3PW=d1p?Or0&v`-z~=Dc_iC=A06~F!qDi~58ij_x z+^+lfSc`{%UyMp^+)U1DuUl@Ra)CDzbXhmeWDIK5E5hl^Ws{Fk7bzpIYE9ktPaS0! z9|T(IBXOEFT#u^0xu`jfRmAlO!BmeDqDN%l1BjghWZaLcsm|BQNMP<(C_NzP}jjv*uF)m^?y#Z~5? z-_y($no2GLp5=e|&vlc073=Z^XT<*1_>c2nh<~|SJkZkHtPU>lUarGs%sc|S+^;9O zT%lXjSk0~~`TBWBlF4&F&+?;D^nVGpcSdRYySW?P}~4#hUvkbGfdxg z&@7{}=Lexq_HNA{AY^YPaE%U3nQ71fi{>fcGz?NlH)U`ka)#`LuHk&YWhzcu4@WRu zh29GYE$&f=L>-mf<;&;k@gLW46-{U#3Iry&W)%MbSVSC@JJ0_BQvU#x8k_o*4Ah&I z4$3Zrg9-$?@!C8PB1=ZPr;2ZFGFC2N&<9B@Mm>*RwY^Kpcm< zoZ+2E#Yj(^f>p6^(GW??AdEQDKByXGZkpD4?2K)7G2(z}mY<0b5GtI?aRP4&Kpq~0 zy+t}~cL|>ohO_&YCwK)*Y)Xv+95-U@vK3@6k`=K0$hPDi!T?D-pj-ittC0DkDRB-Smi{p$e-alF&S9yo93iv z_eG#yY!9LS3P*_a9qKTiJ4sa^1rGDwN|$pL@Q(oEqbm<#p9D-5{rp zL6BA-9*P%TQ0ZiQmC@gS=q}wqx^sMgq1^}c_0e_yj*dawD!l&yr1nki=(b}eQ*%``}sP%XJZ-x0s@=^ReB?5fMMH8^h(DT1ljCBh)g{7Hmigwd!f zopwR3!a0J92bz-3=2t0{aGMxhpm!?n7qkGmjOI33wD$_^w?eTJ)1qj0a8?0r$_4js z+orTMOl*t5lRBvxdI{XCiB>*$S7`1LEy4!+eM7F79vLF}8`)6w5`R{8oYNbJA=!~iJ}0RRF4 z0|NsE0RaI4000000RRypF+oufVR300;pA00BQC9S1!cuc)IS zAp-^s7%+MQ9Rbk5=rZNSixx4Aev%OCpFqN3>7rguafP_G7AU3+&L%jq{{YFJCCir{ zjx!PgP1g@em?tLXdvhHyVS0!#yd02_2?W@eE>i{Hp@;*yiw~?pcq@mt@LO4@ePCP@ zoznJ~16i7jF4cig-Y&B5dLO)_UpmypSvK7+_r+o>&qNEif3$Zkhx`(qx>~P)c|nlH zKN9mztS80I3K{)n(hwSKOL)xDDP5O@eKnOlb36Y4Ad*YHo{%b3n-PhvA`Bxs7#Gat z10`pqd@|CfjU^Bky&kf|I_-DEGFSjX@<3T*O%<3FoLIOUND$DkNY5Z@n0?1=zHVxv z59X>^^r9=#Wo&1j&wX(+Gd4_)JHdf)tOC4Cno%)L-E+hn%Ci3ekWgaP(!X&{&8!bt z6>&vE%b8Z4TzBid8u;LEUS=7RL0e0A7n`YGG9sE>Qr63+Z_Ik1sj*&=D51MI#I;sE z*gfSGv|zc9Rqn$5VmhQQv*}j#mLj`nNTH^2R(>uep60qn`mr}F?J(0Vl(NM5M`?Vd zOoqi8e&PZWd3-{EIbawdFOn)MywbE_RRarG5Oy#<9oXcTM6`p4R^IRxQ3mbysLJe( zLI8^KS__# zP=r2|Ai^A_=jazNp>Ck&G3XXCm;V5`u-0{LFNa2#e@dAX0gRo{wfXo64559tr(C(dBgw!Gb|dN-)B<;yO(4z{;SE;2;QY?& za@M^!m=aS^%X(e@A)yFzAchQD=y~q|2pBPQz9Xf?MZ|cBU|xYk&Sj#>-3+u+w%vah zE0>X(@WvGVu05tpsMbZ9QMFc#sOSdAf(`INN4}Feu#GV+Ju+XSEqFzpo(Q{$U{Vzg zH5%oHS!ga2(cWM!**88TdZYU@4Tv$iyG&Z*wh=ic#Bm>?j%)iZN26Pm;5-JBQ}g34{xrJ zl0%bdu-;FD?H2bWe=zFoMEt=0Sj@8*P;pe^wm;d{sqjL&&T1{{SFcNa3o_9n8pU?(;8p`nSQ24yr$j_#h z7a!l4nLX@0Tu$EWmf*`K%15Vv`8W$Lw%}eUEssV9Rqo|JSPsUk2g+-1Wj)+OYma%p zY8BTuOv=l>t%w^EwIkkRn=3W;K9`5qoxv0v!faGWzZ`XCNX-N#a${@{{X_eS5h4+u9q$>zocx_ zj+-L?0OZT-fB00Twp+kcv}8`rZz*IlYjK9A{P;&8D|%Er>C*1k^>oO98!juFts^E) zA{$3cCx|mC+(Zh^`9AQhyLCDA8A#_gvXaKidL+uQ-B?^dcv}O~C+-okQuzd?a2$+# z!(WIiFWOMCwf2>i0@ZJ{*q(TE8(jg~Q*bLHD2r#fmtKq5i}i{G)5}f3Zv)TjYZY)5 zNVQR*EBK0#K%%r^n|~a7q^C`)TC7%i3P=BeDU^V3Jhz67D z)`#9%I$A2*gN_U1^on|;lEt{;dA~_qE0KId3BVADRmY=Gaz9%7*Nvtsvui>O zXPa^*X5|}~&Oa~(fV-b*&VCaU@`P>~gb$q_^ST_cK-YWrqO!6a9wr?(D8P*!A1FDdU9j%J?FhVs2_VvB zjOv#;^p~Y^`p6v^bOfRV;}t4nV+DWbsCmLbkvkL7b;b`^C@zs-{ihP z*^J&Hvy*2LF54L~cN7*--GDvjs!`mdJ=onAgZ?tLyS^otKG~OUms`{uV09mfSY_Jn z^oYzHp=E?&0a1M?tvnx@l}_OquPcb1g^@j|)F^j;(z#aKDq~1_5G4T0Iv4E&i3MoW zo0MSNR4zBE9PKnb<*Vn?QmwAT>%_?_uK_Lb5G)252bqX;lbw3Z@&jeH`)Mqkb!e24 z4|u-|q$~`L0AGrD6cfUFkOIND}=Lu;zW*MVGDN zY){|il}E-}c!nxI#z>tG;`o}9^-Dg{WQ`Q|N-kwMidrl02D}dCKrHtmlFXgD25M5` zB}nE+(gUOe>H~~Z0$&{Cl*}gwN{`lbI@G8TV9WX##$0+oL-fD;-_uN;z_>Q5!_L1G z2a|s`P>StCUhK6!mg^oSt@&ujydl!(-4yUk*}k^~poZvk3uqzYCPPiTWo`B=SgUF0 zUx)$9FLm`|%Ei>x446%cpH5~sMvEg1gDO|Vy*;?pm+Kx8a6vS7T4Lg*SuXuInAIIR zu}<)cz!|+Dp%Hu8V@HAmNWFW2`tNWXmt{-VW;5*!VtB;a zxo%0nJ!Pb?saHXR4uGN8LW#_J76uJ;II;T3bO}wz-bI1dD* z(;bwg2YFy|h#`TrIG5*V!97{RzMMgxdJ?8#Y^|(Ghy`*zdqtLlyXGc=sv04x-5X^6 z%>+UMSXq=PDQdI^!H+1lmaUnrbFD4pt3bE$0y!2p-Xh6Sp~Mtm+suX38aM^iavT|O z%B&6WM0;NSps>NsjCR9oLthL8uuMOAnFGUU*|*#}zR)$uSF+yy;F1rJ{vZ=G!m~CD z#)7{dW)rKMv%+_F))_*pJHKe_hgmOZR>5x#J)$uz$2ssq^`gd5?lU3xflm|UmSRxR z^=Ny;s6DArH-)OhB693+U7%nO`;mED(zdIfBRmDNO;rm7&z!>o^k*JTHHi3lC^x9~ zsNFzDU7IeWv_J&n{M51JBd5I4=q}xo!j~w|iHV^~b`pt`az}1)iaww}q%vJaXQaJ! zxlQvIq`U(g;l+Q`VQ@JjQAD{}5C7nn^ph6H~)UTz%f;!jrRH;xQDpanO z^*{MBjAg}!V6Xlb0j_uLD@pd!>elrIhJ*e{hK;hY2lSL$xeXL0V|JtLlc^Bs3>Xdf&{ z%C;FpV|V`m7d1g{&>t71uZqppCk~! zM#aoA)T!|iVUBV}p?brC=>q!3H0RaYH45H0JT)_`0dKmtsg|}G3`=dqxnv!G!pl$t zLS6T-%xH*-;)Uy3n46qztDvHBb+EZ>|>q0JFD60@i{fvGJIOt8KI9S#I|@ zeWDI+HU-z0c;&l8Xtt=lDEv)|^ zmtG-a>2^WD)vkoE2GHxnrZkO15qQaliSw3!u{YN4Pr_R1T7!%2AB`A&q8iV-B9vyJ zKeGktR8QRJSBY&caYm$AwyI_8v~Uae6$C7vR~?AZd+-74tkl7wex`PnM)_vR>m5$+ zzR0@(fGJ$7DFAk+I$|5`o+AocteNu5ZacJR5UwpDkW;%tdVv`$(hq_*3V4~~ zZDAt98|+$HIAZqoj~atx+7b>%lfe@Ov$_z>Drjl))Lx|QGd#GKMZ2YVg-4+en4zl* zoV_LW_^n=(IN{hHn3|#i(pCDwSIv+v??!lPt33fI}RnF1-u^0 zR?I5eYtHj3j`RvX@p5_%gFvOi=xUFyADAuq>tCiLdNZuQW?~v}+(|W9WEpZZs*Wbp zd#U-D{l>ph8t8UndM7x~#P0k*Q(NMG3@&fo+aHyhPu$7?-OCJUSB{l2m7|ta<#N2R z&UVo@m$Wyg$Mq}h11Ge-K=L%onuEpV#7pQ29U?j|A=d4HLSdXl8H*t*RMSb9v=5}{ z5QosTO-h7gE{Pte(Nd*G5>#Ut^kdQb@BaW%M5dl%AWE<&cnyo(4MD3KJi*zATRKZr zIobJ{PKJx{X0$_=VFxSRKMwK19@Vqn7FMCU*b@G#VWwBEW0T({U$iMSY+LmUfHlAD zn4o1vK{@W57I>yBe$Xlz8P)ZJxb4vJl!1@=k#%K9;NppU^b-MP*pp-5!jnD zL24V@N4%kJ6Bn8lFQ#ED9>|a8U>@OQja%CU;q46w{Qm3(N4l@QoABv`K8Ph5}?HVP8 z+lb(`qn1-Eb?o z=;74_q!Wf`Tio6ZmTA(6Q4a%eFWCvx2{|t60Q_Euw!gP zExoWZ_Nh(};4no4#!z2&Qm_0)*fnta!f5Z<9@6H(Z+c5&!$WGVn71qM_DvABq4;kl zS4ZMtlshh&^~6$^Y~wZ+HPTykRyJ3rvih6ky-Ygq6L2bZGJPeeV7E+uTXx{5+EI$R z(D)?8XCCi}D$;gHL*};p${Lcaxb&9V_*sY&!K*W+M`*o>6*tH#uxaI--cihfqoaqnjeL;TB-3OJj1@wekq}0v8u7(pl#p5$FK&5+QgW zGAWDJ1ev?RS%x9e1i=aofE8za!d796H8;t51yT)GCmZ+7POa~GfAfCe8O@A1V4^hB zTE~SAH^rq}wgdZ)(-HBRjF; z(bu~xY7~t(%Tb9HfJPdJ(Z5BEGW^R}T+9|Iu(%vUyrKF61gL#wbSAhHF~{gS5FykE zAn2$%AO3$`aid6!-D)ZC1^P`y@5C)st2Ymb+eR*-)6!LWchyg{D0-JC?kI`P3i*jR zLnIdVm+H*o`A0EFMpix`N<+5a6LPtLK`nPu%H^JcK1bFoU~Rw`9L*5U6?-9TRcUMq zRh4ss`@l5d@K5SG-6^{xsaAE;Xc*XaVREJMrX{*qlqw3TMr#?6JGiDh9L**fX=P3m zb1>!9yOij+GH9G*X3G$30W6!RKjTv9B2B{czY-RT4i({UoG zyA^BVQV6l6e&xER)RmhW-#_vi!*|&E+?auShrIh@R2iW&Pu7K{S1TT|OcLx$x@`y@ zw}eZ?3)&aobR&scY8j4t2ZUvT8Vi`VCUIEyfv8^yDmnpaLpYoZtIBN#)vg>X#L!)= z;VL1bAKVaH3+&?*Slnp0n}$P8!d!>EEfJ?geFRt=vYUmRE!L-|WtGkIg-5q6w6xanpc5^R z?|9uo?$c4cfYR7tTfuLWC<`5`f+o8|7H_>m?S;%MJ;{qh7nOs=Cjn>}2-9FVAiT^t zya(MJ-z6H0s}^x3g)DbiY#()odF4!_?=%C{rcs@w-i<`bso=ClZJUK$sE|PuphxHr{{SliNOD0jk*Sq?;!?JX!(7 zRC_S8hOY5LaY|Z!+&^gCW*d8uWqTm}%6@d4NUDB+*oK7ly7>p5HG%#KpEdrJW^UQj?*5<28K@A<(5%zsEvS1E3{+12B~;SJ7WYd4#Y=S?KjWPJsv|W9Svooh%&> z(EShoxI5h53e*D>hIRuem)}@65@g-|E^lOkjSmx0*joOnYS){8ZK6PnozH@91m_2> zN|mX~8u8337qlN{=IjLkJj_;|Y)^S|=w}V7t~Il--ea{xP5$WN?~szcU|)i>e4T*T z)z$$lwbjJI$)*|jg$t)lmjO%0X~mUvJM1E?;o%{L($);2G_YW9Xek+9V}KhkSzAqC zElgaxXwse5Qxr2!CRTtgJzLu9WSXeG;~lEVEKC&H#t4x`#!n^`(G32kPB*=m1lt09 z5Q5YOogiGHI7Zxc>7ICS7};J zE|zax3qo*Utt-?EzZVLYmZ5v^F*mLo9wm)x_L;BXRqBBjv$^|-XVX=kaV>SU#Kh|J z^>QWcxR+g}$Sl`Ch_S&2(Z($#kFGv+)q`k5fhW$=oY*)fhO zNi{}7r>PKL6?V?C zmS%`n7P;*JMh5dwOw0V@W<7U#fQQTyJEEBg(yZFSWhK~>~6x|!1B{<8qpP6B+%D(eZSc4Y# z?=SBH={1@h8Ys@WxKwfI=?Qp-dJhRjXuBXi;Yo2lUa?pdHa_z3*fXR4MPUfbz?9&H zH3w)l6woU_BWbCf#kGE%LZ)4dH2&fWyUykZ&FKb~d9yvBZDGi1a)yU?zOm63$9WeB z$l1K8>zPQXG%RXOJtCCJciIdLfh^lAfQE))?V}y?V$0-Zh__fq>p>)L*YW8}-z96cUFkAsO<`si@7n-HE(k}7mrOUaPMUbSS)W6cVgY+E% zDp%AK79C8InadwR`UrghgjYk*;_5$1kN*G&t8}Xp_-8U~Wq(V|{E3mSfTLY$mfS;P zyVOyjSjqnYQ!Xu-8DVcCyu&nCryOEl&j8HR_W)Rfi+^S@I&j((J4*im#CBZi#Wezw z+vB{{foF(xv@NVqF1aZ5{lqxsnb-RPX?Yrs>`<-b^a+OFx(X;bXseiIXmi8`8}glR zt5{eFUQ|@8=pP@Pztj-s!EysH@D=z<*r>t0&7&h2PwWP#wEL&}%^6XXWQ?{v8Xe^{0`PSv zxSADuzi87!-8HfA7#7G0Z*>Td;#GQv$8@Qgdt04ZL<-n)LlDznU`7K}H=`^!2T*}=}SnNGOLFNQNXo653PT+r2E{-zfW z)fsuHu+5bHwSX$)6kJsm9W4wUw7EU{Q-)WFs}!RW`Gvbfw-Zokjuk0HHmx<+#2a`T zGe`HCa<0(${lcdspdY@H$4BH%)UzZoOmqoQl?#^3m(@{4FA#waw>IdhQTj+A=oxb5 z{X`+u8R!gtoKbxSG5-MJ3xF>Pb18}6!~*65+HK&Rn+-q#^9I%?e|baxh0H74h6C*Y zgBZHhz7^K9FZ-F33X2ff)`}ykShAL?T38gnYHzsItM!5)1r|a1hoBp%dqNPcZO5CH zr&-aDVGU_CjJP+zE`iKbhXO$A(55aA9+(4J)ZFj zVS5T5Wii0F#j?QgZ3u?ZGQjA=32$| zpqEmsXU)=yb)B8$EsL9hOdu@O+UEF+DphbPmqAM2Bk3BZhEo2QQALkNG5-MK60LT+jH1N` z)^wHx%e)>x*|<7R!+BV^=KHE)2Yt{t?+6Pr3KsXAx4RX=?O$kqhFLIs)K624i}O6y7LEHvw0<@|(cPlxO`g);9hO^B zK35fR)-4&e7dMZIXZ>%?zg2yqIgguJnh^AcG{=wpFyU7FJu|KbgIV6rFTAlpjv0TG zC(N*{_|_l@-2=L46oov~Nou0JvH23$4DSV~v5J{dDZRW)O*=Nf-}WO7O@P9hX1X_+ zB4L7z#{@e%GO$3)kd&mV@nU#QWx*Vr&iZc+XE~!USD1gf3O+Z2IM-2~`(|3cRA#GU zHUL#^MQxLqh!&S)PHf&P258jRq^oN@yhgdr|m7)m;2?JTngdCQzLCgBc> zWpzbwN9iU67c1%8=phC;MN-LRQT-i9=wtr?#KSirKr#h_dQ5a%!B0q*z6SI|3v&y# zw~K?k-=EmxAXW`6Q?r?MwNsQ_ZWW-TP*<6H*3&DF?wZdqt#=h*%;HUQXM>o)1|0+6 zXtT)0YIc0ZMXL)yXVw;V3i0IU?=XNlIyV0Rkfk+HDx9D8J=$KbKgmqUM?OYjnAqwp z^nsd(F5dA~W@_AahH})ZdPmEWF<9-)QYMDBapso%f!~T z>o?MD1N`PzhvKi9MyZ@H$VGF!smbY0%?E=1(ydRVgO+=rM!$mnx;ALO`N20{8f-(W zC{U{(NwF_J4K9azfjM=${Kg!m8Cbor3v~k~v^8-yjZ_WTmXQF}qgN?9uxb;seV|GU z*wi_xsA_Wy;#3qvIS`>p-7T}3yFyp6b?nRKlS)_KRmuiwwms%xi`~|Jp|n9@+3d>|n7}NR z>ecEArgkN!8&L5EOYmGmd*fB4b{mS-%{Xu_5GZwn%WHCCdc zhK#pb@9hYTD$FeOV+PZ>P{lx9zu77?R%y4^Y1Fwy9=9|iw5av(2`!jrpShm;Qcy1w zN}`}=<}G2XPuYN!vjWNK3$wavzSRu06We=Bi%j1^(g?7;{{T0GRxGABgae3^O4x_u zeXJ|x_?V&Hb}XH<8&4_75UQUO(v`DO+@ zDrMduE`Z?9=9l_lR%W*hpK@0zee=iSA>vlM+ZoZ5V$Xt7Ncn~R#9B1Nmj?GRjmBFY z)xE~RD2toQUFLb|7KXLo;s_QULs7=R5Ih5by}we5mwJ(!U=3=X&@Dk%mDX|w$NMuW zHZs{tZN`$z8uFEBCFg(pEp>BqHcfSF85}<|3QgB`f+Ala2duFzF+foI#M{9e2c)OM zO@P1lV;7?W0A^;fv~Wd^?=+(QW((X4KF}ejiwsOj5IatPaT*6&(>LB(${s1i2nvIu z)Ed-;AV8JWIs^zp5QHHJeN`$D*XS|&&bI~-bRMMQ$EE1>fB3=6r;7Z`%a|qzEU;$V zL$nAEL%420RakvFn!zstm`C5^O3v^exXPG-WR;w6nNm@>r9ENUXY>-IpxIU_(~Kwl zN_Yl~oWN~lF&tEbLuYg*J_}*jJ!R7iI8!6ekk?u?keo&N2}f=|CP8938y~#*Q~oYF z>>E0J!5*u%@`HDd3LzXphz;0iZ{xGl&sPU5s??gjAYCDoZOUUo?8vz(1J1wlurW@LJge zb6uhZ`yw0-vn7@0DcU@7{zWoI#Co$SPY}rZGP~8Ig7I?y0I+lWAnlo)n1byq#n8R` zOwhW$4t9(B_5f@7GgDGBnXyjyn2P|0GmbnH6)$yi%XPHCt1if^SlNhi0C^e1PG!4m zSZmX?TK4Pc_dF8xXCqxl=3NL^H)X<{>Q_rL^44^H>R1+RhKIZ*1Da_0Wg1|+&5>cJ z-4g!*GPRLaQBY2tAnAAZhB5NEAIwsi1kN_LZBObDM}0xj{o z@kKa+==?I_+nV&TpjE=+g&V+JKJTevbOou>#qTs?70CTXy0qsri5dLK83f5fg;|=V0XgbW0J@j^5*w>eN@H8lX74K4n{_b!{d<`8e|c@MjN+ zwvh46^_R4R%FtB2>ju@4b2`Z|$;fZ8-WL_`JC)N&^42KEfOh|Mx~ zhWqO@y73F6*AsYPqfq1bG~nBjUXZ-r4u=nUVZvR3{{UsdMF#2jinxrJ7n_T7c6!IO z3WaRdtHnpzOKkqIT43EcN0b;3~9X*A(9W0ExAM zc0$^gIyt55C>R1*D80PFU>$0{BF$T`__G~W+~qTwcm-L_VpBC6WqodEi;U8=?*Wsx zr6zqfhSsX?2Knt978Ijz(<}$Jq1Tv-q28+37b`7Z@lJDGrtLRCk$@Jr4*q5#Pi3Wy z#iVc(OuH}gg_I6b!7*x;sDon5y>#saXbait*b_&FRBWMy=#IYRX`gibrtv+kf{|6! z9$g;ONDJa+;+_Zo#WcQbCXgQQXr+hAeWMY)&%rDHsbBR$ES=71n@dy64vpxc8*zy_mh`=Top18kxhGvVs#BID%sjsvXvQ-*(;v87c z2WQMMdn~8!RbH#2-=>gabxj_470kr4GaGNc%n-w{S+mb@L4qNHyXFlK4AuB!r&8FQ z^7&suP-Sp{LZD?O<3SFxO!`KUI#^1CKk+)$sZzeG`YJtG^kV&NfA~OxoZ2###-&sv$2@jgRrh3>&Ut5|1O~jq=SX-O7w6SW=puZoFF#^c8 zudgzYqR2FH;y;0#lUssptCU)L#bL+4Pd{i;kQ(TC+6iHn$GX1|tK>z;iHW9K66N4} zkZyDcN@c9^eq(Oy9LEc*3u|*(g==JZvB`wkci~DZbvR;G#08>;)G;7Vw3j3T{c&PWt?B(wqhrr z$TaZBlJ;VSo?ub0&97NZeZhC)FgtEXnv8`JD+}Atc$A+|s%_#m>0ai%KX{be<`(m7 zv=|AdGexs3T@_l7-TiRwP|8yBW(*Y_G_M!(#zVL(Q&4~48p|xDr{M6?it=S#Qk6Ie4`X;W7vB@_g) zN+zKmm(E0mdf4^YsH2q6f4 zAi;vdE`+#4sq~*+N|gl4WlEJQRH((!^m;!)Mu%7b02luN6GHtt^n%nqh5C_ZQwz#u zxUbo#wGah;+G|;qH?3gaDOgXanH-`EdWxl4-63u!x9%X_Q)HLF+S!B1$jC$_@&e#=4 z{eyg#{K`Tr3^;eA+6M+cTKh{di(tKb#1vaMget1c4!Y(eCXk~~d-as+roKr302sQR zY^&#-O+h-&2$p&~4LM=G&;+C4C92-xb@L4u z(@Sy3+tMa=l`DJ8WVju8+!Em@wCXaHqb%%@wJuwSRd(EF+4 zrfIMZ$N2_}4z8!6G*E$b;5$vS_Od8(q;GvBeZKTz0*IIaVxT-3|%96^>MI^ze{Vy9_wh^Y3n-YUzB7MIiWGSaT?zn$h9(NVM3a8*r$5T`BH{*g>36JY|f!ORFk zT)A+Ipn?TOFX$LU=p}U^OIOiSru!093YF1OCKD-L1c=1xQl)fMV;J?RQTiYJP!^xc z4%367R6wu_sm$PKD+*~OQ;jy35n`dUv;&MV?%kBC8M{I4QAdQ^^9yJfb^ClpE5Tqq zLQyS79i`)WIvgIDCDw;Xt-slqCL77-oW?<+T&z|K*Vbx)`Kki&LZ!9AZ!uz!;fT6O z_6czyuEnKT9-w4@DVT?$XrH-Q)u1-b!bYK^#$c^{vo4z^(Yae``V%nq#LtL}Gp$-3 z^AaKEdxo_c@L;u{;x4t3P7IR_hVL@Ba!=y$U=v&F+pQWG~bD7QkbmY;@%(u zWi!x!xRo5~!Q^+8h}THTTkOD6>g_GH=V_xT8OsL$0Nv&6poZRWm^3487W=2E0CQX3 z(%rpH4R@FY&=$}5%FP2;E8}80LwY@)iI-{Mr!R*QquWeS-XK=kXVe*DXMZ3^qw zXeY1L9oeDhy_7Vy>dL(*?kvAjzAI&}-taMkj+7ynApJED7G)^Ax^ht;%kdBP3y#Mjc_+#q{%F?(etDVgf=T1nTP_*)yJOk z7LI$0ffW&g>nRpO{Q<1fLyP@72{Y*El?ia@bs)sYFilZ<246rz9Zt0jC7fLabqv8o zsa+K-qZ@PH?t*q(g*b*19n|Klzpem0yWeP4;GFN$X26HM&u z+&~&f3iIE*Q45?fdJMlGD<4^8y=+*Mf;F^OKU2~$FUSS_%JX>sEhcEX?H&+X$Sl=z zVbYXqK(k7Fh1>p2z*4}$-r?GZR~qx?QL<56eq}{5V&|qcinW1x)93LIMRowGKvutT z-iXU8vBdnLq%mqu5U(NuDlS`+oJ#U*03!}l+wlsoUD;0)CO{v85M|~N4ll3@SBrRo z12DPhsJo1&yL|06D`dP8p$SDDABY22GhxOkN4zqfa_jp<7?!5#*p{{%gn#5CR@;-( zRQKz?dq;4H8P(bf{5{F;JI=>CD_ye+3WbXx^n#Y`yj?uoE5qd?kJ}MA0M@R<)(nEs z=BxYdJ3(xf{lpd)Wek1*FwPb$1<#m5;CL_gVurkxL(E2lL;}p#jB!{1B7tgo6hGn< za>(ZTZ#m)6Q)eVrFNBZNX<`^QqlnvA;XV182wgxI_%wr_%>z5)p-YL;X32!&ioL0c zq9b%f1f-@w-OJI`Gg7~D+02AJVQE2w2qyIFDI1Z&$uNLBu(zqqNfcclEuLWn8gh^0 zv>SAU=C6sWh_GO(S3+Ut;c}x(b%Ymd&+_GiNmXBAylFL5FpC^|T-QsWgNSrtE?gO& zhfv2({(%TXsR%%U0y>y#Q$)=xrl>9$bWVPRi7k~(VY#GtDpydsils-bb$V1zgpd9T zlEYl+(ljK1s;pLuSp#n>NxF zfdbl>Z#i_BQo&aRdUF-Wfwn8(c+{R#Vg7fB1vOL+e`Z!}E?L4C`b+p>q;22KH;Or&^8gHRE*Xl-X2#p#))EITQ7^;$ zjol)%wdC|No+5KV^j0u0VLl-XH;gzz@ZjIfzgs{}5o`+cT1qgj9AKK$P$|^!3=oDijc66N zV-{NFP!(G2Jqf{7YLGQvOp_XtM4nS211EZYU~~}GR|(#yS$$~ka$H(&03oj+=(WS1jWT43xorw7G3v*v0&BZR; zYP)9;4I!?J?DfRO6f!B7<{&Mv7!LISyIT;Z&bcqfAdYKho}9!rh8Oz3vnaPNP1xc5 zOR*55tI4#aw1G>EANF9U&LlUiZJ@i85Xjv5^kWbOi+u*MDXvPm_rvB}uu^G%=xwf`RaSlMb5MUXk|Q3J@^=00Wt5S_`kU8Un>vm2shG*&6r!P2t(-##5xtw9)b{rI#e=*xXTQ|IHpWVT`CD(4RO{! zhpCkZPCX2IS4LiqeFq=-2;J%`<8o-avX)t;S#Bw{ zvF!DM!zQkgD(ZB1VTBP0mEn2(!R*(U%A(**-LgmMlNRMEBzJ{KxeE*AKbTj5yKUFf z617St+qAS!nk{;BEGi3QUEF46D7q&Z?TNfv$g*c$W|jpsNp~}dT4j9m-I^PFIQr`t z-dI}nN*3Cck6t2}O+^Uxn03bz;{>&ENvsC7MFqb|c^-z|Wwck?_Ccvy60uRSF@=C> zw(z1I6~S*c{>IUFuOZ$qY%6Ea5r7TecM%bHqlc zb_)H+$#qZ+4kZxme>H`Qn~hCX1uYQ~tXClK5C~pfhv^D{t$*xFq;+Tu_>S9bs9if$ zYh>G6uZUFH#&RCfB^;|YJ|Pw>0p-LLL>4P!K(tjMHpELNs<<~m!50WIaD)*%rdmLq zkc1%=A=9E<5)~_@O6YYE=uWYsBqLW^fr(P0qGtUG1EQsLx$_wD1Y&Q z5RMIDw*xt_m^H0LcriCuFsPwsEwzFOQ?vZ2(Bfxv;$y`*tdlTq)|D_?o8+$dEd#Xz z(abQzv-1oqbn$;{3zb>i^3-=hp6k~1 zngb^LrpF~o=7w7-+nmgD4(mSK!D=To<+QlV8@XN`q z&v?Cw+wg{{9I1=;sZh1o_i>10(H71fwc24S0FBq|mYPzPzPObScbNNjw4$2e(oiGD z+pN}RRY*E#Z0j7wjAgO^0I)Gcrr>SfY)?`T%*Qe7q1(@rEU{Y)ms(XsrS%koc8|lEV5o0aAss>9t<3UfO|Pvon1i^Z^A^=-dMA%~p1Hcq=4!;?KMIA9 zG}U9_mbDICz~ui9|IAh7dtx%ImT`wMAa8vM4G-sfVlIfxtzTjUCZ^P zDmjWbo!Fvy$%3_v&J4=vaEaD%>B3!f70p?Lp(RR-QITQ)0Kmg4ZqP;acMrK|3MSt9 zip1+#D~4cB=yA1e382i=Pxb%}!-9I| z0(iAv97;Bu1g~6T3qWsf>vAxpTm~toT_8#fitkKWz>1ZwU)h4d)+GUavjKX>>fk&? zbw=DW=zncBEvAZ&^l-x58Ko6fxJu9~c3q{Jc1#DL!5bz6Mh9;4niI+TjlTQ`y-g-L zQ$_J}AY@Rqt{HJzk~((n76J=2Kb9e8{lUz}3<#~a9pCb-I;NY zKdMktu~QEj{PPEDRdCCV>w1ssGA)=*qR9X#Pq=(0n9FN+2Pt8 zg$||pvlW;cRmn43(-{7^R=c_v+Oc(wAV_TK(KYn(Ew>kjY->74k@Te_Yoq&$3zWT$ zv*uC{@C_x+BClLSx5=ixrLBlwIOh_g)nF=13>cDitGR{!tjH+yQv5v+_??+w$8w}a z}HCOH&dVTjj%?`Va$R?6bJm`A`k{@O3LeCsTX@nP}DtSI{e+YnNeAHgB)!vR|e zvn()lFKJ_KHnbkl?AU3PEGz|)c9s7CA|9EPu!>(^bL|3-Nlc&eZ?z2Fq-L6&f~L?f z3M^`>6Jtn+N3b8MNu*GeVciG_LJ))@2z3_+N`?@GA<#pi1Ry|y35p)bN^D%mHS4Hl zmJiT1^(>(bV=+bsV#OH5=+vl@BOaBeT2$Bd)RuQKXcp%mmYT*$yUtrRg@9Cy`-(gD zMEKwx%nSu{2yeVeNH}ElmDpi)YW+VGR-WI=i}e?H*&bd9u} zD)xUVbDey5F zh5$7TSK$k7&@R{BD$-?R{W9b(yn?-1UFXE0KAXbWydkSjc$93b0AE>q)t8O$b3_20 zAMa>^iXBF-8ID@e3k+QsZ-_eqsD@t9((^>G^)dqUdwa*Us1va=aX%H*os;AvK+4hh zVLD3S##ut@+Z$e9VUba&XXZU^L4RBUB?dP936UKEy_JbFoZKOm(W9?V8sX!AprxVZkSvS(YcG6FZ@L`n)b0FoT^mL73j+9RH)71 zmdc|TqQ@3va6ew2yVXL4PQz9Tf->PXG0?CIk=|S_PuaY~KH4V`$C!iR+EmwBiXI~H zEtI&f4zglg{B8M0xmKEXVw$LKmW0K!>h@LLgv0MAUr55m8MdRp69_PDp;=YjeD<5c zT2U!hj7+m}64?(tOX^jknMIz*6t$;qWu?kw z0BV!OXIM*Ibc?3-(%-}bWy8Xz$jumyAJHjomq9(^Jmv;zCV))1lH?__oicDVY?g%Lr4zT9mw zrN%9R2#U;Xvk1P_uEm1HaGUtbh4VcAV_=pqmzp9g7jp^gtmmzx(g4tfI=oDQV^Og6 zi1grC!q8#c2i_%^7k!3Fe0dvyXUO66l$meRi}AmH8%(F$ z#1Yg7#I$jiVz}Z{$4zx&oAP*@2be$hVyM7%fNI2}cw?%%-siMf*}VWStP4fxH3je9 zJtwzu<`tP*a9fm)xoYUsWTDzpr94g4_lxr`5IqOPRigIVpo@ABH|29uy=NEvMS(9O zF@)41NM*y88oGJ2gG$_7!5u6lxh19X>EtG8CnQ+Tfj;gj8<0g ztT1|vMvDw{rsCIutBrHi@+tG{Tehg;Y) zV@^#zZel?);^5YcYzA5Hf%|O=)6Yvvi#U--tS)>g)@VT{wXbPyoL#*l!Y^T4H4C)O zv`3*PDcIQ%qIf0%Y*~*0VihZXeWllWL1N(p|I7W`AihZff8ksGa`+nx4{-tk#0Q z{;|UhU~%JlvySyC;FN4mi~b*IXa?P4nD1KB@#`E)tA|3Ag?HBG7QBq{8J0IWgcddX zrTWm(l@mPqg`K=Zmm^mSZxs=3Mcuy>IR@`htJW*sNt^Wk;$elcPRCk%T%v`iTW;E9 zs;uq{tCFaSYTH#O8<^uF-Uu-z~FG1X1#{UxAQqfA2X2IXQ@4%`7n zMa+eTZ>$mkWkprUQ&BOKrlI`Ghlsimr~v#$^v+T@c{wM zAu1Sap$J2#WEY4m5)2_Tfz+e~v!X7D3!2ew{{Z21I^uLPr8#=lDkNhTEM~1A1V7Az z{S*A`f5(sc{{T~*V>>~dT?RX~gL6sP+lIeL&=o62D=D{O@TsWXa2CnhRS4jf9>S_Z z7v8!ta}LN@sdwfYFkieZC7^1}OVh>7gWg>e%1trz1xjs-&%CpYD@}6F5l#eQt8^QF z<>f0BhY-19?`dSC?KMxCgL@hbrMGtJJ6~ub)Tl7F#mkmXIyiTTAj(#+@?ehkUsS6G zJ(cdj${2XfYe+25%*ACh`^A~OD$KB7Y_5kIZ!o2&QxEQC#8%}F6CMZJCaVpnHxk0! zz_75!H(6T-zQ?=^S@&4|Kn4-Tv+2yPH!VzU5ujXQ{^PZD=h7v3L08PW#BH&P?HWzT z^H>a|V*>k=0-#W}isi<#=X4IIIEV-_f4G=614f6&@}=|TTl?`4VH;P0;o@9)1Z4(q z$XN86CtHhp6I&&#zF1R&y+*N;a8ioh9)qR-00<~5obInPFyLY;-RqNEO7BAA8`f)P zu`5%`M#DTu^BWu%3r7BBw^b^v_d|{`orGnXT0wY+Mu}_M1SMP! zA<#@df;v#>Sr}XZPyRg$V5xIRrA(QGyU;~OjIM?!&^71(0P%xBRIM0P8^$?aUOU9m z#H)^b%RZ~rJ3+o$8xy^48+DU3uP_SLS{6RLN|+~QWx-PEUSh#pW@^{GLZEoV`>A`K z2y3nwX2%^X?+s$|qZh)gCG$1T{!cRs3EWJ>R7$6^1l4^ovQn|QaQBuVD=pw@ z2T(;X=ZJ2eAB~&iMJ~Fnb@1Mbn=D=AcabHjCpu+~>xEKjpZ5;{( zCgY4s z&cm5N?%=BZ#d;2OU*?wV?;S-4U^nxLaL6cVedPr|iR~#Ab;Fxxyz}#WKw4>*h-=$c z2CV4%P3aEy@bOT;LA=wyj?%?gY+A17D=>SwUS2y&Lx^gX`(gEsXd>x_cI_|`pc^Au zfDKlF*Q_RBat?pljXaixoJ->?EP`P!+ffvbIx8^}D9vu)#K@s6&G;){;$P8_hOf_P zJT9RP{-PBN4YNE#6nonj^XqSAqWsf20pSoMCpwdT=lR0^yRtCB?QUnREUfM zDkHa}9YyFJA3Og5$^igJQGsj@f0~i1)WE1Ir&DG7%90i<4`TsXjetAhLu9I1=A}tv zZKg0UGKP)~r|v4k7LU*3H71ZL{{XRvMgxP=re-y@R$>VX-n=-7m+WZMm>Ef&kMG0? zUj9rwxjF9jjVe)2f%}-@D%-Ug?$d&A(cCWO=_>E2{2Nf%-7iQcHgws?J-fy#N-%&9 z@u%JpfymH+^^PT!Ml-~{HMO)JC5cnH=p{wBaUF-4v%`)K&hP~^&@R~6jp)@$ug=w4 z%UWhklDQ4#B1kF|x2(!Ub5UL*O|&Qk4aXP`ubEIMbXTDSp~&QcbXpG*~ zu!o{oeT=QWqpkKDF_`&ts|p8rlI%9Pag{NtxLpt`v%`K6NpB%AvzltW61l`i#CDg8 z195c#kGd-R;yx<~TRtI2ci`GLS3hC}SDWaI7iVfd$*SQPGnRns3ke=1V?DDB!DVj* zQ!VXDoAVfP*AbpJk3FXP#}3i5h1WR52!+Fn^yV*sdZh*<3x;CPyKlUuN!dkvOY>vt z=q>0OT~a+J5QI8gQJ!-6Ord;B?JdMRAi-mYQk=Rg7t7Vf)2pLU!~Xzn8Kmev<_4@l z(lG=~7?+|;Z7+G~+)`=(0Ot?@g^r^YsQcCd2n*HMzV!qXU8X4OEq)B>Lmzkym26u; zvbb!xT!Zl4WtE^dY&Ney#UxF*Ovu)yFP*qrb@hE@^IMnJv(W2W} zT5{IMLs}y|nveijZQw3)3Q*~@J?M(kSp3;PGVR&X)^_F`qSD8C`w%h1R;h|511WlX3>{@?Qrm`SZc;~j!O=0 zUWSoc0l1}4GE!j<7gHIfYx3$(mT5_GUmHQqCmUXT*9oP zosQDGglbzav}UapFKMjPdNoiza1~Qcw3V$1L^`qKFY&Bb;Wap(!hby~a=IML@+XZm zBq`Ab3?)JgDUV9>nNJWNAi4sgM+iXy&=7irLL&&`=QTPL6-Ph&8#5;w^#ZWLg^YR( zVwlsU!gMK^`Jep5k~wCo^2`dpS7lquSRtR5jgq_fr-?;k#seI1+H_*g18s?Y9e~!_ zlP16#J6KxQ>n<8J^n$gd*A~sg%KnHf;BqnYhO|E79H{rq1qE@99}ur&Do|YjY50dT zkw%@}=VrdYb6-d{9W#GoIh>TLd4Nkk3YTVluxgA@23XpD0s;5dWKuL1_-nKX zD@D@Q8adZ|1E(165m1(;Pm83=YoIdhgN7|ZTISATa7%$+?5?-Y|H}m2R@89n<@zH#kWP&P!QX+tF^dG^xj^= zw5F%D&X6|Bp%T5g7uEo)<|jJec!V2b5A1*sNKrA~&CO;(n4C#g_tG)S7)x8y{{T>c z2^d;61lm)NMN!$U=*?MB^2WR{nwlcq4#M%BU?x*ZTJ!pfQL(gejqNF=TYfwJr2*Sq zYgg(qI#wGR8XU`&qgVqpH5|VG zgBfm%vDbvhpj=5(wFR^0Klw{ogH}%VTt*M}F}8WIO9W){-$+)<`lqZ+ug!1VhfX`h zb(mV9pV#pySVtUxaflI&X1__8cn99Kh%6UXwrvo5a@&qMmwu!ZU6v6J zC7_|Z&ZTzq^~l_ z>ukWztAwT0<^r0~=}{Z73~uc=k$~T_1XL&h&w@LfVa6!UD7?OOgKT*l=*yQ`DaF~@ z2TLFcX_Fbfx55d_KjK%tO`>&m{X3(dod6o=oAVE?z&g$ zG-2sD)k{Q%0N(?1gnlBj3iw&r(_WB5VwzaI(@*a31Hf#({6#>;yn$Ov80Dq|ej&vR z8W<4)FK}-x^96}ypz*^CF!zhK*u*@*(Ae3i8keQ1@~|TNQ%KZ9JH3_e|yB&*?K+j{18{Lu>|-mYYL^HAD^H%)qYG zvVOc2Ca6j$)pWgoCSN8dz!TV3>{ipPP)A&DW{9m;G@7fSIEjv8Kk9U6I zF4$&Jzf-b{R-N8qTmXn}H@&rE(k$awu3s_QJDit_)(262);|#^b%E_%!*@$&WIO`>xjj1NeL0`>tSJC-y) zwJ=QPYPT^}XOiFM9YMob5qc8UcdmuXT%}}uJ>`;<;9=sj%4CjsEvQPzq|y7>w)gWc zB~DnVQ?k6bH;L+uG?7sODzEOi|i;KUM&rs0G`xkxfx23;L9C~qqIeT)n3ae!u)G^YOm zOZroq&#Sykcg*s)cjhOOskWFLA;uHdVx8A6*_d~|@{6M?&|!btLo;k3%}#iZ%w-uS z#*HJaNMfcqy;$dq0@UogO?uVYMKyH`$n8pBtV{@dW$YMjV&SOK(F}+RsGjjK(z_b?hGeOz&DOWPZBdHc zy>00RW}xW4&_#-OUHNCda1ny&K*eV}GaiQwXT~RVA=GyChRAVhAqE!*M-zGM0N;Pi zzCr;_3127bcw>oUI^o`FE6WnI93+b@6tqlR{!L}rYtkC7!)r{%>OBN-9?+`816UH{ zL&Ih@Uej#3ma1H{d2IzUcqN}%prKoCyi8lxF*o#>h$-BAON*uIfh&h)mwf&q+jkw5 z@dD;lR~X7c?!cEa?|XQZR!ze_%sAQ>+7!Y*`jW1NaBFt+t|}_8ofb5{BLdBWmYt@# zT(+{}8wzu;;qNxaAxcLDcBUS0nQlK|c$HXh7vV!&@D_rw!tbph_r}B&~zaxR0wj&kYP-C%BX!I zH&{68E|_#Q<{uI5Ct@OMOL6}If-6i)FqVUaJIf+#2ZgfEi8EitjEm`iP$e;kT~x(cfIxtj#phSb3TDt3+V2HohjB z^60O4T6f1tBQ>DO(^)~RXesWTo*mOxzM}Yey_>l)T}Z4oO}D+Q-9frM$Q`G<9DYxa$=Lk{NO z0A9an8u^egUhdO!l_;z?>y@7|41aQ#bJU~j2=zjJ>L;kPo4JOfhIK3anOU!Hn0xXH zJvWM4Ix~U%Xfqo(}880 zYT8>VfV!&r^f?6>9`g{SR_NIU2eq8m_g>)uq3qBVcyP{DZ+`^>gX;}*{`l?DOo8L@jt(#m$# zmD&QOu-G2hfi<<wZ8YUofyuOdAHgDEJ&kzHp0 z0P%m7aeWoYFujeUr*)MA6aEF2Y6McF*Ay;*dH?wdW&#dsaVbUR0CnjZHo!qYViSG z#4BFX@phrK3evq7SPa<^Rsae2P}&}kV*l^hjuW$P8vQ*QMIacaqk}1)KbvY`^8;Hc8`+fZK2;q_kkPj7vX|o&bp%!Akb(H>R_(! zNbtE4s%tx0t(W zUDVnHsafb?l(Mf)5GzP2uS$d=2uiIw5(=SApv=PI)k}iAfl+P@Sn1j|%gpB)5-PYW zYaKNdWm&9tbP*Q~MqCyXJZ?-O2U#p(h1G2+xqzst=q>*M;jVAKIEeU8rUSH~YQssU zo5fo{HlMjnR&u7kW^37NtohbpIxQr46TG6|9wDvp7Hk`0ASSO}?HQem*R%XjaU$$7 zi1PzMPJzeJTke{sj*ad^SShw2cpHbIc0}b&Nh4R6?8I?JRAr4DxL%9lCdeBM2F8+Tv2f26E33%U&>5 zo*_4Mn3Su@E=tA?HWJYIr+5aklsOx}eIRf=YTpDff-eeaX6tE=Sl4cN6UD=CkRW_E z%%>mO`H#;syrl&I9zWS`?n&Ff_VUAa%n8ZbF1N01X%Pei4VHapxhZF-3^k!T;lrJX zObQ6)wk2)_RlQd6HI5agKeURuEY*U`(2Vw|3-c=mHFH{Zf$=F)yJ8k)Yj@V5G?<}oW7KeIcSgAF){{Uy$ z-AHW$bGy<|u+kA3-rvOEkYGggViVqthx-wuvYI9Mja}1Ijoc23i5Lp$979-_Y0^S* zVbFv+5{4FciL?%L51{I`&_S20$1p(P!VS=BTd$y(k?$f)ic9x|!J~I<1 z!Jq-m5rDYY=V+}^7%GJ&n;vEC%V+90G7Tdyd1O|yLnKCRaoGJ!Hq%>uB2=riaGA_7 z$V+=3KTs|x^>MY#zMRzcZ3JLlMqqi3@@l@dwM)=+U*t^)ka?|{`HD2?8rJt1N5E=5 zp@6lH7Z_0d2qRHAhGsl!87t}YiVc7s7#`GLK~uAPYVZlboI@}u8fvc#b; zhEvBzj)rAJ3{3Q^=oB}^7U~@ihf-0N*@tN?YF~&9p}f09z7m~DV{7RSg9y4@(^FqZ zQ$=(gBZ)^wy(&Y~H6EKCG{F)SnH^W4Mr4%6JBv&llVAP_Yt~uZs5N%LdnM@Ds>*rd zG#KkNXU)VSZlJn|;fnW4)*&d9p6Ux)CdT&d7A`g>D-5e!!H2BVwI49U3Ky(-@dI7e z{_X*)*Cx*Q+dKaNWG0qHq&pnB56m;kjSxoAT|~^vVAgkc{L5%I;HUfMZV@b_(naKH zU>9si6tc2>%ji*FuV`DDHm=g`3;5b=fmlny3-0s3@L~qAxhk_8j~j<>(*1!FLZhcKU}z0_d&$ z&s~mdh*Zj5s}|-xQh&gQxKy_#%&iKpnd6_BCVM2j^h53TYG3LW0b11j^ErUmJ?q3V zPE2vL5N@o+u*T$22@U3<7a`rt4({@Z5uH&Xh9^ZtvRb)uzuYuBQJ0DDUcpA23Z; z1-)XHy&$zg90`hXQmeSozDcU$*vLvfD0H`;S%sRZ=tiWq`D5AxoO(I)hPo<)55o~- z3$kN$>2auzu}cNe(-+=n6oE(uZR;PJ@|>ZhOZe$O?dQC`MTc>Bd^K>8$SkhM8dv5Q zQkL31{`uwt6@A1XP3C|z7G3iaB38{>wLHf)4y_IeEd}S8cZ!UwP6T$5R_wu$&xkm;YCnX4Xq?_V!$d2`Uek^0)UV+m%&X-% zGRcML(`F`UVq6K#S-sVHH$e1J;xiS5ePF(%8ogTupN*OX^;${{WRV-gI5! z8V1+}{IJk;Aek?A;`X*hSg3Zv=M)E%m?~j;634mFXZ-k;+|x(9GNKME*u&Qnl?{xo zkHQb4c9sTmw*gr$OREL`BC&zLGRYTQCv_RF)iRD;01?R*ZFJYp(vmID0LNrsIg9ZY zaazq5GIE?^Kvb5DIxtB5PV)x1H2ufutT6Cp1($HY1jMBD3l;OP5ko;pjo4|c40G! zWWC9D{sVx{YZJUc!F>Lul{Dl(#0N5Hbx-04y4pCi2YSIPcCp!6zf)K$wPVJe`+7tT zHgo`Mm)d3^(@lFLVB1=pd4;%vr}>niuW*0J_J^Vi3maq=Q?x{HWy8tiL0e)N}s;Q7kB*c4hARA2XRRQ!M!>9?(v!LESQi4cFg^cGJ(=5#7bV zW7=5aoG8P*ykB=;WKNagNXCrat_wA4?0fP{X)k#ORs7y#%Fp2OQLARCxvownzh%?z zikml=u~3AfF?}k5F-j*`fd@vUO!UQ-V0{4vz=cbRsg58jZ_$L&T?R0Zq-FG@7~vjf zc*A`I1XPOSE?-fCauWntx&d89(NRC~rf}y6h=Oe~b)HZqi&o7eELUXNc{GFW1=i<& z2;q_{ijO=-^~6=JzCUn)>Q&VV#Mtztqwg9`#Z!?jvvB_ad8fZzq{w}8l4M%B;uEY} zuGSwsd1{i}==mP-HDs*s;$LA_%@5o*@zyr+Cuq(WGXDT*xFxY} zSq}R_iGVIqLV`~@uL$v_7HSpoEZ}QSPu@CRyXA6%L!+);JOrf%iS(2FSbl5N94N)qH8} z%%iQ*H#YAAnC*EB3triFwdQlg(g4~^BD7`8OR%rrrQHzbs$2O@;C17d`^)IO91oHT zSvjL4^nWL4oxjg$i;X+Rq}A7R(lSEq*H5kQG~8(Yu!`-oe`&a5`eNk+z$>C)!{7W= zvZ2SohC&8t+!JN2hj=P9FBY#bgg9e0e$ZjiVYfjNRdfV!nV_zKge8)zqNiDTw>m4K zHNYxdT?VDfVHE~AU!XCJGj|wDdP1@6jxMv-{;PyAW@phLi3ES}u6@jUL{JQ>pV@<7 zcU%5NcCL}CA*~oHf4O3OqMoUUuPs&U#5K-%yh$5!6OLa2^E^vHD3&lS( z3KQRNtPt@A-to22tHy$0s!kbe0*42;dBt{yi~b-H(=Lb#OE_k03-770J57D2dwT5j zgN)68yIe1eD-EA6&=auKR;9`;dqY-8QuSP^y_{Q1*0zd3x;JT33NxV7OmhkgA)#%T z%)=F}pI#tjaUbjE8;N{Y%J0mr6_(qM&uaC8cYX>xJIggiEXLBgT;2%-W0#>hso;Im zoLzQ7Dw#FJHQz7aFx4K)D1l3&X!XIj$KRtAFXaCKVgRccqq=XWcvUL+r=HN(yc2!V z6BN*Xd(Qs=l^ zLMd9qv0F^sPYRm5qP-*vY&y-4eWjqovR3(sEKv&%Jf>NobsI4|PYd^BK&$XTec@OD z6&NQ4oA-jG0Mti_f{Ht?ePu1<1Ah>#WGt*PMKSGhFg|}xrTT$8mb)>iY~9w9cYoBIO#lV0DKGTkzUfWR+Pf|{iS8GWpm>k#c16u_k`Fe z>>t+wFiCqa>QPlt+EUh!VVVi#PUC7f>lzHd7F$tCa5m6-M9`>ZWMF!G5Iv6{DOAH+ z=!e9RzxyzZ@_rBo==urxMlc!xcIld1uffrw&cV2SH;MY|v#Yrz=akQxhAV>%7>u$B zmGAh6QqW3}$6zEXs25h~Fd*!ekO4Lef%RtMoS9`K39ZU11upgU z<{Ajm(D#J4^Pq7I2gEIIN5_bWd%sit>Kf9v7)l}Z8?vDXhfr|>R0&Wc(AD$-PI@0h z7{O$>5OuzWu)<1&f;|HzU1Q36y;s7^=*#J9=qy;GEO^9!@e303uZYuCc!j`H(VT^Nf^Enoy-UKrZRcHeU0{QV3ue31xLB&B;{{Tp0 zmKSbHTaO!bF{C~y2BQQOduQ5GdkcE@VB^u0!6|PQ!pD?JHgfPrq*sCYWvjRoL3v#? z&a3@QfulkhgYJCIF{%OU0M|e$zX%Xm%IEn{+(m$n=T64a`JJs?DrUU9#RX+S8pF$!Ex4dMJuETciRy26g9LHviU6vvjnbcaHv!q`Q1#gkkLhmNB}B|w#k5IO=D5~CF=2SAA~OIemUA)xUF zTs7)+M6Q5yF?t+kRxxLq`Y^^Z%(u9KdUBVEeM`{g7%=Dm02B_iXYCc;;oHO_pWR`x zX3b$9mrd#8OSfRw;2N_HatQW!dXQwk(5Mgh5oso zAZY|tN{Zto3W|M*Y{1F;K*f`0uN5}sZoq?Oi`GGVwT5OCGK|wVN7KHf%%#l%=Xs$E z&V+x@OMF(&@IlEK$= zatpNOb;^>?kR&_B0v|%4bY3Q?EtM)A1P+G|h72JpFgizAm^unFz?U;d5$g<^mE3=*6qPE5z2;S}3rEIcf#Ti$N;LB(p7B*;US(Rc7H< zfuIOmZzP#WG%<+X7n75|CL?!%KXeL+n&(+ToM?<%;_%w@|CQvUIwEhx}d?5r-s zB9E@Iw{tCX>$J!vgO%h*Ob9W*%y~}ZD4t1L&H}-MZYW+^K~Zj4y2Ts*w_auIC-7?; zelUIFGy|ZHS4+x_;NfUYHStJd%R-qVGGu+`~wxm3o(1$bWRjjbRPc z)t~4}Q!aJU!1C`hn%LZ6-|_aGpB+z9ETr*rcZ(SYiLGyD&#y~niNTcZ(l#4Ml(W)I40trwh5GIIps34{qMT}(cClMDKcPFR}qNOz1ec}ss)vDmD6dI;a+(B)i z&L8R`pqgZR7>knMR%ol+XUxcDXy6`ZmW`FJFRAr@lJK3;*R;8{WTWK_P;GSA2pR=Y zP(C3m(IM|KZF~Ton2xnEd3Dg@WZV;Ay`|<&WM%Pi=RCTnzcV|bf|$Kr=@cZ`A$i?+ zfFIl{Mpa9-kKvp3<$Wdrnd=B9(~EuO;KST}e&7NCTL+$+My;+<_d28IA?gOv#dbUo zvQsl!ZBs;1%`x;zPPds-D64I)z#2uhpz#U>rFqCdWVB(Xsp!V?0;QV&05MNiCwq-e z4rM|{`uOVF5}uCT-~do*(@&XoqiZe{P%H&&<%MRejk;=d%rGx=Ys<6~ zUX^$;?=c0C%4-HK84uL++E)X$EVo+tYIm2jQR4;L7KLJ+039Ye7jim6`VdNoKtO>G zilEj9N`s(rT}mtIb19b1CFkrMy&J-G+j#?tWnusNTPaw9FeqQoR@is5DZK_5${CbUmiM*_NYyAR7z2G<99N zw4+xCmH+{vh;0uYrT+l8o?r?N011~(zX)jCdO&L$L1-2<1$)f;S3?;eXhopFMWF+p z{oAy`T{@2p)QT7!bjrQ);m|M161LB&?+u|)H2v|!p@#jDm1#R*hNV+csBvRifU*kj zylnUG-JF@duG05edE>3V-HN{(c+dFQ2?hnyfCW}_>KT`OfAkRqa624TK{mkxo0 z)Xa(?%n*u?(V`Xc8LrZ!1YXV}q)VF4lvWNp9A=J_E<`}IX!Kjai3iaADOoy7;~tOJ zQ6$)rd&+#uWBr7Nrz~@kb*}I}4V2m`IyOQ~yQEs_Spph#3>^q&{XzOi7LaOU?+|Gg zEWVY99<*R)Jq*FJD|gV!FoPB@jH9u{aNJ&EQVG9Jy;1)F!I?CR{{Wtcw?AoXC+02h zFUa{{X`)@^RW;zRAPE(0Ps!5VC0Yd(5;bU=UWBF>!+YLjzrX zs$N(|1#XCTv>xNZE!vui-}5NYJAY8atUL&plBr6s(hRyhEJTf2V_sdS1>OaE!U8EZ z?RxlvA8n>J>T$zV+ ziDuD!EzdAzcUd*~eWsNf)kJX?;cb%i^X4_Vx2<}h;VpU`^oUk8GBY=aB+A_v+C5th zj%#mEGkk|979v!-YAQRg4^KTZ; z`+?M2+Opf$EJ#-_0{Jm(jUJio>N&FN^g*p#4wiKU4Y-)UQl@v-uyn z{14m?L1SMvOREE6O?tq}7c}Skht{mN_h$9XYvWpjihyHBloIjjFB2jM4 z66>kfM@s(yvX;SQ)T}qm73-NDDK!^YSRd6f5%LZDl8W&O_d}#tK)n+EQv#&9R8%aR zLzXDw47yAj8iY7Bc#YQ0BH$wEa%z_08-lTI(;R|En~x+8k7g8mCWc>H*q!e;3_xvf zb9~E-;DB-^I6({YQ|$(&$3oZpv|^;V&}HA+Ft+~y;NouPVXl~akr;x)@P~iIbxuqL zV74`SCgN9oMzR4Ql6kv*KXJwr|F-ZYEYb9sd9~Gt?R@ccfo0+ z#m?$Q@;)WM0~nQt`E%Dl<`VM)*zQA7vq-DA-Z!fnZn=~#3RmmTtfUMhn0Go98-*j%W`LUOKkV4^T#uavg11LOMUl6f%wHv=M1)(`1 z=ns?p`#?{|2Is6QCk2KSckj?C=mr#oa|)=JqnC;(E@tUjh0r|<=p8*bMJ_D3ML9+2 z5sawA25TkC8-b&u^oB689Mvuz120l_wS8=V^b{3W-fIOK;CmAd8%4N=4ZG`mn#EXf zJmKjvahi(sMqIUM@5+`I;u7J9B@cOkDtWl_Pl+`Mi#GEu-k~&|QFV&L1kZ#z9nhfakc|(+GOU;z zM${T=G3n_6OYWNR_l)hUd~6D($-4gef|ExKp1Z|G8_Vr-mHC!XD%3CjPl!f~@(`6Hp8unm2=KPu#-diT?meaP3uQs;IR+Y#aB9p*EQu z!PU<(l}xiy4q?o+D+NMIbZ9zUP+-E4=w<2@xp;#Kx6-L+MNmTq&hq7mRTNmcnx!X1 z)ELgtdP4?gT-EhI`W+dGd+Dx_98!w#t)UKr+XS-A_ACwbl%mQSBz|KLEnD~WmfVFY z;=Oi=R6ON=vmY7_=C~nErkN={eIm-sOgVUWnAGVn4`1zO9HHE&?hzExRsqD{+!BYL zX0`}-V9FO@tL5tm4LMch_{3SExZ4h4ec@c%O}5ZB{{U$ccoj7DjrUy*{dkFeaj@D@ zK6Sf(@Z90%R>H;6)6WpjC-$1at-pDC)NEjDXfF}NGj&lz5A67ZMYf#2vnVu~uD&H0 z$Yg67UyQV|Ll}Tj{{UbG3bl)N@ftf@W%1${s5$z=%#-ws$ zs}hkSt_wAisR5RZ9xpJ!>@6;2@07Jnu6u$hZh^-uEG=%I48dlEw9t&E)@}QrxPs7z zjCW2Q&)h(!oibeK(l`#c^6>$71wQexqR`q1EEcu2#p#T8Bo+i#bj&~uZ zpsmEeNnb*)i!jX4<_?3Ts7e(mw?S+erQ#1xCqTuErqF-zDjZRD$GpqWMH1Mf4vt7e zZ>1SbrC`*4nvYgL_#2eXM!e|GkmPAyFBcWa)sDn)n|Op};90s(; ztku^Gn&4^_Omg;%0-MmoL59u=?+&ua##BT`@n&(v=T?|;3=>8ZNBx!z07bihVmJl! z=%4@SYd6jF|1~I^uSzRT0M+js>7PIXKhQ|-uZ!fzUh+|jant_`v=JuNZ04ye{ z+}=`->sh{PYd{1u0UEO-GV6U1Me)yh}`H%2pa@X|*S74vL$Q9g6+LGelW2 zO~v{u;m?vbjYT5iMT)mU9YWV9oIoEEKN6_1!IQ)SbZ)`@?HjbFvdQ}xg|25xJfI5T zwO`1<*aB^@r-(MN?}Q~2f&9y%UWv5+A(TNaT2cF(pbPYQt)Lrl-7X5!$3q_oirZh| zUp-JnOC3m&y3n!YinS@yipDWG zV23iUv2|AAE?j<`#Du7G^xR!uwJj6qB3~_pt(MR$V!MNynus(YtUT))bY}HcZQ26A z`r_PFas#>H%o@=9qnHR=g^n>YDjF)Ew4%nfWpg0`z-hjHr3IM7(XQ|g;w@rylq!zp z{C=Z565F=-+q~4VoU1c8Lt?gF%L6&KmS42IX{@Fm-jM*t@_S7_Hf6^9@i&jSYw0T# z8iGHxsLn#|_=4qo0Wqgf=6C6Ne4G44Q@k^(%|ZrHAKGHrM9FXJWac{`yLf_*-acgw z>ifzmapG}?Xcwc@Z!+o{H;AtgtNToVSuK^x{j5eA5P1r=u(9EglE3{;D z)F7L(@QW`&bRBvY=n9Y0jAIz7-f+3yAFPCN*XC(!*hESP#J^p5#@!a!$x*#J5V z4f_&+@*1cX1BkkQWoI*0IlUvT(A0g|WTpr&(cd%eLnfZHDZ5)Ud6_R7SdC!My6I@EavoGS^Pcq5b2mnw}OhjmC%)uyXeQ(VBkp!f& zTUXr4F~PSxd-a9;p#8rwEWcPVlCY~PnUyAvlZR<}M-0AQE>7eiO=0r^-dVhBya)yp zd062W2tfx$x!5^tnM_npA=zfDn(_Ee=DvQ3VIfOn% zZmeO{f7LZk*61dBI#z#afiJ^pQPovyYrl(LQ0ho`JukTA_~(%~4((M(!( zeFUy~;i_g4#^LU2Jf$+6SK@Dh%}?@Fjm<@1Eo)%bWf&O~cgGP^fbw7bm;#$5T2_`p z9i*$?N(HEFG?7@|#O-2yVBseLg%&BtM?<@rsct)c+Q9VdD(z=_a3wfFkJj+FG z43!pZd37w&{#(sa-Zx+Dq#c55EUJeGMttYmUUtT{?F~x)BWY_=v3AzeSjSaopD?1m zBkVA1;0EZwNUfPtIzOmt$8r6hn26BPnSxQ&`nByf>;C{gj%%}1+BJgv9NJNs7e~?3 zX{;v}u`b#mnIRDlZdYW+i!x$cJ0+dvx`7)?w~Nfl)@7AU5}gTUL!bvhqHosX#fzc( z1JR7tfA|_gF!~yCgX&<#5>zqNdemn4*L$>?O4oIIxTvxX;__ckC7*ty;v+%9q~VvB zFDo8Kt;(V`#4I((lq@C;sD+xjePh57Y-j#v70v~(iJ0m&!+qkG;LU}@WV2FCu8(M{ z%RRpO!DI%l{{VF4Zw}`HJBTthZ4JA6!3honM)xn6U_#3UHN3ElR~_X&L|`>weY7^h zsd6>C&2Jk38pr+5<^JFp6YRdZmb@XJ6-qT9$9aK8(as_0g(H`LXuxm zbgjm;Y77cf&l0-ubnbA>$~<6v=jg~#YL>$_VX7R z6E?C%ns8res#9LF+Cs|e*96rdqy_xKjCU!ze9Dee$$GEv1m%URzN21XbK+fU3_0%r zKrGP5MGvXQ1qVvAI!jdu+>vpm0K6EM-D^fTEciZ_^R-d;9*`E+o%iM*z+cDiVtZu? zq3gLX=0TIp5Lyx3n26BPnSxN%`cLZb^sAx#AMCn*(2XXsr>XJKeDbl4nKUpl>&Kd4@nTwOj`54dKn^!&y1RMQNk%3GRDk zg!0*|O8J9SyK z+320`0T%1>AkkHU?>W<*=W3j}_KlSu^<&x$g_g5z7V13V@5I4MLi-Fc#oM#zt5(iK zW?IqNe;mw2XlTsADC&J50Q>z4yBqQG0)mc#6Ill+!5Wt@*D&iZjbpONE+WpvyJ(9`oq-!a4- zKq~(Lzfnw5*`FKsmBhwqTNp*X(JG4RYJWmq@eYC7XU_;Q?x@ExO>b;zFd2R0l)EDO z8J1IY!(6~>?+TOrmELP@&HCb8cYx=cxb!~)xrvRVv^ofC_kChx>m9u=Qwsk8fi-A# zOSrKeY!1O``C*oucHSm~`V7>2%&okL2eGG~S zi@~#QW~PT@FNjp_KySai5jM3Mkv9D&BhobN^9gSB1u2yaxpx&Si`g9vIchy-t;vuZ5?A9KVnc3K)&Q!!gI0xL$RROhtaF_eP8qFwgB#Ee&DIF z;58S?du}|!ux(S9hW%khH0_+DN4fqOSxUajhD$PY(=ESgmteuu`+0juW1k&9JMGi@ z{%Q2n7ZuF6Sc_0li{@=7G%F6ExJXNmh&xJ?Bn;Qkx(Gv_g192Cg`((VG5R9Qm(lu; zgcw7l$NrLqO!7hzMURYV>@?8E(tI$-MUmAGjAl zwO@dYdkt+_t7_eka%oqre#vw%8kNHKxbSXUKX5jMrj3Z{r34j|LSBS$D9kQtzu0WT zDQpVRJj>?18aiR^&F5(3rzd#xudw6VZ(E)!X^H%<{SLWA(KR5^=mQU2xmEV)YXvrI zH!ONyy!HMu;wxq-KaYr437${uo%<;k?(U z`r=l$&4=?(sZ73wr)CR?E`(z1F$px7V2>DFBbneuP$1_9BW{|31Ee|`Is=$LNLa;> z=*+ot<1g#DL4y<*DrH3awL)p=dMvY}EMms~(Jb@1-2KaP*Fs;gg~#_4gAEK2VI;i| zKGh0Sr6J#j3nYUBUY-0)2+4Q5=ZMQLS)f0+nOPlQ!~-o)qiBG2UWfZN!;)paLD-sx zbhtJm6)OUW3KlRgdqbCat@5}30ARH*AX$-~V64OpChLc`@!QW%bchS-yy3ADFY8M3XEPJkz(<`mkK-~e=Kx-oyUmv zy5+8TgMsuTvgYO-Zzx?V+u{eJYfrQVQ2_q{*;)$J;Uzf-eh|>FfnM-dO2KzLP4n=4 zn1x$A>P+x#HjLAS8PeCv6tKvuiF*Z^KNb0YdZ37wJ4)Pf@8K0o;D{nGD)*cN$m+vr zRqNmA!)WR}F}BJ8PkC+t+xvnbnmPIuHABqQpPAn72ES78+S9)<{KM@z&zM1) z8S_8sN_gldDkSX88cjl`o2gmQ9BiQk9U07JLG%u@7f9br&;$;yxkk{&Tv)M;;}$7M z$h$?07GGEY00DsQjzV>i+;Gd%fUYgczonF37z# zc%D|Mot_UPWOgNc5kO!dCwB~99 zI|*1WNjb)Bf%Nf(Ih*ftY8}fiOI?Aqh!IhN=a!)pw(byly37KM6I1jTh_UIBVW-#KCX6l4vM*qLDAr z)En>Of5AknSIoU;qK|mCz~OT0KRL`u-xCXIj|uT#ZklTn-0_*0+NhKtRh*aUEApn9 zVsf{C`j&MM5P!nY`UorY(jiv75|va|O%*MZu(mztZHu$Cvr_kEnvWQl!UOp;04M?5 zt;UvPv}TP>&Hn)2hzd(MdVBbo~+Ne^YD8c$hrC3E5q6FP0Se*>1P(!3C zAw2`sQsRpj=|(^L+!>l+nae(-(-kf(zLy@axcg6eN6$jotDx1JS2m4+{v(E1ShHI( zyda0o8V!9S;1&(1cf6>O=>@I%a}E%?QxxWHtaJQ!fzS_itR~CJl!h0><>fo&mLlP= zV~)_Ma4Q}RG?lg(RAyPgXgy+NB^zAo?=D(C=Y{PoyxJ}@Z35C#!ROvsDAZgzmm~7i z=`YvSA9z687Uj&XC%A?pj?)|DxQ!3Uz-MR5;5x_IZ}5uO(hp;_LAk980#KJ}ZEE6b zb;fsM&6Yc=ja74k--uDEU@O*OAQm-!BGAg?8mS#(&f)VkV^pQC&=BhZ-D>xQed7@) zrE7iv08+r+qxkbQf8BrBw7=KlC>BcQWl`R5-HtWKm?oRJGQz3s-`*%u4}A4M*bEkV zT)V36bvs4pCK%AK9W+jU_tS4N2T**()T6|7kj@&y(+o@1HSY?C)N4Krroq?7&!iDx z-kiMsB=DBvQyHg8BWR_4CFiQT6cSYza5CZ0EE#nZJyWR&x(hB5ae9{+ze%ir_PD-) zF5wrW9+w!!nmRb@UnkmaY>SmNThRQRiD|GW?c6o<`c@JEK2xy zAzQLPSRe`Xn_4a*>zDvgQQMKDFA`c>rcRO2V(4L9xH9^Oq3Y2W=orP&{{Z-*u7M9QVHR9i zvgPz+(8S6lr~p}?v}2d!Q;V5PM=A^NEE1jCJ)0ljAzfCdb`V!0^OnRalW&AzW~sr(V8(-WQ$(DHJ5n(+jr&Rv-50+xxJ8?C z{XjL=xz-?#D=bse8=_1q^A!VB`Dap@g6rLyR?OT(*w~pH-}&zXMlG^<1;aI}>buY6 z?H#9P$J~M?jf_c2XooDznWxCsvWDH9a}HpQ*4rQvXh2u3o%~G&kO6?8c*L`@XHjbk zT!OV~<{u#xymGO08D=fKD?+^!bvx#is|ZNS7IJ)a!t55~7?gT1Za$0_$K4z@wpW@b zYghC+?=QYSq`P~b5CVlAF=jOnc}Jr5;#08?&*CyY+xPU{W!o@OcIivx5Y6fJ?sGG~ z{#`=`T3cw_^e85MJ1nuT33eA06)&hJZlRo5xr|FRLBNTu9a*iy` zrN&&ja{3aZ^d5~9&xgbmQ02>Mu{n1|`Id+v)c_q|Gd&|+Tsh~NK`d*$H!*`9Fpm#U72$#Y!ql~9?weEqBW@_R2;hB2WdrRo)Vg~apJFeuC@m*4 z@655l;MM%srT5Eb7&RFH?%kS_hhS83y^O_Fuc4PPYdIC-W`MO{6G?H8Q=+jK(DeK7w94)<{KlZxpc)#>?YFe1GK~*u+XwqaNpLTMRClGzF>f;7 zVs3G#vJ$oJyk`snUgO?jMJ-hwHu;bEw%o4!ZJAycwabsWGxD=fNM9wE2}c#sw!OPd z4PIS$%(cGo?rH%VIQ`4QBI(fl2cp$VXC0`k5OrvzhC;e};k!barfOuf4J@$`I@_z$;TuLO9C1M|_!?eXn;t@mx30h~d$o-4CS3kP3SSHPCz1&X|1U*;hz>P}O?e&>JJV$u+JREx+_=`A( z9Eov0+RseF=(qm>P-c<5t&Q8HfLPiHGxP}kq(ED941Ywl$nYY`NFS|XE^jd8cU;y1 z*4`=?wc7iI;++CQwaG+v681@(NNIsN^RP!r<21&=*=N|;fwB*9eo>jw@F0-S;wP$K z%QkC7WlyTV=ApgS{e!FKUNyw6hfiAY3`RIT3B9@(*B7iHlofrdO`vP8=K;L@J(ua5 ziNYS&>R3#C9R6<1*0JTG^#J)E5;?+q14j{0wxkpdm|Fdsv|4GG$Fp9T{zW7{DVKo4 zcRf<+%4ZAPmzoww?)80UGls(QNCf<9^GUl7?khk?3@Rbg;_BJuB7n0kuYL}6?STMi zwC(=@JIb+q(VYHaUfoqkt-?NU2e)9KBbP()G(H<%UkvkAO0rM@tbb290oQ#Nj=#7d z=Sj>?rC*N|*IFNKnej;Av+yC1IN3<=aJ4|BW3GU7-}gqgjbmbT8Pk>QN(Z$-%+_g` z9OXT>cYwsrhtLtal}YerMnj)*U(&aaMIR>HLdU{vU5m+ltxVMS^QNA_JrDik`lu|7 zCyf9yJq=1!;5Saqp-8jg)OxzNr5vg`4AI?G5`I3=E8Q4~nRzqAyXiW*6x$dbRPnk5 zDc41z`+E5&aw&)xGr|X&k&6AwAQBt|4x4;@MeR^s)jDF5tr)V5K+{ueCuX6wwI9jl0 z!i}sO2sv1D%Sr4;ONhh(1a06QbB0*O;UR8Gs z<&lC~e$W5|IZyup{{Zc?#6_uXr7R=JiK03~umA#zE`R?3_Ae|LQvp7$u}s$?fZJ98 z0D|xT0RI6001ol3J^0%`qk5VXE0&i41)URr{{Z~yO_mN}9*FjaY^0{Tl>h*2y#E0I z0RI38#PDPZc*>t2l=4(wAOHjSSN{P20RI4I9<;U*0iI}9`Sj1A5C8=*-+%uA^EAO3 z`JeLC4w6a5hNMUU2j}9Zi{)Kt4K90J>a4Z8)M$RN02%-xI@{7@Z}CZ-X;d&foZ(tr z>mU~8oJ>2IpRrf37AN#T6IoG45CpMfMqJ}()bXPXBy{=%t;Rg;4y5YB*(PNYzP!hg zv$OFFp{Vya)WzK$pyhjW5w|Z7?Hv*O-~Rwd1Epvd2#zUx(FMx3Xvc5uZN_-znj~fG zX1scFLkES{&ax0*f*cqeSlMF*k#RO!?{@6x2x8Iu4$B;kvd-shmk)r4ZO zBb}*SSdZwh$s*`-h=_H8SJeQd2v zW9&yjH)od#-y4LpYnI z@*7o5%E>Y}H(SlXmfgMdhp9|5_=_?B02nNOe7NKlE|>0M3%9x?^gz){vMLn&YTZ=R zwFIsOWL{ylMF+F4I?%N{eElWiLyURyd^{+f;nxaO5HB=shJXlY$JEtX76Mz8gh z099suydT#-U@7W?)18Ent~-hSoDPS#Qh0`CpWGe z>N_3e7bK4C_Z0sCAXmL&P)mOs_XKcaPC67f(dt{lb$`L~_HNj80UmyW;vjWn!oq1_ zoZz3a@4;LG&HIc=`;R15;TX#52I|ufggRNgQ)uy}F_a=HO5KRwc??fu=YTOhdU}oB z=aNPCaBI4CuU?t7^#g?k&5q*#0OtbOLosH3pDiU-JX>)Y$4s=rLJcRw{>$%Mj6kj$ z82-0yN6#SQ98nUoyzJ1s5n0%7p7!ZmLOjoF0s7Uht7qD|Tjs=K!=ssc8AHc;x^X}j zI9kX50L9MUq^hk4v7_7ruqY#R{KzaQfGu$P#!&CjscvcAdmyl(;-{d+(kdACw{Z=0 z?_Vp5Vf+Ay^|NT$E>-b`=zuhy52zC$Ke710gq!%Rb{Ca^Lp6#+rFXP4m8)>@2+#I@ zd^b>t>AaxnD!%xfPyWa7=vd7E!~iJ}0RRF50s;a80s{d70RaF20RRypF+ovbae00;pA00BP`xvnR9Zjt8d4MrsM!6tOc4J75E-67 zQNUpkK>>-fSlq#kX5J-nqM1Pl;38rN@i?(!;w)IjjJO93s?O2)y-#VZQHq5Ik*80%e&fj@&eqwV{*uiAXaHYEOzs&RVRsI~sBW;NqNW7px~Fyz^P((mMX(7}HlsY^1V*X{zQ)f- zQ42nWLxY8M$YxX;ES4HM1G>da+65H1z8cjZxk}6w3Dt_z&CDz+G9K0V!BGvj3x$1e zSF=8$+K^hfK1k%n+W=Kj?U=fGw~iQ7kmljdn=6=9KrD;4P?gO*+`e;3SZ%c>Z%|

YM>Ss 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�%Xmeo6nfT(luihRKA+=2s0K3M;xG8n&t{s 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 KR)811Pyg9-*pTf2 From 269fb4d8109a6217f1f3419d1a45e7596d6a36ea Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 15 Aug 2025 23:59:55 +0200 Subject: [PATCH 108/122] Only consider the boundary for merging --- src/terrainlib/mesh/merging/helpers.h | 2 +- src/terrainlib/mesh/merging/mapping.cpp | 121 +++++++++++++++++------- src/terrainlib/mesh/utils.h | 11 +++ src/terrainlib/mesh/utils.inl | 50 +++++++++- 4 files changed, 149 insertions(+), 35 deletions(-) diff --git a/src/terrainlib/mesh/merging/helpers.h b/src/terrainlib/mesh/merging/helpers.h index a376c38..653e398 100644 --- a/src/terrainlib/mesh/merging/helpers.h +++ b/src/terrainlib/mesh/merging/helpers.h @@ -23,7 +23,7 @@ inline double estimate_merge_epsilon(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { +// TODO: make only considering the boundary configurable +VertexMapping create_mapping(std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { if (meshes.empty()) { return {}; } @@ -93,58 +94,114 @@ VertexMapping create_mapping(const std::span> reordered; + if (index_of_largest_mesh != 0) { + std::copy(meshes.begin(), meshes.end(), std::back_inserter(reordered)); + std::swap(reordered[0], reordered[index_of_largest_mesh]); + // we dont need to swap mesh_sizes here since we use the original mesh indices for the mapping + meshes = std::span(reordered); + } VertexMapping mapping; mapping.init(mesh_sizes); size_t unique_vertices = 0; - bool has_warned = false; auto add_unique_vertex = [&](const VertexId &vertex) { mapping.add_bidirectional(vertex, unique_vertices); unique_vertices += 1; }; + + // Init a reusable set of containers for the boundary + std::unordered_set boundary_edges; + std::vector is_boundary_vertex; + + // Reusable vector for duplicate vertices std::vector> duplicate_vertices; - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; + + bool has_warned = false; // Flag to only print the intra-mesh merge warning once + for (size_t local_mesh_index = 0; local_mesh_index < meshes.size(); local_mesh_index++) { + const SimpleMesh &mesh = meshes[local_mesh_index]; + + // We need to adjust the mesh index in the generated mapping since we + // may have reordered the meshes before. + size_t mesh_index = local_mesh_index; + if (local_mesh_index == index_of_largest_mesh) { + mesh_index = 0; + } else if (local_mesh_index == 0) { + mesh_index = index_of_largest_mesh; + } + + // Find boundary edges + boundary_edges.clear(); + find_boundary_edges(mesh, boundary_edges); + + // Classify vertices as on the boundary or on the inside + is_boundary_vertex.resize(mesh.vertex_count()); + std::fill(is_boundary_vertex.begin(), is_boundary_vertex.end(), false); + for (const auto& edge : boundary_edges) { + is_boundary_vertex[edge[0]] = true; + is_boundary_vertex[edge[1]] = true; + } + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const glm::dvec3 &position = mesh.positions[vertex_index]; const VertexId current_vertex{ .mesh_index = mesh_index, .vertex_index = vertex_index}; - if (mesh_index == 0) { - deduplicate.add(position, current_vertex); - add_unique_vertex(current_vertex); - } else if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { - // Duplicates detected - std::optional> nearest_duplicate; - for (const auto &other_vertex : duplicate_vertices) { - // Warn if we would perform intra mesh merges (but dont actually do them) - if (other_vertex.get().mesh_index == current_vertex.mesh_index) { - if (!has_warned) { - LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); - has_warned = true; - } - } else { - double distance2 = 0; - // Only caluclate the distance if there is actually more than a single duplicate vertex - if (duplicate_vertices.size() > 1) { - distance2 = glm::distance2(mesh.positions[other_vertex.get().vertex_index], position); + if (is_boundary_vertex[vertex_index]) { + // For each boundary vertex we need to deduplicate + if (mesh_index == 0) { + // For the first mesh we know that there cannot be any duplicates + deduplicate.add(position, current_vertex); + add_unique_vertex(current_vertex); + } else { + duplicate_vertices.clear(); + if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { + // Duplicates detected + std::optional> nearest_duplicate; + for (const auto &other_vertex : duplicate_vertices) { + // Warn if we would perform intra mesh merges (but dont actually do them) + if (other_vertex.get().mesh_index == current_vertex.mesh_index) { + if (!has_warned) { + LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); + has_warned = true; + } + } else { + double distance2 = 0; + // Only caluclate the distance if there is actually more than a single duplicate vertex + if (duplicate_vertices.size() > 1) { + distance2 = glm::distance2(mesh.positions[other_vertex.get().vertex_index], position); + } + if (!nearest_duplicate.has_value() || nearest_duplicate.value().second > distance2) { + nearest_duplicate = {other_vertex.get(), distance2}; + } + } } - if (!nearest_duplicate.has_value() || nearest_duplicate.value().second > distance2) { - nearest_duplicate = {other_vertex.get(), distance2}; + + if (nearest_duplicate.has_value()) { + // We had at least one vertex from another mesh as duplicates + mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); + } else { + // Only vertices from the same mesh were detected as duplicate + // Since we dont want to perform intra-mesh merges, just add it as a new vertex + deduplicate.add(position, current_vertex); + add_unique_vertex(current_vertex); } + } else { + // New vertex / No duplicates + add_unique_vertex(current_vertex); } } - if (nearest_duplicate.has_value()) { - mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); - } else { - deduplicate.add(position, current_vertex); - add_unique_vertex(current_vertex); - } - duplicate_vertices.clear(); } else { - // New vertex / No duplicates + // Not a boundary vertex, so just add directly add_unique_vertex(current_vertex); } } diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index de7f5b5..f73cc4d 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -2,11 +2,14 @@ #include #include +#include #include #include #include +#include "mesh/SimpleMesh.h" + // TODO: put in mesh namespace // TODO: make all methods work with SimpleMesh_ @@ -64,4 +67,12 @@ void flip_triangle_orientations(std::vector &triangles); template void flip_orientation(SimpleMesh_ &mesh); +template +std::unordered_set::Edge> get_edges(const SimpleMesh_ &mesh); + +template +std::unordered_set::Edge> find_boundary_edges(const SimpleMesh_ &mesh); +template +void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set::Edge> &boundary); + #include "utils.inl" diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl index 9187035..dbe211c 100644 --- a/src/terrainlib/mesh/utils.inl +++ b/src/terrainlib/mesh/utils.inl @@ -1,7 +1,5 @@ #pragma once -#include "mesh/SimpleMesh.h" - namespace { template auto calculate_bounds_range(const MeshRange &meshes) { @@ -69,3 +67,51 @@ template void flip_orientation(SimpleMesh_ &mesh) { flip_triangle_orientations(mesh.triangles); } + +template +std::unordered_set::Edge> get_edges(const SimpleMesh_ &mesh) { + using Edge = typename SimpleMesh_::Edge; + std::unordered_set edges; + for (const auto& triangle_ref : mesh.triangles) { + glm::uvec3 triangle = triangle_ref; + std::sort(&triangle.x, &triangle.z + 1); + + const std::array face_edges{glm::uvec2(triangle.x, triangle.y), + glm::uvec2(triangle.y, triangle.z), + glm::uvec2(triangle.x, triangle.z)}; + for (const glm::uvec2 edge : face_edges) { + edges.insert(edge); + } + } + return edges; +} + +template +std::unordered_set::Edge> find_boundary_edges(const SimpleMesh_ &mesh) { + std::unordered_set::Edge> boundary; + find_boundary_edges(mesh, boundary); + return boundary; +} +template +void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set::Edge> &boundary) { + using Triangle = typename SimpleMesh_::Triangle; + using Edge = typename SimpleMesh_::Edge; + for (const auto &triangle_ref : mesh.triangles) { + Triangle triangle = triangle_ref; + std::sort(&triangle.x, &triangle.z + 1); + + const std::array edges{Edge(triangle.x, triangle.y), + Edge(triangle.y, triangle.z), + Edge(triangle.x, triangle.z)}; + for (const Edge& edge : edges) { + auto it = boundary.find(edge); + if (it != boundary.end()) { + // Edge already there -> shared egde -> remove it + boundary.erase(it); + } else { + // Edge not present -> add it + boundary.insert(edge); + } + } + } +} From cb3b7d3531ddd779856c708b87511e9b0ff91d09 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 21 Aug 2025 14:17:39 +0200 Subject: [PATCH 109/122] Finish terrainmerger (except textures on merged meshes) --- out.txt | 0 src/CMakeLists.txt | 23 +- src/mesh_merger/main.cpp | 12 +- src/terrainlib/FixedVector.h | 68 ++++ src/terrainlib/UnionFind.h | 67 ++-- src/terrainlib/log_impls.h | 6 +- src/terrainlib/mesh/connected_components.h | 94 ++++++ src/terrainlib/mesh/holes.cpp | 209 ++++++++++++ src/terrainlib/mesh/holes.h | 16 + src/terrainlib/mesh/merge.h | 24 +- .../mesh/merging/EpsilonVertexDeduplicate.h | 4 +- .../mesh/merging/SphereVertexDeduplicate.h | 27 +- .../mesh/merging/SphereVertexDeduplicate2.h | 28 +- src/terrainlib/mesh/merging/mapping.cpp | 121 ++----- src/terrainlib/mesh/merging/mapping.h | 1 + src/terrainlib/mesh/utils.cpp | 50 ++- src/terrainlib/mesh/utils.h | 8 + src/terrainlib/mesh/utils.inl | 37 +- src/terrainlib/polygon/Polygon.h | 23 ++ src/terrainlib/polygon/triangulate.cpp | 176 ++++++++++ src/terrainlib/polygon/triangulate.h | 13 + src/terrainlib/polygon/utils.cpp | 42 +++ src/terrainlib/polygon/utils.h | 7 + src/terrainmerger/merge/visitor/Masked.h | 24 +- src/terrainmerger/merge/visitor/Simple.h | 1 + unittests/CMakeLists.txt | 6 +- .../terrainlib/mesh_connected_components.cpp | 108 ++++++ unittests/terrainlib/mesh_holes.cpp | 319 ++++++++++++++++++ unittests/terrainlib/mesh_merge.cpp | 7 +- unittests/terrainlib/mesh_merge_mapping.cpp | 117 +++++-- unittests/terrainlib/mesh_utils.cpp | 89 ++++- .../terrainlib/spatial_multi_hashmap.cpp | 0 32 files changed, 1513 insertions(+), 214 deletions(-) delete mode 100644 out.txt create mode 100644 src/terrainlib/FixedVector.h create mode 100644 src/terrainlib/mesh/connected_components.h create mode 100644 src/terrainlib/mesh/holes.cpp create mode 100644 src/terrainlib/mesh/holes.h create mode 100644 src/terrainlib/polygon/Polygon.h create mode 100644 src/terrainlib/polygon/triangulate.cpp create mode 100644 src/terrainlib/polygon/triangulate.h create mode 100644 src/terrainlib/polygon/utils.cpp create mode 100644 src/terrainlib/polygon/utils.h create mode 100644 unittests/terrainlib/mesh_connected_components.cpp create mode 100644 unittests/terrainlib/mesh_holes.cpp delete mode 100644 unittests/terrainlib/spatial_multi_hashmap.cpp diff --git a/out.txt b/out.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc7b7b0..1ea37db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") # TODO: This is needed to avoid NDEBUG being undefined on Release if (CMAKE_BUILD_TYPE MATCHES Release) - # set(ALP_ENABLE_ASSERTS OFF CACHE BOOL "" FORCE) + set(ALP_ENABLE_ASSERTS OFF CACHE BOOL "" FORCE) endif() option(ALP_ENABLE_THREAD_SANITIZER "compiles atb with thread sanitizer enabled (only debug, works only on g++ and clang)" OFF) @@ -123,8 +123,8 @@ add_library(terrainlib terrainlib/mesh/boolean.h terrainlib/mesh/boolean.cpp terrainlib/mesh/cgal.h terrainlib/mesh/clip.h terrainlib/mesh/clip.cpp - terrainlib/mesh/convert.h - terrainlib/mesh/convert.cpp + terrainlib/mesh/convert.h terrainlib/mesh/convert.cpp + terrainlib/mesh/holes.h terrainlib/mesh/holes.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp terrainlib/mesh/merge.h terrainlib/mesh/merge.cpp terrainlib/mesh/merging/VertexDeduplicate.h @@ -159,6 +159,10 @@ add_library(terrainlib terrainlib/octree/traverse.h terrainlib/octree/utils.h + terrainlib/polygon/Polygon.h + terrainlib/polygon/triangulate.h terrainlib/polygon/triangulate.cpp + terrainlib/polygon/utils.h terrainlib/polygon/utils.cpp + terrainlib/spatial_lookup/CellBased.h terrainlib/spatial_lookup/CellBasedStorage.h terrainlib/spatial_lookup/Grid.h @@ -209,8 +213,19 @@ target_link_libraries(tilebuilder PUBLIC tilebuilderlib) add_library(terrainmergerlib - terrainmerger/merge.h + terrainmerger/merge/visitor/Masked.h + terrainmerger/merge/visitor/Simple.h + terrainmerger/merge/visitor/Visitor.h + terrainmerger/merge/NodeData.h + terrainmerger/merge/Result.h + terrainmerger/cut.h + terrainmerger/earth.h terrainmerger/mask.h + terrainmerger/merge.h + terrainmerger/NodeLoader.h + terrainmerger/NodeWriter.h + terrainmerger/SimpleMutex.h + terrainmerger/utils.h ) target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) diff --git a/src/mesh_merger/main.cpp b/src/mesh_merger/main.cpp index 87feca1..f3be3c6 100644 --- a/src/mesh_merger/main.cpp +++ b/src/mesh_merger/main.cpp @@ -8,7 +8,8 @@ #include "log.h" #include "mesh/SimpleMesh.h" #include "mesh/io.h" -#include "mesh/merge.h" +#include "mesh/merging/mapping.h" +#include "mesh/holes.h" SimpleMesh merge(const std::span meshes, const std::optional epsilon) { std::vector> mesh_refs; @@ -17,11 +18,16 @@ SimpleMesh merge(const std::span meshes, const std::optional mesh_refs.push_back(mesh); } + mesh::merging::VertexMapping mapping; if (epsilon.has_value()) { - return mesh::merge(mesh_refs, epsilon.value()); + mapping = mesh::merging::create_mapping(mesh_refs, epsilon.value()); } else { - return mesh::merge(mesh_refs); + mapping = mesh::merging::create_mapping(mesh_refs); } + + SimpleMesh merged = mesh::merging::apply_mapping(mesh_refs, mapping); + mesh::fill_holes_on_merge_border(merged, mapping); + return merged; } void run(const cli::Args &args) { diff --git a/src/terrainlib/FixedVector.h b/src/terrainlib/FixedVector.h new file mode 100644 index 0000000..774bc48 --- /dev/null +++ b/src/terrainlib/FixedVector.h @@ -0,0 +1,68 @@ +#include +#include +#include + +template +class FixedVector { +public: + FixedVector() = default; + + FixedVector(std::initializer_list init) { + if (init.size() > N) { + throw std::out_of_range("capacity exceeded"); + } + for (auto &v : init) { + this->_data[this->_size] = v; + this->_size++; + } + } + + void push_back(const T &value) { + if (this->_size >= N) { + throw std::out_of_range("capacity exceeded"); + } + this->_data[this->_size] = value; + this->_size++; + } + + void pop_back() { + if (this->_size == 0) { + throw std::out_of_range("empty vector"); + } + this->_size--; + } + + T &operator[](std::size_t i) { + return this->_data[i]; + } + const T &operator[](std::size_t i) const { + return this->_data[i]; + } + + std::size_t size() const { + return this->_size; + } + constexpr std::size_t capacity() const { + return N; + } + bool empty() const { + return this->_size == 0; + } + + T *begin() { + return this->_data.data(); + } + T *end() { + return this->_data.data() + this->_size; + } + const T *begin() const { + return this->_data.data(); + } + const T *end() const { + return this->_data.data() + this->_size; + } + +private: + std::array _data; + std::size_t _size = 0; +}; diff --git a/src/terrainlib/UnionFind.h b/src/terrainlib/UnionFind.h index 327eb8c..98540a1 100644 --- a/src/terrainlib/UnionFind.h +++ b/src/terrainlib/UnionFind.h @@ -3,22 +3,42 @@ #include #include +#include + +template class UnionFind { public: using Index = size_t; + using Size = size_t; - explicit UnionFind(const size_t size) - : _parents(size), _sizes(size, 1) { + explicit UnionFind(Size size) + : _parents(size) { std::iota(this->_parents.begin(), this->_parents.end(), 0); + if constexpr (TrackSizes) { + this->_sizes.resize(size, 1); + } } - [[nodiscard]] Index find(const Index x) { - Index &x_parent = this->_parents[x]; - if (x_parent != x) { - const Index x_rep = this->find(x_parent); - x_parent = x_rep; + [[nodiscard]] Index find(const Index item) const { + DEBUG_ASSERT(item < this->size()); + Index current = item; + while (true) { + const Index parent = this->_parents[current]; + if (current == parent) { + return current; + } + current = parent; + } + } + [[nodiscard]] Index find(const Index item) { + DEBUG_ASSERT(item < this->size()); + const Index parent = this->_parents[item]; + if (parent == item) { + return parent; } - return x_parent /* this is x_rep */; + const Index rep = this->find(parent); + this->_parents[item] = rep; + return rep; } void make_union(const Index x, const Index y) { @@ -29,30 +49,39 @@ class UnionFind { return; } - const Index x_size = this->_sizes[x_rep]; - const Index y_size = this->_sizes[y_rep]; - if (x_size < y_size) { - this->_parents[x_rep] = y_rep; - this->_sizes[y_rep] += this->_sizes[x_rep]; - } else { - this->_parents[y_rep] = x_rep; + this->_parents[x_rep] = y_rep; + if constexpr (TrackSizes) { this->_sizes[x_rep] += this->_sizes[y_rep]; } } - [[nodiscard]] Index size() { + [[nodiscard]] Size size() const { return this->_parents.size(); } - [[nodiscard]] bool is_joint() { - return std::find(this->_sizes.begin(), this->_sizes.end(), this->size()) != this->_sizes.end(); + template > + [[nodiscard]] Index get_set_size(Index x) const { + return this->_sizes[this->find(x)]; } + [[nodiscard]] bool is_joint() { + if (this->_parents.empty()) { + return true; + } + + if constexpr (TrackSizes) { + return this->get_set_size(0) == this->size(); + } else { + const Index rep = this->find(0); + return std::all_of(std::next(this->_parents.begin()), this->_parents.end(), + [&](Index i) { return this->find(i) == rep; }); + } + } [[nodiscard]] bool is_disjoint() { return !this->is_joint(); } private: std::vector _parents; - std::vector _sizes; + std::conditional_t, std::monostate> _sizes; }; diff --git a/src/terrainlib/log_impls.h b/src/terrainlib/log_impls.h index a7eb543..91167d3 100644 --- a/src/terrainlib/log_impls.h +++ b/src/terrainlib/log_impls.h @@ -15,7 +15,7 @@ struct formatter { } template - auto format(const std::filesystem::path &path, FormatContext &ctx) { + auto format(const std::filesystem::path &path, FormatContext &ctx) const { return fmt::format_to(ctx.out(), "{}", std::filesystem::weakly_canonical(path).string()); } }; @@ -28,7 +28,7 @@ struct formatter> { } template - auto format(const glm::vec &vec, FormatContext &ctx) { + auto format(const glm::vec &vec, FormatContext &ctx) const { return fmt::format_to(ctx.out(), "{}", glm::to_string(vec)); } }; @@ -41,7 +41,7 @@ struct formatter> { } template - auto format(const radix::geometry::Aabb &aabb, FormatContext &ctx) { + auto format(const radix::geometry::Aabb &aabb, FormatContext &ctx) const { return fmt::format_to(ctx.out(), "[{}-{}]", glm::to_string(aabb.min), glm::to_string(aabb.max)); } }; diff --git a/src/terrainlib/mesh/connected_components.h b/src/terrainlib/mesh/connected_components.h new file mode 100644 index 0000000..75ea98c --- /dev/null +++ b/src/terrainlib/mesh/connected_components.h @@ -0,0 +1,94 @@ +#pragma once + +#include "mesh/SimpleMesh.h" +#include "UnionFind.h" + +namespace { +using VertexIndex = uint32_t; +using ComponentIndex = uint32_t; +} // namespace + +namespace mesh { +struct ComponentsIndex { + std::vector vertex_to_component; + size_t component_count; +}; + +inline ComponentsIndex find_connected_components(const SimpleMesh &mesh) { + const size_t vertex_count = mesh.vertex_count(); + if (vertex_count == 0) { + return {}; + } + + // Union vertices that belong to the same triangle + UnionFind components(vertex_count); + for (const glm::uvec3& triangle : mesh.triangles) { + components.make_union(triangle[0], triangle[1]); + components.make_union(triangle[1], triangle[2]); + } + + // Convert to vertex to component index mapping + std::unordered_map rep_to_index; + ComponentIndex next_index = 0; + + std::vector vertex_to_component(vertex_count); + for (VertexIndex vertex = 0; vertex < vertex_count; vertex++) { + const VertexIndex rep = components.find(vertex); + auto it = rep_to_index.find(rep); + if (it == rep_to_index.end()) { + rep_to_index[rep] = next_index; + vertex_to_component[vertex] = next_index; + next_index += 1; + } else { + vertex_to_component[vertex] = it->second; + } + } + + return ComponentsIndex{ + .vertex_to_component = vertex_to_component, + .component_count = rep_to_index.size()}; +} + +inline std::vector split_into_connected_components(const SimpleMesh &mesh) { + const auto& [vertex_to_component, component_count] = find_connected_components(mesh); + + std::vector components; + components.resize(component_count); + + constexpr VertexIndex invalid_index = std::numeric_limits::max(); + std::vector old_to_new(mesh.vertex_count(), invalid_index); + for (VertexIndex vertex = 0; vertex < mesh.vertex_count(); vertex++) { + const ComponentIndex component_index = vertex_to_component[vertex]; + SimpleMesh &component = components[component_index]; + old_to_new[vertex] = component.positions.size(); + component.positions.push_back(mesh.positions[vertex]); + } + + for (SimpleMesh &component : components) { + component.triangles.reserve((component.positions.size() * 3) / 2); + } + + for (const glm::uvec3 &triangle : mesh.triangles) { + const ComponentIndex component_index = vertex_to_component[triangle[0]]; + + glm::uvec3 new_triangle; + bool skip_triangle = false; + for (size_t k = 0; k < static_cast(triangle.length()); k++) { + if (k > 0 && vertex_to_component[triangle[k]] != component_index) { + skip_triangle = true; + break; + } + new_triangle[k] = old_to_new[triangle[k]]; + } + if (skip_triangle) { + continue; + } + + SimpleMesh &component = components[component_index]; + component.triangles.push_back(new_triangle); + } + + return components; +} + +} // namespace mesh diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp new file mode 100644 index 0000000..952c67b --- /dev/null +++ b/src/terrainlib/mesh/holes.cpp @@ -0,0 +1,209 @@ +#include +#include + +#include "mesh/holes.h" +#include "FixedVector.h" +#include "mesh/utils.h" +#include "mesh/connected_components.h" +#include "log.h" +#include "polygon/Polygon.h" +#include "polygon/triangulate.h" + +namespace { +using Edge = glm::uvec2; +using VertexIndex = uint32_t; +using ComponentIndex = uint32_t; +} // namespace + +namespace mesh { +namespace { +template +void remove_first(std::vector &vec, const T &value) { + auto it = std::find(vec.begin(), vec.end(), value); + if (it != vec.end()) { + vec.erase(it); + } +} +} + +std::vector> find_boundaries(const SimpleMesh &mesh) { + std::unordered_set boundary_edges = find_boundary_edges(mesh); + std::unordered_map> adjacencies; + adjacencies.reserve((boundary_edges.size() * 3) / 2); + for (const Edge &edge : boundary_edges) { + adjacencies[edge[0]].push_back(edge[1]); + } + + auto remove_edge = [&](const auto edge) { + boundary_edges.erase(edge); + remove_first(adjacencies[edge[0]], edge[1]); + }; + + std::vector> boundaries; + while (!boundary_edges.empty()) { + const Edge starting_edge = *boundary_edges.begin(); + remove_edge(starting_edge); + + std::vector boundary; + const VertexIndex starting_vertex_id = starting_edge[0]; + + Edge current_edge = starting_edge; + VertexIndex current_vertex_id = starting_edge[1]; + boundary.push_back(current_vertex_id); + while (true) { + const auto neighbours = adjacencies[current_vertex_id]; + if (neighbours.empty()) { + // non-manifold + break; + } + const VertexIndex next_vertex_id = neighbours[0]; + const Edge next_edge(current_vertex_id, next_vertex_id); + remove_edge(next_edge); + + boundary.push_back(next_vertex_id); + if (next_vertex_id == starting_vertex_id) { + break; + } + current_vertex_id = next_vertex_id; + current_edge = next_edge; + } + + if (boundary.empty()) { + continue; + } + + std::reverse(boundary.begin(), boundary.end()); + + // split boundary into individual loops + std::unordered_map visited; + for (size_t i = 0; i < boundary.size(); i++) { + const VertexIndex vertex = boundary[i]; + auto it = visited.find(vertex); + if (it != visited.end()) { + const size_t first_occurance = it->second; + // finished current loop + DEBUG_ASSERT(first_occurance < i); + auto loop_start = boundary.begin() + first_occurance; + auto loop_end = boundary.begin() + i; + std::vector loop(loop_start, loop_end); + boundaries.push_back(std::move(loop)); + boundary.erase(loop_start, loop_end); + i = first_occurance; + } else { + visited.emplace(vertex, i); + } + } + + if (boundary.empty()) { + continue; + } + + boundaries.push_back(std::move(boundary)); + } + + return boundaries; +} + +namespace { +template +auto iterator_from_ref(std::vector &vec, T &ref) { + // Make sure ref actually belongs to vec + assert(&ref >= vec.data() && &ref < vec.data() + vec.size()); + return vec.begin() + (&ref - vec.data()); +} + +template +auto iterator_from_ref(const std::vector &vec, const T &ref) { + assert(&ref >= vec.data() && &ref < vec.data() + vec.size()); + return vec.cbegin() + (&ref - vec.data()); +} +} + +std::vector> find_holes(const SimpleMesh &mesh) { + std::vector> boundaries = find_boundaries(mesh); + const auto& [vertex_to_component, component_count] = find_connected_components(mesh); + + // For each component, find index of largest boundary + std::vector> largest_boundary_index_per_component(component_count); + for (size_t i = 0; i < boundaries.size(); ++i) { + const auto &boundary = boundaries[i]; + DEBUG_ASSERT(!boundary.empty()); + const ComponentIndex component_index = vertex_to_component[boundary[0]]; + + auto &largest_index_opt = largest_boundary_index_per_component[component_index]; + if (!largest_index_opt.has_value() || + boundaries[i].size() > boundaries[largest_index_opt.value()].size()) { + largest_index_opt = i; + } + } + + // Collect all indices to delete + std::vector to_delete; + to_delete.reserve(component_count); + for (auto idx_opt : largest_boundary_index_per_component) { + if (idx_opt.has_value()) { + to_delete.push_back(idx_opt.value()); + } + } + + // Sort and erase from end + std::sort(to_delete.begin(), to_delete.end()); + for (auto it = to_delete.rbegin(); it != to_delete.rend(); ++it) { + boundaries.erase(boundaries.begin() + *it); + } + + return boundaries; +} + +std::vector> find_holes_on_merge_border(const SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping) { + std::vector> holes = find_holes(mesh); + for (auto it = holes.rbegin(); it != holes.rend(); it++) { + const auto &hole = *it; + + FixedVector source_meshes; + for (const VertexIndex vertex_index : hole) { + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); + if (source_vertex.has_value()) { + source_meshes.push_back(source_vertex.value()); + if (source_meshes.size() > 1) { + break; + } + } + } + if (source_meshes.size() > 1) { + break; + } + } + if (source_meshes.size() == 1) { + // Not a hole between meshes + holes.erase((it + 1).base()); + } + } + return holes; +} + +void fill_planar_hole(SimpleMesh &mesh, const std::span hole) { + if (hole.size() < 3) { + return; + } + + polygon::triangulate(mesh, hole); + + // for (size_t i = 1; i + 1 < hole.size(); i++) { + // mesh.triangles.emplace_back(hole[0], hole[i], hole[i + 1]); + // } +} + +void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes) { + for (const auto& hole : holes) { + fill_planar_hole(mesh, hole); + } +} + +void fill_holes_on_merge_border(SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping) { + const std::vector> holes = find_holes_on_merge_border(mesh, mapping); + fill_planar_holes(mesh, holes); +} + +} diff --git a/src/terrainlib/mesh/holes.h b/src/terrainlib/mesh/holes.h new file mode 100644 index 0000000..3f49d67 --- /dev/null +++ b/src/terrainlib/mesh/holes.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/merging/VertexMapping.h" + +namespace mesh { +std::vector> find_boundaries(const SimpleMesh &mesh); +std::vector> find_holes(const SimpleMesh &mesh); +std::vector> find_holes_on_merge_border(const SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping); +void fill_planar_hole(SimpleMesh &mesh, const std::span hole); +void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes); +void fill_holes_on_merge_border(SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping); +} // namespace mesh \ No newline at end of file diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 550813f..5b39291 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -33,22 +33,30 @@ SimpleMesh merge(const std::span meshes, Args &&...args) { return merge(std::span>(refs), std::forward(args)...); } -template -SimpleMesh merge(const SimpleMesh &mesh1, Args &&...args) { +template +concept SimpleMeshRefConcept = + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v> || + std::is_same_v>; + +template +SimpleMesh merge(Mesh&& mesh1, Args &&...args) { return mesh1; } -template -SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, Args &&...args) { +template +SimpleMesh merge(Mesh1&& mesh1, Mesh2&& mesh2, Args &&...args) { const std::array, 2> meshes = {mesh1, mesh2}; return merge(std::span>(meshes), std::forward(args)...); } -template -SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, const SimpleMesh &mesh3, Args &&...args) { +template +SimpleMesh merge(Mesh1&& mesh1, Mesh2&& mesh2, Mesh3&& mesh3, Args &&...args) { const std::array, 3> meshes = {mesh1, mesh2, mesh3}; return merge(std::span>(meshes), std::forward(args)...); } -template -SimpleMesh merge(const SimpleMesh &mesh1, const SimpleMesh &mesh2, const SimpleMesh &mesh3, const SimpleMesh& mesh4, Args &&...args) { +template +SimpleMesh merge(Mesh1&& mesh1, Mesh2&& mesh2, Mesh3&& mesh3, Mesh4&& mesh4, Args &&...args) { const std::array, 4> meshes = {mesh1, mesh2, mesh3, mesh4}; return merge(std::span>(meshes), std::forward(args)...); } diff --git a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h index 8d33957..3c9899e 100644 --- a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "spatial_lookup/SpatialLookup.h" #include "mesh/merging/VertexDeduplicate.h" @@ -18,7 +20,7 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate_epsilon; } virtual void add(const Vec &point, const Meta meta) override { - this->_lookup.insert(point, meta); + DEBUG_ASSERT_VAL(this->_lookup.insert(point, meta)); } virtual bool get(const Vec &point, std::vector> &duplicates) const override { return this->_lookup.find_all_near(point, this->_epsilon, duplicates); diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h b/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h index c8f6951..e52ce24 100644 --- a/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h @@ -6,27 +6,36 @@ namespace mesh::merging { -template Lookup> +namespace { +template +glm::vec scale_to_length(const glm::vec &v, const T target_length) { + const T len = glm::length(v); + if (len == T(0)) { + return glm::vec(T(0)); + } + return v * (target_length / len); +} +} + +template Lookup> class SphereVertexDeduplicate : public VertexDeduplicate<3, double, Meta> { public: using Vec = glm::vec<3, double>; - using MappedVec = glm::vec<2, double>; - SphereVertexDeduplicate(Lookup &lookup, double epsilon, Vec tangent_point) - : _inner(lookup, epsilon), _projector(tangent_point) {} + SphereVertexDeduplicate(Lookup &lookup, double epsilon, double radius) + : _inner(lookup, epsilon), _radius(radius) {} void add(const Vec &point, const Meta meta) override { - const MappedVec mapped = this->_projector.project_point(point); + const Vec mapped = scale_to_length(point, this->_radius); this->_inner.add(mapped, meta); } bool get(const Vec &point, std::vector> &duplicates) const override { - const MappedVec mapped = this->_projector.project_point(point); + const Vec mapped = scale_to_length(point, this->_radius); return this->_inner.get(mapped, duplicates); } private: - EpsilonVertexDeduplicate<2, double, Meta, Lookup> _inner; - SphereProjector _projector; + EpsilonVertexDeduplicate<3, double, Meta, Lookup> _inner; + double _radius; }; - } diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h b/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h index 6fd4c94..6d737ea 100644 --- a/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h +++ b/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h @@ -6,37 +6,27 @@ namespace mesh::merging { -namespace { -template -glm::vec scale_to_length(const glm::vec &v, const T target_length) { - const T len = glm::length(v); - if (len == T(0)) { - return glm::vec(T(0)); - } - return v * (target_length / len); -} -} - -template Lookup> +template Lookup> class SphereVertexDeduplicate2 : public VertexDeduplicate<3, double, Meta> { public: using Vec = glm::vec<3, double>; + using MappedVec = glm::vec<2, double>; - SphereVertexDeduplicate2(Lookup &lookup, double epsilon, double radius) - : _inner(lookup, epsilon), _radius(radius) {} + SphereVertexDeduplicate2(Lookup &lookup, double epsilon, Vec tangent_point) + : _inner(lookup, epsilon), _projector(tangent_point) {} void add(const Vec &point, const Meta meta) override { - const Vec mapped = scale_to_length(point, this->_radius); + const MappedVec mapped = this->_projector.project_point(point); this->_inner.add(mapped, meta); } bool get(const Vec &point, std::vector> &duplicates) const override { - const Vec mapped = scale_to_length(point, this->_radius); + const MappedVec mapped = this->_projector.project_point(point); return this->_inner.get(mapped, duplicates); } private: - EpsilonVertexDeduplicate<3, double, Meta, Lookup> _inner; - double _radius; + EpsilonVertexDeduplicate<2, double, Meta, Lookup> _inner; + SphereProjector _projector; }; -} +} diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index 6466ba6..a3df5c0 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -73,8 +73,7 @@ VertexMapping create_mapping(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { +VertexMapping create_mapping(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { if (meshes.empty()) { return {}; } @@ -94,114 +93,58 @@ VertexMapping create_mapping(std::span> reordered; - if (index_of_largest_mesh != 0) { - std::copy(meshes.begin(), meshes.end(), std::back_inserter(reordered)); - std::swap(reordered[0], reordered[index_of_largest_mesh]); - // we dont need to swap mesh_sizes here since we use the original mesh indices for the mapping - meshes = std::span(reordered); - } VertexMapping mapping; mapping.init(mesh_sizes); size_t unique_vertices = 0; + bool has_warned = false; auto add_unique_vertex = [&](const VertexId &vertex) { mapping.add_bidirectional(vertex, unique_vertices); unique_vertices += 1; }; - - // Init a reusable set of containers for the boundary - std::unordered_set boundary_edges; - std::vector is_boundary_vertex; - - // Reusable vector for duplicate vertices std::vector> duplicate_vertices; - - bool has_warned = false; // Flag to only print the intra-mesh merge warning once - for (size_t local_mesh_index = 0; local_mesh_index < meshes.size(); local_mesh_index++) { - const SimpleMesh &mesh = meshes[local_mesh_index]; - - // We need to adjust the mesh index in the generated mapping since we - // may have reordered the meshes before. - size_t mesh_index = local_mesh_index; - if (local_mesh_index == index_of_largest_mesh) { - mesh_index = 0; - } else if (local_mesh_index == 0) { - mesh_index = index_of_largest_mesh; - } - - // Find boundary edges - boundary_edges.clear(); - find_boundary_edges(mesh, boundary_edges); - - // Classify vertices as on the boundary or on the inside - is_boundary_vertex.resize(mesh.vertex_count()); - std::fill(is_boundary_vertex.begin(), is_boundary_vertex.end(), false); - for (const auto& edge : boundary_edges) { - is_boundary_vertex[edge[0]] = true; - is_boundary_vertex[edge[1]] = true; - } - + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const glm::dvec3 &position = mesh.positions[vertex_index]; const VertexId current_vertex{ .mesh_index = mesh_index, .vertex_index = vertex_index}; - if (is_boundary_vertex[vertex_index]) { - // For each boundary vertex we need to deduplicate - if (mesh_index == 0) { - // For the first mesh we know that there cannot be any duplicates - deduplicate.add(position, current_vertex); - add_unique_vertex(current_vertex); - } else { - duplicate_vertices.clear(); - if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { - // Duplicates detected - std::optional> nearest_duplicate; - for (const auto &other_vertex : duplicate_vertices) { - // Warn if we would perform intra mesh merges (but dont actually do them) - if (other_vertex.get().mesh_index == current_vertex.mesh_index) { - if (!has_warned) { - LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); - has_warned = true; - } - } else { - double distance2 = 0; - // Only caluclate the distance if there is actually more than a single duplicate vertex - if (duplicate_vertices.size() > 1) { - distance2 = glm::distance2(mesh.positions[other_vertex.get().vertex_index], position); - } - if (!nearest_duplicate.has_value() || nearest_duplicate.value().second > distance2) { - nearest_duplicate = {other_vertex.get(), distance2}; - } - } - } - - if (nearest_duplicate.has_value()) { - // We had at least one vertex from another mesh as duplicates - mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); - } else { - // Only vertices from the same mesh were detected as duplicate - // Since we dont want to perform intra-mesh merges, just add it as a new vertex - deduplicate.add(position, current_vertex); - add_unique_vertex(current_vertex); + if (mesh_index == 0) { + deduplicate.add(position, current_vertex); + add_unique_vertex(current_vertex); + } else if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { + // Duplicates detected + std::optional> nearest_duplicate; + for (const auto &other_vertex : duplicate_vertices) { + // Warn if we would perform intra mesh merges (but dont actually do them) + if (other_vertex.get().mesh_index == current_vertex.mesh_index) { + if (!has_warned) { + LOG_WARN("Deduplication is too inclusive and would perform intra-mesh merges"); + has_warned = true; } } else { - // New vertex / No duplicates - add_unique_vertex(current_vertex); + double distance2 = 0; + // Only caluclate the distance if there is actually more than a single duplicate vertex + if (duplicate_vertices.size() > 1) { + distance2 = glm::distance2(mesh.positions[other_vertex.get().vertex_index], position); + } + if (!nearest_duplicate.has_value() || nearest_duplicate.value().second > distance2) { + nearest_duplicate = {other_vertex.get(), distance2}; + } } } + if (nearest_duplicate.has_value()) { + mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); + } else { + deduplicate.add(position, current_vertex); + add_unique_vertex(current_vertex); + } + duplicate_vertices.clear(); } else { - // Not a boundary vertex, so just add directly + // New vertex / No duplicates add_unique_vertex(current_vertex); } } diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 30d721d..376e5eb 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "mesh/SimpleMesh.h" #include "mesh/merging/VertexDeduplicate.h" diff --git a/src/terrainlib/mesh/utils.cpp b/src/terrainlib/mesh/utils.cpp index 723358a..cd1f623 100644 --- a/src/terrainlib/mesh/utils.cpp +++ b/src/terrainlib/mesh/utils.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include "log.h" #include "mesh/SimpleMesh.h" #include "mesh/TriangleSoup.h" @@ -152,23 +154,51 @@ size_t remove_triangles_of_negligible_size(SimpleMesh &mesh, const double thresh return erased_count; } -glm::uvec3 normalize_triangle(const glm::uvec3 &triangle) { - unsigned int min_index = 0; - for (size_t k = 1; k < static_cast(triangle.length()); k++) { - if (triangle[min_index] > triangle[k]) { +void normalize_face_index_rotation(std::span face) { + if (face.empty()) { + return; + } + + // find index of minimum element + size_t min_index = 0; + for (size_t k = 1; k < face.size(); k++) { + if (face[k] < face[min_index]) { min_index = k; } } - if (min_index == 0) { - return triangle; + + // rotate so minimum is first + if (min_index != 0) { + std::rotate(face.begin(), face.begin() + min_index, face.end()); } +} - glm::uvec3 normalized_triangle; - for (size_t k = 0; k < static_cast(triangle.length()); k++) { - normalized_triangle[k] = triangle[(min_index + k) % triangle.length()]; +void normalize_edge_inplace(glm::uvec2 &edge) { + if (edge.x > edge.y) { + std::swap(edge.x, edge.y); } +} +glm::uvec2 normalize_edge(glm::uvec2 edge) { + normalize_edge_inplace(edge); + return edge; +} - return normalized_triangle; +void normalize_triangle_inplace(glm::uvec3 &triangle) { + std::span data(glm::value_ptr(triangle), triangle.length()); + normalize_face_index_rotation(data); +} +glm::uvec3 normalize_triangle(glm::uvec3 triangle) { + normalize_triangle_inplace(triangle); + return triangle; +} + +void normalize_quad_inplace(glm::uvec4 &quad) { + std::span data(glm::value_ptr(quad), quad.length()); + normalize_face_index_rotation(data); +} +glm::uvec4 normalize_quad(glm::uvec4 quad) { + normalize_quad_inplace(quad); + return quad; } void sort_and_normalize_triangles(std::span triangles) { diff --git a/src/terrainlib/mesh/utils.h b/src/terrainlib/mesh/utils.h index f73cc4d..65ed03b 100644 --- a/src/terrainlib/mesh/utils.h +++ b/src/terrainlib/mesh/utils.h @@ -55,6 +55,14 @@ std::vector find_non_manifold_edges(const SimpleMesh &mesh); std::vector find_single_non_manifold_triangle_indices(const SimpleMesh &mesh); void remove_single_non_manifold_triangles(SimpleMesh& mesh); +void normalize_face_index_rotation(std::span face); +void normalize_edge_inplace(glm::uvec2 &edge); +glm::uvec2 normalize_edge(glm::uvec2 edge); +void normalize_triangle_inplace(glm::uvec3 &triangle); +glm::uvec3 normalize_triangle(glm::uvec3 triangle); +void normalize_quad_inplace(glm::uvec4 &quad); +glm::uvec4 normalize_quad(glm::uvec4 quad); + template void sort_and_normalize_triangles(SimpleMesh_ &mesh); void sort_and_normalize_triangles(std::span triangles); diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl index dbe211c..9a51471 100644 --- a/src/terrainlib/mesh/utils.inl +++ b/src/terrainlib/mesh/utils.inl @@ -86,14 +86,15 @@ std::unordered_set::Edge> get_edges(const Simple return edges; } +/* template -std::unordered_set::Edge> find_boundary_edges(const SimpleMesh_ &mesh) { +std::unordered_set::Edge> find_normalized_boundary_edges(const SimpleMesh_ &mesh) { std::unordered_set::Edge> boundary; - find_boundary_edges(mesh, boundary); + find_normalized_boundary_edges(mesh, boundary); return boundary; } template -void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set::Edge> &boundary) { +void find_normalized_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set::Edge> &boundary) { using Triangle = typename SimpleMesh_::Triangle; using Edge = typename SimpleMesh_::Edge; for (const auto &triangle_ref : mesh.triangles) { @@ -115,3 +116,33 @@ void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set< } } } +*/ + +template +std::unordered_set::Edge> find_boundary_edges(const SimpleMesh_ &mesh) { + std::unordered_set::Edge> boundary; + find_boundary_edges(mesh, boundary); + return boundary; +} +template +void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set::Edge> &boundary) { + using Triangle = typename SimpleMesh_::Triangle; + using Edge = typename SimpleMesh_::Edge; + for (const auto &triangle_ref : mesh.triangles) { + Triangle triangle = triangle_ref; + + const std::array reverse_edges{Edge(triangle.y, triangle.x), + Edge(triangle.z, triangle.y), + Edge(triangle.x, triangle.z)}; + for (const Edge &reverse_edge : reverse_edges) { + auto it = boundary.find(reverse_edge); + if (it != boundary.end()) { + // Edge already there -> shared egde -> remove it + boundary.erase(it); + } else { + // Edge not present -> add it (but in correct order) + boundary.insert(Edge(reverse_edge.y, reverse_edge.x)); + } + } + } +} diff --git a/src/terrainlib/polygon/Polygon.h b/src/terrainlib/polygon/Polygon.h new file mode 100644 index 0000000..3bfc289 --- /dev/null +++ b/src/terrainlib/polygon/Polygon.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include + +template +class Polygon_ { +public: + using Point = glm::vec; + + Polygon_() = default; + Polygon_(std::vector points) : Polygon_(points) {} + + std::vector points; + + size_t size() const { + return this->points.size(); + } +}; + +using Polygon3d = Polygon_<3, double>; +using Polygon2d = Polygon_<2, double>; diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp new file mode 100644 index 0000000..4d42008 --- /dev/null +++ b/src/terrainlib/polygon/triangulate.cpp @@ -0,0 +1,176 @@ +#include "polygon/triangulate.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include "mesh/cgal.h" +#include "mesh/convert.h" + +using Kernel = cgal::kernel::epeck::Kernel; +using Point2 = Kernel::Point_2; +using Polygon2 = CGAL::Polygon_2; + +using VertexBase = CGAL::Triangulation_vertex_base_with_info_2, Kernel>; +using FaceBase = CGAL::Constrained_triangulation_face_base_2; +using TDS = CGAL::Triangulation_data_structure_2; +using ExactTag = CGAL::Exact_predicates_tag; +using CDT = CGAL::Constrained_Delaunay_triangulation_2; +using FaceHandle = CDT::Face_handle; +using VertexHandle = CDT::Vertex_handle; + +namespace polygon { +namespace { +// Compute orthonormal basis (u,v) of polygon plane +struct PlaneBasis { + glm::dvec3 origin; + glm::dvec3 u, v; // orthonormal basis vectors in plane +}; + +PlaneBasis make_basis(const Polygon3d &polygon) { + const glm::dvec3& p0 = polygon.points[0]; + const glm::dvec3& p1 = polygon.points[1]; + const glm::dvec3& p2 = polygon.points[2]; + const glm::dvec3 normal = glm::normalize(glm::cross(p1 - p0, p2 - p0)); + const glm::dvec3 u = glm::normalize(p1 - p0); + const glm::dvec3 v = glm::normalize(glm::cross(normal, u)); + return {p0, u, v}; +} + +// project 3d point onto 2d basis +glm::dvec2 project(const glm::dvec3 &p, const PlaneBasis &basis) { + const glm::dvec3 d = p - basis.origin; + return {glm::dot(d, basis.u), glm::dot(d, basis.v)}; +} + +// lift back to 3d +glm::dvec3 lift(const glm::dvec2 &q, const PlaneBasis &basis) { + return basis.origin + q.x * basis.u + q.y * basis.v; +} + +} + +// TODO: deduplicate overloads +void triangulate(SimpleMesh3d &mesh, const std::span indices) { + // Build the 3D points of the polygon + Polygon3d polygon; + polygon.points.reserve(indices.size()); + for (const uint32_t vertex_index : indices) { + DEBUG_ASSERT(vertex_index < mesh.positions.size()); + polygon.points.push_back(mesh.positions[vertex_index]); + } + + DEBUG_ASSERT(polygon::is_planar(polygon)); + const PlaneBasis basis = make_basis(polygon); + + CDT cdt; + + // Insert all polygon vertices and assign their mesh indices + std::vector handles; + handles.reserve(indices.size()); + for (uint32_t i = 0; i < indices.size(); i++) { + const glm::dvec3 &point = polygon.points[i]; + const glm::dvec2 projected = project(point, basis); + VertexHandle vh = cdt.insert(convert::to_cgal_point(projected)); + vh->info() = indices[i]; + handles.push_back(vh); + } + + // Insert constraints between consecutive vertices + for (size_t i = 0; i < handles.size(); i++) { + cdt.insert_constraint(handles[i], handles[(i + 1) % handles.size()]); + } + + // Mark facets that are inside the domain bounded by the polygon (since the full convex hull is triangulated) + std::unordered_map in_domain_map; + boost::associative_property_map> in_domain(in_domain_map); + CGAL::mark_domain_in_triangulation(cdt, in_domain); + DEBUG_ASSERT(cdt.is_valid()); + + // insert new triangles and vertices + for (const FaceHandle face : cdt.finite_face_handles()) { + if (!get(in_domain, face)) { + continue; // outside polygon + } + + glm::uvec3 triangle; + for (int i = 0; i < 3; i++) { + const auto &vertex = face->vertex(i); + const auto &original_index = vertex->info(); + if (!original_index.has_value()) { + const uint32_t new_index = mesh.positions.size(); + const Point2 &cgal_point = vertex->point(); + const glm::dvec2 point2d = convert::to_glm_point(cgal_point); + const glm::dvec3 point3d = lift(point2d, basis); + mesh.positions.push_back(point3d); + triangle[i] = new_index; + } else { + triangle[i] = original_index.value(); + } + } + + mesh.triangles.push_back(triangle); + } +} + +SimpleMesh3d triangulate(const Polygon3d &polygon) { + ASSERT(false); + // TODO; + return {}; + /* + DEBUG_ASSERT(polygon::is_planar(polygon)); + const PlaneBasis basis = make_basis(polygon); + + CDT cdt; + // insert edges + for (size_t i = 0; i < polygon.size(); i++) { + const glm::dvec2 a = project(polygon.points[i], basis); + const glm::dvec2 b = project(polygon.points[(i + 1) % polygon.size()], basis); + cdt.insert_constraint( + convert::to_cgal_point(a), + convert::to_cgal_point(b) + ); + } + + // Mark facets that are inside the domain bounded by the polygon (since the full convex hull is triangulated) + CGAL::mark_domain_in_triangulation(cdt); + DEBUG_ASSERT(cdt.is_valid()); + + // Build the resulting triangle mesh + SimpleMesh3d result; + // Map from CGAL vertex handles to output mesh indices + std::unordered_map vertex_index_map; + + for (const FaceHandle face : cdt.finite_face_handles()) { + if (!face->info()) { + // not inside polygon + continue; + } + + glm::uvec3 triangle; + for (uint32_t i = 0; i < 3; i++) { + const VertexHandle vertex = face->vertex(i); + auto [it, inserted] = vertex_index_map.emplace(vertex, 0); + if (inserted) { + const uint32_t new_index = result.positions.size(); + const Point2 &cgal_point = vertex->point(); + const glm::dvec2 point2d = convert::to_glm_point(cgal_point); + const glm::dvec3 point3d = lift(point2d, basis); + result.positions.push_back(point3d); + it->second = new_index; + } + triangle[i] = it->second; + } + + result.triangles.push_back(triangle); + } + + return result; + */ +} +} diff --git a/src/terrainlib/polygon/triangulate.h b/src/terrainlib/polygon/triangulate.h new file mode 100644 index 0000000..e16e8b3 --- /dev/null +++ b/src/terrainlib/polygon/triangulate.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include "polygon/Polygon.h" +#include "mesh/SimpleMesh.h" + +namespace polygon { + +SimpleMesh3d triangulate(const Polygon3d &polygon); +void triangulate(SimpleMesh3d &mesh, const std::span indices); + +} // namespace polygon diff --git a/src/terrainlib/polygon/utils.cpp b/src/terrainlib/polygon/utils.cpp new file mode 100644 index 0000000..7bd38ba --- /dev/null +++ b/src/terrainlib/polygon/utils.cpp @@ -0,0 +1,42 @@ +#include +#include + +#include "polygon/utils.h" + + namespace polygon { +bool is_planar(const Polygon3d &polygon, const double epsilon) { + if (polygon.size() < 4) { + return true; // 3 points always define a plane + } + + glm::dvec3 p0 = polygon.points[0]; + glm::dvec3 normal(0); + + // find non-collinear triple (to compute normal) + size_t i = 1; + while (i + 1 < polygon.size()) { + const glm::dvec3 v1 = polygon.points[i] - p0; + const glm::dvec3 v2 = polygon.points[i + 1] - p0; + normal = glm::cross(v1, v2); + if (glm::length2(normal) > epsilon * epsilon) { + break; + } + i++; + } + if (glm::length2(normal) <= epsilon * epsilon) { + // all points collinear + return true; + } + + normal = glm::normalize(normal); + + // check all points + for (const auto &p : polygon.points) { + const double distance = std::abs(glm::dot(p - p0, normal)); + if (distance > epsilon) { + return false; + } + } + return true; +} +} diff --git a/src/terrainlib/polygon/utils.h b/src/terrainlib/polygon/utils.h new file mode 100644 index 0000000..5a4aaec --- /dev/null +++ b/src/terrainlib/polygon/utils.h @@ -0,0 +1,7 @@ +#pragma once + +#include "polygon/Polygon.h" + +namespace polygon { +bool is_planar(const Polygon3d &poly, double eps = 1e-9); +} diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 1fc1de6..2b429cb 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -4,10 +4,11 @@ #include "merge/NodeData.h" #include "merge/Result.h" #include "merge/visitor/Visitor.h" -#include "mesh/merge.h" +#include "mesh/holes.h" #include "mesh/merging/SphereVertexDeduplicate.h" -#include "mesh/merging/SphereVertexDeduplicate2.h" +#include "mesh/merging/VertexMapping.h" #include "mesh/merging/helpers.h" +#include "mesh/merging/mapping.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" #include "spatial_lookup/Hashmap.h" @@ -169,23 +170,22 @@ class Masked { } } + LOG_TRACE("Performing actual mesh merge"); const std::array, 2> meshes = {base_mesh_clipped.get(), new_mesh_clipped.get()}; const double distance_epsilon = mesh::merging::estimate_merge_epsilon(meshes); - /* - spatial_lookup::Hashmap2d map(distance_epsilon * 3); + // We have to use a hashmap here instead of a grid since we dont know + // the bounds of the mesh projected onto the sphere with the deduplication radius. + spatial_lookup::Hashmap3d map(distance_epsilon * 3); const glm::dvec3 tangent_point = meshes[0].get().positions[0]; + const double radius = glm::length(tangent_point); mesh::merging::SphereVertexDeduplicate< - mesh::merging::VertexId, - spatial_lookup::Hashmap2d - > deduplicate(map, 0.01, tangent_point); - */ - auto map = mesh::merging::construct_grid_for_meshes(meshes); - const double radius = glm::length(meshes[0].get().positions[0]); - mesh::merging::SphereVertexDeduplicate2< mesh::merging::VertexId, decltype(map) > deduplicate(map, distance_epsilon, radius); - const SimpleMesh merged_mesh = mesh::merge(meshes, deduplicate); + const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate); + SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping); + LOG_TRACE("Filling holes on merge border"); + mesh::fill_holes_on_merge_border(merged_mesh, mapping); return Merged{merged_mesh}; /* diff --git a/src/terrainmerger/merge/visitor/Simple.h b/src/terrainmerger/merge/visitor/Simple.h index 890c884..9dcec6a 100644 --- a/src/terrainmerger/merge/visitor/Simple.h +++ b/src/terrainmerger/merge/visitor/Simple.h @@ -3,6 +3,7 @@ #include "merge/Result.h" #include "merge/NodeData.h" #include "merge/visitor/Visitor.h" +#include "mesh/merge.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index eae986d..c0a47a6 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -39,14 +39,16 @@ add_executable(unittests_terrainlib terrainlib/index_map.cpp terrainlib/index_traverse.cpp terrainlib/mesh_clip.cpp + terrainlib/mesh_connected_components.cpp + terrainlib/mesh_holes.cpp terrainlib/mesh_io.cpp + terrainlib/mesh_merge_mapping.cpp + terrainlib/mesh_merge.cpp terrainlib/mesh_utils.cpp terrainlib/octree_id.cpp terrainlib/octree_space.cpp terrainlib/progress_indicator_test.cpp terrainlib/spatial_lookup.cpp - terrainlib/mesh_merge_mapping.cpp - terrainlib/mesh_merge.cpp ) target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) diff --git a/unittests/terrainlib/mesh_connected_components.cpp b/unittests/terrainlib/mesh_connected_components.cpp new file mode 100644 index 0000000..f38c5e4 --- /dev/null +++ b/unittests/terrainlib/mesh_connected_components.cpp @@ -0,0 +1,108 @@ +#include + +#include + +#include "../catch2_helpers.h" + +#include "mesh/SimpleMesh.h" +#include "mesh/connected_components.h" + +TEST_CASE("find_connected_components on empty mesh") { + SimpleMesh mesh; + auto result = mesh::find_connected_components(mesh); + + CHECK(result.vertex_to_component.empty()); + CHECK(result.component_count == 0); +} + +TEST_CASE("find_connected_components on single triangle") { + SimpleMesh mesh; + mesh.positions = { + {0.0, 0.0, 0.0}, + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}}; + mesh.triangles = {glm::uvec3(0, 1, 2)}; + + auto result = mesh::find_connected_components(mesh); + + CHECK(result.vertex_to_component.size() == 3); + CHECK(result.component_count == 1); + for (auto c : result.vertex_to_component) { + CHECK(c == 0); + } +} + +TEST_CASE("find_connected_components on two disjoint triangles") { + SimpleMesh mesh; + mesh.positions = { + {0.0, 0.0, 0.0}, + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {2.0, 0.0, 0.0}, + {3.0, 0.0, 0.0}, + {2.0, 1.0, 0.0}}; + mesh.triangles = { + glm::uvec3(0, 1, 2), + glm::uvec3(3, 4, 5)}; + + auto result = mesh::find_connected_components(mesh); + + CHECK(result.vertex_to_component.size() == 6); + CHECK(result.component_count == 2); + + // First triangle vertices share component + CHECK(result.vertex_to_component[0] == result.vertex_to_component[1]); + CHECK(result.vertex_to_component[1] == result.vertex_to_component[2]); + + // Second triangle vertices share component + CHECK(result.vertex_to_component[3] == result.vertex_to_component[4]); + CHECK(result.vertex_to_component[4] == result.vertex_to_component[5]); + + // The two groups must be different + CHECK(result.vertex_to_component[0] != result.vertex_to_component[3]); +} + +TEST_CASE("split_into_connected_components keeps triangles grouped") { + SimpleMesh mesh; + mesh.positions = { + {0.0, 0.0, 0.0}, + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {2.0, 0.0, 0.0}, + {3.0, 0.0, 0.0}, + {2.0, 1.0, 0.0}}; + mesh.triangles = { + glm::uvec3(0, 1, 2), + glm::uvec3(3, 4, 5)}; + + auto components = mesh::split_into_connected_components(mesh); + + CHECK(components.size() == 2); + + // Each component must have exactly one triangle + CHECK(components[0].triangles.size() == 1); + CHECK(components[1].triangles.size() == 1); + + // Each component must have 3 vertices + CHECK(components[0].positions.size() == 3); + CHECK(components[1].positions.size() == 3); +} + +TEST_CASE("split_into_connected_components with shared vertex triangles") { + SimpleMesh mesh; + mesh.positions = { + {0.0, 0.0, 0.0}, // 0 + {1.0, 0.0, 0.0}, // 1 + {0.0, 1.0, 0.0}, // 2 + {1.0, 1.0, 0.0}}; // 3 + mesh.triangles = { + glm::uvec3(0, 1, 2), + glm::uvec3(1, 2, 3)}; + + auto components = mesh::split_into_connected_components(mesh); + + // Both triangles are connected, so one component + CHECK(components.size() == 1); + CHECK(components[0].triangles.size() == 2); + CHECK(components[0].positions.size() == 4); +} diff --git a/unittests/terrainlib/mesh_holes.cpp b/unittests/terrainlib/mesh_holes.cpp new file mode 100644 index 0000000..96a3769 --- /dev/null +++ b/unittests/terrainlib/mesh_holes.cpp @@ -0,0 +1,319 @@ +#include + +#include +#include + +#include "../catch2_helpers.h" + +#include "mesh/SimpleMesh.h" +#include "mesh/holes.h" +#include "mesh/utils.h" +#include "mesh/validate.h" +#include "log_impls.h" + +std::string vec2d_to_string(const std::vector> &v) { + std::ostringstream oss; + oss << "{"; + for (size_t i = 0; i < v.size(); ++i) { + oss << "{"; + for (size_t j = 0; j < v[i].size(); ++j) { + oss << v[i][j]; + if (j + 1 < v[i].size()) + oss << ", "; + } + oss << "}"; + if (i + 1 < v.size()) + oss << ", "; + } + oss << "}"; + return oss.str(); +} + +TEST_CASE("find_boundaries returns empty for empty mesh") { + SimpleMesh mesh; + auto boundaries = mesh::find_boundaries(mesh); + CHECK(boundaries.empty()); +} + +TEST_CASE("find_boundaries returns single boundary of all vertices for single triangle") { + SimpleMesh mesh; + mesh.positions = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}; + mesh.triangles = {glm::uvec3(0, 1, 2)}; + + auto boundaries = mesh::find_boundaries(mesh); + + INFO(vec2d_to_string(boundaries)); + CHECK(boundaries.size() == 1); + std::vector expected = {0, 1, 2}; + CHECK_THAT(boundaries[0], Catch::Matchers::UnorderedEquals(expected)); +} + +TEST_CASE("find_boundaries returns single boundary of all vertices for two connected triangle") { + SimpleMesh mesh; + mesh.positions = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 1, 1}}; + mesh.triangles = {glm::uvec3(0, 1, 3), glm::uvec3(1, 2, 3)}; + + auto boundaries = mesh::find_boundaries(mesh); + + std::vector expected = {0, 3, 2, 1}; + CHECK(boundaries.size() == 1); + auto boundary = boundaries[0]; + normalize_face_index_rotation(boundary); + CHECK_THAT(boundary, Catch::Matchers::UnorderedEquals(expected)); +} + +TEST_CASE("find_boundaries returns two boundaries for two isolated triangles") { + SimpleMesh mesh; + mesh.positions = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 1, 1}, {0, 2, 1}, {0, 1, 2}}; + mesh.triangles = {glm::uvec3(0, 1, 2), glm::uvec3(3, 4, 5)}; + + auto boundaries = mesh::find_boundaries(mesh); + CHECK(boundaries.size() == 2); + if (boundaries[0][0] > boundaries[1][0]) { + std::swap(boundaries[0], boundaries[1]); + } + std::vector expected1 = {0, 1, 2}; + CHECK_THAT(boundaries[0], Catch::Matchers::UnorderedEquals(expected1)); + std::vector expected2 = {3, 4, 5}; + CHECK_THAT(boundaries[1], Catch::Matchers::UnorderedEquals(expected2)); +} + +TEST_CASE("find_holes find square hole") { + SimpleMesh mesh; + // Outer square: 0,1,2,3 + // Inner hole square: 4,5,6,7 + mesh.positions = { + {0, 0, 0}, // 0 + {2, 0, 0}, // 1 + {2, 2, 0}, // 2 + {0, 2, 0}, // 3 + {0.5, 0.5, 0}, // 4 + {1.5, 0.5, 0}, // 5 + {1.5, 1.5, 0}, // 6 + {0.5, 1.5, 0} // 7 + }; + + // Triangles forming a frame (outer square minus inner square) + mesh.triangles = { + // bottom strip + {0, 1, 5}, + {0, 5, 4}, + // right strip + {1, 2, 6}, + {1, 6, 5}, + // top strip + {2, 3, 7}, + {2, 7, 6}, + // left strip + {3, 0, 4}, + {3, 4, 7}}; + + std::vector outer_loop = {0, 1, 2, 3}; + std::vector inner_loop = {4, 5, 6, 7}; + + auto boundaries = mesh::find_boundaries(mesh); + CHECK(boundaries.size() == 2); + if (boundaries[0][0] > boundaries[1][0]) { + std::swap(boundaries[0], boundaries[1]); + } + CHECK_THAT(boundaries[0], Catch::Matchers::UnorderedEquals(outer_loop)); + CHECK_THAT(boundaries[1], Catch::Matchers::UnorderedEquals(inner_loop)); + + auto holes = mesh::find_holes(mesh); + CHECK(holes.size() == 1); + CHECK_THAT(holes[0], Catch::Matchers::UnorderedEquals(inner_loop)); +} + +TEST_CASE("fill_planar_hole fill square hole") { + SimpleMesh mesh; + // Outer square: 0,1,2,3 + // Inner hole square: 4,5,6,7 + mesh.positions = { + {0, 0, 0}, // 0 + {2, 0, 0}, // 1 + {2, 2, 0}, // 2 + {0, 2, 0}, // 3 + {0.5, 0.5, 0}, // 4 + {1.5, 0.5, 0}, // 5 + {1.5, 1.5, 0}, // 6 + {0.5, 1.5, 0} // 7 + }; + + // Triangles forming a frame (outer square minus inner square) + mesh.triangles = { + // bottom strip + {0, 1, 5}, + {0, 5, 4}, + // right strip + {1, 2, 6}, + {1, 6, 5}, + // top strip + {2, 3, 7}, + {2, 7, 6}, + // left strip + {3, 0, 4}, + {3, 4, 7}}; + + const std::vector outer_loop = {0, 1, 2, 3}; + const std::vector inner_loop = {4, 5, 6, 7}; + + const auto holes = mesh::find_holes(mesh); + CHECK(holes.size() == 1); + CHECK_THAT(holes[0], Catch::Matchers::UnorderedEquals(inner_loop)); + + const size_t before = mesh.triangles.size(); + mesh::fill_planar_hole(mesh, inner_loop); + const size_t after = mesh.triangles.size(); + + // two new triangles + CHECK(after == before + 2); + + // all new triangles only use inner_loop vertices + for (size_t i = before; i < after; i++) { + const glm::uvec3 triangle = mesh.triangles[i]; + for (size_t k = 0; k < 3; k++) { + CHECK(std::find(inner_loop.begin(), inner_loop.end(), triangle[k]) != inner_loop.end()); + } + } + + auto triangle_normal = [&](const glm::uvec3 &triangle) { + const auto &a = mesh.positions[triangle[0]]; + const auto &b = mesh.positions[triangle[1]]; + const auto &c = mesh.positions[triangle[2]]; + return glm::normalize(glm::cross(b - a, c - a)); + }; + const glm::dvec3 expected_normal = triangle_normal(mesh.triangles[0]); + for (const glm::uvec3 triangle : mesh.triangles) { + const glm::dvec3 actual_normal = triangle_normal(triangle); + CHECK(expected_normal == actual_normal); + } +} + +TEST_CASE("square frame with two holes sharing a vertex") { + SimpleMesh mesh; + mesh.positions = { + {0, 0, 0}, // 0 + {1, 0, 0}, // 1 + {1, 1, 0}, // 2 + {0, 1, 0}, // 3 + {0.25, 0.25, 0}, // 4 + {0.75, 0.25, 0}, // 5 + {0.75, 0.75, 0}, // 6 + {0.25, 0.75, 0}, // 7 + {0.5, 0.5, 0} // 8 + }; + mesh.triangles = { + // bottom strip + {0, 1, 5}, + {0, 5, 4}, + // right strip + {1, 2, 6}, + {1, 6, 5}, + // top strip + {2, 3, 7}, + {2, 7, 6}, + // left strip + {3, 0, 4}, + {3, 4, 7}, + // top inner + {6, 7, 8}, + // bottom inner + {4, 5, 8} + }; + mesh::validate(mesh); + + SECTION("find_boundary_edges") { + // expected + const std::vector expected_edges = { + // outer loop + {0, 1}, + {1, 2}, + {2, 3}, + {3, 0}, + // inner hole left + {4, 7}, + {8, 4}, + {7, 8}, + // inner hole right + {6, 5}, + {5, 8}, + {8, 6}}; + const std::unordered_set expected_edges_set(expected_edges.begin(), expected_edges.end()); + + // actual + const std::unordered_set actual_edges_set = find_boundary_edges(mesh); + std::vector actual_edges(actual_edges_set.begin(), actual_edges_set.end()); + + // missing edges + std::vector missing; + for (auto const& e : expected_edges) { + if (actual_edges_set.find(e) == actual_edges_set.end()) { + missing.push_back(e); + } + } + + // unexpected edges + std::vector unexpected; + for (auto const& e : actual_edges) { + if (expected_edges_set.find(e) == expected_edges_set.end()) { + unexpected.push_back(e); + } + } + + INFO("Missing edges: " + fmt::format("{}", fmt::join(missing, ", "))); + INFO("Unexpected edges: " + fmt::format("{}", fmt::join(unexpected, ", "))); + + REQUIRE_THAT(actual_edges, Catch::Matchers::UnorderedEquals(expected_edges)); + } + + SECTION("find_boundaries") { + const auto boundaries = mesh::find_boundaries(mesh); + + const std::vector expected_boundaries = {{0, 3, 2, 1}, {4, 8, 7, UINT_MAX}, {5, 6, 8, UINT_MAX}}; + for (const auto &quad : expected_boundaries) { + CHECK(normalize_quad(quad) == quad); + } + + std::vector actual_boundaries; + for (const auto &boundary : boundaries) { + INFO(fmt::format("boundary = [{}]", fmt::join(boundary, ", "))); + REQUIRE(boundary.size() <= 4); + glm::uvec4 quad(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX); + for (size_t i = 0; i < boundary.size(); i++) { + quad[i] = boundary[i]; + } + normalize_quad_inplace(quad); + size_t out_index = 0; + for (size_t i = 0; i < 4; i++) { + if (quad[i] != UINT_MAX) { + quad[out_index] = quad[i]; + out_index += 1; + } + } + for (size_t i = out_index; i < 4; i++) { + quad[out_index] = UINT_MAX; + } + actual_boundaries.push_back(quad); + } + + REQUIRE_THAT(actual_boundaries, Catch::Matchers::UnorderedEquals(expected_boundaries)); + } + + const auto holes = mesh::find_holes(mesh); + SECTION("find_holes") { + const std::vector expected_holes = {{4, 8, 7}, {5, 6, 8}}; + for (const auto &triangle : expected_holes) { + CHECK(normalize_triangle(triangle) == triangle); + } + + std::vector actual_holes; + for (const auto &hole : holes) { + INFO(fmt::format("hole = [{}]", fmt::join(hole, ", "))); + REQUIRE(hole.size() == 3); + const glm::uvec3 triangle(hole[0], hole[1], hole[2]); + actual_holes.push_back(normalize_triangle(triangle)); + } + + REQUIRE_THAT(actual_holes, Catch::Matchers::UnorderedEquals(expected_holes)); + } +} diff --git a/unittests/terrainlib/mesh_merge.cpp b/unittests/terrainlib/mesh_merge.cpp index ffe3a0d..b42e2b2 100644 --- a/unittests/terrainlib/mesh_merge.cpp +++ b/unittests/terrainlib/mesh_merge.cpp @@ -24,18 +24,20 @@ #include "mesh/merge.h" #include "mesh/utils.h" -TEST_CASE("terrainmerger") { +TEST_CASE("mesh::merge") { SECTION("two tris with shared edge") { SimpleMesh mesh1; mesh1.positions.push_back(glm::dvec3(0, 0, 0)); mesh1.positions.push_back(glm::dvec3(1, 1, 0)); mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(1, 0, 0)); mesh2.positions.push_back(glm::dvec3(1, 1, 0)); mesh2.positions.push_back(glm::dvec3(0, 1, 0)); + mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); @@ -45,6 +47,7 @@ TEST_CASE("terrainmerger") { expected.positions.push_back(glm::dvec3(1, 1, 0)); expected.positions.push_back(glm::dvec3(1, 0, 0)); expected.positions.push_back(glm::dvec3(0, 1, 0)); + expected.triangles.push_back(glm::uvec3(0, 1, 2)); expected.triangles.push_back(glm::uvec3(2, 1, 3)); @@ -194,4 +197,4 @@ TEST_CASE("terrainmerger") { CHECK(merged_small.positions.size() > merged_large.positions.size()); } -} +} \ No newline at end of file diff --git a/unittests/terrainlib/mesh_merge_mapping.cpp b/unittests/terrainlib/mesh_merge_mapping.cpp index f8fe677..26a3e6b 100644 --- a/unittests/terrainlib/mesh_merge_mapping.cpp +++ b/unittests/terrainlib/mesh_merge_mapping.cpp @@ -17,13 +17,18 @@ * along with this program. If not, see . *****************************************************************************/ +#include + #include "../catch2_helpers.h" + #include "mesh/SimpleMesh.h" #include "mesh/merging/mapping.h" -#include #include "spatial_lookup/CellBasedStorage.h" #include "spatial_lookup/GridStorage.h" #include "spatial_lookup/HashmapStorage.h" +#include "mesh/merging/SphereVertexDeduplicate.h" +#include "mesh/merging/helpers.h" +#include "spatial_lookup/Hashmap.h" using mesh::merging::VertexId; using mesh::merging::VertexMapping; @@ -36,12 +41,12 @@ TEST_CASE("merging::create_mapping") { SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(0, 0, 0)); - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); - size_t idx1 = mapping.map_forward(VertexId{0, 0}); - size_t idx2 = mapping.map_forward(VertexId{1, 0}); + const size_t idx1 = mapping.map_forward(VertexId{0, 0}); + const size_t idx2 = mapping.map_forward(VertexId{1, 0}); CHECK(idx1 == idx2); } @@ -56,22 +61,22 @@ TEST_CASE("merging::create_mapping") { mesh2.positions.push_back(glm::dvec3(1, 1, 0)); // identical to mesh1[1] mesh2.positions.push_back(glm::dvec3(0, 1, 0)); - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // Merged index of (1, 0, 0) should be the same for both meshes - size_t idx1 = mapping.map_forward(VertexId{0, 2}); - size_t idx2 = mapping.map_forward(VertexId{1, 0}); + const size_t idx1 = mapping.map_forward(VertexId{0, 2}); + const size_t idx2 = mapping.map_forward(VertexId{1, 0}); CHECK(idx1 == idx2); // Merged index of (1,1,0) should be the same for both - size_t idx3 = mapping.map_forward(VertexId{0, 1}); - size_t idx4 = mapping.map_forward(VertexId{1, 1}); + const size_t idx3 = mapping.map_forward(VertexId{0, 1}); + const size_t idx4 = mapping.map_forward(VertexId{1, 1}); CHECK(idx3 == idx4); // (0, 1, 0) should be unique - size_t idx5 = mapping.map_forward(VertexId{1, 2}); + const size_t idx5 = mapping.map_forward(VertexId{1, 2}); CHECK(idx5 != idx1); CHECK(idx5 != idx3); @@ -88,18 +93,18 @@ TEST_CASE("merging::create_mapping") { mesh2.positions.push_back(glm::dvec3(1.05, 0, 0)); // should be merged if epsilon >= 0.1 mesh2.positions.push_back(glm::dvec3(2, 0, 0)); - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); - size_t idx1 = mapping.map_forward(VertexId{0, 1}); // (1, 0, 0) - size_t idx2 = mapping.map_forward(VertexId{1, 0}); // (1.05, 0, 0) + const size_t idx1 = mapping.map_forward(VertexId{0, 1}); // (1, 0, 0) + const size_t idx2 = mapping.map_forward(VertexId{1, 0}); // (1.05, 0, 0) // They are within epsilon => should be merged CHECK(idx1 == idx2); // The far point should be separate - size_t idx3 = mapping.map_forward(VertexId{1, 1}); // (2, 0, 0) + const size_t idx3 = mapping.map_forward(VertexId{1, 1}); // (2, 0, 0) CHECK(idx3 != idx1); CHECK(mapping.find_max_merged_index() + 1 == 3); @@ -111,12 +116,12 @@ TEST_CASE("merging::create_mapping") { SimpleMesh mesh2; mesh2.positions.push_back(glm::dvec3(1.10000001, 0, 0)); - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // epsilon too small + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // epsilon too small - size_t idx1 = mapping.map_forward(VertexId{0, 0}); - size_t idx2 = mapping.map_forward(VertexId{1, 0}); + const size_t idx1 = mapping.map_forward(VertexId{0, 0}); + const size_t idx2 = mapping.map_forward(VertexId{1, 0}); CHECK(idx1 != idx2); CHECK(mapping.find_max_merged_index() + 1 == 2); @@ -131,9 +136,9 @@ TEST_CASE("merging::create_mapping") { mesh2.positions.push_back(glm::dvec3(2, 0, 0)); mesh2.positions.push_back(glm::dvec3(3, 0, 0)); - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // all far apart + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // all far apart CHECK(mapping.find_max_merged_index() + 1 == 4); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{0, 1})); @@ -150,12 +155,74 @@ TEST_CASE("merging::create_mapping") { SimpleMesh mesh2 = mesh1; - std::array, 2> meshes = {mesh1, mesh2}; + const std::array, 2> meshes = {mesh1, mesh2}; - VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); CHECK(mapping.map_forward(VertexId{0, 0}) == mapping.map_forward(VertexId{1, 0})); CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); CHECK(mapping.map_forward(VertexId{0, 2}) == mapping.map_forward(VertexId{1, 2})); } + + SECTION("two tris with shared edge") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0, 0)); + mesh1.positions.push_back(glm::dvec3(1, 1, 0)); + mesh1.positions.push_back(glm::dvec3(1, 0, 0)); + + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(1, 0, 0)); + mesh2.positions.push_back(glm::dvec3(1, 1, 0)); + mesh2.positions.push_back(glm::dvec3(0, 1, 0)); + + mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); + + const std::array, 2> meshes = {mesh1, mesh2}; + + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 2})); + CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.map_forward(VertexId{0, 2}) == mapping.map_forward(VertexId{1, 0})); + } + + SECTION("SphereVertexDeduplicate") { + SimpleMesh mesh1; + mesh1.positions.push_back(glm::dvec3(0, 0.5, 0)); + mesh1.positions.push_back(glm::dvec3(0.5, 0, 0)); + mesh1.positions.push_back(glm::dvec3(0.25, 0.25, 0)); + + mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); + + SimpleMesh mesh2; + mesh2.positions.push_back(glm::dvec3(1, 0, 0)); + mesh2.positions.push_back(glm::dvec3(1, 1, 0)); + mesh2.positions.push_back(glm::dvec3(1.5, 0.5, 0)); + + mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); + + const std::array, 2> meshes = {mesh1, mesh2}; + const double distance_epsilon = 0.001; + auto map = spatial_lookup::Hashmap3d(0.1); + const double radius = 100; + mesh::merging::SphereVertexDeduplicate< + mesh::merging::VertexId, + decltype(map) + > deduplicate(map, distance_epsilon, radius); + const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate); + + CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 0})); + CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 2})); + + CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 0})); + CHECK(mapping.map_forward(VertexId{0, 1}) != mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.map_forward(VertexId{0, 1}) != mapping.map_forward(VertexId{1, 2})); + + CHECK(mapping.map_forward(VertexId{0, 2}) != mapping.map_forward(VertexId{1, 0})); + CHECK(mapping.map_forward(VertexId{0, 2}) == mapping.map_forward(VertexId{1, 1})); + CHECK(mapping.map_forward(VertexId{0, 2}) != mapping.map_forward(VertexId{1, 2})); + } } diff --git a/unittests/terrainlib/mesh_utils.cpp b/unittests/terrainlib/mesh_utils.cpp index 729b258..11f8f72 100644 --- a/unittests/terrainlib/mesh_utils.cpp +++ b/unittests/terrainlib/mesh_utils.cpp @@ -63,22 +63,101 @@ TEST_CASE("reindex_mesh") { glm::dvec3(3.0, 3.0, 3.0), glm::dvec3(4.0, 4.0, 4.0)})); CHECK_THAT(reindexed.uvs, UnorderedEquals({glm::dvec2(0.0, 0.0), - glm::dvec2(1.0, 1.0), - glm::dvec2(3.0, 3.0), - glm::dvec2(4.0, 4.0)})); + glm::dvec2(1.0, 1.0), + glm::dvec2(3.0, 3.0), + glm::dvec2(4.0, 4.0)})); CHECK(reindexed.texture.has_value()); CHECK(mat_equals(*reindexed.texture, *original.texture)); }; SECTION("const SimpleMesh& overload") { - SimpleMesh reindexed_mesh = reindex_mesh(static_cast(mesh)); + SimpleMesh reindexed_mesh = reindex_mesh(static_cast(mesh)); run_checks(mesh, reindexed_mesh); } SECTION("non-const SimpleMesh& overload") { SimpleMesh original_mesh = mesh; - reindex_mesh(static_cast(mesh)); + reindex_mesh(static_cast(mesh)); SimpleMesh reindexed_mesh = std::move(mesh); run_checks(original_mesh, reindexed_mesh); } } + +TEST_CASE("mesh::find_boundary_edges") { + SECTION("empty for empty mesh") { + SimpleMesh mesh; + auto edges = find_boundary_edges(mesh); + + std::vector actual(edges.begin(), edges.end()); + std::vector expected; + + REQUIRE_THAT(actual, Catch::Matchers::UnorderedEquals(expected)); + } + + SECTION("all edges for single triangle") { + SimpleMesh mesh; + mesh.positions = { + {0.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, + {0.f, 1.f, 0.f}}; + mesh.triangles = {glm::uvec3(0, 1, 2)}; + + auto edges = find_boundary_edges(mesh); + + std::vector actual(edges.begin(), edges.end()); + std::vector expected = { + {0, 1}, {1, 2}, {2, 0}}; + REQUIRE_THAT(actual, Catch::Matchers::UnorderedEquals(expected)); + } + + SECTION("two triangles sharing an edge") { + SimpleMesh mesh; + mesh.positions = { + {0.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, + {0.f, 1.f, 0.f}, + {1.f, 1.f, 0.f}}; + mesh.triangles = { + {0, 1, 2}, + {1, 3, 2}}; + + auto edges = find_boundary_edges(mesh); + + std::vector actual(edges.begin(), edges.end()); + std::vector expected = { + {0, 1}, {2, 0}, {1, 3}, {3, 2} // shared edge {1,2} not included + }; + + REQUIRE_THAT(actual, Catch::Matchers::UnorderedEquals(expected)); + } + + SECTION("empty for cube mesh") { + SimpleMesh mesh; + mesh.positions = { + {-1, -1, -1}, // 0 + {1, -1, -1}, // 1 + {1, 1, -1}, // 2 + {-1, 1, -1}, // 3 + {-1, -1, 1}, // 4 + {1, -1, 1}, // 5 + {1, 1, 1}, // 6 + {-1, 1, 1} // 7 + }; + + mesh.triangles = { + {0, 1, 2}, {0, 2, 3}, // front + {1, 5, 6}, {1, 6, 2}, // right + {5, 4, 7}, {5, 7, 6}, // back + {4, 0, 3}, {4, 3, 7}, // left + {3, 2, 6}, {3, 6, 7}, // top + {4, 5, 1}, {4, 1, 0} // bottom + }; + + auto edges = find_boundary_edges(mesh); + + std::vector actual(edges.begin(), edges.end()); + std::vector expected; + + REQUIRE_THAT(actual, Catch::Matchers::UnorderedEquals(expected)); + } +} diff --git a/unittests/terrainlib/spatial_multi_hashmap.cpp b/unittests/terrainlib/spatial_multi_hashmap.cpp deleted file mode 100644 index e69de29..0000000 From f62645c2483091df8e51ac3d957dd748301f821c Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 21 Aug 2025 16:09:39 +0200 Subject: [PATCH 110/122] Only consider boundary when merging --- src/terrainlib/mesh/merging/mapping.cpp | 115 +++++++++++++++----- src/terrainlib/mesh/merging/mapping.h | 12 +- unittests/terrainlib/mesh_merge.cpp | 8 +- unittests/terrainlib/mesh_merge_mapping.cpp | 36 +++--- 4 files changed, 123 insertions(+), 48 deletions(-) diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index a3df5c0..16783b2 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -9,8 +11,8 @@ #include "log.h" #include "mesh/convert.h" #include "mesh/merging/EpsilonVertexDeduplicate.h" -#include "mesh/merging/mapping.h" #include "mesh/merging/helpers.h" +#include "mesh/merging/mapping.h" #include "mesh/utils.h" #include "mesh/validate.h" #include "spatial_lookup/Grid.h" @@ -61,19 +63,26 @@ void validate_epsilon_mapping( } #endif } -} +} // namespace -VertexMapping create_mapping(const std::span> meshes, double distance_epsilon) { +VertexMapping create_mapping( + const std::span> meshes, + double distance_epsilon, + const bool only_consider_boundary) { // auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); auto map = construct_grid_for_meshes(meshes); auto deduplicate = EpsilonVertexDeduplicate(map, distance_epsilon); LOG_TRACE("Creating merge mapping with epsilon = {}", distance_epsilon); - const VertexMapping mapping = create_mapping(meshes, deduplicate); + const VertexMapping mapping = create_mapping(meshes, deduplicate, only_consider_boundary); validate_epsilon_mapping(mapping, meshes, distance_epsilon); return mapping; } -VertexMapping create_mapping(const std::span> meshes, VertexDeduplicate<3, double, VertexId> &deduplicate) { +VertexMapping create_mapping( + const std::span> meshes, + VertexDeduplicate<3, double, VertexId> &deduplicate, + const bool only_consider_boundary +) { if (meshes.empty()) { return {}; } @@ -90,31 +99,69 @@ VertexMapping create_mapping(const std::span mesh_sizes; mesh_sizes.reserve(meshes.size()); std::transform(meshes.begin(), meshes.end(), - std::back_inserter(mesh_sizes), - [](const auto &mesh) { return mesh.get().vertex_count(); }); + std::back_inserter(mesh_sizes), + [](const auto &mesh) { return mesh.get().vertex_count(); }); const size_t maximal_merged_mesh_size = std::accumulate(mesh_sizes.begin(), mesh_sizes.end(), 0); + // Handle all meshes being empty + if (maximal_merged_mesh_size == 0) { + return {}; + } + + // Find the largest mesh and put it as the first element + const size_t index_of_largest_mesh = std::distance(mesh_sizes.begin(), std::max_element(mesh_sizes.begin(), mesh_sizes.end())); + std::vector> reordered; + if (index_of_largest_mesh != 0) { + std::copy(meshes.begin(), meshes.end(), std::back_inserter(reordered)); + std::swap(reordered[0], reordered[index_of_largest_mesh]); + // we dont need to swap mesh_sizes here since we use the original mesh indices for the mapping + // meshes = std::span(reordered); + } VertexMapping mapping; mapping.init(mesh_sizes); size_t unique_vertices = 0; - bool has_warned = false; auto add_unique_vertex = [&](const VertexId &vertex) { mapping.add_bidirectional(vertex, unique_vertices); unique_vertices += 1; }; + + // Init a reusable set of containers for the boundary + std::unordered_set boundary_edges; + std::vector is_boundary_vertex; + + // Reusable vector for duplicate vertices std::vector> duplicate_vertices; + + bool has_warned = false; // Flag to only print the intra-mesh merge warning once for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { const SimpleMesh &mesh = meshes[mesh_index]; + + if (only_consider_boundary) { + // Find boundary edges + boundary_edges.clear(); + find_boundary_edges(mesh, boundary_edges); + + // Classify vertices as on the boundary or on the inside + is_boundary_vertex.resize(mesh.vertex_count()); + std::fill(is_boundary_vertex.begin(), is_boundary_vertex.end(), false); + for (const auto& edge : boundary_edges) { + is_boundary_vertex[edge[0]] = true; + is_boundary_vertex[edge[1]] = true; + } + } + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const glm::dvec3 &position = mesh.positions[vertex_index]; const VertexId current_vertex{ .mesh_index = mesh_index, .vertex_index = vertex_index}; - if (mesh_index == 0) { - deduplicate.add(position, current_vertex); + if (only_consider_boundary && !is_boundary_vertex[vertex_index]) { + add_unique_vertex(current_vertex); + } else if (mesh_index == 0) { add_unique_vertex(current_vertex); + deduplicate.add(position, current_vertex); } else if (!deduplicate.get_or_add(position, current_vertex, duplicate_vertices)) { // Duplicates detected std::optional> nearest_duplicate; @@ -155,6 +202,7 @@ VertexMapping create_mapping(const std::span> meshes, const VertexMapping &mapping) { +SimpleMesh apply_mapping( + const std::span> meshes, + const VertexMapping &mapping, + const bool deduplicate_triangles, // TODO: automatically set to false when only considering boundary + const bool merge_uvs +) { LOG_TRACE("Merging meshes based on mapping"); if (meshes.empty()) { return {}; @@ -360,33 +413,31 @@ SimpleMesh apply_mapping(const std::span written(max_combined_vertex_count, false); -#endif + const bool has_uvs = merge_uvs && std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { + return mesh.has_uvs(); + }); size_t max_vertex_index = 0; merged_mesh.positions.resize(max_combined_vertex_count); + if (has_uvs) { + merged_mesh.uvs.resize(max_combined_vertex_count); + } for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { const SimpleMesh &mesh = meshes[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { const size_t mapped_index = mapping.map_forward(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); - const glm::dvec3 position = mesh.positions[vertex_index]; -#ifndef NDEBUG - if (written[mapped_index]) { - const glm::dvec3 &old = merged_mesh.positions[mapped_index]; - const double dist2 = glm::distance2(position, old); - DEBUG_ASSERT(dist2 <= distance_epsilon * distance_epsilon); - } else { - written[mapped_index] = true; + merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; + if (has_uvs) { + merged_mesh.uvs[mapped_index] = mesh.uvs[vertex_index]; } -#endif - merged_mesh.positions[mapped_index] = position; max_vertex_index = std::max(max_vertex_index, mapped_index); } } DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); merged_mesh.positions.resize(max_vertex_index + 1); + if (has_uvs) { + merged_mesh.uvs.resize(max_vertex_index + 1); + } merged_mesh.triangles.reserve(max_combined_face_count); for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { @@ -405,13 +456,23 @@ SimpleMesh apply_mapping(const std::span meshes); +// TODO: add option structs VertexMapping create_mapping( const std::span> meshes); VertexMapping create_mapping( const std::span> meshes, - double distance_epsilon); + const double distance_epsilon, + const bool only_consider_boundary = false); VertexMapping create_mapping( std::span> meshes, - VertexDeduplicate<3, double, VertexId>& deduplicate); + VertexDeduplicate<3, double, VertexId>& deduplicate, + const bool only_consider_boundary = false); SimpleMesh apply_mapping( const std::span> meshes, - const VertexMapping &mapping); + const VertexMapping &mapping, + const bool deduplicate_triangles = true, + const bool merge_uvs = true +); } // namespace mesh::merging diff --git a/unittests/terrainlib/mesh_merge.cpp b/unittests/terrainlib/mesh_merge.cpp index b42e2b2..d6bcf7d 100644 --- a/unittests/terrainlib/mesh_merge.cpp +++ b/unittests/terrainlib/mesh_merge.cpp @@ -117,7 +117,9 @@ TEST_CASE("mesh::merge") { mesh2.triangles.push_back(glm::uvec3(0, 2, 1)); mesh2.triangles.push_back(glm::uvec3(1, 2, 3)); - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); + const bool only_boundary = GENERATE(true, false); + CAPTURE(only_boundary); + SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1, only_boundary); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -159,8 +161,6 @@ TEST_CASE("mesh::merge") { CHECK(mesh1.triangles == actual.triangles); } - /* - TODO: this currently fails since we dont deduplicate the triangles SECTION("identical meshes collapse to one") { SimpleMesh mesh1; mesh1.positions = { @@ -175,7 +175,7 @@ TEST_CASE("mesh::merge") { CHECK(actual.positions == mesh1.positions); CHECK(actual.triangles == mesh1.triangles); - }*/ + } SECTION("epsilon too small prevents merging") { SimpleMesh mesh1; diff --git a/unittests/terrainlib/mesh_merge_mapping.cpp b/unittests/terrainlib/mesh_merge_mapping.cpp index 26a3e6b..d112ae4 100644 --- a/unittests/terrainlib/mesh_merge_mapping.cpp +++ b/unittests/terrainlib/mesh_merge_mapping.cpp @@ -22,13 +22,13 @@ #include "../catch2_helpers.h" #include "mesh/SimpleMesh.h" +#include "mesh/merging/SphereProjectionVertexDeduplicate.h" +#include "mesh/merging/helpers.h" #include "mesh/merging/mapping.h" #include "spatial_lookup/CellBasedStorage.h" #include "spatial_lookup/GridStorage.h" -#include "spatial_lookup/HashmapStorage.h" -#include "mesh/merging/SphereVertexDeduplicate.h" -#include "mesh/merging/helpers.h" #include "spatial_lookup/Hashmap.h" +#include "spatial_lookup/HashmapStorage.h" using mesh::merging::VertexId; using mesh::merging::VertexMapping; @@ -43,7 +43,7 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); const size_t idx1 = mapping.map_forward(VertexId{0, 0}); const size_t idx2 = mapping.map_forward(VertexId{1, 0}); @@ -63,7 +63,7 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); // Merged index of (1, 0, 0) should be the same for both meshes const size_t idx1 = mapping.map_forward(VertexId{0, 2}); @@ -94,8 +94,8 @@ TEST_CASE("merging::create_mapping") { mesh2.positions.push_back(glm::dvec3(2, 0, 0)); const std::array, 2> meshes = {mesh1, mesh2}; - - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); const size_t idx1 = mapping.map_forward(VertexId{0, 1}); // (1, 0, 0) const size_t idx2 = mapping.map_forward(VertexId{1, 0}); // (1.05, 0, 0) @@ -157,7 +157,9 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const bool only_boundary = GENERATE(true, false); + CAPTURE(only_boundary); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, only_boundary); CHECK(mapping.map_forward(VertexId{0, 0}) == mapping.map_forward(VertexId{1, 0})); CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); @@ -181,7 +183,9 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); + const bool only_boundary = GENERATE(true, false); + CAPTURE(only_boundary); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, only_boundary); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 2})); CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); @@ -206,12 +210,16 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; const double distance_epsilon = 0.001; auto map = spatial_lookup::Hashmap3d(0.1); - const double radius = 100; - mesh::merging::SphereVertexDeduplicate< + + const bool only_boundary = GENERATE(true, false); + CAPTURE(only_boundary); + const double radius = GENERATE(1, 100, 1000); + CAPTURE(radius); + mesh::merging::SphereProjectionVertexDeduplicate< mesh::merging::VertexId, - decltype(map) - > deduplicate(map, distance_epsilon, radius); - const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate); + decltype(map)> + deduplicate(map, distance_epsilon, radius); + const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate, only_boundary); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 0})); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 1})); From 1421ef1eaa0972c6d760be77352fc8fded99bc38 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 21 Aug 2025 16:09:49 +0200 Subject: [PATCH 111/122] Refactoring and fixes --- src/CMakeLists.txt | 3 +- src/terrainlib/mesh/clip.cpp | 2 - src/terrainlib/mesh/merge.cpp | 43 ------------------- src/terrainlib/mesh/merge.h | 23 +++++++--- ....h => SphereProjectionVertexDeduplicate.h} | 4 +- .../mesh/merging/SphereVertexDeduplicate2.h | 32 -------------- src/terrainlib/polygon/triangulate.cpp | 1 + src/terrainmerger/merge/visitor/Masked.h | 9 ++-- 8 files changed, 27 insertions(+), 90 deletions(-) delete mode 100644 src/terrainlib/mesh/merge.cpp rename src/terrainlib/mesh/merging/{SphereVertexDeduplicate.h => SphereProjectionVertexDeduplicate.h} (87%) delete mode 100644 src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ea37db..b00a2f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -126,9 +126,10 @@ add_library(terrainlib terrainlib/mesh/convert.h terrainlib/mesh/convert.cpp terrainlib/mesh/holes.h terrainlib/mesh/holes.cpp terrainlib/mesh/io.h terrainlib/mesh/io.cpp - terrainlib/mesh/merge.h terrainlib/mesh/merge.cpp + terrainlib/mesh/merge.h terrainlib/mesh/merging/VertexDeduplicate.h terrainlib/mesh/merging/EpsilonVertexDeduplicate.h + terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h terrainlib/mesh/merging/VertexMapping.h terrainlib/mesh/merging/mapping.h terrainlib/mesh/merging/mapping.cpp terrainlib/mesh/SimpleMesh.h diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index 8860f4f..cad3b2b 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -441,8 +441,6 @@ Cow mesh::clip_on_bounds_and_cap(const SimpleMesh &mesh, const if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); } - LOG_TRACE("Clip result: original {} faces -> clipped {} faces. Intersections: {}", - mesh.face_count(), cgal_mesh.number_of_faces(), visitor.has_intersections); if (cgal_mesh.number_of_faces() == 0) { return Cow(SimpleMesh()); } diff --git a/src/terrainlib/mesh/merge.cpp b/src/terrainlib/mesh/merge.cpp deleted file mode 100644 index 17be55a..0000000 --- a/src/terrainlib/mesh/merge.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "mesh/merge.h" -#include "mesh/merging/mapping.h" -#include "mesh/merging/VertexMapping.h" - -namespace mesh { - -SimpleMesh merge(const std::span> meshes) { - switch (meshes.size()) { - case 0: - return {}; - case 1: - return meshes[0]; - default: - const merging::VertexMapping mapping = merging::create_mapping(meshes); - return merging::apply_mapping(meshes, mapping); - } -} - -SimpleMesh merge(const std::span> meshes, double distance_epsilon) { - switch (meshes.size()) { - case 0: - return {}; - case 1: - return meshes[0]; - default: - const merging::VertexMapping mapping = merging::create_mapping(meshes, distance_epsilon); - return merging::apply_mapping(meshes, mapping); - } -} - -SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate) { - switch (meshes.size()) { - case 0: - return {}; - case 1: - return meshes[0]; - default: - const merging::VertexMapping mapping = merging::create_mapping(meshes, deduplicate); - return merging::apply_mapping(meshes, mapping); - } -} - -} // namespace mesh diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 5b39291..0fcd091 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -1,19 +1,30 @@ #pragma once -#include #include -#include #include +#include +#include -#include "mesh/merging/VertexDeduplicate.h" #include "mesh/merging/VertexMapping.h" +#include "mesh/merging/mapping.h" #include "pch.h" namespace mesh { -SimpleMesh merge(const std::span> meshes); -SimpleMesh merge(const std::span> meshes, double distance_epsilon); -SimpleMesh merge(const std::span> meshes, merging::VertexDeduplicate<3, double, merging::VertexId> &deduplicate); +template +SimpleMesh merge(std::span> meshes, + Args &&...args) { + switch (meshes.size()) { + case 0: + return {}; + case 1: + return meshes[0]; + default: + const merging::VertexMapping mapping = + merging::create_mapping(meshes, std::forward(args)...); + return merging::apply_mapping(meshes, mapping); + } +} template SimpleMesh merge(const std::span meshes, Args &&...args) { diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h b/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h similarity index 87% rename from src/terrainlib/mesh/merging/SphereVertexDeduplicate.h rename to src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h index e52ce24..17930ee 100644 --- a/src/terrainlib/mesh/merging/SphereVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h @@ -18,11 +18,11 @@ glm::vec scale_to_length(const glm::vec &v, const T target } template Lookup> -class SphereVertexDeduplicate : public VertexDeduplicate<3, double, Meta> { +class SphereProjectionVertexDeduplicate : public VertexDeduplicate<3, double, Meta> { public: using Vec = glm::vec<3, double>; - SphereVertexDeduplicate(Lookup &lookup, double epsilon, double radius) + SphereProjectionVertexDeduplicate(Lookup &lookup, double epsilon, double radius) : _inner(lookup, epsilon), _radius(radius) {} void add(const Vec &point, const Meta meta) override { diff --git a/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h b/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h deleted file mode 100644 index 6d737ea..0000000 --- a/src/terrainlib/mesh/merging/SphereVertexDeduplicate2.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "mesh/merging/EpsilonVertexDeduplicate.h" -#include "mesh/merging/VertexDeduplicate.h" -#include "spatial_lookup/SpatialLookup.h" - -namespace mesh::merging { - -template Lookup> -class SphereVertexDeduplicate2 : public VertexDeduplicate<3, double, Meta> { -public: - using Vec = glm::vec<3, double>; - using MappedVec = glm::vec<2, double>; - - SphereVertexDeduplicate2(Lookup &lookup, double epsilon, Vec tangent_point) - : _inner(lookup, epsilon), _projector(tangent_point) {} - - void add(const Vec &point, const Meta meta) override { - const MappedVec mapped = this->_projector.project_point(point); - this->_inner.add(mapped, meta); - } - bool get(const Vec &point, std::vector> &duplicates) const override { - const MappedVec mapped = this->_projector.project_point(point); - return this->_inner.get(mapped, duplicates); - } - -private: - EpsilonVertexDeduplicate<2, double, Meta, Lookup> _inner; - SphereProjector _projector; -}; - -} diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp index 4d42008..bda45d4 100644 --- a/src/terrainlib/polygon/triangulate.cpp +++ b/src/terrainlib/polygon/triangulate.cpp @@ -11,6 +11,7 @@ #include "mesh/cgal.h" #include "mesh/convert.h" +#include "polygon/utils.h" using Kernel = cgal::kernel::epeck::Kernel; using Point2 = Kernel::Point_2; diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 2b429cb..74c3fde 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -5,7 +5,7 @@ #include "merge/Result.h" #include "merge/visitor/Visitor.h" #include "mesh/holes.h" -#include "mesh/merging/SphereVertexDeduplicate.h" +#include "mesh/merging/SphereProjectionVertexDeduplicate.h" #include "mesh/merging/VertexMapping.h" #include "mesh/merging/helpers.h" #include "mesh/merging/mapping.h" @@ -176,14 +176,15 @@ class Masked { // We have to use a hashmap here instead of a grid since we dont know // the bounds of the mesh projected onto the sphere with the deduplication radius. spatial_lookup::Hashmap3d map(distance_epsilon * 3); + // Deduplication happens by projecting all points onto a sphere and performing epsilon checks there const glm::dvec3 tangent_point = meshes[0].get().positions[0]; const double radius = glm::length(tangent_point); - mesh::merging::SphereVertexDeduplicate< + mesh::merging::SphereProjectionVertexDeduplicate< mesh::merging::VertexId, decltype(map) > deduplicate(map, distance_epsilon, radius); - const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate); - SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping); + const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate, true); + SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, false, false); LOG_TRACE("Filling holes on merge border"); mesh::fill_holes_on_merge_border(merged_mesh, mapping); return Merged{merged_mesh}; From db31f9039285988f5669664fe2d99ee95757c350 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 21 Aug 2025 19:45:38 +0200 Subject: [PATCH 112/122] Refactor merging api --- src/terrainlib/mesh/merge.h | 13 +- .../mesh/merging/EpsilonVertexDeduplicate.h | 17 +- .../SphereProjectionVertexDeduplicate.h | 4 +- src/terrainlib/mesh/merging/helpers.h | 12 ++ src/terrainlib/mesh/merging/mapping.cpp | 49 +++--- src/terrainlib/mesh/merging/mapping.h | 147 ++++++++++++++++-- src/terrainlib/spatial_lookup/CellBased.h | 10 +- src/terrainmerger/merge/visitor/Masked.h | 6 +- 8 files changed, 196 insertions(+), 62 deletions(-) diff --git a/src/terrainlib/mesh/merge.h b/src/terrainlib/mesh/merge.h index 0fcd091..9ae3865 100644 --- a/src/terrainlib/mesh/merge.h +++ b/src/terrainlib/mesh/merge.h @@ -11,18 +11,19 @@ namespace mesh { -template -SimpleMesh merge(std::span> meshes, - Args &&...args) { +template +SimpleMesh merge( + const std::span> meshes, + const merging::CreateOptions create_options = merging::create_options(), + const merging::ApplyOptions apply_options = merging::apply_options()) { switch (meshes.size()) { case 0: return {}; case 1: return meshes[0]; default: - const merging::VertexMapping mapping = - merging::create_mapping(meshes, std::forward(args)...); - return merging::apply_mapping(meshes, mapping); + const merging::VertexMapping mapping = merging::create_mapping(meshes, create_options); + return merging::apply_mapping(meshes, mapping, apply_options); } } diff --git a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h index 3c9899e..5742756 100644 --- a/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/EpsilonVertexDeduplicate.h @@ -12,8 +12,8 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate; - EpsilonVertexDeduplicate(Lookup &lookup, Component epsilon) - : _lookup(lookup), + EpsilonVertexDeduplicate(Lookup lookup, Component epsilon) + : _lookup(std::move(lookup)), _epsilon(epsilon) {} Component epsilon() const { @@ -27,14 +27,15 @@ class EpsilonVertexDeduplicate : public VertexDeduplicate class CellBased, - typename EpsilonType> -EpsilonVertexDeduplicate(CellBased &lookup, EpsilonType epsilon) - -> EpsilonVertexDeduplicate>; +template +EpsilonVertexDeduplicate(L lookup, C epsilon) + -> EpsilonVertexDeduplicate; } diff --git a/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h b/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h index 17930ee..cf36360 100644 --- a/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h +++ b/src/terrainlib/mesh/merging/SphereProjectionVertexDeduplicate.h @@ -22,8 +22,8 @@ class SphereProjectionVertexDeduplicate : public VertexDeduplicate<3, double, Me public: using Vec = glm::vec<3, double>; - SphereProjectionVertexDeduplicate(Lookup &lookup, double epsilon, double radius) - : _inner(lookup, epsilon), _radius(radius) {} + SphereProjectionVertexDeduplicate(Lookup lookup, double epsilon, double radius) + : _inner(std::move(lookup), epsilon), _radius(radius) {} void add(const Vec &point, const Meta meta) override { const Vec mapped = scale_to_length(point, this->_radius); diff --git a/src/terrainlib/mesh/merging/helpers.h b/src/terrainlib/mesh/merging/helpers.h index 653e398..2fb12d4 100644 --- a/src/terrainlib/mesh/merging/helpers.h +++ b/src/terrainlib/mesh/merging/helpers.h @@ -6,6 +6,8 @@ #include "mesh/SimpleMesh.h" #include "mesh/utils.h" #include "spatial_lookup/Grid.h" +#include "mesh/merging/EpsilonVertexDeduplicate.h" +#include "mesh/merging/VertexMapping.h" namespace mesh::merging { @@ -62,4 +64,14 @@ spatial_lookup::Grid3d construct_grid_for_meshes(const std::span(bounds, maximal_merged_mesh_size); } +inline auto make_epsilon_deduplicate(const std::span> meshes, const double epsilon) { + spatial_lookup::Grid3d map = construct_grid_for_meshes(meshes); + return EpsilonVertexDeduplicate(std::move(map), epsilon); +} + +inline auto make_default_deduplicate(const std::span> meshes) { + const double epsilon = estimate_merge_epsilon(meshes); + return make_epsilon_deduplicate(meshes, epsilon); +} + } // namespace mesh::merging diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index 16783b2..cfd5a21 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -19,18 +19,7 @@ #include "spatial_lookup/Hashmap.h" #include "type_utils.h" -namespace mesh::merging { - -VertexMapping create_mapping(const std::span> meshes) { - if (meshes.empty()) { - return {}; - } - - const double distance_epsilon = estimate_merge_epsilon(meshes); - return create_mapping(meshes, distance_epsilon); -} - -namespace { +namespace mesh::merging::detail { void validate_epsilon_mapping( const VertexMapping &mapping, const std::span> meshes, @@ -63,26 +52,14 @@ void validate_epsilon_mapping( } #endif } -} // namespace - -VertexMapping create_mapping( - const std::span> meshes, - double distance_epsilon, - const bool only_consider_boundary) { - // auto map = spatial_lookup::Hashmap3d(distance_epsilon * 3); - auto map = construct_grid_for_meshes(meshes); - auto deduplicate = EpsilonVertexDeduplicate(map, distance_epsilon); - LOG_TRACE("Creating merge mapping with epsilon = {}", distance_epsilon); - const VertexMapping mapping = create_mapping(meshes, deduplicate, only_consider_boundary); - validate_epsilon_mapping(mapping, meshes, distance_epsilon); - return mapping; -} VertexMapping create_mapping( const std::span> meshes, - VertexDeduplicate<3, double, VertexId> &deduplicate, - const bool only_consider_boundary + const ResolvedCreateOptions options ) { + VertexDeduplicate<3, double, VertexId> &deduplicate = options.deduplicate; + const bool only_consider_boundary = options.only_consider_boundary; + if (meshes.empty()) { return {}; } @@ -200,6 +177,15 @@ VertexMapping create_mapping( LOG_DEBUG("Identified {} shared and {} unique vertices", maximal_merged_mesh_size - unique_vertices, unique_vertices); mapping.validate(); +#ifndef NDEBUG + using DefaultEpsilonDeduplicate = EpsilonVertexDeduplicate<3, double, VertexId, spatial_lookup::Grid3d>; + const auto *epsilon_deduplicate = dynamic_cast(&deduplicate); + if (epsilon_deduplicate != nullptr) { + const double epsilon = epsilon_deduplicate->epsilon(); + validate_epsilon_mapping(mapping, meshes, epsilon); + } +#endif + return mapping; } @@ -391,9 +377,11 @@ VertexMapping create_connecting_mapping(std::span> meshes, const VertexMapping &mapping, - const bool deduplicate_triangles, // TODO: automatically set to false when only considering boundary - const bool merge_uvs + const ResolvedApplyOptions options ) { + const bool deduplicate_triangles = options.deduplicate_triangles; + const bool merge_uvs = options.merge_uvs; + LOG_TRACE("Merging meshes based on mapping"); if (meshes.empty()) { return {}; @@ -463,6 +451,7 @@ SimpleMesh apply_mapping( [&](const size_t i) { return mapping.find_source_triangle_in_mesh(new_triangle, i).has_value(); }); if (!is_first_mesh) { + LOG_WARN("Skipping duplicate triangle while merging"); continue; } } diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 5cbe4de..84e4ce1 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -11,23 +11,146 @@ namespace mesh::merging { // VertexMapping create_connecting_mapping(std::span meshes); -// TODO: add option structs -VertexMapping create_mapping( - const std::span> meshes); +namespace detail { +struct ResolvedCreateOptions { + bool only_consider_boundary; + VertexDeduplicate<3, double, VertexId>& deduplicate; +}; + VertexMapping create_mapping( + std::span> meshes, + const ResolvedCreateOptions options); + +struct ResolvedApplyOptions { + bool deduplicate_triangles; + bool merge_uvs; +}; + +SimpleMesh apply_mapping( const std::span> meshes, - const double distance_epsilon, - const bool only_consider_boundary = false); + const VertexMapping &mapping, + const ResolvedApplyOptions options); +} + +struct EstimateEpsilon {}; +struct ProvidedEpsilon { + double value; +}; +struct ProvidedDeduplicate { + VertexDeduplicate<3, double, VertexId>& deduplicate; +}; + +template +struct CreateOptions { +private: + bool _only_consider_boundary = false; + Mode _mode{}; + +public: + template >> + static CreateOptions defaults() { + return {}; + } + + template >> + auto epsilon(const double epsilon) { + return CreateOptions{this->_only_consider_boundary, ProvidedEpsilon{epsilon}}; + } + + template >> + auto deduplicate(VertexDeduplicate<3, double, VertexId> &deduplicate) { + return CreateOptions{this->_only_consider_boundary, ProvidedDeduplicate{deduplicate}}; + } + + bool get_only_consider_boundary() const { + return this->_only_consider_boundary; + } + auto &only_consider_boundary(const bool value) { + this->_only_consider_boundary = value; + return *this; + } + + Mode get_mode() const { + return this->_mode; + } + +private: + // Private constructor for mode transitions + CreateOptions() = default; + CreateOptions(bool only_consider_boundary, Mode mode) : _only_consider_boundary(only_consider_boundary), _mode(mode) {} + friend struct CreateOptions; +}; + +inline CreateOptions create_options() { + return CreateOptions::defaults(); +} + +template VertexMapping create_mapping( - std::span> meshes, - VertexDeduplicate<3, double, VertexId>& deduplicate, - const bool only_consider_boundary = false); + const std::span> meshes, + const CreateOptions options = create_options()) { + switch (meshes.size()) { + case 0: + return {}; + case 1: + return VertexMapping::identity(meshes[0].get().vertex_count()); + default: + if constexpr (std::is_same_v) { + auto deduplicate = make_default_deduplicate(meshes); + LOG_TRACE("Creating merge mapping with default epsilon = {}", deduplicate.epsilon()); + return detail::create_mapping(meshes, {options.get_only_consider_boundary(), deduplicate}); + } else if constexpr (std::is_same_v) { + const double epsilon = options.get_mode().value; + LOG_TRACE("Creating merge mapping with epsilon = {}", epsilon); + auto deduplicate = make_epsilon_deduplicate(meshes, epsilon); + return detail::create_mapping(meshes, {options.get_only_consider_boundary(), deduplicate}); + } else if constexpr (std::is_same_v) { + return detail::create_mapping(meshes, {options.get_only_consider_boundary(), options.get_mode().deduplicate}); + } else { + UNREACHABLE(); + } + } +} -SimpleMesh apply_mapping( +struct ApplyOptions { +public: + static ApplyOptions defaults() { + return {}; + } + + bool get_deduplicate_triangles() const { + return this->_deduplicate_triangles; + } + ApplyOptions &deduplicate_triangles(const bool value) { + this->_deduplicate_triangles = value; + return *this; + } + + bool get_merge_uvs() const { + return this->_merge_uvs; + } + ApplyOptions &merge_uvs(const bool value) { + this->_merge_uvs = value; + return *this; + } + +private: + bool _deduplicate_triangles = true; + bool _merge_uvs = true; +}; + +inline ApplyOptions apply_options() { + return ApplyOptions::defaults(); +} + +inline SimpleMesh apply_mapping( const std::span> meshes, const VertexMapping &mapping, - const bool deduplicate_triangles = true, - const bool merge_uvs = true -); + const ApplyOptions options = apply_options()) { + return detail::apply_mapping(meshes, mapping, detail::ResolvedApplyOptions { + .deduplicate_triangles = options.get_deduplicate_triangles(), + .merge_uvs = options.get_merge_uvs() + }); +} } // namespace mesh::merging diff --git a/src/terrainlib/spatial_lookup/CellBased.h b/src/terrainlib/spatial_lookup/CellBased.h index 7df510a..7923454 100644 --- a/src/terrainlib/spatial_lookup/CellBased.h +++ b/src/terrainlib/spatial_lookup/CellBased.h @@ -35,7 +35,10 @@ std::optional> _find_neare const typename SpatialLookup::Vec &point, const Distance epsilon) { using Vec = SpatialLookup::Vec; - using Value = SpatialLookup::Value; + using Value = std::conditional_t< + std::is_const_v, + const typename SpatialLookup::Value, + typename SpatialLookup::Value>; Distance closest_distance2 = std::numeric_limits::max(); Value *closest_value = nullptr; @@ -60,7 +63,10 @@ bool _find_all_near( const Distance epsilon, Vector &out) { using Vec = SpatialLookup::Vec; - using Value = SpatialLookup::Value; + using Value = std::conditional_t< + std::is_const_v, + const typename SpatialLookup::Value, + typename SpatialLookup::Value>; out.clear(); lookup.for_all_near(point, epsilon, [&](const Vec &, Value &value, Distance) { diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 74c3fde..c6db3c4 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -183,8 +183,10 @@ class Masked { mesh::merging::VertexId, decltype(map) > deduplicate(map, distance_epsilon, radius); - const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate, true); - SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, false, false); + const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().deduplicate(deduplicate).only_consider_boundary(true)); + SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, + mesh::merging::apply_options().deduplicate_triangles(false).merge_uvs(false)); LOG_TRACE("Filling holes on merge border"); mesh::fill_holes_on_merge_border(merged_mesh, mapping); return Merged{merged_mesh}; From 7bcb6cc608fd075bd0e85006909c929fef51473f Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Tue, 2 Sep 2025 20:23:08 +0200 Subject: [PATCH 113/122] Fix mesh textures (breaks hole filling) --- src/CMakeLists.txt | 11 +- src/mesh_merger/cli.cpp | 3 +- src/terrainlib/mesh/SimpleMesh.h | 2 + src/terrainlib/mesh/boolean.cpp | 10 +- src/terrainlib/mesh/cgal.h | 14 +- src/terrainlib/mesh/clip.cpp | 18 +- src/terrainlib/mesh/combine.h | 70 ++++++ src/terrainlib/mesh/convert.cpp | 12 +- src/terrainlib/mesh/convert.h | 4 +- src/terrainlib/mesh/holes.cpp | 189 +++++++++++++-- src/terrainlib/mesh/holes.h | 4 + src/terrainlib/mesh/merging/VertexId.h | 22 ++ src/terrainlib/mesh/merging/VertexMapping.h | 8 +- src/terrainlib/mesh/merging/mapping.cpp | 2 +- src/terrainlib/mesh/merging/mapping.h | 4 +- src/terrainlib/mesh/utils.inl | 1 + src/terrainlib/mesh/uv_map.cpp | 212 +++++++++++++++++ src/terrainlib/mesh/uv_map.h | 82 +++++++ src/terrainlib/octree/storage/RawStorage.cpp | 39 ---- src/terrainlib/polygon/triangulate.cpp | 4 + src/terrainmerger/mask.h | 4 +- src/terrainmerger/merge/visitor/Masked.h | 231 ++++++++++++++++++- unittests/terrainlib/convert.cpp | 2 +- 23 files changed, 846 insertions(+), 102 deletions(-) create mode 100644 src/terrainlib/mesh/combine.h create mode 100644 src/terrainlib/mesh/merging/VertexId.h create mode 100644 src/terrainlib/mesh/uv_map.cpp create mode 100644 src/terrainlib/mesh/uv_map.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b00a2f1..9cb61de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,6 +65,12 @@ alp_add_git_repository(libassert URL https://github.com/jeremy-rifkin/libassert. alp_add_git_repository(magic_enum URL https://github.com/Neargye/magic_enum.git COMMITISH v0.9.7) alp_add_git_repository(ftxui URL https://github.com/ArthurSonzogni/FTXUI COMMITISH v6.1.9) + +alp_add_git_repository(xatlas URL https://github.com/Korinin38/xatlas_hi-res_optimised COMMITISH 67f364cbcec67b586130c61c90f64192fad44fd2 DO_NOT_ADD_SUBPROJECT) +# alp_add_git_repository(xatlas URL https://github.com/jpcy/xatlas COMMITISH f700c7790aaa030e794b52ba7791a05c085faf0c DO_NOT_ADD_SUBPROJECT) +add_library(xatlas STATIC ${xatlas_SOURCE_DIR}/source/xatlas/xatlas.cpp) +target_include_directories(xatlas PUBLIC ${xatlas_SOURCE_DIR}/source) + alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) # Don't build glfw docs, tests and examples @@ -135,6 +141,7 @@ add_library(terrainlib terrainlib/mesh/SimpleMesh.h terrainlib/mesh/TriangleSoup.h terrainlib/mesh/utils.h terrainlib/mesh/utils.cpp + terrainlib/mesh/uv_map.h terrainlib/mesh/uv_map.cpp terrainlib/mesh/validate.h terrainlib/octree/disk/layout/strategy/Default.h @@ -183,7 +190,7 @@ add_library(terrainlib terrainlib/string_utils.h ) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert magic_enum::magic_enum) +target_link_libraries(terrainlib PUBLIC radix ZLIB::ZLIB CGAL::CGAL Eigen3 GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert magic_enum::magic_enum) if(ALP_ENABLE_OVERVIEW_READING) target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) @@ -229,7 +236,7 @@ add_library(terrainmergerlib terrainmerger/utils.h ) target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) -target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) +target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected xatlas) add_executable(terrainmerger terrainmerger/main.cpp terrainmerger/cli.h terrainmerger/cli.cpp diff --git a/src/mesh_merger/cli.cpp b/src/mesh_merger/cli.cpp index b0804c4..c14e706 100644 --- a/src/mesh_merger/cli.cpp +++ b/src/mesh_merger/cli.cpp @@ -38,7 +38,8 @@ Args cli::parse(int argc, const char * const * argv) { ->default_val(spdlog::level::level_enum::info); try { - app.parse(argc, argv); + // app.parse(argc, argv); + app.parse("--input /home/user/master/meshes/out-cut/13/6481/4795/6854.glb /home/user/master/meshes/out-cut/13/6481/4794/6854.glb --output /home/user/master/meshes/test_merge.glb --epsilon 0.00001"); } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/terrainlib/mesh/SimpleMesh.h b/src/terrainlib/mesh/SimpleMesh.h index 7807ce3..0c37211 100644 --- a/src/terrainlib/mesh/SimpleMesh.h +++ b/src/terrainlib/mesh/SimpleMesh.h @@ -10,6 +10,8 @@ template class SimpleMesh_ { public: + static constexpr glm::length_t n_dims = dimensions; + using Component = T; using Triangle = glm::uvec3; using Edge = glm::uvec2; using Position = glm::vec; diff --git a/src/terrainlib/mesh/boolean.cpp b/src/terrainlib/mesh/boolean.cpp index 5704b8d..4d51449 100644 --- a/src/terrainlib/mesh/boolean.cpp +++ b/src/terrainlib/mesh/boolean.cpp @@ -12,12 +12,12 @@ IntersectionAndDifference intersection_and_difference(const SimpleMesh &a, const ASSERT(!a.has_uvs()); ASSERT(!b.has_uvs()); - cgal::SurfaceMesh cgal_a = convert::to_cgal_mesh(a); - cgal::SurfaceMesh cgal_b = convert::to_cgal_mesh(b); + cgal::Mesh cgal_a = convert::to_cgal_mesh(a); + cgal::Mesh cgal_b = convert::to_cgal_mesh(b); - cgal::SurfaceMesh cgal_intersection; - cgal::SurfaceMesh cgal_difference; - std::array, 4> cgal_out; + cgal::Mesh cgal_intersection; + cgal::Mesh cgal_difference; + std::array, 4> cgal_out; const size_t intersection_index = CGAL::Polygon_mesh_processing::Corefinement::Boolean_operation_type::INTERSECTION; const size_t difference_index = CGAL::Polygon_mesh_processing::Corefinement::Boolean_operation_type::TM1_MINUS_TM2; cgal_out[intersection_index] = &cgal_intersection; diff --git a/src/terrainlib/mesh/cgal.h b/src/terrainlib/mesh/cgal.h index 1125cf0..492442c 100644 --- a/src/terrainlib/mesh/cgal.h +++ b/src/terrainlib/mesh/cgal.h @@ -10,13 +10,13 @@ namespace cgal { using Kernel = K; \ using Point2 = Kernel::Point_2; \ using Point3 = Kernel::Point_3; \ - using SurfaceMesh = CGAL::Surface_mesh; \ - using VertexIndex = SurfaceMesh::Vertex_index; \ - using FaceIndex = SurfaceMesh::Face_index; \ - using VertexDescriptor = boost::graph_traits::vertex_descriptor; \ - using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; \ - using EdgeDescriptor = boost::graph_traits::edge_descriptor; \ - using FaceDescriptor = boost::graph_traits::face_descriptor; + using Mesh = CGAL::Surface_mesh; \ + using VertexIndex = Mesh::Vertex_index; \ + using FaceIndex = Mesh::Face_index; \ + using VertexDescriptor = boost::graph_traits::vertex_descriptor; \ + using HalfedgeDescriptor = boost::graph_traits::halfedge_descriptor; \ + using EdgeDescriptor = boost::graph_traits::edge_descriptor; \ + using FaceDescriptor = boost::graph_traits::face_descriptor; namespace kernel { namespace epick { diff --git a/src/terrainlib/mesh/clip.cpp b/src/terrainlib/mesh/clip.cpp index cad3b2b..cb83462 100644 --- a/src/terrainlib/mesh/clip.cpp +++ b/src/terrainlib/mesh/clip.cpp @@ -428,15 +428,15 @@ struct HasIntersectionsVisitor : public CGAL::Polygon_mesh_processing::Corefinem Cow mesh::clip_on_bounds_and_cap(const SimpleMesh &mesh, const radix::geometry::Aabb3d &bounds, const bool remesh_planar_patches) { ASSERT(!mesh.has_uvs()); - cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); + cgal::Mesh cgal_mesh = convert::to_cgal_mesh(mesh); const CGAL::Iso_cuboid_3 cgal_bounds( convert::to_cgal_point(bounds.min), convert::to_cgal_point(bounds.max)); - HasIntersectionsVisitor visitor; + HasIntersectionsVisitor visitor; const auto clip_params = CGAL::Polygon_mesh_processing::parameters::clip_volume(true) .visitor(visitor); - cgal::SurfaceMesh result_cgal_mesh; + cgal::Mesh result_cgal_mesh; const bool success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_bounds, clip_params); if (!success) { throw std::runtime_error("CGAL::Polygon_mesh_processing::clip failed"); @@ -454,7 +454,7 @@ Cow mesh::clip_on_bounds_and_cap(const SimpleMesh &mesh, const return Cow(convert::to_simple_mesh(cgal_mesh)); } - cgal::SurfaceMesh remeshed_cgal_mesh; + cgal::Mesh remeshed_cgal_mesh; const auto remesh_params = CGAL::Polygon_mesh_processing::parameters::cosine_of_maximum_angle(0.999); CGAL::Polygon_mesh_processing::remesh_planar_patches(cgal_mesh, remeshed_cgal_mesh, remesh_params); remeshed_cgal_mesh.collect_garbage(); @@ -611,21 +611,21 @@ Cow mesh::clip_on_mesh(const SimpleMesh &mesh, const SimpleMes } // Convert both meshes to cgal and use their clipping logic. - using UvMap = cgal::SurfaceMesh::Property_map; + using UvMap = cgal::Mesh::Property_map; - cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mesh); - cgal::SurfaceMesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); + cgal::Mesh cgal_mesh = convert::to_cgal_mesh(mesh); + cgal::Mesh cgal_clip_mesh = convert::to_cgal_mesh(clip_mesh); bool success; bool has_intersections; if (mesh.has_uvs()) { UvMap uv_map = cgal_mesh.property_map("v:uv").value(); - UvInterpolatorVisitor visitor(uv_map, cgal_mesh); + UvInterpolatorVisitor visitor(uv_map, cgal_mesh); const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); has_intersections = !visitor.intersections.empty(); } else { - HasIntersectionsVisitor visitor; + HasIntersectionsVisitor visitor; const auto params = CGAL::Polygon_mesh_processing::parameters::visitor(visitor); success = CGAL::Polygon_mesh_processing::clip(cgal_mesh, cgal_clip_mesh, params); has_intersections = visitor.has_intersections; diff --git a/src/terrainlib/mesh/combine.h b/src/terrainlib/mesh/combine.h new file mode 100644 index 0000000..56e1a9a --- /dev/null +++ b/src/terrainlib/mesh/combine.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/merging/VertexMapping.h" + +namespace mesh { + +template +auto combine( + const MeshRange &meshes, + std::vector &vertex_offsets) { + using Mesh = std::remove_cvref_t>>; + using Uv = typename Mesh::Uv; + + size_t combined_vertex_count = 0; + size_t combined_triangle_count = 0; + for (const Mesh &mesh : meshes) { + combined_vertex_count += mesh.vertex_count(); + combined_triangle_count += mesh.face_count(); + } + + bool has_uvs = false; + for (const Mesh &mesh : meshes) { + if (mesh.has_uvs()) { + has_uvs = true; + break; + } + } + + Mesh result; + result.positions.reserve(combined_vertex_count); + result.triangles.reserve(combined_triangle_count); + if (has_uvs) { + result.uvs.reserve(combined_vertex_count); + } + + size_t vertex_offset = 0; + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const Mesh &mesh = meshes[mesh_index]; + result.positions.insert(result.positions.end(), mesh.positions.begin(), mesh.positions.end()); + + if (has_uvs) { + if (mesh.has_uvs()) { + result.uvs.insert(result.uvs.end(), mesh.uvs.begin(), mesh.uvs.end()); + } else { + result.uvs.insert(result.uvs.end(), mesh.vertex_count(), Uv(0)); + } + } + + for (const auto &triangle : mesh.triangles) { + result.triangles.push_back(triangle + static_cast(vertex_offset)); + } + + vertex_offsets.push_back(vertex_offset); + vertex_offset += mesh.vertex_count(); + } + + return result; +} + +template +auto combine(const MeshRange &meshes) { + std::vector vertex_offsets; + return combine(meshes, vertex_offsets); +} + +} diff --git a/src/terrainlib/mesh/convert.cpp b/src/terrainlib/mesh/convert.cpp index 806f998..2dd5ffa 100644 --- a/src/terrainlib/mesh/convert.cpp +++ b/src/terrainlib/mesh/convert.cpp @@ -6,10 +6,10 @@ using namespace cgal; -using UvMap = SurfaceMesh::Property_map; +using UvMap = Mesh::Property_map; -SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { - SurfaceMesh cgal_mesh; +Mesh convert::to_cgal_mesh(const SimpleMesh &mesh) { + Mesh cgal_mesh; const size_t approx_num_edges = (mesh.face_count() * 3) / 2; cgal_mesh.reserve(mesh.vertex_count(), approx_num_edges, mesh.face_count()); @@ -23,7 +23,7 @@ SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { for (size_t index = 0; index < mesh.positions.size(); ++index) { const glm::dvec3 &position = mesh.positions[index]; const cgal::VertexIndex vertex = cgal_mesh.add_vertex(to_cgal_point(position)); - DEBUG_ASSERT(vertex != SurfaceMesh::null_vertex()); + DEBUG_ASSERT(vertex != Mesh::null_vertex()); if (mesh.has_uvs()) { const glm::dvec2 &uv = mesh.uvs[index]; uv_map[vertex] = uv; @@ -35,13 +35,13 @@ SurfaceMesh convert::to_cgal_mesh(const SimpleMesh &mesh) { cgal::VertexIndex(triangle.x), cgal::VertexIndex(triangle.y), cgal::VertexIndex(triangle.z)); - DEBUG_ASSERT(face != SurfaceMesh::null_face()); + DEBUG_ASSERT(face != Mesh::null_face()); } return cgal_mesh; } -SimpleMesh convert::to_simple_mesh(const SurfaceMesh &cgal_mesh) { +SimpleMesh convert::to_simple_mesh(const Mesh &cgal_mesh) { ASSERT(!cgal_mesh.has_garbage()); SimpleMesh mesh; diff --git a/src/terrainlib/mesh/convert.h b/src/terrainlib/mesh/convert.h index 25a5610..1ceaf0c 100644 --- a/src/terrainlib/mesh/convert.h +++ b/src/terrainlib/mesh/convert.h @@ -41,7 +41,7 @@ typename Kernel::Point_2 to_cgal_point(const glm::dvec2 &point) { return typename Kernel::Point_2(point.x, point.y); } -cgal::SurfaceMesh to_cgal_mesh(const SimpleMesh& mesh); -SimpleMesh to_simple_mesh(const cgal::SurfaceMesh& cgal_mesh); +cgal::Mesh to_cgal_mesh(const SimpleMesh& mesh); +SimpleMesh to_simple_mesh(const cgal::Mesh& cgal_mesh); } diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp index 952c67b..9529457 100644 --- a/src/terrainlib/mesh/holes.cpp +++ b/src/terrainlib/mesh/holes.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -155,31 +157,188 @@ std::vector> find_holes(const SimpleMesh &mesh) { return boundaries; } -std::vector> find_holes_on_merge_border(const SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping) { +namespace { +bool contains_shared_vertex( + const std::span vertices_in_merged_mesh, + const mesh::merging::VertexMapping &mapping) { + FixedVector source_meshes; + for (const VertexIndex vertex_index : vertices_in_merged_mesh) { + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); + if (source_vertex.has_value()) { + source_meshes.push_back(source_vertex.value()); + if (source_meshes.size() > 1) { + return true; + } + } + } + } +} +} // namespace + +std::vector> find_holes_on_merge_border( + const SimpleMesh &mesh, + const mesh::merging::VertexMapping &mapping +) { std::vector> holes = find_holes(mesh); for (auto it = holes.rbegin(); it != holes.rend(); it++) { const auto &hole = *it; - FixedVector source_meshes; - for (const VertexIndex vertex_index : hole) { - for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { - const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); - if (source_vertex.has_value()) { - source_meshes.push_back(source_vertex.value()); - if (source_meshes.size() > 1) { - break; - } + if (!contains_shared_vertex(hole, mapping)) { + // Not a hole between meshes + holes.erase((it + 1).base()); + } + } + return holes; +} + +namespace { +bool contains_shared_vertex( + const size_t source_mesh_index, + const std::span vertices_in_source_mesh, + const mesh::merging::VertexMapping &mapping) { + for (const VertexIndex vertex_index : vertices_in_source_mesh) { + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + if (mesh_index == source_mesh_index) { + continue; + } + + const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); + if (source_vertex.has_value()) { + return true; + } + } + } + return false; +} + +bool is_shared_vertex( + const merging::VertexId id, + const merging::VertexMapping &mapping +) { + for (size_t other_mesh_index = 0; other_mesh_index < mapping.mesh_count(); other_mesh_index++) { + if (other_mesh_index == id.mesh_index) { + continue; + } + + const std::optional source_vertex = mapping.map_backward(other_mesh_index, id.vertex_index); + if (source_vertex.has_value()) { + return true; + } + } + return false; +} +} // namespace + + +std::vector> find_holes_between_meshes( + const std::span> &meshes, + const merging::VertexMapping &mapping +) { + using Segment = std::vector; + + // Step 1: Extract all boundary segments betweem two shared vertices + std::forward_list boundary_segments; + std::vector shared_vertices_in_boundary; + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; + + const std::vector> boundaries = find_boundaries(mesh); + for (const auto &boundary : boundaries) { + shared_vertices_in_boundary.clear(); + + // Find shared vertices + for (size_t index_in_boundary = 0; index_in_boundary < boundary.size(); index_in_boundary++) { + const merging::VertexId vertex = { + .mesh_index = mesh_index, + .vertex_index = boundary[index_in_boundary] + }; + + if (is_shared_vertex(vertex, mapping)) { + shared_vertices_in_boundary.push_back(index_in_boundary); } } - if (source_meshes.size() > 1) { - break; + + // Discard if not shared boundary + if (shared_vertices_in_boundary.empty()) { + continue; + } + if (shared_vertices_in_boundary.size() % 2 == 1) { + LOG_WARN("Encountered boundary with only a single shared vertex, unable to generate geometry."); + continue; + } + + // Cut boundary into segments + for (size_t i = 0; i holes; + while (!boundary_segments.empty()) { + Segment current = std::move(boundary_segments.front()); + boundary_segments.pop_front(); + const size_t mesh_index = current[0].mesh_index; + + auto prev = boundary_segments.before_begin(); + auto it = boundary_segments.begin(); + + while (it != boundary_segments.end()) { + Segment &other = *it; + + if (other[0].mesh_index == mesh_index) { + if (current.back() == other.front()) { + Segment hole = std::move(current); + hole.insert(hole.end(), other.begin(), other.end()); + holes.push_back(std::move(hole)); + it = boundary_segments.erase_after(prev); + break; + } else if (current.front() == other.back()) { + Segment hole = std::move(other); + hole.insert(hole.end(), current.begin(), current.end()); + holes.push_back(std::move(hole)); + it = boundary_segments.erase_after(prev); + break; + } + } + + prev = it; + it++; } } + return holes; } diff --git a/src/terrainlib/mesh/holes.h b/src/terrainlib/mesh/holes.h index 3f49d67..6d7aebe 100644 --- a/src/terrainlib/mesh/holes.h +++ b/src/terrainlib/mesh/holes.h @@ -13,4 +13,8 @@ std::vector> find_holes_on_merge_border(const SimpleMesh & void fill_planar_hole(SimpleMesh &mesh, const std::span hole); void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes); void fill_holes_on_merge_border(SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping); +std::vector> find_holes_between_meshes( + const std::span> &meshes, + const merging::VertexMapping &mapping +); } // namespace mesh \ No newline at end of file diff --git a/src/terrainlib/mesh/merging/VertexId.h b/src/terrainlib/mesh/merging/VertexId.h new file mode 100644 index 0000000..8b4ff71 --- /dev/null +++ b/src/terrainlib/mesh/merging/VertexId.h @@ -0,0 +1,22 @@ +#pragma once + +#include "hash_utils.h" + +namespace mesh::merging { + +// Identifies a specific vertex within a particular mesh. +struct VertexId { + size_t mesh_index; + size_t vertex_index; + + auto operator<=>(const VertexId &) const = default; +}; + +} + +template <> +struct std::hash { + size_t operator()(const mesh::merging::VertexId &v) const noexcept { + return ::hash::combine(v.mesh_index, v.vertex_index); + } +}; \ No newline at end of file diff --git a/src/terrainlib/mesh/merging/VertexMapping.h b/src/terrainlib/mesh/merging/VertexMapping.h index a83da39..f6c6b27 100644 --- a/src/terrainlib/mesh/merging/VertexMapping.h +++ b/src/terrainlib/mesh/merging/VertexMapping.h @@ -7,13 +7,9 @@ #include #include -namespace mesh::merging { +#include "mesh/merging/VertexId.h" -// Identifies a specific vertex within a particular mesh. -struct VertexId { - size_t mesh_index; - size_t vertex_index; -}; +namespace mesh::merging { // Represents a triangle from a specific mesh. struct TriangleInMesh { diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index cfd5a21..56c3630 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -401,7 +401,7 @@ SimpleMesh apply_mapping( return {}; } - const bool has_uvs = merge_uvs && std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { + const bool has_uvs = merge_uvs && std::any_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 84e4ce1..55e207e 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -5,7 +5,9 @@ #include "mesh/SimpleMesh.h" #include "mesh/merging/VertexDeduplicate.h" +#include "mesh/merging/VertexId.h" #include "mesh/merging/VertexMapping.h" +#include "mesh/merging/helpers.h" namespace mesh::merging { @@ -136,7 +138,7 @@ struct ApplyOptions { private: bool _deduplicate_triangles = true; - bool _merge_uvs = true; + bool _merge_uvs = false; }; inline ApplyOptions apply_options() { diff --git a/src/terrainlib/mesh/utils.inl b/src/terrainlib/mesh/utils.inl index 9a51471..f9b346d 100644 --- a/src/terrainlib/mesh/utils.inl +++ b/src/terrainlib/mesh/utils.inl @@ -146,3 +146,4 @@ void find_boundary_edges(const SimpleMesh_ &mesh, std::unordered_set< } } } + diff --git a/src/terrainlib/mesh/uv_map.cpp b/src/terrainlib/mesh/uv_map.cpp new file mode 100644 index 0000000..ac90b03 --- /dev/null +++ b/src/terrainlib/mesh/uv_map.cpp @@ -0,0 +1,212 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mesh/convert.h" +#include "merge.h" +#include "uv_map.h" + +using namespace uv_map; + +std::string UvParameterizationError::description() const { + return CGAL::Surface_mesh_parameterization::get_error_message(this->code); +} + +tl::expected uv_map::parameterize_mesh(cgal::Mesh &mesh, Algorithm algorithm, Border border) { + using CircleBorderParameterizer = CGAL::Surface_mesh_parameterization::Circular_border_uniform_parameterizer_3; + using SquareBorderParameterizer = CGAL::Surface_mesh_parameterization::Square_border_uniform_parameterizer_3; + + using TutteBarycentricMappingParameterizerCircularBorder = CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3; + using TutteBarycentricMappingParameterizerSquareBorder = CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3; + using DiscreteAuthalicParameterizerCircularBorder = CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3; + using DiscreteAuthalicParameterizerSquareBorder = CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3; + using DiscreteConformalMapParameterizerCircularBorder = CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3; + using DiscreteConformalMapParameterizerSquareBorder = CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3; + using FloaterMeanValueCoordinatesParameterizerCircularBorder = CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3; + using FloaterMeanValueCoordinatesParameterizerSquareBorder = CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3; + + const cgal::HalfedgeDescriptor bhd = CGAL::Polygon_mesh_processing::longest_border(mesh).first; + + auto uv_map = mesh.add_property_map("v:uv").first; + + CGAL::Surface_mesh_parameterization::Error_code result; + if (border != Border::Circle && border != Border::Square) { + throw std::invalid_argument("illegal border specifier"); + } + + if (algorithm == Algorithm::TutteBarycentricMapping) { + if (border == Border::Circle) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, TutteBarycentricMappingParameterizerCircularBorder(), bhd, uv_map); + } else if (border == Border::Square) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, TutteBarycentricMappingParameterizerSquareBorder(), bhd, uv_map); + } + } else if (algorithm == Algorithm::DiscreteAuthalic) { + if (border == Border::Circle) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteAuthalicParameterizerCircularBorder(), bhd, uv_map); + } else if (border == Border::Square) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteAuthalicParameterizerSquareBorder(), bhd, uv_map); + } + } else if (algorithm == Algorithm::DiscreteConformalMap) { + if (border == Border::Circle) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteConformalMapParameterizerCircularBorder(), bhd, uv_map); + } else if (border == Border::Square) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteConformalMapParameterizerSquareBorder(), bhd, uv_map); + } + } else if (algorithm == Algorithm::FloaterMeanValueCoordinates) { + if (border == Border::Circle) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, FloaterMeanValueCoordinatesParameterizerCircularBorder(), bhd, uv_map); + } else if (border == Border::Square) { + result = CGAL::Surface_mesh_parameterization::parameterize(mesh, FloaterMeanValueCoordinatesParameterizerSquareBorder(), bhd, uv_map); + } + } else { + throw std::invalid_argument("illegal algorithm specifier"); + } + + if (result != CGAL::Surface_mesh_parameterization::OK) { + return tl::unexpected(UvParameterizationError(result)); + } + + for (cgal::VertexDescriptor v : CGAL::vertices(mesh)) { + auto &uv = uv_map[v]; + glm::dvec2 g = convert::to_glm_point(uv); + g = glm::clamp(g, glm::dvec2(0), glm::dvec2(1)); + uv = convert::to_cgal_point(g); + } + + return {}; +} + +namespace { +inline std::vector decode_uv_map(const auto &uv_map, size_t number_of_vertices) { + std::vector uvs; + uvs.reserve(number_of_vertices); + for (size_t i = 0; i < number_of_vertices; i++) { + const cgal::Point2 &uv = uv_map[CGAL::SM_Vertex_index(i)]; + uvs.push_back(convert::to_glm_point(uv)); + } + return uvs; +} +} + +tl::expected, UvParameterizationError> uv_map::parameterize_mesh(const SimpleMesh &mesh, Algorithm algorithm, Border border) { + cgal::Mesh cgal_mesh = convert::to_cgal_mesh(mesh); + const auto result = parameterize_mesh(cgal_mesh, algorithm, border); + if (!result) { + return tl::unexpected(result.error()); + } + auto uv_map_opt = cgal_mesh.property_map("v:uv"); + ASSERT(uv_map_opt.has_value()); + const auto &uv_map = uv_map_opt.value(); + return decode_uv_map(uv_map, mesh.vertex_count()); +} + +template +inline cv::Rect_ clamp_rect_to_mat_bounds(const cv::Rect_ &rect, const cv::Mat &mat) { + const T x = std::max(rect.x, 0); + const T y = std::max(rect.y, 0); + const T width = std::max(std::min(rect.width, mat.cols - x), 0); + const T height = std::max(std::min(rect.height, mat.rows - y), 0); + + return cv::Rect(x, y, width, height); +} + +void warp_triangle( + const cv::Mat &source_image, + cv::Mat &target_image, + std::array source_triangle, + std::array target_triangle, + const uint32_t padding = 1 // TODO: +) { + // Find bounding rectangle for each triangle + const cv::Rect source_rect = clamp_rect_to_mat_bounds(cv::boundingRect(source_triangle), source_image); + const cv::Rect target_rect = clamp_rect_to_mat_bounds(cv::boundingRect(target_triangle), target_image); + if (source_rect.width == 0 || source_rect.height == 0 + || target_rect.width == 0 || target_rect.height == 0) { + return; + } + + + // Relativize triangles to bounds + std::array source_triangle_cropped; + std::array target_triangle_cropped; + for (size_t i = 0; i < 3; i++) { + source_triangle_cropped[i] = cv::Point2f(source_triangle[i].x - source_rect.x, source_triangle[i].y - source_rect.y); + target_triangle_cropped[i] = cv::Point2f(target_triangle[i].x - target_rect.x, target_triangle[i].y - target_rect.y); + } + + // Convert points to int triangles as fillConvexPoly needs a vector of Point2i and not Point2f + std::array target_triangle_cropped_int; + for (size_t i = 0; i < 3; i++) { + target_triangle_cropped_int[i]= cv::Point2i((int)(target_triangle[i].x - target_rect.x), (int)(target_triangle[i].y - target_rect.y)); + } + + // Read source region from source image + cv::Mat source_image_cropped; + source_image(source_rect).copyTo(source_image_cropped); + source_image_cropped.convertTo(source_image_cropped, CV_32FC3); + + // Given a pair of triangles, find the affine transform. + const cv::Mat warp_tranform = cv::getAffineTransform(source_triangle_cropped, target_triangle_cropped); + + // Apply the affine transform just found to the source image + cv::Mat target_image_cropped = cv::Mat::zeros(target_rect.height, target_rect.width, CV_32FC3); + cv::warpAffine(source_image_cropped, target_image_cropped, warp_tranform, target_image_cropped.size(), cv::INTER_LINEAR, cv::BORDER_REFLECT_101); + + // Get mask by filling triangle + cv::Mat mask = cv::Mat::zeros(target_rect.height, target_rect.width, CV_32FC3); + cv::fillConvexPoly(mask, target_triangle_cropped_int, cv::Scalar(1.0, 1.0, 1.0), 16, 0); + + // Copy triangular region of the rectangular patch to the output image + cv::multiply(target_image_cropped, mask, target_image_cropped, 1, CV_32FC3); + cv::multiply(target_image(target_rect), cv::Scalar(1.0, 1.0, 1.0) - mask, target_image(target_rect), 1, CV_32FC3); + target_image(target_rect) = target_image(target_rect) + target_image_cropped; +} + +// TODO: reproject triangles +/* +Texture uv_map::merge_textures( + const std::span> original_meshes, + const SimpleMesh &merged_mesh, + const mesh::merging::VertexMapping &mapping, + const UvMap &uv_map, + const glm::uvec2 merged_texture_size) { + for (const SimpleMesh& mesh : original_meshes) { + DEBUG_ASSERT(mesh.has_texture()); + } + + cv::Mat merged_atlas = cv::Mat::zeros(merged_texture_size.y, merged_texture_size.x, CV_32FC3); + + for (const glm::uvec3 &mapped_triangle : merged_mesh.triangles) { + std::array mapped_uv_triangle; + for (size_t i = 0; i < static_cast(mapped_triangle.length()); i++) { + glm::dvec2 uv = convert::to_glm_point(uv_map[cgal::VertexIndex(mapped_triangle[i])]); + // TODO: Fix for black borders + uv = (uv - 0.5) * 1.01 + 0.5; + mapped_uv_triangle[i] = cv::Point2f(uv.x * merged_texture_size.x, uv.y * merged_texture_size.y); + } + + const mesh::merging::TriangleInMesh source_mesh_and_triangle = mapping.find_source_triangle(mapped_triangle); + const size_t source_mesh_index = source_mesh_and_triangle.mesh_index; + const SimpleMesh &source_mesh = original_meshes[source_mesh_index]; + const glm::uvec3 source_triangle = source_mesh_and_triangle.triangle; + + std::array source_uv_triangle; + for (size_t i = 0; i < static_cast(source_triangle.length()); i++) { + const glm::dvec2 uv = source_mesh.uvs[source_triangle[i]]; + const cv::Size source_texture_size = source_mesh.texture->size(); + source_uv_triangle[i] = cv::Point2f(uv.x * source_texture_size.width, uv.y * source_texture_size.height); + } + + warp_triangle(source_mesh.texture.value(), merged_atlas, source_uv_triangle, mapped_uv_triangle); + } + + return merged_atlas; +} +*/ diff --git a/src/terrainlib/mesh/uv_map.h b/src/terrainlib/mesh/uv_map.h new file mode 100644 index 0000000..9b3b63c --- /dev/null +++ b/src/terrainlib/mesh/uv_map.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/cgal.h" + +typedef cv::Mat Texture; + +namespace uv_map { + +enum class Algorithm { + TutteBarycentricMapping, + DiscreteAuthalic, + DiscreteConformalMap, + FloaterMeanValueCoordinates +}; + +enum class Border { + Circle, + Square +}; + +class UvParameterizationError { +public: + UvParameterizationError() = default; + constexpr UvParameterizationError(int code) + : code(code) {} + + operator int() const { + return this->code; + } + + std::string description() const; + +private: + int code; +}; + +tl::expected parameterize_mesh( + cgal::Mesh &mesh, + Algorithm algorithm, + Border border); + +tl::expected, UvParameterizationError> parameterize_mesh( + const SimpleMesh &mesh, + Algorithm algorithm, + Border border); + +void warp_triangle( + const cv::Mat &source_image, + cv::Mat &target_image, + std::array source_triangle, + std::array target_triangle); + +Texture merge_textures( + const std::span> original_meshes, + const SimpleMesh &merged_mesh, + const mesh::merging::VertexMapping &mapping, + const glm::uvec2 merged_texture_size); + +/* +Texture merge_textures( + const std::span> original_meshes, + const SimpleMesh& merged_mesh, + const mesh::merging::VertexMapping &mapping, + const glm::uvec2 merged_texture_size); + */ + +} diff --git a/src/terrainlib/octree/storage/RawStorage.cpp b/src/terrainlib/octree/storage/RawStorage.cpp index c6e4356..57a307f 100644 --- a/src/terrainlib/octree/storage/RawStorage.cpp +++ b/src/terrainlib/octree/storage/RawStorage.cpp @@ -16,46 +16,7 @@ tl::expected RawStorage::write_node(const Id &id, const auto node_path = this->get_node_path(id); return mesh::io::save_to_path(node, node_path); } -/* -tl::expected RawStorage::copy_node_to(const Id &id, const RawStorage &target) const noexcept { - const auto source_node_path = this->get_node_path(id); - if (!this->has_node(id)) { - return tl::unexpected(CopyMeshErrorKind::FileNotFound); - } - std::error_code ec; - const auto target_node_path = target.get_node_path(id); - if (source_node_path.extension() != target_node_path.extension()) { - // TODO: should this error instead? - const auto load_result = mesh::io::load_from_path(source_node_path); - if (!load_result.has_value()) { - } - const Node node = load_result.value(); - const auto save_result = mesh::io::save_to_path(node, target_node_path); - if (!save_result.has_value()) { - - } - return {}; - } - if (std::filesystem::remove(target_node_path, ec)) { - if (ec) { - return tl::unexpected(CopyMeshErrorKind::RemoveOld); - } - } - std::filesystem::create_directories(target_node_path.parent_path(), ec); - if (ec) { - return tl::unexpected(CopyMeshErrorKind::CreateDirectories); - } - std::filesystem::create_hard_link( - source_node_path, - target_node_path, - ec); - if (ec) { - return tl::unexpected(CopyMeshErrorKind::CreateLink); - } - return {}; -} -*/ tl::expected RawStorage::copy_node_from(const Id &id, const RawStorage &source) noexcept { if (!source.has_node(id)) { return tl::unexpected(CopyMeshErrorKind::FileNotFound); diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp index bda45d4..ca81559 100644 --- a/src/terrainlib/polygon/triangulate.cpp +++ b/src/terrainlib/polygon/triangulate.cpp @@ -109,6 +109,10 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { const glm::dvec2 point2d = convert::to_glm_point(cgal_point); const glm::dvec3 point3d = lift(point2d, basis); mesh.positions.push_back(point3d); + if (mesh.has_uvs()) { + const glm::dvec2 uv = {0, 0}; + mesh.uvs.push_back(uv); + } triangle[i] = new_index; } else { triangle[i] = original_index.value(); diff --git a/src/terrainmerger/mask.h b/src/terrainmerger/mask.h index 484d528..f0cc7ad 100644 --- a/src/terrainmerger/mask.h +++ b/src/terrainmerger/mask.h @@ -406,9 +406,9 @@ inline glm::dvec2 pad_radius_range(const glm::dvec2& radius_range, double paddin inline MeshMask extrude( const SphereMeshMask &mask, const glm::dvec2& radius_range) { - cgal::SurfaceMesh cgal_mesh = convert::to_cgal_mesh(mask.mesh); + cgal::Mesh cgal_mesh = convert::to_cgal_mesh(mask.mesh); - cgal::SurfaceMesh output_mesh; + cgal::Mesh output_mesh; auto bottom = [&](cgal::VertexDescriptor input_vertex, cgal::VertexDescriptor output_vertex) { const cgal::Point3 input_point = cgal_mesh.point(input_vertex); const glm::dvec3 glm_input_point = convert::to_glm_point(input_point); diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index c6db3c4..8e3c64b 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -1,10 +1,13 @@ #pragma once +#include + #include "mask.h" #include "merge/NodeData.h" #include "merge/Result.h" #include "merge/visitor/Visitor.h" #include "mesh/holes.h" +#include "mesh/combine.h" #include "mesh/merging/SphereProjectionVertexDeduplicate.h" #include "mesh/merging/VertexMapping.h" #include "mesh/merging/helpers.h" @@ -16,6 +19,186 @@ namespace merge::visitor { +inline xatlas::MeshDecl to_meshdecl(const SimpleMesh &mesh) { + xatlas::MeshDecl decl{}; + + decl.indexCount = static_cast(mesh.triangles.size() * 3); + decl.indexData = mesh.triangles.data(); + decl.indexFormat = xatlas::IndexFormat::UInt32; + + decl.vertexCount = static_cast(mesh.positions.size()); + decl.vertexPositionData = mesh.positions.data(); + decl.vertexPositionStride = sizeof(SimpleMesh::Position); + + if (mesh.has_uvs()) { + decl.vertexUvData = mesh.uvs.data(); + decl.vertexUvStride = sizeof(SimpleMesh::Uv); + } + + return decl; +} + +inline xatlas::UvMeshDecl to_uvmeshdecl(const SimpleMesh &mesh) { + xatlas::UvMeshDecl decl{}; + + decl.indexCount = static_cast(mesh.triangles.size() * 3); + decl.indexData = mesh.triangles.data(); + decl.indexFormat = xatlas::IndexFormat::UInt32; + + ASSERT(mesh.has_uvs()); + decl.vertexUvData = mesh.uvs.data(); + decl.vertexCount = static_cast(mesh.uvs.size()); + decl.vertexStride = sizeof(SimpleMesh::Uv); + + return decl; +} + +struct Atlas { + std::vector> uvs; + SimpleMesh::Texture texture; +}; + +inline uint32_t next_pow2(uint32_t v) { + if (v <= 1) { + return 1; + } + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return v + 1; +} + +inline uint32_t compute_resolution( + const std::span> meshes) { + size_t total = 0; + for (const SimpleMesh &m : meshes) { + total += m.vertex_count(); + } + const uint32_t result = next_pow2(static_cast(std::ceil(std::sqrt(total)))); + return std::clamp(result, 512u, 4096u); +} + +inline Atlas generate_texture_atlas( + const std::span> meshes +) { + xatlas::Atlas *atlas = xatlas::Create(); + + for (const SimpleMesh &mesh : meshes) { + const xatlas::UvMeshDecl decl = to_uvmeshdecl(mesh); + const xatlas::AddMeshError error = xatlas::AddUvMesh(atlas, decl); + if (error != xatlas::AddMeshError::Success) { + xatlas::Destroy(atlas); + LOG_ERROR_AND_EXIT("Error adding mesh {}", xatlas::StringForEnum(error)); + } + } + + xatlas::ChartOptions chartOptions{}; + chartOptions.useInputMeshUvs = true; + + xatlas::PackOptions packOptions{}; + packOptions.padding = 2; + packOptions.resolution = compute_resolution(meshes); + + xatlas::Generate(atlas, chartOptions, packOptions); + + Atlas result; + result.uvs.resize(meshes.size()); + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh & mesh = meshes[mesh_index]; + result.uvs[mesh_index].resize(mesh.vertex_count()); + } + + for (size_t mesh_index = 0; mesh_index < atlas->meshCount; mesh_index++) { + const xatlas::Mesh &xmesh = atlas->meshes[mesh_index]; + + for (size_t vertex_index = 0; vertex_index < xmesh.vertexCount; vertex_index++) { + const xatlas::Vertex& vertex = xmesh.vertexArray[vertex_index]; + result.uvs[mesh_index][vertex.xref] = glm::dvec2(vertex.uv[0], vertex.uv[1]); + } + } + + + cv::Mat mat(atlas->height, atlas->width, CV_8UC4, atlas->image); + result.texture = mat.clone(); + + xatlas::Destroy(atlas); + + return result; +} + +// Simple grid-based atlas using the largest texture size +inline Atlas generate_texture_atlas_grid( + const std::span> meshes) { + // Identify meshes that actually have textures + std::vector meshes_with_textures; + int max_texture_width = 0; + int max_texture_height = 0; + + for (size_t i = 0; i < meshes.size(); ++i) { + if (meshes[i].get().texture.has_value()) { + meshes_with_textures.push_back(i); + const cv::Mat &tex = meshes[i].get().texture.value(); + max_texture_width = std::max(max_texture_width, tex.cols); + max_texture_height = std::max(max_texture_height, tex.rows); + } + } + + if (meshes_with_textures.empty()) { + return Atlas{}; // No textures to pack + } + + size_t number_of_textured_meshes = meshes_with_textures.size(); + size_t grid_size = static_cast(std::ceil(std::sqrt(number_of_textured_meshes))); + + int atlas_width = next_pow2(static_cast(grid_size * max_texture_width)); + int atlas_height = next_pow2(static_cast(grid_size * max_texture_height)); + + // Create atlas image with transparent background + cv::Mat atlas_image(atlas_height, atlas_width, meshes[meshes_with_textures[0]].get().texture->type(), cv::Scalar(0, 0, 0, 0)); + + Atlas result; + result.uvs.resize(meshes.size()); + + size_t slot_index = 0; + for (size_t mesh_index : meshes_with_textures) { + const SimpleMesh &mesh = meshes[mesh_index].get(); + int row = slot_index / grid_size; + int column = slot_index % grid_size; + + // Compute destination rectangle in atlas + cv::Rect destination_rectangle( + column * max_texture_width, + row * max_texture_height, + mesh.texture->cols, + mesh.texture->rows); + + // Copy the mesh's texture into the atlas + mesh.texture->copyTo(atlas_image(destination_rectangle)); + + // Update UV coordinates to map the mesh's full texture to its slot + result.uvs[mesh_index].resize(mesh.vertex_count()); + double u_start = double(column * max_texture_width) / atlas_width; + double v_start = double(row * max_texture_height) / atlas_height; + double u_end = double(column * max_texture_width + mesh.texture->cols) / atlas_width; + double v_end = double(row * max_texture_height + mesh.texture->rows) / atlas_height; + + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); ++vertex_index) { + const auto &original_uv = mesh.uvs[vertex_index]; + result.uvs[mesh_index][vertex_index] = glm::dvec2( + u_start + original_uv.x * (u_end - u_start), + v_start + original_uv.y * (v_end - v_start)); + } + + ++slot_index; + } + + result.texture = atlas_image; + return result; +} + class Masked { public: using Status = octree::NodeStatusOrMissing; @@ -170,7 +353,8 @@ class Masked { } } - LOG_TRACE("Performing actual mesh merge"); + // Merging the two meshes + LOG_TRACE("Calculating merge mapping"); const std::array, 2> meshes = {base_mesh_clipped.get(), new_mesh_clipped.get()}; const double distance_epsilon = mesh::merging::estimate_merge_epsilon(meshes); // We have to use a hashmap here instead of a grid since we dont know @@ -185,10 +369,47 @@ class Masked { > deduplicate(map, distance_epsilon, radius); const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, mesh::merging::create_options().deduplicate(deduplicate).only_consider_boundary(true)); - SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, - mesh::merging::apply_options().deduplicate_triangles(false).merge_uvs(false)); - LOG_TRACE("Filling holes on merge border"); - mesh::fill_holes_on_merge_border(merged_mesh, mapping); + + LOG_TRACE("Creating combined mesh"); + std::vector vertex_offsets; + SimpleMesh merged_mesh = mesh::combine(meshes, vertex_offsets); + + // Find holes between meshes + LOG_TRACE("Triangulating region between meshes"); + const std::vector> holes = mesh::find_holes_between_meshes(meshes, mapping); + std::vector> mapped_holes; + mapped_holes.reserve(holes.size()); + for (const auto& hole : holes) { + std::vector mapped_hole; + mapped_hole.reserve(hole.size()); + for (const auto& vertex_id : hole) { + const size_t mapped_index = vertex_offsets[vertex_id.mesh_index] + vertex_id.vertex_index; + mapped_hole.push_back(mapped_index); + } + } + + LOG_TRACE("Generating combined texture"); + Atlas atlas = generate_texture_atlas_grid(meshes); + merged_mesh.texture = std::move(atlas.texture); + for (size_t mesh_index=0; mesh_index Date: Thu, 25 Sep 2025 17:21:51 +0200 Subject: [PATCH 114/122] Fix tests --- unittests/terrainlib/mesh_merge.cpp | 21 +++++++------ unittests/terrainlib/mesh_merge_mapping.cpp | 34 +++++++++++++++------ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/unittests/terrainlib/mesh_merge.cpp b/unittests/terrainlib/mesh_merge.cpp index d6bcf7d..5b2aae5 100644 --- a/unittests/terrainlib/mesh_merge.cpp +++ b/unittests/terrainlib/mesh_merge.cpp @@ -40,7 +40,7 @@ TEST_CASE("mesh::merge") { mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); + SimpleMesh actual = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.1)); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -78,7 +78,10 @@ TEST_CASE("mesh::merge") { mesh2.uvs.push_back(glm::dvec2(0, 1)); mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); + SimpleMesh actual = mesh::merge(mesh1, mesh2, + mesh::merging::create_options().epsilon(0.1), + mesh::merging::apply_options().merge_uvs(true) + ); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -119,7 +122,7 @@ TEST_CASE("mesh::merge") { const bool only_boundary = GENERATE(true, false); CAPTURE(only_boundary); - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1, only_boundary); + SimpleMesh actual = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.1).only_consider_boundary(only_boundary)); SimpleMesh expected; expected.positions.push_back(glm::dvec3(0, 0, 0)); @@ -152,9 +155,9 @@ TEST_CASE("mesh::merge") { mesh1.positions.push_back(glm::dvec3(0, 1, 0)); mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); - SimpleMesh mesh2; // empty + const SimpleMesh mesh2; // empty - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.1); + const SimpleMesh actual = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.1)); CHECK(mesh1.positions == actual.positions); CHECK(mesh1.uvs == actual.uvs); @@ -169,9 +172,9 @@ TEST_CASE("mesh::merge") { glm::dvec3(0, 1, 0)}; mesh1.triangles.push_back(glm::uvec3(0, 1, 2)); - SimpleMesh mesh2 = mesh1; + const SimpleMesh mesh2 = mesh1; - SimpleMesh actual = mesh::merge(mesh1, mesh2, 0.001); + const SimpleMesh actual = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.001)); CHECK(actual.positions == mesh1.positions); CHECK(actual.triangles == mesh1.triangles); @@ -192,8 +195,8 @@ TEST_CASE("mesh::merge") { glm::dvec3(1, 1, 0)}; mesh2.triangles.push_back(glm::uvec3(0, 1, 2)); - auto merged_small = mesh::merge(mesh1, mesh2, 0.01); - auto merged_large = mesh::merge(mesh1, mesh2, 0.1); + const SimpleMesh merged_small = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.01)); + const SimpleMesh merged_large = mesh::merge(mesh1, mesh2, mesh::merging::create_options().epsilon(0.1)); CHECK(merged_small.positions.size() > merged_large.positions.size()); } diff --git a/unittests/terrainlib/mesh_merge_mapping.cpp b/unittests/terrainlib/mesh_merge_mapping.cpp index d112ae4..7bf69a5 100644 --- a/unittests/terrainlib/mesh_merge_mapping.cpp +++ b/unittests/terrainlib/mesh_merge_mapping.cpp @@ -43,7 +43,10 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options() + .epsilon(0.1) + .only_consider_boundary(false)); const size_t idx1 = mapping.map_forward(VertexId{0, 0}); const size_t idx2 = mapping.map_forward(VertexId{1, 0}); @@ -63,7 +66,10 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options() + .epsilon(0.1) + .only_consider_boundary(false)); // Merged index of (1, 0, 0) should be the same for both meshes const size_t idx1 = mapping.map_forward(VertexId{0, 2}); @@ -94,8 +100,11 @@ TEST_CASE("merging::create_mapping") { mesh2.positions.push_back(glm::dvec3(2, 0, 0)); const std::array, 2> meshes = {mesh1, mesh2}; - - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, false); + + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options() + .epsilon(0.1) + .only_consider_boundary(false)); const size_t idx1 = mapping.map_forward(VertexId{0, 1}); // (1, 0, 0) const size_t idx2 = mapping.map_forward(VertexId{1, 0}); // (1.05, 0, 0) @@ -118,8 +127,8 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // epsilon too small - + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().epsilon(0.1)); const size_t idx1 = mapping.map_forward(VertexId{0, 0}); const size_t idx2 = mapping.map_forward(VertexId{1, 0}); @@ -138,7 +147,8 @@ TEST_CASE("merging::create_mapping") { const std::array, 2> meshes = {mesh1, mesh2}; - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1); // all far apart + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().epsilon(0.1)); // all far apart CHECK(mapping.find_max_merged_index() + 1 == 4); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{0, 1})); @@ -159,8 +169,9 @@ TEST_CASE("merging::create_mapping") { const bool only_boundary = GENERATE(true, false); CAPTURE(only_boundary); - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, only_boundary); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().epsilon(0.1).only_consider_boundary(only_boundary)); CHECK(mapping.map_forward(VertexId{0, 0}) == mapping.map_forward(VertexId{1, 0})); CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); CHECK(mapping.map_forward(VertexId{0, 2}) == mapping.map_forward(VertexId{1, 2})); @@ -185,7 +196,8 @@ TEST_CASE("merging::create_mapping") { const bool only_boundary = GENERATE(true, false); CAPTURE(only_boundary); - const VertexMapping mapping = mesh::merging::create_mapping(meshes, 0.1, only_boundary); + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().epsilon(0.1).only_consider_boundary(only_boundary)); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 2})); CHECK(mapping.map_forward(VertexId{0, 1}) == mapping.map_forward(VertexId{1, 1})); @@ -219,7 +231,9 @@ TEST_CASE("merging::create_mapping") { mesh::merging::VertexId, decltype(map)> deduplicate(map, distance_epsilon, radius); - const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, deduplicate, only_boundary); + + const VertexMapping mapping = mesh::merging::create_mapping(meshes, + mesh::merging::create_options().deduplicate( deduplicate).only_consider_boundary(only_boundary)); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 0})); CHECK(mapping.map_forward(VertexId{0, 0}) != mapping.map_forward(VertexId{1, 1})); From 2db9294b7e2e2f85aadfc37f57284253e2e8c093 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 25 Sep 2025 17:22:42 +0200 Subject: [PATCH 115/122] Various fixes --- src/mesh_merger/main.cpp | 5 ++-- src/terrainlib/mesh/combine.h | 23 +++++++++++++- src/terrainlib/mesh/holes.cpp | 19 ++++-------- src/terrainlib/mesh/merging/mapping.cpp | 13 +++++--- src/terrainlib/mesh/merging/mapping.h | 3 +- src/terrainlib/mesh/validate.inl | 6 ++-- src/terrainlib/polygon/triangulate.cpp | 40 ++++++++++++++----------- src/terrainlib/polygon/utils.cpp | 4 +-- 8 files changed, 69 insertions(+), 44 deletions(-) diff --git a/src/mesh_merger/main.cpp b/src/mesh_merger/main.cpp index f3be3c6..9af5fbd 100644 --- a/src/mesh_merger/main.cpp +++ b/src/mesh_merger/main.cpp @@ -15,12 +15,13 @@ SimpleMesh merge(const std::span meshes, const std::optional std::vector> mesh_refs; mesh_refs.reserve(meshes.size()); for (const SimpleMesh &mesh : meshes) { - mesh_refs.push_back(mesh); + mesh_refs.push_back(std::cref(mesh)); } mesh::merging::VertexMapping mapping; if (epsilon.has_value()) { - mapping = mesh::merging::create_mapping(mesh_refs, epsilon.value()); + mapping = mesh::merging::create_mapping(mesh_refs, + mesh::merging::create_options().epsilon(epsilon.value())); } else { mapping = mesh::merging::create_mapping(mesh_refs); } diff --git a/src/terrainlib/mesh/combine.h b/src/terrainlib/mesh/combine.h index 56e1a9a..5178957 100644 --- a/src/terrainlib/mesh/combine.h +++ b/src/terrainlib/mesh/combine.h @@ -61,10 +61,31 @@ auto combine( return result; } -template +template auto combine(const MeshRange &meshes) { std::vector vertex_offsets; return combine(meshes, vertex_offsets); } +template +void combine_inplace( + SimpleMesh_ &acc_mesh, + const SimpleMesh_ &other_mesh) { + bool has_uvs = acc_mesh.has_uvs() || other_mesh.has_uvs(); + + acc_mesh.positions.insert(acc_mesh.positions.end(), other_mesh.positions.begin(), other_mesh.positions.end()); + + if (has_uvs) { + if (other_mesh.has_uvs()) { + acc_mesh.uvs.insert(acc_mesh.uvs.end(), other_mesh.uvs.begin(), other_mesh.uvs.end()); + } else { + acc_mesh.uvs.insert(acc_mesh.uvs.end(), other_mesh.vertex_count(), glm::dvec2(0)); + } + } + + acc_mesh.triangles.reserve(acc_mesh.face_count() + other_mesh.face_count()); + for (const auto &triangle : other_mesh.triangles) { + acc_mesh.triangles.push_back(triangle + static_cast(acc_mesh.vertex_count())); + } +} } diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp index 9529457..5bf876e 100644 --- a/src/terrainlib/mesh/holes.cpp +++ b/src/terrainlib/mesh/holes.cpp @@ -110,13 +110,13 @@ namespace { template auto iterator_from_ref(std::vector &vec, T &ref) { // Make sure ref actually belongs to vec - assert(&ref >= vec.data() && &ref < vec.data() + vec.size()); + DEBUG_ASSERT(&ref >= vec.data() && &ref < vec.data() + vec.size()); return vec.begin() + (&ref - vec.data()); } template auto iterator_from_ref(const std::vector &vec, const T &ref) { - assert(&ref >= vec.data() && &ref < vec.data() + vec.size()); + DEBUG_ASSERT(&ref >= vec.data() && &ref < vec.data() + vec.size()); return vec.cbegin() + (&ref - vec.data()); } } @@ -192,6 +192,7 @@ std::vector> find_holes_on_merge_border( return holes; } +/* namespace { bool contains_shared_vertex( const size_t source_mesh_index, @@ -202,7 +203,7 @@ bool contains_shared_vertex( if (mesh_index == source_mesh_index) { continue; } - + const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); if (source_vertex.has_value()) { return true; @@ -299,7 +300,7 @@ std::vector> find_holes_between_meshes( }); } } - + boundary_segments.push_front(std::move(segment)); } } @@ -340,18 +341,10 @@ std::vector> find_holes_between_meshes( } return holes; -} +}*/ void fill_planar_hole(SimpleMesh &mesh, const std::span hole) { - if (hole.size() < 3) { - return; - } - polygon::triangulate(mesh, hole); - - // for (size_t i = 1; i + 1 < hole.size(); i++) { - // mesh.triangles.emplace_back(hole[0], hole[i], hole[i + 1]); - // } } void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes) { diff --git a/src/terrainlib/mesh/merging/mapping.cpp b/src/terrainlib/mesh/merging/mapping.cpp index 56c3630..c5876b4 100644 --- a/src/terrainlib/mesh/merging/mapping.cpp +++ b/src/terrainlib/mesh/merging/mapping.cpp @@ -161,7 +161,9 @@ VertexMapping create_mapping( } } if (nearest_duplicate.has_value()) { - mapping.add_bidirectional(current_vertex, mapping.map_forward(nearest_duplicate.value().first)); + const auto mapped = mapping.map_forward(nearest_duplicate.value().first); + DEBUG_ASSERT(!mapping.map_backward(mesh_index, mapped).has_value()); + mapping.add_bidirectional(current_vertex, mapped); } else { deduplicate.add(position, current_vertex); add_unique_vertex(current_vertex); @@ -372,7 +374,7 @@ VertexMapping create_connecting_mapping(std::span> meshes, @@ -416,12 +418,15 @@ SimpleMesh apply_mapping( const size_t mapped_index = mapping.map_forward(VertexId{.mesh_index = mesh_index, .vertex_index = vertex_index}); merged_mesh.positions[mapped_index] = mesh.positions[vertex_index]; if (has_uvs) { - merged_mesh.uvs[mapped_index] = mesh.uvs[vertex_index]; + merged_mesh.uvs[mapped_index] = mesh.has_uvs() ? mesh.uvs[vertex_index] : glm::dvec2(0); } max_vertex_index = std::max(max_vertex_index, mapped_index); } } - DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count || max_vertex_index == 0); + if (max_vertex_index == 0) { + return {}; + } + DEBUG_ASSERT(max_vertex_index < max_combined_vertex_count); merged_mesh.positions.resize(max_vertex_index + 1); if (has_uvs) { merged_mesh.uvs.resize(max_vertex_index + 1); diff --git a/src/terrainlib/mesh/merging/mapping.h b/src/terrainlib/mesh/merging/mapping.h index 55e207e..b079910 100644 --- a/src/terrainlib/mesh/merging/mapping.h +++ b/src/terrainlib/mesh/merging/mapping.h @@ -87,7 +87,7 @@ inline CreateOptions create_options() { return CreateOptions::defaults(); } -template +template VertexMapping create_mapping( const std::span> meshes, const CreateOptions options = create_options()) { @@ -156,3 +156,4 @@ inline SimpleMesh apply_mapping( } } // namespace mesh::merging + \ No newline at end of file diff --git a/src/terrainlib/mesh/validate.inl b/src/terrainlib/mesh/validate.inl index 406e90c..a0843c1 100644 --- a/src/terrainlib/mesh/validate.inl +++ b/src/terrainlib/mesh/validate.inl @@ -52,9 +52,9 @@ void validate_sorted_normalized_mesh(const SimpleMesh_ &mesh) { for (Triangle &triangle : triangles_ignore_orientation) { std::sort(&triangle.x, &triangle.z + 1); } - std::vector triangles_ignore_orientation2(triangles_ignore_orientation); - sort_and_normalize_triangles(triangles_ignore_orientation); - DEBUG_ASSERT(triangles_ignore_orientation.end() == std::adjacent_find(triangles_ignore_orientation.begin(), triangles_ignore_orientation.end())); + std::vector triangles_ignore_orientation_normalized(triangles_ignore_orientation); + sort_and_normalize_triangles(triangles_ignore_orientation_normalized); + DEBUG_ASSERT(triangles_ignore_orientation_normalized.end() == std::adjacent_find(triangles_ignore_orientation_normalized.begin(), triangles_ignore_orientation_normalized.end())); // Check for isolated vertices DEBUG_ASSERT(find_isolated_vertices(mesh).empty()); diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp index ca81559..5ce3aa1 100644 --- a/src/terrainlib/polygon/triangulate.cpp +++ b/src/terrainlib/polygon/triangulate.cpp @@ -11,6 +11,8 @@ #include "mesh/cgal.h" #include "mesh/convert.h" +#include "mesh/validate.h" +#include "mesh/utils.h" #include "polygon/utils.h" using Kernel = cgal::kernel::epeck::Kernel; @@ -58,6 +60,10 @@ glm::dvec3 lift(const glm::dvec2 &q, const PlaneBasis &basis) { // TODO: deduplicate overloads void triangulate(SimpleMesh3d &mesh, const std::span indices) { + if (indices.size() < 3) { + return; + } + // Build the 3D points of the polygon Polygon3d polygon; polygon.points.reserve(indices.size()); @@ -66,6 +72,9 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { polygon.points.push_back(mesh.positions[vertex_index]); } + // Holes are oriented CW + std::reverse(polygon.points.begin(), polygon.points.end()); + DEBUG_ASSERT(polygon::is_planar(polygon)); const PlaneBasis basis = make_basis(polygon); @@ -124,10 +133,6 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { } SimpleMesh3d triangulate(const Polygon3d &polygon) { - ASSERT(false); - // TODO; - return {}; - /* DEBUG_ASSERT(polygon::is_planar(polygon)); const PlaneBasis basis = make_basis(polygon); @@ -143,39 +148,38 @@ SimpleMesh3d triangulate(const Polygon3d &polygon) { } // Mark facets that are inside the domain bounded by the polygon (since the full convex hull is triangulated) - CGAL::mark_domain_in_triangulation(cdt); + std::unordered_map in_domain_map; + boost::associative_property_map> in_domain(in_domain_map); + CGAL::mark_domain_in_triangulation(cdt, in_domain); DEBUG_ASSERT(cdt.is_valid()); // Build the resulting triangle mesh SimpleMesh3d result; - // Map from CGAL vertex handles to output mesh indices - std::unordered_map vertex_index_map; - + // insert new triangles and vertices for (const FaceHandle face : cdt.finite_face_handles()) { - if (!face->info()) { - // not inside polygon - continue; + if (!get(in_domain, face)) { + continue; // outside polygon } glm::uvec3 triangle; - for (uint32_t i = 0; i < 3; i++) { - const VertexHandle vertex = face->vertex(i); - auto [it, inserted] = vertex_index_map.emplace(vertex, 0); - if (inserted) { + for (int i = 0; i < 3; i++) { + const auto &vertex = face->vertex(i); + const auto &original_index = vertex->info(); + if (!original_index.has_value()) { const uint32_t new_index = result.positions.size(); const Point2 &cgal_point = vertex->point(); const glm::dvec2 point2d = convert::to_glm_point(cgal_point); const glm::dvec3 point3d = lift(point2d, basis); result.positions.push_back(point3d); - it->second = new_index; + triangle[i] = new_index; + } else { + triangle[i] = original_index.value(); } - triangle[i] = it->second; } result.triangles.push_back(triangle); } return result; - */ } } diff --git a/src/terrainlib/polygon/utils.cpp b/src/terrainlib/polygon/utils.cpp index 7bd38ba..4755b66 100644 --- a/src/terrainlib/polygon/utils.cpp +++ b/src/terrainlib/polygon/utils.cpp @@ -3,7 +3,7 @@ #include "polygon/utils.h" - namespace polygon { +namespace polygon { bool is_planar(const Polygon3d &polygon, const double epsilon) { if (polygon.size() < 4) { return true; // 3 points always define a plane @@ -34,7 +34,7 @@ bool is_planar(const Polygon3d &polygon, const double epsilon) { for (const auto &p : polygon.points) { const double distance = std::abs(glm::dot(p - p0, normal)); if (distance > epsilon) { - return false; + // return false; } } return true; From 87ba7673d52fa7789dffccc921d61cf611876591 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 26 Sep 2025 14:36:43 +0200 Subject: [PATCH 116/122] Fix hole filling between merged meshes --- src/terrainlib/mesh/holes.cpp | 36 +- src/terrainlib/mesh/holes.h | 4 +- src/terrainlib/polygon/triangulate.cpp | 79 +--- src/terrainmerger/NodeWriter.h | 1 + src/terrainmerger/merge/visitor/Masked.h | 446 +++++++++++++------ unittests/CMakeLists.txt | 1 + unittests/terrainlib/mesh_holes.cpp | 2 +- unittests/terrainlib/polygon_triangulate.cpp | 187 ++++++++ 8 files changed, 554 insertions(+), 202 deletions(-) create mode 100644 unittests/terrainlib/polygon_triangulate.cpp diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp index 5bf876e..b74495e 100644 --- a/src/terrainlib/mesh/holes.cpp +++ b/src/terrainlib/mesh/holes.cpp @@ -158,21 +158,32 @@ std::vector> find_holes(const SimpleMesh &mesh) { } namespace { +bool is_shared_vertex( + const VertexIndex vertex_index, + const mesh::merging::VertexMapping &mapping) { + bool first_source_mesh_found = false; + for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { + const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); + if (!source_vertex.has_value()) { + continue; + } + if (first_source_mesh_found) { + return true; + } + first_source_mesh_found = true; + } + return false; +} + bool contains_shared_vertex( const std::span vertices_in_merged_mesh, const mesh::merging::VertexMapping &mapping) { - FixedVector source_meshes; for (const VertexIndex vertex_index : vertices_in_merged_mesh) { - for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { - const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); - if (source_vertex.has_value()) { - source_meshes.push_back(source_vertex.value()); - if (source_meshes.size() > 1) { - return true; - } - } + if (is_shared_vertex(vertex_index, mapping)) { + return true; } } + return false; } } // namespace @@ -343,12 +354,13 @@ std::vector> find_holes_between_meshes( return holes; }*/ -void fill_planar_hole(SimpleMesh &mesh, const std::span hole) { +void fill_planar_hole(SimpleMesh &mesh, std::vector hole) { + std::reverse(hole.begin(), hole.end()); polygon::triangulate(mesh, hole); } -void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes) { - for (const auto& hole : holes) { +void fill_planar_holes(SimpleMesh &mesh, std::vector> holes) { + for (auto& hole : holes) { fill_planar_hole(mesh, hole); } } diff --git a/src/terrainlib/mesh/holes.h b/src/terrainlib/mesh/holes.h index 6d7aebe..f78b6cf 100644 --- a/src/terrainlib/mesh/holes.h +++ b/src/terrainlib/mesh/holes.h @@ -10,8 +10,8 @@ namespace mesh { std::vector> find_boundaries(const SimpleMesh &mesh); std::vector> find_holes(const SimpleMesh &mesh); std::vector> find_holes_on_merge_border(const SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping); -void fill_planar_hole(SimpleMesh &mesh, const std::span hole); -void fill_planar_holes(SimpleMesh &mesh, const std::vector> holes); +void fill_planar_hole(SimpleMesh &mesh, std::vector hole); +void fill_planar_holes(SimpleMesh &mesh, std::vector> holes); void fill_holes_on_merge_border(SimpleMesh &mesh, const mesh::merging::VertexMapping &mapping); std::vector> find_holes_between_meshes( const std::span> &meshes, diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp index 5ce3aa1..8c044b0 100644 --- a/src/terrainlib/polygon/triangulate.cpp +++ b/src/terrainlib/polygon/triangulate.cpp @@ -58,11 +58,12 @@ glm::dvec3 lift(const glm::dvec2 &q, const PlaneBasis &basis) { } -// TODO: deduplicate overloads void triangulate(SimpleMesh3d &mesh, const std::span indices) { if (indices.size() < 3) { return; } + + DEBUG_ASSERT(indices.size() <= mesh.positions.size()); // Build the 3D points of the polygon Polygon3d polygon; @@ -72,9 +73,6 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { polygon.points.push_back(mesh.positions[vertex_index]); } - // Holes are oriented CW - std::reverse(polygon.points.begin(), polygon.points.end()); - DEBUG_ASSERT(polygon::is_planar(polygon)); const PlaneBasis basis = make_basis(polygon); @@ -102,27 +100,29 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { CGAL::mark_domain_in_triangulation(cdt, in_domain); DEBUG_ASSERT(cdt.is_valid()); - // insert new triangles and vertices + // Insert new triangles and vertices for (const FaceHandle face : cdt.finite_face_handles()) { if (!get(in_domain, face)) { - continue; // outside polygon + // outside the polygon + continue; } glm::uvec3 triangle; for (int i = 0; i < 3; i++) { const auto &vertex = face->vertex(i); - const auto &original_index = vertex->info(); + auto &original_index = vertex->info(); if (!original_index.has_value()) { const uint32_t new_index = mesh.positions.size(); - const Point2 &cgal_point = vertex->point(); - const glm::dvec2 point2d = convert::to_glm_point(cgal_point); + const glm::dvec2 point2d = convert::to_glm_point(vertex->point()); const glm::dvec3 point3d = lift(point2d, basis); mesh.positions.push_back(point3d); if (mesh.has_uvs()) { - const glm::dvec2 uv = {0, 0}; - mesh.uvs.push_back(uv); + mesh.uvs.push_back({0, 0}); } triangle[i] = new_index; + // Don't add steiner points multiple times + *original_index = new_index; + DEBUG_ASSERT(face->vertex(i)->info().value() == new_index); } else { triangle[i] = original_index.value(); } @@ -133,53 +133,18 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { } SimpleMesh3d triangulate(const Polygon3d &polygon) { - DEBUG_ASSERT(polygon::is_planar(polygon)); - const PlaneBasis basis = make_basis(polygon); - - CDT cdt; - // insert edges - for (size_t i = 0; i < polygon.size(); i++) { - const glm::dvec2 a = project(polygon.points[i], basis); - const glm::dvec2 b = project(polygon.points[(i + 1) % polygon.size()], basis); - cdt.insert_constraint( - convert::to_cgal_point(a), - convert::to_cgal_point(b) - ); + // Copy polygon points into a mesh + SimpleMesh3d mesh; + mesh.positions = polygon.points; + + // Build indices [0..N-1] for the helper + std::vector indices(polygon.points.size()); + for (uint32_t i = 0; i < polygon.points.size(); i++) { + indices[i] = i; } - // Mark facets that are inside the domain bounded by the polygon (since the full convex hull is triangulated) - std::unordered_map in_domain_map; - boost::associative_property_map> in_domain(in_domain_map); - CGAL::mark_domain_in_triangulation(cdt, in_domain); - DEBUG_ASSERT(cdt.is_valid()); - - // Build the resulting triangle mesh - SimpleMesh3d result; - // insert new triangles and vertices - for (const FaceHandle face : cdt.finite_face_handles()) { - if (!get(in_domain, face)) { - continue; // outside polygon - } - - glm::uvec3 triangle; - for (int i = 0; i < 3; i++) { - const auto &vertex = face->vertex(i); - const auto &original_index = vertex->info(); - if (!original_index.has_value()) { - const uint32_t new_index = result.positions.size(); - const Point2 &cgal_point = vertex->point(); - const glm::dvec2 point2d = convert::to_glm_point(cgal_point); - const glm::dvec3 point3d = lift(point2d, basis); - result.positions.push_back(point3d); - triangle[i] = new_index; - } else { - triangle[i] = original_index.value(); - } - } - - result.triangles.push_back(triangle); - } - - return result; + triangulate(mesh, indices); + return mesh; } + } diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index 3cf0112..dc0af1f 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -25,6 +25,7 @@ class NodeWriter { void write_node(const octree::Id &id, const SimpleMesh &mesh) { mesh::validate(mesh); DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); + cv::imwrite("tex_" + std::to_string(id.level()) + "_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".png", mesh.texture.value()); } void copy_subtree_to_output( diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 8e3c64b..1c91e52 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -6,14 +6,16 @@ #include "merge/NodeData.h" #include "merge/Result.h" #include "merge/visitor/Visitor.h" -#include "mesh/holes.h" #include "mesh/combine.h" +#include "mesh/holes.h" #include "mesh/merging/SphereProjectionVertexDeduplicate.h" #include "mesh/merging/VertexMapping.h" #include "mesh/merging/helpers.h" #include "mesh/merging/mapping.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" +#include "polygon/Polygon.h" +#include "polygon/triangulate.h" #include "spatial_lookup/Hashmap.h" #include "utils.h" @@ -81,122 +83,281 @@ inline uint32_t compute_resolution( return std::clamp(result, 512u, 4096u); } -inline Atlas generate_texture_atlas( - const std::span> meshes -) { - xatlas::Atlas *atlas = xatlas::Create(); - - for (const SimpleMesh &mesh : meshes) { - const xatlas::UvMeshDecl decl = to_uvmeshdecl(mesh); - const xatlas::AddMeshError error = xatlas::AddUvMesh(atlas, decl); - if (error != xatlas::AddMeshError::Success) { - xatlas::Destroy(atlas); - LOG_ERROR_AND_EXIT("Error adding mesh {}", xatlas::StringForEnum(error)); +inline Atlas generate_texture_atlas_grid( + const std::span> meshes) { + + // Identify meshes that have textures and find maximum texture size + std::vector textured_mesh_indices; + size_t maximum_texture_width = 0; + size_t maximum_texture_height = 0; + + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index].get(); + if (mesh.texture.has_value()) { + textured_mesh_indices.push_back(mesh_index); + const cv::Mat &texture_image = mesh.texture.value(); + maximum_texture_width = std::max(maximum_texture_width, static_cast(texture_image.cols)); + maximum_texture_height = std::max(maximum_texture_height, static_cast(texture_image.rows)); } } - xatlas::ChartOptions chartOptions{}; - chartOptions.useInputMeshUvs = true; + Atlas result; + result.uvs.resize(meshes.size()); + + if (textured_mesh_indices.empty()) { + // No textures: assign (0,0) UVs for all meshes + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index].get(); + result.uvs[mesh_index].assign(mesh.vertex_count(), glm::dvec2(0.0, 0.0)); + } + return result; + } - xatlas::PackOptions packOptions{}; - packOptions.padding = 2; - packOptions.resolution = compute_resolution(meshes); + const size_t number_of_textured_meshes = textured_mesh_indices.size(); + const size_t grid_size = static_cast(std::ceil(std::sqrt(static_cast(number_of_textured_meshes)))); + const size_t atlas_width = next_pow2(grid_size * maximum_texture_width); + const size_t atlas_height = next_pow2(grid_size * maximum_texture_height); - xatlas::Generate(atlas, chartOptions, packOptions); + // Create transparent atlas image + const int atlas_type = meshes[textured_mesh_indices[0]].get().texture->type(); + cv::Mat atlas_image(atlas_height, atlas_width, atlas_type, cv::Scalar(0, 0, 0, 0)); - Atlas result; - result.uvs.resize(meshes.size()); + size_t slot_index = 0; for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh & mesh = meshes[mesh_index]; + const SimpleMesh &mesh = meshes[mesh_index].get(); result.uvs[mesh_index].resize(mesh.vertex_count()); - } - for (size_t mesh_index = 0; mesh_index < atlas->meshCount; mesh_index++) { - const xatlas::Mesh &xmesh = atlas->meshes[mesh_index]; + if (mesh.texture.has_value() && !mesh.uvs.empty()) { + const size_t row = slot_index / grid_size; + const size_t column = slot_index % grid_size; - for (size_t vertex_index = 0; vertex_index < xmesh.vertexCount; vertex_index++) { - const xatlas::Vertex& vertex = xmesh.vertexArray[vertex_index]; - result.uvs[mesh_index][vertex.xref] = glm::dvec2(vertex.uv[0], vertex.uv[1]); - } - } + const cv::Rect destination_rectangle( + static_cast(column * maximum_texture_width), + static_cast(row * maximum_texture_height), + mesh.texture->cols, + mesh.texture->rows); + mesh.texture->copyTo(atlas_image(destination_rectangle)); - cv::Mat mat(atlas->height, atlas->width, CV_8UC4, atlas->image); - result.texture = mat.clone(); + const double u_start = static_cast(column * maximum_texture_width) / atlas_width; + const double v_start = static_cast(row * maximum_texture_height) / atlas_height; + const double u_end = static_cast(column * maximum_texture_width + mesh.texture->cols) / atlas_width; + const double v_end = static_cast(row * maximum_texture_height + mesh.texture->rows) / atlas_height; - xatlas::Destroy(atlas); + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + const glm::dvec2 &original_uv = mesh.uvs[vertex_index]; + result.uvs[mesh_index][vertex_index] = glm::dvec2( + u_start + original_uv.x * (u_end - u_start), + v_start + original_uv.y * (v_end - v_start)); + } + + slot_index++; + } else { + // No texture or no UVs: fill with (0,0) + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + result.uvs[mesh_index][vertex_index] = glm::dvec2(0.0, 0.0); + } + } + } + result.texture = atlas_image; return result; } -// Simple grid-based atlas using the largest texture size -inline Atlas generate_texture_atlas_grid( - const std::span> meshes) { - // Identify meshes that actually have textures - std::vector meshes_with_textures; - int max_texture_width = 0; - int max_texture_height = 0; - - for (size_t i = 0; i < meshes.size(); ++i) { - if (meshes[i].get().texture.has_value()) { - meshes_with_textures.push_back(i); - const cv::Mat &tex = meshes[i].get().texture.value(); - max_texture_width = std::max(max_texture_width, tex.cols); - max_texture_height = std::max(max_texture_height, tex.rows); - } +#include +#include +#include +#include + +#include +#include +#include + +inline void export_mesh_with_edges( + SimpleMesh mesh, + const std::vector &highlighted_edges, + const std::string &obj_path, + const std::string &mtl_name = "edges.mtl") { + if (mesh.positions.empty()) { + throw std::runtime_error("Mesh has no positions"); } - if (meshes_with_textures.empty()) { - return Atlas{}; // No textures to pack + // --- normalize mesh --- + glm::dvec3 min_pt = mesh.positions[0]; + glm::dvec3 max_pt = mesh.positions[0]; + for (const auto &v : mesh.positions) { + min_pt = glm::min(min_pt, v); + max_pt = glm::max(max_pt, v); + } + glm::dvec3 center = (min_pt + max_pt) * 0.5; + glm::dvec3 extent = max_pt - min_pt; + double scale = std::max({extent.x, extent.y, extent.z}); + if (scale == 0.0) + scale = 1.0; + for (auto &v : mesh.positions) { + v = (v - center) / scale; } - size_t number_of_textured_meshes = meshes_with_textures.size(); - size_t grid_size = static_cast(std::ceil(std::sqrt(number_of_textured_meshes))); + // --- open OBJ --- + std::ofstream out(obj_path); + if (!out) + throw std::runtime_error("Cannot open: " + obj_path); - int atlas_width = next_pow2(static_cast(grid_size * max_texture_width)); - int atlas_height = next_pow2(static_cast(grid_size * max_texture_height)); + out << "mtllib " << mtl_name << "\n"; - // Create atlas image with transparent background - cv::Mat atlas_image(atlas_height, atlas_width, meshes[meshes_with_textures[0]].get().texture->type(), cv::Scalar(0, 0, 0, 0)); + // base mesh vertices + for (const auto &v : mesh.positions) { + out << "v " << v.x << " " << v.y << " " << v.z << "\n"; + } - Atlas result; - result.uvs.resize(meshes.size()); + // faces + for (const auto &tri : mesh.triangles) { + out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; + } - size_t slot_index = 0; - for (size_t mesh_index : meshes_with_textures) { - const SimpleMesh &mesh = meshes[mesh_index].get(); - int row = slot_index / grid_size; - int column = slot_index % grid_size; + // --- edges as quads with red material --- + out << "o highlighted_edges\n"; + out << "usemtl highlighted\n"; + + int vertex_index = static_cast(mesh.positions.size()); + for (const auto &e : highlighted_edges) { + glm::dvec3 a = mesh.positions[e.x]; + glm::dvec3 b = mesh.positions[e.y]; + + glm::dvec3 dir = glm::normalize(b - a); + glm::dvec3 up(0, 0, 1); + if (glm::abs(glm::dot(dir, up)) > 0.9) + up = glm::dvec3(0, 1, 0); + glm::dvec3 offset = glm::normalize(glm::cross(dir, up)) * 0.00002; // thickness + + // four new vertices + out << "v " << (a - offset).x << " " << (a - offset).y << " " << (a - offset).z << "\n"; + out << "v " << (a + offset).x << " " << (a + offset).y << " " << (a + offset).z << "\n"; + out << "v " << (b + offset).x << " " << (b + offset).y << " " << (b + offset).z << "\n"; + out << "v " << (b - offset).x << " " << (b - offset).y << " " << (b - offset).z << "\n"; + + int base = ++vertex_index; + out << "f " << base << " " << base + 1 << " " << base + 2 << "\n"; + out << "f " << base << " " << base + 2 << " " << base + 3 << "\n"; + vertex_index += 3; + } - // Compute destination rectangle in atlas - cv::Rect destination_rectangle( - column * max_texture_width, - row * max_texture_height, - mesh.texture->cols, - mesh.texture->rows); + out.close(); + + // --- MTL --- + std::string dir; + auto pos = obj_path.find_last_of("/\\"); + if (pos != std::string::npos) + dir = obj_path.substr(0, pos + 1); + std::string mtl_path = dir + mtl_name; + + std::ofstream mtl_out(mtl_path); + if (!mtl_out) + throw std::runtime_error("Cannot open: " + mtl_path); + + mtl_out << "newmtl highlighted\n"; + mtl_out << "Kd 1.0 0.0 0.0\n"; // red + mtl_out << "Ka 0.0 0.0 0.0\n"; + mtl_out << "Ks 0.0 0.0 0.0\n"; + mtl_out << "d 1.0\n"; + mtl_out << "illum 1\n"; +} - // Copy the mesh's texture into the atlas - mesh.texture->copyTo(atlas_image(destination_rectangle)); +#include +#include +#include + +inline void export_two_meshes( + SimpleMesh mesh_a, + SimpleMesh mesh_b, + const std::string &obj_path, + const std::string &mtl_name = "two_meshes.mtl") { + if (mesh_a.positions.empty() || mesh_b.positions.empty()) { + throw std::runtime_error("One of the meshes has no positions"); + } - // Update UV coordinates to map the mesh's full texture to its slot - result.uvs[mesh_index].resize(mesh.vertex_count()); - double u_start = double(column * max_texture_width) / atlas_width; - double v_start = double(row * max_texture_height) / atlas_height; - double u_end = double(column * max_texture_width + mesh.texture->cols) / atlas_width; - double v_end = double(row * max_texture_height + mesh.texture->rows) / atlas_height; - - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); ++vertex_index) { - const auto &original_uv = mesh.uvs[vertex_index]; - result.uvs[mesh_index][vertex_index] = glm::dvec2( - u_start + original_uv.x * (u_end - u_start), - v_start + original_uv.y * (v_end - v_start)); - } + // --- compute joint normalization --- + glm::dvec3 min_pt = mesh_a.positions[0]; + glm::dvec3 max_pt = mesh_a.positions[0]; + auto update_bounds = [&](const glm::dvec3 &v) { + min_pt = glm::min(min_pt, v); + max_pt = glm::max(max_pt, v); + }; + for (const auto &v : mesh_a.positions) + update_bounds(v); + for (const auto &v : mesh_b.positions) + update_bounds(v); + + glm::dvec3 center = (min_pt + max_pt) * 0.5; + glm::dvec3 extent = max_pt - min_pt; + double scale = std::max({extent.x, extent.y, extent.z}); + if (scale == 0.0) + scale = 1.0; + + for (auto &v : mesh_a.positions) + v = (v - center) / scale; + for (auto &v : mesh_b.positions) + v = (v - center) / scale; + + // --- write OBJ --- + std::ofstream out(obj_path); + if (!out) + throw std::runtime_error("Cannot open: " + obj_path); + + out << "mtllib " << mtl_name << "\n"; + + // Mesh A + out << "o mesh_a\n"; + out << "usemtl color_a\n"; + for (const auto &v : mesh_a.positions) { + out << "v " << v.x << " " << v.y << " " << v.z << "\n"; + } + for (const auto &tri : mesh_a.triangles) { + out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; + } - ++slot_index; + // Mesh B + out << "o mesh_b\n"; + out << "usemtl color_b\n"; + int vertex_offset = static_cast(mesh_a.positions.size()); + for (const auto &v : mesh_b.positions) { + out << "v " << v.x << " " << v.y << " " << v.z << "\n"; + } + for (const auto &tri : mesh_b.triangles) { + out << "f " + << (tri.x + 1 + vertex_offset) << " " + << (tri.y + 1 + vertex_offset) << " " + << (tri.z + 1 + vertex_offset) << "\n"; } - result.texture = atlas_image; - return result; + out.close(); + + // --- write MTL --- + std::string dir; + auto pos = obj_path.find_last_of("/\\"); + if (pos != std::string::npos) + dir = obj_path.substr(0, pos + 1); + std::string mtl_path = dir + mtl_name; + + std::ofstream mtl_out(mtl_path); + if (!mtl_out) + throw std::runtime_error("Cannot open: " + mtl_path); + + // color for mesh A (blue) + mtl_out << "newmtl color_a\n"; + mtl_out << "Kd 0.0 0.0 1.0\n"; + mtl_out << "Ka 0.0 0.0 0.0\n"; + mtl_out << "Ks 0.0 0.0 0.0\n"; + mtl_out << "d 1.0\n"; + mtl_out << "illum 1\n"; + + // color for mesh B (green) + mtl_out << "newmtl color_b\n"; + mtl_out << "Kd 0.0 1.0 0.0\n"; + mtl_out << "Ka 0.0 0.0 0.0\n"; + mtl_out << "Ks 0.0 0.0 0.0\n"; + mtl_out << "d 1.0\n"; + mtl_out << "illum 1\n"; } class Masked { @@ -209,7 +370,7 @@ class Masked { }; using Result = merge::Result; - explicit Masked(MeshMask mask, octree::Space space) : _mask(mask), _space(space) { } + explicit Masked(MeshMask mask, octree::Space space) : _mask(mask), _space(space) {} Context make_root_context() { return Context{ @@ -239,10 +400,11 @@ class Masked { // If the parent mask is empty, we can just return whatevers on the left if constexpr (left.status() != Status::Missing) { if (ctx.mask.mesh.is_empty()) { + return Ignore{}; return Unchanged{Source::Left}; } } - + LOG_TRACE("Clipping mask for {}", id); const auto bounds = pad_bounds(this->_space.get_node_bounds(id), 1.1); MeshMask mask(mesh::clip_on_bounds_and_cap(ctx.mask.mesh, bounds)); @@ -250,20 +412,21 @@ class Masked { // Same when the current mask is empty if constexpr (left.status() != Status::Missing) { if (mask.mesh.is_empty()) { + return Ignore{}; return Unchanged{Source::Left}; } } // If we have two leaf nodes we can directly merge them. if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { - return this->merge_meshes(left.mesh(), right.mesh(), true, true, mask); + return this->merge_meshes(id, left.mesh(), right.mesh(), true, true, mask); } // If we have a left leaf we either directly return it (after clipping) // or merge if right has a non-missing parent if constexpr (left.status() == Status::Leaf && right.status() == Status::Missing) { if (ctx.has_right_parent) { - return this->merge_meshes(left.mesh(), right.mesh().value(), true, false, mask); + return this->merge_meshes(id, left.mesh(), right.mesh().value(), true, false, mask); } // Right node is actually missing, just return the clipped left node @@ -276,12 +439,12 @@ class Masked { return Merged{result}; } } - + // If we have a right leaf we either directly return it (after clipping) // or merge if left has a non-missing parent if constexpr (left.status() == Status::Missing && right.status() == Status::Leaf) { if (ctx.has_left_parent) { - return this->merge_meshes(left.mesh().value(), right.mesh(), false, true, mask); + return this->merge_meshes(id, left.mesh().value(), right.mesh(), false, true, mask); } // Left node is actually missing, just return the clipped right node @@ -320,9 +483,7 @@ class Masked { Context{ .mask = mask, .has_left_parent = ctx.has_left_parent || left.status() == Status::Leaf, - .has_right_parent = ctx.has_right_parent || right.status() == Status::Leaf - } - }; + .has_right_parent = ctx.has_right_parent || right.status() == Status::Leaf}}; } UNREACHABLE(); @@ -330,6 +491,7 @@ class Masked { private: Result merge_meshes( + const octree::Id &id, const SimpleMesh &base_mesh, const SimpleMesh &new_mesh, const bool can_ref_base_mesh, @@ -339,6 +501,7 @@ class Masked { const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { + return Ignore{}; if (can_ref_base_mesh) { return Unchanged{Source::Left}; } else { @@ -346,6 +509,7 @@ class Masked { } } if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { + return Ignore{}; if (can_ref_new_mesh) { return Unchanged{Source::Right}; } else { @@ -365,52 +529,74 @@ class Masked { const double radius = glm::length(tangent_point); mesh::merging::SphereProjectionVertexDeduplicate< mesh::merging::VertexId, - decltype(map) - > deduplicate(map, distance_epsilon, radius); + decltype(map)> + deduplicate(map, distance_epsilon, radius); const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, - mesh::merging::create_options().deduplicate(deduplicate).only_consider_boundary(true)); + mesh::merging::create_options() + .deduplicate(deduplicate) + .only_consider_boundary(true)); + + LOG_TRACE("Creating merged mesh"); + const SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, + mesh::merging::apply_options() + .deduplicate_triangles(false) + .merge_uvs(false)); + + LOG_TRACE("Filling holes on merge border"); + const auto holes = mesh::find_holes_on_merge_border(merged_mesh, mapping); + Polygon3d polygon; + SimpleMesh3d hole_mesh; + for (const auto &hole : holes) { + polygon.points.clear(); + for (const size_t vertex_index : hole) { + const glm::dvec3 position = merged_mesh.positions[vertex_index]; + polygon.points.push_back(position); + } + std::reverse(polygon.points.begin(), polygon.points.end()); + const SimpleMesh3d patch = polygon::triangulate(polygon); + // mesh::combine_inplace(hole_mesh, patch); + hole_mesh = mesh::combine(std::array{hole_mesh, patch}); + } + hole_mesh.uvs.insert(hole_mesh.uvs.end(), hole_mesh.vertex_count(), glm::dvec2(0)); + + std::vector edges; + for (const auto &hole : holes) { + for (size_t i = 0; i < hole.size(); i++) { + const SimpleMesh::Edge edge( + hole[i], + hole[(i + 1) % hole.size()]); + edges.push_back(edge); + } + } + const std::filesystem::path mesh_path = "/mnt/c/Users/Admin/Downloads/out-merge2/merged_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".obj"; + export_mesh_with_edges(merged_mesh, edges, mesh_path.string()); + export_two_meshes(merged_mesh, hole_mesh, mesh_path.string() + ".two.obj"); + export_mesh_with_edges(hole_mesh, {}, mesh_path.string() + ".holes.obj"); + mesh::validate(merged_mesh); + mesh::validate(hole_mesh); LOG_TRACE("Creating combined mesh"); + const std::array, 3> meshes_and_patches = {meshes[0], meshes[1], hole_mesh}; std::vector vertex_offsets; - SimpleMesh merged_mesh = mesh::combine(meshes, vertex_offsets); - - // Find holes between meshes - LOG_TRACE("Triangulating region between meshes"); - const std::vector> holes = mesh::find_holes_between_meshes(meshes, mapping); - std::vector> mapped_holes; - mapped_holes.reserve(holes.size()); - for (const auto& hole : holes) { - std::vector mapped_hole; - mapped_hole.reserve(hole.size()); - for (const auto& vertex_id : hole) { - const size_t mapped_index = vertex_offsets[vertex_id.mesh_index] + vertex_id.vertex_index; - mapped_hole.push_back(mapped_index); - } - } + SimpleMesh result_mesh = mesh::combine(meshes_and_patches, vertex_offsets); LOG_TRACE("Generating combined texture"); - Atlas atlas = generate_texture_atlas_grid(meshes); - merged_mesh.texture = std::move(atlas.texture); - for (size_t mesh_index=0; mesh_index outer_loop = {0, 1, 2, 3}; - const std::vector inner_loop = {4, 5, 6, 7}; + const std::vector inner_loop = {7, 6, 5, 4}; // {4, 5, 6, 7}; const auto holes = mesh::find_holes(mesh); CHECK(holes.size() == 1); diff --git a/unittests/terrainlib/polygon_triangulate.cpp b/unittests/terrainlib/polygon_triangulate.cpp new file mode 100644 index 0000000..dcff2b0 --- /dev/null +++ b/unittests/terrainlib/polygon_triangulate.cpp @@ -0,0 +1,187 @@ +#include "../catch2_helpers.h" + +#include +#include +#include + +#include + +#include "mesh/SimpleMesh.h" +#include "mesh/validate.h" +#include "polygon/triangulate.h" + + +TEST_CASE("triangulate handles minimal input") { + SimpleMesh3d mesh; + + SECTION("Empty indices") { + std::vector indices; + polygon::triangulate(mesh, indices); + REQUIRE(mesh.positions.empty()); + REQUIRE(mesh.triangles.empty()); + } + + SECTION("Single vertex") { + mesh.positions.push_back({0, 0, 0}); + std::vector indices = {0}; + polygon::triangulate(mesh, indices); + REQUIRE(mesh.triangles.empty()); + } + + SECTION("Two vertices") { + mesh.positions.push_back({0, 0, 0}); + mesh.positions.push_back({1, 0, 0}); + std::vector indices = {0, 1}; + polygon::triangulate(mesh, indices); + REQUIRE(mesh.triangles.empty()); + } +} + +TEST_CASE("triangulate handles a simple triangle") { + SimpleMesh3d mesh; + mesh.positions.push_back({0, 0, 0}); + mesh.positions.push_back({1, 0, 0}); + mesh.positions.push_back({0, 1, 0}); + + std::vector indices = {0, 1, 2}; + polygon::triangulate(mesh, indices); + + REQUIRE(mesh.triangles.size() == 1); + CHECK(compare_equality_triangles(mesh.triangles[0], {0, 1, 2})); +} + +void check_every_vertex_used_at_least_once(const SimpleMesh3d &mesh) { + std::vector counts(mesh.positions.size(), 0); + for (const auto &triangle : mesh.triangles) { + for (size_t i = 0; i < 3; i++) { + const uint32_t vertex_index = triangle[i]; + counts[vertex_index]++; + } + } + + for (size_t i = 0; i < mesh.positions.size(); i++) { + CHECK(counts[i] >= 1); + } +} + +TEST_CASE("triangulate handles a square") { + SimpleMesh3d mesh; + mesh.positions.push_back({0, 0, 0}); + mesh.positions.push_back({1, 0, 0}); + mesh.positions.push_back({1, 1, 0}); + mesh.positions.push_back({0, 1, 0}); + + std::vector indices = {0, 1, 2, 3}; + polygon::triangulate(mesh, indices); + + REQUIRE(mesh.triangles.size() == 2); // A square should produce 2 triangles + check_every_vertex_used_at_least_once(mesh); + mesh::validate(mesh); +} + +TEST_CASE("triangulate works with UVs") { + SimpleMesh3d mesh; + mesh.positions.push_back({0, 0, 0}); + mesh.positions.push_back({1, 0, 0}); + mesh.positions.push_back({1, 1, 0}); + mesh.positions.push_back({0, 1, 0}); + mesh.uvs.resize(4); + + std::vector indices = {0, 1, 2, 3}; + polygon::triangulate(mesh, indices); + + REQUIRE(mesh.uvs.size() == mesh.positions.size()); +} + +std::optional intersection( + const glm::uvec2 &e1, + const glm::uvec2 &e2, + const std::span &positions) { + const glm::dvec2 &p = positions[e1.x]; + const glm::dvec2 r = positions[e1.y] - positions[e1.x]; + + const glm::dvec2 &q = positions[e2.x]; + const glm::dvec2 s = positions[e2.y] - positions[e2.x]; + + double rxs = r.x * s.y - r.y * s.x; // 2D cross product + glm::dvec2 qmp = q - p; + double qpxr = qmp.x * r.y - qmp.y * r.x; + + if (std::abs(rxs) < 1e-6) { + return std::nullopt; // Lines are parallel + } + + double t = (qmp.x * s.y - qmp.y * s.x) / rxs; + double u = qpxr / rxs; + + if (t >= 0.0 && t <= 1.0 && u >= 0.0 && u <= 1.0) { + return p + t * r; // intersection point + } + + return std::nullopt; // No intersection +} + +TEST_CASE("triangulate handles U-shaped polygon") { + SimpleMesh3d mesh; + + // Define U-shape polygon + mesh.positions.push_back({0, 0, 0}); // 0 + mesh.positions.push_back({3, 0, 0}); // 1 + mesh.positions.push_back({3, 1, 0}); // 2 + mesh.positions.push_back({2, 1, 0}); // 3 + mesh.positions.push_back({2, 2, 0}); // 4 + mesh.positions.push_back({1, 2, 0}); // 5 + mesh.positions.push_back({1, 1, 0}); // 6 + mesh.positions.push_back({0, 1, 0}); // 7 + + std::vector indices = {0, 1, 2, 3, 4, 5, 6, 7}; + + polygon::triangulate(mesh, indices); + REQUIRE(!mesh.triangles.empty()); + check_every_vertex_used_at_least_once(mesh); + mesh::validate(mesh); + + // Check that all boundary edges are present in the triangulation + const std::vector boundary_edges = { + {0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 0} + }; + std::vector edges; + for (const auto &triangle : mesh.triangles) { + for (size_t i = 0; i < 3; i++) { + const glm::uvec2 edge = {triangle[i], triangle[(i + 1) % 3]}; + edges.push_back(edge); + } + } + for (const auto &boundary_edge : boundary_edges) { + bool found = false; + for (const auto &edge : edges) { + if (boundary_edge == edge) { + found = true; + break; + } + } + CHECK(found); + } + + // Check that no edge crosses the polygon boundary + std::vector positions_2d; + for (const auto &position : mesh.positions) { + positions_2d.push_back({position.x, position.y}); + } + + for (const auto &edge : edges) { + for (const auto& boundary_edge : boundary_edges) { + const auto intersection_opt = intersection(edge, boundary_edge, positions_2d); + if (intersection_opt.has_value()) { + const glm::dvec2 intersection_point = intersection_opt.value(); + // Check if the intersection point is not an endpoint of either edge + if (intersection_point != positions_2d[edge.x] && + intersection_point != positions_2d[edge.y] && + intersection_point != positions_2d[boundary_edge.x] && + intersection_point != positions_2d[boundary_edge.y]) { + FAIL("Edge crosses polygon boundary"); + } + } + } + } +} From 940b2275373fa08cd27e626830295842b821e91b Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 26 Sep 2025 14:42:08 +0200 Subject: [PATCH 117/122] Cleanup --- src/terrainlib/mesh/holes.cpp | 151 ------------- src/terrainmerger/NodeWriter.h | 1 - src/terrainmerger/merge/visitor/Masked.h | 260 +---------------------- 3 files changed, 4 insertions(+), 408 deletions(-) diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp index b74495e..11132de 100644 --- a/src/terrainlib/mesh/holes.cpp +++ b/src/terrainlib/mesh/holes.cpp @@ -203,157 +203,6 @@ std::vector> find_holes_on_merge_border( return holes; } -/* -namespace { -bool contains_shared_vertex( - const size_t source_mesh_index, - const std::span vertices_in_source_mesh, - const mesh::merging::VertexMapping &mapping) { - for (const VertexIndex vertex_index : vertices_in_source_mesh) { - for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { - if (mesh_index == source_mesh_index) { - continue; - } - - const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); - if (source_vertex.has_value()) { - return true; - } - } - } - return false; -} - -bool is_shared_vertex( - const merging::VertexId id, - const merging::VertexMapping &mapping -) { - for (size_t other_mesh_index = 0; other_mesh_index < mapping.mesh_count(); other_mesh_index++) { - if (other_mesh_index == id.mesh_index) { - continue; - } - - const std::optional source_vertex = mapping.map_backward(other_mesh_index, id.vertex_index); - if (source_vertex.has_value()) { - return true; - } - } - return false; -} -} // namespace - - -std::vector> find_holes_between_meshes( - const std::span> &meshes, - const merging::VertexMapping &mapping -) { - using Segment = std::vector; - - // Step 1: Extract all boundary segments betweem two shared vertices - std::forward_list boundary_segments; - std::vector shared_vertices_in_boundary; - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - - const std::vector> boundaries = find_boundaries(mesh); - for (const auto &boundary : boundaries) { - shared_vertices_in_boundary.clear(); - - // Find shared vertices - for (size_t index_in_boundary = 0; index_in_boundary < boundary.size(); index_in_boundary++) { - const merging::VertexId vertex = { - .mesh_index = mesh_index, - .vertex_index = boundary[index_in_boundary] - }; - - if (is_shared_vertex(vertex, mapping)) { - shared_vertices_in_boundary.push_back(index_in_boundary); - } - } - - // Discard if not shared boundary - if (shared_vertices_in_boundary.empty()) { - continue; - } - if (shared_vertices_in_boundary.size() % 2 == 1) { - LOG_WARN("Encountered boundary with only a single shared vertex, unable to generate geometry."); - continue; - } - - // Cut boundary into segments - for (size_t i = 0; i holes; - while (!boundary_segments.empty()) { - Segment current = std::move(boundary_segments.front()); - boundary_segments.pop_front(); - const size_t mesh_index = current[0].mesh_index; - - auto prev = boundary_segments.before_begin(); - auto it = boundary_segments.begin(); - - while (it != boundary_segments.end()) { - Segment &other = *it; - - if (other[0].mesh_index == mesh_index) { - if (current.back() == other.front()) { - Segment hole = std::move(current); - hole.insert(hole.end(), other.begin(), other.end()); - holes.push_back(std::move(hole)); - it = boundary_segments.erase_after(prev); - break; - } else if (current.front() == other.back()) { - Segment hole = std::move(other); - hole.insert(hole.end(), current.begin(), current.end()); - holes.push_back(std::move(hole)); - it = boundary_segments.erase_after(prev); - break; - } - } - - prev = it; - it++; - } - } - - return holes; -}*/ - void fill_planar_hole(SimpleMesh &mesh, std::vector hole) { std::reverse(hole.begin(), hole.end()); polygon::triangulate(mesh, hole); diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index dc0af1f..3cf0112 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -25,7 +25,6 @@ class NodeWriter { void write_node(const octree::Id &id, const SimpleMesh &mesh) { mesh::validate(mesh); DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); - cv::imwrite("tex_" + std::to_string(id.level()) + "_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".png", mesh.texture.value()); } void copy_subtree_to_output( diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 1c91e52..ed61e31 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "mask.h" #include "merge/NodeData.h" #include "merge/Result.h" @@ -21,40 +19,6 @@ namespace merge::visitor { -inline xatlas::MeshDecl to_meshdecl(const SimpleMesh &mesh) { - xatlas::MeshDecl decl{}; - - decl.indexCount = static_cast(mesh.triangles.size() * 3); - decl.indexData = mesh.triangles.data(); - decl.indexFormat = xatlas::IndexFormat::UInt32; - - decl.vertexCount = static_cast(mesh.positions.size()); - decl.vertexPositionData = mesh.positions.data(); - decl.vertexPositionStride = sizeof(SimpleMesh::Position); - - if (mesh.has_uvs()) { - decl.vertexUvData = mesh.uvs.data(); - decl.vertexUvStride = sizeof(SimpleMesh::Uv); - } - - return decl; -} - -inline xatlas::UvMeshDecl to_uvmeshdecl(const SimpleMesh &mesh) { - xatlas::UvMeshDecl decl{}; - - decl.indexCount = static_cast(mesh.triangles.size() * 3); - decl.indexData = mesh.triangles.data(); - decl.indexFormat = xatlas::IndexFormat::UInt32; - - ASSERT(mesh.has_uvs()); - decl.vertexUvData = mesh.uvs.data(); - decl.vertexCount = static_cast(mesh.uvs.size()); - decl.vertexStride = sizeof(SimpleMesh::Uv); - - return decl; -} - struct Atlas { std::vector> uvs; SimpleMesh::Texture texture; @@ -164,202 +128,6 @@ inline Atlas generate_texture_atlas_grid( return result; } -#include -#include -#include -#include - -#include -#include -#include - -inline void export_mesh_with_edges( - SimpleMesh mesh, - const std::vector &highlighted_edges, - const std::string &obj_path, - const std::string &mtl_name = "edges.mtl") { - if (mesh.positions.empty()) { - throw std::runtime_error("Mesh has no positions"); - } - - // --- normalize mesh --- - glm::dvec3 min_pt = mesh.positions[0]; - glm::dvec3 max_pt = mesh.positions[0]; - for (const auto &v : mesh.positions) { - min_pt = glm::min(min_pt, v); - max_pt = glm::max(max_pt, v); - } - glm::dvec3 center = (min_pt + max_pt) * 0.5; - glm::dvec3 extent = max_pt - min_pt; - double scale = std::max({extent.x, extent.y, extent.z}); - if (scale == 0.0) - scale = 1.0; - for (auto &v : mesh.positions) { - v = (v - center) / scale; - } - - // --- open OBJ --- - std::ofstream out(obj_path); - if (!out) - throw std::runtime_error("Cannot open: " + obj_path); - - out << "mtllib " << mtl_name << "\n"; - - // base mesh vertices - for (const auto &v : mesh.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - - // faces - for (const auto &tri : mesh.triangles) { - out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; - } - - // --- edges as quads with red material --- - out << "o highlighted_edges\n"; - out << "usemtl highlighted\n"; - - int vertex_index = static_cast(mesh.positions.size()); - for (const auto &e : highlighted_edges) { - glm::dvec3 a = mesh.positions[e.x]; - glm::dvec3 b = mesh.positions[e.y]; - - glm::dvec3 dir = glm::normalize(b - a); - glm::dvec3 up(0, 0, 1); - if (glm::abs(glm::dot(dir, up)) > 0.9) - up = glm::dvec3(0, 1, 0); - glm::dvec3 offset = glm::normalize(glm::cross(dir, up)) * 0.00002; // thickness - - // four new vertices - out << "v " << (a - offset).x << " " << (a - offset).y << " " << (a - offset).z << "\n"; - out << "v " << (a + offset).x << " " << (a + offset).y << " " << (a + offset).z << "\n"; - out << "v " << (b + offset).x << " " << (b + offset).y << " " << (b + offset).z << "\n"; - out << "v " << (b - offset).x << " " << (b - offset).y << " " << (b - offset).z << "\n"; - - int base = ++vertex_index; - out << "f " << base << " " << base + 1 << " " << base + 2 << "\n"; - out << "f " << base << " " << base + 2 << " " << base + 3 << "\n"; - vertex_index += 3; - } - - out.close(); - - // --- MTL --- - std::string dir; - auto pos = obj_path.find_last_of("/\\"); - if (pos != std::string::npos) - dir = obj_path.substr(0, pos + 1); - std::string mtl_path = dir + mtl_name; - - std::ofstream mtl_out(mtl_path); - if (!mtl_out) - throw std::runtime_error("Cannot open: " + mtl_path); - - mtl_out << "newmtl highlighted\n"; - mtl_out << "Kd 1.0 0.0 0.0\n"; // red - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; -} - -#include -#include -#include - -inline void export_two_meshes( - SimpleMesh mesh_a, - SimpleMesh mesh_b, - const std::string &obj_path, - const std::string &mtl_name = "two_meshes.mtl") { - if (mesh_a.positions.empty() || mesh_b.positions.empty()) { - throw std::runtime_error("One of the meshes has no positions"); - } - - // --- compute joint normalization --- - glm::dvec3 min_pt = mesh_a.positions[0]; - glm::dvec3 max_pt = mesh_a.positions[0]; - auto update_bounds = [&](const glm::dvec3 &v) { - min_pt = glm::min(min_pt, v); - max_pt = glm::max(max_pt, v); - }; - for (const auto &v : mesh_a.positions) - update_bounds(v); - for (const auto &v : mesh_b.positions) - update_bounds(v); - - glm::dvec3 center = (min_pt + max_pt) * 0.5; - glm::dvec3 extent = max_pt - min_pt; - double scale = std::max({extent.x, extent.y, extent.z}); - if (scale == 0.0) - scale = 1.0; - - for (auto &v : mesh_a.positions) - v = (v - center) / scale; - for (auto &v : mesh_b.positions) - v = (v - center) / scale; - - // --- write OBJ --- - std::ofstream out(obj_path); - if (!out) - throw std::runtime_error("Cannot open: " + obj_path); - - out << "mtllib " << mtl_name << "\n"; - - // Mesh A - out << "o mesh_a\n"; - out << "usemtl color_a\n"; - for (const auto &v : mesh_a.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - for (const auto &tri : mesh_a.triangles) { - out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; - } - - // Mesh B - out << "o mesh_b\n"; - out << "usemtl color_b\n"; - int vertex_offset = static_cast(mesh_a.positions.size()); - for (const auto &v : mesh_b.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - for (const auto &tri : mesh_b.triangles) { - out << "f " - << (tri.x + 1 + vertex_offset) << " " - << (tri.y + 1 + vertex_offset) << " " - << (tri.z + 1 + vertex_offset) << "\n"; - } - - out.close(); - - // --- write MTL --- - std::string dir; - auto pos = obj_path.find_last_of("/\\"); - if (pos != std::string::npos) - dir = obj_path.substr(0, pos + 1); - std::string mtl_path = dir + mtl_name; - - std::ofstream mtl_out(mtl_path); - if (!mtl_out) - throw std::runtime_error("Cannot open: " + mtl_path); - - // color for mesh A (blue) - mtl_out << "newmtl color_a\n"; - mtl_out << "Kd 0.0 0.0 1.0\n"; - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; - - // color for mesh B (green) - mtl_out << "newmtl color_b\n"; - mtl_out << "Kd 0.0 1.0 0.0\n"; - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; -} - class Masked { public: using Status = octree::NodeStatusOrMissing; @@ -419,14 +187,14 @@ class Masked { // If we have two leaf nodes we can directly merge them. if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { - return this->merge_meshes(id, left.mesh(), right.mesh(), true, true, mask); + return this->merge_meshes(left.mesh(), right.mesh(), true, true, mask); } // If we have a left leaf we either directly return it (after clipping) // or merge if right has a non-missing parent if constexpr (left.status() == Status::Leaf && right.status() == Status::Missing) { if (ctx.has_right_parent) { - return this->merge_meshes(id, left.mesh(), right.mesh().value(), true, false, mask); + return this->merge_meshes(left.mesh(), right.mesh().value(), true, false, mask); } // Right node is actually missing, just return the clipped left node @@ -444,7 +212,7 @@ class Masked { // or merge if left has a non-missing parent if constexpr (left.status() == Status::Missing && right.status() == Status::Leaf) { if (ctx.has_left_parent) { - return this->merge_meshes(id, left.mesh().value(), right.mesh(), false, true, mask); + return this->merge_meshes(left.mesh().value(), right.mesh(), false, true, mask); } // Left node is actually missing, just return the clipped right node @@ -491,7 +259,6 @@ class Masked { private: Result merge_meshes( - const octree::Id &id, const SimpleMesh &base_mesh, const SimpleMesh &new_mesh, const bool can_ref_base_mesh, @@ -501,7 +268,6 @@ class Masked { const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { - return Ignore{}; if (can_ref_base_mesh) { return Unchanged{Source::Left}; } else { @@ -509,7 +275,6 @@ class Masked { } } if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { - return Ignore{}; if (can_ref_new_mesh) { return Unchanged{Source::Right}; } else { @@ -554,27 +319,10 @@ class Masked { } std::reverse(polygon.points.begin(), polygon.points.end()); const SimpleMesh3d patch = polygon::triangulate(polygon); - // mesh::combine_inplace(hole_mesh, patch); - hole_mesh = mesh::combine(std::array{hole_mesh, patch}); + mesh::combine_inplace(hole_mesh, patch); } hole_mesh.uvs.insert(hole_mesh.uvs.end(), hole_mesh.vertex_count(), glm::dvec2(0)); - std::vector edges; - for (const auto &hole : holes) { - for (size_t i = 0; i < hole.size(); i++) { - const SimpleMesh::Edge edge( - hole[i], - hole[(i + 1) % hole.size()]); - edges.push_back(edge); - } - } - const std::filesystem::path mesh_path = "/mnt/c/Users/Admin/Downloads/out-merge2/merged_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".obj"; - export_mesh_with_edges(merged_mesh, edges, mesh_path.string()); - export_two_meshes(merged_mesh, hole_mesh, mesh_path.string() + ".two.obj"); - export_mesh_with_edges(hole_mesh, {}, mesh_path.string() + ".holes.obj"); - mesh::validate(merged_mesh); - mesh::validate(hole_mesh); - LOG_TRACE("Creating combined mesh"); const std::array, 3> meshes_and_patches = {meshes[0], meshes[1], hole_mesh}; std::vector vertex_offsets; From 0ac7383a9c0f26dc4fa54f0107267fd7d73c4ec3 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Fri, 26 Sep 2025 14:42:08 +0200 Subject: [PATCH 118/122] Cleanup --- src/terrainlib/mesh/holes.cpp | 151 ------------- src/terrainmerger/NodeWriter.h | 1 - src/terrainmerger/merge/visitor/Masked.h | 265 +---------------------- 3 files changed, 7 insertions(+), 410 deletions(-) diff --git a/src/terrainlib/mesh/holes.cpp b/src/terrainlib/mesh/holes.cpp index b74495e..11132de 100644 --- a/src/terrainlib/mesh/holes.cpp +++ b/src/terrainlib/mesh/holes.cpp @@ -203,157 +203,6 @@ std::vector> find_holes_on_merge_border( return holes; } -/* -namespace { -bool contains_shared_vertex( - const size_t source_mesh_index, - const std::span vertices_in_source_mesh, - const mesh::merging::VertexMapping &mapping) { - for (const VertexIndex vertex_index : vertices_in_source_mesh) { - for (size_t mesh_index = 0; mesh_index < mapping.mesh_count(); mesh_index++) { - if (mesh_index == source_mesh_index) { - continue; - } - - const std::optional source_vertex = mapping.map_backward(mesh_index, vertex_index); - if (source_vertex.has_value()) { - return true; - } - } - } - return false; -} - -bool is_shared_vertex( - const merging::VertexId id, - const merging::VertexMapping &mapping -) { - for (size_t other_mesh_index = 0; other_mesh_index < mapping.mesh_count(); other_mesh_index++) { - if (other_mesh_index == id.mesh_index) { - continue; - } - - const std::optional source_vertex = mapping.map_backward(other_mesh_index, id.vertex_index); - if (source_vertex.has_value()) { - return true; - } - } - return false; -} -} // namespace - - -std::vector> find_holes_between_meshes( - const std::span> &meshes, - const merging::VertexMapping &mapping -) { - using Segment = std::vector; - - // Step 1: Extract all boundary segments betweem two shared vertices - std::forward_list boundary_segments; - std::vector shared_vertices_in_boundary; - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index]; - - const std::vector> boundaries = find_boundaries(mesh); - for (const auto &boundary : boundaries) { - shared_vertices_in_boundary.clear(); - - // Find shared vertices - for (size_t index_in_boundary = 0; index_in_boundary < boundary.size(); index_in_boundary++) { - const merging::VertexId vertex = { - .mesh_index = mesh_index, - .vertex_index = boundary[index_in_boundary] - }; - - if (is_shared_vertex(vertex, mapping)) { - shared_vertices_in_boundary.push_back(index_in_boundary); - } - } - - // Discard if not shared boundary - if (shared_vertices_in_boundary.empty()) { - continue; - } - if (shared_vertices_in_boundary.size() % 2 == 1) { - LOG_WARN("Encountered boundary with only a single shared vertex, unable to generate geometry."); - continue; - } - - // Cut boundary into segments - for (size_t i = 0; i holes; - while (!boundary_segments.empty()) { - Segment current = std::move(boundary_segments.front()); - boundary_segments.pop_front(); - const size_t mesh_index = current[0].mesh_index; - - auto prev = boundary_segments.before_begin(); - auto it = boundary_segments.begin(); - - while (it != boundary_segments.end()) { - Segment &other = *it; - - if (other[0].mesh_index == mesh_index) { - if (current.back() == other.front()) { - Segment hole = std::move(current); - hole.insert(hole.end(), other.begin(), other.end()); - holes.push_back(std::move(hole)); - it = boundary_segments.erase_after(prev); - break; - } else if (current.front() == other.back()) { - Segment hole = std::move(other); - hole.insert(hole.end(), current.begin(), current.end()); - holes.push_back(std::move(hole)); - it = boundary_segments.erase_after(prev); - break; - } - } - - prev = it; - it++; - } - } - - return holes; -}*/ - void fill_planar_hole(SimpleMesh &mesh, std::vector hole) { std::reverse(hole.begin(), hole.end()); polygon::triangulate(mesh, hole); diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index dc0af1f..3cf0112 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -25,7 +25,6 @@ class NodeWriter { void write_node(const octree::Id &id, const SimpleMesh &mesh) { mesh::validate(mesh); DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); - cv::imwrite("tex_" + std::to_string(id.level()) + "_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".png", mesh.texture.value()); } void copy_subtree_to_output( diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index 1c91e52..c427cef 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "mask.h" #include "merge/NodeData.h" #include "merge/Result.h" @@ -21,40 +19,6 @@ namespace merge::visitor { -inline xatlas::MeshDecl to_meshdecl(const SimpleMesh &mesh) { - xatlas::MeshDecl decl{}; - - decl.indexCount = static_cast(mesh.triangles.size() * 3); - decl.indexData = mesh.triangles.data(); - decl.indexFormat = xatlas::IndexFormat::UInt32; - - decl.vertexCount = static_cast(mesh.positions.size()); - decl.vertexPositionData = mesh.positions.data(); - decl.vertexPositionStride = sizeof(SimpleMesh::Position); - - if (mesh.has_uvs()) { - decl.vertexUvData = mesh.uvs.data(); - decl.vertexUvStride = sizeof(SimpleMesh::Uv); - } - - return decl; -} - -inline xatlas::UvMeshDecl to_uvmeshdecl(const SimpleMesh &mesh) { - xatlas::UvMeshDecl decl{}; - - decl.indexCount = static_cast(mesh.triangles.size() * 3); - decl.indexData = mesh.triangles.data(); - decl.indexFormat = xatlas::IndexFormat::UInt32; - - ASSERT(mesh.has_uvs()); - decl.vertexUvData = mesh.uvs.data(); - decl.vertexCount = static_cast(mesh.uvs.size()); - decl.vertexStride = sizeof(SimpleMesh::Uv); - - return decl; -} - struct Atlas { std::vector> uvs; SimpleMesh::Texture texture; @@ -164,202 +128,6 @@ inline Atlas generate_texture_atlas_grid( return result; } -#include -#include -#include -#include - -#include -#include -#include - -inline void export_mesh_with_edges( - SimpleMesh mesh, - const std::vector &highlighted_edges, - const std::string &obj_path, - const std::string &mtl_name = "edges.mtl") { - if (mesh.positions.empty()) { - throw std::runtime_error("Mesh has no positions"); - } - - // --- normalize mesh --- - glm::dvec3 min_pt = mesh.positions[0]; - glm::dvec3 max_pt = mesh.positions[0]; - for (const auto &v : mesh.positions) { - min_pt = glm::min(min_pt, v); - max_pt = glm::max(max_pt, v); - } - glm::dvec3 center = (min_pt + max_pt) * 0.5; - glm::dvec3 extent = max_pt - min_pt; - double scale = std::max({extent.x, extent.y, extent.z}); - if (scale == 0.0) - scale = 1.0; - for (auto &v : mesh.positions) { - v = (v - center) / scale; - } - - // --- open OBJ --- - std::ofstream out(obj_path); - if (!out) - throw std::runtime_error("Cannot open: " + obj_path); - - out << "mtllib " << mtl_name << "\n"; - - // base mesh vertices - for (const auto &v : mesh.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - - // faces - for (const auto &tri : mesh.triangles) { - out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; - } - - // --- edges as quads with red material --- - out << "o highlighted_edges\n"; - out << "usemtl highlighted\n"; - - int vertex_index = static_cast(mesh.positions.size()); - for (const auto &e : highlighted_edges) { - glm::dvec3 a = mesh.positions[e.x]; - glm::dvec3 b = mesh.positions[e.y]; - - glm::dvec3 dir = glm::normalize(b - a); - glm::dvec3 up(0, 0, 1); - if (glm::abs(glm::dot(dir, up)) > 0.9) - up = glm::dvec3(0, 1, 0); - glm::dvec3 offset = glm::normalize(glm::cross(dir, up)) * 0.00002; // thickness - - // four new vertices - out << "v " << (a - offset).x << " " << (a - offset).y << " " << (a - offset).z << "\n"; - out << "v " << (a + offset).x << " " << (a + offset).y << " " << (a + offset).z << "\n"; - out << "v " << (b + offset).x << " " << (b + offset).y << " " << (b + offset).z << "\n"; - out << "v " << (b - offset).x << " " << (b - offset).y << " " << (b - offset).z << "\n"; - - int base = ++vertex_index; - out << "f " << base << " " << base + 1 << " " << base + 2 << "\n"; - out << "f " << base << " " << base + 2 << " " << base + 3 << "\n"; - vertex_index += 3; - } - - out.close(); - - // --- MTL --- - std::string dir; - auto pos = obj_path.find_last_of("/\\"); - if (pos != std::string::npos) - dir = obj_path.substr(0, pos + 1); - std::string mtl_path = dir + mtl_name; - - std::ofstream mtl_out(mtl_path); - if (!mtl_out) - throw std::runtime_error("Cannot open: " + mtl_path); - - mtl_out << "newmtl highlighted\n"; - mtl_out << "Kd 1.0 0.0 0.0\n"; // red - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; -} - -#include -#include -#include - -inline void export_two_meshes( - SimpleMesh mesh_a, - SimpleMesh mesh_b, - const std::string &obj_path, - const std::string &mtl_name = "two_meshes.mtl") { - if (mesh_a.positions.empty() || mesh_b.positions.empty()) { - throw std::runtime_error("One of the meshes has no positions"); - } - - // --- compute joint normalization --- - glm::dvec3 min_pt = mesh_a.positions[0]; - glm::dvec3 max_pt = mesh_a.positions[0]; - auto update_bounds = [&](const glm::dvec3 &v) { - min_pt = glm::min(min_pt, v); - max_pt = glm::max(max_pt, v); - }; - for (const auto &v : mesh_a.positions) - update_bounds(v); - for (const auto &v : mesh_b.positions) - update_bounds(v); - - glm::dvec3 center = (min_pt + max_pt) * 0.5; - glm::dvec3 extent = max_pt - min_pt; - double scale = std::max({extent.x, extent.y, extent.z}); - if (scale == 0.0) - scale = 1.0; - - for (auto &v : mesh_a.positions) - v = (v - center) / scale; - for (auto &v : mesh_b.positions) - v = (v - center) / scale; - - // --- write OBJ --- - std::ofstream out(obj_path); - if (!out) - throw std::runtime_error("Cannot open: " + obj_path); - - out << "mtllib " << mtl_name << "\n"; - - // Mesh A - out << "o mesh_a\n"; - out << "usemtl color_a\n"; - for (const auto &v : mesh_a.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - for (const auto &tri : mesh_a.triangles) { - out << "f " << (tri.x + 1) << " " << (tri.y + 1) << " " << (tri.z + 1) << "\n"; - } - - // Mesh B - out << "o mesh_b\n"; - out << "usemtl color_b\n"; - int vertex_offset = static_cast(mesh_a.positions.size()); - for (const auto &v : mesh_b.positions) { - out << "v " << v.x << " " << v.y << " " << v.z << "\n"; - } - for (const auto &tri : mesh_b.triangles) { - out << "f " - << (tri.x + 1 + vertex_offset) << " " - << (tri.y + 1 + vertex_offset) << " " - << (tri.z + 1 + vertex_offset) << "\n"; - } - - out.close(); - - // --- write MTL --- - std::string dir; - auto pos = obj_path.find_last_of("/\\"); - if (pos != std::string::npos) - dir = obj_path.substr(0, pos + 1); - std::string mtl_path = dir + mtl_name; - - std::ofstream mtl_out(mtl_path); - if (!mtl_out) - throw std::runtime_error("Cannot open: " + mtl_path); - - // color for mesh A (blue) - mtl_out << "newmtl color_a\n"; - mtl_out << "Kd 0.0 0.0 1.0\n"; - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; - - // color for mesh B (green) - mtl_out << "newmtl color_b\n"; - mtl_out << "Kd 0.0 1.0 0.0\n"; - mtl_out << "Ka 0.0 0.0 0.0\n"; - mtl_out << "Ks 0.0 0.0 0.0\n"; - mtl_out << "d 1.0\n"; - mtl_out << "illum 1\n"; -} - class Masked { public: using Status = octree::NodeStatusOrMissing; @@ -400,7 +168,6 @@ class Masked { // If the parent mask is empty, we can just return whatevers on the left if constexpr (left.status() != Status::Missing) { if (ctx.mask.mesh.is_empty()) { - return Ignore{}; return Unchanged{Source::Left}; } } @@ -412,21 +179,20 @@ class Masked { // Same when the current mask is empty if constexpr (left.status() != Status::Missing) { if (mask.mesh.is_empty()) { - return Ignore{}; return Unchanged{Source::Left}; } } // If we have two leaf nodes we can directly merge them. if constexpr (left.status() == Status::Leaf && right.status() == Status::Leaf) { - return this->merge_meshes(id, left.mesh(), right.mesh(), true, true, mask); + return this->merge_meshes(left.mesh(), right.mesh(), true, true, mask); } // If we have a left leaf we either directly return it (after clipping) // or merge if right has a non-missing parent if constexpr (left.status() == Status::Leaf && right.status() == Status::Missing) { if (ctx.has_right_parent) { - return this->merge_meshes(id, left.mesh(), right.mesh().value(), true, false, mask); + return this->merge_meshes(left.mesh(), right.mesh().value(), true, false, mask); } // Right node is actually missing, just return the clipped left node @@ -444,7 +210,7 @@ class Masked { // or merge if left has a non-missing parent if constexpr (left.status() == Status::Missing && right.status() == Status::Leaf) { if (ctx.has_left_parent) { - return this->merge_meshes(id, left.mesh().value(), right.mesh(), false, true, mask); + return this->merge_meshes(left.mesh().value(), right.mesh(), false, true, mask); } // Left node is actually missing, just return the clipped right node @@ -491,7 +257,6 @@ class Masked { private: Result merge_meshes( - const octree::Id &id, const SimpleMesh &base_mesh, const SimpleMesh &new_mesh, const bool can_ref_base_mesh, @@ -501,7 +266,6 @@ class Masked { const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); if (base_mesh_clipped.is_ref() && new_mesh_clipped->is_empty()) { - return Ignore{}; if (can_ref_base_mesh) { return Unchanged{Source::Left}; } else { @@ -509,7 +273,6 @@ class Masked { } } if (new_mesh_clipped.is_ref() && base_mesh_clipped->is_empty()) { - return Ignore{}; if (can_ref_new_mesh) { return Unchanged{Source::Right}; } else { @@ -554,32 +317,18 @@ class Masked { } std::reverse(polygon.points.begin(), polygon.points.end()); const SimpleMesh3d patch = polygon::triangulate(polygon); - // mesh::combine_inplace(hole_mesh, patch); + // TODO: mesh::combine_inplace(hole_mesh, patch); hole_mesh = mesh::combine(std::array{hole_mesh, patch}); } hole_mesh.uvs.insert(hole_mesh.uvs.end(), hole_mesh.vertex_count(), glm::dvec2(0)); - - std::vector edges; - for (const auto &hole : holes) { - for (size_t i = 0; i < hole.size(); i++) { - const SimpleMesh::Edge edge( - hole[i], - hole[(i + 1) % hole.size()]); - edges.push_back(edge); - } - } - const std::filesystem::path mesh_path = "/mnt/c/Users/Admin/Downloads/out-merge2/merged_" + std::to_string(id.x()) + "_" + std::to_string(id.y()) + "_" + std::to_string(id.z()) + ".obj"; - export_mesh_with_edges(merged_mesh, edges, mesh_path.string()); - export_two_meshes(merged_mesh, hole_mesh, mesh_path.string() + ".two.obj"); - export_mesh_with_edges(hole_mesh, {}, mesh_path.string() + ".holes.obj"); - mesh::validate(merged_mesh); - mesh::validate(hole_mesh); + LOG_TRACE("Filled {} holes on merge border", holes.size()); + LOG_TRACE("Generated {} vertices and {} faces for hole patches", hole_mesh.vertex_count(), hole_mesh.face_count()); LOG_TRACE("Creating combined mesh"); const std::array, 3> meshes_and_patches = {meshes[0], meshes[1], hole_mesh}; std::vector vertex_offsets; SimpleMesh result_mesh = mesh::combine(meshes_and_patches, vertex_offsets); - + LOG_TRACE("Generating combined texture"); Atlas atlas = generate_texture_atlas_grid(meshes_and_patches); result_mesh.texture = std::move(atlas.texture); From bcbd52c06070d4bf470c0b00386bf181c74eab4f Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 2 Oct 2025 15:44:09 +0200 Subject: [PATCH 119/122] Alternative merging; trim textures --- src/CMakeLists.txt | 2 +- src/terrainlib/Rect.h | 24 +++ src/terrainlib/mesh/texture_trim.h | 58 ++++++ src/terrainlib/octree/storage/Storage.h | 2 + src/terrainlib/polygon/triangulate.cpp | 21 ++ src/terrainmerger/NodeLoader.h | 4 +- src/terrainmerger/NodeWriter.h | 4 + .../atlas/HorizontalStripLayoutPlanner.h | 64 +++++++ src/terrainmerger/atlas/Layout.h | 22 +++ src/terrainmerger/atlas/LayoutPlanner.h | 18 ++ src/terrainmerger/atlas/Sheet.h | 14 ++ src/terrainmerger/atlas/build.h | 67 +++++++ src/terrainmerger/merge/visitor/Masked.h | 179 ++---------------- src/terrainmerger/utils.h | 9 +- 14 files changed, 323 insertions(+), 165 deletions(-) create mode 100644 src/terrainlib/Rect.h create mode 100644 src/terrainlib/mesh/texture_trim.h create mode 100644 src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h create mode 100644 src/terrainmerger/atlas/Layout.h create mode 100644 src/terrainmerger/atlas/LayoutPlanner.h create mode 100644 src/terrainmerger/atlas/Sheet.h create mode 100644 src/terrainmerger/atlas/build.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9cb61de..8339ca2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ alp_add_git_repository(xatlas URL https://github.com/Korinin38/xatlas_hi-res_opt add_library(xatlas STATIC ${xatlas_SOURCE_DIR}/source/xatlas/xatlas.cpp) target_include_directories(xatlas PUBLIC ${xatlas_SOURCE_DIR}/source) -alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH af07738928ab3129899dde72c8e73ed01622a420 NOT_SYSTEM DEEP_CLONE) +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH 2ce3484513b826bb11e5433f868b048eaffe3e5d NOT_SYSTEM DEEP_CLONE) # Don't build glfw docs, tests and examples set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) diff --git a/src/terrainlib/Rect.h b/src/terrainlib/Rect.h new file mode 100644 index 0000000..3a096d5 --- /dev/null +++ b/src/terrainlib/Rect.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +template +struct Rect { + glm::vec position = {}; + glm::vec size = {}; +}; + +template +using Rect2 = Rect<2, T>; +template +using Rect3 = Rect<3, T>; + +using Rect2d = Rect2; +using Rect2f = Rect2; +using Rect2i = Rect2; +using Rect2ui = Rect2; + +using Rect3d = Rect3; +using Rect3f = Rect3; +using Rect3i = Rect3; +using Rect3ui = Rect3; diff --git a/src/terrainlib/mesh/texture_trim.h b/src/terrainlib/mesh/texture_trim.h new file mode 100644 index 0000000..07f4616 --- /dev/null +++ b/src/terrainlib/mesh/texture_trim.h @@ -0,0 +1,58 @@ +#pragma once + +#include + +#include +#include + +#include "mesh/SimpleMesh.h" + +namespace { + bool is_empty(const radix::geometry::Aabb2i &bounds) { + return bounds.min.x >= bounds.max.x || bounds.min.y >= bounds.max.y; + } +} + +void trim_texture_inplace(cv::Mat &texture, std::span uvs, const uint32_t padding = 2) { + // Calculate the bounding box of the UVs in pixel space + const radix::geometry::Aabb2d uv_bounds = radix::geometry::find_bounds(std::span(uvs)); + const glm::uvec2 texture_size(texture.cols, texture.rows); + const radix::geometry::Aabb2i pixel_bounds = { + glm::floor(uv_bounds.min * glm::dvec2(texture_size)), + glm::ceil(uv_bounds.max * glm::dvec2(texture_size))}; + const radix::geometry::Aabb2i padded_pixel_bounds = { + pixel_bounds.min - glm::ivec2(padding), + pixel_bounds.max + glm::ivec2(padding)}; + const radix::geometry::Aabb2ui clamped_pixel_bounds = { + glm::uvec2(glm::max(padded_pixel_bounds.min, glm::ivec2(0))), + glm::uvec2(glm::min(padded_pixel_bounds.max, glm::ivec2(texture_size)))}; + if (is_empty(clamped_pixel_bounds)) { + return; + } + + // Crop the texture to the bounding box + const cv::Rect roi( + clamped_pixel_bounds.min.x, + clamped_pixel_bounds.min.y, + clamped_pixel_bounds.width(), + clamped_pixel_bounds.height()); + texture = texture(roi).clone(); + // Update the UVs to match the cropped texture + const glm::uvec2 cropped_texture_size(texture.cols, texture.rows); + LOG_TRACE("Trimmed texture from {}x{} to {}x{}", texture_size.x, texture_size.y, cropped_texture_size.x, cropped_texture_size.y); + const radix::geometry::Aabb2d cropped_uv_bounds = { + glm::dvec2(clamped_pixel_bounds.min) / glm::dvec2(texture_size), + glm::dvec2(clamped_pixel_bounds.max) / glm::dvec2(texture_size)}; + for (glm::dvec2 &uv : uvs) { + uv = (uv - cropped_uv_bounds.min) / cropped_uv_bounds.size(); + DEBUG_ASSERT(uv.x >= 0.0 && uv.x <= 1.0); + DEBUG_ASSERT(uv.y >= 0.0 && uv.y <= 1.0); + } +} + +void trim_texture_inplace(SimpleMesh &mesh) { + if (!mesh.has_texture() || !mesh.has_uvs()) { + return; + } + trim_texture_inplace(*mesh.texture, mesh.uvs); +} diff --git a/src/terrainlib/octree/storage/Storage.h b/src/terrainlib/octree/storage/Storage.h index 6e7f138..55b2a25 100644 --- a/src/terrainlib/octree/storage/Storage.h +++ b/src/terrainlib/octree/storage/Storage.h @@ -129,6 +129,8 @@ class Storage { tl::expected write_node(const Id &id, const Node &node, const bool overwrite = false) noexcept { // TODO: implement overwrite + ASSERT(!overwrite); + const auto result = this->_inner.write_node(id, node); if (result.has_value()) { this->_cache.put(id, node); diff --git a/src/terrainlib/polygon/triangulate.cpp b/src/terrainlib/polygon/triangulate.cpp index 8c044b0..6062314 100644 --- a/src/terrainlib/polygon/triangulate.cpp +++ b/src/terrainlib/polygon/triangulate.cpp @@ -14,6 +14,7 @@ #include "mesh/validate.h" #include "mesh/utils.h" #include "polygon/utils.h" +#include "log.h" using Kernel = cgal::kernel::epeck::Kernel; using Point2 = Kernel::Point_2; @@ -72,6 +73,8 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { DEBUG_ASSERT(vertex_index < mesh.positions.size()); polygon.points.push_back(mesh.positions[vertex_index]); } + polygon.points.push_back(polygon.points[0]); // close the polygon + DEBUG_ASSERT(cgal_polygon.is_simple()); DEBUG_ASSERT(polygon::is_planar(polygon)); const PlaneBasis basis = make_basis(polygon); @@ -85,6 +88,7 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { const glm::dvec3 &point = polygon.points[i]; const glm::dvec2 projected = project(point, basis); VertexHandle vh = cdt.insert(convert::to_cgal_point(projected)); + DEBUG_ASSERT(vh.is_valid()); vh->info() = indices[i]; handles.push_back(vh); } @@ -101,6 +105,7 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { DEBUG_ASSERT(cdt.is_valid()); // Insert new triangles and vertices + std::vector new_triangles; for (const FaceHandle face : cdt.finite_face_handles()) { if (!get(in_domain, face)) { // outside the polygon @@ -129,7 +134,23 @@ void triangulate(SimpleMesh3d &mesh, const std::span indices) { } mesh.triangles.push_back(triangle); + new_triangles.push_back(triangle); } + + // Check that all input vertices were used +#ifndef NDEBUG + for (const auto& index : indices) { + bool found = false; + for (const auto& triangle : new_triangles) { + if (triangle[0] == index || triangle[1] == index || triangle[2] == index) { + found = true; + } + } + if (!found) { + UNREACHABLE("Vertex {} was not used in triangulation", index); + } + } +#endif } SimpleMesh3d triangulate(const Polygon3d &polygon) { diff --git a/src/terrainmerger/NodeLoader.h b/src/terrainmerger/NodeLoader.h index 48075bd..751feb6 100644 --- a/src/terrainmerger/NodeLoader.h +++ b/src/terrainmerger/NodeLoader.h @@ -7,6 +7,7 @@ #include "NodeLoader.h" #include "mesh/SimpleMesh.h" #include "mesh/clip.h" +#include "mesh/texture_trim.h" #include "octree/Id.h" #include "octree/NodeStatusOrMissing.h" #include "octree/Space.h" @@ -57,7 +58,8 @@ class NodeLoader { if (parent_mesh_opt.has_value()) { auto parent_mesh = parent_mesh_opt.value(); const auto bounds = this->_space.get_node_bounds(id); - const auto clipped = mesh::clip_on_bounds(parent_mesh, bounds); + SimpleMesh clipped = mesh::clip_on_bounds(parent_mesh, bounds); + trim_texture_inplace(clipped); this->_cache.put(id, clipped); return clipped; } diff --git a/src/terrainmerger/NodeWriter.h b/src/terrainmerger/NodeWriter.h index 3cf0112..6c99e9d 100644 --- a/src/terrainmerger/NodeWriter.h +++ b/src/terrainmerger/NodeWriter.h @@ -25,6 +25,10 @@ class NodeWriter { void write_node(const octree::Id &id, const SimpleMesh &mesh) { mesh::validate(mesh); DEBUG_ASSERT_VAL(this->_storage.write_node(id, mesh, this->_overwrite)); + auto p = this->_storage.get_node_path(id); + // change extension to .png + p.replace_extension(".png"); + cv::imwrite(p, mesh.texture.value_or(cv::Mat())); } void copy_subtree_to_output( diff --git a/src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h b/src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h new file mode 100644 index 0000000..1ede755 --- /dev/null +++ b/src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "atlas/LayoutPlanner.h" +#include "atlas/Layout.h" + +namespace atlas { + +class HorizontalStripLayoutPlanner : public LayoutPlanner { +public: + Layout plan(const std::span> meshes) const override { + Layout layout; + glm::uvec2 cursor(0, 0); + uint32_t max_height = 0; + + for (size_t i = 0; i < meshes.size(); i++) { + const SimpleMesh &mesh = meshes[i]; + if (!mesh.texture.has_value()) { + continue; + } + + const cv::Mat &tex = *mesh.texture; + + const Layout::Slot slot{ + .mesh_index = i, + .pixel_position = cursor, + .uv_space = {} // to be filled later + }; + layout.slots.push_back(slot); + + cursor.x += tex.cols; + max_height = std::max(max_height, static_cast(tex.rows)); + } + + if (layout.slots.empty()) { + layout.atlas_size = glm::uvec2(1, 1); + return layout; + } + + layout.atlas_size = glm::uvec2(cursor.x, max_height); + + // compute uv rects + for (auto &slot : layout.slots) { + const SimpleMesh &mesh = meshes[slot.mesh_index].get(); + const cv::Mat &tex = *mesh.texture; + + const double u0 = static_cast(slot.pixel_position.x) / layout.atlas_size.x; + const double v0 = static_cast(slot.pixel_position.y) / layout.atlas_size.y; + const double u1 = static_cast(slot.pixel_position.x + tex.cols) / layout.atlas_size.x; + const double v1 = static_cast(slot.pixel_position.y + tex.rows) / layout.atlas_size.y; + + slot.uv_space = Rect2d{ + {u0, v0}, + {u1 - u0, v1 - v0}}; + } + + return layout; + } +}; + +} // namespace atlas diff --git a/src/terrainmerger/atlas/Layout.h b/src/terrainmerger/atlas/Layout.h new file mode 100644 index 0000000..94f693e --- /dev/null +++ b/src/terrainmerger/atlas/Layout.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +#include "Rect.h" + +namespace atlas { + +struct Layout { + struct Slot { + size_t mesh_index; + glm::uvec2 pixel_position; + Rect2d uv_space; + }; + + glm::uvec2 atlas_size; + std::vector slots; +}; + +} diff --git a/src/terrainmerger/atlas/LayoutPlanner.h b/src/terrainmerger/atlas/LayoutPlanner.h new file mode 100644 index 0000000..04b50c9 --- /dev/null +++ b/src/terrainmerger/atlas/LayoutPlanner.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include "mesh/SimpleMesh.h" +#include "atlas/Layout.h" + +namespace atlas { + +class LayoutPlanner { +public: + virtual ~LayoutPlanner() = default; + virtual Layout plan( + const std::span> meshes) const = 0; +}; + +} // namespace atlas diff --git a/src/terrainmerger/atlas/Sheet.h b/src/terrainmerger/atlas/Sheet.h new file mode 100644 index 0000000..acf3cb7 --- /dev/null +++ b/src/terrainmerger/atlas/Sheet.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +#include "mesh/SimpleMesh.h" + +namespace atlas { + +struct Sheet { + std::vector> uvs; + SimpleMesh::Texture texture; +}; + +} diff --git a/src/terrainmerger/atlas/build.h b/src/terrainmerger/atlas/build.h new file mode 100644 index 0000000..820fc43 --- /dev/null +++ b/src/terrainmerger/atlas/build.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include + +#include + +#include "mesh/SimpleMesh.h" +#include "atlas/LayoutPlanner.h" +#include "atlas/Layout.h" +#include "atlas/Sheet.h" + +namespace atlas { + +inline Sheet build( + const std::span> meshes, + const Layout &layout) { + Sheet result; + result.uvs.resize(meshes.size()); + + if (layout.slots.empty()) { + // Create single pixel empty texture + result.texture = cv::Mat(1, 1, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + for (size_t i = 0; i < meshes.size(); i++) { + const SimpleMesh &mesh = meshes[i]; + result.uvs[i].assign(mesh.vertex_count(), glm::dvec2(0.0, 0.0)); + } + return result; + } + + const int atlas_type = meshes[layout.slots[0].mesh_index].get().texture->type(); + cv::Mat atlas_image(layout.atlas_size.y, layout.atlas_size.x, atlas_type, cv::Scalar(0, 0, 0, 0)); + + for (const auto &slot : layout.slots) { + const SimpleMesh &mesh = meshes[slot.mesh_index]; + result.uvs[slot.mesh_index].resize(mesh.vertex_count()); + + // copy texture into atlas + cv::Mat roi(atlas_image, + cv::Rect( + static_cast(slot.pixel_position.x), + static_cast(slot.pixel_position.y), + mesh.texture->cols, + mesh.texture->rows)); + mesh.texture->copyTo(roi); + + if (!mesh.uvs.empty()) { + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + const glm::dvec2 &uv = mesh.uvs[vertex_index]; + result.uvs[slot.mesh_index][vertex_index] = glm::dvec2( + slot.uv_space.position.x + uv.x * slot.uv_space.size.x, + slot.uv_space.position.y + uv.y * slot.uv_space.size.y); + DEBUG_ASSERT(result.uvs[slot.mesh_index][vertex_index].x >= 0.0 && result.uvs[slot.mesh_index][vertex_index].x <= 1.0); + DEBUG_ASSERT(result.uvs[slot.mesh_index][vertex_index].y >= 0.0 && result.uvs[slot.mesh_index][vertex_index].y <= 1.0); + } + } else { + for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { + result.uvs[slot.mesh_index][vertex_index] = glm::dvec2(0.0, 0.0); + } + } + } + + result.texture = atlas_image; + return result; +} + +} diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/terrainmerger/merge/visitor/Masked.h index c427cef..a577fde 100644 --- a/src/terrainmerger/merge/visitor/Masked.h +++ b/src/terrainmerger/merge/visitor/Masked.h @@ -16,118 +16,14 @@ #include "polygon/triangulate.h" #include "spatial_lookup/Hashmap.h" #include "utils.h" +#include "atlas/Sheet.h" +#include "atlas/build.h" +#include "atlas/HorizontalStripLayoutPlanner.h" +#include "atlas/LayoutPlanner.h" +#include "atlas/Layout.h" namespace merge::visitor { -struct Atlas { - std::vector> uvs; - SimpleMesh::Texture texture; -}; - -inline uint32_t next_pow2(uint32_t v) { - if (v <= 1) { - return 1; - } - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return v + 1; -} - -inline uint32_t compute_resolution( - const std::span> meshes) { - size_t total = 0; - for (const SimpleMesh &m : meshes) { - total += m.vertex_count(); - } - const uint32_t result = next_pow2(static_cast(std::ceil(std::sqrt(total)))); - return std::clamp(result, 512u, 4096u); -} - -inline Atlas generate_texture_atlas_grid( - const std::span> meshes) { - - // Identify meshes that have textures and find maximum texture size - std::vector textured_mesh_indices; - size_t maximum_texture_width = 0; - size_t maximum_texture_height = 0; - - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index].get(); - if (mesh.texture.has_value()) { - textured_mesh_indices.push_back(mesh_index); - const cv::Mat &texture_image = mesh.texture.value(); - maximum_texture_width = std::max(maximum_texture_width, static_cast(texture_image.cols)); - maximum_texture_height = std::max(maximum_texture_height, static_cast(texture_image.rows)); - } - } - - Atlas result; - result.uvs.resize(meshes.size()); - - if (textured_mesh_indices.empty()) { - // No textures: assign (0,0) UVs for all meshes - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index].get(); - result.uvs[mesh_index].assign(mesh.vertex_count(), glm::dvec2(0.0, 0.0)); - } - return result; - } - - const size_t number_of_textured_meshes = textured_mesh_indices.size(); - const size_t grid_size = static_cast(std::ceil(std::sqrt(static_cast(number_of_textured_meshes)))); - const size_t atlas_width = next_pow2(grid_size * maximum_texture_width); - const size_t atlas_height = next_pow2(grid_size * maximum_texture_height); - - // Create transparent atlas image - const int atlas_type = meshes[textured_mesh_indices[0]].get().texture->type(); - cv::Mat atlas_image(atlas_height, atlas_width, atlas_type, cv::Scalar(0, 0, 0, 0)); - - size_t slot_index = 0; - for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { - const SimpleMesh &mesh = meshes[mesh_index].get(); - result.uvs[mesh_index].resize(mesh.vertex_count()); - - if (mesh.texture.has_value() && !mesh.uvs.empty()) { - const size_t row = slot_index / grid_size; - const size_t column = slot_index % grid_size; - - const cv::Rect destination_rectangle( - static_cast(column * maximum_texture_width), - static_cast(row * maximum_texture_height), - mesh.texture->cols, - mesh.texture->rows); - - mesh.texture->copyTo(atlas_image(destination_rectangle)); - - const double u_start = static_cast(column * maximum_texture_width) / atlas_width; - const double v_start = static_cast(row * maximum_texture_height) / atlas_height; - const double u_end = static_cast(column * maximum_texture_width + mesh.texture->cols) / atlas_width; - const double v_end = static_cast(row * maximum_texture_height + mesh.texture->rows) / atlas_height; - - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { - const glm::dvec2 &original_uv = mesh.uvs[vertex_index]; - result.uvs[mesh_index][vertex_index] = glm::dvec2( - u_start + original_uv.x * (u_end - u_start), - v_start + original_uv.y * (v_end - v_start)); - } - - slot_index++; - } else { - // No texture or no UVs: fill with (0,0) - for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { - result.uvs[mesh_index][vertex_index] = glm::dvec2(0.0, 0.0); - } - } - } - - result.texture = atlas_image; - return result; -} - class Masked { public: using Status = octree::NodeStatusOrMissing; @@ -262,6 +158,7 @@ class Masked { const bool can_ref_base_mesh, const bool can_ref_new_mesh, const MeshMask &mask) { + LOG_TRACE("Clipping meshes on mask"); const Cow new_mesh_clipped = clip_on_mask(new_mesh, mask, true); const Cow base_mesh_clipped = clip_on_mask(base_mesh, mask, false); @@ -280,69 +177,27 @@ class Masked { } } - // Merging the two meshes - LOG_TRACE("Calculating merge mapping"); - const std::array, 2> meshes = {base_mesh_clipped.get(), new_mesh_clipped.get()}; - const double distance_epsilon = mesh::merging::estimate_merge_epsilon(meshes); - // We have to use a hashmap here instead of a grid since we dont know - // the bounds of the mesh projected onto the sphere with the deduplication radius. - spatial_lookup::Hashmap3d map(distance_epsilon * 3); - // Deduplication happens by projecting all points onto a sphere and performing epsilon checks there - const glm::dvec3 tangent_point = meshes[0].get().positions[0]; - const double radius = glm::length(tangent_point); - mesh::merging::SphereProjectionVertexDeduplicate< - mesh::merging::VertexId, - decltype(map)> - deduplicate(map, distance_epsilon, radius); - const mesh::merging::VertexMapping mapping = mesh::merging::create_mapping(meshes, - mesh::merging::create_options() - .deduplicate(deduplicate) - .only_consider_boundary(true)); - - LOG_TRACE("Creating merged mesh"); - const SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, mapping, - mesh::merging::apply_options() - .deduplicate_triangles(false) - .merge_uvs(false)); - - LOG_TRACE("Filling holes on merge border"); - const auto holes = mesh::find_holes_on_merge_border(merged_mesh, mapping); - Polygon3d polygon; - SimpleMesh3d hole_mesh; - for (const auto &hole : holes) { - polygon.points.clear(); - for (const size_t vertex_index : hole) { - const glm::dvec3 position = merged_mesh.positions[vertex_index]; - polygon.points.push_back(position); - } - std::reverse(polygon.points.begin(), polygon.points.end()); - const SimpleMesh3d patch = polygon::triangulate(polygon); - // TODO: mesh::combine_inplace(hole_mesh, patch); - hole_mesh = mesh::combine(std::array{hole_mesh, patch}); - } - hole_mesh.uvs.insert(hole_mesh.uvs.end(), hole_mesh.vertex_count(), glm::dvec2(0)); - LOG_TRACE("Filled {} holes on merge border", holes.size()); - LOG_TRACE("Generated {} vertices and {} faces for hole patches", hole_mesh.vertex_count(), hole_mesh.face_count()); - LOG_TRACE("Creating combined mesh"); - const std::array, 3> meshes_and_patches = {meshes[0], meshes[1], hole_mesh}; + const std::array, 2> meshes = { + base_mesh_clipped, + new_mesh_clipped, + }; std::vector vertex_offsets; - SimpleMesh result_mesh = mesh::combine(meshes_and_patches, vertex_offsets); + SimpleMesh result_mesh = mesh::combine(meshes, vertex_offsets); - LOG_TRACE("Generating combined texture"); - Atlas atlas = generate_texture_atlas_grid(meshes_and_patches); + LOG_TRACE("Creating texture atlas"); + const atlas::HorizontalStripLayoutPlanner planner = {}; + const atlas::Layout layout = planner.plan(meshes); + const atlas::Sheet atlas = atlas::build(meshes, layout); result_mesh.texture = std::move(atlas.texture); - for (size_t mesh_index = 0; mesh_index < meshes_and_patches.size(); mesh_index++) { - const SimpleMesh &mesh = meshes_and_patches[mesh_index]; + for (size_t mesh_index = 0; mesh_index < meshes.size(); mesh_index++) { + const SimpleMesh &mesh = meshes[mesh_index]; const auto vertex_offset = vertex_offsets[mesh_index]; for (size_t vertex_index = 0; vertex_index < mesh.vertex_count(); vertex_index++) { result_mesh.uvs[vertex_offset + vertex_index] = atlas.uvs[mesh_index][vertex_index]; } } - DEBUG_ASSERT(result_mesh.has_uvs()); - DEBUG_ASSERT(result_mesh.has_texture()); - mesh::validate(result_mesh); return Merged{result_mesh}; diff --git a/src/terrainmerger/utils.h b/src/terrainmerger/utils.h index d3e223d..623212f 100644 --- a/src/terrainmerger/utils.h +++ b/src/terrainmerger/utils.h @@ -7,9 +7,16 @@ #include "mask.h" #include "mesh/SimpleMesh.h" #include "mesh/clip.h" +#include "mesh/texture_trim.h" inline Cow clip_on_mask(const SimpleMesh &mesh, const MeshMask &mask, const bool keep_inside = true) { - return mesh::clip_on_mesh(mesh, mask.mesh, keep_inside); + Cow clipped = mesh::clip_on_mesh(mesh, mask.mesh, keep_inside); + if (clipped.is_ref()) { + return clipped; + } + SimpleMesh result = std::move(clipped.get()); + trim_texture_inplace(result); + return Cow::from_owned(std::move(result)); } template From 67bbd60cee061c5bd981daf742c18a524c8a049c Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 9 Oct 2025 17:49:16 +0200 Subject: [PATCH 120/122] Rename targets --- src/CMakeLists.txt | 158 +++++++++--------- src/index_browser/cli.cpp | 2 +- src/{terrainbuilder => mesh_builder}/border.h | 0 src/{terrainbuilder => mesh_builder}/main.cpp | 2 +- .../mesh_builder.cpp | 0 .../mesh_builder.h | 0 src/{terrainbuilder => mesh_builder}/raster.h | 0 .../raw_dataset_reader.h | 0 .../terrainbuilder.cpp | 0 .../terrainbuilder.h | 0 .../texture_assembler.h | 0 .../tile_provider.h | 0 src/{terrainconvert => mesh_convert}/cli.cpp | 2 +- src/{terrainconvert => mesh_convert}/cli.h | 0 src/{terrainconvert => mesh_convert}/main.cpp | 0 .../cli.cpp | 2 +- src/{terrainsimplify => mesh_simplify}/cli.h | 0 .../main.cpp | 0 src/{terrainsimplify => mesh_simplify}/pch.h | 0 .../simplify.cpp | 0 .../simplify.h | 0 .../uv_map.cpp | 0 .../uv_map.h | 0 src/{terrainmerger => sf_merger}/NodeLoader.h | 0 src/{terrainmerger => sf_merger}/NodeWriter.h | 0 .../SimpleMutex.h | 0 .../atlas/HorizontalStripLayoutPlanner.h | 0 .../atlas/Layout.h | 0 .../atlas/LayoutPlanner.h | 0 .../atlas/Sheet.h | 0 .../atlas/build.h | 0 src/{terrainmerger => sf_merger}/cli.cpp | 9 +- src/{terrainmerger => sf_merger}/cli.h | 0 src/{terrainmerger => sf_merger}/cut.h | 0 src/{terrainmerger => sf_merger}/earth.h | 0 src/{terrainmerger => sf_merger}/main.cpp | 0 src/{terrainmerger => sf_merger}/mask.h | 0 src/{terrainmerger => sf_merger}/merge.h | 0 .../merge/NodeData.h | 0 .../merge/Result.h | 0 .../merge/visitor/Masked.h | 0 .../merge/visitor/Simple.h | 0 .../merge/visitor/Visitor.h | 0 src/{terrainmerger => sf_merger}/utils.h | 0 .../DatasetReader.cpp | 0 .../DatasetReader.h | 0 src/{tilebuilder => tile_builder}/Exception.h | 0 src/{tilebuilder => tile_builder}/Image.cpp | 0 src/{tilebuilder => tile_builder}/Image.h | 0 .../ParallelTileGenerator.cpp | 0 .../ParallelTileGenerator.h | 0 .../ParallelTiler.cpp | 0 .../ParallelTiler.h | 0 .../TileHeightsGenerator.cpp | 0 .../TileHeightsGenerator.h | 0 src/{tilebuilder => tile_builder}/Tiler.cpp | 0 src/{tilebuilder => tile_builder}/Tiler.h | 0 .../TopDownTiler.cpp | 0 .../TopDownTiler.h | 0 .../algorithms/primitives.h | 0 .../algorithms/raster_triangle_scanline.h | 0 .../alpine_raster.cpp | 0 .../alpine_raster.h | 0 .../depth_first_tile_traverser.h | 0 src/{tilebuilder => tile_builder}/main.cpp | 0 src/{tilebuilder => tile_builder}/srs.h | 0 66 files changed, 89 insertions(+), 86 deletions(-) rename src/{terrainbuilder => mesh_builder}/border.h (100%) rename src/{terrainbuilder => mesh_builder}/main.cpp (99%) rename src/{terrainbuilder => mesh_builder}/mesh_builder.cpp (100%) rename src/{terrainbuilder => mesh_builder}/mesh_builder.h (100%) rename src/{terrainbuilder => mesh_builder}/raster.h (100%) rename src/{terrainbuilder => mesh_builder}/raw_dataset_reader.h (100%) rename src/{terrainbuilder => mesh_builder}/terrainbuilder.cpp (100%) rename src/{terrainbuilder => mesh_builder}/terrainbuilder.h (100%) rename src/{terrainbuilder => mesh_builder}/texture_assembler.h (100%) rename src/{terrainbuilder => mesh_builder}/tile_provider.h (100%) rename src/{terrainconvert => mesh_convert}/cli.cpp (97%) rename src/{terrainconvert => mesh_convert}/cli.h (100%) rename src/{terrainconvert => mesh_convert}/main.cpp (100%) rename src/{terrainsimplify => mesh_simplify}/cli.cpp (99%) rename src/{terrainsimplify => mesh_simplify}/cli.h (100%) rename src/{terrainsimplify => mesh_simplify}/main.cpp (100%) rename src/{terrainsimplify => mesh_simplify}/pch.h (100%) rename src/{terrainsimplify => mesh_simplify}/simplify.cpp (100%) rename src/{terrainsimplify => mesh_simplify}/simplify.h (100%) rename src/{terrainsimplify => mesh_simplify}/uv_map.cpp (100%) rename src/{terrainsimplify => mesh_simplify}/uv_map.h (100%) rename src/{terrainmerger => sf_merger}/NodeLoader.h (100%) rename src/{terrainmerger => sf_merger}/NodeWriter.h (100%) rename src/{terrainmerger => sf_merger}/SimpleMutex.h (100%) rename src/{terrainmerger => sf_merger}/atlas/HorizontalStripLayoutPlanner.h (100%) rename src/{terrainmerger => sf_merger}/atlas/Layout.h (100%) rename src/{terrainmerger => sf_merger}/atlas/LayoutPlanner.h (100%) rename src/{terrainmerger => sf_merger}/atlas/Sheet.h (100%) rename src/{terrainmerger => sf_merger}/atlas/build.h (100%) rename src/{terrainmerger => sf_merger}/cli.cpp (83%) rename src/{terrainmerger => sf_merger}/cli.h (100%) rename src/{terrainmerger => sf_merger}/cut.h (100%) rename src/{terrainmerger => sf_merger}/earth.h (100%) rename src/{terrainmerger => sf_merger}/main.cpp (100%) rename src/{terrainmerger => sf_merger}/mask.h (100%) rename src/{terrainmerger => sf_merger}/merge.h (100%) rename src/{terrainmerger => sf_merger}/merge/NodeData.h (100%) rename src/{terrainmerger => sf_merger}/merge/Result.h (100%) rename src/{terrainmerger => sf_merger}/merge/visitor/Masked.h (100%) rename src/{terrainmerger => sf_merger}/merge/visitor/Simple.h (100%) rename src/{terrainmerger => sf_merger}/merge/visitor/Visitor.h (100%) rename src/{terrainmerger => sf_merger}/utils.h (100%) rename src/{tilebuilder => tile_builder}/DatasetReader.cpp (100%) rename src/{tilebuilder => tile_builder}/DatasetReader.h (100%) rename src/{tilebuilder => tile_builder}/Exception.h (100%) rename src/{tilebuilder => tile_builder}/Image.cpp (100%) rename src/{tilebuilder => tile_builder}/Image.h (100%) rename src/{tilebuilder => tile_builder}/ParallelTileGenerator.cpp (100%) rename src/{tilebuilder => tile_builder}/ParallelTileGenerator.h (100%) rename src/{tilebuilder => tile_builder}/ParallelTiler.cpp (100%) rename src/{tilebuilder => tile_builder}/ParallelTiler.h (100%) rename src/{tilebuilder => tile_builder}/TileHeightsGenerator.cpp (100%) rename src/{tilebuilder => tile_builder}/TileHeightsGenerator.h (100%) rename src/{tilebuilder => tile_builder}/Tiler.cpp (100%) rename src/{tilebuilder => tile_builder}/Tiler.h (100%) rename src/{tilebuilder => tile_builder}/TopDownTiler.cpp (100%) rename src/{tilebuilder => tile_builder}/TopDownTiler.h (100%) rename src/{tilebuilder => tile_builder}/algorithms/primitives.h (100%) rename src/{tilebuilder => tile_builder}/algorithms/raster_triangle_scanline.h (100%) rename src/{tilebuilder => tile_builder}/alpine_raster.cpp (100%) rename src/{tilebuilder => tile_builder}/alpine_raster.h (100%) rename src/{tilebuilder => tile_builder}/depth_first_tile_traverser.h (100%) rename src/{tilebuilder => tile_builder}/main.cpp (100%) rename src/{tilebuilder => tile_builder}/srs.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8339ca2..2bdd769 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,109 +198,115 @@ endif() add_library(tilebuilderlib - tilebuilder/alpine_raster.h tilebuilder/alpine_raster.cpp - tilebuilder/DatasetReader.h tilebuilder/DatasetReader.cpp - tilebuilder/depth_first_tile_traverser.h - tilebuilder/Exception.h - tilebuilder/Image.h tilebuilder/Image.cpp - tilebuilder/ParallelTileGenerator.h tilebuilder/ParallelTileGenerator.cpp - tilebuilder/ParallelTiler.h tilebuilder/ParallelTiler.cpp - tilebuilder/srs.h - tilebuilder/TileHeightsGenerator.h tilebuilder/TileHeightsGenerator.cpp - tilebuilder/Tiler.h tilebuilder/Tiler.cpp - tilebuilder/TopDownTiler.h tilebuilder/TopDownTiler.cpp - tilebuilder/algorithms/primitives.h - tilebuilder/algorithms/raster_triangle_scanline.h + tile_builder/alpine_raster.h tile_builder/alpine_raster.cpp + tile_builder/DatasetReader.h tile_builder/DatasetReader.cpp + tile_builder/depth_first_tile_traverser.h + tile_builder/Exception.h + tile_builder/Image.h tile_builder/Image.cpp + tile_builder/ParallelTileGenerator.h tile_builder/ParallelTileGenerator.cpp + tile_builder/ParallelTiler.h tile_builder/ParallelTiler.cpp + tile_builder/srs.h + tile_builder/TileHeightsGenerator.h tile_builder/TileHeightsGenerator.cpp + tile_builder/Tiler.h tile_builder/Tiler.cpp + tile_builder/TopDownTiler.h tile_builder/TopDownTiler.cpp + tile_builder/algorithms/primitives.h + tile_builder/algorithms/raster_triangle_scanline.h ) -target_include_directories(tilebuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tilebuilder) +target_include_directories(tilebuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tile_builder) target_link_libraries(tilebuilderlib PUBLIC terrainlib radix ZLIB::ZLIB GDAL::GDAL fmt) -add_executable(tilebuilder - tilebuilder/main.cpp +add_executable(tile-builder + tile_builder/main.cpp ) -target_link_libraries(tilebuilder PUBLIC tilebuilderlib) - - -add_library(terrainmergerlib - terrainmerger/merge/visitor/Masked.h - terrainmerger/merge/visitor/Simple.h - terrainmerger/merge/visitor/Visitor.h - terrainmerger/merge/NodeData.h - terrainmerger/merge/Result.h - terrainmerger/cut.h - terrainmerger/earth.h - terrainmerger/mask.h - terrainmerger/merge.h - terrainmerger/NodeLoader.h - terrainmerger/NodeWriter.h - terrainmerger/SimpleMutex.h - terrainmerger/utils.h +target_link_libraries(tile-builder PUBLIC tilebuilderlib) + + +add_library(sfmergerlib + sf_merger/atlas/build.h + sf_merger/atlas/HorizontalStripLayoutPlanner.h + sf_merger/atlas/Layout.h + sf_merger/atlas/LayoutPlanner.h + sf_merger/atlas/Sheet.h + + sf_merger/merge/visitor/Masked.h + sf_merger/merge/visitor/Simple.h + sf_merger/merge/visitor/Visitor.h + sf_merger/merge/NodeData.h + sf_merger/merge/Result.h + + sf_merger/cut.h + sf_merger/earth.h + sf_merger/mask.h + sf_merger/merge.h + sf_merger/NodeLoader.h + sf_merger/NodeWriter.h + sf_merger/SimpleMutex.h + sf_merger/utils.h ) -target_include_directories(terrainmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainmerger) -target_link_libraries(terrainmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected xatlas) -add_executable(terrainmerger - terrainmerger/main.cpp - terrainmerger/cli.h terrainmerger/cli.cpp +target_include_directories(sfmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/sf_merger) +target_link_libraries(sfmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) +add_executable(sf-merger + sf_merger/main.cpp + sf_merger/cli.h sf_merger/cli.cpp ) -target_link_libraries(terrainmerger PUBLIC terrainmergerlib) - - -add_library(terrainbuilderlib - terrainbuilder/tile_provider.h - terrainbuilder/mesh_builder.h - terrainbuilder/mesh_builder.cpp - terrainbuilder/raw_dataset_reader.h - terrainbuilder/texture_assembler.h - terrainbuilder/border.h - terrainbuilder/raster.h - terrainbuilder/terrainbuilder.h - terrainbuilder/terrainbuilder.cpp +target_link_libraries(sf-merger PUBLIC sfmergerlib) + + +add_library(meshbuilderlib + mesh_builder/tile_provider.h + mesh_builder/mesh_builder.h + mesh_builder/mesh_builder.cpp + mesh_builder/raw_dataset_reader.h + mesh_builder/texture_assembler.h + mesh_builder/border.h + mesh_builder/raster.h + mesh_builder/mesh_builder.h + mesh_builder/mesh_builder.cpp ) -target_include_directories(terrainbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainbuilder) -target_link_libraries(terrainbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) -add_executable(terrainbuilder - terrainbuilder/main.cpp +target_include_directories(meshbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/mesh_builder) +target_link_libraries(meshbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) +add_executable(mesh-builder + mesh_builder/main.cpp ) -target_link_libraries(terrainbuilder PUBLIC terrainbuilderlib) +target_link_libraries(mesh-builder PUBLIC meshbuilderlib) -add_library(terrainsimplifylib - terrainsimplify/cli.h - terrainsimplify/cli.cpp - terrainsimplify/simplify.h - terrainsimplify/simplify.cpp - terrainsimplify/uv_map.h - terrainsimplify/uv_map.cpp +add_library(meshsimplifylib + mesh_simplify/cli.h + mesh_simplify/cli.cpp + mesh_simplify/simplify.h + mesh_simplify/simplify.cpp + mesh_simplify/uv_map.h + mesh_simplify/uv_map.cpp ) -target_include_directories(terrainsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainsimplify) -target_precompile_headers(terrainsimplifylib PRIVATE terrainsimplify/pch.h) -target_link_libraries(terrainsimplifylib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) -add_executable(terrainsimplify - terrainsimplify/main.cpp +target_include_directories(meshsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/mesh_simplify) +target_precompile_headers(meshsimplifylib PRIVATE mesh_simplify/pch.h) +target_link_libraries(meshsimplifylib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) +add_executable(mesh-simplify + mesh_simplify/main.cpp ) -target_link_libraries(terrainsimplify PUBLIC terrainsimplifylib) +target_link_libraries(mesh-simplify PUBLIC meshsimplifylib) add_executable(tile-downloader tile_downloader/main.cpp ) target_link_libraries(tile-downloader PUBLIC terrainlib ${CURL_LIBRARIES}) -add_executable(terrainconvert - terrainconvert/cli.h terrainconvert/cli.cpp - terrainconvert/main.cpp +add_executable(mesh-convert + mesh_convert/cli.h mesh_convert/cli.cpp + mesh_convert/main.cpp ) -target_link_libraries(terrainconvert PUBLIC terrainlib CLI11::CLI11) +target_link_libraries(mesh-convert PUBLIC terrainlib CLI11::CLI11) -add_executable(index_browser +add_executable(index-browser index_browser/cli.h index_browser/cli.cpp index_browser/main.cpp ) -target_link_libraries(index_browser PUBLIC terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) - add_executable(mesh_merger mesh_merger/cli.h mesh_merger/cli.cpp mesh_merger/main.cpp ) target_link_libraries(mesh_merger PUBLIC terrainlib CLI11::CLI11) +target_link_libraries(index-browser PUBLIC terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) add_executable(browser # browser/main2.cpp diff --git a/src/index_browser/cli.cpp b/src/index_browser/cli.cpp index ad8d771..b97f5f5 100644 --- a/src/index_browser/cli.cpp +++ b/src/index_browser/cli.cpp @@ -10,7 +10,7 @@ Args cli::parse(int argc, const char * const * argv) { DEBUG_ASSERT(argc >= 0); Args args; - CLI::App app{"index browser"}; + CLI::App app{"index_browser"}; app.positionals_at_end(false); app.allow_windows_style_options(false); diff --git a/src/terrainbuilder/border.h b/src/mesh_builder/border.h similarity index 100% rename from src/terrainbuilder/border.h rename to src/mesh_builder/border.h diff --git a/src/terrainbuilder/main.cpp b/src/mesh_builder/main.cpp similarity index 99% rename from src/terrainbuilder/main.cpp rename to src/mesh_builder/main.cpp index 36be478..496042e 100644 --- a/src/terrainbuilder/main.cpp +++ b/src/mesh_builder/main.cpp @@ -137,7 +137,7 @@ int run(std::span args) { int argc = args.size(); char **argv = args.data(); - CLI::App app{"Terrain Builder"}; + CLI::App app{"mesh_builder"}; app.allow_windows_style_options(); argv = app.ensure_utf8(argv); diff --git a/src/terrainbuilder/mesh_builder.cpp b/src/mesh_builder/mesh_builder.cpp similarity index 100% rename from src/terrainbuilder/mesh_builder.cpp rename to src/mesh_builder/mesh_builder.cpp diff --git a/src/terrainbuilder/mesh_builder.h b/src/mesh_builder/mesh_builder.h similarity index 100% rename from src/terrainbuilder/mesh_builder.h rename to src/mesh_builder/mesh_builder.h diff --git a/src/terrainbuilder/raster.h b/src/mesh_builder/raster.h similarity index 100% rename from src/terrainbuilder/raster.h rename to src/mesh_builder/raster.h diff --git a/src/terrainbuilder/raw_dataset_reader.h b/src/mesh_builder/raw_dataset_reader.h similarity index 100% rename from src/terrainbuilder/raw_dataset_reader.h rename to src/mesh_builder/raw_dataset_reader.h diff --git a/src/terrainbuilder/terrainbuilder.cpp b/src/mesh_builder/terrainbuilder.cpp similarity index 100% rename from src/terrainbuilder/terrainbuilder.cpp rename to src/mesh_builder/terrainbuilder.cpp diff --git a/src/terrainbuilder/terrainbuilder.h b/src/mesh_builder/terrainbuilder.h similarity index 100% rename from src/terrainbuilder/terrainbuilder.h rename to src/mesh_builder/terrainbuilder.h diff --git a/src/terrainbuilder/texture_assembler.h b/src/mesh_builder/texture_assembler.h similarity index 100% rename from src/terrainbuilder/texture_assembler.h rename to src/mesh_builder/texture_assembler.h diff --git a/src/terrainbuilder/tile_provider.h b/src/mesh_builder/tile_provider.h similarity index 100% rename from src/terrainbuilder/tile_provider.h rename to src/mesh_builder/tile_provider.h diff --git a/src/terrainconvert/cli.cpp b/src/mesh_convert/cli.cpp similarity index 97% rename from src/terrainconvert/cli.cpp rename to src/mesh_convert/cli.cpp index d2d191b..4b69070 100644 --- a/src/terrainconvert/cli.cpp +++ b/src/mesh_convert/cli.cpp @@ -6,7 +6,7 @@ using namespace cli; Args cli::parse(int argc, const char * const* argv) { DEBUG_ASSERT(argc >= 0); - CLI::App app{"terrainconvert"}; + CLI::App app{"mesh_convert"}; std::filesystem::path input_path; app.add_option("--input", input_path, "Path of tile to be converted") diff --git a/src/terrainconvert/cli.h b/src/mesh_convert/cli.h similarity index 100% rename from src/terrainconvert/cli.h rename to src/mesh_convert/cli.h diff --git a/src/terrainconvert/main.cpp b/src/mesh_convert/main.cpp similarity index 100% rename from src/terrainconvert/main.cpp rename to src/mesh_convert/main.cpp diff --git a/src/terrainsimplify/cli.cpp b/src/mesh_simplify/cli.cpp similarity index 99% rename from src/terrainsimplify/cli.cpp rename to src/mesh_simplify/cli.cpp index a2ff0a2..a5c4c20 100644 --- a/src/terrainsimplify/cli.cpp +++ b/src/mesh_simplify/cli.cpp @@ -8,7 +8,7 @@ using namespace cli; Args cli::parse(int argc, const char * const * argv) { DEBUG_ASSERT(argc >= 0); - CLI::App app{"terrainsimplify"}; + CLI::App app{"mesh_simplify"}; app.allow_windows_style_options(); // argv = app.ensure_utf8(argv); diff --git a/src/terrainsimplify/cli.h b/src/mesh_simplify/cli.h similarity index 100% rename from src/terrainsimplify/cli.h rename to src/mesh_simplify/cli.h diff --git a/src/terrainsimplify/main.cpp b/src/mesh_simplify/main.cpp similarity index 100% rename from src/terrainsimplify/main.cpp rename to src/mesh_simplify/main.cpp diff --git a/src/terrainsimplify/pch.h b/src/mesh_simplify/pch.h similarity index 100% rename from src/terrainsimplify/pch.h rename to src/mesh_simplify/pch.h diff --git a/src/terrainsimplify/simplify.cpp b/src/mesh_simplify/simplify.cpp similarity index 100% rename from src/terrainsimplify/simplify.cpp rename to src/mesh_simplify/simplify.cpp diff --git a/src/terrainsimplify/simplify.h b/src/mesh_simplify/simplify.h similarity index 100% rename from src/terrainsimplify/simplify.h rename to src/mesh_simplify/simplify.h diff --git a/src/terrainsimplify/uv_map.cpp b/src/mesh_simplify/uv_map.cpp similarity index 100% rename from src/terrainsimplify/uv_map.cpp rename to src/mesh_simplify/uv_map.cpp diff --git a/src/terrainsimplify/uv_map.h b/src/mesh_simplify/uv_map.h similarity index 100% rename from src/terrainsimplify/uv_map.h rename to src/mesh_simplify/uv_map.h diff --git a/src/terrainmerger/NodeLoader.h b/src/sf_merger/NodeLoader.h similarity index 100% rename from src/terrainmerger/NodeLoader.h rename to src/sf_merger/NodeLoader.h diff --git a/src/terrainmerger/NodeWriter.h b/src/sf_merger/NodeWriter.h similarity index 100% rename from src/terrainmerger/NodeWriter.h rename to src/sf_merger/NodeWriter.h diff --git a/src/terrainmerger/SimpleMutex.h b/src/sf_merger/SimpleMutex.h similarity index 100% rename from src/terrainmerger/SimpleMutex.h rename to src/sf_merger/SimpleMutex.h diff --git a/src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h b/src/sf_merger/atlas/HorizontalStripLayoutPlanner.h similarity index 100% rename from src/terrainmerger/atlas/HorizontalStripLayoutPlanner.h rename to src/sf_merger/atlas/HorizontalStripLayoutPlanner.h diff --git a/src/terrainmerger/atlas/Layout.h b/src/sf_merger/atlas/Layout.h similarity index 100% rename from src/terrainmerger/atlas/Layout.h rename to src/sf_merger/atlas/Layout.h diff --git a/src/terrainmerger/atlas/LayoutPlanner.h b/src/sf_merger/atlas/LayoutPlanner.h similarity index 100% rename from src/terrainmerger/atlas/LayoutPlanner.h rename to src/sf_merger/atlas/LayoutPlanner.h diff --git a/src/terrainmerger/atlas/Sheet.h b/src/sf_merger/atlas/Sheet.h similarity index 100% rename from src/terrainmerger/atlas/Sheet.h rename to src/sf_merger/atlas/Sheet.h diff --git a/src/terrainmerger/atlas/build.h b/src/sf_merger/atlas/build.h similarity index 100% rename from src/terrainmerger/atlas/build.h rename to src/sf_merger/atlas/build.h diff --git a/src/terrainmerger/cli.cpp b/src/sf_merger/cli.cpp similarity index 83% rename from src/terrainmerger/cli.cpp rename to src/sf_merger/cli.cpp index 7afe3c0..e87b0a4 100644 --- a/src/terrainmerger/cli.cpp +++ b/src/sf_merger/cli.cpp @@ -9,7 +9,7 @@ using namespace cli; Args cli::parse(int argc, const char *const *argv) { DEBUG_ASSERT(argc >= 0); - CLI::App app{"terrainmerger"}; + CLI::App app{"mesh_merger"}; app.allow_windows_style_options(); // argv = app.ensure_utf8(argv); @@ -71,11 +71,8 @@ Args cli::parse(int argc, const char *const *argv) { app.require_subcommand(1); try { - // app.parse(argc, argv); - // app.parse("--input ../../../meshes/innenstadt2 ../../../meshes/vienna2 --output ../../../meshes/out --verbosity trace"); - app.parse("merge --new ../../../meshes/innenstadt --base ../../../meshes/vienna --mask ../../../meshes/mask.geojson --output ../../../meshes/out-merge --verbosity trace"); - // app.parse("cut --input ../../../meshes/innenstadt --mask ../../../meshes/mask.geojson --output ../../../meshes/out-cut --keep-outside --verbosity trace"); - } catch (const CLI::ParseError &e) { + app.parse(argc, argv); + } catch (const CLI::ParseError &e) { exit(app.exit(e)); } diff --git a/src/terrainmerger/cli.h b/src/sf_merger/cli.h similarity index 100% rename from src/terrainmerger/cli.h rename to src/sf_merger/cli.h diff --git a/src/terrainmerger/cut.h b/src/sf_merger/cut.h similarity index 100% rename from src/terrainmerger/cut.h rename to src/sf_merger/cut.h diff --git a/src/terrainmerger/earth.h b/src/sf_merger/earth.h similarity index 100% rename from src/terrainmerger/earth.h rename to src/sf_merger/earth.h diff --git a/src/terrainmerger/main.cpp b/src/sf_merger/main.cpp similarity index 100% rename from src/terrainmerger/main.cpp rename to src/sf_merger/main.cpp diff --git a/src/terrainmerger/mask.h b/src/sf_merger/mask.h similarity index 100% rename from src/terrainmerger/mask.h rename to src/sf_merger/mask.h diff --git a/src/terrainmerger/merge.h b/src/sf_merger/merge.h similarity index 100% rename from src/terrainmerger/merge.h rename to src/sf_merger/merge.h diff --git a/src/terrainmerger/merge/NodeData.h b/src/sf_merger/merge/NodeData.h similarity index 100% rename from src/terrainmerger/merge/NodeData.h rename to src/sf_merger/merge/NodeData.h diff --git a/src/terrainmerger/merge/Result.h b/src/sf_merger/merge/Result.h similarity index 100% rename from src/terrainmerger/merge/Result.h rename to src/sf_merger/merge/Result.h diff --git a/src/terrainmerger/merge/visitor/Masked.h b/src/sf_merger/merge/visitor/Masked.h similarity index 100% rename from src/terrainmerger/merge/visitor/Masked.h rename to src/sf_merger/merge/visitor/Masked.h diff --git a/src/terrainmerger/merge/visitor/Simple.h b/src/sf_merger/merge/visitor/Simple.h similarity index 100% rename from src/terrainmerger/merge/visitor/Simple.h rename to src/sf_merger/merge/visitor/Simple.h diff --git a/src/terrainmerger/merge/visitor/Visitor.h b/src/sf_merger/merge/visitor/Visitor.h similarity index 100% rename from src/terrainmerger/merge/visitor/Visitor.h rename to src/sf_merger/merge/visitor/Visitor.h diff --git a/src/terrainmerger/utils.h b/src/sf_merger/utils.h similarity index 100% rename from src/terrainmerger/utils.h rename to src/sf_merger/utils.h diff --git a/src/tilebuilder/DatasetReader.cpp b/src/tile_builder/DatasetReader.cpp similarity index 100% rename from src/tilebuilder/DatasetReader.cpp rename to src/tile_builder/DatasetReader.cpp diff --git a/src/tilebuilder/DatasetReader.h b/src/tile_builder/DatasetReader.h similarity index 100% rename from src/tilebuilder/DatasetReader.h rename to src/tile_builder/DatasetReader.h diff --git a/src/tilebuilder/Exception.h b/src/tile_builder/Exception.h similarity index 100% rename from src/tilebuilder/Exception.h rename to src/tile_builder/Exception.h diff --git a/src/tilebuilder/Image.cpp b/src/tile_builder/Image.cpp similarity index 100% rename from src/tilebuilder/Image.cpp rename to src/tile_builder/Image.cpp diff --git a/src/tilebuilder/Image.h b/src/tile_builder/Image.h similarity index 100% rename from src/tilebuilder/Image.h rename to src/tile_builder/Image.h diff --git a/src/tilebuilder/ParallelTileGenerator.cpp b/src/tile_builder/ParallelTileGenerator.cpp similarity index 100% rename from src/tilebuilder/ParallelTileGenerator.cpp rename to src/tile_builder/ParallelTileGenerator.cpp diff --git a/src/tilebuilder/ParallelTileGenerator.h b/src/tile_builder/ParallelTileGenerator.h similarity index 100% rename from src/tilebuilder/ParallelTileGenerator.h rename to src/tile_builder/ParallelTileGenerator.h diff --git a/src/tilebuilder/ParallelTiler.cpp b/src/tile_builder/ParallelTiler.cpp similarity index 100% rename from src/tilebuilder/ParallelTiler.cpp rename to src/tile_builder/ParallelTiler.cpp diff --git a/src/tilebuilder/ParallelTiler.h b/src/tile_builder/ParallelTiler.h similarity index 100% rename from src/tilebuilder/ParallelTiler.h rename to src/tile_builder/ParallelTiler.h diff --git a/src/tilebuilder/TileHeightsGenerator.cpp b/src/tile_builder/TileHeightsGenerator.cpp similarity index 100% rename from src/tilebuilder/TileHeightsGenerator.cpp rename to src/tile_builder/TileHeightsGenerator.cpp diff --git a/src/tilebuilder/TileHeightsGenerator.h b/src/tile_builder/TileHeightsGenerator.h similarity index 100% rename from src/tilebuilder/TileHeightsGenerator.h rename to src/tile_builder/TileHeightsGenerator.h diff --git a/src/tilebuilder/Tiler.cpp b/src/tile_builder/Tiler.cpp similarity index 100% rename from src/tilebuilder/Tiler.cpp rename to src/tile_builder/Tiler.cpp diff --git a/src/tilebuilder/Tiler.h b/src/tile_builder/Tiler.h similarity index 100% rename from src/tilebuilder/Tiler.h rename to src/tile_builder/Tiler.h diff --git a/src/tilebuilder/TopDownTiler.cpp b/src/tile_builder/TopDownTiler.cpp similarity index 100% rename from src/tilebuilder/TopDownTiler.cpp rename to src/tile_builder/TopDownTiler.cpp diff --git a/src/tilebuilder/TopDownTiler.h b/src/tile_builder/TopDownTiler.h similarity index 100% rename from src/tilebuilder/TopDownTiler.h rename to src/tile_builder/TopDownTiler.h diff --git a/src/tilebuilder/algorithms/primitives.h b/src/tile_builder/algorithms/primitives.h similarity index 100% rename from src/tilebuilder/algorithms/primitives.h rename to src/tile_builder/algorithms/primitives.h diff --git a/src/tilebuilder/algorithms/raster_triangle_scanline.h b/src/tile_builder/algorithms/raster_triangle_scanline.h similarity index 100% rename from src/tilebuilder/algorithms/raster_triangle_scanline.h rename to src/tile_builder/algorithms/raster_triangle_scanline.h diff --git a/src/tilebuilder/alpine_raster.cpp b/src/tile_builder/alpine_raster.cpp similarity index 100% rename from src/tilebuilder/alpine_raster.cpp rename to src/tile_builder/alpine_raster.cpp diff --git a/src/tilebuilder/alpine_raster.h b/src/tile_builder/alpine_raster.h similarity index 100% rename from src/tilebuilder/alpine_raster.h rename to src/tile_builder/alpine_raster.h diff --git a/src/tilebuilder/depth_first_tile_traverser.h b/src/tile_builder/depth_first_tile_traverser.h similarity index 100% rename from src/tilebuilder/depth_first_tile_traverser.h rename to src/tile_builder/depth_first_tile_traverser.h diff --git a/src/tilebuilder/main.cpp b/src/tile_builder/main.cpp similarity index 100% rename from src/tilebuilder/main.cpp rename to src/tile_builder/main.cpp diff --git a/src/tilebuilder/srs.h b/src/tile_builder/srs.h similarity index 100% rename from src/tilebuilder/srs.h rename to src/tile_builder/srs.h From 31998c18b4a1dea8747662178743252413856102 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 9 Oct 2025 17:49:42 +0200 Subject: [PATCH 121/122] Minor fix --- src/mesh_builder/mesh_builder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh_builder/mesh_builder.cpp b/src/mesh_builder/mesh_builder.cpp index d79abbd..88e4735 100644 --- a/src/mesh_builder/mesh_builder.cpp +++ b/src/mesh_builder/mesh_builder.cpp @@ -125,7 +125,7 @@ SimpleMesh transform_mesh(const SimpleMesh &source_mesh, const OGRSpatialReferen std::vector generate_uv_space(const std::vector& positions, const OGRSpatialReference &mesh_srs, const OGRSpatialReference &texture_srs, radix::tile::SrsBounds& texture_bounds) { std::vector uvs = srs::transform_points_to_2d(srs::transformation(mesh_srs, texture_srs).get(), positions); - texture_bounds = radix::tile::SrsBounds(radix::geometry::find_bounds(uvs)); + texture_bounds = radix::tile::SrsBounds(radix::geometry::find_bounds(std::span(uvs))); for (glm::dvec2 &uv : uvs) { uv = (uv - texture_bounds.min) / texture_bounds.size(); From 4acd32d529aa665304f6d7e8597db118969c1c19 Mon Sep 17 00:00:00 2001 From: Martin Braunsperger Date: Thu, 9 Oct 2025 17:49:57 +0200 Subject: [PATCH 122/122] Fix oom bug with large intermediate textures --- src/mesh_builder/texture_assembler.h | 151 +++++++++++++++++++++------ 1 file changed, 120 insertions(+), 31 deletions(-) diff --git a/src/mesh_builder/texture_assembler.h b/src/mesh_builder/texture_assembler.h index e326e0c..5e14154 100644 --- a/src/mesh_builder/texture_assembler.h +++ b/src/mesh_builder/texture_assembler.h @@ -6,6 +6,8 @@ #include #include +#include + #include #include #include @@ -70,23 +72,36 @@ namespace terrainbuilder { return true; } - // Check the region of this tile can be assembled from its children (or further down) - bool all_children_present = false; + // Check if the current tile is available. + const bool has_current_tile = tile_provider.has_tile(tile); + + // If we are not deep enough yet, recurse further down. + bool should_recurse; if (tile.zoom_level + 1 <= min_zoom_level_to_examine.value()) { - all_children_present = true; + // Minimum zoom level to examine not yet reached. + should_recurse = true; + } else { + // Minimum zoom level reached, only continue if the current tile is available. + should_recurse = has_current_tile; + } + + // Check the region of this tile can be assembled from its children (or further down) + if (should_recurse) { + bool all_children_present = true; + for (const radix::tile::Id subtile : tile.children()) { if (!helper(subtile)) { all_children_present = false; } } - } - if (all_children_present) { - return true; + if (all_children_present) { + return true; + } } // Check if the current tile is available as a replacement. - if (!tile_provider.has_tile(tile)) { + if (!has_current_tile) { return false; } @@ -114,10 +129,13 @@ namespace terrainbuilder { const unsigned int zoom_level_range) { const glm::dvec2 relative_min = (target_bounds.min - root_tile_bounds.min) / root_tile_bounds.size(); const glm::dvec2 relative_max = (target_bounds.max - root_tile_bounds.min) / root_tile_bounds.size(); + const unsigned int full_image_size_factor = std::pow(2, zoom_level_range); const glm::uvec2 root_tile_image_size = tile_image_pixel_size * glm::uvec2(full_image_size_factor); const glm::uvec2 target_pixel_offset_min(glm::floor(relative_min * glm::dvec2(root_tile_image_size))); const glm::uvec2 target_pixel_offset_max(glm::ceil(relative_max * glm::dvec2(root_tile_image_size))); + + // Map from bottom-left origin to top-left origin const radix::geometry::Aabb2ui target_image_region( glm::uvec2(target_pixel_offset_min.x, root_tile_image_size.y - target_pixel_offset_max.y), glm::uvec2(target_pixel_offset_max.x, root_tile_image_size.y - target_pixel_offset_min.y)); @@ -129,9 +147,7 @@ namespace terrainbuilder { const radix::tile::Id root_tile, const glm::uvec2 tile_image_pixel_size, const unsigned int max_zoom_level) { - if (tile.scheme != radix::tile::Scheme::SlippyMap) { - tile = tile.to(radix::tile::Scheme::SlippyMap); - } + tile = tile.to(radix::tile::Scheme::SlippyMap); const size_t relative_zoom_level = tile.zoom_level - root_tile.zoom_level; const glm::uvec2 tile_size_factor = glm::uvec2(std::pow(2, max_zoom_level - tile.zoom_level)); const glm::uvec2 tile_size = tile_image_pixel_size * tile_size_factor; @@ -140,32 +156,100 @@ namespace terrainbuilder { return radix::geometry::Aabb2ui(tile_position, tile_position + tile_size); } +[[nodiscard]] cv::Rect to_cv_rect(radix::geometry::Aabb2ui aabb) { + const glm::uvec2 size = aabb.size(); + return cv::Rect{ + static_cast(aabb.min.x), + static_cast(aabb.min.y), + static_cast(size.x), + static_cast(size.y) + }; +} +[[nodiscard]] cv::Size to_cv_size(glm::uvec2 vec) { + return cv::Size{ + static_cast(vec.x), + static_cast(vec.y) + }; +} + void copy_paste_image( cv::Mat &target, const cv::Mat &source, const radix::geometry::Aabb2i target_bounds, const bool trim_excess = false, const cv::InterpolationFlags rescale_filter = cv::INTER_LINEAR) { - if (target_bounds.width() != source.cols || target_bounds.height() != source.rows) { - cv::Mat source_resized; - cv::resize(source, source_resized, cv::Size(target_bounds.width(), target_bounds.height()), 0, 0, rescale_filter); - copy_paste_image(target, source_resized, target_bounds, trim_excess); - return; - } - - cv::Rect source_rect(0, 0, source.cols, source.rows); - cv::Rect target_rect(target_bounds.min.x, target_bounds.min.y, target_bounds.width(), target_bounds.height()); - if (trim_excess) { - const cv::Rect full_target_rect(0, 0, target.cols, target.rows); - target_rect = target_rect & full_target_rect; - source_rect = cv::Rect(target_rect.x - target_bounds.min.x, target_rect.y - target_bounds.min.y, target_rect.width, target_rect.height); - } - - if (source_rect.empty()) { - return; + // Full source/target rectangles + const cv::Rect full_source_rect(0, 0, source.cols, source.rows); + const cv::Rect full_target_rect(0, 0, target.cols, target.rows); + + cv::Rect source_rect = full_source_rect; + // Target rectangle for source image in target image + cv::Rect target_rect = to_cv_rect(target_bounds); + + // Compute scale factors from source to target + const glm::dvec2 scale( + static_cast(source_rect.width) / target_rect.width, + static_cast(source_rect.height) / target_rect.height); + + // Check bounds + const cv::Rect clipped_target_rect = target_rect & full_target_rect; + if (!trim_excess) { + // Must fit entirely + if (clipped_target_rect != target_rect) { + throw std::runtime_error("Target rectangle out of bounds and trim_excess is false"); + } + } else { + target_rect = clipped_target_rect; + if (target_rect.empty()) { + return; + } } - source(source_rect).copyTo(target(target_rect)); + // Calculate offset and size of clipped target rect + const glm::ivec2 trg_offset = glm::ivec2( + target_rect.x - target_bounds.min.x, + target_rect.y - target_bounds.min.y); + const glm::uvec2 trg_size = glm::uvec2(target_rect.width, target_rect.height); + + // Exact source region corresponding to clipped target rect + const radix::geometry::Aabb2d src_exact(glm::dvec2(trg_offset) * scale, glm::dvec2(trg_offset + glm::ivec2(trg_size)) * scale); + + // Pad outwards to integer pixel boundaries for OpenCV crop + const radix::geometry::Aabb2ui src_padded( + glm::uvec2(glm::floor(src_exact.min)), + glm::uvec2(glm::ceil(src_exact.max))); + const radix::geometry::Aabb2d src_padding( + src_exact.min - glm::dvec2(src_padded.min), + glm::dvec2(src_padded.max) - src_exact.max); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(src_padding, glm::dvec2(0)))); + + // Safe integer crop of source + const cv::Rect src_padded_cv = to_cv_rect(src_padded); + DEBUG_ASSERT(src_padded_cv == (src_padded_cv & full_source_rect)); + const cv::Mat source_cropped = source(src_padded_cv); + + // Compute the target size including padding + const radix::geometry::Aabb2ui target_padding( + glm::uvec2(glm::round(src_padding.min / scale)), + glm::uvec2(glm::round(src_padding.max / scale)) + ); + const glm::uvec2 padded_target_size = target_padding.min + trg_size + target_padding.max; + + // Resize the padded crop -> padded target size + cv::Mat source_resized; + cv::resize(source_cropped, source_resized, to_cv_size(padded_target_size), 0, 0, rescale_filter); + + // Crop off the padding + const radix::geometry::Aabb2ui unpad_rect( + target_padding.min, + target_padding.min + trg_size); + const cv::Rect unpad_rect_cv = to_cv_rect(unpad_rect); + DEBUG_ASSERT(unpad_rect_cv == (unpad_rect_cv & cv::Rect(0, 0, source_resized.cols, source_resized.rows))); + + const cv::Mat final_source = source_resized(unpad_rect_cv); + + // Copy into target + final_source.copyTo(target(target_rect)); } void copy_paste_image( @@ -210,7 +294,7 @@ std::optional try_get_tile_path(const radix::tile::Id til DEBUG_ASSERT(max_zoom_level >= root_tile.zoom_level); const unsigned int zoom_level_range = max_zoom_level - root_tile.zoom_level; - // Choose any tile to load infer like tile size and format to allocate our texture buffer accordingly. + // Choose any tile to infer tile size and format to allocate our texture buffer accordingly. const radix::tile::Id &any_tile = tiles_to_splatter.front(); const cv::Mat any_tile_image = tile_provider.get_tile(any_tile).value(); const glm::uvec2 tile_image_size(any_tile_image.cols, any_tile_image.rows); @@ -221,10 +305,15 @@ std::optional try_get_tile_path(const radix::tile::Id til const glm::uvec2 image_size = target_image_region.size(); // Allocate the image to write all the individual tiles into. + LOG_DEBUG("Allocating image {}x{} type={} (≈{:.2f} MB)", + image_size.x, + image_size.y, + cv::typeToString(any_tile_image.type()), + (image_size.x * image_size.y * any_tile_image.elemSize()) / (1024.0 * 1024.0)); cv::Mat image = cv::Mat::zeros(image_size.y, image_size.x, any_tile_image.type()); for (const radix::tile::Id &tile : tiles_to_splatter) { - cv::Mat tile_image = tile_provider.get_tile(tile).value(); + const cv::Mat tile_image = tile_provider.get_tile(tile).value(); if (tile_image.empty()) { const std::optional tile_path = try_get_tile_path(tile, tile_provider); if (tile_path.has_value()) { @@ -254,6 +343,7 @@ std::optional try_get_tile_path(const radix::tile::Id til // Resize current tile image and copy into image buffer. copy_paste_image(image, tile_image, target_pixel_tile_bounds, true /* allows und handles overflow */, rescale_filter); + } cv::flip(image, image, 0); @@ -304,5 +394,4 @@ std::optional try_get_tile_path(const radix::tile::Id til // Splatter tiles into texture buffer return splatter_tiles_to_texture(smallest_encompassing_tile, grid, encompassing_bounds, tile_provider, tiles_to_splatter, rescale_filter); } - }